Obfuscated SSH

Tunneling your browsing through an obfuscated SSH connection is a less common strategy and therefore less likely to be expected by censors.

This article shows you how to create an obfuscated SSH server and client. In the examples, your client is at IP address xx.xx.xx.xx, and the server is at IP address yy.yy.yy.yy. Wherever you see these values in the examples, you will need to change them to match your actual IP addresses. If you do not know your client’s IP address, you can determine it by opening a browser and visiting IPchicken.com.

The server and client in this tutorial both run Debian 10.

1. Server

1.1. Choose Port for Obfuscated SSH

We will provide the obfuscated SSH service on an obscure port number. Choose a random port number between 10,000 and 50,000 by issuing this command:

awk -v min=10000 -v max=50000 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'

The example port number that we will use in the rest of this article:

20727

1.2. Choose Key for Obfuscated SSH

Choose a key. We will use this like a password to hide the availability of obfuscated SSH from casual visitors and port scanners. Generate a key by issuing this command:

< /dev/urandom tr -dc a-z0-9 | head -c8

The example key that we will use in the rest of this article:

qsxopp83

1.3. Install and Configure Firewall

If your server does not already have a firewall, then install and configure a firewall now. We will open both port 22 for regular SSH and port 20727 (in our example) for obfuscated SSH:

apt update && apt upgrade -y
apt install nftables -y
systemctl enable nftables
systemctl start nftables
nft add rule inet filter input ct state related,established counter accept
nft add rule inet filter input iif lo counter accept
nft add rule inet filter input ip protocol icmp counter accept
nft add rule inet filter input ip6 nexthdr icmpv6 counter accept
nft add rule inet filter input tcp dport 22 counter accept
nft add rule inet filter input tcp dport 20727 counter accept
nft add rule inet filter input counter drop

Save these firewall rules:

nft list ruleset > /etc/nftables.conf

For better security, restrict port 22 access to trusted IP addresses only. For example, if you always log in from IP address xx.xx.xx.xx:

vi /etc/nftables.conf

Edit the line for the regular SSH port, and restrict it to accept SSH requests only from your personal IP address:

tcp dport ssh ip saddr xx.xx.xx.xx/32 counter packets 0 bytes 0 accept

Save the file. Restart the firewall:

systemctl restart nftables

1.4. Add Obfuscated OpenSSH Repository

Create a new APT repository file:

vi /etc/apt/sources.list.d/zinglau.list

Insert a line:

deb https://deb.zinglau.com/debian buster main

Save the file. Use the following commands to enable this repository:

apt install gnupg -y
wget https://deb.zinglau.com/pubkey.gpg -O - | apt-key add -
apt update

1.5. Install Obfuscated OpenSSH

Install the patched version of OpenSSH:

apt list --upgradeable
apt install openssh-server -y

1.6. Configure APT Priorities

When multiple repositories are enabled, a package can exist in several of them. To know which one should be installed, APT assigns priorities to packages. The default is 500. Higher priorities will be chosen in preference to lower priorities.

To configure APT priorities, create a file in /etc/apt/preferences.d:

vi /etc/apt/preferences.d/zinglau

Insert the following contents:

Package: *
Pin: release o=zinglau.com
Pin-Priority: 600

Save the file. Verify the change:

apt-cache policy openssh-server

The obfuscated version should be at the top.

1.7. Configure SSH Daemon

Edit the OpenSSH daemon configuration file:

vi /etc/ssh/sshd_config

Uncomment the line:

Port 22

Insert lines (using our example port number and key):

ObfuscatedPort 20727
ObfuscateKeyword qsxopp83

Save the file with your changes.

1.8. Restart SSH

Restart the SSH daemon with new binary and new configuration:

systemctl restart sshd

Make sure the SSH daemon is listening on both the regular and the obfuscated port:

ss -tulpn | grep sshd

The server work is done for now, so exit your SSH session:

exit

2. Client

2.1. Add Obfuscated OpenSSH Repository

Now do the same thing on your client PC as you did on the server. Create a new APT repository file:

sudo apt update && sudo apt upgrade -y
sudo vi /etc/apt/sources.list.d/zinglau.list

Insert a line:

deb https://deb.zinglau.com/debian buster main

Save the file. Use the following commands to enable this repository:

sudo apt install gnupg -y
wget https://deb.zinglau.com/pubkey.gpg -O - | sudo apt-key add -
sudo apt update

2.2. Install Obfuscated OpenSSH

Install the patched version of OpenSSH:

sudo apt list --upgradeable
sudo apt install openssh-client -y

2.3. Configure APT Priorities

As on the server, create an APT configuration file in /etc/apt/preferences.d:

sudo vi /etc/apt/preferences.d/zinglau

Insert the contents:

Package: *
Pin: release o=zinglau.com
Pin-Priority: 600

Save the file. Verify the change:

sudo apt-cache policy openssh-client

The obfuscated version should be at the top.

2.4. Test Obfuscated SSH Connection

Attempt to make an obfuscated SSH connection to your server. In the example below, we assume the obfuscation key is qsxopp83, the obfuscation port is 20727, and the server is located at IP addressyy.yy.yy.yy. You will need to change these parameters to match your actual situation.

ssh -z -Z qsxopp83 -p 20727 root@yy.yy.yy.yy.yy

You should be able to log in as usual. Once you have confirmed this, log out for now:

exit

2.5. Create SSH Configuration File

The parameters may be hard to remember, so we will put them in an SSH client configuration file. Choose a memorable name for your server. We will use as an example obssh1. Edit your SH client configuration file:

vi ~/.ssh/config

Insert lines as shown below. Replace the parameters in the example with those matching your actual situation.

Host obssh1
    HostName yy.yy.yy.yy
    Port 20727
    ObfuscateHandshake yes
    ObfuscateKeyword qsxopp83

Save the file.

2.6. Test SSH

Now that you have save the parameters in a file, you can connect with just:

ssh obssh1 -l root

You should be able to log in again. Once you have confirmed this, log out:

exit

2.7. Start SSH

To use the obfuscated SSH connection for censorship circumvention, we need to invoke the dynamic port forwarding feature of OpenSSH. Therefore connect again, with localhost port 1080 being dynamically port forwarded through the tunnel:

ssh obssh1 -l root -D 1080

Leave the SSH session running while we go on to the next step.

2.8. Configure Firefox

With the SSH connection still running, open Firefox. From the hamburger menu, select Preferences. Scroll down to Network Settings, and click Settings.

Click OK.

2.9. End-to-End Test

In Firefox, visit IP Chicken. You should see the IP address of your remote server, not your local client.

2.10. Finish Up

When you have finished browsing, set your network connection in Firefox back to Use system proxy settings.

In your terminal window, log out of your SSH session:

exit

3. Get Help and Report Issues

The documentation for the obfuscated OpenSSH patch is on zinglau.com.

You can raise issues with the patch on GitHub.