diff options
author | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2024-01-05 16:13:01 -0500 |
---|---|---|
committer | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2024-01-05 16:13:01 -0500 |
commit | fb0b3914086484d9284426985984e2c1699ba557 (patch) | |
tree | 963a2288a3b33f389972a78efaf3b6462bbe1925 /roles/private | |
parent | b62d5f559b81556a1dd6197c72a0c43ba1744477 (diff) | |
download | oldinfra-fb0b3914086484d9284426985984e2c1699ba557.tar.gz oldinfra-fb0b3914086484d9284426985984e2c1699ba557.zip |
ldap, internal CA, internal webserver, dns, etc.
Diffstat (limited to 'roles/private')
8 files changed, 257 insertions, 0 deletions
diff --git a/roles/private/files/johan/http.ca.internal.simponic.xyz.conf b/roles/private/files/johan/http.ca.internal.simponic.xyz.conf new file mode 100644 index 0000000..f1cea50 --- /dev/null +++ b/roles/private/files/johan/http.ca.internal.simponic.xyz.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name ca.internal.simponic.xyz; + + location /.well-known/acme-challenge { + root /var/www/letsencrypt; + try_files $uri $uri/ =404; + } + + location / { + rewrite ^ https://ca.internal.simponic.xyz$request_uri? permanent; + } +} diff --git a/roles/private/files/johan/http.lldap.internal.simponic.xyz.conf b/roles/private/files/johan/http.lldap.internal.simponic.xyz.conf new file mode 100644 index 0000000..8b9efe5 --- /dev/null +++ b/roles/private/files/johan/http.lldap.internal.simponic.xyz.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name lldap.internal.simponic.xyz; + + location /.well-known/acme-challenge { + root /var/www/letsencrypt; + try_files $uri $uri/ =404; + } + + location / { + rewrite ^ https://lldap.internal.simponic.xyz$request_uri? permanent; + } +} diff --git a/roles/private/files/johan/http.pihole.internal.simponic.xyz.conf b/roles/private/files/johan/http.pihole.internal.simponic.xyz.conf new file mode 100644 index 0000000..a30ffc3 --- /dev/null +++ b/roles/private/files/johan/http.pihole.internal.simponic.xyz.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name pihole.internal.simponic.xyz; + + location /.well-known/acme-challenge { + root /var/www/letsencrypt; + try_files $uri $uri/ =404; + } + + location / { + rewrite ^ https://pihole.internal.simponic.xyz$request_uri? permanent; + } +} diff --git a/roles/private/files/johan/https.ca.internal.simponic.xyz.conf b/roles/private/files/johan/https.ca.internal.simponic.xyz.conf new file mode 100644 index 0000000..8d7d190 --- /dev/null +++ b/roles/private/files/johan/https.ca.internal.simponic.xyz.conf @@ -0,0 +1,32 @@ +server { + listen 443 ssl; + server_name ca.internal.simponic.xyz; + + ssl_certificate /etc/letsencrypt/live/ca.internal.simponic.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/ca.internal.simponic.xyz/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/ca.internal.simponic.xyz/fullchain.pem; + + ssl_session_cache shared:SSL:50m; + ssl_session_timeout 5m; + ssl_stapling on; + ssl_stapling_verify on; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; + + ssl_dhparam /etc/nginx/dhparams.pem; + ssl_prefer_server_ciphers on; + + location / { + proxy_pass https://ca.internal.simponic.xyz:5239; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $server_name; + proxy_buffering off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; + } +} diff --git a/roles/private/files/johan/https.lldap.internal.simponic.xyz.conf b/roles/private/files/johan/https.lldap.internal.simponic.xyz.conf new file mode 100644 index 0000000..98306f5 --- /dev/null +++ b/roles/private/files/johan/https.lldap.internal.simponic.xyz.conf @@ -0,0 +1,32 @@ +server { + listen 443 ssl; + server_name lldap.internal.simponic.xyz; + + ssl_certificate /etc/letsencrypt/live/lldap.internal.simponic.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/lldap.internal.simponic.xyz/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/lldap.internal.simponic.xyz/fullchain.pem; + + ssl_session_cache shared:SSL:50m; + ssl_session_timeout 5m; + ssl_stapling on; + ssl_stapling_verify on; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; + + ssl_dhparam /etc/nginx/dhparams.pem; + ssl_prefer_server_ciphers on; + + location / { + proxy_pass http://127.0.0.1:17170; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $server_name; + proxy_buffering off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; + } +} diff --git a/roles/private/files/johan/https.pihole.internal.simponic.xyz.conf b/roles/private/files/johan/https.pihole.internal.simponic.xyz.conf new file mode 100644 index 0000000..b231f3f --- /dev/null +++ b/roles/private/files/johan/https.pihole.internal.simponic.xyz.conf @@ -0,0 +1,32 @@ +server { + listen 443 ssl; + server_name pihole.internal.simponic.xyz; + + ssl_certificate /etc/letsencrypt/live/pihole.internal.simponic.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/pihole.internal.simponic.xyz/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/pihole.internal.simponic.xyz/fullchain.pem; + + ssl_session_cache shared:SSL:50m; + ssl_session_timeout 5m; + ssl_stapling on; + ssl_stapling_verify on; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; + + ssl_dhparam /etc/nginx/dhparams.pem; + ssl_prefer_server_ciphers on; + + location / { + proxy_pass http://127.0.0.1:9135; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $server_name; + proxy_buffering off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; + } +} diff --git a/roles/private/files/nginx.conf b/roles/private/files/nginx.conf new file mode 100644 index 0000000..f978052 --- /dev/null +++ b/roles/private/files/nginx.conf @@ -0,0 +1,27 @@ +user www-data; +worker_processes 4; +pid /run/nginx.pid; +load_module modules/ndk_http_module.so; + +events { + worker_connections 768; +} + +http { + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + include /etc/nginx/mime.types; + default_type application/octet-stream; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + gzip on; + gzip_disable "msie6"; + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} diff --git a/roles/private/tasks/main.yml b/roles/private/tasks/main.yml new file mode 100644 index 0000000..5c4eb7e --- /dev/null +++ b/roles/private/tasks/main.yml @@ -0,0 +1,95 @@ +--- +- name: allow http from vpn + ufw: + rule: allow + port: '80' + proto: tcp + from: 100.64.0.0/10 + +- name: allow https from vpn + ufw: + rule: allow + port: '443' + proto: tcp + from: 100.64.0.0/10 + +- name: restart ufw + service: name=ufw state=restarted enabled=yes + +- name: install letsencrypt + apt: name=letsencrypt state=latest + +- name: create letsencrypt directory + file: name=/var/www/letsencrypt state=directory + +- name: install nginx + apt: name=nginx state=latest + +- name: remove default nginx + file: name=/etc/nginx/sites-enabled/default state=absent + +- name: generate dhparams + shell: openssl dhparam -out /etc/nginx/dhparams.pem 2048 + args: + creates: /etc/nginx/dhparams.pem + +- name: add system nginx config + template: + src: ../files/nginx.conf + dest: /etc/nginx/nginx.conf + +- name: copy http nginx configuration for each domain + copy: + src: "{{ item }}" + dest: "/etc/nginx/sites-enabled/" + with_fileglob: + - "files/{{ inventory_hostname }}/http.*.conf" + +- name: restart nginx to get letsencrypt certificate + service: name=nginx state=restarted enabled=yes + +- name: find deployed domains + ansible.builtin.find: + paths: "/etc/nginx/sites-enabled/" + patterns: "http.*.conf" + register: nginx_conf_files + delegate_to: "{{ inventory_hostname }}" + +- name: extract domains from deployed nginx configurations + shell: | + grep -oP 'server_name\s+\K[^;]+' "{{ item.path }}" + loop: "{{ nginx_conf_files.files }}" + register: extracted_domains + +# crt is given from the "ca" role to all hosts; that needs to run first +- name: request letsencrypt certificate + shell: > + REQUESTS_CA_BUNDLE="/usr/local/share/ca-certificates/{{ step_bootstrap_ca_url }}.crt" \ + letsencrypt certonly -n -d {{ item.stdout }} \ + --server https://{{ step_bootstrap_ca_url }}:{{ step_ca_port }}/acme/ACME/directory \ + --webroot -w /var/www/letsencrypt \ + --agree-tos --email {{ step_acme_cert_contact }} + args: + creates: "/etc/letsencrypt/live/{{ item.stdout }}" + loop: "{{ extracted_domains.results }}" + when: item.stdout != "" + +- name: copy https nginx configuration for each domain + copy: + src: "{{ item }}" + dest: "/etc/nginx/sites-enabled/" + with_fileglob: + - "files/{{ inventory_hostname }}/https.*.conf" + +- name: reload nginx to activate sites + service: name=nginx state=restarted + +- name: add monthly letsencrypt cronjob for cert renewal based on hash of domain name to prevent hitting LE rate limits + cron: + name: "letsencrypt_renewal_{{ item.stdout }}" + day: "{{ '%02d' | format(1 + (item.stdout | hash('md5') | int(0, 16) % 27)) }}" + hour: "{{ (item.stdout | hash('md5') | int(0, 16) % 24 ) }}" + minute: "{{ (item.stdout | hash('md5') | int(0, 16) % 60 ) }}" + job: "REQUESTS_CA_BUNDLE=/usr/local/share/ca-certificates/{{ step_bootstrap_ca_url }}.crt letsencrypt renew --server https://{{ step_bootstrap_ca_url }}:{{ step_ca_port }}/acme/ACME/directory --cert-name {{ item.stdout }} -n --webroot -w /var/www/letsencrypt --agree-tos --email {{ step_acme_cert_contact }} && service nginx reload" + loop: "{{ extracted_domains.results }}" + when: item.stdout != "" |