Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
How to setup Ngrok with a self-signed SSL cert


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.


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

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.

git clone
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.

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 commented Jun 20, 2014

This helps a lot, thanks man!

Great, it's working~ Thanks!

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 commented Jul 8, 2015

Well done!


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

my ngrok client config

trust_host_root_certs: false

https: 8080
tcp: 22
http: 80
please tell me what am i doing bad?

thanks a alot


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

damtur commented Aug 17, 2015

Hey there,

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


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, as long as you've done everything lined out in the gist above, including make release-client.

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.

🍻 😆

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.

Thanks a lot! It works well!

I just want to point out a thing for the people that stumble upon this article (very helpful btw, thank you). It is really important that you compile you server and client application with the certificate that your going to use already copied into the assets/client/tls/ folder. Otherwise you'll get the Failed to read message: remote error: bad certificate error.

Hi @danielmorandini , I'm getting the error you mentioned. Don't really understand your suggestion on how to fix it, do you mind to explain more? Thanks!

@danielmorandini , @h4ck4life,

same problem here. Tried to rebuild client with custom root CA but its not working, still getting errors of invalid certificates..

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