Personal Proxy on IPv6 + NAT IPv4 Server

In some countries mainstream sites like Google, YouTube, and Wikipedia are blocked by censors. People who want to get around the censors have to use VPNs or encrypted proxies. Some countries have the additional problem of a devalued currency. People in these countries want to build their proxy server as cheaply as possible, and this means IPv6 with shared NAT IPv4. This post is aimed at these users. It requires two things:

  • An Ubuntu 20.04 server with IPv6 and NAT IPv4, and a minimum of 256 MB RAM. This tutorial was developed on a dual-stack VPS with both IPv6 and IPv4, so if you want to test it on a real NAT IPv4 server, you are welcome to go ahead and leave your results in the comments.
  • You'll also need a domain name, either a free one or one of those dollar-a-year introductory offers.

At your domain name registrar, create an AAAA record pointing from your host name — let's use www.example.com as our example — to your server's IPv6 address.

Now you have your server provisioned, we're ready to go.

Create Camouflage Website

Part of the art of getting past censors is to disguise your proxy server as a web server. For this reason, you need to install Nginx and some realistic but uncontroversial web pages. Install Nginx like this:

apt update && apt upgrade -y

apt install nginx -y

Add some content, so that your web server looks like a real web server. What follows is just an example. You can add whatever content you like so that your server passes manual inspection by the censors:

apt install wget zip unzip -y

wget https://github.com/arcdetri/sample-blog/archive/master.zip

unzip master.zip

cp -rf sample-blog-master/html/* /var/www/html/

Now configure Nginx to listen on IPv6 only, and specify the actual name of your server. We're using www.example.com in the templates here. Edit /etc/nginx/sites-available/default and make it look like this:

server {
        listen [::]:80 default_server;
        root /var/www/html;
        index index.html;
        server_name www.example.com;
        location / {
                try_files $uri $uri/ =404;
        }
}

Save the file, and restart Nginx with your new configuration:

systemctl restart nginx

Install Let's Encrypt SSL Certificate

To get past censors you need to encrypt traffic between your client and the server. To offer an encrypted HTTPS website, we'll use a free SSL certificate from the Let's Encrypt project. You'll need to have waited an hour or more for your DNS records to propagate before you proceed. You can check at Network-Tools or CentralOps to see if they know about your www.example.com server name and a query type of AAAA.

Once your DNS records have propagated, obtain your Let's Encrypt SSL certificate using Certbot client:

apt install certbot python3-certbot-nginx -y

certbot --nginx

certbot renew --dry-run

When I tested this, I experienced a problem with the Certbot renew attempt not connecting to my server. If this happens to you, you can retry with webroot authentication like this:

certbot certonly --webroot -w /var/www/html -d www.example.com

certbot renew --dry-run

Protect Server with Cloudflare

It's also helpful to conceal your server's IP address. We do that by positioning the server behind a Content Distribution Network. The CDN we use here is Cloudflare.

Add your domain to Cloudflare. If you don't already have a Cloudflare account, you'll be prompted to create one when you create your first domain. Specify that you want the FREE plan.

Now you need to change your domain's nameservers at your domain name registrar. Cloudflare will provide you with the new Cloudflare nameservers you need to use.

Back at Cloudflare, set the SSL/TLS Encryption mode to Full.

Wait a few hours for the email to arrive saying domain is now active on Cloudflare. Then check that your server now gives Cloudflare IPv4 and IPv6 addresses, and not the real IPv6 address of your server.

nslookup www.example.com

At this point, you can check in a browser to see what a censor visiting your server would see:

https://www.example.com

Install V2Ray Plugin

Install the V2Ray plugin for Shadowsocks on the server:

wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.3.1/v2ray-plugin-linux-amd64-v1.3.1.tar.gz

tar -xf v2ray-plugin-linux-amd64-v1.3.1.tar.gz

cp v2ray-plugin_linux_amd64 /usr/bin/v2ray-plugin

Install Shadowsocks-libev

Now we come to the Shadowsocks install in the server. The version of Shadowocks we'll use is Shadowsocks-libev. It's written in pure C and is designed to be a lightweight implementation of the Shadowsocks protocol that keeps resource usage as low as possible. Also, Shadowsocks-libev supports plugins.

Install the package:

apt install shadowsocks-libev -y

Edit the configuration file /etc/shadowsocks-libev/config.json. Make the contents look like the template below. Replace the password and secret path by your actual chosen values.

{
    "server":"::1",
    "server_port":10001,
    "password":"pass1234",
    "timeout":300,
    "method":"chacha20-ietf-poly1305",
    "ipv6_first":true,
    "plugin":"/usr/bin/v2ray-plugin",
    "plugin_opts":"server;path=/abc123"
}

Save the file, and restart Shadowsocks on the server:

systemctl restart shadowsocks-libev

Pass Traffic from Nginx to SS+V2Ray

Incoming traffic arrives first at Nginx. If the user requests the secret path, Nginx passes the request to Shadowsocks+V2Ray. (You must keep the path name secret and hard to guess.) To do this hand-off, add a new Nginx location block within the server block for port 443. Edit the configuration file /etc/nginx/sites-available/default. Add the block as specified:

location /abc123 {
    proxy_redirect off;
    proxy_pass http://[::1]:10001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
}

Save the file, and restart Nginx:

systemctl restart nginx

Configure Client

The V2Ray plugin exists for Windows, macOS, Linux, FreeBSD, and Android. In this post, we will use Android as our sample client.

  • Install Shadowsocks by Max Lv. You can get it from the Google Play Store. If that is censored in your country, you can get it from GitHub.
  • Install the V2Ray Plugin by Max Lv. You can also get it from the Google Play Store or from GitHub.

Open the Shadowsocks app. Add a new profile, creating it from Manual Settings:

  • Profile Name = ss+v2ray
  • Server = www.example.com
  • Remote Port = 443
  • Password = pass1234
  • Encrypt Method = chacha20-ietf-poly1305
  • Route = All
  • IPv6 Route = On
  • Apps VPN Mode = Off
  • Metered Hint = Off
  • Remote DNS = 8.8.8.8
  • Send DNS over UDP = Off
  • Plugin = v2ray
  • Transport mode = websocket-tls
  • Hostname = www.example.com
  • Path = /abc123
  • Concurrent connections = 1
  • Certificate for TLS verification = Not set
  • Logcat level = warning
  • Generated line = path=/abc123;host=www.example.com;tls
  • UDP Fallback = Disabled

Now open a browser and connect to the web via your encrypted proxy server. Happy surfing!

Comments

  • I know you said it requires 256MB. But I'm gonna ask it anyway, is there a way to make this work with 128MB? I'd put my $2/yr VPS to good use. Thanks for the guide.

  • Nice tutorial... I like it!

    Thanked by (1)AndyMcFadden

    A simple uptime dashboard using UptimeRobot API https://upy.duo.ovh
    Currently using VPS from BuyVM, GreenCloudVPS, Gullo's, Hetzner, HostHatch, InceptionHosting, LetBox, MaxKVM, MrVM, VirMach.

  • @Ouji said:
    I know you said it requires 256MB. But I'm gonna ask it anyway, is there a way to make this work with 128MB? I'd put my $2/yr VPS to good use. Thanks for the guide.

    I honestly haven’t tried it.

  • AbdullahAbdullah Hosting ProviderOG
  • mikhomikho AdministratorOG

    @Ouji said:
    I know you said it requires 256MB. But I'm gonna ask it anyway, is there a way to make this work with 128MB? I'd put my $2/yr VPS to good use. Thanks for the guide.

    Try using the minimal Debian template instead of Ubuntu.

    Optimise by removing unused services.

    After reading the tutorial (nice one!), I’m sure it would be possible running it on a 128mb instance.
    It will require some work to get the ram usage to a minimum.

    Thanked by (1)Ouji

    “Technology is best when it brings people together.” – Matt Mullenweg

  • Premium tutorial ?

  • Great! Thank you!

  • I'm a little confused as to why I need CloudFlare instead of proxy direstly from the assigned ports. CloudFlare is extra overhead in this case.

    Action and Reaction in history

  • @elliotc said:
    I'm a little confused as to why I need CloudFlare instead of proxy direstly from the assigned ports. CloudFlare is extra overhead in this case.

    Assume it's because China, etc, could block connections to your server but not Cloudflare.

    Probably better to not use Cloudflare though unless it becomes a necessity.

  • Nice How-to , thanks for sharing

  • Nice guide!!! @AndyMcFadden

    work like a champ with nat vps from @Abdullah

    Thanked by (1)Abdullah

    Backend Ruby Dev and Linux user

  • ApeWebApeWeb Hosting Provider

    Cool guide I think we will see more IPv6 + NAT IPv4 Servers. I suspect it could even work on 128mb ram with a minimal debian install.

Sign In or Register to comment.