npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mygrok

v2.1.0

Published

[![en](https://img.shields.io/badge/lang-en-red.svg)](https://github.com/PauloIVM/mygrok/blob/master/README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](https://github.com/PauloIVM/mygrok/blob/master/README.pt-br.md)

Downloads

11

Readme

myGrok :computer: :telephone_receiver: :computer:

en pt-br

Summary

Introduction

This is a tunneling tool to help you reduce infrastructure costs.

Strongly inspired by nGrok, myGrok is also a tunneling tool, however with the difference of establishing end-to-end tunnels. The idea is to run it on the side of the local server(s) and also on the side of a hosted server (with a fixed IP or domain).

myGrok tunnels have a more durable nature. That is, if you can maintain a hosted server with tunnels to other servers with dynamic IPs for several days, months or years. This is because myGrok has a re-connection system if the availability of local/dynamic servers drops for a short period of time (either due to the internet provider changing the IP, or actually a temporary internet outage).

Tunneling is done with symmetric encryption, providing security against any middle-man attack. In addition to a token (also encrypted), which can be passed to prevent third parties from connecting to your tunnels (which would be undesirable, as even if they were unable to decrypt the data, it would block your connection).

To learn more about the most suitable use cases for the lib, check out Motivation.

Installation

To use the lib as a CLI, simply run:

npm i -g mygrok

If you want to incorporate the lib into a project, you can also install it in the project without the -g flag.

Tutorial

myGrok has a command to be executed in the hosted application and a second command to be executed in one or more local applications (the applications that you want to expose through the tunnels).

The command to run on the hosted side is mygrok server <...options> and the command on the local side is mygrok client <...options>.

For the mygrok server command, the following parameters can be passed:

| Option | Argument | Description | Example | |--------|--------|--------|--------| | -h | <server-hosts> | Hosts available for clients to connect to via a tunnel. | -h foo.org,bar.org | | -p | <server-port> | Port on which mygrok-server will receive connections. | -p 3000 | | -r | <reconnection-timeout> | Maximum time for a client to reconnect to a mygrok-server host in milliseconds. | -r 8000 | | -t | <token> | Token for socket authentication. | -t my_token | | -s | <secret-key> | SecretKey for encryption of data transmitted through the tunnels. A string of exactly 32 characters must be passed. | -s T8s9G4j6M1x2D7p0W3q5B8z4L7v1N6k3 | | -m | <max-http-buffer-size> | Defaults = 1e6. If tunneling large files in a single strem-chunk, you may want increase this value. | -m 100000000 | | -e | | By default, only the headers of http requests are encrypted. Use this flag to also encrypt the request and response body data. | -e |

For the mygrok client command, the following parameters can be passed:

| Option | Argument | Description | Example | |--------|--------|--------|--------| | -h | <server-host> | One of the available hosts passed on the server to connect to. | -h foo.org | | -u | <server-url> | Server connection url. | -u https://foo.org | | -p | <client-port> | Port that mygrok-client will attempt to expose to mygrok-server. | -p 4000 | | -l | <client-hostname> | Hostname that mygrok-client will attempt to expose to mygrok-server | -l 0.0.0.0 | | -t | <token> | Token for socket authentication. | -t my_token | | -s | <secret-key> | SecretKey for encryption of data transmitted through the tunnels. A string of exactly 32 characters must be passed. | -s T8s9G4j6M1x2D7p0W3q5B8z4L7v1N6k3 | | -e | | By default, only the headers of http requests are encrypted. Use this flag to also encrypt the request and response body data. | -e |

Authentication and encryption are symmetric. That is, you must pass the same -t and -s in mygrok client and mygrok server. If the -e flag is used on the server, it must also be used on the client.

The -e flag is optional, you must use it if you want the body of tunneled requests and responses to also be encrypted. By default, only the headers are encrypted, for performance reasons; If you need to guarantee greater security, it may be interesting to use this configuration.

It is not strictly necessary for you to pass a token, because, given the encryption, the sokects connection will only be established if the mygrok client has the secret-key to properly encrypt the token. So, in practice you could not pass a token and a hard-coded default token would be used. However, it is interesting to pass a unique token to add another layer of security.

As for secret-key, it is very important that you enter a unique key, created by yourself and not shared, of 32 characters. This will ensure that the data transmitted through the tunnels is encrypted, and, if there is any intermediate proxy between your mygrok client and the mygrok server, it will not be aware of the information transmitted.

The -l flag of mygrok client is optional; by default the value will be localhost; but depending on the case you may want to pass another host, such as 0.0.0.0.

Examples

Hello world

For a first example, create a test-server.js file with the following code:

const http = require("http");
const PORT = 4000;
const server = http.createServer((req, res) => {
    req.on("data", () => {}).on("end", () => {
        res.end(`hello from port ${PORT}`);
    });
});
server.listen(PORT, () => {
    console.log(`Client server running on :: ${PORT}`);
});

Run the created script:

node test-server.js

This will be a generic server, which we might want to expose on another machine via myGrok tunneling.

Open a terminal and type:

mygrok server -p 3000

In another terminal, enter:

mygrok client -p 4000 -u http://localhost:3000

Now, if we do a curl to http://localhost:3000, we will see the JS server that we uploaded on port 4000 responding.

Alt text

Notice that the server is running on port 4000, but we are accessing port 3000 due to myGrok doing the tunneling that we configured with the two commands executed.

Of course, until then, we are running everything locally and on the same host, which may not make the purpose of the lib as clear. So let's move on to some more interesting uses.

Running multiple clients

Let's say you have something like an EC2 and an AWS Route 53 at your disposal. So, let's say you have directed several subdomains to this EC2, and you want each subdomain to connect to a different local process.

In this case, you can use the -h flag in mygrok server and mygrok client. On the server, you can pass multiple hosts, which are the hosts available for clients to connect to. Each host can remain connected to a single client; and if you try to establish a connection from a client to a host already connected to another client, then the handshake will fail.

To simulate this case, but still running everything locally, we can change /etc/hosts, adding more local hosts. When you open this file, you will likely find the line 127.0.0.1 localhost filled in; So, let's add other hosts as follows in this file:

127.0.0.1 localhost
127.0.0.1 server-a
127.0.0.1 server-b
127.0.0.1 server-c

Having added these hosts, now run three JS servers, similar to what we did in the previous example, each on a different port. Let's assume you booted one on port 4000, another on 4001, and another on 4002.

Now, we can run the server as follows:

mygrok server -h server-a,server-b,server-c -p 3000

And we run the tunnels for each of the clients:

mygrok client -h server-a -p 4000 -u http://localhost:3000
mygrok client -h server-b -p 4001 -u http://localhost:3000
mygrok client -h server-c -p 4002 -u http://localhost:3000

And ready. By accessing http://server-a:3000 in your browser, the proxy will be made to the local server running on port 4000. If you access the url with server-b, to 4001, and so on.

IMPORTANT: Remember to provide a valid secret-key to ensure encryption of data sent in the tunnels.

Motivation

Cloud services have made hosting web services much easier; however, in many cases, the costs can be daunting, especially if your software is not yet monetized and you have no money left over.

In these cases, there are some very interesting free solutions, for example:

Services like ngrok easily allow you to tunnel directly from your personal computer to the web. ddns services, such as duckdns, allow you to upload a local server using a dynamic IP, and, whenever your IP changes, this service will notice this and proxy it accordingly, or inform the client of the new IP adress.

So, what is the use of this project?

Imagine that you want to test an MVP, and leave a website up for a few days. Or you want to upload a portfolio to the air.

Still, it is possible to use ngrok, right? In the free mode, eventually your tunnel will die, and the application will stop working; Besides, the url provided is usually in the ngrok domain, generating only a specific sub-domain for your application. This could be bad if your case is testing an MVP; for example, what if your website relies minimally on SEO? What if you want to test a project for a while, without spending a lot, and only then decide whether to invest in more expensive infrastructure?

Okay, but then these ddns services would certainly work, wouldn't they? The disadvantage of not having your own domain may continue to be a problem. Additionally, depending on your internet provider, you may end up having problems if your provider uses CGNAT strategies. By this I mean that your provider could be using the same public IP for several clients (and each client with a private IP on the provider's network), and this would make it very difficult for the ddns server to proxy to your local server. In these CGNAT cases, the ideal is something based on tunneling, like ngrok.

Ok. In a case where I cannot resort to either ngrok or duckdns, it is inevitable that I will have to resort to cloud services or set up my on-premise infrastructure. What would this project be useful for then?

In this scenario, myGrok would be useful to reduce cloud costs (repair, reduce, not eliminate completely).

Imagine you have a ReactJS/NextJS project, and about two or three apis, plus a database. This is the MVP that wants to move up to the cloud. The EC2 t2.micro, which is a free machine offered by AWS, has only 1GB of RAM; It's possible that this won't even run your ReactJS application. If you are going to rent more machines, at the time of writing this readme, the cheapest instances cost around 6 dollars; Your project could easily end up being very expensive for a simple MVP or portfolio.

Still along these lines, my personal computer is an Intel Core I5 ​​with 32GB of RAM. A more or less equivalent AWS machine, the t3.2xlarge, 32GB, currently costs USD 0.3328 per hour, which gives us around 240 dollars per month!!

So, we arrive at the most suitable use case for myGrok. Imagine that you have a powerful local machine, with the possibility of leaving it on 24/7. You want to put a reasonably complex project into production, which requires considerable RAM and processing. You need, or want, to climb into a realm of your own.

Instead of renting a powerful machine like t3.2xlarge, you could rent a single t2.micro and create several tunnels pointing to apis running on your local server. In other words, myGrok allows you to rent only network services, but reducing computational costs given the use of your own machines.

In other words, the ideal scenario for myGrok is when you only want to rent network resources, but not computational resources, even if the cloud provider wants to sell you everything together in the same package.