Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(automated): Update docs from Gitbook #1258

Merged
merged 12 commits into from
Aug 30, 2024
Binary file added docs/.gitbook/assets/atPlanes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 3 additions & 6 deletions docs/installation/linux/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
---
description: Installation of client and server software
icon: linux
description: Installation of client and server software
---

# Unix Installation Guide
# Linux & MacOS Installation Guide

{% embed url="https://www.youtube.com/watch?v=HSthe7wVGao" %}
Prefer to follow along to a video ? Great ! Below you can just cut and paste along with Colin. 
{% endembed %}
{% embed url="https://www.youtube.com/watch?v=pYyGXpMWN0Y" %}

\
For more control of the installation look at the [advanced-installation-guides](../advanced-installation-guides/ "mention").

| Legend | Meaning |
Expand Down
44 changes: 23 additions & 21 deletions docs/reference/how-it-works.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
icon: magnifying-glass
description: >-
SSH No Ports uses Atsign’s end-to-end encrypted control plane to initiate SSH
connections without opening ports on either of your devices.
icon: magnifying-glass
---

# How It Works
Expand All @@ -20,26 +20,28 @@ icon: magnifying-glass
5. **Zero Trust**\
Atsign’s technology is designed so that cryptographic keys are only stored on the edge device. No third party or intermediary ever possesses the decryption keys which are required to access the information. You don’t need to trust any of the microservices, because they never see information in the clear.

## **How SSH No Ports uses Atsign’s Control Plane**

{% embed url="https://player.vimeo.com/video/859419053?app_id=122963&referrer=https://www.noports.com/" %}
**How SSH No Ports Works** (_This video doesn't include the new SR authentication and traffic encryption features yet, we will release an updated video soon!_) 
{% endembed %}

1. Alice wants to securely connect to her remote device, @alice\_device.
2. To initiate this, Alice’s client, @alice\_client, will first select a socket rendezvous, or SR for short.
3. The SR will issue two connection ports to @alice\_client by providing the host address and two port numbers. This is done through Atsign’s control plane, and the information is end-to-end encrypted.
4. Next, @alice\_client requests a connection to @alice\_device and shares one port from the SR.
5. The device, @alice\_device, generates a new ephemeral SSH key pair for the session.
6. @alice\_device automatically sends the ephemeral SSH private key to @alice\_client.
7. @alice\_device will then connect to the SR using Atsign's SR client. The SR client authenticates to the SR, then forwards @alice\_device's SSHD port to the SR. The SR client ensures that all traffic sent to the SR is encrypted, and it also decrypts all traffic from the SR.  
8. @alice\_client can now also connect and authenticate to the SR using the SR client. This side also encrypts all traffic to the SR, and decrypts all traffic from the SR, ensuring that the connection is fully end-to-end encrypted between @alice\_client and @alice\_device.
9. The SR connects both ports issued to @alice ensuring that traffic sent between the connection is able to reach the other side.
10. An SSH tunnel from @alice\_client is created over the connected tunnel through the SR to @alice\_device.
11. This tunnel forwards an ephemeral port on @alice\_client’s localhost to @alice\_device’s SSHD port.
12. Now the connection is ready! The application will provide an SSH command which can be used to connect over this tunnel.
13. When running the command, Alice will be able to SSH connect to @alice\_device!
14. Alice has successfully connected to her remote device, @alice\_device.
## **How SSH No Ports uses Atsign’s Control Plane & Policy Plane**

<div data-full-width="true">

<figure><img src="../.gitbook/assets/atPlanes.png" alt=""><figcaption><p>Planes of the atPlatform</p></figcaption></figure>

</div>

1. @client makes a request to @relay for two listening TCP/IP ports
2. @client contacts @server to get status and capabilities
3. @server responds if @client is permitted to connect, permission is either given locally or via @policy
4. @client derives a new ephemeral AES 256bit key and sends the key along with the IP/DNS name and one of the ports it received from @relay plus the requested remote host:service
5. @server confirms that @client is allowed to connect and to the service requested either locally or via @policy. If permitted, then @server makes a TCP/IP connection to @relay on the specified port and authenticates
6. @client makes a connection to @relay on the other port and authenticates
7. @relay then relays the data between the two TCP connections **@relay does not have the AES key** so cannot "see" the encrypted dataflow
8. @client listens on the localhost interface of the client and encrypts any connections made to it with the ephemeral AES key from stage 4
9. @server connects the to the required TCP/IP service requested in stage 5 and then encrypts the connection and forwards on to @relay
10. At this point a client application connects to the localhost interface on the client on the requested port and any data is encrypted and passed via @relay and on to @server then on to the listening service.

If the service requested by @client was SSH on @server for example. The `ssh` command would be directed to locahost on @client and yet in fact that connection would be forward to the `sshd` daemeon on @server, via the outbound connections to @relay.

This handshake takes a few seconds to make but once established the connection is near real time. You can see the handshake happening as you use the `sshnp` or the `npt` commands and if you what to see more details then, add the `-v` flag.



172 changes: 115 additions & 57 deletions docs/reference/underthehood.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@ icon: engine
# Under The Hood

{% hint style="info" %}
This document describes version 4.0.0-rc.2. Other versions use a different method of forming the connection.
This document describes version 5.6.x Other versions use a different method of forming the connection.
{% endhint %}

## Overview

There are three atSigns involved - one for each of
There are four atSigns involved - one for each of

* the noports daemon program (`sshnpd`) which runs on the device you want to ssh to
* the noports client program (`sshnp`) which you run on the device you want to ssh from
* 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`) creates a unique guid for the session
* 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
Expand All @@ -30,22 +31,14 @@ In brief
* 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 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
* opens a socket to the rv\_host:rv\_port\_1 and authenticates
* and opens a socket to its local sshd port
* and bridges the sockets together
* and bridges the sockets together whilst also encrypting data towards the rv\_host
* and sends a response notification to the `sshnp` client
* The client
* issues an ssh command like this to set up the ssh tunnel and do a local port forwarding

```
/usr/bin/ssh [email protected] -p 40189 -i /Users/gary/.ssh/noports \
-L 58358:localhost:22 -t -t -f \
-o StrictHostKeyChecking=accept-new -o IdentitiesOnly=yes \
-o BatchMode=yes -o ExitOnForwardFailure=yes \
sleep 15
```
* 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.
Expand All @@ -58,7 +51,15 @@ This high-level flow is visualized in the diagrams below.

### Overview diagram

![](../.gitbook/assets/overview.png)
<div data-full-width="true">

<img src="../.gitbook/assets/atPlanes.png" alt="">

</div>

### 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.&#x20;

### Control plane

Expand All @@ -67,53 +68,110 @@ In the following sequence diagram, atServer address lookup flows, authentication
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

```mermaid
sequenceDiagram
participant C as sshnp (@client)
participant R as sshrvd (@rv)
participant D as sshnpd (@device)

note over R,D: service startups
D->D: Authentication
D->D: Start monitor <br> (notification listener)

R->R: Authentication
R->R: Start monitor <br> (notification listener)

note left of C: user runs the sshnp program
C->C: Authentication
C->C: Start monitor <br> (notification listener)

note left of C: sshnp sends session request <br> notification to sshrvd
C->C: Create sessionId guid to send to @rv
C->C: Encrypt message to send to @rv
C->>R: Send notification to @rv <br> requesting host and port

R->R: Decrypt request payload
R->R: Find two unused ports
R->R: Create an isolate <br> which creates server sockets <br> on the ports, waits for connections, <br> and joins their i/o streams
R->R: Create and encrypt <br> response message containing <br> sessionId, host, port_1, port_2
R->>C: Send response notification <br> to @client

C->C: Create and encrypt request message <br> to send to @device (sessionId, host, port1)
C->>D: Send request to sshnpd
D->>D: SPAWN an sshrv process
D->>R: (Spawned) Open socket $npd_to_rv to host:port_1
D->>D: (Spawned) Open socket $npd_to_sshd to localhost:22
D->>D: (Spawned) Join $npd_to_rv and $npd_to_sshd <br> i/o streams, and vice versa
D->>C: Send "connected" response notification if spawned successfully
C->>C: Find an available $local_port<br>or use one supplied by the user via the command line
C->>C: Spawn an initial ssh command to set up the local port forwarding tunnel
C->>C: If spawned successfully, Write to stdout: "ssh -p $local_port $username@localhost"
sequenceDiagram
participant c as client
participant cs as client atServer
participant rs as relay atServer
participant r as relay
participant ds as daemon atServer
participant d as daemon

note over c,d: Phase - Background services startup
par
r ->> rs: connect
r ->> rs: pkam authenticate
r ->> rs: monitor for notifications
and
d ->> ds: connect
d ->> ds: pkam authenticate
d ->> ds: monitor for notifications
end


note over c,d: Phase - Ping daemon
c ->> cs: connect & pkam authenticate
c ->> cs: monitor for notifications
alt
c ->> d: ping the daemon
activate d
else actual data flow
c -->> cs:
cs -->> ds:
ds -->> d:
end


note over c,d: Phase - Request relay session
alt
c ->> r: request two public ports from relay: {session id, nonce from client}
else actual data flow
c -->> cs:
cs -->> rs:
rs -->> r:
end
r ->> r: Request ephemeral ports from OS
alt
r ->> c: ports response from relay: {session id, host1:port1, host2:port2, nonce from relay}
else actual data flow
r -->> rs:
rs -->> cs:
cs -->> c:
end

note over c,d: Phase - Receive ping response from daemon: {list of available features}
alt
d ->> c: ping response (device info / features) from daemon
deactivate d
else actual data flow
d -->> ds:
ds -->> cs:
cs -->> c:
end
c ->> c: Validate request against daemon ping info

note over c,d: Phase - Request daemon session
c ->> c: generate new aes encryption key & iv nonce
alt
c ->> d: send session request to the daemon: {host2:port2 from relay, aes stream encryption key, aes iv nonce, requested service to access (host:port), nonce from relay, nonce from client}
else actual data flow
c -->> cs:
cs -->> ds:
ds -->> d:
end
d ->> d: Verify perimissions for client's request (based on session request info - i.e. is client allowed to connect?)
d -x r: [TCP - A] Reverse TCP the requested service to open relay host2:port2
d -x r: [TCP - A] Send auth string (signed json payload of: session id, nonce from relay, nonce from client)
r ->> r: [TCP - A] Verify auth string
alt
d ->> c: session (success) response from daemon
else actual data flow
d -->> ds:
ds -->> cs:
cs -->> c:
end
note over c,d: Phase - Client TCP connect
c ->> c: Bind a local socket to expose the service on
c -x r: [TCP - B] TCP connect to the other open relay port
c -x r: [TCP - B] Send auth string (signed json payload of: session id, nonce from relay, nonce from client)
r ->> r: [TCP - B] Verify auth string
note over c,d: Phase - internal traffic relays (lasts entire duration of the session)
par
r -->> r: relay all traffic from [TCP - A] to [TCP - B] and vice-versa
and
c -->> c: relay all traffic from [TCP - A] to local socket and vice-versa
end
note over c,d: Phase - using the connection
c ->> c: You connect to the local socket as if it were the remote service!
```

### 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 device port 22 and $rv\_host:$rv\_port\_1
* there is an ssh process running on the client host which provides the local port forwarding tunnel
* User may now type "ssh -p $local\_port username@localhost" with traffic flowing
* 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
Expand Down
20 changes: 19 additions & 1 deletion docs/usage/integrate-with-ssh-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ icon: square-sliders-vertical

## The Template

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

{% code title="~/.ssh/config" overflow="wrap" lineNumbers="true" %}
```
Expand All @@ -20,6 +20,24 @@ Host <host>
```
{% endcode %}

Example:

{% code overflow="wrap" %}
```
Host alice_device
Hostname localhost
AddKeysToAgent yes
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
IdentityFile ~/.ssh/id_ed25519
ProxyCommand=$(sshnp -f @alice_client -t @alice_device -r @rv_am -d my_device -u <username> -x 2>/dev/null) -W "%h:%p" -o "StrictHostKeyChecking=no"
```
{% endcode %}

```
sshnp -f @alice_client -t @alice_device -d my_server -r @rv_am
```

### Usage

Use this config as you would any other ssh config entry:
Expand Down
26 changes: 26 additions & 0 deletions docs/use-cases/be-your-own-vpn.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,32 @@ Be your own VPN

With this example, you can see that port `63155` was used in the sshuttle command. You do not need to SSH into the machine—you can just get the port number and use `sshuttle.` The choice is yours.

This can get a bit tedious to do every day so feel free to script for your environment. Here is an example bash script that does just that!

```bash
#!/bin/bash
#
export USER=$USER
export SSHNPHOME=$HOME/.local/bin <--<default-location-for-SSHNP>
export HOSTDEVICE=<your-host-running-SSHNPD>
export CLIENTATSIGN=<your-local-atsign format @34mypersonalatsign>>
export HOSTATSIGN=<the-host-device-atsign format @55hostdeviceatsign>
export LOCALPORT=<the-port-ito-use-forconnection example 46393>
export SRVD=<atSign-of-srvd-daemon example @rv_eu or @rv_am or @rv_ap>
export NETA=<network-CIDR-style example 0/0 or 10.0.0.0/8>
export NETB=<network-CIDR-style example 172.16.0.0/16>
export NETC=<network-CIDR-style example 192.168.1.0/24>
#
echo ""
echo Starting Atsign SSHNP connects to $HOSTDEVICE on port 46393 for personal VPN
echo ""
#
$SSHNPHOME/sshnp --from $CLIENTATSIGN --to $HOSTATSIGN --srvd $SRVD --remote-user-name $USER --output-execution-command --idle-timeout 90 --device $HOSTDEVICE --local-port $LOCALPORT
sleep 3
sshuttle --dns -r [email protected]:$LOCALPORT $NETA $NETB $NETC
#
```

### SOCKS

If you are using Windows, this is likely your best option unless you are comfortable setting up a virtual machine and using sshuttle.
Expand Down