基于公网22端口实现千级客户端反向SSH隧道的按需选择问询
Got it, let's break down how to set this up properly. You've got a server locked down behind a firewall (only port 22 open) with both public and private IPs, and you need 1000 clients to establish reverse SSH tunnels—each tied to a unique ID that maps to a server port—plus the ability to access specific clients from your laptop. Here's a step-by-step solution that's scalable and secure:
The key here is leveraging reverse SSH tunnels: clients initiate outgoing connections to your server (since the firewall only allows inbound port 22 traffic), and each client forwards a local port (e.g., their SSH port 22) to a unique port on your server matching their ID. When you connect to the server from your laptop, you can target those unique ports to access the corresponding client.
First, tweak your server's SSH settings to support reverse tunnels properly:
Update SSHD Config
Edit /etc/ssh/sshd_config and ensure these lines are set (uncomment if they're commented out):
AllowTcpForwarding yes GatewayPorts clientspecified
AllowTcpForwarding yesenables TCP port forwarding (required for tunnels)GatewayPorts clientspecifiedlets clients bind their forwarded ports to the server's public/private IP (not just localhost), so your laptop can access them later.
Restart the SSH service to apply changes:
sudo systemctl restart sshd
Create a Dedicated Tunnel User
For security, don't use root or your personal account for tunnel connections. Create a dedicated user:
sudo useradd -m ssh-tunnel-user sudo passwd ssh-tunnel-user # Skip this if you'll use SSH keys (recommended)
Then, set up SSH key authentication for clients: have each client generate a key pair (ssh-keygen -t ed25519) and send their public key to you. Add all client public keys to ~ssh-tunnel-user/.ssh/authorized_keys on the server.
To lock down this user further (prevent them from running commands on the server), prepend this to each public key in authorized_keys:
command="echo 'This account is only for tunnel forwarding'",no-agent-forwarding,no-X11-forwarding,no-pty
Each client needs to establish a persistent reverse tunnel to your server, mapping their ID to a server port.
Basic Tunnel Command
Replace <CLIENT_ID> with the unique ID (e.g., 1001, 1002... up to 1999 to avoid conflicting with system ports) and <SERVER_PUBLIC_IP> with your server's public IP:
ssh -N -R <CLIENT_ID>:localhost:22 ssh-tunnel-user@<SERVER_PUBLIC_IP> -p 22
-N: Don't execute remote commands (only forward ports)-R <SERVER_PORT>:localhost:<CLIENT_LOCAL_PORT>: Forwards the client's local port 22 (SSH) to the server's port<CLIENT_ID>
Keep Tunnels Persistent
To ensure tunnels stay up through reboots or network blips, use autossh (install it first with sudo apt install autossh or similar):
autossh -M 0 -N -R <CLIENT_ID>:localhost:22 ssh-tunnel-user@<SERVER_PUBLIC_IP> -p 22
-M 0 disables autossh's separate monitoring port and relies on SSH's built-in keepalive.
For even more reliability, wrap this in a systemd service. Create /etc/systemd/system/reverse-ssh-tunnel.service on the client:
[Unit] Description=Persistent Reverse SSH Tunnel to Central Server After=network.target [Service] User=client-user # Replace with the client's local user ExecStart=/usr/bin/autossh -M 0 -N -R <CLIENT_ID>:localhost:22 ssh-tunnel-user@<SERVER_PUBLIC_IP> -p 22 Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
Enable and start the service:
sudo systemctl enable --now reverse-ssh-tunnel.service
Once tunnels are active, you can access any client by targeting their ID port on the server.
Direct Access via Server
First, SSH into your server:
ssh your-user@<SERVER_PUBLIC_IP> -p 22
Then, connect to the client using their ID port:
ssh client-local-user@localhost -p <CLIENT_ID>
Forward Port to Your Laptop (Alternative)
If you want to access the client directly from your laptop without first logging into the server, use a local port forward:
ssh -L <YOUR_LOCAL_PORT>:localhost:<CLIENT_ID> your-user@<SERVER_PUBLIC_IP> -p 22
Then, on your laptop, connect to the client via your local port:
ssh client-local-user@localhost -p <YOUR_LOCAL_PORT>
- Port Range: Use a dedicated port range for client IDs (e.g., 10000–10999) to avoid conflicts with system services.
- Monitor Tunnels: On the server, run
ss -tulpn | grep ssh-tunnel-userto list all active tunnels and verify which clients are connected. - Rate Limiting: To prevent abuse, add SSH rate limiting via
iptablesorufwon the server. - Log Monitoring: Check
/var/log/auth.logon the server to track tunnel connections and detect anomalies.
内容的提问来源于stack exchange,提问作者Curious Mind

