简介

        OpenVPN是一个跨平台 VPN (虚拟专用网络)客户端/服务器。 与…兼容 微软 Windows,GNU / Linux的,macOS操作系统,甚至有免费的应用程序 Android系统 以及 iOS系统。 OpenVPN的另一个优点是一些路由器制造商正在将其整合到他们的设备中,因此我们将有可能在路由器上配置OpenVPN服务器。

        它使我们能构建虚拟专用网络(VPN) 以远程连接到服务器。 VPN的功能是帮助公司里的远程用户(出差,在家)、公司的分支机构、商业合作伙伴及供应商等公司和自己的公司内部网络之间建立可信的安全连接或者是局域网连接,确保数据的加密安全传输和业务访问,对于运维工程师来说,还可以连接不同的机房为局域网来处理相关事宜。

OpenVPN是一个用于创建虚拟专用网络加密通道的软件包,最早由James Yonan编写。OpenVPN允许创建的VPN使用公开密钥、电子证书、或者用户名/密码来进行身份验证。它的技术核心是虚拟网卡,其次是SSL协议实现。

        虚拟网卡是使用网络底层编程技术实现的一个驱动软件。安装此类程序后主机上会增加一个非真实的网卡,并可以像其它网卡一样进行配置。服务程序可以在应用层打开虚拟网卡,如果应用软件(如网络浏览器)向虚拟网卡发送数据,则服务程序可以读取到该数据。如果服务程序写合适的数据到虚拟网卡,应用软件也可以接收得到。虚拟网卡在很多的操作系统中都有相应的实现,这也是OpenVPN能够跨平台使用的一个重要原因。

        在OpenVPN中,如果用户访问一个远程的虚拟地址(属于虚拟网卡配用的地址系列,区别于真实地址),则操作系统会通过路由机制将数据包(TUN模式)或数据帧(TAP模式)发送到虚拟网卡上,服务程序接收该数据并进行相应的处理后,会通过SOCKET从外网上发送出去。这完成了一个单向传输的过程,反之亦然。当远程服务程序通过SOCKET从外网上接收到数据,并进行相应的处理后,又会发送回给虚拟网卡,则该应用软件就可以接收到。

工作流程

1.用户 使用openvpn客户端软件,通过ip地址集中连接到公司的中央VPN服务器。
2.公司中央VPN服务器返回虚拟网卡给客户端,客户端通过内网ip访问公司服务器设备机房。
NAT(网络地址转换): 在计算机网络中是一种在IP数据包通过路由器或防火墙时重写来源IP地址或目的IP地址的技术。这种技术被普遍使用在有多台主机但只通过一个公有IP地址访问互联网的私有网络中。它是一个方便且得到了广泛应用的技术。当然,NAT也让主机之间的通信变得复杂,导致了通信效率的降低。
INTERNET: 因特网
10.10.10.0/30 : 虚拟网卡
公共IP:任何可公开访问的网络硬件都需要公共IP地址,例如家庭路由器以及托管网站的服务器。 公共IP地址是插入公共互联网的所有设备的不同之处。 每个访问互联网的设备都使用唯一的IP地址。
OpenVPNServer : VPN中央服务器

部署openvpn需要对服务端以及客户端都进行配置

服务端配置以及部署

  • 首先需要安装openVPN以及easy-rsa,easy-rsa用于实现一切的证书操作

    1
    2
    3
    4
    5
    // centos使用 yum进行安装
    yum install -y openvpn easy-rsa
    // unbantu使用 apt install 进行安装
    apt install openvpn easy-rsa openssl

  1. 安装完openvpn之后,就会在/etc目录下有出现openvpn的相关文件夹,同样的,在usr/share/,/usr/share/doc当中也出现了两个文件夹,如图

    image

    image

    之后,将我们需要的示例配置文件复制到/etc/openvpn中,这个示例文件存在于/usr/share/doc/openvpn中。我们需要的文件名字叫server.conf,在本次实践中,它被压缩成gz文件。

    于是可以键入

    • cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn

    • cd /etc/openvpn

    • gzip -d server.conf.gz

    到这里示例的配置文件已经拿到了,之后会在这个配置文件中做一些定制化的修改。但是现在先告一段落。

  2. 准备好生成证书的东西。

    生成证书这一个我们使用easy-rsa来完成。 首先,将esay-rsa的文件复制到/etc/openvpn中

    cp -r /usr/share/easy-rsa /etc/openvpn/easy-rsa-server

    准备好证书的相关配置文件,示例配置文件在/usr/share/easy-rsa当中可以找到

    image

    将这个示例文件复制一份放到/etc/openvpn中

    现在在/etc/openvpn当中应该有这些文件

    image

    easy-rsa-server当中的文件结构应该是这样的

    image

    vars文件夹里面有着vars

    如果想要对证书的有效时间等有什么要求的话,可以根据里面的注释编辑var.example当中的配置

    image

    这里我们不做改动,进入到var目录当中准备生成证书

    回到/etc/openvpn/easy-rsa-server当中,通过 ./easyrsa help options 查看这个命令如何使用

    image

    在这里,我们关注这两个东西 一个是 –vars 另外一个是 –pki-dir

    其中 –vars是指定生成证书的配置文件路径 –pki-dir是指生成的PKI相关文件存放路径

    在这里我们新建一个目录pki_gen ,将pki文件放在这个目录中,于是键入以下指令

    1
    sudo  ./easyrsa   --vars=./vars/vars.example --pki-dir=pki_gen init-pki

    image

    在这里默认就好了

    image

    有了这个相应的pki之后,我们cd到pki_gen目录下去生成我们的ca,这边应该到这个文件需要root权限,然而cd是shell的命令不在bash中,使用sudo -i暂且提到root之后再cd 进去。

    image

    到这里,通过easy --pki-dir=./ build-ca nopass 创建ca机构,这里直接回车就好

    image

    之后使用openssl验证一下我们的ca证书

    image

    键入 openssl x509 -in ./ca.crt -noout -text

    image

    可以看到我们的ca证书也就成功的创建处理出来了,之后创建服务器的证书,回到上级目录,键入 ./easyrsa --pki-dir=./ gen-req server nopass ,遇到要输入的直接回车就行

    image

    之后,根据这两个东西,生成我们最终的证书,键入./easyrsa sign server server

    image

    最后,验证我们的证书是否生成正确

    image

    没有任何输出表示证书正确,有那就是错误的

  3. 创建 Diffie-Hellman 密钥

    创建 Diffie-Hellman 密钥有两种方法均可使用
    方式一:
    ./easyrsa gen-dh
    注意:
    请耐心等待(短则 1分钟 长则 10分钟)
    方式二:
    openssl dhparam -out /etc/openvpn/dh2048.pem 2048

    这里使用第一种方式

    image

    创建完毕之后出现

    image

客户端证书配置

客户端大部分的操作与服务端是一致的,依旧是使用easy-rsa去生成客户端的证书 ,主要是将生成的证书在服务端的server中签发一下

  • sudo cp -r /usr/share/easy-rsa/ /etc/openvpn/easy-rsa-client
  • 将client的文件目录与server保持一致(即在client中创建一个vars, pki_gen,将vars.example文件放在vars中)
  • 处理完之后,键入 sudo ./easyrsa --pki-dir=./pki_gen --vars=./vars/vars.example init-pki

  • 将pki_gen下面生成的req里面的那个req文件复制到server那里的req当中。

    image

  • 键入 sudo ./easyrsa --pki-dir=./pki_gen sign client chenyang 进行签发

  • 最后,验证这两张图的证书是否是一致的

    image

    image

    可以看到,这两个文件当中的pem都是一致的,则说明客户端的证书成功签发

创建服务端连接配置文件

  • 先备份一下,cd到/etc/openvpn的目录下,键入cp server.conf server.conf.bk

    执行以下操作

    • >/etc/openvpn/server.conf 清空所有内容

    • 使用vim将这些全部复制进去

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      #端口,1194是udp的默认端口,这里改成了tcp
      port 1194
      #使用协议tcp
      proto tcp
      #采用tun模式,这个模式上面有提到过, tun tap
      dev tun
      dev-type tun
      persist-tun
      #设定ca
      ca /etc/openvpn/certs/ca.crt
      #设定服务器端的证书
      cert /etc/openvpn/certs/server.crt
      #设定服务器的私钥
      key /etc/openvpn/certs/server.key
      #用户密钥交换的dh公钥,使用 easyrsa 生成的那个
      dh /etc/openvpn/certs/dh.pem
      # 这里是指客户端虚拟成哪个子网频段下
      server 10.8.0.0 255.255.255.0
      #这里是指客户端访问的内网频段,如果只访问这一个服务器,可以设定死IP
      push "route 172.26.245.203 255.255.255.255"
      # 心跳检测
      keepalive 10 120
      cipher AES-256-CBC
      # 压缩算法
      compress lz4-v2
      push "compress lz4-v2"
      #设置最大可连接主机数
      max-clients 2048
      #降权自动选择
      user lgh
      group sudo
      status /var/log/openvpn/openvpn-status.log
      log-append /var/log/openvpn/openvpn.log
      verb 3
      mute 20

      其中必须需要根据实际改动的是 push “route 172.26.245.203 255.255.255.2”这一个,换成自己服务器的内网ip。降权为了方便设置了存在的用户

      之后创建日志文件目录,/var/log/openvpn,将权限给到设置的降权用户,可以使用chown

    • 创建证书存放目录,之后将所有需要的证书放进去/etc/openvpn/certs/

      image

    • 之后开启系统内核网络转发功能

      echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf

      sysctl -p

      image

    • 使用ufw开放端口转发

      如果用firewalld的话,禁用一下

      1
      2
      sudo systemctl stop firewalld
      sudo systemctl disable firewalld

      启动ufw设置规则

      1
      2
      3
      4
      # 允许 OpenVPN 端口(1194/tcp)
      sudo ufw allow 1194/tcp
      # 启用 NAT 规则(等价于 iptables 的 MASQUERADE)
      sudo vim /etc/ufw/before.rules

      在文件末尾添加

      1
      2
      :POSTROUTING ACCEPT [0:0]
      -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

      启用ip转发sudo vim /etc/ufw/sysctl.conf 添加 net.ipv4.ip_forward=1 之后应用 sysctl -p

      启动ufw

      1
      2
      sudo ufw enable
      sudo ufw status # 查看规则

      image

启动服务端

键入 systemctl enable --now openvpn@server 启动服务端

image

查看相应的状态

image

再这里看看到,openvpn启动失败了,原因可以去日志里面进行查找 我们的日志根据配置可以知道存在于/var/log/openvpn/openvpn.log,以及/var/log/openvpn/openvpn-status.log。打开发现是端口被占用了,也就是说openvpn并没有做全局唯一的检测,由于我们的配置文件配置需要使用的端口是1194,所以之前的openvpn占用了1194,所以我们可以通过

1
sudo netstat -tulnp | grep 1194

得到pid之后 使用’’’ kill -9 pid号```将其杀死

注意,打开 systemctl cat openvpn@server 需要对这一个execStart进行解释

image

可以看到,这个系统服务注册启动的命令是

/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

他的意思是说,启动sbin里面的openvpn,使用配置为/etc/目录下的.conf后缀文件。 所以实际上openvpn是监听/etc/openvpn下面的server.conf。如果这个位置不喜欢,可以通过 systemctl edit openvpn@server 自定义覆盖服务启动细节。

使用 sudo netstat -tulnp | grep 1194 ,可以看到openvpn也确实启动了

image

使用 ip a show tun0 可以看到虚拟网卡是正常启动并运作

image

编写客户端链接文件

回到我们的/etc/openvpn目录,创建目录 easy-rsa-client,将关于客户端的这些证书放在在该目录下,分别是ca.crt (签发机构证书), chenyang.key (客户端私钥) , chenyang.crt(客户端证书)。编写cilnet端的链接文件,如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
client		#客户端声明
dev tun # tun网卡
proto tcp # tcp协议
remote 120.76.41.122 1194 # 公网 端口
resolv-retry infinite
nobind
ca ca.crt #ca凭证
cert chenyang.crt # 客户端证书
key chenyang.key # 证书请求 私钥
remote-cert-tls server
cipher AES-256-CBC
verb 3 # 日志等级
compress lz4-v2 # 压缩

将这四个文件都通过scp放到本地,之后导入即可。

延申:这个属于使用证书签发作为验证凭证的openvpn使用方式,还有一种使用方式是使用密码,这样只需要提供ca凭证即可。这个方式还待实践。

总的来说openVPN实际上在本次实践中是开了两个端点在服务端以及客户端,服务端生成ca,服务端证书,客户端生成客户端证书,之后再服务端进行dh算法之后的签发。内部openvpn会根据配置,创建网卡的类型,之后通过push route这个路由规则,将流量路由到相应的网络中。再通过ssl的方式实现客户端以及服务端互通。