The purpose of this blog post is to provide information on how and when to use SSH Tunneling and finally a few notes on how to audit and prevent SSH tunneling.
I am often testing solutions in a hybrid lab. Having both some public cloud services and my on-prem lab environment, definetely provides the best of both worlds for me.
I find DigitalOcean who provides cloud hosted VMs (Droplets) down to $5/mo to be a compelling service offering. Additionally Microsoft Azure provides a great cloud service for a variety of business use cases as well.
When working in my Lab environment, I often need access from outside towards internal services, without exposing multiple internal services via the Firewall. Therefore one of the methods I am using, is to leverage Linux SSH Server as a Proxy / Bastion host, allowing me to access my environment which is behind a Firewall, also without the overhead of managing complex firewall rules.
SSH (Secure Shell) is a protocol that provides a secure channel over an unsecured network in a client-server based architecture. Both Mac OS, Linux and most recent Windows versions has native support for SSH.
SSH basically enables secure remote login, secure file transfers, secure remote command execution and port forwarding/tunneling.
Obs. DigitalOcean has a great guide on how to secure your SSH Server with 2-factor or MFA login.
How to setup Multi-Factor Authentication for SSH on Ubuntu
In the next sections I will provide an overview and examples for 3 different SSH Tunneling options:
- Local Port Forwarding
- Remote/Reverse Port Forwarding
- Dynamic Port Forwarding (SOCKS)
Why SSH Tunneling?
I need to access a service or device behind a Firewall, which not directly available.
Reverse SSH Port Forwarding / Tunneling
Below is an example of a high-level diagram of the Reverse / Remote forwarding scenario.
This scenario does not require us to modify inbound firewall rules. Our device on the internal network will initiate a outbound SSH Connection and a Remote SSH Tunnel to our public hosted SSH Server, which is set up to listen on port 443 in this case. The internal device (RDS Server in this example) will map a source port 3388 to our SSH Server and a destination host and port to be localhost:3389. Then our Client will bind a local address localhost:3390 and connect to the remote address localhost:3388 which will be tunnelled to our SSH Server on 443.
This allows us to RDP connect to our internal RDS server from our client without it being exposed to the internet – Our Client will connect to RDP address localhost:3390 which will tunnel the RDP traffic through our SSH Server to the internal RDS server.
Typical use cases for Remote SSH Port Forwarding:
- Allowing internal services to be reached from the outside without configuring Firewall rules.
Local SSH Port Forwarding / Tunneling
Below is an example of a high-level diagram of the Local SSH Tunneling scenario.
This scenario requires the Firewall to allow inbound traffic to pass on to a SSH Server. Then we can tunnel traffic through the SSH Tunnel from our Client to the SSH Server, and the SSH Server will proxy traffic to internal reachable servers. Our Client establishes a SSH Session to our SSH Server on port 889, while defined source and destination ports are established and tunnelled. Allowing the client to connect to https://localhost:4443 which will forward the traffic through our SSH Server to the Server IP on port 443 as configured. RDP could easily also be a tunneled application layered protocol in this scenario.
Typical use cases for local port forwarding:
- Tunneling sessions and file transfers through jump servers.
- Connecting to a service on an internal network from the Internet.
- Connecting to a remote file share over the Internet.
Dynamic SSH Port Forwarding / Tunneling (SOCKS)
Below is an example of a high-level diagram of the Dynamic SSH Tunneling scenario.
In this scenario all HTTP/HTTPS traffic from your browser is being SOCKS proxied through a SSH host.
A local listener is being created on localhost with defined local tcp port, then the browser is setup to connect to this as a SOCKS Proxy. This will tunnell the HTTP/HTTPS traffic to the internal network.
Typical use cases for Dynamic port forwarding:
- Connecting to a HTTP/HTTPS service on an internal network from the Internet.
How to set up Reverse SSH Tunneling
SSH Server Could be an Ubuntu Server – typically a candidate for a public cloud.
In this example I am running Ubuntu Server 16.04 with OpenSSH-Server installed.
Modified SSH Port to 443 from default port 22 in /etc/ssh/sshd_config
Device the device that you are accessing and provides local og remote services via a SSH Client – typically is Windows or Linux based. (Below screenshot is from Kitty Portable on Windows)
ssh -R 3388:localhost:3389 -p SSH-PORT user@sshserver
Client Device Your desktop client – could be a Mac OS, Linux or Windows based with a SSH Client.
ssh -L 3390:localhost:3388 -p SSH-PORT user@sshserver
How to set up Local SSH Tunneling
Firewall Allowed inbound SSH traffic to my SSH Server.
SSH Server Running Ubuntu 16.04 with OpenSSH-Server.
Modified SSH Port to 889 from default port 22 in /etc/ssh/sshd_config
Client With Secure Pipes and Local Forwards:
ssh -L 4443:10.0.0.4:443 -p SSH-PORT user@sshserver
Connect to https://localhost:4443
How to set up a SSH as a SOCKS Proxy for tunneling?
ssh -D 8888 user@ssh-server
Set your web browser to use localhost on port 8888 as SOCKS Proxy, and all your HTTP/HTTPS requests will go through the SSH tunnel.
In FireFox go to Options and Network Proxy settings:
On Mac OS X/Linux I prefer to use Bash, Secure Pipes or iTerm2:
On Windows I prefer Kitty or Putty:
On the SSH server side I prefer Ubuntu / Linux.
How do you prevent SSH Tunneling?
For many enterprises this is a very challenging area, but I would recommend to audit and inspect traffic using a Firewall IDS/IPS signature based solution.
Another method could be to introduce a solution like CryptoAuditor.
CryptoAuditor can be used to monitor, control and audit SSH sessions.
It can decrypt SSH sessions at firewall based on policy, using access to host keys. It can also control file transfers, record sessions for forensics and internal audit, and pass encrypted session contents to data loss prevention, analytics, and intrusion detection systems (IDS).