aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Chris Lovering <[email protected]>2023-06-01 22:40:36 +0100
committerGravatar ChrisJL <[email protected]>2023-07-24 14:42:09 +0100
commit0d8bb6829dfe9358ad29ac7f0bf9ef80fd553e3d (patch)
tree5b586b477335e08d5f8b6e9f62f59599c1c2cade
parentRemove bad default fail2ban ignore IP (diff)
Re-add previous ansible roles
Co-authored-by: Hassan Abouelela <[email protected]> Co-authored-by: Johannes Christ <[email protected]> Co-authored-by: Joe Banks <[email protected]> Co-authored-by: MarkKoz <[email protected]>
-rw-r--r--inventory/.gitignore1
-rw-r--r--inventory/README.md34
-rw-r--r--inventory/hosts.yaml29
-rw-r--r--inventory/inventory.ini38
-rw-r--r--playbook.yml10
-rw-r--r--roles/certbot/README.md3
-rw-r--r--roles/certbot/files/rsync.sh7
-rw-r--r--roles/certbot/tasks/main.yml110
-rw-r--r--roles/certbot/templates/renewal-hook.sh.j26
-rw-r--r--roles/certbot/vars/main/main.yml6
-rw-r--r--roles/certbot/vars/main/vault.yml9
-rw-r--r--roles/nginx-cloudflare-mtls/README.md16
-rw-r--r--roles/nginx-cloudflare-mtls/defaults/main.yml3
-rw-r--r--roles/nginx-cloudflare-mtls/files/cloudflare.crt35
-rw-r--r--roles/nginx-cloudflare-mtls/meta/main.yml3
-rw-r--r--roles/nginx-cloudflare-mtls/tasks/main.yml20
-rw-r--r--roles/nginx-geoip/meta/main.yml3
-rw-r--r--roles/nginx-geoip/tasks/main.yml13
-rw-r--r--roles/nginx-ufw/README.md3
-rw-r--r--roles/nginx-ufw/meta/main.yml4
-rw-r--r--roles/nginx-ufw/tasks/main.yml7
-rw-r--r--roles/nginx/README.md3
-rw-r--r--roles/nginx/files/default_server.conf24
-rw-r--r--roles/nginx/handlers/main.yml7
-rw-r--r--roles/nginx/tasks/main.yml21
-rw-r--r--roles/postgres/tasks/main.yml8
-rw-r--r--roles/wireguard/defaults/main/vars.yml4
-rw-r--r--roles/wireguard/handlers/main.yml4
-rw-r--r--roles/wireguard/tasks/main.yml72
-rw-r--r--roles/wireguard/templates/wg0.conf.j225
30 files changed, 435 insertions, 93 deletions
diff --git a/inventory/.gitignore b/inventory/.gitignore
deleted file mode 100644
index aa29d08..0000000
--- a/inventory/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-credentials/
diff --git a/inventory/README.md b/inventory/README.md
deleted file mode 100644
index 294d80b..0000000
--- a/inventory/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Inventory
-The main inventory for the pydis cluster.
-
-## Content
-This directory is not covered by ansible-lint, and should generally not be used to add new configuration.
-Instead, that should be placed appropriately within the project as normal.
-- `hosts.yaml`: The main hosts file for our infrastructure.
-
-## Deployment
-To deploy the kuberspray roles on our infrastructure, run the following commands in the root directory.
-
-### Environment
-Run the following commands, then enter your sudo password in the file that opens:
-
-```shell
-python3.10 -m venv venv
-source venv/bin/activate
-pip install -r kubespray/requirements-2.12.txt
-export ANSIBLE_CONFIG=ansible.cfg
-```
-
-### Deployment
-Enter your username into the command below, and run (this will take a while, so go grab a drink):
-
-```
-ansible-playbook kubespray/cluster.yml -v -u <user>
-```
-
-One useful argument for the command above is `--become-password-file`
-which should point to a file with your sudo password for seamless execution.
-
-Additionally, you may find it helpful to pre-configure all hosts in known_hosts
-to prevent the prompt from timing out during execution. This can be achieved by SSHing
-into the machines beforehand, or running an ad-hoc command and confirming all hosts.
diff --git a/inventory/hosts.yaml b/inventory/hosts.yaml
index c9f597c..a6938c5 100644
--- a/inventory/hosts.yaml
+++ b/inventory/hosts.yaml
@@ -1,25 +1,20 @@
all:
hosts:
turing:
- ansible_host: 89.58.25.151
- ip: 89.58.25.151
- access_ip: 89.58.25.151
- hopper:
- ansible_host: 89.58.24.117
- ip: 89.58.24.117
- access_ip: 89.58.24.117
+ ansible_host: turing.box.pydis.wtf
+ wireguard_subnet: 10.1.0.0/16
lovelace:
- ansible_host: 89.58.26.118
- ip: 89.58.26.118
- access_ip: 89.58.26.118
+ ansible_host: lovelace.box.pydis.wtf
+ wireguard_subnet: 10.2.0.0/16
+ hopper:
+ ansible_host: hopper.box.pydis.wtf
+ wireguard_subnet: 10.3.0.0/16
ritchie:
- ansible_host: 89.58.25.224
- ip: 89.58.25.224
- access_ip: 89.58.25.224
+ ansible_host: ritchie.box.pydis.wtf
+ wireguard_subnet: 10.4.0.0/16
neumann:
- ansible_host: 89.58.12.244
- ip: 89.58.12.244
- access_ip: 89.58.12.244
+ ansible_host: neumann.box.pydis.wtf
+ wireguard_subnet: 10.5.0.0/16
children:
podman:
hosts:
@@ -29,3 +24,5 @@ all:
nginx:
hosts:
turing:
+ vars:
+ wireguard_port: 46850
diff --git a/inventory/inventory.ini b/inventory/inventory.ini
deleted file mode 100644
index 99a6309..0000000
--- a/inventory/inventory.ini
+++ /dev/null
@@ -1,38 +0,0 @@
-# ## Configure 'ip' variable to bind kubernetes services on a
-# ## different ip than the default iface
-# ## We should set etcd_member_name for etcd cluster. The node that is not a etcd member do not need to set the value, or can set the empty string value.
-[all]
-# node1 ansible_host=95.54.0.12 # ip=10.3.0.1 etcd_member_name=etcd1
-# node2 ansible_host=95.54.0.13 # ip=10.3.0.2 etcd_member_name=etcd2
-# node3 ansible_host=95.54.0.14 # ip=10.3.0.3 etcd_member_name=etcd3
-# node4 ansible_host=95.54.0.15 # ip=10.3.0.4 etcd_member_name=etcd4
-# node5 ansible_host=95.54.0.16 # ip=10.3.0.5 etcd_member_name=etcd5
-# node6 ansible_host=95.54.0.17 # ip=10.3.0.6 etcd_member_name=etcd6
-
-# ## configure a bastion host if your nodes are not directly reachable
-# [bastion]
-# bastion ansible_host=x.x.x.x ansible_user=some_user
-
-[kube_control_plane]
-# node1
-# node2
-# node3
-
-[etcd]
-# node1
-# node2
-# node3
-
-[kube_node]
-# node2
-# node3
-# node4
-# node5
-# node6
-
-[calico_rr]
-
-[k8s_cluster:children]
-kube_control_plane
-kube_node
-calico_rr
diff --git a/playbook.yml b/playbook.yml
index 91a025c..995dc0b 100644
--- a/playbook.yml
+++ b/playbook.yml
@@ -4,6 +4,7 @@
- common
- ufw
- prometheus-node-exporter
+ - wireguard
- fail2ban
- name: Deploy our monitoring stack
@@ -11,6 +12,15 @@
roles:
- prometheus
+- name: Deploy nginx & certbot to hosts
+ hosts: nginx
+ roles:
+ - certbot
+ - nginx
+ - nginx-geoip
+ - nginx-ufw
+ - nginx-cloudflare-mtls
+
- name: Deploy podman to container service hosts
hosts: podman
roles:
diff --git a/roles/certbot/README.md b/roles/certbot/README.md
new file mode 100644
index 0000000..b9d3e36
--- /dev/null
+++ b/roles/certbot/README.md
@@ -0,0 +1,3 @@
+# Role "certbot"
+
+Installs certbot and the Cloudflare DNS plugin for certbot to provision and deploy TLS certificates for web properties.
diff --git a/roles/certbot/files/rsync.sh b/roles/certbot/files/rsync.sh
new file mode 100644
index 0000000..fa9b27b
--- /dev/null
+++ b/roles/certbot/files/rsync.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Start the rsync server and perform the transfer
+rrsync -wo /etc/letsencrypt/live
+
+# Reload NGINX
+systemctl reload nginx
diff --git a/roles/certbot/tasks/main.yml b/roles/certbot/tasks/main.yml
new file mode 100644
index 0000000..abe22cc
--- /dev/null
+++ b/roles/certbot/tasks/main.yml
@@ -0,0 +1,110 @@
+---
+- name: Install certbot and certbot Cloudflare plugin
+ when: inventory_hostname == ansible_play_hosts_all[0]
+ package:
+ name:
+ - python3-certbot
+ - python3-certbot-dns-cloudflare
+ state: present
+ tags:
+ - role::certbot
+
+- name: Install rsync on certbot hosts
+ package:
+ name: rsync
+ state: present
+ tags:
+ - role::certbot
+
+- name: Generate Cloudflare credentials file on designated leader
+ when: inventory_hostname == ansible_play_hosts_all[0]
+ copy:
+ content: |
+ # This file is managed by Ansible
+ dns_cloudflare_api_token = {{ certbot_cloudflare_token }}
+ dest: /etc/letsencrypt/cloudflare.ini
+ owner: root
+ group: root
+ mode: 0400
+ tags:
+ - role::certbot
+
+- name: Generate SSH key for certificate distribution
+ when: inventory_hostname == ansible_play_hosts_all[0]
+ community.crypto.openssh_keypair:
+ path: /root/.ssh/cert_{{ item }}_key_ed25519
+ type: ed25519
+ state: present
+ comment: certificate distribution key for {{ item }}
+ with_items:
+ - "{{ ansible_play_hosts | reject('in', [inventory_hostname]) }}"
+ tags:
+ - role::certbot
+ register: generated_keys
+
+- name: Create certificate directories on replica certificate hosts
+ when: inventory_hostname != ansible_play_hosts[0]
+ file:
+ path: /etc/letsencrypt/live
+ recurse: true
+ state: directory
+ owner: root
+ group: root
+ mode: 0700
+ tags:
+ - role::certbot
+
+- name: Install rsync + nginx reload script to replica servers
+ when: inventory_hostname != ansible_play_hosts[0]
+ copy:
+ src: rsync.sh
+ dest: /opt/cert_rsync.sh
+ owner: root
+ group: root
+ mode: 0500
+ tags:
+ - role::certbot
+
+- name: Install certificate distribution keys to other NGINX nodes
+ when: inventory_hostname != ansible_play_hosts[0]
+ ansible.posix.authorized_key:
+ user: root
+ state: present
+ key: |
+ {{ hostvars[ansible_play_hosts_all[0]]['generated_keys']['results']
+ | selectattr('item', 'equalto', inventory_hostname)
+ | map(attribute='public_key')
+ | first }}
+ comment: "certificate distribution key"
+ key_options: 'from="{{ hostvars[ansible_play_hosts_all[0]]["wireguard_subnet"] }}",restrict,command="/opt/cert_rsync.sh"'
+ tags:
+ - role::certbot
+
+- name: Create renewal hook to synchronize certificates
+ when: inventory_hostname == ansible_play_hosts_all[0]
+ template:
+ src: renewal-hook.sh.j2
+ dest: /etc/letsencrypt/renewal-hooks/deploy/distribute-certs
+ owner: root
+ group: root
+ mode: 0700
+ tags:
+ - role::certbot
+
+- name: Request certificates for configured domains
+ when: inventory_hostname == ansible_play_hosts_all[0]
+ command: |
+ certbot certonly
+ --agree-tos
+ --non-interactive
+ --email {{ certbot_email }}
+ --dns-cloudflare
+ --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini
+ --deploy-hook /etc/letsencrypt/renewal-hooks/deploy/distribute-certs
+ -d {{ item }} -d *.{{ item }} -d cloud.native.is.fun.and.easy.pydis.wtf
+ args:
+ creates: "/etc/letsencrypt/live/{{ item }}/fullchain.pem"
+ with_items:
+ - "{{ certbot_domains }}"
+ tags:
+ - role::certbot
diff --git a/roles/certbot/templates/renewal-hook.sh.j2 b/roles/certbot/templates/renewal-hook.sh.j2
new file mode 100644
index 0000000..7fa7252
--- /dev/null
+++ b/roles/certbot/templates/renewal-hook.sh.j2
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -ex
+
+{% for host in ansible_play_hosts if host != inventory_hostname %}
+rsync --copy-links --delete --recursive -e "ssh -i /root/.ssh/cert_{{ host }}_key_ed25519 -o StrictHostKeyChecking=accept-new" /etc/letsencrypt/live/* root@{{ hostvars[host]['wireguard_subnet'] | split("/") | first }}:/etc/letsencrypt/live
+{% endfor %}
diff --git a/roles/certbot/vars/main/main.yml b/roles/certbot/vars/main/main.yml
new file mode 100644
index 0000000..fdfc7b1
--- /dev/null
+++ b/roles/certbot/vars/main/main.yml
@@ -0,0 +1,6 @@
+---
+certbot_cloudflare_token: "{{ encrypted_cloudflare_token }}"
+certbot_email: "[email protected]"
+certbot_domains:
+ - pydis.wtf
+ - pythondiscord.com
diff --git a/roles/certbot/vars/main/vault.yml b/roles/certbot/vars/main/vault.yml
new file mode 100644
index 0000000..c669b69
--- /dev/null
+++ b/roles/certbot/vars/main/vault.yml
@@ -0,0 +1,9 @@
+$ANSIBLE_VAULT;1.1;AES256
+66336535306366333038666137306135663438346366643735383962623339636236343438633766
+6565343931306531623330373936313730353539303264390a333031363634663236636232386461
+34353239643364653464373531653236383963303137326438343239313136376537336636326162
+3537383737323732310a623836363138646434636165643130366362656661393937346534313632
+37663966613031363036623838326666636231313462363831396366363837343632646131303863
+35363032386463346164623733656463633735376161653361343231326166313466643236623762
+31343562323362353238663666303435353138643463656531373466336639316464376632623731
+32646464393438656134
diff --git a/roles/nginx-cloudflare-mtls/README.md b/roles/nginx-cloudflare-mtls/README.md
new file mode 100644
index 0000000..081cacb
--- /dev/null
+++ b/roles/nginx-cloudflare-mtls/README.md
@@ -0,0 +1,16 @@
+# Role "nginx-cloudflare-mtls"
+
+Installs the certificate required for performing mutual TLS authentication
+between NGINX and Cloudflare.
+
+To use mutual TLS in your NGINX virtual hosts, add this configuration snippet:
+
+```nginx
+ssl_client_certificate {{ nginx_cloudflare_mtls_certificate_path }};
+ssl_verify_client on;
+```
+
+
+## Variables
+
+See [role defaults](./defaults/main.yml) for an annotated overview.
diff --git a/roles/nginx-cloudflare-mtls/defaults/main.yml b/roles/nginx-cloudflare-mtls/defaults/main.yml
new file mode 100644
index 0000000..ff1c667
--- /dev/null
+++ b/roles/nginx-cloudflare-mtls/defaults/main.yml
@@ -0,0 +1,3 @@
+---
+# The path at which to install the certificate.
+nginx_cloudflare_mtls_certificate_path: /etc/nginx/certs/cloudflare.crt
diff --git a/roles/nginx-cloudflare-mtls/files/cloudflare.crt b/roles/nginx-cloudflare-mtls/files/cloudflare.crt
new file mode 100644
index 0000000..965f0bf
--- /dev/null
+++ b/roles/nginx-cloudflare-mtls/files/cloudflare.crt
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGCjCCA/KgAwIBAgIIV5G6lVbCLmEwDQYJKoZIhvcNAQENBQAwgZAxCzAJBgNV
+BAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMRQwEgYDVQQLEwtPcmln
+aW4gUHVsbDEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv
+cm5pYTEjMCEGA1UEAxMab3JpZ2luLXB1bGwuY2xvdWRmbGFyZS5uZXQwHhcNMTkx
+MDEwMTg0NTAwWhcNMjkxMTAxMTcwMDAwWjCBkDELMAkGA1UEBhMCVVMxGTAXBgNV
+BAoTEENsb3VkRmxhcmUsIEluYy4xFDASBgNVBAsTC09yaWdpbiBQdWxsMRYwFAYD
+VQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMSMwIQYDVQQD
+ExpvcmlnaW4tcHVsbC5jbG91ZGZsYXJlLm5ldDCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBAN2y2zojYfl0bKfhp0AJBFeV+jQqbCw3sHmvEPwLmqDLqynI
+42tZXR5y914ZB9ZrwbL/K5O46exd/LujJnV2b3dzcx5rtiQzso0xzljqbnbQT20e
+ihx/WrF4OkZKydZzsdaJsWAPuplDH5P7J82q3re88jQdgE5hqjqFZ3clCG7lxoBw
+hLaazm3NJJlUfzdk97ouRvnFGAuXd5cQVx8jYOOeU60sWqmMe4QHdOvpqB91bJoY
+QSKVFjUgHeTpN8tNpKJfb9LIn3pun3bC9NKNHtRKMNX3Kl/sAPq7q/AlndvA2Kw3
+Dkum2mHQUGdzVHqcOgea9BGjLK2h7SuX93zTWL02u799dr6Xkrad/WShHchfjjRn
+aL35niJUDr02YJtPgxWObsrfOU63B8juLUphW/4BOjjJyAG5l9j1//aUGEi/sEe5
+lqVv0P78QrxoxR+MMXiJwQab5FB8TG/ac6mRHgF9CmkX90uaRh+OC07XjTdfSKGR
+PpM9hB2ZhLol/nf8qmoLdoD5HvODZuKu2+muKeVHXgw2/A6wM7OwrinxZiyBk5Hh
+CvaADH7PZpU6z/zv5NU5HSvXiKtCzFuDu4/Zfi34RfHXeCUfHAb4KfNRXJwMsxUa
++4ZpSAX2G6RnGU5meuXpU5/V+DQJp/e69XyyY6RXDoMywaEFlIlXBqjRRA2pAgMB
+AAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgECMB0GA1Ud
+DgQWBBRDWUsraYuA4REzalfNVzjann3F6zAfBgNVHSMEGDAWgBRDWUsraYuA4REz
+alfNVzjann3F6zANBgkqhkiG9w0BAQ0FAAOCAgEAkQ+T9nqcSlAuW/90DeYmQOW1
+QhqOor5psBEGvxbNGV2hdLJY8h6QUq48BCevcMChg/L1CkznBNI40i3/6heDn3IS
+zVEwXKf34pPFCACWVMZxbQjkNRTiH8iRur9EsaNQ5oXCPJkhwg2+IFyoPAAYURoX
+VcI9SCDUa45clmYHJ/XYwV1icGVI8/9b2JUqklnOTa5tugwIUi5sTfipNcJXHhgz
+6BKYDl0/UP0lLKbsUETXeTGDiDpxZYIgbcFrRDDkHC6BSvdWVEiH5b9mH2BON60z
+0O0j8EEKTwi9jnafVtZQXP/D8yoVowdFDjXcKkOPF/1gIh9qrFR6GdoPVgB3SkLc
+5ulBqZaCHm563jsvWb/kXJnlFxW+1bsO9BDD6DweBcGdNurgmH625wBXksSdD7y/
+fakk8DagjbjKShYlPEFOAqEcliwjF45eabL0t27MJV61O/jHzHL3dknXeE4BDa2j
+bA+JbyJeUMtU7KMsxvx82RmhqBEJJDBCJ3scVptvhDMRrtqDBW5JShxoAOcpFQGm
+iYWicn46nPDjgTU0bX1ZPpTpryXbvciVL5RkVBuyX2ntcOLDPlZWgxZCBp96x07F
+AnOzKgZk4RzZPNAxCXERVxajn/FLcOhglVAKo5H0ac+AitlQ0ip55D2/mf8o72tM
+fVQ6VpyjEXdiIXWUq/o=
+-----END CERTIFICATE-----
diff --git a/roles/nginx-cloudflare-mtls/meta/main.yml b/roles/nginx-cloudflare-mtls/meta/main.yml
new file mode 100644
index 0000000..72b1bd7
--- /dev/null
+++ b/roles/nginx-cloudflare-mtls/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - nginx
diff --git a/roles/nginx-cloudflare-mtls/tasks/main.yml b/roles/nginx-cloudflare-mtls/tasks/main.yml
new file mode 100644
index 0000000..d5ef7f4
--- /dev/null
+++ b/roles/nginx-cloudflare-mtls/tasks/main.yml
@@ -0,0 +1,20 @@
+---
+- name: Create nginx certificates directory
+ file:
+ path: /etc/nginx/certs
+ state: directory
+ owner: root
+ group: root
+ mode: 0444
+ tags:
+ - role::nginx-cloudflare-mtls
+
+- name: Copy the cloudflare mutual TLS certificate
+ copy:
+ src: cloudflare.crt
+ dest: /etc/nginx/certs/cloudflare.crt
+ owner: root
+ group: root
+ mode: 0444
+ tags:
+ - role::nginx-cloudflare-mtls
diff --git a/roles/nginx-geoip/meta/main.yml b/roles/nginx-geoip/meta/main.yml
new file mode 100644
index 0000000..72b1bd7
--- /dev/null
+++ b/roles/nginx-geoip/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - nginx
diff --git a/roles/nginx-geoip/tasks/main.yml b/roles/nginx-geoip/tasks/main.yml
new file mode 100644
index 0000000..f772278
--- /dev/null
+++ b/roles/nginx-geoip/tasks/main.yml
@@ -0,0 +1,13 @@
+---
+- name: Configure the geoip module
+ copy:
+ # ref https://nginx.org/en/docs/http/ngx_http_geoip_module.html
+ content: geoip_country /usr/share/GeoIP/GeoIP.dat;
+ dest: /etc/nginx/conf.d/geoip.conf
+ owner: root
+ group: root
+ mode: 0444
+ tags:
+ - role::nginx-geoip
+ notify:
+ - reload the nginx service
diff --git a/roles/nginx-ufw/README.md b/roles/nginx-ufw/README.md
new file mode 100644
index 0000000..e657afb
--- /dev/null
+++ b/roles/nginx-ufw/README.md
@@ -0,0 +1,3 @@
+# Role "nginx-ufw"
+
+Allows NGINX HTTP and HTTPS traffic through the UFW firewall.
diff --git a/roles/nginx-ufw/meta/main.yml b/roles/nginx-ufw/meta/main.yml
new file mode 100644
index 0000000..dac7049
--- /dev/null
+++ b/roles/nginx-ufw/meta/main.yml
@@ -0,0 +1,4 @@
+---
+dependencies:
+ - nginx
+ - ufw
diff --git a/roles/nginx-ufw/tasks/main.yml b/roles/nginx-ufw/tasks/main.yml
new file mode 100644
index 0000000..fb703bf
--- /dev/null
+++ b/roles/nginx-ufw/tasks/main.yml
@@ -0,0 +1,7 @@
+---
+- name: Allow http(s) traffic through the firewall
+ ufw:
+ app: Nginx Full
+ rule: allow
+ tags:
+ - role::nginx-ufw
diff --git a/roles/nginx/README.md b/roles/nginx/README.md
new file mode 100644
index 0000000..9961a69
--- /dev/null
+++ b/roles/nginx/README.md
@@ -0,0 +1,3 @@
+# Role "nginx"
+
+Installs nginx on target hosts and provides a handler for reloading nginx, for instance on configuration change.
diff --git a/roles/nginx/files/default_server.conf b/roles/nginx/files/default_server.conf
new file mode 100644
index 0000000..13e74a0
--- /dev/null
+++ b/roles/nginx/files/default_server.conf
@@ -0,0 +1,24 @@
+# Managed by Ansible
+server {
+ listen 443 ssl http2 default_server;
+
+ ssl_certificate /etc/letsencrypt/live/pydis.wtf/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/pydis.wtf/privkey.pem;
+
+ location / {
+ set_by_lua_block $url {
+ local urls = {
+ "https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-ride",
+ "https://en.wikipedia.org/wiki/Tax_evasion",
+ "https://jchri.st/blog/apfs-sadness-on-macos-big-sur.html",
+ "https://cdn.discordapp.com/attachments/675756741417369640/852688961516077086/Screenshot_2021-06-11_at_00.21.22.png",
+ "https://news.ycombinator.com/",
+ "https://www.hertfordshire.gov.uk/latest/letchworth-webcam.jpg",
+ "https://media.discordapp.net/attachments/922169059175444501/952929630459924501/1svkf3xto3n61.png"
+ }
+ return urls [ math.random(#urls) ]
+ }
+
+ return 302 $url;
+ }
+}
diff --git a/roles/nginx/handlers/main.yml b/roles/nginx/handlers/main.yml
new file mode 100644
index 0000000..376d85a
--- /dev/null
+++ b/roles/nginx/handlers/main.yml
@@ -0,0 +1,7 @@
+---
+- name: reload the nginx service
+ service:
+ name: nginx
+ state: reloaded
+ tags:
+ - role::nginx
diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml
new file mode 100644
index 0000000..3419cb3
--- /dev/null
+++ b/roles/nginx/tasks/main.yml
@@ -0,0 +1,21 @@
+---
+- name: Install NGINX & modules
+ package:
+ name:
+ - nginx
+ - libnginx-mod-http-lua
+ state: present
+ tags:
+ - role::nginx
+
+- name: Copy NGINX default config
+ copy:
+ src: default_server.conf
+ dest: /etc/nginx/conf.d/default_server.conf
+ group: root
+ owner: root
+ mode: 0644
+ tags:
+ - role::nginx
+ notify:
+ - reload the nginx service
diff --git a/roles/postgres/tasks/main.yml b/roles/postgres/tasks/main.yml
index 01638af..9551c4e 100644
--- a/roles/postgres/tasks/main.yml
+++ b/roles/postgres/tasks/main.yml
@@ -1,4 +1,4 @@
-- name: Install postgres packages.
+- name: Install postgres packages
apt:
name:
- python3-psycopg2
@@ -9,7 +9,7 @@
tags:
- role::postgres
-- name: Check postgres is started and enabled on boot.
+- name: Check postgres is started and enabled on boot
service:
name: '{{ postgresql_daemon }}'
state: started
@@ -17,7 +17,7 @@
tags:
- role::postgres
-- name: Add postgres users.
+- name: Add postgres users
community.postgresql.postgresql_user: "{{ item }}"
with_items: "{{ postgresql_users }}"
become: true
@@ -25,7 +25,7 @@
tags:
- role::postgres
-- name: Add postgres databases.
+- name: Add postgres databases
community.postgresql.postgresql_db: "{{ item }}"
with_items: "{{ postgresql_databases }}"
become: true
diff --git a/roles/wireguard/defaults/main/vars.yml b/roles/wireguard/defaults/main/vars.yml
new file mode 100644
index 0000000..10c80ae
--- /dev/null
+++ b/roles/wireguard/defaults/main/vars.yml
@@ -0,0 +1,4 @@
+extra_keys:
+ - name: Joe
+ pubkey: /dJ+tKXzxv7nrUleNlF+CGyq7OIVlqL8/9Sn8j+cEAc=
+ subnet: 10.0.1.0/24
diff --git a/roles/wireguard/handlers/main.yml b/roles/wireguard/handlers/main.yml
new file mode 100644
index 0000000..0edcf3a
--- /dev/null
+++ b/roles/wireguard/handlers/main.yml
@@ -0,0 +1,4 @@
+- name: reload wg-quick
+ service:
+ name: wg-quick@wg0
+ state: reloaded
diff --git a/roles/wireguard/tasks/main.yml b/roles/wireguard/tasks/main.yml
new file mode 100644
index 0000000..46ff3e9
--- /dev/null
+++ b/roles/wireguard/tasks/main.yml
@@ -0,0 +1,72 @@
+- name: Install WireGuard
+ apt:
+ update_cache: true
+ cache_valid_time: 3600
+ pkg:
+ - wireguard
+ - wireguard-tools
+ - linux-headers-{{ ansible_kernel }}
+ tags:
+ - role::wireguard
+
+- name: Generate WireGuard private key
+ shell: set -o pipefail && wg genkey > /etc/wireguard/key.priv
+ args:
+ executable: /bin/bash
+ creates: /etc/wireguard/key.priv
+ tags:
+ - role::wireguard
+
+- name: Generate WireGuard public key
+ shell: set -o pipefail && cat /etc/wireguard/key.priv | wg pubkey > /etc/wireguard/key.pub
+ args:
+ executable: /bin/bash
+ creates: /etc/wireguard/key.pub
+ tags:
+ - role::wireguard
+
+- name: Ensure file permissions for keys set correctly
+ file:
+ path: '{{ item }}'
+ owner: root
+ group: root
+ mode: '0600'
+ with_items:
+ - /etc/wireguard/key.priv
+ - /etc/wireguard/key.pub
+ tags:
+ - role::wireguard
+
+- name: Fetch private key for all hosts
+ slurp:
+ src: /etc/wireguard/key.priv
+ register: wg_priv_key
+ tags:
+ - role::wireguard
+
+- name: Fetch public key for all hosts
+ slurp:
+ src: /etc/wireguard/key.pub
+ register: wg_pub_key
+ tags:
+ - role::wireguard
+
+- name: Generate WireGuard configuration file
+ template:
+ src: wg0.conf.j2
+ dest: /etc/wireguard/wg0.conf
+ mode: '0600'
+ group: root
+ owner: root
+ notify:
+ - reload wg-quick
+ tags:
+ - role::wireguard
+
+- name: Start and enable the WireGuard service
+ service:
+ name: wg-quick@wg0
+ enabled: true
+ state: started
+ tags:
+ - role::wireguard
diff --git a/roles/wireguard/templates/wg0.conf.j2 b/roles/wireguard/templates/wg0.conf.j2
new file mode 100644
index 0000000..647854a
--- /dev/null
+++ b/roles/wireguard/templates/wg0.conf.j2
@@ -0,0 +1,25 @@
+# Configuration managed by Ansible
+[Interface]
+Address = {{ wireguard_subnet }}
+ListenPort = {{ wireguard_port }}
+PrivateKey = {{ wg_priv_key['content'] | b64decode | trim }}
+
+PostUp = ip route add local {{ wireguard_subnet }} dev eth0
+
+{% for host in hostvars.keys() if not host == inventory_hostname %}
+# Peer config for: {{ host }}
+[Peer]
+AllowedIPs = {{ hostvars[host]['wireguard_subnet'] }}
+PublicKey = {{ hostvars[host]['wg_pub_key']['content'] | b64decode | trim }}
+Endpoint = {{ host }}.box.pydis.wtf:{{ wireguard_port }}
+PersistentKeepalive = 30
+
+{% endfor %}
+
+{% for key in extra_keys %}
+# DevOps config for: {{ key.name }}
+[Peer]
+AllowedIPs = {{ key.subnet }}
+PublicKey = {{ key.pubkey }}
+
+{% endfor %}