How to Disable SSH Shell Access While Maintaining Web Tunneling: Secure SOCKS Proxy Configuration


3 views

When implementing SSH tunneling as a lightweight VPN solution, we often need to restrict interactive shell access while maintaining port forwarding capabilities. The scenario typically involves:

start putty -D 9999 mysshserver.com -N

The -N flag prevents shell session startup client-side, but server-side configuration provides more robust control.

Ubuntu Server with OpenSSH offers several methods to disable shell access:

  1. ForceCommand in sshd_config:
    Match User tunneluser
        ForceCommand /bin/false
        PermitTTY no
  2. Custom shell alternative:
    sudo usermod -s /usr/sbin/nologin tunneluser
  3. Command restriction:
    command="echo 'Interactive shell disabled'" ssh-rsa AAAAB3NzaC1yc2E...

    (in authorized_keys)

Beyond basic hardening (non-root access, key auth, port change), consider:

# /etc/ssh/sshd_config
AllowUsers tunneluser
AllowTcpForwarding yes
PermitTunnel yes
X11Forwarding no
GatewayPorts no
ClientAliveInterval 300
MaxAuthTries 2
PasswordAuthentication no

Complete setup for a web-only tunneling user:

# Create restricted user
sudo adduser --shell /usr/sbin/nologin --disabled-password tunneluser

# Configure SSH
echo 'Match User tunneluser
    AllowTcpForwarding yes
    PermitTTY no
    ForceCommand /bin/false' | sudo tee -a /etc/ssh/sshd_config

# Restart SSH
sudo service ssh restart

Client connection then works normally for tunneling but blocks shell access attempts:

ssh -N -D 9999 tunneluser@yourserver.com

If connections fail after configuration:

  • Verify PermitTunnel and AllowTcpForwarding settings
  • Check SELinux/AppArmor restrictions on SSH
  • Test with -v flag for connection debugging

When implementing SSH tunneling as a lightweight VPN alternative for web traffic, security-conscious administrators often want to restrict interactive shell access while maintaining the tunneling functionality. The key challenge is maintaining SOCKS proxy capabilities (via -D flag) while preventing unauthorized command execution.

While the client-side -N flag prevents shell initialization, these server-side approaches provide more robust control:

# Method 1: ForceCommand in sshd_config
Match User tunneluser
    ForceCommand echo "This account permits web tunneling only"
    PermitTTY no

# Method 2: Custom shell wrapper
#!/bin/sh
if [ -z "$SSH_ORIGINAL_COMMAND" ]; then
    echo "Tunnel active - interactive shell disabled"
else
    echo "Command execution blocked"
fi

For production deployments, combine these OpenSSH server configurations (/etc/ssh/sshd_config):

Port 2222  # Change from default
PermitRootLogin no
PasswordAuthentication no
AllowUsers tunneluser
PermitTunnel yes
X11Forwarding no
AllowTcpForwarding yes
GatewayPorts no

The optimal Putty configuration for Windows clients:

putty.exe -ssh -N -D 127.0.0.1:9999 tunneluser@yourserver.com -P 2222 -i private_key.ppk

For Linux/macOS clients:

ssh -fN -D 9999 -p 2222 tunneluser@yourserver.com -i ~/.ssh/tunnel_key

Confirm restricted access works by attempting shell access:

$ ssh -p 2222 tunneluser@yourserver.com
Tunnel active - interactive shell disabled
Connection closed.

Check active tunnels with:

ss -tnp | grep sshd
lsof -i -n | egrep '\<sshd\>'

For maximum isolation, create a restricted environment:

# In /etc/ssh/sshd_config
Match User tunneluser
    ChrootDirectory /var/lib/ssh_tunnel
    ForceCommand internal-sftp
    PermitTunnel yes
    AllowTCPForwarding yes