Run Ngrok on Your Own Server Using Self-Signed SSL Certificate

Using ngrok is a great way to quickly demo/show your development to other people or for other purposes that you can think of by creating a tunnel from your local computer to the internet and the best part is it is free, you don’t even need to sign up to use its service although signing up will provide you with additional features and you can even pay for even more additional features available for paid user. You can read more about the features from ngrok official website: https://ngrok.com/.

And oh, did I mention that it is actually open source? You can even run ngrok from your own server if you want to, maybe to get better latency (I think ngrok official server is locatedin US) or just to have your very own personal tunnel server which you can control. So with that said, let’s get started and run ngrok in your own server.

First you will need to install the build tools first in your linux installation if you haven’t done so since you are going to build and compile your own ngrok’s server and client. I’m using Ubuntu in this tutorial, so you can install it by running the following command:

Next you will need to install go language tools as well since ngrok is developed using go language.

Ngrok also relies on mercurial (version control) so you will need to have it installed in your system otherwise it won’t build.

Install all the required tools/packages

Once you have everything installed, you are set to build and compile your own ngrok’s server and client. So, clone ngrok’s github into your working directory (or whatever directory you wanted), and run the following command to clone ngrok’s github and change your working directory to ngrok:

Clone ngrok repository

By the way you can find ngrok’s github page here: https://github.com/inconshreveable/ngrok

Once it has finished cloning ngrok to your local machine, there is yet another thing you will need to do before you can build and compile your very own ngrok server and client and that is to create your own self-signed SSL certificate and this is required because ngrok provides the secure tunnel via TLS and in order for both the client and server to work you will need to build and compile ngrok using your self signed SSL certificate and these are linked to each other. So you cannot connect to your self-signed ngrokd server via the official ngrok client as both the server and client need to be signed using the same certificate.

So let’s get  started by creating the SSL certificate. You can create the certificate by running the following command:

Generating certificate pair for ngrok server and client

Replace [NGROK_BASE_DOMAIN] (tunnel.svenbit.com in the screenshot) in the command stated above with the base domain of your choice where you wish to run your ngrok from. For example if you are planning to run your ngrok tunnels from [whatever-tunnel].yourdomain.com, set the [NGROK_BASE_DOMAIN] to yourdomain.com, or if you are planning to run your ngrok tunnels from *.ngrok.yourdomain.com subdomain, set the [NGROK_BASE_DOMAIN] to ngrok.yourdomain.com. And if you notice the following files will be generated as a result of the commands that we run earlier above:

With that said you also need to setup wildcard ( * ) A record that points to your ngrok’s server IP address, configuration may vary on different domain registrars so you may want to check with your domain registrar about the details. I’m using namecheap for as my domain registrar and I’m going to run ngrok from tunnel subdomain (svenbit.com), so all I need to do is to add a wildcard A record under that subdomain that points to my ngrok’s server:

Setup host record for ngrok

Here’s a few more example:

Ngrok Base Domain HostName Ngrok Tunnel Url
yourdomain.com * [ngrok-generated-url].yourdomain.com
tunnel.yourdomain.com *.tunnel [ngrok-generated-url].tunnel.yourdomain.com
ngrok.yourdomain.com *.ngrok [ngrok-generated-url].ngrok.yourdomain.com
tunnel.ngrok.yourdomain.com *.tunnel.ngrok [ngrok-generated-url].tunnel.ngrok.yourdomain.com

Now that you have generated your own certificate and configured your domain all you need to do left is to build/make ngrok, but first you will need to replace ngrok’s default client certificate file located at assets/client/tls/ngrokroot.crt with the one that you have just created:

Replace default ngrok client certificate with the one that you have just created

Now build/make the executable for both the server (release-server) and client (release-client), it may takes a while:

Make ngrok server and client

Once it is done, the executable will be available inside /bin directory: ngrok is the client executable and ngrokd is the server executable. You may need to make the file executable first by running the following command:

And also, take note that the default executable generated is for Linux.

Running Ngrok Server

To start ngrok server, you will need server.key and server.crt that we generated earlier, so I suggest copying the executable (ngrokd) to some directory or to the server you wish to start ngrok server from along with the server.key and server.crt files together in one directory to make it easier (I have uploaded ngrokd executable along with the certificate files to my public server in the screenshot below):

Putting ngrokd (server) executable and the certificates together

And then you can start ngrok server by running the following command (you may need root permission, run with sudo or su or whatever . . .):

Fire up that ngrokd server!

Again, replace [NGROK_BASE_DOMAIN] with the very same domain that you specify when you generate the certificate file earlier. You can change the httpAddr port and httpsAddr to any port that you wanted, just make sure that it is accessible and is not used by other services.

Your ngrok server should now be accessible from the domain ([NGROK_BASE_DOMAIN]) and port that you specify. To test it out try accessing it from your web browser:

For example, since my ngrok base domain is tunnel.svenbit.com and I set the httpAddr port to 8080 I can test my ngrok server by accessing the following url:

Testing out ngrok server

Note: Cat is not included in ngrok default page

Also, if you notice from the screenshot ngrok server and its tunnels will only be accessible via the subdomain of the base domain that you specified ([NGROK_BASE_DOMAIN]), so ngrok server will catch all any request (wildcard) made to the subdomains under ngrok base domain that you specified, and not the base domain itself.

And now that the server is running, next is to connect to the server using the client executable.

Running Ngrok Client

Now that you have run ngrok server, you can connect to the server using ngrok executable generated earlier. Again, this client can only be used to the ngrok server that you created earlier and cannot be use to connect to the official ngrok server due to the certificate pairing (they are made for each other @.@). Copy ngrok client executable to the server or computer that you want to connect from. And create a configuration file in the same directory with the ngrok client executable, you can name it anything you want (config.txt, ngrok.cfg, my.config, etc. . .).

Just paste the following text into the configuration file:

Creating ngrok client configuration file #1

 

Creating ngrok client configuration file #2

Again, for the million times, replace [NGROK_BASE_DOMAINwith your own base domain. And if you are wondering trust_host_root_certs is set to false because the certificate is self-signed, and server_addr is well, where your ngrok server located at along with the port number where 4443 is the default access port for ngrok.

Once the config file is in place you can connect to your own ngrok server by running the following command, please replace [YOUR_CONFIG_FILE_NAME] with the name of the configuration file that you have just created:

The command above will allow you to connect to your local 80 port from  testing subdomain of your ngrok server, in this case it will be accessible from http://testing.tunnel.svenbit.com:8080. If you did not specify the -subdomain parameter ngrok will generate one for you.

Running ngrok client

 

Ngrok client in action

 

Ngrok tunnel test page

You can even use ngrok to tunnel tcp connection to specific port, for example for your MySQL Server, like so:

For other usages, I suggest you read more about it from ngrok’s official page: https://ngrok.com/usage.

Well that’s it, now you have your own ngrok server which you can use for development purposes or anything that you find applicable.

  • janw23

    I typed “make release-server release-client” and it showed: GOOS=”” GOARCH=”” go get github.com/jteeuwen/go-bindata/go-bindata

    github.com/jteeuwen/go-bindata

    src/github.com/jteeuwen/go-bindata/release.go:36: function ends without a return statement
    src/github.com/jteeuwen/go-bindata/release.go:55: function ends without a return statement
    src/github.com/jteeuwen/go-bindata/toc.go:48: function ends without a return statement
    make: *** [bin/go-bindata] Error 2
    How to fix that?

    • Hmm.. I just tested again with clean workspace and it works fine, it appears to be something to do with go-bindata from https://github.com/jteeuwen/go-bindata repository . Can you post me your golang version?

      go version

      And what version of linux distro and version are you running on? Is it Ubuntu? Try to check whether you have go-bindata executable inside your ngrok’s bin folder and remove it if it’s available then try to run “#make release-server release-client” command again.

  • xiaozhang

    Happy new year

    Could the ngrok server (running on RaspberryPi) in a subnet? I got my domain in namecheap too. but what IP the HOST NAME (@ www)point to. I need it point to my pi, which is located in a subnet?

    • Hi xiaozhang,

      I’m not really certain if it is possible if the ngrok server is located in a different subnet, but I have tried setting up ngrok server behind a router, I just need to properly setup the port forwarding on the router to the ngrok server, so it may be possible to setup the ngrok server in a subnet.

  • Pingback: 内网穿透神器-ngrok,自建ngrok服务器 | 沛哥博客()

  • david

    Is it possible to set NGROK_BASE_DOMAIN as IP?

    • Hi david, I don’t think it is possible to use IP address as the NGROK_BASE_DOMAIN as it needs to be a domain name.

    • Jose Barahona

      yes it can be, actually am using ngrok like that thru a strange config with a vpn that not allowed to pass domain or direct internet traffic.

  • Hi

    Thank for this awesom tut.

    How can I build client for windows OS when my server is on linux system.
    Thank

    • Hi Creative Mentor,

      To build the client and server for Windows OS go to the ngrok directory and run the following command:

      sudo GOOS=windows GOARCH=386 make release-client release-server

      The command above will build the executable for Windows (32-bit) and it will be placed inside bin/windows_386 directory. $GOOS and $GOARCH above refers to name of the target operating system and architecture respectively. To view the full list of available GOOS and GOARCH you can refer to the following documentation: https://golang.org/doc/install/source#environment

      So let say to build the 64-bit version for windows you can run the following command:

      sudo GOOS=windows GOARCH=amd64make release-client release-server

      You will also need to run the command above as root (sudo) as it needs to access golang windows library.

      • Hello my friend !
        Thanks so much for your reply. Let me try it. I will let you know if I am facing a problem.
        Have a nice day

        • Hi
          I have just done the make release client and server for ngrok. I got two exe files : ngrokd.exe and ngrok.exe. the ngrok.exe is for my windows client, but I can’t run ngrokd.exe (the server version ) under ubuntu. Do I have to make another make-release server just for the ubuntu server?
          thank.

          • Hi!

            If you are planning to run the server on Ubuntu then you can just use the ngrokd executable that should be generated in the first place if you follow the guide above, which should be located inside the bin folder, if the executable is not there then you will need to run:

            That should create the server’s executable file for linux (ngrokd) and it will be placed inside the bin directory. Don’t forget to make it executable:

            After you have run the ngrokd server on your Ubuntu server you can just use ngrok.exe from your Windows client to connect to the server.

          • Good morning bro
            Ok. I understand your explanations. I will try it in the next second.

  • Hello SvenBit
    I have followed what you told me and I have build a windows executable. But I am still not able to run the app. My windows client can’t connect to my server. It keep saying reconnecting. Is there any special configuration I have
    to make for the client side as you did for the linux client side to make
    my ngrok client work on window.

    When I make http request to my xxxx.tunnel.domain.com I can get : Tunnel my xxxx.tunnel.domain.com not found.
    I think I am doing something wrong. Need help please.
    Thank you anyway

    • Hi Creative Mentor,

      Good to know that you manage to get it working and I’m glad that you find the guide useful 🙂

  • Hello
    My ngrok client is doing something wrong, and I don’t know why. My ngrok base domain is for exemple ngrok.mydomain.com, but ngrok client make a forwardind adress to something like http://testing.ngrok.mydomain.com.ngrok.mydomain.com:8081 as if my base domain was ngrok.mydomain.com.ngrok.mydomain.com

    what am I doing wrong

  • Hi SvenBit
    I need some help again;
    I would like to keep ngrok server running even if I close putty. I have used screen but that seems not to work. Is there a way.
    Also I want to know if it is possible to run mutliple simultaneous ngrok client?
    Thank u.
    Have a nice day

    • Hi Creative Mentor,

      You can use nohup command to run ngrokd server in background. For example to run ngrokd server in background you can type in the following command:

      Take note that, the command above will write the output from ngrokd server to /dev/null which means that the information will not be logged. If you want, you can change /dev/null to a file instead to write the output into the file.

      To kill the ngrokd server you will need to find the process ID using the following command:

      Get the first process ID listed from the output and run the kill -9 command followed by the process id to stop the process. (if no output is displayed that means that the ngrokd server is not running, you may need to run kill command as root). Ex:

      Check the attached image below for reference.

      And to answer your last question, yes, you can run multiple ngrok client at the same time 🙂

      • Hi
        nohup command not doing the job. I am looking for another solution. I let you know if I found something. Thank again for your help.

        • Hi Creative Mentor,

          Can you try the following command instead:

          Notice the -log option, and no nohup required this time. (from ./ngrokd –help)

          • Hi Sebastian
            Your command work great. I have used it since yesterday and ngrok is still running although putty was off.

            But I have another big problem….You remember when I asked you If I could run multiple ngrok client?

            When I run simultaneous ngrok client, some of them change automatically the server listening port.
            For exemple from 8000 to 8001. And this make me keep changing the port to the 8001 or getting it back to 8000 to have my url work.

            Is there anyway to prevent the port to change when running multiple client on the same time.

            Very sorry for my english. And thank you again for all your help.

            Do you have whatsapp?

          • Hi Creative Mentor,

            Sorry for the late reply. It seems that you are trying to run multiple ngrok server (ngrokd) not ngrok client (ngrok), if you are trying to run multiple ngrok server at the same time I don’t think it is possible.

          • Hi Sebastian
            The system is going better now. I would like to thank you again for all your help toward me.
            It was very kind .

          • Hi Creative Mentor,

            You are welcome, I’m happy that you managed to get it working and find the guide useful 🙂

  • Damian Turczyński

    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
    Damian

  • Gean Ceretta

    Thanks Sebastian. Works like a charm.

  • wangjinwei2008

    hell

    src/ngrok/main/ngrokd/ngrokd.go:4:2: no buildable Go source files in /usr/local/go/src/ngrok/server

  • wangjinwei2008

    hello

    src/ngrok/main/ngrokd/ngrokd.go:4:2: no buildable Go source files in /usr/local/go/src/ngrok/server

  • wangjinwei2008

    how to move

    can’t load package: ../../go/src/ngrok/ngrok/src/ngrok/client/tls.go:9:2: cannot find package “ngrok/client/assets” in any of:

    /usr/local/go/src/ngrok/client/assets (from $GOROOT)

    /usr/local/src/ngrok/src/ngrok/client/assets (from $GOPATH)

    can’t load package: src/ngrok/server/tls.go:6:2: cannot find package “ngrok/server/assets” in any of:

    /usr/local/go/src/ngrok/server/assets (from $GOROOT)

    /usr/local/src/ngrok/src/ngrok/server/assets (from $GOPATH)

    ?

    • Hi there,

      Did you pull from the latest branch? I will need to check first, can you try to re-pull the branch and redo the steps ? It seems to be missing some files.

      • wangjinwei2008

        thank you ! lLast night I was successful。。。

  • Hi there,

    Did you pull from the latest branch? I will need to check first, can you try to re-pull the branch and redo the steps?

  • bobjoy

    Hi, i as you said, step by step, finally the Windows OS client can be connected to the Server normally, but the Mac OS client connection, the prompt bad certificate

    • Andres Rocha

      I don’t know if its the case but remember to recompile using GOOS and GOARCH on the PC where you created the server certificates, also to add the final line to the client configuration file

  • Andres Rocha

    Hi! I followed every single step of your guide even I created 3 different compilations to troubleshoot using GOOS and GOARCH because I pretend to put the client on a raspberry as well as on windows but the problem is, I can’t get to connect the client with the server, if I type any tunnel I get the “tunnel not found” as @Creative mentor said, also I read that he fixed it with the client configuration file
    But in my case I couldn’t
    I created the configuration file and used it while starting ngrok (./ngrok -subdomain xxx -config=config.txt 80) but it seems like the client is never getting to the server as there is no evidence in the server log
    Am I missing something?
    Please help!

    • Since there is no evidence in the server log, it could be due a few things. Have you configured the A host record on the domain name? And do you have firewall activated on the server? You may need to open the port if firewall is active on the server.

      • Andres Rocha

        I find out what the problemas was, i followed your tutorial many times and encounter as many possible problems as I could so I think the best way to thank you is to share possible fixes for the problems that I faced.
        First I point out a simple step that could be as clear as possible in the tutorial but I struggled to understand that we have to create TWO HOST RECORDS (I figured it out when I revisited your tutorial and found your two lines) the first one is for the wildcards *.tunnel.domain.com
        And the second is for the creation of these domains at the control port 4443 on the base ngrok name, this step created my problem as it seems like you didn’t have any other hosted webpage on your base domain, or you hosted your webpage on your selfserver.
        So, the problem that I faced about the server was basically that I had a front end webserver at the (ngrok base domain) hosted on my domain (godaddy domain+godaddy hosting account).
        This problem could be faced by others if they had a webpage and they try to set the tunnels based on the main server name
        As you pointed (*.domain.com).
        Because as the domain gets all the wildcards and redirect it to the IP of the selfserver (this step is good) then the second host record (the one directed to the 4443 port) would interfere with the hosting that I previously had.
        ##I hope I’ve been clear as I’m struggling to make it as clear as possible##
        So the fix and the short version of the story is this: I you have a hosting account and a webserver you cannot have your wildcards as short as *.domain.com as your control account would be domain.com and it cannot be redirected, fix it by adding another name as *.tunnel.domain.com as your control server will be on tunnel.domain.com:4443

        Another problem:
        Also I compiled this tutorial about 4 days ago and it was good but yesterday I recompiled and I found that one dependency (log4go) was creating problems, so for the people that could face this problem, the fix is just to update the dependency as it seems like code.Google is taking down their stuff to pass it to github I will find again the server and the line that I edited and post it next.

        Finally the last problem.
        You already fixed this one but for another platform, well many people are using raspberry to run either the server or the client so if you want to compile this for your raspberry the the line you need is this:
        sudo GOOS=Linux GOARCH=arm GOARM=6 make release-client release-server (this works on raspi b+ as they run on armv6 processors)

        Thank you very much for this tutorial you helped a lot on our project.
        Andres Rocha

        • Andres Rocha

          OK I found the dependency again, maybe ngrok’s development team could fix it but until then if you have problems with this dependency then go to src/ngrok/log/logger.go then sudo nano it and edit the line that says
          log “code.google.com/p/log4go”
          And change it to:
          log “github.com/keepeye/log4go”
          And that’s it you shouldn’t have any other problems with “deps”

          • Awesome! Glad you manage to get it working 🙂

            Perhaps I should make the steps on setting up the domain name clearer, it can be rather confusing.

            And thank you for listing out the possible problems along with the solutions. I am sure it will help others who had similar issues 😀

  • Pingback: 内网穿透神器-ngrok,自建ngrok服务器 | 沛哥博客 – Log@X.X.B()

  • Pingback: 自己建立ngrok服务器进行内网穿透 – 老高的技术博客 ‹ Log@X.X.B()

  • Tobias Schulz

    can i build a client with an existing purchased ssl cert?

  • Raffaele Pantaleoni

    Hello. Thanks for your tutorial. I am a software writer (mainly c/c++). I have followed all of your instructions but when it comes to “make release-server” (and release-client as well) I receive the following error:
    #make release-server
    GOOS=”” GOARCH=”” go get github.com/jteeuwen/go-bindata/go-bindata
    # github.com/jteeuwen/go-bindata
    src/github.com/jteeuwen/go-bindata/toc.go:47: function ends without a return statement
    make: *** [bin/go-bindata] Error 2

    I don’t know the go language, nevertheless I tried to take a look at the toc.go source file but I can’t get which object or value should be returned.

    My system is running Debian Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.84-1 x86_64 GNU/Linux

    Thank you.
    Raffaele

Search