使用树莓派搭建 PPTP VPN 的 WiFi 热点
1 背景
为了响应国家的号召,媳妇的公司也让在家办公了,她们公司也提供了 VPN 方便访问公司内网。但是 VPN 用的是 PPTP 协议,由于安全原因,macOS 已不再支持此协议,甚至从 Catalina 开始,从内核移除了相关代码。
因为 VPN 是公司提供的,因此不考虑更换协议的可能性,摆在面前的选项就只有:
- 使用 Windows 办公。
- 使用第三方 macOS VPN 客户端(但都是收费的)。
- 自己折腾。
想到家里还有个正在吃灰的树莓派,正好可以练练手,因此选择了自己折腾。
2 方案
手头可用的材料有:
- 树莓派 3B + 一只,这个型号预置了 WiFi 模块,无需另接无线网卡。
- 支持树莓派的 Linux 系统:ArchLinux ARM。
目标方案为:树莓派通过有线网连接 VPN,用 WiFi 做热点,将从热点进来的流量全部导向 VPN。macOS 只需要连接树莓派的热点,即可通过 VPN 访问公司内网。
3 操作步骤
首先分解一下需要进行的操作:
- 连接 PPTP VPN。
- 配置 WiFi 热点。
- 将来自 WiFi 热点的流量导向 VPN。
下面就基于 ArchLinux ARM,介绍每一步的操作。
操作过程中的大部分指令,都需要以 root 权限执行,因此请先切换到 root 用户。如果不想切换到 root 用户,请在每个指令前加上 sudo。
3.1 连接 PPTP VPN
在连接 VPN 之前,首先需要确保树莓派连接的有线网络的 IP 段,不与 VPN 的内网 IP 段相冲突。
假设 VPN 的内网 IP 段是 192.168.1.0/24,那么树莓派的有线网络 IP 段不能与这个 IP 段有任何交集,比如使用 172.16.1.0/24。
3.1.1 安装软件包
| 1 | pacman -Sy pptpclient | 
有些 Linux 发行版已经预置了这个软件包,安装前可以先执行 pptpsetup --help,检查一下软件包是否已经存在。
3.1.2 配置 VPN
| 1 | # 这里我们创建了一个VPN配置,将其命名为:officevpn | 
3.1.3 连接 / 断开 VPN
| 1 | # 连接VPN | 
3.1.4 查看 VPN 状态
执行命令 ip addr show,查看所有的网络连接。
如果列表中有一个名字以”ppp” 开头的网络连接,且成功分配了 IP,即表示 VPN 连接成功。
3.2 配置 WiFi 热点
配置 WiFi 热点时,同样也需要为热点网络选择一个子网 IP 段,这个 IP 段也是不能与 VPN 内网的 IP 段冲突,另外最好也不要与有线网络的 IP 段冲突,例如使用 10.1.1.0/24。
3.2.1 安装软件包
| 1 | pacman -Sy dnsmasq hostapd | 
如果你比较习惯使用
NetworkManager,也可以用它来配置热点,这里只是以dnsmasq+hostapd来举例。
3.2.2 配置 DHCP 客户端
首先我们需要为 WiFi 网卡配置一个静态 IP:10.1.1.1。
备份并编辑文件”/etc/dhcpcd.conf”,在文件最后追加如下内容:
| 1 | interface wlan0 | 
重启服务:
| 1 | systemctl restart dhcpcd | 
3.2.3 配置 dnsmasq
在这里,仅将 dnsmasq 作为 DHCP 服务器来使用。
备份并编辑文件”/etc/dnsmasq.conf”,在里面添加如下内容:
| 1 | interface=wlan0 | 
安装并启动 dnsmasq 服务:
| 1 | # 安装服务 | 
3.2.4 配置 hostapd
hostapd 的配置文件为”/etc/hostapd/hostapd.conf”,如果文件已存在,建议将其改名备份,之后新建一份空白的同名文件,输入如下内容:
| 1 | interface=wlan0 | 
配置中的”WiFi 名称” 和”WiFi 密码” 两项,可根据实际情况修改。其他参数,如果你不了解其意义,建议不要修改。
安装并启动 hostapd 服务:
| 1 | # 安装服务 | 
3.2.5 测试热点
使用手机或者一台电脑,尝试搜索并连接前面配置的 WiFi。
如果能够成功连接到 WiFi,并分配到了一个在”10.1.1.2”~”10.1.1.255” 之间的 IP,即表示一切正常。
当然,这个阶段你还无法通过这个热点上网,这是接下来要做的事情。
3.3 流量转发
这里我们不需要任何第三方软件包,直接使用系统自带的 iproute2 和 iptables 工具包来搞定。
请先通过如下命令,判断一下你的系统是否有对应的工具包:
| 1 | # 测试iproute2 | 
回顾一下方案,我们的需求是将所有来自 WiFI 热点的流量,导向 VPN 连接。因此,首先需要为所有来自 WiFi 热点的数据包做一个标记,然后将这些数据包全部转发到 VPN 连接。
3.3.1 启用数据包转发
| 1 | # 开启数据包转发 | 
为了让该配置在重启后仍然生效,创建文件”/etc/sysctl.d/ip-forward.conf”,并在其中添加如下内容:
| 1 | net.ipv4.ip_forward=1 | 
3.3.2 配置转发规则
在配置规则前,首先需要获取 VPN 连接的一些信息。
执行命令 ip addr show,找到 ppp 开头的 VPN 连接信息,例如:
| 1 | 4: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1496 qdisc fq_codel state UNKNOWN group default qlen 3 | 
记下其中的连接名称(例子中为 ppp0)和 peer IP(例子中为 192.168.1.33)。
现在开始配置转发规则:
| 1 | # 这里我们自定义了一个路由表,将其编号定义为201 | 
配置完上述规则后,连接 WiFI 热点的设备,即可直接访问公司内网的资源。
3.3.3 自动配置
上一步配置的所有规则,都是不存盘的,因此每次连接 VPN 之后,都要重新配置。
所幸 pptpclient 提供了 hook 机制,当 pptp 连接建立成功时,它自动会执行”/etc/ppp/ip-up.d/“下面的所有”.sh” 脚本。因此我们可以创建一个 hook 脚本,实现自动配置规则。
在”/etc/ppp/ip-up.d/“下面创建文件” auto-hotspot.sh”,写入如下内容:
| 1 | #!/bin/sh | 
最后,不要忘记为 hook 脚本添加执行权限:
| 1 | chmod a+x /etc/ppp/ip-up.d/auto-hotspot.sh |