Unix and Linux network configuration. Multiple network interfaces. Bridged NICs. High-availability network configurations.


Reviews of latest Unix and Linux software. Helpful tips for application support admins. Automating application support.


Disk partitioning, filesystems, directories, and files. Volume management, logical volumes, HA filesystems. Backups and disaster recovery.


Distributed server monitoring. Server performance and capacity planning. Monitoring applications, network status and user activity.

Commands & Shells

Cool Unix shell commands and options. Command-line tools and application. Things every Unix sysadmin needs to know.

Home » Commands & Shells, Networking, Security

Bulk-Adding IPTables Rules

Submitted by on December 12, 2019 – 9:46 pm

I’ve been using my mod of this handy script to block countries with iptables. One issue with the script is that it is adding rules one-by-one using the iptables -A syntax. This is the proper way to add rules, but it does take a long while. And here’s how you can make it orders of magnitude faster.

Here’s the basic process in the original script:

for each country_code
  download zone file
  get a list of all IPs
  for each IP in the list
    add a logging rule to iptables
    add a block rule to iptables

Here’s what I have in my revised version:

save current iptables config
copy saved config to a temp file
remove (but remember) the COMMIT footer at the end of the config file

for each country_code
  download zone file
  get a list of all IPs
  for each IP in the list
    echo logging rule to temp file
    echo block rule to temp file

move temp file to iptables config file
reload iptables

The iptables command is called after all the rules are already in the config file, and not for every single rule, of which there may be tens of thousands.

Here’s the actual code for this:

function func_add_rules() {
  iptables-save > /etc/sysconfig/iptables
  /bin/cp -p /etc/sysconfig/iptables ${tmpfile3}
  footer="$(sed -n '/^COMMIT/{:a;n;/*$/b;p;ba}' ${tmpfile3})"
  sed -i "/^COMMIT/,/*$/d" ${tmpfile3}
  for country_code in af cn ua jp
    wget -O /root/${country_code}.zone ${download_url}/${country_code}.zone
    log_msg="${country_code} CountryDrop"
    banned_ips=$(grep -Ev "^#|^$" /root/${country_code}.zone)
    for ban_ip in ${banned_ips}
      echo "-A ${chain_name} -s ${ban_ip} -j LOG --log-prefix ${log_msg}" >> ${tmpfile3}
      echo "-A ${chain_name} -s ${ban_ip} -j DROP" >> ${tmpfile3}
  echo COMMIT >> ${tmpfile3}
  echo "${footer}" >> ${tmpfile3}
  awk '/^COMMIT$/ { delete x; }; !x[$0]++' ${tmpfile3} > /etc/sysconfig/iptables
  iptables-restore < /etc/sysconfig/iptables
  /sbin/service iptables reload
  /sbin/service iptables save


Print Friendly, PDF & Email

Leave a Reply