Ubuntu 搭建OpenVPN服务器

sunfeng 2025-01-20 13:01 阅读数 10 #Linux

VPN:虚拟专用通道,是提供给企业之间或者个人与公司之间安全传输的隧道,OpenVPN是Linux下开源VPN的先锋,提供了良好的性能和友好的用户GUI。

OpenVPN通过使用公开密钥(非对称密钥,加密解密使用不同的Key,一个称为Publice Key,另外一个是Private Key)对数据进行加密的。这种方式称为TLS加密

OpenVPN使用TLS加密的工作过程是,首先VPN Sevrver端和VPN Client端要有相同的CA证书,双方通过交换证书验证双方的合法性,用于决定是否建立VPN连接。


1.安装 OpenVPN 和 Easy-RSA

安装 OpenVPN 和 Easy-RSA。 

Easy-RSA 是一种公钥基础设施 (PKI) 管理工具,用于在OpenVPN 服务器上生成证书请求。

sudo apt update
sudo apt upgrade
sudo apt install openvpn easy-rsa

安装完毕确认下openvpn版本

openvpn --version

2.通过 easy-rsa 制作CA证书、server端证书、client端证书

①制作CA证书

进入 /usr/share/easy-rsa 目录,将 vars.example 拷贝并重命名为 vars

cd /usr/share/easy-rsa/
sudo cp vars.example vars

sunfeng@ubuntu:/usr/share/easy-rsa$ ls
easyrsa  openssl-easyrsa.cnf  vars  vars.example  x509-types

然后编辑 vars ,去掉注释并修改内容

#国家
set_var EASYRSA_REQ_COUNTRY    "CN"
#省份
set_var EASYRSA_REQ_PROVINCE    "Beijing"
#市
set_var EASYRSA_REQ_CITY      "Beijing"
#版本
set_var EASYRSA_REQ_ORG      "Copyleft Certificate Co"
#邮箱
set_var EASYRSA_REQ_EMAIL     "me@example.net"
#组织
set_var EASYRSA_REQ_OU       "My Organizational Unit"

在末尾加入 export KEY_NAME 值(随意设置)并记住,制作服务端证书事会用到

#set_var EASYRSA_DIGEST         "sha256"

# Batch mode. Leave this disabled unless you intend to call Easy-RSA explicitly
# in batch mode without any user input, confirmation on dangerous operations,
# or most output. Setting this to any non-blank string enables batch mode.
#
#set_var EASYRSA_BATCH          ""
export KEY_NAME="BTyun"

查看 easy-rsa 命令描述

upport for subjectAltName
--------------------------

# ./easyrsa init-pki
# ./easyrsa build-ca nopass
# ./easyrsa --subject-alt-name="DNS:www.example.net,DNS:secure.example.net" build-server-full alttest nopass

https://github.com/OpenVPN/easy-rsa/issues/22#issuecomment-362899370

开始制作 CA 证书

sudo ./easyrsa init-pki
sudo ./easyrsa build-ca nopass
sunfeng@ubuntu:/usr/share/easy-rsa$ sudo ./easyrsa init-pki
Notice
------
'init-pki' complete; you may now create a CA or requests.

Your newly created PKI dir is:
* /usr/share/easy-rsa/pki

Using Easy-RSA configuration:
* /usr/share/easy-rsa/vars

sunfeng@ubuntu:/usr/share/easy-rsa$ sudo ./easyrsa build-ca nopass
Using Easy-RSA 'vars' configuration:
* /usr/share/easy-rsa/vars

Using SSL:
* openssl OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)
.........+.........+.....+.+..+...+++++++++*....+...+..............+.+...+++++*...+......+..+++++
.......+
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:

Notice
------
CA creation complete. Your new CA certificate is at:
* /usr/share/easy-rsa/pki/ca.crt

sunfeng@ubuntu:/usr/share/easy-rsa$ ls
easyrsa  openssl-easyrsa.cnf  pki  vars  vars.example  x509-types
sunfeng@ubuntu:/usr/share/easy-rsa$ cd pki        #进入pki目录需要修改pki目录的权限 sudo chmod -R 755 pki
sunfeng@ubuntu:/usr/share/easy-rsa/pki$ ls
ca.crt           index.txt       inline  openssl-easyrsa.cnf  reqs     serial
certs_by_serial  index.txt.attr  issued  private              revoked

pki目录下多出一个 ca.crtca.crt就是CA端证书,包含 CA 的公钥,用于验证服务器和客户端证书的有效性。客户端会使用此证书来验证服务器的身份。

②制作服务端证书

sudo ./easyrsa build-server-full BTyun nopass    # BTyun 是制作CA证书时在vars中添加的 export KEY_NAME 值    # nopass表示不加密
sunfeng@ubuntu:/usr/share/easy-rsa$ sudo ./easyrsa build-server-full BTyun nopass
Using Easy-RSA 'vars' configuration:
* /usr/share/easy-rsa/vars

Using SSL:
* openssl OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)
...............+.+.....+...+.+.....+..........+...+...+..............+.+..+.+..+....+...+..+....+..............+.+..+.........+.+...+...
Notice
------
Private-Key and Public-Certificate-Request files created.
Your files are:
* req: /usr/share/easy-rsa/pki/reqs/BTyun.req
* key: /usr/share/easy-rsa/pki/private/BTyun.key 

You are about to sign the following certificate:
Request subject, to be signed as a server certificate 
for '825' days:

subject=
    commonName                = BTyun

Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes        #此处需要输入“yes”

服务端证书制作完成,查看证书和私钥:

ls pki/issued/
ls pki/private/
sunfeng@ubuntu:/usr/share/easy-rsa$ ls pki/issued/
BTyun.crt
sunfeng@ubuntu:/usr/share/easy-rsa$ ls pki/private/
BTyun.key  ca.key

③制作客户端证书

sudo ./easyrsa build-client-full hkcnas nopass        # "hkcnas" 为客户端名称,可以随意修改   # nopass表示不加密
sunfeng@ubuntu:/usr/share/easy-rsa$ sudo ./easyrsa build-client-full hkcnas nopass
Using Easy-RSA 'vars' configuration:
* /usr/share/easy-rsa/vars

Using SSL:
* openssl OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)

WARNING
=======
Ignoring unknown command option: 'nopass~'
.+......+........+.............+..+.+..+.......+...+..++++++++++++++++++++++++++++++++++++++++*...+..+
....+......+..+.+..+...+.+........................+.....++++++++++++++++++++++++++++++++

客户端证书制作完成,查看证书和私钥:

ls pki/issued/
ls pki/private/
sunfeng@ubuntu:/usr/share/easy-rsa$ ls pki/issued/
BTyun.crt  hkcnas.crt
sunfeng@ubuntu:/usr/share/easy-rsa$ ls pki/private/
BTyun.key  ca.key  hkcnas.key

④创建Diffie-Hellman密钥

秘钥交换时的DH算法,确保密钥可以穿越不安全网络

sudo ./easyrsa gen-dh
sunfeng@ubuntu:/usr/share/easy-rsa$ sudo ./easyrsa gen-dh
Using Easy-RSA 'vars' configuration:
* /usr/share/easy-rsa/vars

Using SSL:
* openssl OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)
Generating DH parameters, 2048 bit long safe prime
........................................................................................
.....+.........................................................+..............................
....+.....................................................................+.......................
...........+............................................................................................
..................................................................
++*++*++*
DH parameters appear to be ok.

Notice
------

DH parameters of size 2048 created at:
* /usr/share/easy-rsa/pki/dh.pem

3、服务端配置文件

将服务端配置文件模板拷贝到 /etc/openvpn

sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/
cd /etc/openvpn/

根据个人情况修改 server.conf 配置信息

sudo vi server.conf
在#openvpn服务端的监听地址
local 0.0.0.0
#openvpn服务端的监听端口(默认1194)
port 1194
#使用的协议,tcp/udp
proto tcp
#使用三层路由ip隧道(tun),还是二层以太网隧道(tap),一般使用tun
dev tun
#ca证书、服务端证书、服务端秘钥和秘钥交换文件
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh.pem
# 网络拓扑
topology subnet
#vpn服务端为自己和客户端分配的ip地址池。
#服务端自己获取网段的第一个地址(此处是10.8.0.1),后为客户端分配其他的可用地址。以后客户端就可以和10.8.0.1进行通信。
注意:以下网段地址不要和已有网段冲突或重复
server 10.8.0.0  255.255.255.0
#使用一个文件记录已分配虚拟ip的客户端和虚拟ip的对应关系。以后openvpn重启时,将可以按照此文件继续为对应的客户端分配此前相同的ip(自动续借ip)
ifconfig-pool-persist ipp.txt
#使用tap模式的时候考虑此选项
server-bridge XXXXXX
#vpn服务端向客户端推送vpn服务端内网网段的路由配置,以便让客户端能够找到服务端的内网。多条路由写多个push指令
push "route 10.0.10.0  255.255.255.0"
Push "route 192.168.10.0 255.255.255.0"
# 启用后,所有客户端的默认网关都将重定向到VPN
push "redirect-gateway def1 bypass-dhcp"
# 推送DNS服务器
push "dhcp-option DNS 114.114.114.114"
push "dhcp-option DNS 223.5.5.5"
#让vpn客户端之间可以通信。默认情况客户端只能服务端进行通信
#默认此项是注释的,客户端之间不能相互通信
client-to-client
#多个用户共用一个证书,一般用于测试环境,生产环境都是一个用户一个证书
#默认是注释的,不支持多个客户端登录一个账号
duplicate-cn
#每10秒ping一次,120秒后没收到ping就说明对方挂了
keepalive 10 120
#加强认证方式,防攻击。如果配置文件中启用此项(默认是启用的),需要执行openvpn --genkey --secret ta.key,并把ta.key放到/etc/openvpn/server/目录,服务端第二个参数为0;同时客户端也要有此文件,且client.conf中此指令的第二个参数需要为1
tls-auth /etc/openvpn/server/ta.key 0
#选择一个密码。如果在服务器上使用了cipher选项,那么也必须在这里指定它。注意,v2.4客户端/服务端将在tls模式下自动协商AES-256-GCM
cipher AES-256-CBC
#openvpn 2.4版本的vpn才能设置此选项。表示服务端启用lz4的压缩功能 ,传输数据给客户端时会压缩数据包。
Push后在客户端也配置启用lz4的压缩功能,向服务端发数据时也会压缩。如果是2.4版本以下的老版本,则使用用comp-lzo指令
compress lz4-v2
push "compress lz4-v2"
#启用lzo数据压缩格式,此指令用于低于2.4版本的老版本,且如果服务端配置了该指令,客户端也必须要配置
comp-lzo
#并发客户端的连接数
max-clients 10
# 在完成初始化工作之后,降低OpenVPN守护进程的权限。 该指令仅限于非Windows系统中使用
user nobody
group nogroup
#通过ping得知超时时,当重启vpn后将使用同一个秘钥文件以及保持tun连接状态
persist-key
persist-tun
#在文件中输出当前的连接信息,每分钟截断并重写一次该文件
status openvpn-status.log
#log指令表示每次启动vpn时覆盖式记录到指定日志文件中
#log-append则表示每次启动vpn时追加式的记录到指定日志中
#但两者只能选其一,或者不选时记录到rsyslog中
log  /var/log/openvpn.log
log-append  /var/log/openvpn.log
# 为日志文件设置适当的冗余级别(0~9)。冗余级别越高,输出的信息越详细。
# 0 表示静默运行,只记录致命错误。
# 4 表示合理的常规用法。
# 5 和 6 可以帮助调试连接错误。
# 9 表示极度冗余,输出非常详细的日志信息。
verb 3
# 重复信息的沉默度。
# 相同类别的信息只有前20条会输出到日志文件中。
;mute 20

# 通知客户端,在服务端重启后可以自动重新连接,仅能用于udp模式,
# tcp模式不需要配置即可实现断开重连接
explicit-exit-notify 1

# 允许使用自定义脚本
# script-security 3

# 指定认证脚本
# auth-user-pass-verify /etc/openvpn/check.sh via-env

# 用户密码登陆方式验证
# username-as-common-name
注释掉server.conf 里VPN重定向客户端全部流量的配置
# push "redirect-gateway def1 bypass-dhcp"

修改客户端配置
在客户端配置文件中,增加下面的内容,第一行表示取消从VPN服务器拉取路由,第二行表示手动指定访问 192.168.1.0 这个网段的IP才会走VPN

route-nopull    # 不要从服务器拉取路由
route 192.168.1.0 255.255.255.0 # 指定 192.168.1.0 网段所有流量走VPN

4、运行OpenVPN Server

使用以下命令运行并查看OpenVPN Server

sudo systemctl start openvpn@server
sudo systemctl status openvpn@server

使用以下命令查看日志

sudo tail -f /var/log/openvpn/openvpn.log

5、设置防火墙

开启1194和SSH端口并重启ufw防火墙

sudo ufw allow 1194
sudo ufw allow OpenSSH
sudo ufw disable
sudo ufw enable


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

搜索
标签列表