There are legitimate scenarios where you might want to allow SSH connections solely for port forwarding while preventing shell access or file transfers. This is particularly useful for:
- Providing secure database access to external developers
- Creating VPN-like tunnels without full server access
- Implementing secure service proxies
The key to achieving this lies in the sshd_config
file. Here's the essential configuration:
# /etc/ssh/sshd_config
Match User restricted_tunnel_user
ForceCommand /bin/false
PermitTTY no
X11Forwarding no
AllowTcpForwarding yes
PermitOpen any
GatewayPorts no
First, create a user specifically for tunneling:
sudo adduser --system --shell /bin/false restricted_tunnel_user
For security, always use key-based auth for tunnel-only users:
sudo -u restricted_tunnel_user mkdir -p ~/.ssh
sudo -u restricted_tunnel_user chmod 700 ~/.ssh
echo "ssh-rsa AAAAB3NzaC... user@client" | sudo tee -a /home/restricted_tunnel_user/.ssh/authorized_keys
sudo chmod 600 /home/restricted_tunnel_user/.ssh/authorized_keys
After reloading SSH (sudo systemctl reload sshd
), test with:
ssh -N -L 3306:localhost:3306 restricted_tunnel_user@yourserver.com
Attempting to get a shell should fail:
ssh restricted_tunnel_user@yourserver.com
# Connection should immediately close
For more granular control, you can restrict which ports can be forwarded:
Match User db_tunnel_user
ForceCommand /bin/false
PermitOpen localhost:3306
AllowTcpForwarding yes
- Always use strong SSH keys (ed25519 or 4096-bit RSA)
- Consider rate limiting with fail2ban
- Monitor tunnel connections in your auth logs
You can also enforce restrictions directly in the authorized_keys file:
command="/bin/false",no-pty,no-X11-forwarding,permitopen="localhost:3306" ssh-rsa AAAAB3NzaC...
When managing Linux servers, there are scenarios where you want users to establish SSH tunnels for port forwarding but prevent them from gaining shell access or interacting with the filesystem. This is particularly useful for:
- Database administrators needing secure tunnels
- Remote developers accessing internal services
- Secure proxy configurations
- Third-party service integrations
The key to achieving this lies in the sshd_config
file and proper user permission management. Here's the core configuration approach:
# /etc/ssh/sshd_config
Match User tunneluser
ForceCommand /bin/false
PermitTTY no
X11Forwarding no
AllowTcpForwarding yes
PermitTunnel yes
GatewayPorts no
Let's walk through a complete setup example:
# Create a dedicated user
sudo useradd -m -s /bin/false tunneluser
sudo passwd tunneluser
# Configure SSH (add to the END of sshd_config)
echo 'Match User tunneluser
ForceCommand /bin/false
PermitTTY no
AllowTcpForwarding yes
PermitTunnel yes
GatewayPorts no' | sudo tee -a /etc/ssh/sshd_config > /dev/null
# Restart SSH service
sudo systemctl restart sshd
Test the setup with these commands:
# This should fail (no shell access)
ssh tunneluser@yourserver.com
# This should work (port forwarding only)
ssh -N -L 3306:localhost:3306 tunneluser@yourserver.com
For more granular control, consider these additional parameters:
Match User tunneluser
AllowAgentForwarding no
AllowStreamLocalForwarding no
AuthenticationMethods publickey
PermitOpen "localhost:3306" # Restrict to specific ports
If you encounter problems:
- Check
/var/log/auth.log
for SSH connection attempts - Verify permissions on user's
~/.ssh
directory (should be 700) - Ensure the user's shell is properly set to
/bin/false
or/usr/sbin/nologin
When implementing this setup:
- Always use SSH key authentication instead of passwords
- Regularly rotate keys for tunnel-only users
- Consider using
PermitOpen
to restrict which ports can be forwarded - Monitor active tunnels with
ss -tnlp | grep sshd
For more dynamic control, you can use the command=
option in authorized_keys:
# In ~tunneluser/.ssh/authorized_keys
command="/bin/false",no-pty,no-X11-forwarding,permitopen="localhost:3306" ssh-rsa AAAAB3Nz... user@client