
背景:
我有一台Debian服务器,它的配置是4代i5 + 16G内存,目前运行了很多Web服务,包括魔兽世界-巫妖王之怒。到目前为止,都很流畅,是真的流畅。因为我优化的好???
但是随着军团再临版本的更新,i5 4590 + 16G已经无法流畅的运行军团再临的服务端了。军团再临不仅吃CPU,还吃内存,4核16G分分钟给我干爆!
于是,为了艾泽拉斯
,我迫切需要升级我的服务器。
洋垃圾
然后,贫穷使我理智
。
我忽然想起来之前在拼多多淘的洋垃圾,E5 CPU + 64G内存,别说跑一个服务器,打10个都没问题。
服务器是有了,但是洋垃圾的网络环境有点尴尬,它在一个手机热点的网络环境中,没有公网IP,不能直接映射Debian的请求,那怎么去实现呢?
OpenVPN
好朋友G哥你太美告诉我通过搭建虚拟专用网络可以实现,我把问题简单化一下,如图所示:
Debian服务器需要将某些请求映射到E5 洋垃圾,公网无法直接映射,那就给它来条专线🚀,也就是VPN(虚拟专用网络)。
关键词
- OpenVPN 安全可靠的VPN,开源且免费
- EasyRSA 管理X.509PKI(公钥基础设施),颁发生成证书
- 军团再临 全新的军团再临服务器,哥哥不注册一个号嘛?
- Debian Server虽然i5 4590,但咱后头有人~
- 马伯恩的小站
OpenVpn
OpenVPN也是属于VPN,也就是虚拟专用网络,是指一种使用公共互联网等不安全通信介质在计算机设备和计算机网络之间或两个网络之间创建安全连接
的机制。
简单的可以理解为拉了一条虚拟专线,话不多说,我们直接开搞!
先决条件
- 一台CA服务器,用于证书的颁发,包括服务器和客户端的证书
- 一台OpenVPN服务器,用于搭建VPN的服务端,这里我们就使用Debian服务器
- 一台客户端,用于虚拟网络的测试,也就是我们的洋垃圾
安装配置CA服务器
我们这里通过虚拟机另起一台Debian机器,用作于我们的CA服务器
。
- 安装EasyRSA EasyRSA是用于构建我们的CA公钥技术设施(PKI)的工具,通过如下命令安装:
sudo apt update
wget -P ~/ https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.6/EasyRSA-unix-v3.1.6.tgz
- 解压EasyRSA
cd ~
tar xvf EasyRSA-unix-v3.1.6.tgz
- 配置EasyRSA并构建CA EasyRSA 安装了一个配置文件,您可以编辑该文件来为您的 CA 定义许多变量。
在您的CA 机器上,导航到 EasyRSA 目录:
cd ~/EasyRSA-v3.1.6/
在这个目录中有一个名为vars.example
. 制作此文件的副本,并命名副本,vars
但不带文件扩展名:
cp vars.example vars
使用我们熟悉的文本编辑器打开这个新文件:
gedit vars
查找为新证书设置字段默认值的设置。它看起来像这样:
~/EasyRSA-v3.1.6/vars
. . .
#set_var EASYRSA_REQ_COUNTRY "US"
#set_var EASYRSA_REQ_PROVINCE "California"
#set_var EASYRSA_REQ_CITY "San Francisco"
#set_var EASYRSA_REQ_ORG "Copyleft Certificate Co"
#set_var EASYRSA_REQ_EMAIL "me@example.net"
#set_var EASYRSA_REQ_OU "My Organizational Unit"
. . .
取消注释这些行并将突出显示的值更新为自己喜欢的任何值,但不要将它们留空:
~/EasyRSA-v3.1.6/vars
. . .
set_var EASYRSA_REQ_COUNTRY "CN"
set_var EASYRSA_REQ_PROVINCE "Peking"
set_var EASYRSA_REQ_CITY "BeiJing"
set_var EASYRSA_REQ_ORG "majun.fun"
set_var EASYRSA_REQ_EMAIL "jason@majun.fun"
set_var EASYRSA_REQ_OU "Mazeroth VPN"
. . .
完成后,保存并关闭文件。
EasyRSA 目录中有一个脚本,调用easyrsa
它来执行与构建和管理 CA 相关的各种任务。运行此脚本并init-pki
选择在 CA 服务器上启动公钥基础结构:
./easyrsa init-pki
输出看起来是这样:
Output
. . .
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/jason/EasyRSA-v3.1.6/pki
在此之后,再次调用easyrsa
脚本,并跟随build-ca
选项。这将构建 CA 并创建两个重要的文件 –ca.crt
和ca.key
– 构成 SSL 证书的公共和私有方面信息。
ca.crt
是 CA 的公共证书文件,在 OpenVPN 的上下文中,服务器和客户端使用它来通知彼此它们是同一信任网络的一部分,而不是执行中间人攻击的人。因此,您的服务器和所有客户端都需要该ca.crt
文件的副本。ca.key
是 CA 机器用来为服务器和客户端签署密钥和证书的私钥。如果攻击者获得对您的 CA 的访问权限,进而访问您的ca.key
文件,他们将能够签署证书请求并获得对您的 VPN 的访问权限,从而阻碍其安全性。这就是为什么你的ca.key
文件应该只在你的 CA 机器上。
理想情况下,你的 CA 机器应该在不签署证书请求时保持离线状态作为额外的安全措施。(说通俗点就是为机器颁发完证书之后,就关闭,以保证安全性。)
如果您不想在每次与 CA 交互时都提示输入密码(推荐做法
),则可以build-ca
使用该nopass
选项运行命令,如下所示:
./easyrsa build-ca nopass
在输出中,系统会要求您确认CA的通用名称:
Output
. . .
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:
公用名是用于在证书颁发机构上下文中引用此机器的名称。您可以为 CA 的通用名称输入任何字符串,但为简单起见,请按ENTER接受默认名称。
这样,您的 CA 服务器就已就绪,可以开始签署证书请求了。
安装配置OpenVPN服务器
我们需要再OpenVPN服务器上安装2个应用,分别是OpenVPN的服务端和EasyRSA应用。不要问我为什么又要安装EasyRSA,让你装,你就装。
sudo apt update
# 安装OpenVPN服务端
sudo apt install openvpn
#安装EasyRSA应用
wget -P ~/ https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.6/EasyRSA-unix-v3.1.6.tgz
cd ~
#解压EasyRSA
tar xvf EasyRSA-unix-v3.1.6.tgz
现在我们已经准备好 CA,我们可以从OpenVPN的服务器生成一个私钥和证书请求,然后将请求传输到 CA服务器 进行签名,从而创建所需的证书。还可以自由创建一些在加密过程中使用的附加文件(新手就别折腾这个了)。
首先导航到OpenVPN服务器上的 EasyRSA 目录:
cd EasyRSA-v3.1.6/
从那里,easyrsa
使用该init-pki
选项运行脚本。尽管我们已经在 CA 机器上运行了此命令,但有必要在此处运行它,因为您的服务器和 CA 将具有单独的 PKI
目录:
./easyrsa init-pki
然后再次调用easyrsa
脚本,这次使用gen-req
选项后跟机器的通用名称。
为了测试方便,OpenVPN 服务器的通用名称将简单地称为“server”。一定要包括该nopass
选项。如果不这样做,将对请求文件进行密码保护,这可能会导致以后出现权限问题:
./easyrsa gen-req server nopass
注意:如果我们在此处选择“server”以外的名称,则必须调整下面的一些说明。例如,将生成的文件复制到
/etc/openvpn
目录时,我们必须替换正确的名称。我们还必须/etc/openvpn/server.conf
稍后修改该文件以指向正确的.crt
和.key
文件。
这将为服务器创建一个私钥和一个名为server.req
, 将服务器密钥复制到/etc/openvpn/
目录:
sudo cp ~/EasyRSA-v3.1.6/pki/private/server.key /etc/openvpn/
使用安全方法(例如 SCP,在我们下面的示例中),将server.req文件传输到我们的 CA 机器(如果是虚拟机,也可以直接拷贝):
scp ~/EasyRSA-v3.1.6/pki/reqs/server.req jason@your_CA_ip:/tmp
接下来,在我们的 CA 机器上,导航到 EasyRSA 目录:
cd EasyRSA-v3.1.6/
再次使用easyrsa调用该脚本server.req,按照文件路径及其通用名称导入文件:
./easyrsa import-req /tmp/server.req server
然后通过运行easyrsa
并带有sign-req
的选项来签署请求,加上请求类型和通用名称。请求类型可以是client
或server
,但对于 OpenVPN 服务器的证书请求,请务必使用server
请求类型:
./easyrsa sign-req server server
在输出中,系统会要求验证请求是否来自受信任的来源。输入yes然后按ENTER确认:
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a server certificate for 1080 days:
subject=
commonName = server
Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes
如果我们加密了 CA 密钥,此时系统会提示输入密码,输入即可。
接下来,使用安全方法将签名证书传输回我们的 OpenVPN 服务器:
scp pki/issued/server.crt jason@your_server_ip:/tmp
在注销我们的 CA 机器之前,也将ca.crt
文件也传输到我们的OpenVPN服务器:
scp pki/ca.crt jason@your_server_ip:/tmp
接下来,重新登录到 OpenVPN服务器并将server.crt
和ca.crt
文件复制到/etc/openvpn/
目录中:
sudo cp /tmp/{server.crt,ca.crt} /etc/openvpn/
然后导航到我们的 EasyRSA 目录:
cd EasyRSA-v3.1.6/
从那里,通过键入以下内容创建一个强大的 Diffie-Hellman 密钥以在密钥交换期间使用:
./easyrsa gen-dh
这可能需要几分钟才能完成。完成后,生成 HMAC 签名以加强服务器的 TLS 完整性验证功能:
sudo openvpn --genkey secret ta.key
命令完成后,将两个新文件复制到/etc/openvpn/
目录中:
sudo cp ~/EasyRSA-v3.1.6/ta.key /etc/openvpn/
sudo cp ~/EasyRSA-v3.1.6/pki/dh.pem /etc/openvpn/
最后一步,我们还需要将我们的服务器启用ipv4转发:
打开/etc/sysctl.conf
文件并添加或取消注释以下行net.ipv4.ip_forward = 1
:
sudo gedit /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
完成后,保存并关闭文件。
通过如下命令应用新的设置:
sudo sysctl -p
net.ipv4.ip_forward = 1
如果有防火墙的话,我们还需要配置防火墙规则,我这边就不做赘述了。
这样,我们的服务器所需的所有证书和密钥文件都已生成。同时也准备好了创建相应的证书和密钥,我们的客户端计算机将使用这些证书和密钥来访问 OpenVPN 服务器。
启动OpenVPN服务器
在启动OpenVPN服务器之前,我们需要对配置文件进行配置:
复制配置文件模板至/etc/openvpn/
路径下:
sudo cp -ri /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/server.conf"
然后使用gedit打开配置文件:
sudo gedit /etc/openvpn/server.conf
- 找到证书,密钥和 DH 参数指令并更改文件名:
cert server1.crt
key server1.key
dh dh.pem
- 要通过 VPN 重定向客户端流量,请查找并取消注释redirect-gateway和dhcp-option选项:
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 114.114.114.114"
push "dhcp-option DNS 8.8.8.8"
- 找到userandgroup指令并通过删除每行开头的
;
来取消对这些设置的注释:
user nobody
group nogroup
- 在文件末尾追加以下行。该指令将消息认证算法 (HMAC) 从 SHA1 更改为 SHA256
auth SHA256
完成后,服务器配置文件(不包括注释)应如下所示:
port 1194
proto tcp
dev tun
ca ca.crt
cert server.crt
key server.key # This file should be kept secret
dh dh.pem
server 192.168.1.3 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 114.114.114.114"
push "dhcp-option DNS 8.8.8.8"
keepalive 10 120
tls-auth ta.key 0 # This file is secret
cipher AES-256-CBC
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
verb 3
explicit-exit-notify 1
auth SHA256
我们通过如下命令启用OpenVPN服务器:
sudo systemctl start openvpn@server
通过键入以下内容验证服务是否已成功启动:
sudo systemctl status openvpn@server
● openvpn@server.service - OpenVPN connection to server
Loaded: loaded (/lib/systemd/system/openvpn@.service; disabled; vendor preset: enabled)
Active: active (running) since Tue 2023-08-29 03:49:53 PDT; 3s ago
Docs: man:openvpn(8)
https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
https://community.openvpn.net/openvpn/wiki/HOWTO
Process: 1722 ExecStart=/usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --config /etc/openvpn/server.conf --writepid /run/openvpn/server.pid (code=exited, status=0/SUCCESS)
Main PID: 1723 (openvpn)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
└─1723 /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --config /etc/openvpn/server.conf --writepid /run/openvpn/server.pid
设置开机启动项:
sudo systemctl enable openvpn@server
Created symlink /etc/systemd/system/multi-user.target.wants/openvpn@server.service → /lib/systemd/system/openvpn@.service
启动时,OpenVPN 服务器会创建一个 tun 设备tun0。要验证它,请使用如下命令 :
ip a show tun0
输出应如下所示:
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
link/none
inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
valid_lft forever preferred_lft forever
至此,我们的 OpenVPN 服务器已配置并正常运行。
配置客户端证书和密钥
生成客户端证书和配置文件的整个过程如下:
- 在 OpenVPN 服务器上生成私钥和证书请求。
- 将请求发送到要签名的 CA 机器。
- 将签名的 SSL 证书复制到 OpenVPN 服务器并生成配置文件。
- 将配置文件发送到 VPN 客户端的机器。
为了简单起见,我们直接在OpenVPN服务器上为客户端创建客户端证书和密钥文件,在根目录下创建一个目录结构:
mkdir -p ~/openvpn-clients/{configs,base,files}
base
目录将存储将在所有客户端文件之间共享的基本文件和配置。configs
目录将存储生成的客户端配置。files
目录将存储客户端特定的证书/密钥对。
将ca.crt
和ta.key
文件复制到~/openvpn-clients/base
目录:
cp ~/EasyRSA-v3.1.6/ta.key ~/openvpn-clients/base/
cp /etc/openvpn/ca.crt ~/openvpn-clients/base/
接下来将示例 VPN 客户端配置文件复制到 client-~/openvpn-clients/base
目录中。我们将使用此文件作为基本配置:
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/openvpn-clients/base/
现在我们需要编辑文件以匹配我们的服务器设置和配置。使用文本编辑器打开配置文件:
gedit ~/openvpn-clients/base/client.conf
- 找到 remote 指令并使用 OpenVPN 服务器的公共 IP 地址:
# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote www.majun.fun 1194
接下来,将示例客户端配置文件复制到client-configs
目录中以用作基本配置:
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
在文本编辑器中打开这个新文件:
gedit ~/client-configs/base.conf
在里面,找到remote指令。这将客户端指向 OpenVPN 服务器地址——我们的 OpenVPN 服务器的公共 IP 地址:
~/client-configs/base.conf
. . .
# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
# server ip 也可以是域名
remote your_server_ip 1194
. . .
找到并注释掉ca,cert和key指令,证书和密钥将添加到客户端配置文件中:
# SSL/TLS parms.
# See the server config file for more
# description. It's best to use
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.
# ca ca.crt
# cert client.crt
# key client.key
在文件末尾追加以下行以匹配服务器设置:
auth SHA256
完成后,客户端配置文件应如下所示:
client
dev tun
proto tcp
remote www.majun.fun 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
verb 3
auth SHA256
key-direction 1
下面,我们创建一个简单的bash脚本,它将帮助我们合并配置文件和证书,并将生成的配置存储到~/openvpn-clients/configs
目录中。
打开编辑器创建以下脚本:
gedit ~/openvpn-clients/gen_config.sh
创建之后,添加脚本文件:~/openvpn-clients/gen_config.sh
#!/bin/bash
FILES_DIR=$HOME/openvpn-clients/files
BASE_DIR=$HOME/openvpn-clients/base
CONFIGS_DIR=$HOME/openvpn-clients/configs
BASE_CONF=${BASE_DIR}/client.conf
CA_FILE=${BASE_DIR}/ca.crt
TA_FILE=${BASE_DIR}/ta.key
CLIENT_CERT=${FILES_DIR}/${1}.crt
CLIENT_KEY=${FILES_DIR}/${1}.key
# Test for files
for i in "$BASE_CONF" "$CA_FILE" "$TA_FILE" "$CLIENT_CERT" "$CLIENT_KEY"; do
if [[ ! -f $i ]]; then
echo " The file $i does not exist"
exit 1
fi
if [[ ! -r $i ]]; then
echo " The file $i is not readable."
exit 1
fi
done
# Generate client config
cat > ${CONFIGS_DIR}/${1}.ovpn <<EOF
$(cat ${BASE_CONF})
<key>
$(cat ${CLIENT_KEY})
</key>
<cert>
$(cat ${CLIENT_CERT})
</cert>
<ca>
$(cat ${CA_FILE})
</ca>
<tls-auth>
$(cat ${TA_FILE})
</tls-auth>
EOF
保存文件并使其可执行chmod
:
chmod u+x ~/openvpn-clients/gen_config.sh
创建客户端证书私钥和配置
生成客户端私钥和证书请求的过程与我们生成服务器密钥和证书请求的过程相同。我们将创建一个VPN客户端的配置文件。
- 在OpenVPN的服务器上的EasyRSA目录上为客户端生成新的私钥和证书请求文件:
cd ~/EasyRSA-v3.1.6/
./easyrsa gen-req client nopass
该命令将创建两个文件,一个私钥 (client.key
) 和一个证书请求文件 (client.req
)。
Common Name (eg: your user, host, or server name) [client]:
Keypair and certificate request completed. Your files are:
req: /home/majun/EasyRSA-v3.1.6/pki/reqs/client.req
key: /home/majun/EasyRSA-v3.1.6/pki/private/client.key
- 将私钥
client.key
复制到~/openvpn-clients/files
目录中:
cp ~/EasyRSA-v3.1.6/pki/private/client.key ~/openvpn-clients/files/
- 将证书请求文件传输到我们的CA服务器:
scp ~/EasyRSA-v3.1.6/pki/reqs/client.req jason@your_ca_ip:/tmp
- 登录我们的CA服务器,然后导入证书请求文件:
cd ~/EasyRSA-v3.1.6
./easyrsa import-req /tmp/client.req client
第一个参数是证书请求文件的路径,第二个参数是客户端名称。
The request has been successfully imported with a short name of: client
You may now use this name to perform signing operations on this request.
- 从CA机器上的 EasyRSA 目录中运行以下命令来签署请求:
cd ~/EasyRSA-v3.1.6
./easyrsa sign-req client client
系统会提示验证请求是否来自受信任的来源。输入yes
并按下enter
确认:
...
Certificate created at: /home/causer/EasyRSA-v3.1.6/pki/issued/client.crt
- 接下来,将签名的证书
client.crt
文件传输回我们的OpenVPN服务器:
scp ~/EasyRSA-v3.1.6/pki/issued/client.crt jason@your_server_ip:/tmp
- 登录到OpenVPN服务器,并将
client.crt
文件移动到~/openvpn-clients/files
目录中:
mv /tmp/client.crt ~/openvpn-clients/files
- 最后一步是使用
gen_config.sh
脚本生成客户端配置。切换到~/openvpn-clients
目录并使用客户端名称作为参数运行脚本:
cd ~/openvpn-clients
./gen_config.sh client
该脚本将在~/client-configs/configs
目录中创建一个名为client.ovpn
的文件。您可以通过列出目录来检查:
ls ~/openvpn-clients/configs
client.ovpn
要添加其他客户端,只需重复相同的步骤。
测试配置客户端
首先,我们在测试机器上安装OpenVPN客户端,下载地址:https://openvpn.net/client/client-connect-vpn-for-windows/
然后将我们刚刚生成的客户端配置文件导入OpenVPN客户端中即可。
OpenVPN连接完成状态:
结束语
要点总结:
- 证书的签名比较繁琐,所以有点难办。
- VPN的排错部分需要对网络有一定的了解,但是,都是百度一下就能出的东西,也不是太难办。
- 难办。
