-
Notifications
You must be signed in to change notification settings - Fork 0
feat: nginx security stack with WAF, CrowdSec, and rate limiting #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ViktorPalchynskyi
wants to merge
16
commits into
master
Choose a base branch
from
dev
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
213983e
feat: add docker-compose and project structure
ViktorPalchynskyi 4e23d87
feat: add nginx configuration with rate limiting and security headers
ViktorPalchynskyi e56ede5
feat: add ModSecurity WAF rules and exclusions
ViktorPalchynskyi 9e9b4ca
feat: add CrowdSec configuration with Prometheus metrics
ViktorPalchynskyi 707a328
feat: add Prometheus scrape config and alerting rules
ViktorPalchynskyi f6d2c2e
feat: add security and false-positive test scripts
ViktorPalchynskyi 568e8b2
docs: add comprehensive README with setup and troubleshooting
ViktorPalchynskyi e841ff8
chore: remove empty gitkeep placeholders
ViktorPalchynskyi 6eaff66
chore: remove alerting rules template
ViktorPalchynskyi 61eee9d
docs: remove alerting rules references from README
ViktorPalchynskyi d82cb37
fix: update configs for OWASP ModSecurity CRS container compatibility
ViktorPalchynskyi 7ea0081
refactor: remove bouncer, simplify CrowdSec to monitoring role
ViktorPalchynskyi ef71135
feat: add rate limiting for auth endpoints
ViktorPalchynskyi e8e594e
docs: update README, remove unused nginx configs
ViktorPalchynskyi 9eb8784
fix: add exclusions for math expressions false positives
ViktorPalchynskyi 68ed348
feat: add container security hardening, SSRF protection, and automation
ViktorPalchynskyi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| # =========================================== | ||
| # Nginx Security Stack - Environment Variables | ||
| # =========================================== | ||
| # Copy this file to .env and customize values | ||
|
|
||
| # =========================================== | ||
| # Backend Configuration | ||
| # =========================================== | ||
|
|
||
| # Backend application | ||
| # Default: httpbin for testing (started automatically with make start) | ||
| BACKEND=http://httpbin:80 | ||
|
|
||
| # For your own backend, change to: | ||
| # BACKEND=http://your-app:3000 | ||
|
|
||
| # =========================================== | ||
| # Port Configuration | ||
| # =========================================== | ||
|
|
||
| # Nginx ports (use 80/443 for production, 8080/8443 for development) | ||
| NGINX_HTTP_PORT=8080 | ||
| NGINX_HTTPS_PORT=8443 | ||
|
|
||
| # Metrics ports (for Prometheus scraping) | ||
| NGINX_EXPORTER_PORT=9113 | ||
| CROWDSEC_METRICS_PORT=6060 | ||
|
|
||
| # Optional monitoring stack ports | ||
| LOKI_PORT=3100 | ||
| GRAFANA_PORT=3000 | ||
|
|
||
| # =========================================== | ||
| # ModSecurity Configuration | ||
| # =========================================== | ||
|
|
||
| # WAF mode: On (blocking), DetectionOnly (logging), Off (disabled) | ||
| MODSEC_RULE_ENGINE=On | ||
|
|
||
| # OWASP CRS Paranoia Level (1-4, higher = more strict) | ||
| PARANOIA=1 | ||
|
|
||
| # Anomaly scoring thresholds | ||
| ANOMALY_INBOUND=5 | ||
| ANOMALY_OUTBOUND=4 | ||
|
|
||
| # =========================================== | ||
| # CrowdSec Configuration | ||
| # =========================================== | ||
|
|
||
| # User/Group ID for CrowdSec | ||
| GID=1000 | ||
|
|
||
| # CrowdSec Firewall Bouncer API Key (optional, for iptables IP blocking) | ||
| # Generate with: docker exec crowdsec cscli bouncers add firewall-bouncer -o raw | ||
| # CROWDSEC_BOUNCER_KEY=your-bouncer-api-key | ||
|
|
||
| # =========================================== | ||
| # Grafana Configuration (Optional) | ||
| # =========================================== | ||
|
|
||
| # Grafana admin password | ||
| GRAFANA_PASSWORD=your-secure-password |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,139 +1,52 @@ | ||
| # Logs | ||
| logs | ||
| *.log | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| lerna-debug.log* | ||
|
|
||
| # Diagnostic reports (https://nodejs.org/api/report.html) | ||
| report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
|
||
| # Runtime data | ||
| pids | ||
| *.pid | ||
| *.seed | ||
| *.pid.lock | ||
|
|
||
| # Directory for instrumented libs generated by jscoverage/JSCover | ||
| lib-cov | ||
|
|
||
| # Coverage directory used by tools like istanbul | ||
| coverage | ||
| *.lcov | ||
|
|
||
| # nyc test coverage | ||
| .nyc_output | ||
|
|
||
| # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
| .grunt | ||
|
|
||
| # Bower dependency directory (https://bower.io/) | ||
| bower_components | ||
|
|
||
| # node-waf configuration | ||
| .lock-wscript | ||
|
|
||
| # Compiled binary addons (https://nodejs.org/api/addons.html) | ||
| build/Release | ||
|
|
||
| # Dependency directories | ||
| node_modules/ | ||
| jspm_packages/ | ||
|
|
||
| # Snowpack dependency directory (https://snowpack.dev/) | ||
| web_modules/ | ||
|
|
||
| # TypeScript cache | ||
| *.tsbuildinfo | ||
|
|
||
| # Optional npm cache directory | ||
| .npm | ||
|
|
||
| # Optional eslint cache | ||
| .eslintcache | ||
|
|
||
| # Optional stylelint cache | ||
| .stylelintcache | ||
|
|
||
| # Optional REPL history | ||
| .node_repl_history | ||
|
|
||
| # Output of 'npm pack' | ||
| *.tgz | ||
| # =========================================== | ||
| # Nginx Security Stack - Git Ignore | ||
| # =========================================== | ||
|
|
||
| # Yarn Integrity file | ||
| .yarn-integrity | ||
|
|
||
| # dotenv environment variable files | ||
| # Environment files (contain secrets) | ||
| .env | ||
| .env.* | ||
| !.env.example | ||
|
|
||
| # parcel-bundler cache (https://parceljs.org/) | ||
| .cache | ||
| .parcel-cache | ||
|
|
||
| # Next.js build output | ||
| .next | ||
| out | ||
|
|
||
| # Nuxt.js build / generate output | ||
| .nuxt | ||
| dist | ||
|
|
||
| # Gatsby files | ||
| .cache/ | ||
| # Comment in the public line in if your project uses Gatsby and not Next.js | ||
| # https://nextjs.org/blog/next-9-1#public-directory-support | ||
| # public | ||
|
|
||
| # vuepress build output | ||
| .vuepress/dist | ||
|
|
||
| # vuepress v2.x temp and cache directory | ||
| .temp | ||
| .cache | ||
|
|
||
| # Sveltekit cache directory | ||
| .svelte-kit/ | ||
|
|
||
| # vitepress build output | ||
| **/.vitepress/dist | ||
|
|
||
| # vitepress cache directory | ||
| **/.vitepress/cache | ||
|
|
||
| # Docusaurus cache and generated files | ||
| .docusaurus | ||
|
|
||
| # Serverless directories | ||
| .serverless/ | ||
|
|
||
| # FuseBox cache | ||
| .fusebox/ | ||
|
|
||
| # DynamoDB Local files | ||
| .dynamodb/ | ||
|
|
||
| # Firebase cache directory | ||
| .firebase/ | ||
|
|
||
| # TernJS port file | ||
| .tern-port | ||
|
|
||
| # Stores VSCode versions used for testing VSCode extensions | ||
| .vscode-test | ||
|
|
||
| # yarn v3 | ||
| .pnp.* | ||
| .yarn/* | ||
| !.yarn/patches | ||
| !.yarn/plugins | ||
| !.yarn/releases | ||
| !.yarn/sdks | ||
| !.yarn/versions | ||
| # Logs | ||
| logs/* | ||
| !logs/.gitkeep | ||
| *.log | ||
|
|
||
| # Vite logs files | ||
| vite.config.js.timestamp-* | ||
| vite.config.ts.timestamp-* | ||
| # SSL Certificates (sensitive) | ||
| certs/* | ||
| !certs/.gitkeep | ||
| *.pem | ||
| *.key | ||
| *.crt | ||
| *.csr | ||
|
|
||
| # CrowdSec data (created by Docker at runtime) | ||
| config/crowdsec-bouncer/ | ||
| config/crowdsec/* | ||
| !config/crowdsec/config.yaml.local | ||
| crowdsec-data/ | ||
|
|
||
| # Docker volumes data | ||
| loki-data/ | ||
| grafana-data/ | ||
|
|
||
| # IDE/Editor | ||
| .idea/ | ||
| .vscode/ | ||
| *.swp | ||
| *.swo | ||
| *~ | ||
|
|
||
| # OS files | ||
| .DS_Store | ||
| Thumbs.db | ||
|
|
||
| # Backup files | ||
| *.bak | ||
| *.backup | ||
| *.old | ||
| *.orig | ||
|
|
||
| # Temp files | ||
| *.tmp | ||
| *.temp |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| .PHONY: help start stop restart test test-security test-false-pos logs logs-audit status bans unban-all health clean start-monitoring | ||
|
|
||
| # Default target | ||
| help: | ||
| @echo "Nginx Security Stack - Available Commands" | ||
| @echo "" | ||
| @echo " make start - Start all core services" | ||
| @echo " make start-monitoring - Start with monitoring stack (Loki, Promtail, Grafana)" | ||
| @echo " make stop - Stop all services" | ||
| @echo " make restart - Restart all services" | ||
| @echo " make test - Run all tests" | ||
| @echo " make test-security - Run security tests only" | ||
| @echo " make test-false-pos - Run false positive tests only" | ||
| @echo " make logs - View nginx-waf logs" | ||
| @echo " make logs-audit - View ModSecurity audit logs" | ||
| @echo " make status - Show service status" | ||
| @echo " make bans - List CrowdSec bans" | ||
| @echo " make unban-all - Remove all CrowdSec bans" | ||
| @echo " make health - Check health endpoints" | ||
| @echo " make clean - Stop services and remove volumes" | ||
|
|
||
| # Service management | ||
| start: | ||
| docker-compose up -d nginx-waf crowdsec nginx-exporter httpbin | ||
| @echo "Waiting for services to start..." | ||
| @sleep 15 | ||
| @$(MAKE) health | ||
|
|
||
| start-monitoring: | ||
| docker-compose --profile monitoring up -d | ||
| @echo "Waiting for services to start..." | ||
| @sleep 20 | ||
| @$(MAKE) health | ||
|
|
||
| stop: | ||
| docker-compose down | ||
|
|
||
| restart: | ||
| docker-compose restart nginx-waf crowdsec nginx-exporter | ||
|
|
||
| # Testing | ||
| test: test-security test-false-pos | ||
| @echo "All tests completed" | ||
|
|
||
| test-security: | ||
| @./scripts/test-security.sh localhost:8080 http | ||
|
|
||
| test-false-pos: | ||
| @./scripts/test-false-positives.sh localhost:8080 http | ||
|
|
||
| # Logs and monitoring | ||
| logs: | ||
| docker-compose logs -f nginx-waf | ||
|
|
||
| logs-audit: | ||
| @docker exec nginx-waf tail -f /var/log/modsecurity/audit.log 2>/dev/null | jq . || \ | ||
| docker exec nginx-waf tail -f /var/log/modsecurity/audit.log | ||
|
|
||
| status: | ||
| docker-compose ps | ||
|
|
||
| # CrowdSec operations | ||
| bans: | ||
| docker exec crowdsec cscli decisions list | ||
|
|
||
| unban-all: | ||
| docker exec crowdsec cscli decisions delete --all | ||
|
|
||
| # Health checks | ||
| health: | ||
| @echo "Checking health endpoints..." | ||
| @curl -sf http://localhost:8080/healthz > /dev/null 2>&1 && echo "nginx-waf: OK" || echo "nginx-waf: FAIL" | ||
| @curl -sf http://localhost:9113/metrics > /dev/null 2>&1 && echo "nginx-exporter: OK" || echo "nginx-exporter: FAIL" | ||
| @curl -sf http://localhost:6060/metrics > /dev/null 2>&1 && echo "crowdsec: OK" || echo "crowdsec: FAIL" | ||
|
|
||
| # Cleanup | ||
| clean: | ||
| docker-compose down -v | ||
| rm -rf logs/nginx/* logs/modsecurity/* |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,52 @@ | ||
| # cloud-native-nginx | ||
| Nginx image with enabled plugins for security and observability | ||
| # Nginx Security Stack | ||
|
|
||
| Docker-based security stack: WAF (ModSecurity + OWASP CRS), CrowdSec, Rate Limiting. | ||
|
|
||
| ## Quick Start | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I not really get what process Cloudbankin team should follow to setup it properly. Does them need to clone repo on production VM and run |
||
|
|
||
| ```bash | ||
| cp .env.example .env | ||
| make start | ||
| make test | ||
| ``` | ||
|
|
||
| Works out of the box with test backend (httpbin). | ||
|
|
||
| For your own backend, edit `BACKEND` in `.env`: | ||
| ```bash | ||
| BACKEND=http://your-app:3000 | ||
| ``` | ||
|
|
||
| ## Commands | ||
|
|
||
| ```bash | ||
| make help # Show all commands | ||
| make start # Start core services | ||
| make start-monitoring # Start with monitoring (Loki, Grafana) | ||
| make stop # Stop all services | ||
| make restart # Restart services | ||
| make test # Run all tests | ||
| make test-security # Security tests only | ||
| make test-false-pos # False positive tests only | ||
| make logs # View nginx-waf logs | ||
| make logs-audit # View ModSecurity audit logs | ||
| make status # Show service status | ||
| make health # Check health endpoints | ||
| make bans # List CrowdSec bans | ||
| make unban-all # Remove all bans | ||
| make clean # Stop and remove volumes | ||
| ``` | ||
|
|
||
| ## Ports | ||
|
|
||
| | Service | Port | | ||
| |---------|------| | ||
| | nginx-waf HTTP | 8080 | | ||
| | nginx-waf HTTPS | 8443 | | ||
| | nginx-exporter | 9113 | | ||
| | crowdsec | 6060 | | ||
|
|
||
| ## Docs | ||
|
|
||
| - [Quick Reference](docs/QUICK_REFERENCE.md) | ||
| - [Emergency Procedures](docs/EMERGENCY.md) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.