Skip to content

Instantly share code, notes, and snippets.

@DominicBreuker
Last active October 14, 2021 17:47
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save DominicBreuker/c948d938adc9257585fc2f40d50b96c4 to your computer and use it in GitHub Desktop.
Save DominicBreuker/c948d938adc9257585fc2f40d50b96c4 to your computer and use it in GitHub Desktop.
iptables firewall

iptables cheat sheet

Concepts

iptables defines tables, which group features:

  • filter: use it to filter traffic
  • nat: use it to implement NAT
  • raw: use it to define which connections iptables should track (stateful firewall)
  • mangle: use it to change some fields in packets (e.g., TTL)
  • security: use it to define access control

For each table, several chains exist. You can define your own chains too. Predefined chains come with a default target (see below). Typically, the following predefined chains exist:

  • INPUT: incoming packets
  • FORWARD: packets routed through the system
  • OUTPUT: packets originating from the system

Each chain is a list of rules. If a chain is processed, iptables walks through the rules from top to bottom until a rule matches. If no rule matches, the default target applies. A rule may also tell iptables to jump to another chain. If the end of that chain is reached without anything matching, iptables jumps back into the original chain. Each rule has:

  • one or more matches: define which packets match the rule (e.g., packets with source IP 10.10.10.15 with protocol TCP)
  • one target: the action to take if the rule applies. Either a real action (DROP, ACCEPT, ...) or a jump to another chain.

Traversal of tables and chains looks roughly like this: Table and chain traversal

iptables is a stateful filewall. It tracks connections to allow for more sophisticated filtering rules. States can be:

  • NEW: first package of any new connection
  • ESTABLISHED: at least one reply has been sent to the NEW package for this connection. All other now have ESTABLISHED state.
  • RELATED: packets are connected to another connection (e.g., FTP data traffic could be related to the control traffic)
  • INVALID: means that iptables is confused
  • UNTRACKED: the packet was marked as NOTRACK in the raw table

Edit config

List rules

iptables -L -n -v --line-numbers

Add rules

Add single rules by specifying:

  • one chain (INPUT, FORWARD, OUTPUT)
  • one or more matches (e.g., -s 10.10.10.1 to match by source IP)
  • one target (e.g., DROP to drop the packets)
iptables -A INPUT -s 10.10.10.1 -j DROP

By default, you append to the chain. To insert, e.g., at position 4, run:

iptables -I INPUT 4 -s 10.10.10.1 -j DROP

Delete rules

Delete everything and start from scratch:

iptables -F

Delete single rule by line number:

iptables -L --line-numbers # get number of line to delete
iptables -D INPUT <line_number> # then delete it

Delete single rule by specification

iptables -S # shows iptables commands which were used to add current rules
iptables -D ... # paste the command from above, but without the -A

Load/save rules

Save current rules to file

iptables-save > /etc/sysconfig/iptables

Load rules from file (must be set up to happen on boot, possibly manually by admin)

iptables-restore < /etc/sysconfig/iptables

Examples

Block single IP

iptables -A INPUT -s 10.10.10.1 -j DROP

Allow incoming SSH from IP range

iptables -A INPUT -p tcp -s 10.10.0.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

Allow outgoing DNS requests only on interface eth0

iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT

Port forwarding to machine on private network (e.g., connect to firewall on port 2222 and be forwarded to other machine on 22)

iptables -t nat -A PREROUTING -p tcp -d 10.10.10.1 --dport 2222 -j DNAT --to 192.168.0.100:22

Sample configuration SSH

An example configuration for incoming SSH connections. Protects against brute forcing and limits parallel connections.

# delete all rules and custom chains
iptables -F
iptables -X

# drop incoming traffic by default
iptables -P INPUT DROP

# accept established connections
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# SSH to init chain
iptables -N ssh_init
iptables -A INPUT -p tcp --dport 22 --syn -j ssh_init

# SSH traffic init chain
# maintains a list of IP addresses trying to establish SSH connections (--set).
# Drops packets if IP tried it more than 3 times in last 60 seconds.
# --rttl ensures we match both IP and TTL of the packets so that nobody can (too easily) spoof our IP and DoS us.
iptables -A ssh_init -m recent --name ssh_ip_list --rcheck --seconds 60 --hitcount 3 --rttl -j DROP
iptables -A ssh_init -m recent --name ssh_ip_list --set -j RETURN

# SSH traffic to throttle ssh
iptables -N ssh_throttle
iptables -A INPUT -p tcp --dport 22 --syn -j ssh_throttle

# SSH traffic throttle chain
# ensures we can have an SSH connection only every 20 secs and max 3 at a time
iptables -A ssh_throttle -m connlimit --connlimit-above 3 -j DROP
iptables -A ssh_throttle -m limit --limit 3/m --limit-burst 1 -j ACCEPT

Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment