Ubuntu 15.10搭建IPSec L2TP服務器


以下步驟完全使用於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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM