Difference between revisions of "Firewall basics"

(Created page with "Category:Linux =Set IP preference= If you enable IPv6 then that will be the default. You can override that and '''set IPv4 as the default protocol''': <syntaxhighli...")
 
(FTP client)
 
(21 intermediate revisions by the same user not shown)
Line 6: Line 6:
  
 
If you enable IPv6 then that will be the default.
 
If you enable IPv6 then that will be the default.
 +
 +
 +
[[File:Ipv6logo.jpg|64px|caption|IPv6]]
 +
'''Recommended solution''' : IPv6 is now available in a lot of places. It's time to use it!
 +
 +
 +
[[File:Ipv4.jpg|64px|caption|IPv4 only]]
 +
If you don't want to use IPv6 you can force IPv4 mode. This is not recommended any-more! IPv6 is becoming bigger and bigger, you need to switch.
  
  
Line 25: Line 33:
  
  
 +
=Global networking configuration=
  
=Enable modules=
+
==Enable modules==
  
 
First things first! Before writing any rule you have to enable the required modules in your current O.S.
 
First things first! Before writing any rule you have to enable the required modules in your current O.S.
Line 38: Line 47:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
MODPROBE=`which modprobe`
 
MODPROBE=`which modprobe`
 
  
 
echo -e " "
 
echo -e " "
Line 45: Line 53:
 
echo -e "-----------------------------"
 
echo -e "-----------------------------"
  
# IPv4
+
##### IPv4
echo " ... IPv4"
 
 
$MODPROBE ip_tables
 
$MODPROBE ip_tables
 
$MODPROBE iptable_filter
 
$MODPROBE iptable_filter
Line 52: Line 59:
 
# Allow to use state match
 
# Allow to use state match
 
$MODPROBE ip_conntrack
 
$MODPROBE ip_conntrack
 +
# Allow NAT
 +
$MODPROBE iptable_nat
  
# IPv6
+
##### IPv6
echo " ... IPv6"
 
 
$MODPROBE ip6_tables
 
$MODPROBE ip6_tables
 
$MODPROBE ip6table_filter
 
$MODPROBE ip6table_filter
 
$MODPROBE ip6table_mangle
 
$MODPROBE ip6table_mangle
  
# Allow NAT
+
##### Allow active / passive FTP
echo " ... NAT"
 
$MODPROBE iptable_nat
 
 
 
# Allow active / passive FTP
 
echo " ... FTP"
 
 
$MODPROBE ip_conntrack_ftp
 
$MODPROBE ip_conntrack_ftp
 
$MODPROBE ip_nat_ftp
 
$MODPROBE ip_nat_ftp
  
# Allow log limits
+
##### Allow log limits
 
echo " ... burst limit"
 
echo " ... burst limit"
 
$MODPROBE ipt_limit
 
$MODPROBE ipt_limit
Line 76: Line 79:
  
  
=Network features=
+
==Set network features==
  
Now that you've enable some modules, you need to choose which Network's features you're gonna use or not.  
+
Now that you've enable some modules, you need to choose which network features you're gonna use or not.  
  
  
Line 106: Line 109:
 
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
 
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
 
echo 0 > /proc/sys/net/ipv6/conf/all/accept_source_route
 
echo 0 > /proc/sys/net/ipv6/conf/all/accept_source_route
 
 
## Check TCP window  
 
## Check TCP window  
 
echo 1 > /proc/sys/net/ipv4/tcp_window_scaling
 
echo 1 > /proc/sys/net/ipv4/tcp_window_scaling
Line 116: Line 118:
  
  
# Port forwarding in general
+
# Enable port forwarding in general
echo " ... Enable forwarding"
+
# (i) Some might argue that it should only be done by routers...  
 +
#    Since I'm using a VPN, I like to access both networks and exchange data between them.
 +
#    That's why port forwarding is enable.
 
echo 1 > /proc/sys/net/ipv4/ip_forward
 
echo 1 > /proc/sys/net/ipv4/ip_forward
 +
 +
echo 2 > /proc/sys/net/ipv6/conf/all/use_tempaddr
 +
echo 2 > /proc/sys/net/ipv6/conf/default/use_tempaddr
 +
echo 2 > /proc/sys/net/ipv6/conf/eth0/use_tempaddr
 
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
 
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
 
+
echo 0 > /proc/sys/net/ipv6/conf/default/forwarding
 +
echo 0 > /proc/sys/net/ipv6/conf/eth0/forwarding
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 143: Line 152:
  
  
==Linux script==
+
==Set default policies==
  
 
This is how you defined a default policy.
 
This is how you defined a default policy.
  
 +
[[File:Best-pratice-icon.png|64px|caption|Best practice]] '''Recommendations''' :
 +
* You should set all policies in ''ACCEPT'' ; and ''DROP'' the packets at the end of your firewall. By doing so you'll probably not be locked away from your server in case of firewall change. 
 +
* You should keep the ''RELATED'' and ''ESTABLISHED'' connections
  
Note:
 
* You have to adjust the policy to your own settings
 
* You should NOT set the INPUT in ACCEPT mode. That's risky!
 
  
  
Line 163: Line 172:
 
echo -e "------------------------"
 
echo -e "------------------------"
  
 +
# Delete GENERIC rules
 
$IP6TABLES -F
 
$IP6TABLES -F
 +
$IP6TABLES -X
 +
$IPTABLES -F
 +
$IPTABLES -X
  
 +
# delete FILTER rule (in/out)
 
$IPTABLES -t filter -F
 
$IPTABLES -t filter -F
 
$IPTABLES -t filter -X
 
$IPTABLES -t filter -X
 +
$IP6TABLES -t filter -F
 +
$IP6TABLES -t filter -X
 +
 +
# delete MANGLE rules (packets modifications)
 +
$IPTABLES -t mangle -F
 +
$IPTABLES -t mangle -X
 +
$IP6TABLES -t mangle -F
 +
$IP6TABLES -t mangle -X
  
# delete NAT rules
+
# delete NAT rules [IPv4 only]
 
$IPTABLES -t nat -F
 
$IPTABLES -t nat -F
 
$IPTABLES -t nat -X
 
$IPTABLES -t nat -X
  
# delete MANGLE rules (packets modifications)
 
$IPTABLES -t mangle -F
 
$IPTABLES -t mangle -X
 
  
 
echo -e " "
 
echo -e " "
Line 180: Line 199:
 
echo -e " Default policy"
 
echo -e " Default policy"
 
echo -e "------------------------"
 
echo -e "------------------------"
echo -e "             || --> OUTGOING    reject all "
+
$IPTABLES -P INPUT ACCEPT
echo -e "         --> ||    INCOMING    reject all "
+
$IPTABLES -P FORWARD ACCEPT
echo -e "         --> || --> FORWARDING reject all (each redirection manual needs configuration)"
+
$IPTABLES -P OUTPUT ACCEPT
 +
 
 +
$IP6TABLES -P INPUT ACCEPT
 +
$IP6TABLES -P FORWARD ACCEPT
 +
$IP6TABLES -P OUTPUT ACCEPT
 +
 
 +
 
 +
echo -e " "
 +
echo -e "------------------------"
 +
echo -e " Keep connections"
 +
echo -e "------------------------"
 +
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
 +
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
 +
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
 +
 
 +
$IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
 +
$IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
 +
$IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
 +
 
 +
 
 +
[...]
 +
 
 +
 
 +
# End of script (optional)
 +
$IPTABLES -A INPUT -j DROP
 +
$IP6TABLES -A INPUT -j DROP
 +
 
 +
$IPTABLES -A OUTPUT -j DROP
 +
$IP6TABLES -A OUTPUT -j DROP
 +
 
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
=Basic protection and protocol(s) enforcement=
 +
 
 +
 
 +
==Basic (minimal) protection==
 +
 
 +
You should put some minimal protection. This layer relies on your O.S and its internal checks. Most of the time that's enough to block malformed and suspicious packets.
 +
 
 +
 
 +
<syntaxhighlight lang="bash">
 +
IPTABLES=`which iptables`
 +
IP6TABLES=`which ip6tables`
 +
 
 +
 
 +
#####################
 +
### All protocols ###
 +
#####################
 +
# Reject invalid packets
 +
$IPTABLES -A INPUT -m state --state INVALID -m comment --comment "Invalid input" -j DROP
 +
$IPTABLES -A OUTPUT -m state --state INVALID -m comment --comment "Invalid input" -j DROP
 +
$IPTABLES -A FORWARD -m state --state INVALID -m comment --comment "Invalid forward" -j DROP
 +
 
 +
$IP6TABLES -A INPUT -m state --state INVALID -m comment --comment "Invalid input" -j DROP
 +
$IP6TABLES -A OUTPUT -m state --state INVALID -m comment --comment "Invalid input" -j DROP
 +
$IP6TABLES -A FORWARD -m state --state INVALID -m comment --comment "Invalid forward" -j DROP
 +
 
 +
# Ensure TCP connection requests start with SYN flag
 +
$IPTABLES -A INPUT -p tcp -m state --state NEW ! --syn -m comment --comment "Invalid conn request" -j DROP
 +
$IPTABLES -A OUTPUT -p tcp -m state --state NEW ! --syn -m comment --comment "Invalid conn request" -j DROP
 +
 
 +
$IP6TABLES -A INPUT -p tcp -m state --state NEW ! --syn -m comment --comment "Invalid conn request" -j DROP
 +
$IP6TABLES -A OUTPUT -p tcp -m state --state NEW ! --syn -m comment --comment "Invalid conn request" -j DROP
 +
 
 +
 
 +
############
 +
### IPv4 ###
 +
############
 +
## Localhost
 +
$IPTABLES -A INPUT ! -i lo -s 127.0.0.0/24 -m comment --comment "Reject none loopback on 'lo'" -j DROP  
 +
$IPTABLES -A OUTPUT ! -o lo -d 127.0.0.0/24 -m comment --comment "Reject none loopback on 'lo'" -j DROP
 +
# Accept all local packets
 +
$IPTABLES -A INPUT -i lo -m comment --comment "Accept localhost packets" -j ACCEPT
 +
$IPTABLES -A OUTPUT -o lo -m comment --comment "Accept localhost packets" -j ACCEPT
 +
 
 +
 
 +
############
 +
### IPv6 ###
 +
############
 +
# Allow localhost traffic. These rules are for all protocols.
 +
$IP6TABLES -A INPUT -s ::1 -d ::1 -j ACCEPT
 +
$IP6TABLES -A INPUT ! -i lo -s ::1 -m comment --comment "Reject none loopback on 'lo'" -j DROP
 +
$IP6TABLES -A OUTPUT ! -o lo -d ::1 -m comment --comment "Reject none loopback on 'lo'" -j DROP
 +
 
 +
# Allow Link-Local addresses
 +
$IP6TABLES -A INPUT -s fe80::/10 -j ACCEPT
 +
$IP6TABLES -A OUTPUT -s fe80::/10 -j ACCEPT
  
# INCOMING = avoid intrusions
+
# Normally, link-local packets should NOT be forwarded and don't need an entry in the FORWARD rule.
# OUTGOING = avoid disclosure of sensitive / private data
+
# However, when bridging in Linux (e.g. in Xen or OpenWRT), the FORWARD rule is needed:
$IPTABLES -P INPUT DROP
+
$IP6TABLES -A FORWARD -s fe80::/10 -j ACCEPT
$IPTABLES -P FORWARD DROP
 
$IPTABLES -P OUTPUT DROP
 
  
$IP6TABLES -P INPUT DROP
+
#################
$IP6TABLES -P FORWARD DROP
+
### Multicast ###
$IP6TABLES -P OUTPUT DROP
+
#################
 +
$IPTABLES -A INPUT -m comment --comment "Multicast auto-configuration"  -d 224.0.0.0/24 -j ACCEPT
 +
$IPTABLES -A OUTPUT -m comment --comment "Multicast request"  -d 224.0.0.0/24 -j ACCEPT
  
echo -e " ... Reject invalid packets"
+
$IP6TABLES -A INPUT -d ff00::/8 -j ACCEPT
$IPTABLES -A INPUT -p tcp -m state --state INVALID -j DROP
+
$IP6TABLES -A INPUT -s ff00::/8 -j ACCEPT
$IPTABLES -A INPUT -p udp -m state --state INVALID -j DROP
+
$IP6TABLES -A OUTPUT -d ff00::/8 -j ACCEPT
$IPTABLES -A INPUT -p icmp -m state --state INVALID -j DROP
+
$IP6TABLES -A OUTPUT -s ff00::/8 -j ACCEPT
$IPTABLES -A OUTPUT -p tcp -m state --state INVALID -j DROP
 
$IPTABLES -A OUTPUT -p udp -m state --state INVALID -j DROP
 
$IPTABLES -A OUTPUT -p icmp -m state --state INVALID -j DROP
 
$IPTABLES -A FORWARD -p tcp -m state --state INVALID -j DROP
 
$IPTABLES -A FORWARD -p udp -m state --state INVALID -j DROP
 
  
$IP6TABLES -A INPUT -p tcp -m state --state INVALID -j DROP
+
</syntaxhighlight>
$IP6TABLES -A INPUT -p udp -m state --state INVALID -j DROP
 
$IP6TABLES -A INPUT -p icmp -m state --state INVALID -j DROP
 
$IP6TABLES -A OUTPUT -p tcp -m state --state INVALID -j DROP
 
$IP6TABLES -A OUTPUT -p udp -m state --state INVALID -j DROP
 
$IP6TABLES -A OUTPUT -p icmp -m state --state INVALID -j DROP
 
$IP6TABLES -A FORWARD -p tcp -m state --state INVALID -j DROP
 
$IP6TABLES -A FORWARD -p udp -m state --state INVALID -j DROP
 
  
  
echo " ... Avoid spoofing and local subnets"
+
==Block IPv4 in IPv6 tunnels==
# Reserved addresses. We shouldn't received any packets from them!
 
### TODO #### Adjust these values
 
$IPTABLES -A INPUT -s 10.0.0.0/8 -j DROP
 
#$IPTABLES -A INPUT -s 172.16.0.0/12 -j DROP
 
#$IPTABLES -A INPUT -s 192.168.0.0/16 -j DROP
 
$IPTABLES -A INPUT -s 169.254.0.0/16 -j DROP
 
 
  
# Only localhost on Loopback interface + no forward
+
If your ISP delivers you a native IPv6 connection then you don't need to use IPv4 tunneling! Just use either IPv4 or IPv6 native mode.  
$IPTABLES -A INPUT ! -i lo -s 127.0.0.0/24 -j DROP
+
 
$IPTABLES -A FORWARD -s 127.0.0.0/24 -j DROP
+
 
$IP6TABLES -A INPUT ! -i lo -s ::1/128 -j DROP
+
<syntaxhighlight lang="bash">
$IP6TABLES -A FORWARD -s ::1/128 -j DROP
+
IPTABLES=`which iptables`
 +
IP6TABLES=`which ip6tables`
  
  
 
## IPv6 security
 
## IPv6 security
 
# No IPv4 -> IPv6 tunneling
 
# No IPv4 -> IPv6 tunneling
echo " ... Do not allow IPv4 @ tunnel in IPv6 !! Use native IPv6 instead !!"
+
$IP6TABLES -A INPUT -s 2002::/16 -m comment --comment "Reject 6to4 tunnels" -j DROP
$IP6TABLES -A INPUT -s 2002::/16 -j DROP # 6to4 tunnels
+
$IP6TABLES -A FORWARD -s 2002::/16 -m comment --comment "Reject 6to4 tunnels" -j DROP
$IP6TABLES -A FORWARD -s 2002::/16 -j DROP
+
$IP6TABLES -A INPUT -s 2001:0::/32 -m comment --comment "Reject Teredo tunnels" -j DROP
$IP6TABLES -A INPUT -s 2001:0::/32 -j DROP # Teredo tunnels
+
$IP6TABLES -A FORWARD -s 2001:0::/32 -m comment --comment "Reject Teredo tunnels" -j DROP
$IP6TABLES -A FORWARD -s 2001:0::/32 -j DROP
+
   
 
 
# Block IPv6 protocol in IPv4 frames
 
# Block IPv6 protocol in IPv4 frames
echo " ... Block IPv6 protocol in IPv4 frames"
+
$IPTABLES -A INPUT -p 41 -m comment --comment "Block IPv6 protocol in IPv4 frames" -j DROP
$IPTABLES -A INPUT -p 41 -j DROP
+
$IPTABLES -A OUTPUT -p 41 -m comment --comment "Block IPv6 protocol in IPv4 frames" -j DROP
$IPTABLES -A OUTPUT -p 41 -j DROP
+
$IPTABLES -A FORWARD -p 41 -m comment --comment "Block IPv6 protocol in IPv4 frames" -j DROP
$IPTABLES -A FORWARD -p 41 -j DROP
 
  
 +
</syntaxhighlight>
  
## Stateful connections
 
echo -e " ... Keep ESTABLISHED connections "
 
$IPTABLES -A INPUT -m state --state ESTABLISHED -j ACCEPT
 
$IPTABLES -A FORWARD -m state --state ESTABLISHED -j ACCEPT
 
$IPTABLES -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
 
 
$IP6TABLES -A INPUT -m state --state ESTABLISHED -j ACCEPT
 
$IP6TABLES -A FORWARD -m state --state ESTABLISHED -j ACCEPT
 
$IP6TABLES -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
 
 
 
echo -e " ... Keep RELATED connections (required for FTP)"
 
$IPTABLES -A INPUT -m state --state RELATED -j ACCEPT
 
$IPTABLES -A FORWARD -m state --state RELATED -j ACCEPT
 
$IPTABLES -A OUTPUT -m state --state RELATED -j ACCEPT
 
 
$IP6TABLES -A INPUT -m state --state RELATED -j ACCEPT
 
$IP6TABLES -A FORWARD -m state --state RELATED -j ACCEPT
 
$IP6TABLES -A OUTPUT -m state --state RELATED -j ACCEPT
 
  
 +
==Block IPv6 routing headers==
  
 +
<syntaxhighlight lang="bash">
 +
# Filter all packets that have RH0 headers:
 +
$IP6TABLES -A INPUT -m rt --rt-type 0 -j DROP
 +
$IP6TABLES -A FORWARD -m rt --rt-type 0 -j DROP
 +
$IP6TABLES -A OUTPUT -m rt --rt-type 0 -j DROP
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
 +
==Protocol(s) enforcement==
  
=Protocol(s) enforcement=
+
You can even push the standard protection a bit higher by checking some protocols flags.
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Line 281: Line 357:
 
echo -e " Protocols enforcement"
 
echo -e " Protocols enforcement"
 
echo -e "------------------------"
 
echo -e "------------------------"
echo -e " ... Layer 2: ICMP v4"
+
 
 +
####### IPv4 #######
 +
echo " ... Layer 2: ICMP v4"
 
# ICMP packets should not be fragmented
 
# ICMP packets should not be fragmented
$IPTABLES -A INPUT --fragment -p icmp -j DROP
+
$IPTABLES -A INPUT --fragment -p icmp -m comment --comment "no ICMP fragments" -j DROP  
 
+
# SMURF attack protection
 +
$IPTABLES -A INPUT -p icmp -m icmp --icmp-type address-mask-request -m comment --comment "address-mask-request" -j DROP
 +
$IPTABLES -A INPUT -p icmp -m icmp --icmp-type timestamp-request -m comment --comment "timestamp-request" -j DROP
 
# Limit ICMP Flood
 
# Limit ICMP Flood
$IPTABLES -A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j ACCEPT
+
$IPTABLES -A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -m comment --comment "ICMP flood protection" -j ACCEPT  
$IPTABLES -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT
+
$IPTABLES -A OUTPUT -p icmp --icmp-type 0 -m comment --comment "echo reply" -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type 3 -j ACCEPT
+
$IPTABLES -A OUTPUT -p icmp --icmp-type 3 -m comment --comment "destination unreachable" -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT
+
$IPTABLES -A OUTPUT -p icmp --icmp-type 8 -m comment --comment "echo request" -j ACCEPT   
 
# Avoid common attacks ... but blocks ping :(
 
# [Network, Host, Protocol, Port] unreacheable + [Destination Host, Destination network] prohibited
 
#$IPTABLES -A OUTPUT -p icmp --icmp-type 3 -j DROP
 
  
  
echo -e " ... Layer 2: ICMP v6 "
+
####### IPv6 #######
# Feedback for problems
+
echo " ... Layer 2: ICMP v6 "
$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type 1 -j ACCEPT
+
# Don't DROP ICMP6 a lot of things are happening over there! It might completly block the connection if you DROP icmp6
$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type 2 -j ACCEPT
+
$IP6TABLES -A INPUT -j ACCEPT
$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type 3 -j ACCEPT
+
$IP6TABLES -A OUTPUT -p icmpv6 -j ACCEPT
$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type 4 -j ACCEPT
+
$IP6TABLES -A FORWARD -p icmpv6 -j ACCEPT
 
# Router and neighbor discovery
 
$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type 133 -j ACCEPT
 
$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type 134 -j ACCEPT
 
$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type 135 -j ACCEPT
 
$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type 136 -j ACCEPT
 
  
$IP6TABLES -A OUTPUT -p icmpv6 --icmpv6-type 133 -j ACCEPT
 
$IP6TABLES -A OUTPUT -p icmpv6 --icmpv6-type 134 -j ACCEPT
 
$IP6TABLES -A OUTPUT -p icmpv6 --icmpv6-type 135 -j ACCEPT
 
$IP6TABLES -A OUTPUT -p icmpv6 --icmpv6-type 136 -j ACCEPT
 
 
# Ping requests
 
$IP6TABLES -A INPUT -p icmpv6 --icmpv6-type 128 -j ACCEPT
 
$IP6TABLES -A OUTPUT -p icmpv6 --icmpv6-type 128 -j ACCEPT
 
  
+
####### TCP IPv4 #######
 
echo " ... Layer 4: TCP # check packets conformity"
 
echo " ... Layer 4: TCP # check packets conformity"
 
# INCOMING packets check
 
# INCOMING packets check
 
# All new incoming TCP should be SYN first
 
# All new incoming TCP should be SYN first
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
+
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -m comment --comment "new TCP connection check" -j DROP
 
# Avoid SYN Flood (max 3 SYN packets / second. Then Drop all requests !!)
 
# Avoid SYN Flood (max 3 SYN packets / second. Then Drop all requests !!)
$IPTABLES -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
+
$IPTABLES -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -m comment --comment "avoid TCP SYN flood" -j ACCEPT
 
# Avoid fragment packets
 
# Avoid fragment packets
$IPTABLES -A INPUT -f -j DROP
+
$IPTABLES -A INPUT -f -m comment --comment "no fragments" -j DROP
 
# Check TCP flags -- flag 64, 128 = bogues
 
# Check TCP flags -- flag 64, 128 = bogues
$IPTABLES -A INPUT -p tcp --tcp-option 64 -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-option 64 -m comment --comment "ECE flag" -j DROP
$IPTABLES -A INPUT -p tcp --tcp-option 128 -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-option 128 -m comment --comment "CWR flag" -j DROP
 +
 
 +
 
 
echo " ... Layer 4: TCP # Avoid NMAP Scans"
 
echo " ... Layer 4: TCP # Avoid NMAP Scans"
 
# XMAS-NULL
 
# XMAS-NULL
$IPTABLES -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags ALL NONE -m comment --comment "attack XMAS-NULL" -j DROP
 
# XMAS-TREE
 
# XMAS-TREE
$IPTABLES -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags ALL ALL -m comment --comment "attack XMAS-tree" -j DROP
 +
# Stealth XMAS Scan
 +
$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -m comment --comment "attack XMAS stealth" -j DROP
 
# SYN/RST Scan
 
# SYN/RST Scan
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -m comment --comment "scan SYN/RST" -j DROP
 
# SYN/FIN Scan
 
# SYN/FIN Scan
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -m comment --comment "scan SYN/FIN" -j DROP
 
# SYN/ACK Scan
 
# SYN/ACK Scan
#$IPTABLES -A INPUT -p tcp --tcp-flags ALL ACK -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,ACK SYN,ACK -m comment --comment "scan SYN/ACK" -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,ACK SYN,ACK -j DROP
 
 
# FIN/RST Scan
 
# FIN/RST Scan
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -m comment --comment "scan FIN/RST" -j DROP
 
# FIN/ACK Scan
 
# FIN/ACK Scan
$IPTABLES -A INPUT -p tcp -m tcp --tcp-flags FIN,ACK FIN -j DROP
+
$IPTABLES -A INPUT -p tcp -m tcp --tcp-flags FIN,ACK FIN -m comment --comment "scan FIN/ACK" -j DROP
 
# ACK/URG Scan
 
# ACK/URG Scan
$IPTABLES -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags ACK,URG URG -m comment --comment "scan ACK/URG" -j DROP
 
# FIN/URG/PSH Scan
 
# FIN/URG/PSH Scan
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,URG,PSH FIN,URG,PSH -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,URG,PSH FIN,URG,PSH -m comment --comment "scan FIN/URG/PSH" -j DROP
# Stealth XMAS Scan
 
$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
 
 
# XMAS-PSH Scan
 
# XMAS-PSH Scan
$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -m comment --comment "scan XMAS/PSH" -j DROP
 
# End TCP connection
 
# End TCP connection
$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN -m comment --comment "end TCP connection flag" -j DROP
 
# Ports scans
 
# Ports scans
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m comment --comment "common scan FIN/SYN/RST/ACK SYN" -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
+
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -m comment --comment "common scan FIN/SYN/RST/ACK/PSH/URG NONE" -j DROP
  
 
</syntaxhighlight>
 
</syntaxhighlight>
Line 373: Line 436:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
IPTABLES=`which iptables`
 
IPTABLES=`which iptables`
 +
IP6TABLES=`which ip6tables`
  
  
 
# DHCP client >> Broadcast IP request  
 
# DHCP client >> Broadcast IP request  
$IPTABLES -A OUTPUT -p udp -d 255.255.255.255 --sport 68 --dport 67 -j ACCEPT
+
$IPTABLES -A INPUT -p udp --sport 67:68 --dport 67:68 -m comment --comment "DHCP" -j ACCEPT  
$IPTABLES -A INPUT -p udp -s 255.255.255.255 --sport 67 --dport 68 -j ACCEPT
+
$IPTABLES -A OUTPUT -p udp --sport 67:68 --dport 67:68 -m comment --comment "DHCP" -j ACCEPT  
$IPTABLES -A OUTPUT -p udp --dport 67 -j ACCEPT  
+
 
$IPTABLES -A OUTPUT -p udp --dport 68 -j ACCEPT  
+
$IP6TABLES -A INPUT -p udp --sport 67:68 --dport 67:68 -m comment --comment "DHCP" -j ACCEPT  
 +
$IP6TABLES -A OUTPUT -p udp --sport 67:68 --dport 67:68 -m comment --comment "DHCP" -j ACCEPT  
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 390: Line 455:
 
IPTABLES=`which iptables`
 
IPTABLES=`which iptables`
 
IP6TABLES=`which ip6tables`
 
IP6TABLES=`which ip6tables`
 +
 +
# DNS
 +
$IPTABLES -A INPUT -p udp --sport 53 -m comment --comment "DNS UDP sPort" -j ACCEPT
 +
$IPTABLES -A OUTPUT -p udp --sport 53 -m comment --comment "DNS UDP sPort" -j ACCEPT
 +
 +
$IPTABLES -A INPUT -p udp --dport 53 -m comment --comment "DNS UDP dPort" -j ACCEPT
 +
$IPTABLES -A OUTPUT -p udp --dport 53 -m comment --comment "DNS UDP dPort" -j ACCEPT
 +
 +
   
 +
$IP6TABLES -A INPUT -p udp --sport 53 -m comment --comment "DNS UDP sPort" -j ACCEPT
 +
$IP6TABLES -A OUTPUT -p udp --sport 53 -m comment --comment "DNS UDP sPort" -j ACCEPT
 +
 +
$IP6TABLES -A INPUT -p udp --dport 53 -m comment --comment "DNS UDP dPort" -j ACCEPT
 +
$IP6TABLES -A OUTPUT -p udp --dport 53 -m comment --comment "DNS UDP dPort" -j ACCEPT
  
  
$IPTABLES -A OUTPUT -p udp --dport 53 -m limit --limit 100/s -j ACCEPT
+
# DNS SEC
$IPTABLES -A OUTPUT -p udp --sport 53 -m limit --limit 100/s -j ACCEPT
+
# Established, related input are already accepted earlier
$IPTABLES -A INPUT -p udp --sport 53 -m limit --limit 100/s -j ACCEPT
+
$IPTABLES -A OUTPUT -p tcp --sport 53 -m comment --comment "DNS Sec TCP sPort" -j ACCEPT
$IPTABLES -A INPUT -p udp --dport 53 -m limit --limit 100/s -j ACCEPT
+
$IPTABLES -A OUTPUT -p tcp --dport 53 -m comment --comment "DNS Sec TCP dPort" -j ACCEPT
  
 +
$IP6TABLES -A OUTPUT -p tcp --sport 53 -m comment --comment "DNS Sec TCP sPort" -j ACCEPT
 +
$IP6TABLES -A OUTPUT -p tcp --dport 53 -m comment --comment "DNS Sec TCP dPort" -j ACCEPT
  
$IP6TABLES -A OUTPUT -p udp --dport 53 -m limit --limit 100/s -j ACCEPT
 
$IP6TABLES -A OUTPUT -p udp --sport 53 -m limit --limit 100/s -j ACCEPT
 
$IP6TABLES -A INPUT -p udp --dport 53 -m limit --limit 100/s -j ACCEPT
 
$IP6TABLES -A INPUT -p udp --sport 53 -m limit --limit 100/s -j ACCEPT
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
 +
<big>!! IMPORTANT !!! </big>
 +
 +
If you ever loose Internet access after that you need to check your <code>/etc/resolv.conf</code> configuration and make sure you're using a valid DNS server.
 +
  
  
Line 447: Line 530:
 
# NTP client
 
# NTP client
 
echo -e " ... Allow NTP time sync"
 
echo -e " ... Allow NTP time sync"
$IPTABLES -A OUTPUT -p udp --dport 123 -j ACCEPT
+
$IPTABLES -A INPUT -p udp --sport 123 -m state --state ESTABLISHED -m comment --comment "NTP (UDP)" -j ACCEPT
$IPTABLES -A INPUT -p udp --sport 123 -j ACCEPT
+
$IPTABLES -A INPUT -p tcp --sport 123 -m state --state ESTABLISHED -m comment --comment "NTP (TCP)" -j ACCEPT
 +
 
 +
$IPTABLES -A OUTPUT -p udp --dport 123 -m state --state NEW,ESTABLISHED -m comment --comment "NTP (UDP)" -j ACCEPT
 +
$IPTABLES -A OUTPUT -p tcp --dport 123 -m state --state NEW,ESTABLISHED -m comment --comment "NTP (TCP)" -j ACCEPT
  
$IP6TABLES -A OUTPUT -p udp --dport 123 -j ACCEPT
 
$IP6TABLES -A INPUT -p udp --sport 123 -j ACCEPT
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 459: Line 543:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
IPTABLES=`which iptables`
 
IPTABLES=`which iptables`
 
  
 
# SAMBA share
 
# SAMBA share
 
# Access filtering is done in /etc/samba/smb.conf
 
# Access filtering is done in /etc/samba/smb.conf
$IPTABLES -A INPUT -p udp --dport 137 -j ACCEPT                 # NetBios Name Service
+
$IPTABLES -A INPUT -p tcp --dport 135 -m comment --comment "DCE endpoint resolution" -j ACCEPT
$IPTABLES -A INPUT -p udp --dport 138 -j ACCEPT                # NetBios Data Exchange
+
$IPTABLES -A INPUT -p udp --dport 137 -m comment --comment "NetBIOS Name Service" -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 139 -j ACCEPT                 # NetBios Session + Samba
+
$IPTABLES -A INPUT -p udp --dport 138 -m comment --comment "NetBIOS Datagram" -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 445 -j ACCEPT                # CIFS - Partage Win2K and more
+
$IPTABLES -A INPUT -p tcp --dport 139 -m comment --comment "NetBIOS Session" -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 548 -j ACCEPT                 # Apple File Sharing Protocol
+
$IPTABLES -A INPUT -p tcp --dport 445 -m comment --comment "SMB over TCP" -j ACCEPT
</syntaxhighlight>
 
 
 
 
 
==FTP client==
 
 
 
<syntaxhighlight lang="bash">
 
IPTABLES=`which iptables`
 
 
 
 
 
# FTP client - base rules
 
$IPTABLES -A INPUT -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
 
$IPTABLES -A OUTPUT -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
 
  
# Active FTP
+
$IPTABLES -A OUTPUT -p tcp --sport 135 -m state --state ESTABLISHED -m comment --comment "DCE endpoint resolution" -j ACCEPT
$IPTABLES -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT
+
$IPTABLES -A OUTPUT -p udp --dport 137 -m comment --comment "NetBios Name Service" -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT
+
$IPTABLES -A OUTPUT -p udp --dport 138 -m comment --comment "NetBios Data Exchange" -j ACCEPT
 +
$IPTABLES -A OUTPUT -p tcp --dport 139 -m comment --comment "NetBios Session + Samba" -j ACCEPT
 +
$IPTABLES -A OUTPUT -p tcp --dport 445 -m comment --comment "CIFS - Partage Win2K and more" -j ACCEPT
 +
$IPTABLES -A OUTPUT -p tcp --dport 548 -m comment --comment "Apple file sharing" -j ACCEPT
  
# Passive FTP
 
$IPTABLES -A INPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT
 
$IPTABLES -A OUTPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
==VPN==
+
==FTP client==
 
 
Adjust the following to your own port, network ID and protocol:
 
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
IPTABLES=`which iptables`
 
IPTABLES=`which iptables`
  
INT_ETH=eth0
+
# FTP
IP_LAN_ETH=`/sbin/ifconfig $INT_ETH | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'`
+
# FTP INPUT (Client <--from-- Server)
 
+
$IPTABLES -A INPUT -p tcp --dport 21 -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "FTP command: allow FTP connections" -j ACCEPT
INT_VPN=tun0
+
$IPTABLES -A INPUT -p tcp --dport 20 -m conntrack --ctstate NEW,ESTABLISHED,RELATED -m comment --comment "FTP data (active)" -j ACCEPT
VPN_PORT="8080"
+
$IPTABLES -A INPUT -p tcp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "FTP data (passive)" -j ACCEPT
VPN_PROTOCOL="udp"
+
$IPTABLES -A INPUT -p tcp -m state --state ESTABLISHED -m comment --comment "FTP established connections" -j ACCEPT
LAN_ADDRESS_VPN="172.16.60.0/24"
 
 
 
echo -e " "
 
echo -e "------------------------"
 
echo -e " VPN configuration"
 
echo -e "------------------------"
 
 
 
echo " "
 
echo -e "# VPN interface  : $INT_VPN"
 
echo -e "# VPN IP @      : $LAN_ADDRESS_VPN"
 
echo -e "# VPN port      : $VPN_PORT"
 
echo -e "# VPN protocol  : $VPN_PROTOCOL"
 
echo -e "-------------------------------------- "
 
 
 
# Allow devices communication $ETH0 <--> tun0
 
$IPTABLES -t nat -A POSTROUTING -s $LAN_ADDRESS_VPN -o $INT_ETH -j MASQUERADE
 
$IPTABLES -A FORWARD -s $LAN_ADDRESS_VPN -j ACCEPT
 
 
 
echo -e " ... Allow VPN connections"
 
$IPTABLES -A INPUT -p $VPN_PROTOCOL --dport $VPN_PORT -j ACCEPT
 
$IPTABLES -A OUTPUT -p tcp --dport $VPN_PORT -j ACCEPT
 
 
 
echo -e " ... Allow everything to go through VPN - all INPUT,OUTPUT,FORWARD"
 
$IPTABLES -A INPUT -i $INT_VPN -m state ! --state INVALID -j ACCEPT
 
$IPTABLES -A OUTPUT -o $INT_VPN -m state ! --state INVALID -j ACCEPT
 
$IPTABLES -A FORWARD -o $INT_VPN -m state ! --state INVALID -j ACCEPT
 
  
echo -e " ... Allow VPN network communication (required for client <> client comm.)"
+
# FTP OUTPUT (Client --to--> Server)  
$IPTABLES -A INPUT -s $LAN_ADDRESS_VPN -d $LAN_ADDRESS_VPN -j ACCEPT
+
$IPTABLES -A OUTPUT -p tcp --dport 21 -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "FTP command: allow FTP connections" -j ACCEPT
$IPTABLES -A OUTPUT -s $LAN_ADDRESS_VPN -d $LAN_ADDRESS_VPN -j ACCEPT
+
$IPTABLES -A OUTPUT -p tcp --dport 20 -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "FTP data (active)" -j ACCEPT
 +
$IPTABLES -A OUTPUT -p tcp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate NEW,ESTABLISHED,RELATED -m comment --comment "FTP data (passive)" -j ACCEPT
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 18:33, 22 April 2017



Set IP preference

If you enable IPv6 then that will be the default.


IPv6 Recommended solution : IPv6 is now available in a lot of places. It's time to use it!


IPv4 only If you don't want to use IPv6 you can force IPv4 mode. This is not recommended any-more! IPv6 is becoming bigger and bigger, you need to switch.


You can override that and set IPv4 as the default protocol:

vim /etc/gai.conf


About line 54, un-comment the following line:

#
#    For sites which prefer IPv4 connections change the last line to
#
precedence ::ffff:0:0/96  100


Global networking configuration

Enable modules

First things first! Before writing any rule you have to enable the required modules in your current O.S.


- Note -

If your server is hosted over Internet then you're probably using a custom Kernel (such as OVH, Tripnet, ...). In that case most modules are already enabled.


MODPROBE=`which modprobe`

echo -e " "		
echo -e "-----------------------------"
echo -e " Enable networking modules"
echo -e "-----------------------------"

##### IPv4
$MODPROBE ip_tables
$MODPROBE iptable_filter
$MODPROBE iptable_mangle
# Allow to use state match
$MODPROBE ip_conntrack
# Allow NAT
$MODPROBE iptable_nat

##### IPv6
$MODPROBE ip6_tables
$MODPROBE ip6table_filter
$MODPROBE ip6table_mangle

##### Allow active / passive FTP
$MODPROBE ip_conntrack_ftp
$MODPROBE ip_nat_ftp

##### Allow log limits
echo " ... burst limit"
$MODPROBE ipt_limit


Set network features

Now that you've enable some modules, you need to choose which network features you're gonna use or not.


IPTABLES=`which iptables`
IP6TABLES=`which ip6tables`


echo -e " "		
echo -e "------------------------"
echo -e " Set network features"
echo -e "------------------------"
echo " ... Enable common Linux protections"
# Avoid broadcast echo
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# avoid TCP SYN Cookie
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
# protection against bogus responses
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
# Avoid IP Spoofing (discard non routable IP@)
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done
# Avoid ICMP redirect
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
echo 0 > /proc/sys/net/ipv6/conf/all/accept_redirects
# Avoid Source Routed
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
echo 0 > /proc/sys/net/ipv6/conf/all/accept_source_route
## Check TCP window 
echo 1 > /proc/sys/net/ipv4/tcp_window_scaling
## Avoid DoS
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_time
## Adjust TTL value
echo 64 > /proc/sys/net/ipv4/ip_default_ttl


# Enable port forwarding in general
# (i) Some might argue that it should only be done by routers... 
#     Since I'm using a VPN, I like to access both networks and exchange data between them. 
#     That's why port forwarding is enable.
echo 1 > /proc/sys/net/ipv4/ip_forward

echo 2 > /proc/sys/net/ipv6/conf/all/use_tempaddr
echo 2 > /proc/sys/net/ipv6/conf/default/use_tempaddr
echo 2 > /proc/sys/net/ipv6/conf/eth0/use_tempaddr
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
echo 0 > /proc/sys/net/ipv6/conf/default/forwarding
echo 0 > /proc/sys/net/ipv6/conf/eth0/forwarding



Default policy

Attacks types

As a reminder, there are 3 different kind of attacks:

  • INPUT = intrusion. Someone want something from your computer, NOW.
  • OUTPUT = disclosure. Someone want something from your computer or network - and you might give it LATER.
  • FORWARD = get access. someone want something from your network. ... Or even worse: they will use your computer to perform attacks on your behalf!


Attacks types

You can read more about each attack over Internet.


Set default policies

This is how you defined a default policy.

Best practice Recommendations :

  • You should set all policies in ACCEPT ; and DROP the packets at the end of your firewall. By doing so you'll probably not be locked away from your server in case of firewall change.
  • You should keep the RELATED and ESTABLISHED connections


IPTABLES=`which iptables`
IP6TABLES=`which ip6tables`


echo -e " "		
echo -e "------------------------"
echo -e " Flush existing rules "
echo -e "------------------------"

# Delete GENERIC rules
$IP6TABLES -F
$IP6TABLES -X	
$IPTABLES -F
$IPTABLES -X

# delete FILTER rule (in/out)
$IPTABLES -t filter -F
$IPTABLES -t filter -X
$IP6TABLES -t filter -F
$IP6TABLES -t filter -X

# delete MANGLE rules (packets modifications)
$IPTABLES -t mangle -F
$IPTABLES -t mangle -X
$IP6TABLES -t mangle -F
$IP6TABLES -t mangle -X

# delete NAT rules [IPv4 only]
$IPTABLES -t nat -F
$IPTABLES -t nat -X


echo -e " "		
echo -e "------------------------"
echo -e " Default policy"
echo -e "------------------------"
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT		

$IP6TABLES -P INPUT ACCEPT
$IP6TABLES -P FORWARD ACCEPT
$IP6TABLES -P OUTPUT ACCEPT


echo -e " "		
echo -e "------------------------"
echo -e " Keep connections"
echo -e "------------------------"
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

$IP6TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IP6TABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$IP6TABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


[...]


# End of script (optional)
$IPTABLES -A INPUT -j DROP
$IP6TABLES -A INPUT -j DROP

$IPTABLES -A OUTPUT -j DROP
$IP6TABLES -A OUTPUT -j DROP


Basic protection and protocol(s) enforcement

Basic (minimal) protection

You should put some minimal protection. This layer relies on your O.S and its internal checks. Most of the time that's enough to block malformed and suspicious packets.


IPTABLES=`which iptables`
IP6TABLES=`which ip6tables`


#####################
### All protocols ###
#####################
# Reject invalid packets
$IPTABLES -A INPUT -m state --state INVALID -m comment --comment "Invalid input" -j DROP
$IPTABLES -A OUTPUT -m state --state INVALID -m comment --comment "Invalid input" -j DROP
$IPTABLES -A FORWARD -m state --state INVALID -m comment --comment "Invalid forward" -j DROP

$IP6TABLES -A INPUT -m state --state INVALID -m comment --comment "Invalid input" -j DROP
$IP6TABLES -A OUTPUT -m state --state INVALID -m comment --comment "Invalid input" -j DROP
$IP6TABLES -A FORWARD -m state --state INVALID -m comment --comment "Invalid forward" -j DROP

# Ensure TCP connection requests start with SYN flag
$IPTABLES -A INPUT -p tcp -m state --state NEW ! --syn -m comment --comment "Invalid conn request" -j DROP
$IPTABLES -A OUTPUT -p tcp -m state --state NEW ! --syn -m comment --comment "Invalid conn request" -j DROP

$IP6TABLES -A INPUT -p tcp -m state --state NEW ! --syn -m comment --comment "Invalid conn request" -j DROP
$IP6TABLES -A OUTPUT -p tcp -m state --state NEW ! --syn -m comment --comment "Invalid conn request" -j DROP


############
### IPv4 ###
############
## Localhost
$IPTABLES -A INPUT ! -i lo -s 127.0.0.0/24 -m comment --comment "Reject none loopback on 'lo'" -j DROP  
$IPTABLES -A OUTPUT ! -o lo -d 127.0.0.0/24 -m comment --comment "Reject none loopback on 'lo'" -j DROP
# Accept all local packets
$IPTABLES -A INPUT -i lo -m comment --comment "Accept localhost packets" -j ACCEPT
$IPTABLES -A OUTPUT -o lo -m comment --comment "Accept localhost packets" -j ACCEPT


############
### IPv6 ###
############
# Allow localhost traffic. These rules are for all protocols.
$IP6TABLES -A INPUT -s ::1 -d ::1 -j ACCEPT
$IP6TABLES -A INPUT ! -i lo -s ::1 -m comment --comment "Reject none loopback on 'lo'" -j DROP
$IP6TABLES -A OUTPUT ! -o lo -d ::1 -m comment --comment "Reject none loopback on 'lo'" -j DROP

# Allow Link-Local addresses
$IP6TABLES -A INPUT -s fe80::/10 -j ACCEPT
$IP6TABLES -A OUTPUT -s fe80::/10 -j ACCEPT

# Normally, link-local packets should NOT be forwarded and don't need an entry in the FORWARD rule.
# However, when bridging in Linux (e.g. in Xen or OpenWRT), the FORWARD rule is needed:
$IP6TABLES -A FORWARD -s fe80::/10 -j ACCEPT

#################
### Multicast ###
#################
$IPTABLES -A INPUT -m comment --comment "Multicast auto-configuration"  -d 224.0.0.0/24 -j ACCEPT 
$IPTABLES -A OUTPUT -m comment --comment "Multicast request"  -d 224.0.0.0/24 -j ACCEPT 

$IP6TABLES -A INPUT -d ff00::/8 -j ACCEPT
$IP6TABLES -A INPUT -s ff00::/8 -j ACCEPT
$IP6TABLES -A OUTPUT -d ff00::/8 -j ACCEPT
$IP6TABLES -A OUTPUT -s ff00::/8 -j ACCEPT


Block IPv4 in IPv6 tunnels

If your ISP delivers you a native IPv6 connection then you don't need to use IPv4 tunneling! Just use either IPv4 or IPv6 native mode.


IPTABLES=`which iptables`
IP6TABLES=`which ip6tables`


## IPv6 security
# No IPv4 -> IPv6 tunneling
$IP6TABLES -A INPUT -s 2002::/16 -m comment --comment "Reject 6to4 tunnels" -j DROP
$IP6TABLES -A FORWARD -s 2002::/16 -m comment --comment "Reject 6to4 tunnels" -j DROP
$IP6TABLES -A INPUT -s 2001:0::/32 -m comment --comment "Reject Teredo tunnels" -j DROP
$IP6TABLES -A FORWARD -s 2001:0::/32 -m comment --comment "Reject Teredo tunnels" -j DROP
    
# Block IPv6 protocol in IPv4 frames
$IPTABLES -A INPUT -p 41 -m comment --comment "Block IPv6 protocol in IPv4 frames" -j DROP
$IPTABLES -A OUTPUT -p 41 -m comment --comment "Block IPv6 protocol in IPv4 frames" -j DROP
$IPTABLES -A FORWARD -p 41 -m comment --comment "Block IPv6 protocol in IPv4 frames" -j DROP


Block IPv6 routing headers

# Filter all packets that have RH0 headers:
$IP6TABLES -A INPUT -m rt --rt-type 0 -j DROP
$IP6TABLES -A FORWARD -m rt --rt-type 0 -j DROP
$IP6TABLES -A OUTPUT -m rt --rt-type 0 -j DROP


Protocol(s) enforcement

You can even push the standard protection a bit higher by checking some protocols flags.

IPTABLES=`which iptables`
IP6TABLES=`which ip6tables`


echo -e " "		
echo -e "------------------------"
echo -e " Protocols enforcement"
echo -e "------------------------"

####### IPv4 #######
echo " ... Layer 2: ICMP v4"
# ICMP packets should not be fragmented
$IPTABLES -A INPUT --fragment -p icmp -m comment --comment "no ICMP fragments" -j DROP    
# SMURF attack protection
$IPTABLES -A INPUT -p icmp -m icmp --icmp-type address-mask-request -m comment --comment "address-mask-request" -j DROP
$IPTABLES -A INPUT -p icmp -m icmp --icmp-type timestamp-request -m comment --comment "timestamp-request" -j DROP
# Limit ICMP Flood
$IPTABLES -A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -m comment --comment "ICMP flood protection" -j ACCEPT    
$IPTABLES -A OUTPUT -p icmp --icmp-type 0 -m comment --comment "echo reply" -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type 3 -m comment --comment "destination unreachable" -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type 8 -m comment --comment "echo request" -j ACCEPT    


####### IPv6 #######
echo " ... Layer 2: ICMP v6 "
# Don't DROP ICMP6 a lot of things are happening over there! It might completly block the connection if you DROP icmp6
$IP6TABLES -A INPUT -j ACCEPT
$IP6TABLES -A OUTPUT -p icmpv6 -j ACCEPT  
$IP6TABLES -A FORWARD -p icmpv6 -j ACCEPT  


####### TCP IPv4 #######
echo " ... Layer 4: TCP # check packets conformity"
# INCOMING packets check
# All new incoming TCP should be SYN first
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -m comment --comment "new TCP connection check" -j DROP
# Avoid SYN Flood (max 3 SYN packets / second. Then Drop all requests !!)
$IPTABLES -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -m comment --comment "avoid TCP SYN flood" -j ACCEPT
# Avoid fragment packets
$IPTABLES -A INPUT -f -m comment --comment "no fragments" -j DROP
# Check TCP flags -- flag 64, 128 = bogues
$IPTABLES -A INPUT -p tcp --tcp-option 64 -m comment --comment "ECE flag" -j DROP
$IPTABLES -A INPUT -p tcp --tcp-option 128 -m comment --comment "CWR flag" -j DROP


echo " ... Layer 4: TCP # Avoid NMAP Scans"
# XMAS-NULL
$IPTABLES -A INPUT -p tcp --tcp-flags ALL NONE -m comment --comment "attack XMAS-NULL" -j DROP
# XMAS-TREE
$IPTABLES -A INPUT -p tcp --tcp-flags ALL ALL -m comment --comment "attack XMAS-tree" -j DROP
# Stealth XMAS Scan
$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -m comment --comment "attack XMAS stealth" -j DROP
# SYN/RST Scan
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -m comment --comment "scan SYN/RST" -j DROP
# SYN/FIN Scan
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -m comment --comment "scan SYN/FIN" -j DROP
# SYN/ACK Scan
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,ACK SYN,ACK -m comment --comment "scan SYN/ACK" -j DROP
# FIN/RST Scan
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -m comment --comment "scan FIN/RST" -j DROP
# FIN/ACK Scan
$IPTABLES -A INPUT -p tcp -m tcp --tcp-flags FIN,ACK FIN -m comment --comment "scan FIN/ACK" -j DROP
# ACK/URG Scan
$IPTABLES -A INPUT -p tcp --tcp-flags ACK,URG URG -m comment --comment "scan ACK/URG" -j DROP
# FIN/URG/PSH Scan
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,URG,PSH FIN,URG,PSH -m comment --comment "scan FIN/URG/PSH" -j DROP
# XMAS-PSH Scan
$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -m comment --comment "scan XMAS/PSH" -j DROP
# End TCP connection
$IPTABLES -A INPUT -p tcp --tcp-flags ALL FIN -m comment --comment "end TCP connection flag" -j DROP
# Ports scans
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m comment --comment "common scan FIN/SYN/RST/ACK SYN" -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -m comment --comment "common scan FIN/SYN/RST/ACK/PSH/URG NONE" -j DROP


Allow services and network protocols

DHCP

DHCP client:

IPTABLES=`which iptables`
IP6TABLES=`which ip6tables`


# DHCP client >> Broadcast IP request 
$IPTABLES -A INPUT -p udp --sport 67:68 --dport 67:68 -m comment --comment "DHCP" -j ACCEPT 
$IPTABLES -A OUTPUT -p udp --sport 67:68 --dport 67:68 -m comment --comment "DHCP" -j ACCEPT 

$IP6TABLES -A INPUT -p udp --sport 67:68 --dport 67:68 -m comment --comment "DHCP" -j ACCEPT 
$IP6TABLES -A OUTPUT -p udp --sport 67:68 --dport 67:68 -m comment --comment "DHCP" -j ACCEPT


DNS

This will allow your computer to perform DNS requests:

IPTABLES=`which iptables`
IP6TABLES=`which ip6tables`

# DNS
$IPTABLES -A INPUT -p udp --sport 53 -m comment --comment "DNS UDP sPort" -j ACCEPT
$IPTABLES -A OUTPUT -p udp --sport 53 -m comment --comment "DNS UDP sPort" -j ACCEPT

$IPTABLES -A INPUT -p udp --dport 53 -m comment --comment "DNS UDP dPort" -j ACCEPT
$IPTABLES -A OUTPUT -p udp --dport 53 -m comment --comment "DNS UDP dPort" -j ACCEPT

    
$IP6TABLES -A INPUT -p udp --sport 53 -m comment --comment "DNS UDP sPort" -j ACCEPT
$IP6TABLES -A OUTPUT -p udp --sport 53 -m comment --comment "DNS UDP sPort" -j ACCEPT

$IP6TABLES -A INPUT -p udp --dport 53 -m comment --comment "DNS UDP dPort" -j ACCEPT
$IP6TABLES -A OUTPUT -p udp --dport 53 -m comment --comment "DNS UDP dPort" -j ACCEPT


# DNS SEC
# Established, related input are already accepted earlier
$IPTABLES -A OUTPUT -p tcp --sport 53 -m comment --comment "DNS Sec TCP sPort" -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 53 -m comment --comment "DNS Sec TCP dPort" -j ACCEPT

$IP6TABLES -A OUTPUT -p tcp --sport 53 -m comment --comment "DNS Sec TCP sPort" -j ACCEPT
$IP6TABLES -A OUTPUT -p tcp --dport 53 -m comment --comment "DNS Sec TCP dPort" -j ACCEPT


!! IMPORTANT !!!

If you ever loose Internet access after that you need to check your /etc/resolv.conf configuration and make sure you're using a valid DNS server.


LAN communication

To allow communication in the local network, without any restrictions:

IPTABLES=`which iptables`
IP_LAN_V4="172.16.50.0/24"
IP_LAN_V6="2001:DB8:1::1"


# Allow LAN communication
if [ ! -z "$IP_LAN_V4" ] 
then
 	echo -e " ... Allow LAN communication - IP v4"
	$IPTABLES -A INPUT -s $IP_LAN_V4 -d $IP_LAN_V4 -j ACCEPT
	$IPTABLES -A OUTPUT -s $IP_LAN_V4 -d $IP_LAN_V4 -j ACCEPT
        # Allow forwarding within the LAN
        $IPTABLES -A FORWARD -s $IP_LAN_V4 -j ACCEPT
fi

if [ ! -z "$IP_LAN_V6" ] 
then
	echo -e " ... Allow LAN communication - IP v6"
	$IP6TABLES -A INPUT -s $IP_LAN_V6 -d $IP_LAN_V6 -j ACCEPT
	$IP6TABLES -A OUTPUT -s $IP_LAN_V6 -d $IP_LAN_V6 -j ACCEPT
        # Allow forwarding within the LAN
        $IP6TABLES -A FORWARD -s $IP_LAN_V6 -j ACCEPT
fi

Note: thanks to the ! -z operator if the variable is not set or "" then the rule will be skipped.


NTP (time syncronization) client

IPTABLES=`which iptables`


# NTP client
echo -e " ... Allow NTP time sync"
$IPTABLES -A INPUT -p udp --sport 123 -m state --state ESTABLISHED -m comment --comment "NTP (UDP)" -j ACCEPT
$IPTABLES -A INPUT -p tcp --sport 123 -m state --state ESTABLISHED -m comment --comment "NTP (TCP)" -j ACCEPT

$IPTABLES -A OUTPUT -p udp --dport 123 -m state --state NEW,ESTABLISHED -m comment --comment "NTP (UDP)" -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 123 -m state --state NEW,ESTABLISHED -m comment --comment "NTP (TCP)" -j ACCEPT


Samba file-share

IPTABLES=`which iptables`

# SAMBA share
# Access filtering is done in /etc/samba/smb.conf
$IPTABLES -A INPUT -p tcp --dport 135 -m comment --comment "DCE endpoint resolution" -j ACCEPT
$IPTABLES -A INPUT -p udp --dport 137 -m comment --comment "NetBIOS Name Service" -j ACCEPT
$IPTABLES -A INPUT -p udp --dport 138 -m comment --comment "NetBIOS Datagram" -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 139 -m comment --comment "NetBIOS Session" -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 445 -m comment --comment "SMB over TCP" -j ACCEPT

$IPTABLES -A OUTPUT -p tcp --sport 135 -m state --state ESTABLISHED -m comment --comment "DCE endpoint resolution" -j ACCEPT
$IPTABLES -A OUTPUT -p udp --dport 137 -m comment --comment "NetBios Name Service" -j ACCEPT
$IPTABLES -A OUTPUT -p udp --dport 138 -m comment --comment "NetBios Data Exchange" -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 139 -m comment --comment "NetBios Session + Samba" -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 445 -m comment --comment "CIFS - Partage Win2K and more" -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 548 -m comment --comment "Apple file sharing" -j ACCEPT


FTP client

IPTABLES=`which iptables`

# FTP
# FTP INPUT (Client <--from-- Server)
$IPTABLES -A INPUT -p tcp --dport 21 -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "FTP command: allow FTP connections" -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 20 -m conntrack --ctstate NEW,ESTABLISHED,RELATED -m comment --comment "FTP data (active)" -j ACCEPT
$IPTABLES -A INPUT -p tcp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "FTP data (passive)" -j ACCEPT
$IPTABLES -A INPUT -p tcp -m state --state ESTABLISHED -m comment --comment "FTP established connections" -j ACCEPT

# FTP OUTPUT (Client --to--> Server) 
$IPTABLES -A OUTPUT -p tcp --dport 21 -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "FTP command: allow FTP connections" -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 20 -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "FTP data (active)" -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate NEW,ESTABLISHED,RELATED -m comment --comment "FTP data (passive)" -j ACCEPT