Ubuntu 16.04上安装OpenVPN服务器(一)

本文介绍了如何安装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

最后找到usergroup设置并删掉”;”来取消注释:/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命令中选择了其他的名字,需要修改certkey行指向正确的.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

下面,删除”;”取消注释usergroup指令:~/client-configs/base.conf

# Downgrade privileges after initialization (non-Windows only)
user nobody
group nogroup

找到设置cacertkey的指令。注释掉这些指定,因为我们会在文件本身中添加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

修改cipherauth为我们在/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服务器(二)

猜你喜欢

转载自blog.csdn.net/VictoriaW/article/details/80315426