配置VPN

作者: xieyan0811 | 来源:发表于2023-10-20 09:12 被阅读0次

    1 问题解析

    VPN 的使用前提是需要知道对方主机 ip 地址及开放的端口。

    我遇到的问题是,自用的机器 A 和服务器 B 都没有固定 IP,机器 A 在局域网里,机器 B 使用物联网卡,本身没有对外的 IP 地址,物联网厂商也不提供端口映射。

    这样 A 只能使用“向日葵”类的远程桌面软件连接服务器 B,它的问题是:

    • 同一时间只能供一个连接操作
    • 远程桌面传输屏幕变化,比只传输字符的 ssh 类工具慢很多
    • 向日葵在用户登录后才能启动,所以如果远程无人职守,重启后就连不上了
    • 不能复制粘贴,拷个东西费死劲,很多命令只能手敲,界面还反应慢

    我的解决方案是:

    • 使用 VPN 隧道,在一台有外部 IP 的云服务器 C 上搭建 VPN,然后用 A 和 B 同时连接 C,此时它们在同一网络中,即可使用 A 访问 B。
    • 进一步简化:只在 B 和 C 上配置 VPN,然后把 B 的端口映射成到 C 的端口,任意机器通过 C 来访问 B,这种做法的优点是不用配置 A,缺点是所有需要暴露的端口都需要映射。选择哪一种方法,主要看需求。

    2 生成密钥

    2.1 Easy-RSA

    Easy-RSA 是一款用于生成和管理公共密钥基础设施(PKI)的开源工具。

    2.2 生成密钥

    (环境 CentOS)

    yum install -y openvpn 
    yum install -y easy-rsa
    cd /usr/share/easy-rsa/3
    
    ./easyrsa init-pki #初始化,生成pki文件夹,用于存放证书文件
    ./easyrsa build-ca #生成ca根证书,需要输入两次根证书密码,和 common name
    
    ./easyrsa gen-req server nopass #创建服务器端证书, nopass表示不加密私钥文件
    ./easyrsa sign server server #签约服务端证书
    
    ./easyrsa gen-req client1 #创建客户端证书,这里需要输入客户端PEM密码(每次连都要输密码),也可用nopass不加密
    ./easyrsa sign client client1 #给client端证书签名
    
    ./easyrsa gen-dh #创建Diffie-Hellman文件, 时间比较长
    

    上面示例了一个 client 的生成方法,请据此生成多个 client,因为同一 client 只能获取一个 ip 地址,多个 client 无法同时互联。

    3 服务端配置

    3.1 复制密钥

    mkdir /etc/openvpn/server/pki -p
    cp -r /usr/share/easy-rsa/3/pki/ca.crt /etc/openvpn/server/pki/
    cp -r /usr/share/easy-rsa/3/pki/issued/server.crt  /etc/openvpn/server/pki/
    cp -r /usr/share/easy-rsa/3/pki/private/server.key /etc/openvpn/server/pki/
    cp -r /usr/share/easy-rsa/3/pki/dh.pem  /etc/openvpn/server/pki/
    

    创建抵御 dos 攻击的文件

    openvpn --genkey --secret ta.key  
    mv ta.key /etc/openvpn/server/pki/
    

    3.2 配置文件

    cp -r /usr/share/doc/openvpn-2.4.12/sample/sample-config-files server.conf /etc/openvpn/ 
    # 可以过滤掉注释行:grep '^[^#|;]' server/server.conf
    

    修改一下 server.conf,请参考:

    port 1194
    proto tcp
    dev tun
    ca /etc/openvpn/server/pki/ca.crt
    cert /etc/openvpn/server/pki/server.crt
    key /etc/openvpn/server/pki/server.key  # This file should be kept secret
    dh /etc/openvpn/server/pki/dh.pem
    client-to-client # 重要,让client间可以相互访问
    server 10.9.0.0 255.255.255.0 # 10.8.0.0 与我本地docker冲突,故使用10.9...
    ifconfig-pool-persist /var/log/openvpn/ipp.txt
    keepalive 10 120
    tls-auth /etc/openvpn/server/pki/ta.key 0 # This file is secret
    cipher AES-256-CBC
    persist-key
    persist-tun
    status /var/log/openvpn/openvpn-status.log
    verb 3
    

    测试配置文件是否正常:

    openvpn --config /etc/openvpn/server.conf
    

    3.3 以服务方式启动 openvpn

    systemctl start openvpn@server
    systemctl enable openvpn@server
    

    查看网络状态

    netstats -lntup|grep 设置的端口号
    

    查看虚拟网卡,可看到 tun0 设备

    ifconfig
    

    3.4 注意事项

    • 注意如果在云服务器配置,请在安全策略中打开端口

    4 客户端配置

    4.1 基本配置

    之前我们网管同学都是将下列配置文件写入一个 ovpn 文件方便大家使用,自己做就不那么麻烦了。把刚才生成的以下文件复制到客户端对应目录:

    ca.crt client1.crt client1.key dh.pem ta.key

    生成配置端文件 client.ovpn

    client
    dev tun
    proto tcp 
    remote 43.140.247.164 1194
    resolv-retry infinite
    nobind
    persist-key
    persist-tun
    ca /etc/openvpn/client/pki/ca.crt
    cert /etc/openvpn/client/pki/client1.crt
    key /etc/openvpn/client/pki/client1.key
    remote-cert-tls server
    tls-auth /etc/openvpn/client/pki/ta.key 1
    cipher AES-256-CBC
    verb 3
    

    连接

    sudo nohup openvpn --config tencent.ovpn &
    

    注意事项:不同机器用不同的 client 文件,否则分配的是同一 ip,无法相互访问

    4.2 配置路由

    VPN 一般有两种常见用途:

    • 想利用 vpn 科学上网,在此情况下,希望所有访问都走 vpn 网路,使用上述设置即可。
    • 想利用 vpn 访问远程网络,其它网络访问,还使用之前本地网络配置,这种情况下请做以下修改:

    修改 client.ovpn 配置文件,加入:

    route-nopull # 不改变路由
    

    然后手动设置本地路由,把对指定网段的访问指向 vpn 网关:

    sudo ip route add 10.9.0.0/24 via 10.9.0.5
    

    注意:每次断开再连 vpn 都请重新设置 route

    说明:建议在服务器 B 设置 route-nopull,因为它是被连的一端,这样即可以保证可用,又避免影响其网络状态。

    5 查看状态

    5.1 查看当前哪些客户端正在连接

    cat /var/log/openvpn/openvpn-status.log
    

    6 进一步简化

    做完上述配置,机器 A 访问机器 B 时需要先连接 vpn,还是比较麻烦,下面使用内网穿透技术,进一步简化:只在机器 C 和机器 B 间建立 openvpn 连接,然后做端口映射,把机器 B 的端口映射到机器 C 的端口。在机器 C 上做如下配置:

    ssh -L 0.0.0.0:3302:Server_B_IP:22 -f -N root@Server_B_IP
    

    这样就把 机器 B 的 22 端口映射到了 机器 C 的 3302 端口,我们可以在任何一台机器 (A1, A2, A3...) 上,访问机器 B,同时也不用在 A 上安装 vpn。其中设置 0.0.0.0 使任何主机都可以访问 3302 端口。

    这样做的缺点是:需要对每个用到的端口做映射。

    7 问题与限制

    • 在客户端设置 openvpn 时,可能影响向日葵的连接,导致需要重启向日葵

      在 ssh 正常连接服务器 B 的情况下,可以用 “ssh -X 地址”,连接 X 桌面,然后在本地操作向日葵,尽管这么操作很奇怪。

    • 机器 A 可以访问服务器 B,ssh 连接后可使用 B 所在网络的资源;但不能像直连 VPN 一样使用 B 所在的整个网络,比如安装在 A 上的 Navicat 不能通过端口直接连接 B 机器所在网络中其它机器上的数据库。

    • 经过简化配置,相当于我们可以将 服务器 B 的所有端口通过服务器 C 的地址对外暴露。由此,也可以在 服务器 B 上配置 VPN 服务,供其它机器访问 B 所在的整个网络。

    8 参考

    很详细的教程

    相关文章

      网友评论

          本文标题:配置VPN

          本文链接:https://www.haomeiwen.com/subject/terkidtx.html