Packet Flow

ASCII

Original by Tachtler.

ASCII (Simplified)

From the Advanced Routing Howto.

Flush Tables

Can be used at the start of the script.

# Flush tables
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X

Common Attack Protections

# Block w00tw00t
iptables -A INPUT -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t.at.ISC.SANS.' -j DROP
# Block DNS ANY
iptables -A INPUT -p udp --dport 53 -m string --from 50 --algo bm --hex-string '|0000FF0001|' -m recent --set --name dnsanyquery
iptables -A INPUT -p udp --dport 53 -m string --from 50 --algo bm --hex-string '|0000FF0001|' -m recent --name dnsanyquery --rcheck --seconds 10 --hitcount 3 -j DROP

Spoofed Packets

## Reject packets from RFC1918 class networks (i.e., spoofed)
## Your internal network should be commented, any unused classes
## should be blocked by removing the comment.
 
#iptables -A INPUT -s 169.254.0.0/16 -j DROP
#iptables -A INPUT -s 192.168.0.0/16 -j DROP
#iptables -A INPUT -s 172.16.0.0/12  -j DROP
 
#iptables -A INPUT -s 127.0.0.0/8    -j DROP
iptables -A INPUT -s 224.0.0.0/4      -j DROP
iptables -A INPUT -d 224.0.0.0/4      -j DROP
iptables -A INPUT -s 240.0.0.0/5      -j DROP
iptables -A INPUT -d 240.0.0.0/5      -j DROP
#iptables -A INPUT -s 0.0.0.0/8        -j DROP
#iptables -A INPUT -d 0.0.0.0/8        -j DROP
iptables -A INPUT -d 239.255.255.0/24 -j DROP
#iptables -A INPUT -d 255.255.255.255  -j DROP

Packet Flood Protections

The following rules should block and limit most packet-related attacks.

# NEW TCP packets must have SYN
iptables -A INPUT -p tcp -m state --state NEW ! --syn -j DROP
# Block SYN-flood
iptables -A INPUT -p tcp -m state --state NEW -m limit --limit 2/second --limit-burst 2 -j ACCEPT
# Packet fragments (Teardrop, etc...)
iptables -A INPUT --fragment -j DROP
# Block Smurf
iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP
iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP
# Ping of Death
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 3/s -m length --length 60:65535 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT
# Block Fraggle
iptables -A INPUT -p udp -m pkttype --pkt-type broadcast -j DROP
iptables -A INPUT -p udp -m limit --limit 3/s -j ACCEPT
# Drop bad TCP flags (XMAS, NULL)
iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
iptables -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
# Drop all invalid packets
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP

You can also increase the recent table size (in this case, to 1000 entries), since on Linux it is fixed to 100 entries:

cat >> /etc/modprobe.d/xt_recent.conf << EOF
options xt_recent ip_pkt_list_tot=1000 ip_list_tot=1000
EOF

Service Flood Protection

Brute-force authentication attacks should be mitigated using sshguard that dynamically bans offending connections for most common services. The rule below can be used to limit connections to service ports that do not necessarily involve authentication.

# SERVICE_PORT, SERVICE_CONNECTION_RATE, SERVICE_CONNECTION_RATE_BURST, SERVICE_NAME, EXPIRE_TIME
# have to be substituted. Some reasonable values are given in the table below.
iptables -t mangle -A PREROUTING -p SERVICE_PROTOCOL --dport SERVICE_PORT -m state --state NEW \
        -m hashlimit --hashlimit-above SERVICE_CONNECTION_RATE --hashlimit-burst SERVICE_CONNECTION_RATE_BURST \
        --hashlimit-htable-expire EXPIRE_TIME --hashlimit-name SERVICE_NAME --hashlimit-mode srcip -j DROP

Here is a reference of some decent settings:

SERVICE_PORT SERVICE_PROTOCOL SERVICE_CONNECTION_RATE SERVICE_CONNECTION_RATE_BURST SERVICE_NAME
80 tcp 45/sec 60 http
22 tcp 5/sec 7 ssh
1723 tcp 5/sec 10 pptp
25 tcp 5/minute 10 smtp

Note that EXPIRE_TIME has to be defined and represents the time in milliseconds after which the entries expire.

The reason to perform checking in mangle on the PREROUTING chain is that these limits will be enforced before any nat-ing rules apply. Otherwise if we were to perform the same on the INPUT chain, only the packets with the current machine as destination would be limited.

For reference, hashlimit match has the following possible parameters:

  --hashlimit-upto            max average match rate
                                   [Packets per second unless followed by
                                   /sec /minute /hour /day postfixes]
  –hashlimit-above           min average match rate
  –hashlimit-mode           mode is a comma-separated list of
                                   dstip,srcip,dstport,srcport (or none)
  –hashlimit-srcmask      source address grouping prefix length
  –hashlimit-dstmask      destination address grouping prefix length
  –hashlimit-name           name for /proc/net/ipt_hashlimit
  –hashlimit-burst 	    number to match in a burst, default 5
  –hashlimit-htable-size     number of hashtable buckets
  –hashlimit-htable-max      number of hashtable entries
  –hashlimit-htable-gcinterval    interval between garbage collection runs
  –hashlimit-htable-expire        after which time are idle entries expired?

Clamp to MSS

iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o EXTERNAL_IF -j TCPMSS --clamp-mss-to-pmtu
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

where EXTERNAL_IF should be the external, outbound interface.

Bypass ISP NAT Detection

NAT can be detected by ISPs by measuring the TTL of packets on the network. Every gateway along the path decreases the TTL so it is easy to determine that NAT is being used if packets coming from a network have a different TTL value.

The following rule clamps the TTL to 128 on the OUTPUT chain:

iptables -t mangle -A OUTPUT -j TTL --ttl-set 128

Log WOL Packets

The string matcher from iptables can be used:

iptables -I INPUT 1 -p udp -m string --algo bm --hex-string '|FF FF FF FF FF FF|' -j LOG --log-prefix '[WOL]' --log-level DEBUG

The rule can be made stronger by extending the hex-string with the actual MAC address of the destination machine.

Remember, WOL packets are meant to be received by the machine when it is powered off and that iptables only works when the machine is powered on. More details about Wake-On-Lan can be found on the wake on lan page.

TARPIT

The TARPIT target of iptables (as an analogy to moats around castles) captures and holds incoming TCP connections using no local resources. Connections are accepted and then switched to the persist state (0 byte window) in which the remote side stops sending data and asks to continue every 60 to 270 seconds. Attempts from the remote side to close a connection are ignored wich forces the remote connection to timeout in 12 to 24 minutes.

For example, to tarpit all incoming connections from 134.45.233.16, you would issue:

iptables -A INPUT -p tcp -s 134.45.233.16 -j TARPIT

Restricting Interface Access to User Processes

Suppose that you have a beachhead on a server with a VPN service on the server that uses an interface and that you would like to restrict any traffic from that interface to the other end of your VPN to a set of users.

A sketch of what you would like to achieve is the following:

where:

  • you would like to allow all the traffic from your own server to the beachhead,
  • you would only like to allow the traffic belonging to certain users to your own server.

Suppose that the interface on the beachhead server is tap0 and that you would like to allow traffic from the beachhead server to your server for the users having the UID (from /etc/passwd) 0 (root), 1000 (some user), 1001 (some other user).

In that case, we can use ipt_owner. First, append ipt_owner to /etc/modules and then create the following iptables rules:

iptables -N OUT_TAP0
iptables -A OUTPUT -o tap0 -m owner --uid-owner 0 -j OUT_TAP0
iptables -A OUTPUT -o tap0 -m owner --uid-owner 1000 -j OUT_TAP0
iptables -A OUTPUT -o tap0 -m owner --uid-owner 1001 -j OUT_TAP0
iptables -A OUT_TAP0 -j ACCEPT
iptables -A OUTPUT -o tap0 ! -p icmp -j DROP

The rules create a jump table on the OUTPUT chain that accepts traffic from the processes with UID 0, 1000, 1001 and drops all other traffic through tap0 except ICMP (useful for testing).

Block Attacks with Emerging Threats

The following script pulls a fresh lists of hosts to block from Emerging Threats and adds firewall rules to block the retrieved IPs. The script is re-entry safe - so, suitable to be run via cron. You can drop the script in the /etc/cron.daily folder and it will recreate the block list every day.

The script relies on the following tools:

  • ipset,
  • curl,
  • egrep

all of which should be available to install via the distribution's package manager.

emerging-threats
#!/usr/bin/env bash
###########################################################################
##  Copyright (C) Wizardry and Steamworks 2020 - License: GNU GPLv3      ##
###########################################################################
# Downloads from emergingthreats.net and adds all the networks to ipset. ##
###########################################################################
## Possible firewall configuration:
## Delete all the old rules.
#I=`/sbin/iptables-save | grep -- "-A INPUT -j EMERGING-THREATS"`
#O=`/sbin/iptables-save | grep -- "-A OUTPUT -j EMERGING-THREATS"`
#if [ ! -z "$I" ] || [ ! -z "$O" ]; then
#    /sbin/iptables -F EMERGING-THREATS
#    /sbin/iptables -X EMERGING-THREATS
#fi
#if [ ! -z "$I" ]; then
#    /sbin/iptables -D INPUT -j EMERGING-THREATS
#fi
#if [ ! -z "$O" ]; then
#    /sbin/iptables -D OUTPUT -j EMERGING-THREATS
#fi
## Create the chain again and add all the new rules.
#/sbin/iptables -N EMERGING-THREATS
#/sbin/iptables -I INPUT 1 -j EMERGING-THREATS
#/sbin/iptables -I OUTPUT 1 -j EMERGING-THREATS
#/sbin/iptables -A EMERGING-THREATS -p all -m set --match-set EMERGING-THREATS src,dst -j DROP
## Continue with the rest.
#/sbin/iptables -A EMERGING-THREATS -j RETURN
###########################################################################
 
`ipset list EMERGING-THREATS 2>/dev/null >/dev/null`
if [ $? = 1 ]; then
    ipset create EMERGING-THREATS hash:net family inet
fi
ipset flush EMERGING-THREATS
for net in `curl -s http://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt | \
    egrep '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/*[0-9]{0,2}'`; do
    ipset add EMERGING-THREATS $net
done

To use, simply copy the script to /etc/cron.hourly and then insert the iptables rules at the top into the existing firewall.

Block Attacks with FireHOL Level 1 IP Abuse List

The FireHOL level 1 list is a general purpose list that can be used to block various flavours of attacks including ransomeware reported IP addresses. Contrary to the emerging threats list, The FireHOL level 1 list is updated on average every half an hour such that the script presented here is best placed in /etc/cron.hourly.

The script will additionally filter the FireHOL level 1 list of IPs and networks through a list of private and reserved IPs in order to not block local networks. It uses ipsets for speed and creates a separate chain to keep the iptables rules well organized.

The script relies on the following tools:

  • ipset,
  • curl
  • egrep,
  • awk
firehol-level1
#!/usr/bin/env bash
###########################################################################
##  Copyright (C) Wizardry and Steamworks 2020 - License: GNU GPLv3      ##
###########################################################################
# Downloads the FireHOL level 1 list and adds all networks to an IP set. ##
###########################################################################
## Possible firewall configuration:
## Delete all the old rules.
#I=`/sbin/iptables-save | grep -- "-A INPUT -j FIREHOL-LEVEL1"`
#O=`/sbin/iptables-save | grep -- "-A OUTPUT -j FIREHOL-LEVEL1"`
#if [ ! -z "$I" ] || [ ! -z "$O" ]; then
#    /sbin/iptables -F FIREHOL-LEVEL1
#    /sbin/iptables -X FIREHOL-LEVEL1
#fi
#if [ ! -z "$I" ]; then
#    /sbin/iptables -D INPUT -j FIREHOL-LEVEL1
#fi
#if [ ! -z "$O" ]; then
#    /sbin/iptables -D OUTPUT -j FIREHOL-LEVEL1
#fi
## Create the chain again and add all the new rules.
#/sbin/iptables -N FIREHOL-LEVEL1
#/sbin/iptables -I INPUT 1 -j FIREHOL-LEVEL1
#/sbin/iptables -I OUTPUT 1 -j FIREHOL-LEVEL1
#/sbin/iptables -A FIREHOL-LEVEL1 -p all -m set --match-set FIREHOL-LEVEL1 src,dst -j DROP
## Continue with the rest.
#/sbin/iptables -A FIREHOL-LEVEL1 -j RETURN
###########################################################################
 
# Cleanup routine to delete bogon and firehol list on termination.
trap '{
 
# Delete the temporary bogon and firehol lists.
for i in $BOGONS_LIST $FIREHOL_LIST; do
    if [ -f $i ]; then
        rm $i
    fi
done
 
}' KILL QUIT TERM EXIT INT HUP
 
# Delete current set.
`ipset list FIREHOL-LEVEL1 2>/dev/null >/dev/null`
if [ $? = 1 ]; then
    # Create the set.
    ipset create FIREHOL-LEVEL1 hash:net family inet
fi
 
# Flush the existing IPs.
ipset flush FIREHOL-LEVEL1
 
# Generate a list of private subnet IP addresses defined by
# RFC 1918, RFC 5735, and RFC 6598.
BOGONS_LIST=`mktemp`
cat > $BOGONS_LIST <<EOF
0.0.0.0/8
10.0.0.0/8
100.64.0.0/10
127.0.0.0/8
169.254.0.0/16
172.16.0.0/12
192.0.0.0/24
192.0.2.0/24
192.168.0.0/16
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
224.0.0.0/3
EOF
 
# Download the firehol netset level 1
FIREHOL_LIST=`mktemp`
# Force curl to fail for anything other than HTTP 200
curl -q -f -s 'https://iplists.firehol.org/files/firehol_level1.netset' > $FIREHOL_LIST 2>/dev/null
# Check that curl completed successfully and that the list is not empty.
if [ $? != 0 ] || [ -z $FIREHOL_LIST ]; then
    echo 'FireHOL Level 1 Netset list could not be downloaded.'
    exit
fi
 
# Filter the firehol netset through the bogon list and also filter out valid
# IP and net blocks. Add the results to the created IP set.
for net in `awk '{if (f==1) { r[$0] } else if (! ($0 in r)) { print $0 } } ' f=1 $BOGONS_LIST f=2 $FIREHOL_LIST | \
    egrep '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/*[0-9]{0,2}'`; do
    ipset add FIREHOL-LEVEL1 $net
done

To use, simply copy the script to /etc/cron.hourly and then insert the iptables rules at the top into the existing firewall.

Delete a Single Rule

A single rule can be deleted by specifying either:

  • the rule number (of the chain)
  • the entire rule

using the -D parameter passed to iptables.

For instance, to remove the IP address 199.233.85.0 contained inside the EMERGING chain, issue:

iptables -L -n --line-numbers | grep 199.233.85.0 | awk '{ print $1 }' | xargs iptables -D EMERGING

The command will:

  • display the iptables rules (-L),
  • without attempting to resolve the IP addresses to names (-n),
  • by printing the rule number in each chain –line-numbers

and will then match the IP address 199.233.85.0 and filter out the first number (which will be the rule number) via awk. The number is then piped into xargs that will make iptables delete the rule corresponding to the passed number inside the EMERGING chain.

A longer variant that lets you specify the IP address on the command line and then takes care to remove that IP address from all the chains is the following procedure:

  1. declare the IP address to remove
    IP=83.141.2.155
  2. use the following snippet to remove the IP address from all chains
    iptables -n -L --line-numbers | \
    grep -oP "((?<=Chain\s)(.+?)\s)|(^[0-9]+(?=.+?$IP))" | \
    xargs | \
    grep -oP '([^\s]+?)\s([0-9]+)' | \
    xargs -l sh -c 'iptables -D $0 $1'

Create Country IP Sets Without GeoIP

Leveraging the pure shell JSON parser, a script can be placed in crontab in order to maintain country IP lists in the form of IP sets.

generate-country-ip-sets.sh
#!/usr/bin/env bash
###########################################################################
##  Copyright (C) Wizardry and Steamworks 2020 - License: GNU GPLv3      ##
###########################################################################
# Downloads the IP blocks for selected countries and creates IP sets.    ##
###########################################################################
 
###########################################################################
##                            CONFIGURATION                              ##
###########################################################################
 
# Generate IP sets for the following country codes.
COUNTRY_CODES=( sv )
 
###########################################################################
##                              INTERNALS                                ##
###########################################################################
 
JSON_BASH_PARSER=$(cat <<EOF
cigpIHsgaWYgWyAtdCAwIF07IHRoZW4gYj0kKHN0dHkgLWcpOyBzdHR5IC1pY2Fub24gLWVjaG8g
bWluIDEgdGltZSAwOyBmaTsgYz0kKGRkIGJzPTEgY291bnQ9MSBjb252PW5vZXJyb3Isc3luYyAy
Pi9kZXYvbnVsbCk7IGlmIFsgLXQgMCBdOyB0aGVuIHN0dHkgIiRiIjsgZmk7IH07IGUoKSB7IGVj
aG8gIiQxPSQyIjsgfTsgYSgpIHsgbG9jYWwgZD0iJHsxOiskMS59JDIiOyBsb2NhbCBmPSJ1Ijsg
bG9jYWwgZz0wOyB3aGlsZSBbICIkaCIgLWx0ICIkaiIgXTsgZG8gWyAiJGkiID0gIjAiIF0gJiYg
aD0kKChoICsgMSkpICYmIHIgYzsgaT0wOyBjPSR7YzotJyAnfTsgY2FzZSAiJGYiIGluICJ1Iikg
Y2FzZSAiJGMiIGluICd7JykgbyAiJGQiICIkZyI7IGY9ImwiOyA7OyAnXScpIHJldHVybjsgOzsg
W1widGZURlwtMC05XSkgaT0xOyB2ICIkZCIgIiRnIjsgaT0xOyBmPSJsIjsgOzsgZXNhYyA7OyAi
bCIpIFsgIiRjIiA9ICIsIiBdICYmIGc9JCgoZyArIDEpKSAmJiBmPSJ1IjsgWyAiJGMiID0gIl0i
IF0gJiYgcmV0dXJuOyA7OyBlc2FjIGRvbmUgfTsgdigpIHsgbG9jYWwgZD0iJHsxOiskMS59JDIi
OyBsb2NhbCBmPSJ1Ijsgd2hpbGUgWyAiJGgiIC1sdCAiJGoiIF07IGRvIFsgIiRpIiA9ICIwIiBd
ICYmIGg9JCgoaCArIDEpKSAmJiByIGM7IGk9MDsgYz0ke2M6LScgJ307IGNhc2UgIiRmIiBpbiAi
dSIpIGNhc2UgIiRjIiBpbiAnIicpIGY9InoiOyBrPSIiOyA7OyBbXC0wLTldKSBmPSJ5Ijsgaz0i
JGMiOyA7OyBbdGZURl0pIGY9IngiOyBrPSIkYyI7IDs7ICJbIikgYSAiIiAiJGQiOyByZXR1cm47
IDs7ICJ7IikgbyAiIiAiJGQiOyByZXR1cm47IDs7IGVzYWMgOzsgInoiKSBjYXNlICIkYyIgaW4g
JyInKSBbICIkbSIgPSAiMCIgXSAmJiBlICIkZCIgIiRrIiAmJiByZXR1cm47IFsgIiRtIiA9ICIx
IiBdICYmIGs9IiRrJGMiICYmIG09MDsgOzsgJ1wnKSBbICIkbSIgPSAiMSIgXSAmJiBrPSIkayRj
IjsgbT0kKCgxIC0gbSkpOyA7OyAqKSBtPTA7IGs9IiRrJGMiOyA7OyBlc2FjIDs7ICJ5IikgY2Fz
ZSAiJGMiIGluIFssXF19XSkgZSAiJGQiICIkayI7IGk9MTsgcmV0dXJuIDs7IFtcLTAtOS5dKSBr
PSIkayRjIjsgOzsgZXNhYyA7OyAieCIpIGNhc2UgIiRjIiBpbiBbLFxdfV0pIGUgIiRkIiAiJGsi
OyBpPTE7IHJldHVybjsgOzsgW2EtekEtWl0pIGs9IiRrJGMiOyA7OyBlc2FjIDs7IGVzYWMgZG9u
ZSB9OyBvKCkgeyBsb2NhbCBkPSIkezE6KyQxLn0kMiI7IGxvY2FsIGY9InUiOyB3aGlsZSBbICIk
aCIgLWx0ICIkaiIgXTsgZG8gWyAiJGkiID0gIjAiIF0gJiYgaD0kKChoICsgMSkpICYmIHIgYzsg
aT0wOyBjPSR7YzotJyAnfTsgY2FzZSAiJGYiIGluICJ1IikgWyAiJGMiID0gIn0iIF0gJiYgcmV0
dXJuOyBbICIkYyIgPSAiXCIiIF0gJiYgZj0idyIgJiYgbj0iIiAmJiBtPTA7IDs7ICJ3IikgY2Fz
ZSAiJGMiIGluICciJykgWyAiJG0iID0gIjAiIF0gJiYgZj0icCI7IFsgIiRtIiA9ICIxIiBdICYm
IG49IiRuJGMiICYmIG09MDsgOzsgJ1wnKSBtPSQoKDEgLSBtKSk7IG49IiRuJGMiOyA7OyAqKSBt
PTA7IG49IiRuJGMiOyA7OyBlc2FjIDs7ICJwIikgWyAiJGMiID0gIjoiIF0gJiYgdiAiJGQiICIk
biIgJiYgZj0icSI7IDs7ICJxIikgWyAiJGMiID0gJywnIF0gJiYgZj0idSI7IFsgIiRjIiA9ICd9
JyBdICYmIHJldHVybjsgOzsgZXNhYyBkb25lIH07IHMoKSB7IGg9MDsgaT0wOyB3aGlsZSBbICIk
aCIgLWx0ICIkaiIgXTsgZG8gciBjOyBjPSR7YzotJyAnfTsgaD0kKChoICsgMSkpOyBbICIkYyIg
PSAieyIgXSAmJiBvICIiICIiICYmIHJldHVybjsgWyAiJGMiID0gIlsiIF0gJiYgYSAiIiAiIiAm
JiByZXR1cm47IGRvbmUgfTsganNvbigpIHsgaWYgWyAteiAiJEAiIF07IHRoZW4gdD0kKGNhdCAt
KTsgZWxzZSB0PSQoZWNobyAiJEAiKTsgZmk7IGo9IiR7I3R9IjsgZWNobyAiJHt0fSIgfCBzOyB9
Cgo=
EOF
)
 
eval `printf '%s\n' "$JSON_BASH_PARSER" | base64 -d`
 
for i in ${!COUNTRY_CODES[*]}; do
    COUNTRY=${COUNTRY_CODES[$i]}
    # Create or purge IPv4/6 for configured countries.
    for FAMILY in inet inet6; do
        SET_NAME=$COUNTRY"-"$FAMILY
        `ipset list $SET_NAME 2>/dev/null >/dev/null`
        if [ $? = 1 ]; then
            ipset create $SET_NAME hash:net family $FAMILY
        fi
        ipset flush $SET_NAME
    done
    curl -s -o - 'https://stat.ripe.net/data/country-resource-list/data.json?v4_format=prefix;resource='$COUNTRY | \
        json | \
        while read LINE; do 
            K=$(echo $LINE | awk -F'=' '{ print $1 }')
            V=$(echo $LINE | awk -F'=' '{ print $2 }')
            if [ "$K" = "status" ] && [ "$V" != "ok" ]; then
                for FAMILY in inet inet6; do
                    ipset destroy $COUNTRY"-"$FAMILY 2>/dev/null >/dev/null
                done
                continue
            fi
            case $( echo "$K" | cut -c 1-19 ) in
                "data.resources.ipv4")
                    ipset add $COUNTRY"-inet" $V
                    ;;
                "data.resources.ipv6")
                    ipset add $COUNTRY"-inet6" $V
                    ;;
            esac
    done
done

The generate-country-ip-sets.sh script presented above will create 8 separate lists, 2 lists per country for both IPv4 and IPv6 using a list of countries COUNTRY_CODES adjustable in the configuration section of the script.

PeerBlock Level 1

PeerBlock is a list of agencies dealing with copyright protection. The following script can be used to create an IP set and batch-block all of them.

#!/usr/bin/env bash
###########################################################################
##  Copyright (C) Wizardry and Steamworks 2023 - License: GNU GPLv3      ##
###########################################################################
# Downloads peerblock level 1 and adds all the networks to ipset.        ##
###########################################################################
## Possible firewall configuration:
## Delete all the old rules.
#I=`/sbin/iptables-save | grep -- "-A INPUT -j PEERBLOCK-LEVEL1"`
#O=`/sbin/iptables-save | grep -- "-A OUTPUT -j PEERBLOCK-LEVEL1"`
#if [ ! -z "$I" ] || [ ! -z "$O" ]; then
#    /sbin/iptables -F PEERBLOCK-LEVEL1
#    /sbin/iptables -X PEERBLOCK-LEVEL1
#fi
#if [ ! -z "$I" ]; then
#    /sbin/iptables -D INPUT -j PEERBLOCK-LEVEL1
#fi
#if [ ! -z "$O" ]; then
#    /sbin/iptables -D OUTPUT -j PEERBLOCK-LEVEL1
#fi
## Create the chain again and add all the new rules.
#/sbin/iptables -N PEERBLOCK-LEVEL1
#/sbin/iptables -I INPUT 1 -j PEERBLOCK-LEVEL1
#/sbin/iptables -I OUTPUT 1 -j PEERBLOCK-LEVEL1
#/sbin/iptables -A PEERBLOCK-LEVEL1 -p all -m set --match-set PEERBLOCK-LEVEL1 src,dst -j DROP
## Continue with the rest.
#/sbin/iptables -A PEERBLOCK-LEVEL1 -j RETURN
###########################################################################
 
`ipset list PEERBLOCK-LEVEL1 2>/dev/null >/dev/null`
if [ $? = 1 ]; then
    ipset create PEERBLOCK-LEVEL1 hash:net maxelem 262144 family inet
fi
ipset flush PEERBLOCK-LEVEL1
curl -s -L "http://list.iblocklist.com/?list=bt_level1&amp;fileformat=p2p&amp;archiveformat=gz" -o - |
    gunzip |
    cut -d: -f2 |
    grep -E "^[-0-9.]+$" |
    awk '{print "add PEERBLOCK-LEVEL1 "$1}' |
    ipset restore -exist

Ideally, this script could be placed in /etc/cron.daily in order to daily refresh the set of IPs.

Banning Countries on Debian

On Debian, the procedure to obtain the geoip iptables module is to install the packages:

  • xtables-addons-dkms,
  • xtables-addons-common,
  • libtext-csv-xs-perl

With the packages installed, there are some tools under /usr/lib/exec/xtables-addons that can be used to both download a geoip database as well as create the necessary mappings in order to be able to block countries. The tools are the following:

  • xt_geoip_dl,
  • xt_geoip_build

and:

  • xt_geoip_dl_maxmind,
  • xt_geoip_build_maxmind

and can be used in pairs in order to generate a database for iptables. The procedure is to first issue:

xt_geoip_dl

in order to download a database, followed by:

xt_geoip_build

in order to build the lookup table for the iptables geoip module.

Note that xt_geoip_dl_maxmind will require a license file to be supplies as the first parameter in order to download the MaxMind database.

The last command, xt_geoip_build will generate iv4 and iv6 files in the current directory and they will have to be moved into /usr/share/xt_geoip/:

mkdir -p /usr/share/xt_geoip/
mv *.iv4 *.iv6 /usr/share/xt_geoip

fuss/iptables.txt · Last modified: 2023/08/02 00:05 by office

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.