将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应用端。

赵亚南dip方案

### 实践效果 ###

实践了六年以上,未依赖第三方(花生壳等)DDNS服务,可靠性、可控性非常好。

### 实施细节参考 ###

dip客户端配置

办公区的linux服务器,建自动任务于/etc/crontab

* * * * * root curl -u dip:pass --retry 3 --retry-delay 1 --connect-timeout 7 --max-time 5 http://dip.domain.com:83/uploadip_office01.txt > /dev/null 2>&1

运行该任务的办公区服务器,和员工PC机访问的目标服务器,应该在同一条上网线路下,假如有多条线路,那么建议使用多台服务器或者在核心路由(比如RouterOS)实现,

使用多台服务器时,为方便脚本统一实现最终目的,访问目标URL可以按下面的规律配置:

http://dip.domain.com:83/uploadip_office01.txt

http://dip.domain.com:83/uploadip_office02.txt

http://dip.domain.com:83/uploadip_office03.txt

其中RouterOS可通过自带脚本功能,使用fetch命令访问具有不同的目标端口的URL来区分ADSL线路,可自行研究。

dip服务端配置

nginx配置示例

    server {
        listen       83;
        server_name  dip.domain.com;
        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  mail@domain.com  create
# 2017/11/28  mail@domain.com  调整格式,采用新的标准发件方式
# 2018/06/12  mail@domain.com  更换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="mail@domain.com"
mailtoadd="mail@domain.com"


# 时间和环境变量,一般无需修改
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     mail@domain.com
# 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  mail@domain.com  
# 2012/09/10  mail@domain.com
# 2013/11/19  mail@domain.com   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.domain.com: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.domain.com: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     mail@domain.com
# date       2012/09/07
# update     2012/09/21   mail@domain.com  Bug fixes
# update     2012/09/24   mail@domain.com  Improve function
# update     2012/10/08   mail@domain.com  Improve function
# update     2012/11/09   mail@domain.com  Improve function
# update     2013/01/05   mail@domain.com  To modify mail address variable
# update     2013/07/19   mail@domain.com  for the xen
# update     2013/08/02   mail@domain.com  fix bug
# update     2013/11/19   mail@domain.com  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="mail@domain.com.test"
#mailtoadd='mail@domain.com.test'
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.domain.com:83/downloadip_${location_name}.txt`
#dynamic_newip=1.1.1.1
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.domain.com: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年 dy   创始
rem 2016/03 mail@domain.com 整改
rem 2017/03/24  mail@domain.com 调整默认策略,其它略有调整
rem 2018/11/22  mail@domain.com 增加动态策略,和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  # VPN 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.domain.com: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.domain.com: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   mail@domain.com    首次创建,结合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.domain.com: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.domain.com: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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉思的归零者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值