I am trying to set up iptables to allow SSH port only from outside and all traffic from inside. Also, I'm trying to set some rules to prevent some basic DOS attacks. How do I manage the iptables rules properly?
I installed a Debian VM on VirtualBox where I set up a local static ip such as 10.0.2.3/30. I changed the SSH default port from 22 to 2222. I can connect to SSH from outside after setting up port forwarding on VirtualBox using NAT with 127.0.0.1 port 2222 on Host and 10.0.2.3 port 2222 on Client. So far so good.
Now I tried to set up firewall and DOS protection with iptables using the help of this guide such as I wrote the following script also using the kernel settings as described in the article.
sudo iptables -P INPUT DROP
### 1: Drop invalid packets ###
#sudo iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP
### 2: Drop TCP packets that are new and are not SYN ###
#sudo iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
### 3: Drop SYN packets with suspicious MSS value ###
sudo iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
### 4: Block packets with bogus TCP flags ###
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
sudo iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
### 6: Drop ICMP (you usually don't need this protocol) ###
sudo iptables -t mangle -A PREROUTING -p icmp -j DROP
### 7: Drop fragments in all chains ###
sudo iptables -t mangle -A PREROUTING -f -j DROP
### 8: Limit connections per source IP ###
sudo iptables -A INPUT -p tcp -m connlimit --connlimit-above 111 -j REJECT --reject-with tcp-reset
### 9: Limit RST packets ###
sudo iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT
sudo iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP
### 10: Limit new TCP connections per second per source IP ###
sudo iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT
sudo iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP
### 11: Use SYNPROXY on port 2222 (SSH) (disables connection limiting rule) ###
#sudo iptables -t raw -A PREROUTING -p tcp --dport 2222 -m tcp --syn -j CT --notrack
#sudo iptables -A INPUT -p tcp --dport 2222 -m tcp -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
sudo iptables -A INPUT -p tcp --dport 2222 -m conntrack --ctstate INVALID -j DROP
### SSH brute-force protection ###
sudo iptables -A INPUT -p tcp --dport 2222 -m conntrack --ctstate NEW -m recent --set
sudo iptables -A INPUT -p tcp --dport 2222 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP
### Protection against port scanning ###
sudo iptables -N port-scanning
sudo iptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN
sudo iptables -A port-scanning -j DROP
echo "Allowing traffic from SSH port 2222 and Internet traffic
# Allowing SSH connection from LAN
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
# Allowing Internet traffic
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
### Make the iptables rules persistent after reboot
sudo bash -c "iptables-save > /etc/iptables/rules.v4"
I identified these lines to have an impact on SSH connection from my LAN:
### 1: Drop invalid packets ###
#sudo iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP
I cannot connect to SSH when I uncomment these, and I don't understand why.
I figured out that my #1 rule was simply invalid #11 rule. I either had to use one or the other.