Skip to content

Commit 887d2a6

Browse files
committed
Add sshmux and image
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
1 parent d227a01 commit 887d2a6

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
layout: post
3+
title: Introducing sshmux - connect to any of your private servers with a single tunnel VM
4+
description: "Access all your remote SSH servers on your private network from a single TCP tunnel using the new sshmux feature."
5+
author: Alex Ellis
6+
tags: ssh sshmux tls remote tcp
7+
author_img: alex
8+
image: /images/2024-02-sshmux/background.png
9+
date: 2023-09-01
10+
---
11+
12+
Access all your remote SSH servers on your network from a single TCP tunnel using the new sshmux feature.
13+
14+
## Introduction
15+
16+
Quite often those of us wanting to expose or tunnel a single server or service, have several more like that which we'd also like to access. Take a HTTP server for instance, it's quite likely you'll have more than one domain - maybe one for Prometheus, one for Grafana, one for your blog, and maybe OpenFaaS on your Raspberry Pi.
17+
18+
At L7 HTTP routing is solved by inspecting the "Host:" header sent by the HTTP client. When traffic is encrypted end to end, you have L4 TLS routing, which obscures the Host header, however, it does a handshake which allows a server name to be read. This is called "Server Name Indication" or SNI.
19+
20+
So what about SSH?
21+
22+
SSH is a bespoke protocol which is usually multiplexed by having to use different ports, or various distinct IP addresses. You could do that with inlets prior to the new `sshmux` feature, but it would mean remapping ports, or adding extra tunnel server VMs to get additional IPs.
23+
24+
The `sshmux` feature acts just like a reverse proxy, and reads a TLS header to determine which server to forward the connection to. It's SNI for SSH.
25+
26+
If you'd like to learn how to expose a SSH server only, then see this tutorial: [Tutorial: Expose a private SSH server over a TCP tunnel](https://docs.inlets.dev/tutorial/ssh-tcp-tunnel/).With this tutorial, since the tunnel VM itself had SSH installed on port 22, you needed to add an extra port on your private SSH server's configuration. That's no longer needed with `sshmux`.
27+
28+
### Disclaimer
29+
30+
Now it goes without saying that there's a few things you should do before you put an computer running SSH onto the Internet.
31+
32+
At a bare-minimum, I'd suggest you:
33+
34+
* Disable password-based logins
35+
* Disable root logins
36+
* Only allow key-based logins
37+
* Only put the hosts in the config.yaml file that you'd like to connect to remotely
38+
39+
These settings are very well documented and you can find them in `/etc/ssh/sshd_config` on most Linux systems.
40+
41+
## How it works
42+
43+
First off, you'll want to create a new TCP tunnel server so that you can play with it and not worry about breaking anything:
44+
45+
```bash
46+
inletsctl create \
47+
--provider digitalocean \
48+
--region lon1 \
49+
--tcp
50+
```
51+
52+
DigitalOcean will email you an initial root password. Use it to log in and then change the `/etc/defaults/inlets` file and edit the line `--proxy-protocol=""` to `"--proxy-protocol=v2"`. We do this to ensure we get the remote IP address of the client send to sshmux.
53+
54+
Restart the server with `sudo systemctl daemon-reload && sudo systemctl restart inlets-pro`.
55+
56+
Next create a config.yaml file on a computer in your private network. You can think of this machine as being like a jump box, or a bastion host. The `sshmux server` will run here in order to forward connections to your other servers.
57+
58+
```yaml
59+
# config.yaml
60+
61+
upstreams:
62+
- name: nuc.inlets
63+
upstream: 172.10.0.100:22
64+
- name: rpi.inlets
65+
upstream: 172.10.0.101:22
66+
```
67+
68+
I've used the IP addresses of my machines on my local network in the `upstream` field. You can also use a DNS name here like `raspberrypi.local`, so long as you first add an extra in `/etc/hosts` such as `raspberrypi.local 172.10.0.101`.
69+
70+
Run the `sshmux server` on the jump box:
71+
72+
```bash
73+
inlets-pro \
74+
sshmux server \
75+
config.yaml
76+
```
77+
78+
It'll listen for TCP traffic on port 8443, so now you can connect the `inlets-pro tcp client` using the details you were given when you created the tunnel server.
79+
80+
```bash
81+
inlets-pro \
82+
tcp client \
83+
--url "wss://..." \
84+
--token "..." \
85+
--upstream "127.0.0.1" \
86+
--port 8443
87+
```
88+
89+
## Try it out
90+
91+
From your laptop, you can now use the IP address of the exit server VM to ssh into any of the machines in the config.yaml file.
92+
93+
Edit `~/.ssh/config` and add the following:
94+
95+
```
96+
Host *.inlets
97+
HostName %h
98+
Port 8443
99+
ProxyCommand inlets-pro sshmux connect TUNNEL_IP:%p %h
100+
```
101+
102+
Just update TUNNEL_IP to the IP address of the exit server VM.
103+
104+
Now you can use the `nuc.inlets` and `rpi.inlets` hostnames to connect to your servers.
105+
106+
```bash
107+
ssh nuc.inlets "uname -a && uptime"
108+
ssh rpi.inlets "uname -a && uptime"
109+
```
110+
111+
## Wrapping up
112+
113+
In a very short period of time, a prototype written over the FOSDEM weekend has made it into the inlets-pro product. It's not the only way to connect to various machines with your local network, but it's a very simple and effective way to do it if you're already using inlets.
114+

images/2024-02-sshmux/background.png

49.5 KB
Loading

0 commit comments

Comments
 (0)