From d3dec2cc0ccf5af471bfe15a4c1ebda86f2b1032 Mon Sep 17 00:00:00 2001 From: alastairong1 <177203013+alastairong1@users.noreply.github.com> Date: Wed, 6 May 2026 10:26:10 +0000 Subject: [PATCH] Nginx hardening + infra updates (#87) ## Summary - Add nginx rate limiting (10r/s per IP, burst 20) with 429 status - Add security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy) - Block common exploit scanner paths (PHP, ASP, Docker, ThinkPHP) - Set `client_max_body_size 1m` for API payloads - Enable recommended gzip and optimisation settings - Add Alastair SSH key to infra and ssh roles ## Test plan - [x] NixOS configuration evaluates without errors - [x] `cargo check` passes - [x] `rainix-rs-static` passes - [ ] Rate limiting returns 429 when exceeded in deployed nginx - [ ] Exploit scanner paths return 444 (connection drop) in deployed nginx - [ ] Security headers present in deployed responses ## Summary by CodeRabbit * **New Features** * API request rate limiting implemented. * Scanner path blocking enabled. * **Chores** * Added infrastructure access for new team member. * Web server optimization and compression enabled. * HTTP headers added to the API endpoint. --- keys.nix | 6 ++++-- os.nix | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/keys.nix b/keys.nix index 538238b..2519d61 100644 --- a/keys.nix +++ b/keys.nix @@ -9,10 +9,12 @@ rec { arda = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAyTREGZCOzMsl7N9dp1saN/t7DCs7YesusVUKApMJ78"; sid = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPl3/6RlR6Rvz0ZRyZukzFtt4zUYNz5OVuTsajJl7V3n"; + alastair = + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJArH3PA+bFIon0JkCVQGs9aWr45lnVjiiTLLO9BPItn"; }; roles = with keys; { - infra = [ st0x-op ci sid ]; - ssh = [ st0x-op ci arda sid ]; + infra = [ st0x-op ci sid alastair ]; + ssh = [ st0x-op ci arda sid alastair ]; }; } diff --git a/os.nix b/os.nix index 76d0686..ae314e7 100644 --- a/os.nix +++ b/os.nix @@ -99,11 +99,42 @@ in { enable = true; recommendedTlsSettings = true; recommendedProxySettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + + # Rate-limit zone: 10 req/s per IP, burst 20 + appendHttpConfig = '' + limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; + ''; + virtualHosts."api.st0x.io" = { enableACME = true; forceSSL = true; + + extraConfig = '' + # Security headers + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "DENY" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + + # Limit request body size (API payloads are small) + client_max_body_size 1m; + ''; + + # Block common exploit scanners (PHP, Docker, ThinkPHP, etc.) + locations."~* \\.(php|asp|aspx|jsp|cgi)$" = { + return = "444"; + }; + locations."~* ^/(containers|_ignition|vendor|public/index)" = { + return = "444"; + }; + locations."/" = { proxyPass = "http://127.0.0.1:8000"; + extraConfig = '' + limit_req zone=api burst=20 nodelay; + limit_req_status 429; + ''; }; }; };