Step-by-step instructions for configuring a Linux VM as a jump server: - SSH server config (AllowTcpForwarding, GatewayPorts, keepalive) - Tunnel user creation (password or key auth, no shell) - Zoraxy/Nginx reverse proxy for TLS:443 - Testing and troubleshooting
6.8 KiB
Jump Server Setup for Wallarm Remote Assistance
This guide explains how to configure a Linux VM as a jump server so engineers
can securely access customer Wallarm nodes through the wallarm --tunnel feature.
Architecture
Customer VM (VM-A) Jump Server (VM-B) Engineer
┌──────────────────┐ TLS:443 ┌──────────────────┐ SSH ┌──────────┐
│ wallarm binary │───────────►│ sshd │◄─────────│ You │
│ (reverse tunnel) │◄───────────│ │ │ │
│ │ │ localhost:9042 │ │ │
│ │ │ → VM-A:22 │ │ │
└──────────────────┘ └──────────────────┘ └──────────┘
VM-A opens an outbound TLS connection to VM-B on port 443 (looks like HTTPS to firewalls). VM-B terminates TLS and proxies to its internal SSH server. VM-A then requests a reverse port forward: VM-B:9042 → VM-A:22. The engineer SSH's into VM-B, then jumps through localhost:9042 to reach VM-A.
Prerequisites
- Linux VM (any distro) with a public IP or reachable via Zoraxy/Nginx reverse proxy
- OpenSSH server 7.6+
- Port 443 accessible from customer environments (outbound only, no inbound needed)
Step 1: Install and Configure SSH Server
# Install SSH server
apt-get install -y openssh-server # Debian/Ubuntu
yum install -y openssh-server # RHEL/CentOS
# Edit SSH config
nano /etc/ssh/sshd_config
Add or uncomment these lines:
# Required: allow TCP forwarding for the reverse tunnel
AllowTcpForwarding yes
# Required: keep idle tunnels alive
ClientAliveInterval 60
ClientAliveCountMax 3
# Optional: allow remote binds on non-localhost addresses
# (only needed if you want engineers to connect directly to VM-B:9042
# instead of SSH'ing into VM-B first)
GatewayPorts yes
Restart SSH:
systemctl restart sshd
Step 2: Create the Tunnel User
This user is used by the wallarm binary on customer VMs to authenticate
and open the reverse tunnel. It should NOT have a shell — it exists only
for port forwarding.
# Create tunnel-only user (no shell, no home directory needed)
useradd -m -s /bin/false wallarm-tunnel
# Create SSH directory
mkdir -p ~wallarm-tunnel/.ssh
chmod 700 ~wallarm-tunnel/.ssh
Option A: Password Authentication (simpler for customers)
# Set a password for the tunnel user
passwd wallarm-tunnel
The customer enters this password when prompted by wallarm.
Option B: SSH Key Authentication (more secure)
Generate a key pair and share the private key with customers:
# On the jump server
ssh-keygen -t ed25519 -f ~wallarm-tunnel/.ssh/wallarm_tunnel -N "" -C "wallarm-tunnel"
cat ~wallarm-tunnel/.ssh/wallarm_tunnel.pub >> ~wallarm-tunnel/.ssh/authorized_keys
chmod 600 ~wallarm-tunnel/.ssh/authorized_keys
chown -R wallarm-tunnel:wallarm-tunnel ~wallarm-tunnel/.ssh
# Share the private key securely with customers
cat ~wallarm-tunnel/.ssh/wallarm_tunnel
The customer provides the key path when prompted by wallarm.
Step 3: Zoraxy / Reverse Proxy (Optional)
If the jump server sits behind a Zoraxy edge proxy, configure it to forward
TLS:443 → internal SSH:22. This lets wallarm connect over port 443 (which
passes through most corporate firewalls).
Zoraxy Configuration
-
Add a new proxy rule:
- Domain:
ssh.sechpoint.app - Target:
tcp://<jump-server-ip>:22 - TLS: Enabled (auto-cert or custom)
- Domain:
-
No WebSocket or HTTP mode needed — Zoraxy proxies raw TCP.
Manual Nginx Stream Proxy (Alternative)
stream {
server {
listen 443 ssl;
proxy_pass <jump-server-ip>:22;
ssl_certificate /etc/ssl/certs/jump.crt;
ssl_certificate_key /etc/ssl/private/jump.key;
}
}
Step 4: Test the Setup
From the Jump Server Itself
# Verify SSH is listening
ss -tlnp | grep 22
# Verify tunnel user can authenticate (no shell expected)
ssh wallarm-tunnel@localhost echo test
# Expected: command fails (user has no shell), authentication succeeds
From an External Machine (Customer VM)
# Test TLS connection (if Zoraxy is configured)
openssl s_client -connect ssh.sechpoint.app:443 </dev/null 2>/dev/null | head -5
# Test SSH over TLS
ssh -p 443 wallarm-tunnel@ssh.sechpoint.app
# Expected: "This account is currently not available" or immediate disconnect
# This confirms authentication works but no shell is allowed — correct.
How wallarm Uses It
On the customer VM, the wallarm binary offers two paths:
wallarm --tunnel— starts tunnel with pre-configured credentials (build-time or env var)wallarm→ Remote Assistance — prompts for jumphost URL, username, password/key interactively
The binary does:
- TLS dial to
ssh.sechpoint.app:443 - SSH authenticate as
wallarm-tunnel - Request reverse forward:
0.0.0.0:9042 → localhost:22(orlocalhost:9042if GatewayPorts is off) - Keep tunnel alive with 30s heartbeats
Engineer Connection (Assistance Flow)
After the customer starts the tunnel, the engineer connects with two hops:
# Step 1: SSH into the jump server
ssh engineer@ssh.sechpoint.app
# Step 2: Jump through the tunnel to the customer VM
ssh root@localhost -p 9042
Or as a single command:
ssh -o ProxyJump=engineer@ssh.sechpoint.app root@localhost -p 9042
The engineer now has a root shell on the customer VM and can run the deployment wizard or troubleshoot directly.
Security Notes
- The
wallarm-tunneluser has no shell (/bin/false) — authentication only succeeds for port forwarding - The tunnel is outbound-only from the customer VM — no inbound ports opened
- TLS encrypts the connection end-to-end (VM-A → Zoraxy → VM-B)
- Add
Match User wallarm-tunnelblocks insshd_configto further restrict:Match User wallarm-tunnel PermitTTY no PermitTunnel no X11Forwarding no AllowAgentForwarding no ForceCommand /bin/false
Troubleshooting
| Symptom | Check |
|---|---|
| "Connection refused" from customer VM | Jump server port 443 reachable? Zoraxy running? |
| "Permission denied" | Tunnel user password/key correct? ~wallarm-tunnel/.ssh/authorized_keys permissions 600? |
| Tunnel opens but engineer can't reach VM-A | AllowTcpForwarding yes in sshd_config? SSH server restarted? |
| Tunnel drops after a few minutes | ClientAliveInterval set? Check firewall idle timeout |