0x01 前言
我之前写了一个python脚本,利用阿里云的DNS解析服务做了DDNS服务(通过python将阿里云DNS解析作为DDNS使用)。
现在有一个安全问题,我用家里的网络去访问公网的服务器的时候,因为家里使用PPPoE,所以IP会不断变化,所以公网服务器需要开放端口的话就只能开放全部IP。
虽然端口都是使用数字证书加密和验证的,但依然很难让人放心,要是能动态更新iptables就好了。
0x02 脚本
来一个简单的脚本,首先是获取域名的IP地址:
ping -c 1 -t 1 ngx.hk | grep 'PING' | awk '{print $3}' | sed 's/[(,)]//g' #运行结果如下 [root@web ~]# ping -c 1 -t 1 ngx.hk | grep 'PING' | awk '{print $3}' | sed 's/[(,)]//g' 10.1.1.1
然后是放行的iptables:
iptables -A INPUT -p tcp --dport 8081 -s 10.1.1.1 -j ACCEPT
还有删除iptables的命令:
iptables -D INPUT -p tcp --dport 8081 -s $get_ip -j ACCEPT
我们需要怎样取得就IP呢?通过iptables去获取是可以的,但是这样的话,在第一次运行之前必须手动运行一次放行的命令。如果有多个IP对应一个端口的情况,也很难编写脚本。
所以我选择将IP写入到一个临时文件:
`iptables -A INPUT -p tcp --dport 8081 -s $get_ip -j ACCEPT` echo $get_ip >> ./dyn_ip.txt
这样的话,第一次运行时会自动将放行命令添加到iptables并写入到临时文件。
为此还需要一个判断,如果该临时文件存在的话,就直接从文件中获取临时文件的最后一行:
tail ./dyn_ip.txt -n 1
取得旧IP,就可以和get_ip的值做比较:
if ! [ "$old_ip" = "$get_ip" ]; then `iptables -D INPUT -p tcp --dport 8081 -s $old_ip -j ACCEPT` `iptables -A INPUT -p tcp --dport 8081 -s $get_ip -j ACCEPT` echo $get_ip >> ./dyn_ip.txt fi
上面这段脚本的意思是:如果旧IP和新IP不一致,则先删除旧IP的iptables,然后添加新IP到iptables中,最后将新IP写入临时文件。
因为将IP写入了文件,所以还需要判断该文件是否存在,如果不存在则直接运行添加iptables命令并写入文件,如果存在则输出最后一行并比对:
if [ -e './dyn_ip.txt' ]; then old_ip=`tail ./dyn_ip.txt -n 1` if ! [ "$old_ip" = "$get_ip" ]; then `iptables -D INPUT -p tcp --dport 8081 -s $old_ip -j ACCEPT` `iptables -A INPUT -p tcp --dport 8081 -s $get_ip -j ACCEPT` echo $get_ip >> ./dyn_ip.txt fi else `iptables -A INPUT -p tcp --dport 8081 -s $get_ip -j ACCEPT` echo $get_ip >> ./dyn_ip.txt fi
0x03 最终
为了使临时文件保存的路径和脚本的路径一致,还需要添加以下命令:
cd `dirname $0`
先获取脚本路径,然后使用cd进入到该路径。
最终的脚本如下:
#!/bin/sh get_ip=`ping -c 1 -t 1 ngx.hk | grep 'PING' | awk '{print $3}' | sed 's/[(,)]//g'` cd `dirname $0` if [ -e './dyn_ip.txt' ]; then old_ip=`tail ./dyn_ip.txt -n 1` if ! [ "$old_ip" = "$get_ip" ]; then `iptables -D INPUT -p tcp --dport 8081 -s $old_ip -j ACCEPT` `iptables -A INPUT -p tcp --dport 8081 -s $get_ip -j ACCEPT` echo $get_ip >> ./dyn_ip.txt fi else `iptables -A INPUT -p tcp --dport 8081 -s $get_ip -j ACCEPT` echo $get_ip >> ./dyn_ip.txt fi
一共17行,简单明了。
0x04 运行
手动运行:
sh /usr/local/shell/dyn_iptables.sh
既然写了脚本,肯定不希望手动运行啦。那么使用crond建立定时任务:
#打开文件 [root@web ~]# vim /etc/crontab #添加以下一行后保存并退出 */1 * * * * root sh /usr/local/shell/dyn_iptables.sh >> /dev/null 2>&1 #重启crond服务 [root@web ~]# systemctl restart crond.service
以上crond任务为每分钟执行一次,而后面的尾巴:
>> /dev/null 2>&1
是为了避免不必要的root mail产生。
0x05 结语
这样就可以很安心地使用开放的端口了。