Difference between revisions of "Iptables"

From Christoph's Personal Wiki
Jump to: navigation, search
(See also)
(Stateful filtering)
Line 22: Line 22:
  
 
  -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 --sport 63636 -s 10.0.0.2 -j ACCEPT
 
  -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 --sport 63636 -s 10.0.0.2 -j ACCEPT
 +
 +
* Get a list of ICMP type names:
 +
$ iptables -p icmp -h
 +
 +
;<code>REJECT</code>: This is used to send back an error packet in response to the matched packet: otherwise it is equivalent to DROP so it is a terminating TARGET, ending rule traversal. This target is only valid in the INPUT, FORWARD, and OUTPUT chains, and user-defined chains which are only called from those chains. The following option controls the nature of the error packet returned:
 +
--reject-with type
 +
: The type given can be:
 +
::<code>icmp-net-unreachable</code>
 +
::<code>icmp-host-unreachable</code>
 +
::<code>icmp-port-unreachable</code>
 +
::<code>icmp-proto-unreachable</code>
 +
::<code>icmp-net-prohibited</code>
 +
::<code>icmp-host-prohibited</code>
 +
::<code>icmp-admin-prohibited</code> (*)
 +
:which return the appropriate ICMP error message (port-unreachable is the default). The option tcp-reset can be used on rules which only match the TCP protocol: this causes a TCP RST packet to be sent back. This is mainly useful for blocking ident (113/tcp) probes, which frequently occur when sending mail to broken mail hosts (which will not accept your mail otherwise).
 +
:(*) Using icmp-admin-prohibited with kernels that do not support it will result in a plain DROP instead of REJECT
  
 
==Examples==
 
==Examples==

Revision as of 19:31, 14 September 2016

Stateful filtering

  • TCP states: NEW, RELATED, ESTABLISHED, INVALID
  • Basic ruleset:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [241:19144]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -p icmp -j ACCEPT 
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 53 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited 
-A FORWARD -j REJECT --reject-with icmp-host-prohibited 
COMMIT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 --sport 63636 -s 10.0.0.2 -j ACCEPT
  • Get a list of ICMP type names:
$ iptables -p icmp -h
REJECT
This is used to send back an error packet in response to the matched packet: otherwise it is equivalent to DROP so it is a terminating TARGET, ending rule traversal. This target is only valid in the INPUT, FORWARD, and OUTPUT chains, and user-defined chains which are only called from those chains. The following option controls the nature of the error packet returned:
--reject-with type
The type given can be:
icmp-net-unreachable
icmp-host-unreachable
icmp-port-unreachable
icmp-proto-unreachable
icmp-net-prohibited
icmp-host-prohibited
icmp-admin-prohibited (*)
which return the appropriate ICMP error message (port-unreachable is the default). The option tcp-reset can be used on rules which only match the TCP protocol: this causes a TCP RST packet to be sent back. This is mainly useful for blocking ident (113/tcp) probes, which frequently occur when sending mail to broken mail hosts (which will not accept your mail otherwise).
(*) Using icmp-admin-prohibited with kernels that do not support it will result in a plain DROP instead of REJECT

Examples

  • Sample `iptables` ruleset:
*filter

# Dropping incoming connections that don't have explecit rules bellow
:INPUT DROP [68:4456]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1628:151823]

# Allow established connections for both public and private connections
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Opening ports wide open
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -p udp -m udp --dport 53 -j ACCEPT

# Opening a port to a specific IP
-A INPUT -p tcp -m tcp --dport 10000 -s 192.168.1.1 -j ACCEPT

# Opening a port to a range of IPs
-A INPUT -p tcp -m tcp --dport 20000 -s 192.168.0.0/24 -j ACCEPT

# Commmiting the rules to the firewall
COMMIT
#!/bin/bash
# Set INPUT chain default policy to DROP
iptables -P INPUT DROP
# Flushes all rule in the filter table
iptables -F
# ACCEPT all packets from loopback interface
iptables -A INPUT -i lo -j ACCEPT
# ACCEPT all ESTABLISHED,RELATED packets
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# ACCEPT all NEW connections to tcp port 22
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT
# REJECT all packets from 192.168.1.0/24 network
iptables -A INPUT -s 192.168.1.0/24 -j REJECT
# ACCEPT all icmp traffic from 192.168.0.0/24
iptables -A INPUT -p icmp -s 192.168.0.0/24 -j ACCEPT
# save rules
iptables-save > /etc/sysconfig/iptables
# print out saved rules
iptables-save
iptables -nvL

Network Address Translation (NAT)

  • The chains available in the filter table are: INPUT, FORWARD, OUTPUT
  • The chains available in the nat table are: PREROUTING, POSTROUTING, OUTPUT
  • Example:
$ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
$ iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.0.1
$ iptables -t nat -A PREROUTING -i eth0 -m tcp -p tcp --dport 80 -j DNAT --to-destination 192.168.0.100:8080
  • The DNAT target can only be used in the PREROUTING chain and the OUTPUT chain of the nat table.
  • To enable forwarding persistently across reboots, add net.ipv4.ip_forward=1 to /etc/sysctl.conf then run sysctl -p, or:
sysctl -w net.ipv4.ip_forward=1

Basic command options

Chain manipulation (three default chains, INPUT, FORWARD, OUTPUT, are always present):

  • Create a new chain (-N, --new-chain chain)
  • Delete an empty chain (-X, --delete-chain [chain])
  • Change the policy for a built-in chain (-P, --policy chain target)
  • List the rules in a chain (-L, --list [chain])
  • Flush the rules out of a chain (-F, --flush [chain])
  • Zero the packet and byte counters in all chains (-Z, --zero) (note: It is legal to specify the -L, --list (list) option as well, to see the counters immediately before they are cleared.)

Rule manipulation:

  • Append a new rule to a chain (-A, --append chain rule-specification)
  • Delete a rule at some position in a chain (-D, --delete chain rule-specification)
NEW 
packet starts a new communication, adds a rule to the state tracking table
ESTABLISHED 
any packet that matches a rule in the state tracking table
RELATED 
traffic "related" in some way to ESTABLISHED traffic; protocols like SSH, FTP, etc.
INVALID 
packet cannot be identified; normally these should be rejected or dropped

NOTE: Running the `iptables` command changes the netfilter kernel module rules in memory, but will not persist across a reboot.

Running `service iptables save` will take the current rules in memory and write them to /etc/sysconfig/iptables which is read during system boot. Run instead:

service iptables restart

Help (-h)

Usage

iptables -[AD] chain rule-specification [options]
iptables -[RI] chain rulenum rule-specification [options]
iptables -D chain rulenum [options]
iptables -[LFZ] [chain] [options]
iptables -[NX] chain
iptables -E old-chain-name new-chain-name
iptables -P chain target [options]
iptables -h (print this help information)

Commands

Either long or short options are allowed.

--append -A chain 
append to chain
--delete -D chain 
delete matching rule from chain
--delete -D chain rulenum 
delete rule rulenum (1 = first) from chain
--insert -I chain [rulenum] 
insert in chain as rulenum (default 1=first)
--replace -R chain rulenum 
replace rule rulenum (1 = first) in chain
--list -L [chain] 
list the rules in a chain or all chains
--flush -F [chain] 
delete all rules in chain or all chains
--zero -Z [chain] 
zero counters in chain or all chains
--new -N chain 
create a new user-defined chain
--delete-chain -X [chain] 
delete a user-defined chain
--policy -P chain target 
change policy on chain to target
--rename-chain -E old-chain new-chain 
change chain name, (moving any references)

Options

--proto -p [!] proto 
protocol: by number or name, eg. 'tcp'
--source -s [!] address[/mask] 
source specification
--destination -d [!] address[/mask] 
destination specification
--in-interface -i [!] input name[+] 
network interface name ([+] for wildcard)
--jump -j target 
target for rule (may load target extension)
--goto -g chain 
jump to chain with no return
--match -m match 
extended match (may load extension)
--numeric -n 
numeric output of addresses and ports
--out-interface -o [!] output name[+] 
network interface name ([+] for wildcard)
--table -t table 
table to manipulate (default: 'filter')
--verbose -v 
verbose mode
--line-numbers 
print line numbers when listing
--exact -x 
expand numbers (display exact values)
[!] --fragment -f 
match second or further fragments only
--modprobe=<command> 
try to insert modules using this command
--set-counters PKTS BYTES 
set the counter during insert/append
[!] --version -V 
print package version.

Netmask

Netmask Bit Values
Addrs Bits Pref Class Mask
0 /32 255.255.255.255
2 1 /31 255.255.255.254
4 2 /30 255.255.255.252
8 3 /29 255.255.255.248
16 4 /28 255.255.255.240
32 5 /27 255.255.255.224
64 6 /26 255.255.255.192
128 7 /25 255.255.255.128
256 8 /24 1C 255.255.255.0
512 9 /23 2C 255.255.254.0
1K 10 /22 4C 255.255.252.0
2K 11 /21 8C 255.255.248.0
4K 12 /20 16C 255.255.240.0
8K 13 /19 32C 255.255.224.0
16K 14 /18 64C 255.255.192.0
32K 15 /17 128C 255.255.128.0
64K 16 /16 1B 255.255.0.0
128K 17 /15 2B 255.254.0.0
256K 18 /14 4B 255.252.0.0
512K 19 /13 8B 255.248.0.0
1M 20 /12 16B 255.240.0.0
2M 21 /11 32B 255.224.0.0
4M 22 /10 64B 255.192.0.0
8M 23 /9 128B 255.128.0.0
16M 24 /8 1A 255.0.0.0
32M 25 /7 2A 254.0.0.0
64M 26 /6 4A 252.0.0.0
128M 27 /5 8A 248.0.0.0
256M 28 /4 16A 240.0.0.0
512M 29 /3 32A 224.0.0.0
1024M 30 /2 64A 192.0.0.0
2048M 31 /1 128A 128.0.0.0
4096M 32 /0 256A 0.0.0.0


ICMP datagram types

see: RFC 1700 (Assigned Numbers)
/usr/include/netinet/ip_icmp.h
ICMP Datagram Types
Type number iptables mnemonic Type description
0 echo-reply Echo Reply
3 destination-unreachable Destination Unreachable
4 source-quench Source Quench
5 redirect Redirect
8 echo-request Echo Request
11 time-exceeded Time Exceeded
12 parameter-problem Parameter Problem
13 timestamp-request Timestamp Request
14 timestamp-reply Timestamp Reply
15 none Information Request
16 none Information Reply
17 address-mask-request Address Mask Request
18 address-mask-reply Address Mask Reply


Type Of Service (TOS)

Suggested Uses for TOS Bitmasks
TOS ANDmask XORmask Suggested Use
Minimum Delay 0x01 0x10 ftp, telnet, ssh
Maximum Throughput 0x01 0x08 ftp-data, www
Maximum Reliability 0x01 0x04 snmp, dns
Minimum Cost 0x01 0x02 nntp, smtp


Example script

#!/bin/bash

LOOPBACK="127.0.0.0/8"
CLASS_A="10.0.0.0/8"
CLASS_B="172.16.0.0/12"
CLASS_C="192.168.0.0/16"
CLASS_D="224.0.0.0/4"
CLASS_E="240.0.0.0/5"
BROADCAST_SRC="0.0.0.0"
BROADCAST_DEST="255.255.255.255"

########
# flush iptables
iptables -F
iptables -t nat -F
iptables -t mangle -F

########
# loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

########
# policies
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
iptables -t nat -P POSTROUTING ACCEPT

iptables -t mangle -P PREROUTING ACCEPT
iptables -t mangle -P OUTPUT ACCEPT

########
# allow related incoming
iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT

########
# programs and stuff (add a line for each service you want to allow)

# SSH on local network
iptables -A INPUT -s $CLASS_A -p tcp --destination-port 22 -j ACCEPT

# apache server (on all interfaces/networks)
iptables -A INPUT -p tcp --destination-port 80 -j ACCEPT

# samba + network share
iptables -A INPUT -s $CLASS_A -p tcp --destination-port 137 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p udp --destination-port 137 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p tcp --destination-port 138 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p udp --destination-port 138 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p tcp --destination-port 139 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p udp --destination-port 139 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p tcp --destination-port 445 -j ACCEPT
iptables -A INPUT -s $CLASS_A -p udp --destination-port 445 -j ACCEPT

Map external IP address onto an internal one

Let's say your external IP address is 128.65.225.10 and your internal IP address is 10.0.17.10, then:

-A PREROUTING -d 128.65.225.10 -j DNAT --to-destination 10.0.17.10
-A POSTROUTING -s 10.0.17.10 -j SNAT --to-source 128.65.225.10

You can then view the results with

iptables --list -n -t nat -v

Scripts

Tips

  • Find your external interface:
$ ip route ls
10.0.213.56 via 10.0.27.5e dev eth0  metric 10
192.168.27.0/24 dev eth0  proto kernel  scope link  src 192.168.27.63  metric 10
10.0.27.0/24 dev eth0  proto kernel  scope link  src 10.0.27.63  metric 10
169.254.0.0/16 dev eth0  scope link  metric 10
127.0.0.0/8 dev lo  scope link
default via 10.0.27.153 dev eth0  metric 10

The last line shows eth0 to be your external interface.

  • Determine the IP address of your external interface:
$ ip addr ls dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 100
   link/ether 00:19:d1:4f:22:60 brd ff:ff:ff:ff:ff:ff
   inet 128.95.27.63/24 brd 10.0.27.255 scope global eth0
   inet 192.168.27.63/24 brd 192.168.27.255 scope global eth0:0
   inet6 fe80::219:d1ff:fe4f:2260/64 scope link
      valid_lft forever preferred_lft forever
  • So, the IP address of the external interface is 128.95.27.63.

See also

External links

Free firewall software

Tutorials / Howtos / Examples / etc.