Since I will be travelling to China next week I thought now would be a good time to setup a VPN that at least had some chance of working through the GFW. After doing some research I found there are a few possible solutions but the one I settled on was using OpenVPN with the scramble patch.
The goal of this guide is to help those travelling or living in China or other countries that have limitations on their internet access. In my case I am trying to bypass China’s Great Firewall which actively seeks out VPN connections and blocks them. Using a typical OpenVPN configuration is no longer good enough as the GFW uses deep packet inspection to block OpenVPN connections. Using an obfuscation technique I hope it will confuse the deep packet inspection and let the VPN function. Full credit to the author of this thread for designing the scrambling technique.
Choosing a Server
I found a cheap VPN provider that has TUN/TAP enabled and a dedicated IP since I didn’t want to worry about a NAT’d IP. The actual specs of the machine are not that important as long as you get a sufficient amount of bandwidth for what you need it for. I also selected one in the USA despite the privacy concerns but for the added benefit of being able to use it for US Netflix and other USA only services. This is not meant to be an extremely NSA-proof server, but something I can use to get around China’s firewall restrictions. If you have more privacy concerns, I would choose something in another country.
My Server Specs:
- 20gb HDD
- RAM: 768mb / vSWAP: 768mb
- 2TB Bandwidth
- 1 IPv4
Lets get to setting up the server.
Setting Up The OpenVPN Server
The first thing to do is to make sure the system is up to date and the required packages are installed.
apt-get install gcc make automake autoconf dh-autoreconf file patch perl dh-make debhelper devscripts gnupg lintian quilt libtool pkg-config libssl-dev liblzo2-dev libpam0g-dev libpkcs11-helper1-dev chkconfig -y
After the system is updated, get the source code of OpenVPN and the patch.
cp openvpn_xorpatch-master/openvpn_xor.patch openvpn-2.3.6/
git apply --check openvpn_xor.patch
git apply openvpn_xor.patch
Lets make and install OpenVPN.
wget --no-check-cert https://Scott.StevensonOnThe.Net/files/OpenVPN/etcinitdopenvpn.sh -O /etc/init.d/openvpn
chmod +x /etc/init.d/openvpn
update-rc.d openvpn defaults
After this is complete, you should check to make sure OpenVPN has been added to the startup. This way, if your machine restarts, OpenVPN will be started automatically.
chkconfig --list | grep openvpn
The output of this line should look like this:
openvpn 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Now that OpenVPN is installed, we need to create the client and server certificates.
Lets create some folders for the client and server files.
git clone git://github.com/OpenVPN/easy-rsa
In this step, you can specify the client name by replacing xclientx with the name of your client. You will need to change it anywhere that you see xclientx. This will generate the client req file.
./easyrsa gen-req xclientx nopass
git clone git://github.com/OpenVPN/easy-rsa
Generate keys/certificates for the server.
./easyrsa gen-req server nopass
./easyrsa sign-req server server
openssl dhparam -out dh2048.pem 2048
openvpn --genkey --secret ta.key
./easyrsa import-req $HOME/clientside/easy-rsa/easyrsa3/pki/reqs/xclientx.req xclientx
./easyrsa sign-req client xclientx
After all the certificates and keys are generated, copy them to the respective client and server directories.
cp $HOME/serverside/easy-rsa/easyrsa3/pki/ca.crt $HOME/serverside/
cp $HOME/serverside/easy-rsa/easyrsa3/pki/issued/server.crt $HOME/serverside/
cp $HOME/serverside/easy-rsa/easyrsa3/dh2048.pem $HOME/serverside/
cp $HOME/serverside/easy-rsa/easyrsa3/pki/private/server.key $HOME/serverside/
cp $HOME/serverside/easy-rsa/easyrsa3/ta.key $HOME/serverside/
cp $HOME/serverside/easy-rsa/easyrsa3/pki/issued/xclientx.crt $HOME/clientside/
cp $HOME/serverside/easy-rsa/easyrsa3/ta.key $HOME/clientside/
cp $HOME/serverside/easy-rsa/easyrsa3/pki/ca.crt $HOME/clientside/
cp $HOME/clientside/easy-rsa/easyrsa3/pki/private/xclientx.key $HOME/clientside/
Create the client configuration script.
If nano is not installed, install it before the previous step.
apt-get install nano
Using nano, create a configuration with the following:
scramble obfuscate insert_password_here
remote insert_server_address_here 443
tls-auth ta.key 1
As you can see, I am using port 443, but any port can be used as long as its the same on the server and client side. The reason I am choosing port 443 is because this is a common port for encrypted traffic. I am hoping traffic on this port may be left alone by the GFW more then a random port. Each situation is different however, so choose what will work for you.
After saving the configuration (ctrl-o and then ctrl-x) its time to merge the configuration and the certificates into one file.
wget https://Scott.StevensonOnThe.Net/files/OpenVPN/merge.sh -O merge.sh
chmod +x merge.sh
Edit the file to change the xclientx names. Save the file.
Run the script.
Now there will be a single file in your $HOME/clientside/ directory called xclientx.ovpn. Use WinSCP to connect via SCP to this directory and copy the file to your PC. We will use it later to setup OpenVPN on our PC.
The server setup is very much the same as the client setup. Open nano and create a configuration file.
For the DNS settings, you can set it to anything you want, but I went to the Open Nic Project to find some DNS servers that keep no logs and are close to my server location to keep the DNS lookups quick. You can also use Google (184.108.40.206, 220.127.116.11) or OpenDNS (18.104.22.168, 22.214.171.124). I have left in Googles DNS for the example.
scramble obfuscate test
tls-auth ta.key 0
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1"
push "dhcp-option DNS 126.96.36.199"
push "dhcp-option DNS 188.8.131.52"
keepalive 5 30
Like we did with the client configuration, merge the keys, certificates and configuration into one file.
wget --no-check-cert https://Scott.StevensonOnThe.Net/files/OpenVPN/merge_server.sh -O merge_server.sh
chmod +x merge_server.sh
cp $HOME/serverside/server.conf /etc/openvpn/
Next enable data redirect.
Uncomment the following line and save the file. (ctrl-o)
Make a file for the firewall settings.
Paste the following rules and save the file.
iptables -t filter -F
iptables -t nat -F
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s "10.8.0.0/24" -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -t nat -A POSTROUTING -s "10.8.0.0/24" -j MASQUERADE
Change the permissions on the file so its executable
chmod +x /usr/local/bin/firewall.sh
Make the firewall settings apply after each reboot.
Add the following to the file before the line “exit 0” and save it.
Apply the settings.
sysctl -w net.ipv4.ip_forward=1
Any time changes are made to the server configuration OpenVPN must be restarted. To restart OpenVPN use the following:
Now that we have the server and client configuration completed, all that remains is to set this up on the client PC. Download OpenVPN 2.3.6 from the official source. Install this on your Windows machine. After installation, you need to apply the patched executable to make scramble work. Download from here. (Mirror: OpenVPN Scramble Patched Windows 64bit 2.3.6) Replace the file located in C:\Program Files\OpenVPN\bin.
I’ll post an update from China if this works.