I am having issues with suricata and httpd as a reverse proxy, i’ve noticed that it does not seem to alert anything to my supprise so I start searching and came on a feature that’s called xff.
I have tried to implement this but I am not sure what I am doing wrong.
this is the nftables rules (i’ve cleaned up other rules for illustration):
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iifname "lo" queue to 0
tcp dport { 80, 443 } queue to 0
}
I’ve also tried to put it in the prerouting with priority -100, but that does not seem to change anything.
An example of the vhost file I am using:
<VirtualHost *:80>
ServerName example.com
ServerSignature Off
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [NE,R,L]
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerSignature Off
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / http://172.16.1.248/
ProxyPassReverse / http://172.16.1.248/
Header always set X-Forwarded-Proto https
Header always append X-Forwarded-For %{REMOTE_ADDR}s
RemoteIPHeader X-Forwarded-For
ErrorLog /var/log/httpd/example.com-error.log
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b" combined
CustomLog /var/log/httpd/example.com-access.log combined
</VirtualHost>
I have tried multiple things with header, X-Forwarded-For, … as you can see
I’ve also changed settings in suricata.yaml for xff on 2 places, like extra-data, overwrite, …
The above is from a vhost file on the reverse proxy itself where suricata is running, the actual server also has multiple vhost files.
I’m using a combination of nftables (with NFQUEUE) and Suricata. Initially, I encountered issues where Suricata wasn’t detecting my HTTP/HTTPS traffic.
It turned out the solution was quite simple, I discovered that the way the ruleset is configured is crucial for ensuring proper traffic inspection.
My current working configuration:
include "/etc/nftables/variables.conf"
table ip filter {
set blocked_countries {
type ipv4_addr
flags interval
}
chain prerouting {
type nat hook prerouting priority -100; policy accept;
iifname $WAN tcp dport 18443 dnat to $QBITTORRENT:18443
iifname $WAN tcp dport 8888 dnat to $MYSQL:3306
ip saddr $BRABEN-OVPN-USER2 ip daddr $MYSQL tcp dport 8888 dnat to $MYSQL:3306
queue num 0 bypass
}
chain input {
type filter hook input priority 0; policy drop;
tcp dport { 80, 443 } queue num 0 bypass
tcp sport { 80, 443 } queue num 0 bypass
ct state established,related accept
iifname "lo" queue num 0
ip saddr @blocked_countries drop
ip saddr $LAN-SUBNET tcp dport 53 accept
ip saddr $LAN-SUBNET udp dport 53 accept
ip saddr $VPN-SUBNET tcp dport 53 accept
ip saddr $VPN-SUBNET udp dport 53 accept
ip saddr $COMPANY-WAN tcp dport 22 accept
ip saddr $BRABEN-OVPN-USER1 tcp dport 22 accept
iifname $LAN tcp dport 22 accept
iifname $LAN udp dport 68 accept
iifname $LAN udp sport 67 udp dport 68 accept
udp dport 1194 accept
}
chain forward {
type filter hook forward priority 10; policy drop;
ip saddr @blocked_countries drop
ip daddr @blocked_countries drop
# queue everything to Suricata
queue num 0 bypass
}
chain postrouting {
type nat hook postrouting priority 0; policy accept;
oifname $WAN ct state established,related,new masquerade
}
chain output {
type filter hook output priority 0; policy accept;
ip daddr @blocked_countries drop
# ip protocol tcp queue num 0 bypass
tcp dport {80, 443} queue num 0 bypass
tcp sport {80, 443} queue num 0 bypass
}
}
I believe this configuration has potential for improvement, but I’m still in the process of testing and learning.
Currently, the issue is resolved, as Suricata is now successfully detecting traffic to and from the reverse proxy.
If I understand correctly, when someone connects to my WAN IP or via an FQDN defined in a virtual host file, the TLS handshake is managed by the reverse proxy. After that, the traffic is sent unencrypted to the backend web server within the same network. My plan is to enable encryption for this internal traffic by generating certificates and configuring TLS between the reverse proxy and the backend servers.