搭建VPN

本文介绍如何使用pivpn这个工具一键在树莓派上安装openvpn。

博主的目的是从海外通过vpn连接到国内家中内网里的树莓派(家里的网络没有公网IP,使用花生壳的内网穿透服务连接树莓派),使用国内家中的局域网环境。

一旦连上vpn可以干的事情就很多了,比如翻墙回国,比如不需要自建服务器就可以冒充局域网联机玩我的世界,比如远程登录家中的电脑。等等。。。

系统升级

更新软件包地址。

sudo apt-get update

继续升级软件包。

sudo apt-get upgrade

系统升级可能需要花一段时间,在国内可能还要花更久的时间,需要耐心等待。(更新源要提前换成国内源)

PiVPN

PiVPN是一个专门为树莓派设计的OpenVPN平台。我们可以在树莓派上访问PiVPN来直接将OpenVPN安装到自己的树莓派上。

SSH登陆树莓派并且完成了系统升级后,在命令行输入

curl -L https://install.pivpn.io | bash

博主自己的环境需要做以下操作(读者请无视)

先在外网下载好传输到国内树莓派上

wget https://install.pivpn.io

会下载为index.html,重命名为pivpn.sh

mv index.html pivpn.sh

然后scp传输到国内树莓派上

scp -P [ssh port] pivpn.sh pi@[host or domain]:/home/pi/.

进入国内树莓派赋予执行权限

chmod +x pivpn.sh

然后连上国外proxy (前提是配置好mytools和~/.bashrc里面的proxyon命令)

proxyon

然后执行安装shell

./pivpn.sh

博主自己的环境需要做以上操作(完)

按下回车,启动PiVPN的安装。等待一段时间后会出现如下界面。按下回车确认。

注意,在PiVPN的安装过程中,空格键用于选择,回车键用于确认当前选择并进入下一步。

接下来在网络界面选择里,选择你的网络(wifi或者Ethernet,根据树莓派联网的实际情况)。

下一步安装程序会询问你是否应用静态的IP地址。这个IP地址是你的路由器分配给树莓派使用的IP地址,通常不会改变,所以在这里选择Yes就好。

现在安装程序会要求你进行VPN服务器的参数设置。首先它会询问你,使用树莓派上的哪个用户来创建VPN服务器。通常选择pi用户就好。

接下来安装程序会询问你是否开启自动安全更新。鉴于我们的VPN服务器至少会暴露一个端口到互联网上,所以及时的安全更新还是很重要的。树莓派并不会定期重启,所以要应用最新的安全更新,我们需要不定时的手动重启树莓派。

随后需要我们选择网络协议。选择UDP就好。

博主这里需要配合花生壳的内网穿透,而花生壳低版本不支持UDP穿透,所以这里要选择TCP

接下来这一步很重要,我们要选择VPN的端口。默认的端口号是1194。但是出于网络安全的考虑,强烈建议你把端口号修改成其他数字。比如下图中的11948。

博主这里配合花生壳的内网穿透,填入花生壳配置的映射端口作为服务端口。

image.png

接下来一步,要设置加密密钥的长度。一般来说,2048比特的密钥就已经足够了。而4096比特长度的密钥就过于复杂,生成起来时间很久。

按下OK以后就开始生成我们VPN服务器的加密密钥了,如下图所示。正如命令行提示的那样,This is going to take a long time…….在我的树莓派Zero W上大概运行了有一个小时左右才最终生成完毕(但是在B型树莓派3上大概只花了1分钟)。所以,耐心等待吧。

加密密钥生成以后我们要设置IP。如果你的网络运营商分配给你的是一个固定IP,那选择第一项就好。如果你的网络运营商分配给你的是一个动态IP,那你就需要设置DNS入口。你需要在类似No-IP这样的网站上注册一个账号以追踪你的IP地址。注册完账号以后会分配给你一个类似xxxx.noip.com的地址,填在下面DNS Entry页面中即可。想要了解如何在No-IP上设置动态IP的DNS解析,可以参考我的这篇教程:为PiVPN设置动态IP的DNS解析

博主这里配合花生壳的内网穿透,填入花生壳配置的穿透域名。

我的IP是静态固定IP,所以我选择的第一项。下图中,我家的IP地址已经被我抹去了。

下一步会询问你,你要给你的VPN用户选择哪个DNS服务器。如果你要在中国大陆使用VPN的话,建议选择最后一个自定义选项Custom。这个链接里有国内常用的DNS服务器汇总,选择一个适合自己的DNS服务器就可以。如果你主要在中国大陆以外的其他地区使用VPN,恭喜你可以直接选择Google。如果一切设定完成以后想要想修改OpenVPN的DNS服务器,可以参考我的这篇教程:如何在设定完毕后修改PiVPN的配置文件

博主这里选择custom并填入114.114.114.144, 114.114.115.115

到这里位置,VPN服务器就搭建结束了。在命令行中输入

sudo reboot

再按下回车,重启树莓派。

博主追加

如何连接vpn

使用openvpn客户端软件。各平台都有免费的。

官方提供的软件下载在这里

使用后面说明的pivpn add命令生成一个连接用的文件,用客户端打开即可连接。这个文件其实是一个纯文本文件,如果服务器换了IP或者想换成域名形式的话也可以直接修改这个文件。但文件里一堆key不用去动他。

常用命令

  • pivpn -h 查看帮助
  • pivpn -d 查看调试信息
  • pivpn add 添加客户端用户(添加完成以后会生成一个用于openvpn客户端连接用的文件)
  • pivpn add nopass 添加免密码的客户端用户
  • pivpn -r 取消指定用户
  • sudo service openvpn restart 重启openvpn服务

配置完成以后如何修改

pivpn的配置文件

/etc/pivpn/openvpn/setupVars.conf

主要是修改

Name用途
pivpnPROTO协议udp / tcp
pivpnPORT服务端口
pivpnSEARCHDOMAIN服务器域名(花生壳分配的穿透域名),如果是固定IP可留空
pivpnHOST服务器IP(ping一下花生壳穿透域名得到的IP即可)

openvpn的配置文件

/etc/openvpn/server.conf

主要是修改

Name用途
proto协议udp / tcp
port服务端口

|
修改配置以后需要重启openvpn服务

sudo service openvpn restart

pivpn add生成的连接用文件

/home/pi/ovpns/xxx.ovpn

如果安装时协议,域名,端口都正确配置了那么这个文件不需要修改。不放心打开检查一下。

但如果安装的时候没有设置正确,那么即使修改了前面两个配置文件,pivpn add生成的客户端连接文件中的内容依然是错误的(这个实在没找到还有哪里需要修改,博主只好直接修改生成以后的文件内容了,好在是文本文件可以修改)

Name用途
proto协议udp / tcp
remote花生壳域名或固定IP 花生壳映射端口号(如 abc.cn 12345)

问题解决Tips:在ubuntu 20.04 LTS安装pivpn,客户端无法连接或者可以连接上服务器但没有因特网连接无法上网

在ubuntu 20.04 LTS下安装完成后你会发现虽然可以连接上服务器但是没有因特网连接,这是因为PiVPN工具对ubuntu 20的支持并不太好(官方只支持到ubuntu 18.04)。

尝试执行pivpn -d可能会得到以下3个错误。

错误1,提示ufw没有启动

但是我手动执行 sudo ufw status verbose 查看防火墙状态却显示 运行中 。要知道ufw防火墙工具是ubuntu自带的一般不会不启动。折腾好久终于查看pivpn源代码发现它只是单纯的对命令ufw status的输出是否为 active 这个英文单词做了验证,而如果你的local设置是中文那自然通不过验证。哎这种check真是作者拍脑袋写出来的很无语。知道原因就不用管它了,提示错误就错误,实际上并没有影响。

当然如果你是强迫症患者也可以修改local文件将中文改成英文后重启即可消除这个错误提示。

可以但没必要。

错误2,提示ufw的入站规则没有设置

并询问是否修复,但即使尝试进行修复也会报一个莫名其妙的错误。具体内容如下

:: [ERR] Ufw input rule is not set, attempt fix now? [Y/n] Y
ERROR: Invalid position '1'
Firewall reloaded
Don

这次直接看源码得知需要添加一条入站规则(废话),根据之前创建服务器设置的协议(udp / tcp)和端口号用iptables命令自行设置一条规则即可。比如

sudo iptables -I INPUT -p udp --dport 1194 -j ACCEPT
sudo iptables-save
# 下面两句是为了持久化,需要先安装 iptables-persistent 这个工具(用apt-get install安装)
sudo netfilter-persistent save
sudo netfilter-persistent reload

自行设置入站规则以后运行pivpn -d时依然会报错,无视即可。

相关源码参考(/usr/local/src/pivpn/scripts/self_check.sh):

if iptables -C INPUT -i "${IPv4dev}" -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT -m comment --comment "${VPN}-input-rule" &> /dev/null; then
  echo ":: [OK] Iptables INPUT rule set"
else
  ERR=1
  read -r -p ":: [ERR] Iptables INPUT rule is not set, attempt fix now? [Y/n] " REPLY
  if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then
    iptables -I INPUT 1 -i "${IPv4dev}" -p "${pivpnPROTO}" --dport "${pivpnPORT}" -j ACCEPT -m comment --comment "${VPN}-input-rule"
    iptables-save > /etc/iptables/rules.v4
    echo "Done"
  fi
fi

错误3,提示转发规则没有设置

跟错误2一样,即使尝试修复也会报错,具体如下

:: [ERR] Ufw forwarding rule is not set, attempt fix now? [Y/n] Y
ERROR: Invalid position '1'
Firewall reloaded
Done

原因也和错误2一样,这个工具的自动修复命令行语法不适配ubuntu 20,所以也需要按它的源码要求自行添加规则,应该一来一回添加2条即可。这里我没有仔细研究了,因为现在已经特么凌晨3点多了。我直接修改ufw的配置文件,将 DEFAULT_FORWARD_POLICY 从 DROP 改为 ACCEPT ,默认允许所有转发。

#修改ufw配置文件
sudo vi /etc/default/ufw
...
#将 DEFAULT_FORWARD_POLICY 从 DROP 改为 ACCEPT
#DEFAULT_FORWARD_POLICY="DROP"
DEFAULT_FORWARD_POLICY="ACCEPT"
...
#修改配置文件后重新load
sudo ufw reload

相关源码参考:

if iptables -C FORWARD -s "${pivpnNET}/${subnetClass}" -i "${pivpnDEV}" -o "${IPv4dev}" -j ACCEPT -m comment --comment "${VPN}-forward-rule" &> /dev/null; then
  echo ":: [OK] Iptables FORWARD rule set"
else
  ERR=1
  read -r -p ":: [ERR] Iptables FORWARD rule is not set, attempt fix now? [Y/n] " REPLY
  if [[ ${REPLY} =~ ^[Yy]$ ]] || [[ -z ${REPLY} ]]; then
    iptables -I FORWARD 1 -d "${pivpnNET}/${subnetClass}" -i "${IPv4dev}" -o "${pivpnDEV}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "${VPN}-forward-rule"
    iptables -I FORWARD 2 -s "${pivpnNET}/${subnetClass}" -i "${pivpnDEV}" -o "${IPv4dev}" -j ACCEPT -m comment --comment "${VPN}-forward-rule"
    iptables-save > /etc/iptables/rules.v4
    echo "Done"
  fi
fi

以上即可解决客户端可以连接但不能上网的问题。

Last modification:February 2, 2022
If you think my article is useful to you, please feel free to appreciate