Skip to content

Compiled binaries of the ngroklink software which utilizes ngrok's kubernetes bindings to achieve an "agent2agent" connection

Notifications You must be signed in to change notification settings

ngrok/ngroklink-distro

Repository files navigation

ngrok Link (ngroklink)

ngroklink provides a way to connect to remote services through a secure agent-to-agent tunnel without requiring direct access to those services. It creates secure connections between your local machine and remote services through the ngrok edge network.

How the Agent-to-Agent Model Works

ngroklink establishes secure connections using an agent-to-agent architecture:

  1. Remote Agent: A remote ngrok agent runs in proximity to the services you want to access.
  2. Local Agent (ngroklink): The ngroklink tool on your local machine acts as the local agent.
  3. Secure Connection: The two agents establish an encrypted tunnel through ngrok's edge network.
  4. Service Access: Traffic flows from your local applications through the tunnel to the remote services.

This architecture provides several advantages:

  • No direct exposure of services to the internet
  • End-to-end encryption between agents
  • No need for complex VPN setups
  • Access to services across network boundaries
┌─────────────┐     ┌───────────────┐     ┌────────────────┐     ┌─────────────┐
│             │     │               │     │                │     │             │
│   Local     │━━━━▶│   ngroklink   │━━━━▶│  Remote ngrok  │━━━━▶│   Remote    │
│ Application │     │ (Local Agent) │     │     Agent      │     │   Service   │
│             │     │               │     │                │     │             │
└─────────────┘     └───────────────┘     └────────────────┘     └─────────────┘

Setting Up the Remote Agent

Before using ngroklink on your local machine, you need to set up the remote ngrok agent at the service location.

Installing the Remote ngrok Agent

  1. Download the ngrok agent from ngrok.com for the appropriate platform
  2. Install and authenticate the agent using your authtoken:
    ngrok config add-authtoken YOUR_AUTHTOKEN

Starting the Remote Agent

You can start the remote agent in one of two ways:

Command Line Method

For TCP services:

ngrok tcp <port for your service> --url tcp://service.identifier:port --binding kubernetes

For HTTP services:

ngrok http <port for service> --url http://service.identifier --binding kubernetes

Replace <port for your service> with the actual port your service is running on, and service.identifier with a unique identifier for your service.

Using a Configuration File

For more complex setups, you can use the ngrok configuration file:

  1. Create a ngrok.yml file with your endpoint definitions
  2. Start the agent with this configuration: ngrok start --all

Example configuration:

version: 3
agent:
  authtoken: YOUR_AUTHTOKEN

endpoints:
  - name: my-http-service
    url: http://service.identifier
    binding: kubernetes
    upstream:
      url: http://localhost:8080
  
  - name: my-tcp-service
    url: tcp://service.identifier:5432
    binding: kubernetes
    upstream:
      url: tcp://localhost:5432

For more advanced configuration options, refer to the ngrok configuration documentation.

Setup

Installation

ngroklink provides platform-specific installation scripts to help you get started quickly:

For macOS and Linux:

  1. Download the appropriate zip file for your platform (e.g., ngroklink-darwin-arm64.zip for Apple Silicon Macs).
  2. Extract the zip file.
  3. Run the installation script:
    # For macOS
    ./install-macos.sh
    
    # For Linux
    ./install-linux.sh
    This will install ngroklink to /usr/local/bin so you can run it from anywhere.

For Windows:

  1. Download the Windows zip file (ngroklink-windows-amd64.zip).
  2. Extract the zip file.
  3. Run the install-windows.bat script and follow the prompts.

First-time Configuration

After installation, configure ngroklink with your ngrok credentials:

ngroklink --ngrok-api-key=YOUR_API_KEY --ngrok-authtoken=YOUR_AUTH_TOKEN

This will save your configuration to ~/.ngrok-agent/config.yaml for future use. You only need to do this once, or when you want to update your credentials.

Cleaning Up Configuration

If you need to start fresh or are redistributing ngroklink, you can clean up the existing configuration using the provided cleanup script:

./clean-config.sh

This will backup and remove your existing configuration file, allowing you to set up ngroklink again with new credentials.

Usage

ngroklink can be used in several ways:

1. Server Mode (Default)

In server mode, the agent connects to the ngrok API, registers with the remote agent, and starts all configured connections. To start the server mode with all your connections:

./ngroklink connect --all

This will start all your saved connections simultaneously, allowing you to access multiple services at once.

2. Connect Mode (One-off Connection)

In connect mode, the agent creates a local forwarding to a specific remote endpoint without saving it to the configuration. This is useful for temporary connections or quick testing.

./ngroklink connect ENDPOINT_URL --port=LOCAL_PORT_OR_HOSTPORT

Where:

  • ENDPOINT_URL is in the format protocol://service.identifier:port (e.g., tcp://myservice.prod:80)
  • --port can be either:
    • Just a port number (e.g., 8080) - This binds to localhost
    • A host:port combination (e.g., 192.168.1.10:8080) - This binds to the specific interface

Examples:

# Listen on localhost:8080
./ngroklink connect tcp://nginx.prod:80 --port=8080

# Listen on a specific network interface 192.168.1.10:8080
./ngroklink connect tcp://nginx.prod:80 --port=192.168.1.10:8080

# Listen on localhost but explicitly specify it
./ngroklink connect http://webapp.prod:80 --port=localhost:8080

The connection is established through the remote agent to the specified service. You can then access the service by connecting to your specified local address.

3. Managing Persistent Connections

The agent provides commands to manage persistent connections that will be started automatically in server mode:

Add a Connection

./ngroklink add --name=CONNECTION_NAME --url=ENDPOINT_URL --port=LOCAL_PORT_OR_HOSTPORT [--description=DESCRIPTION]

Examples:

# Using just port (binds to localhost)
./ngroklink add --name=nginx --url=tcp://nginx.prod:80 --port=8080 --description="Nginx web server"

# Using host:port format to bind to a specific interface
./ngroklink add --name=nginx-specific --url=tcp://nginx.prod:80 --port=192.168.1.10:8080 --description="Nginx on specific interface"

This saves a named connection to your configuration file. You can add multiple connections and start them all at once with the server mode.

Edit a Connection

./ngroklink edit CONNECTION_NAME [--url=ENDPOINT_URL] [--port=LOCAL_PORT_OR_HOSTPORT] [--description=DESCRIPTION]

Example:

# Update to use a specific IP binding
./ngroklink edit nginx --port=192.168.1.5:8080 --description="Updated nginx server with specific binding"

This updates the connection settings while keeping any non-specified settings unchanged.

List Connections

./ngroklink list

This displays all configured connections with their details, including any specific host bindings.

Remove a Connection

./ngroklink remove CONNECTION_NAME

Removes a connection from your configuration.

Start a Specific Connection

./ngroklink start CONNECTION_NAME

Starts a single named connection instead of all connections. This is useful when you only need one specific service.

4. Managing Configuration

Edit Configuration File Directly

You can directly edit the configuration file using your default text editor:

./ngroklink config edit

This opens the ~/.ngrok-agent/config.yaml file in your default editor (determined by the EDITOR environment variable, or defaults to nano).

5. Getting Help

The agent provides comprehensive help information:

# Display general help
./ngroklink --help

# Display help for a specific command
./ngroklink help COMMAND

# Or use the -h/--help flag with any command
./ngroklink COMMAND --help

Example:

./ngroklink help connect
./ngroklink config edit --help

Configuration File Format

The agent stores its configuration in ~/.ngrok-agent/config.yaml. The file contains:

  • Agent configuration with your ngrok credentials
  • A list of persistent connections

You can manually edit this file using the config edit command or use the CLI commands to manage your connections.

YAML Configuration Format

# Agent Configuration (Required)
connections_agent:
  authtoken: YOUR_AUTH_TOKEN
  api-key: YOUR_API_KEY

# Connections Definitions
connections:
  - name: example1
    description: Service 1 Description
    url: tcp://service1.prod:8080
    localport: 8080
  - name: example2
    description: Service 2 Description
    url: http://service2.prod:80
    localport: 8081
    localhost: 192.168.1.10  # Optional: specify binding interface

Note that:

  • The localport field is always required and specifies the port number
  • The localhost field is optional and specifies a specific host/interface to bind to
  • If localhost is not specified or is empty, the connection binds to localhost (127.0.0.1)
  • Optional fields like description can be omitted, and the agent will use default values

Comprehensive Example

Here's a more comprehensive example configuration with various types of services and binding options:

connections_agent:
  authtoken: 2ath1n3BXXtgPYwQmf9H1ubQXhVX_5XAjfZbeVzi7UYfudWXmD
  api-key: 2ath1q8TtdYye79qPAqTFSXcJJJi_4bciJZSYa4YfzGAsL2Jpn

connections:
  - name: nginx
    description: Nginx web server
    url: tcp://nginx.prod:80
    localport: 8080
    # No localhost specified - binds to 127.0.0.1 (default)
    
  - name: api-service
    description: REST API service with specific binding
    url: http://api-service.backend:8000
    localport: 3000
    localhost: 192.168.1.5  # Binds to this specific interface
    
  - name: postgres
    description: PostgreSQL database
    url: tcp://postgres.database:5432
    localport: 5432
    
  - name: grpc-service
    description: gRPC service on all interfaces
    url: tcp://grpc-service.services:50051
    localport: 50051
    localhost: 0.0.0.0  # Binds to all available network interfaces

With this configuration:

  • Accessing localhost:8080 would connect to the Nginx service through the remote agent
  • Accessing 192.168.1.5:3000 would connect to the API service through the remote agent
  • Accessing localhost:5432 would connect to the PostgreSQL database through the remote agent
  • Accessing <any-local-ip>:50051 would connect to the gRPC service through the remote agent (since it's bound to all interfaces)

Common Use Cases

Accessing Development Services

Connect to a development environment:

./ngroklink add --name=dev-frontend --url=http://frontend.dev:80 --port=3000 --description="Development Frontend"
./ngroklink add --name=dev-api --url=http://api.dev:8000 --port=8000 --description="Development API"
./ngroklink

Database Access

Connect to a database through the remote agent:

./ngroklink connect tcp://mysql.database:3306 --port=3306

Then use your database client to connect to localhost:3306.

Multi-Interface Connectivity

Access services on different network interfaces:

# Bind to WiFi interface for a web app
./ngroklink add --name=webapp --url=http://webapp.prod:80 --port=192.168.1.5:8080

# Bind to Ethernet interface for a database
./ngroklink add --name=database --url=tcp://db.prod:5432 --port=10.0.0.5:5432

# Bind to all interfaces for a monitoring service
./ngroklink add --name=monitoring --url=http://monitoring.prod:3000 --port=0.0.0.0:3000

Shared Service Access

Allow multiple users on the same network to access a service:

# Bind to all interfaces
./ngroklink connect tcp://shared-service.prod:80 --port=0.0.0.0:8080

Other users on the network can now access the service via your machine's IP address.

Technical Details

Connection Flow

When you start a connection with ngroklink, the following steps occur:

  1. Authentication: ngroklink authenticates with the ngrok API using your API key.
  2. Certificate Generation: A client certificate signing request (CSR) is generated locally.
  3. Certificate Signing: The CSR is sent to the ngrok API and signed.
  4. Agent Registration: ngroklink registers itself as a local agent.
  5. Binding Connection: A TLS connection is established to the ngrok edge (binding-ingress.ngrok.io:443).
  6. Connection Upgrade: The TLS connection is upgraded to a binding connection with information about the remote service.
  7. Local Listener: A TCP listener is started on your specified local port and interface.
  8. Traffic Forwarding: Each connection accepted on the local interface is paired with a new binding connection to the remote agent.
  9. End-to-End Flow: Traffic flows from your local application ➔ ngroklink ➔ ngrok edge ➔ remote agent ➔ remote service.

This allows you to securely connect to remote services without direct access to the remote network.

Security Model

ngroklink implements multiple security layers:

  1. API Authentication: Your ngrok API key authenticates requests to the ngrok API.
  2. Certificate-Based Authentication: Client certificates ensure only authorized agents can establish connections.
  3. TLS Encryption: All traffic between agents is encrypted using TLS.
  4. Mutual Authentication: Both the local and remote agents authenticate each other.
  5. Limited Scope: Each connection only provides access to the specific service defined in the configuration.
  6. Local File Security: The configuration file is stored with restricted permissions (0600).

Troubleshooting

If you encounter connection issues, verify:

  1. Your ngrok credentials are correct and have the necessary permissions
  2. The remote agent is properly configured and running
  3. The service identifier in the URL is correct (e.g., service.identifier)
  4. The service is accessible from the remote agent
  5. Your local port is not already in use by another application
  6. If using a specific interface, ensure it exists and is accessible

Common Issues

Connection Refused

If you see connection refused errors when trying to connect to your local port:

  • Check that ngroklink is running
  • Verify that you're connecting to the correct port and interface
  • Make sure the remote service identifier exists and is accessible from the remote agent

Authentication Errors

If you encounter authentication errors:

  • Ensure your API key and authtoken are correct
  • Check that your ngrok account has permissions to create agent bindings

Binding Errors

If you see errors about binding to an address:

  • Ensure the port is not already in use
  • Check that you have permissions to bind to the specified port (ports below 1024 typically require elevated privileges)
  • Verify that the interface/IP you specified exists on your system

Slow Connection

If connections are slow to establish:

  • The first connection might take longer as the agent needs to generate and sign a client certificate
  • Subsequent connections should be faster

Security Considerations

  • ngroklink stores your ngrok credentials in ~/.ngrok-agent/config.yaml. Ensure this file has appropriate permissions (the agent sets 0600 permissions automatically).
  • Client certificates are generated on-the-fly and stored in temporary files that are removed after use.
  • All connections are secured with TLS.
  • The agent uses mutual TLS authentication with the ngrok binding endpoint.
  • When binding to 0.0.0.0 (all interfaces), be aware that other users on your network may be able to access the service through your machine.
  • Consider using specific interface bindings instead of 0.0.0.0 when security is a concern.

About

Compiled binaries of the ngroklink software which utilizes ngrok's kubernetes bindings to achieve an "agent2agent" connection

Resources

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published