# NoPorts Documentation

NoPorts improves remote access security and simplifies network and firewall configuration. Devices using NoPorts have no exposed ports, making them undetectable on a network scan.

## Proactive Security

NoPorts shifts the security paradigm from “ports are open, I need to close them” to “ports are closed, I need to open them (securely).” Ports are closed and secure by default, allowing you to manage only the things you actively use.

Communication between devices is always peer-to-peer and end-to-end encrypted. Encryption keys are cut and stored securely on the device and controlled by the device owner.

Available via both command line and as a desktop application, NoPorts is already being used in the field to replace VPNs and firewalls, enable zero-trust remote access, improve cloud security, and apply Atsign’s preemptive security approach to a wide range of industries and use cases.

### Products

**NoPorts management suite**

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><mark style="color:orange;"><strong>NoPorts Policy Service</strong></mark></td><td>Centralizes access controls, allowing administrators to define and enforce security policies for NoPorts connections.</td><td></td></tr><tr><td><mark style="color:orange;"><strong>NoPorts Desktop Application</strong></mark></td><td>Allows you to make remote connections via a full desktop application for MacOS and Windows. (Also available for Linux, but we do not currently ship release builds)</td><td></td></tr><tr><td><mark style="color:orange;"><strong>NoPorts Relay</strong></mark></td><td>Acts as an intermediary to facilitate secure connection handshakes acting as the open network surface, so that your devices remain secure.</td><td></td></tr></tbody></table>

**NoPorts command line suite**

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><mark style="color:orange;"><strong>NoPorts Tunnel</strong></mark> <mark style="color:orange;"><strong>Client</strong></mark> <mark style="color:orange;"><strong>(npt)</strong></mark></td><td>Establishes secure, encrypted tunnels for remote access to any application.</td><td></td></tr><tr><td><mark style="color:orange;"><strong>NoPorts SSH Client (sshnp)</strong></mark></td><td>Enables remote SSH access without exposing ports by leveraging NoPorts' outbound connectivity.</td><td></td></tr><tr><td><mark style="color:orange;"><strong>NoPorts Daemon (sshnpd)</strong></mark></td><td>A background agent which enables a machine to act as a NoPorts “endpoint” – to this machine, or machine in the same subnet, depending on how it’s configured.</td><td></td></tr></tbody></table>

### Get Started

Click below to learn everything you need to get started with NoPorts.

{% content-ref url="/pages/jVNX8tPSINRznfW0UQfd" %}
[Getting Started](/getting-started)
{% endcontent-ref %}

### Usage

If you don't understand how something works, or if you want to see the full configuration options, check out the Usage section.

{% content-ref url="/pages/FKKETDYe7URRgWfIGr2B" %}
[Usage](/usage)
{% endcontent-ref %}

### Need Help?

{% content-ref url="/pages/D4JvEGLU5gxP5ijyvGlH" %}
[Frequently Asked Questions](/reference/faq)
{% endcontent-ref %}

<details>

<summary><mark style="color:orange;">via Email</mark></summary>

Send us an email: <support@noports.com>

Monday - Friday, 6am - 6pm (PT)

</details>

<details>

<summary><mark style="color:orange;">via Discord</mark></summary>

[Join our Discord](https://discord.gg/atsign-778383211214536722) for technical support. Our team and community are here to help!

</details>


# Getting Started

This page details everything you need to get started with NoPorts.

### Let's Talk About Keys

To make your NoPorts installation smoother and easier to understand, take a moment to watch this short video explaining NoPorts cryptographic keys.

{% embed url="<https://vimeo.com/1075825418>" %}

### Getting Started Overview

{% stepper %}
{% step %}

### <mark style="color:orange;">Sign up for NoPorts</mark>

Sign up for a NoPorts subscription or free trial, which includes 2 Atsigns.
{% endstep %}

{% step %}

### <mark style="color:orange;">Install the NoPorts Client</mark>

Download and install the NoPorts Client on the machine you are connecting from.
{% endstep %}

{% step %}

### <mark style="color:orange;">Install the NoPorts Daemon</mark>

Download and install the NoPorts Daemon onto the machine(s) you are connecting to.
{% endstep %}

{% step %}

### <mark style="color:orange;">Use NoPorts</mark>

Use NoPorts or explore the use cases available below.
{% endstep %}
{% endstepper %}

### <mark style="color:orange;">Step 1. Sign up for NoPorts</mark>

You'll need to head over to [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans) to sign up for a NoPorts subscription or free trial.

{% hint style="warning" %}
During sign up, you will receive your Atsigns. Ensure that you make note of them for reference during installation.
{% endhint %}

### <mark style="color:orange;">Steps 2 and 3. Install NoPorts</mark>

We offer a range of installation options to suit your needs. Choose from our quick-start guides, which let you try NoPorts with our test connection, or see our detailed, step-by-step instructions to help you set up your own machines.

{% content-ref url="/pages/0Z1heMX2MntV0MTxrIr0" %}
[Installation](/installation)
{% endcontent-ref %}

### <mark style="color:orange;">Step 4. Use NoPorts</mark>

NoPorts has endless use cases. We've provided a list of the most common ones:

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><mark style="color:purple;"><strong>MCP</strong></mark></td><td><a href="/pages/ngtuNiJYcjB4gYtlWQGf">/pages/ngtuNiJYcjB4gYtlWQGf</a></td><td><a href="/files/AHJ3mRqyQnOskSaYEYeB">/files/AHJ3mRqyQnOskSaYEYeB</a></td></tr><tr><td><mark style="color:blue;"><strong>SSH</strong></mark></td><td><a href="/pages/q5v7yL2pgoevZqZa94KB">/pages/q5v7yL2pgoevZqZa94KB</a></td><td><a href="/files/eA6on0oxsESvXDDrawVk">/files/eA6on0oxsESvXDDrawVk</a></td></tr><tr><td><mark style="color:orange;"><strong>SFTP</strong></mark></td><td><a href="/pages/91NY3Ha8Uy9I7loW436y">/pages/91NY3Ha8Uy9I7loW436y</a></td><td><a href="/files/0XGG48D2NmCX2fkwtfbt">/files/0XGG48D2NmCX2fkwtfbt</a></td></tr><tr><td><mark style="color:green;"><strong>RDP</strong></mark></td><td><a href="/pages/f0ZZQzMPcerYMHsbOiw6">/pages/f0ZZQzMPcerYMHsbOiw6</a></td><td><a href="/files/9kIPElrt8Kd7t0gJIIfL">/files/9kIPElrt8Kd7t0gJIIfL</a></td></tr><tr><td><mark style="color:purple;"><strong>Web Server</strong></mark></td><td><a href="/pages/JO4Som2PYbhCBqNpFjQm">/pages/JO4Som2PYbhCBqNpFjQm</a></td><td><a href="/files/Be616FYn3mf2ljgQteiI">/files/Be616FYn3mf2ljgQteiI</a></td></tr><tr><td><mark style="color:blue;"><strong>SMB</strong></mark></td><td><a href="/pages/683e2mYrUQrq6cpsZ68Q">/pages/683e2mYrUQrq6cpsZ68Q</a></td><td><a href="/files/UcMdb5ibOsh24s2jyKIK">/files/UcMdb5ibOsh24s2jyKIK</a></td></tr><tr><td><mark style="color:orange;"><strong>Be your own VPN</strong></mark></td><td><a href="/pages/DqvnLHx0noZHUa0bwJbt">/pages/DqvnLHx0noZHUa0bwJbt</a></td><td><a href="/files/6wDX6WVQ8w37r3rDIINC">/files/6wDX6WVQ8w37r3rDIINC</a></td></tr></tbody></table>

We recommend reviewing the [resources page](/installation-faq) before beginning your installation.


# Installation

Get started with NoPorts! Find secure remote access setup instructions and installation guides for each OS on this page.

Getting Started Overview

{% stepper %}
{% step %}

### <mark style="color:orange;">Sign up for NoPorts</mark>

Sign up for a NoPorts subscription or free trial, which includes 2 Atsigns.
{% endstep %}

{% step %}

### <mark style="color:orange;">Install the NoPorts Client</mark>

Download and install the NoPorts Client on the machine you are connecting from.
{% endstep %}

{% step %}

### <mark style="color:orange;">Install the NoPorts Daemon</mark>

Download and install the NoPorts Daemon onto the machine(s) you are connecting to.
{% endstep %}

{% step %}

### <mark style="color:orange;">Use NoPorts</mark>

Use NoPorts or explore the use cases available [here](/use-cases).
{% endstep %}
{% endstepper %}

### Sign up for a NoPorts subscription or free trial

Head over to [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans) to sign up for a subscription or free trial.

{% hint style="warning" %}
During registration, you will receive your atSigns. Ensure that you make note of them for future reference.
{% endhint %}

### Quick Start for macOS and Windows Only

Follow these guides to try NoPorts using the desktop application. You can establish a remote connection to our test connection page or set up a connection to your own remote machine.

{% content-ref url="/pages/UBIFJlGGrXiEBF5v5kbF" %}
[Quick Start from macOS or Windows](/installation/quick-start-for-macos-and-windows)
{% endcontent-ref %}

### Install via CLI for macOS, Linux and Windows

Follow these detailed guides to install NoPorts via the command line and use it for establishing remote connections to your devices.

Select your operating system and remote device to see specific installation instructions.

<details>

<summary>Connecting from macOS</summary>

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>to macOS</td><td><a href="/pages/KpWgO1Itckpy4LvfTY4O">/pages/KpWgO1Itckpy4LvfTY4O</a></td></tr><tr><td>to Linux</td><td><a href="/pages/RzoGBd68DdgxYSuNikHu">/pages/RzoGBd68DdgxYSuNikHu</a></td></tr><tr><td>to Windows</td><td><a href="/pages/NgiK5BOFF4USJgaRA0gr">/pages/NgiK5BOFF4USJgaRA0gr</a></td></tr></tbody></table>

</details>

<details>

<summary>Connecting from Linux</summary>

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>to macOS</td><td><a href="/pages/PdZH0ENKBZX7MaHm2WmN">/pages/PdZH0ENKBZX7MaHm2WmN</a></td></tr><tr><td>to Linux</td><td><a href="/pages/ygLnhEaPe7epa74zK2Oe">/pages/ygLnhEaPe7epa74zK2Oe</a></td></tr><tr><td>to Windows</td><td><a href="/pages/50lmyhIFNFMw4e7tiSi6">/pages/50lmyhIFNFMw4e7tiSi6</a></td></tr></tbody></table>

</details>

<details>

<summary>Connecting from Windows</summary>

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>to macOS</td><td><a href="/pages/aGYOqLSEhKihPuMSxLbD">/pages/aGYOqLSEhKihPuMSxLbD</a></td></tr><tr><td>to Linux</td><td><a href="/pages/lgRoNLVK7Bps7Rd33J7R">/pages/lgRoNLVK7Bps7Rd33J7R</a></td></tr><tr><td>to Windows</td><td><a href="/pages/KSBNqhx7QgpbTFM5aaqf">/pages/KSBNqhx7QgpbTFM5aaqf</a></td></tr></tbody></table>

</details>

### Other Installation Options

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Cloud Installation</strong></td><td><a href="/files/VER69eR1kFgGbdytXI2v">/files/VER69eR1kFgGbdytXI2v</a></td><td><a href="/pages/jT8vUMJ57K5HPthO6Wbf">/pages/jT8vUMJ57K5HPthO6Wbf</a></td></tr><tr><td><strong>OpenWrt Installation</strong></td><td><a href="/files/ZvnivXsBD16pdghzMgVj">/files/ZvnivXsBD16pdghzMgVj</a></td><td><a href="/pages/pAgEt8Tpzh6bpVlClMRr">/pages/pAgEt8Tpzh6bpVlClMRr</a></td></tr><tr><td><strong>Manual Installation</strong></td><td><a href="/files/vqEN5ZVdFEVNSg2JbxQh">/files/vqEN5ZVdFEVNSg2JbxQh</a></td><td><a href="/pages/xZdWqkN0ILndj5WRlDHi">/pages/xZdWqkN0ILndj5WRlDHi</a></td></tr><tr><td><strong>Custom OS Installation</strong></td><td><a href="/files/MgdGiSCMvo52Cj5gLDGJ">/files/MgdGiSCMvo52Cj5gLDGJ</a></td><td><a href="/pages/30LDOHUciGe1dOVpSmvN">/pages/30LDOHUciGe1dOVpSmvN</a></td></tr><tr><td><strong>Installs at Scale</strong></td><td><a href="/files/pq39GlrG0XN5LKJiFwC8">/files/pq39GlrG0XN5LKJiFwC8</a></td><td><a href="/pages/0hpxWmYU7ywF5R1YYuji">/pages/0hpxWmYU7ywF5R1YYuji</a></td></tr><tr><td><strong>Upgrading NoPorts</strong></td><td><a href="/files/180lOcg80hMp7GZxXm1B">/files/180lOcg80hMp7GZxXm1B</a></td><td><a href="/pages/RCtqsElPwgiAXD3Bqmle">/pages/RCtqsElPwgiAXD3Bqmle</a></td></tr></tbody></table>

## Use NoPorts

Start by exploring the available use cases, such as [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb). We also provide in-depth usage information here.

{% content-ref url="/pages/FKKETDYe7URRgWfIGr2B" %}
[Usage](/usage)
{% endcontent-ref %}

### Need Help?

{% content-ref url="/pages/D4JvEGLU5gxP5ijyvGlH" %}
[Frequently Asked Questions](/reference/faq)
{% endcontent-ref %}

<details>

<summary><mark style="color:orange;">via Email</mark></summary>

Send us an email: <support@noports.com>

Monday - Friday, 6am - 6pm (PT)

</details>

<details>

<summary><mark style="color:orange;">via Discord</mark></summary>

[Join our Discord](https://discord.gg/atsign-778383211214536722) for technical support. Our team and community are here to help!

</details>


# Quick Start from macOS or Windows

How to quickly install and try NoPorts on both MacOS and Windows devices.

This guide is intended for people connecting from a machine running Windows or macOS.

{% hint style="info" %}
For people connecting from Linux please follow the [Linux Installation Guide](/installation/connecting-from-linux).
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Sign up for NoPorts or log into the NoPorts Management Portal

If you have not already signed up or purchased NoPorts, go to [my.noports.com](https://my.noports.com/no-ports-invite/30dayfreetrial) and sign up for a subscription or free trial then proceed to **Step 2**.\
\
If you already have a NoPorts account, you’ll need to start by logging into the Management Portal. Go to [my.noports.com/login](https://my.noports.com/login) and enter your registered email address to receive your one‑time password. Once logged in, select the subscription for the Atsigns you want to activate, then continue with the instructions below.

{% hint style="info" %}
Make note of your atSigns (e.g., @example01\_np, @example02\_np). You'll need them shortly.
{% endhint %}

### <mark style="color:orange;">Step 2:</mark> Initiate Atsign activation in the Management Portal

1. Click **Activate All** and wait for the activation file to be generated.
2. Once its completed, download the activation file. It should look something like youratsigns\_activation\_file.yaml.

### <mark style="color:orange;">Step 3:</mark> Download the NoPorts desktop application

Download the NoPorts desktop app using one of the links below:

[Link to Apple Store](https://apps.apple.com/ca/app/noports-desktop/id6737338881)

[Link to Windows Store](https://apps.microsoft.com/detail/9n69scrrgv6r)

{% hint style="info" %}
For people connecting from Linux please follow the [Linux Installation Guide](/installation/connecting-from-linux).
{% endhint %}

### <mark style="color:orange;">Step 4:</mark> Complete Atsign activation in the NoPorts desktop application

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client atSign, while `@example02_np` will represent the device atSign.
{% endhint %}

1. Launch the NoPorts desktop application and click **Get Started** and then click **Complete Activation**
2. Upload or drag and drop you activation file (.yaml) and then click **Next**.

{% hint style="info" %}
If you don’t have an activation file, you can activate your Atsigns individually by entering each one in the Manual Atsign section and following the steps provided in the app.
{% endhint %}

{% hint style="danger" %}
For Windows, if the app stalls at "Preparing for activation", verify that your CA certificates are up to date.
{% endhint %}

### <mark style="color:orange;">Step 4:</mark> Save your atKeys

Your atKeys (cryptographic keys) will be used to pair your Atsign with this and other devices in future. You can [learn more about these keys here](https://www.youtube.com/watch?v=bRRLCOHP-BY).

1. Click on **Save atKeys**
2. Select a memorable location on your machine and **save** your keys.

All your Atsigns will be activated and the keys will be saved in your chosen location.

### <mark style="color:orange;">Step 5:</mark> Generate a device atSign authorization passcode

Once the activation process is complete you will be signed in using one of your activated Atsigns. This will be your device Atsign, e.g. @example02\_np.

Click on **Authenticator** at the top of the screen and then click on **OTP.** Take note of the 6-character code as you will use it in **Step 8**.

### <mark style="color:orange;">Step 6:</mark> Switch to the machine you are connecting to OR use a demo profile to access our test page

Now that your Atsigns are ready, you can either set up your remote machine or try our hidden test page.

* **Remote machine setup:** Install NoPorts on the remote machine, authorize Atsign access to the remote machine and create a connection profile in the desktop app (about 10 minutes).
* **Test page:** Try our demo profile to access our hidden test page if you don't have a machine to connect to.

**Remote Machine Setup**\
Please select the operating system running on the machine you are connecting to and follow the relevant instructions on that machine:

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th></tr></thead><tbody><tr><td><strong>macOS</strong></td><td><a href="/pages/XkZhWKVdm8V1sAtX9kZJ">/pages/XkZhWKVdm8V1sAtX9kZJ</a></td><td><a href="/files/F0WmszFofGp7DSDipNBc">/files/F0WmszFofGp7DSDipNBc</a></td></tr><tr><td><strong>Linux</strong></td><td><a href="/pages/NMzUY7wnPIL3c9b4Hehk">/pages/NMzUY7wnPIL3c9b4Hehk</a></td><td><a href="/files/WaLiS3PiY6Qv356ZX3Dr">/files/WaLiS3PiY6Qv356ZX3Dr</a></td></tr><tr><td><strong>Windows</strong></td><td><a href="/pages/m231xEtORXNWtDxlilfl">/pages/m231xEtORXNWtDxlilfl</a></td><td><a href="/files/jRoC58DcqkZNiKv5h53s">/files/jRoC58DcqkZNiKv5h53s</a></td></tr></tbody></table>

**OR Test Page**

1. In the NoPorts desktop application, on the Connections tab, you'll see a banner saying "Demo. Click here to load the test profile." Click **Try Now.**
2. Once the profile has been added to your list, click the **Connect Icon ▶️** to establish a connection.
3. Open a web browser and navigate to`http://localhost:8080`.

Congratulations! You're connected to a hidden webpage via NoPorts!


# Quick Start to macOS

This guide provides instructions for connecting from the NoPorts desktop application, to a machine running macOS .

### Step 7 and Step 8

Complete these steps **on the machine you are connecting to (MacOS)**

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 7:</mark> Download and run the Installer

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `device` when prompted.

**Your Atsigns**

* Client Atsign: e.g., `@example01_np`
* Device Atsign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.

### <mark style="color:orange;">Step 8:</mark> Initiate atSign authorization request

Run the following command to make an authorization request:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 5**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

</details>

### Step 9 to Step 12

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 9:</mark> Approve the atSign authorization request

1. Click on **Requests** and approve the pending request. The request will then move to the approved enrollments list.
2. After a few seconds, the request will also show as approved on the machine you are connecting to.

### <mark style="color:orange;">Step 10:</mark> Switch to your client atSign (@example01\_np)

1. Click on **your Atsign** in the top right corner of the screen. This will open a list of atSigns that are currently signed into the app.
2. Select the one you would like to use as your **client Atsign** in order to switch to it.

### <mark style="color:orange;">Step 11:</mark> Create a Connection Profile

1. If you aren't already on the Connections tab, click on **Connections** at the top of the Screen. Then click **Add New**, to create a new profile.
2. Enter the following information into the profile then click **Submit**.
   1. Profile Name - The name that will be displayed in the profile list.
   2. Device Atsign - Your device Atsign (eg example02\_np).
   3. Device Name - The name of your remote device.
   4. Relay - Select the relay sever closest to you for optimum speed.
   5. Local Port - The port you will use on your local machine.
   6. Local Host - The hostname or IP address to bind to on your local machine.
   7. Remote Host - The hostname or IP address of the machine you are connecting to.
   8. Remote Port - The port that will be used on the remote machine.

For reference, we've documented our most common use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

### <mark style="color:orange;">Step 12:</mark> Establish a connection

Click the **Connect Icon ▶️** to establish a connection with your remote device. If the connection is successful, you will see green. If you see red, hover over the icon to see reason for failure.

</details>


# Quick Start to Linux

This guide provides instructions for connecting from the NoPorts desktop application, to a machine running Linux.

### Step 7 and Step 8

Complete these steps **on the machine you are connecting to (Linux)**

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 7:</mark> Download and run the Installer

{% hint style="warning" %}
Do not run the following commands while logged in as the root user. Instead, use `sudo` from a regular account when elevated privileges are required, and create a regular account if one does not already exist.
{% endhint %}

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
sudo ./universal.sh
```

NB the device install *can* be done without `sudo` but that will just install the binaries in the user's `$HOME/.local/bin` directory. `sudo` is used to install into `/usr/bin` and configure systemd services.

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `device` when prompted.

**Your atSigns**

* Client Atsign: e.g., `@example01_np`
* Device Atsign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.

### <mark style="color:orange;">Step 8:</mark> Initiate Atsign authorization request

Run the following command to make an authorization request:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 5**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

</details>

### Step 9 to Step 12

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 9:</mark> Approve the Atsign authorization request

1. Click on **Requests** and approve the pending request. The request will then move to the approved enrollments list.
2. After a few seconds, the request will also show as approved on the machine you are connecting to.

### <mark style="color:orange;">Step 10:</mark> Switch to your client Atsign (@example01\_np)

1. Click on **your Atsign** in the top right corner of the screen. This will open a list of Atsigns that are currently signed into the app.
2. Select the one you would like to use as your **client Atsign** in order to switch to it.

### <mark style="color:orange;">Step 11:</mark> Create a Connection Profile

1. If you aren't already on the Connections tab, click on **Connections** at the top of the Screen. Then click **Add New**, to create a new profile.
2. Enter the following information into the profile then click **Submit**.
   1. Profile Name - The name that will be displayed in the profile list.
   2. Device atSign - Your device Atsign (eg example02\_np).
   3. Device Name - The name of your remote device.
   4. Relay - Select the relay sever closest to you for optimum speed.
   5. Local Port - The port you will use on your local machine.
   6. Local Host - The hostname or IP address to bind to on your local machine.
   7. Remote Host - The hostname or IP address of the machine you are connecting to.
   8. Remote Port - The port that will be used on the remote machine.

For reference, we've documented our most common use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

### <mark style="color:orange;">Step 12:</mark> Establish a connection

Click the **Connect Icon ▶️** to establish a connection with your remote device. If the connection is successful, you will see green. If you see red, hover over the icon to see reason for failure.

</details>


# Quick Start to Windows

This guide provides instructions for connecting from the NoPorts desktop application, to a machine running Windows.

### Step 7 to Step 9

Complete these steps **on the machine you are connecting to (Windows)**

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 7:</mark> Download and run the Installer

Download the NoPorts msi installer [from GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-windows-x64.zip). You can run the MSI inside the sshnp-windows zip.

Ensure both Core Tools & Daemon Service are being installed.

<figure><img src="/files/2mtUgH0jFj3LuoFFpqnp" alt=""><figcaption></figcaption></figure>

### <mark style="color:orange;">Step 8:</mark> Initiate Atsign authorization request

Open a terminal (Command Prompt or PowerShell) and run the following command to make an authorization request.

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 5**,

`<USER>` with your **Windows username**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">at_activate.exe enroll -a "@&#x3C;REPLACE>_np" `
<strong>  -s &#x3C;PASSCODE> `
</strong><strong>  -p noports `
</strong><strong>  -k C:\Users\&#x3C;USER>\.atsign\keys\@&#x3C;REPLACE>_np_key.atKeys `
</strong><strong>  -d &#x3C;DEVICE_NAME> `
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

{% hint style="info" %}
If you encounter a handshake exception, it usually means your root certificates are outdated. To refresh them, run the following command with administrator privileges:<kbd>Install-Script -Name UpdateRootCertificates</kbd>
{% endhint %}

### <mark style="color:orange;">Step 9:</mark> Setup Service Config

The service config lives in C:\Program Data\NoPorts\sshnpd.yaml, you can open it in notepad buy running the following command:

{% hint style="danger" %}
Make sure you run notepad/terminal as administrator or else you won't be able to save your changes!
{% endhint %}

```
notepad C:\ProgramData\NoPorts\sshnpd.yaml
```

Ensure you provide the following fields to your service config:

* **atsign**
  * `atsign: example02_np`
  * `atsign: '@example02_np'`
* **keys (windows path)**
  * `keys: C:\Users\alice\.atsign\keys\@example02_np_key.atKeys`
* **manager**
  * `manager: example01_np`
  * `manager: '@example01_np'`

Examples on how to fill in the fields are inside the config file.

</details>

### Step 10 to Step 13

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 10:</mark> Approve the Atsign authorization request

1. Click on **Requests** and approve the pending request. The request will then move to the approved enrollments list.
2. After a few seconds, the request will also show as approved on the machine you are connecting to.

### <mark style="color:orange;">Step 11:</mark> Switch to your client Atsign (@example01\_np)

1. Click on **your Atsign** in the top right corner of the screen. This will open a list of atSigns that are currently signed into the app.
2. Select the one you would like to use as your **client Atsign** in order to switch to it.

### <mark style="color:orange;">Step 12:</mark> Create a Connection Profile

1. If you aren't already on the Connections tab, click on **Connections** at the top of the Screen. Then click **Add New**, to create a new profile.
2. Enter the following information into the profile then click **Submit**.
   1. Profile Name - The name that will be displayed in the profile list.
   2. Device Atsign - Your device Atsign (eg example02\_np).
   3. Device Name - The name of your remote device.
   4. Relay - Select the relay sever closest to you for optimum speed.
   5. Local Port - The port you will use on your local machine.
   6. Local Host - The hostname or IP address to bind to on your local machine.
   7. Remote Host - The hostname or IP address of the machine you are connecting to.
   8. Remote Port - The port that will be used on the remote machine.

For reference, we've documented our most common use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

### <mark style="color:orange;">Step 13:</mark> Establish a connection

Click the **Connect Icon ▶️** to establish a connection with your remote device. If the connection is successful, you will see green. If you see red, hover over the icon to see reason for failure.

</details>


# Copy of Quick Start from macOS or Windows

How to quickly install and try NoPorts on both MacOS and Windows devices.

This guide is intended for people connecting from a machine running Windows or macOS.

{% hint style="info" %}
For people connecting from Linux please follow the [Linux Installation Guide](/installation/connecting-from-linux).
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Sign up for a NoPorts free trial

Go to [noports.com](https://my.noports.com/no-ports-invite/30dayfreetrial) and sign up for a subscription or free trial

{% hint style="info" %}
Make note of your atSigns (e.g., @example01\_np, @example02\_np). You'll need them shortly.
{% endhint %}

### <mark style="color:orange;">Step 2:</mark> Download the NoPorts desktop application

Download the NoPorts desktop app using one of the links below:

[Link to Apple Store](https://apps.apple.com/ca/app/noports-desktop/id6737338881)

[Link to Windows Store](https://apps.microsoft.com/detail/9n69scrrgv6r)

{% hint style="info" %}
For people connecting from Linux please follow the [Linux Installation Guide](/installation/connecting-from-linux).
{% endhint %}

### <mark style="color:orange;">Step 3:</mark> Activate your client atSign (@example01\_np)

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client atSign, while `@example02_np` will represent the device atSign.
{% endhint %}

1. Launch the NoPorts desktop app and click **Get Started**.
2. Enter your **client atSign** into the text field (e.g., @example01\_np), leave the root domain as is, and then click **Next**.
3. A **one-time password (OTP)** will be sent to you via email. Enter this OTP into the app and then click **Confirm**.

{% hint style="info" %}
For Windows, if the app stalls at "Preparing for activation", verify that your CA certificates are up to date.
{% endhint %}

### <mark style="color:orange;">Step 4:</mark> Save a copy of your client atKeys

Your atKeys (cryptographic keys) will be used to pair your atSign with this and other devices in future. You can [learn more about these keys here](https://www.youtube.com/watch?v=bRRLCOHP-BY).

1. Click on **Save atKeys**
2. Select a memorable location on your machine and **save** your keys.

### <mark style="color:orange;">Step 5:</mark> Establish a connection

**Connection Options**\
You can either connect to your own remote machine or use our hidden test connection page.

* **Remote machine setup:** Activate a second atSign, install NoPorts on the remote machine, and create a connection profile in the desktop app (about 10 minutes).
* **Test connection:** Use the hidden test page for a quicker option.

Select a tab below to continue.

{% tabs %}
{% tab title="Your Remote Machine" %}

### <mark style="color:orange;">Step 5.1:</mark> Activate your device atSign (@example02\_np)

{% hint style="warning" %}
Both the atSigns are activated on the machine you are connecting from. Later, you’ll grant your remote machine access to the keys stored on this machine.
{% endhint %}

1. You'll need to switch atSigns. To sign out from the client atSign, click on **your atSign** at the top right of the screen, then select **Sign Out**.
2. Click **Get Started** and enter your **device atSign** into the text field (e.g., @example02\_np). Leave the root domain as is, and then click **Next**.
3. A **one-time password (OTP)** will be sent to you via email. Enter this OTP into the app and then click **Confirm**.

### <mark style="color:orange;">Step 5.2:</mark> Save a copy of your device atKeys

Your atKeys (cryptographic keys) will be used to pair your atSign with this and other devices in future. You can [learn more about these keys here](https://www.youtube.com/watch?v=bRRLCOHP-BY).

1. Click on **Save atKeys**
2. Select a memorable location on your machine and **save** your keys.

### <mark style="color:orange;">Step 5.3:</mark> Generate a device atSign authorization passcode

Click on **Authenticator** at the top of the screen and then click on **OTP.** You will use this 4 character code in **Step 7**.

### <mark style="color:orange;">Step 5.4:</mark> Switch to the machine you are connecting to

Please select the operating system running on the machine you are connecting to and follow the relevant instructions:

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>macOS</strong></td><td><a href="/pages/XkZhWKVdm8V1sAtX9kZJ">/pages/XkZhWKVdm8V1sAtX9kZJ</a></td></tr><tr><td><strong>Linux</strong></td><td><a href="/pages/NMzUY7wnPIL3c9b4Hehk">/pages/NMzUY7wnPIL3c9b4Hehk</a></td></tr><tr><td><strong>Windows</strong></td><td><a href="/pages/m231xEtORXNWtDxlilfl">/pages/m231xEtORXNWtDxlilfl</a></td></tr></tbody></table>
{% endtab %}

{% tab title="Our Test Page " %}

1. On the Connections tab, you'll see a banner saying "Demo. Click here to load the test profile." Click **Try Now.**
2. Once the profile has been added to your list, click the **Connect Icon ▶️** to establish a connection.
3. Open a web browser and navigate to`http://localhost:8080`.

Congratulations! You're connected to a hidden webpage via NoPorts!
{% endtab %}
{% endtabs %}


# Quick Start to macOS

This guide provides instructions for connecting from the NoPorts desktop application, to a machine running macOS .

### Step 6 and Step 7

Complete these steps **on the machine you are connecting to (MacOS)**

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 6:</mark> Download and run the Installer

Download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `device` when prompted.

**Your atSigns**

* Client atSign: e.g., `@example01_np`
* Device atSign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.

### <mark style="color:orange;">Step 7:</mark> Initiate atSign authorization request

Run the following command to make an authorization request:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device atSign**,

`<PASSCODE>` with the **passcode generated in Step 5**,

`@<REPLACE>_np_key` with your **device atSign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

</details>

### Step 8 to Step 11

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 8:</mark> Approve the atSign authorization request

1. Click on **Requests** and approve the pending request. The request will then move to the approved enrollments list.
2. After a few seconds, the request will also show as approved on the machine you are connecting to.

### <mark style="color:orange;">Step 9:</mark> Switch back to your client atSign (@example01\_np)

1. Click on **your atSign** in the top right corner of the screen. This will open a list of atSigns that are currently signed into the app.
2. Select your **client atSign** in order to switch to it.

### <mark style="color:orange;">Step 10:</mark> Create a Connection Profile

1. If you aren't already on the Connections tab, click on **Connections** at the top of the Screen. Then click **Add New**, to create a new profile.
2. Enter the following information into the profile then click **Submit**.
   1. Profile Name - The name that will be displayed in the profile list.
   2. Device atSign - Your device atSign (eg example02\_np).
   3. Device Name - The name of your remote device.
   4. Relay - Select the relay sever closest to you for optimum speed.
   5. Local Port - The port you will use on your local machine.
   6. Local Host - The hostname or IP address to bind to on your local machine.
   7. Remote Host - The hostname or IP address of the machine you are connecting to.
   8. Remote Port - The port that will be used on the remote machine.

For reference, we've documented our most common use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

### <mark style="color:orange;">Step 11:</mark> Establish a connection

Click the **Connect Icon ▶️** to establish a connection with your remote device. If the connection is successful, you will see green. If you see red, hover over the icon to see reason for failure.

</details>


# Quick Start to Linux

This guide provides instructions for connecting from the NoPorts desktop application, to a machine running Linux.

### Step 6 and Step 7

Complete these steps **on the machine you are connecting to (Linux)**

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 6:</mark> Download and run the Installer

{% hint style="warning" %}
Do not run the following commands while logged in as the root user. Instead, use `sudo` from a regular account when elevated privileges are required, and create a regular account if one does not already exist.
{% endhint %}

Download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `device` when prompted.

**Your atSigns**

* Client atSign: e.g., `@example01_np`
* Device atSign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.

### <mark style="color:orange;">Step 7:</mark> Initiate atSign authorization request

Run the following command to make an authorization request:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device atSign**,

`<PASSCODE>` with the **passcode generated in Step 5**,

`@<REPLACE>_np_key` with your **device atSign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

</details>

### Step 8 to Step 11

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 8:</mark> Approve the atSign authorization request

1. Click on **Requests** and approve the pending request. The request will then move to the approved enrollments list.
2. After a few seconds, the request will also show as approved on the machine you are connecting to.

### <mark style="color:orange;">Step 9:</mark> Switch back to your client atSign (@example01\_np)

1. Click on **your atSign** in the top right corner of the screen. This will open a list of atSigns that are currently signed into the app.
2. Select your **client atSign** in order to switch to it.

### <mark style="color:orange;">Step 10:</mark> Create a Connection Profile

1. If you aren't already on the Connections tab, click on **Connections** at the top of the Screen. Then click **Add New**, to create a new profile.
2. Enter the following information into the profile then click **Submit**.
   1. Profile Name - The name that will be displayed in the profile list.
   2. Device atSign - Your device atSign (eg example02\_np).
   3. Device Name - The name of your remote device.
   4. Relay - Select the relay sever closest to you for optimum speed.
   5. Local Port - The port you will use on your local machine.
   6. Local Host - The hostname or IP address to bind to on your local machine.
   7. Remote Host - The hostname or IP address of the machine you are connecting to.
   8. Remote Port - The port that will be used on the remote machine.

For reference, we've documented our most common use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

### <mark style="color:orange;">Step 11:</mark> Establish a connection

Click the **Connect Icon ▶️** to establish a connection with your remote device. If the connection is successful, you will see green. If you see red, hover over the icon to see reason for failure.

</details>


# Quick Start to Windows

This guide provides instructions for connecting from the NoPorts desktop application, to a machine running Windows.

### Step 6 to Step 8

Complete these steps **on the machine you are connecting to (Windows)**

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 6:</mark> Download and run the Installer

Download the NoPorts msi installer [from GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-windows-x64.zip). You can run the MSI inside the sshnp-windows zip.

Ensure both Core Tools & Daemon Service are being installed.

<figure><img src="/files/2mtUgH0jFj3LuoFFpqnp" alt=""><figcaption></figcaption></figure>

### <mark style="color:orange;">Step 7:</mark> Initiate atSign authorization request

Run the following command to make an authorization request.

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device atSign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`<USER>` with your **Windows username**,

`@<REPLACE>_np_key` with your **device atSign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">at_activate.exe enroll -a "@&#x3C;REPLACE>_np" `
<strong>  -s &#x3C;PASSCODE> `
</strong><strong>  -p noports `
</strong><strong>  -k C:\Users\&#x3C;USER>\.atsign\keys\@&#x3C;REPLACE>_np_key.atKeys `
</strong><strong>  -d &#x3C;DEVICE_NAME> `
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

{% hint style="info" %}
If you encounter a handshake exception, it usually means your root certificates are outdated. To refresh them, run the following command with administrator privileges:<kbd>Install-Script -Name UpdateRootCertificates</kbd>
{% endhint %}

### <mark style="color:orange;">Step 8:</mark> Setup Service Config

The service config lives in C:\Program Data\NoPorts\sshnpd.yaml, you can open it in notepad with this command:

{% hint style="danger" %}
Make sure you run notepad/terminal as administrator or else you won't be able to save your changes!
{% endhint %}

```
notepad C:\ProgramData\NoPorts\sshnpd.yaml
```

Ensure you provide the following fields to your service config:

* **atsign**
  * `atsign: example02_np`
  * `atsign: '@example02_np'`
* **keys (windows path)**
  * `keys: C:\Users\alice\.atsign\keys\@example02_np_key.atKeys`
* **manager**
  * `manager: example01_np`
  * `manager: '@example01_np'`

Examples on how to fill in the fields are inside the config file.

</details>

### Step 9 to Step 12

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 8:</mark> Approve the atSign authorization request

1. Click on **Requests** and approve the pending request. The request will then move to the approved enrollments list.
2. After a few seconds, the request will also show as approved on the machine you are connecting to.

### <mark style="color:orange;">Step 9:</mark> Switch back to your client atSign (@example01\_np)

1. Click on **your atSign** in the top right corner of the screen. This will open a list of atSigns that are currently signed into the app.
2. Select your **client atSign** in order to switch to it.

### <mark style="color:orange;">Step 10:</mark> Create a Connection Profile

1. If you aren't already on the Connections tab, click on **Connections** at the top of the Screen. Then click **Add New**, to create a new profile.
2. Enter the following information into the profile then click **Submit**.
   1. Profile Name - The name that will be displayed in the profile list.
   2. Device atSign - Your device atSign (eg example02\_np).
   3. Device Name - The name of your remote device.
   4. Relay - Select the relay sever closest to you for optimum speed.
   5. Local Port - The port you will use on your local machine.
   6. Local Host - The hostname or IP address to bind to on your local machine.
   7. Remote Host - The hostname or IP address of the machine you are connecting to.
   8. Remote Port - The port that will be used on the remote machine.

For reference, we've documented our most common use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

### <mark style="color:orange;">Step 11:</mark> Establish a connection

Click the **Connect Icon ▶️** to establish a connection with your remote device. If the connection is successful, you will see green. If you see red, hover over the icon to see reason for failure.

</details>


# Connecting from macOS

### Overview

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

### Installation

Select the operating system running on the **machine you're connecting to** for installation instructions.

<mark style="color:orange;">**Connecting from macOS**</mark>

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>to macOS</td><td><a href="/pages/KpWgO1Itckpy4LvfTY4O">/pages/KpWgO1Itckpy4LvfTY4O</a></td></tr><tr><td>to Linux</td><td><a href="/pages/RzoGBd68DdgxYSuNikHu">/pages/RzoGBd68DdgxYSuNikHu</a></td></tr><tr><td>to Windows</td><td><a href="/pages/NgiK5BOFF4USJgaRA0gr">/pages/NgiK5BOFF4USJgaRA0gr</a></td></tr></tbody></table>


# macOS to macOS

How to install NoPorts when connecting from macOS to macOS

### Prerequisite

Before starting the NoPorts installation, ensure you have **at least two atSigns** available. If you don’t yet have any atSigns, you can sign up for a NoPorts subscription or free trial at [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans).

### Step 1 to Step 4

These initial steps set up the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client atSign, while `@example02_np` will represent the device atSign.
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Download and run the Installer

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `client` when prompted.

**Your Atsigns (Skip this step)**

* To skip this step, simply press the Enter/Return key twice. Your Atsigns will be activated in the upcoming steps.

### <mark style="color:orange;">Step 2:</mark> Activate your client Atsign (@example01\_np)

{% hint style="warning" %}
If you've already activated your **client** Atsign on another device, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

This command activates your Atsign and prompts you to enter an OTP. This is only done during the setup of a brand new Atsign.

{% hint style="info" %}
Replace `@<REPLACE>_np` with your **client Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 3:</mark> Activate your device Atsign (@example02\_np)

Run the same command, but for your device Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **device Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 4:</mark> Generate an Atsign authorization passcode for your device Atsign

Run the following command to generate a 6-character one-time passcode. You will use this passcode in **Step 6.**

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your device **Atsign.**
{% endhint %}

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_np
```

</details>

### Step 5 and Step 6

After setting up the machine you're connecting from, you'll configure the machine you're connecting to.

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 5:</mark> Download and run the Installer

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `device` when prompted.

**Your atSigns**

* Client Atsign: e.g., `@example01_np`
* Device Atsign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.

### <mark style="color:orange;">Step 6:</mark> Initiate Atsign authorization request

Run the following command to make an authorization request:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

</details>

### Step 7 and Step 8

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 7:</mark> Approve the Atsign authorization request

Run the following command:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`@<REPLACE_NAME>` with the **device name** **from Step 6.**
{% endhint %}

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>
```

### <mark style="color:orange;">Step 8:</mark> Use NoPorts!

That's it. You can start using NoPorts or explore some of the documented use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

</details>


# macOS to Linux

How to install NoPorts when connecting from macOS to Linux

### Prerequisite

Before starting the NoPorts installation, ensure you have **at least two atSigns** available. If you don’t yet have any atSigns, you can sign up for a NoPorts subscription or free trial at [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans).

### Step 1 to Step 4

These initial steps set up the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client atSign, while `@example02_np` will represent the device atSign.
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Download and run the Installer

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below.

```bash
chmod u+x universal.sh
./universal.sh
```

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `client` when prompted.

**Your Atsigns (Skip this step)**

* To skip this step, simply press the Enter/Return key twice. Your Atsigns will be activated in the upcoming steps.

### <mark style="color:orange;">Step 2:</mark> Activate your client Atsign (@example01\_np)

{% hint style="warning" %}
If you've already activated your **client** Atsign on another device, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

This command activates your Atsign and prompts you to enter an OTP. This is only done during the setup of a brand new Atsign.

{% hint style="info" %}
Replace `@<REPLACE>_np` with your **client Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 3:</mark> Activate your device Atsign (@example02\_np)

Run the same command, but for your device Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **device Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 4:</mark> Generate an Atsign authorization passcode for your device Atsign

Run the following command to generate a 6-character one-time passcode. You will use this passcode in **Step 6.**

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your device **Atsign.**
{% endhint %}

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_np
```

</details>

### Step 5 and Step 6

After setting up the machine you're connecting from, you'll configure the machine you're connecting to.

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 5:</mark> Download and run the Installer

{% hint style="warning" %}
Do not run the following commands while logged in as the root user. Instead, use `sudo` from a regular account when elevated privileges are required, and create a regular account if one does not already exist.
{% endhint %}

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `device` when prompted.

**Your atSigns**

* Client Atsign: e.g., `@example01_np`
* Device Atsign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.

### <mark style="color:orange;">Step 6:</mark> Initiate Atsign authorization request

Run the following command to make an authorization request:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

</details>

### Step 7 and Step 8

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 7:</mark> Approve the Atsign authorization request

Run the following command:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`@<REPLACE_NAME>` with the **device name** **from Step 6.**
{% endhint %}

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>
```

### <mark style="color:orange;">Step 8:</mark> Use NoPorts!

That's it. You can start using NoPorts or explore some of the documented use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

</details>


# macOS to Windows

How to install NoPorts when connecting from macOS to Windows

### Prerequisite

Before starting the NoPorts installation, ensure you have **at least two atSigns** available. If you don’t yet have any atSigns, you can sign up for a NoPorts subscription or free trial at [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans).

### Step 1 to Step 4

These initial steps set up the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client Atsign, while `@example02_np` will represent the device Atsign.
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Download and run the Installer

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `client` when prompted.

**Your Atsigns (Skip this step)**

* To skip this step, simply press the Enter/Return key twice. Your Atsigns will be activated in the upcoming steps.

### <mark style="color:orange;">Step 2:</mark> Activate your client Atsign (@example01\_np)

{% hint style="warning" %}
If you've already activated your **client** Atsign on another device, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

This command activates your Atsign and prompts you to enter an OTP. This is only done during the setup of a brand new Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **client Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 3:</mark> Activate your device Atsign (@example02\_np)

Run the same command, but for your device Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **device Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 4:</mark> Generate an Atsign authorization passcode for your device Atsign

Run the following command to generate a 6-character one-time passcode. You will use this passcode in **Step 6.**

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your device **Atsign.**
{% endhint %}

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_np
```

</details>

### Step 5 to Step 7

After setting up the machine you're connecting from, you'll configure the machine you're connecting to.

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 5:</mark> Download and run the Installer

Download the msi installer [from GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-windows-x64.zip). You can run the msi right from the windows-bundle.zip.

Ensure both Core Tools & Daemon Service are being installed.

<figure><img src="/files/2mtUgH0jFj3LuoFFpqnp" alt=""><figcaption></figcaption></figure>

### <mark style="color:orange;">Step 6:</mark> Initiate device Atsign authorization request

Open a terminal (Command Prompt or PowerShell) and run the following command to make an authorization request.

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`<USER>` with your **Windows username**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">at_activate.exe enroll -a "@&#x3C;REPLACE>_np" `
<strong>  -s &#x3C;PASSCODE> `
</strong><strong>  -p noports `
</strong><strong>  -k C:\Users\&#x3C;USER>\.atsign\keys\@&#x3C;REPLACE>_np_key.atKeys `
</strong><strong>  -d &#x3C;DEVICE_NAME> `
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

{% hint style="info" %}
If you encounter a handshake exception, it usually means your root certificates are outdated. To refresh them, run the following command with administrator privileges:<kbd>Install-Script -Name UpdateRootCertificates</kbd>
{% endhint %}

### <mark style="color:orange;">Step 7:</mark> Setup Service Config on Device

The service config lives in C:\Program Data\NoPorts\sshnpd.yaml, you can open it in notepad by running the following command:

{% hint style="danger" %}
Make sure you run notepad/terminal as administrator or else you won't be able to save your changes!
{% endhint %}

```
notepad C:\ProgramData\NoPorts\sshnpd.yaml
```

Ensure you provide the following fields to your service config:

* **atsign**
  * `atsign: example02_np`
  * `atsign: '@example02_np'`
* **keys (windows path)**
  * `keys: C:\Users\alice\.atsign\keys\@example02_np_key.atKeys`
* **manager**
  * `manager: example01_np`
  * `manager: '@example01_np'`

Examples on how to fill in the fields are inside the config file.

</details>

### Step 8 and Step 9

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 8:</mark> Approve the Atsign authorization request

Run the following command:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`@<REPLACE_NAME>` with the **device name** **from Step 5.**
{% endhint %}

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>
```

### <mark style="color:orange;">Step 9:</mark> Use NoPorts!

That's it. You can start using NoPorts or explore some of the documented use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

</details>


# Connecting from Linux

### Overview

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

### Installation

Select the operating system running on the **machine you're connecting to** for installation instructions.

<mark style="color:orange;">**Connecting from Linux**</mark>

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>to macOS</td><td><a href="/pages/PdZH0ENKBZX7MaHm2WmN">/pages/PdZH0ENKBZX7MaHm2WmN</a></td></tr><tr><td>to Linux</td><td><a href="/pages/ygLnhEaPe7epa74zK2Oe">/pages/ygLnhEaPe7epa74zK2Oe</a></td></tr><tr><td>to Windows</td><td><a href="/pages/50lmyhIFNFMw4e7tiSi6">/pages/50lmyhIFNFMw4e7tiSi6</a></td></tr></tbody></table>


# Linux to macOS

How to install NoPorts when connecting from Linux to macOS

### Prerequisite

Before starting the NoPorts installation, ensure you have **at least two atSigns** available. If you don’t yet have any atSigns, you can sign up for a NoPorts subscription or free trial at [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans).

### Step 1 to Step 4

These initial steps set up the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client Atsign, while `@example02_np` will represent the device Atsign.
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Download and run the Installer

{% hint style="warning" %}
Do not run the following commands while logged in as the root user. Instead, use `sudo` from a regular account when elevated privileges are required, and create a regular account if one does not already exist.
{% endhint %}

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `client` when prompted.

**Your Atsigns (Skip this step)**

* To skip this step, simply press the Enter/Return key twice. Your Atsigns will be activated in the upcoming steps.

### <mark style="color:orange;">Step 2:</mark> Activate your client Atsign (@example01\_np)

{% hint style="warning" %}
If you've already activated your **client** Atsign on another device, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

This command activates your Atsign and prompts you to enter an OTP. This is only done during the setup of a brand new Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **client Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 3:</mark> Activate your device Atsign (@example02\_np)

Run the same command, but for your device Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **device Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 4:</mark> Generate an Atsign authorization passcode for your device Atsign

Run the following command to generate a 6-character one-time passcode. You will use this passcode in **Step 6.**

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your device **Atsign.**
{% endhint %}

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_np
```

</details>

### Step 5 and Step 6

After setting up the machine you're connecting from, you'll configure the machine you're connecting to.

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 5:</mark> Download and run the Installer

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `device` when prompted.

**Your Atsigns**

* Client Atsign: e.g., `@example01_np`
* Device Atsign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.

### <mark style="color:orange;">Step 6:</mark> Initiate atSign authorization request

Run the following command to make an authorization request.

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

</details>

### Step 7 and Step 8

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 7:</mark> Approve the Atsign authorization request

Run the following command:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`@<REPLACE_NAME>` with the **device name** **from Step 6.**
{% endhint %}

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>
```

### <mark style="color:orange;">Step 8:</mark> Use NoPorts!

That's it. You can start using NoPorts or explore some of the documented use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

</details>


# Linux to Linux

How to install NoPorts when connecting from Linux to Linux

### Prerequisite

Before starting the NoPorts installation, ensure you have **at least two atSigns** available. If you don’t yet have any atSigns, you can sign up for a NoPorts subscription or free trial at [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans).

### Step 1 to Step 4

These initial steps set up the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client Atsign, while `@example02_np` will represent the device Atsign.
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Download and run the Installer

{% hint style="warning" %}
Do not run the following commands while logged in as the root user. Instead, use `sudo` from a regular account when elevated privileges are required, and create a regular account if one does not already exist.
{% endhint %}

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `client` when prompted.

**Your Atsigns (Skip this step)**

* To skip this step, simply press the Enter/Return key twice. Your Atsigns will be activated in the upcoming steps.

### <mark style="color:orange;">Step 2:</mark> Activate your client Atsign (@example01\_np)

{% hint style="warning" %}
If you've already activated your **client** Atsign on another device, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

This command activates your Atsign and prompts you to enter an OTP. This is only done during the setup of a brand new Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **client Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 3:</mark> Activate your device Atsign (@example02\_np)

Run the same command, but for your device Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **device Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 4:</mark> Generate an Atsign authorization passcode for your device Atsign

Run the following command to generate a 6-character one-time passcode. You will use this passcode in **Step 6.**

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your device **Atsign.**
{% endhint %}

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_np
```

</details>

### Step 5 and Step 6

After setting up the machine you're connecting from, you'll configure the machine you're connecting to.

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 5:</mark> Download and run the Installer

{% hint style="warning" %}
Do not run the following commands while logged in as the root user. Instead, use `sudo` from a regular account when elevated privileges are required, and create a regular account if one does not already exist.
{% endhint %}

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `device` when prompted.

**Your Atsigns**

* Client Atsign: e.g., `@example01_np`
* Device Atsign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.

### <mark style="color:orange;">Step 6:</mark> Initiate Atsign authorization request

Run the following command to make an authorization request.

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

</details>

### Step 7 and Step 8

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 7:</mark> Approve the Atsign authorization request

Run the following command:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`@<REPLACE_NAME>` with the **device name** **from Step 6.**
{% endhint %}

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>
```

### <mark style="color:orange;">Step 8:</mark> Use NoPorts!

That's it. You can start using NoPorts or explore some of the documented use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

</details>


# Linux to Windows

How to install NoPorts when connecting from Linux to Windows

### Prerequisite

Before starting the NoPorts installation, ensure you have **at least two atSigns** available. If you don’t yet have any atSigns, you can sign up for a NoPorts subscription or free trial at [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans).

### Step 1 to Step 4

These initial steps set up the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client atSign, while `@example02_np` will represent the device atSign.
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Download and run the Installer

{% hint style="warning" %}
Do not run the following commands while logged in as the root user. Instead, use `sudo` from a regular account when elevated privileges are required, and create a regular account if one does not already exist.
{% endhint %}

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `client` when prompted.

**Your Atsigns (Skip this step)**

* To skip this step, simply press the Enter/Return key twice. Your Atsigns will be activated in the upcoming steps.

### <mark style="color:orange;">Step 2:</mark> Activate your client Atsign (@example01\_np)

{% hint style="warning" %}
If you've already activated your **client** Atsign on another device, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

This command activates your Atsign and prompts you to enter an OTP. This is only done during the setup of a brand new Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **client Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 3:</mark> Activate your device Atsign (@example02\_np)

Run the same command, but for your device Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **device Atsign.**
{% endhint %}

```
~/.local/bin/at_activate -a @<REPLACE>_np
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 4:</mark> Generate an Atsign authorization passcode for your device Atsign

Run the following command to generate a 6-character one-time passcode. You will use this passcode in **Step 6.**

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your device **Atsign.**
{% endhint %}

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_np
```

</details>

### Step 5 to Step 7

After setting up the machine you're connecting from, you'll configure the machine you're connecting to.

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 5:</mark> Download and run the Installer

Download the msi installer [from GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-windows-x64.zip). You can run the msi right from the windows-bundle.zip.

Ensure both Core Tools & Daemon Service are being installed.

<figure><img src="/files/2mtUgH0jFj3LuoFFpqnp" alt=""><figcaption></figcaption></figure>

### <mark style="color:orange;">Step 6:</mark> Initiate device Atsign authorization request

Open a terminal (Command Prompt or PowerShell) and run the following command to make an authorization request.

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`<USER>` with your **Windows username**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">at_activate.exe enroll -a "@&#x3C;REPLACE>_np" `
<strong>  -s &#x3C;PASSCODE> `
</strong><strong>  -p noports `
</strong><strong>  -k C:\Users\&#x3C;USER>\.atsign\keys\@&#x3C;REPLACE>_np_key.atKeys `
</strong><strong>  -d &#x3C;DEVICE_NAME> `
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

{% hint style="info" %}
If you encounter a handshake exception, it usually means your root certificates are outdated. To refresh them, run the following command with administrator privileges:<kbd>Install-Script -Name UpdateRootCertificates</kbd>
{% endhint %}

### <mark style="color:orange;">Step 7:</mark> Setup Service Config on Device

The service config lives in C:\Program Data\NoPorts\sshnpd.yaml, you can open it in notepad by running the following command:

{% hint style="danger" %}
Make sure you run notepad/terminal as administrator or else you won't be able to save your changes!
{% endhint %}

```
notepad C:\ProgramData\NoPorts\sshnpd.yaml
```

Ensure you provide the following fields to your service config:

* **atsign**
  * `atsign: example02_np`
  * `atsign: '@example02_np'`
* **keys (windows path)**
  * `keys: C:\Users\alice\.atsign\keys\@example02_np_key.atKeys`
* **manager**
  * `manager: example01_np`
  * `manager: '@example01_np'`

Examples on how to fill in the fields are inside the config file.

</details>

### Step 8 and Step 9

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 8:</mark> Approve the Atsign authorization request

Run the following command:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`@<REPLACE_NAME>` with the **device name** **from Step 5.**
{% endhint %}

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>
```

### <mark style="color:orange;">Step 9:</mark> Use NoPorts!

That's it. You can start using NoPorts or explore some of the documented use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

</details>


# Connecting from Windows

### Overview

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

### Installation

Select the operating system running on the **machine you're connecting to** for installation instructions.

<mark style="color:orange;">**Connecting from Windows**</mark>

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>to macOS</td><td><a href="/pages/aGYOqLSEhKihPuMSxLbD">/pages/aGYOqLSEhKihPuMSxLbD</a></td></tr><tr><td>to Linux</td><td><a href="/pages/lgRoNLVK7Bps7Rd33J7R">/pages/lgRoNLVK7Bps7Rd33J7R</a></td></tr><tr><td>to Windows</td><td><a href="/pages/KSBNqhx7QgpbTFM5aaqf">/pages/KSBNqhx7QgpbTFM5aaqf</a></td></tr></tbody></table>


# Windows to macOS

How to install NoPorts when connecting from Windows to macOS

### Prerequisite

Before starting the NoPorts installation, ensure you have **at least two atSigns** available. If you don’t yet have any atSigns, you can sign up for a NoPorts subscription or free trial at [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans).

### Step 1 to Step 4

These initial steps set up the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client Atsign, while `@example02_np` will represent the device Atsign.
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Download and run the Installer

Download the msi installer from [GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/NoPorts-x64.msi). You can run the msi right from the windows-bundle.zip.

<figure><img src="/files/2mtUgH0jFj3LuoFFpqnp" alt=""><figcaption></figcaption></figure>

### <mark style="color:orange;">Step 2:</mark> Client Atsign activation (@example01\_np)

{% hint style="warning" %}
If you've already activated your **client** Atsign on another device, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

Open a terminal (Command Prompt or PowerShell) and run the following commands. This command activates your Atsign and prompts you to enter an OTP. This is only done during the setup of a brand new Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **client Atsign.**
{% endhint %}

```
at_activate.exe -a "@<REPLACE>_np"
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `C:\Users\<user>\.atsign\keys`.

### <mark style="color:orange;">Step 3:</mark> Device Atsign activation (@example02\_np)

Run the same command, but for your device Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **device Atsign.**
{% endhint %}

```
at_activate.exe -a "@<REPLACE>_np"
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `C:\Users\<user>\.atsign\keys`.

### <mark style="color:orange;">Step 4:</mark> Generate an Atsign authorization passcode for your device Atsign

Run the following command to generate a 6-character one-time passcode. You will use this passcode in **Step 6.**

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your device **Atsign.**
{% endhint %}

```bash
at_activate.exe otp -a "@<REPLACE>_np"
```

</details>

### Step 5 and Step 6

After setting up the machine you're connecting from, you'll configure the machine you're connecting to.

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 5:</mark> Download and run the Installer

Open a terminal and download the installer from Github by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `device` when prompted.

**Your atSigns**

* Client Atsign: e.g., `@example01_np`
* Device Atsign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.

### <mark style="color:orange;">Step 6:</mark> Initiate Atsign authorization request

Run the following command to make an authorization request.

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

</details>

### Step 7 and Step 8

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 7:</mark> Approve the Atsign authorization request

Run the following command:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`@<REPLACE_NAME>` with the **device name** **from Step 6.**
{% endhint %}

```bash
.\at_activate approve -a "@<REPLACE>_np" --arx noports --drx <REPLACE_NAME>
```

### <mark style="color:orange;">Step 8:</mark> Use NoPorts!

That's it. You can start using NoPorts or explore some of the documented use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

</details>


# Windows to Linux

How to install NoPorts when connecting from Windows to Linux

### Prerequisite

Before starting the NoPorts installation, ensure you have **at least two atSigns** available. If you don’t yet have any atSigns, you can sign up for a NoPorts subscription or free trial at [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans).

### Step 1 to Step 4

These initial steps set up the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client Atsign, while `@example02_np` will represent the device Atsign.
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Download and run the Installer

Download the msi installer from [GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/NoPorts-x64.msi). You can run the msi right from the windows-bundle.zip.

<figure><img src="/files/2mtUgH0jFj3LuoFFpqnp" alt=""><figcaption></figcaption></figure>

### <mark style="color:orange;">Step 2:</mark> Client Atsign activation (@example01\_np)

{% hint style="warning" %}
If you've already activated your **client** Atsign on another device, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

Open a terminal (Command Prompt or PowerShell) and run the following commands. This command activates your Atsign and prompts you to enter an OTP. This is only done during the setup of a brand new Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **client Atsign.**
{% endhint %}

```
at_activate.exe -a "@<REPLACE>_np"
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `C:\Users\<user>\.atsign\keys`.

### <mark style="color:orange;">Step 3:</mark> Device Atsign activation (@example02\_np)

Run the same command, but for your device Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **device Atsign.**
{% endhint %}

```
at_activate.exe -a "@<REPLACE>_np"
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `C:\Users\<user>\.atsign\keys`.

### <mark style="color:orange;">Step 4:</mark> Generate an Atsign authorization passcode for your device Atsign

Run the following command to generate a 6-character one-time passcode. You will use this passcode in **Step 6.**

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your device **Atsign.**
{% endhint %}

```bash
at_activate.exe otp -a "@<REPLACE>_np"
```

</details>

### Step 5 and Step 6

After setting up the machine you're connecting from, you'll configure the machine you're connecting to.

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 5:</mark> Download and run the Installer

{% hint style="warning" %}
Do not run the following commands while logged in as the root user. Instead, use `sudo` from a regular account when elevated privileges are required, and create a regular account if one does not already exist.
{% endhint %}

Open a terminal and download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

{% hint style="info" %}
You may be asked to enter your password if your machine requires sudo privileges.
{% endhint %}

**The install type**

* Enter `device` when prompted.

**Your Atsigns**

* Client Atsign: e.g., `@example01_np`
* Device Atsign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.

### <mark style="color:orange;">Step 6:</mark> Initiate Atsign authorization request

Run the following command to make an authorization request:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

</details>

### Step 7 and Step 8

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 7:</mark> Approve the Atsign authorization request

Run the following command:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`@<REPLACE_NAME>` with the **device name** **from Step 6.**
{% endhint %}

```bash
.\at_activate approve -a "@<REPLACE>_np" --arx noports --drx <REPLACE_NAME>
```

### <mark style="color:orange;">Step 8:</mark> Use NoPorts!

That's it. You can start using NoPorts or explore some of the documented use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

</details>


# Windows to Windows

How to install NoPorts when connecting from Windows to Windows

{% hint style="warning" %}
NoPorts version <5.13.0 should follow old instructions located here: [Windows to Windows Legacy](/installation/connecting-from-windows/windows-to-windows-1)
{% endhint %}

### Prerequisite

Before starting the NoPorts installation, ensure you have **at least two atSigns** available. If you don’t yet have any atSigns, you can sign up for a NoPorts subscription or free trial at [my.noports.com/no-ports-plans](https://my.noports.com/no-ports-plans).

### Step 1 to Step 4

These initial steps set up the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client Atsign, while `@example02_np` will represent the device Atsign.
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Download and run the Installer

Download the msi installer from [GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/NoPorts-x64.msi). You can run the msi right from the windows-bundle.zip.

<figure><img src="/files/2mtUgH0jFj3LuoFFpqnp" alt=""><figcaption></figcaption></figure>

### <mark style="color:orange;">Step 2:</mark> Client Atsign activation (@example01\_np)

{% hint style="warning" %}
If you've already activated your **client** Atsign on another device, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

Open a terminal (Command Prompt or PowerShell) and run the following commands. This command activates your Atsign and prompts you to enter an OTP. This is only done during the setup of a brand new Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **client Atsign.**
{% endhint %}

```
at_activate.exe -a "@<REPLACE>_np"
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `C:\Users\<user>\.atsign\keys`.

### <mark style="color:orange;">Step 3:</mark> Device Atsign activation (@example02\_np)

Run the same command, but for your device Atsign.

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your **device Atsign.**
{% endhint %}

```
at_activate.exe -a "@<REPLACE>_np"
```

#### Enter the one-time password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one-time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `C:\Users\<user>\.atsign\keys`.

### <mark style="color:orange;">Step 4:</mark> Generate an Atsign authorization passcode for your device Atsign

Run the following command to generate a 6-character one-time passcode. You will use this passcode in **Step 6.**

{% hint style="warning" %}
Replace `@<REPLACE>_np` with your device **Atsign.**
{% endhint %}

```bash
at_activate.exe otp -a "@<REPLACE>_np"
```

</details>

### Step 5 to Step 7

After setting up the machine you're connecting from, you'll configure the machine you're connecting to.

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 5:</mark> Download and run the Installer

Download the msi installer [from GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-windows-x64.zip). You can run the msi right from the windows-bundle.zip.

Ensure both Core Tools & Daemon Service are being installed.

<figure><img src="/files/2mtUgH0jFj3LuoFFpqnp" alt=""><figcaption></figcaption></figure>

### <mark style="color:orange;">Step 6:</mark> Initiate device Atsign authorization request

Open a terminal (Command Prompt or PowerShell) and run the following command to make an authorization request.

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`<USER>` with your **Windows username**,

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">at_activate.exe enroll -a "@&#x3C;REPLACE>_np" `
<strong>  -s &#x3C;PASSCODE> `
</strong><strong>  -p noports `
</strong><strong>  -k C:\Users\&#x3C;USER>\.atsign\keys\@&#x3C;REPLACE>_np_key.atKeys `
</strong><strong>  -d &#x3C;DEVICE_NAME> `
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

{% hint style="info" %}
If you encounter a handshake exception, it usually means your root certificates are outdated. To refresh them, run the following command with administrator privileges:<kbd>Install-Script -Name UpdateRootCertificates</kbd>
{% endhint %}

### <mark style="color:orange;">Step 7:</mark> Setup Service Config on Device

The service config lives in C:\Program Data\NoPorts\sshnpd.yaml, you can open it in notepad by running the following command:

{% hint style="danger" %}
Make sure you run notepad/terminal as administrator or else you won't be able to save your changes!
{% endhint %}

```
notepad C:\ProgramData\NoPorts\sshnpd.yaml
```

Ensure you provide the following fields to your service config:

* **atsign**
  * `atsign: example02_np`
  * `atsign: '@example02_np'`
* **keys (windows path)**
  * `keys: C:\Users\alice\.atsign\keys\@example02_np_key.atKeys`
* **manager**
  * `manager: example01_np`
  * `manager: '@example01_np'`

Examples on how to fill in the fields are inside the config file.

</details>

### Step 8 and Step 9

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 8:</mark> Approve the device atSign authorization request

Run the following command:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device atSign**,

`@<REPLACE_NAME>` with the **device name** **from Step 6.**
{% endhint %}

```bash
at_activate.exe approve -a "@<REPLACE>_np" --arx noports --drx <REPLACE_NAME>
```

### <mark style="color:orange;">Step 9:</mark> Use NoPorts!

That's it. You can start using NoPorts or explore some of the documented use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

</details>


# Windows to Windows Legacy

How to install NoPorts when connecting from Windows to Windows

### Step 1 to Step 4

These initial steps set up the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

{% hint style="warning" %}
In this installation guide, `@example01_np` will represent the client atSign, while `@example02_np` will represent the device atSign.
{% endhint %}

### <mark style="color:orange;">Step 1:</mark> Download and run the Installer

Download the installer from [GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/NoPortsInstaller-windows-x64.zip). Then unzip the file.

Launch the NoPortsInstaller.exe program and allow it administrative permissions. Click **Client Install** and follow the process until installation is complete.

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

<figure><img src="/files/91NGEtgLhx6SE8W4t9yx" alt=""><figcaption></figcaption></figure>

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

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

### <mark style="color:orange;">Step 2:</mark> Activate your client atSign (@example01\_np)

{% hint style="warning" %}
If you've already activated your **client** atSign on another device, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

Step 2.1 Click on **Activate atSign.**

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

Step 2.2 Enter the atSign you wish to activate and click **Submit**.

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

Step 2.3 Check your email for the OTP (one-time password), then enter it and press **Generate.**

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

Step 2.4 Once activated, the master keys will save at `~/.atsign/keys`. Wait for the keys to generate, then go back **Home**.

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

### <mark style="color:orange;">Step 3:</mark> Activate your device atSign (@example02\_np)

Repeat the activation process, but for your device atSign. The device master keys will also save at `~/.atsign/keys`.

### <mark style="color:orange;">Step 4:</mark> Generate an atSign authorization passcode for your device atSign

Follow the steps below to generate a 6-character one-time passcode which you will use in **Step 6.**

4.1 Click **Manage Keys**.

<figure><img src="/files/4KE0h9rQ1nwhpNB3EB1q" alt=""><figcaption></figcaption></figure>

4.2 Enter your device atSign and click **Next**.

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

4.3 Click **New OTP**.

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

4.4 Wait a few seconds for the OTP to appear, then proceed to **Step 5** on the machine you are connecting to

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

</details>

### Step 5 and Step 6

After setting up the machine you're connecting from, you'll configure the machine you're connecting to.

<details>

<summary>On the machine you are connecting to</summary>

### <mark style="color:orange;">Step 5:</mark> Download and run the Installer

Download the installer [from GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/NoPortsInstaller-windows-x64.zip). Then unzip the file.

Install the Device Software

5.1 Click **Device Install**.

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

5.2 Enter both of your atSigns into the associated fields, then enter the name of the machine you are on into the a device name field, and click **Next**. You will need to enter this device name in **Step 7**.

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

5.3 If you wish to add additional arguments to pass to sshnpd, enter them, and then click **Next.**

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

5.4 Wait for the installation to complete, then click **Next.**

### <mark style="color:orange;">Step 6:</mark> Initiate atSign authorization request

You will see the following screen. Enter the **one-time passcode generated in Step 4** on the machine you are connecting from. Then click **Generate**.

<figure><img src="/files/6vexWqrm5LYpMQ5WWgsI" alt=""><figcaption></figcaption></figure>

</details>

### Step 7 and Step 8

With both machines now configured, the final steps bring us back to the machine initiating the connection.

<details>

<summary>On the machine you are connecting from</summary>

### <mark style="color:orange;">Step 7:</mark> Approve the atSign authorization request

Click **Refresh** and the new request will appear.

* If the request looks incorrect, press **Deny** to deny it and start the process again.
* If the request looks correct, press **Approve** to approve it.

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

Once approved, the request will disappear from the list. On the machine you are connecting to, it will take a few seconds to process the approval.

### <mark style="color:orange;">Step 8:</mark> Use NoPorts!

That's it. You can start using NoPorts or explore some of the documented use cases, including [MCP](/use-cases/mcp), [SSH](/use-cases/ssh), [RDP](/use-cases/rdp), [SFTP](/use-cases/sftp), [Web Server](/use-cases/web-server), and [SMB](/use-cases/smb).

</details>

### Connecting more machines to your device atSign

To connect more machines to your device atSign, repeat **Steps 4 through 7**.


# MacOS Installation Guides

How to install NoPorts on macOS. Guides for desktop app, CLI, and device installation.

### Desktop App Installation

If this is your first time using NoPorts, we recommend you start here:

{% content-ref url="/pages/yfsuX78LmoRIjEa7RspY" %}
[MacOS Desktop Client Installation](/installation/macos/desktop)
{% endcontent-ref %}

### CLI Client Installation

If you are more comfortable with the CLI, you can follow this guide to install the binaries:

{% content-ref url="/pages/xJI67KwMYFI9WkLbanca" %}
[MacOS CLI Client Installation](/installation/macos/cli-client)
{% endcontent-ref %}

### Device Installation

If you want to setup access to your MacOS device, follow this guide:

{% content-ref url="/pages/0u7zLwksq459AsCdfxND" %}
[MacOS Device Installation](/installation/macos/device)
{% endcontent-ref %}


# MacOS Desktop Client Installation

Video and written directions for installing the NoPorts desktop app

{% embed url="<https://vimeo.com/1038239765>" %}
NoPorts Desktop Overview
{% endembed %}

## Step 1: Download the NoPorts desktop application

[Link to Apple Store](https://apps.apple.com/ca/app/noports-desktop/id6737338881)

## Step 2: Log into the NoPorts desktop application

1. Launch the NoPorts desktop app and click 'Get Started'.
2. Enter your client atSign into the text field (e.g., @pluto83\_client), leave the root domain as is, and then click 'Next'.
3. A one-time password (OTP) will be sent to you via email. Enter this OTP into the app and then click 'Confirm'.

## Step 3: Back up your atKeys

Your atKeys (cryptographic keys) will be used to pair your atSign with this and other devices in future. You can [learn more about these keys here](https://www.youtube.com/watch?v=bRRLCOHP-BY).

1. Click on the Settings Icon in the top right corner of the app.
2. Click on 'Back Up Your Keys' in the left navigation panel.
3. Select a location on your device and save your keys.

## Step 4: Prepare a Profile to establish a NoPorts connection

1. Return to the Dashboard
2. Click the 'Add New' button to create a new Profile
   1. Enter the details for the new profile
   2. Start the connection by pressing :arrow\_forward: for the profile you just created
3. **Or,** connect using our test profile.
   1. Download the[ NoPorts test connection profile. ](https://drive.google.com/file/d/1qb0YrpRaGstLSBKoLJ4wwVUIMO5zCaMq/view)This is a json file containing connection details for a test profile we have created.
   2. Return to the NoPorts app Dashboard.
   3. Click 'Import' and select the test connection profile that you just downloaded.
   4. Click the Connect Icon :arrow\_forward: to establish a connection.
   5. Open a web browser and navigate to`http://localhost:8080`to confirm you successfully connected to our hidden webpage.

{% hint style="info" %}
\*Note, if you are connecting to your remote device, the remote device installation must be complete before the profile will connect. If utilizing a test profile, it will connect to our test site without needing a remote device to be set up first.
{% endhint %}


# MacOS CLI Client Installation

### Step 1: Download the Installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

### Step 2: Run the Installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

### Step 3: Activate your client atSign

{% hint style="warning" %}
If you've activated your **client** atSign on another device already, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
~/.local/bin/at_activate -a @<REPLACE>_client
```

#### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.\
\
Once activated, the master keys will save at `~/.atsign/keys`.


# MacOS Device Installation (Hidden)

## Step 1 : Activate the device atSign from your `client machine`

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

### (1.1) Download the activation software on the `client machine`

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

### (1.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

### (1.3) Activate the device atSign from the `client machine`

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
C:\\Program\ Files\\NoPorts\\at_activate.exe otp -a @<REPLACE>_device
```

#### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~\.atsign\keys`.

## Step 2 : Installing on the `device`

### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

***

## Step 3: Authorizing the device atSign

### (3.1) Generate a passcode from your `client machine`

### (3.2) Make an authorization request from your `device machine`

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

#### Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

### (3.3) Approve the authorization request from your `client machine`

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```


# MacOS Device Installation

## Choose the operating system which is running on your <mark style="color:red;">CLIENT machine</mark>:

{% tabs %}
{% tab title="MacOS" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (1.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

#### (1.3) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
~/.local/bin/at_activate -a @<REPLACE>_device
```

#### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~/.atsign/keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

#### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

***

### Step 3: Authorizing the device atSign

#### (3.1) Generate a passcode from your <mark style="color:red;">client machine</mark>

Run the following command. It should output a 6-character passcode.

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_device
```

#### (3.2) Make an authorization request from your <mark style="color:orange;">device machine</mark>

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

#### Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```

{% endtab %}

{% tab title="Linux" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (1.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

#### (1.3) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
~/.local/bin/at_activate -a @<REPLACE>_device
```

#### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~/.atsign/keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

#### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

***

### Step 3: Authorizing the device atSign

#### (3.1) Generate a passcode from your <mark style="color:red;">client machine</mark>

Run the following command. It should output a 6-character passcode.

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_device
```

#### (3.2) Make an authorization request from your <mark style="color:orange;">device machine</mark>

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

#### Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```

{% endtab %}

{% tab title="Windows" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

See the Windows [Windows Installation Guide](/installation/windows#cli-client-installation)

#### (1.2) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
C:\\Program\ Files\\NoPorts\\at_activate.exe otp -a @<REPLACE>_device
```

#### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~\.atsign\keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

#### Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Run the following command

```bash
C:\\Program\ Files\\NoPorts\\at_activate.exe approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```

{% endtab %}
{% endtabs %}

Choose the operating system which is running on your <mark style="color:red;">CLIENT machine</mark>:

{% tabs %}
{% tab title="MacOS" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (1.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

#### (1.3) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
~/.local/bin/at_activate -a @<REPLACE>_device
```

**Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders**

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~/.atsign/keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

#### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

### Step 3: Authorizing the device atSign

#### (3.1) Generate a passcode from your <mark style="color:red;">client machine</mark>

Run the following command. It should output a 6-character passcode.

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_device
```

#### (3.2) Make an authorization request from your <mark style="color:orange;">device machine</mark>

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

**Once you see this text, you're ready to continue to the next step.**

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```

{% endtab %}

{% tab title="Linux" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (1.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

#### (1.3) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
~/.local/bin/at_activate -a @<REPLACE>_device
```

**Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders**

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~/.atsign/keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

#### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

***

### Step 3: Authorizing the device atSign

#### (3.1) Generate a passcode from your <mark style="color:red;">client machine</mark>

Run the following command. It should output a 6-character passcode.

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_device
```

#### (3.2) Make an authorization request from your <mark style="color:orange;">device machine</mark>

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

**Once you see this text, you're ready to continue to the next step.**

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```

{% endtab %}

{% tab title="Windows" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

If you haven't already done so, download the installer [from GitHub](https://github.com/atsign-foundation/noports/releases/download/v5.8.7/NoPortsInstaller-windows-x64.zip). Then unzip the file.

#### (1.2) Activate the device atSign from the <mark style="color:red;">client machine</mark>

Open the installer and click Activate atSign

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

Enter the device atSign and click Submit

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

A one-time password will be sent to your registered email address. Enter the OTP and then click Generate

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

Once activated, the keys will be saved in `~\.atsign\keys`. You can go back to the installer home screen.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

#### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

### Step 3: Authorizing the device atSign

#### (3.1) Generate a passcode from your <mark style="color:red;">client machine</mark>

Open the installer and click on Manage Keys.

<figure><img src="/files/4KE0h9rQ1nwhpNB3EB1q" alt=""><figcaption></figcaption></figure>

Enter the device atSign and click Next.

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

Click New OTP.

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

Wait a few seconds for the OTP to appear then proceed to the next step.

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

#### (3.2) Make an authorization request from your <mark style="color:orange;">device machine</mark>

Run the following command on your remote device.

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

**Once you see the text below, you're ready to continue to the next step.**

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Click Refresh and the new request will appear

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

If the request looks incorrect, then click "Deny" to deny it, and start the process again.

If the request looks correct, then click "Approve" to approve it.

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

Once the request has been approved, it should disappear from the list in the installer. The enrollment will complete on the remote device in a few seconds.

<figure><img src="/files/Xvkjo49a8MNsQ2TlB2JG" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}


# Linux Installation Guide

Full installation of client and server software on two Linux machines

### Client Only Installation

If you want to setup a Linux client, use this guide:

{% content-ref url="/pages/aqG9VGsqMjDoeLaREcFt" %}
[Linux Cli Client Installation](/installation/linux/cli-client)
{% endcontent-ref %}

### Device Only Installation

If you want to setup a Linux device, use this guide:

{% content-ref url="/pages/jGywDtuWRY50NiHFrt2h" %}
[Linux Device Installation](/installation/linux/device)
{% endcontent-ref %}


# Linux Cli Client Installation

### Step 1: Download the Installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

### Step 2: Run the Installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

### Step 3: Activate your client atSign

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
~/.local/bin/at_activate -a @<REPLACE>_device
```

#### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~/.atsign/keys`.


# Linux Device Installation (hidden)

## Step 1 : Activate the device atSign from your `client machine`

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

### (1.1) Download the activation software on the `client machine`

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

### (1.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

### (1.3) Activate the device atSign from the `client machine`

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
C:\\Program\ Files\\NoPorts\\at_activate.exe otp -a @<REPLACE>_device
```

#### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~\.atsign\keys`.

## Step 2 : Installing on the `device`

### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

***

## Step 3: Authorizing the device atSign

### (3.1) Generate a passcode from your `client machine`

### (3.2) Make an authorization request from your `device machine`

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

#### Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

### (3.3) Approve the authorization request from your `client machine`

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```


# Linux Device Installation

## Choose the operating system which is running on your <mark style="color:red;">CLIENT machine</mark>:

{% tabs %}
{% tab title="MacOS" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (1.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

#### (1.3) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
~/.local/bin/at_activate -a @<REPLACE>_device
```

#### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~/.atsign/keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

#### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

***

### Step 3: Authorizing the device atSign

#### (3.1) Generate a passcode from your <mark style="color:red;">client machine</mark>

Run the following command. It should output a 6-character passcode.

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_device
```

#### (3.2) Make an authorization request from your <mark style="color:orange;">device machine</mark>

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

#### Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```

{% endtab %}

{% tab title="Linux" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (1.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

#### (1.3) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
~/.local/bin/at_activate -a @<REPLACE>_device
```

#### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~/.atsign/keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

#### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

***

### Step 3: Authorizing the device atSign

#### (3.1) Generate a passcode from your <mark style="color:red;">client machine</mark>

Run the following command. It should output a 6-character passcode.

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_device
```

#### (3.2) Make an authorization request from your <mark style="color:orange;">device machine</mark>

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

#### Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```

{% endtab %}

{% tab title="Windows" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

See the Windows [Windows Installation Guide](/installation/windows#cli-client-installation)

#### (1.2) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
C:\\Program\ Files\\NoPorts\\at_activate.exe otp -a @<REPLACE>_device
```

#### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~\.atsign\keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

#### Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```

{% endtab %}
{% endtabs %}

## Choose the operating system which is running on your <mark style="color:red;">CLIENT machine</mark>:

{% tabs %}
{% tab title="MacOS" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (1.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

#### (1.3) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
~/.local/bin/at_activate -a @<REPLACE>_device
```

**Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders**

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~/.atsign/keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

#### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

***

### Step 3: Authorizing the device atSign

#### (3.1) Generate a passcode from your <mark style="color:red;">client machine</mark>

Run the following command. It should output a 6-character passcode.

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_device
```

#### (3.2) Make an authorization request from your <mark style="color:orange;">device machine</mark>

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

**Once you see this text, you're ready to continue to the next step.**

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```

{% endtab %}

{% tab title="Linux" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (1.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

#### (1.3) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
~/.local/bin/at_activate -a @<REPLACE>_device
```

**Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders**

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~/.atsign/keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

#### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

### Step 3: Authorizing the device atSign

#### (3.1) Generate a passcode from your <mark style="color:red;">client machine</mark>

Run the following command. It should output a 6-character passcode.

```bash
~/.local/bin/at_activate otp -a @<REPLACE>_device
```

#### (3.2) Make an authorization request from your <mark style="color:orange;">device machine</mark>

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

**Once you see this text, you're ready to continue to the next step.**

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Run the following command

```bash
~/.local/bin/at_activate approve -a @<REPLACE>_device --arx noports --drx <DEVICE_NAME>
```

{% endtab %}

{% tab title="Windows" %}

### Step 1 : Activate the device atSign from your <mark style="color:red;">CLIENT machine</mark>

If you've already activated the device atSign skip to [step 2](#step-2-installing-on-the-device).

#### (1.1) Download the activation software on the <mark style="color:red;">client machine</mark>

If you haven't already done so, download the installer [from GitHub](https://github.com/atsign-foundation/noports/releases/download/v5.8.7/NoPortsInstaller-windows-x64.zip). Then unzip the file.

#### (1.2) Activate the device atSign from the <mark style="color:red;">client machine</mark>

This command activates your atSign and prompts you to enter an OTP. This is only done during the setup of a brand new atsign.

```
C:\\Program\ Files\\NoPorts\\at_activate.exe otp -a @<REPLACE>_device
```

**Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders**

at\_activate will pause and wait for the input of a one time pin (OTP) sent to your email or phone number.

Once activated, the management keys will be saved in `~\.atsign\keys`.

### Step 2 : Installing on the <mark style="color:orange;">DEVICE machine</mark>

#### (2.1) Download the installer

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

#### (2.2) Run the installer

Make the script executable and run the script.

```bash
chmod u+x universal.sh
./universal.sh
```

### Step 3: Authorizing the device atSign

#### (3.1) Generate a passcode from your <mark style="color:red;">client machine</mark>

Open the installer and click on Manage Keys.

<figure><img src="/files/4KE0h9rQ1nwhpNB3EB1q" alt=""><figcaption></figcaption></figure>

Enter the device atSign and click Next.

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

Click New OTP.

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

Wait a few seconds for the OTP to appear then proceed to the next step.

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

#### (3.2) Make an authorization request from your <mark style="color:orange;">device machine</mark>

Run the following command on your remote device.

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_device \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_device_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

**Once you see the text below, you're ready to continue to the next step.**

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

#### (3.3) Approve the authorization request from your <mark style="color:red;">client machine</mark>

Click Refresh and the new request will appear

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

If the request looks incorrect, then click "Deny" to deny it, and start the process again.

If the request looks correct, then click "Approve" to approve it.

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

Once the request has been approved, it should disappear from the list in the installer. The enrollment will complete on the remote device in a few seconds.

<figure><img src="/files/jA2UzxaGTQtmSPP6ZmGI" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}


# Windows Installation Guide

This guide walks you through installing NoPorts on Windows machines.

### Desktop App Installation

If this is your first time using NoPorts, we recommend you start here:

{% content-ref url="/pages/9bGAZdcLhoBC8N96s8Yw" %}
[Windows Desktop Client Installation](/installation/windows/desktop)
{% endcontent-ref %}

### CLI Client Installation

If you are more comfortable with the CLI, you can follow this guide to install the binaries:

{% content-ref url="/pages/v9RVKdNucOptf6ET3SAR" %}
[Windows CLI Client Installation](/installation/windows/cli-client)
{% endcontent-ref %}

### Device Installation

If you want to setup access to your Windows device, follow this guide:

{% content-ref url="/pages/XALJBM3XnX9Ftb2NNjps" %}
[Windows Device Installation](/installation/windows/device)
{% endcontent-ref %}


# Windows Desktop Client Installation

Video and written directions for installing the NoPorts desktop app

{% embed url="<https://vimeo.com/1038239765>" %}
NoPorts Desktop Overview
{% endembed %}

## Step 1: Download the NoPorts desktop application

[Link to Windows Store](https://apps.microsoft.com/detail/9n69scrrgv6r)

## Step 2: Log into the NoPorts desktop application

1. Launch the NoPorts desktop app and click 'Get Started'.
2. Enter your client atSign into the text field (e.g., @pluto83\_client), leave the root domain as is, and then click 'Next'.
3. A one-time password (OTP) will be sent to you via email. Enter this OTP into the app and then click 'Confirm'.

## Step 3: Back up your atKeys

Your atKeys (cryptographic keys) will be used to pair your atSign with this and other devices in future. You can [learn more about these keys here](https://www.youtube.com/watch?v=bRRLCOHP-BY).

1. Click on the Settings Icon in the top right corner of the app.
2. Click on 'Back Up Your Keys' in the left navigation panel.
3. Select a location on your device and save your keys.

## Step 4: Prepare a Profile to establish a NoPorts connection

1. Return to the Dashboard
2. Click the 'Add New' button to create a new Profile
   1. Enter the details for the new profile
   2. Start the connection by pressing :arrow\_forward: for the profile you just created
3. **Or,** connect using our test profile.
   1. Download the[ NoPorts test connection profile. ](https://drive.google.com/file/d/1qb0YrpRaGstLSBKoLJ4wwVUIMO5zCaMq/view)This is a json file containing connection details for a test profile we have created.
   2. Return to the NoPorts app Dashboard.
   3. Click 'Import' and select the test connection profile that you just downloaded.
   4. Click the Connect Icon :arrow\_forward: to establish a connection.
   5. Open a web browser and navigate to`http://localhost:8080`to confirm you successfully connected to our hidden webpage.

{% hint style="info" %}
\*Note, if you are connecting to your remote device, the remote device installation must be complete before the profile will connect. If utilizing a test profile, it will connect to our test site without needing a remote device to be set up first.
{% endhint %}


# Windows CLI Client Installation

### Step 1: Download the Installer

Download the installer [from GitHub](https://github.com/atsign-foundation/noports/releases/download/v5.8.7/NoPortsInstaller-windows-x64.zip).

### Step 2: Client Install

Launch the NoPorts-x64.msi program and allow it administrative permissions:

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

<figure><img src="/files/91NGEtgLhx6SE8W4t9yx" alt=""><figcaption></figcaption></figure>

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

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

### Step 3: Activate your client Atsign

{% hint style="warning" %}
If you've activated your **client** atSign on another device already, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

#### Step 3.1 Open the Windows installer and click "Activate atSign"

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

#### Step 3.2 Enter the atSign you wish to activate and click "Submit"

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

#### Step 3.3 Wait for the OTP (One time pincode) then enter it and press "Generate"

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

#### Step 3.4 Wait for the keys to generate, then you may either exit the program or go home

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


# Windows Device Installation

### Step 1: Download the Installer

Download the installer [from GitHub](https://github.com/atsign-foundation/noports/releases/download/v5.8.7/NoPortsInstaller-windows-x64.zip). Then unzip the file.

### Step 2: Activate your client Atsign

{% hint style="warning" %}
If you've activated your **client** atSign on another device already, this step will not work. Instead, follow this guide: [Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endhint %}

#### Step 2.1 Open the Windows installer and click "Activate atSign"

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

#### Step 2.2 Enter the atSign you wish to activate and click "Submit"

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

#### Step 2.3 Wait for the OTP (One time pincode) then enter it and press "Generate"

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

#### Step 2.4 Wait for the keys to generate, then go home

### Step 3: Install the Device Software

#### 3.1 Click "Device Install"

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

#### 3.2 Enter both of your atSigns into the associated fields, then pick a device name, and click "Next"

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

#### 3.3 If you wish to add additional arguments to pass sshnpd enter them, then click "Next"

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

#### 3.4 Wait for the installation to complete, then click "Next", and continue through the rest of the installation. Once installation has completed, it will look like this:

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

## FAQ

### How does the Windows Service work?

We use a lightweight wrapper service to run sshnpd. It pulls the arguments from the Windows Registry and executes sshnpd with them.

### How do I start or stop the service?

Open services.msc (appears as "services" from the start menu). The service will be called `sshnpd` with description `NoPorts-SSH-Daemon` . Click on the service and you will be provided with options to start/restart/stop the service depending on it's current status.

### How do I modify my configuration?

Open the registry editor (a.k.a. regedit) and navigate to `Computer\HKEY_LOCAL_MACHINE\SOFTWARE\NoPorts` . The `DeviceArgs` entry will contain all of the arguments that get passed directly into sshnpd. You may modify these accordingly, then [restart the service](#how-do-i-start-or-stop-the-service).


# Cloud Installation Guides

How to install NoPorts as part of creating a new VM

{% hint style="info" %}
This is a generic cloud-init guide, we also have some [cloud specific guides](#cloud-specific-guides) below
{% endhint %}

The NoPorts daemon can be installed on a Linux cloud virtual machine (VM) using a cloud-init script of the form:

```bash
#!/bin/bash
# Modify these lines to set the installation specific variables
ATCLIENT="@changeme_clientatsign"
ATDEVICE="@changeme_deviceatsign"
DEVNAME="changeme_devicename"
OTP="123456"
USER="changeme_user"
# The rest of the script shouldn't be changed
export HOME="/home/${USER}"
export SUDO_USER="${USER}"
mkdir -p /run/atsign
cd /run/atsign
VERSION=$(wget -q -O- "https://api.github.com/repos/atsign-foundation/noports/releases/latest" | grep -Po '"tag_name": "v\K.*?(?=")')
wget https://github.com/atsign-foundation/noports/releases/download/v${VERSION}/universal.sh
sh universal.sh -t device -c ${ATCLIENT} -d ${ATDEVICE} -n ${DEVNAME}
/usr/local/bin/at_activate enroll -a ${ATDEVICE} -s ${OTP} -p noports -k /home/${USER}/.atsign/keys/${ATDEVICE}_key.atKeys -d ${DEVNAME} -n "sshnp:rw,sshrvd:rw"
chown -R ${USER}:${USER} /home/${USER}/.atsign
```

Some clouds, such as Azure and Oracle Cloud will take the script pretty much as presented above. Other clouds, including AWS and GCP need alternate formatting or additional customisation.

In all cases the variables in the first section of the script should be changed to match the Atsigns being used, the desired device name, the Linux username and the one time password (OTP) or semi-permanent passcode (SPP) being used. e.g.:

```bash
#!/bin/bash
# Modify these lines to set the installation specific variables
ATCLIENT="@democlient"
ATDEVICE="@demodevice"
DEVNAME="cloudvm1"
OTP="643791"
USER="ubuntu"
```

Once the VM is started (which will generally take a few minutes) the NoPorts daemon will be waiting for an APKAM key in order to start up. That key can be approved using `at_activate`:

```bash
at_activate approve -a @democlient --arx noports --drx cloudvm1
```

### Cloud Specific Guides

{% content-ref url="/pages/PsSEAPWYUthqOKC2Cyig" %}
[Automated Installation on Amazon Web Services (AWS)](/installation/cloud-installation-guides/automated-installation-on-amazon-web-services-aws)
{% endcontent-ref %}

{% content-ref url="/pages/ocDE62yEXrQHHrQOalN5" %}
[Automated Installation on Google Cloud Platform (GCP)](/installation/cloud-installation-guides/automated-installation-on-google-cloud-platform-gcp)
{% endcontent-ref %}

{% content-ref url="/pages/ussqaaU7TwK06wpinYrR" %}
[Automated Installation on Microsoft Azure](/installation/cloud-installation-guides/automated-installation-on-microsoft-azure)
{% endcontent-ref %}

{% content-ref url="/pages/TaRBDBVzgf6SGbT4MfJk" %}
[Automated Installation on Oracle Cloud Infrastructure (OCI)](/installation/cloud-installation-guides/automated-installation-on-oracle-cloud-infrastructure-oci)
{% endcontent-ref %}


# Automated Installation on Amazon Web Services (AWS)

How to deploy NoPorts on Amazon Web Services using a cloud-init script

{% embed url="<https://vimeo.com/1015039889>" %}

When launching an instance on EC2 choose settings as usual for the instance type etc.

A security group with no external ports open can be created or reused.

Expand the `Advanced details` section at the bottom of the Launch an Instance page:

<div align="left"><figure><img src="/files/wmT2ewegkhUbOUWO7nGV" alt=""><figcaption></figcaption></figure></div>

Scroll down to the `User data - optional` box and paste in your customised YAML e.g.:

```yaml
#cloud-config
runcmd:
  - # Modify these lines to set the installation specific variables
  - ATCLIENT="@democlient"
  - ATDEVICE="@demodevice"
  - DEVNAME="cloudvm1"
  - OTP="739128"
  - USER="ec2-user"
  - # The rest of the script shouldn't be changed
  - export HOME="/home/${USER}"
  - export SUDO_USER="${USER}"
  - mkdir -p /run/atsign
  - cd /run/atsign
  - VERSION=$(wget -q -O- "https://api.github.com/repos/atsign-foundation/noports/releases/latest" | jq -r .tag_name)
  - wget https://github.com/atsign-foundation/noports/releases/download/${VERSION}/universal.sh
  - sh universal.sh -t device -c ${ATCLIENT} -d ${ATDEVICE} -n ${DEVNAME}
  - /usr/local/bin/at_activate enroll -a ${ATDEVICE} -s ${OTP} -p noports -k /home/${USER}/.atsign/keys/${ATDEVICE}_key.atKeys -d ${DEVNAME} -n "sshnp:rw,sshrvd:rw"
  - chown -R ${USER}:${USER} /home/${USER}/.atsign
```

Which will end up looking something like this:

<div align="left"><figure><img src="/files/YbyEWjNhK7eruA1noGbe" alt=""><figcaption></figcaption></figure></div>

The VM config should now be ready for `Launch instance`

After a few minutes the APKAM key can be approved:

```
at_activate approve -a @demodevice --arx noports --drx cloudvm1
```

If the VM isn't quite ready you'll see:

```
Found 0 matching enrollment records
No matching enrollment(s) found
```

Waiting a little longer and retrying should produce a successful approval:

```
Found 1 matching enrollment records
Approving enrollmentId 0bd3613d-d3e2-45b3-b175-8cab06c9bad0
Server response: AtEnrollmentResponse{enrollmentId: 0bd3613d-d3e2-45b3-b175-8cab06c9bad0, enrollStatus: EnrollmentStatus.approved}
```

The VM is now ready for connection with the NoPorts client.


# Automated Installation on Google Cloud Platform (GCP)

How to deploy NoPorts on Google Cloud Platform using a cloud-init script

{% embed url="<https://vimeo.com/1015037879>" %}

Navigate to Compute Engine > VM instances and hit the `+ CREATE INSTANCE` button as usual, then select Name, Region, Machine configuration etc.

Expand `Advanced options` at the bottom of the page:

<div align="left"><figure><img src="/files/oayU8XQUws7J94QmFzRk" alt=""><figcaption></figcaption></figure></div>

Then scroll down and expand `Management`:

<div align="left"><figure><img src="/files/504yA3dtH4YZquS1EbG2" alt=""><figcaption></figcaption></figure></div>

In the `Automation` section paste in your customised startup script like:

```bash
#!/bin/bash
# Modify these lines to set the installation specific variables
ATCLIENT="@democlient"
ATDEVICE="@demodevice"
DEVNAME="cloudvm1"
OTP="739128"
USER="noports"
# The rest of the script shouldn't be changed
useradd ${USER}
export HOME="/home/${USER}"
export SUDO_USER="${USER}"
mkdir -p /run/atsign
cd /run/atsign
VERSION=$(wget -q -O- "https://api.github.com/repos/atsign-foundation/noports/releases/latest" | grep -Po '"tag_name": "v\K.*?(?=")')
wget https://github.com/atsign-foundation/noports/releases/download/v${VERSION}/universal.sh
sh universal.sh -t device -c ${ATCLIENT} -d ${ATDEVICE} -n ${DEVNAME}
/usr/local/bin/at_activate enroll -a ${ATDEVICE} -s ${OTP} -p noports -k /home/${USER}/.atsign/keys/${ATDEVICE}_key.atKeys -d ${DEVNAME} -n "sshnp:rw,sshrvd:rw"
chown -R ${USER}:${USER} /home/${USER}
```

NB this script is creating a new user `noports` to deal with the fact that GCP images don't have default usernames.

Once filled, the box should look something like:

<div align="left"><figure><img src="/files/w86lRAdUDbZCBFHyRn0D" alt=""><figcaption></figcaption></figure></div>

The VM is now ready for `Create`

After a few minutes the APKAM key can be approved:

```
at_activate approve -a @demodevice --arx noports --drx cloudvm1
```

If the VM isn't quite ready you'll see:

```
Found 0 matching enrollment records
No matching enrollment(s) found
```

Waiting a little longer and retrying should produce a successful approval:

```
Found 1 matching enrollment records
Approving enrollmentId 0bd3613d-d3e2-45b3-b175-8cab06c9bad0
Server response: AtEnrollmentResponse{enrollmentId: 0bd3613d-d3e2-45b3-b175-8cab06c9bad0, enrollStatus: EnrollmentStatus.approved}
```

The VM is now ready for connection with the NoPorts client.


# Automated Installation on Microsoft Azure

How to deploy NoPorts on Azure using a cloud-init script

{% embed url="<https://vimeo.com/1015039181>" %}

In the Azure Portal select `Virtual machines` and hit the `+ Create` button.

Choose your preferred options for each sub-page of the `Create a virtual machine` process.

On the `Advanced` sub-page there's a `Custom data and cloud init` section where your customised script can be pasted:

```bash
#!/bin/bash
# Modify these lines to set the installation specific variables
ATCLIENT="@democlient"
ATDEVICE="@demodevice"
DEVNAME="cloudvm1"
OTP="739128"
USER="azureuser"
# The rest of the script shouldn't be changed
export HOME="/home/${USER}"
export SUDO_USER="${USER}"
mkdir -p /run/atsign
cd /run/atsign
VERSION=$(wget -q -O- "https://api.github.com/repos/atsign-foundation/noports/releases/latest" | grep -Po '"tag_name": "v\K.*?(?=")')
wget https://github.com/atsign-foundation/noports/releases/download/v${VERSION}/universal.sh
sh universal.sh -t device -c ${ATCLIENT} -d ${ATDEVICE} -n ${DEVNAME}
/usr/local/bin/at_activate enroll -a ${ATDEVICE} -s ${OTP} -p noports -k /home/${USER}/.atsign/keys/${ATDEVICE}_key.atKeys -d ${DEVNAME} -n "sshnp:rw,sshrvd:rw"
chown -R ${USER}:${USER} /home/${USER}/.atsign
```

It should look like this:

<div align="left"><figure><img src="/files/8CYfuFQrovd7WAEU72qh" alt=""><figcaption></figcaption></figure></div>

Once that's complete the VM is ready for `Review + create` then if all looks well hit `Create`

After a few minutes the APKAM key can be approved:

```
at_activate approve -a @demodevice --arx noports --drx cloudvm1
```

If the VM isn't quite ready you'll see:

```
Found 0 matching enrollment records
No matching enrollment(s) found
```

Waiting a little longer and retrying should produce a successful approval:

```
Found 1 matching enrollment records
Approving enrollmentId 0bd3613d-d3e2-45b3-b175-8cab06c9bad0
Server response: AtEnrollmentResponse{enrollmentId: 0bd3613d-d3e2-45b3-b175-8cab06c9bad0, enrollStatus: EnrollmentStatus.approved}
```

The VM is now ready for connection with the NoPorts client.


# Automated Installation on Oracle Cloud Infrastructure (OCI)

How to deploy NoPorts on Oracle Cloud Infrastructure using a cloud-init script

{% embed url="<https://vimeo.com/1015035980>" %}

When starting a VM on OCI first click the `Show advanced options` button having selected the usual options above that.

<div align="left"><figure><img src="/files/szUk3qozADg4snkKI6mU" alt=""><figcaption></figcaption></figure></div>

Then (in the `Management` tab) select `Paste cloud-init script`

<div align="left"><figure><img src="/files/l6x2jazndVYxKK23UPc0" alt=""><figcaption></figcaption></figure></div>

And paste your customised script into the `Cloud-init script` box:

```bash
#!/bin/bash
# Modify these lines to set the installation specific variables
ATCLIENT="@democlient"
ATDEVICE="@demodevice"
DEVNAME="cloudvm1"
OTP="739128"
USER="opc"
# The rest of the script shouldn't be changed
export HOME="/home/${USER}"
export SUDO_USER="${USER}"
mkdir -p /run/atsign
cd /run/atsign
VERSION=$(wget -q -O- "https://api.github.com/repos/atsign-foundation/noports/releases/latest" | grep -Po '"tag_name": "v\K.*?(?=")')
wget https://github.com/atsign-foundation/noports/releases/download/v${VERSION}/universal.sh
sh universal.sh -t device -c ${ATCLIENT} -d ${ATDEVICE} -n ${DEVNAME}
/usr/local/bin/at_activate enroll -a ${ATDEVICE} -s ${OTP} -p noports -k /home/${USER}/.atsign/keys/${ATDEVICE}_key.atKeys -d ${DEVNAME} -n "sshnp:rw,sshrvd:rw"
chown -R ${USER}:${USER} /home/${USER}/.atsign
```

<div align="left"><figure><img src="/files/zSnggMawIcCSCcApbFF7" alt=""><figcaption></figcaption></figure></div>

The VM is now ready for `Create`

After a few minutes the APKAM key can be approved:

```bash
at_activate approve -a @demodevice --arx noports --drx cloudvm1
```

If the VM isn't quite ready you'll see:

```bash
Found 0 matching enrollment records
No matching enrollment(s) found
```

Waiting a little longer and retrying should produce a successful approval:

```bash
Found 1 matching enrollment records
Approving enrollmentId 0bd3613d-d3e2-45b3-b175-8cab06c9bad0
Server response: AtEnrollmentResponse{enrollmentId: 0bd3613d-d3e2-45b3-b175-8cab06c9bad0, enrollStatus: EnrollmentStatus.approved}
```

The VM is now ready for connection with the NoPorts client.


# OpenWrt Installation Guide

How to install NoPorts onto an OpenWrt router.

{% embed url="<https://vimeo.com/1060920058>" %}
OpenWrt installation walk through
{% endembed %}

### Package repo for OpenWrt 24.10 and 23.05

We now have our own [package repo](https://atsign-foundation.github.io/OpenWrt-releases/) for the currently supported releases of OpenWrt. Please follow [this guide](https://github.com/atsign-foundation/OpenWrt-releases/tree/gh-pages?tab=readme-ov-file#how-to-use-on-openwrt) for installing the Atsign key and adding the packages.

### Manual install using the LuCI web interface

First download the latest packages for your chosen architecture from our [releases](https://github.com/atsign-foundation/Atsign_OpenWRT_packages/releases) page.

We've created packages for aarch64\_cortex-a53, arm\_cortex-a7\_neon-vfpv4, mips\_siflower, ramips (mipsel\_24k) and x86\_64; but if your chosen architecture isn't there please let us know by opening an [issue](https://github.com/atsign-foundation/Atsign_OpenWRT_packages/issues). These packages *should* work on older OpenWrt (and OpenWrt derivatives like GL.iNet), though note that the LuCI package uses the JavaScript framework that was introduced in OpenWrt 21.02.

With the packages ready to go, sign into the web interface for your router and go to `System`> `Software` in the menu. Click on `Upload Package` and `Browse` to the csshnpd package you downloaded. Click `Open` then `Upload` and `Install`. Repeat that process with the luci-app-csshnpd package.

For the new menu to appear you'll need to `Log out` then sign in again.

You can now go to `Network`>`NoPorts` and fill out the config tab with your device Atsign, manager Atsign, device name and the OTP for key generation. Click the `Enabled` box then hit `Save & Apply`.

Now go to the `NoPorts Enrollment` tab and follow the instructions there to generate a device key.

With the key in place navigate to `System`>`Startup` and `Start` the `sshnpd` service.

### Command line installation

{% embed url="<https://vimeo.com/1068947993>" %}
Walk through of OpenWrt CLI installation onto a Teltonika RUT241
{% endembed %}

The [releases](https://github.com/atsign-foundation/Atsign_OpenWRT_packages/releases) page includes instructions for command line installation. These will work on OpenWrt derivatives that don't use LuCI (e.g. Teltonika) or if you just prefer working on the command line.

Those command line snippets set some variables for the `RELEASE` number, `ARCH` for system architecture and `PACKAGE` name then use `wget` to download the package from GitHub.

Packages are installed using `opkg install` for OpenWrt 24.10 and earlier releases that use `.ipk` type packages, or `apk add` for newer OpenWrt which uses `.apk` packages.

For example, to install the c1.0.14 release:

```
RELEASE="1.0.14"
ARCH=$(opkg print-architecture | grep ' 10$' | awk '{print $2}')
PACKAGE="csshnpd_${RELEASE}-1_${ARCH}.ipk"
wget -O ${PACKAGE} https://github.com/atsign-foundation/Atsign_OpenWRT_packages/releases/download/c${RELEASE}/${PACKAGE}
opkg install ${PACKAGE}
```

Now edit `/etc/config/sshnpd` to use your Atsigns, device name and device Atsign OTP:

```
config sshnpd
        option atsign   '@example_device'
        option manager  '@example_client'
        option device   'rutx10'
        option args     ''
        option otp      '123456'
        option enabled  '1'
```

Run `at_enroll.sh` on the device. It will ask you to approvement the enrollment on your client (where you previously activated the Atsigns and generated the OTP):

```
at_activate approve -a @example_device --arx noports --drx rutx10
```

On the device you should see a message saying enrollment is complete, and that the .atKeys file has been written.

Now start the sshnpd service:

```
service sshnpd start
```

And you should be ready to connect to the device:

```
sshnp -f @example_client -t @example_device -d rutx10_remote -h rv_eu
```

### SNAPSHOT packages

NoPorts is now upstream in SNAPSHOT builds so you can install `luci-app-csshnpd` from the System > Software page on LuCI. Or for a command line install run:

```
apk update
apk add csshnpd
```


# Installation Explained

The universal.sh installer does a lot, but you may want to have more control

### Linux packages

NoPorts is packaged in a .deb for Debian based systems such as Kali, Mint, Raspberry Pi OS (previously Raspbian) and Ubuntu; and in .rpm for Red Hat based systems such as Alma Linux, Amazon Linux, CentOS, Fedora, Red Hat Enterprise Linux (RHEL) and Rocky Linux.

`universal.sh` checks whether it's being run on a distro that supports those packages, and installs from the appropriate package manager.

Once these packages are installed they will be automatically upgraded alongside other packages on the system (e.g. when you run `sudo apt update && sudo apt upgrade -y` or `sudo dnf update`)

If you'd like to install the packages yourself then:

#### apt package

**step by step**

First add our public key to your keyring:

```
sudo mkdir -p /usr/share/keyrings
curl -fsSL https://apt.noports.com/noports.pub.asc | \
  sudo gpg --dearmor -o /usr/share/keyrings/noports-archive-keyring.gpg
```

Then add the `apt.noports.com` repo to apt sources:

```
echo "deb [signed-by=/usr/share/keyrings/noports-archive-keyring.gpg] https://apt.noports.com/ stable main" | \
  sudo tee /etc/apt/sources.list.d/noports.list
```

Then update sources and install NoPorts:

```
sudo apt update && sudo apt install -y noports
```

**one liner**

Alternatively those steps can be combined into a single line:

```
sudo mkdir -p /usr/share/keyrings ; curl -fsSL https://apt.noports.com/noports.pub.asc | sudo gpg --dearmor -o /usr/share/keyrings/noports-archive-keyring.gpg ; echo "deb [signed-by=/usr/share/keyrings/noports-archive-keyring.gpg] https://apt.noports.com/ stable main" | sudo tee /etc/apt/sources.list.d/noports.list ; sudo apt update ; sudo apt install -y noports
```

#### rpm package

Create a repository file at `/etc/yum.repos.d/noports.repo`:

```
sudo tee /etc/yum.repos.d/noports.repo <<EOF
[noports]
name=NoPorts Repository
baseurl=https://rpm.noports.com/\$basearch/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://rpm.noports.com/noports.pub.asc
EOF
```

Then install NoPorts:

```
sudo dnf install noports
```

### Mac Homebrew

If `universal.sh` finds the `brew` command it will offer to install from our [Homebrew tap](https://github.com/atsign-foundation/homebrew-tap). If you'd rather do that yourself then:

```
brew tap atsign-foundation/homebrew-tap
brew install noports
```

### No Package Manager

When `universal.sh` doesn't find a supported package manager it will install NoPorts binaries to `/usr/bin` when run as root (with `sudo`) or `$HOME/.local/bin` when not run as root.

That's done by downloading the platform/architecture appropriate archive (`.tgz` or `.zip`) from the [latest NoPorts GitHub release](https://github.com/atsign-foundation/noports/releases/latest), and then unpacking the files into their destination directory.

If you'd rather not use `universal.sh` or one of the packages mentioned above then download an archive directly and unpack it to the destination of your choice.

### Daemon config - /etc/noports/sshnpd.yaml

`univeral.sh` will ask about client and manager addresses and the device name and use those to populate the config file in `/etc/noports/sshnpd.yaml` . That config can be edited and customised to suit more complex use cases. On systemd based systems a unit file will be installed to run the NoPorts daemon. For more details see [systemd unit](/installation/advanced-installation-guides/device-installation-sshnpd/systemd-unit). If systemd isn't present then there are various options for [running without systemd](/installation/advanced-installation-guides/device-installation-sshnpd/standalone-binaries).

{% content-ref url="/pages/iQ88En9CW0N7RcEeanHH" %}
[Device Installation](/installation/advanced-installation-guides/device-installation-sshnpd)
{% endcontent-ref %}

{% content-ref url="/pages/5UrDYh36Udmp7wgtVGvY" %}
[Client Installation](/installation/advanced-installation-guides/client-installation-sshnp)
{% endcontent-ref %}


# Device Installation

There are three steps to getting a device installed:

### 1. Install binaries

As described in [Installation Explained](/installation/advanced-installation-guides) this can be done using the `universal.sh` install script, installing from a package manager (e.g. apt or dnf for Linux or brew for MacOS), or simply downloading the binary archive from [GitHub releases](https://github.com/atsign-foundation/noports/releases) and expanding it to your preferred destination.

### 2. Provide config

The NoPorts daemon `sshnpd` will look for config in `/etc/noports/sshnpd.yaml`. The `universal.sh` script will set this up for you in response to prompts, or it can be edited manually.

Config can also be provided in a different file location using the `--config` flag.

Or config options can be passed directly to `sshnpd` using [command line flags](/usage/sshnpd-configuration)

### 3. Provide device atKeys file

The NoPorts address used by a device (say `@exampledevice_np`) is held in a file that defaults to `$HOME/.atsign/keys/@exampledevice_np.atKeys`

The `at_activate` command is used to create the atKeys file.

Usually atKeys on a device are created by performing an enrollment operation `at_activate enroll ...` , but it's also possible to activate an atKey directly on a device using `at_activate ...`


# Running without systemd

The NoPorts daemon doesn't have to be run by systemd

Once NoPorts is installed with a `/etc/noports/sshnpd.yaml` config and an atKeys file all that's needed to start the daemon is to run `sshnpd` .

But... without systemd there's nothing to restart `sshnpd` if it exits, and there's nothing capturing logs (and compressing, rotating and pruning them).

At the most basic level a simple script will restart the daemon if it fails:

```bash
#!/bin/bash
BACKOFF_INTERVAL=10
while true; do
  sshnpd
  sleep "$BACKOFF_INTERVAL"
done
```

Whatever runs `sshnpd` should be some kind of background task (so it doesn't exit when the session launching it is disconnected). For example redirect logs and run in background with:

```
nohup sshnpd > sshnpd.log 2> sshnpd.err < /dev/null &
```

A similar effect can be achieved by running `sshnpd` inside a terminal multiplexer such as [GNU Screen](https://www.gnu.org/software/screen/) or [Tmux](https://en.wikipedia.org/wiki/Tmux).


# Systemd Unit

How we use systemd

[systemd](https://en.wikipedia.org/wiki/Systemd) has become the standard way of defining and managing services on all major Linux distributions. Our .deb and .rpm packages will automatically install a systemd unit for the NoPorts daemon `sshnpd` into `/lib/systemd/system/sshnpd.service`:

```systemd
[Unit]
Description=NoPorts Daemon
After=network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Type=simple
Restart=always
RestartSec=3
KillMode=process

# The line below runs the sshnpd service, with the config from
# /etc/noports/sshnpd.yaml
ExecStart=/usr/bin/sshnpd
```

### override.conf

We also create an `/etc/systemd/system/sshnpd.service.d/override.conf` that's primarily used to set the username that NoPorts runs as. The template (without comments) is:

```systemd
[Service]
User=1000
```

`1000` will be replaced by `universal.sh` with the username of the user running the install script. To set it manually, or change it to another user, run `sudo systemctl edit sshnpd` . Once changes have been made then run `sudo systemctl daemon-reload` to pick up the changes then `sudo systemctl restart sshnpd` to restart the daemon. You can follow the daemon logs with `journalctl -u sshnpd -f` .

### NoPorts daemon config - sshnpd.yaml

The expected location for NoPorts daemon config is at `/etc/noports/sshnpd.yaml` and that file should be edited to reflect your choice of device and client names etc. At a minimum the sections marked `TODO` must be filled out correctly.

#### Config migration

Previous versions of NoPorts put config into environment variables in systemd units and then passed those into command line arguments for the daemon.

When upgrading with `universal.sh` those variables will be migrated from the systemd units to `sshnpd.yaml` . If you've created a very complex config please check that the migration has completed correctly.


# Client Installation

There are two steps to getting a client installed:

### 1. Install binaries

As described in [Installation Explained](/installation/advanced-installation-guides) this can be done using the `universal.sh` install script, installing from a package manager (e.g. apt or dnf for Linux or brew for MacOS), or simply downloading the binary archive from [GitHub releases](https://github.com/atsign-foundation/noports/releases) and expanding it to your preferred destination.

### 1a. Add binaries folder to the path

If binaries are installed to their default location then this shouldn't be necessary, but if they're elsewhere it's recommend that you add the binary install location to the PATH.

{% tabs %}
{% tab title="Linux" %}
If you chose not to install as root, you will need to add `~/.local/bin` to your `PATH`.\
Add the following line to your shell's rc file:

```sh
export PATH="$PATH:$HOME/.local/bin";
```

{% endtab %}

{% tab title="macOS" %}
If you chose not to install as root, you will need to add `~/.local/bin` to your `PATH`.\
Add the following line to your shell's rc file:

```sh
export PATH="$PATH:$HOME/.local/bin";
```

{% endtab %}
{% endtabs %}

### 2. Activate your client address

{% hint style="danger" %}
If you don't own a pair of NoPorts addresses, please visit [the registrar](https://my.noports.com/no-ports-plans) before continuing.
{% endhint %}

### 2.1. First time activating your address

We will now activate the client address, you only need to activate the client address now. The device address should be activated during the device installation.

{% tabs %}
{% tab title="Linux" %}
Now that you have at\_activate installed, you can invoke the command with the name of the address you would like to activate:

<pre class="language-bash"><code class="lang-bash"><strong>at_activate -a @my_noports_client
</strong></code></pre>

{% endtab %}

{% tab title="macOS" %}
Now that you have at\_activate installed, you can invoke the command with the name of the address you would like to activate:

```bash
at_activate -a @my_noports_client
```

{% endtab %}
{% endtabs %}

### Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

The application will pause and wait for the input of a one time pin (OTP) before you can continue. You should receive this pin to the contact information associated with the registration of your noports address (i.e. email or text message).

\*\*\*If you are using a gmail.com account we have seen that sometimes the OTP gets stuck in the SPAM or PROMOTIONS folder. If you do not see the OTP check those folders.

Once you receive the message, enter the pin into the application and press enter to continue. The application should proceed to create the cryptographic keys and store them at `~/.atsign/keys/@my_noports_client_key.atKeys`.

An address can only be activated once, to install this address to future devices, you must copy this file to the device (see 3.b.).

### 2.2. Activated this address before

{% hint style="warning" %}
If you have activated the client address before, you must copy the address from another machine where it's been activated.
{% endhint %}

The address will be located at `~/.atsign/keys/@my_noports_client_key.atKeys`. Copy this file from your other machine to the same location on the machine that you are installing NoPorts on.

### All Done!

sshnp is ready to go, you can now proceed to [installing your device](/installation/advanced-installation-guides/device-installation-sshnpd), or if you've already done that, checkout our [usage guide](/usage/basic-usage-1).


# Custom OS/Device Installs

Here you'll find instructions for custom operating systems or device installs.

{% content-ref url="/pages/g7wvPHAgfy5FGsXVvTCB" %}
[IPFire](/installation/custom-os-device-installs/ipfire)
{% endcontent-ref %}

{% content-ref url="/pages/jVd7XixhMEA3RZAscZnw" %}
[Nokia SR Linux](/installation/custom-os-device-installs/nokia-sr-linux)
{% endcontent-ref %}


# IPFire

Installation of sshnpd on the IPFire.org firewall

{% embed url="<https://youtu.be/6PzJqeI5g9g>" %}

### Install IPFire

IPFire provides a solid Firewall and uses a base Linux OS. The installation of the OS itself is well documented at ipfire.org. X64 and Arm devices like Raspberry PI's are well supported.

\
Make sure to configure the network interfaces and ensure you can get to the Web Interface on

```
https://<GREEN Interface IP>:444
```

### Installing sshnpd the SSH No Ports Daemon

#### Web UI Setup

SSH No Ports relies on the SSH daemon and so the first step is to enable it on the IPFire Web interface, under System.

<figure><img src="/files/uE6svdwKw73zAVQrZfcR" alt=""><figcaption><p>Enable all options</p></figcaption></figure>

We will also need to add the TMUX package via the web interface under the IPFire section click Pakfire, then add TMUX.

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

#### Linux Setup

#### Add non root user

IPFire only has a root user after installation, so the first step is to set up a non privileged account. In this example we will use `atsign` but feel free to pick your own. Log in to the console or via SSH as root and type:

```
useradd -d /home/atsign -m -U atsign
```

#### Non root user environment

The next step is su to the user you just created and set up the directories sshnpd will need

```
su - atsign
mkdir -p ~/.atsign/keys ~/.ssh
chmod 700 ~/.atsign ~/.atsign/keys ~/.ssh
touch ~/.ssh/authorized keys
chmod 600 ~/.ssh/authorized keys
```

#### Adding sudo access (if you want to) to the new user account

Using `sudo` allows you to get access to the root account if you need it, but it's a good (though optional) practice to remain at a non root shell when you don't.

As root you will need to edit the /etc/sudoers file and uncomment the line below as shown by removing the #. Note that you may need to use `w!` in vi to force the update of the file.

```
## Uncomment to allow members of group sudo to execute any command
%sudo	ALL=(ALL:ALL) ALL
```

Once done, then you can add the sudo group and then add the username atsign to the group with the following commands as root:

```
groupad sudo
usermod -a -G sudo atsign
```

Then add a password to the atsign account again as root:

```
passwd atsign
```

Once completed, then check everything is working by su - to atsign the using sudo -s to get back to root.

```
su - atsign
sudo -s 
```

#### Installing sshnpd

As atsign (not root!) download the SSH No Ports software, which we can do with curl, and then unpack the archive with tar. The curl command below brings in the x64 CPU architecture file. If you are using Arm/Arm64, then curl down the right option by picking the right link from:

{% content-ref url="/pages/xZdWqkN0ILndj5WRlDHi" %}
[Installation Explained](/installation/advanced-installation-guides)
{% endcontent-ref %}

```
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-x64.tgz -o sshnp.tgz
tar zxvf sshnp.tgz
```

To install the software, just cd and run the install command:

```
cd sshnp
./install.sh tmux sshnpd
```

You will see some errors at this stage as IPFire uses fcron instead of cron. Installing fcron jobs requires root privileges, which we will address shortly.

#### Configuring the sshnpd.sh file

The sshnpd is started via a script and that script and that script needs some simple edits. You will need to know your atSign for the device (\_device) and manager (\_client). to edit use nano/vi on this file.

```
~/.local/bin/sshnpd.sh
```

Then edit the lines as below with **your** details.

```
manager_atsign="@cconstab" # MANDATORY: Manager/client address/Comma separated addresses (atSign/s)
device_atsign="@ssh_1"     # MANDATORY: Device address (atSign)
device_name="ipfire01"     # Device name

```

#### Certificate Authority public certificates

IPFire has non standard base certificates, but we can install the latest versions from Mozilla so the sshnpd daemon can use TLS, by using these commands.

```
sudo mkdir -p /etc/pki/tls/certs
curl --etag-compare etag.txt --etag-save etag.txt --remote-name https://curl.se/ca/cacert.pem && sudo mv cacert.pem /etc/pki/tls/certs/ca-bundle.crt
```

#### Put your atSign atKeys file in place

If you have not got your atKeys file you will need to use at\_activate to get them as explained in the the advanced installation guide. If you do have the keys for your device then they need to be in the \~/.atsign/keys directory. You can scp them over for instance. Its a good idea to chmod them to 600.

```
chmod 600 ~/.atsign/keys/*
```

#### Adding the fcron entries

As mentioned above fcron is used not cron so a couple of extra steps are required. First add your username to the /etc/fcron.allow file.

```
sudo vi /etc/fcron.allow
```

Then add your username ours looks like this

```
root
atsign
```

Once that is completed then you can add an entry to atsign's fcron, this can only be done as root and uses vi to edit by default.

```
sudo fcrontab -u atsign -e
```

Then you will need to add the following line:

```
@reboot tmux new-session -d -s sshnpd && tmux send-keys -t sshnpd /home/atsign/.local/bin/sshnpd.sh C-m
```

That's it. You are done!

To test you can reboot or as atsign run the command below and try and log in using sshnp

```
@reboot tmux new-session -d -s sshnpd && tmux send-keys -t sshnpd /home/atsign/.local/bin/sshnpd.sh C-m &
```

#### Logging in from a remote machine

At this point you will be able to log in remotely using sshnp. The first time you will need to specify an ssh key using the -i and -s arguments. This will put the public key into the authorized\_hosts file on the IPFire machine. In my case, I would use:

```
sshnp -f @cconstab -t @ssh_1 -h @rv_am -d ipfire01 -i ~/.ssh/id_rsa -s
```

Yours will look like something similar depending on your SSH Key pair (you can generate one if you do not have one with ssh-keygen) and your client/device atSigns.

When you get logged in, you can remove the -s and the -i flags and log in on subsequent logins, as the public key will be in place on the IPFire machine. You will have to put the keys you want to use in \~/.ssh/config also on the machine you are ssh'ing from. In my case, I use a single line:

```
IdentityFile ~/.ssh/id_rsa
```

Remember to keep your SSH and atSign keys safe and make a copy offline.

You are now able to log in from anywhere as long as the firewall and you have Internet access. Congrats!

#### For the paranoid

If you would like to remove the ssh daemon from the GREEN side as well then you can edit the `/etc/ssh/sshd_config` file to only bind on localhost but updating this line:

```
ListenAddress 0.0.0.0
```

to:

```
ListenAddress localhost
```

and then reboot or restart the sshd daemon.


# Nokia SR Linux

NoPorts as a native feature of the Nokia SR Linux network OS

NoPorts runs on Nokia [SR Linux](https://learn.srlinux.dev) routers as a **native application**, built with the SR Linux NetOps Development Kit (NDK) and listed in Nokia's official [NDK App Catalog](https://learn.srlinux.dev/ndk/apps/noports/). Unlike a generic Linux install, everything is managed the way router operators expect:

* Configuration lives in the **router's own config tree** (CLI, gNMI, or JSON-RPC) with candidate/commit/rollback semantics — no env files, no hand-managed daemons
* Operational state (`oper-state`, PID, daemon version) is published into the state tree and streams over gNMI telemetry
* Device keys are cut **on the router** with APKAM enrollment — no atKeys files are ever copied to the device
* The daemon runs in the management VRF and is supervised (restarted, reconfigured on commit) by the NDK agent

Source, releases and full documentation: [atsign-foundation/noports-srlinux](https://github.com/atsign-foundation/noports-srlinux).

### Requirements

* SR Linux 24.3.1 or later (Debian-based releases); amd64 or arm64
* Two Atsigns: one for the router, one for the operator — see [noports.com](https://noports.com)
* The NoPorts client installed on your machine (see [Client Installation](/installation/advanced-installation-guides/client-installation-sshnp))

{% hint style="info" %}
No router hardware? The [repo quickstart](https://github.com/atsign-foundation/noports-srlinux/blob/trunk/QUICKSTART.md) includes two free virtual labs using Nokia's public SR Linux container image: a [containerlab](https://containerlab.dev) topology, and a standalone plain-Docker variant that runs natively on Apple Silicon.
{% endhint %}

### Install

Download the `.deb` (amd64 and arm64) from the [releases page](https://github.com/atsign-foundation/noports-srlinux/releases), copy it to the router, then from the SR Linux CLI drop to the shell with `bash`:

```bash
sudo dpkg -i noports-srlinux_*.deb   # postinstall reloads app_mgr
```

### Configure from the SR Linux CLI

```
enter candidate
set / noports device-atsign @mydevice
set / noports access managers [ @manager ]
set / noports device name srl-router-1
set / noports admin-state enable
commit now
save startup
```

Check what the agent thinks:

```
info from state / noports state
```

Until the router is onboarded it reports `oper-state awaiting-onboarding`. The full command surface — policy Atsigns for fleet-scale access control, device groups, permit-open lists for `npt`, sshd options — is documented in the repo's [CLI reference](https://github.com/atsign-foundation/noports-srlinux/blob/trunk/docs/cli-reference.md).

### Onboard the router (APKAM)

Enrollment cuts new, scope-limited APKAM keys on the router itself, using a one-time passcode; the device Atsign's full keys never leave your custody.

On your machine:

```bash
at_activate otp -a @mydevice
```

On the router (bash shell):

```bash
sudo /opt/noports/onboard-noports.sh <passcode>
```

While it waits, approve from your machine:

```bash
at_activate approve -a @mydevice --arx noports --drx srl-router-1
```

The agent detects the new keys within about 15 seconds and starts the daemon — `info from state / noports state` shows `oper-state running`.

### Connect

```bash
sshnp -f @manager -t @mydevice -d srl-router-1 -u admin
```

You can also tunnel gNMI (or NETCONF/JSON-RPC) without SSH — add the port to the permit-open list first (`set / noports access permit-open [ localhost:22 localhost:57400 ]`):

```bash
npt -f @manager -t @mydevice -d srl-router-1 -r localhost -p 57400 -l 57400
gnmic -a localhost:57400 -u admin --skip-verify capabilities
```

### Networks that only allow outbound 443

Management VRFs are often restricted to well-known outbound ports. Both sides of NoPorts can be pinned to 443 — this exact combination is verified end-to-end on SR Linux:

On the router (before onboarding, so enrollment uses it too):

```
set / noports root-server proxy:proxy0001.atsign.org:443
```

On the client, add `--443` so the relay data path also uses 443:

```bash
sshnp -f @manager -r @rv_oc -t @mydevice -d srl-router-1 -u admin \
  --443 --relay-auth-mode escr \
  --root-domain "proxy:proxy0001.atsign.org:443"
```

{% hint style="info" %}
NoPorts device packages also exist for **Cisco IOS-XE** app hosting ([noports-iosxe](https://github.com/atsign-foundation/noports-iosxe)) and **Junos OS Evolved** containers ([noports-junos-evolved](https://github.com/atsign-foundation/noports-junos-evolved)).
{% endhint %}


# Installs at Scale

Typing is less fun after a few devices.

### Important Notes

This is an engineering guide, not a definitive solution, as every production environment is different. Feel free to borrow what is useful and ignore what is not. If you have better ideas or ways, please let us know!

### Other considerations

By default, the hostname is used as the `-d`DEVICE\_NAME. Your hostnames may not match the requirements of the DEVICE\_NAME flag.

* Lowercase Alphanumeric max 15 Characters Snake Case before version 5.0.3
* Case insensitive Alphanumeric max 36 Chars Snake Case from version 5.0.3 onwards.
  * allows UUID snake cased device names.

### Install.sh

Cut and paste this script and tailor it to your needs. Do not forget to chmod 500 or else it will not run! More details below on how to set things up, and a demo run, too, using Docker.

```bash
#!/bin/bash
# Configure these variables to your liking or pass in args
if [ $# -ne 8 ]
then
# USERNAME & PASSWORD created with sudo priviledges by install.sh
export USERNAME="ubuntu"
export PASSWORD="changeme"
# URL of the config/sshnpd.sh file contained in this repo (this will change if repo is cloned)
export CONFIG_URL="https://gist.githubusercontent.com/cconstab/142c942ce0c8caa3348d0976a60fbfd1/raw/d243d64573bf2b7de5e827ff9b7b7f2f2413901b/gistfile1.txt"
# Remember to encrypt your keys!!!!
# Encrypt with
# openssl enc -aes-256-cbc -pbkdf2 -iter 1000000 -salt -in ~/.atsign/keys/@ssh_1_key.atKeys -out @ssh_1_key.atKeys.aes
# Test decrypt with
# openssl aes-256-cbc -d -salt -pbkdf2 -iter 1000000 -in ./@ssh_1_key.atKeys.aes -out ./@ssh_1_key.atKeys
export ATKEYS_URL="https://filebin.net/cpme4bhrqolyrnts/_ssh_1_key.atKeys.aes"
# This is the AES password you used to encrypt the above file
export ATKEY_PASSWORD="helloworld12345!"
# Manager atSign either a Single atSign or comma delimited list from sshnpd v5.0.3
export MANAGER_ATSIGN="@cconstab"
export DEVICE_ATSIGN="@ssh_1"
export DEVICE_NAME="$(hostname)"
else 
export USERNAME=$1
export PASSWORD=$2
export CONFIG_URL=$3
export ATKEYS_URL=$4
export ATKEY_PASSWORD=$5
export MANAGER_ATSIGN=$6
export DEVICE_ATSIGN=$7
export DEVICE_NAME=$8
fi
####################################################################
# Get machine updated and with the needed packages                 #
####################################################################
apt update
apt install tmux openssh-server curl cron sudo -y 
# create USERNAME with sudo priviledges
useradd -m -p $(openssl passwd -1 ${PASSWORD}) -s /bin/bash -G sudo ${USERNAME}
####################################################################
# start sshd listening on localhost only                           #
####################################################################
# Update the sshd config so it only runs on localhost
#sed -i 's/#ListenAddress 0.0.0.0/ListenAddress 127.0.0.1/' /etc/ssh/sshd_config
# restart sshd if your OS starts it on install
# e.g on Ubuntu/Debian
#systemctl restart ssh.service
# or Redhat/Centos
#systemctl restart sshd.service
####################################################################
# Start sshd Only needed if sshd is not started by default         #
# for example a docker container                                   #
# Remove these lines if the OS you are using starts up sshd itself #
####################################################################
# File needed for sshd to run
mkdir /run/sshd
# generate the sshd Keys
ssh-keygen -A
# Start sshd listening on localhost and with no password auth 
/usr/sbin/sshd -D -o "ListenAddress 127.0.0.1" -o "PasswordAuthentication no"  &
####################################################################
# Install sshnpd as the selected USERNAME                          #
####################################################################
su --whitelist-environment="MANAGER_ATSIGN,DEVICE_ATSIGN,ATKEY_PASSWORD,ATKEYS_URL,DEVICE_NAME" -c ' \
set -eux; \
    case "$(dpkg --print-architecture)" in \
        amd64) \
            SSHNPD_IMAGE="https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-x64.tgz" ;; \
        armhf) \
            SSHNPD_IMAGE="https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-arm.tgz" ;; \
        arm64) \
            SSHNPD_IMAGE="https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-arm64.tgz" ;; \
        riscv64) \
            SSHNPD_IMAGE="https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-riscv.tgz" ;; \
        *) \
            echo "Unsupported architecture" ; \
            exit 5;; \
    esac; \
cd ; \
mkdir -p ~/.local/bin ; \
mkdir -p ~/.atsign/keys ; \
curl -fSL ${ATKEYS_URL} -o atKeys.aes ; \
openssl aes-256-cbc -d -salt -pbkdf2 -iter 1000000 -in ./atKeys.aes -out ~/.atsign/keys/${DEVICE_ATSIGN}_key.atKeys --pass env:ATKEY_PASSWORD ; \
chmod 600 ~/.atsign/keys/${DEVICE_ATSIGN}_key.atKeys ; \
curl -fSL $SSHNPD_IMAGE -o sshnp.tgz ; \
tar zxvf sshnp.tgz ;\
sshnp/install.sh tmux sshnpd ;\
curl --output ~/.local/bin/sshnpd.sh ${CONFIG_URL} ; \
sed -i "s/MANAGER_ATSIGN/$MANAGER_ATSIGN/" ~/.local/bin/sshnpd.sh ; \
sed -i "s/DEVICE_ATSIGN/$DEVICE_ATSIGN/" ~/.local/bin/sshnpd.sh ; \
sed -i "s/DEVICE_NAME/$DEVICE_NAME/"  ~/.local/bin/sshnpd.sh ; \
# Uncomment this if you _want_ to use '-u' for sshnpd ; \
#sed -i "s/# u=\"-u\"/u=\"-u\"/" ~/.local/bin/sshnpd.sh ; \
# Uncomment this if you do _not_ want `-s` enabled (you would need to send ssh keys)
#sed -i "s/s=\"-s\"/# s=\"-s\"/"  ~/.local/bin/sshnpd.sh ; \
rm -r sshnp ; \
rm sshnp.tgz atKeys.aes' $USERNAME
####################################################################
# Start sshnpd, the crontab entry will do this on reboots          #
####################################################################
su - $USERNAME sh -c "/usr/bin/tmux new-session -d -s sshnpd && tmux send-keys -t sshnpd /home/ubuntu/.local/bin/sshnpd.sh C-m" 
# Helpful to sleep if using Docker so container stays alive.
# sleep infinity
```

### Set up your environment.

Each Atsign has its own set of keys that are "cut" with at\_activate. This will cut the keys for the Atsign and place them in `~/.atsign/keys`. Each machine requires the atKeys file to run sshnpd, so, we need to have a way to get them to each device. It is possible to ssh/scp them, but that becomes very cumbersome at scale. Instead, we encrypt the keys with AES256 and place them on a webserver. When the install script is run, it knows both the URL and the encryption password and can pull the atKeys file to the right place.

The steps are to (1) get the atKeys file as normal using at\_activate, then (2) encrypt them using a command like this:

```
mkdir enckeys
cd enckeys
openssl enc -aes-256-cbc -pbkdf2 -iter 1000000 -salt -in ~/.atsign/keys/@ssh_1_key.atKeys -out @ssh_1_key.atKeys.aes
```

This command will ask you for a password which you will put in the `install.sh` file as `ATKEY_PASSWORD`.

You can then set up a simple http (the file is encrypted) server to serve the keys with. For example, a Python single line of code:

`python3 -m http.server 8080 --bind 0`

Alternatively, you can put the keys file on filebin.net and it will locate the file in a random URL which you can put into the `install.sh` file. For example:

`https://filebin.net/s2w5r6gwemmz5kvi/_ssh_1_key.atKeys.aes`

It is worth noting that the `@` gets translated to a `_` but that does not effect the script. Using this site has the advantage that the URL is hidden, and it uses TLS—plus you can delete the files once completed.

At this point you can derive the URL of the encrypted atKeys file and put it in the `install.sh` file headers.

```
export ATKEYS_URL="http://192.168.1.61:8080/@ssh_1_key.atKeys.aes"
# This is the AES password you used to encrypt the above file
export ATKEY_PASSWORD="helloworld12345!"
```

The other variables should be straightforward enough.

```
export USERNAME=ubuntu
export PASSWORD="changeme"
export CONFIG_URL="https://raw.githubusercontent.com/cconstab/sshnpd_config/main/config/sshnpd.sh"
```

{% embed url="<https://gist.githubusercontent.com/cconstab/142c942ce0c8caa3348d0976a60fbfd1/raw/d243d64573bf2b7de5e827ff9b7b7f2f2413901b/gistfile1.txt>" %}
Gist for sshnpd config file
{% endembed %}

The other variables set up the Atsigns for the manager and device and for the device name itself. The device name by default uses the `hostname` using the shell command `$(hostname)` , but that only works if the hostname is compliant with the `-d` format of sshnpd. You can pick another way to identify the host or just make sure the hostname is compliant.

### Running the install.sh (Note: Has to be run as root)

This is a simple matter now of getting the install.sh to the target device and running it. The needed files will be installed, the username name created, cronjobs put in place, and the 'sshnpd' will be started.

How you get the `install.sh` file to the target machine is going to vary depending on your environment. Using scp is a good option, as is using ssh or curl and pulling the file (using the same encryption method perhaps).

### Scaling things up

The install.sh script works fine on individual machines, but if you want to install on, say, 25 machines, this is how you do it.

First, you need to have ssh root access to the machines you want to install on. *This SSH access will be removed as you do the install with this line uncommented:*

```bash
#sed -i 's/#ListenAddress 0.0.0.0/ListenAddress 127.0.0.1/' /etc/ssh/sshd_config
```

If you pass 8 arguments into the install.sh they will be used rather than the hardcoded values. This allows you to pass in the values needed as the script is run QED.

For example:

`./install.sh ubuntu changeme https://raw.githubusercontent.com/cconstab/sshnpd_config/main/config/sshnpd.sh http://192.168.1.61:8080/@ssh_1_key.atKeys.aes helloworld @cconstab @ssh_1 $(hostname)`

### To test this

Using Docker is the simple way to test any options first before moving to production.

Something like this will mount the script and start a basic Linux build:

`docker run -it -v ./install.sh:/root/install.sh debian:trixie-slim`

You can then cd and run the `install.sh` script. For example:

```
╰$ docker run -it -v ./install.sh:/root/install.sh debian:trixie-slim
root@f5040633c8a0:/# cd
root@f5040633c8a0:~# ls
install.sh
root@f5040633c8a0:~# ./install.sh 
```

After the install has completed, you can su - to the USERNAME you chose and see tmux/sshnpd running.

```
root@f5040633c8a0:~# su - ubuntu
ubuntu@f5040633c8a0:~$ tmux ls
sshnpd: 1 windows (created Sun Mar  3 22:48:01 2024)
ubuntu@f5040633c8a0:~$ 
```

On another machine, you can log in to the container using the select MANAGER\_ATSIGN, remembering to give the daemon a ssh key and the username.

```
~/.local/bin/sshnp -f @cconstab -t @ssh_1  -h @rv_am -s -i ~/.ssh/id_ed25519 -u ubuntu  -d f5040633c8a0
2024-03-03 14:51:34.574057 : Resolving remote username for user session
2024-03-03 14:51:34.574107 : Resolving remote username for tunnel session
2024-03-03 14:51:34.574562 : Sharing ssh public key
2024-03-03 14:51:36.239757 : Fetching host and port from srvd
2024-03-03 14:51:39.239811 : Sending session request to the device daemon
2024-03-03 14:51:39.469112 : Waiting for response from the device daemon
2024-03-03 14:51:40.993543 : Received response from the device daemon
2024-03-03 14:51:40.994470 : Creating connection to socket rendezvous
2024-03-03 14:51:41.114766 : Starting tunnel session
2024-03-03 14:51:41.989428 : Starting user session
Linux f5040633c8a0 6.6.12-linuxkit #1 SMP Fri Jan 19 08:53:17 UTC 2024 aarch64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Mar  3 22:51:42 2024 from 127.0.0.1
-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
ubuntu@f5040633c8a0:~$
```

You are now logged into the container. If you need root access, you can use the password you chose to `sudo -s`

{% embed url="<https://asciinema.org/a/645698>" %}

Feel free to adapt this outline to your specific needs and share your improvements back with the community.


# Upgrading NoPorts Software

### Overview

Keeping NoPorts up to date ensures optimal performance, security, and compatibility with new features. The guides below detail the upgrade process for both the client and the daemon.

{% content-ref url="/pages/HK9edCv2pwmYoqF7vpF9" %}
[NoPorts Client Upgrade](/installation/upgrading-noports-software/client-upgrade-sshnp)
{% endcontent-ref %}

{% content-ref url="/pages/OR7hA04Mg8s3GKg6nwhk" %}
[NoPorts Daemon Upgrade](/installation/upgrading-noports-software/device-upgrade-sshnpd)
{% endcontent-ref %}


# NoPorts Client Upgrade

### Upgrade sshnp

Upgrading to the latest version of sshnp follows the same process as installation, as the installer automatically replaces existing binaries with the new ones.

To upgrade, follow the [installation guide](/installation/advanced-installation-guides/client-installation-sshnp) up to **Step 3**, then return to this page to verify the upgrade.

### Verify the Upgrade

To check the current version of sshnp installed on your machine simply execute the binary:

{% tabs %}
{% tab title="Linux" %}

<pre class="language-sh"><code class="lang-sh"><strong>sshnp --version
</strong></code></pre>

The first line of output should contain the version information:

```sh
Version : x.x.x
```

{% endtab %}

{% tab title="macOS" %}

```bash
sshnp --version
```

The first line of output should contain the version information:

```tex
Version : x.x.x
```

{% endtab %}

{% tab title="Windows" %}

```powershell
sshnp.exe
```

The first line of output should contain the version information:

```tex
Version : x.x.x
```

{% endtab %}
{% endtabs %}

### Troubleshooting the Upgrade

If you continue to get an old version number, it's likely that there's an old binary which wasn't replaced on the machine. Try the following to debug your binary location:

{% tabs %}
{% tab title="Linux" %}
First, use this command to locate the sshnp binary:

```bash
command -v sshnp
```

The command should output the location of the binary which is on the `PATH`. Try deleting this binary then rerunning the installer.

```sh
rm "$(command -v sshnp)"
```

{% endtab %}

{% tab title="macOS" %}
First, use this command to locate the sshnp binary:

```bash
command -v sshnp
```

The command should output the location of the binary which is on the `PATH`. Try deleting this binary then rerunning the installer.

```sh
rm "$(command -v sshnp)"
```

{% endtab %}

{% tab title="Windows" %}
Since Windows doesn't include a dedicated installer, upgrading should be as simple as moving the new binary to wherever you installed the previous one.
{% endtab %}
{% endtabs %}


# NoPorts Daemon Upgrade

### Upgrade the sshnpd binary

Upgrading to the latest version of sshnpd follows the same process as installation, as the installer automatically replaces existing binaries with the new ones.

To upgrade, follow the [installation guide](/installation/advanced-installation-guides/device-installation-sshnpd) up to **Step 3**, then return to this page to complete the process.

### Verify the Upgrade

To check the current version of sshnpd installed on your machine, simply execute the binary:

{% tabs %}
{% tab title="Linux" %}

```sh
$HOME/.local/bin/sshnpd
```

Or, if you installed as root:

```
/usr/local/bin/sshnpd
```

The first line of output should contain the version information:

```sh
Version : x.x.x
```

{% endtab %}

{% tab title="macOS" %}

```sh
$HOME/.local/bin/sshnpd
```

Or if you installed as root:

```
/usr/local/bin/sshnpd
```

The first line of output should contain the version information:

```sh
Version : x.x.x
```

{% endtab %}
{% endtabs %}

### Reload the sshnpd service

After upgrading the sshnpd binary, we must restart the sshnpd service so that it runs using the new version. How you proceed is dependent upon the original installation method you used:

1. [Systemd unit](#systemd-unit)
2. [Tmux session](#tmux-session)
3. [Headless (cron + nohup)](#headless-cron--nohup)

### Systemd unit

The `universal.sh`installer script will automatically restart the `sshnpd.service`unit.

Any existing config will be preserved.

### Tmux session

The installer automatically restarts your tmux session, no other steps required!

### Headless (cron + nohup)

#### Retrieve the Process ID

To safely restart the headless service, we must be slightly more careful with the headless installation. First we must grab the process id of sshnpd:

```bash
pgrep -f "$(eval echo \"$( cat $HOME/.local/bin/sshnpd.sh | grep /sshnpd | awk '{$1=$1};1')\" )"
```

<details>

<summary>If you're curious how this command works</summary>

```bash
cat $HOME/.local/bin/sshnpd.sh | grep /sshnpd | awk '{$1=$1};1'
```

Print out the contents of the sshnpd.sh service file, then extract the line where we execute the sshnpd program.

```bash
eval echo \"$(...)\"
```

Resolve any variables in place for the output of the previous expression.

```bash
pgrep -f "$(...)"
```

Find the process id of the program which was started using the command matching the output of the previous expression.

</details>

You should get a single number as output, this is the process ID of the sshnpd process.

**Example:**

```
atsign@sshnpd-test:~# pgrep -f "$(eval echo \"$( cat $HOME/.local/bin/sshnpd.sh | grep /sshnpd | awk '{$1=$1};1')\" )"
289
```

#### Verify the Process ID

Before we continue, it is good practice to make sure that we have the correct ID:

```bash
ps -fp <process ID>
```

**Example:**

```
atsign@sshnpd-test:~# ps -fp 289
UID            PID    PPID  C STIME TTY          TIME CMD
atsign         289     114  0 11:10 ?        00:00:00 /home/atsign/.local/bin/sshnpd -a @atsign_device -m @atsign_client -d mydevice -suv
```

As you can see, under `CMD` we have `/home/atsign/.local/bin/sshnpd -a @atsign_device -m @atsign_client -d mydevice -suv`. This is the command inside our sshnpd.sh service which used to start sshnpd. This is the correct process that we want to kill in order to restart sshnpd.

#### Killing the process

Now that we have retrieved and verified the process ID, we can use the kill command to kill the process:

```bash
kill -9 <process ID>
```

Example:

```
root@sshnpd-test:~# kill -9 289
```

#### Verify the Process has been killed

Use the same verification command from before:

```bash
ps -fp <process ID>
```

**Example:**

```
root@sshnpd-test:~# ps -fp 289
UID          PID    PPID  C STIME TTY          TIME CMD
```

As you can see, there are no entries anymore. This means process 289 has been killed, sshnpd should automatically restart under a new process ID.


# Policy Service Installation

This guide explains how to install and run the NoPorts Policy Service via the command line. This guide shows you how to run the Policy Server in a Linux environment (virtual machine).

### Architecture

All devices have no open ports to the public Internet. The policy server delegates access into device. Modifying the policy rules gives you finegrain control on which clients get access to which devices and on what host and port.

<figure><picture><source srcset="/files/EGCAYsziPytbHqS4qlVh" media="(prefers-color-scheme: dark)"><img src="/files/6T6BhdLV6JF0mdjxl6Y6" alt=""></picture><figcaption><p>Client / Device / Policy Server architecture</p></figcaption></figure>

### Terminology

| Machine Type   | Description                                                                                                                                                                 |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Client machine | <p>The machine establishing connections.</p><p>All manager key copies are kept on this machine in \~/.atsign/keys, where subsequent copies are made for other machines.</p> |
| Device machine | <p>The remote machine that you are connecting to.</p><p>This has an actively running NoPorts daemon that will service connection requests from clients.</p>                 |
| Policy machine | <p>A machine running the policy service that responds to policy requests made by NoPorts daemons.<br><br>This has an actively running NoPorts Policy Service.</p>           |

### Prerequisites

Before you begin the installation, please ensure the following steps are complete:

1. **You own at least 3 Atsigns:** one as the client, one as the device, and one for policy. You may purchase more Atsigns through our [professional tier](https://my.noports.com/no-ports-plans).
2. **Installation & Activation**: NoPorts is installed and Atsigns are activated on at least two machines, one to connect *from* and one to connect *to*. [View installation guides](/installation).

### Step 1: Activate Policy Atsign on Client machine

If your policy Atsign is already activated, then you may skip this step. This step can only be completed once.

<details>

<summary>Steps to be completed on the Client machine</summary>

In this step, we will be activating the policy Atsign on your **client machine**. The initial activation happens in this step and administering a copy securely will be done in the next step. Atsign activation can only be done once. If your Atsign is already activated, you can move onto the next step.

1. Run the onboard command.

On your client machine, ensure you have the `at_activate` binary installed.

Replace `@my_policy_atsign` with your Atsign.

```bash
at_activate onboard -a @my_policy_atsign
```

2. You will get an OTP from your email, enter that into the program. If it expires, simply rerun the first step.
3. Your new key file should be in `~/.atsign/keys/` You can validate via `ls -la ~/.atsign/keys/`

</details>

### Step 2: Set up binaries on Policy machine

<details>

<summary>Steps to be completed on the Policy machine</summary>

Navigate to the NoPorts GitHub Releases page and copy the link address for the **file matching your operating system**.

Latest release: <https://github.com/atsign-foundation/noports/releases/latest>

Open a terminal, and from your home directory run the following command to download the file and save it as `sshnpd.tgz`.

```bash
curl -L -o sshnp.tgz <YOUR URL>
```

Example (for x86\_64 machine):

```bash
curl -L -o sshnp.tgz https://github.com/atsign-foundation/noports/releases/download/v5.15.0/sshnp-linux-x64.tgz
```

Example (for ARM machine):

```bash
curl -L -o sshnp.tgz https://github.com/atsign-foundation/noports/releases/download/v5.15.0/sshnp-linux-arm64.tgz
```

Once this is done, extract the contents of the file to your home directory.

```bash
tar -xvzf sshnp.tgz
cd sshnp
```

After extraction, copy the `npp_atserver` and `at_activate` binary to `/usr/bin`

```bash
sudo cp ./npp_atserver ./at_activate /usr/bin
```

</details>

### Step 3: Administer key copy to Policy machine

This step requires shell access on both your **client machine** and **policy machine**.

Once your policy key file exists (e.g. `~/.atsign/keys/@policy_atsign_key.atKeys` ) on your client machine, it is time to give a copy of it to the policy machine. This is known as an "APKAM copy" with restricted namespace permissions and can be revoked later on.

<details>

<summary>Steps to be completed on Client machine</summary>

The goal here is for your client machine (which contains the manager set of policy Atsign keys) to administer a copy to the policy machine.

1. Generate an OTP (note this OTP down, as you will need it very soon)

```bash
at_activate otp -a @policy_atsign
```

2. Set up an auto approval service. This will automatically apporove the enrollment request which will be done in the next step.

```bash
at_activate auto -a @policy_atsign -A noports -D policy -L 1 --approve-existing
```

Leave this process running in the background.

</details>

<details>

<summary>Steps to be completed on Policy machine</summary>

1. Enroll

Using the OTP generated from the previous step, send an enrollment request. This enrollment request should be automatically approved (almost immediately) once it is sent, and that is because we set up an auto approval service beforehand.

```bash
at_activate enroll \
  -p noports \
  -n "sshnp:rw,sshrvd:rw"
  -a <@ATSIGN> \
  -s <OTP> \
  -d <DEVICE_NAME> \
  -k ~/.atsign/keys/<@ATSIGN>_key.atKeys \
```

You should see a response like this:

```
Enroll : submitting enrollment requestEnrollment ID: 95a7f54b-a0a2-4c23-9c9c-49654172ed85
Waiting for approval; will check every 10 seconds
    Enroll : submitted OK
      PKAM : Enrollment has been approved (PKAM auth success)Creating atKeys file
[Success] Your .atKeys file saved at /home/user/.atsign/keys/@policy_atsign_key.atKeys
```

If the enrollment request hangs for more than a minute, then ensure you have an auto approval service running on your client machine.

</details>

### Step 4: Set up NoPorts Policy Service

<details>

<summary>Step to be completed on the Policy machine</summary>

1. Set up the systemd file.

Copy and paste this content to this new file: `/etc/systemd/system/npp_atserver.service`

Modify these mandatory fields accordingly:

* `User=noports` - change this to the Linux username of the policy machine
* `policy_atsign="@policy_atsign"` - change this to your Policy Atsign

```
[Unit]
Description=NoPorts Policy Service
After=network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Type=simple
Restart=always
RestartSec=3

# Configuration of NoPorts Policy service
# This unit script is a template for the sshnpd background service.
# You can configure the service by editing the variables below.

# MANDATORY: User to run the daemon as
User=noports

# MANDATORY: Policy manager address (atSign)
Environment=policy_atsign="@policy_atsign"

# Comment to disable verbose logging
Environment=v="-v"

# The line below runs the noports policy service, with the options set above.
# You can edit this line to further customize the service to your needs.
ExecStart=/usr/bin/npp_atserver -a "$policy_atsign" "$v"
```

2. Start your new systemd service

```bash
sudo systemctl daemon-reload
sudo systemctl enable npp_atserver.service
sudo systemctl start npp_atserver.service
sudo systemctl status npp_atserver.service
```

3. Tail the logs and ensure the output looks healthy

```bash
journalctl -u npp_atserver.service -f
```

What healthy output looks like:

```
SHOUT|2025-04-16 19:12:51.399918|PolicyServiceWithAtClient|Loading groups via AtClient 
SHOUT|2025-04-16 19:12:52.293882|PolicyServiceWithAtClient|Load complete 
SHOUT|2025-04-16 19:12:52.294012| npp |Daemon atSigns: {} 
```

</details>

### Step 5: Register your daemon with the policy service

<details>

<summary>Step to be completed on your Device machine</summary>

Depending on what version your NoPorts daemon you are running, you will be editing a different configuration file:

```bash
sshnpd --version
```

| sshnpd version < v5.14.13                            | sshnpd version >= v5.14.13 |
| ---------------------------------------------------- | -------------------------- |
| `/etc/systemd/system/sshnpd.service.d/override.conf` | `/etc/noports/sshnpd.yaml` |

1. If your sshnpd version is less than v5.14.13, edit the `/etc/systemd/system/sshnpd.service.d/override.conf` file.

Edit the "delegate\_policy" environment variable to your Policy Atsign.

```yaml
Environment=delegate_policy="@policy_atsign"
```

2. If your sshnpd version is greater or equal than v5.14.13, edit the `/etc/noports/sshnpd.yaml` file.

Edit the "policy:" to your Atsign **without its "@" at symbol**. Example:

```
  policy: policy_atsign
```

3. Then run the following command to restart the daemon.

```bash
sudo systemctl daemon-reload && sudo systemctl restart sshnpd
```

Finishing this step will register your NoPorts daemon to send policy requests to the delegated policy Atsign when a non-manager attempts to make a request to your device machine.

</details>

### Step 6: Writing your policy rules

<details>

<summary>Steps to be completed on the Client machine</summary>

Now it's time to write policy rules.

1. Download the latest sshnp binaries from our [releases](https://github.com/atsign-foundation/noports/releases/latest).

```bash
curl -L -o /tmp/sshnp.tgz https://github.com/atsign-foundation/noports/releases/download/v5.15.0/sshnp-linux-x64.tgz
cd /tmp
tar -xvzf sshnp.tgz
cd sshnp
sudo cp np_admin /usr/bin
```

2. Download web assets

This next step requires **git** and **npm** installed on your machine.

```bash
cd /tmp
git clone https://github.com/atsign-foundation/noports
cd noports/apps/admin/webapp
npm i && npm run build
sudo mkdir -p /usr/bin/web/admin
sudo cp -r dist/* /usr/bin/web/admin/
```

If the `npm run build` step fails, ensure you have an up-to-date version of `npm`

3. Write Policy rules

Run the following command:

```
np_admin
```

This will start a web server. Open the web server at `https://localhost:3000`

Now you can

* Create user groups
* Monitor policy logs

Below is an example of a test group that gives @some\_atsign access to @bob's device "device1" on localhost:22 and localhost:3389.

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

</details>


# Use Cases

NoPorts has endless use cases. We've compiled a list of the most frequently used ones:

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><mark style="color:purple;"><strong>MCP</strong></mark></td><td><a href="/pages/ngtuNiJYcjB4gYtlWQGf">/pages/ngtuNiJYcjB4gYtlWQGf</a></td><td><a href="/files/AHJ3mRqyQnOskSaYEYeB">/files/AHJ3mRqyQnOskSaYEYeB</a></td></tr><tr><td><mark style="color:blue;"><strong>SSH</strong></mark></td><td><a href="/pages/q5v7yL2pgoevZqZa94KB">/pages/q5v7yL2pgoevZqZa94KB</a></td><td><a href="/files/eA6on0oxsESvXDDrawVk">/files/eA6on0oxsESvXDDrawVk</a></td></tr><tr><td><mark style="color:orange;"><strong>SFTP</strong></mark></td><td><a href="/pages/91NY3Ha8Uy9I7loW436y">/pages/91NY3Ha8Uy9I7loW436y</a></td><td><a href="/files/0XGG48D2NmCX2fkwtfbt">/files/0XGG48D2NmCX2fkwtfbt</a></td></tr><tr><td><mark style="color:green;"><strong>RDP</strong></mark></td><td><a href="/pages/f0ZZQzMPcerYMHsbOiw6">/pages/f0ZZQzMPcerYMHsbOiw6</a></td><td><a href="/files/9kIPElrt8Kd7t0gJIIfL">/files/9kIPElrt8Kd7t0gJIIfL</a></td></tr><tr><td><mark style="color:purple;"><strong>Web Server</strong></mark></td><td><a href="/pages/JO4Som2PYbhCBqNpFjQm">/pages/JO4Som2PYbhCBqNpFjQm</a></td><td><a href="/files/Be616FYn3mf2ljgQteiI">/files/Be616FYn3mf2ljgQteiI</a></td></tr><tr><td><mark style="color:blue;"><strong>SMB</strong></mark></td><td><a href="/pages/683e2mYrUQrq6cpsZ68Q">/pages/683e2mYrUQrq6cpsZ68Q</a></td><td><a href="/files/UcMdb5ibOsh24s2jyKIK">/files/UcMdb5ibOsh24s2jyKIK</a></td></tr><tr><td><mark style="color:orange;"><strong>Be your own VPN</strong></mark></td><td><a href="/pages/DqvnLHx0noZHUa0bwJbt">/pages/DqvnLHx0noZHUa0bwJbt</a></td><td><a href="/files/6wDX6WVQ8w37r3rDIINC">/files/6wDX6WVQ8w37r3rDIINC</a></td></tr></tbody></table>


# MCP

In this guide, we demonstrate how to use the NoPorts Tunnel to securely access an MCP server running on a remote device, making it accessible via localhost:3000 on your local machine

### Video Tutorial

{% embed url="<https://vimeo.com/1145333189?fe=ci&fl=sv&share=copy>" %}

### Prerequisites

Before continuing, make sure that the following steps have been completed on the machine you’ll be using to remotely connect to your MCP server:

* NoPorts Desktop is installed.
* Your NoPorts Atsigns are activated, and the associated keys are saved locally.
* You are signed in with your device Atsign and have recorded your authentication passcode by opening the Authenticator tab and noting the displayed OTP.

If these steps are not yet complete, please follow **Steps 1 through 5.3** in the [Quick Start guide for macOS or Windows](/installation/quick-start-for-macos-and-windows) then return to this page.

### Step 1: Set up the MCP Server

{% hint style="warning" %}
Steps 1 through 4 are to be completed on the machine that your MCP server will be running on
{% endhint %}

In this example, the MCP server is implemented in **Python** using the **FastMCP** library. The reference code can be found at: <https://gofastmcp.com/deployment/http>

In this example, the server will be running locally at:

* **Host**: `127.0.0.1`
* **Port**: `3000`

You can choose whichever port number works best for you.

{% hint style="info" %}
The MCP Server must be served over a TCP Protocol to function with NoPorts.
{% endhint %}

### Step 2: Set up the NoPorts Daemon

Select the operating system running on the machine your MCP server is running on and follow the steps to install the NoPorts Daemon.

{% tabs %}
{% tab title="MacOS" %}
Download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

You may be asked to enter your password if your machine requires sudo privileges.

**The install type**

* Enter `device` when prompted.

**Your Atsigns**

* Client Atsign: e.g., `@example01_np`
* Device Atsign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.
  {% endtab %}

{% tab title="Linux" %}
Download the installer from GitHub by running the following command:

```bash
curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
```

To check if the installation downloaded correctly:

```bash
stat universal.sh
```

Make the script executable and run the script by running the command below:

```bash
chmod u+x universal.sh
./universal.sh
```

During installation, you’ll be prompted to enter the following items:

You may be asked to enter your password if your machine requires sudo privileges.

**The install type**

* Enter `device` when prompted.

**Your atSigns**

* Client atSign: e.g., `@example01_np`
* Device atSign: e.g., `@example02_np`

**Your device name**

* This should be the name of the machine you're currently installing on.
  {% endtab %}

{% tab title="Windows" %}
Download the msi installer [from GitHub](https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-windows-x64.zip). You can run the msi right from the windows-bundle.zip.

Ensure both Core Tools & Daemon Service are being installed.

<figure><img src="/files/2mtUgH0jFj3LuoFFpqnp" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

### Step 3: Configure Permit‑Open on Localhost:3000

1\. Edit the override configuration file:

```bash
sudo vim /etc/systemd/system/sshnpd.service.d/override.conf
```

2\. Under **“any additional command line arguments for sshnpd”**, add the following line:

```bash
Environment=additional_args="--permit-open=\"localhost:3000,127.0.0.1:3000\""
```

3\. Apply the changes by restarting and reloading the service:

```bash
sudo systemctl restart sshnpd.service
sudo systemctl daemon-reload
```

### Step 4: Initiate an authorization request

Select the operating system running on the machine your MCP server is running on and follow the steps provided.

{% tabs %}
{% tab title="MacOS" %}
Run the following command to make an authorization request:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device Atsign**,

`<PASSCODE>` with the **passcode generated in step 5 of the prerequisite instructions**

`@<REPLACE>_np_key` with your **device Atsign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

{% endtab %}

{% tab title="Linux" %}
Run the following command to make an authorization request:

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device atSign**,

`<PASSCODE>` with the **passcode generated in step 5 of the prerequisite instructions**

`@<REPLACE>_np_key` with your **device atSign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">~/.local/bin/at_activate enroll -a @&#x3C;REPLACE>_np \
<strong>  -s &#x3C;PASSCODE> \
</strong><strong>  -p noports \
</strong><strong>  -k ~/.atsign/keys/@&#x3C;REPLACE>_np_key.atKeys \
</strong><strong>  -d &#x3C;DEVICE_NAME> \
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

{% endtab %}

{% tab title="Windows" %}
Run the following command to make an authorization request.

{% hint style="warning" %}
Be sure to replace the following values:

`@<REPLACE>_np` with your **device atSign**,

`<PASSCODE>` with the **passcode generated in Step 4**,

`<USER>` with your **Windows username**,

`@<REPLACE>_np_key` with your **device atSign**,

`<DEVICE_NAME>` with the name of the machine you are on
{% endhint %}

<pre class="language-bash"><code class="lang-bash">at_activate.exe enroll -a "@&#x3C;REPLACE>_np" `
<strong>  -s &#x3C;PASSCODE> `
</strong><strong>  -p noports `
</strong><strong>  -k C:\Users\&#x3C;USER>\.atsign\keys\@&#x3C;REPLACE>_np_key.atKeys `
</strong><strong>  -d &#x3C;DEVICE_NAME> `
</strong><strong>  -n "sshnp:rw,sshrvd:rw"
</strong></code></pre>

Once you see this text, you're ready to continue to the next step.

```
Submitting enrollment request 
Enrollment ID: ---------------------
Waiting for approval; will check every 10 seconds
```

{% hint style="info" %}
If you encounter a handshake exception, it usually means your root certificates are outdated. To refresh them, run the following command with administrator privileges:<kbd>Install-Script -Name UpdateRootCertificates</kbd>
{% endhint %}
{% endtab %}
{% endtabs %}

### Step 5: Approve the request

{% hint style="warning" %}
Steps 5 through 7 are to be coompleted on the machine you'll be using to remotely connnect to your MCP server.
{% endhint %}

1\. Click on Requests and approve the pending request. The request will then move to the approved enrollments list.

2\. After a few seconds, the request will also show as approved on the machine you are connecting to.

### Step 6: Create the profile in the desktop app

Click on Connection and create a profile for your MCP connection. You will enter the following information

1. Profile Name - The name that will be displayed in the profile list.
2. Device Atsign - Your device Atsign (eg mcp\_demo\_02\_np).
3. Device Name - The name of your remote device.
4. Relay - Select the relay server closest to you for optimum speed.
5. Local Port - The port you will use on your local machine.
6. Local Host - The hostname or IP address to bind to on your local machine.
7. Remote Host - The hostname or IP address of the machine you are connecting to.
8. Remote Port - The port that will be used on the remote machine.

{% hint style="info" %}
In this example, the we use details shown in the video. When following along, be sure to replace these with **your own data**.
{% endhint %}

|                   |                    |
| ----------------- | ------------------ |
| **Profile Name**  | mcp\_demo          |
| **Device Atsign** | @mcp\_demo\_02\_np |
| **Device Name**   | mcp\_demo          |
| **Relay**         | @rv\_am            |
| **Local Port**    | 3000               |
| **Local Host**    |                    |
| **Remote Host**   | 127.0.0.1          |
| **Remote Port**   | 3000               |

### Step 7: Interact with the MCP Server via Witsy

**Whitsy** is an open‑source LLM client. Download and install it from [https://witsyai.com](https://witsyai.com/).

1\. Open Whitsy, select **MCP**, then click the **+** icon to add a new MCP server.

2\. Set **Type** to *streamable HTTP*, choose any **Label** you like, and enter the following URL:

```bash
http://127.0.0.1:3000/mcp
```

Click **Save** and you should see a green checkmark.

3\. Go to **Chat**, then open **Customize** and enable the **process\_data** option.

4\. To test, type the following:

```bash
process data using MCP "hello"
```


# SSH

In this guide, we demonstrate how to use SSH NoPorts to SSH to a remote machine.

### Prerequisites

Before continuing, make sure that the following steps have been completed:

* NoPorts has been installed on both machines.
* Your NoPorts Atsigns are activated, and the associated keys are saved locally.

If you haven’t completed these steps, follow the appropriate installation guide on the [Installation Instructions](/installation) page, then return here once finished.

### Command Line

The command should look like:

```
sshnp -f @<client> -t @<device> -d <device name> -r @<relay> -i <your ssh key>
```

Example:

```
sshnp -f @alice_client -t @alice_device -d my_server -r @rv_am -i ~/.ssh/id_ed25519
```

#### Auto SSH key upload

If you don't have an ssh key uploaded on the remote machine, you can upload one by adding `-s` to the command:

```
sshnp -f @alice_client -t @alice_device -d my_server -r @rv_am -i ~/.ssh/id_ed25519 -s
```

{% hint style="warning" %}
Note: this feature can be disabled in sshnpd. If you get an error when using -s, it is likely that the administrator disabled this feature for security reasons.
{% endhint %}

### To learn more about SSHNP

{% content-ref url="/pages/qfKnYIHsZe1mUxKK2xJM" %}
[sshnp Usage](/usage/basic-usage-1)
{% endcontent-ref %}

### Desktop Application

When using the NoPorts desktop application, your connection profile should look something like this:

|                   |                   |
| ----------------- | ----------------- |
| **Profile Name**  | My SSH Connection |
| **Device Atsign** | @alice\_device    |
| **Device Name**   | my\_server        |
| **Relay**         | @rv\_am           |
| **Local Port**    | 2222              |
| **Local Host**    | localhost         |
| **Remote Host**   |                   |
| **Remote Port**   | 22                |


# SFTP

In this guide, we demonstrate how to use the NoPorts Tunnel to bridge SFTP on a remote machine to localhost:2222 so we can access it in an SFTP client locally.

### Prerequisites

Before continuing, make sure that the following steps have been completed:

* NoPorts has been installed on both machines.
* Your NoPorts Atsigns are activated, and the associated keys are saved locally.

If you haven’t completed these steps, follow the appropriate installation guide on the [Installation Instructions](/installation) page, then return here once finished.

### Command Line

The command should look like:

```
npt -f @<client> -t @<device> -d <device name> -r @<relay> -p 22 -l 2222
```

Example:

```
npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 22 -l 2222
```

Now you can connect to localhost:2222 in your favorite SFTP client.

### To learn more about NPT

{% content-ref url="/pages/GFSL623eCh6sSMokUywY" %}
[npt Usage](/usage/basic-usage)
{% endcontent-ref %}

### Desktop Application

When using the NoPorts desktop application, your connection profile should look something like this:

|                   |                    |
| ----------------- | ------------------ |
| **Profile Name**  | My SFTP Connection |
| **Device Atsign** | @alice\_device     |
| **Device Name**   | my\_server         |
| **Relay**         | @rv\_am            |
| **Local Port**    | 2222               |
| **Local Host**    | localhost          |
| **Remote Host**   |                    |
| **Remote Port**   | 22                 |


# RDP

In this guide, we demonstrate how to use the NoPorts Tunnel to RDP on a remote machine to localhost:3389 so we can access the RDP service locally.

### Prerequisites

Before continuing, make sure that the following steps have been completed:

* NoPorts has been installed on both machines.
* Your NoPorts Atsigns are activated, and the associated keys are saved locally.

If you haven’t completed these steps, follow the appropriate installation guide on the [Installation Instructions](/installation) page, then return here once finished.

### Command Line

The command should look like:

```
npt -f @<client> -t @<device> -d <device name> -r @<relay> -p 3389 -l 33389
```

Example:

```
npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 3389 -l 33389
```

Now you can connect to localhost:33899 in your favorite RDP client.

### To learn more about NPT

{% content-ref url="/pages/GFSL623eCh6sSMokUywY" %}
[npt Usage](/usage/basic-usage)
{% endcontent-ref %}

### Desktop Application

When using the NoPorts desktop application, your connection profile should look something like this:

|                   |                   |
| ----------------- | ----------------- |
| **Profile Name**  | My RDP Connection |
| **Device Atsign** | @alice\_device    |
| **Device Name**   | my\_server        |
| **Relay**         | @rv\_am           |
| **Local Port**    | 33389             |
| **Local Host**    | localhost         |
| **Remote Host**   |                   |
| **Remote Port**   | 3389              |


# Web Server

This guide covers usage of NoPorts with webpages or APIs.

### Prerequisites

Before continuing, make sure that the following steps have been completed:

* NoPorts has been installed on both machines.
* Your NoPorts Atsigns are activated, and the associated keys are saved locally.

If you haven’t completed these steps, follow the appropriate installation guide on the [Installation Instructions](/installation) page, then return here once finished.

### Command Line

Here, we demonstrate how to use the NoPorts Tunnel to bridge a web server on a remote machine to localhost:80 so we can access the web server locally.

{% hint style="info" %}
We are assuming that the web server is running on port `8080`, you can replace it with the port that your web server is running on. (Also works over TLS with port 443)
{% endhint %}

\
The command should look like:

```
npt -f @<client> -t @<device> -d <device name> -r @<relay> -p 8080 -l 80
```

Example:

```
npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 8080 -l 80
```

Now you can access localhost:80 in your browser to access the web server locally.

### To learn more about NPT

{% content-ref url="/pages/GFSL623eCh6sSMokUywY" %}
[npt Usage](/usage/basic-usage)
{% endcontent-ref %}

### Desktop Application

When using the NoPorts desktop application, your connection profile should look something like this:

|                   |                          |
| ----------------- | ------------------------ |
| **Profile Name**  | My Web Server Connection |
| **Device Atsign** | @alice\_device           |
| **Device Name**   | my\_server               |
| **Relay**         | @rv\_am                  |
| **Local Port**    | 8880                     |
| **Local Host**    | localhost                |
| **Remote Host**   |                          |
| **Remote Port**   | 8080                     |


# SMB

In this guide, we demonstrate how to use the NoPorts Tunnel to mount a SMB share on a remote machine on 192.168.1.90 to localhost:9000 so we can access the SMB share service locally.

### Prerequisites

Before continuing, make sure that the following steps have been completed:

* NoPorts has been installed on both machines.
* Your NoPorts Atsigns are activated, and the associated keys are saved locally.

If you haven’t completed these steps, follow the appropriate installation guide on the [Installation Instructions](/installation) page, then return here once finished.

### Command Line

The command should look like:

```
npt -f @<client> -t @<device> -d <device name> -r @<relay> -p 445 \
-h 192.168.1.90 -l 9000
```

Example:

```
npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 445 \
-h 192.168.1.90 -l 9000
```

{% hint style="info" %}
NOTE Make sure the sshnpd daemon is allowing port 445 to the SMB file server see Basic Usage for details.
{% endhint %}

Now you can mount the SMB share locally using the finder app ( Go->Connect to server) on MacOs

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

Once mounted, you can use the file share as normal. As you dismount the file share, the NPT command will disconnect.

{% hint style="info" %}
Windows mounting on a non-standard port is currently not supported by Microsoft but they are working on it.

If you need this functionality, it is possible but fiddly to set up. Contact us if you want to know how.
{% endhint %}

### To learn more about NPT

{% content-ref url="/pages/GFSL623eCh6sSMokUywY" %}
[npt Usage](/usage/basic-usage)
{% endcontent-ref %}

### Desktop Application

When using the NoPorts desktop application, your connection profile should look something like this:

|                   |                   |
| ----------------- | ----------------- |
| **Profile Name**  | My SMB Connection |
| **Device Atsign** | @alice\_device    |
| **Device Name**   | my\_server        |
| **Relay**         | @rv\_am           |
| **Local Port**    | 9000              |
| **Local Host**    | localhost         |
| **Remote Host**   |                   |
| **Remote Port**   | 445               |


# Be your own VPN

Using sshuttle and SSH built in SOCKS proxy.

To follow this guide, you will need to set up a NoPorts device (`sshnpd)`on your home network. For this, you could use a Raspberry Pi, an old PC running Linux, a virtual machine, or even a docker container—the choice is yours. You can get your NoPorts free trial account [here](https://my.noports.com/no-ports-plans) and follow the [installation guide](/installation/connecting-from-linux) to get started.

SSH is a hugely versatile tool for command line access, but what if you want a full IP tunnel, like a VPN?

SSH has you covered with the use of two tools: the first is a built in SOCKS proxy; the second is an open source piece of code called `sshuttle`. With these two tools you can use your sshnp service as your own VPN.

### The amazing sshuttle

Once you have NoPorts up and running, you will be able to connect to your device from anywhere on the Internet. You will notice that you did not have to open any ports to the Internet in order to connect. *There is no access to the device from the Internet and yet you can connect.*

If you are happy with command line access only, great; but you might want to now use your SSH connection as a VPN and have a full IP tunnel. For this, [sshuttle](https://github.com/sshuttle/sshuttle) is the perfect tool. However, if you are using Windows, then you will have to set up a local VM/Container. (If that sounds like too much, skip down to the section below on using SOCKS.)

To use sshuttle, we need to make sure that the SSH command itself can log in without any complex arguments. This requires two steps:

1. **Create SSH keys:** First, make sure that you have created SSH keys.
2. **Place public keys on the remote device:** Next, either:
   * **Manual placement:** Place the public keys directly on the remote device.
   * **`sshnpd`flag:** Or, use the `-s` flag of `sshnp` to place them on the remote `sshnpd`. That requires the `-s` flag to be enabled on the `sshnpd` service/config file.

Once the SSH keys are in place, you can put an entry in `~/.ssh/config` to let SSH know which key to use to log into localhost. For example:

```
Host localhost
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    IdentityFile ~/.ssh/id_ed25519
    LogLevel QUIET
```

The next thing to do is install `sshuttle` on your machine. The GitHub page details this very well for both Linux and OSX machines.

Once sshuttle is installed, let's use it!

This is a two step process:

1. **Connect to the device using `sshnp:`** Add the `-x` flag. This flag prints out the SSH command that you can cut and paste to log into the remote device.
2. **Establish the VPN:** In another terminal window, run the sshuttle command to connect to the remote device. You'll need to tweak your IP routing to use this connection as a VPN. **The important part is to use the port number that the** `-x` **flag gave you in the** `sshuttle` **command**.

{% embed url="<https://asciinema.org/a/msDJ8hPaVtRFEZZHFbnlNnWGh>" %}
Be your own VPN
{% endembed %}

With this example, you can see that port `63155` was used in the sshuttle command. You do not need to SSH into the machine—you can just get the port number and use `sshuttle.` The choice is yours.

This can get a bit tedious to do every day so feel free to script for your environment. Here is an example bash script that does just that!

```bash
#!/bin/bash
#
export USER=$USER
export SSHNPHOME=$HOME/.local/bin <--<default-location-for-SSHNP>
export HOSTDEVICE=<your-host-running-SSHNPD>
export CLIENTATSIGN=<your-local-atsign format @34mypersonalatsign>>
export HOSTATSIGN=<the-host-device-atsign format @55hostdeviceatsign>
export LOCALPORT=<the-port-ito-use-forconnection example 46393>
export SRVD=<atSign-of-srvd-daemon example @rv_eu or @rv_am or @rv_ap>
export NETA=<network-CIDR-style example 0/0 or 10.0.0.0/8>
export NETB=<network-CIDR-style example 172.16.0.0/16>
export NETC=<network-CIDR-style example 192.168.1.0/24>
#
echo ""
echo Starting Atsign SSHNP connects to $HOSTDEVICE on port 46393 for personal VPN
echo ""
#
$SSHNPHOME/sshnp --from $CLIENTATSIGN --to $HOSTATSIGN --srvd $SRVD --remote-user-name $USER --output-execution-command --idle-timeout 90 --device $HOSTDEVICE --local-port $LOCALPORT
sleep 3
sshuttle --dns -r $USER@127.0.0.1:$LOCALPORT $NETA $NETB $NETC 
#
```

### SOCKS

If you are using Windows, this is likely your best option unless you are comfortable setting up a virtual machine and using sshuttle.

All you need to do is add an option to the normal `sshnp` command and that will set up a local SOCKS proxy: `-o "-D 1080"` That's it!

```bash
sshnp -f @my_client -t @my_device -h @rv_am -d my_pi -o "-D 1080"
```

This will set up a local SOCKS proxy on your machine that will forward requests to the remote device. In effect, you will be at home whilst away. To use this SOCKS proxy, you need to tell your browser or your Operating System. The Firefox browser is the simple choice, and in settings you can configure it as shown below:

<figure><img src="/files/t81Dy8VFx7Up2DBn5qcg" alt=""><figcaption><p>configure your SOCKS proxy</p></figcaption></figure>

Once you have setup Firefox, you can browse as if you were at home! On Windows and Mac, you can configure your SOCKS proxy in directly in the OS in settings. **This works, but you have to remember to remove the setting once you have disconnected from the `sshnpd` session.**


# Usage

Learn how to use NoPorts. This guide covers some of the things you can run via NoPorts, as well as how to set up the NoPorts Tunnel (npt).

### Use Cases

If you have a specific use case, we may already cover the steps you need to take. Check out these guides.

<table data-header-hidden><thead><tr><th data-type="content-ref"></th><th data-type="content-ref"></th></tr></thead><tbody><tr><td><a href="/pages/JO4Som2PYbhCBqNpFjQm">/pages/JO4Som2PYbhCBqNpFjQm</a></td><td><a href="/pages/q5v7yL2pgoevZqZa94KB">/pages/q5v7yL2pgoevZqZa94KB</a></td></tr><tr><td><a href="/pages/f0ZZQzMPcerYMHsbOiw6">/pages/f0ZZQzMPcerYMHsbOiw6</a></td><td><a href="/pages/91NY3Ha8Uy9I7loW436y">/pages/91NY3Ha8Uy9I7loW436y</a></td></tr><tr><td><a href="/pages/ngtuNiJYcjB4gYtlWQGf">/pages/ngtuNiJYcjB4gYtlWQGf</a></td><td><a href="/pages/683e2mYrUQrq6cpsZ68Q">/pages/683e2mYrUQrq6cpsZ68Q</a></td></tr><tr><td><a href="/pages/DqvnLHx0noZHUa0bwJbt">/pages/DqvnLHx0noZHUa0bwJbt</a></td><td></td></tr></tbody></table>

### Usage of NoPorts

If your primary use case involves more than just SSH, start here, or check out some of our use cases below.

{% content-ref url="/pages/GFSL623eCh6sSMokUywY" %}
[npt Usage](/usage/basic-usage)
{% endcontent-ref %}

### SSH Specific Usage over NoPorts

If your primary use case is SSH, start here. We also recommend the ssh config integration for a seamless experience.

{% content-ref url="/pages/qfKnYIHsZe1mUxKK2xJM" %}
[sshnp Usage](/usage/basic-usage-1)
{% endcontent-ref %}

{% content-ref url="/pages/IsJZhuzS0laCtoLId0DK" %}
[OpenSSH Config](/integrations/integrate-with-ssh-config)
{% endcontent-ref %}


# Policy Service

This page describes using the policy service

### Policy Service Status

The Policy Service must remain running at all times to listen for incoming requests from daemons querying the policy server.

### Policy Roles

In the context of the Policy Service, a **role** defines a set of access permissions that determine which Atsigns can interact with specific devices or groups of devices through NoPorts.

When creating a role you will need to enter the following information:

|                    |                                                                                                                               |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------- |
| **Name**           | The role's name                                                                                                               |
| **Description**    | The role's description                                                                                                        |
| **Device Atsigns** | The device Atsign(s) to which the policy role will be applied                                                                 |
| **Devices**        | The device name(s) associated with the device Atsign along with the local ports that NoPorts has permitted for secure access  |
| **Device Groups**  | The device name(s) associated with a group of devices along with the local ports that NoPorts has permitted for secure access |
| **User Atsigns**   | The Atsigns that will have access to the devices and/or device groups                                                         |

After a role is created and saved, the Atsigns listed in the User Atsigns section will be able to connect to the designated ports and interact with the specified devices using the assigned device Atsigns.

If using device groups, be sure the specify the device group name when running the NoPorts Daemon on your device. For example:

```bash
./sshnpd -a @<YOUR DEVICE ATSIGN> -p @<YOUR POLICY ATSIGN> --device-group <DEVICE GROUP>
```


# NoPorts Desktop Usage


# Managing Profiles

* Explain local port conflicts well
* Explain remote host lookup
* Explain deletion / editing as well


# Start a Connection

* Explain favorites as well here


# Importing Profiles


# Exporting Profiles


# Managing atSigns


# Settings


# npt Usage

### Quick Start

```bash
npt -f @<your_client_atsign> -t @<your_device_atsign> -r @rv_[am|ap|eu|oc] -d <name> \
-p <remote-port> -l <local-port>
```

### Overview

This guide covers the basics to understanding the parameters of npt and invoking npt.

The NoPorts Tunnel, or npt for short, provides an end to end encrypted TCP Tunnel without the need for inbound listening ports on either of your machines.

### Options

<table><thead><tr><th width="100">Option</th><th width="134">Required / Default</th><th width="230">Value Format</th><th width="382">Description</th></tr></thead><tbody><tr><td>-f</td><td><strong>required</strong></td><td>Atsign</td><td>The client Atsign, a.k.a. the <strong>from</strong> Atsign, since we are connecting from the client.</td></tr><tr><td>-t</td><td><strong>required</strong></td><td>Atsign</td><td>The device Atsign, a.k.a. the <strong>to</strong> Atsign, since we are connecting to the device.</td></tr><tr><td>-r</td><td><strong>required</strong></td><td>Atsign</td><td><p>The Atsign of the relay service used to establish the session connection. NoPorts currently provides coverage in 4 regions:</p><p>@rv_am - Americas</p><p>@rv_eu - Europe</p><p>@rv_ap - Asia/Pacific<br>@rv_oc - Oceania</p></td></tr><tr><td>-d</td><td><strong>required</strong></td><td>String<br><em>Only <code>[a-z0-9_-]</code> allowed.</em><br><em>Maximum of 36 characters.</em></td><td>Allows multiple devices to run sshnpd under a single device name.</td></tr><tr><td>-p</td><td><strong>required</strong></td><td>Port number.<br><em>Between 1-65535.</em></td><td>The port you are connecting to on the device/remote side. This port must be included in the --permit-open list and/or policy allowances.</td></tr><tr><td>-l</td><td>"0"</td><td>Port number<br><em>Between 1024-65535.</em></td><td>The port you are connecting to on the client/local side. Defaults to any unused port.</td></tr><tr><td>-h</td><td>"localhost"</td><td>DNS / ip address</td><td>The host that the daemon will connect to. nslookup is resolved on the remote machine where the daemon is running.</td></tr><tr><td>-K</td><td>N/A</td><td>N/A</td><td>Keep alive. If a session ends, try to create a new session and re-bind the port. If you are using this in a script or as a daemon, it's recommended that you handle restarts externally (e.g. with an init system) and do not rely on npt -K.</td></tr><tr><td>-T</td><td>"30s"<br>"24h" (with -K)</td><td>Human readable duration:<br>e.g. "7d" or "1h,14m,30s"</td><td>How long to keep the npt session open if there have been no connections. To "never" timeout, use "-T 0" which sets a timeout of 365 days.</td></tr><tr><td>-x</td><td>N/A</td><td>N/A</td><td><p>Starts the session in the background under a different process id, then exits, printing the bound port to stdout.</p><p>Note that the background npt session will automatically close due to the timeout feature (see -T).</p><p>If you are scripting npt, this feature means you will lose control over the session process, do not use this feature if you also intend to control when npt stops or if you need to detect when the npt session dies.</p></td></tr><tr><td>-v / -q</td><td>N/A</td><td>N/A</td><td>Use -v for verbose logging.<br>Use -q for quiet (i.e. less) logging.</td></tr></tbody></table>

### Example

```bash
npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 3389 -l 33389
```

### Use Cases

{% content-ref url="/pages/f0ZZQzMPcerYMHsbOiw6" %}
[RDP](/use-cases/rdp)
{% endcontent-ref %}

{% content-ref url="/pages/91NY3Ha8Uy9I7loW436y" %}
[SFTP](/use-cases/sftp)
{% endcontent-ref %}

{% content-ref url="/pages/JO4Som2PYbhCBqNpFjQm" %}
[Web Server](/use-cases/web-server)
{% endcontent-ref %}


# sshnp Usage

### TL;DR

<pre><code><strong>sshnp -f @&#x3C;your_client_atsign> -t @&#x3C;your_device_atsign> -h @rv_(am|ap|eu|oc) -d &#x3C;name> -i &#x3C;~/.ssh&#x3C;ssh_key> -s
</strong></code></pre>

{% hint style="info" %}
Replace the \<??> with your details and remember to logout and back into the client so you have `sshnp` in your PATH.

Once you have successfully used the command to get access to the device once, you can drop the `-i` and `-s` flags if you wish.
{% endhint %}

### Overview

This guide covers the basics to understanding the parameters of and invoking sshnp.

### The four main parameters

### -f, --from

This argument is the client address, a.k.a. the from address, since we are **connecting** **from** the client. This argument is mandatory, in the form of an Atsign. For example:

```bash
sshnp ... -f @alice_client ...
```

### -t, --to

This argument is the device address, a.k.a. the to address, since we are **connecting** **to** the device. This argument is mandatory, in the form of an Atsign. For example:

```bash
sshnp ... -t @alice_device ...
```

### -d, --device

This argument is the device name, which works in tandem with `--to` to allow multiple devices to run sshnpd under a single device name. By default, this value is `"default"`, so unless you named your sshnpd device the same thing, you will need to include this parameter. For example:

```bash
sshnp ... -d my_device ...
```

### -h, --host

This argument is the address of the socket rendezvous used to establish the session connection. Atsign currently provides coverage in 3 regions, use whichever is closest to you:

### Americas

```bash
sshnp ... -h @rv_am ...
```

### Europe

```bash
sshnp ... -h @rv_eu ...
```

### Asia-Pacific

```bash
sshnp ... -h @rv_ap ...
```

### SSH Authentication

In addition to the four main parameters, it is important to ensure that the appropriate SSH authentication keys are in place.

### Pre-existing keys in place

If you already have an SSH public key installed on the device, use `-i` to specify it. For example:

```bash
sshnp ... -i path/to/my/ssh/private/key ...
```

### Automated SSH public key management

If you don't have an SSH public key installed on the device, and -s is enabled for the device, then sshnp can extract the SSH public key from the SSH private key, and send it to the daemon for you. This will automatically authorize your SSH private key. For example:

```bash
sshnp ... -i path/to/my/ssh/private/key -s ...
```

### Manual SSH public key management

If you don't have any SSH public keys in place, you must install them yourself. Copy the SSH public key to `~/.ssh/authorized_keys` on the remote device. For example:

```
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBOkiUzsOq8wc9/HaEbE4lgcWeQoICBmp8XgRW0vf5T8 (Comment / identifier to remember this key here)
```

Then use the associated private key, as mentioned under [#pre-existing-keys-in-place](#pre-existing-keys-in-place "mention"):

```
sshnp ... -i path/to/my/ssh/private/key ...
```

### Putting it all together

An example of a complete command might look like this:

```bash
sshnp -f @alice_client -t @alice_device -d my_server -h @rv_am -i ~/.ssh/id_ed25519
```

\*Note if the username on the remote machine is different than your local machine you will have to also use the `-u` flag and the `-U` flag with the remote username. For example, if the remote username is `bocbc`. If you used the `-u` flag when running the sshnpd daemon then you can safely omit the `-U` flag.

```bash
sshnp -f @alice_client -t @alice_device -d my_server \
 -h @rv_am -i ~/.ssh/id_ed25519 -u bobc -U bobc
```

### Additional Configuration

The rest of the configuration for `sshnp` is contained in a separate guide:

{% content-ref url="/pages/nLPFXNGCoI0ybNFCWgIV" %}
[Client Additional Configuration](/usage/basic-usage-1/additional-configuration)
{% endcontent-ref %}

## Want to use RDP, SFTP or etc?

The NoPorts Tunnel (NPT) can carry a wide variety of TCP based protocols such as [SFTP](/use-cases/sftp), [RDP](/use-cases/rdp), [SMB](/use-cases/smb) and [HTTP(S)](/use-cases/web-server).


# Client Additional Configuration

NoPorts client \`sshnp\` additional configuration

## Additional Options

### -k, --key-file

Specify the `.atKeys` file for the `-f, --from` Atsign if it's not stored in \~/.atsign/keys

### -v, --verbose

More logging.

### -l, --local-port

The local port which will be forwarded to the remote sshd port. If this is set to "0", it defers to to the OS to assign an ephemeral port.\
(Defaults to "0")

### --remote-sshd-port

The remote port which we expect sshd to be running on.

(Defaults to "22")

### -u, --remote-user-name

The username to use in the ssh session on the remote host.

(a.k.a. the user you want to sign in as)

### -U, --tunnel-user-name

The username to use for the initial ssh tunnel.

(a.k.a. the user running sshnpd)

### -i, --identity-file

Identity file to use for the ssh connection.

### --identity-passphrase

Passphrase for identity file.

### -s, --send-ssh-public-key

Send the ssh public key to the remote host for automatic authorization.

### --idle-timeout

Number of seconds after which inactive ssh connections will be closed

(Defaults to "15")

### -o, --local-ssh-options

Additional ssh options which are passed to the ssh program.

### --add-forwards-to-tunnel

Enable this flag to pass the `-o, --local-ssh-options` to the initial ssh tunnel instead of the ssh session.

### --ssh-client

Which ssh-client to use, `openssh` (default) or `dart`.

### --legacy-daemon

Request is to a legacy (< 4.0.0) noports daemon.

### -x, --output-execution-command

Output the ssh execution command instead of executing it.

### --config-file

Pass command line arguments via an environment file.

### --list-devices

List devices which have discovery (-u) enabled.


# sshnpd configuration

### TL;DR

```
sshnpd -m @<_client> -a @<_device> -d <name> 
```

{% hint style="info" %}
Replace the \<??> with your specific Atsign details
{% endhint %}

### Overview

sshnpd is the daemon that runs on a device to facilitate access using NoPorts.

### The three main parameters

These mainly mirror the parameters from [sshnp](/usage/basic-usage-1), but there's one fewer as the socket rendezvous is only ever set by the client.

### 1. -a, --atsign

This argument is the device address, a.k.a. the to address, since this is the address that the device is associated with. This argument is mandatory, in the form of an Atsign. For example:

```
sshnpd ... -a @alice_device ...
```

### 2a. -m, --manager, --managers

This is the address of the client(s) that will be allowed to connect to the device. For example:

```
sshnpd ... -m @alice_client ...
```

### 2b. -p, --policy-manager

As an alternative to defining a list of managers a policy manager can be used, and the policy defined on that manager will describe which clients are allowed to connect. For example:

```
sshnpd ... -p @alice_policy ...
```

### 3. -d, --device

The device name. This is used to associate multiple devices with the same Atsign. By default the value is `default` so unless you want that as the device name you will need to include this parameter. For example:

```
sshnpd ... -d my_device ...
```

### Putting it all together

An example of a complete command might look like this:

```
sshnpd -a @alice_device -m @alice_client -d my_server
```

### Running the daemon as a service

The daemon should normally be run as a service so that it starts up automatically and can be restarted if it should fail.

Most mainstream Linux distributions use [systemd](https://en.wikipedia.org/wiki/Systemd) to manage services, and we provide a systemd unit file that's configured by the universal installer. That file can be edited after installation to customize or add additional options. For distributions such as OpenWrt we provide config and init files that can be customized with a text editor or configured through the web admin interface.

### Additional Configuration

The rest of the configuration for `sshnpd` is contained in a separate guide:

{% content-ref url="/pages/N7gnKkd0tRPYMzr0OkVT" %}
[Daemon Additional Configuration](/usage/sshnpd-configuration/daemon-additional-configuration)
{% endcontent-ref %}

### Modifying your device's systemd unit

If you installed sshnpd through the universal installer, then you can modify the `/etc/systemd/system/sshnpd.service.d/override.conf` file to take advantage of the configurations and options listed above to tailor sshnpd to your needs.

Lots of configuration can be done to sshnpd by editing this file, such as changing the user that sshnpd runs as, changing the Atsign, enabling/disabling verbose logging, and more.

Below is a sample `override.conf` file:

```sh
# MANDATORY: User to run the daemon as
User=bob

# MANDATORY: Manager (client) or policy manager address (atSign)
Environment=manager_atsign="@alice"

# MANDATORY: Device address (atSign)
Environment=device_atsign="@bob"

# OPTIONAL: Delegated access policy management
Environment=delegate_policy=""

# Device name
Environment=device_name="atsign"

# Comment if you don't want the daemon to update authorized_keys to include
# public keys sent by authorized manager atSigns
Environment=s="-s"

# Comment to disable verbose logging
Environment=v="-v"

# Any additional command line arguments for sshnpd
Environment=additional_args=""
```

Adding additional arguments is as simple as modifying the `Environment=additional_args=""`string found inside of `override.conf` .

The example below adds the `--permit-open` to the string of additional args which enables clients to access ports 22, 3389, and 2221 on localhost.

```sh
# Any additional command line arguments for sshnpd
Environment=additional_args="--permit-open \"localhost:22,localhost:3389,localhost:2221\""
```

Don't forget to update sshnpd by executing by executing the following. May require sudo.

```sh
systemctl daemon-reload
systemctl restart sshnpd.service
```


# Daemon Additional Configuration

NoPorts daemon \`sshnpd\` additional configuration

### Additional Options

### -k, --key-file, --keyFile

Specify the `.atKeys` file for the `-a, --atsign` Atsign if it's not stored in `~/.atsign/keys`

### -s, --\[no-]sshpublickey

When set, will update authorized\_keys to include public key sent by manager.

### -h, --hide

Hides the device from advertising its information to the manager Atsign. Even with this enabled, sshnpd will still respond to ping requests from the manager. (This takes priority over the \[now deprecated] -u / --un-hide flag).

### -v, --\[no-]verbose

More logging

### --ssh-client

What to use for outbound ssh connections.

\[openssh (default), dart]

### --root-domain

atDirectory domain

(Defaults to "root.atsign.org")

### --device-group

The name of this device's group. When delegated authorization is being used then the group name is sent to the authorizer service as well as the device name, this daemon's Atsign, and the client Atsign which is requesting a connection

(Defaults to "\_\_none\_\_")

### --local-sshd-port

Port on which sshd is listening locally on localhost

(Defaults to "22")

### -S, --sshpublickey-permissions

When --sshpublickey is enabled, will include the specified permissions in the public key entry in authorized\_keys

(Defaults to "")

### --ephemeral-permissions

The permissions which will be added to the authorized\_keys file for the ephemeral public keys which are generated when a client is connecting via forward ssh e.g. PermitOpen="host-1:3389",PermitOpen="localhost:80"

(Defaults to "")

### --ssh-algorithm

Use RSA 4096 keys rather than the default ED25519 keys

\[ssh-ed25519 (default), ssh-rsa]

### --storage-path

Directory for local storage.

(Defaults to `$HOME/.atsign/storage/$atSign/.npd/$deviceName/`)

### --permit-open,--po

Comma separated-list of host:port to which the daemon will permit a connection from an authorized client. Hosts may be dns names or ip addresses.

(Defaults to "localhost:22,localhost:3389")


# Integrations

NoPorts integrates seamlessly with Linux and macOS SSH configurations, allowing secure outbound connections via OpenSSH config.

{% content-ref url="/pages/IsJZhuzS0laCtoLId0DK" %}
[OpenSSH Config](/integrations/integrate-with-ssh-config)
{% endcontent-ref %}

For Windows, NoPorts works with PuTTY, enabling efficient management of multiple SSH sessions without exposed ports.

{% content-ref url="/pages/LZmFiOrwLX3zVRL1iHZc" %}
[PuTTY config](/integrations/putty-config)
{% endcontent-ref %}


# OpenSSH Config

How to integrate NoPorts into your native Linux and macOS ssh configuration

### Overview

This guide will help you setup NoPorts in your SSH configuration. Once set up, you will be able to ssh to machines using NoPorts the same way you would for a normal ssh host. As this is integrated with the SSH configuration, it will also work with other applications that support SSH proxying.

### Usage

Once you've set up your configuration, you will be able to SSH over NoPorts just like any other host, using your own custom hostnames for devices.

For example, with a device called `my_lab`:

```sh
ssh my_lab
```

### The Template

The following is a template for adding an sshnp connection to your ssh config for ease of use:

{% code title="\~/.ssh/config" overflow="wrap" lineNumbers="true" %}

```
Host <host>
  Hostname localhost
  AddKeysToAgent yes
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  IdentityFile ~/.ssh/id_ed25519
  ProxyCommand=$(sshnp -f <client> -t <device> -r <srvd> -d <device_name> -u <username> -x 2>/dev/null) -W "%h:%p" -o "StrictHostKeyChecking=no"
  ControlMaster auto
  ControlPath ~/.ssh/control-%r@%n:%p

```

{% endcode %}

You need to replace the values surrounded with `<>` on lines 1 & 7 with your own values.

`host` is any valid hostname you would like, this is what you will use to invoke your ssh command, so make sure it's easy to remember and type.

`username` is the username on the remote machine you wish to login as.

The rest of the values are the normal arguments you would invoke with sshnp, see [here](/usage/basic-usage-1) for more info.

#### Example

{% code overflow="wrap" %}

```
Host alice_device
  Hostname localhost
  AddKeysToAgent yes
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  IdentityFile ~/.ssh/id_ed25519
  ProxyCommand=$(sshnp -f @alice_client -t @alice_device -r @rv_am -d my_device -u <username> -x 2>/dev/null) -W "%h:%p" -o "StrictHostKeyChecking=no"
  ControlMaster auto
  ControlPath ~/.ssh/control-%r@%n:%p
```

{% endcode %}

This example shows the configuration for the following equivalent sshnp command:

```
sshnp -f @alice_client -t @alice_device -d my_server -r @rv_am
```

When you want to connect to this device, this is what you would type:

```bash
ssh alice_device
```

`alice_device` maps the the `Host alice_device` line.

### Additional Usage Tips

#### 1. Extending ssh config

You can add any additional ssh config to the file as you normally would, for example a TCP forwarding:

{% code title="\~/.ssh/config" overflow="wrap" lineNumbers="true" %}

```
Host my_webdev_server
  Hostname localhost
  AddKeysToAgent yes
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  IdentityFile ~/.ssh/id_ed25519
  LocalForward 8080:0:8080
  ProxyCommand=...
```

{% endcode %}

#### 2. Extending ssh command

You can also add any additional flags to the ssh command, for example a TCP forwarding:

```bash
ssh my_webdev_server -L "8080:0:8080"
```

### Template Explained

If you want to understand each line of the template, and what it does, read on.

#### Line 1

`<host>` is the "nickname" you would use to connect to, e.g. `ssh <host>`.

{% hint style="info" %}
You can pick anything you want, but you should make sure that this won't clash with other hostnames you might want to connect to.
{% endhint %}

#### Line 2

Line 2 is mandatory due to the nature of how sshnp works, sshnp must connect over the loopback interface where the NoPorts tunnel was created.

#### Line 3

Tell ssh to automatically add the ssh keys to the agent when we load them (we will load them on line 6)

#### Line 4

Don't cache the connection to known hosts, since sshnp uses ephemeral ports, it is pointless to do so.

#### Line 5

Because we are using ephemeral ports, it is useful to suppress strict host key checking.

#### Line 6

The ssh key you would like to load and authenticate with (this is equivalent to `ssh -i`).

#### Line 7

A proxy command, which first executes sshnp to determine the ssh proxy command which will be executed, fill in the arguments on this line as you would normally.

See [sshnp Usage](/usage/basic-usage-1) to learn more about filling in this line.

#### Lines 8 & 9

ControlMaster and ControlPath tell ssh to try to reuse existing ssh connections if you start up multiple. This means only the first connection will setup sshnp, the rest of the connections will use the tunnel that is already there!


# PuTTY config

How to manage tons of NoPorts SSH connections with Putty

## PuTTY config

### Overview

This guide will help you setup some very minimal Python scripts to manage connections with NoPorts. In most cases only 4-5 lines of python will be required to setup a new device.

#### Requirements

* Python (version 3)
* OpenSSH (acts as a proxy between NoPorts & PuTTY)

#### Usage

Once you've setup your configuration, you will be able to SSH over NoPorts by double clicking a simple shortcut. It will first launch NoPorts, then once NoPorts is started, it will setup your PuTTY session.

#### The Base Configuration

The base configuration contains all of the core logic for starting a PuTTY session over NoPorts. Copy this to the folder where you want to store all of your device configurations, name the file `noports_base.py`.

<details>

<summary>Open this to copy the code</summary>

{% code title="noports\_base.py" %}

```python
from subprocess import run, PIPE, Popen, CREATE_NO_WINDOW
from socket import socket

class noports_config:
    # NoPorts configs
    client_atsign: str
    device_atsign: str
    device_name: str
    relay_atsign: str
    openssh_keyfile: str
    upload_public_key: bool = False

    # Putty configs
    ssh_user: str
    local_host: str = "localhost"
    local_port: int = None
    putty_keyfile: str

    def get_ephemeral_port(self) -> int:
        sock = socket()
        sock.bind(('', 0))
        port = sock.getsockname()[1]
        sock.close()
        return port

    def run_noports(self):
        if self.local_port == None:
            self.local_port = self.get_ephemeral_port()
        args = ["C:\\Program Files\\NoPorts\\sshnp.exe",
            "-f", self.client_atsign,
            "-t", self.device_atsign,
            "-d", self.device_name,
            "-r", self.relay_atsign,
            "-l", f"{self.local_port}",
            "-i", self.openssh_keyfile,
            "-u", self.ssh_user,
            "-x",
        ]
        if self.upload_public_key:
            args.append("-s")
        result = run(args, stdout=PIPE)
        return result.stdout

    def run_putty(self):
        Popen(["C:\\Program Files\\PuTTY\\putty.exe", 
            "-proxycmd",  self.run_noports(),
            f"{self.ssh_user}@{self.local_host}",
            "-P", f"{self.local_port}",
            "-i", self.putty_keyfile,
        ], creationflags=CREATE_NO_WINDOW)
 
# TODO: Change the strings below to setup your default profile values
class my_default_config(noports_config):
    client_atsign = "@alice_client"
    device_atsign = "@alice_device"
    relay_atsign = "@rv_am"

    # path to ssh keys in openssh key format
    # you may use PuTTYgen to convert from .ppk
    openssh_keyfile = "C:\\Users\\chant\\.ssh\\id_ed25519"

    # path to ssh keys in putty key format
    # you may use PuTTYgen to convert another key to .ppk
    putty_keyfile = "C:\\Users\\chant\\.ssh\\id_ed25519.ppk"
    
    # Upload your SSH public key automatically
    # -s must be enabled on sshnpd for this to work
    upload_public_key = False 
    
    # The username to sign in as
    ssh_user = "alice"
```

{% endcode %}

</details>

#### Setting up a new device

To setup a new device, create a new python (`.py`) in the same folder where you created `noports_base.py`. Then copy the following file:

{% code title="example\_config.py" %}

```python
from .noports_base import my_default_config
class device(my_default_config):
    # TODO: setup device name and override any default config here
    # make sure to indent these lines the same
    device_name = "my_device_name"
    pass
device().run_putty()
```

{% endcode %}

#### Overriding the Default Configuration

If you have a bunch of devices that all use the same configuration values, then you'd want to put that in the noports\_base configuration. However, there may be a few devices where you want to use a different value. You can simply override the value from your device profile:

{% code title="override\_defaults.py" %}

```python
from .noports_base import my_default_config
class device(my_default_config):
    # TODO: setup device name and override any default config here
    # make sure to indent these lines the same
    device_name = "my_device_name"
    # Overriding the client & device atsign:
    client_atsign = "@my_other_client_atsign"
    device_atsign = "@my_other_device_atsign"
    pass
device().run_putty()
```

{% endcode %}

#### Create Shortcuts to Organize your Profiles

Because all of the profiles need to be in the same directory as the `noports_base.py` file, you can't easily move those files around to organize them. To work around this, simply create shortcuts of all the device profiles, then you can move and rename those shortcuts around freely.

<figure><img src="/files/rtmTIO764wEtF41Pqq8I" alt=""><figcaption><p>Example of separate shortcuts into different folders</p></figcaption></figure>

\---\
description: How to manage tons of NoPorts SSH connections with Putty\
icon: windows\
\---

## PuTTY config

#### Overview

This guide will help you set up some very minimal Python scripts to manage connections with NoPorts. In most cases only 4-5 lines of Python will be required to set up a new device.

#### Requirements

* Python (version 3)
* OpenSSH (acts as a proxy between NoPorts & PuTTY)

#### Usage

Once you've setup your configuration, you will be able to SSH over NoPorts by double clicking a simple shortcut. It will first launch NoPorts, then once NoPorts is started, it will set up your PuTTY session.

#### The Base Configuration

The base configuration contains all of the core logic for starting a PuTTY session over NoPorts. Copy this to the folder where you want to store all of your device configurations, name the file `noports_base.py`.

<details>

<summary>Open this to copy the code</summary>

{% code title="noports\_base.py" %}

```python
from subprocess import run, PIPE, Popen, CREATE_NO_WINDOW
from socket import socket

class noports_config:
    # NoPorts configs
    client_atsign: str
    device_atsign: str
    device_name: str
    relay_atsign: str
    openssh_keyfile: str
    upload_public_key: bool = False

    # Putty configs
    ssh_user: str
    local_host: str = "localhost"
    local_port: int = None
    putty_keyfile: str

    def get_ephemeral_port(self) -> int:
        sock = socket()
        sock.bind(('', 0))
        port = sock.getsockname()[1]
        sock.close()
        return port

    def run_noports(self):
        if self.local_port == None:
            self.local_port = self.get_ephemeral_port()
        args = ["C:\\Program Files\\NoPorts\\sshnp.exe",
            "-f", self.client_atsign,
            "-t", self.device_atsign,
            "-d", self.device_name,
            "-r", self.relay_atsign,
            "-l", f"{self.local_port}",
            "-i", self.openssh_keyfile,
            "-u", self.ssh_user,
            "-x",
        ]
        if self.upload_public_key:
            args.append("-s")
        result = run(args, stdout=PIPE)
        return result.stdout

    def run_putty(self):
        Popen(["C:\\Program Files\\PuTTY\\putty.exe", 
            "-proxycmd",  self.run_noports(),
            f"{self.ssh_user}@{self.local_host}",
            "-P", f"{self.local_port}",
            "-i", self.putty_keyfile,
        ], creationflags=CREATE_NO_WINDOW)
 
# TODO: Change the strings below to setup your default profile values
class my_default_config(noports_config):
    client_atsign = "@alice_client"
    device_atsign = "@alice_device"
    relay_atsign = "@rv_am"

    # path to ssh keys in openssh key format
    # you may use PuTTYgen to convert from .ppk
    openssh_keyfile = "C:\\Users\\chant\\.ssh\\id_ed25519"

    # path to ssh keys in putty key format
    # you may use PuTTYgen to convert another key to .ppk
    putty_keyfile = "C:\\Users\\chant\\.ssh\\id_ed25519.ppk"
    
    # Upload your SSH public key automatically
    # -s must be enabled on sshnpd for this to work
    upload_public_key = False 
    
    # The username to sign in as
    ssh_user = "alice"
```

{% endcode %}

</details>

#### Setting up a new device

To set up a new device, create a new python (`.py`) in the same folder where you created `noports_base.py`. Then copy the following file:

{% code title="example\_config.py" %}

```python
from .noports_base import my_default_config
class device(my_default_config):
    # TODO: setup device name and override any default config here
    # make sure to indent these lines the same
    device_name = "my_device_name"
    pass
device().run_putty()
```

{% endcode %}

#### Overriding the Default Configuration

If you have a bunch of devices that all use the same configuration values, then you'd want to put that in the noports\_base configuration. However, there may be a few devices where you want to use a different value. You can simply override the value from your device profile:

{% code title="override\_defaults.py" %}

```python
from .noports_base import my_default_config
class device(my_default_config):
    # TODO: setup device name and override any default config here
    # make sure to indent these lines the same
    device_name = "my_device_name"
    # Overriding the client & device atsign:
    client_atsign = "@my_other_client_atsign"
    device_atsign = "@my_other_device_atsign"
    pass
device().run_putty()
```

{% endcode %}

#### Create Shortcuts to Organize your Profiles

Because all of the profiles need to be in the same directory as the `noports_base.py` file, you can't easily move those files around to organize them. To work around this, simply create shortcuts of all the device profiles, then you can move and rename those shortcuts around freely.

<figure><img src="/files/rtmTIO764wEtF41Pqq8I" alt=""><figcaption><p>Example of separate shortcuts into different folders</p></figcaption></figure>


# Remmina Config

Integrate RDP and VNC over NoPorts using Remmina (Linux)

Remmina is a Remote Desktop client for Linux which supports a number of remote access protocols. This guide will walk you through setting up Remmina to connect over NoPorts. While it focuses on VNC and RDP, it should work for most of the other protocols available through Remmina.

Prerequisites:

* Linux Desktop
* [NoPorts Cli binaries](/installation/connecting-from-linux) installed

### Installing Remmina and Plugins

Dependent on your distribution, the steps may vary. Remmina is quite popular, so you should be able to web search your way to installing Remmina.

{% hint style="warning" %}
When installing Remmina, make sure it is not installed to a sandboxed environment such as Flatpak, otherwise the "Execute a Command" feature in Remmina will not work.
{% endhint %}

In most cases, the package name is `remmina` and you will need to make sure that some optional dependencies are installed:

* `freerdp` - if you want to use RDP (a.k.a. Windows app) with Remmina
* `libvncserver` - if you want to VNC (a.k.a. MacOS screen sharing) with Remmina

If you already have Remmina running, you may need to restart it after installing these optional dependencies, otherwise they won't appear as options to create profiles for. By default, Remmina won't full quit when you close the window. So, check your app tray to full quit, or use the `killall remmina` command.

### Getting the path to npt

If Remmina doesn't have access to the `PATH`, it may not be able to find `npt` . To mitigate this, we will use the absolute path when we create our hook for Remmina.

Run the following command:

```bash
which npt
```

The command should output a path such as:

```
/usr/local/bin/npt
```

Save this path for later; we will use it during profile creation.

### Setting up an RDP profile

Create a new profile. There are four settings we should change on this screen:

* Name: a nickname for your profile, anything you want.
* Protocol: RDP
* Server: The loopback interface IP address followed by a random free local port of your choice.
  * Make sure the port is unique per profile, or you can only use one at a time.
* Username: The username of the account you want to log in as.

<div align="left" data-full-width="false"><figure><img src="/files/l3QQhO9SForE3rtyLsZX" alt=""><figcaption></figcaption></figure></div>

Now go to the `Behavior` tab.

Here, we need to craft an npt command that will get us access to RDP on the remote machine.

```bash
/usr/local/bin/npt -f @your_client -t @your_device -d device_name -r @rv_am --lp 12345 -p 3389 -x
```

Breaking down this command:

<table><thead><tr><th width="302.5">Command portion</th><th>Explanation</th></tr></thead><tbody><tr><td><code>/usr/local/bin/npt</code></td><td>Run the npt command</td></tr><tr><td><code>-f @your_client</code></td><td>The "from" Atsign (Atsign of the current computer)</td></tr><tr><td><code>-t @your_device</code></td><td>The "to" Atsign (Atsign of the device you're connecting to)</td></tr><tr><td><code>-d device_name</code></td><td>The device name you gave when you setup sshnpd</td></tr><tr><td><code>-r @rv_am</code></td><td>The Atsign of the relay you want to use</td></tr><tr><td><code>--lp 12345</code></td><td>The local port, must match the port we added on the basic page.</td></tr><tr><td><code>-p 3389</code></td><td>The remote port, 3389 is the canonical RDP port</td></tr><tr><td><code>-x</code></td><td>Tell npt to exit when connected<br>(which tells remmina npt is ready for it to connect)</td></tr></tbody></table>

Place this command in the "Before connecting" field.

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

Save the profile, then use it to connect. At first, you will see a popup window that Remmina opens when it runs the command. That window will automatically close if the command is successful, at which point it will start the RDP connection.

### Setting up a VNC profile

Create a new profile. There are four settings we should change on this screen:

* Name: a nickname for your profile, anything you want.
* Protocol: VNC
* Server: The loopback host followed by a random free local port of your choice.
  * Make sure the port is unique per profile, or you can only use one at a time.
* Username: The username of the account you want to login as.

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

Now go to the `Behavior` tab.

Here, we need to craft an npt command that will get us access to RDP on the remote machine.

```bash
/usr/local/bin/npt -f @your_client -t @your_device -d device_name -r @rv_am --lp 56789 -p 5900 -x
```

Breaking down this command:

<table><thead><tr><th width="302.5">Command portion</th><th>Explanation</th></tr></thead><tbody><tr><td><code>/usr/local/bin/npt</code></td><td>Run the npt command</td></tr><tr><td><code>-f @your_client</code></td><td>The "from" Atsign (Atsign of the current computer)</td></tr><tr><td><code>-t @your_device</code></td><td>The "to" Atsign (Atsign of the device you're connecting to)</td></tr><tr><td><code>-d device_name</code></td><td>The device name you gave when you setup sshnpd</td></tr><tr><td><code>-r @rv_am</code></td><td>The Atsign of the relay you want to use</td></tr><tr><td><code>--lp 56789</code></td><td>The local port, must match the port we added on the basic page</td></tr><tr><td><code>-p 5900</code></td><td>The remote port, 5900 is the canonical VNC port on MacOS</td></tr><tr><td><code>-x</code></td><td>Tell npt to exit when connected<br>(which tells remmina npt is ready for it to connect)</td></tr></tbody></table>

Place this command in the "Before connecting" field.

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

Save the profile, then use it to connect. At first, you will see a popup window that Remmina opens when it runs the command. That window will automatically close if the command is successful, at which point it will start the VNC connection.

### Troubleshooting

If you have trouble, try running the npt command in a terminal first. If you run into issues, then you know it is your npt command. If the command does work in a terminal, then it is likely something with your Remmina configuration, you may have to tweak additional settings.


# Copy of Troubleshooting

## TimeoutException: Connection timeout to srvd \<atsign> service

You receive the following error while using NoPorts:

```
TimeoutException: Connection timeout to srvd <atsign> service
```

There are a few possibilities for why this might be happening:

1. The relay atsign (-r in cli) is not running a relay or doesn't exist
2. The device atsign (-t in cli) doesn't exist

## TimeoutException: Daemon feature check timed out

You receive the following error while using NoPorts:

```
TimeoutException: Daemon feature check timed out
```

There are a few possibilities for why this might be happening:

1. There is no device running with device name (-d in cli)
2. You don't have permissions to make this connection to the device

* TODO: permit open / policy
* Replace the \<??> with your details and remember to logout and back into the client so you have`npt`in your PATH.\
  \
  Note: ensure that the sshnpd on the server includes the remote port in their --permit-open/--po rules. If you installed using defaults then you need to edit the `/etc/systemd/system/sshnpd.service` file and add the hosts/ports you want to connect to via npt. \\

  For example:

  `ExecStart=/usr/local/bin/sshnpd -a "$device_atsign" -m "$manager_atsign" -d "$device_name" "$s" "$u" "$v"`

  Would become

  `ExecStart=/usr/local/bin/sshnpd -a "$device_atsign" -m "$manager_atsign" -d "$device_name" "$s" "$u" "$v" --po 127.0.0.1:22,192.168.1.90:445`

  To allow localhost access to SSH and SMB/CIFS access to 192.168.1.90 on port 445. Then run.

  `sudo systemctl daemon-reload`

  `sudo systemctl restart sshnpd.service`

  If you used a non root install (e.g. TMUX) then you will need to make a similar edit to `~/.local/bin/sshnpd.sh` and restart the script\\


# Troubleshooting

### Summary Table (Quick Reference)

| [Timeout to srvd](#issue-timeout-to-srvd)                                           | `TimeoutException: Connection timeout to srvd <atsign> service` | Check if relay or device Atsign exists                                      |
| ----------------------------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------- |
| [Daemon feature check timeout](#issue-daemon-feature-check-timeout)                 | `TimeoutException: Daemon feature check timed out`              | Ensure device name is correct and permissions are in place                  |
| [Keys not found after install](#issue-keys-not-found-after-install)                 | Keys missing after install                                      | Avoid enrolling as root; match user with SSHNPD install                     |
| [Client SSH error "chown failed error"](#issue-client-ssh-error-chown-failed-error) | SSH error on client                                             | Use `--permit-open` with both 127.0.0.1 and localhost; check file ownership |
| [Windows app hangs on activation](#issue-windows-app-hangs-on-activation)           | Stuck on “preparing for activation”                             | Update CA certificates via certutil                                         |
| [Enrollment authorization failed](#issue-enrollment-authorization-failed)           | `Failed to authorise enrollment`                                | Use manager keys instead of reused ones                                     |
| [SUDO\_USER is not set](#issue-sudo_user-is-not-set)                                | `SUDO_USER: unbound variable` or `SUDO_USER is not set`         | Log in with a regular account instead of root                               |

### ❌ Issue: Timeout to srvd

**Symptom** You receive the following error while using NoPorts: `TimeoutException: Connection timeout to srvd <atsign> service`

**Possible Causes**

* The relay Atsign (`-r`) is not running or doesn’t exist
* The device Atsign (`-t`) doesn’t exist

**Solution**

* Double-check the relay and device Atsigns for typos
* Use `sshnp --list-devices` to verify device availability

***

### ❌ Issue: Daemon Feature Check Timeout

**Symptom** `TimeoutException: Daemon feature check timed out`

**Possible Causes**

* No device is running with the specified device name (`-d`)
* You lack permission to connect to the device

**Solution**

* Confirm the device is online and registered
* Ensure your Atsign has permission to access the device

***

### ❌ Issue: Keys Not Found After Install

**Symptom** Keys are not found after device installation

**Root Cause** sshnpd was installed as root, but the enrollment was also done as root. The keys were saved to `/root/.atsign/keys/` instead of the correct user directory.

**Solution**

* Always enroll using the same user that sshnpd runs under
* Add a warning in the docs or script to prevent root-based enrollment

***

### ❌ Issue: Client SSH Error "chown failed error"

**Symptom** Error message: `invalid daemon response: chown failed error: Operation not permitted`

**Root Cause** Raspberry Pi may behave inconsistently with `localhost` vs `127.0.0.1`, or file permissions are incorrect.

**Solution**

* Use `--permit-open="127.0.0.1:22,127.0.0.1:3389,localhost:22,localhost:3389"`
* Ensure `~/.ssh` is owned by the correct user:

  ```
  sudo chown -R $USER:$USER ~/.ssh
  ```

***

### ❌ Issue: Windows App Hangs on Activation

**Symptom** NoPorts desktop app hangs on “preparing for activation”

**Root Cause** Outdated CA certificates on Windows 11

**Solution** Follow these steps to update root certificates:

1. Run Windows Update
2. Open Command Prompt as Administrator
3. Run:

   ```
   certutil -generateSSTFromWU roots.sst  
   certutil -addstore -f root roots.sst
   ```
4. Verify with `certmgr.msc`
5. Repeat for Trusted Publishers if needed

***

### ❌ Issue: Enrollment Authorization Failed

**Symptom** `Failed to authorise enrollment. Client is not authorised for namespaces in the enrollment request.`

**Root Cause** You’re using a previously enrolled key for a new enrollment.

**Solution** Use the correct **manager keys** for enrollment.

***

### ❌ Issue: SUDO\_USER is not set

**Symptom** `SUDO_USER: unbound variable` or `SUDO_USER is not set`

**Root Cause**

* You are logged in as the root user.
* No regular (non‑root) account exists on the system.

**Solution**

* Log in with a regular account instead of root.
* Use `sudo` when elevated privileges are required.
* If you do not have a regular account, create one before running NoPorts commands.


# Resources

These guides cover our most commonly asked NoPorts installation questions

While these are frequently asked questions, if you are responsible for installing NoPorts for your organization, these guides are worth reading for better understanding.

{% content-ref url="/pages/SEE2tsV0IkwCDe5pZZ0T" %}
[How to activate an Atsign](/installation-faq/activating-your-atsigns)
{% endcontent-ref %}

{% content-ref url="/pages/bykq6IDRp0eStQrmBpiE" %}
[Reuse your client Atsign on another machine](/installation-faq/reuse-your-client-atsign-on-another-machine)
{% endcontent-ref %}

{% content-ref url="/pages/RuNrUBpp3UUAbDY1UL4n" %}
[How to name a device](/installation-faq/installation-details)
{% endcontent-ref %}

{% content-ref url="/pages/HPWDkzrOyH27F85hTslg" %}
[How to generate SSH keys](/installation-faq/how-to-generate-ssh-keys)
{% endcontent-ref %}

{% content-ref url="/pages/vKuJu4jm6xGCEzmu2XgK" %}
[Why activate the device Atsign on the client?](/installation-faq/why-activate-the-device-atsign-on-the-client)
{% endcontent-ref %}


# How to activate an Atsign

Steps for client and device Atsign

## Overview

NoPorts needs to be installed on both the machine you are going to connect to (device) and the machine you are going to connect from (client). NoPorts uses Atsigns as addresses and you will need two, one for the client and one for the device.

{% hint style="danger" %}
If you don't own a pair of Atsigns/addresses, please visit [my.noports.com](https://my.noports.com/no-ports-plans) before continuing.
{% endhint %}

Example client Atsign

```
@sshnp_client
```

Example device Atsign

```
@sshnp_device
```

## Activate your Atsigns

{% hint style="info" %}
Activation of a particular Atsign is only done once. During activation, cryptographic keys are cut and stored on your machine.

You will activate both the client Atsign ***and*** the device Atsign on your client machine, and you will then authorize your device(s) to use the device Atsign.
{% endhint %}

### Activate the client Atsign

(1) Run the at\_activate command for the client Atsign

<pre class="language-bash"><code class="lang-bash"><strong>~/.local/bin/at_activate -a @&#x3C;REPLACE>_client
</strong></code></pre>

(2) Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

at\_activate will pause and wait for the input of a one time pin (OTP) before you can continue. You should receive this pin to the contact information associated with the registration of your NoPorts address (i.e. email or text message).

{% hint style="warning" %}
If you are using a gmail.com account we have seen that sometimes the OTP gets stuck in the SPAM or PROMOTIONS folder. If you do not see the OTP check those folders.
{% endhint %}

Once you receive the message, enter the pin into the application and press enter to continue. The application should proceed to create the cryptographic keys and store them in the `~/.atsign/keys/` directory with a filename that includes the Atsign.

### Activate the device Atsign

1\) Run the at\_activate command for the device Atsign

<pre class="language-bash"><code class="lang-bash"><strong>~/.local/bin/at_activate -a @&#x3C;REPLACE>_device
</strong></code></pre>

2\) Enter the One Time Password (OTP) & Check your SPAM/PROMOTIONS folders

Again, at\_activate will pause and wait for the input of a one time pin (OTP) before you can continue. You should receive this pin to the contact information associated with the registration of your NoPorts address (i.e. email or text message).

{% hint style="warning" %}
If you are using a gmail.com account we have seen that sometimes the OTP gets stuck in the SPAM or PROMOTIONS folder. If you do not see the OTP check those folders.
{% endhint %}

Once you receive the message, enter the pin into the application and press enter to continue. The application should proceed to create the cryptographic keys and store them in the `~/.atsign/keys/` directory with a filename that includes the atSign.


# Reuse your client Atsign on another machine

A review of two available methods

## Want to use your Atsign on a different machine?

You can:

A. Generate a new set of cryptographic keys (Recommended)

B. Copy the cryptographic keys from the machine where it's been activated in the past (Not recommended)

### **Option A) Generate a new set of cryptographic keys (Recommended)**

To generate a new set of cryptographic keys, there are three main steps. They occur from two different machines, so pay careful attention to which machine you perform each step on.

"Old machine" is the machine that has the **original** set of cryptographic keys that were generated. "New machine" is the device you want the new set of cryptographic keys on. These new keys will have restricted permissions that only work with NoPorts, and cannot be used for generating other keys.

1. \[Old machine] Generate a Passcode
2. \[New machine] Enroll the new key pair (send a request for keys from the new machine)
3. \[Old machine] Approve the request

**For detailed instructions, follow this guide:**

{% content-ref url="/pages/XyWfPHHRFggzmCNpS40d" %}
[Generate a new set of cryptographic keys](/installation-faq/reuse-your-client-atsign-on-another-machine/generate-a-new-set-of-cryptographic-keys)
{% endcontent-ref %}

### **Option B) Copy the cryptographic keys from the machine where it's been activated in the past (Not recommended)**

* The Atsign keys file will be located at `~/.atsign/keys/` directory with a filename that will include the Atsign. Copy this file from your other machine to the same location on the machine that you are installing SSH No Ports on, using `scp` or similar.

Why don't we recommend this approach?

> When you use method A, it creates a new set of cryptographic keys. These keys can be disabled individually, which means if a device's keys are compromised, you can disable those keys without affecting your other devices.


# Generate a new set of cryptographic keys

"<mark style="color:red;">**Old machine**</mark>" is the machine that has the **original** set of cryptographic keys that were generated. "<mark style="color:orange;">**New machine**</mark>" is the device you want the new set of cryptographic keys on.

### Step 1) Generate a passcode from your <mark style="color:red;">Old machine</mark>

Choose the operating system that is running on your old machine.

{% tabs %}
{% tab title="MacOS/Linux" %}
{% hint style="warning" %}
Make sure to replace `<REPLACE_client>` with your client Atsign
{% endhint %}

```
~/.local/bin/at_activate otp -a @<REPLACE_client>
```

{% endtab %}

{% tab title="Windows" %}

#### 1.1 Open the Windows installer program and click "Manage Keys"

<figure><img src="/files/4KE0h9rQ1nwhpNB3EB1q" alt=""><figcaption></figcaption></figure>

#### 1.2 Enter the atSign you wish to manage and click "Next"

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

#### 1.3 Click "New OTP"

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

#### 1.4 Wait a few seconds for the OTP to appear then proceed to Step 2 on the <mark style="color:orange;">New machine</mark>

<figure><img src="/files/Xvkjo49a8MNsQ2TlB2JG" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

### Step 2) Make an authorization request on your <mark style="color:orange;">New machine</mark>

Choose the operating system that is running on your new machine.

{% tabs %}
{% tab title="Running MacOS/Linux" %}
{% hint style="warning" %}
Make sure to replace the appropriate values:\
`<REPLACE_client>` with your client Atsign\
`<client_device_name>` with a unique name for the device\
`<PASSCODE>` with the passcode from **Step 1**
{% endhint %}

```
~/.local/bin/at_activate enroll -a @<REPLACE_client> \
  -s <PASSCODE> \
  -p noports \
  -k ~/.atsign/keys/@<REPLACE_client>_key.atKeys \
  -d <client_device_name> \
  -n "sshnp:rw,sshrvd:rw"
```

{% endtab %}

{% tab title="Running Windows" %}

#### 2.1 Open the Windows Installer and click "Generate Keys"

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

#### 2.2 Enter the atSign you wish to transfer and click "Next"

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

#### 2.3 Enter the OTP then press "Generate"

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

#### 2.4 Proceed to Step 3. Once the request has been approved in Step 3, you should see this screen

<figure><img src="/files/nuPm5ayh3pcFqGesFtJ2" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

### Step 3) Approve the request on your <mark style="color:red;">Old machine</mark>

Choose the operating system that is running on your old machine.

{% tabs %}
{% tab title="MacOS/Linux" %}
{% hint style="warning" %}
Make sure to replace `<client_device_name>` with the device name from **Step 2**
{% endhint %}

```
~/.local/bin/at_activate approve -a @<REPLACE_client> \
  --arx noports \
  --drx <client_device_name>
```

{% endtab %}

{% tab title="Windows" %}
{% hint style="info" %}
If you aren't already on the "Manage Keys" screen, follow **Steps 1.1 and 1.2** above.
{% endhint %}

#### 3.1 Once step 2 is complete press refresh and the new request will appear

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

#### 3.2 Approve or Deny the request

* If the request looks incorrect, then press "Deny" to deny it, and start the process again.
* If the request looks correct, then press "Approve" to approve it.

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

#### 3.3 Once the request is approved, it should disappear from the installer, the new machine's enrollment should complete in a few seconds.

<figure><img src="/files/jA2UzxaGTQtmSPP6ZmGI" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}


# New machine: activate from the command line

{% hint style="info" %}
Make sure to replace the appropriate values:\
`<REPLACE_client>` to your client atSign\
`<client_device_name>` to a unique name for the device\
`<PASSCODE>` with the passcode from step 1
{% endhint %}

### Step 2) Enroll the new key pair (send a request for keys from the new machine)

```
~/.local/bin/at_activate enroll -a @<REPLACE_client> \
  -s <PASSCODE> \
  -p noports \
  -k ~/.atsign/keys/@<REPLACE_client>_key.atKeys \
  -d <client_device_name> \
  -n "sshnp:rw,sshrvd:rw"
```


# New machine: activate from the Windows installer

### Step 2) Enroll the new key pair (send a request for keys from the new machine)

#### 2.1 Open the Windows Installer program and click "Generate Keys"

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

#### 2.2 Enter the atSign you wish to transfer and click "Next"

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

#### 2.3 Enter the OTP then press "Generate"

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

#### 2.4 Proceed to step 3. Once approved in step 3, you should see this screen

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


# Old machine: activate from the command line

{% hint style="info" %}
Make sure to replace the appropriate values:\
`<REPLACE_client>` to your client atSign\
`<client_device_name>` with the device name from step 2
{% endhint %}

### Step 1) Generate an OTP (one time pin code)

```
~/.local/bin/at_activate otp -a @<REPLACE_client>
```

### Step 3) Approve the request

```
~/.local/bin/at_activate approve -a @<REPLACE_client> \
  --arx noports \
  --drx <client_device_name>
```


# Old machine: activate from the Windows installer

### Step 1) Generate an OTP (one time pin code)

#### 1.1 Open the Windows installer program and click "Manage Keys"

<figure><img src="/files/4KE0h9rQ1nwhpNB3EB1q" alt=""><figcaption></figcaption></figure>

#### 1.2 Enter the atSign you wish to manage and click "Next"

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

#### 1.3 Click "New OTP"

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

#### 1.4 Wait a few seconds for the OTP to appear then proceed to step 2 on the new machine

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

### Step 3) Approve the request

{% hint style="info" %}
If you aren't already on the "Manage Keys" screen follow steps 1.1 and 1.2 above.
{% endhint %}

#### 3.1 Once step 2 is complete press refresh and the new request will appear

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

#### 3.2 Approve or Deny the request

* If the request looks incorrect, then press "Deny" to deny it, and start the process again.
* If the request looks correct, then press "Approve" to approve it.

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

#### 3.3 Once the request is approved, it should disappear from the installer, the new machine's enrollment should complete in a few seconds

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


# How to name a device

Each device Atsign can be used for multiple devices and so each device needs a unique name.

### Device Name Format

The device name has the following constraints.

* May contain only the following characters:
  * `a-z` (lowercase letters)
  * `0-9` (numbers)
  * `_` (underscore)
  * `-` (dash)
* Maximum of 36 characters.
* Must start with a letter.

### Examples

```
my_host
canary02
oci_mail_0001
dc_001_row_009_rack_0067_ru_014
fa4969ca-9714-42a7-8edd-8d15158ce641
```

### Nerdy Stuff

#### The regular expression (regex)

```
[a-z][a-z0-9_-]{0,35}
```

#### Fun fact!

Originally we only supported alphanumeric snakecase up to 15 characters, but we loosened the constraints to support uuid v4.


# How to generate SSH keys

Using ssh-keygen

SSH uses keys to authenticate as well as having a fallback of using passwords, but using keys is easier and more secure than "mypassword!". If you already are a seasoned user of SSH then you might have keys already, but if not, then on the client machine you can create a key pair using ssh-keygen.

Example ssh-keygen command to create SSH Key Pair

```
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519
```


# Why activate the device Atsign on the client?

When you activate an Atsign, you are doing a handful of steps to prepare the Atsign for use. One of these steps is cutting a unique set of cryptographic keys.

The first time you activate, this set of keys that gets generated is a set of management keys. These keys have full permissions to your atServer, the personalized service which powers your Atsign.

We recommend cutting the management keys on the client for a few reasons:

1. It's extremely important that you don't lose these keys:
   1. They are less likely to get lost on your client machine than on your device.
   2. If a device is stolen you still have your management keys to recover from the theft.
2. For each device we can issue it's own set of cryptographic keys which has a few perks:
   1. This allows us to limit the permissions of those keys to the bare minimum required for NoPorts.
   2. If a device gets compromised, we can safely revoke the set of cryptographic keys associated with that device, without affecting the other devices using the same Atsign.


# The NoPorts Philosophy

### The Guiding Principle

At its heart, NoPorts has one guiding principle behind it:

> No ports should ever be open where there is any data of value.

#### What NoPorts Offers

Simply put, NoPorts improves network security while simplifying its management.

#### How It's Achieved

With NoPorts the paradigm shifts from "things are open, I need to close them" to "things are closed, I need to open them securely". (i.e. closed & secure by default)

#### Why This Matters

NoPorts allows you to stop the impossible task of actively managing everything, instead you only need to manage the things you actually use.


# NoPorts Desktop Application

A streamlined application for managing remote connections.

The NoPorts desktop application streamlines remote connection management by providing a structured interface for configuring remote connections.

The NoPorts Desktop application is available for download on both [Windows](https://apps.microsoft.com/detail/9n69scrrgv6r) and [MacOS](https://apps.apple.com/ca/app/noports-desktop/id6737338881).

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


# NoPorts Policy Service

A flexible suite of policy management tools. Use a standalone database to store and manage policies using our administration interface, or integrate it with your existing policy database or service.

<figure><img src="/files/ZwTFeDI80xsZxVBnmKjg" alt=""><figcaption><p>High level overview of the NoPorts architecture</p></figcaption></figure>

Learn how to install it at [Policy Service Installation](/installation/policy-service-installation).

The NoPorts Policy Service is currently in alpha status. [Schedule a call](https://calendly.com/noports/installation-help) with one of our engineers to become an alpha tester.


# Frequently Asked Questions

Common questions about NoPorts

### How NoPorts Works

<details>

<summary>How is NoPorts different from Tailscale and Ngrok?</summary>

Everything is in your control. There are no Web Interfaces or centralized control by us, as we never want to be an attack surface for your infrastructure. NoPorts does not connect "networks," but provides on demand encrypted TCP connectivity to existing SSH daemons.

NoPorts is focused on providing end-to-end encrypted and authenticated access to a remote ssh daemon, bound to localhost.

NoPorts does not require any open (listening) ports on external interfaces, so there is no network attack surface on devices using NoPorts.

NoPorts provide relays like Ngrok, but connections are authenticated then connected. Once connected, the connection is encrypted with ephemeral (AES256) keys that the relay never has or needs.

NoPorts abstracts away the TCP/IP layer, so whilst IP address on the client or device may change, the command you use never does.

</details>

<details>

<summary>Why is additional encryption needed when SSH provides its own encryption?</summary>

Additional encryption protects the request and rendezvous information (on the relay) that is sent from the client device to the remote device’s atServer and ultimately to the client. Without encryption, this information could be intercepted, and a bad actor could meet the client device at the relay This is precisely how the <https://terrapin-attack.com/> works. Using NoPorts mitigates any man-in-the-middle attacks like Terrapin.

</details>

<details>

<summary>Is sshnp a reverse SSH tunnel?</summary>

sshnp is similar to a reverse tunnel in that it has the remote device start an outbound SSH session. What makes sshnp better than a reverse SSH tunnel is that you don’t need access to the device to initiate it. This means you don’t need to leave open ports when not in use (i.e. there are no network attack surfaces).

</details>

<details>

<summary>The TCP layer is not taken out in your architecture. Does your protocol run over and above it?</summary>

Yes. NoPorts uses the atProtocol which runs on TCP. In order for NoPorts to reach the device, the device must have an IP address. However, it does not need to be a static IP address, and NoPorts doesn't even need to know what the IP address is. So, even though it runs over TCP/IP, it does away with all the pain of finding and managing IP addresses.

</details>

### **Relay Service and Network Behavior**

<details>

<summary>Is the relay necessary?</summary>

The relay ensures that connections from client and server are always outbound, removing the need for listening ports, firewall rules, and network attack surfaces on devices.

NoPorts uses TCP sockets to communicate. "Hole punching" can work sometimes, but we decided to never do that. Using the relay, you know that NoPorts will always work and is friendly to both network admins and firewall rules.

For most customers our relay service is robust and placed regionally. The relay code is open and the binaries are part of the distribution, so you can place your own relay where it makes sense for your network.

</details>

<details>

<summary>If a bad actor takes down the relay, does the tool fail?</summary>

In the unlikely event that a bad actor takes down an relay, the tool will indeed fail. Fortunately, we run multiple relays, so if one is down or unavailable, you can easily switch to another.

</details>

<details>

<summary>Since the device and the client need to connect out to the relays, do I need to open ports on my firewall for them to connect out to the relay?</summary>

You do not need to open any inbound ports to connect out to the relay. However, the outbound traffic to the relay server does need to be open. Outbound access is, in most situations, automatically allowed so things just work. If you work in a location where outbound access is also controlled, then please contact us as we have options for for your IT team.

</details>

<details>

<summary>Who pays the ingress &#x26; egress costs to the relay?</summary>

These costs are included in the NoPorts subscription.

</details>

### Security and Access Control

<details>

<summary>How do I close port 22?</summary>

To close port 22, edit `/etc/ssh/sshd_config` remove any lines containing `ListenAddress` and then add `ListenAddress localhost` on a new line. Then restart your sshd service (this varies by operating system, a quick web search will help you figure how to do it for your device).

{% hint style="info" %}
Additional notes for advanced users
{% endhint %}

You may also replace `localhost` with the ipv4 (`127.0.0.1`) or ipv6 (`::1`) loopback address. However beware! All NoPorts tech defaults to doing lookups for localhost. If your system has both configured in `/etc/hosts` then NoPorts may resolve to the wrong address for which sshd is configured for.

</details>

<details>

<summary>What Security Group rules are needed for CSP (Cloud Service Provider) deployments, for both data and control plane traffic?</summary>

Security groups only need to allow outbound internet access.

</details>

<details>

<summary>What npt or iptables rules are needed for non-CSP deployments, for both data and control plane traffic?</summary>

Only outbound internet access via NAT/CGNAT is required.

</details>

<details>

<summary>If the control plane is unreachable, what fallback or break-glass contingency is available?</summary>

Break-glass options include console access or, if you trust the local network, leaving sshd listening on an internal interface. We’ve designed the system to minimize lockout risks. In production use, lockouts have been extremely rare, but when they happen it’s normally inadvertent blocking of outbound TCP connections being the issue.

</details>

<details>

<summary>Why do I see man-in-the-middle warnings when connecting to my NoPorts devices?</summary>

These warnings occur because each time you SSH into a machine, you’re connecting to localhost on a random port number. If you later use the same localhost and port number to connect to a different machine, this may be interpreted as a potential security risk, triggering a man-in-the-middle warning—even if the system is not compromised.

</details>

<details>

<summary>How can I prevent these warnings?</summary>

You can address this issue with one of two approaches:

1. Assign a Fixed Local Port – By default, each session is assigned a random local port. To prevent mismatches, you can manually specify a static local port for each machine using the -l \<port number> option.
2. Trust NoPorts for Keys and Adjust SSH Config – You can update your SSH configuration (\~/.ssh/config) to disable strict host key checking for localhost sessions:

```
Host 127.0.0.1
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    IdentityFile ~/.ssh/GitHub_rsa
    LogLevel QUIET
```

</details>

<details>

<summary>Why do I see extra entries in my ~/.ssh/authorized_keys file, and can I remove them?</summary>

You may notice additional entries appearing in your \~/.ssh/authorized\_keys file. These entries were originally included for backward compatibility and were used for ephemeral SSH keys in reverse SSH. In most cases, they are not actively used and may persist even after a session ends.

You can safely delete these extra entries, as they do not impact functionality unless specifically needed. We will be removing them from the code soon, but in the meantime, any leftover entries can be manually cleaned up without affecting your setup.

</details>

### **Component Deployment and Operation**

<details>

<summary>How are the NoPorts Tunnel, NoPorts daemon, and the NoPorts TCP relay service deployed?</summary>

Deployment is done using curl and tar directly from our GitHub repo. You can do this manually or using a provided bash script that does the hard work for you. Refer to the [Installation](https://docs.noports.com/installation) documentation for detailed instructions.

</details>

<details>

<summary>How are these components started and managed?</summary>

Systemd is the default service manager. Alternatives like cron and TMUX also work, but Systemd is recommended for standard deployments.

</details>

<details>

<summary>How are these components patched or updated?</summary>

To update, re-run the installation script. You can verify the currently deployed versions using the --list-devices option with with the sshnp command.

</details>

<details>

<summary>Do these components require root privileges to run?</summary>

No, these components must not run as root.

</details>

<details>

<summary>How does SELinux affect these components?</summary>

SELinux does not affect them, as these components operate in user space. That said, they require permission to open ports on the localhost interface and establish outbound TCP connections.

</details>

<details>

<summary>During the Startup Phase, the relay and npt handshake with their respective Atsign services. Does npt on the client also handshake with its Atsign service once at boot, or on each SSH initiation?</summary>

The sshnpd maintains a persistent connection to its atServer. Other interactions are event-driven.

</details>

<details>

<summary>Does the bridging between ingress/egress ports within np services require the same NIC, or can it occur across different NICs?</summary>

This involves standard TCP connections, so normal connectivity rules apply. No layer 2 bridging is performed; only TCP connections are established in user space.

</details>

### **Scripting and Remote Command Execution**

<details>

<summary>Does NoPorts support scripting and remote command execution?</summary>

Yes, NoPorts allows for scripting and remote command execution, similar to standard SSH. While the -x option in sshnp does not directly execute commands on the remote machine, you can still achieve this using the following format:

`$(sshnp -f @bob -t @ssh_1 -r @rv_am -d iot_device01 -x) hostname`

</details>

<details>

<summary>What are the requirements for executing remote commands via NoPorts?</summary>

For this method to work, you need a clean login, meaning SSH keys must be properly configured and in place for sshnp. Ensuring your SSH setup supports key-based authentication will allow commands to run on the remote machine.

</details>

### **Usage and Protocol Support**

<details>

<summary>So, you can SSH without any open ports... what about RDP?</summary>

You can use NoPorts Tunnel for RDP. [This guide](/use-cases/rdp) demonstrates how.

</details>

### Did we miss something?

If you have a question that needs answering, please do one of the following:

* Create a new [GitHub issue](https://github.com/atsign-foundation/noports/issues/new/choose)
* Join [our discord](https://discord.atsign.com) and post to our `📑｜forum` channel
* [Contact support via email](mailto:support@noports.com)


# How It Works

NoPorts connection establishment and architecture

**What is NoPorts?** NoPorts is a zero trust security tool that uses Atsign Platform to initiate connections without opening ports on either of your devices. It creates a privacy-first environment, and completely removes network attack surfaces. NoPorts is already being used in the field to do things like [replace VPNs and firewalls](https://www.noports.com/use-cases/vpn-replacement), and enable [zero trust remote access](https://www.noports.com/use-cases/remote-access).

**How does this technology work?** In the simplest explanation, NoPorts utilizes Atsign Platform and Atsigns to create an encrypted connection between devices over TCP/IP. An intriguing part of this technology is that TCP ports are not open on the endpoints, and the connection is completely invisible to prying eyes with no entry-point for cybersecurity attacks. Any device or application sitting behind NoPorts has no open ports, no static IP address required, and cannot be digitally hacked! This a huge leap forward in cybersecurity as there are no other solutions that can provide this level of system security. Pretty awesome right? We think so too!\
\
To further our understanding of how zero trust security is established via NoPorts, let’s briefly discuss the function of an Atsign. Then, we can explore the connectivity process with easy to follow diagrams. An Atsign is a resolvable address assigned to a device, person, an entire organization, or anything you like. For example, @alice could be an Atsign for a person named Alice. An Atsign is used to securely exchange information without any chance of surveillance, impersonation, or theft.

Now, let’s look at a diagram of a completed Atsign/NoPorts connection between two devices.

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

In the diagram, you can see two devices connected with Atsign (@PointA and @PointB). The connection is established without having any open external ports on the client or remote machine and any TCP application can be setup to utilize a NoPorts connection. Because all ports are closed, the Atsign encrypted tunnel is set up with outbound requests only which are sent to an atServer.

Now, let’s discuss what an atServer is and how it functions as part of the overall Atsign Platform topology. An atServer is responsible for managing identity and maintaining the key-value data store for each Atsign. It performs cryptographic identity validation to ensure that each entity is who they claim to be, supporting secure interactions. It serves as a secure repository and only holds data that is either explicitly made public or data that is encrypted. The atServers cannot decrypt or view any encrypted data as they do not hold the keys to decrypt it. Each Atsign utilizes a separate atServer, and the atServers complete the negotiation for setting up the connection between the endpoints.

Since we now have a basic understanding of Atsigns and atServers we can take a look at a more comprehensive diagram and discuss further details about Atsign Platform.

<figure><img src="/files/Kbrr1JNDixbpTenCEvqD" alt=""><figcaption><p>Atsign Platform</p></figcaption></figure>

**Connection Establishment**

So, how exactly does a NoPorts connection get established and what are the steps? Let's look at a summary overview of each step in a NoPorts connection:

1. NoPorts Client @pointA sends a request to NoPorts Relay service @relay to ask for an IP address and a pair of ports to rendezvous with Remote Machine @pointB.
2. NoPorts Relay receives the request, allocates a pair of ports on the host it is running on, responds with its IP address and the pair of ports.
3. Client receives response from Relay
4. Client sends request to the Remote Machine to connect which includes session information, the client’s intent (such as destination TCP port 3389 on localhost), and the generated public key from an ephemeral asymmetric key-pair.
5. NoPorts Daemon on Remote Machine sends request to NoPorts Policy service @policy to determine whether or not @pointA is permitted to connect to @pointB on the specified localhost port.
6. Policy service looks up information accordingly and sends response back to the daemon on Remote Machine.
   1. If request is not allowed, the daemon will not respond to the client, or send a not permitted response.
   2. If request is allowed, the daemon generates a symmetric encryption key and a socket connection to the Relay IP address and port 2. Response is sent to the Client for ‘session started’ and includes the symmetric encryption key which is encrypted with the ephemeral public key which was previously sent by the Client.
7. NoPorts daemon on Remote Machine sends response to Client as ‘session started’.
8. Client receives response and creates a socket to the Relay IP address and port 1.
9. The Relay verifies the authentication strings and joins the authenticated sockets from the Client and Remote Machine.
10. NoPorts connection established.

And that's it! At this point, the real client application (e.g. RDP) can connect to a local port on the Client to be sent over the NoPorts connection for secure remote access to the Remote Machine.




---

[Next Page](/llms-full.txt/1)

