When you run ssh 12.34.56.78 -L 8888:localhost:8000
, you're telling SSH to:
- Forward local port 8888
- To
localhost:8000
on the remote server
However, in your SSH config file, you specified:
LocalForward 8888 12.34.56.78:8000
This is actually trying to forward to port 8000 on your local machine (since 12.34.56.78 resolves to your local network when the tunnel is established).
Here's the proper way to configure it in your ~/.ssh/config
file:
Host myhost
User myuser
Hostname 12.34.56.78
IdentityFile ~/.ssh/id_rsa
LocalForward 8888 localhost:8000
The key difference is that the destination address (localhost:8000
) is relative to the remote server, not your local machine.
After updating your config, test it with:
ssh -N myhost
The -N
flag tells SSH not to execute any remote commands, just establish the connection and port forwarding.
You can add these parameters for more control:
Host myhost
# ... existing config ...
LocalForward 8888 localhost:8000
ExitOnForwardFailure yes
ServerAliveInterval 60
ServerAliveCountMax 3
ExitOnForwardFailure
will make SSH exit if the port forwarding fails, rather than silently continuing.
If you still see "Connection refused" errors:
- Verify the service is running on port 8000 on the remote server
- Check firewall rules on both local and remote machines
- Try connecting directly to the remote service first
To test the remote service:
ssh myuser@12.34.56.78 "curl -I http://localhost:8000"
Using command-line port forwarding like ssh 12.34.56.78 -L 8888:localhost:8000
works perfectly, but becomes tedious when you need to establish these connections frequently. The logical solution is to move this configuration to your SSH config file, but it's not as straightforward as it seems.
The key issue in your configuration is the destination address in the LocalForward
directive:
LocalForward 8888 12.34.56.78:8000 # This is incorrect
When you specify the server's public IP as the destination, SSH tries to connect to that address from the server itself, which won't work for services bound to localhost.
Here's the proper way to set up local forwarding in your SSH config:
Host myappserver
HostName 12.34.56.78
User myuser
IdentityFile ~/.ssh/id_rsa
LocalForward 8888 localhost:8000 # Note the change here
ServerAliveInterval 60
ExitOnForwardFailure yes
- localhost vs server IP: The destination must be relative to the remote server's perspective
- ExitOnForwardFailure: Ensures the connection fails if forwarding can't be established
- ServerAliveInterval: Maintains the connection for long-running forwards
For more complex scenarios, consider these patterns:
# Multiple forwards in one host
Host devserver
LocalForward 8888 localhost:8000
LocalForward 8889 localhost:8001
# Dynamic forwarding (SOCKS proxy)
Host remotesite
DynamicForward 1080
# Gateway ports (allow remote connections to forwarded ports)
Host exposed
GatewayPorts yes
LocalForward *:8888 localhost:8000
If you encounter connection problems:
- Run SSH in verbose mode:
ssh -vvv myhost
- Check if the remote service is running:
ssh myhost "netstat -tuln | grep 8000"
- Verify local port availability:
netstat -tuln | grep 8888
- Test with raw SSH command first before moving to config
For critical forwards that must stay alive:
# Install autossh first
autossh -M 0 -f -N -L 8888:localhost:8000 myuser@12.34.56.78
# Or in your config:
Host criticalapp
HostName 12.34.56.78
User myuser
LocalForward 8888 localhost:8000
RemoteCommand "/usr/bin/autossh -M 0 -N -L 8888:localhost:8000 %h"
Remember that port forwarding can expose services in unexpected ways:
- Avoid using
GatewayPorts
unless absolutely necessary - Consider using
AllowTcpForwarding
in your server'ssshd_config
- For sensitive services, add
PermitOpen
restrictions