本文介绍了如何安装OpenVPN服务器,以及如何对Windows、OS X、iOS和安卓的接入进行设置。
要求
- Ubuntu 16.04服务器
- sudo权限:你可以根据Ubuntu 16.04 initial server setup guide来设置用户拥有适当的权限。这篇教程也建立了防火墙,我们在本教程中假设已经设置好了。
步骤一:安装OpenVPN
首先在服务器上安装OpenVPN。在Ubuntu的默认软件库中有OpenVPN,所以可以用apt
命令进行安装。然后需要安装easy-rsa
软件包,这个包用于建立一个内部CA (certificate authority,证书颁发机构)供VPN使用。
$ sudo apt-get update
$ sudo apt-get install openvpn easy-rsa
这样需要用到的软件就安装好了。
步骤二:创建CA目录
OpenVPN是一个TLS/SSL VPN。这表示它使用证书来加密服务器和客户端之间的流量。为了颁发可信任的证书,我们需要建立自己的简单认证机构(CA)。
首先,我们可以使用make-cadir
命令将easy-rsa
模板目录复制到我们的主目录中:
$ make-cadir ~/openvpn-ca
进入新创建的目录中,开始配置CA:
$ cd ~openvpn-ca
步骤三:配置CA变量
为了配置我们的CA会用到的变量,需要编辑这个目录下的vars
文件。用文本编辑器打开这个文件:
$ vim vars
在这个文件中,你可以找到一些变量,这些变量用来决定你的证书是如何创建的。
在文件底部,找到类似下面的行,这些行为新证书设置了一些默认值:~/openvpn-ca/vars
. . .
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="[email protected]"
export KEY_OU="MyOrganizationalUnit"
. . .
你可以随便修改这些设置的值,但是不要为空。
我们也需要编辑这一块下面的KEY_NAME
值,为了简单起见,在这篇教程中我们把它设成server
:~/openvpn-ca/vars
export KEY_NAME="server"
步骤四:建立证书颁发机构
现在,我们可以使用我们刚才设置的变量和easy-rsa
程序来构建我们的证书颁发机构。
确保你现在在CA目录下,然后source
刚刚编辑的vars
文件:
$ cd ~/openvpn-ca
$ source vars
如果正确source
的话,那么会看到:
Output
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/sammy/openvpn-ca/keys
确保我们在一个干净的环境中操作:
$ ./clean-all
现在可以通过以下命令来构建根CA:
$ ./build-ca
这会启动创建根证书颁发机构的密钥以及证书的过程。由于我们上面修改了vars
文件,所有的值都会自动填充。只需要根据提示按Enter键确认选择即可:
Output
Generating a 2048 bit RSA private key
..........................................................................................+++
...............................+++
writing new private key to 'ca.key'
-----
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.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [NY]:
Locality Name (eg, city) [New York City]:
Organization Name (eg, company) [DigitalOcean]:
Organizational Unit Name (eg, section) [Community]:
Common Name (eg, your name or your server's hostname) [DigitalOcean CA]:
Name [server]:
Email Address [admin@email.com]:
现在我们有了一个CA,可以用来创建我们需要的其他文件。
步骤五:创建服务器证书、密钥和加密文件
下面,我们会生成服务器证书以及密钥对,以及在加密过程中需要的其他文件。
首先生成OpenVPN服务器证书以及密钥对:
注意:如果你选择的名字不是
server
, 那么下面的指导中需要做些调整。比如,在把生成的文件复制到/etc/openvpn
目录下时,必须替换为正确的名称。你还需要修改/etc/openvpn/server.conf
文件以指向正确的.crt
和.key
文件。
$ ./build-key-server server
现在你只需要按Enter键接受默认值即可。在最后的时候,你需要为两个问题输入y
来签署和提交证书:
Output
. . .
Certificate is to be certified until May 1 17:51:16 2026 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
接下来,我们将生成一些其他项。我们可以通过下面的命令生成强大的Diffie-Hellman密钥以在密钥交换的过程中使用:
$ ./build-dh
这会花费几分钟的时间。
之后,我们可以生成一个HMAC签名来加强服务器的TLS完整性炎症功能:
$ openvpn --genkey --secret keys/ta.key
步骤六:生成客户端证书和密钥对
接下来,我们可以生成客户端证书和密钥对。尽管这可以在客户端机器上完成,然后出于安全的目的由服务器/CA进行签名,但为了简单起见,在本指南中我们将在服务器上生成签名密钥。
本指南中我们会生成一个客户端密钥/证书,但如果你有多个客户端,可以根据需要多次重复此过程。为每个客户传递一个唯一值给脚本。
因为你过会可能会回到这一步,我们会重新source
vars
文件。本指南中我们会使用client1
作为证书/密钥对的值。
输入如下命令:
$ cd ~/openvpn-ca
$ source vars
$ ./build-key client1
同样,默认值会自动填充,所以只要按Enter键继续。将密码留空,并确保对是否签名并提交证书的问题输入y。
步骤七:配置OpenVPN服务
下面我们会使用生成的证书以及文件来配置OpenVPN服务。
拷贝文件到OpenVPN目录
首先,我们需要把必要的文件拷贝到/etc/openvpn
配置目录中。
可以从我们刚刚生成的所有文件开始。这些文件在生成的时候位于~openvpn-ca/keys
目录下。我们需要移动CA证书、服务器证书和密钥、HMAC签名以及Diffie-Hellman文件:
$ cd ~/openvpn-ca/keys
$ sudo cp ca.crt server.crt server.key ta.key dh2048.pem /etc/openvpn
然后,我们需要拷贝并解压一个简单的OpenVPN配置文件到配置目录中:
$ gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf
修改OpenVPN配置
现在我们可以修改服务器配置文件了:
sudo vim /etc/openvpn/server.conf
基本配置
首先,通过查找tls-auth
指定找到HMAC部分。删掉”;”来取消注释tls-auth
行。在下一行添加key-direction
参数并设置为”0”:/etc/openvpn/server.conf
tls-auth ta.key 0 # This file is secret
key-direction 0
然后,通过查找注释掉的cipher
行来找到加密密码部分。AES-128-CBC
密码提供了很好的加密级别。删掉”;”以取消掉cipher AES-128-CBC
行的注释:/etc/openvpn/server.conf
cipher AES-128-CBC
在这行的下面加上auth
行来选择HMAC消息算法。SHA256
就很好:/etc/openvpn/server.conf
auth SHA256
最后找到user
和group
设置并删掉”;”来取消注释:/etc/openvpn/server.conf
user nobody
group nogroup
(可选)重定向所有流到VPN
上面的设置会建立两台机器之间的VPN连接,但是不会强制任何连接使用隧道。如果你希望使用VPN来路由所有的流量,那么你需要将DNS设置推送到客户端电脑。
取消那些注释掉配置客户端重定向所有流到VPN的指令。找到redirect-gateway
部分并删除”;”:/etc/openvpn/server.conf
push "redirect-gateway def1 bypass-dhcp"
在下面,找到dhcp-option
部分,删掉”;”:/etc/openvpn/server.conf
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
这应该有助于客户端重新配置DNS设置,以使用VPN隧道作为默认网关。
(可选)修改端口和协议
默认情况下,OpenVPN服务器使用端口1194和UDP协议来接受客户端连接。如果你需要使用不同的端口,是可以更改端口选项的。可以用端口443,因为一般这是被防火墙规则允许的:/etc/openvpn/server.conf
# Optional!
port 443
通常协议也会被限制在该端口,如果是这样的花,把协议从UDP修改到TCP:/etc/openvpn/server.conf
# Optional!
proto tcp
如果你不需要使用不同的端口,最好把两个设置设成默认值。
(可选)指向非默认证书
如果之前在./build-key-server
命令中选择了其他的名字,需要修改cert
和key
行指向正确的.crt
和.key
文件。如果使用了默认的server
,则应该已经正确设置:/etc/openvpn/server.conf
cert server.crt
key server.key
完成之后,保存并关闭文件。
步骤八:修改服务器网络配置
下面我们需要对服务器的网络做一些调整使得OpenVPN可以正确路由流量。
允许IP转发
首先,我们需要允许服务器转发流量。这对于我们希望VPN服务器提供的功能是非常重要的。
可以通过修改/etc/sysctl.conf
文件来调整设置:
$ sudo vim /etc/sysctl.conf
找到设置net.ipv4.ip_forward
的那一行,删除这行前面的”#”:/etc/sysctl.conf
net.ipv4.ip_forward=1
保存并关闭文件。
要读取文件并调整当前会话的值,请输入:
$ sudo sysctl -p
调整UFW规则以伪装客户端连接
如果你遵守要求里面的Ubuntu 16.04初始服务器设置指南,那么应该有UFW防火墙。无论你是否使用防火墙阻止不想要的流量,这篇指南中我们需要防火墙来处理进入服务器的一些流量。我们需要修改规则文件来设置伪装,这是一个iptables的概念,它提供了即时动态NAT来正确路由客户端连接。
在打开防火墙配置文件添加伪装之前,我们需要找到机器的公网接口。为此,请输入:
$ ip route | grep default
你的公网接口应该在单词”dev”后面。比如,下面的结果显示了名为wlp11s0
的接口:
Output
default via 203.0.113.1 dev wlp11s0 proto static metric 600
当你的接口与默认路由相关联时,打开/etc/ufw/before.rules
文件来添加相关配置:
$ sudo vim /etc/ufw/before.rules
这个文件处理处理在加载传统UFW规则之前应该放置的配置。在文件顶部添加下面的行。这会为nat
表中的POSTROUTING
链接设置默认策略,并伪装来自VPN的所有流量:/etc/ufw/before.rules
注意:记得把
-A POSTROUTING
行中的wlp11s0
换成你自己的接口。
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
# ufw-before-input
# ufw-before-output
# ufw-before-forward
#
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to wlp11s0 (change to the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/8 -o wlp11s0 -j MASQUERADE
COMMIT
# END OPENVPN RULES
# Don't delete these required lines, otherwise there will be errors
*filter
. . .
保存并关闭文件。
我们需要告诉UFW默认允许转发数据包。为此,我们打开/etc/default/ufw
文件:
sudo vim /etc/default/ufw
找到DEFAULT_FORWARD_POLICY
指令,把值从DROP
改成ACCEPT
:/etc/default/ufw
DEFAULT_FORWARD_POLICY="ACCEPT"
保存并关闭文件。
打开OpenVPN端口并启用更改
下面,我们将调整防火墙本身以允许流量到OpenVPN。
如果你没有改变/etc/openvpn/server.conf
文件中的端口和协议,你需要打开UDP流量到端口1194。如果你修改了端口和/或协议,请使用你选择的值。
我们还会添加SSH端口:
$ sudo ufw allow 1194/udp
$ sudo ufw allow OpenSSH
现在我们禁用然后重新启用UFW来加载所有修改过的文件中的更改:
$ sudo ufw disable
$ sudo ufw enable
服务器现在配置成可以正确处理OpenVPN流量。
步骤九:启动并启用OpenVPN服务
我们终于准好好在服务器上启动OpenVPN服务了。可以使用systemd来做到这点。
我们需要通过在systemd单元文件名称后面指定配置文件名作为实例变量来启动OpenVPN服务器。我们服务器的配置文件叫做/etc/openvpn/server.conf
,所以我们会在单元文件的末尾添加@server
:
$ sudo systemctl start openvpn@server
通过下面的命令检查服务是否成功启动:
$ sudo systemctl status openvpn@server
如果一切正常,那么你的输出应该看起来像:
Output
● openvpn@server.service - OpenVPN connection to server
Loaded: loaded (/lib/systemd/system/[email protected]; disabled; vendor preset: enabled)
Active: active (running) since Tue 2016-05-03 15:30:05 EDT; 47s ago
Docs: man:openvpn(8)
https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
https://community.openvpn.net/openvpn/wiki/HOWTO
Process: 5852 ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid (code=exited, sta
Main PID: 5856 (openvpn)
Tasks: 1 (limit: 512)
CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
└─5856 /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/server.conf --writepid /run/openvpn/server.pid
May 03 15:30:05 openvpn2 ovpn-server[5856]: /sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2
May 03 15:30:05 openvpn2 ovpn-server[5856]: /sbin/ip route add 10.8.0.0/24 via 10.8.0.2
May 03 15:30:05 openvpn2 ovpn-server[5856]: GID set to nogroup
May 03 15:30:05 openvpn2 ovpn-server[5856]: UID set to nobody
May 03 15:30:05 openvpn2 ovpn-server[5856]: UDPv4 link local (bound): [undef]
May 03 15:30:05 openvpn2 ovpn-server[5856]: UDPv4 link remote: [undef]
May 03 15:30:05 openvpn2 ovpn-server[5856]: MULTI: multi_init called, r=256 v=256
May 03 15:30:05 openvpn2 ovpn-server[5856]: IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
May 03 15:30:05 openvpn2 ovpn-server[5856]: IFCONFIG POOL LIST
May 03 15:30:05 openvpn2 ovpn-server[5856]: Initialization Sequence Completed
你也可以通过下面的命令检查OpenVPNtun0
接口是否可用:
$ ip addr show tun0
你应该看到一个配置接口:
Output
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue 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
如果一切正常,启用服务以便在服务器启动的时候自动启动:
$ sudo systemctl enable openvpn@server
步骤十:创建客户配置
下面,我们需要建立一个系统,使我们能轻松创建客户端配置文件。
创建客户配置目录结构
在home目录下创建一个目录结构用来保存文件:
$ mkdir -p ~/client-configs/files
因为我们的客户端配置文件将嵌入客户端密钥,我们应该锁定内部目录的权限:
$ chmod 700 ~/client-configs/files
创建一个基本配置
下面,我们将示例客户端配置拷贝到我们的目录中作为一个基本配置:
$ cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
打开这个新文件:
$ vim ~/client-configs/base.conf
首先,定位到remote
指令。这把客户指向到我们的OpenVPN服务器地址。这应该是你的OpenVPN服务器的公网IP地址。如果你修改了OpenVPN服务器正在侦听的接口,那么把1194
改成你选择的接口:~/client-configs/base.conf
. . .
# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote server_IP_address 1194
. . .
确保协议和你在服务器配置中使用的一样:~/client-configs/base.conf
proto udp
下面,删除”;”取消注释user
和group
指令:~/client-configs/base.conf
# Downgrade privileges after initialization (non-Windows only)
user nobody
group nogroup
找到设置ca
,cert
,key
的指令。注释掉这些指定,因为我们会在文件本身中添加certs和keys:~/client-configs/base.conf
# 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
修改cipher
和auth
为我们在/etc/openvpn/server.conf
文件中设置的:~/client-configs/base.conf
cipher AES-128-CBC
auth SHA256
下面,在文件中添加key-direction
指令。必须设置成1才能使用服务器:~/client-configs/base.conf
key-direction 1
最后,添加一些注释掉的行。我们想在每个配置中都包含这些配置,但只应该为Linux客户端启用它们,配合/etc/openvpn/update-resolv-conf
文件。此脚本使用resolvconf
更新Linux客户端的DNS信息:~/client-configs/base.conf
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
如果你的客户端运行在Linux上并且具有/etc/openvpn/update-resolv-conf
文件,那么应该从生成的OpenVPN客户端配置文件中取消注释这些行。
保存文件。
创建配置生成脚本
下面,我们会创建一个简单的脚本,用相关证书、密钥和加密文件来编译我们的基本配置。这会把生成的配置文件放在~/client-configs/files
目录下。
在~/client-configs
目录下创建并打开一个文件make_config.sh
:
$ vim ~/client-configs/make_config.sh
粘贴下面的脚本到这个文件中:~/client-configs/make_config.sh
#!/bin/bash
# First argument: Client identifier
KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf
cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-auth>') \
${KEY_DIR}/ta.key \
<(echo -e '</tls-auth>') \
> ${OUTPUT_DIR}/${1}.ovpn
保存并关闭文件。
通过下面命令把这个脚本文件设置为可执行:
$ chmod 700 ~/client-configs/make_config.sh
步骤十一:生成客户端配置
现在可以很容易地生成客户端配置文件。
如果你遵守这篇指南,那么在步骤六中通过运行./build-key client1
命令,分别创建了一个客户端证书client1.crt
和秘钥client1.key
。我们可以使用创建的脚本文件生成配置:
$ cd ~/client-configs
$ ./make_config.sh client1
如果一切正常,那么在~/client-configs/files
目录下会生成一个client1.opvn
文件:
$ ls ~/client-configs/files
Output
client1.ovpn
把配置文件传到客户端设备
我们需要把客户端配置文件传输到相关设备上。比如,你的本地计算机或者一个移动设备。
虽然用于完成此传输的程序取决于你的选择和设备的操作系统,但你希望应用程序在后端使用SFTP和SCP。这将通过加密连接传输客户端的VPN认证文件。
以下是使用SFTP命令传输client1.opvn
的示例。这个命令可以在你的本地计算机(OS X或者Linux)运行。它把.opvn
文件放到你的主目录中:
sftp sammy@openvpn_server_ip:client-configs/files/client1.ovpn ~/
当然你也可以选择其他方式把服务器上的.opvn
文件传到你的本地计算机或者其他设备中。
未完,下一篇:Ubuntu 16.04上安装OpenVPN服务器(二)