The ngrok project is composed of two components, the ngrok client (ngrok) and the ngrok server (ngrokd). The ngrok client is the more complicated piece because it has UIs for displaying saved requests and responses.
git clone git@github.com:inconshreveable/ngrok.git
cd ngrok && make
bin/ngrok [LOCAL PORT]
There are Makefile targets for compiling just the client or server.
make client
make server
NB: You must compile with Go 1.1+! You must have Mercurial SCM Installed.
Both the client and the server contain static asset files. These include TLS/SSL certificates and the html/css/js for the client's web interface. The release versions embed all of this data into the binaries themselves, whereas the debug versions read these files from the filesystem.
You should always develop on debug versions so that you don't have to recompile when testing changes in the static assets.
There are Makefile targets for compiling the client and server for releases:
make release-client
make release-server
make release-all
The strategy I use for developing on ngrok is to do the following:
Add the following lines to /etc/hosts:
127.0.0.1 ngrok.me
127.0.0.1 test.ngrok.me
Run ngrokd with the following options:
./bin/ngrokd -domain ngrok.me
Create an ngrok configuration file, "debug.yml" with the following contents:
server_addr: ngrok.me:4443
tunnels:
test:
proto:
http: 8080
Then run ngrok with either of these commands:
./bin/ngrok -config=debug.yml -log=ngrok.log start test
./bin/ngrok -config=debug.yml -log=ngrok.log -subdomain=test 8080
This will get you setup with an ngrok client talking to an ngrok server all locally under your control. Happy hacking!
At a high level, ngrok's tunneling works as follows:
Messages are sent over the wire as netstrings of the form:
<message length><message payload>
The message length is sent as a 64-bit little endian integer.
The definitions and shared protocol routines lives under src/ngrok/msg
All of the different message types (Auth, AuthResp, ReqTunnel, RegProxy, StartProxy, etc) are defined here and their fields documented. This is a good place to go to understand exactly what messages are sent between the client and server.
Code for the server lives under src/ngrok/server
The ngrokd entry point is in src/ngrok/server/main.go. There is a stub at src/ngrok/main/ngrokd/ngrokd.go for the purposes of creating a properly named binary and being in its own "main" package to comply with go's build system.
Code for the client lives under src/ngrok/client
The ngrok entry point is in src/ngrok/client/main.go. There is a stub at src/ngrok/main/ngrok/ngrok.go for the purposes of creating a properly named binary and being in its own "main" package to comply with go's build system.
The html and javascript code for the ngrok web interface as well as other static assets like TLS/SSL certificates live under the top-level assets directory.
More documentation can be found in the comments of the code itself.