diff --git a/infra/Caddyfile b/infra/Caddyfile index 7945ce4..db3df81 100644 --- a/infra/Caddyfile +++ b/infra/Caddyfile @@ -2,6 +2,14 @@ monotrope.au { root * /var/www/monotrope file_server + # Security headers + header { + X-Content-Type-Options "nosniff" + X-Frame-Options "DENY" + Referrer-Policy "strict-origin-when-cross-origin" + Permissions-Policy "camera=(), microphone=(), geolocation=()" + } + # Compression encode zstd gzip @@ -27,6 +35,13 @@ www.monotrope.au { reader.monotrope.au { reverse_proxy localhost:8080 + header { + X-Content-Type-Options "nosniff" + X-Frame-Options "DENY" + Referrer-Policy "strict-origin-when-cross-origin" + Permissions-Policy "camera=(), microphone=(), geolocation=()" + } + encode zstd gzip } @@ -34,6 +49,12 @@ reader.monotrope.au { git.monotrope.au { reverse_proxy localhost:3000 + header { + X-Content-Type-Options "nosniff" + Referrer-Policy "strict-origin-when-cross-origin" + Permissions-Policy "camera=(), microphone=(), geolocation=()" + } + encode zstd gzip } @@ -41,5 +62,12 @@ git.monotrope.au { stats.monotrope.au { reverse_proxy localhost:8081 + header { + X-Content-Type-Options "nosniff" + X-Frame-Options "DENY" + Referrer-Policy "strict-origin-when-cross-origin" + Permissions-Policy "camera=(), microphone=(), geolocation=()" + } + encode zstd gzip } diff --git a/infra/ansible/playbook.yml b/infra/ansible/playbook.yml index 9a80909..f7d2f05 100644 --- a/infra/ansible/playbook.yml +++ b/infra/ansible/playbook.yml @@ -33,8 +33,35 @@ - apt-transport-https - curl - ufw + - unattended-upgrades state: present + - name: Configure unattended-upgrades + copy: + dest: /etc/apt/apt.conf.d/50unattended-upgrades + owner: root + group: root + mode: '0644' + content: | + Unattended-Upgrade::Allowed-Origins { + "${distro_id}:${distro_codename}-security"; + "${distro_id}ESMApps:${distro_codename}-apps-security"; + "${distro_id}ESM:${distro_codename}-infra-security"; + }; + Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; + Unattended-Upgrade::Remove-Unused-Dependencies "true"; + Unattended-Upgrade::Automatic-Reboot "false"; + + - name: Enable automatic updates + copy: + dest: /etc/apt/apt.conf.d/20auto-upgrades + owner: root + group: root + mode: '0644' + content: | + APT::Periodic::Update-Package-Lists "1"; + APT::Periodic::Unattended-Upgrade "1"; + # ── Caddy ─────────────────────────────────────────────────────────────── - name: Add Caddy GPG key @@ -309,6 +336,7 @@ url: "https://github.com/arp242/goatcounter/releases/download/v{{ goatcounter_version }}/goatcounter-v{{ goatcounter_version }}-linux-amd64.gz" dest: /tmp/goatcounter.gz mode: '0644' + checksum: "sha256:98d221cb9c8ef2bf76d8daa9cca647839f8d8b0bb5bc7400ff9337c5da834511" tags: goatcounter - name: Decompress GoatCounter binary diff --git a/infra/gitea/docker-compose.yml b/infra/gitea/docker-compose.yml index 2128798..3c22be6 100644 --- a/infra/gitea/docker-compose.yml +++ b/infra/gitea/docker-compose.yml @@ -1,7 +1,12 @@ services: gitea: - image: gitea/gitea:latest + image: gitea/gitea:1.25 restart: unless-stopped + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" depends_on: db: condition: service_healthy @@ -26,6 +31,11 @@ services: db: image: postgres:16-alpine restart: unless-stopped + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" volumes: - gitea_db:/var/lib/postgresql/data environment: diff --git a/infra/miniflux/docker-compose.yml b/infra/miniflux/docker-compose.yml index 61f4df7..10d6400 100644 --- a/infra/miniflux/docker-compose.yml +++ b/infra/miniflux/docker-compose.yml @@ -1,7 +1,12 @@ services: miniflux: - image: miniflux/miniflux:latest + image: miniflux/miniflux:2.2.19 restart: unless-stopped + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" depends_on: db: condition: service_healthy @@ -20,6 +25,11 @@ services: db: image: postgres:16-alpine restart: unless-stopped + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" volumes: - miniflux_db:/var/lib/postgresql/data environment: