IPTables is a command-line utility that is the standard interface for controlling the firewall netfilter for Linux kernels. To use the IPTables utility you need superuser privileges (root).

    netfilter is a set of system messages within the Linux kernel that allows kernel modules to register callback functions from the network stack. The registered callback function handles every packet passing through the network stack.

    The firewall in Linux is controlled by iptables, which has IPv4 filtering functions

    The # sign means that the command is executed as root. Open a console with root privileges beforehand - sudo -i on Debian-based systems or su on others.

    *Show status.

    # iptables -L -n -v
    

    Sample output of the command for an inactive firewall:

    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)  
     pkts bytes target prot opt in out source destination
    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)  
     pkts bytes target prot opt in out source destination
    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)  
     pkts bytes target prot opt in out source destination
    

    For an active firewall:

    Chain INPUT (policy DROP 0 packets, 0 bytes)  
     pkts bytes target prot opt in out source destination
        0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID
      394 43586 ACCEPT all -- * * 0.0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
       93 17292 ACCEPT all -- br0 * 0.0.0.0.0/0 0.0.0.0/0
        1 142 ACCEPT all -- lo * 0.0.0.0/0/0 0.0.0.0/0
    Chain FORWARD (policy DROP 0 packets, 0 bytes)  
     pkts bytes target prot opt in out source destination
        0 0 0 ACCEPT all -- br0 br0 0.0.0.0/0 0.0.0.0/0
        0 0 0 DROP all -- * * 0.0.0.0/0 0.0.0/0 state INVALID
        0 0 0 TCPMSS tcp -- * * * 0.0.0.0/0 0.0.0.0/0 tcp flags:0x06/0x02 TCPMSS clamp to PMTU
        0 0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0/0 state RELATED,ESTABLISHED
        0 0 0 wanin all -- -- vlan2 * 0.0.0.0/0 0.0.0.0/0
        0 0 0 wanout all -- * vlan2 0.0.0.0/0 0.0.0.0/0
        0 0 0 ACCEPT all -- br0 * 0.0.0.0/0 0.0.0.0/0
    Chain OUTPUT (policy ACCEPT 425 packets, 113K bytes)  
     pkts bytes target prot opt in out source destination
    Chain wanin (1 references)  
     pkts bytes target prot opt in out source destination
    Chain wanout (1 references)  
     pkts bytes target prot opt in out source destination
    

    Where:

    • L : Show list of rules.
    • v : Show additional information. This option shows the interface name, options, TOS mask. It also displays suffixes 'K', 'M' or 'G'.
    • n : Display IP address and port as numbers (without using a DNS server to define names. This will speed up the display).

    **Display rule list with line numbers

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

    Approximate output:

    Chain INPUT (policy DROP)  
    num target prot prot opt source destination  
    1 DROP all -- 0.0.0.0/0 0.0.0.0/0 state INVALID  
    2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED  
    3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0  
    4 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0  
    Chain FORWARD (policy DROP)  
    num target prot opt source destination  
    1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0  
    2 DROP all -- 0.0.0.0/0 0.0.0.0/0 state INVALID  
    3 TCPMSS tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x06/0x02 TCPMSS clamp to PMTU  
    4 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED  
    5 wanin all -- 0.0.0.0/0 0.0.0.0/0  
    6 wanout all -- 0.0.0.0/0 0.0.0.0/0  
    7 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0  
    Chain OUTPUT (policy ACCEPT)  
    num target prot opt source destination  
    Chain wanin (1 references)  
    num target prot opt source destination  
    Chain wanout (1 references)  
    num target prot opt source destination  
    

    You can use line numbers to add new rules.

    **Display the INPUT or OUTPUT of a rule chain

    # iptables -L INPUT -n -v
    # iptables -L OUTPUT -n -v --line-numbers
    

    *# Stop, start, restart the firewall

    By the system itself:

    # service ufw stop
    # service ufw start
    

    You can also use iptables commands to stop the firewall and remove all rules:

    # iptables -F
    # iptables -X
    # iptables -t nat -F
    # iptables -t nat -X
    # iptables -t mangle -F
    # iptables -t mangle -X
    # iptables -P INPUT ACCEPT
    # iptables -P OUTPUT ACCEPT
    # iptables -P FORWARD ACCEPT
    

    Where:

    • F : Remove (flush) all rules.
    • X : Remove the chain.
    • t table_name : Select a table (nat or mangle) and delete all rules.
    • P : Select the default action (such as DROP, REJECT, or ACCEPT).

    *Remove firewall rules

    To display the line number with existing rules:

    # iptables -L INPUT -n --line-numbers
    # iptables -L OUTPUT -n --line-numbers
    # iptables -L OUTPUT -n --line-numbers | less
    # iptables -L OUTPUT -n --line-numbers | grep 202.54.1.1
    

    We get a list of IP addresses. Just look at the number on the left and remove the corresponding line. For example for number 3:

    # iptables -D INPUT 3
    

    Or find the source IP address (202.54.1.1) and remove it from the rule:

    # iptables -D INPUT -s 202.54.1.1 -j DROP
    

    Where:

    • D : Remove one or more rules from the chain.

    Add rule to the firewall.

    To add one or more rules to a chain, we start by displaying a list using line numbers:

    # iptables -L INPUT -n --line-numbers
    

    Sample output:

    Chain INPUT (policy DROP)  
    num target prot opt source destination  
    1 DROP all -- 202.54.1.1 0.0.0/0  
    2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state NEW,ESTABLISHED  
    

    To insert a rule between line 1 and line 2:

    # iptables -I INPUT 2 -s 202.54.1.2 -j DROP
    

    Check if the rule has been updated:

    # iptables -L INPUT -n --line-numbers
    

    The output will go like this:

    Chain INPUT (policy DROP)  
    num target prot prot opt source destination  
    1 DROP all -- 202.54.1.1 0.0.0/0  
    2 DROP all -- 202.54.1.2 0.0.0/0  
    3 ACCEPT all -- 0.0.0.0/0 0.0.0/0 state NEW,ESTABLISHED  
    

    **Save firewall rules

    Through iptables-save:

    # iptables-save > /etc/iptables.rules
    

    *# Restore rules

    Through iptables-restore

    # iptables-restore < /etc/iptables.rules
    

    *# Set default policies

    To reset all traffic:

    # iptables -P INPUT DROP
    # iptables -P OUTPUT DROP
    # iptables -P FORWARD DROP
    # iptables -L -v -n
    

    After the above commands no packets will leave this host.

    # ping google.com
    

    **Block only incoming connections

    To drop all incoming packets not initiated by you, but allow outgoing traffic:

    # iptables -P INPUT DROP
    # iptables -P FORWARD DROP
    # iptables -P OUTPUT ACCEPT
    # iptables -A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT
    # iptables -L -v -n
    

    Outgoing packets and those that have been remembered within established sessions are allowed.

    # ping google.com
    

    *# Reset isolated network addresses on the public network

    # iptables -A INPUT -i eth1 -s 192.168.0.0/24 -j DROP
    # iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
    

    List of IP addresses for isolated networks:
    10.0.0.0/8 -j (A)
    172.16.0.0/12 (B)
    192.168.0.0/16 ©
    224.0.0.0/4 (MULTICAST D)
    240.0.0.0/5 (E)
    127.0.0.0/8 (LOOPBACK)

    ** Blocking a specific IP address

    To block burglar address 1.2.3.4:

    # iptables -A INPUT -s 1.2.3.4 -j DROP
    # iptables -A INPUT -s 192.168.0.0/24 -j DROP
    

    Block incoming port requests.

    To block all incoming port 80 requests:

    # iptables -A INPUT -p tcp --dport 80 -j DROP
    # iptables -A INPUT -i eth1 -p tcp --dport 80 -j DROP
    

    To block a port 80 request from address 1.2.3.4:

    # iptables -A INPUT -p tcp -s 1.2.3.4 --dport 80 -j DROP
    # iptables -A INPUT -i eth1 -p tcp -s 192.168.1.0/24 --dport 80 -j DROP
    

    **Block outgoing IP address requests

    To block a certain domain, find out its address:

    # host -t a facebook.com
    

    Conclusion: facebook.com has address 69.171.228.40
    Find the CIDR for 69.171.228.40:

    # whois 69.171.228.40 | grep CIDR
    

    Output:
    CIDR: 69.171.224.0/19

    Block access to 69.171.224.0/19:

    # iptables -A OUTPUT -p tcp -d 69.171.224.0/19 -j DROP
    

    You can also use the domain to block:

    # iptables -A OUTPUT -p tcp -d www.fаcebook.com -j DROP
    # iptables -A OUTPUT -p tcp -d  -j DROP
    

    Record the event and reset it.

    To log packet traffic before resetting, let's add a rule:

    # iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j LOG --log-prefix "IP_SPOOF A: "
    # iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
    

    Check the log (by default /var/log/messages):

    # tail -f /var/log/messages
    # grep -i --color 'IP SPOOF' /var/log/messages
    

    # Record the event and reset it (with a limit on the number of entries).*

    To avoid overfilling the partition with a bloated log, we will limit the number of entries using -m. For example, to record every 5 minutes a maximum of 7 lines:

    # iptables -A INPUT -i eth1 -s 10.0.0.0/8 -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix "IP_SPOOF A: "
    # iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
    

    **Reset or allow traffic from certain MAC addresses

    # iptables -A INPUT -m mac --mac-source 00:0F:EA:91:04:08 -j DROP
    ## *allow only for TCP port # 8080 with mac address 00:0F:EA:91:04:07 ##
    # iptables -A INPUT -p tcp --destination-port 22 -m mac --mac-source 00:0F:EA:91:04:07 -j ACCEPT
    

    *Allow or deny ICMP Ping requests

    Deny Icmp messages.
    It is also good practice to forbid ICMP messages which might give out additional information about the host or be used to perform various malicious actions (e.g., modifying the routing table). Below is a table with a list of possible ICMP message types:

    ICMP message types.

    0 - echo reply (echo ping)  
    3 - destination unreachable  
    4 - source quench  
    5 - redirect  
    8 - echo request  
    9 - router advertisement  
    10 - router solicitation  
    11 - time-to-live exceeded  
    12 - IP header bad  
    13 - timestamp request (timestamp value request)  
    14 - timestamp reply (request for timestamp value)  
    15 - information request  
    16 - information reply (request for information)  
    17 - address mask request  
    18 - address mask reply (request for netmask)  
    

    As you can see, replying to some ICMP messages may lead to disclosure of some host information, while others may lead to modification of the routing table, so they should be forbidden.

    Typically, ICMP messages 0, 3, 4, 11, and 12 are allowed out to the outside world, while only 3, 8, and 12 are allowed in. This is how it is implemented in different firewalls:

    Deny dangerous ICMP messages.

    iptables -A INPUT -p icmp --icmp-type 3,8,12 -j ACCEPT  
    iptables -A OUTPUT -p icmp --icmp-type 0,3,4,11,12 -j ACCEPT  
    

    To prohibit:

    # iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
    # iptables -A INPUT -i eth1 -p icmp --icmp-type echo-request -j DROP
    

    Allow for certain networks/hosts:

    # iptables -A INPUT -s 192.168.1.0/24 -p icmp --icmp-type echo-request -j ACCEPT
    

    Allow only part of the ICMP requests:

    ### ** it is assumed that the default policy for inbound is set to DROP ** ###
    # iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
    # iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
    # iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
    ## ** let us respond to the request ** ##
    # # iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
    
    • iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
    • iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
    • iptables -A INPUT -p icmp --icmp-type 12 -j ACCEPT

    • iptables -A OUTPUT -i eth0 -p icmp --icmp-type 0 -j ACCEPT

    **Open port range

    # iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 7000:7010 -j ACCEPT
    

    *Open a range of addresses

    ## allow connection to port 80 (Apache) if address range is 192.168.1.100 to 192.168.1.200 ##
    # iptables -A INPUT -p tcp --destination-port 80 -m iprange --src-range 192.168.1.100-192.168.1.200 -j ACCEPT
    
    ## example for nat ##
    # iptables -t nat -A POSTROUTING -j SNAT --to-source 192.168.1.20-192.168.1.25
    

    Close or open standard ports.

    Replace ACCEPT with DROP to block the port.

    ## ssh tcp port 22 ##
    iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT  
    iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT  
    
    ## cups (printing service) udp/tcp port 631 for local network ##
    iptables -A INPUT -s 192.168.1.0/24 -p udp -m udp --dport 631 -j ACCEPT  
    iptables -A INPUT -s 192.168.1.0/24 -p tcp -m tcp --dport 631 -j ACCEPT  
    
    ## time sync via NTP for local network (udp port 123) ##
    iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 123 -j ACCEPT  
    
    ## tcp port 25 (smtp) ##
    iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j ACCEPT  
    
    # dns server ports ##
    iptables -A INPUT -m state --state NEW -p udp --dport 53 -j ACCEPT  
    iptables -A INPUT -m state --state NEW -p tcp --dport 53 -j ACCEPT  
    
    ## http/https www server port ##
    iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT  
    iptables -A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT  
    
    ## tcp port 110 (pop3) ##
    iptables -A INPUT -m state --state NEW -p tcp --dport 110 -j ACCEPT  
    
    ## tcp port 143 (imap) ##
    iptables -A INPUT -m state --state NEW -p tcp --dport 143 -j ACCEPT  
    
    ## Samba file server for local network ##
    iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 137 -j ACCEPT  
    iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 138 -j ACCEPT  
    iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 139 -j ACCEPT  
    iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 445 -j ACCEPT  
    
    ## proxy server for local network ##
    iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 3128 -j ACCEPT  
    
    ## mysql server for local network ##
    iptables -I INPUT -p tcp --dport 3306 -j ACCEPT  
    

    *Limit the number of concurrent connections to the server for one address

    The connlimit module is used for restrictions. To allow only 3 ssh connections per client:

    # iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 3 -j REJECT
    

    Set the number of HTTP requests to 20:

    # iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 -connlimit-mask 24 -j DROP
    

    Where:

    • connlimit-above 3 : Specifies that the rule is valid only if the number of connections exceeds 3.
    • connlimit-mask 24 : Specifies the network mask.