diff --git a/ansible/group_vars/servers.yml b/ansible/group_vars/servers.yml index f2f2121..7fb2303 100644 --- a/ansible/group_vars/servers.yml +++ b/ansible/group_vars/servers.yml @@ -2,30 +2,81 @@ flatpaks: false install_ui_apps: false +# European countries for EU-specific access control +eu_countries_codes: + - AL # Albania + - AD # Andorra + - AM # Armenia + - AT # Austria + - AZ # Azerbaijan + # - BY # Belarus (Belarus is disabled due to geopolitical reasons) + - BE # Belgium + - BA # Bosnia and Herzegovina + - BG # Bulgaria + - HR # Croatia + - CY # Cyprus + - CZ # Czech Republic + - DK # Denmark + - EE # Estonia + - FI # Finland + - FR # France + - GE # Georgia + - DE # Germany + - GR # Greece + - HU # Hungary + - IS # Iceland + - IE # Ireland + - IT # Italy + - XK # Kosovo + - LV # Latvia + - LI # Liechtenstein + - LT # Lithuania + - LU # Luxembourg + - MK # North Macedonia + - MT # Malta + - MD # Moldova + - MC # Monaco + - ME # Montenegro + - NL # Netherlands + - NO # Norway + - PL # Poland + - PT # Portugal + - RO # Romania + # - RU # Russia (Russia is disabled due to geopolitical reasons) + - SM # San Marino + - RS # Serbia + - SK # Slovakia + - SI # Slovenia + - ES # Spain + - SE # Sweden + - CH # Switzerland + - TR # Turkey + - UA # Ukraine + - GB # United Kingdom + - VA # Vatican City + +# Trusted non-EU countries for extended access control +trusted_countries_codes: + - US # United States + - AU # Australia + - NZ # New Zealand + - JP # Japan + # Countries that are allowed to access the server Caddy reverse proxy allowed_countries_codes: - - US # United States - - CA # Canada - - GB # United Kingdom - - DE # Germany - - FR # France - - ES # Spain - - IT # Italy - - NL # Netherlands - - AU # Australia - - NZ # New Zealand - - JP # Japan - - KR # South Korea - - SK # Slovakia - - FI # Finland - - DK # Denmark - - SG # Singapore - - AT # Austria - - CH # Switzerland - -# IP ranges for blocked countries (generated automatically) -# This will be populated by the country blocking script -blocked_countries: [] + - US # United States + - GB # United Kingdom + - DE # Germany + - FR # France + - IT # Italy + - NL # Netherlands + - JP # Japan + - KR # South Korea + - CH # Switzerland + - AU # Australia (Added for UpDown.io to monitor server uptime) + - CA # Canada (Added for UpDown.io to monitor server uptime) + - FI # Finland (Added for UpDown.io to monitor server uptime) + - SG # Singapore (Added for UpDown.io to monitor server uptime) # Enable/disable country blocking globally enable_country_blocking: true diff --git a/ansible/tasks/servers/server.yml b/ansible/tasks/servers/server.yml index b21dc58..ba7090f 100644 --- a/ansible/tasks/servers/server.yml +++ b/ansible/tasks/servers/server.yml @@ -5,15 +5,13 @@ ansible.builtin.package: name: openssh state: present - when: ansible_pkg_mgr == 'pacman' and 'microsoft-standard-WSL2' not in ansible_kernel - become: true + when: ansible_pkg_mgr == 'pacman' - name: Ensure openssh-server is installed on non-Arch systems ansible.builtin.package: name: openssh-server state: present - when: ansible_pkg_mgr != 'pacman' and 'microsoft-standard-WSL2' not in ansible_kernel - become: true + when: ansible_pkg_mgr != 'pacman' - name: Ensure Borg is installed on Arch-based systems ansible.builtin.package: @@ -161,3 +159,7 @@ enabled: true hosts: - mennos-server + - name: necesse + enabled: true + hosts: + - mennos-server diff --git a/ansible/tasks/servers/services/caddy/Caddyfile.j2 b/ansible/tasks/servers/services/caddy/Caddyfile.j2 index 4eeed84..17d0aff 100644 --- a/ansible/tasks/servers/services/caddy/Caddyfile.j2 +++ b/ansible/tasks/servers/services/caddy/Caddyfile.j2 @@ -5,9 +5,9 @@ } } -# Country blocking snippet using MaxMind GeoLocation - reusable across all sites +# Country allow list snippet using MaxMind GeoLocation - reusable across all sites {% if enable_country_blocking | default(false) and allowed_countries_codes | default([]) | length > 0 %} -(country_block) { +(country_allow) { @allowed_local { remote_ip 127.0.0.1 ::1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 157.180.41.167 2a01:4f9:c013:1a13::1 } @@ -23,56 +23,125 @@ respond @not_allowed_countries "Access denied" 403 } {% else %} -(country_block) { - # Country blocking disabled +(country_allow) { + # Country allow list disabled +} +{% endif %} + +# European country allow list - allows all European countries only +{% if eu_countries_codes | default([]) | length > 0 %} +(eu_country_allow) { + @eu_allowed_local { + remote_ip 127.0.0.1 ::1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 157.180.41.167 2a01:4f9:c013:1a13::1 + } + @eu_not_allowed_countries { + not remote_ip 127.0.0.1 ::1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 157.180.41.167 2a01:4f9:c013:1a13::1 + not { + maxmind_geolocation { + db_path "/etc/caddy/geoip/GeoLite2-Country.mmdb" + allow_countries {{ eu_countries_codes | join(' ') }} + } + } + } + respond @eu_not_allowed_countries "Access denied" 403 +} +{% else %} +(eu_country_allow) { + # EU country allow list disabled +} +{% endif %} + +# Trusted country allow list - allows US, Australia, New Zealand, and Japan +{% if trusted_countries_codes | default([]) | length > 0 %} +(trusted_country_allow) { + @trusted_allowed_local { + remote_ip 127.0.0.1 ::1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 157.180.41.167 2a01:4f9:c013:1a13::1 + } + @trusted_not_allowed_countries { + not remote_ip 127.0.0.1 ::1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 157.180.41.167 2a01:4f9:c013:1a13::1 + not { + maxmind_geolocation { + db_path "/etc/caddy/geoip/GeoLite2-Country.mmdb" + allow_countries {{ trusted_countries_codes | join(' ') }} + } + } + } + respond @trusted_not_allowed_countries "Access denied" 403 +} +{% else %} +(trusted_country_allow) { + # Trusted country allow list disabled +} +{% endif %} + +# Sathub country allow list - combines EU and trusted countries +{% if eu_countries_codes | default([]) | length > 0 and trusted_countries_codes | default([]) | length > 0 %} +(sathub_country_allow) { + @sathub_allowed_local { + remote_ip 127.0.0.1 ::1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 157.180.41.167 2a01:4f9:c013:1a13::1 + } + @sathub_not_allowed_countries { + not remote_ip 127.0.0.1 ::1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 157.180.41.167 2a01:4f9:c013:1a13::1 + not { + maxmind_geolocation { + db_path "/etc/caddy/geoip/GeoLite2-Country.mmdb" + allow_countries {{ (eu_countries_codes + trusted_countries_codes) | join(' ') }} + } + } + } + respond @sathub_not_allowed_countries "Access denied" 403 +} +{% else %} +(sathub_country_allow) { + # Sathub country allow list disabled } {% endif %} {% if inventory_hostname == 'mennos-server' %} git.mvl.sh { - import country_block + import country_allow reverse_proxy gitea:3000 tls {{ caddy_email }} } git.vleeuwen.me { - import country_block + import country_allow redir https://git.mvl.sh{uri} tls {{ caddy_email }} } df.mvl.sh { - import country_block + import country_allow redir / https://git.mvl.sh/vleeuwenmenno/dotfiles/raw/branch/master/setup.sh tls {{ caddy_email }} } fsm.mvl.sh { - import country_block + import country_allow reverse_proxy factorio-server-manager:80 tls {{ caddy_email }} } fsm.vleeuwen.me { - import country_block + import country_allow redir https://fsm.mvl.sh{uri} tls {{ caddy_email }} } beszel.mvl.sh { - import country_block + import country_allow reverse_proxy beszel:8090 tls {{ caddy_email }} } beszel.vleeuwen.me { - import country_block + import country_allow redir https://beszel.mvl.sh{uri} tls {{ caddy_email }} } sathub.de { - import country_block + import sathub_country_allow handle { reverse_proxy sathub-frontend:4173 @@ -93,31 +162,31 @@ sathub.de { } api.sathub.de { - import country_block + import sathub_country_allow reverse_proxy sathub-backend:4001 tls {{ caddy_email }} } sathub.nl { - import country_block + import sathub_country_allow redir https://sathub.de{uri} tls {{ caddy_email }} } photos.mvl.sh { - import country_block + import country_allow reverse_proxy immich:2283 tls {{ caddy_email }} } photos.vleeuwen.me { - import country_block + import country_allow redir https://photos.mvl.sh{uri} tls {{ caddy_email }} } home.mvl.sh { - import country_block + import country_allow reverse_proxy host.docker.internal:8123 { header_up Host {upstream_hostport} header_up X-Real-IP {http.request.remote.host} @@ -126,7 +195,7 @@ home.mvl.sh { } home.vleeuwen.me { - import country_block + import country_allow reverse_proxy host.docker.internal:8123 { header_up Host {upstream_hostport} header_up X-Real-IP {http.request.remote.host} @@ -160,13 +229,13 @@ hotspot.mvl.sh:80 { } bin.mvl.sh { - import country_block + import country_allow reverse_proxy privatebin:8080 tls {{ caddy_email }} } ip.mvl.sh ip.vleeuwen.me { - import country_block + import country_allow reverse_proxy echoip:8080 { header_up X-Real-IP {http.request.remote.host} } @@ -174,26 +243,26 @@ ip.mvl.sh ip.vleeuwen.me { } http://ip.mvl.sh http://ip.vleeuwen.me { - import country_block + import country_allow reverse_proxy echoip:8080 { header_up X-Real-IP {http.request.remote.host} } } overseerr.mvl.sh { - import country_block + import country_allow reverse_proxy overseerr:5055 tls {{ caddy_email }} } overseerr.vleeuwen.me { - import country_block + import country_allow redir https://overseerr.mvl.sh{uri} tls {{ caddy_email }} } plex.mvl.sh { - import country_block + import country_allow reverse_proxy host.docker.internal:32400 { header_up Host {upstream_hostport} header_up X-Real-IP {http.request.remote.host} @@ -202,13 +271,13 @@ plex.mvl.sh { } plex.vleeuwen.me { - import country_block + import country_allow redir https://plex.mvl.sh{uri} tls {{ caddy_email }} } tautulli.mvl.sh { - import country_block + import country_allow reverse_proxy host.docker.internal:8181 { header_up Host {upstream_hostport} header_up X-Real-IP {http.request.remote.host} @@ -217,13 +286,13 @@ tautulli.mvl.sh { } tautulli.vleeuwen.me { - import country_block + import country_allow redir https://tautulli.mvl.sh{uri} tls {{ caddy_email }} } cloud.mvl.sh { - import country_block + import country_allow reverse_proxy cloudreve:5212 { header_up Host {host} header_up X-Real-IP {http.request.remote.host} @@ -232,13 +301,13 @@ cloud.mvl.sh { } cloud.vleeuwen.me { - import country_block + import country_allow redir https://cloud.mvl.sh{uri} tls {{ caddy_email }} } collabora.mvl.sh { - import country_block + import country_allow reverse_proxy collabora:9980 { header_up Host {host} header_up X-Real-IP {http.request.remote.host} @@ -247,7 +316,7 @@ collabora.mvl.sh { } drive.mvl.sh drive.vleeuwen.me { - import country_block + import country_allow # CalDAV and CardDAV redirects redir /.well-known/carddav /remote.php/dav/ 301 diff --git a/ansible/tasks/servers/services/necesse/docker-compose.yml.j2 b/ansible/tasks/servers/services/necesse/docker-compose.yml.j2 new file mode 100644 index 0000000..9009e90 --- /dev/null +++ b/ansible/tasks/servers/services/necesse/docker-compose.yml.j2 @@ -0,0 +1,15 @@ +services: + necesse: + image: brammys/necesse-server + container_name: necesse + restart: unless-stopped + ports: + - "14159:14159/udp" + environment: + - MOTD=StarDebris' Server! + - PASSWORD=2142 + - SLOTS=4 + - PAUSE=1 + volumes: + - {{ necesse_data_dir }}/saves:/necesse/saves + - {{ necesse_data_dir }}/logs:/necesse/logs diff --git a/ansible/tasks/servers/services/necesse/necesse.yml b/ansible/tasks/servers/services/necesse/necesse.yml new file mode 100644 index 0000000..d221d5a --- /dev/null +++ b/ansible/tasks/servers/services/necesse/necesse.yml @@ -0,0 +1,41 @@ +--- +- name: Deploy Necesse service + block: + - name: Set Necesse directories + ansible.builtin.set_fact: + necesse_service_dir: "{{ ansible_env.HOME }}/.services/necesse" + necesse_data_dir: "/mnt/services/necesse" + + - name: Create Necesse service directory + ansible.builtin.file: + path: "{{ necesse_service_dir }}" + state: directory + mode: "0755" + + - name: Create Necesse data directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: "0755" + loop: + - "{{ necesse_data_dir }}" + - "{{ necesse_data_dir }}/saves" + - "{{ necesse_data_dir }}/logs" + + - name: Deploy Necesse docker-compose.yml + ansible.builtin.template: + src: docker-compose.yml.j2 + dest: "{{ necesse_service_dir }}/docker-compose.yml" + mode: "0644" + register: necesse_compose + + - name: Stop Necesse service + ansible.builtin.command: docker compose -f "{{ necesse_service_dir }}/docker-compose.yml" down --remove-orphans + when: necesse_compose.changed + + - name: Start Necesse service + ansible.builtin.command: docker compose -f "{{ necesse_service_dir }}/docker-compose.yml" up -d + when: necesse_compose.changed + tags: + - services + - necesse diff --git a/ansible/tasks/servers/services/redis/redis.yml b/ansible/tasks/servers/services/redis/redis.yml index 22b0f29..3f043f3 100644 --- a/ansible/tasks/servers/services/redis/redis.yml +++ b/ansible/tasks/servers/services/redis/redis.yml @@ -34,6 +34,7 @@ register: juicefs_stop changed_when: juicefs_stop.changed when: redis_compose.changed and juicefs_service_stat.stat.exists + become: true - name: List containers that are running ansible.builtin.command: docker ps -q @@ -68,6 +69,7 @@ register: juicefs_start changed_when: juicefs_start.changed when: juicefs_service_stat.stat.exists + become: true - name: Restart containers that were stopped ansible.builtin.command: docker start {{ item }} diff --git a/ansible/tasks/servers/services/sathub/.env.j2 b/ansible/tasks/servers/services/sathub/.env.j2 index e4ac420..dc73eb6 100644 --- a/ansible/tasks/servers/services/sathub/.env.j2 +++ b/ansible/tasks/servers/services/sathub/.env.j2 @@ -45,3 +45,9 @@ CORS_ALLOWED_ORIGINS=https://sathub.de,https://sathub.nl,https://api.sathub.de # Frontend configuration (optional - defaults are provided) VITE_API_BASE_URL=https://api.sathub.de VITE_ALLOWED_HOSTS=sathub.de,sathub.nl + +# Discord related messsaging +DISCORD_CLIENT_ID={{ lookup('community.general.onepassword', 'sathub', vault='Dotfiles', field='DISCORD_CLIENT_ID') }} +DISCORD_CLIENT_SECRET={{ lookup('community.general.onepassword', 'sathub', vault='Dotfiles', field='DISCORD_CLIENT_SECRET') }} +DISCORD_REDIRECT_URI={{ lookup('community.general.onepassword', 'sathub', vault='Dotfiles', field='DISCORD_REDIRECT_URL') }} +DISCORD_WEBHOOK_URL={{ lookup('community.general.onepassword', 'sathub', vault='Dotfiles', field='DISCORD_WEBHOOK_URL') }} diff --git a/ansible/tasks/servers/services/sathub/docker-compose.yml.j2 b/ansible/tasks/servers/services/sathub/docker-compose.yml.j2 index 86191dd..69c3def 100644 --- a/ansible/tasks/servers/services/sathub/docker-compose.yml.j2 +++ b/ansible/tasks/servers/services/sathub/docker-compose.yml.j2 @@ -62,6 +62,12 @@ services: - MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY} - MINIO_SECRET_KEY=${MINIO_SECRET_KEY} - MINIO_EXTERNAL_URL=https://obj.sathub.de + + # Discord settings + - DISCORD_CLIENT_ID=${DISCORD_CLIENT_ID} + - DISCORD_CLIENT_SECRET=${DISCORD_CLIENT_SECRET} + - DISCORD_REDIRECT_URI=${DISCORD_REDIRECT_URI} + - DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL} networks: - sathub - caddy_network @@ -98,6 +104,12 @@ services: - MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY} - MINIO_SECRET_KEY=${MINIO_SECRET_KEY} - MINIO_EXTERNAL_URL=https://obj.sathub.de + + # Discord settings + - DISCORD_CLIENT_ID=${DISCORD_CLIENT_ID} + - DISCORD_CLIENT_SECRET=${DISCORD_CLIENT_SECRET} + - DISCORD_REDIRECT_URI=${DISCORD_REDIRECT_URI} + - DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL} networks: - sathub depends_on: @@ -113,7 +125,7 @@ services: - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=${DB_NAME:-sathub} volumes: - - postgres_data:/var/lib/postgresql/data + - {{ sathub_data_dir }}/postgres_data:/var/lib/postgresql/data networks: - sathub @@ -136,7 +148,7 @@ services: - MINIO_ROOT_USER=${MINIO_ROOT_USER} - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD} volumes: - - minio_data:/data + - {{ sathub_data_dir }}/minio_data:/data command: server /data --console-address :9001 networks: - sathub @@ -158,12 +170,6 @@ services: networks: - sathub -volumes: - minio_data: - driver: local - postgres_data: - driver: local - networks: sathub: driver: bridge diff --git a/config/bash.nix b/config/bash.nix index eda3ccb..bb52338 100644 --- a/config/bash.nix +++ b/config/bash.nix @@ -82,6 +82,8 @@ if [[ "$(uname -a)" == *"microsoft-standard-WSL2"* ]]; then [ -f "${config.home.homeDirectory}/.agent-bridge.sh" ] && source "${config.home.homeDirectory}/.agent-bridge.sh" alias winget='winget.exe' + alias ssh-add="ssh-add.exe" + alias git="git.exe" fi # Set SSH_AUTH_SOCK to 1Password agent if not already set @@ -137,11 +139,6 @@ bind -x '"\C-r": fzf_history_search' fi - # In case this is WSL, let's add various Windows executables as aliases - if [ -f "/mnt/c/Windows/System32/cmd.exe" ]; then - alias ssh-add="ssh-add.exe" - fi - # Display welcome message for interactive shells if [ -t 1 ]; then command -v helloworld &> /dev/null && helloworld