# Overview

{% hint style="info" %}
**Need help or have feedback?** Reach us at **<hello@holesail.io>**.
{% endhint %}

Holesail is a **peer-to-peer networking and tunneling system** that lets you securely access services running on private machines, anywhere on the internet—without port forwarding, static IP addresses, user accounts, or centralized infrastructure.

Holesail creates direct, encrypted connections between peers. There are no relay servers, no traffic brokers, and no control plane that can observe your network or your data.

This documentation introduces the Holesail model, its guarantees, and how it differs from traditional VPNs and hosted tunneling solutions.

***

### How Holesail Works

Holesail connects two peers directly using a shared connection key (or QR code). That key enables:

* **Peer discovery** — only peers with the key can find each other
* **Authentication** — no usernames, passwords, or accounts
* **Encryption** — all traffic is end-to-end encrypted by default

Once connected, Holesail tunnels TCP and UDP traffic as if both peers were on the same local network.

There is no central coordination server, no relay path, and no metadata collection. Traffic flows **directly between peers**.

***

### Design Principles

#### Peer-to-Peer by Default

Holesail is built on a strictly peer-to-peer architecture. Connections are established directly between devices, without fallback relays or intermediaries.

Only the peer you explicitly share a connection key with can discover and connect to your service. Other peers on the network cannot see:

* What services you are running
* Whether those services are active
* Whether you are using Holesail at all

#### Zero Configuration

Holesail requires no network setup:

* No port forwarding
* No static IP addresses
* No firewall configuration
* No NAT or router changes

Run a single command, scan a QR code, and connect.

#### End-to-End Security

All Holesail connections are encrypted end to end. Encryption is applied automatically and cannot be disabled.

Because there are no intermediary servers, traffic never passes through third-party infrastructure. Data is visible only to the peers involved in the connection.

This model significantly reduces the attack surface compared to publicly exposed services or hosted tunneling systems.

#### Zero-Knowledge Architecture

Holesail does not operate any control plane or metadata service:

* No user accounts
* No identity database
* No connection logs
* No usage tracking

Holesail cannot see who is using the network, what is being shared, or how it is used.

#### Open Source

Holesail and all of its core components are fully open source. The source code is available for inspection, modification, and integration.

This enables independent security review and allows third parties to embed Holesail into their own products and workflows.

***

### Key Capabilities

* **Peer-to-peer tunnels**\
  Direct connections without intermediary servers.
* **Zero setup**\
  No configuration or networking expertise required.
* **TCP and UDP support**\
  Tunnel services that rely on either protocol.
* **Unlimited bandwidth**\
  No artificial limits or throttling.
* **End-to-end encryption**\
  Always on, with no trusted third parties.
* **Built-in file sharing**\
  Securely transfer files and folders between peers.
* **Cross-platform support**\
  Works on Linux, macOS, Windows, iOS, and Android using Bare modules and the Pear runtime.
* **Command-line interface**\
  Simple, scriptable CLI designed for automation and daily use.

***

### Common Use Cases

* Access private machines remotely without exposing ports
* Share locally running web servers, APIs, and AI models
* Secure SSH access without public IPs
* Play LAN-based games like Minecraft over the internet
* Transfer large files without size limits
* Access self-hosted services such as:
  * Vaultwarden
  * Portainer
  * RustDesk
  * Ollama
  * Minecraft servers
  * BTCPay Server

If a service runs locally, Holesail can make it reachable—securely and directly.

***

### Why Holesail

> *“It’s Tailscale but without servers, no accounts, and no complicated setup.”*\
> — Guy Swann

> It’s Tailscale but without servers, no accounts, and no complicated setup. Just scan the QR, and you’re connected, encrypted, fast, and easy.&#x20;
>
> — From [Guy Swann](https://x.com/TheGuySwann)

> I’ve become a Holesail addict. If I can’t just generate a key and connect remotely to my service now, I’m now just looking for a replacement that does let me do this. I don’t even try anymore. It’s either as easy as Holesail, or I’ll find a replacement 🤣
>
> — From [Pear Report](https://fountain.fm/episode/MyIucEf5hVoN3xsQmhbg)

> Just used @holesail\_io to connect to a service running on Linux localhost on my MacBook. I can use it easily and from anywhere.&#x20;
>
> \
> Even via Terminal, this is the easiest and quickest way I've ever connected two computers and shared a service/app. Generate key, paste key, done.

> Holesail allows us to provide a revolutionary Peer-to-Peer (P2P) tunnelling solution, giving users instant access to their local networks without the need for complex configurations. This innovative approach ensures seamless connectivity and robust security through end-to-end encryption.\
> — From [Discord Linux](https://discord-linux.com)

For teams and individuals who want private networking without infrastructure ownership or trust assumptions, Holesail offers a minimal, transparent alternative.

***

### Get Started

Follow the quickstart guides to install Holesail, generate a connection key, and connect your first service in minutes.


# Install through npm

Holesail is available through npm, which is an easy way to install and use it currently. All the latest updates, patches, and bug fixes are first applied to the npm package and then to everything else.

## Step 1- Install Nodejs

Holesail needs at least Nodejs version 16 >= or above to run. On Linux or Mac, you can use [NVM](https://github.com/nvm-sh/nvm) to install Nodejs.

Run the following command to install the Node version manager:

```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
```

Add nvm to the environment variable:

```bash
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
```

Close and reopen the terminal to install Nodejs 20:

```bash
nvm install 20
nvm use 20
```

### Install Nodejs Windows

You can install Nodejs on Windows by downloading a prebuilt installer from [here](https://nodejs.org/en/download/prebuilt-installer/current).&#x20;

## Step 2- Install Holesail through npm

Once you have the latest Node version installed, you can run the following commands to install Holesail.

**On Linux:**

```bash
sudo npm i holesail -g
```

**On Mac:**

```bash
npm i holesail -g
```

On Windows, open **command prompt** and type:

```bash
npm i holesail -g
```

If your installation fails on Windows, try running the command prompt instead of Powershell or Terminal. You can also try enabling third-party script execution by launching Powershell as Administrator and running:

```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
```

## Step 3 - Verify Installation

Run the following command, if it returns an output then holesail is installed on your system:

```bash
holesail --help
```

You are now all set to set sail with holesail.


# Holesail executable (Windows, Linux, Mac)

Holesail compiled executables for **Terminal** are available for all major platforms, i.e., Windows, Mac, and Linux. This procedure does not require installing or setting up Nodejs. You can simply download the executable and use it from the terminal.

## Step 1: Download Holesail executable

Head over to the[ latest release](https://github.com/holesail/holesail/releases/latest) page of Holesail on github and download the package that is compatible with your operating system and architecture.

If you do not download the correct file, it will result in an "unsupported architecture" error.

<figure><img src="/files/eeHOXCu7kJ7IuavdJYuV" alt=""><figcaption></figcaption></figure>

## Step 2: Mark as executable

On Mac and Linux, you need to mark the downloaded package as executable. CD to the directory where you have saved the file in Terminal and run the following command:

```bash
chmod +x holesail*
```

## Step 3: Run Holesail from Terminal

You can now call Holesail from the terminal by running it from the same directory where you have saved it:

{% hint style="info" %}
Make sure you are using the correct name for Holesail while executing this command
{% endhint %}

```bash
./holesail-macos-arm64-signed --help
```

<figure><img src="/files/jji6wQHaefnac5vB5pGN" alt=""><figcaption></figcaption></figure>

### Windows: Run Holesail from command prompt

On Windows, the process is slightly different:

1. Open Command prompt.
2. Go to the directory where holesail is saved.
3. Enter the name of the package, for example "[holesail-win-x64-unsigned.exe](https://github.com/holesail/holesail/releases/download/1.6.1/holesail-win-x64-unsigned.exe)" and press enter.
4. You will see a error message saying Invalid arguments, that implies holesail is now working on your system.
5. Check out usage guide. Use appropriate options and you are good to go.


# Holesail Go for Mobile

Holesail Go is our mobile application available on the [Apple Store](https://apps.apple.com/us/app/holesail-go/id6503728841) and the [Play store](https://play.google.com/store/apps/details?id=io.holesail.holesail.go). It supports all features available through the Holesail CLI.

<figure><img src="/files/U1I8J3eTcF2pthue9gBa" alt=""><figcaption></figcaption></figure>


# Docker Container

Holesail provides an official Docker image that allows you to run servers, clients, and the built-in file manager without installing Node.js or managing binaries manually.

Docker is the **recommended installation method** for:

* Headless servers (VPS, NAS, homelab)
* Production deployments
* Isolated or reproducible environments
* Easy upgrades and rollbacks

Requirements:

* Docker
* A system that supports host networking (Linux recommended)

Pull the docker image:

```bash
docker pull holesail/holesail:latest
```

### Server Mode

Runs a Holesail server that exposes a local service.

```
docker run -d --name holesail \
  -e MODE=server \
  -e PORT=25565 \
  -e HOST=127.0.0.1 \
  -e KEY=very-super-secret \
  -e PUBLIC=false \
  --network host \
  holesail:latest
```

### Client Mode

Connects to a remote Holesail server using its key.

```
docker run -d --name holesail-client \
  -e MODE=client \
  -e PORT=25565 \
  -e HOST=127.0.0.1 \
  -e KEY=very-super-secret \
  -e FORCE=true \
  -e LOG=true \
  --network host \
  holesail:latest
```

### File Manager Mode

Runs the Holesail file manager, allowing secure file access over P2P.

```
docker run -d \
  --name holesail-filemanager \
  -p 8080:8080 \
  -e MODE=filemanager \
  -e PORT=8080 \
  -e HOST=127.0.0.1 \
  -e PUBLIC=true \
  -e LOG=true \
  -e KEY=my-filemanager-key \
  -e FORCE=true \
  -e DIR=/app/files \
  -e USERNAME=admin \
  -e PASSWORD=securepass \
  -e ROLE=admin \
  -v /path/to/local/files:/app/files \
  holesail:latest
```

### Environment Variable Configuration

Holesail’s Docker image uses environment variables exclusively for configuration.\
The behavior is determined primarily by the `MODE` variable.

| Variable | Description                            |
| -------- | -------------------------------------- |
| `MODE`   | `server`, `client`, or `filemanager`   |
| `PORT`   | Local port to bind                     |
| `HOST`   | Bind address (default: `127.0.0.1`)    |
| `KEY`    | Connection key                         |
| `PUBLIC` | Allow public access (`true` / `false`) |
| `FORCE`  | Allow to use a short KEY               |
| `LOG`    | Enable logging                         |

File Manager Mode

| Variable   | Description              |
| ---------- | ------------------------ |
| `DIR`      | Directory to share       |
| `USERNAME` | Login username           |
| `PASSWORD` | Login password           |
| `ROLE`     | User role (e.g. `admin`) |

You can also define the flags above using a  `.env`  file if you choose to Docker compose instead of our existing image.


# Overview

Holesail can be segregated into mainly two parts, one is the **serve**r and other the **client**. When you set a port live (expose a port), you use the Holesail server, and when you connect to a Holesail server, you use a Holesail client.

## Step 1 : Share a port

Let's assume we have a react website running on localhost:8080, to share this service we need to run the following in terminal:

```
holesail --live 8080 --host localhost
```

<figure><img src="https://media.discordapp.net/attachments/1232882914635681823/1390098304104140943/image.png?ex=6867056e&#x26;is=6865b3ee&#x26;hm=c0f8c70030796bf6ed70422f0237a448bf6a19b54b44147032b6a47bc0517b33&#x26;=&#x26;format=webp&#x26;quality=lossless&#x26;width=759&#x26;height=370" alt=""><figcaption></figcaption></figure>

## Step 2: Connect to the server

Now, on a different computer (or even same) copy the connection key you got from the previous step  and run:

```
holesail <key>
```

<figure><img src="https://media.discordapp.net/attachments/1232882914635681823/1390098730664984576/image.png?ex=686705d4&#x26;is=6865b454&#x26;hm=af79c8f01b711262703958f696247c754d5a09732909988a7cbb705cf252c64c&#x26;=&#x26;format=webp&#x26;quality=lossless&#x26;width=822&#x26;height=370" alt=""><figcaption></figcaption></figure>

Replacing \<key> with the key your received from Step 1.

You can also scan the QR code using Holesail Go app on your phone to connect.

## Step 3: Access the application

**You are now connected, and the port from device 1 is available on device 2.** You can now access the running application on the provided URL after "Access application on". Which is localhost:8080 in this case.

<figure><img src="https://media.discordapp.net/attachments/1232882914635681823/1390099849369751552/image.png?ex=686706de&#x26;is=6865b55e&#x26;hm=ccfa5c1cf0c866b77e4075fd686643ace15a4538f632a04874879d61588cc485&#x26;=&#x26;format=webp&#x26;quality=lossless&#x26;width=822&#x26;height=370" alt=""><figcaption></figcaption></figure>

The port details used when the host started the connection will automatically transfer along with the connection, however, if the user on device 2 wants to utilize a different port and host, they may specify a custom port using the --port and --host flag.


# Start a Holesail server

It is quite easy to share a port securely with holesail:

```
holesail --live <PORT>
```

Supported flags:

| Option   | Purpose                                      | Required / Optional                           |
| -------- | -------------------------------------------- | --------------------------------------------- |
| --live   | Port to expose / set live                    | Required                                      |
| --host   | Listen to a custom host                      | Optional. Default is 127.0.0.1                |
| --public | Use public connection mode                   | Optional. Default is private connection mode. |
| --key    | Connect to a server using its key            | Optional. Automatically generated by default  |
| --force  | Bypass custom connection string length limit | Optional. Default is false                    |
| --log    | Start debug logging                          | Optional.                                     |

<mark style="color:orange;">Examples:</mark>

1. Start a Holesail server on port 3000 with default host and private mode:

```
holesail --live 3000
```

2. Start a Holesail server on port 3000 for sharing with third parties (public connection string):

```
holesail --live 3000 --public
```

3. Start a Holesail server on port 3000 with a custom host and custom connection string:

```
holesail --live 3000 --host 192.168.1.1 --key "my-custom-key-string"
```

4. Start a holesail server with custom connection key and its smaller than 32 characters:

```
holesail --live 4545 --key "its-quite-small" --force
```

You can combine multiple options according to your needs. After executing any of the command above, you will get a QR code and a connection string along with some basic information.

<figure><img src="https://media.discordapp.net/attachments/1232882914635681823/1390098304104140943/image.png?ex=6867056e&#x26;is=6865b3ee&#x26;hm=c0f8c70030796bf6ed70422f0237a448bf6a19b54b44147032b6a47bc0517b33&#x26;=&#x26;format=webp&#x26;quality=lossless&#x26;width=759&#x26;height=370" alt=""><figcaption></figcaption></figure>


# Connect to Holesail server

Run the following command to connect to a Holesail server instance:

```
holesail <KEY>
```

Supported options:

| Option    | Purpose                                           | Required / Optional            |
| --------- | ------------------------------------------------- | ------------------------------ |
| \<key>    | Connect to a holesail server                      | Required                       |
| --connect | Similar to doing holesail KEY\_STRING             | Optional                       |
| --host    | Bind to a custom host                             | Optional. Default is 127.0.0.1 |
| --port    | Specify a custom port to use on the local machine | Optional. Default is port 8989 |
| --log     | Start debug logging                               | Optional.                      |

<mark style="color:orange;">Examples:</mark>

1. Connect to a Holesail server with default options:

```
  holesail hs://s000a19f5778ccf3b7471fd45205758ad44a572aec1e7cdf76864613db0e63b8a49c
```

2. Connect to a Holesail server with a custom key and custom port:

```
  holesail my-custom-connection --port 8080
```

3. Connect to a Holesail server and listen on a custom port and host:

```
holesail "my-connection-key" --port 8765 --host localhost
```

4. Start a holesail server with custom connection string and its smaller than 32 characters:

```
holesail --live 4545 --key "its-quite-small" --force
```

You can use multiple flags as per your need. Once you are connected, you can access the running application on the host and port you specified before.

<figure><img src="https://media.discordapp.net/attachments/1232882914635681823/1390098730664984576/image.png?ex=686705d4&#x26;is=6865b454&#x26;hm=af79c8f01b711262703958f696247c754d5a09732909988a7cbb705cf252c64c&#x26;=&#x26;format=webp&#x26;quality=lossless&#x26;width=822&#x26;height=370" alt=""><figcaption></figcaption></figure>


# Filemanager

Holesail file manager let's you share files and folders with anyone and across devices with a single command.

There are no restrictions on the number of files that can be shared, the bandwidth or the size of the file.

**Command:**

```
holesail --filemanager
```

Supported options:

| Option             | Purpose                                                                            | Required / Optional                      |
| ------------------ | ---------------------------------------------------------------------------------- | ---------------------------------------- |
| --filemanager      | Start file manager in current directory                                            | Required                                 |
| --filemanager PATH | Start file manager in the given directory                                          | Optional                                 |
| --username         | Set a custom username for authentication                                           | Optional. Default is admin               |
| --password         | Set a custom password                                                              | Optional. Default is admin               |
| --role             | Allow a user to create folder and files by setting role to **admin**               | Optional. Default is "user".             |
| --connector        | Set a custom connection string. Can not be less than 32 chars or equal to 64 chars | Optional. The default is auto-generated. |
| --force            | Bypass custom connection string length limit                                       | Optional. Default is false               |

<mark style="color:orange;">Examples:</mark>

1. Start a filemanager session in the current directory with default username and password:

```
holesail --filemanager
```

2. Start a filemanager session in a custom directory with custom username:

```
holesail --filemanager "/Users/supersu" --username "holesail"
```

3. Start a filemanager session in a custom directory with custom username and password and admin role:

```
holesail --filemanager "/Users/supersu" --username "holesail" --password "securepass@99#123" --role admin
```

You can combine multiple options according to your needs. You will get a connection string and QR code that you can use to connect with Holesail filemanager and access in the browser.


# Connection Keys

## The Connection Key

A **connection key** is what you need to connect to someone with Holesail.&#x20;

The QR code has connection key stored in it for easy sharing.

Connection keys are automatically generated but you can specify custom connection keys. They should be at least 32 chars long for security purpose but you can override that with the --force flag.

### The Key and Keypair

Custom Keys act as a **seed** for generating a Keypair. This keypair is used to announce yourself on the peer-to-peer network and for authentication.

The keypair has a public key and a private key. We announce the public key on the network and that is what becomes your address, other peers will find you through this public key.

Private key on the other hand is a method for authentication. More on public and private keys in the next section.


# Private vs Public connection keys

Holesail has two connection modes, a private mode and a public mode. \
\
We use different terminology for the same:

* Private connection key and Public connection key
* Private mode and a Public Mode

## Private Connection Keys

Private connection keys are what Holesail connection's use by default, you can also specify a custom "key".

**From the custom key we derive a Keypair, that has a Public key and a Private key.** We announce the public key on the P2P [DHT](https://en.wikipedia.org/wiki/Distributed_hash_table) network. This public key is how other users will find you on the network.

On the client side,  When you share your private connection key with someone we will again derive a key pair and use the public key to find the server.

While establishing a connection the client has the same private key as the server and it is sent with the connection. The server will verify this private key and permit the connection, but if the key is incorrect or there is no private key set, the server will not respond at all.

This ensures, that other peer who know about your public key can not connect to you because they do not have the private key.

This process works pretty much like SSH. The public key can be considered your IP address which people know but they can not connect unless they have the private key.

{% hint style="info" %}
Treat Private connection strings how you would treat SSH key, do not share it with anyone you do not trust.\
\
If someone else start a server with your private connection string, they will take over.
{% endhint %}

## Public Connection Keys

With private connection key, we can access our system safely and know that no third party can connect without our permission, but they are only meant for personal use (like SSH) but what if we want to share the server with a third party?

This is where public connection keys come into play. This time we again generate a random Keypair, discard the private key and announce our public key on the P2P network.

The public key is what becomes your "Public connection key", there is no authentication involved, and you can safely share it with any third party as it is your address itself and not the seed.&#x20;

We like to compare public connection keys with Domains. They exist on the DHT, anyone can find you using it or by scanning the DHT and connect to you.

{% hint style="info" %}
Treat public connection keys like you would treat a domain name on a public server, if there is anything private on it, it is your responsibility to password protect it or use private connection keys instead.
{% endhint %}


