Files
microdao-daarion/ops/nginx/node1-hardened.conf
Apple 0c8bef82f4 feat: Add Alateya, Clan, Eonarch agents + fix gateway-router connection
## Agents Added
- Alateya: R&D, biotech, innovations
- Clan (Spirit): Community spirit agent
- Eonarch: Consciousness evolution agent

## Changes
- docker-compose.node1.yml: Added tokens for all 3 new agents
- gateway-bot/http_api.py: Added configs and webhook endpoints
- gateway-bot/clan_prompt.txt: New prompt file
- gateway-bot/eonarch_prompt.txt: New prompt file

## Fixes
- Fixed ROUTER_URL from :9102 to :8000 (internal container port)
- All 9 Telegram agents now working

## Documentation
- Created PROJECT-MASTER-INDEX.md - single entry point
- Added various status documents and scripts

Tokens configured:
- Helion, NUTRA, Agromatrix (existing)
- Alateya, Clan, Eonarch (new)
- Druid, GreenFood, DAARWIZZ (configured)
2026-01-28 06:40:34 -08:00

225 lines
7.3 KiB
Plaintext

#
# NODE1 Hardened Nginx Configuration
# Version: 2.0
# Last Updated: 2026-01-26
#
# Features:
# - TLS 1.2/1.3 only with modern ciphers
# - HSTS with preload
# - Rate limiting (standard + heavy endpoints)
# - WAF-lite rules (block scanners, sensitive files)
# - Security headers (XSS, CSRF, clickjacking)
# - Logging with privacy (no auth headers)
#
# === Rate Limit Zones ===
limit_req_zone $binary_remote_addr zone=api_per_ip:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=heavy_per_ip:10m rate=2r/s;
limit_req_zone $binary_remote_addr zone=webhook_per_ip:10m rate=50r/s;
limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;
# === Logging format (no Authorization header) ===
log_format api_safe '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
# === Upstream ===
upstream gateway_upstream {
server 127.0.0.1:9300;
keepalive 64;
}
# === HTTP → HTTPS redirect ===
server {
listen 80;
listen [::]:80;
server_name gateway.daarion.city api.daarion.io 144.76.224.179 _;
# Allow ACME challenge for certificate renewal
location /.well-known/acme-challenge/ {
root /var/www/html;
}
# Redirect everything else to HTTPS
location / {
return 301 https://$host$request_uri;
}
}
# === Main HTTPS Server ===
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name gateway.daarion.city api.daarion.io 144.76.224.179;
# === SSL Configuration ===
ssl_certificate /etc/letsencrypt/live/gateway.daarion.city/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/gateway.daarion.city/privkey.pem;
# Modern SSL (TLS 1.2+ only)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# SSL session
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# === Security Headers ===
# HSTS (2 years, with preload)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# Prevent clickjacking
add_header X-Frame-Options "SAMEORIGIN" always;
# Prevent MIME sniffing
add_header X-Content-Type-Options "nosniff" always;
# XSS Protection
add_header X-XSS-Protection "1; mode=block" always;
# Referrer policy
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Content Security Policy (adjust as needed)
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self' wss: https:;" always;
# === Logging ===
access_log /var/log/nginx/api-access.log api_safe;
error_log /var/log/nginx/api-error.log warn;
# === WAF-lite: Block sensitive files ===
location ~* \.(env|git|sql|bak|swp|old|backup|log|ini|conf|config|yml|yaml|json|xml|db|sqlite)$ {
return 444; # Close connection without response
}
# Block common attack paths
location ~* ^/(\.git|\.svn|\.hg|\.env|wp-admin|wp-login|phpmyadmin|admin\.php|xmlrpc\.php) {
return 444;
}
# Block suspicious query strings
if ($query_string ~* "(union|select|insert|drop|delete|update|truncate|exec|script|alert)") {
return 403;
}
# === Rate limit status (internal only) ===
location = /nginx-status {
stub_status on;
allow 127.0.0.1;
deny all;
}
# === Health check (no rate limit) ===
location = /health {
limit_req off;
proxy_pass http://gateway_upstream/health;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
# === Webhook endpoints (higher burst for Telegram) ===
location ~ ^/(webhook|telegram|bot) {
limit_req zone=webhook_per_ip burst=100 nodelay;
limit_conn conn_per_ip 50;
proxy_pass http://gateway_upstream;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
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 $scheme;
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
client_max_body_size 10m;
}
# === Heavy endpoints (stricter limit) ===
location ~ ^/(v1/rag|v1/image|v1/search|v1/embed|v1/generate) {
limit_req zone=heavy_per_ip burst=5 nodelay;
limit_conn conn_per_ip 10;
proxy_pass http://gateway_upstream;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
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 $scheme;
# Longer timeouts for heavy operations
proxy_connect_timeout 10s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
client_max_body_size 100m;
}
# === Default API (standard rate limit) ===
location / {
limit_req zone=api_per_ip burst=20 nodelay;
limit_conn conn_per_ip 20;
proxy_pass http://gateway_upstream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
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 $scheme;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_cache_bypass $http_upgrade;
client_max_body_size 10m;
}
# === Error pages ===
error_page 429 = @rate_limited;
location @rate_limited {
default_type application/json;
return 429 '{"error": "rate_limit_exceeded", "message": "Too many requests", "retry_after": 1}';
}
error_page 403 = @forbidden;
location @forbidden {
default_type application/json;
return 403 '{"error": "forbidden", "message": "Access denied"}';
}
}
# === WebSocket upgrade mapping ===
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# === Admin Panel (localhost only, via SSH tunnel) ===
server {
listen 127.0.0.1:8080;
server_name localhost;
location /grafana/ {
proxy_pass http://127.0.0.1:3030/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
location /prometheus/ {
proxy_pass http://127.0.0.1:9090/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
}