Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port pre-assignment #146

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ on:
tags:
- v*
branches:
- master
- main
pull_request:
branches:
- master
- main

jobs:
build:
Expand Down Expand Up @@ -48,7 +48,7 @@ jobs:
fi

DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
REF="${BRANCH_NAME:-master}"
REF="${BRANCH_NAME:-main}"
OTHER_ARGS=""
OTHER_PUSH_ARGS=""

Expand Down
29 changes: 27 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ An open source serveo/ngrok alternative.
## Deploy

Builds are made automatically for each commit to the repo and are pushed to Dockerhub. Builds are
tagged using a commit sha, branch name, tag, latest if released on master.
tagged using a commit sha, branch name, tag, latest if released on main.
You can find a list [here](https://hub.docker.com/r/antoniomika/sish/tags).
Each release builds separate `sish` binaries that can be downloaded from
[here](https://github.com/antoniomika/sish/releases) for various OS/archs.
Expand Down Expand Up @@ -62,6 +62,14 @@ the letsencrypt files in /etc/letsencrypt, _not_ ./letsencrypt.

I use these files in my deployment of `ssi.sh` and have included them here for consistency.

## Google Cloud Platform

There is a tutorial for creating an instance in Google Cloud Platform
with sish fully setup that can be found [here](https://github.com/antoniomika/sish/blob/main/deploy/gcloud.md).
It can be accessed through [Google Cloud Shell](https://cloud.google.com/shell).

[![Open in Cloud Shell](https://gstatic.com/cloudssh/images/open-btn.svg)](https://ssh.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fantoniomika%2Fsish&cloudshell_git_branch=main&cloudshell_tutorial=deploy%2Fgcloud.md)

## How it works

SSH can normally forward local and remote ports. This service implements
Expand Down Expand Up @@ -167,6 +175,23 @@ sish@sish0:~/sish/pubkeys# curl https://github.com/antoniomika.keys > antoniomik
This will load my public keys from GitHub, place them in the directory that sish is watching,
and then load the pubkey. As soon as this command is run, I can SSH normally and it will authorize me.

### Port pre-assignment

If you use authentication keys, you can also pre-assign the port that a particular host can bind
with this option:

```--use-ports-from-keys```

It is slightly abusing the auth_keys specifications (sshd(8)) according to which you can specify
SSH options within the keys. Your line in pubkeys directory might look like this:

```permitlisten="12345" ssh-rsa THE_PUBKEY_IS_HERE comment@HOSTNAME```

sish will allow the host to use only this particular port for TCP forwarding.
This might be useful for managing multiple computers to which 3rd party might have access.
If you do this for every machine, none of them can block the pre-designated port dedicated for the other
even if somebody tried to mangle the settings.

## Custom domains

sish supports allowing users to bring custom domains to the service, but SSH key auth is required to be
Expand Down Expand Up @@ -224,7 +249,6 @@ need to set `--geodb` to `true`.
To use sish, you need to add a wildcard DNS record that is used for multiplexed subdomains.
Adding an `A` record with `*` as the subdomain to the IP address of your server is the simplest way to achieve this configuration.


## Demo - At this time, the demo instance has been set to require auth due to abuse

There is a demo service (and my private instance) currently running on `ssi.sh` that
Expand Down Expand Up @@ -297,6 +321,7 @@ Flags:
--debug Enable debugging information
-d, --domain string The root domain for HTTP(S) multiplexing that will be appended to subdomains (default "ssi.sh")
--force-requested-aliases Force the aliases used to be the one that is requested. Will fail the bind if it exists already
--use-ports-from-keys Ignore requested port and use the one specified as "permitlisten" option with the user's pubkey, if exists
--force-requested-ports Force the ports used to be the one that is requested. Will fail the bind if it exists already
--force-requested-subdomains Force the subdomains used to be the one that is requested. Will fail the bind if it exists already
--geodb Use a geodb to verify country IP address association for IP filtering
Expand Down
1 change: 1 addition & 0 deletions cmd/sish.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func init() {
rootCmd.PersistentFlags().StringP("load-templates-directory", "", "templates/*", "The directory and glob parameter for templates that should be loaded")

rootCmd.PersistentFlags().BoolP("force-requested-ports", "", false, "Force the ports used to be the one that is requested. Will fail the bind if it exists already")
rootCmd.PersistentFlags().BoolP("use-ports-from-keys", "", false, "Ignore requested port and use the one specified as \"permitlisten\" option with the user's pubkey, if exists")
rootCmd.PersistentFlags().BoolP("force-requested-aliases", "", false, "Force the aliases used to be the one that is requested. Will fail the bind if it exists already")
rootCmd.PersistentFlags().BoolP("force-requested-subdomains", "", false, "Force the subdomains used to be the one that is requested. Will fail the bind if it exists already")
rootCmd.PersistentFlags().BoolP("bind-random-subdomains", "", true, "Force bound HTTP tunnels to use random subdomains instead of user provided ones")
Expand Down
135 changes: 135 additions & 0 deletions deploy/gcloud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# sish installation

sish is an open source serveo/ngrok alternative that can be used to open a tunnel
to localhost that is accessible to the open internet using only SSH. sish implements
an SSH server that can handle multiplexing of HTTP(S), TCP, and TCP Aliasing
([more about this can be found in the README](https://github.com/antoniomika/sish/blob/main/README.md))

This tutorial will teach you how to:

* Setup an instance in Google Cloud using the [free tier](https://cloud.google.com/free)
* Add and modify authentication for users
* Access sish from a remote computer

## Project selection

You first need to select a project to host the resources created in this tutorial.
I'd suggest creating a new project at this time where your sish instance will live.
<walkthrough-project-setup></walkthrough-project-setup>

## Access Google Cloud Shell

<walkthrough-auto-open-cloud-shell></walkthrough-auto-open-cloud-shell>

## Create the instance running the container

Here is a command to create the instance running the sish container. This will start the container
on a hardened [Container Optimized OS](https://cloud.google.com/container-optimized-os/docs) and start
the service. This is just a starting command that runs sish on port `2222`, `80`, and `443`. If you
accept the [Let's Encrypt TOS](https://letsencrypt.org/repository/), you can enable automatic SSL cert loading.
This command does *NOT* include authentication and it is up to you to properly tune these parameters based on
the documentation [here](https://github.com/antoniomika/sish#cli-flags). Make sure to update `YOURDOMAIN`
to the actual domain you own. You will also need to setup the DNS records as described below. Also feel free
to change the `--zone` used for these commands.

```bash
gcloud compute instances create-with-container sish \
--zone="us-central1-a" \
--tags="sish" \
--container-mount-host-path="host-path=/mnt/stateful_partition/sish/ssl,mount-path=/ssl" \
--container-mount-host-path="host-path=/mnt/stateful_partition/sish/keys,mount-path=/keys" \
--container-mount-host-path="host-path=/mnt/stateful_partition/sish/pubkeys,mount-path=/pubkeys" \
--container-image="antoniomika/sish:latest" \
--machine-type="f1-micro" \
--container-arg="--domain=YOURDOMAIN" \
--container-arg="--ssh-address=:2222" \
--container-arg="--http-address=:80" \
--container-arg="--https-address=:443" \
--container-arg="--https=true" \
--container-arg="--https-certificate-directory=/ssl" \
--container-arg="--authentication-keys-directory=/pubkeys" \
--container-arg="--private-key-location=/keys/ssh_key" \
--container-arg="--bind-random-ports=false" \
--container-arg="--bind-random-subdomains=false" \
--container-arg="--bind-random-aliases=false" \
--container-arg="--tcp-aliases=true" \
--container-arg="--service-console=true" \
--container-arg="--log-to-client=true" \
--container-arg="--admin-console=true" \
--container-arg="--verify-ssl=false" \
--container-arg="--https-ondemand-certificate=false" \
--container-arg="--https-ondemand-certificate-accept-terms=false" \
--container-arg="--https-ondemand-certificate-email=certs@YOURDOMAIN" \
--container-arg="--idle-connection=false" \
--container-arg="--ping-client-timeout=2m"
```

## Network Setup

### Open the firewall to allow access to all instance ports

```bash
gcloud compute firewall-rules create allow-all-tcp-sish \
--action="allow" \
--direction="ingress" \
--rules="tcp" \
--source-ranges="0.0.0.0/0" \
--priority="1000" \
--target-tags="sish"
```

### Adding a DNS record

Get the external IP address of your machine and create two DNS records

* An `A` record for YOURDOMAIN pointing it to the output below
* An `A` record for *.YOURDOMAIN pointing it to the output below

```bash
gcloud compute instances describe sish \
--zone="us-central1-a" \
--format='get(networkInterfaces[0].accessConfigs[0].natIP)'
```

## Using sish

### Try using SSH to connect to the sish service

```bash
ssh -p 2222 -R foo:80:httpbin.org:80 YOURDOMAIN
```

### Access the address sish gave you

```bash
curl -vvv http://foo.YOURDOMAIN/anything
```

## Advanced usage

### Login into your new machine

```bash
gcloud compute ssh sish --zone="us-central1-a"
```

### Adding SSH keys for when you enable auth

```bash
echo "ssh_public_key_here" >> /mnt/stateful_partition/sish/pubkeys/your_user.keys
```

## Tear it down

### First the instance

```bash
gcloud compute instances delete sish \
--zone="us-central1-a"
```

### Then the firewall rule

```bash
gcloud compute firewall-rules delete allow-all-tcp-sish
```
58 changes: 31 additions & 27 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,41 +1,45 @@
module github.com/antoniomika/sish

go 1.15

require (
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5
github.com/antoniomika/go-proxyproto v0.1.4-0.20200616163129-7fa9d35a141d
github.com/antoniomika/oxy v1.1.1-0.20200517194743-bedd7c62c77e
github.com/caddyserver/certmagic v0.11.2
github.com/cenkalti/backoff/v4 v4.0.2 // indirect
github.com/caddyserver/certmagic v0.12.0
github.com/fsnotify/fsnotify v1.4.9
github.com/gin-gonic/gin v1.6.3
github.com/go-playground/validator/v10 v10.3.0 // indirect
github.com/golang/protobuf v1.4.2 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/golang/protobuf v1.4.3 // indirect
github.com/gorilla/websocket v1.4.2
github.com/jpillora/ipfilter v1.2.1
github.com/jpillora/ipfilter v1.2.2
github.com/json-iterator/go v1.1.10 // indirect
github.com/klauspost/cpuid v1.3.0 // indirect
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381
github.com/mailgun/timetools v0.0.0-20170619190023-f3a7b8ffff47 // indirect
github.com/miekg/dns v1.1.29 // indirect
github.com/klauspost/cpuid v1.3.1 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/magiconair/properties v1.8.4 // indirect
github.com/mholt/acmez v0.1.3 // indirect
github.com/miekg/dns v1.1.38 // indirect
github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a
github.com/mitchellh/mapstructure v1.3.2 // indirect
github.com/pelletier/go-toml v1.8.0 // indirect
github.com/phuslu/geoip v1.0.20200531 // indirect
github.com/sirupsen/logrus v1.6.0
github.com/spf13/afero v1.2.2 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/pelletier/go-toml v1.8.1 // indirect
github.com/phuslu/iploc v1.0.20210129 // indirect
github.com/pires/go-proxyproto v0.4.2
github.com/sirupsen/logrus v1.7.0
github.com/spf13/afero v1.5.1 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/cobra v1.0.0
github.com/spf13/cobra v1.1.3
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.0
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 // indirect
google.golang.org/protobuf v1.24.0 // indirect
gopkg.in/ini.v1 v1.57.0 // indirect
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect
github.com/spf13/viper v1.7.1
github.com/ugorji/go v1.2.4 // indirect
github.com/vulcand/oxy v1.1.0
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.16.0 // indirect
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/text v0.3.5 // indirect
google.golang.org/protobuf v1.25.0 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
)

go 1.15
replace github.com/vulcand/oxy => github.com/antoniomika/oxy v1.1.1-0.20210215225031-0afb828604bb

replace github.com/pires/go-proxyproto => github.com/antoniomika/go-proxyproto v0.1.4-0.20210215223815-7210fcdac442
Loading