OPEN VPN+花生壳实现设备远程访问

前言

虚拟专用网(Virtual Private Network,简称VPN),能够在地理位置较远并且处于不同运营商网络下的两个设备之间,跨越公网搭建专用的虚拟局域网络,实现两设备的远程访问。
但前提是至少有一个设备拥有公网IP。只有基于公网IP搭建VPN服务端后,另一个设备的VPN客户端才能访问到公网VPN服务端,从而在客户端与服务端之间搭建虚拟网络。
然而大部分网络运营商只给拨号用户提供二级IP地址,也就是说设备持有的只是一个私网IP。针对这种情况有一种方法是购买公网云服务器,在云服务器上部署VPN服务端,然后两个设备作为VPN客户端统一连接到公网VPN服务端,建立虚拟局域网。
本文借助花生壳的内网穿透功能提供另一种方案,使用花生壳和开源的OPEN VPN,无需购买云服务器就能便捷实现设备的远程访问。

方案原理

在这里插入图片描述
方案原理如图所示。在本文中以树莓派和PC为例,其中树莓派集成5G模组且插有SIM卡,通过移动网络运营商接入互联网;PC通过校园网接入互联网。虽然两设备都能访问到互联网,但都是私网IP无法直接互通。
因此借助花生壳提供的内网穿透功能,在树莓派安装VPN服务端后,将树莓派私网IP+VPN服务端口映射到花生壳提供的公网域名+端口上。这样PC上的VPN客户端就能通过公网域名+端口访问到树莓派VPN服务端,从而建立虚拟网络隧道,实现PC对树莓派的远程访问。

实施步骤

1、花生壳配置

1.1、树莓派安装花生壳

进入下载地址,下滑找到树莓派版本下载。

https://hsk.oray.com/download

将下载好的deb安装包上传到树莓派,并安装。

dpkg -i phddns_5.1.0_rapi_aarch64.deb

安装成功后,会显示设备SN码,默认密码以及远程管理地址。
在这里插入图片描述

1.2、注册花生壳账户并登录

1.3、花生壳管理平台添加设备

进入花生壳管理平台,在左侧菜单栏选择"设备列表",填写设备SN码、默认密码添加设备。

1.4、花生壳管理平台配置内网穿透

在花生壳管理平台左侧菜单栏选择"内网穿透",点击添加映射。
花生壳免费提供两条映射,这里使用一条用于配置VPN服务映射。
如下图,映射类型选择TCP,TCP类型选择普通TCP,外网域名选默认域名,外网端口选择动态端口即可,内网主机填写运营商给树莓派分配的IP,内网端口填写1194(OPEN VPN服务端口),其余默认即可。
在这里插入图片描述
完成后点击确认,然后可在“内网穿透”页面中,点击刚才新建的映射后面的“诊断”选项,检查花生壳内网穿透映射配置是否正确。
如果有问题,检查树莓派是否已接入互联网,运营商是否有给树莓派分配IP,以及映射配置信息填写是否正确。
在这里插入图片描述
上图中外网地址47xxxx.fun就是后续vpn客户端访问树莓派vpn服务端使用的地址,47557是端口号。

2、VPN服务端配置

2.1、安装OPEN VPN和证书生成工具

apt install -y openvpn
apt install -y easy-rsa

2.2、制作证书

安装后,将easy-rsa文件夹复制到openvpn路径下,并进入easy-rsa文件夹。

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

在当前路径初始化pki目录,之后生成的证书文件都会存放在pki目录下。

./easyrsa init-pki

创建根证书,后面给Server端、Client端证书签名时使用,nopass表示不加密,提示“Common Name (eg: your user, host, or server name) [Easy-RSA CA]:”可输入自定义证书名,直接回车表示使用默认证书名。

./easyrsa build-ca nopass

完成后在/etc/openvpn/easy-rsa/pki/路径下生成根证书ca.crt

创建服务端证书,server111是自定义的服务端名称,遇到“Common Name (eg: your user, host, or server name) [server111]:”回车即可。

./easyrsa gen-req server111 nopass

给服务端证书签名,中间遇到“ Confirm request details:”输入yes。

./easyrsa sign-req server server111

完成后在/etc/openvpn/easy-rsa/pki/issued/路径下生成服务端证书server111.crt,在/etc/openvpn/easy-rsa/pki/private/路径下生成服务端密钥server111.key

创建客户端证书,client1为自定义的客户端名称,执行过程中间回车即可。

./easyrsa gen-req client1 nopass

给客户端证书签名,中间遇到“ Confirm request details:”输入yes。

./easyrsa sign-req client client1

完成后在/etc/openvpn/easy-rsa/pki/issued/路径下生成客户端证书client1.crt,在/etc/openvpn/easy-rsa/pki/private/路径下生成客户端密钥client1.key

Diffie-Hellman

./easyrsa gen-dh

完成后在/etc/openvpn/easy-rsa/pki/路径下生成认证算法dh.pem

TLS认证密钥

openvpn --genkey --secret ta.key

完成后在/etc/openvpn/easy-rsa/路径下生成ta.key

将所有证书、密钥文件汇总到同一文件夹下。

mkdir /etc/openvpn/keys
cp /etc/openvpn/easy-rsa/pki/ca.crt /etc/openvpn/keys
cp /etc/openvpn/easy-rsa/pki/issued/server111.crt /etc/openvpn/keys
cp /etc/openvpn/easy-rsa/pki/private/server111.key /etc/openvpn/keys
cp /etc/openvpn/easy-rsa/pki/issued/client1.crt /etc/openvpn/keys
cp /etc/openvpn/easy-rsa/pki/private/client1.key /etc/openvpn/keys
cp /etc/openvpn/easy-rsa/pki/dh.pem /etc/openvpn/keys
cp /etc/openvpn/easy-rsa/ta.key /etc/openvpn/keys

2.3、创建服务端配置文件

因为需要在配置文件中指定服务端使用的证书和密钥文件的路径,所以直接在存放证书和密钥的文件夹下创建服务端配置文件,配置文件会在同级路径下搜索,这样文件中直接写需要使用的证书和密钥的文件名即可。

cd /etc/openvpn/keys/
touch server.conf

将以下内容复制到server.conf中。

port 1194
proto tcp
dev tun

ca ca.crt
cert server111.crt
key server111.key 
dh dh.pem
tls-auth ta.key 

server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
keepalive 10 120
cipher AES-256-CBC
persist-key
persist-tun

status /var/log/openvpn/openvpn-status.log
log-append  /var/log/openvpn/openvpn.log
verb 3

3、VPN客户端配置

3.1、安装OPEN VPN

Linux系统

apt install -y openvpn

Windows系统

https://openvpn.net/community-downloads/

3.2、从服务端下载客户端所需证书

将以下文件复制过来
ca.crt
ta.key
client1.crt
client1.key
Linux系统复制到/etc/openvpn/下。
Windows系统复制到openvpn安装路径的config文件夹下。

3.3、创建客户端配置文件

Linux系统中,在/etc/openvpn/下创建client1.ovpn文件。

cd /etc/openvpn/
touch client1.ovpn

Windows系统中,在openvpn安装路径的config文件夹下创建client1.ovpn文件。

将以下内容复制到client1.ovpn,其中带注释内容需根据实际情况修改。

client
dev tun
proto tcp

# 花生壳内网穿透映射配置后提供的公网域名和端口
remote 47xxxx.fun 47557

resolv-retry infinite

nobind
persist-key
persist-tun

# 证书和密钥文件绝对路径,例如:ca D:\\openvpn\\config\\ca.crt
ca ca.crt
cert client1.crt
key client1.key
tls-auth ta.key 1

key-direction 1
verb 5

4、开启VPN服务端

在树莓派进入server.conf所在路径,开启服务端。

openvpn --config server.conf &

打开日志显示,显示“Initialization Sequence Completed”即正常。

tail -f /var/log/openvpn/openvpn.log

服务端开启后,可查看服务端设备在虚拟局域网的IP,为10.8.0.1(可在server.conf修改)。

5、开启VPN客户端

5.1、Linux系统

进入client1.ovpn所在路径,开启客户端。

openvpn --config client.ovpn

成功连接服务端后,显示如下。
在这里插入图片描述
可查看客户端设备在虚拟机局域网中的IP为10.8.0.14,与服务端设备在同一网段。
在这里插入图片描述

5.2、Windows系统

打开openvpn后,在任务栏中找到openvpn图标,右键选择“选项”,打开如下界面,并选择“高级”,在“配置文件”处选择存放客户端相关文件的文件夹路径,点击确定。
在这里插入图片描述
再次双击任务栏中openvpn图标,开始连接服务端,图标中电脑屏幕变绿表示连接成功。
在这里插入图片描述
可查看客户端设备在虚拟机局域网中的IP为10.8.0.10,与服务端设备在同一网段。在这里插入图片描述

6、虚拟局域网连通性测试

在PC上ping 10.8.0.1,测试PC与树莓派间的虚拟网络是否互通。如果互通,就可使用10.8.0.1这是IP来访问树莓派中服务和资源,如ssh服务。
在这里插入图片描述
在这里插入图片描述

7、自动化配置

7.1、树莓派开机自启phddns

设置开机自启,树莓派开机后自动登录phddns客户端,连接花生壳服务器。

phddns enable

在这里插入图片描述
可在花生壳管理平台“设备列表”中,查看设备登录情况。
在这里插入图片描述

7.2、树莓派开机自动拨号、邮件上报IP并开启VPN服务端

树莓派开机接入运营商网络后,运营商会为树莓派动态分配IP,导致使用花生壳建立的内网穿透映射失效。
使用下面的shell脚本和python程序,实现树莓派开机自动拨号上网,并将获取到的IP通过邮件形式自动上报,然后开启VPN服务端。
shell脚本auto_email_ip.sh,注释内容根据实际情况修改。

#!/bin/bash
export PATH='/home/pi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/snap/bin'
# ethx是接入运营商网络使用的网卡
echo root | sudo -s udhcpc -i ethx
while true; do (echo `ip a show ethx |egrep '\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9][0-9])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9][0-9])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9][0-9])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9][0-9])\>' | awk '{print $2}'`)&& break;sleep 1;done;
# python程序路径
python3 /root/code/email_ip/email_ip.py 
openvpn --config /etc/openvpn/keys/server.conf &
# 此程序可以使用一个邮箱账户自己给自己发邮件,也就是说my_sender和my_user使用一个邮箱即可
# coding=utf-8
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
import os
import time

# RTCQDBHTITKEQAGN
#发送内容t
def mail(t):
    ret=True
    try:
        msg=MIMEText(t,'plain','utf-8')
        msg['From']=formataddr(["PI",my_sender])          # 括号里的对应发件人邮箱昵称、发件人邮箱账号
        msg['To']=formataddr(["Admin",my_user])              # 括号里的对应收件人邮箱昵称、收件人邮箱账号
        msg['Subject']="树莓派IP地址上报"                   # 邮件的主题,也可以说是标题
        server=smtplib.SMTP("smtp.163.com", 25)             # 发件人邮箱中的SMTP服务器,端口是25
        server.login(my_sender, my_pass)                    # 括号中对应的是发件人邮箱账号、邮箱密码
        server.sendmail(my_sender,[my_user,],msg.as_string())  # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
        server.quit()  # 关闭连接
    except Exception:  # 如果 try 中的语句没有执行,则会执行下面的 ret=False
        ret=False
    return ret

cmd='ip a show ethx |egrep \'\\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9][0-9])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9][0-9])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9][0-9])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9][0-9])\\>\' | awk \'{print $2}\''
t = "empty"
while t == "empty":
    with os.popen(cmd,"r") as p:
        t = p.read()
        if not t:
            t = "empty"
    time.sleep(5)

# 设置发件人和收件人信息
my_sender='xxx@163.com'  # 自己的邮箱账号
my_pass = ''   			# 发件人邮箱授权码
my_user=my_sender    	# 自己的邮箱账号

ret=mail(t)

if ret:
    print("发送邮件成功")
else:
    print("发送邮件失败")

设置开机自动运行shell脚本。

crontab -e

在配置文件最后一行添加 @reboot /root/code/email_ip/auto_email_ip.sh
在这里插入图片描述
完成上述配置后,树莓派开机后会自动接入运营商网络,获取到IP后自动发邮件上报,并自动开启vpn服务。
用户只需要在花生壳管理平台中修改内网穿透映射配置中的树莓派内网IP,然后启动vpn客户端即可在PC和树莓派间建立连接。

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-04 04:54:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-04 04:54:01       101 阅读
  3. 在Django里面运行非项目文件

    2024-02-04 04:54:01       82 阅读
  4. Python语言-面向对象

    2024-02-04 04:54:01       91 阅读

热门阅读

  1. 【Node系列】Buffer详解

    2024-02-04 04:54:01       43 阅读
  2. Python 机器学习 K-近邻算法 鸢尾花种类预测

    2024-02-04 04:54:01       57 阅读
  3. Android PMS——网络下载应用安装(六)

    2024-02-04 04:54:01       48 阅读
  4. MongoDB的索引与索引字段的顺序

    2024-02-04 04:54:01       46 阅读
  5. Interfaces & Abstract Classes

    2024-02-04 04:54:01       42 阅读
  6. 头歌C++之函数强化练习题

    2024-02-04 04:54:01       46 阅读
  7. 深入学习和实践Python

    2024-02-04 04:54:01       43 阅读
  8. Python循环语句——while循环的基础应用

    2024-02-04 04:54:01       50 阅读
  9. 解密Android某信聊天记录

    2024-02-04 04:54:01       50 阅读
  10. android tv开发-1,leanback 2

    2024-02-04 04:54:01       48 阅读
  11. linux 脚本 多行重定向

    2024-02-04 04:54:01       52 阅读