secure-reverse-ssh-tunnel/README.md

137 lines
4.4 KiB
Markdown

# secure-reverse-ssh-tunnel
This project provides ready-to-use tools to configure a remote host via an ssh tunnel and a jump host.
## Example
### Premise:
- HTE) Host you wish to expose. Currently network restricted (behind a FW or a NAT)
- EUD) End user device such as a laptop or mobile device provided with an ssh client.
- JH) A host publicly accessible over the internet (or a network accessible to both HTE and EUD) running Openssh server.
### Scenario:
- EUD wants to access a service running on HTE, but HTE can be accessed only from within its own network.
- EUD can generate outgoing traffic to the internet or external networks.
- HTE can't accept incoming connections from the internet or other networks.
- HTE can generate outgoing traffic to the internet or external networks.
- JH is accessible to both HTE and EUD and runs an Openssh server.
Normally, to allow communication between EUD and HTE, you would need to setup a portforward for HTE on its network's edge router. Then have EUD connect to the edge router's Public IP at the forwarded port.
This might not be feasible or out of HTE's control, thus an ssh reverse tunnel can be used.
By using a jump server we can establish a tunnel from HTE to JH and respectively a communication from EUD to JH securely, using SSH and our private keys.
At this point EUD can access HTE's service just like any other service running on JH.
The Reverse tunnel binds HTE's port to JH's network-interface:port (JumpHost's localhost by default, see **[GatewayPorts](https://gitlab.com/enkht04/secure-reverse-ssh-tunnel#note)**)
Meaning every request sent to JH's binded port is going to be forwarded HTE's port.
**In ssh cli terms:**
```bash
ssh -R ${JH_PORT}:localhost:${HTE_PORT} ${USER}@${TARGET}
```
---
## Support us
Whether you use this project, have learned something from it, or simply like it, please consider supporting it by donation, so we can spend more time on open-source projects like this :)
<a href="https://it.liberapay.com/Unitoo/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a>
---
## Components
- setup-remote-host.sh: This script must be run as root after setup step
- authorized_keys: should contains the ssh pubkey for JH
- config: example host configuration for "EUD" computer
- secure-tunnel@.service: SystemD ready to use example service
- targets/* : contains multiple targets that need to be used as jump servers
___
## Setup
Before you run the script as root user, you should:
1) append your keypair's pubkey into JH authorized_keys
2) edit targets based on the example provided
3) adjust your EUD's ~/.ssh/config like the one provided.
4) now you are able to run the script as root on HTE.
___
## Usage
### SystemD
```bash
## To enable at boot
systemctl enable secure-tunnel@<target>
## To disable at boot
systemctl disable secure-tunnel@<target>
## To start manually
systemctl start secure-tunnel@<target>
## To stop manually
systemctl stop secure-tunnel@<target>
```
___
## Tips
To check if the tunnel is active and the dedicated port is up, ssh into your jump host and run:
```bash
netstat -tupln | grep 20001
```
You should see autossh's process to your chosen port :)
### Remote port forwarding
By default **sshd** will bind forwarded ports only to the server's loopback interface (localhost, 127.0.0.0/8)
For instance the following reverse tunnel :
```bash
ssh -R ${JH_PORT}:localhost:${HTE_PORT} ${USER}@${TARGET}
```
would result in a bind like this:
```bash
127.0.0.1:${JH_PORT} LISTEN pid/sshd
```
To expose forwarded ports over every jumphost's IP (0.0.0.0) add the following to `/etc/ssh/sshd_config`
```bash
GatewayPorts yes
```
###### Note:
Every forwarded port will now be publicly exposed (unless FW rules are in place.)
A better approach would be:
```bash
GatewayPorts clientspecified
```
The reverse tunnel above becomes;
```bash
ssh -R ${JH_ADDR}:${JH_PORT}:localhost:${HTE_PORT} ${USER}@${TARGET}
```
### Local port forward
You could use your Jump Host even to bind a local port to a web interface on a remote host or something else with:
```bash
ssh -N -L ${LOCALPORT}:127.0.0.1:${JH_PORT} ${USER}${TARGET}
```
For example to access a remote pihole web interface locally :)
___
## License
>You can check out the full license [here](https://gitlab.com/unitoo/secure-reverse-ssh-tunnel/-/blob/master/LICENSE)
This project is licensed under the terms of the **GPLv3** license.