Page 1 of 1

SYNPROXY with CSF

Posted: 11 Dec 2018, 12:18
by gnusys
I am trying to implement SYNPROXY for the http/https ports with csfpre.sh

Code: Select all

iptables -t raw -I PREROUTING -p tcp -m tcp --syn --dport 80 -j CT --notrack
iptables -t raw -I PREROUTING -p tcp -m tcp --syn --dport 443 -j CT --notrack
iptables -t filter -I INPUT -p tcp -m tcp --dport 80 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables -t filter -I INPUT -p tcp -m tcp --dport 443 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables -t filter -A INPUT -p tcp -m tcp --dport 80 -m state --state INVALID -j DROP
iptables -t filter -A INPUT -p tcp -m tcp --dport 443 -m state --state INVALID -j DROP
is what I have added in the pre script .

Above works with LF_SPI = "0" , but the ports are closed when LF_SPI = "1"

The difference I see when LF_SPI = 1 is the iptables rule

Code: Select all

target     prot  opt  source                destination
INVALID    tcp  --  anywhere             anywhere
this somehow blocks the traffic.

Is there a way around to have stateful packet inspection and SYNPROXY together?

Re: SYNPROXY with CSF

Posted: 04 Nov 2019, 12:38
by MarcinKabiesz
Hello,
note that CSF uses the default DROP policy on INPUT and OUTPUT chains. For proper synrpoxy to work with CSF use the following lines:

/etc/csf/csfpost.sh: (HTTP 80 and HTTPs 443)

Code: Select all

iptables -t raw -A PREROUTING -i eth0 -p tcp --dport 80 --syn -j NOTRACK
iptables -t raw -A PREROUTING -i eth0 -p tcp --dport 443 --syn -j NOTRACK
iptables -t filter -I INPUT -i eth0 -p tcp -m tcp -m conntrack --ctstate INVALID, UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables -t filter -I OUTPUT -o eth0 -p tcp --sport 443 -m conntrack --ctstate INVALID, UNTRACKED -m tcp --tcp-flags SYN, RST, ACK SYN, ACK -j ACCEPT
iptables -t filter -I OUTPUT -o eth0 -p tcp --sport 80 -m conntrack --ctstate INVALID, UNTRACKED -m tcp --tcp-flags SYN, RST, ACK SYN, ACK -j ACCEPT
Firewall Restart
Done !! IT WORKS !!

Best Regards

Re: SYNPROXY with CSF

Posted: 06 May 2020, 01:04
by BobbyWibowo
MarcinKabiesz wrote: 04 Nov 2019, 12:38 Hello,
note that CSF uses the default DROP policy on INPUT and OUTPUT chains. For proper synrpoxy to work with CSF use the following lines:
<omitted>
Firewall Restart
Done !! IT WORKS !!

Best Regards
Unfortunately, those didn't work on my end. Among other things, they appeared to have invalid syntaxes. For example:

Code: Select all

--ctstate INVALID, UNTRACKED
needs to be

Code: Select all

--ctstate INVALID,UNTRACKED
Same thing with the line below that has spaces where they shouldn't:

Code: Select all

--tcp-flags SYN, RST, ACK SYN, ACK
Even after having fixed all that however, they appeared to be mistakenly ignoring >75% of real proper connections.
And some of those proper connections might end up falling apart soon later as well.
Unfortunately, I'm not an expert on iptables either, so I've got zero idea of what's wrong with those rules.

Re: SYNPROXY with CSF

Posted: 06 May 2020, 04:14
by BobbyWibowo
WARNING: I think these solutions are specific to RedHat/CentOS 7.
In the end these are all what I end up with:

These needs to be put in /etc/csf/csfpre.sh (create if not exist):

Code: Select all

#!/bin/bash

## Mitigating TCP flood attacks
## https://www.redhat.com/en/blog/mitigate-tcp-syn-flood-attacks-red-hat-enterprise-linux-7-beta

iptables -A INPUT -m state --state INVALID -j DROP

## Mitigating SYN flood attacks
## https://github.com/netoptimizer/network-testing/blob/master/iptables/iptables_synproxy.sh#L103

# Port 80 (HTTP)
iptables -t raw -I PREROUTING -i eth0 -p tcp -m tcp --syn --dport 80 -j CT --notrack
iptables -A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables -A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state INVALID -j DROP

# Port 433 (HTTPS)
iptables -t raw -I PREROUTING -i eth0 -p tcp -m tcp --syn --dport 433 -j CT --notrack
iptables -A INPUT -i eth0 -p tcp -m tcp --dport 433 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables -A INPUT -i eth0 -p tcp -m tcp --dport 433 -m state --state INVALID -j DROP

## Protection against port scanning
## https://javapipe.com/blog/iptables-ddos-protection/#bonus-rules

iptables -N port-scanning
iptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN
iptables -A port-scanning -j DROP
If you only need SYN flood attacks mitigation, it's fine to leave out the others. They're all independent from each other.

WARNING: The steps below may be the bits that are actually specific to RedHat/CentOS 7.
However, it's necessary to run the following commands before reloading csf with those new changes:

Code: Select all

# More strict conntrack handling to get unknown ACKs (from 3WHS) to be marked as INVALID state (else a conntrack is just created)
/sbin/sysctl -w net/netfilter/nf_conntrack_tcp_loose=0

# Enable timestamping, because SYN cookies uses TCP options field
/sbin/sysctl -w net/ipv4/tcp_timestamps=1

# Adjusting maximum number of connection tracking entries possible (288 * 2000000 / 10^6 = 576.0 MB)
/sbin/sysctl -w net/netfilter/nf_conntrack_max=2000000

# IMPORTANT: Also adjust hash bucket size for conntracks (8 * 2000000 / 10^6 = 16 MB)
sh -c 'echo 2000000 > /sys/module/nf_conntrack/parameters/hashsize'
Consider noting down their original values.

The size mentioned in the 3rd command is simply a theoretical max memory usage assuming all 2M entries are populated.
It will NOT actually pre-allocate them as a whole, but feel free to adjust them according to your needs.

I'm not sure about the 4th command, but it appears to be necessary to increase it regardless.
The article I link below suggests just 1M, but the GitHub repo suggests 2M.

Source:
https://www.redhat.com/en/blog/mitigate ... nux-7-beta

Additional reference:
https://javapipe.com/blog/iptables-ddos ... onus-rules
note: Using SYNPROXY rules from the reference above as-is, did NOT work for me on CentOS 7.
I'm guessing the 4 commands above were required to get it working with theirs as well.