前言 使用open vpn软件,可以在能够访问互联网的树莓派、PC上安装vpn客户端,然后在公网服务器上安装vpn服务端,从而在三者之间组建虚拟局域网,实现PC远程访问树莓派,但这种方式通常需要购买具备公网IP的云服务器来搭建vpn服务端。本文将open vpn与花生壳配合使用,仅利用花生壳免费功能来实现PC远程访问树莓派,且仅需占用树莓派1194端口用于vpn服务,其他端口可任意使用。
方案原理
实施步骤 1、花生壳配置 a、树莓派安装花生壳 1 2 3 4 5 6 # 下载地址 https://hsk.oray.com/download # 下载后将deb安装包上传到树莓派 # 安装 dpkg -i xxxx.deb
1 # 安装成功后,会显示设备SN码,默认密码以及远程管理地址
b、注册花生壳账户并登录 略
c、花生壳管理平台添加设备 1 2 # 进入花生壳管理平台,在左侧菜单栏选择"设备列表" # 使用设备SN码、默认密码添加树莓派
d、花生壳管理平台配置内网穿透 1 2 3 4 # 在花生壳管理平台,左侧菜单栏选择"内网穿透" # 点击添加映射 # 花生壳免费提供两条映射,在此使用一条用于配置VPN服务映射 # 如下图,映射类型选择TCP;TCP类型选择普通TCP;外网域名默认域名;外网端口选择动态端口即可(不用付费);内网主机填写运营商为树莓派分配的IP;内网端口填写1194(open vpn服务端口)
1 2 3 # 完成后点击确认即可 # 然后可在“内网穿透”页面中,点击刚才新建映射后面的“诊断”选项,查看花生壳内网穿透映射配置是否正常 # 如果有问题,检查树莓派是否接入互联网,运营商是否有给树莓派分配ip,以及映射配置信息填写是否正确
1 # 上图中外网地址47xxxx.fun就是后续vpn客户端访问树莓派vpn服务端使用的地址,47557是端口号
2、树莓派-vpn服务端配置 a、安装open vpn和证书生成工具 1 2 apt install -y openvpn apt install -y openvpn
b、制作相关证书 CA证书 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 进入openvpn文件夹 cd /etc/openvpn/ # 将easy-rsa文件夹复制到openvpn文件家下 cp -r /usr/share/easy-rsa/ /etc/openvpn/ # 进入/etc/openvpn/easy-rsa/目录下 cd /etc/openvpn/easy-rsa/ # 初始化目录 ./easyrsa init-pki # 创建根证书,nopss表示不加密,遇到“Common Name (eg: your user, host, or server name) [Easy-RSA CA]:”回车即可 ./easyrsa build-ca nopass
Server端证书 1 2 3 4 5 # 创建服务端证书,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
1 2 # 使用build-server-full参数可直接完成上述创建证书和签名两个步骤 ./easyrsa build-server-full server111 nopass
Client端证书 1 2 3 4 5 # 创建客户端证书,client1为自定义的客户端名称,执行过程中间回车即可 ./easyrsa gen-req client1 nopass # 给客户端证书签名,中间遇到“ Confirm request details:”输入yes即可 ./easyrsa sign-req client client1
1 2 # 使用build-client-full参数可直接完成上述创建证书和签名两个步骤 ./easyrsa build-client-full client1 nopass
Diffie-Hellman TLS认证密钥 1 openvpn --genkey --secret ta.key
整理所有证书到指定文件夹 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 mkdir /etc/openvpn/keys cp /etc/openvpn/easy-rsa/ta.key /etc/openvpn/keys/ cp /etc/openvpn/easy-rsa/pki/ca.crt /etc/openvpn/keys cp /etc/openvpn/easy-rsa/pki/dh.pem /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/issued/client2.crt /etc/openvpn/keys cp /etc/openvpn/easy-rsa/pki/private/client2.key /etc/openvpn/keys
c、创建服务端配置文件 1 2 3 4 5 6 7 8 9 # 进入指定文件夹下,解压出server.conf cd /usr/share/doc/openvpn/examples/sample-config-files gzip -d /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz # 复制server.conf到/etc/openvpn/keys cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/keys/ # 修改server.conf中的配置,具体如下 # ";"是注释符号,加";"的行不会起作用
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 ;local a.b.c.d port 1194 proto tcp ;proto udp ;dev tap dev tun ;dev-node MyTap # 如果执行openvpn开启命令时所在的路径就是下列文件的所在路径,只写文件名即可,否则需要写绝对路径 ca ca.crt cert server111.crt key server111.key dh dh.pem ;topology subnet server 10.8.0.0 255.255.255.0 ifconfig-pool-persist /var/log/openvpn/ipp.txt ;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 ;server-bridge ;push "route 192.168.10.0 255.255.255.0" ;push "route 192.168.20.0 255.255.255.0" ;client-config-dir ccd ;route 192.168.40.128 255.255.255.248 ;client-config-dir ccd ;route 10.9.0.0 255.255.255.252 ;learn-address ./script ;push "redirect-gateway def1 bypass-dhcp" ;push "dhcp-option DNS 208.67.222.222" ;push "dhcp-option DNS 208.67.220.220" ;client-to-client # 不允许多用户使用同一客户端证书 ;duplicate-cn keepalive 10 120 # 如果执行openvpn开启命令时所在的路径就是ta.key的所在路径,只写文件名即可,否则需要写绝对路径 tls-auth ta.key 0 cipher AES-256-CBC ;compress lz4-v2 ;push "compress lz4-v2" ;comp-lzo ;max-clients 100 ;user nobody ;group nogroup persist-key persist-tun status /var/log/openvpn/openvpn-status.log ;log /var/log/openvpn/openvpn.log log-append /var/log/openvpn/openvpn.log verb 3 ;explicit-exit-notify 1
3、PC-vpn客户端配置 a、安装open vpn 1 2 3 4 5 # linux apt install -y openvpn # windows https://openvpn.net/community-downloads/
b、从服务端下载客户端所需证书文件 1 2 3 4 5 6 7 8 # 需要下列文件 ca.crt ta.key client1.crt client1.key # linux复制到/etc/openvpn/下 # windows复制到\openvpn\config\下
c、创建客户端配置文件 1 2 3 4 5 6 7 # linux中,在/etc/openvpn/下创建client1.ovpn cd /etc/openvpn/ vim client1.ovpn # windows中,在\openvpn\config\下创建client1.ovpn # 配置文件内容如下,根据注释内容按实际情况修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 client dev tun proto tcp # 花生壳内网穿透映射配置后提供的公网域名和端口 remote 47xxxx.fun 47557 resolv-retry infinite nobind persist-key persist-tun # 最好写绝对路径 ca ca.crt cert client1.crt key client1.key tls-auth ta.key 1 key-direction 1 verb 5
4、开启树莓派vpn服务端 1 2 3 4 5 6 # 进入server.conf所在目录下 # 开启服务端 openvpn --config server.conf & # 打开日志显示,显示“Initialization Sequence Completed”即正常 tail -f /var/log/openvpn/openvpn.log
1 服务端开启后,可查看vpn局域网ip,为10.8.0.1(可在server.conf修改)
5、开启PC vpn客户端 a、Linux系统下开启 1 2 3 # 进入client1.ovpn所在目录下 # 开启客户端 openvpn --config client.ovpn
1 成功开启并连接到服务端后,可查看vpn局域网IP
b、Windows系统下开启 1 2 3 打开openvpn后,在任务栏中找到openvpn图标,右键选择“选项”,打开如下界面,并选择“高级” 在“配置文件”处选择存放客户端相关文件的文件夹路径,点击确定
1 再次双击任务栏中openvpn图标,开始连接服务端,图标中电脑屏幕变绿即连接成功
6、vpn虚拟局域网连通性测试 1 2 在PC中ping 10.8.0.1,测试PC与树莓派间的vpn网络是否互通 如果互通,即可使用10.8.0.1这是ip来访问树莓派中应用(SSH、I-CON PLC RTE等)
7、自动化配置 a、树莓派开机自启phddns 1 2 # 设置开机自启,树莓派开机后自动登录phddns客户端,连接花生壳服务器 phddns enable
1 # 可在花生壳管理平台“设备列表”中,查看设备登录情况
b、树莓派开机自动拨号、邮件上报IP、开启VPN服务端 1 2 3 4 # 树莓派开机接入运营商网络后,运营商会为树莓派动态分配IP,导致使用花生壳建立的内网穿透映射失效 # 使用下面的shell脚本和python程序,实现树莓派开机自动拨号上网,并将获取到的IP通过邮件形式自动上报,最后开启VPN服务端 # shell脚本:auto_email_ip.sh # python程序:email_ip.py
1 2 3 4 5 6 7 # !/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
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 36 37 38 39 40 41 42 43 44 45 46 47 import smtplibfrom email.mime.text import MIMETextfrom email.utils import formataddrimport osimport timedef 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 ) server.login(my_sender, my_pass) server.sendmail(my_sender,[my_user,],msg.as_string()) server.quit() except Exception: 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 ("发送邮件失败" )
1 2 3 4 # 设置开机自动运行shell脚本 crontab -e # 在配置文件最后一行添加 @reboot /root/code/email_ip/reportIp.sh
1 2 完成上述配置后,树莓派开机后会自动接入运营商网络,获取到IP后自动发邮件上报,并自动开启vpn服务 用户只需要在花生壳管理平台中修改内网穿透映射配置中的内网IP,然后启动vpn客户端即可