This shows you the differences between two versions of the page.
Previous revisionNext revision | |||
— | fuss:iptables [2020/02/16 21:28] – [Create Country IP Sets Without GeoIP] office | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Packet Flow ====== | ||
+ | {{fuss_iptables_flow_through_netfilter.svg? | ||
+ | |||
+ | ===== Abridged Version ===== | ||
+ | |||
+ | {{fuss_iptables_flow_through_netfilter_abridged.png? | ||
+ | |||
+ | ===== ASCII ===== | ||
+ | |||
+ | Original by [[http:// | ||
+ | |||
+ | < | ||
+ | Packet | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | ↓ | ||
+ | mangle | ||
+ | PREROUTING | ||
+ | | | ||
+ | | | ||
+ | ↓ | ||
+ | nat | ||
+ | PREROUTING | ||
+ | | | ||
+ | ↓ | ||
+ | +————————→+ | ||
+ | filter | ||
+ | FORWARD | ||
+ | | | ||
+ | | | ||
+ | | | ||
+ | +——————————————————————————————————————————→+————————→+ | ||
+ | | | ||
+ | ↓ | ||
+ | Packet | ||
+ | </ | ||
+ | ====== Flush Tables ====== | ||
+ | |||
+ | Can be used at the start of the script. | ||
+ | |||
+ | <code bash> | ||
+ | # 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 ====== | ||
+ | |||
+ | <code bash> | ||
+ | # Block w00tw00t | ||
+ | iptables -A INPUT -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET / | ||
+ | # Block DNS ANY | ||
+ | iptables -A INPUT -p udp --dport 53 -m string --from 50 --algo bm --hex-string ' | ||
+ | iptables -A INPUT -p udp --dport 53 -m string --from 50 --algo bm --hex-string ' | ||
+ | </ | ||
+ | |||
+ | ====== Spoofed Packets ====== | ||
+ | |||
+ | <code bash> | ||
+ | ## 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/ | ||
+ | #iptables -A INPUT -s 192.168.0.0/ | ||
+ | #iptables -A INPUT -s 172.16.0.0/ | ||
+ | |||
+ | #iptables -A INPUT -s 127.0.0.0/ | ||
+ | iptables -A INPUT -s 224.0.0.0/ | ||
+ | iptables -A INPUT -d 224.0.0.0/ | ||
+ | iptables -A INPUT -s 240.0.0.0/ | ||
+ | iptables -A INPUT -d 240.0.0.0/ | ||
+ | #iptables -A INPUT -s 0.0.0.0/ | ||
+ | #iptables -A INPUT -d 0.0.0.0/ | ||
+ | iptables -A INPUT -d 239.255.255.0/ | ||
+ | #iptables -A INPUT -d 255.255.255.255 | ||
+ | </ | ||
+ | |||
+ | ====== Packet Flood Protections ====== | ||
+ | |||
+ | The following rules should block and limit most packet-related attacks. | ||
+ | |||
+ | <code bash> | ||
+ | # 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, | ||
+ | iptables -A INPUT -p tcp --tcp-flags ALL SYN, | ||
+ | # 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: | ||
+ | |||
+ | <code bash> | ||
+ | cat >> / | ||
+ | options xt_recent ip_pkt_list_tot=1000 ip_list_tot=1000 | ||
+ | EOF | ||
+ | </ | ||
+ | |||
+ | ====== Service Flood Protection ====== | ||
+ | |||
+ | Brute-force authentication attacks should be mitigated using [[unix: | ||
+ | |||
+ | <code bash> | ||
+ | # SERVICE_PORT, | ||
+ | # 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: | ||
+ | |||
+ | ^ '' | ||
+ | | '' | ||
+ | | '' | ||
+ | | '' | ||
+ | | '' | ||
+ | |||
+ | Note that '' | ||
+ | |||
+ | The reason to perform checking in '' | ||
+ | |||
+ | For reference, '' | ||
+ | < | ||
+ | --hashlimit-upto | ||
+ | | ||
+ | /sec /minute /hour /day postfixes] | ||
+ | –hashlimit-above | ||
+ | –hashlimit-mode | ||
+ | | ||
+ | –hashlimit-srcmask | ||
+ | –hashlimit-dstmask | ||
+ | –hashlimit-name | ||
+ | –hashlimit-burst number to match in a burst, default 5 | ||
+ | –hashlimit-htable-size | ||
+ | –hashlimit-htable-max | ||
+ | –hashlimit-htable-gcinterval | ||
+ | –hashlimit-htable-expire | ||
+ | </ | ||
+ | |||
+ | ====== Clamp to MSS ====== | ||
+ | |||
+ | <code bash> | ||
+ | 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 '' | ||
+ | |||
+ | |||
+ | ====== Bypass ISP NAT Detection ====== | ||
+ | |||
+ | '' | ||
+ | |||
+ | The following rule clamps the TTL to '' | ||
+ | |||
+ | <code bash> | ||
+ | iptables -t mangle -A OUTPUT -j TTL --ttl-set 128 | ||
+ | </ | ||
+ | |||
+ | ====== Log WOL Packets ====== | ||
+ | |||
+ | The '' | ||
+ | |||
+ | <code bash> | ||
+ | iptables -I INPUT 1 -p udp -m string --algo bm --hex-string '|FF FF FF FF FF FF|' -j LOG --log-prefix ' | ||
+ | </ | ||
+ | |||
+ | 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 '' | ||
+ | |||
+ | ====== TARPIT ====== | ||
+ | |||
+ | The '' | ||
+ | |||
+ | For example, to tarpit all incoming connections from '' | ||
+ | |||
+ | <code bash> | ||
+ | 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: | ||
+ | |||
+ | < | ||
+ | |||
+ | | ||
+ | | BeachHead | Allow all traffic | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | </ | ||
+ | |||
+ | 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 '' | ||
+ | |||
+ | In that case, we can use '' | ||
+ | <code bash> | ||
+ | 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 '' | ||
+ | |||
+ | ====== Block Attacks with Emerging Threats ====== | ||
+ | |||
+ | The following script pulls a fresh lists of hosts to block from [[http:// | ||
+ | |||
+ | The script relies on the following tools: | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | all of which should be available to install via the distribution' | ||
+ | |||
+ | <file bash emerging-threats> | ||
+ | #! /bin/sh | ||
+ | ########################################################################### | ||
+ | ## Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 ## | ||
+ | ########################################################################### | ||
+ | # Downloads from emergingthreats.net and blocks all the IPs in the list. ## | ||
+ | ########################################################################### | ||
+ | |||
+ | # Delete all the old rules. | ||
+ | JUMP=`iptables-save | grep -- "-A INPUT -j EMERGING" | ||
+ | if [ ! -z " | ||
+ | iptables -D INPUT -j EMERGING | ||
+ | iptables -F EMERGING | ||
+ | iptables -X EMERGING | ||
+ | fi | ||
+ | |||
+ | # Create the set chain. | ||
+ | iptables -N EMERGING | ||
+ | iptables -I INPUT 1 -j EMERGING | ||
+ | |||
+ | # Delete current set. | ||
+ | EMERGING=`ipset list EMERGING 2>/ | ||
+ | if [ $? = 1 ]; then | ||
+ | # Create the set. | ||
+ | ipset create EMERGING hash:net | ||
+ | |||
+ | fi | ||
+ | |||
+ | # Flush the existing IPs. | ||
+ | ipset flush EMERGING | ||
+ | |||
+ | # Create the chain again and add all the new rules. | ||
+ | for i in `curl -s ' | ||
+ | egrep ' | ||
+ | ipset add EMERGING $i | ||
+ | done | ||
+ | |||
+ | # Drop all entries in the ip set. | ||
+ | iptables -A EMERGING -m set --match-set EMERGING src -j DROP | ||
+ | |||
+ | # Return to the rest of the chain. | ||
+ | iptables -A EMERGING -j RETURN | ||
+ | </ | ||
+ | ====== Block Attacks with FireHOL Level 1 IP Abuse List ====== | ||
+ | |||
+ | The [[http:// | ||
+ | |||
+ | 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: | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | <file bash firehol-level1> | ||
+ | #! /bin/sh | ||
+ | ########################################################################### | ||
+ | ## Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 ## | ||
+ | ########################################################################### | ||
+ | # Downloads the FireHOL level 1 list and blocks all the entries. | ||
+ | ########################################################################### | ||
+ | |||
+ | # 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; | ||
+ | if [ -f $i ]; then | ||
+ | rm $i | ||
+ | fi | ||
+ | done | ||
+ | |||
+ | }' KILL QUIT TERM EXIT INT HUP | ||
+ | |||
+ | # Delete all the old iptables rules. | ||
+ | JUMP=`iptables-save | grep -- "-A INPUT -j FIREHOL_LEVEL1" | ||
+ | if [ ! -z " | ||
+ | iptables -D INPUT -j FIREHOL_LEVEL1 | ||
+ | iptables -F FIREHOL_LEVEL1 | ||
+ | iptables -X FIREHOL_LEVEL1 | ||
+ | fi | ||
+ | |||
+ | # Create the set chain. | ||
+ | iptables -N FIREHOL_LEVEL1 | ||
+ | iptables -I INPUT 1 -j FIREHOL_LEVEL1 | ||
+ | |||
+ | # Delete current set. | ||
+ | FIREHOL_LEVEL1=`ipset list FIREHOL_LEVEL1 2>/ | ||
+ | if [ $? = 1 ]; then | ||
+ | # Create the set. | ||
+ | ipset create FIREHOL_LEVEL1 hash:net | ||
+ | |||
+ | 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/ | ||
+ | 127.0.0.0/8 | ||
+ | 169.254.0.0/ | ||
+ | 172.16.0.0/ | ||
+ | 192.0.0.0/ | ||
+ | 192.0.2.0/ | ||
+ | 192.168.0.0/ | ||
+ | 198.18.0.0/ | ||
+ | 198.51.100.0/ | ||
+ | 203.0.113.0/ | ||
+ | 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 -f -s ' | ||
+ | # Check that curl completed successfully and that the list is not empty. | ||
+ | if [ $? != 0 ] || [ -z $FIREHOL_LIST ]; then | ||
+ | echo ' | ||
+ | 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 i in `awk '{if (f==1) { r[$0] } else if (! ($0 in r)) { print $0 } } ' f=1 $BOGONS_LIST f=2 $FIREHOL_LIST | \ | ||
+ | egrep ' | ||
+ | ipset add FIREHOL_LEVEL1 $i | ||
+ | done | ||
+ | |||
+ | # Drop all entries in the ip set. | ||
+ | iptables -A FIREHOL_LEVEL1 -m set --match-set FIREHOL_LEVEL1 src -j DROP | ||
+ | |||
+ | # Return to the rest of the chain. | ||
+ | iptables -A FIREHOL_LEVEL1 -j RETURN | ||
+ | </ | ||
+ | |||
+ | To use, simply copy the script to ''/ | ||
+ | |||
+ | ====== Delete a Single Rule ====== | ||
+ | |||
+ | A single rule can be deleted by specifying either: | ||
+ | * the rule number (of the chain) | ||
+ | * the entire rule | ||
+ | |||
+ | using the '' | ||
+ | |||
+ | |||
+ | For instance, to remove the IP address '' | ||
+ | <code bash> | ||
+ | iptables -L -n --line-numbers | grep 199.233.85.0 | awk '{ print $1 }' | xargs iptables -D EMERGING | ||
+ | </ | ||
+ | |||
+ | The command will: | ||
+ | * display the '' | ||
+ | * without attempting to resolve the IP addresses to names ('' | ||
+ | * by printing the rule number in each chain '' | ||
+ | |||
+ | and will then match the IP address '' | ||
+ | |||
+ | 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: | ||
+ | - declare the IP address to remove <code bash> | ||
+ | IP=83.141.2.155 | ||
+ | </ | ||
+ | - use the following snippet to remove the IP address from all chains <code bash> | ||
+ | iptables -n -L --line-numbers | \ | ||
+ | grep -oP " | ||
+ | xargs | \ | ||
+ | grep -oP ' | ||
+ | xargs -l sh -c ' | ||
+ | </ | ||
+ | |||
+ | ====== Create Country IP Sets Without GeoIP ====== | ||
+ | |||
+ | Leveraging [[sh/ | ||
+ | |||
+ | <file bash generate-country-ip-sets.sh> | ||
+ | # | ||
+ | ########################################################################### | ||
+ | ## 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 ' | ||
+ | |||
+ | for i in ${!COUNTRY_CODES[*]}; | ||
+ | COUNTRY=${COUNTRY_CODES[$i]} | ||
+ | # Create or purge IPv4/6 for configured countries. | ||
+ | for FAMILY in inet inet6; do | ||
+ | SET_NAME=$COUNTRY" | ||
+ | `ipset list $SET_NAME 2>/ | ||
+ | if [ $? = 1 ]; then | ||
+ | ipset create $SET_NAME hash:net family $FAMILY | ||
+ | fi | ||
+ | ipset flush $SET_NAME | ||
+ | done | ||
+ | curl -s -o - ' | ||
+ | json | \ | ||
+ | while read LINE; do | ||
+ | K=$(echo $LINE | awk -F' | ||
+ | V=$(echo $LINE | awk -F' | ||
+ | if [ " | ||
+ | for FAMILY in inet inet6; do | ||
+ | ipset destroy $COUNTRY" | ||
+ | done | ||
+ | continue | ||
+ | fi | ||
+ | case $( echo " | ||
+ | " | ||
+ | ipset add $COUNTRY" | ||
+ | ;; | ||
+ | " | ||
+ | ipset add $COUNTRY" | ||
+ | ;; | ||
+ | esac | ||
+ | done | ||
+ | done | ||
+ | |||
+ | </ | ||
+ | |||
+ | The '' |