IPTables
From Wikislax
Packet filtering affords opening access only to these services you have decided to open The TCP or UDP packets include a piece of information called the port number, that is used to identify the type of service. A few port number examples are :
| Protocol | Port # | Secure Protocol | Secure Port # | Service |
|---|---|---|---|---|
| SMTP | 25 | SMTPS | 465 | Mail exchange |
| HTTP | 80 | HTTPS | 443 | Web browsing |
| POP3 | 110 | POP3S | 993 | Mail retrieval |
| NTTP | 119 | NTTPS | 563 | News exchange |
| IMAP | 143 | IMAPS | 995 | Mail retrieval |
| LDAP | 389 | LDAPS | 636 | Ldap Directory |
On server side, the services are provided by applications that may have vulnerabilities and be attacked. Examples of attacks are buffer overflow or format string attacks, that afford getting full access on the target machine by crafting special strings sent to it. An attacker could then obtain any information present there or modify or destroy the system.
To reduce the number of possible attacks, the number of services authorized, or who can access the system, must be restricted. This is known as packet filtering. It is only an aspect of security (obviously, the applications on the server side must also be secured ...), but it is important. Never *** ever *** connect to the network a computer not protected by a packet filter !
To illustrate, let's configure our two-interfaces computer to be its own firewall. eth0 is the Internet interface, it uses network 192.168.0.x, the gateway is an ADSL router/switch at 192.168.0.254. eth1 is the (Intranet) interface to the internal network 192.168.1.x.
Iptables Filtering
Since Linux 2.4, packet filtering is effected inside the kernel, and configuration effected by the iptables user-space program. In addition to rules for incoming and outgoing packets, iptables affords defining rules for routing between the interfaces. The iptables command affords entering the rules one by one. Using a script affords entering all the rules.
For more information, see the netfilter official site. This site has links to various documents, including a simple introduction to packet filtering in this HOWTO.
In Slackware, the script used is /etc/rc.d/rc.firewall. It is called automatically when the system starts or stops, using commands ./rc.firewall start or ./rc.firewall stop.
#! /bin/sh
#
# startup script for local packet filter
#
fw_start () {
echo "Loading packet filter rules"
The flush command affords deleting all the active nat and filtering rules :
# flush old rules iptables -t nat --flush iptables -flush
The -P option affords defining the default policy. A good practise is to forbid by default everything not authorized. This is done here for packets incoming, outgoing, and routed between the interfaces :
# drop by default iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP
The -A option affords adding a rule. Here all the packets on the loopback interface are accepted :
# pass all traffic for network 127.0.0.0/8 on loopback interface iptables -A INPUT -i lo -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT iptables -A OUTPUT -o lo -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT
Then all packets for network 192.168.0.0/24 on the eth0 interface are accepted :
# pass all traffic for network 192.168.0.0/24 on eth0 interface iptables -A INPUT -i eth0 -s 192.168.0.0/24 -d 192.168.0.0/24 -j ACCEPT iptables -A OUTPUT -o eth0 -s 192.168.0.0/24 -d 192.168.0.0/24 -j ACCEPT
Connections already established are authorized to continue :
# accept packets that are part of previously OK'ed sessions iptables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED iptables -A OUTPUT -j ACCEPT -m state --state ESTABLISHED,RELATED iptables -A FORWARD -j ACCEPT -m state --state ESTABLISHED,RELATED
The command below affords early dropping of useless VoiP packets :
# drop SIP Cirpack KeepAlive Packet # iptables -A INPUT -p udp -j DROP --dport 5060 -m string --string "Cirpack KeepAlive Packet" --algo bm
The Network Address Translation rule below affords replacing the source address in the packets coming from the internal interface by the source address of the external interface. The packets outgoing to the Internet then all seem to come from the external interface, whatever their real origin (this translation affords hiding to the outside the addresses used internally) :
# nat traffic going to internet with our local network address iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 192.168.0.1
On both interfaces, we forbid communications where the remote address is a private network address, as specified by RFC 1918 (except 192.168.x.x, that we use internally). On the Internet, addresses of RFC 1918 private networks are not routable. So packets with such addresses are not expected on the internal network :
# INBOUND POLICY # multicast traffic iptables -A INPUT -s 0.0.0.0/8 -d 224.0.0.0/8 -j LOG --log-prefix "INPUT multicast traffic " iptables -A INPUT -s 0.0.0.0/8 -d 224.0.0.0/8 -j DROP # anti-spoofing rules iptables -A INPUT -s 0.0.0.0/8 -j LOG --log-prefix "INPUT spoofed IP " iptables -A INPUT -s 0.0.0.0/8 -j DROP iptables -A INPUT -s 10.0.0.0/8 -j LOG --log-prefix "INPUT spoofed IP " iptables -A INPUT -s 10.0.0.0/8 -j DROP iptables -A INPUT -s 127.0.0.0/8 -j LOG --log-prefix "INPUT spoofed IP " iptables -A INPUT -s 127.0.0.0/8 -j DROP iptables -A INPUT -s 172.16.0.0/12 -j LOG --log-prefix "INPUT spoofed IP " iptables -A INPUT -s 172.16.0.0/12 -j DROP iptables -A INPUT -s 255.0.0.0/8 -j LOG --log-prefix "INPUT spoofed IP " iptables -A INPUT -s 255.0.0.0/8 -j DROP
The protocols corresponding to services offered externally are accepted :
# services FTP SMTP HTTP NNTP HTTPS IMAPS POP3S # iptables -A INPUT -p tcp -j ACCEPT --dport 20 -m state --state NEW # iptables -A INPUT -p tcp -j ACCEPT --dport 21 -m state --state NEW iptables -A INPUT -p tcp -j ACCEPT --dport 25 -m state --state NEW iptables -A INPUT -p tcp -j ACCEPT --dport 80 -m state --state NEW iptables -A INPUT -p tcp -j ACCEPT --dport 119 -m state --state NEW iptables -A INPUT -p tcp -j ACCEPT --dport 443 -m state --state NEW iptables -A INPUT -p tcp -j ACCEPT --dport 993 -m state --state NEW # iptables -A INPUT -p tcp -j ACCEPT --dport 995 -m state --state NEW
The protocols corresponding to services offered on the local network are accepted :
# services on local network DNS POP IMAP SMTP LDAPS VNC VOIP iptables -A INPUT -p udp -j ACCEPT --dport 53 -s 192.168.0.0/24 iptables -A INPUT -p tcp -j ACCEPT --dport 53 -m state --state NEW -s 192.168.0.0/24 # iptables -A INPUT -p tcp -j ACCEPT --dport 110 -m state --state NEW -s 192.168.0.0/24 iptables -A INPUT -p tcp -j ACCEPT --dport 143 -m state --state NEW -s 192.168.0.0/24 iptables -A INPUT -p tcp -j ACCEPT --dport 389 -m state --state NEW -s 192.168.0.0/24 iptables -A INPUT -p tcp -j ACCEPT --dport 587 -m state --state NEW -s 192.168.0.0/24 iptables -A INPUT -p tcp -j ACCEPT --dport 636 -m state --state NEW -s 192.168.0.0/24 iptables -A INPUT -p tcp -j ACCEPT --dport 5900:5910 -m state --state NEW -s 192.168.0.0/2 iptables -A INPUT -p udp -j ACCEPT --dport 5060:5061 -s 192.168.0.0/24 iptables -A INPUT -p udp -j ACCEPT --dport 10000:20000 -s 192.168.0.0/24
Accept samba traffic on the local network :
# samba ports iptables -A INPUT -p tcp -j ACCEPT --dport 135 -m state --state NEW -s 192.168.0.0/24 iptables -A INPUT -p udp -j ACCEPT --dport 135 -s 192.168.0.0/24 iptables -A INPUT -p tcp -j ACCEPT --dport 137 -m state --state NEW -s 192.168.0.0/24 iptables -A INPUT -p udp -j ACCEPT --dport 137 -s 192.168.0.0/24 iptables -A INPUT -p udp -j ACCEPT --dport 138 -s 192.168.0.0/24 iptables -A INPUT -p tcp -j ACCEPT --dport 139 -m state --state NEW -s 192.168.0.0/24 iptables -A INPUT -p tcp -j ACCEPT --dport 445 -m state --state NEW -s 192.168.0.0/24 iptables -A INPUT -p udp -j ACCEPT --dport 445 -s 192.168.0.0/24
Accept VOIP traffic from freephonie.net :
# services to freephonie network VOIP iptables -A INPUT -p udp -j ACCEPT --dport 5060:5061 -s 212.27.52.0/24 iptables -A INPUT -p udp -j ACCEPT --dport 10000:20000 -s 212.27.52.0/24
Accept X-Window traffic on the local network :
# SSH-tunnelled X-Window output appears as input on interface lo iptables -A INPUT -p udp -j ACCEPT --dport 177 -s 192.168.0.0/24 iptables -A INPUT -i lo -p tcp -j ACCEPT --dport 6000:6063 -m state --state NEW -s 192.168.0.0/24
Accept ping :
# accept echo-request icmp packets iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT -s 192.168.0.0/24
Accept dcc antispam answers :
# accept dcc answers (dcc antispam service) iptables -A INPUT -p udp -j ACCEPT --dport 1024:65535 --sport 6277
Log anything not accepted above :
# log anything not accepted above # iptables -A INPUT -j LOG --log-prefix "INPUT bad traffic "
In the example all outbound packets are accepted, which would for example afford using a network scanner. In a production environment, there would be a stricter policy :
# OUTBOUND POLICY # accept all outbound TCP UDP ICMP packets iptables -A OUTPUT -p tcp -j ACCEPT -m state --state NEW iptables -A OUTPUT -p udp -j ACCEPT -m state --state NEW iptables -A OUTPUT -p icmp -j ACCEPT -m state --state NEW # log anything not accepted above iptables -A OUTPUT -j LOG --log-prefix "dropped by default "
For routing between the interfaces, everything coming from eth1 is accepted. Again, in a production environment, there would be a more strict policy :
# FORWARD POLICY # forward all outbound TCP UDP ICMP packets iptables -A FORWARD -i eth1 -p tcp -j ACCEPT -m state --state NEW iptables -A FORWARD -i eth1 -p udp -j ACCEPT -m state --state NEW iptables -A FORWARD -i eth1 -p icmp -j ACCEPT -m state --state NEW
Accept all traffic between bridged interfaces (Xen) :
# pass all bridged traffic iptables -A FORWARD -m physdev --physdev-in peth0 --physdev-out vif+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-out peth0 --physdev-in vif+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-in peth0 --physdev-out tap+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-out peth0 --physdev-in tap+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-in eth0 --physdev-out vif+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-out eth0 --physdev-in vif+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-in eth0 --physdev-out tap+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-out eth0 --physdev-in tap+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-out vif+ --physdev-in tap+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-in vif+ --physdev-out tap+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-out vif+ --physdev-in vif+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-in vif+ --physdev-out vif+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-out tap+ --physdev-in tap+ -j ACCEPT iptables -A FORWARD -m physdev --physdev-in tap+ --physdev-out tap+ -j ACCEPT # log anything not accepted above iptables -A FORWARD -j LOG --log-prefix "dropped by default " }
After the fw_start() function ends, the fw_stop() function is defined to authorize everything :
fw_stop () {
echo "Unloading all packet filter rules"
iptables -t nat --flush
iptables -flush
# accept by default
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
}
case "$1" in
‘start’)
fw_start
;;
’stop’)
fw_stop
;;
’restart’)
fw_start
;;
*)
echo "usage $0 start | stop | restart"
Testing the firewall
Use nmap -sU hostname (UDP) and nmap -sT hostname (TCP) to make sure what ports are visible locally and do the same from the outside.
Download example
| Configuration files | Main Page | X11 configuration |