Skip to content

Commit

Permalink
tunnel server: update the deployment guide
Browse files Browse the repository at this point in the history
  • Loading branch information
Roy Razon committed Feb 11, 2024
1 parent 4e7d3d8 commit 77de072
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 127 deletions.
27 changes: 17 additions & 10 deletions tunnel-server/deployment/k8s/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,25 @@ Deploying a private instance of the Tunnel Server allows for fine-grained contro
## Requirements

- A Kubernetes cluster
- An ingress solution to make K8S Services accesible from your network (e.g, Traefik). In this example, we'll use your cloud provider's load balancer.
- A TLS certificate for your domain
- `kubectl` and `kustomize`

## Overview

The Tunnel Server natively listens on two ports:
The Tunnel Server natively listens on three ports:
- A SSH port which accepts tunneling SSH connections from environments
- A HTTP port which accepts requests from clients (browsers, etc)
- A TLS port which directs incoming connections to either the SSH server or the HTTP server according to the [SNI server name](https://en.wikipedia.org/wiki/Server_Name_Indication).

In this deployment scheme, both ports are wrapped with TLS using [`stunnel`](https://www.stunnel.org/). Both HTTP and SSH connections are accepted on a [single port](https://vadosware.io/post/stuffing-both-ssh-and-https-on-port-443-with-stunnel-ssh-and-traefik/) and routed using [`sslh`](https://github.com/yrutschle/sslh/) to the tunnel server ports.
The `SSH_HOSTNAMES` env var determines which hostnames are directed to the SSH server and the rest are directed to the HTTP server. If the env var is not specified, the hostname of the `BASE_URL` is used.

The `stunnel` port is then exposed using a [`LoadBalancer-type K8S Service`](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer).
In this deployment scheme, the TLS port is exposed using a [`LoadBalancer-type K8S Service`](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer). The base hostname `yourdomain.example` is used for tunneling SSH connections and any hostname on the subdomain `*.yourdomain.example` will be used for client requests.

## Instructions

### 1. Setup the domain and the TLS certificate

Make sure the certificate is for a wildcard subdomain, e.g, `*.yourdomain.example`
Make sure the certificate is for both the base domain and the wildcard subdomain, e.g, `yourdomain.example` and `*.yourdomain.example`.

Put the cert and key (in PEM format) in the files `tls.crt` and `tls.key`

Expand Down Expand Up @@ -78,12 +78,13 @@ To test the SSH endpoint (replace `$MY_DOMAIN` with your domain):
```bash
MY_DOMAIN=yourdomain.example

EXTERNAL_IP=$(kubectl get service tunnel-server-tls -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
# NOTE: for EKS, replace .ip with .hostname below
EXTERNAL_IP=$(kubectl get service tunnel-server -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

ssh -nT -o "ProxyCommand openssl s_client -quiet -verify_quiet -servername $MY_DOMAIN -connect %h:%p" -p 443 foo@$EXTERNAL_IP hello
```

### 6. Create DNS records for the `tunnel-server` Service external IP
### 6. Create DNS records for the `tunnel-server` Service external IP or hostname

Create two DNS records: `*.yourdomain.example` and `yourdomain.example`, both pointing to the external IP of the `tunnel-server` service.

Expand All @@ -93,8 +94,14 @@ The address is not guaranteed to be static. According to your Kubernetes provide
- Google Cloud: [GKE](https://cloud.google.com/kubernetes-engine/docs/concepts/service-load-balancer)
- Azure: [AKS](https://learn.microsoft.com/en-us/azure/aks/load-balancer-standard)

Another approach would be to use a 3rd-party ingress solution like [Traefik](https://doc.traefik.io/traefik/user-guides/crd-acme/).

## Using your Tunnel Server instance with the Preevy CLI
### 7. Use your Tunnel Server instance with the Preevy CLI

The `up` and `urls` commands accept a `-t` flag which can be used to set the Tunnel Server URL. Specify `ssh+tls://yourdomain.example` to use your instance.

### 8. Cleanup: Delete the deployed objects

To delete the deployed Tunnel Server and associated Kubernetes objects, run:

```bash
kustomize build . | kubectl delete -f -
```
5 changes: 1 addition & 4 deletions tunnel-server/deployment/k8s/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- tunnel-server-stunnel.yaml
- tunnel-server.yaml
secretGenerator:
- files:
Expand All @@ -19,8 +18,6 @@ secretGenerator:
configMapGenerator:
- name: tunnel-server-config
envs: [config.env]
- name: tunnel-server-sslh-config
files: [sslh.conf]
images:
- name: ghcr.io/livecycle/preevy/tunnel-server
newTag: main-5f80bc0
newTag: main-8a9d527
16 changes: 0 additions & 16 deletions tunnel-server/deployment/k8s/sslh.conf

This file was deleted.

77 changes: 0 additions & 77 deletions tunnel-server/deployment/k8s/tunnel-server-stunnel.yaml

This file was deleted.

37 changes: 17 additions & 20 deletions tunnel-server/deployment/k8s/tunnel-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ spec:
secret:
defaultMode: 400
secretName: tunnel-server-ssh
- name: sslh-config
configMap:
defaultMode: 420
name: tunnel-server-sslh-config
- name: tls-cert
secret:
defaultMode: 400
secretName: tunnel-server-tls
containers:
- env:
- name: COOKIE_SECRETS
Expand Down Expand Up @@ -52,6 +52,9 @@ spec:
- containerPort: 3000
name: http
protocol: TCP
- containerPort: 8443
name: tls
protocol: TCP
resources:
limits:
cpu: "1"
Expand All @@ -69,35 +72,29 @@ spec:
- mountPath: /etc/livecycle-ssh
name: ssh
readOnly: true
- image: oorabona/sslh:v2.0-rc1
imagePullPolicy: IfNotPresent
name: sslh
command: [sslh-ev, --config=/etc/sslh/sslh.conf]
volumeMounts:
- mountPath: /etc/sslh
name: sslh-config
- mountPath: /app/tls/cert.pem
name: tls-cert
readOnly: true
ports:
- containerPort: 2443
name: sslh
protocol: TCP
restartPolicy: Always
terminationGracePeriodSeconds: 30
subPath: tls.crt
- mountPath: /app/tls/key.pem
name: tls-cert
readOnly: true
subPath: tls.key
---
apiVersion: v1
kind: Service
metadata:
name: tunnel-server
spec:
type: LoadBalancer
ports:
- name: sslh
- name: tls
port: 443
protocol: TCP
targetPort: 2443
targetPort: 8443
- name: metrics
port: 8888
protocol: TCP
targetPort: 8888
selector:
app: tunnel-server
type: ClusterIP

0 comments on commit 77de072

Please sign in to comment.