Skip to content

Commit

Permalink
Add post on ssh with inlets-cloud
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
  • Loading branch information
alexellis committed Oct 17, 2024
1 parent 84b0748 commit 2287d9a
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 0 deletions.
179 changes: 179 additions & 0 deletions blog/_posts/2024-10-17-ssh-with-inlets-cloud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
---
layout: post
title: SSH Into Any Private Host With Inlets Cloud
description: Inlets Cloud is a SaaS hosted version of inlets that can give you SSH access to any host on your network.
author: Alex Ellis
tags: ssh remoteaccess inletscloud support
author_img: alex
image: /images/2024-10-inlets-cloud-ssh/background.jpg
date: 2024-10-17
---

When you're away from home it's not only convenient, but often necessary to connect back to your machines. This could be to connect to a remote VSCode instance, run a backup, check on a process, or to debug a problem. SSH can also be used to port-forward services, or to copy files with `scp` or `rsync`.

In this post I'll show you how to use inlets cloud to get SSH access to any host on your network without needing a VPN, and without having to host a tunnel server. You'll be able to expose one or more machines over a single tunnel, using DNS names to route traffic.

## What is inlets cloud?

inlets cloud is a SaaS hosted version of inlets-pro servers, and it makes for a convenient way to share local webservices, APIs, and endpoints like a blog, database server, Ollama endpoint, or a Kubernetes cluster. The client for inlets cloud uses TCP passthrough, so when your service uses SSH or TLS, there's no way for our infrastructure to decrypt the traffic.

You can already use a self-hosted tunnel server to expose SSH for a single host, or for many with sshmux:

* [Expose a single host over SSH](https://docs.inlets.dev/tutorial/ssh-tcp-tunnel/)
* [Expose multiple hosts over SSH](https://inlets.dev/blog/2024/02/05/access-all-your-ssh-servers-with-sshmux.html)

But in this tutorial, we're going to do it with inlets-cloud, without having to host, maintain or even consider any infrastructure. There are two regions for the beta - the EU and USA.

Traditionally, SSH had to be exposed on a public IP address using port-forwarding rules, or a random TCP port using a SaaS tunnel, or perhaps using a complex SaaS VPN solution.

SSH is a simple technology that is designed to be exposed to the public Internet, the main issue is that it's hard to multiplex multiple hosts over a single port.

We built [sshmux](https://inlets.dev/blog/2024/02/05/access-all-your-ssh-servers-with-sshmux.html) into inlets to solve this problem, and now you can use it with inlets-cloud.

The diagram below shows sshmux with a self-hosted tunnel server, but in this tutorial, we'll be using inlets-cloud to provide the hosting instead.

![Self-hosted sshmux tunnel](https://inlets.dev/images/2024-02-sshmux/conceptual.png)

sshmux is a simple way to expose multiple SSH backends over a single port, using a DNS name to route traffic. Just create a wildcard domain entry, or add one entry per host, and then configure sshmux to direct traffic accordingly.

You will of course need to follow the general security advise on hardening SSH, which is easy to find on the Internet, or via a brief chat with ChatGPT.

## Prerequisites

* You'll need a domain name, and the ability to create CNAME or A records, you'll create one entry per host that you want to access.
* OpenSSH set up on one or more machines in your private network, follow the usual security precautions like disabling *Root access* and *Password authentication*
* An inlets cloud account, you can sign up for free at [cloud.inlets.dev](https://cloud.inlets.dev)

## Create a tunnel on inlets-cloud

Create a new tunnel, the name is not important, but the list of sub-domains is, this is where you add one entry for each host you want to access.

You can add more after creating the tunnel, so feel free to start with one, if that's easier.

![Create a new tunnel](/images/2024-10-inlets-cloud-ssh/create-tunnel.png)

Create any CNAME entries in your DNS provider as directed, and verify the top-level domain with a TXT record.

Then navigate back to the tunnel details page, and copy the text under "Caddy/Nginx":

![Create a new tunnel](/images/2024-10-inlets-cloud-ssh/copy-connect.png)

We want to adjust it slightly, so that we can use it with sshmux instead of Nginx or Caddy. We'll be directing in SSH traffic, not TLS traffic for webservers.

```diff
inlets-pro uplink client \
--url="wss://cambs1.uplink.inlets.dev/alexellis/sshmux" \
--token=******** \
- --upstream=80=127.0.0.1:80 \
+ --upstream=443=127.0.0.1:8443
```

We remap any incoming requests to the hosted server on port 443, to port 8443, which is the default port for sshmux.

Run the command to start the tunnel, it should day "Connection established".

## Install the inlets-pro client

If you haven't already, install the inlets-pro client:

```bash
curl -sLSf https://get.arkade.dev | sudo sh

arkade install inlets-pro
```

Alternatively, download the binary from the [inlets-pro releases page](https://github.com/inlets/inlets-pro/releases).

## Start sshmmux

sshmux is an SSH multiplexer that can expose multiple SSH backends over a single port, using a DNS name to route traffic.

Typically, other solutions will require you to use a different port for each host, and then you have to memorise random numbers, or resort to clever SaaS-based VPNs.

Create a `config.yaml` file:

```yaml
upstreams:
- name: nuc.example.com
upstream: 192.168.0.200:22
- name: nas.example.com
upstream: 10.0.0.2:2222
```
Then start sshmux:
```bash
inlets-pro sshmux server \
--port 8443 \
config.yaml
```

SSH does not support using a SNI header, or a TLS hostname, so we use sshmux to wrap the traffic with this header.

You can use the `openssl` tool for this, or our convenience command `inlets-pro sshmux connect`.

Edit .ssh/config:

```bash
Host *.example.com
HostName %h
Port 443
ProxyCommand inlets-pro sshmux connect cambs1.uplink.inlets.dev:%p %h
```

The text `cambs1.uplink.inlets.dev` is the DNS entry you used for the CNAMES in the previous step, so if you're using a different region, use that value here instead.

All this does is to tell SSH to use the `inlets-pro sshmux connect` command to connect to the remote host, and to pass the hostname and port number to the command.

## Connect to one of your hosts

Now you can connect to one of your hosts:

```bash
ssh nuc.example.com
```

You can also use the `-L` flag to forward ports or services running on the remote host to your local machine.

For instance, if you were running a Node.js application on port 3000 on the remote host, you could forward it to your local machine like this:

```bash
ssh -L 3000:127.0.0.1:3000 nuc.example.com
```

Of course you can also copy files with `scp` or use `rsync` over the SSH connection.

Copy a single remote file to your host:

```bash
scp nuc.example.com:~/debug.log .
```

Rsync the code for k3sup, that you're hacking on to the remote computer:

```bash
rsync -av -r -e "ssh" ~/go/src/github.com/alexellis/k3sup .
```

The port override for `443` is not necessary since the .ssh/config file will handle this, but you can explicitly add the flag if you want. `ssh` uses `-p` and `scp` uses `-P`.

## Conclusion

You've now got a secure way to access any host on your network, without needing to host a tunnel server, or to set up a VPN. This is a great way to access your home network, or to provide support to friends and family.

Any time you want to add or remove a host, you can do so via the inlets-cloud dashboard, by navigating to the "Tunnels" page and editing the list of domains. Then make sure you have an entry in your sshmux config file, and restart it with the new configuration.

Access is completely private, there is no way to decrypt the SSH traffic, and it gets passed directly on to your own machine inside your local network.

For taking things further, sshmux also supports an IP allow list, which will be available in inlets-cloud shortly, or which you can use already today with the self-hosted version of inlets-pro.

If the IP for your mobile hotspot was 35.202.222.154, you could write the following to restrict access to `nuc.example.com` to only yourself:

```yaml
upstreams:
- name: nuc.example.com
upstream: 192.168.0.120:22
allowed:
- 35.202.222.154
```
Binary file added images/2024-10-inlets-cloud-ssh/background.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/2024-10-inlets-cloud-ssh/copy-connect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/2024-10-inlets-cloud-ssh/create-tunnel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2287d9a

Please sign in to comment.