Trojan-GFW on Debian and Windows Tutorial

Trojan aims to help you bypass the Great Firewall (GFW) of China. It features multiple protocols over Transport Layer Security (TLS) to avoid both active and passive detection and Internet Service Provider (ISP) Quality-of-Service (QoS) limitations.

In this tutorial, you’ll learn how to install Trojan-GFW on a Debian server and a Windows client.

Debian is a long-established and highly respected Linux distribution. It is popular with server administrators. New releases are issued every few years, and at the time of writing the latest release is Debian 10.

Windows 10 continues to be Microsoft’s most popular desktop operating system, running on around half of all desktop computers.

Trojan clients are also available for Linux and MacOS. Igniter, a Trojan client for Android, is under construction.

The Great Wall of China

1. Set Up Server

Before you begin, you’ll need to acquire a domain name and a server. This tutorial assumes you start with a newly created virtual private server (VPS). The domain name used in the examples is example.com with a sample hostname of westcoast.example.com.

1.1. SSH as Root

Log in to your server using a tool such as PuTTY, XSHELL, or PowerShell (if you use Windows on your workstation), or the SSH command in a terminal emulator (if you use Linux or Mac on your workstation).

If your VPS provider sent you a root password by email, then change the root password to something only you know:

passwd root

If you do not know the root password, then SSH in as a non-root user, and set the root password:

sudo passwd root

If you logged in as a non-root user, then switch to the root user now:

su -

1.2. Update Your Server

Get your entire system up to date by issuing these commands as root:

apt update

apt dist-upgrade

apt autoremove

1.3. Implement BBR Congestion Control

Bottleneck Bandwidth and Roundtrip propagation time (BBR) is a congestion control algorithm for Transmission Control Protocol (TCP). It aims to achieve higher bandwidths and lower latencies.

Edit your Linux system control parameters file, /etc/sysctl.conf, to specify the BBR congestion control algorithm. You can use any command-line editor for this. For example, if your favorite editor is the vi editor:

vi /etc/sysctl.conf

Alternatively, if your favorite editor is the nano editor:

nano /etc/sysctl.conf

Add two lines at the end of the current file:

net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr

Write the file to disk, and quit the editor. Activate this change by issuing the command:

sysctl -p

1.4. Install Firewall

Install the nftables firewall package:

apt install nftables

Specify that you want to start nftables after every reboot, and start it now:

systemctl enable nftables

systemctl start nftables

1.5. Configure Firewall

List the current nftables rules:

nft list ruleset

You should see a table for inet filter, plus a chain within it for each of input, forward, and output.

table inet filter {
	chain input {
		type filter hook input priority 0; policy accept;
	}

	chain forward {
		type filter hook forward priority 0; policy accept;
	}

	chain output {
		type filter hook output priority 0; policy accept;
	}
}

If this table and its chains do not exist, then create them now:

nft add table inet filter

nft add chain inet filter input { type filter hook input priority 0 \; policy accept\; }

nft add chain inet filter forward { type filter hook forward priority 0 \; policy accept\; }

nft add chain inet filter output { type filter hook output priority 0 \; policy accept\; }

On the other hand, if these rules do already exist, then simply carry on as follows.

Add a rule to accept all related and established traffic:

nft add rule inet filter input ct state related,established counter accept

Add a rule to accept all loopback interface traffic:

nft add rule inet filter input iif lo counter accept

For the next rule, you need to know your workstation’s Internet Protocol (IP) address. If you do not know your IP address, you can find it out by opening a browser and visiting https://www.ipip.net or https://whatismyipaddress.com.

Let’s assume your workstation’s IP address is 11.22.33.44. If that is realtively fixed, whitelist your IP address for access to port 22, which is the port you use for SSH:

nft add rule inet filter input tcp dport 22 ip saddr 11.22.33.44/32 counter accept

Alternatively, you can open port 22 for a range of IP addresses. For example, if your ISP allocates addresses in the range 11.22.0.0 through 11.22.255.255, you could open port 22 for the entire range like this:

nft add rule inet filter input tcp dport 22 ip saddr 11.22.0.0/16 counter accept

Do not open port 22 for the entire world.

We will use ports 80 and 443 for Trojan, so open them too:

nft add rule inet filter input tcp dport {http, https} counter accept

Check that the rules now look as expected:

nft list ruleset

To persist these changes across reboots, save your rules to /etc/nftables.conf:

nft list ruleset > /etc/nftables.conf

Now we are going to change the default policy to drop all other input.

Edit the nftables configuration file in your preferred editor. For example, if your preferred editor is the vi editor:

vi /etc/nftables.conf

Alternatively, if your preferred editor is the nano editor:

nano /etc/nftables.conf

Change the policy from accept to drop:

chain input { 
        type filter hook input priority 0; policy drop; 

Restart nftables with your new configuration:

systemctl restart nftables

1.6. Install Nginx

Install Nginx:

apt install nginx

1.7. Configure Nginx

Edit the Nginx default site configuration at /etc/nginx/sites-available/default. If you prefer the vi editor, then issue the command:

vi /etc/nginx/sites-available/default

Alternatively, if you prefer the nano editor, then issue the command:

nano /etc/nginx/sites-available/default

Set the server_name and set a custom 404 page (this is the page served if the user requests a page that is not found). In the example shown below, we assume your hostname is westcoast.example.com. Replace this by your actual hostname:

server_name westcoast.example.com;
error_page 404 /index.html;

Write the file to disk, and quit the editor.

To make this change effective, reload your Nginx configuration:

systemctl reload nginx

1.8. Add Website Content

For extra realism, we will add some sample content to the web server.

Download the archive file for some sample content from GitHub:

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

Unpack the archive:

apt install unzip

unzip master.zip

Copy the downloaded sample blog into your website directory:

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

1.9. Obtain Let’s Encrypt SSL Certificate

The Let’s Encrypt offers free SSL certificates. These allow your website to be served as HTTPS as well as, or instead of, HTTP.

Before you do this step, you need to check that your hostname DNS records have propagated, so that the hostname points to your server IP address:

apt install dnsutils

nslookup westcoast.example.com 8.8.8.8

Assuming your server IP address is returned, you can now proceed. Install the required packages:

apt install certbot python-certbot-nginx

Obtain a Let’s Encrypt SSL certificate and key:

certbot certonly --nginx

Respond to the certbot prompts:

  1. Enter your email address
  2. Enter a for agree
  3. Enter y or n to share your email address
  4. Select the appropriate number of your hostname that you require a certificate for

You should see a success message with wording such as Congratulations! Your certificate and chain have been saved.

Let’s Encrypt SSL certificates are valid for 90 days. Set everything up for automatic renewal every 90 days:

certbot renew --dry-run

Make your Let’s Encrypt certificates and keys readable and your Let’s Encrypt directories executable:

chmod -R +rx /etc/letsencrypt

The web server is now set up.

1.10. Install Trojan

Install Trojan from your Linux distribution’s repositories:

apt install trojan

1.11. Configure Trojan

Configure Trojan by editing the configuration file /etc/trojan/config.json. If you prefer the vi editor, then issue the command:

vi /etc/trojan/config.json

Alternatively, if you prefer the nano editor, then issue the command:

nano /etc/trojan/config.json

Make these changes to the default configuration. Replace westcoast.example.com by your actual hostname in the examples below:

  1. Insert your own value for password1 and remove the trailing comma
  2. Delete the line for password2
  3. Your certificate is in /etc/letsencrypt/live/westcoast.example.com/fullchain.pem, so specify that on the cert line
  4. Your key is in /etc/letsencrypt/live/westcoast.example.com/privkey.pem, so specify that on the key line

Write the file to disk, and quit the editor.

1.12. Run Trojan

After writing the file to disk and quitting the editor, make Trojan start after every reboot, and start it now:

systemctl enable trojan

systemctl start trojan

1.13. Exit SSH Session

Your work on the server is done for now. Exit your SSH session by typing the command:

exit

2. Set Up Client

Now work on the Windows PC that will be your client.

2.1. Download Trojan

Open a browser, and visit https://github.com/trojan-gfw/trojan/releases.

Download the latest release of Trojan for Windows. At the time of writing it is named trojan-1.14.1-win.zip.

Right-click on the zip file and select Extract All... to unzip the zip file.

2.2. Configure Trojan

In the folder Downloads\trojan-1.14.1-win\trojan edit the file config.json. You can use Notepad, Notepad++, or any other text editor.

These values must match your server.

When you have finished editing, save the file, and close the editor.

2.3. Run Trojan

Open a Command Prompt window by doing Windows+r, typing cmd, and clicking OK.

Change into the unzipped directory. At the time of writing, and with our example folder names, that command is:

cd Downloads\trojan-1.14.1-win\trojan

Launch Trojan by issuing the command:

trojan

You will see a message, [WARN] trojan service (client) started at 127.0.0.1:1080. This means Trojan is listening on localhost port 1080.

Leave the Command Prompt window open.

2.4. Configure Browser

Now configure your browser to use Trojan, which is listening on localhost port 1080.

In Firefox, from the hamburger menu select Options. Under Network Settings, select Settings. Choose Manual proxy configuration, SOCKS Host 127.0.0.1, Port 1080, SOCKS v5. Choose Proxy DNS when using SOCKS v5. Click OK.

Firefox configured to use a proxy server

In Chrome, you can configure your browser to use a proxy server by installing and configuring the extension SwitchyOmega by FelisCatus from the Chrome Web Store at https://chrome.google.com/webstore/category/extensions. On the SwitchyOmega dashboard, click the PROFILE marked proxy. Specify protocol SOCKS v5, Server 127.0.0.1, and Port 1080. Click Apply changes. Find the SwitchyOmega logo at the top right of Chrome. Initially it is black for System Proxy. Select proxy to activate it. The SwitchyOmega logo at the top right of Chrome turns pale blue.

Chrome configured to use a proxy server

2.5. Test Browser

Test your browser by visiting https://ipchicken.com.

You should see your server IP address, not your client IP address.

2.6. End Browsing Session

Close the Command Prompt window with Trojan running in it.

Set your browser back to its direct, non-proxied settings.

3. Troubleshoot Issues

You can find more information on Trojan on the Trojan wiki at https://github.com/trojan-gfw/trojan/wiki.

If you have any problems, here are some steps you can take to troubleshoot.

Firstly, double-check that your client configuration file is an exact match for the settings on your server.

On the Windows client, if you are using Chrome, try switching to Firefox, and vica versa.

Your Trojan Command Prompt window on your PC may show some error messages. Technical problems in Windows may also result in messages in the Windows Event Viewer (type event viewer in the Windows 10 search box, and select the Event Viewer app).

On the Debian server, you can look for messages with these commands:

systemctl status trojan

journalctl -xe

journalctl -u trojan

For serious system errors, you can also look for messages in your server’s /var/log directory.

You can ask questions in the Telegram Messenger group Trojan-GFW.

If you still have a problem, you can create a new issue on https://github.com/trojan-gfw/trojan/issues.