infra-ansible
ansible script to ship alpine/ssh/wireguard
git clone https://9o.is/git/infra-ansible.git
commit aa2d65dfae2fb2c340a0157fc6f34e47e3a10f1d parent 0e124ff8430f3a3aab3b2929fb417416efd9a4c2 Author: Jul <jul@9o.is> Date: Sat, 1 Jun 2024 05:32:12 +0800 adjust tasks for alpine Diffstat:
34 files changed, 331 insertions(+), 338 deletions(-)
diff --git a/host/alpine.yml b/host/alpine.yml @@ -1,6 +1,7 @@ --- - name: Build Alpine hosts: servers + remote_user: root gather_facts: false roles: - alpine diff --git a/host/ansible.cfg b/host/ansible.cfg @@ -5,6 +5,3 @@ vault_password_file = contrib/vault-password.sh [diff] always = true -[privilege_escalation] -become = true - diff --git a/host/env/000_cross_env_vars b/host/env/000_cross_env_vars @@ -1,4 +1,7 @@ -alpine_version: 3.19 +alpine_version: '3.20' +alpine_repositories: + - https://dl-cdn.alpinelinux.org/alpine/v{{ alpine_version }}/main + static_interface: eth0 debian_preinstalled: false wireguard_port: 62620 diff --git a/host/env/prod/host_vars/server01.qh.is b/host/env/prod/host_vars/server01.qh.is @@ -1,3 +1,6 @@ +ansible_become_method: doas +ansible_python_interpreter: /usr/bin/python3.12 + debian_preinstalled: true debian_net_interface: ens3 diff --git a/host/env/test/host_vars/server01.local b/host/env/test/host_vars/server01.local @@ -1,3 +1,6 @@ +ansible_become_method: doas +ansible_python_interpreter: /usr/bin/python3.12 + static_ip: 10.137.0.5 static_subnet: 255.255.255.255 static_gateway: 10.137.0.39 diff --git a/host/readme.md b/host/readme.md @@ -1,7 +1,27 @@ ### Installation ``` -ansible-playbook alpine.yml --user root +ansible-playbook alpine.yml ansible-playbook site.yml --user root ``` +### Making changes + +- omit user root +- set become to true +- use tags + - basic + - apk + - user + - ssh + - vpn + - firewall + +``` +ansible-playbook site.yml --become --tags vpn,firewall +``` + +### Production + +- Use prod inventory path with `-i env/prod` + diff --git a/host/roles/alpine/tasks/build.yml b/host/roles/alpine/tasks/build.yml @@ -1,7 +1,6 @@ --- - name: create iso directory - become: false delegate_to: localhost file: path: '{{ alpine_output }}/iso' @@ -9,7 +8,6 @@ state: directory - name: add Containerfile - become: false delegate_to: localhost template: src: Containerfile.j2 @@ -17,7 +15,6 @@ mode: '0600' - name: add entrypoint.sh - become: false delegate_to: localhost template: src: entrypoint.sh.j2 @@ -25,7 +22,6 @@ mode: '0755' - name: add mkimg.x.sh - become: false delegate_to: localhost template: src: mkimg.x.sh.j2 @@ -33,7 +29,6 @@ mode: '0755' - name: add genapkovl-mkimgoverlay.sh - become: false delegate_to: localhost template: src: genapkovl-mkimgoverlay.sh.j2 @@ -41,7 +36,6 @@ mode: '0755' - name: build alpine-builder - become: false delegate_to: localhost podman_image: name: alpine-builder @@ -50,14 +44,12 @@ register: alpine_builder - name: check alpine iso - become: false delegate_to: localhost stat: path: '{{ alpine_iso }}' register: iso_file - name: build alpine iso - become: false delegate_to: localhost containers.podman.podman_container: name: 'alpine-builder-{{ inventory_hostname }}' @@ -70,6 +62,7 @@ register: iso_build - name: fix ownership of iso directory + become: true delegate_to: localhost file: path: '{{ alpine_iso_dir }}' diff --git a/host/roles/alpine/tasks/debian_autoboot.yml b/host/roles/alpine/tasks/debian_autoboot.yml @@ -3,7 +3,6 @@ raw: apt install -y iproute2 && ip link set {{ debian_net_interface }} mtu {{ static_mtu }} - name: Reset ssh connection to apply mtu change - become: false delegate_to: localhost command: rm -rf ~/.ansible/cp diff --git a/host/roles/firewall/handlers/main.yml b/host/roles/firewall/handlers/main.yml @@ -1,6 +0,0 @@ ---- -- name: restart nftables - service: - name: nftables - state: restarted - diff --git a/host/roles/firewall/tasks/main.yml b/host/roles/firewall/tasks/main.yml @@ -1,21 +0,0 @@ ---- -- name: install nftables - package: - name: nftables - state: present - -- name: enable nftables service - service: - name: nftables - enabled: true - -- name: upload server nftables config - template: - src: nftables.conf.j2 - dest: /etc/nftables.conf - owner: root - group: root - mode: '0755' - validate: nft --check --file %s - notify: restart nftables - diff --git a/host/roles/openssh/handlers/main.yml b/host/roles/openssh/handlers/main.yml @@ -1,6 +0,0 @@ ---- -- name: restart sshd - service: - name: sshd - state: restarted - diff --git a/host/roles/openssh/tasks/main.yml b/host/roles/openssh/tasks/main.yml @@ -1,34 +0,0 @@ ---- -- name: Create ssh user - include_tasks: user.yml - -- name: install openssh server - package: - name: - - openssh-server - - openssh-sftp-server - state: present - -- name: enable sshd - service: - name: sshd - enabled: true - -- name: empty motd - copy: - content: '' - dest: /etc/motd - owner: root - group: root - mode: '0644' - -- name: configure sshd - template: - src: sshd_config.j2 - dest: /etc/ssh/sshd_config - owner: root - group: root - mode: '0644' - validate: sshd -t -f %s - notify: restart sshd - diff --git a/host/roles/openssh/tasks/user.yml b/host/roles/openssh/tasks/user.yml @@ -1,38 +0,0 @@ ---- -- name: install sudo - package: - name: sudo - state: present - -- name: create user - user: - name: user - password: '*' - shell: /bin/bash - -- name: assign user sudo privilege - copy: - dest: /etc/sudoers.d/user - owner: root - group: root - mode: '0440' - validate: /usr/sbin/visudo -csf %s - content: | - user ALL=(ALL) NOPASSWD:ALL - -- name: create user ssh directory - file: - path: /home/user/.ssh - owner: user - group: user - state: directory - -- name: authorize user ssh keys - copy: - dest: /home/user/.ssh/authorized_keys - owner: user - group: user - mode: '0644' - content: | - {{ ssh_authorized_key }} - diff --git a/host/roles/openssh/templates/sshd_config.j2 b/host/roles/openssh/templates/sshd_config.j2 @@ -1,32 +0,0 @@ -AllowUsers user - -# Supported HostKey algorithms by order of preference. -HostKey /etc/ssh/ssh_host_ed25519_key - -# Specifies the available ciphers, kex, and mac algorithms. -KexAlgorithms curve25519-sha256 -Ciphers chacha20-poly1305@openssh.com -MACs hmac-sha2-512-etm@openssh.com - -# LogLevel VERBOSE logs user's key fingerprint on login -# Needed to have a clear audit track of which key was using to log in. -LogLevel VERBOSE - -# Log sftp level file access (read/write/etc.) that would not be easily logged otherwise. -Subsystem sftp /usr/lib/openssh/sftp-server -f AUTHPRIV -l INFO - -# Disable root user login -PermitRootLogin no -ChallengeResponseAuthentication no -PasswordAuthentication no -UsePAM no - -# Disable password-based login -AuthenticationMethods publickey -PubkeyAuthentication yes -PermitEmptyPasswords no -AuthorizedKeysFile .ssh/authorized_keys - -# Hide version -DebianBanner no - diff --git a/host/roles/setup/handlers/main.yml b/host/roles/setup/handlers/main.yml @@ -4,3 +4,24 @@ name: networking state: restarted +- name: restart sshd + service: + name: sshd + state: restarted + +- name: restart server wireguard + service: + name: wg-quick.wg0 + state: restarted + +- name: restart client wireguard + delegate_to: localhost + service: + name: wg-quick@{{ wg_client_iface }} + state: restarted + +- name: restart nftables + service: + name: nftables + state: restarted + diff --git a/host/roles/setup/tasks/apk.yml b/host/roles/setup/tasks/apk.yml @@ -0,0 +1,31 @@ +--- +- name: set repository + copy: + dest: /etc/apk/repositories + owner: root + group: root + mode: '0644' + content: | + {{ alpine_repositories | join('\n') }} + +- name: update repositories and update all installed packages + apk: + update_cache: true + upgrade: true + +- name: start and enable crond + service: + name: crond + enabled: true + state: started + +- name: periodically upgrade packages + copy: + dest: /etc/periodic/daily/apk-autoupgrade + owner: root + group: root + mode: '0700' + content: | + #!/bin/sh + apk upgrade --update | sed "s/^/[`date`] /" >> /var/log/apk-autoupgrade.log + diff --git a/host/roles/setup/tasks/apt-upgrades.yml b/host/roles/setup/tasks/apt-upgrades.yml @@ -1,22 +0,0 @@ ---- -- name: Update and upgrade apt packages - apt: - upgrade: yes - autoremove: yes - update_cache: yes - -- name: Install unattended upgrades package - package: - name: unattended-upgrades - state: present - -- name: Copy unattended-upgrades configuration files in place - template: - src: "{{ item }}.j2" - dest: "/etc/apt/apt.conf.d/{{ item }}" - owner: root - group: root - mode: '0644' - with_items: - - 10periodic - - 50unattended-upgrades diff --git a/host/roles/setup/tasks/basic.yml b/host/roles/setup/tasks/basic.yml @@ -0,0 +1,38 @@ +--- +- name: set hostname + copy: + dest: /etc/hostname + owner: root + group: root + mode: '0644' + content: | + {{ inventory_hostname }} + +- name: set network interfaces + copy: + dest: /etc/network/interfaces + owner: root + group: root + mode: '0644' + content: | + auto lo + iface lo inet loopback + + auto {{ static_interface }} + iface {{ static_interface }} inet static + address {{ static_ip }} + netmask {{ static_subnet }} + gateway {{ static_gateway }} + mtu {{ static_mtu }} + notify: restart networking + +- name: set dns + copy: + dest: /etc/resolv.conf + owner: root + group: root + mode: '0644' + content: | + nameserver {{ static_nameservers[0] }} + nameserver {{ static_nameservers[1] }} + diff --git a/host/roles/setup/tasks/hostname.yml b/host/roles/setup/tasks/hostname.yml @@ -1,18 +0,0 @@ ---- -- name: set hostname in /etc/hostname - copy: - dest: /etc/hostname - owner: root - group: root - mode: '0644' - content: | - {{ ansible_host }} - -- name: register current hostname - shell: hostnamectl hostname - register: current_hostname - -- name: set hostname with hostnamectl - shell: hostnamectl set-hostname {{ ansible_host }} - when: current_hostname.stdout != ansible_host - diff --git a/host/roles/setup/tasks/main.yml b/host/roles/setup/tasks/main.yml @@ -1,16 +1,29 @@ --- -- name: set networking - tags: networking - import_tasks: networking.yml +- name: Set Basic Configurations + import_tasks: basic.yml + tags: basic -- name: set hostname - tags: hostname - import_tasks: hostname.yml +- name: Configure apk + import_tasks: apk.yml + tags: apk -- name: upgrade packages and set auto-updates - tags: apt-upgrade - import_tasks: apt-upgrades.yml +- name: Create User + import_tasks: user.yml + tags: user -- name: refresh ansible facts - setup: +- name: OpenSSH + import_tasks: openssh.yml + tags: ssh + +- name: Wireguard Client + import_tasks: wireguard_client.yml + tags: vpn + +- name: Wireguard Server + import_tasks: wireguard_server.yml + tags: vpn + +- name: Set nftables + import_tasks: nftables.yml + tags: firewall diff --git a/host/roles/setup/tasks/networking.yml b/host/roles/setup/tasks/networking.yml @@ -1,39 +0,0 @@ ---- - -- name: set up /etc/network/interfaces - copy: - dest: /etc/network/interfaces - owner: root - group: root - mode: '0644' - content: | - source-directory /etc/network/interfaces.d - notify: restart networking - -- name: set up loopback interface - copy: - dest: /etc/network/interfaces.d/lo - owner: root - group: root - mode: '0644' - content: | - auto lo - iface lo inet loopback - notify: restart networking - -- name: set up {{ static_interface }} interface - copy: - dest: '/etc/network/interfaces.d/{{ static_interface }}' - owner: root - group: root - mode: '0644' - content: | - auto {{ static_interface }} - iface {{ static_interface }} inet static - address {{ static_ip }} - netmask {{ static_subnet }} - gateway {{ static_gateway }} - dns-nameservers {{ static_nameservers | join(' ') }} - mtu {{ static_mtu }} - notify: restart networking - diff --git a/host/roles/setup/tasks/nftables.yml b/host/roles/setup/tasks/nftables.yml @@ -0,0 +1,21 @@ +--- +- name: install nftables + package: + name: nftables + state: present + +- name: enable nftables service + service: + name: nftables + enabled: true + +- name: upload server nftables config + template: + src: nftables.conf.j2 + dest: /etc/nftables.nft + owner: root + group: root + mode: '0644' + validate: nft --check --file %s + notify: restart nftables + diff --git a/host/roles/setup/tasks/openssh.yml b/host/roles/setup/tasks/openssh.yml @@ -0,0 +1,28 @@ +--- +- name: install openssh + package: + name: openssh + state: present + +- name: enable sshd + service: + name: sshd + enabled: true + +- name: empty motd + copy: + content: '' + dest: /etc/motd + owner: root + group: root + mode: '0644' + +- name: configure sshd + template: + src: sshd_config.j2 + dest: /etc/ssh/sshd_config + owner: root + group: root + mode: '0644' + validate: sshd -t -f %s + notify: restart sshd diff --git a/host/roles/setup/tasks/user.yml b/host/roles/setup/tasks/user.yml @@ -0,0 +1,43 @@ +--- +- name: install doas + package: + name: doas + state: present + +- name: create group user + group: + name: user + state: present + +- name: create user + user: + name: user + group: user + password: '*' + shell: /bin/sh + +- name: assign user doas privilege + copy: + dest: /etc/doas.d/user.conf + owner: root + group: root + mode: '0600' + content: | + permit nopass :user + +- name: create user ssh directory + file: + path: /home/user/.ssh + owner: user + group: user + state: directory + +- name: authorize user ssh keys + copy: + dest: /home/user/.ssh/authorized_keys + owner: user + group: user + mode: '0600' + content: | + {{ ssh_authorized_key }} + diff --git a/host/roles/wireguard/tasks/client.yml b/host/roles/setup/tasks/wireguard_client.yml diff --git a/host/roles/setup/tasks/wireguard_server.yml b/host/roles/setup/tasks/wireguard_server.yml @@ -0,0 +1,63 @@ +--- +- name: install wireguard + package: + name: + - wireguard-tools + - wireguard-tools-openrc + state: present + +- name: create server wireguard directory + file: + path: /etc/wireguard + owner: root + group: root + mode: '0700' + state: directory + +- name: configure server interface + ini_file: + path: /etc/wireguard/wg0.conf + owner: root + group: root + mode: '0600' + section: Interface + option: '{{ item.option }}' + value: '{{ item.value }}' + with_items: + - option: PrivateKey + value: '{{ wg_server_private_key }}' + - option: Address + value: '{{ wg_server_ip }}/32' + - option: ListenPort + value: '{{ wireguard_port }}' + notify: restart server wireguard + +- name: add client peer to server config + ini_file: + path: /etc/wireguard/wg0.conf + owner: root + group: root + mode: '0600' + section: Peer + option: '{{ item.option }}' + value: '{{ item.value }}' + with_items: + - option: PublicKey + value: '{{ wg_client_public_key }}' + - option: AllowedIPs + value: '{{ wg_client_ip }}/32' + notify: restart server wireguard + +- name: create wireguard openrc service + file: + src: /etc/init.d/wg-quick + dest: /etc/init.d/wg-quick.wg0 + owner: root + group: root + state: link + +- name: enable wireguard service + service: + name: wg-quick.wg0 + enabled: true + diff --git a/host/roles/setup/templates/10periodic.j2 b/host/roles/setup/templates/10periodic.j2 @@ -1,4 +0,0 @@ -APT::Periodic::Update-Package-Lists "1"; -APT::Periodic::Download-Upgradeable-Packages "1"; -APT::Periodic::AutocleanInterval "7"; -APT::Periodic::Unattended-Upgrade "1"; diff --git a/host/roles/setup/templates/50unattended-upgrades.j2 b/host/roles/setup/templates/50unattended-upgrades.j2 @@ -1,5 +0,0 @@ -Unattended-Upgrade::MinimalSteps "true"; -Unattended-Upgrade::Automatic-Reboot "true"; -Unattended-Upgrade::Automatic-Reboot-Time "00:00"; -Unattended-Upgrade::MailOnlyOnError "true"; -Unattended-Upgrade::Remove-Unused-Dependencies "true"; diff --git a/host/roles/firewall/templates/nftables.conf.j2 b/host/roles/setup/templates/nftables.conf.j2 diff --git a/host/roles/setup/templates/sshd_config.j2 b/host/roles/setup/templates/sshd_config.j2 @@ -0,0 +1,28 @@ +AllowUsers user + +# Supported HostKey algorithms by order of preference. +HostKey /etc/ssh/ssh_host_ed25519_key + +# Specifies the available ciphers, kex, and mac algorithms. +KexAlgorithms curve25519-sha256 +Ciphers chacha20-poly1305@openssh.com +MACs hmac-sha2-512-etm@openssh.com + +# LogLevel VERBOSE logs user's key fingerprint on login +# Needed to have a clear audit track of which key was using to log in. +LogLevel VERBOSE + +# Log sftp level file access (read/write/etc.) that would not be easily logged otherwise. +Subsystem sftp /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO + +# Disable root user login +PermitRootLogin no +ChallengeResponseAuthentication no +PasswordAuthentication no + +# Disable password-based login +AuthenticationMethods publickey +PubkeyAuthentication yes +PermitEmptyPasswords no +AuthorizedKeysFile .ssh/authorized_keys + diff --git a/host/roles/wireguard/handlers/main.yml b/host/roles/wireguard/handlers/main.yml @@ -1,17 +0,0 @@ ---- -- name: restart server wireguard - service: - name: wg-quick@wg0 - state: restarted - -- name: restart client wireguard - delegate_to: localhost - service: - name: wg-quick@{{ wg_client_iface }} - state: restarted - -- name: restart nftables - service: - name: nftables - state: restarted - diff --git a/host/roles/wireguard/tasks/main.yml b/host/roles/wireguard/tasks/main.yml @@ -1,7 +0,0 @@ ---- -- name: configure wireguard client - include_tasks: client.yml - -- name: configure wireguard server - include_tasks: server.yml - diff --git a/host/roles/wireguard/tasks/server.yml b/host/roles/wireguard/tasks/server.yml @@ -1,54 +0,0 @@ ---- -- name: install wireguard - package: - name: wireguard - state: present - -- name: create server wireguard directory - file: - path: /etc/wireguard - owner: root - group: root - mode: '0700' - state: directory - -- name: configure server interface - ini_file: - path: /etc/wireguard/wg0.conf - owner: root - group: root - mode: '0600' - section: Interface - option: '{{ item.option }}' - value: '{{ item.value }}' - with_items: - - option: PrivateKey - value: '{{ wg_server_private_key }}' - - option: Address - value: '{{ wg_server_ip }}/32' - - option: ListenPort - value: '{{ wireguard_port }}' - notify: restart server wireguard - -- name: add client peer to server config - ini_file: - path: /etc/wireguard/wg0.conf - owner: root - group: root - mode: '0600' - section: Peer - option: '{{ item.option }}' - value: '{{ item.value }}' - with_items: - - option: PublicKey - value: '{{ wg_client_public_key }}' - - option: AllowedIPs - value: '{{ wg_client_ip }}/32' - notify: restart server wireguard - - -- name: enable wireguard service - service: - name: wg-quick@wg0 - enabled: true - diff --git a/host/site.yml b/host/site.yml @@ -1,16 +1,7 @@ --- -- name: Set Up Host Services +- name: Set Up Servers hosts: servers roles: - role: setup tags: setup - - role: openssh - tags: openssh - - - role: wireguard - tags: wireguard - - - role: firewall - tags: firewall -