将ADSL线路的动态IP实时应用于Linux的iptables和Win2k8的firewall防火墙
### 背景 ###
办公区或家里的上网线路不是专线(专线好贵啊),没有固定的公网IP,而服务器的某些网络服务不便对公网开放,仅想征对办公区或家里的线路开放。
### 思路简介 ###
办公区每条ADSL线路下(实际上现在都是光纤接入,只是服务近似于以往的ADSL)准备一台不需要关机的服务器,通过计划任务配置curl客户端基于验证去不断请求一个URL,公网IP就送到了web服务的日志中去了,
公网环境下准备一台linux服务器,搭建web服务(推荐nginx),通过一个脚本定期去web服务的日志中获得可信任的最新的办公区IP,提供基于验证的http服务,公网上可下载到该IP,
应用动态IP到防火墙的服务器,始终通过定制的脚本配置防火墙所有规则(应该养成通过脚本配置防火墙的习惯,如果再通过手动修改防火墙将可能导致配置丢失或冲突),并且跑一个计划任务来获取最新的IP,有变更时,便应用到本地防火墙指定的策略中。
该方案我们简称为dip方案吧,于是下文便有名称:dip客户端,dip服务端,dip应用端。
### 实践效果 ###
实践了六年以上,未依赖第三方(花生壳等)DDNS服务,可靠性、可控性非常好。
### 实施细节参考 ###
dip客户端配置
办公区的linux服务器,建自动任务于/etc/crontab
* * * * * root curl -u dip:pass --retry 3 --retry-delay 1 --connect-timeout 7 --max-time 5 http://dip.zhaoyanan.cn:83/uploadip_office01.txt > /dev/null 2>&1
运行该任务的办公区服务器,和员工PC机访问的目标服务器,应该在同一条上网线路下,假如有多条线路,那么建议使用多台服务器或者在核心路由(比如RouterOS)实现,
使用多台服务器时,为方便脚本统一实现最终目的,访问目标URL可以按下面的规律配置:
http://dip.zhaoyanan.cn:83/uploadip_office01.txt
http://dip.zhaoyanan.cn:83/uploadip_office02.txt
http://dip.zhaoyanan.cn:83/uploadip_office03.txt
其中RouterOS可通过自带脚本功能,使用fetch命令访问具有不同的目标端口的URL来区分ADSL线路,可自行研究。
dip服务端配置
nginx配置示例
server {
listen 83;
server_name dip.zhaoyanan.cn;
set $host_dir /opt/web/dip;
charset gb2312;
access_log logs/dip_access.log main;
location / {
root $host_dir;
index index.html index.htm;
}
location ~ ^/uploadip_(.*).txt {
#autoindex on;
#autoindex_exact_size off;
auth_basic "Please enter your username and password";
auth_basic_user_file /opt/nginx/conf/dip-htpasswd;
root $host_dir;
index index.html index.htm index.php;
}
location ~ /\.ht {
deny all;
}
}
生成/opt/nginx/conf/dip-htpasswd的方法:
python /root/sh/htpasswd.py -c -b /opt/nginx/conf/dip-htpasswd user pass
htpasswd.py脚本内容
#!/usr/bin/python
"""Replacement for htpasswd"""
# Original author: Eli Carter
import os
import sys
import random
from optparse import OptionParser
# We need a crypt module, but Windows doesn't have one by default. Try to find
# one, and tell the user if we can't.
try:
import crypt
except ImportError:
try:
import fcrypt as crypt
except ImportError:
sys.stderr.write("Cannot find a crypt module. "
"Possibly http://carey.geek.nz/code/python-fcrypt/\n")
sys.exit(1)
def salt():
"""Returns a string of 2 randome letters"""
letters = 'abcdefghijklmnopqrstuvwxyz' \
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' \
'0123456789/.'
return random.choice(letters) + random.choice(letters)
class HtpasswdFile:
"""A class for manipulating htpasswd files."""
def __init__(self, filename, create=False):
self.entries = []
self.filename = filename
if not create:
if os.path.exists(self.filename):
self.load()
else:
raise Exception("%s does not exist" % self.filename)
def load(self):
"""Read the htpasswd file into memory."""
lines = open(self.filename, 'r').readlines()
self.entries = []
for line in lines:
username, pwhash = line.split(':')
entry = [username, pwhash.rstrip()]
self.entries.append(entry)
def save(self):
"""Write the htpasswd file to disk"""
open(self.filename, 'w').writelines(["%s:%s\n" % (entry[0], entry[1])
for entry in self.entries])
def update(self, username, password):
"""Replace the entry for the given user, or add it if new."""
pwhash = crypt.crypt(password, salt())
matching_entries = [entry for entry in self.entries
if entry[0] == username]
if matching_entries:
matching_entries[0][1] = pwhash
else:
self.entries.append([username, pwhash])
def delete(self, username):
"""Remove the entry for the given user."""
self.entries = [entry for entry in self.entries
if entry[0] != username]
def main():
"""%prog [-c] -b filename username password
Create or update an htpasswd file"""
# For now, we only care about the use cases that affect tests/functional.py
parser = OptionParser(usage=main.__doc__)
parser.add_option('-b', action='store_true', dest='batch', default=False,
help='Batch mode; password is passed on the command line IN THE CLEAR.'
)
parser.add_option('-c', action='store_true', dest='create', default=False,
help='Create a new htpasswd file, overwriting any existing file.')
parser.add_option('-D', action='store_true', dest='delete_user',
default=False, help='Remove the given user from the password file.')
options, args = parser.parse_args()
def syntax_error(msg):
"""Utility function for displaying fatal error messages with usage
help.
"""
sys.stderr.write("Syntax error: " + msg)
sys.stderr.write(parser.get_usage())
sys.exit(1)
if not options.batch:
syntax_error("Only batch mode is supported\n")
# Non-option arguments
if len(args) < 2:
syntax_error("Insufficient number of arguments.\n")
filename, username = args[:2]
if options.delete_user:
if len(args) != 2:
syntax_error("Incorrect number of arguments.\n")
password = None
else:
if len(args) != 3:
syntax_error("Incorrect number of arguments.\n")
password = args[2]
passwdfile = HtpasswdFile(filename, create=options.create)
if options.delete_user:
passwdfile.delete(username)
else:
passwdfile.update(username, password)
passwdfile.save()
if __name__ == '__main__':
main()
建自动任务于/etc/crontab
* * * * * root /root/sh/dip.sh do >> /root/sh/dip.log 2>&1; sleep 30; /root/sh/dip.sh do >> /root/sh/dip.log 2>&1
/root/sh/dip.sh脚本运行前,先创建文件:
echo 1.1.1.1 > /opt/web/dip/downloadip_office01.txt
echo uploadip_office01 > /opt/web/dip/uploadip_office01.txt
echo 1.1.1.1 > /opt/web/dip/downloadip_office02.txt
echo uploadip_office02 > /opt/web/dip/uploadip_office02.txt
downloadip文件首先不能为空,所以先随便输入一个IP到文件中。
/root/sh/dip.sh脚本内容:
(脚本发邮件功能需要mutt支持,如果不需要发邮件通知,可以去掉该功能)
#!/bin/bash
###################################
# function get the dynamic IP to write the file
#
# 参考创建或使用示例: touch /root/sh/dip.sh; chmod 700 /root/sh/dip.sh
# Initialization:
# echo 1.1.1.1 > /opt/web/dip/downloadip_office01.txt
# echo uploadip_office01 > /opt/web/dip/uploadip_office01.txt
# echo 1.1.1.1 > /opt/web/dip/downloadip_office02.txt
# echo uploadip_office02 > /opt/web/dip/uploadip_office02.txt
# task:
# */3 * * * * root /root/sh/dip.sh > /dev/null 2>&1
# Change History:
# date author note
# 2013/11/18 [email protected] create
# 2017/11/28 [email protected] 调整格式,采用新的标准发件方式
# 2018/06/12 [email protected] 更换ip合法性判断方法,解决无法识别末尾为0的IP的bug
###################################
############# ENV #################
# 脚本名称,临时文件或邮件中可能用到,避免同类脚本的变量的冲突,下面直接取脚本名
export project_name=`echo ${0##*/} | cut -d'.' -f 1`
# 工作目录,可能会产生临时文件
export work_dir=/root/sh
# 临时文件目录
export tmp_dir=/tmp
# 动态IP简称
export location_name_group="office01" # eg: "office01 office02"
#export location_name_group="office01 office02" # eg: "office01 office02"
export location_name_group_mail="office01" # eg: "office01 office02" 这组不会应用到异地iptables,会直接在本脚本进行发件通知
#export location_name_group_mail="office01 office02" # eg: "office01 office02" 这组不会应用到异地iptables,会直接在本脚本进行发件通知
# nginx请求日志
export nginx_dip_log=/opt/nginx/logs/dip_access.log
# 收发邮件地址
mailfromadd="[email protected]"
mailtoadd="[email protected]"
# 时间和环境变量,一般无需修改
export datetime=$(date +%Y%m%d-%H%M)
export HOME=/root # 使用mutt,脚本又在/etc/crontab中运行,那么HOME变量是会受干扰的,所以必须指定
export LANG=C
export LC_ALL=C
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
export parameter1=$1
############# PROC #################
# 记录开始时间
start_time=$(date +%s)
### 函数 ###
# 帮助信息
function help_msg() {
echo -e "\033[41merror!!! 小心点,不要慌,现在出错了,请仔细查看下面的帮助信息:\033[0m"
cat <<EOF
ADSL动态IP获取
HELP:
\$1: parameters eg: do
exec eg:
sh $0 do
EOF
echo -e "\033[41merror!!! 小心点,不要慌,现在出错了,请仔细查看上面的帮助信息:\033[0m"
}
function mailto() {
# mail
echo "$msg" | /opt/mutt/bin/mutt \
-e 'set content_type="text/html"' \
-s "[dip] $projectname $sub" \
-e 'my_hdr from:'"$mailfromadd" \
-c "$mailccadd" \
"$mailtoadd" --
}
function check_ip() {
# Example:
# check_ip 192.168.1.1
# check_ip 256.1.1.1
IP=$1
if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
FIELD1=$(echo $IP|cut -d. -f1)
FIELD2=$(echo $IP|cut -d. -f2)
FIELD3=$(echo $IP|cut -d. -f3)
FIELD4=$(echo $IP|cut -d. -f4)
if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then
# echo "IP $IP available."
check_ip_result=0
else
echo "IP $IP not available!"
check_ip_result=1
fi
else
echo "IP format error!"
check_ip_result=1
fi
}
cd $work_dir
if [ "$parameter1" == "" ] || [ "$parameter1" == "help" ]; then
help_msg
exit
echo "`date +"%Y-%m-%d %H:%M:%S"` error, exit."
elif [ "$parameter1" == "do" ]; then
true
fi
# 下面这个方法判断末尾为0的IP不行,所以放弃
# regex="\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\b"
sub="Nothing, please login server view"
msg="Nothing, please login server view"
echo -e "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
<title>${projectname}_rsync_report_${current_time}</title></head><body>" > Routine_reports_${project_name}.html
echo "出口线路的公网IP有变化的如下列:<br>" >> Routine_reports_${project_name}.html
echo "name oldip newip <br><hr>" >> Routine_reports_${project_name}.html
i=0
for location_name in $location_name_group
do
dynamic_oldip=`cat /opt/web/dip/downloadip_"$location_name".txt`
#dynamic_newip=`grep "uploadip_$location_name\.txt" $nginx_dip_log | egrep "curl|Mikrotik" | grep -v 401 | grep 200 | awk '{ print $1; }' | tail -1`
dynamic_newip=`grep "uploadip_$location_name\.txt" $nginx_dip_log | grep -v 401 | egrep "200|304" | awk '{ print $1; }' | tail -1`
check_ip $dynamic_oldip
if [ "$check_ip_result" == "1" ];then
dynamic_oldip=null
fi
check_ip $dynamic_newip
if [ "$check_ip_result" == "1" ];then
dynamic_newip=error
fi
if [ "$check_ip_result" == "0" ] && [ "$dynamic_oldip" != "$dynamic_newip" ] && [ "$dynamic_newip" != "error" ];then
echo $dynamic_newip > /opt/web/dip/downloadip_"$location_name".txt
fi
for location_name_mail in $location_name_group_mail
do
if [ "$location_name" == "$location_name_mail" ] && [ "$dynamic_oldip" != "$dynamic_newip" ]; then
i=1
echo "$location_name $dynamic_oldip $dynamic_newip <br>" >> Routine_reports_${project_name}.html
fi
done
done
echo -e "</body></html>" >> Routine_reports_${project_name}.html
# mail
if [ "$i" -eq 1 ]; then
sub="notice: dynamic IP changed"
msg="$(cat Routine_reports_${project_name}.html)"
mailto
echo "`date +"%Y-%m-%d %H:%M:%S"` "$sub", mail notification has been sent."
fi
echo ""
stop_time=$(date +%s)
echo "本次脚本运行了$((${stop_time}-${start_time}))秒。"
dip应用服务器linux配置
linux防火墙iptables主脚本
#!/bin/bash
###################################
# author [email protected]
# date 2012/08/31
# function iptables config
#
# create: touch /root/sh/iptables.sh; chmod 700 /root/sh/iptables.sh
#
# Change History:
# date author note
# 2012/09/07 [email protected]
# 2012/09/10 [email protected]
# 2013/11/19 [email protected] for dynamic IP
###################################
######### ENV ####################
export LANG=C
export LC_ALL=C
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
###### filter table ################
###### INPUT chains ######
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -X
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
### ICMP ###
iptables -A INPUT -p icmp -m icmp --icmp-type any -m limit --limit 20/s -j ACCEPT
#iptables -A INPUT -p icmp -j ACCEPT
### web ###
iptables -A INPUT -p tcp -m state --state NEW -m multiport --dport 80,443 --tcp-flags SYN,RST,ACK SYN -j ACCEPT
### Trust Network #################
for adminip in 1.1.1.1 2.2.2.2
do
iptables -A INPUT -s $adminip -j ACCEPT
done
### 动态IP策略开始 ###
dynamic_newip=`curl -s -S http://dip.zhaoyanan.cn:83/downloadip_office01.txt`
if [ "$dynamic_newip" == "" ];then
echo "$dynamic_name IP did not get."
else
iptables -A INPUT -s $dynamic_newip -p tcp -m state --state NEW -m multiport --dport 1521 --tcp-flags SYN,RST,ACK SYN -j ACCEPT -m comment --comment "input-dynamicoffice01-rule"
fi
dynamic_newip=`curl -s -S http://dip.zhaoyanan.cn:83/downloadip_office02.txt`
if [ "$dynamic_newip" == "" ];then
echo "$dynamic_name IP did not get."
else
iptables -A INPUT -s $dynamic_newip -p tcp -m state --state NEW -m multiport --dport 1521 --tcp-flags SYN,RST,ACK SYN -j ACCEPT -m comment --comment "input-dynamicoffice02-rule"
fi
### 动态IP策略结束 ###
# temp
### global ###
iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
###### save ####################
iptables-save -c > /etc/sysconfig/iptables
iptables-save -c > /etc/sysconfig/iptables_$(date +%Y%m%d-%H%M)
linux防火墙iptables动态策略脚本
/root/sh/iptables_dynamicoffice01.sh示例:
一条线路一个脚本,/root/sh/iptables_dynamicoffice02.sh内容一样,只需要改location_name的值为office02
#!/bin/bash
###################################################################
# author [email protected]
# date 2012/09/07
# update 2012/09/21 [email protected] Bug fixes
# update 2012/09/24 [email protected] Improve function
# update 2012/10/08 [email protected] Improve function
# update 2012/11/09 [email protected] Improve function
# update 2013/01/05 [email protected] To modify mail address variable
# update 2013/07/19 [email protected] for the xen
# update 2013/08/02 [email protected] fix bug
# update 2013/11/19 [email protected] Increase program: Through the shell and HTTP protocol to get the office dynamic IP
#
# function soonyo ddns iptables config for xen
#
# Automatically and periodically run:
# Create a script, Append the following to /etc/crontab file
# touch /root/sh/iptables_dynamicoffice01.sh;chmod u+x /root/sh/iptables_dynamicoffice01.sh
# * * * * * root /root/sh/iptables_dynamicoffice01.sh >> /root/sh/iptables_dynamicoffice01.log 2>&1
###################################################################
####################### ENV #######################################
# 脚本名称,临时文件或邮件中可能用到,避免同类脚本的变量的冲突,下面直接取脚本名
export project=`echo ${0##*/} | cut -d'.' -f 1`
location_name=office01
dynamic_name=dynamic${location_name}
mailfromadd="[email protected]"
#mailtoadd='[email protected]'
mailccadd=
export LANG=C
export LC_ALL=C
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
workdir=/root/sh
####################### do ############################
regex="\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\b"
dynamic_newip=`curl -s -S http://dip.zhaoyanan.cn:83/downloadip_${location_name}.txt`
#dynamic_newip=123.145.32.111
dynamic_oldip=`iptables -nL | grep "$dynamic_name"-rule | awk '{print $4; }' | head -1 | egrep $regex`
dynamic_oldip_num=`iptables -nL | grep "$dynamic_name"-rule | awk '{print $4; }' | uniq -c | wc -l`
input_commend_repnum=`iptables -nL --line | grep input-"$dynamic_name"-rule | awk '{print $(NF-1); }' | uniq -c | sort -n | awk '{print $1; }' | tail -1`
#forward_commend_repnum=`iptables -nL --line | grep "forward-"$dynamic_name"-rule" | awk '{print $(NF-1); }' | uniq -c | sort -n | awk '{print $1; }' | tail -1`
test -f /tmp/ddns_m_value_"$project" || echo "0" > /tmp/ddns_m_value_"$project"
test -f /tmp/ddns_n_value_"$project" || echo "0" > /tmp/ddns_n_value_"$project"
m=`cat /tmp/ddns_m_value_"$project"`
n=`cat /tmp/ddns_n_value_"$project"`
i=0
function mailto() {
/usr/sbin/sendmail -t <<EOF
From: $mailfromadd
To: $mailtoadd
Cc: $mailccadd
Subject: [dip] $project $sub
$msg
EOF
}
sub="Nothing, please login server view"
msg="Nothing, please login server view"
# check and mail #
if [ "$dynamic_oldip_num" == "" ];then
sub="fatal: iptables does not exist in a dynamic IP"
msg="Such as the title."
echo "`date` $sub"
m=$(($m+1)); echo $m > /tmp/ddns_m_value_"$project"
elif [ "$dynamic_oldip_num" -ge 2 ];then
sub="warn: iptables there are multiple different dynamic IP"
msg="Such as the title."
echo "`date` $sub"
m=$(($m+1)); echo $m > /tmp/ddns_m_value_"$project"
fi
if [ "$input_commend_repnum" == "" ];then
sub="warn: iptables comments incomplete"
msg="Such as the title."
echo "`date` $sub"
m=$(($m+1)); echo $m > /tmp/ddns_m_value_"$project"
elif [ "$input_commend_repnum" -ge 2 ];then
sub="warn: iptables there are multiple different dynamic IP or same comment"
msg="Such as the title."
echo "`date` $sub"
m=$(($m+1)); echo $m > /tmp/ddns_m_value_"$project"
fi
if [ "$dynamic_newip" == "" ];then
sleep 10
#dynamic_newip=`nslookup $ddomain ns1.gnway.com | grep "Address:" | grep -v "#" | cut -d' ' -f 2 | egrep $regex`
dynamic_newip=`curl -s -S http://dip.zhaoyanan.cn:83/downloadip_${location_name}.txt`
fi
if [ "$dynamic_newip" == "" ];then
sub="warn: dynamic IP did not get, iptables not change"
msg="Such as the title, results:$dynamic_newip."
echo "`date` "$sub", results:$dynamic_newip, mail notification has been sent."
m=$(($m+1)); echo $m > /tmp/ddns_m_value_"$project"
else
m=0; echo $m > /tmp/ddns_m_value_"$project"
i=1
fi
if [ "$i" -eq 0 ] && [ "$n" -eq 0 ]; then
sub="warn: dynamic IP problem, iptables not change"
msg="Such as the title, results:$dynamic_newip, see the log."
mailto
echo "`date` "$sub", results:$dynamic_newip, mail notification has been sent."
n=1; echo $n > /tmp/ddns_n_value_"$project"
elif [ "$i" -eq 0 ] && [ "$m" -eq 120 ]; then
sub="warn: dynamic IP problem(too many times), iptables not change"
msg="Such as the title."
mailto
echo "`date` "$sub", mail notification has been sent again."
m=0; echo $m > /tmp/ddns_m_value_"$project"
elif [ "$m" -eq 0 ] && [ "$n" -eq 1 ]; then
sub="notice: dynamic IP successfully got"
msg="Such as the title."
mailto
echo "`date` "$sub",results:$dynamic_newip, mail notification has been sent."
n=0; echo $n > /tmp/ddns_n_value_"$project"
fi
# replace rule #
if [ "$dynamic_oldip" != "$dynamic_newip" ] && [ "$i" -eq 1 ]; then
iptables -nL --line | grep input-"$dynamic_name"-rule | awk '{print $1":"$(NF-1); }' > /tmp/input-"$dynamic_name"-list.txt
sed -n /env_start/,/env_over/{p} "$workdir"/iptables.sh > "$workdir"/iptables_"$dynamic_name"_tempcmd.sh
echo "dynamic_newip=$dynamic_newip" >> "$workdir"/iptables_"$dynamic_name"_tempcmd.sh
for k in `cat /tmp/input-"$dynamic_name"-list.txt`
do
input_dynamic_rule_line=`echo $k | awk -F ':' '{print $1; }'`
input_dynamic_rule_comment=`echo $k | awk -F ':' '{print $2; }'`
grep "$input_dynamic_rule_comment" "$workdir"/iptables.sh | sed 's/-A INPUT -s/-R INPUT '"$input_dynamic_rule_line"' -s/g' | sed 's/$dynamic_newip./$dynamic_newip /g' >> "$workdir"/iptables_"$dynamic_name"_tempcmd.sh
done
/bin/bash "$workdir"/iptables_"$dynamic_name"_tempcmd.sh
sub="notice: dynamic IP changes to $dynamic_newip"
msg="Such as the title."
mailto
echo "`date` "$sub", mail notification has been sent."
fi
配置计划任务于/etc/crontab:
* * * * * root /root/sh/iptables_dynamicoffice01.sh >> /root/sh/iptables_dynamicoffice01.log 2>&1
* * * * * root /root/sh/iptables_dynamicoffice02.sh >> /root/sh/iptables_dynamicoffice02.log 2>&1
dip应用服务器win2k8配置
win2k8时间格式配置
注意:脚本用到了date命令,需要修改系统控制面板中的“区域和语言”--》“格式”,变更格式M为MM,H为HH,以保证输出的年月日的数字个数总是相同的。
例如:
win2k8防火墙firewall主脚本内容
注意:把IP替换为自已的IP,
脚本用到了curl.exe命令,需要把windows下可运行的curl.exe拷贝到脚本所在目录,
@echo off
rem ##################################################################
rem 更新日期 作者 更改内容
rem 2015年 denyb 创始
rem 2016/03 [email protected] 整改
rem 2017/03/24 [email protected] 调整默认策略,其它略有调整
rem 2018/11/22 [email protected] 增加动态策略,和firewall_dynamic.bat脚本配合使用;增加临时目录备份目录;
rem ##################################################################
:1
title firewall.bat 防火墙主脚本
cd %~dp0
if not exist tmp (
mkdir tmp
)
if not exist bak (
mkdir bak
)
for /f "delims=" %%i in ('time /t') do set timef=%%i
set datetime=%date:~0,10%-%timef:~0,2%%timef:~3,2%
netsh advfirewall export "bak\firewall_policy_%datetime%.bak" # 备份策略
netsh advfirewall set allprofiles state on # 防火墙状态,off为关闭,on为开启,注意,关闭可能导致全部网络中断
netsh advfirewall set allprofiles firewallpolicy allowinbound,allowoutbound # 这里临时设置默认防火墙策略全部允许,后面再调整默认配置
netsh advfirewall set global statefulftp enable # 开启FTP支持
rem 删除原策略
netsh advfirewall firewall delete rule name=all
rem allow admin ip
netsh advfirewall firewall add rule name=adminip dir=in remoteip=1.1.1.1 action=allow description=trustip # v*n and office
rem 允许某些公共协议
netsh advfirewall firewall add rule name=allow_icmp dir=in protocol=icmpv4 action=allow description=allow_icmp_in
netsh advfirewall firewall add rule name=allow_icmp dir=in protocol=icmpv6 action=allow description=allow_icmp_in
rem 允许开放本机某些端口
netsh advfirewall firewall add rule name=allow_game_port dir=in remoteip=any protocol=tcp localport=10001 action=allow description=allow_gs_port # 游戏服务端口
netsh advfirewall firewall add rule name=allow_web_sever dir=in remoteip=2.2.2.2 action=allow description=trustip # web服主动连接gs服
rem 动态策略,该策略由firewall_dynamic.bat定时检查和变更,请不要修改name或者增加相同name的策略,以免动态策略失效
set location_name=office01
curl -s -S --connect-timeout 7 http://dip.zhaoyanan.cn:83/downloadip_%location_name%.txt > tmp\firewall_dynamic%location_name%_tmp2.txt
for /f "tokens=1 delims= " %%i in (tmp\firewall_dynamic%location_name%_tmp2.txt) do set dynamic_newip=%%i/32
netsh advfirewall firewall add rule name=dynamic%location_name% dir=in remoteip=%dynamic_newip% action=allow description=禁止复制或参考该条策略
set location_name=office02
curl -s -S --connect-timeout 7 http://dip.zhaoyanan.cn:83/downloadip_%location_name%.txt > tmp\firewall_dynamic%location_name%_tmp2.txt
for /f "tokens=1 delims= " %%i in (tmp\firewall_dynamic%location_name%_tmp2.txt) do set dynamic_newip=%%i/32
netsh advfirewall firewall add rule name=dynamic%location_name% dir=in remoteip=%dynamic_newip% action=allow description=禁止复制或参考该条策略
rem 全局策略
netsh advfirewall set allprofiles state on # 防火墙状态,off为关闭,on为开启,注意,关闭可能导致全部网络中断
netsh advfirewall set allprofiles firewallpolicy blockinbound,allowoutbound # 设置默认防火墙入站策略,拒绝不匹配允许的请求
rem 20170323发现360办公区连接登陆服异常,经分析判断,有logon服主动出站的包,所以出站不再做限制,日后可再抓包进一步分析
win2k8防火墙firewall动态策略脚本
@echo off
rem ################################################
rem date author
rem 2018/11/12 [email protected] 首次创建,结合dip方案,实现windows防火墙策略动态变更,从而在安全前提下方便网络权限的灵活分派
rem ################################################
:1
title firewall_dynamic.bat 动态防火墙策略脚本
setlocal
set path="C:\Program Files\WinRAR";%Path%
for /f "delims=" %%i in ('time /t') do set timef=%%i
set datetime=%date:~0,10%-%timef:~0,2%%timef:~3,2%
echo ###### do ########
echo %date% %time% start
cd %~dp0
if not exist tmp (
mkdir tmp
)
set location_name=office01
netsh advfirewall firewall show rule name=dynamic%location_name% | find "远程 IP:" > tmp\firewall_dynamic%location_name%_tmp.txt
for /f "tokens=3 delims= " %%i in (tmp\firewall_dynamic%location_name%_tmp.txt) do set dynamic_oldip=%%i
curl -s -S --connect-timeout 7 http://dip.zhaoyanan.cn:83/downloadip_%location_name%.txt > tmp\firewall_dynamic%location_name%_tmp2.txt
for /f "tokens=1 delims= " %%i in (tmp\firewall_dynamic%location_name%_tmp2.txt) do set dynamic_newip=%%i/32
if not %dynamic_newip% == %dynamic_oldip% (
netsh advfirewall firewall set rule name=dynamic%location_name% new remoteip=%dynamic_newip% action=allow description=禁止复制或参考该条策略
) else if %dynamic_newip% == %dynamic_oldip% (
echo "Nothing to do"
) else (
echo %date% %time% error
goto exit
)
set location_name=office02
netsh advfirewall firewall show rule name=dynamic%location_name% | find "远程 IP:" > tmp\firewall_dynamic%location_name%_tmp.txt
for /f "tokens=3 delims= " %%i in (tmp\firewall_dynamic%location_name%_tmp.txt) do set dynamic_oldip=%%i
curl -s -S --connect-timeout 7 http://dip.zhaoyanan.cn:83/downloadip_%location_name%.txt > tmp\firewall_dynamic%location_name%_tmp2.txt
for /f "tokens=1 delims= " %%i in (tmp\firewall_dynamic%location_name%_tmp2.txt) do set dynamic_newip=%%i/32
if not %dynamic_newip% == %dynamic_oldip% (
netsh advfirewall firewall set rule name=dynamic%location_name% new remoteip=%dynamic_newip% action=allow description=禁止复制或参考该条策略
) else if %dynamic_newip% == %dynamic_oldip% (
echo "Nothing to do"
) else (
echo %date% %time% error
goto exit
)
echo %date% %time% done
echo ###### done ######
endlocal
配置计划任务到win2k8系统中,每分钟跑一次firewall_dynamic.bat。
原文:https://www.zhaoyanan.cn/adsl-dynamicip-iptables-firewall.html