diff --git a/cookbooks/lxc/default.rb b/cookbooks/lxc/default.rb new file mode 100644 index 0000000..f63eb27 --- /dev/null +++ b/cookbooks/lxc/default.rb @@ -0,0 +1,16 @@ +# Install the necessary packages: +include_recipe './packages.rb' +include_recipe './eget.rb' + +# `unattended-upgrade` settings: +include_recipe './unattended-upgrade.rb' + +# `ufw` configurations: +include_recipe './ufw.rb' + +# timezone configurations: +include_recipe './timezone.rb' + +execute 'ufw allow 22/tcp' do + notifies :run, 'execute[ufw reload-or-enable]' +end diff --git a/cookbooks/lxc/eget.rb b/cookbooks/lxc/eget.rb new file mode 100644 index 0000000..a70978a --- /dev/null +++ b/cookbooks/lxc/eget.rb @@ -0,0 +1,14 @@ +result = run_command('which eget', error: false) +if result.exit_status != 0 + # Install eget + execute 'curl https://zyedidia.github.io/eget.sh | sh' do + cwd '/usr/local/bin/' + end + + execute 'chown root:root /usr/local/bin/eget' + execute 'chmod 755 /usr/local/bin/eget' +end + +%w( zyedidia/eget mgdm/htmlq ).each do |p| + execute "eget #{p} --to /usr/local/bin/ --upgrade-only" +end diff --git a/cookbooks/lxc/files/etc/apt/apt.conf.d/20auto-upgrades b/cookbooks/lxc/files/etc/apt/apt.conf.d/20auto-upgrades new file mode 100644 index 0000000..8d6d7c8 --- /dev/null +++ b/cookbooks/lxc/files/etc/apt/apt.conf.d/20auto-upgrades @@ -0,0 +1,2 @@ +APT::Periodic::Update-Package-Lists "1"; +APT::Periodic::Unattended-Upgrade "1"; diff --git a/cookbooks/lxc/files/etc/apt/apt.conf.d/50unattended-upgrades b/cookbooks/lxc/files/etc/apt/apt.conf.d/50unattended-upgrades new file mode 100644 index 0000000..307996d --- /dev/null +++ b/cookbooks/lxc/files/etc/apt/apt.conf.d/50unattended-upgrades @@ -0,0 +1,143 @@ +// Automatically upgrade packages from these (origin:archive) pairs +// +// Note that in Ubuntu security updates may pull in new dependencies +// from non-security sources (e.g. chromium). By allowing the release +// pocket these get automatically pulled in. +Unattended-Upgrade::Allowed-Origins { + "${distro_id}:${distro_codename}"; + "${distro_id}:${distro_codename}-security"; + // Extended Security Maintenance; doesn't necessarily exist for + // every release and this system may not have it installed, but if + // available, the policy for updates is such that unattended-upgrades + // should also install from here by default. + "${distro_id}ESMApps:${distro_codename}-apps-security"; + "${distro_id}ESM:${distro_codename}-infra-security"; +// "${distro_id}:${distro_codename}-updates"; +// "${distro_id}:${distro_codename}-proposed"; +// "${distro_id}:${distro_codename}-backports"; +}; + +// Python regular expressions, matching packages to exclude from upgrading +Unattended-Upgrade::Package-Blacklist { + // The following matches all packages starting with linux- +// "linux-"; + + // Use $ to explicitely define the end of a package name. Without + // the $, "libc6" would match all of them. +// "libc6$"; +// "libc6-dev$"; +// "libc6-i686$"; + + // Special characters need escaping +// "libstdc\+\+6$"; + + // The following matches packages like xen-system-amd64, xen-utils-4.1, + // xenstore-utils and libxenstore3.0 +// "(lib)?xen(store)?"; + + // For more information about Python regular expressions, see + // https://docs.python.org/3/howto/regex.html +}; + +// This option controls whether the development release of Ubuntu will be +// upgraded automatically. Valid values are "true", "false", and "auto". +Unattended-Upgrade::DevRelease "auto"; + +// This option allows you to control if on a unclean dpkg exit +// unattended-upgrades will automatically run +// dpkg --force-confold --configure -a +// The default is true, to ensure updates keep getting installed +//Unattended-Upgrade::AutoFixInterruptedDpkg "true"; + +// Split the upgrade into the smallest possible chunks so that +// they can be interrupted with SIGTERM. This makes the upgrade +// a bit slower but it has the benefit that shutdown while a upgrade +// is running is possible (with a small delay) +//Unattended-Upgrade::MinimalSteps "true"; + +// Install all updates when the machine is shutting down +// instead of doing it in the background while the machine is running. +// This will (obviously) make shutdown slower. +// Unattended-upgrades increases logind's InhibitDelayMaxSec to 30s. +// This allows more time for unattended-upgrades to shut down gracefully +// or even install a few packages in InstallOnShutdown mode, but is still a +// big step back from the 30 minutes allowed for InstallOnShutdown previously. +// Users enabling InstallOnShutdown mode are advised to increase +// InhibitDelayMaxSec even further, possibly to 30 minutes. +//Unattended-Upgrade::InstallOnShutdown "false"; + +// Send email to this address for problems or packages upgrades +// If empty or unset then no email is sent, make sure that you +// have a working mail setup on your system. A package that provides +// 'mailx' must be installed. E.g. "user@example.com" +//Unattended-Upgrade::Mail ""; + +// Set this value to one of: +// "always", "only-on-error" or "on-change" +// If this is not set, then any legacy MailOnlyOnError (boolean) value +// is used to chose between "only-on-error" and "on-change" +//Unattended-Upgrade::MailReport "on-change"; + +// Remove unused automatically installed kernel-related packages +// (kernel images, kernel headers and kernel version locked tools). +Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; + +// Do automatic removal of newly unused dependencies after the upgrade +Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; + +// Do automatic removal of unused packages after the upgrade +// (equivalent to apt-get autoremove) +Unattended-Upgrade::Remove-Unused-Dependencies "true"; + +// Automatically reboot *WITHOUT CONFIRMATION* if +// the file /var/run/reboot-required is found after the upgrade +Unattended-Upgrade::Automatic-Reboot "false"; + +// Automatically reboot even if there are users currently logged in +// when Unattended-Upgrade::Automatic-Reboot is set to true +//Unattended-Upgrade::Automatic-Reboot-WithUsers "true"; + +// If automatic reboot is enabled and needed, reboot at the specific +// time instead of immediately +// Default: "now" +//Unattended-Upgrade::Automatic-Reboot-Time "02:00"; + +// Use apt bandwidth limit feature, this example limits the download +// speed to 70kb/sec +//Acquire::http::Dl-Limit "70"; + +// Enable logging to syslog. Default is False +// Unattended-Upgrade::SyslogEnable "false"; + +// Specify syslog facility. Default is daemon +// Unattended-Upgrade::SyslogFacility "daemon"; + +// Download and install upgrades only on AC power +// (i.e. skip or gracefully stop updates on battery) +// Unattended-Upgrade::OnlyOnACPower "true"; + +// Download and install upgrades only on non-metered connection +// (i.e. skip or gracefully stop updates on a metered connection) +// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true"; + +// Verbose logging +// Unattended-Upgrade::Verbose "false"; + +// Print debugging information both in unattended-upgrades and +// in unattended-upgrade-shutdown +// Unattended-Upgrade::Debug "false"; + +// Allow package downgrade if Pin-Priority exceeds 1000 +// Unattended-Upgrade::Allow-downgrade "false"; + +// When APT fails to mark a package to be upgraded or installed try adjusting +// candidates of related packages to help APT's resolver in finding a solution +// where the package can be upgraded or installed. +// This is a workaround until APT's resolver is fixed to always find a +// solution if it exists. (See Debian bug #711128.) +// The fallback is enabled by default, except on Debian's sid release because +// uninstallable packages are frequent there. +// Disabling the fallback speeds up unattended-upgrades when there are +// uninstallable packages at the expense of rarely keeping back packages which +// could be upgraded or installed. +// Unattended-Upgrade::Allow-APT-Mark-Fallback "true"; diff --git a/cookbooks/lxc/files/etc/cron-apt/action.d/3-download b/cookbooks/lxc/files/etc/cron-apt/action.d/3-download new file mode 100644 index 0000000..93d2631 --- /dev/null +++ b/cookbooks/lxc/files/etc/cron-apt/action.d/3-download @@ -0,0 +1,2 @@ +autoclean -y +upgrade -y -o APT::Get::Show-Upgraded=true diff --git a/cookbooks/lxc/files/etc/cron-apt/config b/cookbooks/lxc/files/etc/cron-apt/config new file mode 100644 index 0000000..8c21dc6 --- /dev/null +++ b/cookbooks/lxc/files/etc/cron-apt/config @@ -0,0 +1,11 @@ +# Configuration for cron-apt. For further information about the possible +# configuration settings see the README file. + +SYSLOGON="always" +DEBUG="verbose" + +MAILON="" + +APTCOMMAND=/usr/bin/apt + +OPTIONS="-o quiet=1 -o Dir::Etc::SourceList=/etc/apt/security.sources.list" diff --git a/cookbooks/lxc/packages.rb b/cookbooks/lxc/packages.rb new file mode 100644 index 0000000..d0d9856 --- /dev/null +++ b/cookbooks/lxc/packages.rb @@ -0,0 +1,14 @@ +# Execute `apt update`: +execute 'apt update' + +# Install the necessary packages: +%w[build-essential zsh vim-nox debian-keyring curl direnv jq avahi-daemon wget gpg coreutils].each do |pkg| + package pkg +end + +execute 'ufw allow 5353/udp' do + user 'root' + + not_if 'LANG=c ufw status | grep 5353' + notifies :run, 'execute[ufw reload-or-enable]' +end diff --git a/cookbooks/lxc/templates/etc/apt/sources.list.d/git.list b/cookbooks/lxc/templates/etc/apt/sources.list.d/git.list new file mode 100644 index 0000000..dbb2a29 --- /dev/null +++ b/cookbooks/lxc/templates/etc/apt/sources.list.d/git.list @@ -0,0 +1 @@ +deb "http://ppa.launchpad.net/git-core/ppa/ubuntu" <%= @distribution %> main diff --git a/cookbooks/lxc/timezone.rb b/cookbooks/lxc/timezone.rb new file mode 100644 index 0000000..c5bf6ed --- /dev/null +++ b/cookbooks/lxc/timezone.rb @@ -0,0 +1,23 @@ +case node['platform_version'] +when "18.04", "20.04", "22.04", "24.04" + execute 'timedatectl set-timezone Asia/Tokyo' do + not_if 'timedatectl | grep Tokyo' + end +else + remote_file '/etc/timezone' do + user 'root' + owner 'root' + group 'root' + mode '644' + end + + [ + 'cp -f /usr/share/zoneinfo/Asia/Tokyo /etc/localtime' + ].each do |cmd| + execute cmd do + user 'root' + + not_if 'diff /usr/share/zoneinfo/Asia/Tokyo /etc/localtime' + end + end +end diff --git a/cookbooks/lxc/ufw.rb b/cookbooks/lxc/ufw.rb new file mode 100644 index 0000000..d9ecd41 --- /dev/null +++ b/cookbooks/lxc/ufw.rb @@ -0,0 +1,6 @@ +execute 'ufw reload-or-enable' do + user 'root' + command 'LANG=C ufw reload | grep skipping && ufw --force enable || exit 0' + + action :nothing +end diff --git a/cookbooks/lxc/unattended-upgrade.rb b/cookbooks/lxc/unattended-upgrade.rb new file mode 100644 index 0000000..1a522aa --- /dev/null +++ b/cookbooks/lxc/unattended-upgrade.rb @@ -0,0 +1,56 @@ +case run_command('grep VERSION_ID /etc/os-release | awk -F\" \'{print $2}\'').stdout.chomp +when "18.04" + # Install `cron-apt`: + package 'cron-apt' + + # From here, we are going to set up `cron-apt` to + # install the important security updates every day. + remote_file '/etc/cron-apt/config' do + user 'root' + + owner 'root' + group 'root' + mode '644' + end + + remote_file '/etc/cron-apt/action.d/3-download' do + user 'root' + + owner 'root' + group 'root' + mode '644' + end + + execute 'grep security /etc/apt/sources.list > /etc/apt/security.sources.list' do + user 'root' + + not_if 'test -e /etc/apt/security.sources.list' + end + + file '/var/log/cron-apt/log' do + user 'root' + + content 'foo\n' + + owner 'root' + group 'root' + mode '666' + + not_if 'test -e /var/log/cron-apt/log' + end + + execute '/usr/sbin/logrotate -f /etc/logrotate.d/cron-apt' do + user 'root' + + not_if 'test -e /var/log/cron-apt/log' + end + +when '20.04', '22.04', '24.04' + %w(20auto-upgrades 50unattended-upgrades).each do |conf| + remote_file "/etc/apt/apt.conf.d/#{conf}" do + owner 'root' + group 'root' + mode '644' + end + end +end diff --git a/roles/lxc.rb b/roles/lxc.rb new file mode 100644 index 0000000..986877d --- /dev/null +++ b/roles/lxc.rb @@ -0,0 +1,6 @@ +include_recipe "../cookbooks/lxc/default.rb" +include_recipe "../cookbooks/vault/default.rb" +include_recipe "../cookbooks/consul-template/default.rb" +include_recipe "../cookbooks/consul/default.rb" +include_recipe "../cookbooks/vector/default.rb" +include_recipe "../cookbooks/prometheus-exporters/default.rb" diff --git a/tasks/lxc.rake b/tasks/lxc.rake new file mode 100644 index 0000000..5142621 --- /dev/null +++ b/tasks/lxc.rake @@ -0,0 +1,9 @@ +#!/usr/bin/env rake + +desc 'Invoke itamae command for the lxc container' +task :lxc do + node = `ls -1 nodes/*.json | xargs -I % basename % .json | fzf` + node.chomp! + + sh "ITAMAE_PASSWORD=musashi bundle ex itamae ssh --host #{node} -j nodes/#{node}.json -u root entrypoint.rb" +end