希望通过自己的智能手机或者笔记本经由非受信网络(例如旅馆或者咖啡厅WiFi)安全访问互联网?虚拟专有网络 (VPN)无疑是最理想的解决方案。流量会首先被引导至VPN服务器,而后再前往目的地。
在结合了HTTPS连接后,这套设置允许我们保证自己的无线登录与事务处理流程。大家可以突破地理限制,并对自己的位置及未加密HTTP流量进行保护。
OpenVPN是一套功能齐全的开源安全嵌套层(简称SSL)VPN解决方案,且提供广泛的配置选项。在本教程中,我们将在Droplet上设置一套OpenVPN服务器,而后立足于Windows、OS X、iOS与Android对其进行访问。本教程会尽量简化相关配置流程。
先决条件
要完成本教程,大家需要接入一套Ubuntu 16.04服务器。
另外,我们还需要以sudo权限配置一个非root用户。
准备就绪后,以sudo用户登录Ubuntu服务器。
第一步——安装OpenVPN
首先在服务器上安装OpenVPN。Ubuntu默认库中即提供OpenVPN,另外我们还需要安装easy-rsa软件包,其负责为VPN设置一套内部CA(即认证中心)。
更新服务器软件包目录并安装必要软件包类型:
sudo apt-get update
sudo apt-get install openvpn easy-rsa
现在必要的软件已经安装完成,接下来进行配置。
第二步——设置CA目录
OpenVPN属于TLS/SSL VPN,意味着其利用证书对服务器与客户端间的流量进行加密。为了使用受信证书,我们需要设置自己的简单认证中心(简称CA)。
首先将easy-rsa模板目录复制到主目录中:
make-cadir ~/openvpn-ca
前往新目录并开始配置CA:
cd ~/openvpn-ca
第三步——配置CA变量
要配置CA所使用的变量,我们需要编辑目录内的vars文件。打开该文件:
nano vars
找到需要调整的对应变量。首先在文件结尾处找到新证书的默认设置字段:
~/openvpn-ca/vars
. . .
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"
. . .
将红字部分修改为实际值,但千万不要留空:
~/openvpn-ca/vars
. . .
export KEY_COUNTRY="US"
export KEY_PROVINCE="NY"
export KEY_CITY="New York City"
export KEY_ORG="DigitalOcean"
export KEY_EMAIL="admin@example.com"
export KEY_OU="Community"
. . .
另外,我们还要编辑接下来的KEY_NAME。为了方便起见,本示例中将其称为server:
~/openvpn-ca/vars
export KEY_NAME="server"
完成后保存并退出。
第四部:构建认证中心
现在我们可以构建自己的认证中心了。确保当前处于CA目录内,而后source刚刚编辑完成的vars文件:
cd ~/openvpn-ca
source vars
如果操作无误,则输出结果如下:
Output
请注意,如果大家运行./clean-all,则在/home/sammy/openvpn-ca/keys中执行rm -rf。
确保在清洁环境下执行指令:
./clean-all
现在构建我们的root CA:
./build-ca
由于我们已经调整了vars文件,因此所有值都能够自动填充。直接按下回车确认即可:
Output
Generating a 2048 bit RSA private key
...............................+++
...............................+++
writing new private key to 'ca.key'
-----
现在根据提示向输入信息。
这里需要输入的为专有名称,简称DN。
其中字段很多,但我们可以将一部分留空。部分字段已经拥有默认值,输入“.”则会令字段留空。
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服务器证书与密钥对:
./build-key-server server
其中仍然包含部分基于服务器与vars文件的默认值。
大家可以按入回车接受默认值。这时先不要输入密码,在结尾处我们在两个问题中按下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进行签署,但在本教程中我们将直接在服务器上生成签名密钥以简化流程。
由于大家可能在读到后面时需要返回这部分内容,所以我们对vars文件再source一次。这里使用client1作为首套证书/密钥对的值:
cd ~/openvpn-ca
source vars
./build-key client1
各默认项目仍然已经填充完成,一路回车即可。密码留空,按两次y以确认签署并提交证书。
第七步——配置OpenVPN服务
下面开始利用刚刚生成的证书与文件配置OpenVPN服务。
将文件复制到OpenVPN目录
首先将需要的文件复制到/etc/openvpn配置目录。
我们可以先从已经生成完毕的全部文件开始。这些文件位于~/openvpn-ca/keys,我们需要移动其中的CA证书与密钥、服务器证书与密钥、HMAC签名以及Diffie-Hellman文件:
cd ~/openvpn-ca/keys
sudo cp ca.crt ca.key 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 nano /etc/openvpn/server.conf
首先取消几条指令的注释,从而配置客户端设备以将全部网络流量通过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"
下面找到包含tls-auth指令的HMAC部分,取消其注释并添加key-direction参数,其值为“0”:
/etc/openvpn/server.conf
tls-auth ta.key 0 # This file is secret
key-direction 0
最后找到user与group设置,删除“;”取消注释:
/etc/openvpn/server.conf
user nobody
group nogroup
完成后保存并退出。
第八步:调整服务器网络配置
下面调整服务器网络,从而保证OpenVPN能够正确路由流量。
允许IP转发
首先,允许服务器进行流量转发。
修改/etc/sysctl.conf文件中的设置实现:
sudo nano /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。
打开/etc/ufw/before.rules文件并添加相关配置:
sudo nano /etc/ufw/before.rules
此文件负责处理那些应当在UFW规则载入完成前首先到位的配置。在文件顶部,添加以下高亮部分,这意味着nat表中的POSTROUTING链将拥有默认策略,同时伪装一切来自该VPN的流量:
/etc/ufw/before.rules
#
# 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]
# END 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
. . .
在以上行中,我们需要修改-A POSTROUTING行以匹配自己的公共网络接口。要找到公共接口,使用以下命令:
ip route | grep default
我们的公共接口应当在“dev”一词之后。例如,此结果显示接口名为wlp11s0,那么相关显示内容如下:
Output
default via 192.168.1.1 dev wlp11s0 proto static metric 600
使用找到的结果对-A POSTROUTING规则中的部分进行替换:
/etc/ufw/before.rules
#
# 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 eth0
-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 nano /etc/default/ufw
在这里找到DEFAULT_FORWARD_POLICY指令,将其值由DROP变更为ACCEPT:
/etc/default/ufw
DEFAULT_FORWARD_POLICY="ACCEPT"
完成后保存并退出。
打开OpenVPN端口并启用变更
下面调整防火墙,在端口1194上接纳UDP流量:
sudo ufw allow 1194/udp
现在我们可以禁用再重新启用UFW,从而载入之前做出的变更:
sudo ufw disable
sudo ufw enable
服务器配置完成,OpenVPN流量已经能够得到正确处理。
第九步:启动并启用OpenVPN服务
我们使用systemd在服务器上启动OpenVPN服务。
我们需要在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/openvpn@.service; 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
我们还可以检查OpenVPN tun0接口是否可用:
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
第十步:创建客户端配置基础设施
下面,我们设置一套系统以轻松创建客户端配置文件。
创建客户端配置目录结构
在主目录中设置配置目录结构以容纳这些文件:
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
打开此新文件:
nano ~/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.
remote server_IP_address 1194
. . .
下面删除“;”以取消user与group指令的注释:
~/client-configs/base.conf
# Downgrade privileges after initialization (non-Windows only)
user nobody
group nogroup
找到设置ca、cert与key的指令,将其调整为注释,因为我们需要在文件内部添加证书与密钥:
~/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
最后添加key-direction指令,将其值设定为“1”以实现同服务器的协作:
~/client-configs/base.conf
key-direction 1
完成后保存并退出。
创建一套配置生成脚本
现在我们创建一套简单的脚本,负责将我们的基本配置编译为对应的证书、密钥与加密文件。这套脚本将把配置生成至~/client-configs/files目录。
在~/client-configs目录中生成一个make_config.sh文件:
nano ~/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
第十一步:生成客户端配置
如果大家严格按照本教程的顺序,那么已经分别创建了客户端证书与密钥。我们可以前往~/client-configs目录并使用之前生成的脚本生成配置:
cd ~/client-configs
./make_config.sh client1
如果一切顺利,那么现在~/client-configs/files目录中已经出现了client1.ovpn文件:
ls ~/client-configs/files
Output
client1.ovpn
将配置传输至客户端设备
我们需要将客户端配置文件传递至对应设备。
大家可能希望应用在后端上使用SFTP(即SSH文件传输协议)或者SCP(安全复制)。这意味着我们的客户端VPN验证文件将通过加密连接进行传输。
以下命令可以运行在本地计算机上,其负责在主目录中放置.ovpn文件:
sftp sammy@openvpn_server_ip:client-configs/files/client1.ovpn ~/
第十二步:安装客户端配置
下面了解如何在各类系统平台上安装客户端VPN配置。
OpenVPN连接的名称与.ovpn文件名称一致。在本示例中,意味着连接名称为client1。
Windows
安装
大家可以通过OpenVPN下载页面获取OpenVPN的Windows版本。选择与您所用系统版本对应的安装器版本。
注意,OpenVPN需要管理权限方可正常安装。安装完成后,将.ovpn文件复制到:
C:\Program Files\OpenVPN\config
OpenVPN必须在每次使用时以管理员权限运行。这意味着标准用户需要输入管理员密码方可使用OpenVPN。另外,标准用户无法接入该服务器,除非客户端上的OpenVPN应用拥有管理员权限。
大家可以右键点击其图标并前往属性选项使其始终以管理员方式运行,而后在兼容性标签最下方点击以确保变更对全部用户有效。
连接
在每次启动OpenVPN GUI,Windows都会询问是否希望其对计算机做出变更。点击同意。启动OpenVPN客户端,系统托盘中会显示其图标并在必要时连接并断开VPN。
OpenVPN启动时,我们需要在系统托盘图标处右击以初始化一条连接。弹出菜单中选定client1,而后选择连接。
连接建立后,会有状态窗口显示日志输出结果。
右击系统托架内的图标并选择断开连接,即可断开VPN。
OS X
安装
Tunnelblick是一款OS X的免费开源OpenVPM客户端。 大家可以通过Tunnelblick下载页面下载,双击.dmg文件并根据提示进行安装。
在安装流程结束时,Tunnelblick会询问是否拥有配置文件。回答无即可完成安装。打开Finder窗口并双击client1.ovpn,Tunnelblick会安装该客户端配置(要求管理权限)。
连接
在应用程序文件夹内启动Tunnelblick。启动后,屏幕右上角会显示其图标。点击该图标,而后选择连接选项以初始化VPN连接。最后选定client1进行连接。
iOS
安装
在iTunes App Store中搜索并安装OpenVPN Connect。要将iOS客户端配置传输至设备,可直接将其接入计算机。
打开计算机上的iTunes,点击iPhone应用。下滚至底部文件共享部分,点击OpenVPN应用。在右侧的空白处,即为OpenVPN文件共享处。将.ovpn文件拖至该窗口。
现在在iPhone上启动OpenVPN应用,其会提示目前有可用的新配置。点击绿色加号进行导入即可。
连接
现在OpenVPN已经可以使用,将Connect按钮滑至On位置即可启用,滑至Off则为断开。
注意
设置中的VPN开关不可用于连接VPN。如果进行尝试,大家会收到提示,指出请只使用OpenVPN应用进行连接。
Android
安装
打开Play Store搜索并下载Android OpenVPN Connect。
我们可以将设备接入计算机以传输.ovpn配置文件。另外,如果大家手头有SD读卡器,也可以拆下设备的SD卡接入计算机,从而直接传输该文件。
打开OpenVPN应用并通过菜单导入配置文件。
导航至保存配置文件的位置(截屏所示为/sdcard/Download/)并选定该文件。该应用会提示配置文件导入完成。
连接
点击Connect按钮即可实现连接。系统会询问是否信任该OpenVPN应用。点击OK以初始化连接。要断开连接,返回OpenVPN并选择Disconnect即可。
第十三步:测试VPN连接
一切就绪后,我们需要进行测试。首先在不开启VPN连接的情况下打开浏览器并前往DNSLeakTest。
该站点将返回由互联网服务供应商分配的IP地址。通过该网站检查DNS设置,具体为点击Extended Test,其会告知我们目前所使用的DNS服务器。
现在将OpenVPN客户端接入Droplet的VPN并刷新浏览器。这时VPN服务器的IP地址将发生变化。再次使用DNSLeakTest的Extended Test检查DNS设置,并确认我们正在使用由VPN提供的DNS解析器。
总结
祝贺大家!现在我们已经能够安全地完成流量,而无需担心自己的身份、位置及流量为他人所窥探。
要配置更多客户端,大家重复第六步,并通过第十一到第十三步进行设备添加即可。