Ich darf in „How-Tos“ keine Beiträge verfassen, also poste ich dies hier ![]()
Übersicht
Das Ziel ist es, eine WAF (Web Application Firewall) zu bestehenden Ressourcen hinzuzufügen, ohne die Leistung bei einer kleinen Installation zu beeinträchtigen. In diesem Beispiel verwenden wir eine einzelne EC2-Instanz. Da Discourse in Docker läuft, können wir NGINX auf dem Host installieren und per Proxy-Pass den Verkehr in unseren Docker-Container leiten. Zudem nutzen wir RDS für PostgreSQL.
Discourse-Konfiguration
Unser erster Schritt besteht darin, die Datei app.yml für eine benutzerdefinierte Discourse-Installation zu konfigurieren. In diesem Beispiel führen wir die Rollen „web“ und „redis“ aus. Wir verwenden weder die DB-Rolle noch die SSL-Rollen.
Außerdem möchten wir sicherstellen, dass wir keine Web-Ports im Docker-Container exponieren. Der Grund dafür ist, dass wir den Webzugriff über den NGINX-Proxy auf dem Host bereitstellen.
Beispiel für eine app.yml-Datei
## Dies ist die All-in-One-Standalone-Discourse-Docker-Container-Vorlage
##
## Nach Änderungen an dieser Datei MUSS neu erstellt werden:
## /var/discourse/launcher rebuild app
##
## SEHR VORSICHT BEI DER BEARBEITUNG!
## YAML-DATEIEN SIND EXTREM EMPFINDLICH GEGENÜBER FEHLERN IN LEERZEICHEN ODER AUSRICHTUNG!
## Besuchen Sie http://www.yamllint.com/, um diese Datei bei Bedarf zu validieren
templates:
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
- "templates/web.socketed.template.yml"
## Kommentieren Sie diese beiden Zeilen aus, wenn Sie Lets Encrypt (https) hinzufügen möchten
#- "templates/web.ssl.template.yml"
#- "templates/web.letsencrypt.ssl.template.yml"
## Welche TCP/IP-Ports soll dieser Container exponieren?
## Wenn Sie Discourse einen Port mit einem anderen Webserver wie Apache oder nginx teilen möchten,
## siehe https://meta.discourse.org/t/17247 für Details
expose:
# - "80:80" # http
# - "443:443" # https
params:
db_default_text_search_config: "pg_catalog.english"
## Setzen Sie db_shared_buffers auf maximal 25 % des gesamten Arbeitsspeichers.
## Wird automatisch vom Bootstrap basierend auf dem erkannten RAM gesetzt oder Sie können überschreiben
db_shared_buffers: "768MB"
## Kann die Sortierleistung verbessern, erhöht jedoch den Speicherverbrauch pro Verbindung
#db_work_mem: "40MB"
## Welchen Git-Revision soll dieser Container verwenden? (Standard: tests-passed)
#version: tests-passed
env:
LANG: en_US.UTF-8
# DISCOURSE_DEFAULT_LOCALE: en
## Wie viele gleichzeitige Webanfragen werden unterstützt? Hängt vom Arbeitsspeicher und den CPU-Kernen ab.
## Wird automatisch vom Bootstrap basierend auf den erkannten CPUs gesetzt oder Sie können überschreiben
UNICORN_WORKERS: 2
## TODO: Der Domainname, auf den diese Discourse-Instanz antworten soll
## Erforderlich. Discourse funktioniert nicht mit einer reinen IP-Nummer.
DISCOURSE_HOSTNAME: cloudforums.net
## Kommentieren Sie dies aus, wenn Sie möchten, dass der Container mit dem gleichen
## Hostnamen (-h-Option) wie oben angegeben gestartet wird (Standard: „$hostname-$config")
#DOCKER_USE_HOSTNAME: true
## TODO: Liste der durch Komma getrennten E-Mail-Adressen, die bei der ersten Registrierung zu Administratoren und Entwicklern werden
## Beispiel: 'user1@example.com,user2@example.com'
DISCOURSE_DEVELOPER_EMAILS: 'youremail@domain.com'
## TODO: Der SMTP-Mailserver, der zur Validierung neuer Konten und zum Senden von Benachrichtigungen verwendet wird
## SMTP-Adresse, Benutzername und Passwort sind erforderlich
## WARNUNG: Das Zeichen '#' im SMTP-Passwort kann Probleme verursachen!
DISCOURSE_SMTP_ADDRESS: YOUR_SMTP
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: YOUR_SMTP_USERNAME
DISCOURSE_SMTP_PASSWORD: YOUR_SMTP_PASSWORD
#DISCOURSE_SMTP_ENABLE_START_TLS: true # (optional, Standard: true)
## Wenn Sie die Lets Encrypt-Vorlage hinzugefügt haben, kommentieren Sie unten aus, um ein kostenloses SSL-Zertifikat zu erhalten
#LETSENCRYPT_ACCOUNT_EMAIL: me@example.com
DISCOURSE_DB_SOCKET: ''
DISCOURSE_DB_USERNAME: YOUR_USERNAME
DISCOURSE_DB_PASSWORD: YOUR_PASSWORD
DISCOURSE_DB_HOST: YOUR_HOST
## Die HTTP- oder HTTPS-CDN-Adresse für diese Discourse-Instanz (konfiguriert zum Abrufen)
## siehe https://meta.discourse.org/t/14857 für Details
#DISCOURSE_CDN_URL: https://discourse-cdn.example.com
## Der Docker-Container ist zustandslos; alle Daten werden in /shared gespeichert
volumes:
- volume:
host: /var/discourse/shared/standalone
guest: /shared
- volume:
host: /var/discourse/shared/standalone/log/var-log
guest: /var/log
## Plugins gehen hier
## siehe https://meta.discourse.org/t/19157 für Details
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/docker_manager.git
## Beliebige benutzerdefinierte Befehle, die nach dem Erstellen ausgeführt werden sollen
run:
- exec: echo „Beginn der benutzerdefinierten Befehle"
## Wenn Sie die Absender-E-Mail-Adresse für Ihre erste Registrierung festlegen möchten, kommentieren Sie dies aus und ändern Sie:
## Nachdem Sie die erste Anmelde-E-Mail erhalten haben, kommentieren Sie die Zeile erneut aus. Sie muss nur einmal ausgeführt werden.
- exec: rails c „SiteSetting.enable_badge_sql = true"
- exec: echo „Ende der benutzerdefinierten Befehle"
Beginn der Discourse-Installation
Discourse-Repository klonen
sudo -u root git clone https://github.com/discourse/discourse_docker.git /var/discours
Benutzerdefinierte app.yml für die Installation kopieren
Sie können den folgenden Befehl ausführen, um dies für Sie zu erledigen. Ersetzen Sie einfach den Testtext „PASTE YOUR FULL APP.YML HERE“ durch Ihre vollständige app.yml.
sudo -u root cat > /var/discourse/containers/app.yml <<\EOF
PASTE YOUR FULL APP.YML HERE
EOF
Discourse-Setup ausführen
Starten Sie das Discourse-Setup ohne Aufforderungen mit dem folgenden Befehl.
sudo -u yes "" | /var/discourse/./discourse-setup
Die Discourse-Installation sollte etwa 10–15 Minuten dauern.
NGINX-, WAF- und GEOIP-Installation
Updates ausführen und Voraussetzungen installieren
apt update -y
apt upgrade -y
apt -y install libpcre3-dev libssl-dev unzip build-essential daemon libxml2-dev libxslt1-dev libgd-dev libgeoip-dev zlib1g-dev libpcre3
Installieren Sie die MindMax-Datenbank, damit Sie GEO-IP-Regeln basierend auf dem Standort ausführen können. Mit dieser Datenbank können Sie den Verkehr basierend auf dem Standort routen oder blockieren. Unsere NGINX-Protokolle zeigen nun das Land des Benutzers an, selbst wenn Sie die Geo-Blockierung nicht aktivieren.
sudo add-apt-repository -y ppa:maxmind/ppa
apt update -y
apt install -y libmaxminddb0 libmaxminddb-dev mmdb-bin
NGINX und NAXSI WAF herunterladen und extrahieren
Hinweis: Ersetzen Sie NGINX durch die neueste Version
mkdir ~/nginx-waf
wget https://nginx.org/download/nginx-1.16.1.tar.gz -O ~/nginx-waf/nginx.tar.gz
tar xzf ~/nginx-waf/nginx.tar.gz -C ~/nginx-waf
wget https://github.com/nbs-system/naxsi/archive/master.zip -O ~/nginx-waf/waf.zip
unzip ~/nginx-waf/waf.zip -d ~/nginx-waf/
Git-Clone des GEO IP2-Moduls für NGINX
apt install -y git
git clone https://github.com/leev/ngx_http_geoip2_module.git /etc/ngx_http_geoip2_module
NGINX kompilieren
Wir erstellen ein Skript, das dies für uns erledigt, und führen es unten aus.
cat > ~/nginx-waf/nginx-1.16.1/install.sh <<\EOF
cd ~/nginx-waf/nginx-1.16.1/
./configure --conf-path=/etc/nginx/nginx.conf --add-module=../naxsi-master/naxsi_src/ --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --user=www-data --group=www-data --with-http_ssl_module --without-mail_pop3_module --without-mail_smtp_module --without-mail_imap_module --without-http_uwsgi_module --add-dynamic-module=/etc/ngx_http_geoip2_module --without-http_scgi_module --prefix=/usr
make
make install
EOF
sh ~/nginx-waf/nginx-1.16.1/install.sh
Firewall-Regeln erstellen
Die unten stehende Standardkonfiguration aktiviert die WAF und blockiert bösartige Anfragen. Wenn Sie die WAF im Lernmodus ausführen möchten, können Sie dies tun, indem Sie „Learning Mode“ zur Regeldatei unten hinzufügen.
cp ~/nginx-waf/naxsi-master/naxsi_config/naxsi_core.rules /etc/nginx/
cat > /etc/nginx/naxsi.rules <<\EOF
SecRulesEnabled;
DeniedUrl "/RequestDenied";
## Prüfen Sie Naxsi-Regeln
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
EOF
NGINX-Konfigurationsdatei erstellen
Standardmäßig ist in dieser Konfigurationsdatei die Geo-Blockierung auskommentiert, Sie können sie jedoch auskommentieren und aktivieren, wenn Sie möchten.
Hinweis: Wir müssen NGINX zunächst OHNE SSL ausführen, da wir benötigen, dass certbot eine live Domain sieht. Wir werden in einem späteren Schritt SSL erhalten und tatsächlich eine neue NGINX-Conf-Datei herunterladen, um diese zu ersetzen.
Hinweis: Ersetzen Sie cloudforums.net durch Ihren Domainnamen.
cat > /etc/nginx/nginx.conf <<\EOF
#user nobody;
worker_processes 1;
load_module modules/ngx_http_geoip2_module.so;
events {
worker_connections 1024;
}
http {
include mime.types;
include /etc/nginx/naxsi_core.rules;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
geoip2 /etc/geo_ip/GeoLite2-Country.mmdb {
$geoip2_data_country_code source=$remote_addr country iso_code;
$geoip2_data_country_name source=$remote_addr country names en;
}
log_format main_geo '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$geoip2_data_country_code $geoip2_data_country_name';
access_log /var/log/nginx/access.log main_geo;
default_type application/octet-stream;
error_log /var/log/nginx/error.log;
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name cloudforums.net;
root /;
location /.well-known/acme-challenge/ {
root /var/www;
}
location / {
return 301 https://$host$request_uri;
include /etc/nginx/naxsi.rules;
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
EOF
Upstart-Skript für NGINX erstellen
Wir müssen ein Skript für den NGINX-Dienst erstellen, damit er gestartet werden kann.
cat > /etc/init.d/nginx <<\EOF
#! /bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/nginx
NAME=nginx
DESC=nginx
test -x $DAEMON || exit 0
# Fügen Sie NGINX-Standardwerte hinzu, falls verfügbar
if [ -f /etc/nginx ] ; then
. /etc/nginx
fi
set -e
case "$1" in
start)
echo -n „Starten von $DESC: "
start-stop-daemon --start --quiet --pidfile /var/run/nginx.pid \
--exec $DAEMON -- $DAEMON_OPTS
echo „$NAME."
;;
stop)
echo -n „Stoppen von $DESC: "
start-stop-daemon --stop --quiet --pidfile /var/run/nginx.pid \
--exec $DAEMON
echo „$NAME."
;;
restart|force-reload)
echo -n „Neustarten von $DESC: "
start-stop-daemon --stop --quiet --pidfile \
/var/run/nginx.pid --exec $DAEMON
sleep 1 start-stop-daemon --start --quiet --pidfile \
/var/run/nginx.pid --exec $DAEMON -- $DAEMON_OPTS
echo „$NAME."
;;
reload)
echo -n „Neuladen der $DESC-Konfiguration: "
start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/nginx.pid \
--exec $DAEMON
echo „$NAME."
;;
*)
N=/etc/init.d/$NAME
echo „Verwendung: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
EOF
systemctl daemon-reload
NGINX-Dienstdatei erstellen
cat > /lib/systemd/system/nginx.service <<\EOF
[Unit]
Description=Ein leistungsstarker Webserver und ein Reverse-Proxy-Server
Documentation=man:nginx(8)
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
Geo IP-Länderdatenbank herunterladen
mkdir /etc/geo_ip
wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
gzip -d GeoLite2-Country.mmdb.gz
mv GeoLite2-Country.mmdb /etc/geo_ip/
NGINX aktivieren und starten
systemctl stop apache2
systemctl daemon-reload
systemctl enable nginx
systemctl start nginx
SSL-Zertifikat für Ihre Domain hinzufügen
Vergessen Sie nicht, cloudforums.net durch Ihre domain.com zu ersetzen.
mkdir /var/www
apt-get -y update
apt-get -y install letsencrypt
yes „n" | letsencrypt certonly --webroot --agree-tos -w /var/www -d cloudforums.net -m youremail@domain.com
Neue NGINX-Datei mit SSL-Regeln erstellen
Erstellen Sie eine neue NGINX-Datei mit dem SSL-Zertifikat, das Sie gerade heruntergeladen haben.
Hinweis: Ändern Sie cloudforums.net in Ihre Domain.
cat > /etc/nginx/nginx.conf <<\EOF
#user nobody;
worker_processes 1;
load_module modules/ngx_http_geoip2_module.so;
events {
worker_connections 1024;
}
http {
include mime.types;
include /etc/nginx/naxsi_core.rules;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
geoip2 /etc/geo_ip/GeoLite2-Country.mmdb {
$geoip2_data_country_code source=$remote_addr country iso_code;
$geoip2_data_country_name source=$remote_addr country names en;
}
log_format main_geo '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$geoip2_data_country_code $geoip2_data_country_name';
#***********************************************************
#Auskommentieren, um Geo-Blocking durchzuführen. Standardmäßig ist in den untenstehenden Einstellungen nur die USA aktiviert
#***********************************************************
#map $geoip2_data_country_code $allowed_country {
# default no;
# US yes;
# }
access_log /var/log/nginx/access.log main_geo;
default_type application/octet-stream;
error_log /var/log/nginx/error.log;
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name cloudforums.net;
root /;
location /.well-known/acme-challenge/ {
root /var/www;
}
location / {
return 301 https://$server_name$request_uri;
include /etc/nginx/naxsi.rules;
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 443 ssl; listen [::]:443 ssl;
server_name cloudforums.net;
ssl on;
ssl_certificate /etc/letsencrypt/live/cloudforums.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloudforums.net/privkey.pem;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security „max-age=63072000;";
ssl_stapling on;
ssl_stapling_verify on;
client_max_body_size 0;
location / {
proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
}
}
# HTTPS-Server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
EOF
NGINX neu starten
systemctl restart nginx
Sie haben jetzt eine großartige Open-Source-WAF!! ![]()
Schamlose Werbung
Vergessen Sie nicht, uns bei cloudforums.net beizutreten, wenn Ihnen dieser Leitfaden gefallen hat. Wir würden uns sehr freuen, Sie hier zu haben. Wir verkaufen nichts und haben keine Werbung. Wir suchen nur nach guten IT-Beiträgen ![]()
