Skip to content

Instantly share code, notes, and snippets.

@ubergesundheit
Last active September 21, 2021 00:14
Show Gist options
  • Save ubergesundheit/3cd98be47f2489177128d78fd06c0a97 to your computer and use it in GitHub Desktop.
Save ubergesundheit/3cd98be47f2489177128d78fd06c0a97 to your computer and use it in GitHub Desktop.
Ngrok alternative with mmatczuk/go-http-tunnel server

mmatczuk/go-http-tunnel server

Server

  • Download release 2.1 for your architecture https://github.com/mmatczuk/go-http-tunnel/releases/tag/2.1
  • Move tunneld to /usr/local/bin/tunneld
  • Create user useradd -r tunneld
  • Create /etc/tunneld
  • Install Certstrap 1.1.1 to /usr/local/bin/certstrap
  • Download generateCertificates.sh and chmod +x generateCertificates.sh
  • Generate your certificates ./generateCertificates.sh YOUR-CA-NAME hostname-of-your-tunnel-server,clientname1,clientname2
    • You can always come back and generate additional certificates..
  • Move the server certificate, server key and ca certificate to /etc/tunneld. Name them ca.crt, server.crt and server.key
  • Download the clients file to /etc/tunneld/clients
  • chown -R tunneld:tunneld /etc/tunneld
  • Download the tunneld.service to /etc/systemd/system/tunnel.service
    • If you want http tunneling, change the parameters to /usr/local/bin/tunneld accordingly and maybe put the http stuff behind a proxy server (Caddy is perfect for this!)
  • systemctl daemon-reload
  • systemctl enable tunneld
  • systemctl start tunneld

Client

  • Download https://github.com/mmatczuk/go-http-tunnel/releases/tag/2.1 matching your clients architecture
  • Extract tunnel binary to /usr/local/bin/tunnel
  • Create user tunnel useradd -r tunnel
  • Create /etc/tunnel and copy tls certificate files there
  • Create /etc/tunnel/tunnel.yml (See example tunnel.yml)
  • chown -R tunnel:tunnel /etc/tunnel
  • tunnel -config /etc/tunnel/tunnel.yml id to show your client id, you have to add this one to the allowed clients (/etc/tunneld/clients) on the server
  • Download tunnel.service to /etc/systemd/system/tunnel.service
  • systemctl enable tunnel
  • systemctl start tunnel
# List your client-ids here
# Each line should contain only a single client-id followed by a comma (,) and a backslash (\)
# The last line shouldn't have the comma and backslash!
#
# Make sure no stray whitespace at the end of lines!!!
# with vim do :%s/\s\+$//e
#
# Please list the client ids here with name
#
# client-id description
# TVFU53T-M4J2ELM-ET9YZLI-SPHSWLY-WVO3T7B-RM3SC2A-EDURNZY-LUP5SQG client1
# 2DZE5EU-DGZIA5W-60ORFAS-S3PF74R-CWKTMTK-LHCBJES-W43SOFU-ZDCXMAI client2
CLIENTS=\
TVFU53T-M4J2ELM-ET9YZLI-SPHSWLY-WVO3T7B-RM3SC2A-EDURNZY-LUP5SQG,\
2DZE5EU-DGZIA5W-60ORFAS-S3PF74R-CWKTMTK-LHCBJES-W43SOFU-ZDCXMAI
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
CA_NAME=${1:-}
SERVICES=${2:-}
if [[ -z "$CA_NAME" || -z "${SERVICES}" ]]; then
echo "CA_NAME and SERVICE[,SERVICE,...] parameters required"
echo "Usage: $0 CA_NAME SERVICE[,SERVICE,...]"
exit 1
fi
# Some certstrap options
DEPOT_PATH=certificates
EXPIRES="10 years"
KEY_BITS=4096
certstrap_with_opts () {
certstrap --depot-path "${DEPOT_PATH}" "$@"
}
generateCA () {
if [[ -f "${DEPOT_PATH}/${CA_NAME}.crt" ]]; then
echo "CA \"${CA_NAME}\" already exists"
return
fi
echo "Generate root CA \"${CA_NAME}\""
certstrap_with_opts init --passphrase "" --expires "${EXPIRES}" --common-name "${CA_NAME}"
}
requestAndSignCertificate () {
local SERVICE=$1
echo "Create certificate request for ${SERVICE}"
certstrap_with_opts request-cert --passphrase "" --key "${DEPOT_PATH}/${CA_NAME}.key" --key-bits "${KEY_BITS}" --common-name "${SERVICE}"
echo "Sign certificate request for ${SERVICE}"
certstrap_with_opts sign --passphrase "" --expires "${EXPIRES}" --CA "${CA_NAME}" "${SERVICE}"
}
generateCA
SERVICES=${SERVICES//,/$'\n'}
for SERVICE in $SERVICES
do
requestAndSignCertificate "${SERVICE}"
done
[Unit]
Description=tunnel
Documentation=https://github.com/mmatczuk/go-http-tunnel
[Service]
User=tunnel
Group=tunnel
ExecStart=/usr/local/bin/tunnel -config /etc/tunnel/tunnel.yml start-all
# systemd.exec
ProtectHome=yes
ProtectSystem=full
[Install]
WantedBy=multi-user.target
server_addr: YOUR-SERVER-HOSTNAME:5223
tls_crt: /etc/tunnel/client.crt
tls_key: /etc/tunnel/client.key
root_ca: /etc/tunnel/ca.crt
tunnels:
ssh:
proto: tcp
addr: localhost:22
remote_addr: 0.0.0.0:1025
[Unit]
Description=tunneld
Documentation=https://github.com/mmatczuk/go-http-tunnel
[Service]
Environment="CA=/etc/tunneld/ca.crt"
Environment="CERT=/etc/tunneld/server.crt"
Environment="KEY=/etc/tunneld/server.key"
Environment="TUNNELADDR=YOUR-HOSTNAME:5223"
EnvironmentFile=/etc/tunneld/clients
User=tunneld
Group=tunneld
ExecStart=/usr/local/bin/tunneld -rootCA ${CA} -tlsCrt ${CERT} -tlsKey ${KEY} -httpsAddr "" -httpAddr "" -tunnelAddr ${TUNNELADDR} -clients ${CLIENTS}
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
# systemd.exec
ProtectHome=yes
ProtectSystem=full
[Install]
WantedBy=multi-user.target
@vanrin
Copy link

vanrin commented Apr 11, 2020

Hi, where could I get client.crt and client.key?

@ubergesundheit
Copy link
Author

Use the bash script to generate one. Change the file name in the systemd unit accordingly

@vanrin
Copy link

vanrin commented Apr 11, 2020

Thanks for reply, but I still have problem connecting to server.
For example if I generate certificate using cmd like
./generateCertificates.sh example example.com
I will have to rename: example.crt => ca.crt , example.key => client.key, example.com.crt => client.crt?

@ubergesundheit
Copy link
Author

The ca cert is the certificate of the certificate authority. Use the example.com.crt & example.com.key for client cert & key

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment