Linux下SoftEther服务器搭建

  之前一直在用OpenVPN连接学校服务器获取学校资源,但是最近总是会间歇性的丢包,OpenVPN采用的UDP协议,隔一段时间会有一两分钟完全收不到包,表现出来就是虽然显示连接正常,但是这一两分钟完全连不上网络,过一会儿又一切正常,并且如果这时重连的话也一切正常。因此怀疑是链路上被干扰了。

  (4月9日追记:我可能错怪移动了,链路上应该并没有UDP连接干扰,而是家里换了光猫后,光猫的设置里自动开启了DoS攻击保护。可能长时间同一端口的UDP流量被光猫的防火墙误识别为了DoS攻击把下行流量丢弃了,现在关掉后似乎没问题了。另外IPv6真的是爽,在光猫上开启IPv6流量转发后可以从外网直连家里的计算机了,相当于家里每台设备都有公网地址了。)

  另一个问题是家里的网是300Mbps的光纤,但是连接OpenVPN后的速度只有40~50Mbps。之前一直以为是学校上传带宽的限制,但是前几天偶然发现直接从学校服务器通过HTTP下载速度能达到200Mbps以上,我才明白移动的光纤限速只有HTTP下载流量即TCP 80和443端口的下行流量能达到光纤的标识速度,其他的流量都被限制在了20~50Mbps。如此一来基于UDP的OpenVPN反而不如基于HTTPS的VPN占优势。(OpenVPN不建议用TCP,它的流量特征尤其是握手阶段与一般的HTTPS还是有所区别,使用TCP很容易被鉴别出来进行干扰。之前服务器用了TCP的OpenVPN之后感觉服务器端正常的HTTPS握手都被干扰了。)

  如此一来我就想到了前段时间看到的SoftEther这个开源VPN软件。它不仅有自己的Ethernet over HTTPS协议,服务端还同时支持OpenVPN、IPSec/L2TP、SSTP等VPN协议,这样只需在服务端安装一个SoftEther就可以从各种客户端进行连接。正好家里换了移动光猫后有IPv6了,并且学校IPv6的TCP端口没有被防火墙过滤。于是我准备搭建一个SoftEther服务器来代替之前的OpenVPN,这样客户端有IPv6的情况下可以使用SoftEther和SSTP等TCP协议,没有IPv6的情况下也可以使用基于UDP的OpenVPN进行连接(IPv4的TCP SYN数据包被学校路由器过滤掉了,因此无法直接进行IPv4的TCP连接)。

0x01 服务端配置

  我们的目标是用CentOS 7服务器搭建一个同时支持SoftEther VPN协议、OpenVPN协议以及SSTP协议的SoftEther服务器,并且组建一个同时支持IPv4和IPv6的NAT子网络。通过以下步骤来完成SoftEther服务器的配置工作。

1. 安装SoftEther

  在服务器上运行下列命令进行SoftEther VPN Server的安装

cd /usr/local
wget https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/v4.34-9745-beta/softether-vpnserver-v4.34-9745-beta-2020.04.05-linux-x64-64bit.tar.gz
tar xzf softether-vpnserver-v4.34-9745-beta-2020.04.05-linux-x64-64bit.tar.gz
cd vpnserver
make

  其中链接可根据情况替换为SoftEther官网上相应CPU最新版本的包。

2. 安全性设置

  SoftEther安装完成后默认开启了许多不必要的功能,需要将它们关闭以减少服务暴露的风险。我们首先将SoftEther服务启动并停止一次,让其自动生成vpn_server.config配置文件

./vpnserver start
./vpnserver stop

  之后用编辑器打开安装目录中的vpn_server.config文件做如下修改并保存

  • 关闭NAT穿越。通常来说我们的服务器都有公网IP,因此没必要开启NAT穿越,将bool DisableNatTraversal设置为true来禁用。
  • 关闭动态DNS。这个功能不但同样在有固定公网IP的情况下没有用处,相反还很容易使服务暴露,将块declare DDnsClient中的bool Disabled设置为true来禁用。
  • 关闭内建网页管理以及JsonRpc。默认情况下浏览器直接访问服务器地址就可以看到SoftEther VPN Server的介绍页面,这一下就暴露了服务器的用途,因此也要将其禁用,将bool DisableJsonRpcWebApi设置为true来禁用。

  之后再次输入命令./vpnserver start启动SoftEther服务器。为管理服务器,需要再从官网上下载SoftEther VPN Server Manager软件安装到自己的计算机上,安装完成后打开管理器,填入服务器地址进行连接,连接之后进行以下操作:

  • 关闭保持互联网连接。现在的计算机基本上都不会自动闲置断线了,因此也没必要开启,通过取消勾选加密与网络->使用并保持互联网连接禁用。
  • 删除多余的监听端口。所有的TCP监听端口功能都是一样的,保留一个即可,通过管理监听器->删除移除多余的端口,仅保留443端口。

3. 虚拟HUB设置

  HUB是集线器的意思,真实的HUB就是简单的将多台计算机用一根电缆连接起来。SoftEther提供了整个数据链路层的以太网协议,它的虚拟HUB相当于一个虚拟的交换机,提供了虚拟的物理层线路,我们需要进行一些设置使得客户端可以连接到这个虚拟HUB上。在Server管理器中点击管理虚拟HUB进行以下设置:

  • 创建用户。通过管理用户->新建创建一个用户,开源版本只能选择匿名认证或者密码认证,没有证书功能。
  • 允许IPv6默认路由器。默认情况下SoftEther不会向客户端设置IPv6的默认路由器,即客户端无法自动获取IPv6网关而连不上IPv6网络,因此需要通过虚拟HUB属性->编辑虚拟HUB扩展选项列表,将其中NoIPv6DefaultRouterInRAWhenIPv6的值修改为0以允许IPv6 RA数据包。
  • IPv6路由表。IPv6一般为全球单播地址,将ManageOnlyLocalUnicastIPv6修改为0来记录客户端的IPv6地址。

4. 证书设置

  SSTP连接需要和HTTPS一样的受信证书。因此如果有域名的话,最方便的方法是直接申请一个SSL证书,现在免费签发SSL证书的网站也有很多,这里推荐FreeSSL.cn这个网站,可以直接在浏览器上一键生成证书,当然如果需要安全性的话就需要自行考量了。生成的证书中包含证书文件full_chain.pem以及私钥文件private.key。在管理器中通过加密与网络->服务端证书设置->导入将以上两个文件导入到SoftEther服务器中,之后浏览器访问服务器的https地址就可以看到地址前面的小锁了,并且SSTP也可以成功连接了。

5. 本地网桥设置

  由于SoftEther自带的SecureNAT性能很低,并且不支持IPv6设置,所以用本地网桥来代替SecureNAT。参考Softether on VPS using local bridge - Coding, Coding, Coding这篇文章,先在Server管理器中通过本地网桥设置->新tap设备的桥接创建一个名称为softether的TAP设备,之后在服务器bash中输入命令ip addr应该可以看到tap_softether这个设备。接下来给这个设备分配IP地址

ip addr add 192.168.30.1/24 dev tap_softether
ip addr add fc01:250:5405:1::1/64 dev tap_softether

  现在我们的子网需要一个DHCP服务器来分配IPv4地址,以及IPv6路由器通告来配置客户端IPv6地址。这里安装dnsmasq来实现上述功能,当然也可以使用dhcpd作为DHCP服务器,radvd作为IPv6的路由器通告。输入命令yum -y install dnsmasq安装程序,之后将配置文件/etc/dnsmasq.conf编辑成以下内容

# 仅在该虚拟网络设备上提供DHCP服务,如果设置不当可能会被网管封禁MAC地址
interface=tap_softether
# IPv4分配地址范围,需要在之前分配给设备的地址范围之内
dhcp-range=tap_softether,192.168.30.50,192.168.30.150,12h
# IPv6路由器通告
dhcp-range=tap_softether,fc01:250:5405:1::, ra-only
# 开启IPv6路由器定期广告,不开启的话会导致客户端连接30分钟后IPv6消失
enable-ra

  然后就可以启动dnsmasq了

systemctl start dnsmasq

6. 设置IP转发及NAT

  使用以下命令开启IPv4以及IPv6转发,并使之生效

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
sysctl -p

  IPv6的转发可能还要在/etc/sysconfig/network中加入IPV6FORWARDING=yes。然后利用iptables工具配置NAT,可将命令写在/etc/rc.local中使其重启后也能生效

iptables --table nat --append POSTROUTING --out-interface ens192 --jump MASQUERADE
ip6tables --table nat --append POSTROUTING --out-interface ens192 --jump MASQUERADE

  虽然IPv6不推荐NAT,但是由于我们的服务器并不是路由器,返回VPN客户端的数据包无法正确从服务端连接的路由器路由到VPN服务端,并且服务端的路由器会丢弃来自网络内部却声称外部地址的数据包,在桥接TAP设备的情况下很难不经过NAT实现IPv6的互联网连接。因此对于IPv6我们仍旧使用了NAT,这样也可以获取各高校的IPv6资源了。

7. 开机自启动

  为实现SoftEther开机后可以自启动我们需要编写一个服务脚本,在/etc/systemd/system中创建一个服务脚本文件softether.service编辑成以下内容

[Unit]
Description=The SoftEther VPN Server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
ExecStart=/usr/local/vpnserver/vpnserver start
ExecStartPost=/usr/local/vpnserver/start_post.sh
ExecStop=/usr/local/vpnserver/vpnserver stop

[Install]
WantedBy=multi-user.target

  由于SoftEther服务器停止后会自动删除本地网桥,每次启动后需要重新给TAP设备分配IP地址,因此需要创建个启动后运行脚本/usr/local/vpnserver/start_post.sh,内容为

#!/bin/bash

sleep 2
ip addr add 192.168.30.1/24 dev tap_softether
ip addr add fc01:250:5405:1::1/64 dev tap_softether

  最后设置服务开机自启动

systemctl enable softether
systemctl enable dnsmasq

0x02 客户端配置

1. SoftEther VPN Client

  SoftEther VPN协议需要在客户端进行一些设置来提高性能及安全性,打开属性界面进行以下设置

  • 勾选禁用NAT-T。服务器有公网IP的情况下没必要使用NAT穿越,因此将其关闭。
  • 勾选总是验证服务端证书,防止中间人攻击。
  • 勾选高级设置->禁用UDP加速功能。关闭不必要的功能防止服务被识别。
  • 设置合适的高级设置->TCP连接数。我这里设置成6,即一般浏览器默认的同一域名最大并发连接数。
  • 勾选高级设置->设置每个TCP的连接寿命,并设置合适的寿命。有些环境中保持过长的TCP连接会自动断掉,这里我们设置为180秒,以符合一般HTTP服务器的KeepAlive超时时间。
  • 不要勾选使用SSL 3.0并且始终保持勾选高级设置->使用SSL加密VPN会话。默认情况下会使用安全性比SSL 3.0更高的TSL版本,使用SSL 3.0的话有可能会被链路干扰,并且为了安全性,需要始终保持链路加密。

2. OpenVPN

  关于OpenVPN的详细内容可参见本博客中另一篇文章『Linux下OpenVPN服务器搭建』,这里只有一个主要的不同点,开源版本的SoftEther只能使用密码认证的方法进行连接,不支持原先的证书认证。其配置文件可通过Server管理器上的OpenVPN/MS-SSTP设置->为OpenVPN Client生成配置样本文件获得。

  注意由于SoftEther源码没有实现点对点链路的IPv6支持,采用dev tun的话只能支持IPv4子网,要想支持IPv6子网的话需要使用dev tap。在TAP模式下,SoftEther服务端不会推送redirect-gateway选项。由于SoftEther无法直接修改服务端的OpenVPN配置文件,要想所有流量都走VPN的话,需要在客户端配置文件添加以下几行内容

# IPv4
route-gateway dhcp
redirect-gateway def1 bypass-dhcp
# IPv6
route-ipv6 fc00::/7 fc01:250:5405:1::1
route-ipv6 3000::/4 fc01:250:5405:1::1
route-ipv6 2000::/4 fc01:250:5405:1::1
route-ipv6 ::/3 fc01:250:5405:1::1

  另外可在客户端配置文件中加入remote-cert-tls server来验证服务端证书,防止中间人攻击。

  对于需要自动连接的情况,可以将用户名和密码保存到一个文件,比如/etc/openvpn/pass.txt,第一行为用户名,第二行为密码

username
password

  然后配置文件中auth-user-pass这一行改为

auth-user-pass /etc/openvpn/pass.txt

  这样启动openvpn的时候就可以不用交互输入用户名密码了。

3. SSTP

  SSTP其实是PPP over HTTPS,它的所有流量通过TCP 443端口在SSL加密下进行。SSTP是微软开发的VPN协议,因此在Windows系统中有内建的SSTP客户端,无需安装任何额外软件即可使用。Windows 10下打开设置->网络和Internet->VPN->添加VPN连接,VPN提供商选择Windows(内置),VPN类型选择安全套接字隧道协议(SSTP),填入其他相应的信息即可创建SSTP连接。

2条评论

  1. 感谢那么详细的文章,我尝试建立了softethervpn服务,但尝试通过ipv6下的openvpn连接udp 1194端口无法建立连接,连接ipv4 udp1194则正常;然后我就尝试连接ipv6的tcp 5555也正常。

    接着我看netstat -nlptu|grep vpn看了下服务器监听的端口:
    root@OpenWrt:~# netstat -nlptu|grep vpn
    tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 5392/vpnserver
    tcp 0 0 0.0.0.0:992 0.0.0.0:* LISTEN 5392/vpnserver
    tcp 0 0 0.0.0.0:1194 0.0.0.0:* LISTEN 5392/vpnserver
    tcp 0 0 0.0.0.0:5555 0.0.0.0:* LISTEN 5392/vpnserver
    tcp 0 0 :::443 :::* LISTEN 5392/vpnserver
    tcp 0 0 :::992 :::* LISTEN 5392/vpnserver
    tcp 0 0 :::1194 :::* LISTEN 5392/vpnserver
    tcp 0 0 :::5555 :::* LISTEN 5392/vpnserver
    udp 0 0 0.0.0.0:1701 0.0.0.0:* 5392/vpnserver
    udp 0 0 0.0.0.0:47745 0.0.0.0:* 5392/vpnserver
    udp 0 0 0.0.0.0:23241 0.0.0.0:* 5392/vpnserver
    udp 0 0 0.0.0.0:60981 0.0.0.0:* 5392/vpnserver
    udp 0 0 0.0.0.0:4500 0.0.0.0:* 5392/vpnserver
    udp 0 0 0.0.0.0:500 0.0.0.0:* 5392/vpnserver
    udp 0 0 0.0.0.0:1194 0.0.0.0:* 5392/vpnserver

    发现并没有监听ipv6的udp 1194端口,请问是不是softethervpn还不支持openvpn的ipv6 udp功能?

发表评论

电子邮件地址不会被公开。 必填项已用*标注