How to hide (obfuscate) SSH traffic using obfs4
Overview
In the previous post, I talked about pt-spec-v1 and obfs4 and explained how obfs4proxy
can be setup and used outside of Tor. You are advised to read it to get the most out of this post.
In this post I’m going to give you a real example of obfs4proxy being used to obfuscate SSH traffic.
For this, I’ll be using two Ubuntu 18.04 Servers. But with a little to no adjustment, any other decent distro should work.
Assumptions
- Both server and client are running Ubuntu 18.04 Server
- Server IP address is 10.0.0.1
- Client can access the obfs4proxy server port (2222 in our example)
Common configurations
These are configurations that needed on both sides:
Installing obfs4proxy
You can either compile it from source or use your distro’s repository:
sudo sh -c 'apt-get update && apt-get install obfs4proxy'
Setting up the user and pt_state
There should be no reason to run obfs4proxy as root. So we create a dedicated user/group for it:
sudo adduser \
--system \
--home "/var/lib/obfs4proxy-ssh/" \
--shell "/usr/sbin/nologin" \
--group \
--gecos "obfs4proxy for ssh" \
obfs4-ssh
Note that in the process, we also made a home directory with the required permissions. Later we’ll use that as the TOR_PT_STATE_LOCATION
value.
Server configurations
These are configurations that needed on the server side:
Configuring SSH daemon
Obviously openssh-server
must be already installed and correctly configured.
Apart from that, I also recommend setting it to bind to localhost only (to not expose the non-obfuscated port to the public).
We can do that by adding an extra line to /etc/ssh/sshd_config :
ListenAddress 127.0.0.1
And then restarting the sshd:
sudo systemctl restart sshd.service
Using a privileged port for obfs4proxy
This step is optional. If you really need to make obfs4proxy to listen to a privileged port (a port lower than 1024), I recommend using an additional NAT rule for it instead.
In this setup, instead of actually binding obfs4proxy server to a privileged port, we redirect incoming traffic to it.
For example assuming obfs4proxy is listening on port 2222
and you want the incoming traffic to be sent to port 550
, this is how it may be done:
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp \
--dport 550 -j REDIRECT --to-port 2222
In Ubuntu you may also take advantage of UFW to make such rule persistent across reboots.
Running obfs4proxy server
Now we are ready to run obfs4proxy in server mode:
sudo -u obfs4-ssh env \
TOR_PT_MANAGED_TRANSPORT_VER="1" \
TOR_PT_STATE_LOCATION="/var/lib/obfs4proxy-ssh/" \
TOR_PT_SERVER_TRANSPORTS="obfs4" \
TOR_PT_SERVER_BINDADDR="obfs4-0.0.0.0:2222" \
TOR_PT_ORPORT="127.0.0.1:22" \
obfs4proxy -enableLogging -logLevel DEBUG
stdout will contain couple of messages like these:
VERSION 1
SMETHOD obfs4 [::]:2222 ARGS:cert=/IHHeIOw7yPM77GZn3cKvLH4pzBB8WscwjwP/HGP5phk0nSXNLZPzZYZNVGmd2dRLlPeUg,iat-mode=0
SMETHODS DONE
obfs4proxy server now stays in the foreground ready to accept new connections on port 2222. Also notice the cert value that is being reported.
Client configuration
These are configurations that needed on the client side:
Installing nmap
openssh-client
, supports SOCKS proxy via ProxyCommand option.
Unfortunately, nc is not good enough for the job as netcat-openbsd
still doesn’t support authentication for SOCKS proxies.
So we’re going to use ncat instead (part of the nmap
package):
sudo sh -c 'apt-get update && apt-get install nmap'
Running obfs4proxy client
Now we are ready to run obfs4proxy in client mode:
sudo -u obfs4-ssh env \
TOR_PT_MANAGED_TRANSPORT_VER="1" \
TOR_PT_STATE_LOCATION="/var/lib/obfs4proxy-ssh/" \
TOR_PT_CLIENT_TRANSPORTS="obfs4" \
obfs4proxy -enableLogging -logLevel DEBUG
stdout will contain couple of messages like these:
VERSION 1
CMETHOD obfs4 socks5 127.0.0.1:39047
CMETHODS DONE
obfs4proxy client now stays in the foreground ready to accept local traffic on it’s SOCKS5 port 39047 (This port changes on each run).
Running SSH client
Now open up another shell and run this command:
ssh \
-o 'ProxyCommand ncat \
--proxy "127.0.0.1:39047" \
--proxy-type "socks5" \
--proxy-auth "cert=/IHHeIOw7yPM77GZn3cKvLH4pzBB8WscwjwP/HGP5phk0nSXNLZPzZYZNVGmd2dRLlPeUg;iat-mode=:0" %h %p' \
-p 2222 [email protected]
Notice that the cert
and iat-mode
arguments are separated with a “;
”. Also the last character (the mode of iat) is set as the password.
And voilà! You just made your SSH traffic obfuscated using obfs4.
Good for you!
Ctrl-C
twice.
And finally, I would love to know your thoughts on this article. Please leave a comment below and share them with me!