Create a gist now

Instantly share code, notes, and snippets.

How to setup Ngrok with a self-signed SSL cert

Intro

The plan is to create a pair of executables (ngrok and ngrokd) that are connected with a self-signed SSL cert. Since the client and server executables are paired, you won't be able to use any other ngrok to connect to this ngrokd, and vice versa.

DNS

Add two DNS records: one for the base domain and one for the wildcard domain. For example, if your base domain is domain.com, you'll need a record for that and for *.domain.com.

Different Operating Systems

If the OS on which you'll be compiling ngrok (that's the server section below) is different than the OS on which you'll be running the client, then you will need to set the GOOS and GOARCH env variables. I run Linux everywhere, so I don't know how to do that. Please Google it or see the discussion here. If you know how to do this and want to add GOOS/GOARCH instructions here, please let me know.

On Server

MAKE SURE YOU SET NGROK_DOMAIN BELOW. Set it to the base domain, not the wildcard domain.

NGROK_DOMAIN="my.domain.com"
git clone https://github.com/inconshreveable/ngrok.git
cd ngrok

openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj "/CN=$NGROK_DOMAIN" -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000

cp rootCA.pem assets/client/tls/ngrokroot.crt
# make clean
make release-server release-client

Copy bin/ngrok to whatever computer you want to connect from. Then start the server:

bin/ngrokd -tlsKey=device.key -tlsCrt=device.crt -domain="$NGROK_DOMAIN" -httpAddr=":8000" -httpsAddr=":8001"

On Client

MAKE SURE YOU SET NGROK_DOMAIN BELOW. Set it to the base domain, not the wildcard domain.

NGROK_DOMAIN="my.domain.com"
echo -e "server_addr: $NGROK_DOMAIN:4443\ntrust_host_root_certs: false" > ngrok-config
./ngrok -config=ngrok-config 80

Or for SSH forwarding: ./ngrok -config=ngrok-config --proto=tcp 22

@gliheng
gliheng commented Jun 20, 2014

This helps a lot, thanks man!

@chenyang-tao

Great, it's working~ Thanks!

@prikevs
prikevs commented Mar 16, 2015

I've followed your guidance step by step, and write hosts on my client computer to alias my AWS ip, but 'bad certificate' problem still occurs. It's really weird...hmmm, but I'm trying to figure it out. Help me if you have any ideas about this. Thanks a lot.

@elgalu
elgalu commented Jul 8, 2015

Well done!

@solucionesmipc

hi:

i am using v1.7 , i can establish tunnels for http, but i cannot get https tunnel

my ngrok client config

server_addr: xxx.xxxxxxxxx.com:4443
trust_host_root_certs: false

tunnels:
secureweb:
proto:
https: 8080
ssh:
proto:
tcp: 22
web:
proto:
http: 80
please tell me what am i doing bad?

thanks a alot

luis

@goofansu

Thank you so much. I've created one as ngrok.com is slow in China.

@damtur
damtur commented Aug 17, 2015

Hey there,

I have question about *.host.com certificate. Why when I issue cert on *.host.com and compile code with same certificate ngrok client can't connect with server?
Why do I need *.host.com? Well to use https. I have been only able to set up tunnel with certificate issued on host.com. When after setting up a tunnel I type http://subdomain.host.com it works fine, but when I go to https://subdomain.host.com It doesn't work - it complains that certificate is not issued on subdomain.host.com but on host.com.
Also why if I create CA with host.com and then create server.crt with *.host.com it also doesn't work?
Can anyone please explain me how ngrok is using both those certs (root.pem and server.key, server.crt)

Thanks

@wouterhund

It might be a good idea to also edit defaultServerAddr in src/ngrok/client/model.go to $NGROK_DOMAIN:4443 (Don't put $NGROK_DOMAIN literally in the file. Put your domain there). Then everything will work for your users without them needing a config file.

Also you can easily cross-compile using GOPATH=$(pwd) gox -tags 'release' ngrok/main/ngrok (to install gox: go get github.com/mitchellh/gox), as long as you've done everything lined out in the gist above, including make release-client.

@goofansu

Just FYI, if you use server on linux and client on OS X, it will be very easy to use golang docker image to make a cross compile.

docker pull golang:1.4.3-cross
cd ngrok
docker run --rm  -v `pwd`:`pwd` -w `pwd` golang:1.4.3-cross make release-server
docker run --rm  -v `pwd`:`pwd` -w `pwd` -e GOOS=darwin -e GOARCH=amd64 golang:1.4.3-cross make release-client

Then in the bin directory, you can find ngrokd and darwin_amd64/ngrok.

🍻 😆

@lukehorvat

In my case, I needed a server binary for an Ubuntu droplet on Digital Ocean, and client binaries for a Macbook Pro and Raspberry Pi. So I did the following:

GOOS="linux" GOARCH="amd64" make release-server
GOOS="darwin" GOARCH="amd64" make release-client
GOOS="linux" GOARCH="arm" make release-client

All possible GOOS / GOARCH values are documented here.

@Yaoshicn

Thanks a lot! It works well!

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