---
# System prepended metadata

title: SSH reverse tunnel through HTTP proxy
tags: [Blog, ' Note']

---

---
tags: Blog, Note
disqus: ship-theseus
---
# SSH reverse tunnel through HTTP proxy

## Background

```mermaid
graph LR
    guest(Guest)
    proxy(HTTP proxy)
    host(Host)
    internet(Internet)
    subgraph Lab
        host --> proxy
    end
    proxy --> internet
    guest --> internet
    guest -.SSH.-> internet -.SSH.-> proxy -.SSH.-> host
```

*Host* is in a Lab intranet which cannot allow any traffic to go out except HTTP(s).
In addition, no traffic can go inside to the Lab network actively.

What I want to do is `ssh` from the *Guest* to *Host*.

## HowTo

1. SSH through HTTP proxy
2. SSH reverse tunnel

## Detail

1. *Guest* disguises as a HTTPS Server by make SSH server listen to 443
    - Modify `/etc/ssh/sshd_config`
    - Restart SSH service
    - Grant firewall and SELinux
    - [ref](https://kifarunix.com/how-to-configure-ssh-to-use-a-different-port-on-centos-7/)
2. Install `connect-proxy` on *Host*; otherwise, use `nc` instead if it can support proxy
    - [ref](https://stackoverflow.com/questions/19161960/connect-with-ssh-through-a-proxy)
3. `ssh` from *Host* to *Guest* and enable SSH reverse tunnel
    - `ssh -R 19999:localhost:22 -o ProxyCommand="connect-proxy -H xxxxx:8080 %h 443" guest_user@guest`
    - `19999:locahost:22` -> `<port on guest>:<host on guest>:<port on host>`
    - `-H xxxxx:8080` if the proxy is HTTP proxy; if it is SSH proxy, use `-S`
    - `%h 443` proxy to the which destination; in this case, the operand `%h` means *Guest*
4. **Congratulation**, now you can `ssh` from *Guest* to *Host* due to the reverse tunnel
    - `ssh host_user@localhost -p 19999`

## MoreInfo

- *Guest* as a gateway
    - Modify `/etc/ssh/sshd_config`
    - Enable `GatewayPorts yes`
    - Restart SSH service
- Keep alive on tunnel
    - `ssh -o ServerAliveInterval=60 host_user@localhost -p 19999`