在CentOS 7上搭建L2TP/IPSec服务,用来在外时也能访问内网Git服务器。
搭建方法有很多现成的脚本。

因为只需要设置一个简单的VPN, 查看了下teddysun/across的l2tp.sh比较方便,因此选用了该方法。
在此将脚本中有关CentOS 7的步骤罗列解析一下。方便后续有配置要改动的时候做到心中有数。

脚本化安装

脚本化安装步骤如下:

基础信息

脚本: https://github.com/teddysun/across/blob/master/l2tp.sh
安装环境: VMWare下的虚拟机上的CentOS 7
系统局域网IP: 192.168.172.193, 也是我们VPN的接入IP

下载安装脚本并修改

下载脚本

1
2
3
wget --no-check-certificate https://github.com/teddysun/across/blob/master/l2tp.sh
# 或者
wget --no-check-certificate https://raw.githubusercontent.com/teddysun/across/master/l2tp.sh

修改脚本中的IP为需要登录访问的IP:
此处需要注意,脚本中的get_os_info函数会检测服务器上的接入IP, 目前逻辑是会剔除局域网IP的。如果网口上没有配置的公网IP, 会请求ipv4.icanhazip.com来获取服务器的出口IP。
如果服务器上没有配置公网IP, 或者VPN搭建是为了内部接入,就需要修改脚本中函数get_os_info中变量IP的的值。
本例中,接入IP是192.168.172.193, 因此直接将IP设定为192.168.172.193即可。
l2tp.sh.org是原始脚本,l2tp.sh是修改后的脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ diff -C 3 l2tp.sh.org l2tp.sh
*** l2tp.sh.org Thu Aug 18 16:21:56 2022
--- l2tp.sh Thu Aug 25 09:56:37 2022
***************
*** 42,47 ****
--- 42,48 ----
get_os_info(){
IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 )
[ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com )
+ IP="192.168.172.193"
local cname=$( awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' )
local cores=$( awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo )
]$

运行安装脚本

运行脚本

1
2
3
# 赋予权限
chmod +x l2tp.sh
./l2tp.sh

初始会输出一些系统信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
###############################################################
# L2TP VPN Auto Installer #
# System Supported: CentOS 6+ / Debian 7+ / Ubuntu 12+ #
# Intro: https://teddysun.com/448.html #
# Author: Teddysun <i@teddysun.com> #
###############################################################
SELINUX=enforcing
########## System Information ##########
CPU model : Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz
Number of cores : 2
CPU frequency : 2711.687 MHz
Total amount of ram : 1819 MB
Total amount of swap : 2047 MB
System uptime : 0days, 0:15:30
Load average : 0.00, 0.02, 0.05
OS : CentOS 7.6.1810
Arch : x86_64 (64 Bit)
Kernel : 3.10.0-957.el7.x86_64
Hostname : localhost.localdomain
IPv4 address : 192.168.172.193
########################################

然后会要求输入一些数值,只要脚本默认的192.168.18网段和内网IP不冲突,可以直接一路回车,账号密码可以后续进行修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Please enter IP-Range:
(Default Range: 192.168.18):
Please enter PSK:
(Default PSK: teddysun.com):
Please enter Username:
(Default Username: teddysun):
Please enter teddysun's password:
(Default Password: f8wGwUZblx):
ServerIP:192.168.172.193
Server Local IP:192.168.18.1
Client Remote IP Range:192.168.18.2-192.168.18.254
PSK:teddysun.com
Press any key to start... or press Ctrl + C to cancel.

按回车进行安装,最终输出安装成功信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
###############################################################
# L2TP VPN Auto Installer #
# System Supported: CentOS 6+ / Debian 7+ / Ubuntu 12+ #
# Intro: https://teddysun.com/448.html #
# Author: Teddysun <i@teddysun.com> #
###############################################################
If there is no [FAILED] above, you can connect to your L2TP
VPN Server with the default Username/Password is below:
Server IP: 192.168.172.193
PSK : teddysun.com
Username : teddysun
Password : f8wGwUZblx
If you want to modify user settings, please use below command(s):
l2tp -a (Add a user)
l2tp -d (Delete a user)
l2tp -l (List all users)
l2tp -m (Modify a user password)
Welcome to visit our website: https://teddysun.com/448.html
Enjoy it!

接下来就直接可以根据输出的账号信息在客户端进行接入了

1
2
3
4
Server IP: 192.168.172.193
PSK : teddysun.com
Username : teddysun
Password : f8wGwUZblx

解析脚本安装过程

挖一下l2tp.sh的部署步骤,讲解涉及到CentOS 7下安装的各个步骤, 并且罗列一下,如果需要手动安装的话,哪些步骤和配置文件需要进行修改。

总步骤

脚本中的总步骤分为如下这几个函数:

1
2
3
4
5
6
7
8
rootness
tunavailable
disable_selinux
version_check
get_os_info
preinstall_l2tp
install_l2tp
finally

rootness

检查是不是root用户,必须要是root用户才可使用

tunavailable

检查文件/dev/net/tun是否存在,系统是否开启tun功能

脚本中的配置如下:

1
2
3
4
if [[ ! -e /dev/net/tun ]]; then
echo "Error:TUN/TAP is not available!" 1>&2
exit 1
fi

/dev/net/tun相关知识的拓展:

disable_selinux

关闭selinux

脚本中的配置如下:

1
2
3
4
if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
fi

version_check

检查如果是CentOS 5的话,提示不支持

get_os_info

得到系统的一些信息

  • 得到全局配置的公网IP, 如果要设置的局域网内网IP, 则需要手动指定
  • 输出一些系统信息:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    echo "########## System Information ##########"
    echo
    echo "CPU model : ${cname}"
    echo "Number of cores : ${cores}"
    echo "CPU frequency : ${freq} MHz"
    echo "Total amount of ram : ${tram} MB"
    echo "Total amount of swap : ${swap} MB"
    echo "System uptime : ${up}"
    echo "Load average : ${load}"
    echo "OS : ${opsy}"
    echo "Arch : ${arch} (${lbit} Bit)"
    echo "Kernel : ${kern}"
    echo "Hostname : ${host}"
    echo "IPv4 address : ${IP}"
    echo
    echo "########################################"

preinstall_l2tp

预安装检查

  • 输入IP-Range, 该IP是VPN服务器和VPN客户端之间使用的IP, 不需要设置为服务器内网IP或者公网IP, 存在全局变量 iprange 中
  • 输入PSK, VPN服务器和客户端间通讯连接需要协商的字串, 存在全局变量 mypsk 中
  • 输入Username, 服务器用户名(后续可修改), 存在全局变量 username 中
  • 输入password, 服务器用户密码(后续可修改), 存在全局变量 tmppassword 中

输出后续所需要用到的IP信息等

1
2
3
4
5
6
7
echo
echo "ServerIP:${IP}"
echo "Server Local IP:${iprange}.1"
echo "Client Remote IP Range:${iprange}.2-${iprange}.254"
echo "PSK:${mypsk}"
echo
echo "Press any key to start... or press Ctrl + C to cancel."

install_l2tp

install_l2tp 开始安装l2tp-vpn服务, 下面忽略脚本中debain和CentOS 6的安装分支,只介绍CentOS 7的安装步骤

安装yum包

1
2
3
yum -y install epel-release yum-utils
yum-config-manager --enable epel
yum -y install ppp libreswan xl2tpd firewalld

设置各个配置文件


设置/etc/ipsec.conf文件

脚本中的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
cat > /etc/ipsec.conf<<EOF
version 2.0
config setup
protostack=netkey
nhelpers=0
uniqueids=no
interfaces=%defaultroute
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!${iprange}.0/24
conn l2tp-psk
rightsubnet=vhost:%priv
also=l2tp-psk-nonat
conn l2tp-psk-nonat
authby=secret
pfs=no
auto=add
keyingtries=3
rekey=no
ikelifetime=8h
keylife=1h
type=transport
left=%defaultroute
leftid=${IP}
leftprotoport=17/1701
right=%any
rightprotoport=17/%any
dpddelay=40
dpdtimeout=130
dpdaction=clear
sha2-truncbug=yes
EOF

如果要手动安装的话,需要替换的部分

  • [config setup] -> [virtual_private] 中的${iprange}需要替换为实际使用的VPN内部协商的IP段,建议直接保留192.168.18即可
  • [conn l2tp-psk-nonat] -> [leftid] 中${IP}需要根据实际情况配置为VPN的接入IP, 公网VPN就设置为服务器的公网IP, 内网VPN就设置为服务器的局域网IP

设置/etc/ipsec.secrets文件

设置PSK 预共享密钥
脚本中的配置如下:

1
2
3
cat > /etc/ipsec.secrets<<EOF
%any %any : PSK "${mypsk}"
EOF

如果要手动安装的话,需要替换的部分

  • 将${mypsk}替换为实际需要设置的与共享密钥

设置 /etc/xl2tpd/xl2tpd.conf

设置xl2tp服务的配置

脚本中的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat > /etc/xl2tpd/xl2tpd.conf<<EOF
[global]
port = 1701
[lns default]
ip range = ${iprange}.2-${iprange}.254
local ip = ${iprange}.1
require chap = yes
refuse pap = yes
require authentication = yes
name = l2tpd
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
EOF

如果要手动安装的话,需要替换的部分

  • [lns default] -> [ip range], 中的${iprange}需要替换为实际使用的VPN内部协商的IP段,建议直接保留192.168.18即可
  • [lns default] -> [local ip], 中的${iprange}需要替换为实际使用的VPN内部协商的IP段,建议直接保留192.168.18即可

设置 /etc/ppp/options.xl2tpd

设置xl2tpd的options
脚本中的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat > /etc/ppp/options.xl2tpd<<EOF
ipcp-accept-local
ipcp-accept-remote
require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
noccp
auth
hide-password
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
proxyarp
connect-delay 5000
EOF

如果要手动安装的话,需要替换的部分

  • ms-dns: 可能需要修改为企业内部的DNS, 或者配置为可信的DNS

设置/etc/ppp/chap-secrets

配置vpn访问的用户名和密码

脚本中的配置如下:

1
2
3
4
5
6
rm -f /etc/ppp/chap-secrets
cat > /etc/ppp/chap-secrets<<EOF
# Secrets for authentication using CHAP
# client server secret IP addresses
${username} l2tpd ${password} *
EOF

如果要手动安装的话,需要替换的部分

  • 将${username} 替换为实际需要登录的用户名
  • 将${password} 替换为对应用户的密码

设置转发规则 /etc/sysctl.conf

备份原/etc/sysctl.conf文件,再添加一些配置

脚本中的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cp -pf /etc/sysctl.conf /etc/sysctl.conf.bak
echo "# Added by L2TP VPN" >> /etc/sysctl.conf
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_syncookies=1" >> /etc/sysctl.conf
echo "net.ipv4.icmp_echo_ignore_broadcasts=1" >> /etc/sysctl.conf
echo "net.ipv4.icmp_ignore_bogus_error_responses=1" >> /etc/sysctl.conf
for each in `ls /proc/sys/net/ipv4/conf/`; do
echo "net.ipv4.conf.${each}.accept_source_route=0" >> /etc/sysctl.conf
echo "net.ipv4.conf.${each}.accept_redirects=0" >> /etc/sysctl.conf
echo "net.ipv4.conf.${each}.send_redirects=0" >> /etc/sysctl.conf
echo "net.ipv4.conf.${each}.rp_filter=0" >> /etc/sysctl.conf
done
sysctl -p

如果要手动安装的话,需要替换的部分

  • 可以直接在shell中照着执行
  • 也可以先通过ls /proc/sys/net/ipv4/conf/列出所有的网卡,然后有选择的进行添加,物理机一般为eth0, eth1, 虚拟机可能为ens33, ens34

在firewalld中添加xl2tpd的servidce 开通4500和1701端口

脚本中的配置如下:

1
2
3
4
5
6
7
8
9
10
cat > /etc/firewalld/services/xl2tpd.xml<<EOF
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>xl2tpd</short>
<description>L2TP IPSec</description>
<port protocol="udp" port="4500"/>
<port protocol="udp" port="1701"/>
</service>
EOF
chmod 640 /etc/firewalld/services/xl2tpd.xml

如果要手动安装的话,需要替换的部分


启动ipsec, xl2tpd和firewalld

脚本中的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
systemctl enable ipsec
systemctl enable xl2tpd
systemctl enable firewalld
systemctl status firewalld > /dev/null 2>&1
if [ $? -eq 0 ]; then
firewall-cmd --reload
echo "Checking firewalld status..."
firewall-cmd --list-all
echo "add firewalld rules..."
firewall-cmd --permanent --add-service=ipsec
firewall-cmd --permanent --add-service=xl2tpd
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload
else
echo "Firewalld looks like not running, trying to start..."
systemctl start firewalld
if [ $? -eq 0 ]; then
echo "Firewalld start successfully..."
firewall-cmd --reload
echo "Checking firewalld status..."
firewall-cmd --list-all
echo "adding firewalld rules..."
firewall-cmd --permanent --add-service=ipsec
firewall-cmd --permanent --add-service=xl2tpd
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload
else
echo "Failed to start firewalld. please enable udp port 500 4500 1701 manually if necessary."
fi
fi
systemctl restart ipsec
systemctl restart xl2tpd
echo "Checking ipsec status..."
systemctl -a | grep ipsec
echo "Checking xl2tpd status..."
systemctl -a | grep xl2tpd
echo "Checking firewalld status..."
firewall-cmd --list-all

如果要手动安装的话,需要替换的部分

finally

最后将l2tp.sh安装文件拷贝至/usr/bin/l2tp,用于管理登录用户和密码,并输出登录信息

脚本中的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
cd ${cur_dir}
rm -fr ${cur_dir}/l2tp
# create l2tp command
cp -f ${cur_dir}/`basename $0` /usr/bin/l2tp
echo "Please wait a moment..."
sleep 5
ipsec verify
echo
echo "###############################################################"
echo "# L2TP VPN Auto Installer #"
echo "# System Supported: CentOS 6+ / Debian 7+ / Ubuntu 12+ #"
echo "# Intro: https://teddysun.com/448.html #"
echo "# Author: Teddysun <i@teddysun.com> #"
echo "###############################################################"
echo "If there is no [FAILED] above, you can connect to your L2TP "
echo "VPN Server with the default Username/Password is below:"
echo
echo "Server IP: ${IP}"
echo "PSK : ${mypsk}"
echo "Username : ${username}"
echo "Password : ${password}"
echo
echo "If you want to modify user settings, please use below command(s):"
echo "l2tp -a (Add a user)"
echo "l2tp -d (Delete a user)"
echo "l2tp -l (List all users)"
echo "l2tp -m (Modify a user password)"
echo
echo "Welcome to visit our website: https://teddysun.com/448.html"
echo "Enjoy it!"
echo

需要手动替换的部分

  • 可以通过命令来管理用户,也可以直接手动修改

客户端使用

客户端配置参见配置 IPsec/L2TP VPN 客户端, 这边对各个系统的客户端都做了详尽的说明。

Mac下连接VPN服务器提示无响应

如果Mac下自带的客户端连接时,提示出现服务器无响应,尝试编辑文件/etc/ppp/options, sudo vim /etc/ppp/options添加如下配置

1
2
plugin L2TP.ppp
l2tpnoipsec

如果不行,就把l2tpnoipsec去掉再尝试。

MacOS更新Monterey后,l2tp VPN连接异常

更新了Monterey后,l2tp VPN连接异常,变现为可以拨上号。可以ping IP, 但是DNS,ssh, http 内网服务无法访问。
网上找到了一个使用iphone连接的方法,但可能不通用。

还有一些相关的网址:

一些相关的命令

检测ipsec的命令

使用ipsec verify来验证ipsec的配置。
命令输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@localhost ~]# ipsec verify
Verifying installed system and configuration files
Version check and ipsec on-path [OK]
Libreswan 3.25 (netkey) on 3.10.0-957.el7.x86_64
Checking for IPsec support in kernel [OK]
NETKEY: Testing XFRM related proc values
ICMP default/send_redirects [OK]
ICMP default/accept_redirects [OK]
XFRM larval drop [OK]
Pluto ipsec.conf syntax [OK]
Two or more interfaces found, checking IP forwarding [OK]
Checking rp_filter [OK]
Checking that pluto is running [OK]
Pluto listening for IKE on udp 500 [OK]
Pluto listening for IKE/NAT-T on udp 4500 [OK]
Pluto ipsec.secret syntax [OK]
Checking 'ip' command [OK]
Checking 'iptables' command [OK]
Checking 'prelink' command does not interfere with FIPS [OK]
Checking for obsolete ipsec.conf options [OK]
[root@localhost ~]#

Reference

留言