Make process generally smoother
This commit is contained in:
parent
a5e85742a0
commit
3e616d9165
@ -17,6 +17,9 @@ escalation_method: doas
|
|||||||
|
|
||||||
sshd_port: 2500
|
sshd_port: 2500
|
||||||
|
|
||||||
|
# Username for the priviledged user
|
||||||
|
admin_username: maestro
|
||||||
|
|
||||||
# Username for unpriviledged user
|
# Username for unpriviledged user
|
||||||
username: dogeystamp
|
username: dogeystamp
|
||||||
|
|
||||||
@ -129,6 +132,9 @@ enable_nameserver: yes
|
|||||||
# SSL ACME (Let's Encrypt)
|
# SSL ACME (Let's Encrypt)
|
||||||
enable_ssl: yes
|
enable_ssl: yes
|
||||||
|
|
||||||
|
# nginx: necessary for gitea, synapse, wiki, and website.
|
||||||
|
enable_webserver: yes
|
||||||
|
|
||||||
# Git server
|
# Git server
|
||||||
enable_gitea: yes
|
enable_gitea: yes
|
||||||
|
|
||||||
|
7
hosts.example
Normal file
7
hosts.example
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Copy this to hosts.
|
||||||
|
|
||||||
|
# fallback_host would be the DHCP address given to the host.
|
||||||
|
# It will be changed to local_ip during execution of the connection role.
|
||||||
|
|
||||||
|
[sv]
|
||||||
|
your_hostname fallback_host=192.168.0.109 ansible_port=2500 ansible_connection=ssh ansible_ssh_private_key_file=~/.ssh/keys/patria
|
@ -9,13 +9,36 @@
|
|||||||
enabled: yes
|
enabled: yes
|
||||||
state: started
|
state: started
|
||||||
|
|
||||||
- name: Disable existing eth0 connection
|
- name: Send script to remove externally managed eth0 connection
|
||||||
community.general.nmcli:
|
template:
|
||||||
conn_name: eth0
|
src: rmconn.sh
|
||||||
state: absent
|
dest: /root/rmconn.sh
|
||||||
register: networkmanager_config
|
mode: 700
|
||||||
|
register: rmconn
|
||||||
|
|
||||||
- name: Set static IP address
|
- name: Run rmconn every 30 minutes
|
||||||
|
cron:
|
||||||
|
name: "Ensure eth0 is not externally managed"
|
||||||
|
minute: "*/30"
|
||||||
|
job: "/root/rmconn.sh"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Run rmconn every minute (temporarily)
|
||||||
|
cron:
|
||||||
|
name: "Ensure eth0 is not externally managed (temporary)"
|
||||||
|
minute: "*"
|
||||||
|
job: "/root/rmconn.sh"
|
||||||
|
state: present
|
||||||
|
when: rmconn.changed
|
||||||
|
|
||||||
|
- name: Run rmconn at boot
|
||||||
|
cron:
|
||||||
|
name: "Ensure eth0 is not externally managed (at reboot)"
|
||||||
|
special_time: reboot
|
||||||
|
job: "/root/rmconn.sh"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create NetworkManager connection
|
||||||
community.general.nmcli:
|
community.general.nmcli:
|
||||||
dns4: "{{ dns_forward }}"
|
dns4: "{{ dns_forward }}"
|
||||||
dns4_ignore_auto: yes
|
dns4_ignore_auto: yes
|
||||||
@ -25,11 +48,21 @@
|
|||||||
conn_name: wired
|
conn_name: wired
|
||||||
ifname: "{{ interface }}"
|
ifname: "{{ interface }}"
|
||||||
type: ethernet
|
type: ethernet
|
||||||
when: networkmanager_config.changed
|
register: nmcli_conf
|
||||||
|
poll: 0
|
||||||
|
async: 1000
|
||||||
|
|
||||||
- name: Cronjob to remove externally managed eth0 connection
|
- name: Set ansible_host to static IP
|
||||||
|
set_fact:
|
||||||
|
ansible_host: "{{ local_ip }}"
|
||||||
|
|
||||||
|
- name: Reconnect to new IP
|
||||||
|
wait_for_connection:
|
||||||
|
timeout: 240
|
||||||
|
|
||||||
|
when: nmcli_conf.changed
|
||||||
|
|
||||||
|
- name: Remove rmconn task at every minute
|
||||||
cron:
|
cron:
|
||||||
name: "Ensure eth0 is not externally managed"
|
name: "Ensure eth0 is not externally managed (temporary)"
|
||||||
minute: "*/10"
|
state: absent
|
||||||
job: "/usr/bin/nmcli connection down eth0 > /dev/null 2>&1; /usr/bin/nmcli connection down wired > /dev/null 2>&1; /usr/bin/nmcli connection up wired > /dev/null"
|
|
||||||
state: present
|
|
||||||
|
8
roles/networking/connection/templates/rmconn.sh
Normal file
8
roles/networking/connection/templates/rmconn.sh
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
sleep 30
|
||||||
|
|
||||||
|
/usr/bin/nmcli connection down {{ interface }} > /dev/null 2>&1
|
||||||
|
/usr/bin/nmcli connection down "Wired connection 1" > /dev/null 2>&1
|
||||||
|
/usr/bin/nmcli connection down wired > /dev/null 2>&1
|
||||||
|
/usr/bin/nmcli connection up wired > /dev/null
|
@ -1,6 +1,10 @@
|
|||||||
- name: Ensure nginx is installed
|
- name: Ensure relevant packages are installed
|
||||||
community.general.pacman:
|
community.general.pacman:
|
||||||
name: nginx
|
name:
|
||||||
|
- nginx
|
||||||
|
- certbot
|
||||||
|
- certbot-nginx
|
||||||
|
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Create directories for ACME
|
- name: Create directories for ACME
|
||||||
@ -37,7 +41,7 @@
|
|||||||
register: result
|
register: result
|
||||||
when: cert_file.stat.exists
|
when: cert_file.stat.exists
|
||||||
|
|
||||||
- name: Determine whethe certificate should be regenerated
|
- name: Determine whether the certificate should be regenerated
|
||||||
set_fact:
|
set_fact:
|
||||||
cert_regen: yes
|
cert_regen: yes
|
||||||
when: not cert_file.stat.exists or result.expired | bool
|
when: not cert_file.stat.exists or result.expired | bool
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- role: webserver
|
|
@ -18,6 +18,20 @@
|
|||||||
state: present
|
state: present
|
||||||
notify: Restart gitea
|
notify: Restart gitea
|
||||||
|
|
||||||
|
- name: Find owner of data folder
|
||||||
|
stat:
|
||||||
|
path: "{{ dataroot }}/gitea/"
|
||||||
|
register: data_folder
|
||||||
|
|
||||||
|
- name: Ensure data folder is under correct owner
|
||||||
|
file:
|
||||||
|
path: "{{ dataroot }}/gitea/"
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
||||||
|
owner: gitea
|
||||||
|
group: gitea
|
||||||
|
when: data_folder.stat.pw_name != "gitea"
|
||||||
|
|
||||||
- name: Ensure gitea is stopped
|
- name: Ensure gitea is stopped
|
||||||
service:
|
service:
|
||||||
name: gitea
|
name: gitea
|
||||||
|
4
roles/services/synapse/handlers/main.yml
Normal file
4
roles/services/synapse/handlers/main.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
- name: Restart synapse
|
||||||
|
service:
|
||||||
|
name: synapse
|
||||||
|
state: restarted
|
@ -1,2 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- role: webserver
|
|
@ -7,16 +7,19 @@
|
|||||||
copy:
|
copy:
|
||||||
src: signing.key.secret
|
src: signing.key.secret
|
||||||
dest: /etc/synapse/signing.key
|
dest: /etc/synapse/signing.key
|
||||||
|
notify: Restart synapse
|
||||||
|
|
||||||
- name: Deploy matrix homeserver configuration
|
- name: Deploy matrix homeserver configuration
|
||||||
template:
|
template:
|
||||||
src: homeserver.yaml.j2
|
src: homeserver.yaml.j2
|
||||||
dest: /etc/synapse/homeserver.yaml
|
dest: /etc/synapse/homeserver.yaml
|
||||||
|
notify: Restart synapse
|
||||||
|
|
||||||
- name: Deploy matrix logging configuration
|
- name: Deploy matrix logging configuration
|
||||||
template:
|
template:
|
||||||
src: log.config.j2
|
src: log.config.j2
|
||||||
dest: /etc/synapse/log.config
|
dest: /etc/synapse/log.config
|
||||||
|
notify: Restart synapse
|
||||||
|
|
||||||
- name: Change systemd unit file to allow access to dataroot
|
- name: Change systemd unit file to allow access to dataroot
|
||||||
lineinfile:
|
lineinfile:
|
||||||
@ -25,6 +28,22 @@
|
|||||||
regexp: "^ReadWritePaths.*"
|
regexp: "^ReadWritePaths.*"
|
||||||
line: "ReadWritePaths={{ dataroot }}/synapse/"
|
line: "ReadWritePaths={{ dataroot }}/synapse/"
|
||||||
state: present
|
state: present
|
||||||
|
notify: Restart synapse
|
||||||
|
|
||||||
|
- name: Find owner of data folder
|
||||||
|
stat:
|
||||||
|
path: "{{ dataroot }}/synapse/"
|
||||||
|
register: data_folder
|
||||||
|
|
||||||
|
- name: Ensure data folder is under correct owner
|
||||||
|
file:
|
||||||
|
path: "{{ dataroot }}/synapse/"
|
||||||
|
state: directory
|
||||||
|
recurse: yes
|
||||||
|
owner: synapse
|
||||||
|
group: synapse
|
||||||
|
when: data_folder.stat.pw_name != "synapse"
|
||||||
|
notify: Restart synapse
|
||||||
|
|
||||||
- name: Enable matrix service
|
- name: Enable matrix service
|
||||||
service:
|
service:
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- role: webserver
|
|
@ -1,2 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- role: webserver
|
|
@ -1,4 +0,0 @@
|
|||||||
- name: Restart sshd
|
|
||||||
service:
|
|
||||||
name: sshd
|
|
||||||
state: restarted
|
|
@ -12,6 +12,16 @@
|
|||||||
update_cache: yes
|
update_cache: yes
|
||||||
upgrade: yes
|
upgrade: yes
|
||||||
|
|
||||||
|
- name: Determine if reboot for kernel update is needed
|
||||||
|
shell:
|
||||||
|
cmd: "if [[ $(pacman -Q linux | cut -d \" \" -f 2) > $(uname -r) ]]; then echo reboot; fi"
|
||||||
|
register: reboot_check
|
||||||
|
|
||||||
|
- name: Reboot for kernel update
|
||||||
|
reboot:
|
||||||
|
when:
|
||||||
|
reboot_check.stdout == "reboot"
|
||||||
|
|
||||||
- name: Install utility packages
|
- name: Install utility packages
|
||||||
community.general.pacman:
|
community.general.pacman:
|
||||||
name: "{{ util_pack }}"
|
name: "{{ util_pack }}"
|
||||||
@ -30,7 +40,7 @@
|
|||||||
ansible.posix.authorized_key:
|
ansible.posix.authorized_key:
|
||||||
user: "{{ username }}"
|
user: "{{ username }}"
|
||||||
state: present
|
state: present
|
||||||
key: "{{ lookup('file', '~/.ssh/keys/{{ ansible_hostname }}.pub')}}"
|
key: "{{ lookup('file', '~/.ssh/keys/{{ inventory_hostname }}.pub')}}"
|
||||||
|
|
||||||
- name: Enable cron daemon
|
- name: Enable cron daemon
|
||||||
service:
|
service:
|
||||||
|
56
roles/system/tasks/initial.yml
Normal file
56
roles/system/tasks/initial.yml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
- name: Determine whether initial setup is needed
|
||||||
|
set_fact:
|
||||||
|
initial_setup: yes
|
||||||
|
when:
|
||||||
|
ansible_user != admin_username
|
||||||
|
|
||||||
|
- name: Fallback to su
|
||||||
|
set_fact:
|
||||||
|
ansible_become_method: "su"
|
||||||
|
ansible_become_user: "root"
|
||||||
|
ansible_become_password: "root"
|
||||||
|
when:
|
||||||
|
initial_setup is defined
|
||||||
|
|
||||||
|
- setup:
|
||||||
|
|
||||||
|
- name: Install opendoas
|
||||||
|
community.general.pacman:
|
||||||
|
name: opendoas
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Configure doas
|
||||||
|
template:
|
||||||
|
src: doas.conf.j2
|
||||||
|
dest: /etc/doas.conf
|
||||||
|
|
||||||
|
- name: Create priviledged user
|
||||||
|
user:
|
||||||
|
name: "{{ admin_username }}"
|
||||||
|
groups: wheel
|
||||||
|
|
||||||
|
- name: Deploy SSH key to admin user
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: "{{ admin_username }}"
|
||||||
|
state: present
|
||||||
|
key: "{{ lookup('file', '~/.ssh/keys/{{ inventory_hostname }}.pub')}}"
|
||||||
|
|
||||||
|
- name: Reset variables to before fallback
|
||||||
|
set_fact:
|
||||||
|
ansible_become_method: "{{ escalation_method }}"
|
||||||
|
ansible_user: "{{ admin_username }}"
|
||||||
|
ansible_ssh_password: ""
|
||||||
|
when:
|
||||||
|
initial_setup is defined
|
||||||
|
|
||||||
|
- name: Reconnect as new administrator
|
||||||
|
wait_for_connection:
|
||||||
|
timeout: 10
|
||||||
|
when:
|
||||||
|
initial_setup is defined
|
||||||
|
|
||||||
|
- name: Delete initial user
|
||||||
|
user:
|
||||||
|
name: "alarm"
|
||||||
|
force: yes
|
||||||
|
state: absent
|
@ -1,2 +1,3 @@
|
|||||||
|
- include_tasks: initial.yml
|
||||||
- include_tasks: essential.yml
|
- include_tasks: essential.yml
|
||||||
- include_tasks: sshd.yml
|
- include_tasks: sshd.yml
|
||||||
|
@ -3,11 +3,27 @@
|
|||||||
dest: /etc/ssh/sshd_config
|
dest: /etc/ssh/sshd_config
|
||||||
regexp: "^#PasswordAuthentication yes"
|
regexp: "^#PasswordAuthentication yes"
|
||||||
line: "PasswordAuthentication no"
|
line: "PasswordAuthentication no"
|
||||||
notify: Restart sshd
|
register: sshd_config
|
||||||
|
|
||||||
- name: Change SSH port
|
- name: Change SSH port
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/ssh/sshd_config
|
dest: /etc/ssh/sshd_config
|
||||||
regexp: "^#Port 22"
|
regexp: "^#Port 22"
|
||||||
line: "Port {{ sshd_port }}"
|
line: "Port {{ sshd_port }}"
|
||||||
notify: Restart sshd
|
register: sshd_config
|
||||||
|
|
||||||
|
- name: Restart SSHD
|
||||||
|
service:
|
||||||
|
name: sshd
|
||||||
|
state: restarted
|
||||||
|
when: sshd_config.changed
|
||||||
|
|
||||||
|
- name: Reset ansible_ssh_port
|
||||||
|
set_fact:
|
||||||
|
ansible_ssh_port: "{{ sshd_port }}"
|
||||||
|
when: sshd_config.changed
|
||||||
|
|
||||||
|
- name: Reconnect under new port
|
||||||
|
wait_for_connection:
|
||||||
|
timeout: 10
|
||||||
|
when: sshd_config.changed
|
||||||
|
1
roles/system/templates/doas.conf.j2
Normal file
1
roles/system/templates/doas.conf.j2
Normal file
@ -0,0 +1 @@
|
|||||||
|
permit nopass :wheel
|
30
run.yml
30
run.yml
@ -2,27 +2,42 @@
|
|||||||
- hosts: sv
|
- hosts: sv
|
||||||
become: yes
|
become: yes
|
||||||
|
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
pre_tasks:
|
||||||
|
- import_tasks: tasks/set_host.yml
|
||||||
|
- import_tasks: tasks/ssh_port.yml
|
||||||
|
|
||||||
roles:
|
roles:
|
||||||
- role: system
|
- role: system
|
||||||
|
|
||||||
- role: dotfiles
|
|
||||||
when: enable_dotfiles
|
|
||||||
|
|
||||||
- role: filesystems
|
- role: filesystems
|
||||||
when: enable_filesystems
|
when: enable_filesystems
|
||||||
|
|
||||||
- role: networking/connection
|
- role: networking/connection
|
||||||
when: enable_connection
|
when: enable_connection
|
||||||
|
|
||||||
|
- role: firewall
|
||||||
|
when: enable_firewall
|
||||||
|
|
||||||
- role: networking/ddclient
|
- role: networking/ddclient
|
||||||
when: enable_ddclient
|
when: enable_ddclient
|
||||||
|
|
||||||
- role: networking/nameserver
|
- role: networking/nameserver
|
||||||
when: enable_nameserver
|
when: enable_nameserver
|
||||||
|
|
||||||
|
- role: services/sftp
|
||||||
|
when: enable_sftpr
|
||||||
|
|
||||||
|
- role: services/mail
|
||||||
|
when: enable_mail
|
||||||
|
|
||||||
- role: networking/ssl
|
- role: networking/ssl
|
||||||
when: enable_ssl
|
when: enable_ssl
|
||||||
|
|
||||||
|
- role: services/webserver
|
||||||
|
when: enable_webserver
|
||||||
|
|
||||||
- role: services/gitea
|
- role: services/gitea
|
||||||
when: enable_gitea
|
when: enable_gitea
|
||||||
|
|
||||||
@ -35,8 +50,5 @@
|
|||||||
- role: services/website
|
- role: services/website
|
||||||
when: enable_website
|
when: enable_website
|
||||||
|
|
||||||
- role: services/sftp
|
- role: dotfiles
|
||||||
when: enable_sftpr
|
when: enable_dotfiles
|
||||||
|
|
||||||
- role: services/mail
|
|
||||||
when: enable_mail
|
|
||||||
|
15
tasks/set_host.yml
Normal file
15
tasks/set_host.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
- name: Determine if host is up at static IP
|
||||||
|
local_action: "command ping -c 1 {{ local_ip }}"
|
||||||
|
become: no
|
||||||
|
ignore_errors: true
|
||||||
|
register: up_static
|
||||||
|
|
||||||
|
- name: Switch ansible_host to fallback IP
|
||||||
|
set_fact:
|
||||||
|
ansible_host: "{{ fallback_host }}"
|
||||||
|
when: up_static.rc != 0
|
||||||
|
|
||||||
|
- name: Switch ansible_host to static IP
|
||||||
|
set_fact:
|
||||||
|
ansible_host: "{{ local_ip }}"
|
||||||
|
when: up_static.rc == 0
|
42
tasks/ssh_port.yml
Normal file
42
tasks/ssh_port.yml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
- name: Set default user for SSH
|
||||||
|
set_fact:
|
||||||
|
ansible_user: "{{ admin_username }}"
|
||||||
|
|
||||||
|
- name: Attempt ssh connection
|
||||||
|
become: no
|
||||||
|
wait_for_connection:
|
||||||
|
timeout: 10
|
||||||
|
ignore_errors: true
|
||||||
|
register: ssh_result_default
|
||||||
|
|
||||||
|
- name: Set ssh to fallback port
|
||||||
|
set_fact:
|
||||||
|
ansible_ssh_port: 22
|
||||||
|
when:
|
||||||
|
- ssh_result_default is failed
|
||||||
|
|
||||||
|
- name: Attempt ssh connection
|
||||||
|
become: no
|
||||||
|
wait_for_connection:
|
||||||
|
timeout: 10
|
||||||
|
ignore_errors: true
|
||||||
|
register: ssh_result_port
|
||||||
|
when:
|
||||||
|
- ssh_result_default is failed
|
||||||
|
|
||||||
|
- name: Set ssh to fallback port and default Arch Linux ARM credentials
|
||||||
|
set_fact:
|
||||||
|
ansible_ssh_port: "22"
|
||||||
|
ansible_user: "alarm"
|
||||||
|
ansible_ssh_password: "alarm"
|
||||||
|
when:
|
||||||
|
- ssh_result_default is failed
|
||||||
|
- ssh_result_port is failed
|
||||||
|
|
||||||
|
- name: Attempt ssh connection
|
||||||
|
become: no
|
||||||
|
wait_for_connection:
|
||||||
|
timeout: 10
|
||||||
|
when:
|
||||||
|
- ssh_result_default is failed
|
||||||
|
- ssh_result_port is failed
|
Reference in New Issue
Block a user