Skip to content

Instantly share code, notes, and snippets.

@LordAro
Last active November 14, 2020 12:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LordAro/3db5925b921ca986272f7d77bca0ae58 to your computer and use it in GitHub Desktop.
Save LordAro/3db5925b921ca986272f7d77bca0ae58 to your computer and use it in GitHub Desktop.
`ansible-playbook --ask-vault-pass -i ottd-inventory ottd-ansible-playbook.yml`
- hosts: bananas_fileservers
gather_facts: true
become: true
vars:
# Our vars, for easy reuse
cache_timeout: "1y" # Basically just as long as nginx runs for
bananas_server: https://bananas.openttd.org
bananas_cdn_server: https://bananas.cdn.openttd.org
bananas_server_secret: !vault |
$ANSIBLE_VAULT;1.1;AES256
6231336539666234306139346433616thisisnotarealsecret13633653634306231386433626436623361
nginx_shared_config: |
location = /healthz {
access_log off;
return 200;
}
# Rewrite the first to the second:
# base-graphics/12345678/12345678901234567890123456789012/filename.tar.gz
# base-graphics/12345678/12345678901234567890123456789012.tar.gz
# This allows the OpenTTD client to know the name to use for the file,
# while the S3 only knows the md5sum based name.
location / {
rewrite "^/([a-z-]+)/([a-f0-9]{8})/([a-f0-9]{32})/[a-zA-Z0-9-_.]+\.tar\.gz$" $1/$2/$3.tar.gz break;
proxy_pass https://{{ bananas_cdn_server }}/;
proxy_hide_header Strict-Transport-Security;
proxy_cache nginx-cache;
proxy_cache_valid 200 {{ cache_timeout }};
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_revalidate on;
proxy_cache_lock on;
proxy_ignore_headers Set-Cookie;
add_header X-Cache-Status $upstream_cache_status;
}
# Role config vars
certbot_admin_email: info@openttd.org
certbot_create_if_missing: true
certbot_create_standalone_stop_services:
- nginx # OK as only necessary on initial creation
certbot_certs:
- domains:
- {{ inventory_hostname }}
nginx_extra_conf_options: |
proxy_cache_path /tmp/nginx-cache/ levels=1:2 keys_zone=nginx-cache:16m max_size=1g inactive={{ cache_timeout }} use_temp_path=off;
nginx_vhosts:
- listen: "80"
server_name: {{ inventory_hostname }}
filename: "{{ inventory_hostname }}.80.conf"
extra_parameters: |
{{ nginx_shared_config }}
- listen: "443 ssl http2"
server_name: {{ inventory_hostname }}
filename: "{{ inventory_hostname }}.443.conf"
# Config partially taken from https://ssl-config.mozilla.org/#server=nginx&version=1.14.2&config=intermediate&openssl=1.1.1d&guideline=5.6
extra_parameters: |
ssl_certificate /etc/letsencrypt/live/{{ inventory_hostname }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ inventory_hostname }}/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
{{ nginx_shared_config }}
pre_tasks:
- name: Update apt cache & install https support.
apt:
name: apt-transport-https
update_cache: true
cache_valid_time: 86400 # a day is plenty
changed_when: false
- name: Install cron.
apt:
name: cron # required for certbot
state: present
roles:
- geerlingguy.certbot
- geerlingguy.nginx
tasks:
- name: Flush handlers in case any configs have changed.
meta: flush_handlers
- name: Test secure connection to SSL domain.
uri:
url: https://{{ inventory_hostname }}/
status_code: 200
delegate_to: localhost
become: false
- name: Install some helpful utilities.
apt:
name:
- bash-completion
- logrotate
- molly-guard
- rsync
- unattended-upgrades
- vim
state: present
- name: Copy sshd config
file:
src: sshd_config
dest: /etc/ssh/sshd_config
notify:
restart ssh
- name: "Add FQDN to /etc/hosts"
lineinfile:
path: /etc/hosts
regexp: "127.0.1.1"
line: "127.0.1.1 {{ inventory_hostname }} {{ inventory_hostname_short }}"
state: present
# bananas-notifier
# TODO: Consider splitting this out into a separate role
- name: Install bananas-notifier dependencies.
apt:
name:
- python3
- python3-requests
- name: Install bananas-notifier.py
file:
src: ottd-bananas-notifier.py
dest: /usr/local/bin/bananas-notifier.py
- name: Install cronjob
cron:
minute: "*/5" # every 5 mins
name: bananas-notifier
job: python3 /usr/local/bin/bananas-notifier.py {{ bananas_server }} {{ bananas_server_secret }}
no_log: true # hide secret
handlers:
- name: restart ssh
service:
name: ssh
state: restarted
#!/usr/bin/env python3
import os
import requests
import socket
import sys
if len(sys.argv) != 3:
print("Incorrect number of arguments provided", file=sys.stderr)
print(f"Expected {sys.argv[0]} bananas_server bananas_server_secret", file=sys.stderr)
os.exit(1)
bananas_server = sys.argv[1]
bananas_server_secret = sys.argv[2]
self_hostname = socket.getfqdn()
if requests.get(f"http://{self_hostname}/healthz").status_code != 200:
print("NGINX does not appear to be running :(", file=sys.stderr)
os.exit(2)
requests.post("https://bananas.openttd.org/update_fileserver", data={"hostname": self_hostname, "secret": bananas_server_secret})
[bananas_fileservers]
bananas-1.cdn.openttd.org
bananas-2.cdn.openttd.org
# Copied from https://infosec.mozilla.org/guidelines/openssh.html
# Supported HostKey algorithms by order of preference.
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
# Password based logins are disabled - only public key based logins are allowed.
AuthenticationMethods publickey
# 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
# Root login is not allowed for auditing reasons. This is because it's difficult to track which process belongs to which root user:
#
# On Linux, user sessions are tracking using a kernel-side session id, however, this session id is not recorded by OpenSSH.
# Additionally, only tools such as systemd and auditd record the process session id.
# On other OSes, the user session id is not necessarily recorded at all kernel-side.
# Using regular users in combination with /bin/su or /usr/bin/sudo ensure a clear audit track.
PermitRootLogin No
# Use kernel sandbox mechanisms where possible in unprivileged processes
# Systrace on OpenBSD, Seccomp on Linux, seatbelt on MacOSX/Darwin, rlimit elsewhere.
UsePrivilegeSeparation sandbox
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment