Only this pageAll pages
Powered by GitBook
1 of 77

NoPorts

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Product Information

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Related Pages

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.

Getting Started Overview

1

Sign up for NoPorts

Sign up for a NoPorts subscription or free trial, which includes 2 atSigns.

2

Step 1. Sign up for NoPorts

You'll need to head over to to sign up for a NoPorts subscription or free trial.

During sign up, you will receive your atSigns. Ensure that you make note of them for reference during installation.

Steps 2 and 3. Install NoPorts

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.

Step 4. Use NoPorts

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

We recommend reviewing the before beginning your installation.

Install the NoPorts Client

Download and install the NoPorts Client on the machine you are connecting from.

3

Install the NoPorts Daemon

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

4

Use NoPorts

Use NoPorts or explore the use cases available below.

my.noports.com/no-ports-plans
Installation
resources page
Cover

MCP

Cover

SSH

Cover

SFTP

Cover

RDP

Cover

Web Server

Cover

SMB

Cover

Be your own VPN

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

NoPorts command line suite

Get Started

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

Usage

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

Need Help?

via Email

Send us an email: [email protected]

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

via Discord

Join our Discord for technical support. Our team and community are here to help!

Getting Started
Usage
Frequently Asked Questions

Installation

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

Getting Started Overview

1

Sign up for NoPorts

Sign up for a NoPorts subscription or free trial, which includes 2 atSigns.

2

Install the NoPorts Client

Download and install the NoPorts Client on the machine you are connecting from.

3

Install the NoPorts Daemon

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

4

Use NoPorts

Use NoPorts or explore the use cases available .

Sign up for a NoPorts subscription or free trial

Head over to to sign up for a subscription or free trial.

During registration, you will receive your client and device atSigns. Ensure that you make note of them for future reference.

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.

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.

Connecting from macOS
Connecting from Linux
Connecting from Windows

Other Installation Options

Use NoPorts

Start by exploring the available use cases, such as , , , , , and . We also provide in-depth usage information here.

Need Help?

via Email

Send us an email:

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

via Discord

for technical support. Our team and community are here to help!

Manual Installation Guides

These guides also use shell scripts for installation, but they require manual invocation if you want a truly manual process.

Overview

NoPorts offers flexible installation methods. While shell scripts streamline the setup process, this guide provides step-by-step instructions for those who prefer complete control over each stage of the installation.

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.

NoPorts Policy Service

Centralizes access controls, allowing administrators to define and enforce security policies for NoPorts connections.

NoPorts Desktop Application

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)

NoPorts Relay

Acts as an intermediary to facilitate secure connection handshakes acting as the open network surface, so that your devices remain secure.

NoPorts Tunnel Client (npt)

Establishes secure, encrypted tunnels for remote access to any application.

NoPorts SSH Client (sshnp)

Enables remote SSH access without exposing ports by leveraging NoPorts' outbound connectivity.

NoPorts Daemon (sshnpd)

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.

Device Installation
Client Installation
NoPorts Client Upgrade
NoPorts Daemon Upgrade
here
my.noports.com/no-ports-plans
Quick Start from macOS or Windows
MCP
SSH
RDP
SFTP
Web Server
SMB
Usage
Frequently Asked Questions
[email protected]
Join our Discord

to macOS

to Linux

to Windows

to macOS

to Linux

to Windows

to macOS

to Linux

to Windows

Cover

Cloud Installation

Cover

OpenWrt Installation

Cover

Manual Installation

Cover

Custom OS Installation

Cover

Installs at Scale

Cover

Upgrading NoPorts

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")

Custom OS/Device Installs

Here you'll find instructions for custom operating systems or device installs.

IPFire

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.

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.

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.

How to activate an atSignReuse your client atSign on another machineHow to name a deviceHow to generate SSH keysWhy activate the device atSign on the client?

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

Use Cases

NoPorts has endless use cases. We've compiled a list of the most frequently used ones:

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 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:

The first line of output should contain the version information:

The first line of output should contain the version information:

The first line of output should contain the version information:

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:

First, use this command to locate the sshnp binary:

The command should output the location of the binary which is on the PATH. Try deleting this binary then rerunning the installer.

First, use this command to locate the sshnp binary:

The command should output the location of the binary which is on the PATH. Try deleting this binary then rerunning the installer.

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.

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:

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:

Automated Installation on Oracle Cloud Infrastructure (OCI)

How to deploy NoPorts on Oracle Cloud Infrastructure using a cloud-init script

When starting a VM on OCI first click the Show advanced options button having selected the usual options above that.

Then (in the Management tab) select Paste cloud-init script

And paste your customised script into the Cloud-init script box:

#!/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

The VM is now ready for Create

After a few minutes the APKAM key can be approved:

If the VM isn't quite ready you'll see:

Waiting a little longer and retrying should produce a successful approval:

The VM is now ready for connection with the NoPorts client.

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.

Command Line

The command should look like:

npt -f @<client> -t @<device> -d <device name> -r @<relay> -p 22 -l 2222

Example:

Now you can connect to localhost:2222 in your favorite SFTP client.

To learn more about NPT

Desktop Application

When using the NoPorts desktop application, your connection profile should look something like this:

Standalone Binaries

Follow these two steps to install the NoPorts daemon so you can install your own background service.

Step 1. Run the installer

  1. Change directories into the unpacked download:

cd sshnp
  1. Then run the installer:

This will install the binaries to ~/.local/bin. Instead, if you'd like to install the binaries to /usr/local/bin, run the installer as root:

  1. Change directories into the unpacked download:

  1. Then run the installer:

This will install the binaries to ~/.local/bin. Instead, if you'd like to install the binaries to /usr/local/bin, run the installer as root:

Step 2. Set up the installer

You are on your own for setting up the background service to start sshnpd. See our other options if you need help setting this up.

Step 3. All Done!

You can now proceed to , or if you've already done that, check out our .

Windows to Windows

How to install NoPorts when connecting from Windows to Windows

NoPorts version <5.13.0 should follow old instructions located here: Windows to Windows Legacy

Step 1 to Step 4

These initial steps set up the machine initiating the connection.

Step 5 to Step 7

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

Step 8 and Step 9

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

On the machine you are connecting from

Step 8: Approve the device atSign authorization request

Run the following command:

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.

High level overview of the NoPorts architecture

Learn how to install it at Policy Service Installation.

The NoPorts Policy Service is currently in alpha status. Schedule a call with one of our engineers to become an alpha tester.

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 and MacOS.

Connecting from macOS

Overview

Installation

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

Connecting from macOS

Windows to macOS

How to install NoPorts when connecting from Windows to macOS

Step 1 to Step 4

These initial steps set up the machine initiating the connection.

Step 5 and Step 6

Client Additional Configuration

NoPorts client `sshnp` additional configuration

Additional Options

-k, --key-file

Specify the .atKeys

Automated Installation on Microsoft Azure

How to deploy NoPorts on Azure using a cloud-init script

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:

It should look like this:

Once that's complete the VM is ready for Review + create

SSH

In this guide, we demonstrate how to use SSH NoPorts to SSH to a remote machine.

Command Line

The command should look like:

Example:

Auto SSH key upload

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:3001 on your local machine

In this example, we assume the OpenAPI-based MCP Server is listening on port 3000. These instructions apply to other MCP server types as well, not just OpenAPI-based deployments.

Command Line

The command should look like:

Automated Installation on Google Cloud Platform (GCP)

How to deploy NoPorts on Google Cloud Platform using a cloud-init script

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:

Then scroll down and expand Management:

In the Automation section paste in your customised startup script like:

NB this script is creating a new user noports

Integrations

NoPorts integrates seamlessly with Linux and macOS SSH configurations, allowing secure outbound connections via OpenSSH config.

For Windows, NoPorts works with PuTTY, enabling efficient management of multiple SSH sessions without exposed ports.

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:

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.

Command Line

The command should look like:

Example:

NOTE Make sure the sshnpd daemon is allowing port 445 to the SMB file server see Basic Usage for details.

Cloud Installation Guides

How to install NoPorts as part of creating a new VM

This is a generic cloud-init guide, we also have some below

The NoPorts daemon can be installed on a Linux cloud virtual machine (VM) using a cloud-init script of the form:

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.:

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

Automated Installation on Amazon Web Services (AWS)

How to deploy NoPorts on Amazon Web Services using a cloud-init script

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:

Scroll down to the User data - optional box and paste in your customised YAML e.g.:

Which will end up looking something like this:

The VM config should now be ready for Launch instance

Connecting from Windows

Overview

Installation

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

Sequence Diagram

The following sequence diagram covers the "Happy path" for the startup of a NoPorts session. When a step fails with an error, then the client halts the process, all existing connections automatically timeout and shutdown after a short period of time.

To view this diagram in more detail, click Export as PDF in the top right corner of the page, then zoom in using the built-in browser zoom functionality.

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.

Command Line

The command should look like:

Example:

Now you can connect to localhost:33899 in your favorite RDP client.

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.

Web Server

This guide covers usage of NoPorts with webpages or APIs.

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.

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)

Connecting from Linux

Overview

Installation

Select the operating system running on the machine you're connecting to

npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 22 -l 2222
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.

OpenSSH Config
PuTTY config

MCP

SSH

SFTP

RDP

Web Server

SMB

Be your own VPN

Cover
Cover
Cover
Cover
Cover
Cover
Cover

to macOS

to Linux

to Windows

installing your client
usage guide
./install.sh sshnpd
sudo ./install.sh sshnpd
cd sshnp
./install.sh sshnpd
sudo ./install.sh sshnpd
sshnp
Version : x.x.x
sshnp
command -v sshnp
rm "$(command -v sshnp)"
command -v sshnp
rm "$(command -v sshnp)"
sshnp.exe
Version : x.x.x
Version : x.x.x

22

Profile Name

My SFTP Connection

Device atSign

@alice_device

Device Name

my_server

Relay

@rv_am

Local Port

2222

Local Host

localhost

Remote Host

npt Usage

Remote Port

SMB
Be your own VPN

Usage of NoPorts

If your primary use case involves more than just SSH, start here, or check out some of our use cases below.

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.

Web Server
SSH
RDP
SFTP
MCP
npt Usage
sshnp Usage
OpenSSH Config

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

a-z (lowercase letters)

  • 0-9 (numbers)

  • _ (underscore)

  • - (dash)

  • Maximum of 36 characters.

  • Must start with a letter.

  • Examples

    Nerdy Stuff

    The regular expression (regex)

    Fun fact!

    Originally we only supported alphanumeric snakecase up to 15 characters, but we loosened the constraints to support uuid v4.

    :

    Cloud Specific Guides

    cloud specific guides
    Automated Installation on Amazon Web Services (AWS)
    Automated Installation on Google Cloud Platform (GCP)
    Automated Installation on Microsoft Azure
    Automated Installation on Oracle Cloud Infrastructure (OCI)
    ./sshnpd -a @<YOUR DEVICE ATSIGN> -p @<YOUR POLICY ATSIGN> --device-group <DEVICE GROUP>
    my_host
    canary02
    oci_mail_0001
    dc_001_row_009_rack_0067_ru_014
    fa4969ca-9714-42a7-8edd-8d15158ce641
    [a-z][a-z0-9_-]{0,35}
    #!/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
    #!/bin/bash
    # Modify these lines to set the installation specific variables
    ATCLIENT="@democlient"
    ATDEVICE="@demodevice"
    DEVNAME="cloudvm1"
    OTP="643791"
    USER="ubuntu"
    at_activate approve -a @democlient --arx noports --drx cloudvm1

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    @<REPLACE_NAME> with the device name from Step 6.

    Step 9: Use NoPorts!

    That's it. You can start using NoPorts or explore some of the documented use cases, including MCP, SSH, RDP, SFTP, Web Server, and SMB.

    at_activate.exe approve -a "@<REPLACE>_np" --arx NoPorts --drx <REPLACE_NAME>
    After setting up the machine you're connecting from, you'll configure the machine you're connecting to.
    On the machine you are connecting to

    Step 5: Download and run the Installer

    Download the installer from Github by running the following command:

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

    To check if the installation downloaded correctly:

    stat universal.sh

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

    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.

    Step 6: Initiate atSign authorization request

    Run the following command to make an authorization request.

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    <PASSCODE> with the passcode generated in Step 4,

    @<REPLACE>_np_key

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

    Step 7 and Step 8

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

    then if all looks well hit
    Create

    After a few minutes the APKAM key can be approved:

    If the VM isn't quite ready you'll see:

    Waiting a little longer and retrying should produce a successful approval:

    The VM is now ready for connection with the NoPorts client.

    #!/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

    If you don't have an ssh key uploaded on the remote machine, you can upload one by adding -s to the command:

    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.

    To learn more about SSHNP

    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

    sshnp Usage
    Example:

    Now you can interact with your OpenAPI-based MCP server by connecting to http://localhost:3001 .

    To learn more about NPT

    Desktop Application

    When using the NoPorts desktop application, your connection profile should look something like this:

    Profile Name

    My MCP Connection

    Device atSign

    @alice_device

    Device Name

    my_server

    Relay

    @rv_am

    Local Port

    3001

    Local Host

    localhost

    Remote Host

    npt Usage
    to deal with the fact that GCP images don't have default usernames.

    Once filled, the box should look something like:

    The VM is now ready for Create

    After a few minutes the APKAM key can be approved:

    If the VM isn't quite ready you'll see:

    Waiting a little longer and retrying should produce a successful approval:

    The VM is now ready for connection with the NoPorts client.

    Now you can mount the SMB share locally using the finder app ( Go->Connect to server) on MacOs

    Once mounted, you can use the file share as normal. As you dismount the file share, the NPT command will disconnect.

    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.

    To learn more about NPT

    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

    npt Usage
    After a few minutes the APKAM key can be approved:

    If the VM isn't quite ready you'll see:

    Waiting a little longer and retrying should produce a successful approval:

    The VM is now ready for connection with the NoPorts client.

    at_activate approve -a @demodevice --arx noports --drx cloudvm1

    Connecting from Windows

    To learn more about NPT

    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

    npt Usage

    The command should look like:

    Example:

    Now you can access localhost:80 in your browser to access the web server locally.

    To learn more about NPT

    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

    npt Usage
    for installation instructions.

    Connecting from Linux

    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)

    On the machine you are connecting to

    Step 6: Download and run the Installer

    Download the installer from GitHub by running the following command:

    To check if the installation downloaded correctly:

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

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

    Step 8 to Step 11

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

    On the machine you are connecting from

    Step 8: Approve the atSign authorization request

    1. Click on

    Linux to Windows

    How to install NoPorts when connecting from Linux to Windows

    Step 1 to Step 4

    These initial steps set up the machine initiating the connection.

    On the machine you are connecting from

    In this installation guide, @example01_np will represent the client atSign, while @example02_np will represent the device atSign.

    Step 1: Download and run the Installer

    Download the installer from GitHub by running the following command:

    To check if the installation downloaded correctly:

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

    You may be asked to enter your password if your machine requires sudo privileges.

    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.

    Step 2: Activate your client atSign (@example01_np)

    If you've already activated your client atSign on another device, this step will not work. Instead, follow this guide:

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

    Replace @<REPLACE>_np with your client atSign.

    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.

    Step 3: Activate your device atSign (@example02_np)

    Run the same command, but for your device atSign.

    Replace @<REPLACE>_np with your device atSign.

    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.

    Step 4: 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.

    Replace @<REPLACE>_np with your device atSign.

    Step 5 to Step 7

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

    Step 8 and Step 9

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

    On the machine you are connecting from

    Step 8: Approve the atSign authorization request

    Run the following command:

    How to activate an atSign

    Steps for client and device atSigns

    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.

    If you don't own a pair of atSigns/addresses, please visit my.noports.com before continuing.

    Example client atSign

    Example device atSign

    Activate your atSigns

    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.

    Activate the client atSign

    (1) Run the at_activate command for the client atSign

    (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).

    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 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

    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).

    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 in the ~/.atsign/keys/ directory with a filename that includes the atSign.

    Windows to Linux

    How to install NoPorts when connecting from Windows to Linux

    Step 1 to Step 4

    These initial steps set up the machine initiating the connection.

    Step 5 and Step 6

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

    On the machine you are connecting to

    Step 5: Download and run the Installer

    Download the installer from GitHub by running the following command:

    To check if the installation downloaded correctly:

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

    Step 7 and Step 8

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

    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:

    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.

    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.

    For people connecting from Linux please follow the .

    Step 1: Sign up for a NoPorts free trial

    sshnpd configuration

    TL;DR

    Replace the <??> with your specific atSign details

    npt Usage

    Quick Start

    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.

    How It Works

    NoPorts connection establishment and architecture

    What is NoPorts? NoPorts is a zero trust security tool that uses Atsign's atPlatform 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 , and enable .

    How does this technology work? In the simplest explanation, NoPorts utilizes the atPlatform 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.

    In the diagram, you can see two devices connected with atSigns (@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.

    macOS to Windows

    How to install NoPorts when connecting from macOS to Windows

    Step 1 to Step 4

    These initial steps set up the machine initiating the connection.

    On the machine you are connecting from
    at_activate approve -a @demodevice --arx noports --drx cloudvm1
    Found 0 matching enrollment records
    No matching enrollment(s) found
    Found 1 matching enrollment records
    Approving enrollmentId 0bd3613d-d3e2-45b3-b175-8cab06c9bad0
    Server response: AtEnrollmentResponse{enrollmentId: 0bd3613d-d3e2-45b3-b175-8cab06c9bad0, enrollStatus: EnrollmentStatus.approved}
    sshnp -f @<client> -t @<device> -d <device name> -r @<relay> -i <your ssh key>
    sshnp -f @alice_client -t @alice_device -d my_server -r @rv_am -i ~/.ssh/id_ed25519
    sshnp -f @alice_client -t @alice_device -d my_server -r @rv_am -i ~/.ssh/id_ed25519 -s
    npt -f @<client> -t @<device> -d <device name> -r @<relay> -p 3000 -l 3001
    npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 3000 -l 3001
    #!/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}
    at_activate approve -a @demodevice --arx noports --drx cloudvm1
    Found 0 matching enrollment records
    No matching enrollment(s) found
    Found 1 matching enrollment records
    Approving enrollmentId 0bd3613d-d3e2-45b3-b175-8cab06c9bad0
    Server response: AtEnrollmentResponse{enrollmentId: 0bd3613d-d3e2-45b3-b175-8cab06c9bad0, enrollStatus: EnrollmentStatus.approved}
    npt -f @<client> -t @<device> -d <device name> -r @<relay> -p 445 \
    -h 192.168.1.90 -l 9000
    npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 445 \
    -h 192.168.1.90 -l 9000
    #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
    Found 0 matching enrollment records
    No matching enrollment(s) found
    Found 1 matching enrollment records
    Approving enrollmentId 0bd3613d-d3e2-45b3-b175-8cab06c9bad0
    Server response: AtEnrollmentResponse{enrollmentId: 0bd3613d-d3e2-45b3-b175-8cab06c9bad0, enrollStatus: EnrollmentStatus.approved}
    npt -f @<client> -t @<device> -d <device name> -r @<relay> -p 3389 -l 33389
    npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 3389 -l 33389
    npt -f @<client> -t @<device> -d <device name> -r @<relay> -p 8080 -l 80
    npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 8080 -l 80
    at_activate approve -a @demodevice --arx noports --drx cloudvm1
    Found 0 matching enrollment records
    No matching enrollment(s) found
    Found 1 matching enrollment records
    Approving enrollmentId 0bd3613d-d3e2-45b3-b175-8cab06c9bad0
    Server response: AtEnrollmentResponse{enrollmentId: 0bd3613d-d3e2-45b3-b175-8cab06c9bad0, enrollStatus: EnrollmentStatus.approved}

    Remote Port

    22

    Remote Port

    3000

    Remote Port

    3389

    Remote Port

    8080

    to macOS

    to Linux

    to Windows

    to macOS

    to Linux

    to Windows

    Generate a new set of cryptographic keys

    Remote Port

    445

    NoPorts Desktop Usage

    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, 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:

    2a. -m, --manager, --managers

    This is the address of the client(s) that will be allowed to connect to the device. For example:

    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:

    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:

    Putting it all together

    An example of a complete command might look like this:

    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 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:

    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 atSigns, enabling/disabling verbose logging, and more.

    Sample override.conffile:

    Adding additional arguments is as simple as modifying the Environment=additional_args=""string found inside of override.conf .

    The example adds the --permit-open to the string of additional args which enables clients to access ports 22, 3389, and 2221 on localhost.

    Don't forget to update sshnpd by executing (may require sudo):

    Daemon Additional Configuration
    @sshnp_client
    @sshnp_device
    ~/.local/bin/at_activate -a @<REPLACE>_client
    ~/.local/bin/at_activate -a @<REPLACE>_device
    sshnpd -m @<_client> -a @<_device> -d <name> 
    sshnpd ... -a @alice_device ...
    sshnpd ... -m @alice_client ...
    sshnpd ... -p @alice_policy ...
    sshnpd ... -d my_device ...
    sshnpd -a @alice_device -m @alice_client -d my_server
    # 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=""
    # Any additional command line arguments for sshnpd
    Environment=additional_args="--permit-open \"localhost:22,localhost:3389,localhost:2221\""
    systemctl daemon-reload
    systemctl restart sshnpd.service
    with your
    device atSign
    ,

    <DEVICE_NAME> with the name of the machine you are on

    Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    ~/.local/bin/at_activate enroll -a @<REPLACE>_np \
      -s <PASSCODE> \
      -p noports \
      -k ~/.atsign/keys/@<REPLACE>_np_key.atKeys \
      -d <DEVICE_NAME> \
      -n "sshnp:rw,sshrvd:rw"
    On the machine you are connecting from

    In this installation guide, @example01_np will represent the client atSign, while @example02_np will represent the device atSign.

    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.

    Step 7: Initiate atSign authorization request

    Run the following command to make an authorization request:

    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

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

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

  • Step 9: 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.

    Step 10: 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, SSH, RDP, SFTP, Web Server, and SMB.

    Step 11: 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.

    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
    stat universal.sh
    chmod u+x universal.sh
    ./universal.sh
    Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    ~/.local/bin/at_activate enroll -a @<REPLACE>_np \
      -s <PASSCODE> \
      -p noports \
      -k ~/.atsign/keys/@<REPLACE>_np_key.atKeys \
      -d <
    

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    @<REPLACE_NAME> with the device name from Step 5.

    Step 9: Use NoPorts!

    That's it. You can start using NoPorts or explore some of the documented use cases, including MCP, SSH, RDP, SFTP, Web Server, and SMB.

    Reuse your client atSign on another machine
    ~/.local/bin/at_activate -a @<REPLACE>_np
    ~/.local/bin/at_activate -a @<REPLACE>_np
    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
    stat universal.sh
    chmod u+x universal.sh
    ./universal.sh
    ~/.local/bin/at_activate otp -a @<REPLACE>_np
    ~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>
    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.

    Step 6: Initiate atSign authorization request

    Run the following command to make an authorization request:

    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

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

    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
    stat universal.sh
    chmod u+x universal.sh
    ./universal.sh
    Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    ~/.local/bin/at_activate enroll -a @<REPLACE>_np \
      -s <PASSCODE> \
      -p noports \
      -k ~/.atsign/keys/@<REPLACE>_np_key.atKeys \
      -d <
    
    On the machine you are connecting from

    In this installation guide, @example01_np will represent the client atSign, while @example02_np will represent the device atSign.

    Go to noports.com and sign up for a subscription or free trial

    Make note of your atSigns (e.g., @example01_np, @example02_np). You'll need them shortly.

    Step 2: Download the NoPorts desktop application

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

    Link to Apple Store

    Link to Windows Store

    For people connecting from Linux please follow the Linux Installation Guide.

    Step 3: Activate your client atSign (@example01_np)

    In this installation guide, @example01_np will represent the client atSign, while @example02_np will represent the device atSign.

    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.

    For Windows, if the app stalls at "Preparing for activation", verify that your CA certificates are up to date.

    Step 4: 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.

    1. Click on Save atKeys

    2. Select a memorable location on your machine and save your keys.

    Step 5: Establish a connection

    Step 5.1: Activate your device atSign (@example02_np)

    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.

    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.

    Step 5.2: 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 .

    1. Click on Save atKeys

    2. Select a memorable location on your machine and save your keys.

    Step 5.3: 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.

    Step 5.4: 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:

    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 tohttp://localhost:8080.

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

    Linux Installation Guide

    Options

    Option
    Required / Default
    Value Format
    Description

    -f

    required

    atSign

    The client atSign, a.k.a. the from atSign, since we are connecting from the client.

    -t

    required

    atSign

    The device atSign, a.k.a. the to atSign, since we are connecting to the device.

    -r

    required

    atSign

    Example

    Use Cases

    RDP
    SFTP
    Web Server

    Now, let’s discuss what an atServer is and how it functions as part of the overall atPlatform 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 the atPlatform.

    atPlatform

    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.

    replace VPNs and firewalls
    zero trust remote access

    In this installation guide, @example01_np will represent the client atSign, while @example02_np will represent the device atSign.

    Step 1: Download and run the Installer

    Download the installer from GitHub by running the following command:

    To check if the installation downloaded correctly:

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

    You may be asked to enter your password if your machine requires sudo privileges.

    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.

    Step 2: Activate your client atSign (@example01_np)

    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

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

    Replace @<REPLACE>_np with your client atSign.

    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.

    Step 3: Activate your device atSign (@example02_np)

    Run the same command, but for your device atSign.

    Replace @<REPLACE>_np with your device atSign.

    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.

    Step 4: 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.

    Replace @<REPLACE>_np with your device atSign.

    Step 5 to Step 7

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

    Step 8 and Step 9

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

    On the machine you are connecting from

    Step 8: Approve the atSign authorization request

    Run the following command:

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    @<REPLACE_NAME> with the device name from Step 5.

    Step 9: Use NoPorts!

    That's it. You can start using NoPorts or explore some of the documented use cases, including , , , , , and .

    ~/.local/bin/at_activate -a @<REPLACE>_np
    ~/.local/bin/at_activate -a @<REPLACE>_np
    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
    stat universal.sh
    chmod u+x universal.sh
    ./universal.sh
    ~/.local/bin/at_activate otp -a @<REPLACE>_np

    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)

    On the machine you are connecting to

    Step 6: Download and run the Installer

    Download the NoPorts msi installer . You can run the MSI inside the sshnp-windows zip.

    Ensure both Core Tools & Daemon Service are being installed.

    Step 9 to Step 12

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

    On the machine you are connecting from

    Step 8: Approve the atSign authorization request

    1. Click on

    sshnp Usage

    TL;DR

    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.

    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:

    -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:

    -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:

    -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

    Europe

    Asia-Pacific

    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:

    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:

    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:

    Then use the associated private key, as mentioned under :

    Putting it all together

    An example of a complete command might look like this:

    *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.

    Additional Configuration

    The rest of the configuration for sshnp is contained in a separate guide:

    Want to use RDP, SFTP or etc?

    The NoPorts Tunnel (NPT) can carry a wide variety of TCP based protocols such as , , and .

    Policy Service Installation

    This guide explains how to install and run the NoPorts Policy Service via the command line, and how to use it within the NoPorts desktop application. We recommend running the Policy Server in a Linux environment (virtual machine) for easier management.

    Prerequisites

    Before you begin the installation, please ensure the following steps are complete:

    1. Subscription: You’ve signed up for a NoPorts subscription or free trial.

    2. Installation & Activation: NoPorts is installed and atSigns are activated on at least two machines, one to connect from and one to connect to. .

    3. NoPorts Desktop App : If you didn’t use the NoPorts desktop app during installation, you can download it here:

    Step 1 and Step 2

    Steps to be completed on the Admin/Client Machine

    Step 1: Activate your policy atSign (in NoPorts Desktop)

    1) If you were already signed in with another atSign, click on Settings and then Sign Out.

    2) Click Get Started and then enter your policy atSign.

    3) You'll receive an OTP via email and after entering it, you'll be prompted to save your keys.

    Step 3 and Step 4

    Steps to be completed on the Policy Machine

    Step 3: Download and extract the policy server binaries

    Navigate to the NoPorts GitHub Releases page and copy the link address for the file matching your operating system.

    Location:

    Open a terminal, and from your home directory run the following command to download the file and save it as

    Step 5

    Step to be completed on the Admin/Client Machine

    Step 5: Approve the atSign authorization request

    1. Click on Requests and approve the pending request. The request will then move to the approved enrollments list.

    Step 6

    Step to be completed on the Policy Machine

    Step 6: Run the NoPorts Policy Server Software

    Run npp_atserver, with the previously activated policy atSign.

    This should display output that looks similar to this

    Step 7

    Step to be completed on the machine you'll be connecting to (Device)

    Step 7: Restart the NoPorts Daemon

    Edit /etc/systemd/system/sshnpd.service.d/override.conf and add your policy atSign to the delegate_policy environment variable.

    Step 8

    You're now ready to use the Policy Service. You can find instructions in the NoPorts desktop application .

    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 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:

    Or, if you installed as root:

    The first line of output should contain the version information:

    Or if you installed as root:

    The first line of output should contain the version information:

    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:

    Systemd unit

    The universal.shinstaller script will automatically restart the sshnpd.serviceunit.

    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:

    If you're curious how this command works

    Print out the contents of the sshnpd.sh service file, then extract the line where we execute the sshnpd program.

    Resolve any variables in place for the output of the previous expression.

    Find the process id of the program which was started using the command matching the output of the previous expression.

    You should get a single number as output, this is the process ID of the sshnpd process.

    Example:

    Verify the Process ID

    Before we continue, it is good practice to make sure that we have the correct ID:

    Example:

    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:

    Example:

    Verify the Process has been killed

    Use the same verification command from before:

    Example:

    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.

    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:

    The Template

    The following is a template for adding an sshnp connection to your ssh config for ease of use:

    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 for more info.

    Example

    This example shows the configuration for the following equivalent sshnp command:

    When you want to connect to this device, this is what you would type:

    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:

    2. Extending ssh command

    You can also add any additional flags to the ssh command, for example a TCP forwarding:

    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>.

    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.

    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 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!

    Available Releases

    Includes stable and beta releases

    In most cases, you will want to see our Installation page. Here, we've provided a list of all of our releases for visibility, but these links do not provide installation information.

    Stable Releases

    We recommend choosing a release from stable, if there's one available that's supported on your platform.

    Desktop App

    Our dedicated desktop app is preferred in most cases.

    If your use case is primarily SSH, we recommend using sshnp from the section.

    Operating System
    Download Location

    Cli Binaries

    This includes all binaries for NoPorts.

    Architecture
    Linux
    macOS
    Windows

    Beta Releases

    These releases are subject to potential instability or breaking changes as we mature the product-line.

    Type
    Download Location

    OpenWrt Installation Guide

    How to install NoPorts onto an OpenWrt router.

    Package repo for OpenWrt 24.10 and 23.05

    We now have our own package repo for the currently supported releases of OpenWrt. Please follow this guide 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 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 . 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

    The 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:

    Now edit /etc/config/sshnpd to use your atSigns, device name and device atSign OTP:

    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):

    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:

    And you should be ready to connect to the device:

    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:

    Generate a new set of cryptographic keys

    "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.

    Step 1) Generate a passcode from your Old machine

    Choose the operating system that is running on your old machine.

    Make sure to replace <REPLACE_client> with your client atSign

    1.1 Open the Windows installer program and click "Manage Keys"

    1.2 Enter the atSign you wish to manage and click "Next"

    Step 2) Make an authorization request on your New machine

    Choose the operating system that is running on your new machine.

    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

    Step 3) Approve the request on your Old machine

    Choose the operating system that is running on your old machine.

    Make sure to replace <client_device_name> with the device name from Step 2

    If you aren't already on the "Manage Keys" screen, follow Steps 1.1 and 1.2 above.

    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)

    On the machine you are connecting to

    Step 6: Download and run the Installer

    Download the installer from GitHub by running the following command:

    To check if the installation downloaded correctly:

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

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

    Step 8 to Step 11

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

    On the machine you are connecting from

    Step 8: Approve the atSign authorization request

    1. Click on

    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 and follow the installation guide 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, 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.

    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:

    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.

    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!

    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!

    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:

    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.

    Troubleshooting

    Summary Table (Quick Reference)

    TimeoutException: Connection timeout to srvd <atsign> service

    Check if relay or device atSign exists

    TimeoutException: Daemon feature check timed out

    Ensure device name is correct and permissions are in place

    ❌ 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:


    ❌ 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:

    4. Verify with certmgr.msc


    ❌ 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.


    macOS to macOS

    How to install NoPorts when connecting from macOS to macOS

    Step 1 to Step 4

    These initial steps set up the machine initiating the connection.

    On the machine you are connecting from

    Systemd Unit

    Follow these five steps to set up the NoPorts daemon as a systemd unit background service.

    Step 1. Run the installer

    1. First, change directories into the unpacked download:

    macOS to Linux

    How to install NoPorts when connecting from macOS to Linux

    Step 1 to Step 4

    These initial steps set up the machine initiating the connection.

    On the machine you are connecting from

    Tmux session

    Follow these four steps to run the NoPorts daemon within a tmux session

    Step 1. Run the installer

    1. First, ensure tmux is installed on your machine:

    If tmux is not available, a quick web search of Install tmux for <your distro>

    Headless

    Follow these four steps to install the NoPorts daemon in a headless environment

    Step 1. Run the installer

    It is important to note that the log files of the headless job have the potential to grow infinitely. We recommend implementing a logrotate cron job to prevent this.

    IPFire

    Installation of sshnpd on the IPFire.org firewall

    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

    Linux to Linux

    How to install NoPorts when connecting from Linux to Linux

    Step 1 to Step 4

    These initial steps set up the machine initiating the connection.

    On the machine you are connecting from
    On the machine you are connecting from

    In this installation guide, @example01_np will represent the client atSign, while @example02_np will represent the device atSign.

    npt -f @<your_client_atsign> -t @<your_device_atsign> -r @rv_[am|ap|eu|oc] -d <name> \
    -p <remote-port> -l <local-port>
    npt -f @alice_client -t @alice_device -d my_server -r @rv_am -p 3389 -l 33389
    sshnp -f @<your_client_atsign> -t @<your_device_atsign> -h @rv_(am|ap|eu|oc) -d <name> -i <~/.ssh<ssh_key> -s
    DEVICE_NAM
    E
    >
    \
    -n "sshnp:rw,sshrvd:rw"

    The atSign of the relay service used to establish the session connection. NoPorts currently provides coverage in 4 regions:

    @rv_am - Americas

    @rv_eu - Europe

    @rv_ap - Asia/Pacific @rv_oc - Oceania

    -d

    required

    String Only [a-z0-9_-] allowed. Maximum of 36 characters.

    Allows multiple devices to run sshnpd under a single device name.

    -p

    required

    Port number. Between 1-65535.

    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.

    -l

    "0"

    Port number Between 1024-65535.

    The port you are connecting to on the client/local side. Defaults to any unused port.

    -h

    "localhost"

    DNS / ip address

    The host that the daemon will connect to. nslookup is resolved on the remote machine where the daemon is running.

    -K

    N/A

    N/A

    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.

    -T

    "30s" "24h" (with -K)

    Human readable duration: e.g. "7d" or "1h,14m,30s"

    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.

    -x

    N/A

    N/A

    Starts the session in the background under a different process id, then exits, printing the bound port to stdout.

    Note that the background npt session will automatically close due to the timeout feature (see -T).

    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.

    -v / -q

    N/A

    N/A

    Use -v for verbose logging. Use -q for quiet (i.e. less) logging.

    learn more about these keys here

    macOS

    Linux

    Windows

    Client Additional Configuration
    SFTP
    RDP
    SMB
    HTTP(S)
    Pre-existing keys in place
    /usr/local/bin/sshnpd
    /usr/local/bin/sshnpd
    Systemd unit
    Tmux session
    Headless (cron + nohup)
    $HOME/.local/bin/sshnpd
    Version : x.x.x
    $HOME/.local/bin/sshnpd
    Version : x.x.x
    here
    sshnp Usage

    Repeat for Trusted Publishers if needed

    Keys missing after install

    Avoid enrolling as root; match user with SSHNPD install

    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

    Stuck on “preparing for activation”

    Update CA certificates via certutil

    Enrollment authorization failed

    Failed to authorise enrollment

    Use manager keys instead of reused ones

    Timeout to srvd
    Daemon feature check timeout
    Keys not found after install
    sshnp ... -f @alice_client ...
    sshnp ... -t @alice_device ...
    sshnp ... -d my_device ...
    sshnp ... -h @rv_am ...
    sshnp ... -h @rv_eu ...
    sshnp ... -h @rv_ap ...
    sshnp ... -i path/to/my/ssh/private/key ...
    sshnp ... -i path/to/my/ssh/private/key -s ...
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBOkiUzsOq8wc9/HaEbE4lgcWeQoICBmp8XgRW0vf5T8 (Comment / identifier to remember this key here)
    sshnp ... -i path/to/my/ssh/private/key ...
    sshnp -f @alice_client -t @alice_device -d my_server -h @rv_am -i ~/.ssh/id_ed25519
    sshnp -f @alice_client -t @alice_device -d my_server \
     -h @rv_am -i ~/.ssh/id_ed25519 -u bobc -U bobc
    pgrep -f "$(eval echo \"$( cat $HOME/.local/bin/sshnpd.sh | grep /sshnpd | awk '{$1=$1};1')\" )"
    cat $HOME/.local/bin/sshnpd.sh | grep /sshnpd | awk '{$1=$1};1'
    eval echo \"$(...)\"
    pgrep -f "$(...)"
    atsign@sshnpd-test:~# pgrep -f "$(eval echo \"$( cat $HOME/.local/bin/sshnpd.sh | grep /sshnpd | awk '{$1=$1};1')\" )"
    289
    ps -fp <process ID>
    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
    kill -9 <process ID>
    root@sshnpd-test:~# kill -9 289
    ps -fp <process ID>
    root@sshnpd-test:~# ps -fp 289
    UID          PID    PPID  C STIME TTY          TIME CMD
    ssh my_lab
    ~/.ssh/config
    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
    
    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
    sshnp -f @alice_client -t @alice_device -d my_server -r @rv_am
    ssh alice_device
    ~/.ssh/config
    Host my_webdev_server
      Hostname localhost
      AddKeysToAgent yes
      UserKnownHostsFile /dev/null
      StrictHostKeyChecking no
      IdentityFile ~/.ssh/id_ed25519
      LocalForward 8080:0:8080
      ProxyCommand=...
    ssh my_webdev_server -L "8080:0:8080"
    sudo chown -R $USER:$USER ~/.ssh
    certutil -generateSSTFromWU roots.sst  
    certutil -addstore -f root roots.sst
    Step 7: Initiate atSign authorization request

    Run the following command to make an authorization request.

    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

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

    If you encounter a handshake exception, it usually means your root certificates are outdated. To refresh them, run the following command with administrator privileges:Install-Script -Name UpdateRootCertificates

    Step 8: Setup Service Config

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

    Make sure you run notepad/terminal as administrator or else you won't be able to save your changes!

    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.

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

  • Step 9: 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.

    Step 10: 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, SSH, RDP, SFTP, Web Server, and SMB.

    Step 11: 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.

    from GitHub
    Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    notepad C:\ProgramData\NoPorts\sshnpd.yaml
    at_activate.exe enroll -a "@<REPLACE>_np" `
      -s <PASSCODE> `
      -p noports `
      -k C:\Users\<USER>
    

    Step 2: Generate a policy atSign authorization passcode

    1) Click on Authenticator and make note of the One-Time Password displayed on screen.

    sshnpd.tgz
    .

    Example:

    Once this is done, extract the contents of the file to your home directory.

    After extraction, copy the npp_atserver and at_activate binary to ~/.local/bin (whichever you prefer and whichever is on your PATH)

    Step 4: Initiate an atSign authorization request

    Run the following command to make an authorization request:

    Be sure to replace the following values:

    @<REPLACE>_np with your policy atSign,

    <PASSCODE> with the passcode generated in Step 2,

    @<REPLACE>_np_key with your policy atSign,

    <DEVICE_NAME> with the name of the machine you are on

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

  • After a few seconds, the request will also show as approved on the machine you are connecting to.

  • Then run the following command to restart the daemon.

    Ensure the daemon is running

    Your sshnpd process should now be sending heartbeats to the policy service. You should see a log similar to below after waiting 5 minutes.

    View installation guides
    Link to Apple Store
    Link to Windows Store
    https://github.com/atsign-foundation/noports/releases
    here
    Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    curl -L -o sshnp.tgz <YOUR URL>
    curl -L -o sshnp.tgz https://github.com/atsign-foundation/noports/releases/download/v5.13.0/sshnp-linux-x64.tgz
    tar -xvzf sshnp.tgz
    cd sshnp
    sudo cp ./npp_atserver ./at_activate ~/.local/bin
    ~/.local/bin/at_activate enroll -a @<REPLACE>_np \
      -s <PASSCODE> \
      -p noports \
      -k ~/.atsign/keys/@<REPLACE>_np_key.atKeys \
      -d <
    

    risc-v

    Windows

    Windows Store

    MacOS

    App Store

    Linux

    Build from Source

    x64

    sshnp-linux-x64.tgz

    sshnp-macos-x64.zip (intel)

    sshnp-windows-x64.zip

    arm64

    sshnp-linux-arm64.tgz

    sshnp-macos-arm64.zip (apple)

    arm

    sshnp-linux-arm.tgz

    Windows CLI Client / Device Installer

    GitHub

    Cli Binaries

    1.3 Click "New OTP"

    1.4 Wait a few seconds for the OTP to appear then proceed to Step 2 on the New machine

    2.1 Open the Windows Installer and click "Generate Keys"

    2.2 Enter the atSign you wish to transfer and click "Next"

    2.3 Enter the OTP then press "Generate"

    2.4 Proceed to Step 3. Once the request has been approved in Step 3, you should see this screen

    3.1 Once step 2 is complete press refresh and the new request will appear

    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.

    3.3 Once the request is approved, it should disappear from the installer, the new machine's enrollment should complete in a few seconds.

    ~/.local/bin/at_activate otp -a @<REPLACE_client>
    ~/.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"
    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.

    Step 7: Initiate atSign authorization request

    Run the following command to make an authorization request:

    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

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

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

  • Step 9: 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.

    Step 10: 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, SSH, RDP, SFTP, Web Server, and SMB.

    Step 11: 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.

    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
    stat universal.sh
    chmod u+x universal.sh
    ./universal.sh
    Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    ~/.local/bin/at_activate enroll -a @<REPLACE>_np \
      -s <PASSCODE> \
      -p noports \
      -k ~/.atsign/keys/@<REPLACE>_np_key.atKeys \
      -d <
    
    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.
    sshuttle
    configure your SOCKS proxy
    DEVICE_NAM
    E
    >
    \
    -n "sshnp:rw,sshrvd:rw"
    Step 1: Download and run the Installer

    Download the msi installer from GitHub. You can run the msi right from the windows-bundle.zip.

    Step 2: Client atSign activation (@example01_np)

    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

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

    Replace @<REPLACE>_np with your client atSign.

    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.

    Step 3: Device atSign activation (@example02_np)

    Run the same command, but for your device atSign.

    Replace @<REPLACE>_np with your device atSign.

    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.

    Step 4: 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.

    Replace @<REPLACE>_np with your device atSign.

    at_activate.exe -a "@<REPLACE>_np"
    at_activate.exe -a "@<REPLACE>_np"
    at_activate.exe otp -a "@<REPLACE>_np"
    On the machine you are connecting from

    Step 7: Approve the atSign authorization request

    Run the following command:

    In this installation guide, @example01_np will represent the client atSign, while @example02_np will represent the device atSign.

    Step 1: Download and run the Installer

    Download the installer from GitHub by running the following command:

    To check if the installation downloaded correctly:

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

    You may be asked to enter your password if your machine requires sudo privileges.

    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.

    Step 2: Activate your client atSign (@example01_np)

    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

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

    Replace @<REPLACE>_np with your client atSign.

    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.

    Step 3: Activate your device atSign (@example02_np)

    Run the same command, but for your device atSign.

    Replace @<REPLACE>_np with your device atSign.

    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.

    Step 4: 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.

    Replace @<REPLACE>_np with your device atSign.

    Step 5 and Step 6

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

    On the machine you are connecting to

    Step 5: Download and run the Installer

    Download the installer from GitHub by running the following command:

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

    To check if the installation downloaded correctly:

    stat universal.sh

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

    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.

    Step 6: Initiate atSign authorization request

    Run the following command to make an authorization request:

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    <PASSCODE> with the passcode generated in Step 4,

    @<REPLACE>_np_key

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

    Step 7 and Step 8

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

    On the machine you are connecting from

    Step 7: Approve the atSign authorization request

    Run the following command:

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    @<REPLACE_NAME> with the device name from Step 6.

    Step 8: Use NoPorts!

    That's it. You can start using NoPorts or explore some of the documented use cases, including , , , , , and .

    ~/.local/bin/at_activate -a @<REPLACE>_np
    ~/.local/bin/at_activate -a @<REPLACE>_np
    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
    stat universal.sh
    chmod u+x universal.sh
    ./universal.sh
    ~/.local/bin/at_activate otp -a @<REPLACE>_np

    Then run the installer:

    This installer must be run as root.

    Not available for macOS

    Step 2. Configure the service file

    After installing the systemd unit, we must configure it. This requires root privileges.

    You'll then be greeted with a file that looks like this:

    Replace <username> with the linux user running sshnpd (we suggest creating service account not running as root)

    Replace <@device_atsign> with the device address

    Replace <@manager_atsign> with the client address

    Replace <device_name> with your own custom **unique ** identifier for this device. You will need this value later, so don't forget it.

    <device_name> must be alphanumeric snake case, max length 30 - e.g. dev_abc1

    Add any additional config to the end of the line where sshnpd is run, some useful flags you should consider adding:

    • -u : "unhide" the device, sharing the username and making it discoverable by sshnp --list-devices

    • -s : "ssh-public-key", allow ssh public keys to be shared by sshnp and automatically authorized by sshd, saves you from dealing with ssh public key management. If multiple people use the device, we recommend leaving this off and managing ssh public keys yourself.

    • To see the rest of the available options run sshnpd to see the usage.

    Step 3. Activate your device address

    If you don't own a pair of noports addresses, please visit the registrar before continuing.

    Step 3.1. First time activating your address

    We will now activate the device address—you only need to activate the device address now. The client address will be activated later during the client installation.

    Now that you have at_activate installed, you can invoke the command with the name of the address you would like to activate:

    Now that you have at_activate installed, you can invoke the command with the name of the address you would like to activate:

    Enter the One-Time Password (OTP) & Check your SPAM/PROMOTIONS folders

    The application will pause and wait for the input of a one-time password (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_device_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.).

    Step 3.1. Activated this address before

    If you have activated the device address before, you must copy the address from another machine where it's been activated.

    The address will be located at ~/.atsign/keys/@my_noports_device_key.atKeys. Copy this file from your other machine to the same location on the machine that you are installing sshnpd on.

    Step 4. Enable the service

    Using systemctl we can enable and start the sshnpd service.

    Observing the service

    If you need to verify the status of the service:

    If you want to follow the logs of the service you can with

    Step 5. Check your environment.

    There are a number of fiddly things to get in place for ssh to work. The first is the ~/.ssh/authorized_keysfile of the user being used to run the systemd unit.

    The file needs to owned by the user running the systemd unit. Currently there is a bug in the script and this sets the user to root, which needs to be corrected if not running as root. You can do this with the following command substituting debain for your username and group.

    The file also needs to be only writable by the owner, else the sshd will not allow logins. This can be checked with ls -l and corrected with the chmod command.

    Once complete it should look like this.

    Running sshnpd at root special steps (not recommended)

    If you decided to use the root user in the service setup you have a futher couple of steps.

    Then you need to make sure that the root user is allowed to login via sshd. Whist this is not recommended, you can get it working by editing the /etc/ssh/sshd_config file and removing the # on this line.

    Once removed, you will need to restart the sshd daemon. How to do this varies from distribution/OS so check on how to do it or reboot.

    Step 6. All Done !

    Your systemd service is ready to go. You can now proceed to installing your client, or if you've already done that, check out our usage guide.

    cd sshnp
    sudo ./install.sh systemd sshnpd

    In this installation guide, @example01_np will represent the client atSign, while @example02_np will represent the device atSign.

    Step 1: Download and run the Installer

    Download the installer from GitHub by running the following command:

    To check if the installation downloaded correctly:

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

    You may be asked to enter your password if your machine requires sudo privileges.

    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.

    Step 2: Activate your client atSign (@example01_np)

    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

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

    Replace @<REPLACE>_np with your client atSign.

    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.

    Step 3: Activate your device atSign (@example02_np)

    Run the same command, but for your device atSign.

    Replace @<REPLACE>_np with your device atSign.

    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.

    Step 4: 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.

    Replace @<REPLACE>_np with your device atSign.

    Step 5 and Step 6

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

    On the machine you are connecting to

    Step 5: Download and run the Installer

    Download the installer from GitHub by running the following command:

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

    To check if the installation downloaded correctly:

    stat universal.sh

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

    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.

    Step 6: Initiate atSign authorization request

    Run the following command to make an authorization request:

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    <PASSCODE> with the passcode generated in Step 4,

    @<REPLACE>_np_key

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

    Step 7 and Step 8

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

    On the machine you are connecting from

    Step 7: Approve the atSign authorization request

    Run the following command:

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    @<REPLACE_NAME> with the device name from Step 6.

    Step 8: Use NoPorts!

    That's it. You can start using NoPorts or explore some of the documented use cases, including , , , , , and .

    ~/.local/bin/at_activate -a @<REPLACE>_np
    ~/.local/bin/at_activate -a @<REPLACE>_np
    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
    stat universal.sh
    chmod u+x universal.sh
    ./universal.sh
    ~/.local/bin/at_activate otp -a @<REPLACE>_np
    should help you easily install it. Most distros include the tmux package in their repository.
    1. Change directories into the unpacked download:

    1. Then run the installer:

    This will install the binaries to ~/.local/bin. Instead, if you'd like to install the binaries to /usr/local/bin, run the installer as root:

    1. First, ensure tmux is installed on your machine:

    [[ -n $(command -v tmux) ]] && echo 'Good to go!' || echo 'Uh oh! Install tmux before continuing...'

    If tmux is not available, the recommended way to install tmux on macOS is with homebrew.

    [[ -n $(command -v brew) ]] && brew install tmux || echo 'brew not installed, first install brew at https://brew.sh, then run this command again.'
    1. Change directories into the unpacked download:

    cd sshnp
    1. Then run the installer:

    ./install.sh tmux sshnpd

    This will install the binaries to ~/.local/bin. Instead, if you'd like to install the binaries to /usr/local/bin, run the installer as root:

    Step 2. Configure the startup script

    After installing the startup script, we must configure it, with nano or vi depending upon your preference.

    or

    You'll then be greeted with a file that looks like this:

    Replace $user with the linux user running sshnpd

    Replace $device_atsign with the device address

    Replace $manager_atsign with the client address

    Replace $device_name with your own custom **unique ** identifier for this device. You will need this value later, so don't forget it.

    $device_name must be alphanumeric snake case, max length 30 - e.g. dev_abc1

    Add any additional config to the end of the line where sshnpd is run, some useful flags you should consider adding:

    • -u : "unhide" the device, sharing the username and making it discoverable by sshnp --list-devices

    • -s : "ssh-public-key", allow ssh public keys to be shared by sshnp and automatically authorized by sshd, saves you from dealing with ssh public key management. If multiple people use the device, we recommend leaving this off and managing ssh public keys yourself.

    • To see the rest of the available options run sshnpd to see the usage.

    Step 3. Activate your device address

    If you don't own a pair of noports addresses, please visit the registrar before continuing.

    Step 3.1. First time activating your address

    We will now activate the device address, you only need to activate the device address now. The client address will be activated later during the client installation.

    Now that you have at_activate installed, you can invoke the command with the name of the address you would like to activate:

    Now that you have at_activate installed, you can invoke the command with the name of the address you would like to activate:

    Enter the One-Time Password (OTP) & Check your SPAM folder!

    The application will pause and wait for the input of a one-time password (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/<address_name>_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.).

    Step 3.2. Activated this address before

    If you have activated the device address before, you must copy the address from another machine where it's been activated.

    The address will be located at ~/.atsign/keys/<address_name>_key.atKeys. Copy this file from your other machine to the same location on the machine that you are installing sshnpd on.

    Step 4. Start the service

    The tmux service will automatically be started by the cron @reboot directive when your machine restarts. If you would like to start it immediately, note that you must make sure to disown the tmux process so that it doesn't hang up when you log out.

    Run the following command to start it immediately:

    Observing the service

    You can use regular tmux commands to observe the service:

    To detach from the tmux session use the keybind Ctrl + B, D. This will safely detach from the tmux session without killing it.

    Step 5. All done!

    Your tmux session is ready to go, you can now proceed to installing your client, or if you've already done that, check out our usage guide.

    [[ -n $(command -v tmux) ]] && echo 'Good to go!' || echo 'Uh oh! Install tmux before continuing...'
    cd sshnp
    ./install.sh tmux sshnpd
    sudo ./install.sh tmux sshnpd
  • Change directories into the unpacked download:

    1. Then run the installer:

    This will install the binaries to ~/.local/bin. Instead, if you'd like to install the binaries to /usr/local/bin, run the installer as root:

    1. Change directories into the unpacked download:

    cd sshnp
    1. Then run the installer:

    ./install.sh headless sshnpd

    This will install the binaries to ~/.local/bin. Instead, if you'd like to install the binaries to /usr/local/bin, run the installer as root:

    sudo ./install.sh headless sshnpd

    Step 2. Configure the startup script

    After installing the startup script, we must configure it.

    You'll then be greeted with a file that looks like this:

    Replace $user with the linux user running sshnpd

    Replace $device_atsign with the device address

    Replace $manager_atsign with the client address

    Replace $device_name with your own custom **unique ** identifier for this device. You will need this value later, so don't forget it.

    $device_name must be alphanumeric snake case, max length 30 - e.g. dev_abc1

    Add any additional config to the end of the line where sshnpd is run, some useful flags you should consider adding:

    • -u : "unhide" the device, sharing the username and making it discoverable by sshnp --list-devices

    • -s : "ssh-public-key", allow ssh public keys to be shared by sshnp and automatically authorized by sshd, saves you from dealing with ssh public key management. If multiple people use the device, we recommend leaving this off and managing ssh public keys yourself.

    • To see the rest of the available options run sshnpd to see the usage.

    This service does not do log rotations of the logs stored at $HOME/.sshnpd/logs.

    It is recommended that you implement a cron job which handles log rotations.

    Step 3. Activate your device address

    If you don't own a pair of NoPorts addresses, please visit my.noports.com before continuing.

    Step 3.1. First time activating your address

    We will now activate the device address—you only need to activate the device address now. The client address will be activated later during the client installation.

    Now that you have at_activate installed, you can invoke the command with the name of the address you would like to activate:

    Now that you have at_activate installed, you can invoke the command with the name of the address you would like to activate:

    Enter the One-Time Password (OTP) & Check your SPAM/PROMOTIONS folders

    The application will pause and wait for the input of a one-time password (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/<address_name>_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.).

    Step 3.2. Activated this address before

    If you have activated the device address before, you must copy the address from another machine where it's been activated.

    The address will be located at ~/.atsign/keys/<address_name>_key.atKeys. Copy this file from your other machine to the same location on the machine that you are installing sshnpd on.

    Step 4. Start the service

    The headless service will automatically be started by the cron @reboot directive when your machine restarts. If you would like to start it immediately, note that you must make sure to disown the process so that it doesn't hang up when you log out.

    Run the following command to start it immediately:

    Observing the service

    The service should already be running in the background, to observe the logs:

    Most of the logs will be found in sshnpd.err, it is usually worth checking that file first

    Step 5. All done!

    Your headless job is ready to go. You can now proceed to installing your client, or if you've already done that, check out our usage guide.

    cd sshnp
    ./install.sh headless sshnpd
    sudo ./install.sh headless sshnpd
    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.

    Enable all options

    We will also need to add the TMUX package via the web interface under the IPFire section click Pakfire, then add TMUX.

    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:

    Non root user environment

    The next step is su to the user you just created and set up the directories sshnpd will need

    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.

    Once done, then you can add the sudo group and then add the username atsign to the group with the following commands as root:

    Then add a password to the atsign account again as root:

    Once completed, then check everything is working by su - to atsign the using sudo -s to get back to root.

    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:

    To install the software, just cd and run the install command:

    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.

    Then edit the lines as below with your details.

    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.

    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.

    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.

    Then add your username ours looks like this

    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.

    Then you will need to add the following line:

    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

    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:

    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:

    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:

    to:

    and then reboot or restart the sshd daemon.

    Manual Installation Guides

    In this installation guide, @example01_np will represent the client atSign, while @example02_np will represent the device atSign.

    Step 1: Download and run the Installer

    Download the installer from GitHub by running the following command:

    To check if the installation downloaded correctly:

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

    You may be asked to enter your password if your machine requires sudo privileges.

    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.

    Step 2: Activate your client atSign (@example01_np)

    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

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

    Replace @<REPLACE>_np with your client atSign.

    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.

    Step 3: Activate your device atSign (@example02_np)

    Run the same command, but for your device atSign.

    Replace @<REPLACE>_np with your device atSign.

    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.

    Step 4: 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.

    Replace @<REPLACE>_np with your device atSign.

    Step 5 and Step 6

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

    On the machine you are connecting to

    Step 5: Download and run the Installer

    Download the installer from GitHub by running the following command:

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

    To check if the installation downloaded correctly:

    stat universal.sh

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

    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.

    Step 6: Initiate atSign authorization request

    Run the following command to make an authorization request.

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    <PASSCODE> with the passcode generated in Step 4,

    @<REPLACE>_np_key

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

    Step 7 and Step 8

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

    On the machine you are connecting from

    Step 7: Approve the atSign authorization request

    Run the following command:

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    @<REPLACE_NAME> with the device name from Step 6.

    Step 8: Use NoPorts!

    That's it. You can start using NoPorts or explore some of the documented use cases, including , , , , , and .

    ~/.local/bin/at_activate -a @<REPLACE>_np
    ~/.local/bin/at_activate -a @<REPLACE>_np
    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
    stat universal.sh
    chmod u+x universal.sh
    ./universal.sh
    ~/.local/bin/at_activate otp -a @<REPLACE>_np
    Step 1: Download and run the Installer

    Download the msi installer from GitHub. You can run the msi right from the windows-bundle.zip.

    Step 2: Client atSign activation (@example01_np)

    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

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

    Replace @<REPLACE>_np with your client atSign.

    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.

    Step 3: Device atSign activation (@example02_np)

    Run the same command, but for your device atSign.

    Replace @<REPLACE>_np with your device atSign.

    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.

    Step 4: 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.

    Replace @<REPLACE>_np with your device atSign.

    at_activate.exe -a "@<REPLACE>_np"
    at_activate.exe -a "@<REPLACE>_np"
    at_activate.exe otp -a "@<REPLACE>_np"
    Step 1: Download and run the Installer

    Download the msi installer from GitHub. You can run the msi right from the windows-bundle.zip.

    Step 2: Client atSign activation (@example01_np)

    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

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

    Replace @<REPLACE>_np with your client atSign.

    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.

    Step 3: Device atSign activation (@example02_np)

    Run the same command, but for your device atSign.

    Replace @<REPLACE>_np with your device atSign.

    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.

    Step 4: 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.

    Replace @<REPLACE>_np with your device atSign.

    at_activate.exe -a "@<REPLACE>_np"
    at_activate.exe -a "@<REPLACE>_np"
    at_activate.exe otp -a "@<REPLACE>_np"
    On the machine you are connecting from

    Step 7: Approve the atSign authorization request

    Run the following command:

    releases
    issue
    releases
    MCP
    SSH
    RDP
    SFTP
    Web Server
    SMB
    ~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>

    Device Installation

    Begin with the three steps below

    Overview

    The NoPorts daemon (a.k.a. sshnpd) is installable as a background service in many ways. Choose the best option for your environment. The service may be installed as a systemd unit, docker container, tmux session, or as a background job using cron and nohup. The binaries can also be installed standalone so that you can install your own custom background service.

    ⚠️ This guide doesn't support Windows

    On Windows, we strongly recommend sticking to our automated installation process on Windows. This is because properly installing NoPorts as a Windows service requires making entries in the registry. If you want to create a custom installer for your organization, please speak to us directly at .

    Step 1. Download

    Step 1.1. Download from GitHub

    You can , or see the table below to download the latest release for your platform.

    1.b. Download using curl

    Architecture
    Linux
    macOS
    Windows

    Step 1.2. Download using curl

    Alternatively, if you want to download from the command line, you can do so with curl.

    x64:

    arm64:

    arm:

    risc-v:

    x64 (intel):

    arm64 (apple):

    Step 2. Unpack the Archive

    If you downloaded from GitHub, the file name may be slightly different.

    Step 3. Install sshnpd

    See the links in the table below to continue with the installation process.

    Installation method
    When to use this method

    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 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.

    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.

    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:

    The command should output a path such as:

    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.

    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.

    Breaking down this command:

    Command portion
    Explanation

    Place this command in the "Before connecting" field.

    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.

    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.

    Breaking down this command:

    Command portion
    Explanation

    Place this command in the "Before connecting" field.

    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.

    Linux to macOS

    How to install NoPorts when connecting from Linux to macOS

    Step 1 to Step 4

    These initial steps set up the machine initiating the connection.

    On the machine you are connecting from

    In this installation guide, @example01_np will represent the client atSign, while @example02_np will represent the device atSign.

    Step 1: Download and run the Installer

    Download the installer from GitHub by running the following command:

    To check if the installation downloaded correctly:

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

    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 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.

    Step 2: Activate your client atSign (@example01_np)

    If you've already activated your client atSign on another device, this step will not work. Instead, follow this guide:

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

    Replace @<REPLACE>_np with your client atSign.

    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.

    Step 3: Activate your device atSign (@example02_np)

    Run the same command, but for your device atSign.

    Replace @<REPLACE>_np with your device atSign.

    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.

    Step 4: 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.

    Replace @<REPLACE>_np with your device atSign.

    Step 5 and Step 6

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

    On the machine you are connecting to

    Step 5: Download and run the Installer

    Download the installer from GitHub by running the following command:

    To check if the installation downloaded correctly:

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

    Step 7 and Step 8

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

    On the machine you are connecting from

    Step 7: Approve the atSign authorization request

    Run the following command:

    Under The Hood

    This guide provides information on the technical aspects of NoPorts, including its architecture, protocols, and security mechanisms.

    This document describes version 5.6.x Other versions use a different method of forming the connection.

    Overview

    There are four atSigns involved - one for each of

    ~/.local/bin/npp_atserver -a @<YOUR POLICY ATSIGN>
    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: {} 
    Environment=delegate_policy="@policy_atsign_123"
    sudo systemctl daemon reload && sudo systemctl restart sshnpd.service
    journalctl -u sshnpd.service -f
    Nov 10 23:54:17 atsign sshnpd[124155]: INFO|2025-11-10 23:54:17.310764| sshnpd |Sending heartbeat to policy service @tastelessbanana
    ~/.local/bin/at_activate approve -a @<REPLACE_client> \
      --arx noports \
      --drx <client_device_name>
    Host localhost
        StrictHostKeyChecking no
        UserKnownHostsFile /dev/null
        IdentityFile ~/.ssh/id_ed25519
        LogLevel QUIET
    #!/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 [email protected]:$LOCALPORT $NETA $NETB $NETC 
    #
    sshnp -f @my_client -t @my_device -h @rv_am -d my_pi -o "-D 1080"
    ./at_activate -a @my_noports_device
    ./at_activate -a @my_noports_device
    sudo vi /etc/systemd/system/sshnpd.service
    sudo systemctl enable sshnpd.service
    sudo systemctl start sshnpd.service
    sudo systemctl status sshnpd.service
    sudo journalctl -u sshnpd.service -f
    debian@beaglebone:~$ ls -l ~/.ssh/
    total 0
    -rw-r--r-- 1 root root 0 Feb 18 00:28 authorized_keys
    debian@beaglebone:~$ sudo chown debian:debian ~/.ssh/authorized_keys
    debian@beaglebone:~$ ls -l ~/.ssh/
    total 0
    -rw-r--r-- 1 debian debian 0 Feb 18 00:28 authorized_keys
    debian@beaglebone:~$ chmod 600 ~/.ssh/authorized_keys
    debian@beaglebone:~$ ls -l ~/.ssh/
    total 0
    -rw------- 1 debian debian 0 Feb 18 00:28 authorized_keys
    debian@beaglebone:~$
    sudo mkdir -p ~root/.ssh
    sudo touch ~root/.ssh/authorized_keys
    sudo chmod 600 ~root/.ssh/authorized_keys
    # PermitRootLogin prohibit-password
    ./at_activate -a @my_noports_device
    ./at_activate -a @my_noports_device
    nano ~/.local/bin/sshnpd.sh
    vi ~/.local/bin/sshnpd.sh
    nohup &>/dev/null tmux new-session -d -s sshnpd && tmux send-keys -t sshnpd $HOME/.local/bin/sshnpd.sh C-m
    tmux a -t sshnpd
    ./at_activate -a @my_noports_device
    ./at_activate -a @my_noports_device
    vi ~/.local/bin/sshnpd.sh
    nohup $HOME/.local/bin/sshnpd.sh > $HOME/.sshnpd/logs/sshnpd.log 2> $HOME/.sshnpd/logs/sshnpd.err &
    tail -f $HOME/.sshnpd/logs/sshnpd.log
    tail -f $HOME/.sshnpd/logs/sshnpd.err
    https://<GREEN Interface IP>:444
    useradd -d /home/atsign -m -U atsign
    su - atsign
    mkdir -p ~/.atsign/keys ~/.ssh
    chmod 700 ~/.atsign ~/.atsign/keys ~/.ssh
    touch ~/.ssh/authorized keys
    chmod 600 ~/.ssh/authorized keys
    ## Uncomment to allow members of group sudo to execute any command
    %sudo	ALL=(ALL:ALL) ALL
    groupad sudo
    usermod -a -G sudo atsign
    passwd atsign
    su - atsign
    sudo -s 
    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-x64.tgz -o sshnp.tgz
    tar zxvf sshnp.tgz
    cd sshnp
    ./install.sh tmux sshnpd
    ~/.local/bin/sshnpd.sh
    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
    
    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
    chmod 600 ~/.atsign/keys/*
    sudo vi /etc/fcron.allow
    root
    atsign
    sudo fcrontab -u atsign -e
    @reboot tmux new-session -d -s sshnpd && tmux send-keys -t sshnpd /home/atsign/.local/bin/sshnpd.sh C-m
    @reboot tmux new-session -d -s sshnpd && tmux send-keys -t sshnpd /home/atsign/.local/bin/sshnpd.sh C-m &
    sshnp -f @cconstab -t @ssh_1 -h @rv_am -d ipfire01 -i ~/.ssh/id_rsa -s
    IdentityFile ~/.ssh/id_rsa
    ListenAddress 0.0.0.0
    ListenAddress localhost
    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}
    config sshnpd
            option atsign   '@example_device'
            option manager  '@example_client'
            option device   'rutx10'
            option args     ''
            option otp      '123456'
            option enabled  '1'
    at_activate approve -a @example_device --arx noports --drx rutx10
    service sshnpd start
    sshnp -f @example_client -t @example_device -d rutx10_remote -h rv_eu
    apk update
    apk add csshnpd
    \.
    atsign
    \k
    eys
    \@
    <
    REPLAC
    E
    >
    _np_key.atKeys
    `
    -d <DEVICE_NAME> `
    -n "sshnp:rw,sshrvd:rw"
    DEVICE_NAM
    E
    >
    \
    -n "sshnp:rw,sshrvd:rw"
    DEVICE_NAM
    E
    >
    \
    -n "sshnp:rw,sshrvd:rw"
    sshnp-linux-riscv.tgz
    with your
    device atSign
    ,

    <DEVICE_NAME> with the name of the machine you are on

    Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    MCP
    SSH
    RDP
    SFTP
    Web Server
    SMB
    ~/.local/bin/at_activate enroll -a @<REPLACE>_np \
      -s <PASSCODE> \
      -p noports \
      -k ~/.atsign/keys/@<REPLACE>_np_key.atKeys \
      -d <DEVICE_NAME> \
      -n "sshnp:rw,sshrvd:rw"
    ~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>
    with your
    device atSign
    ,

    <DEVICE_NAME> with the name of the machine you are on

    Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    MCP
    SSH
    RDP
    SFTP
    Web Server
    SMB
    ~/.local/bin/at_activate enroll -a @<REPLACE>_np \
      -s <PASSCODE> \
      -p noports \
      -k ~/.atsign/keys/@<REPLACE>_np_key.atKeys \
      -d <DEVICE_NAME> \
      -n "sshnp:rw,sshrvd:rw"
    ~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>
    with your
    device atSign
    ,

    <DEVICE_NAME> with the name of the machine you are on

    Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    MCP
    SSH
    RDP
    SFTP
    Web Server
    SMB
    ~/.local/bin/at_activate enroll -a @<REPLACE>_np \
      -s <PASSCODE> \
      -p noports \
      -k ~/.atsign/keys/@<REPLACE>_np_key.atKeys \
      -d <DEVICE_NAME> \
      -n "sshnp:rw,sshrvd:rw"
    ~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    @<REPLACE_NAME> with the device name from Step 6.

    Step 8: Use NoPorts!

    That's it. You can start using NoPorts or explore some of the documented use cases, including MCP, SSH, RDP, SFTP, Web Server, and SMB.

    .\at_activate approve -a "@<REPLACE>_np" --arx NoPorts --drx <REPLACE_NAME>

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    @<REPLACE_NAME> with the device name from Step 6.

    Step 8: Use NoPorts!

    That's it. You can start using NoPorts or explore some of the documented use cases, including MCP, SSH, RDP, SFTP, Web Server, and SMB.

    .\at_activate approve -a "@<REPLACE>_np" --arx NoPorts --drx <REPLACE_NAME>
    OpenWrt installation walk through
    Walk through of OpenWrt CLI installation onto a Teltonika RUT241

    Username: The username of the account you want to log in as.

    -p 3389

    The remote port, 3389 is the canonical RDP port

    -x

    Tell npt to exit when connected (which tells remmina npt is ready for it to connect)

    Username: The username of the account you want to login as.

    -p 5900

    The remote port, 5900 is the canonical VNC port on MacOS

    -x

    Tell npt to exit when connected (which tells remmina npt is ready for it to connect)

    /usr/local/bin/npt

    Run the npt command

    -f @your_client

    The "from" atSign (atSign of the current computer)

    -t @your_device

    The "to" atSign (atSign of the device you're connecting to)

    -d device_name

    The device name you gave when you setup sshnpd

    -r @rv_am

    The atSign of the relay you want to use

    --lp 12345

    The local port, must match the port we added on the basic page.

    /usr/local/bin/npt

    Run the npt command

    -f @your_client

    The "from" atSign (atSign of the current computer)

    -t @your_device

    The "to" atSign (atSign of the device you're connecting to)

    -d device_name

    The device name you gave when you setup sshnpd

    -r @rv_am

    The atSign of the relay you want to use

    --lp 56789

    The local port, must match the port we added on the basic page

    which npt
    /usr/local/bin/npt
    /usr/local/bin/npt -f @your_client -t @your_device -d device_name -r @rv_am --lp 12345 -p 3389 -x
    /usr/local/bin/npt -f @your_client -t @your_device -d device_name -r @rv_am --lp 56789 -p 5900 -x

    risc-v

    x64

    sshnp-linux-x64.tgz

    sshnp-macos-x64.zip (intel)

    sshnp-windows-x64.zip

    arm64

    sshnp-linux-arm64.tgz

    sshnp-macos-arm64.zip (apple)

    arm

    sshnp-linux-arm.tgz

    You are on Linux and have root access. (Recommended)

    You have tmux installed, or can install it. (Deprecated)

    If you do not have root access and cannot install tmux (Deprecated)

    You want to manually setup the background service after downloading the binaries. (roll your own)

    [email protected]
    download a release from GitHub
    Systemd Unit
    Tmux session
    Headless
    Standalone Binaries

    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.

    Step 6: Initiate atSign authorization request

    Run the following command to make an authorization request.

    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

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

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    @<REPLACE_NAME> with the device name from Step 6.

    Step 8: Use NoPorts!

    That's it. You can start using NoPorts or explore some of the documented use cases, including MCP, SSH, RDP, SFTP, Web Server, and SMB.

    Reuse your client atSign on another machine
    ~/.local/bin/at_activate -a @<REPLACE>_np
    ~/.local/bin/at_activate -a @<REPLACE>_np
    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
    stat universal.sh
    chmod u+x universal.sh
    ./universal.sh
    ~/.local/bin/at_activate otp -a @<REPLACE>_np
    curl -L https://github.com/atsign-foundation/noports/releases/latest/download/universal.sh -o universal.sh
    stat universal.sh
    chmod u+x universal.sh
    ./universal.sh
    Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    ~/.local/bin/at_activate enroll -a @<REPLACE>_np \
      -s <PASSCODE> \
      -p noports \
      -k ~/.atsign/keys/@<REPLACE>_np_key.atKeys \
      -d <
    
    ~/.local/bin/at_activate approve -a @<REPLACE>_np --arx noports --drx <DEVICE_NAME>
  • the noports daemon program (sshnpd) which runs on the device you want to ssh to

  • the noports client programs (sshnp/npt) which you run on the device you want to ssh from

  • the noports tcp rendezvous program (sshrvd)

  • if required a policy engine

  • The programs communicate via the atProtocol and the atClient SDKs; as a result, the payloads of the messages the programs send to each other are all end-to-end encrypted.

    In brief

    • The client (sshnp/npt) creates a unique guid for the session

      • and sends a request notification to the sshrvd for a port1/port2 pair for this sessionId

    • The sshrvd

      • finds a pair of available ports

      • opens server sockets for both of them

        • Note: rvd will allow just a single client socket to connect to each server socket

          • and will bridge them together

      • sends response to the client

    • The client

      • receives the response notification from sshrvd (rv_host, rv_port_1, rv_port_2)

      • and sends a request notification to the sshnpd including the sessionId and the rv_host:rv_port_1 and a new ephemeral AES 256 key

    • The daemon (sshnpd)

      • opens a socket to the rv_host:rv_port_1 and authenticates

      • and opens a socket to its local sshd port

    • The client

      • Listens on a specified port and on connection encrypts traffic received with the AES key and forward on to the rv_host

    • The client displays a message to the user that they may now ssh -p $local_port $username@localhost, i.e. ssh -p 58358 gary@localhost in the example above, and exits

    This high-level flow is visualized in the diagrams below.

    NB Requests from unauthorized client atSigns are ignored. Note that one may also completely prevent requests from any other atSigns ever even reaching the daemon by using the atProtocol's config:allow list feature.

    In the personal edition of noports, a daemon may have only a single authorized client atSign.

    The Team and Enterprise editions will allow for multiple authorized client atSigns, controlled not by the daemon but by a separate noports authorization controller process, with its own atSign.

    Overview diagram

    Policy Plane

    At any point the sshnpd or the srvd software rather than using a local configuration to manage access rights, can forward those questions to another atSign. That atSign can in turn pass those queries to a policy engine and reflect the answer back to the asking atSign. In the example above @relay and/or @server could ask if @client is allowed to access the service. This allows decisions to be made at the Policy plane level and provides operational segregation of duties.

    Control plane

    In the following sequence diagram, atServer address lookup flows, authentication flows, key exchange flows, precise encryption mechanics and notification transmission flows are not covered in detail; those details are provided in the links provided in the "Further Details" section below.

    Since the full details are provided in those other links, the client_1 -> atServer_1 -> atServer_2 -> client_2 message flows are abbreviated to @atSign_1 -> @atSign_2 in the sequence diagram. Thus, for example, sshnp (@client) encapsulates both the sshnp program and the sshnp atServer

    Data plane

    Once the interactions above have completed

    • the sshnpd nor the sshnp programs are no longer involved

    • there is a new sshrv process running on the device host which pipes i/o between requested server:port and $rv_host:$rv_port_1

    • there is a client process running on the client host which provides the local port forwarding tunnel

    • User may now type "ssh -p $local_port username@localhost" or use a client application like and RDP client with traffic flowing

      • client ssh program <===>

        • $client_localhost:$local_port <===> bridged by client-side ssh tunnel to

          • $rv_host:$rv_port_2 <===> bridged by sshrvd to

    Further Details

    In the sections above, we referred to "authentication", "sending notifications" and "receiving notifications", and we made the statement that "the payloads of the messages the programs send to each other are all end-to-end encrypted"

    Here are some links to detailed diagrams covering

    • how atClients authenticate to their atServers

    • how encrypted data is exchanged (including how keys are exchanged)

    • how notifications work

    On the machine you are connecting to

    Step 5: Download and run the Installer

    Download the msi installer from GitHub. You can run the msi right from the windows-bundle.zip.

    Ensure both Core Tools & Daemon Service are being installed.

    Step 6: Initiate device atSign authorization request

    Run the following command to make an authorization request.

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    <PASSCODE> with the passcode generated in Step 4,

    <USER>

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

    If you encounter a handshake exception, it usually means your root certificates are outdated. To refresh them, run the following command with administrator privileges:Install-Script -Name UpdateRootCertificates

    Step 7: Setup Service Config on Device

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

    Make sure you run notepad/terminal as administrator or else you won't be able to save your changes!

    Ensure you provide the following fields to your service config:

    • atsign

      • atsign: example02_np

      • atsign: '@example02_np'

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

    sudo ./install.sh tmux sshnpd
    On the machine you are connecting to

    Step 5: Download and run the Installer

    Download the msi installer from GitHub. You can run the msi right from the windows-bundle.zip.

    Ensure both Core Tools & Daemon Service are being installed.

    Step 6: Initiate device atSign authorization request

    Run the following command to make an authorization request.

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    <PASSCODE> with the passcode generated in Step 4,

    <USER>

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

    If you encounter a handshake exception, it usually means your root certificates are outdated. To refresh them, run the following command with administrator privileges:Install-Script -Name UpdateRootCertificates

    Step 7: Setup Service Config on Device

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

    Make sure you run notepad/terminal as administrator or else you won't be able to save your changes!

    Ensure you provide the following fields to your service config:

    • atsign

      • atsign: example02_np

      • atsign: '@example02_np'

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

    On the machine you are connecting to

    Step 5: Download and run the Installer

    Download the msi installer from GitHub. You can run the msi right from the windows-bundle.zip.

    Ensure both Core Tools & Daemon Service are being installed.

    Step 6: Initiate device atSign authorization request

    Run the following command to make an authorization request.

    Be sure to replace the following values:

    @<REPLACE>_np with your device atSign,

    <PASSCODE> with the passcode generated in Step 4,

    <USER>

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

    If you encounter a handshake exception, it usually means your root certificates are outdated. To refresh them, run the following command with administrator privileges:Install-Script -Name UpdateRootCertificates

    Step 7: Setup Service Config on Device

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

    Make sure you run notepad/terminal as administrator or else you won't be able to save your changes!

    Ensure you provide the following fields to your service config:

    • atsign

      • atsign: example02_np

      • atsign: '@example02_np'

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

    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.

    Using sshuttle with SSH No Portsasciinema.org
    Be your own VPN
    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-x64.tgz -o sshnp.tgz
    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-arm64.tgz -o sshnp.tgz
    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-arm.tgz -o sshnp.tgz
    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-riscv.tgz -o sshnp.tgz
    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-macos-x64.zip -o sshnp.zip
    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-macos-arm64.zip -o sshnp.zip
    tar -xf sshnp.tgz
    unzip sshnp.zip
    DEVICE_NAM
    E
    >
    \
    -n "sshnp:rw,sshrvd:rw"
    sshnp-linux-riscv.tgz
    and bridges the sockets together whilst also encrypting data towards the rv_host
  • and sends a response notification to the sshnp client

  • $rv_host:$rv_port_1 <===> bridged by device-side sshrv to

    • $device_host:22 <===>

      • device sshd program

    with your
    Windows username
    ,

    @<REPLACE>_np_key with your device atSign,

    <DEVICE_NAME> with the name of the machine you are on

    keys (windows path)
    • keys: C:\Users\alice\.atsign\keys\@example02_np_key.atKeys

  • manager

    • manager: example01_np

    • manager: '@example01_np'

  • Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    notepad C:\ProgramData\NoPorts\sshnpd.yaml
    at_activate.exe enroll -a "@<REPLACE>_np" `
      -s <PASSCODE> `
      -p noports `
      -k C:\Users\<USER>\.atsign\keys\@<REPLACE>_np_key.atKeys `
      -d <DEVICE_NAME> `
      -n "sshnp:rw,sshrvd:rw"
    with your
    Windows username
    ,

    @<REPLACE>_np_key with your device atSign,

    <DEVICE_NAME> with the name of the machine you are on

    keys (windows path)
    • keys: C:\Users\alice\.atsign\keys\@example02_np_key.atKeys

  • manager

    • manager: example01_np

    • manager: '@example01_np'

  • Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    notepad C:\ProgramData\NoPorts\sshnpd.yaml
    at_activate.exe enroll -a "@<REPLACE>_np" `
      -s <PASSCODE> `
      -p noports `
      -k C:\Users\<USER>\.atsign\keys\@<REPLACE>_np_key.atKeys `
      -d <DEVICE_NAME> `
      -n "sshnp:rw,sshrvd:rw"
    with your
    Windows username
    ,

    @<REPLACE>_np_key with your device atSign,

    <DEVICE_NAME> with the name of the machine you are on

    keys (windows path)
    • keys: C:\Users\alice\.atsign\keys\@example02_np_key.atKeys

  • manager

    • manager: example01_np

    • manager: '@example01_np'

  • Submitting enrollment request 
    Enrollment ID: ---------------------
    Waiting for approval; will check every 10 seconds
    notepad C:\ProgramData\NoPorts\sshnpd.yaml
    at_activate.exe enroll -a "@<REPLACE>_np" `
      -s <PASSCODE> `
      -p noports `
      -k C:\Users\<USER>\.atsign\keys\@<REPLACE>_np_key.atKeys `
      -d <DEVICE_NAME> `
      -n "sshnp:rw,sshrvd:rw"
    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.

    Open this to copy the code
    noports_base.py
    from subprocess import run, PIPE, Popen, CREATE_NO_WINDOW
    from socket import socket
    
    class noports_config:
        # NoPorts configs
        client_atsign: str
    

    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:

    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:

    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.

    Example of separate shortcuts into different folders

    --- 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.

    Open this to copy the code

    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:

    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:

    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.

    Example of separate shortcuts into different folders

    Frequently Asked Questions

    Common questions about NoPorts

    How NoPorts Works

    How is NoPorts different from Tailscale and Ngrok?

    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.

    Why is additional encryption needed when SSH provides its own encryption?

    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 works. Using NoPorts mitigates any man-in-the-middle attacks like Terrapin.

    Is sshnp a reverse SSH tunnel?

    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).

    The TCP layer is not taken out in your architecture. Does your protocol run over and above it?

    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.

    Relay Service and Network Behavior

    Is the relay necessary?

    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.

    If a bad actor takes down the relay, does the tool fail?

    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.

    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?

    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.

    Who pays the ingress & egress costs to the relay?

    These costs are included in the NoPorts subscription.

    Security and Access Control

    How do I close port 22?

    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).

    Additional notes for advanced users

    What Security Group rules are needed for CSP (Cloud Service Provider) deployments, for both data and control plane traffic?

    Security groups only need to allow outbound internet access.

    What npt or iptables rules are needed for non-CSP deployments, for both data and control plane traffic?

    Only outbound internet access via NAT/CGNAT is required.

    If the control plane is unreachable, what fallback or break-glass contingency is available?

    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.

    Why do I see man-in-the-middle warnings when connecting to my NoPorts devices?

    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.

    How can I prevent these warnings?

    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.

    1. 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:

    Why do I see extra entries in my ~/.ssh/authorized_keys file, and can I remove them?

    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.

    Component Deployment and Operation

    How are the NoPorts Tunnel, NoPorts daemon, and the NoPorts TCP relay service deployed?

    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 documentation for detailed instructions.

    How are these components started and managed?

    Systemd is the default service manager. Alternatives like cron and TMUX also work, but Systemd is recommended for standard deployments.

    How are these components patched or updated?

    To update, re-run the installation script. You can verify the currently deployed versions using the --list-devices option with with the sshnp command.

    Do these components require root privileges to run?

    No, these components must not run as root.

    How does SELinux affect these components?

    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.

    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?

    The sshnpd maintains a persistent connection to its atServer. Other interactions are event-driven.

    Does the bridging between ingress/egress ports within np services require the same NIC, or can it occur across different NICs?

    This involves standard TCP connections, so normal connectivity rules apply. No layer 2 bridging is performed; only TCP connections are established in user space.

    Scripting and Remote Command Execution

    Does NoPorts support scripting and remote command execution?

    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

    What are the requirements for executing remote commands via NoPorts?

    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.

    Usage and Protocol Support

    So, you can SSH without any open ports... what about RDP?

    You can use NoPorts Tunnel for RDP. demonstrates how.

    Did we miss something?

    If you have a question that needs answering, please do one of the following:

    • Create a new

    • Join and post to our 📑|forum channel

    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

    noports_base.py
    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"
    example_config.py
    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()
    override_defaults.py
    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()
    example_config.py
    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()
    override_defaults.py
    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()
    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"
    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.
    https://terrapin-attack.com/
    Installation
    This guide
    GitHub issue
    our discord
    Contact support via email
    Host 127.0.0.1
        StrictHostKeyChecking no
        UserKnownHostsFile /dev/null
        IdentityFile ~/.ssh/GitHub_rsa
        LogLevel QUIET
    By default, the hostname is used as the -dDEVICE_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.

    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:

    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.

    The other variables should be straightforward enough.

    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:

    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:

    After the install has completed, you can su - to the USERNAME you chose and see tmux/sshnpd running.

    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.

    You are now logged into the container. If you need root access, you can use the password you chose to sudo -s

    Feel free to adapt this outline to your specific needs and share your improvements back with the community.

    Client Installation

    Overview

    The SSH No Ports client (a.k.a. sshnp) is available as a command line application or desktop application (alpha). This guide is for installing the command line application, the desktop application installation guide will be made available upon official release.

    https://github.com/atsign-foundation/noports/blob/trunk/packages/dart/sshnoports/bundles/shell/headless/sshnpd.sh
    https://github.com/atsign-foundation/noports/blob/trunk/packages/dart/sshnoports/bundles/shell/headless/sshnpd.sh
    https://github.com/atsign-foundation/noports/blob/trunk/packages/dart/sshnoports/bundles/shell/systemd/sshnpd.service
    #!/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
    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
    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!"
    export USERNAME=ubuntu
    export PASSWORD="changeme"
    export CONFIG_URL="https://raw.githubusercontent.com/cconstab/sshnpd_config/main/config/sshnpd.sh"
    #sed -i 's/#ListenAddress 0.0.0.0/ListenAddress 127.0.0.1/' /etc/ssh/sshd_config
    ╰$ docker run -it -v ./install.sh:/root/install.sh debian:trixie-slim
    root@f5040633c8a0:/# cd
    root@f5040633c8a0:~# ls
    install.sh
    root@f5040633c8a0:~# ./install.sh 
    root@f5040633c8a0:~# su - ubuntu
    ubuntu@f5040633c8a0:~$ tmux ls
    sshnpd: 1 windows (created Sun Mar  3 22:48:01 2024)
    ubuntu@f5040633c8a0:~$ 
    ~/.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:~$
    #!/bin/sh
    # disable "var is referenced but not assigned" warning for template
    # shellcheck disable=SC2154
    # SCRIPT METADATA
    binary_path="$HOME/.local/bin"
    manager_atsign="@example_client" # MANDATORY: Manager/client address/Comma separated addresses (atSign/s)
    device_atsign="@example_device"  # MANDATORY: Device address (atSign)
    device_name="default"            # Device name
    user="$(whoami)"                 # MANDATORY: Username
    v="-v"                           # Comment to disable verbose logging
    s="-s"                           # Comment to disable sending public keys
    u="-u"                           # Comment to disable sending user information
    delegate_policy=""
    # END METADATA
    
    sleep 10 # allow machine to bring up network
    export USER="$user"
    while true; do
    	# The line below runs the sshnpd service, with the options set above.
    	# You can edit this line to further customize the service to your needs.
    	"$binary_path"/sshnpd -a "$device_atsign" -m "$manager_atsign" -d "$device_name" "$delegate_policy" "$s" "$u" "$v"
    	sleep 10
    done
    
    #!/bin/sh
    # disable "var is referenced but not assigned" warning for template
    # shellcheck disable=SC2154
    # SCRIPT METADATA
    binary_path="$HOME/.local/bin"
    manager_atsign="@example_client" # MANDATORY: Manager/client address/Comma separated addresses (atSign/s)
    device_atsign="@example_device"  # MANDATORY: Device address (atSign)
    device_name="default"            # Device name
    user="$(whoami)"                 # MANDATORY: Username
    v="-v"                           # Comment to disable verbose logging
    s="-s"                           # Comment to disable sending public keys
    u="-u"                           # Comment to disable sending user information
    delegate_policy=""
    # END METADATA
    
    sleep 10 # allow machine to bring up network
    export USER="$user"
    while true; do
    	# The line below runs the sshnpd service, with the options set above.
    	# You can edit this line to further customize the service to your needs.
    	"$binary_path"/sshnpd -a "$device_atsign" -m "$manager_atsign" -d "$device_name" "$delegate_policy" "$s" "$u" "$v"
    	sleep 10
    done
    
    [Unit]
    Description=Ssh No Ports 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 options set in
    # /etc/systemd/system/sshnpd.d/override.conf.
    # You can edit that config with: sudo systemctl edit sshnpd
    ExecStart=/usr/local/bin/sshnpd -a "$device_atsign" -m "$manager_atsign" -d "$device_name" "$delegate_policy" "$s" "$u" "$v" "$additional_args"
    
    Step 1. Download

    Step 1.1. Download from GitHub

    You can download a release from GitHub, or see the table below to download the latest release for your platform.

    Platform
    Linux
    macOS
    Windows

    x64

    (intel)

    arm64

    (apple)

    arm

    Step 1.2. Download using curl

    x64:

    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-x64.tgz -o sshnp.tgz

    arm64:

    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-arm64.tgz -o sshnp.tgz

    arm:

    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-arm.tgz -o sshnp.tgz

    risc-v:

    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-linux-riscv.tgz -o sshnp.tgz

    x64 (intel):

    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-macos-x64.zip -o sshnp.zip

    arm64 (apple):

    curl -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-macos-arm64.zip -o sshnp.zip

    x64:

    curl.exe -fSL https://github.com/atsign-foundation/noports/releases/latest/download/sshnp-windows-x64.zip -o sshnp.zip

    Step 2. Unpack the Archive

    If you downloaded from GitHub, the file name may be slightly different.

    Step 3. Install sshnp

    1. First, change directories into the unpacked download:

    1. Then run the installer:

    This will install the binaries to ~/.local/bin. Instead, if you'd like to install the binaries to /usr/local/bin, run the installer as root:

    1. First, change directories into the unpacked download:

    1. Then run the installer:

    This will install the binaries to ~/.local/bin. Instead, if you'd like to install the binaries to /usr/local/bin, run the installer as root:

    Windows doesn't have a dedicated installer at this time.

    You can find sshnp.exe in the unpacked archive, you may move this binary to wherever you like.

    Step 4. Add bin folder to the path

    This step is optional, but highly recommended.

    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:

    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:

    Step 5. Activate your client address

    If you don't own a pair of NoPorts addresses, please visit the registrar before continuing.

    Step 5.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.

    Now that you have at_activate installed, you can invoke the command with the name of the address you would like to activate:

    Now that you have at_activate installed, you can invoke the command with the name of the address you would like to activate:

    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.).

    Step 5.2. Activated this address before

    If you have activated the client address before, you must copy the address from another machine where it's been activated.

    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 sshnpd on.

    All Done!

    sshnp is ready to go, you can now proceed to installing your device, or if you've already done that, checkout our usage guide.

    tar -xf sshnp.tgz
    unzip sshnp.zip
    Expand-Archive -Force .\sshnp.zip
    cd sshnp
    ./install.sh sshnp && ./install.sh srv
    sudo ./install.sh sshnp && sudo ./install.sh srv
    export PATH="$PATH:$HOME/.local/bin";
    export PATH="$PATH:$HOME/.local/bin";
    ./at_activate -a @my_noports_client
    ./at_activate -a @my_noports_device

    risc-v

    sshnp-linux-riscv.tgz

    sshnp-linux-x64.tgz
    sshnp-macos-x64.zip
    sshnp-windows-x64.zip
    sshnp-linux-arm64.tgz
    sshnp-macos-arm64.zip
    sshnp-linux-arm.tgz
    cd sshnp
    ./install.sh sshnp && ./install.sh srv
    sudo ./install.sh sshnp && sudo ./install.sh srv
    Installing sshnpd with a single commandasciinema.org
    https://gist.githubusercontent.com/cconstab/142c942ce0c8caa3348d0976a60fbfd1/raw/d243d64573bf2b7de5e827ff9b7b7f2f2413901b/gistfile1.txtgist.githubusercontent.com
    Gist for sshnpd config file
    Logo
    Logo