Using Raspberry Pi to Build a US VPN Server for My Family in China

Category: []

Excerpt:

Around December 2023, all ChatGPT access node IPs used by our ClashX VPN were blocked by OpenAI. This situation led me to seek alternative methods to restore unrestricted internet access for my family. In this blog post, I’m going to share my experience and detailed process of setting up a Raspberry Pi as a VPN…

Thumbnail:



Disclaimer: This post is based on my personal experience and is not sponsored or influenced by any platform or service mentioned.

In this blog post, I’m going to share my experience and detailed process of setting up a Raspberry Pi as a VPN server for my family in China. Due to the “Great Firewall” of China (for a more detailed background on this, please refer to my previous post here), accessing services like Google and ChatGPT is always a big challenge for the internet users in China (including my family). This became even more pressing when, around December 2023, all ChatGPT access node IPs used by our ClashX VPN were blocked by OpenAI. This situation led me to seek alternative methods to restore unrestricted internet access for my family.

To circumvent these restrictions, I decided to set up a VPN server using a Raspberry Pi. I placed the Raspberry Pi at my friend Ethan’s house, whom I thank for his and his wife Lily’s help! (website)

Why Raspberry Pi? I chose a Raspberry Pi due to its compact size, low power consumption, and affordability (the total price of the Raspberry Pi Kit I bought is 187.41$ after tax).

(March 14, 2024: Update, I just uploaded a video of Raspberry Pi 5 (which recorded on January 26, 2024) to YouTube so you can see how small it is.)

Why this VPN? WireGuard was chosen over OpenVPN for its simplicity, lighter nature and better performance, though both are viable options. I configured the Raspberry Pi using the CLI interface to maximize performance since a GUI consumes more resources. So for those looking to optimize their Raspberry Pi for VPN use, I recommend switching the “boot option” in “system config” to “text console” through sudo raspi-config.

One critical aspect was configuring port forwarding and static routing in NAT to enable communication between the VPN clients and the server. Port forwarding was set to direct traffic from port 51820 by default(used by WireGuard) to the Raspberry Pi, enabling external VPN client connections. Meanwhile, port forwarding and static routing was necessary within the home network to guide traffic destined for the VPN network directly to the Raspberry Pi in the router’s NAT setting, ensuring proper internal communication and internet access. Incidentally, I chose CloudFlare as the DNS provider.

And the Deco router in Ethan’s home has the ability to interact with IPv4 devices via NAT port forwarding, theoretically eliminating the need for Dynamic DNS (DDNS) for VPN connections, because the combination of the router’s IPv6 + the specified port number can create a definitive pathway for initiating communication and accessing the Raspberry Pi remotely.

However, I heard that IPv6 supports better security features natively as more ISPs and devices are gradually shifting to IPv6. So I prefer using IPv6 for my Raspberry Pi’s remote SSH access (in my case, as I’m frequently updating and maintaining my custom-designed Discord bot (here) for my game dev team (CruxAbyss) hosted on the Raspberry Pi recently: Despite Cloudflare Workers is a popular choice for serverless code hosting (with the first 100,000 requests each day being free!), I prefer direct control in Raspberry Pi for frequent update at the current stage, particularly as the request volume my code would generate may exceed this number each day.), especially, I’m very interested in applying the real-time IP address updates for my Raspberry Pi to deal with the dynamic property of Ethan’s router’s IPv6 address assignments:

The main challenge was dealing with dynamic IP addresses due to Ethan’s router (a Deco model) using DHCPv6. Assigning a static IPv6 to the router itself was not feasible due to the limitations of the router’s model and the potential security risks involved. Furthermore, I attempted to configure the router to reserve a static IPv6 address to the Raspberry Pi. However, I found that Ethan’s Deco router could only assign static IPv4 addresses, not IPv6. So this led to the necessity of implementing DDNS to keep the server accessible despite changing IP addresses. Thus, I resorted to using DDNS to ensure the SSH accessibility to my Raspberry Pi server regardless of the changes in its IPv6.

Awkwardly, during the setup, I discovered that Ethan’s Deco router supported VPN settings (including VPN like OpenVPN) 😂, including DDNS, but its DDNS was intended for the router’s use, not the devices under it. Therefore, I used a custom CloudFlare-DDNS solution (the repo is here). Also, ensure to initiate the ddns configuration on the Raspberry Pi by first establishing an SSH connection to input the token, as manual entry can be pretty cumbersome…

Forgot to mention, to enable SSH for Raspberry Pi, please execute sudo raspi-config, followed by sudo systemctl restart cron and sudo reboot. Initially, I recommend to connect both the Raspberry Pi and the controlling computer to the same network for SSH access. To enable SSH access under different networks later on, you need to make adjustments to the router’s firewall and Raspberry Pi’s UFW settings to permit SSH and VPN traffic, also ensuring port 22 is open for SSH connections. For IPv6 SSH connection, make sure both the client and server have IPv6 addresses and are configured to accept IPv6 connections. The device’s IPv6 connectivity can be checked using online tests such as here.

Once you could access the SSH connection with Raspberry Pi, then make sure replace the “DROP” in “DEFAULT_FORWARD_POLICY” the UFW config file with “ACCEPT”, or the traffic coming from the VPN interface (for example, wg0) and destined for the internet won’t be forwarded. This would prevent your VPN clients (like your phone) from accessing external websites or any resource outside the Raspberry Pi itself!

After configuring the VPN and resolving the networking issues, I recommend running pivpn debug to identify and resolve potential problems. This step is essential to ensure the VPN operates smoothly and securely.

Note: For the CloudFlare users, a significant step was configuring the CloudFlare DDNS script without enabling the “proxied” option in your CloudFlare DNS record settings. This was crucial as the VPN service needed to recognize direct connection requests from clients (recall the public DNS name you previously input), not masked ones via CloudFlare’s DDoS protection services (the underlying mechanism involves CloudFlare’s proxy acting to overlay a masking IP onto your domain. You can verify this by pinging your proxied domain directly from the terminal, which reveals that the IPv6 address returned is not the actual IPv6 of your domain.). Ensuring the DNS records for the VPN were not proxied allowed for direct and secure connections to the Raspberry Pi server.

However, I noticed that when I’m on an external network (outside my home), I can SSH into your Raspberry Pi using both its IPv4 and IPv6 addresses. But, when I’m at home and on the same local network as my Raspberry Pi, I can only SSH into it using its IPv4 address, as the SSH over IPv6 fails when I’m on the same local network. I think the most likely cause is that the router’s default settings were blocking or not routing IPv6 traffic correctly within the local network. As many home routers are configured primarily to handle IPv4 traffic internally.



4 responses to “Using Raspberry Pi to Build a US VPN Server for My Family in China”

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. 安东尼 Avatar
    安东尼

    nb!不过为什么我在外网就不可以ssh家里的树莓派了?我也跑了pivpn debug发现没有报错啊

    1. louis0liu Avatar

      哦哦可能是你家里router firewall的配置原因,你看一下家里router的firewall config setting里有没有允许raspberry pi’s ipv6的port 22的traffic,允许了之后应该就可以ssh它的ipv6了。同时有没有给port 22设置port forwarding to raspberry pi’s ipv4,这样可以ssh它的ipv4。如果还没有解决的话你直接disord上联系我好了

  2. gc Avatar
    gc

    这么贵吗,我以为一百刀以内就可以全部搞定了

    1. louis0liu Avatar

      哦哦者其实完全可以的哦,如果预算在100刀以内,你可以买raspberry pi 4 (或3,更老的可能找不到了) + 2gb RAM 的kit (可以看here),不过要选那些带着容量更小的micro sd卡的kit,然后其他配件,比如壳子啊或者线啊也不要太贵的,或者你只买主板,其他配件自己配也是可以的。但如果你不在乎性能损失的话,其实最低50刀以内就可以配出一个私用vpn server,那你可以选择买raspberry pi zero。

      我个人买的比较贵是因为我除了需要让它run vpn,run 网站,还要run一些python程序什么的,所以性能就给它配满了哈哈