以下步驟完全使用於Ubuntu 14.04版本
首先安裝以下所需包
sudo apt-get install openswan xl2tpd ppp lsof
!注意!Ubuntu 15.10會提示無法找到openswan包,解決辦法是用喜歡的編輯器編輯以下文件,實例用vim
sudo vim /etc/apt/sources.list
在文件最后添加一行
deb http://us.archive.ubuntu.com/ubuntu precise main universe
保存后,執行下面命令
sudo apt-get update
sudo apt-get install openswan
防火牆和轉發
設置允許轉發數據包
iptables -t nat -A POSTROUTING -j SNAT --to-source %SERVERIP% -o eth+
將上面的%SERVERIP%替換成服務器IP,eth+換成服務器的網卡名。!注意!不一定所有的網卡都是eth開頭的
執行下列命令允許內核轉發,並且禁用ICP重定向
echo "net.ipv4.ip_forward = 1" | tee -a /etc/sysctl.conf echo "net.ipv4.conf.all.accept_redirects = 0" | tee -a /etc/sysctl.conf echo "net.ipv4.conf.all.send_redirects = 0" | tee -a /etc/sysctl.conf echo "net.ipv4.conf.default.rp_filter = 0" | tee -a /etc/sysctl.conf echo "net.ipv4.conf.default.accept_source_route = 0" | tee -a /etc/sysctl.conf echo "net.ipv4.conf.default.send_redirects = 0" | tee -a /etc/sysctl.conf echo "net.ipv4.icmp_ignore_bogus_error_responses = 1" | tee -a /etc/sysctl.conf
如果有其他網絡接口,執行同樣的設置
for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done
應用以上設置
sysctl -p
保證每次開機這些設置生效
for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done iptables -t nat -A POSTROUTING -j SNAT --to-source %SERVERIP% -o eth+
配置OpenSwan(IPSEC)
用編輯器打開以下文件
/etc/ipsec.conf
# /etc/ipsec.conf - Openswan IPsec configuration file # This file: /usr/share/doc/openswan/ipsec.conf-sample # # Manual: ipsec.conf.5 version 2.0 # conforms to second version of ipsec.conf specification # basic configuration config setup dumpdir=/var/run/pluto/ #in what directory should things started by setup (notably the Pluto daemon) be allowed to dump core? nat_traversal=yes #whether to accept/offer to support NAT (NAPT, also known as "IP Masqurade") workaround for IPsec virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v6:fd00::/8,%v6:fe80::/10 #contains the networks that are allowed as subnet= for the remote client. In other words, the address ranges that may live behind a NAT router through which a client connects. oe=off protostack=netkey #decide which protocol stack is going to be used. conn L2TP-PSK-NAT rightsubnet=vhost:%priv also=L2TP-PSK-noNAT conn L2TP-PSK-noNAT authby=secret #shared secret. Use rsasig for certificates. pfs=no #Disable pfs rekey=no dpddelay=30 dpdtimeout=120 dpdaction=clear auto=add #start at boot keyingtries=3 #Only negotiate a conn. 3 times. ikelifetime=8h keylife=1h type=transport #because we use l2tp as tunnel protocol left=%SERVERIP% leftprotoport=17/%any right=%any rightprotoport=17/%any forceencaps=yes #force all to be nat'ed. because of iOS
將上述%SERVERIP%換成服務器IP
共享密鑰
用編輯器打開以下文件
/etc/ipsec.secrets
添加以下格式的內容
%SERVERIP% %any: PSK "69EA16F2C529E74A7D1B0FE99E69F6BDCD3E44"
%SERVERIP%為服務器IP地址。PSK為共享密鑰,可以用以下命令生成隨機密鑰
openssl rand -hex 30
驗證OpenSwan(IPSEC)設置
ipsec verify
我的機器示例輸出如下
Linux Openswan U2.6.37/K4.2.0-35-generic (netkey) Checking for IPsec support in kernel [OK] SAref kernel support [N/A] NETKEY: Testing XFRM related proc values [OK] [OK] [OK] Hardware RNG detected, testing if used properly [FAILED] Hardware RNG is present but 'rngd' or 'clrngd' is not running. No harware random used! Checking that pluto is running [OK] Pluto listening for IKE on udp 500 [OK] Pluto listening for NAT-T on udp 4500 [OK] Two or more interfaces found, checking IP forwarding [OK] Checking NAT and MASQUERADEing [OK] Checking for 'ip' command [OK] Checking /bin/sh is not /bin/dash [WARNING] Checking for 'iptables' command [OK] Opportunistic Encryption Support [DISABLED]
配置xl2tpd
用編輯器編輯下述文件
/etc/xl2tpd/xl2tpd.conf
將內容替換為以下內容
[global] ipsec saref = yes saref refinfo = 30 [lns default] ip range = 172.16.1.2-172.16.1.100 local ip = 172.16.1.1 refuse pap = yes require authentication = yes ppp debug = yes pppoptfile = /etc/ppp/options.xl2tpd length bit = yes
配置PPP
編輯以下文件
/etc/ppp/options.xl2tpd
將文件內容替換為以下內容
require-mschap-v2 ms-dns 8.8.8.8 ms-dns 8.8.4.4 auth mtu 1200 mru 1000 crtscts hide-password modem name l2tpd proxyarp lcp-echo-interval 30 lcp-echo-failure 4
添加用戶(用戶認證)
編輯以下文件添加用戶
/etc/ppp/chap-secrets
格式內容如下
# Secrets for authentication using CHAP # client server secret IP addresses alice l2tpd 0F92E5FC2414101EA * bob l2tpd DF98F09F74C06A2F *
可以使用以下腳本自動添加用戶名和密碼。復制內容到本地文件。重命名為addvpnuser.sh
#this script add vpn user to /etc/ppp/chap-secret #you must be root to run this script if [ $EUID -ne 0 ] then echo "You must be root to run this script." exit -1 fi if ! getopts ":a:d:q:" opt then echo "Usage: ./addvpnuser.sh -a username | -d username | -q username" echo "-a for add, -d for delete and -q for query user's password ." exit -1 fi OPTIND=0 while getopts ":a:d:q:" opt do case $opt in a) #add user switch is triggered. #check the username parameter is correct. if [[ $OPTARG = -* ]] then echo "Option -a needs an username as a parameter." ((OPTIND--)) continue fi #check whether the user to be added is existed. if grep -qP "^$OPTARG\t" /etc/ppp/chap-secrets then echo "cannot add user '$OPTARG' because the user has already existed." continue fi #get a random number less than 15. n=$RANDOM n=$(( n % 15 )) #VPN Server Type. TYPE="l2tpd" #get the server external IP. IP=`wget http://ipinfo.io/ip -qO -` #get the PRE PSK key of the VPN. PREKEY=`cat /etc/ipsec.secrets | tail -1 | awk '{print $4}' | cut -d\" -f2` #calculate user's password using the following algorithm. PW=`echo -n $OPTARG$RANDOM | md5sum | cut -c$n-$(( n+10 ))` echo -e "$OPTARG\t$TYPE\t$PW\t*" >> /etc/ppp/chap-secrets #successfully added user to configure file. #print out user information. copy and send to him. if [ $? -eq 0 ] then echo "Type: $TYPE" #IP=`ifconfig eth0 | grep "inet addr" | awk '{print $2}' | cut -d: -f2` echo "VPN Server IP: $IP" echo "User: $OPTARG Password: $PW" echo "PRE PSK KEY: $PREKEY" echo "Done." else #failed to write the file. echo "cannot write to configure file." fi ;; d) #echo "-d was triggered. Parameter: $OPTARG" #check the username parameter is correct. if [[ $OPTARG = -* ]] then echo "Option -d requires an username as a parameter." ((OPTIND--)) continue fi #check whether the user to be deleted is exist. if ! grep -qP "^$OPTARG\t" /etc/ppp/chap-secrets then echo "user '$OPTARG' does not exist." continue fi #maybe can use $$(pid) instead RANDOM1=$RANDOM RANDOM2=$RANDOM #delete and overwrite file. grep -vP "^$OPTARG\t" /etc/ppp/chap-secrets > /etc/ppp/chap-secrets$RANDOM1$RANDOM2 mv /etc/ppp/chap-secrets$RANDOM1$RANDOM2 /etc/ppp/chap-secrets #check result. if [ $? -eq 0 ] then echo "user '$OPTARG' has been successfully deleted." else echo "cannot write to file. Please check it." fi ;; q) #check the username parameter is correct. if [[ $OPTARG = -* ]] then echo "Option -q requires an username as a parameter." ((OPTIND--)) continue fi grep -P "^$OPTARG\t" /etc/ppp/chap-secrets | awk '{print $1, $3}' 2>/dev/null ;; \?) echo "Invalid option -$OPTARG" ;; :) echo "Option -$OPTARG requires an username as a parameter." ;; esac done
保存后為文件添加可執行權限
chmod 755 addvpnuser.sh
執行示例
#添加VPN用戶 ./addvpnuser.sh -a [username] #刪除VPN用戶 ./addvpnuser.sh -d [username] #查詢VPN用戶密碼 ./addvpnuser.sh -q [username]
測試
執行下列命令重啟IPsec和xl2tpd服務
/etc/init.d/ipsec restart
/etc/init.d/xl2tpd restart
防火牆
如果開啟了ufw防火牆的話,則需要開放udp 500, udp 4500, udp 1701三個端口
ufw allow 500/udp ufw allow 1701/udp ufw allow 4500/udp
注意
配置過程中發現按照上述步驟操作,通過Android或者iOS設備可以連接到VPN服務器,但是不能連接到互聯網。經過調試發現是由於Ubuntu開啟了ufw(防火牆),數據包被防火牆屏蔽掉了。解決辦法如下
打開以下文件
/etc/default/ufw
將下列行中的DROP替換成ACCEPT
DEFAULT_FORWARD_POLICY="DROP" 替換成 DEFAULT_FORWARD_POLICY="ACCEPT"
調試
出現無法連接或者無法聯網的情況,下列命令可以幫助調試
sudo tcpdump -i ppp0 sudo tail -f /var/log/auth.log sudo tail -f /var/log/syslog