利用ADSL组建VPN网络
(姜道友 2005-09-17)
前言:
很多公司总部采用专线上网,而子公司或办事处采用ADSL上网,因分公司或办事处需要访问公司总部的应用服务器,所以需要组建VPN网络。但分公司或办事处很难承担专线的费用,这时我们可以利用ADSL组建VPN网络。具体方案为:我们可以在公司总部安装一台专门连接远程ADSL站点的VPN服务器,采用固定IP地址。而分公司或办事处采用宽带VPN路由器,并使用DDNS(动态域名,如花生壳)。
办事处宽带路由器配置:
办事处可以购买一款VPN路由器,要求支持动态域名,如:3322.org。然后配置到总公司VPN服务器的Net to Net之VPN
总部的vpn服务器配置:
总部的VPN服务器可以安装一台Linux,并配置openswan之VPN服务,最简单的方法是安装一台ipcop主机,其上已经集成了防火墙和VPN服务。然后编写一个VPN自动刷新程序,功能是:当远程站点的ADSL重拨而导致获取的公网IP地址发生改变,远程站点的宽带VPN路由器上会自动更新DDNS,利用此程序来实时检测远程动态域名DDNS解析的IP地址,一旦发生改变,将刷新VPN通道。下面是本人编写的VPN自动刷新程序如下:
echo -e "\t\t\n\n"
echo -e "\033[1;031m \n"
echo "######################################################################"
echo "# DDNS VPN auto flush system 3.0 #"
echo "# E-mail:jdaoyou@sohu.com #"
echo "######################################################################"
echo -e "\033[m \n"
echo ""
echo ""
############ dns nameserver ###################
nameserver=(61.177.95.125 61.132.94.158 .......... .......略) 定义DNS服务器
############ DDNS name var###################
ddnsname=(xxxx.3322.org yyyy.3322.org ............略) 定义远程站点的DDNS
############ VPN Tunnel name var###################
tunnelname=(xxxx yyyy .............略) 定义VPN隧道名称
############ get changed IP program ###################
getchangeip(){ 此函数主要检测DDNS解析的IP地址是否有变化
directory="/home/jiangvpn"
ipinf_file=`/bin/date |awk '{print $6""$2""$3"_"$4}'|awk -F: '{print $1""$2""$3}'`
/usr/bin/nslookup xxxx.3322.org 61.177.95.125|grep "Add"|grep -v "${nameserver[0]}"|grep -v "${nameserver[1]}"|grep -v "${nameserver[2]}"|grep -v "${nameserver[3]}"|grep -v "127.0.0.1"|awk '{printf "%-20s\t%-20s\n",$2"\t","xxxx.3322.org"}' > $directory/$ipinf_file
/usr/bin/nslookup yyyy.3322.org 61.177.95.125|grep "Add"|grep -v "${nameserver[0]}"|grep -v "${nameserver[1]}"|grep -v "${nameserver[2]}"|grep -v "${nameserver[3]}"|grep -v "127.0.0.1"|awk '{printf "%-20s\t%-20s\n",$2"\t","yyyy.3322.org"}' >> $directory/$ipinf_file
……….略
if [ -e $directory/ipoldinfo ];then 这部分为检测DDNS对应的IP是否有改变
/usr/bin/diff $directory/$ipinf_file $directory/ipoldinfo |grep -v ">" > $directory/changeip
/bin/mv $directory/$ipinf_file $directory/ipoldinfo
else
/bin/cp $directory/$ipinf_file $directory/ipoldinfo
getchangeip
fi
}
#################### Log ########################
updatelog(){
if [ -e $directory/ddnsupdatelog ];then
..........略 这部分主要功能是当远程DDNS有变化时记录日志
fi
}
############ flush route list ###################
changeroute(){
略 这部分为如果需要改变路由,可以在刷新通道前设置路由表 注:这部分主要是双线路考虑的
}
############ VPN flush program ###################
flushddnsvpn(){ 此函数功能为:刷新已经改变peer IP的VPN通道
NEWIP=`/bin/cat /home/jiangvpn/ipoldinfo|grep $1|awk '{print $1}'`
OLDIP=`/bin/cat /etc/hosts|grep $1|awk '{print $1}'`
if [ "$NEWIP" != "$OLDIP" ] ; then
echo -e "\033[1;032m$1 tunnel is flushing ...........\n"
updatelog $1
/usr/sbin/ipsec auto --delete $1
#/bin/cat /home/jiangvpn/ipoldinfo >> /etc/hosts
vim -e -s -c ":%s/$OLDIP/$NEWIP/g" -c ":wq" /etc/hosts
#sed 's/$OLDIP/$NEWIP/g' /etc/hosts|tee /etc/hosts
/usr/sbin/ipsec auto --add $1
/usr/sbin/ipsec auto --route $1
#/usr/sbin/ipsec auto --rereadsecrets
#/usr/sbin/ipsec auto --rereadcacerts
#/usr/sbin/ipsec auto --rereadmycert
/usr/sbin/ipsec auto --rereadall
/usr/sbin/ipsec auto --asynchronous --up $1
fi
}
############ Main program ###################
这部分是最难编写的。
while :
do
checkpid=`/bin/ps -ax|grep "/home/jiangvpn/flushddnsvpn"|grep -v "Warning"|grep -v "grep"|awk '{print $1}'`
vpnstatus=`/etc/rc.d/ipsec --status|grep "IPsec"|awk '{print $2}'`
if [ "$checkpid" = "" ] ; then
if [ "$vpnstatus" = "running" ] ; then
#echo "ipsec services is running..............."
getchangeip
while read changeddnsname
do
#*************************************************************
# #
# Flush Zombie Tunnel #
# #
#*************************************************************
case $changeddnsname in
*${ddnsname[0]}*)
changeroute ${tunnelname[0]}
flushddnsvpn ${tunnelname[0]}
;;
*${ddnsname[1]}*)
flushddnsvpn ${tunnelname[1]};;
*${ddnsname[2]}*)
flushddnsvpn ${tunnelname[2]};;
*${ddnsname[3]}*)
...........
flushddnsvpn ${tunnelname[13]};;
*${ddnsname[14]}*)
flushddnsvpn ${tunnelname[14]};;
*${ddnsname[15]}*)
flushddnsvpn ${tunnelname[15]};;
*${ddnsname[16]}*)
flushddnsvpn ${tunnelname[16]};;
*${ddnsname[17]}*)
flushddnsvpn ${tunnelname[17]};;
..........
esac
done < $directory/changeip
else
echo "ipsec services is down..............."
/etc/rc.d/ipsec --restart
fi
fi
sleep 10 每10秒刷新一次
# break
done
注:以上只是程序的架构,其中部分程序省略了,如果需要的朋友,可以留言或发邮件给我。多谢支持。