fix: rate limits, fail2ban, readme, secret scheme

This commit is contained in:
Jet Pham 2026-03-04 16:32:53 -08:00
parent ad8cb52169
commit bb20443241
No known key found for this signature in database
4 changed files with 96 additions and 9 deletions

View file

@ -6,9 +6,13 @@ services:
- forgejo (git.extremist.software) - forgejo (git.extremist.software)
- stalwart (mail.extremist.software) - stalwart (mail.extremist.software)
- searxng (search.extremist.software) - searxng (search.extremist.software)
- conduit (matrix.extremist.software) - synapse (matrix.extremist.software)
- caddy (reverse proxy)
- grafana/prometheus (status.extremist.software) - grafana/prometheus (status.extremist.software)
- uptime-kuma (uptime.extremist.software)
- ntfy (ntfy.extremist.software)
- mymx (mymx.extremist.software)
- caddy (reverse proxy + rate limiting)
- fail2ban
## Deployment ## Deployment
@ -39,15 +43,15 @@ nix run github:nix-community/nixos-anywhere -- --store-paths \
root@<TARGET_IP> | tee install.log root@<TARGET_IP> | tee install.log
``` ```
### 3. Update Existing Server (No Wipe) ### 4. Update Existing Server (No Wipe)
Once the server is running NixOS, use `nh` to push updates. This repository provides `nh` via `direnv` (loaded from `flake.nix` devShell), so just run `direnv allow` first. Once the server is running NixOS, use the `nhs` script to push updates. This repository provides `nhs` and `nh` via `direnv` (loaded from `flake.nix` devShell), so just run `direnv allow` first.
```bash ```bash
# Update via IP # Update via Tailscale (uses nhs convenience script)
nh os switch --hostname extremist-software --target-host root@<TARGET_IP> --impure path:. nhs
# Update via Tailscale (Once tailored up) # Or manually via IP
nh os switch --hostname extremist-software --target-host root@extremist-software --impure path:. nh os switch --hostname extremist-software --target-host root@<TARGET_IP> --impure path:.
``` ```
repo uses `impure` build to load `secrets/secrets.nix` directly. no encrypted secrets in git. repo uses `impure` build to load `secrets/secrets.nix` directly. no encrypted secrets in git.

View file

@ -46,12 +46,31 @@
settings.PermitRootLogin = "prohibit-password"; settings.PermitRootLogin = "prohibit-password";
}; };
# Fail2ban
services.fail2ban = {
enable = true;
maxretry = 5;
bantime = "1h";
bantime-increment = {
enable = true;
maxtime = "168h";
overalljails = true;
};
ignoreIP = [
"100.64.0.0/10"
"127.0.0.0/8"
];
jails.sshd.settings = {
backend = "systemd";
maxretry = 3;
};
};
# nh (yet another nix helper) # nh (yet another nix helper)
programs.nh = { programs.nh = {
enable = true; enable = true;
clean.enable = true; clean.enable = true;
clean.extraArgs = "--keep 2"; clean.extraArgs = "--keep 2";
flake = "/home/jet/Documents/extremist-software";
}; };
# System # System

View file

@ -3,7 +3,14 @@
{ {
services.caddy = { services.caddy = {
enable = true; enable = true;
package = pkgs.caddy.withPlugins {
plugins = [ "github.com/mholt/caddy-ratelimit@v0.1.0" ];
hash = "sha256-MBYvVqWB9GK3LSWigeb4NOgclGA2qZTSUyBJMdB635M=";
};
email = "postmaster@extremist.software"; email = "postmaster@extremist.software";
globalConfig = ''
order rate_limit before basicauth
'';
virtualHosts = { virtualHosts = {
"extremist.software" = { "extremist.software" = {
useACMEHost = "extremist.software"; useACMEHost = "extremist.software";
@ -35,6 +42,13 @@
"git.extremist.software" = { "git.extremist.software" = {
extraConfig = '' extraConfig = ''
rate_limit {
zone git_per_ip {
key {remote.ip}
events 120
window 1m
}
}
reverse_proxy localhost:3000 reverse_proxy localhost:3000
''; '';
}; };
@ -46,6 +60,13 @@
root * /var/lib/acme/acme-challenge root * /var/lib/acme/acme-challenge
file_server file_server
} }
rate_limit {
zone mail_per_ip {
key {remote.ip}
events 60
window 1m
}
}
handle { handle {
reverse_proxy localhost:8080 reverse_proxy localhost:8080
} }
@ -54,36 +75,78 @@
"search.extremist.software" = { "search.extremist.software" = {
extraConfig = '' extraConfig = ''
rate_limit {
zone search_per_ip {
key {remote.ip}
events 60
window 1m
}
}
reverse_proxy localhost:8082 reverse_proxy localhost:8082
''; '';
}; };
"status.extremist.software" = { "status.extremist.software" = {
extraConfig = '' extraConfig = ''
rate_limit {
zone grafana_per_ip {
key {remote.ip}
events 120
window 1m
}
}
reverse_proxy localhost:3001 # Grafana reverse_proxy localhost:3001 # Grafana
''; '';
}; };
"uptime.extremist.software" = { "uptime.extremist.software" = {
extraConfig = '' extraConfig = ''
rate_limit {
zone uptime_per_ip {
key {remote.ip}
events 60
window 1m
}
}
reverse_proxy localhost:4001 reverse_proxy localhost:4001
''; '';
}; };
"ntfy.extremist.software" = { "ntfy.extremist.software" = {
extraConfig = '' extraConfig = ''
rate_limit {
zone ntfy_per_ip {
key {remote.ip}
events 120
window 1m
}
}
reverse_proxy localhost:2586 reverse_proxy localhost:2586
''; '';
}; };
"mymx.extremist.software" = { "mymx.extremist.software" = {
extraConfig = '' extraConfig = ''
rate_limit {
zone mymx_per_ip {
key {remote.ip}
events 60
window 1m
}
}
reverse_proxy localhost:4002 reverse_proxy localhost:4002
''; '';
}; };
"matrix.extremist.software" = { "matrix.extremist.software" = {
extraConfig = '' extraConfig = ''
rate_limit {
zone matrix_per_ip {
key {remote.ip}
events 240
window 1m
}
}
reverse_proxy /_matrix/* 127.0.0.1:8008 reverse_proxy /_matrix/* 127.0.0.1:8008
reverse_proxy /_synapse/client/* 127.0.0.1:8008 reverse_proxy /_synapse/client/* 127.0.0.1:8008
reverse_proxy /.well-known/matrix/* 127.0.0.1:8008 reverse_proxy /.well-known/matrix/* 127.0.0.1:8008

View file

@ -9,6 +9,7 @@
minecraftRcon = "changeme_rcon"; minecraftRcon = "changeme_rcon";
tailscaleKey = "tskey-auth-PLACEHOLDER"; tailscaleKey = "tskey-auth-PLACEHOLDER";
sshPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA..."; sshPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...";
grafanaSecret = "changeme_grafana_secret";
matrixMacaroon = "changeme_matrix_macaroon_secret_key"; matrixMacaroon = "changeme_matrix_macaroon_secret_key";
ntfyAdminHash = "changeme_bcrypt_hash_from_ntfy_user_hash"; ntfyAdminHash = "changeme_bcrypt_hash_from_ntfy_user_hash";
mymxWebhookSecret = "changeme_mymx_webhook_secret"; mymxWebhookSecret = "changeme_mymx_webhook_secret";