Gost Tutorial

Go Simple Tunnel (Gost) is tunneling software written in the Go language. It connects local nodes to forward nodes, possibly in a chain. Supported protocols include HTTP, HTTPS, HTTP/2, SOCKS4(A), and SOCKS5.

In this tutorial, we present a simple case where traffic from one client is tunneled to one server. The tunneling protocol in this example is HTTP/2. The client in our example runs Windows 10. The server runs Debian 10 and Nginx.

From the client’s point of view, traffic is received locally (L) and tunneled to a forward node (F).

From the server’s point of view, traffic is received locally (L) and output to the Internet.

Of course, the client’s (F) and the server’s (L) are exactly the same node — just seen from the point of view of the client or the point of view of the server.

Gost tunnels traffic from local (L) to forward (F)

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 sfo.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 log in as root and 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 to something you do know:

sudo passwd root

Then switch to the root user:

su -

For the rest of this tutorial, we assume you are logged in as root.

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 relatively 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 Gost, 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

Note: Some cloud providers require you also to open your server’s “Security Group.”

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 sfo.example.com. Replace this by your actual hostname:

server_name sfo.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 project offers free SSL certificates. Before you apply for your SSL certificate, 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 sfo.example.com 1.1.1.1

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 (sfo.example.com in our example) for which you require a certificate

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

1.10. Install Gost

On your workstation, open a browser and visit https://github.com/ginuerzh/gost/releases.

Look for the latest release of Gost. For us right now, it is 2.10.1.

Now, back on your server, download the latest release of Gost for 64-bit Linux like this:

wget https://github.com/ginuerzh/gost/releases/download/v2.10.1/gost-linux-amd64-2.10.1.gz

Extract the archive:

gunzip gost-linux-amd64–2.10.1.gz

Rename the binary to simply gost:

mv gost-linux-amd64-2.10.1 gost

Make gost executable:

chmod +x gost

1.11. Run Gost

We will run Gost in a separate screen session. Screen is a Linux utility that can be used to multiplex a terminal session into several independent processes. It may already be present on your server, so the install command below may do nothing:

apt install screen

Create a new screen session for Gost named gost:

screen -S gost

In the example in this tutorial, Gost on the server received local input (L) in the HTTP/2 protocol. If the client does not send the correct user and password, we resist this probe by redirecting their request to Nginx, which is listening on port 80.

In the next command, replace user by your choice of user id, replace password by your choice of password, and replace sfo.example.com by your actual hostname. This is one long command, even thought it may span several lines in this post. The backslash (\) indicates that a new line character is escaped:

./gost -L "http2://user:password@0.0.0.0:443?\ cert=/etc/letsencrypt/live/sfo.example.com/fullchain.pem\ &key=/etc/letsencrypt/live/sfo.example.com/privkey.pem\ &probe_resist=host:127.0.0.1:80"

You will see a message that indicates that Gost is now listening on port 443:

http2://0.0.0.0:443 on [::]:443

To detach from your screen session, type Ctrl+a followed by d.

1.12. 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 Gost

Open a browser, and visit https://github.com/ginuerzh/gost/releases.

Download the latest release of Gost for Windows. At the time of writing it is named gost-windows-amd64–2.10.1.zip.

In Windows File Explorer, navigate to your Downloads folder, then right-click on the zip file and select Extract All....

2.2. Run Gost

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

Change into the unzipped directory. For example, since we are working with version 2.10.1, the command would be:

cd Downloads\gost-windows-amd64-2.10.1

Now we invoke Gost to forward local input (L) in SOCKS5 (the default) on port 1080 to the forward node (F), which is our server port 443, with the required user id and password. We use Cloudflare (1.1.1.1) for DNS resolution

In the next command, replace user by your choice of user id, replace password by your choice of password, and replace sfo.example.com by your actual hostname. This is one long command, even thought it may span more than one line on your screen:

gost-windows-amd64 -L :1080?dns=1.1.1.1/tcp-chain -F http2://user:password@sfo.example.com:443

If necessary, click Yes to allow access.

Leave your Command Prompt window open.

2.3. Configure Browser

Now configure your browser to use Gost, which is listening locally on 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.4. Test Browser

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

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

2.5. End Browsing Session

Close the Command Prompt window with Gost running in it.

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

3. Troubleshoot Issues

You can find more information on Gost on the Gost wiki at https://docs.ginuerzh.xyz/gost/. Information is available in δΈ­ζ–‡ and English.

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

Firstly, double-check that your client parameters are an exact match for the paremeters on your server.

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

Your Gost 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 in the Gost screen session. SSH back into your server, and reattach the screen session named gost:

screen -r gost

Look for messages. When you are done, detach from your screen session by typing Ctrl+a followed by d.

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

You can ask any unresolved questions you may have about Gost in the Telegram Messenger group Gost.

If you still have a problem, you can create a new issue on https://github.com/ginuerzh/gost/issues.