diff --git a/deploy-scurvy.yml b/deploy-scurvy.yml new file mode 100644 index 0000000..93de041 --- /dev/null +++ b/deploy-scurvy.yml @@ -0,0 +1,4 @@ +- name: scurvy setup + hosts: scurvy + roles: + - scurvy diff --git a/group_vars/scurvy.yml b/group_vars/scurvy.yml new file mode 100644 index 0000000..2e9b716 --- /dev/null +++ b/group_vars/scurvy.yml @@ -0,0 +1,2 @@ +--- +openvpn_user: "{{ lookup('env', 'OPENVPN_USER') }}" diff --git a/inventory b/inventory index fc218c6..b1d4c90 100644 --- a/inventory +++ b/inventory @@ -45,3 +45,6 @@ mail.simponic.xyz ansible_user=root ansible_connection=ssh [roundcube] europa ansible_user=root ansible_connection=ssh + +[scurvy] +europa ansible_user=root ansible_connection=ssh diff --git a/roles/private/files/europa/http.jellyfin.internal.simponic.xyz.conf b/roles/private/files/europa/http.jellyfin.internal.simponic.xyz.conf new file mode 100644 index 0000000..7c11e5e --- /dev/null +++ b/roles/private/files/europa/http.jellyfin.internal.simponic.xyz.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name jellyfin.internal.simponic.xyz; + + location /.well-known/acme-challenge { + root /var/www/letsencrypt; + try_files $uri $uri/ =404; + } + + location / { + rewrite ^ https://jellyfin.internal.simponic.xyz$request_uri? permanent; + } +} diff --git a/roles/private/files/europa/http.scurvy.internal.simponic.xyz.conf b/roles/private/files/europa/http.scurvy.internal.simponic.xyz.conf new file mode 100644 index 0000000..24e9fc1 --- /dev/null +++ b/roles/private/files/europa/http.scurvy.internal.simponic.xyz.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name scurvy.internal.simponic.xyz; + + location /.well-known/acme-challenge { + root /var/www/letsencrypt; + try_files $uri $uri/ =404; + } + + location / { + rewrite ^ https://scurvy.internal.simponic.xyz$request_uri? permanent; + } +} diff --git a/roles/private/files/europa/https.jellyfin.internal.simponic.xyz.conf b/roles/private/files/europa/https.jellyfin.internal.simponic.xyz.conf new file mode 100644 index 0000000..b1823b9 --- /dev/null +++ b/roles/private/files/europa/https.jellyfin.internal.simponic.xyz.conf @@ -0,0 +1,32 @@ +server { + listen 443 ssl; + server_name jellyfin.internal.simponic.xyz; + + ssl_certificate /etc/letsencrypt/live/jellyfin.internal.simponic.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/jellyfin.internal.simponic.xyz/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/jellyfin.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:8096; + 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/europa/https.scurvy.internal.simponic.xyz.conf b/roles/private/files/europa/https.scurvy.internal.simponic.xyz.conf new file mode 100644 index 0000000..14c7a6b --- /dev/null +++ b/roles/private/files/europa/https.scurvy.internal.simponic.xyz.conf @@ -0,0 +1,32 @@ +server { + listen 443 ssl; + server_name scurvy.internal.simponic.xyz; + + ssl_certificate /etc/letsencrypt/live/scurvy.internal.simponic.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/scurvy.internal.simponic.xyz/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/scurvy.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:9000; + 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/scurvy/tasks/main.yml b/roles/scurvy/tasks/main.yml new file mode 100644 index 0000000..c1d8902 --- /dev/null +++ b/roles/scurvy/tasks/main.yml @@ -0,0 +1,22 @@ +--- +- name: ensure scurvy docker/compose exist + file: + path: /etc/docker/compose/scurvy + state: directory + owner: root + group: root + mode: 0700 + +- name: build scurvy docker-compose.yml.j2 + template: + src: ../templates/docker-compose.yml.j2 + dest: /etc/docker/compose/scurvy/docker-compose.yml + owner: root + group: root + mode: u=rw,g=r,o=r + +- name: daemon-reload and enable scurvy + ansible.builtin.systemd_service: + state: restarted + enabled: true + name: docker-compose@scurvy diff --git a/roles/scurvy/templates/docker-compose.yml.j2 b/roles/scurvy/templates/docker-compose.yml.j2 new file mode 100644 index 0000000..838030c --- /dev/null +++ b/roles/scurvy/templates/docker-compose.yml.j2 @@ -0,0 +1,61 @@ +version: '3' +services: + gluetun: + image: qmcgaw/gluetun + container_name: gluetun + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun:/dev/net/tun + ports: + - 127.0.0.1:9000:8080/tcp + - 127.0.0.1:6881:6881 + - 127.0.0.1:6881:6881/udp + volumes: + - /gluetun + environment: + - VPN_SERVICE_PROVIDER=mullvad + - VPN_TYPE=openvpn + - OPENVPN_USER={{ openvpn_user }} + - SERVER_CITIES=Salt Lake City UT + + qbittorrent: + image: hotio/qbittorrent:latest + container_name: qbittorrent + environment: + - PUID=1000 + - PGID=1000 + volumes: + - qbittorrent_config:/config:rw + - type: bind + source: /mnt/hdd-01 + target: /hdd-01 + - type: bind + source: /mnt/ssd-01 + target: /ssd-01 + restart: unless-stopped + network_mode: "container:gluetun" + + jellyfin: + image: lscr.io/linuxserver/jellyfin:latest + container_name: jellyfin + environment: + - JELLYFIN_PublishedServerUrl=https://jellyfin.internal.simponic.xyz + ports: + - 127.0.0.1:8096:8096 + devices: + - /dev/dri:/dev/dri + volumes: + - type: bind + source: /mnt/hdd-01 + target: /hdd-01 + - type: bind + source: /mnt/ssd-01 + target: /ssd-01 + - jellyfin_config:/config:rw + - jellyfin_cache:/cache:rw + +volumes: + jellyfin_config: + jellyfin_cache: + qbittorrent_config: