【问题标题】:Bash script, need help for loopBash脚本,循环需要帮助
【发布时间】:2016-05-30 00:09:27
【问题描述】:

目前我正在使用这个脚本来屏蔽中国的IP地址:

# Create the ipset list
ipset -N china hash:net

# remove any old list that might exist from previous runs of this script
rm cn.zone

# Pull the latest IP set for China
wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone

# Add each IP address from the downloaded list into the ipset 'china'
for i in $(cat ./cn.zone ); do ipset -A china $i; done

# Restore iptables
/sbin/iptables-restore < /etc/iptables/rules.v4

这很好用,但我如何在多个国家/地区使用它?

我试过了,但它不起作用:

ipset -N blockall hash:net
rm blockall.zone

for i in $(wget -P . http://www.ipdeny.com/ipblocks/data/countries/{cn,in,iq,af,ir,ae,sg,hk,kw,kg}.zone);
do ipset -A blockall $i; done

/sbin/iptables-restore < /etc/iptables/rules.v4

更新

根据 Agnul 的回答,我尝试了这个:

rm blockall.zone
# pull files for each country
wget -P . http://www.ipdeny.com/ipblocks/data/countries/{cn,in,iq,af,ir,ae,sg,hk,kw,kg}.zone

# for each country file
for c in *.zone; do

  #for each line in country
  while read i; do
    ipset -A blockall $i;
  done <"$c"

done

然后我chmod我的脚本

chmod +x /etc/block-blockall.sh

但是,它并没有按照应有的方式创建文件 blockall.zone 或单个文件 *.zone

【问题讨论】:

  • 它不起作用,因为这个{cn,in,iq,af,ir,ae,sg,hk,kw,kg} 是错误的......bash 中数组的正确方法是什么?为这个问题的简单性提前道歉

标签: linux bash iptables


【解决方案1】:

假设第一个脚本,中国的,正在做你所期望的,试试这个来处理几个国家:

#!/bin/bash

COUNTRIES="cn in iq af ir ae sg hk kw kg"

ipset -N blockall hash:net

for country in $COUNTRIES; do
  wget -O - http://www.ipdeny.com/ipblocks/data/countries/$country.zone 2>/dev/null | while read ip; do
    ipset -A blockall $ip; 
  done
done


/sbin/iptables-restore < /etc/iptables/rules.v4

注意临时文件不需要也不需要。

如果出于任何原因需要临时文件,请使用:

#!/bin/bash

COUNTRIES="cn in iq af ir ae sg hk kw kg" 
ZONEFILE=blockall.zone

rm -f $ZONEFILE

ipset -N blockall hash:net

for country in $COUNTRIES; do
  wget -O - http://www.ipdeny.com/ipblocks/data/countries/$country.zone 2>/dev/null >> $ZONEFILE
done

while read ip; do
  ipset -A blockall $ip; 
done < $ZONEFILE

/sbin/iptables-restore < /etc/iptables/rules.v4

【讨论】:

    【解决方案2】:

    类似

    # pull files for each country
    wget -P . http://www.ipdeny.com/ipblocks/data/countries/{cn,in,iq,af,ir,ae,sg,hk,kw,kg}.zone
    
    # for each country file
    for c in *.zone; do
    
      #for each line in country
      while read i; do
        ipset -A blockall $i;
      done <"$c"
    
    done
    

    应该可以。

    【讨论】:

    • 我试过但同样的错误--2016-05-27 10:33:18-- http://www.ipdeny.com/ipblocks/data/countries/%7Bcn,in,iq,af,ir,ae,sg,hk,kw,kg%7D.zone Resolving www.ipdeny.com (www.ipdeny.com)... 192.xxx.xxx.22 Connecting to www.ipdeny.com (www.ipdeny.com)|192.xxx.xxx.22|:80... connected. HTTP request sent, awaiting response... 404 Not Found 2016-05-27 10:33:18 ERROR 404: Not Found.
    • for i in $(cat ...) 是一种反模式。请改用while-read 循环。此外,它应该是单独的"$c",而不是$c.zone,因为扩展$c 将有尾随.zone
    • 是的,我并没有真正尝试过 ;-) 我的错。
    • www.ipdeny.com/ipblocks/data/countries/{cn,in,iq,af,ir,ae,sg,hk,kw,kg}.zone 网址无效
    • 如果使用的 shell 是 bash 作为标签和标题声明,那么 brace expansion 会生成一个可能有效的 URL 列表:www.ipdeny.com/ipblocks/data/countries/cn.zone www.ipdeny.com/ipblocks/data/countries/in.zone ... www.ipdeny.com/ipblocks/data/countries/kw.zone www.ipdeny.com/ipblocks/data/countries/kg.zone。如果使用的 shell 不是 Bash(例如 /bin/sh),则可能不会发生扩展(例如,/bin/sh 可能不是 Bash)。