remote-forward
04 — Remote forward -R
Learning objectives
- Build a loopback
-Rso B can reach a lab service on A. - Refuse
GatewayPorts yesfor classroom demos.
Intuition
-R is "park a doorbell on their box that rings my service."
Friend annotation — -R in one breath
You still type this on A. Listener sits on B (:18080). B hitting it makes A serve your :8080.
ssh -N -R 127.0.0.1:18080:127.0.0.1:8080 user@B
sequenceDiagram participant You as A your laptop participant B as B bastion participant Svc as A service :8080 Note over B: Listener on B :18080 Note over Svc: Your lab HTTP on A B->>B: curl 127.0.0.1:18080 B->>You: SSH channel (-R) You->>Svc: A dials 127.0.0.1:8080 Svc-->>You: response You-->>B: back through SSH
Compare with -L on whiteboard / local-forward / the SSH Tunneling handout.
Class reminder
You still type -R on A. B gets the listener. Prefix 127.0.0.1: on the remote side; do not enable GatewayPorts for class. Myths / port-order: whiteboard FAQ.
Practitioner
Goal: Something on B reaches a service listening on A.
Shape: Listener on B (prefer B's loopback); real connect opened by A.
Pattern
On A, run a tiny authorized listener (lab HTTP, etc.), then:
ssh -N -o ExitOnForwardFailure=yes \
-R 127.0.0.1:18080:127.0.0.1:8080 \
user@B
From B: curl http://127.0.0.1:18080 → hits A's :8080.
Classroom safety
- Keep remote bind on
127.0.0.1unless a reviewed bastion design says otherwise - Do not enable
GatewayPorts yesfor a friend demo - If another host must reach the forward, that is a separate hardened bastion exercise — not this lesson
When Academy / Registry is too heavy
Use a 3-host home lab: A (student) · B (SSH) · optional C. Practice -R on B→A without needing a Hard HTB box.
Hop chain
- Something on B →
127.0.0.1:REMOTE_PORT(e.g. 2226 on the jumpbox) - Listener on B (remote SSH server) — still typed from A
- Traffic tunnels back through the SSH session
- A dials the target (often
127.0.0.1:8080on your laptop)
ssh -N -R 127.0.0.1:2226:127.0.0.1:8080 user@JUMPBOX
Checkpoint
- Friends answer: "Who listens?" → B
- Benign request from B succeeds
- Session torn down; no leftover listeners on B
Evidence: artifacts/evidence/04-R-check.md.
Cite: [S-PC-01], [S-OSS-01], [S-OSS-02] (sshd_config / GatewayPorts).
Deep dive
GatewayPorts and PermitOpen belong in bastion hardening, not friend demos [S-OSS-02 | high | primary].
Check
B curls A's forwarded port; GatewayPorts untouched; tear-down confirmed.