diff --git a/docs/.gitbook/assets/atPlanes.png b/docs/.gitbook/assets/atPlanes.png
new file mode 100644
index 000000000..92cbcbc50
Binary files /dev/null and b/docs/.gitbook/assets/atPlanes.png differ
diff --git a/docs/installation/linux/README.md b/docs/installation/linux/README.md
index 1dfd78d81..279df83d5 100644
--- a/docs/installation/linux/README.md
+++ b/docs/installation/linux/README.md
@@ -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 |
diff --git a/docs/reference/how-it-works.md b/docs/reference/how-it-works.md
index a18de298d..173eca2b0 100644
--- a/docs/reference/how-it-works.md
+++ b/docs/reference/how-it-works.md
@@ -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
@@ -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**
+
+
+
+
Planes of the atPlatform
+
+
+
+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.
diff --git a/docs/reference/underthehood.md b/docs/reference/underthehood.md
index 40564561d..ad2733808 100644
--- a/docs/reference/underthehood.md
+++ b/docs/reference/underthehood.md
@@ -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
@@ -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 gary@85.239.63.180 -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.
@@ -58,7 +51,15 @@ This high-level flow is visualized in the diagrams below.
### 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
@@ -67,43 +68,100 @@ 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 (notification listener)
-
- R->R: Authentication
- R->R: Start monitor (notification listener)
-
- note left of C: user runs the sshnp program
- C->C: Authentication
- C->C: Start monitor (notification listener)
-
- note left of C: sshnp sends session request 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 requesting host and port
-
- R->R: Decrypt request payload
- R->R: Find two unused ports
- R->R: Create an isolate which creates server sockets on the ports, waits for connections, and joins their i/o streams
- R->R: Create and encrypt response message containing sessionId, host, port_1, port_2
- R->>C: Send response notification to @client
-
- C->C: Create and encrypt request message 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 i/o streams, and vice versa
- D->>C: Send "connected" response notification if spawned successfully
- C->>C: Find an available $local_port 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
@@ -111,9 +169,9 @@ sequenceDiagram
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
diff --git a/docs/usage/integrate-with-ssh-config.md b/docs/usage/integrate-with-ssh-config.md
index 26e7eae81..edaa5b9bf 100644
--- a/docs/usage/integrate-with-ssh-config.md
+++ b/docs/usage/integrate-with-ssh-config.md
@@ -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" %}
```
@@ -20,6 +20,24 @@ 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 -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:
diff --git a/docs/use-cases/be-your-own-vpn.md b/docs/use-cases/be-your-own-vpn.md
index 2205e6f87..7964cce8c 100644
--- a/docs/use-cases/be-your-own-vpn.md
+++ b/docs/use-cases/be-your-own-vpn.md
@@ -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 <--
+export HOSTDEVICE=
+export CLIENTATSIGN=>
+export HOSTATSIGN=
+export LOCALPORT=
+export SRVD=
+export NETA=
+export NETB=
+export NETC=
+#
+echo ""
+echo Starting Atsign SSHNP connects to $HOSTDEVICE on port 46393 for personal VPN
+echo ""
+#
+$SSHNPHOME/sshnp --from $CLIENTATSIGN --to $HOSTATSIGN --srvd $SRVD --remote-user-name $USER --output-execution-command --idle-timeout 90 --device $HOSTDEVICE --local-port $LOCALPORT
+sleep 3
+sshuttle --dns -r $USER@127.0.0.1:$LOCALPORT $NETA $NETB $NETC
+#
+```
+
### SOCKS
If you are using Windows, this is likely your best option unless you are comfortable setting up a virtual machine and using sshuttle.