在ubuntu环境上安装OpenVPN服务

写在最前
  这我很早之前看过的一篇配置教程,感觉整体上比较详实。虽然文章中有些小问题,但我在整理的过程中已经进行了修改。由于原文已经被河蟹吃掉,我在整理时的内容也是来自百度快照,所以原文链接就不贴出来了!

注:本文内容于ubuntu(16.04&18.04)LTS X64环境,验证可行。


第一步:安装OpenVPN
  OpenVPN在Ubuntu的默认仓库中是可用的,直接使用apt来安装。安装easy-rsa包,这个包可以帮助我们建立一个内部CA(certificate authority)。
更新你的服务器包索引并安装必要的包类型:

# apt-get update
# apt-get install openvpn easy-rsa

第二步:建立CA目录
  OpenVPN是一个TLS/SSLVPN,这意味着它需要使用证书来在客户端和服务器之间加密数据。为了发布可信的证书,我需要建立我们自己的简单CA(certificate authority)。
  开始之前,我们可以使用make-cadir命令,用于复制easy-rsa临时目录到我们的home目录下面:

$ make-cadir ~/openvpn-ca
#上面这条命令也用下面的两条命令来做:
$ mkdir ~/openvpn-ca
$ cp -r /usr/share/easy-rsa/*  ~/openvpn-ca

然后进入到我们新创建的目录中来开始配置CA:

$ cd ~/openvpn-ca

第三步:配置CA变量
  我们需要编辑当前目录下vars文件来配置CA要用到的值,用你的文本编辑器打开vars文件,在这个文件里面,你会发现许多变量,这些变量用于决定怎样生成你的证书,你可以修改这些变量的值。在这里我们只需要关注几个变量就行。在文件的底部,找到如下信息:

~/openvpn-ca/vars
. . .
exportKEY_COUNTRY="US"
exportKEY_PROVINCE="CA"
exportKEY_CITY="SanFrancisco"
exportKEY_ORG="Fort-Funston"
exportKEY_EMAIL="me@myhost.mydomain"
exportKEY_OU="MyOrganizationalUnit"
 . . .
#将这些红色的值编辑成任何你喜欢的,但不要让它们空着。到这步之后,我们再编辑KEY_NAME的值,简单起见,我们将它命名为server,如下:
~/openvpn-ca/vars
export KEY_NAME="server"

完成之后,保存并退出。

第四步:制作CA
  现在我们可以使用我们刚刚设置的变量,用easy-rsa包来制作CA。确保你处在你的CA目录下面,然后source我们刚刚编辑的vars文件。

$ cd ~/openvpn-ca
$ source vars

如果source正确的话,你会看到如下信息:

NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/demo/openvpn-ca/keys

通过输入如下命令确保我们的操作处于一个clean环境中:

$ ./clean-all

现在我们可以制作我们的root CA:

$ ./build-ca

上面这一步会开始制作根证书颁发机构密钥(rootcertificate authority key )和证书(certificate),由于我们刚刚填了vars文件,证书制作所需要变量的值都会自动填充,制作过程中你只需要回车来确认就行。消息输出如下:

Generating a 2048 bit RSA private key
..........................................................................................+++...............................+++
writing new private key to 'ca.key'
\-----
You are about to be asked to enter information that willbe incorporated
into your certificate request.What you are about to enter is what is called aDistinguished 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) [CN]:
State or Province Name (full name) [GD]:
Locality Name (eg, city) [ShanTou City]:
Organization Name (eg, company) [STU]:
Organizational Unit Name (eg, section) [University]:
Common Name (eg, your name or your server's hostname) [STUCA]:
Name [server]:
Email Address [demo@163.com]:

现在我们得到了一个CA文件,CA文件可以用于制作我们接下来所需的文件。

第五步:制作Server端的 Server Certificate, Key, Encryption Files
  接下来,我们将制作服务端所需要的证书,这些证书就像传统的用于加密过程的文件一样。通过键入如下命令来生成服务端所需的证书:

$ ./build-key-server server

上面红色字体的server就是我们在vars文件中填入的export KEY_NAME=”server”,如果你不是填入的server这个名称,则./build-key-server后面输入你自己填的那个名称。制作过程中一路回车,中间出现 challenge password ,不要输入任何值回车就行,最后的会有两个问题,输入y就行,如下所示:

. . .
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

  如果以上操作无误的话应该可以看到生成的server.crt、server.key和server.csr三个文件。其中server.crt和server.key两个文件是我们所需要的。现在再为服务器生成加密交换时的Diffie-Hellman文件。输入以下命令:

$ ./build-dh

完成这一步可能需要几分钟时间。最后,我们可以生成一个HMAC签名来增强服务器的TLS完整性验证能力:

$ openvpn --genkey --secret keys/ta.key

第六步:制作Client端的 Client Certificate, Key
  尽管客户端的相关证书可以在客户端的机器上面生成,为了简单起见,在这篇教程中我们在服务器上面来生成客户端的相关证书,然后再把服务器上生成的客户端证书下载到本地客户端上面。我们用client1来命名我们的第一个证书/密钥对,用build-key命令来生成没有密码情况下的凭证,并且用于自动连接:
注意,这个地方是非必须的,可以直接集成到最后的生成脚本里。

$ cd ~/openvpn-ca
$ source vars
$ ./build-key client1
client1

如果你想生成一个带密码保护的凭证,可以使用build-key-pass命令:

$ cd ~/openvpn-ca
$ source vars
$ ./build-key-pass client1

然后一路回车,中间出现challenge password,不要输入任何值回车就行,最后的会有两个问题,输入y就行。

第七步:配置OpenVPN服务器
  接下来,我们利用已经生成的相关文件来配置OpenVPN服务器。

  1. 把相关证书复制到OpenVPN的目录下面
      开始之前,把我们需要的相关文件复制到/etc/openvpn这个配置目录中去,即把~/openvpn-ca/keys目录下面的ca.crt,ca.key,server.crt,server.key,HMAC签名以及Diffie-Hellman文件复制到/etc/openvpn这个目录下面:

    $ cd ~/openvpn-ca/keys
    $ sudo cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn

    然后从OpenVPN自带的配置模板中复制配置文件:

    $ cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
    $ cd /etc/openvpn/
    $ gzip -d server.conf.gz
  2. 修改OpenVPN配置文件

    $ sudo vim /etc/openvpn/server.conf

基本配置步骤如下:
首先,通过查找tls-auth指令找到HMAC部分,移除”;”来解注释tls-auth,并且在tls-auth的下面,增加一个key-direction参数,设置其参数值为0,如下:

/etc/openvpn/server.conf
tls-auth ta.key 0 # This file is secret
key-direction 0

然后,通过查找被注释的clipher这一行找到加密密码的部分,aes128-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

(可选配置)推动DNS更改让VPN重定向所有流量
  上面的配置可以在客户端和服务器端上创建VPN连接,但是没有强迫连接去使用tunnel。如果你希望用VPN来路由你的所有流量,你需要更改你的客户端机器的DNS设置。你可以按照以下步骤设置,解注释一些指令使得你的客户端机器把所有的web流量重定向到VPN上面,找到redirect-gateway部分然后移除它之前的”;”,如下:

/etc/openvpn/server.conf
push "redirect-gateway def1 bypass-dhcp"

在这条指令的下面,找到dhcp-option部分,移除这两行之前的”;”,如下:

push "dhcp-option DNS 223.5.5.5"
push "dhcp-option DNS 114.114.114.114"

这就可以协助客户版重新配置DNS,以便使用VPN tunnel来作为默认网关。
(可选配置)修改OpenVPN服务器的端口和协议
  OpenVPN服务器默认使用1194端口和UDP协议来接收客户端的连接,也许由于客户端那边的网络环境限制,你需要使用一个不同的端口,那么你可以改变port选项,如果你的Ubuntu16.04服务器没有托管web服务,那么443端口是一个可替换1194的不错选择,因为防火墙往往对443端口不受限。

/etc/openvpn/server.conf
\# Optional!
port 443

我们同样可以将协议从UDP换成TCP:

/etc/openvpn/server.conf
\# Optional!
proto tcp

如果你没有更换端口的需求,最好将上述的两项保持默认设置。

(可选配置)指定非默认的凭证(Point to Non-Default Credentials)
  如果你在之前的./build-key-server命令用了不同的名字(我们之前用的server这个名字),那么修改cert和key这两行,将这两行的值设为你之前用的那个名字.crt和你之前那个名字.key,如果你默认使用的server这个名字,那么这里你已经正确的设置好了,如下:

/etc/openvpn/server.conf
cert server.crt
key server.key

以上设置完毕之后,保存并退出server.conf这个文件。

第八步:调整Ubuntu16.04服务的网络配置
  接下来,我们需要调整Ubuntu16.04服务器上面网络的一些配置,以便于OpenVPN服务器可以正确的路由流量。

  1. 允许IP转发
      首先,我们需要让我们的服务器来转发流量,这是我们需要VPN服务器来提供的最基本的功能。我们可以通过修改/etc/sysctl.conf文件来调整网络设置:
    $ sudo vim /etc/sysctl.conf
    在这个文件里面,找到net.ipv4.ip_forward,去除这一行之前的”#”来解注释这个参数:
    etc/sysctl.conf
    net.ipv4.ip_forward=1
    完成后保存并退出该文件。
    为了读取sysctl.conf文件并且让调整后设置对当前系统的session生效,键入如下命令:
    $ sudo sysctl -p
  2. 调整防火墙(UFW)规则来伪装客户端的连接
      在这篇教程中我们需要配置防火墙规则来引导进入服务器的一些流量,我们需要修改防火墙规则文件来建立伪装规则,iptables的概念用于提供动态的NAT,从而正确地路由客户端连接。在打开防火墙配置文件以添加伪装规则之前,我们需要找到我们Ubuntu服务器的公共网络接口,输入如下命令:
    $ ip route | grep default
    你的公共网络接口应当紧跟在单词”dev”后面,例如,我的接口名字为eth0:
    default via 172.18.21.203 dev eth0
    当你有一个与你的默认路由相关联的接口的时候,打开/etc/ufw/before.rules这个文件并添加相应的规则:
    $ sudo vim /etc/ufw/before.rules
    这个文件处理在加载常规UFW规则之前应该被放置的文件,在这个文件的最开始处加入下面的内容。这样可以为nat表设置POSTROUTING默认规则,并且为来自VPN的任何流量设置伪装连接。
/etc/ufw/before.rules
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0] 
# Allow traffic from OpenVPN client to eth0(changeto the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -jMASQUERADE
COMMIT
# END OPENVPN RULES

完成后保存并退出。
然后告诉防火墙默认允许转发包:

$ sudo vim /etc/default/ufw

在这个文件里面,找到DEFAULT_FORWARD_POLICY指令,将它的值从DROP改成ACCEPT:

/etc/default/ufw
DEFAULT_FORWARD_POLICY="ACCEPT"

完成后保存并退出。

  1. 打开OpenVPN端口并且使变化生效
      接下来,调整防火墙本身,以允许流量到OpenVPN。如果你在/etc/openvpn/server.conf文件中没有修改OpenVPN的端口号和协议类型,那么直接配置防火墙允许UDP流量到1194端口,如果你改变了端口和协议类型,那么根据你自己设置的端口和协议类型进行配置。
    $ sudo ufw allow 1193/udp
    $ sudo ufw allow OpenSSH
    现在,我们可以从所有修改过的文件中装载配置来关闭和重启防火墙:
    $ sudo ufw disable
    $ sudo ufw enable
    到这里我们的服务器可以正确地处理OpenVPN流量了。

第九步:开启OpenVPN服务
  在systemd单元文件的后面,我们通过指定特定的配置文件名来作为一个实例变量来开启OpenVPN服务,我们的配置文件名称为/etc/openvpn/server.conf,所以我们在systemd单元文件的后面添加@server来开启OpenVPN服务:

$ sudo systemctl start openvpn@server

通过如下命令再次确认OpenVPN服务已经成功地开启了:

$ 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 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: 5852ExecStart=/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 addradd dev tun0 local 10.8.0.1 peer 10.8.0.2
May 03 15:30:05 openvpn2 ovpn-server[5856]: /sbin/iproute add 10.8.0.0/24 via 10.8.0.2
May 03 15:30:05 openvpn2 ovpn-server[5856]: GID set tonogroup
May 03 15:30:05 openvpn2 ovpn-server[5856]: UID set tonobody
May 03 15:30:05 openvpn2 ovpn-server[5856]: UDPv4 linklocal (bound): [undef]
May 03 15:30:05 openvpn2 ovpn-server[5856]: UDPv4 linkremote: [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]: IFCONFIGPOOL: base=10.8.0.4 size=62, ipv6=0
May 03 15:30:05 openvpn2 ovpn-server[5856]: IFCONFIG POOLLIST
May 03 15:30:05 openvpn2 ovpn-server[5856]:Initialization Sequence Completed

你可以通过如下命令来确认OpenVPN tun0接口是否可用

$ ip addr show tun0

你应该可以看到一个配置接口:

4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP>mtu 1500 qdisc noqueue state UNKNOWN group default qlen 100
  link/none
  inet 10.8.0.1peer 10.8.0.2/32 scope global tun0
​    valid_lftforever preferred_lft forever

如果一切运行正常,将OpenVPN设置为开机自启动:

$ sudo systemctl enable openvpn@server

第十步:构造客户端所需的.ovpn文件配置工厂
  这一步,我们建立一个更加容易生成客户端所需配置文件的系统。

  1. 创建客户端配置目录结构
      在你的home目录下面创建一个目录结构来保存客户端的相应配置文件:

    $ mkdir -p ~/client-configs/files

    由于客户端的配置目录里面将包含客户端的密钥,所以我们应该对这个目录进行权限的锁定:

    $ chmod 700 ~/client-configs/files
  2. 创建基本的配置文件
      这一步,我们将OpenVPN自带的客户端配置模板复制到我们刚刚创建的客户端配置目录中作为一个客户端的基本配置文件:

    $ cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf     ~/client-configs/base.conf

    打开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
    . . .

    确保你在server配置文件(/etc/openvpn/server.conf文件)里面你所设置的协议类型:

    ~/client-configs/base.conf
    proto udp

    然后去除user和group指令前面的”;”,如下:

    ~/client-configs/base.conf
    # Downgrade privileges after initialization (non-Windowsonly)
    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

    然后镜像(或者说模仿)我们在/etc/openvpn/server.conf文件里面设置的cipher和auth:

    ~/client-configs/base.conf
    cipher AES-128-CBC
    auth SHA256

    接下来,在文件的某位置处增加key-direction指令,这个指令的值必须设置为1才能与服务器合作:

    ~/client-configs/base.conf
    key-direction 1

    最后添加一些注释信息,我们希望配置信息能够用于所有的客户端,但是下面的注释信息只能用于Linux客户端:

    ~/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文件,你应当将上面的三条指令解注释。最后保存并退出base.conf文件。

  3. 写一个自动生成客户端.ovpn配置文件的脚本
      这一步,我们写一个简单的脚本,用于将相关的certificate,key和加密文件编译我们刚刚制作的base.conf文件,编译完成后得到一个.ovpn客户端文件。在~/client-configs目录下面创建make_config.sh文件:

    $ vim ~/client-configs/make_config.sh

    在将如下内容复制到make_config.sh文件中:

    #!/bin/bash
    KEY_DIR=~/openvpn-ca/keys
    OUTPUT_DIR=~/client-configs/files
    BASE_CONFIG=~/client-configs/base.conf
    cd ~/openvpn-ca
    source vars
    ./build-key ${1}
    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

第十一步:生成客户端.ovpn配置文件
  现在我们可以轻松地生成客户端配置文件,只需要如下简单的命令即可:

$ cd ~/client-configs
$ ./make_config.sh yourname

如果一切顺利的话,在~/client-configs/files目录下面会生成一个yourname.ovpn文件。最后在~/client-configs/files文件夹内会生成你所命名的.ovpn文件。接下来把yourname.ovpn下载到你的客户端即可。

第十二步:在客户端OpenVPN上安装配置文件
  这个步骤比较简单,先根据你的操作系统平台选择下载相应的客户端OpenVPN,然后把第十一步中的.ovpn配置文件导入到客户端的OpenVPN即可,正常情况下可以直接连接到服务器端的OpenVPN。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 irvin.em@live.com。

文章标题:在ubuntu环境上安装OpenVPN服务

文章字数:4.8k

本文作者:dino

发布时间:2019-11-05, 17:13:27

最后更新:2019-11-08, 21:27:03

原始链接:https://blog.walkbc.com/2019/11/05/InstallOpenVPNInUbuntu/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

QQ交流群:273078549

目录