SSH Reverse Proxy Solutions for Restricted Corporate Firewall Environments


3 views

When working within corporate data center environments, we often face strict firewall policies that only allow inbound SSH connections on port 22. This creates significant challenges when needing to provide external access to multiple virtual machines running on the host server.

The key constraints in this scenario are:

  • Only port 22 is open for inbound SSH
  • No additional ports can be opened
  • Clients expect simple connection methods (Putty/FileZilla)
  • Solution must be transparent to end users

Standard approaches like port forwarding or VPNs won't work here because:

# Traditional port forwarding example (won't work in this case)
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.100:22

The requirement to maintain simplicity for end users while working within these constraints leads us to explore SSH reverse proxy solutions.

We can leverage SSH's built-in port forwarding capabilities to create a transparent proxy. Here's a basic implementation:

# On the corporate server (acting as jump host)
ssh -N -D 1080 user@internal-vm1
ssh -N -D 1081 user@internal-vm2

However, this requires clients to use SOCKS proxies, which may be too complex for some users.

A more elegant solution uses SSH's ProxyCommand to create transparent routing:

# Client-side ~/.ssh/config
Host vm1-access
  HostName corporate-server.example.com
  User corporate-user
  ProxyCommand ssh -W %h:%p corporate-user@corporate-server.example.com

This approach still requires client-side configuration, which may not be ideal for non-technical users.

The most robust approach combines several techniques:

# On the corporate server
socat TCP-LISTEN:22,fork,reuseaddr EXEC:"ssh -W internal-vm1:22 user@localhost"

# For multiple VMs, use different usernames:
socat TCP-LISTEN:22,fork,reuseaddr EXEC:"ssh -W internal-vm2:22 vm2-user@localhost"

This solution provides:

  • Single port access (22) for all VMs
  • Transparent to end users (standard SSH clients work)
  • No client-side configuration required
  • Secure authentication maintained

Here's a complete implementation using a wrapper script:

#!/bin/bash

# /usr/local/bin/ssh-proxy-wrapper
case $USER in
  vm1-user) TARGET="internal-vm1";;
  vm2-user) TARGET="internal-vm2";;
  *) echo "Access denied"; exit 1;;
esac

exec /usr/bin/ssh -W $TARGET:22 $USER@localhost

Configure /etc/ssh/sshd_config:

Match User vm1-user,vm2-user
  ForceCommand /usr/local/bin/ssh-proxy-wrapper
  AllowTcpForwarding no
  PermitTTY no
  X11Forwarding no

When implementing this solution:

  • Use SSH keys exclusively (disable password auth)
  • Implement rate limiting
  • Monitor connection attempts
  • Consider fail2ban for brute force protection

Many developers face this frustrating scenario: You're working on a server in a tightly controlled corporate data center where only SSH port 22 is accessible through the firewall. You need to provide external access to multiple virtual machines running on that server, but:

  • No additional ports can be opened
  • You can't modify firewall rules
  • End users need simple connection methods (like basic Putty)

Standard approaches like port forwarding or VPNs won't work here because:


# This would require opening new ports - impossible in our scenario
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 10.0.0.2:22

The answer lies in using SSH's built-in capabilities to create a reverse proxy tunnel. Here's how it works:


# On your internal server (running on port 22)
ssh -R 2222:localhost:22 external-user@public-proxy.example.com -N

This creates a secure tunnel that forwards connections from the public proxy's port 2222 back to your internal server.

Here's a complete setup example using sshuttle as a more sophisticated solution:


# Install sshuttle on your jump host
sudo apt-get install sshuttle

# Create the reverse proxy tunnel
sshuttle -r user@corporate-server:22 10.0.0.0/24

To make it easy for end users, create simple connection scripts:


:: Windows batch file for Putty users
@echo off
start putty.exe -ssh user@public-proxy.example.com -P 2222 -pw theirpassword

Always implement these security measures:

  • Use SSH key authentication instead of passwords
  • Implement connection rate limiting
  • Set up proper user isolation

For more advanced setups, consider this approach:


# In ~/.ssh/config
Host internal-vm1
  HostName public-proxy.example.com
  Port 22
  ProxyJump corporate-gateway
  User vm1-user