A QNAP NAS runs a custom Linux operating system, providing storage and other services in a consumer and small to medium business environment.
Installing the Agilicus Connector on the NAS can facilitate accessing the shares remotely, as well as providing a means of remote management.
Install
The Agilicus Connector will run as a container on the QNAP. In order to do this, you must have the Container Station feature enabled.
Enable QNAP Container Station
Create Agilicus Connector as Container
There are two methods to this: via the QNAP Web management interface, and, via the QNAP shell. Both achieve the same objective. If you use the QNAP Web management interface, be aware there is an expiry time on the challenge-id when you are copying from the Agilicus admin interface.
Option 1: QNAP Web interface
You will copy 3 fields from the Agilicus connector install screen (Resources/Connectors/New): two environment variables, and one image. The image should be cr.agilicus.com/pub/images/agilicus-agent/client:stable and the environment variables will be AGILICUS_CHALLENGE_ID=XXX and AGILICUS_CHALLENGE_CODE=XXX. These latter two are only good for a few minutes, regenerate if it takes you longer.
You will likely want to mount /Share into /Share (via bind host mount path), allowing re-exporting shares via Agilicus Share.
Option 2: Paste via Shell
The command line given from the Agilicus Admin interface on the install new connector, docker tab, will work as-is, you can just paste it. However, you will likelywant to mount /Share into /Share (via bind host mount path), allowing re-exporting shares via Agilicus Share. You can achieve this by adding -v /Share:/Share into the command line before the image. This will look like:
In this sample, we are going to use a single service forwarder to transfer a port from the local connector to a remote connector, and, over top of that, run a web socket UDP tunnel, and, over top of that, run a Wireguard VPN. This will provide layer 3 adjacency. We will use wstunnel to facilitate. We will use the Agilicus connector to facilitate the inbound/outbound connectivity, and, authenticate via a Service Account for always-on operation.
For the sample, we assume the main site and the remote site(s) each have a device running Linux (the sample is for Debian or Ubuntu). We also assume the sites have non-overlapping IP (avoiding the need for NAT in either of the directions).
High Level Steps
Create a connector on each of ‘Main site’ and ‘Remote site’
Create a network on Remote Site, using destination 127.0.0.1, port 4443
Create a service forwarder, via ‘Main Site’, listening on 127.0.0.1 port 4443, destination the network created above
Run ‘wstunnel’ on Remote site, listening for connections on 127.0.01 4443
Run ‘wstunnel’ on Main site, sending connections to 127.0.0.1, port 4443
Run wireguard on each of the sites, using wstunnel as the source/sink
Agilicus Connector & Network Setup
In this example, we assume your domain is connect.example.org. This you would use https://admin.connect.example.org for administration. We assume you are going to have two sites connected, ‘main’, and ‘remote-1’ (you can later add more remotes).
Main: Connector & Service Account & Application Setup & SSH
On the ‘main’ site, install an Agilicus Connector.
Now we will create a ‘application’ to use this Connector. First, we will create a Service Account, a special system user that will have always-on permission to use it.
Now, we will create an “application’ to use this Connector.
Now we will assign permissions to the Service Account we created above:
Download and save the ‘Authentication Document’ for this Service Account, we will use it below. Also, copy and save the service account email, we will use that below.
Now, let us setup SSH so we can remotely administer this device:
NOTE: feel free to modify the options. The ‘DISCUSS’ on users auto-signing in, this may be a convenient way to use a browser-based sign in without giving users the password of the device.
At this stage we are complete setting up ‘main’.
Remote: Connector & SSH
Install the connector as above in main, switching the connector name to remote-1.
Setup SSH as above in ‘main’, switching the connector to remote-1 and the SSH name.
Checks
If we examine the connector screen, we can see that each of our new connectors exists, and has SSH bound to it, as well as ‘main’ has the wireguard service from the application we created:
We can also check by opening https://profile.connect.example.org and hitting refresh, we should see an SSH icon for each, and, if selected, should be able to sign-in. NOTE: we recommend creating an SSH key and using the native integration for a more seamless and secure experience.
Linux Setup
We now have some Linux-specific setup to do, outside the scope of Agilicus AnyX. This is to install a site-to-site connectivity agent called ‘wireguard’ and a WebSocket tunnel to facilitate it.
Install Wireguard: Main
On the ‘main’ site Linux device, run the following commands as root (e.g. run sudo su - first):
apt-get update
apt-get install -y wireguard wireguard-tools
mkdir -p /etc/wireguard
chmod 700 /etc/wireguard
cd /etc/wireguard
wg genkey | tee wg.key | wg pubkey > wg.pub
chmod 600 /etc/wireguard/*.key
KEY=$(cat wg.key)
cat <<EOF > wg0.conf
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
SaveConfig = false
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PrivateKey = $KEY
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
EOF
echo -e "\nCopy below line to remote machine:"
echo -e "MAIN_KEY=$(cat wg.pub)\n"
Install Wireguard: Remote
On the ‘remote’ site Linux device, run the following commands as root (e.g. run sudo su - first):
<<PASTE MAIN_KEY=... LINE FROM ABOVE>>
MAIN_SUBNET=172.16.30.0/24
apt-get update
apt-get install -y wireguard wireguard-tools
mkdir -p /etc/wireguard
chmod 700 /etc/wireguard
cd /etc/wireguard
wg genkey | tee wg.key | wg pubkey > wg.pub
chmod 600 /etc/wireguard/*.key
KEY=$(cat wg.key)
cat <<EOF > wg0.conf
[Interface]
Address = 10.8.0.2/24
SaveConfig = false
PrivateKey = $KEY
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
[Peer]
PublicKey = $MAIN_KEY
AllowedIPs = 10.8.0.0/24,$MAIN_SUBNET
Endpoint = 127.0.0.1:51821
PersistentKeepalive = 10
EOF
echo -e "\nCopy below line to main machine:"
echo -e "REMOTE_KEY=$(cat wg.pub)\n"
Add Remote Trust to Main
On the ‘main’ site Linux device, run the following commands as root (e.g. run sudo su - first). This will cause it to trust the remote.
<<PASTE REMOTE_KEY=... LINE FROM ABOVE>>
REMOTE_SUBNET=172.16.0.0/24
cat <<EOF >> wg0.conf
[Peer]
PublicKey = $REMOTE_KEY
AllowedIPs = 10.8.0.0/24,$REMOTE_SUBNET
EOF
Examine Wireguard Configuration
Now, let us examine the configuration. On the ‘main’ site, run cat /etc/wireguard/wg0.conf’ and observe the output, as below:
Reading, we can see that the ‘server’ has a private key, and the remotes it trusts have a public key. Also, the ‘main’ is going to have an IP of 10.8.0.1, we will assign 10.8.0.2 to the remote.
On the ‘remote’ site, let us also examine the config. We can see the assign of the 10.8.0.2 IP
systemctl status wstunnel
● wstunnel.service - Tunnel WG UDP over websocket
Loaded: loaded (/etc/systemd/system/wstunnel.service; enabled; preset: enabled)
Active: active (running) since Sat 2024-09-14 16:51:03 EDT; 4s ago
Main PID: 1437967 (wstunnel)
Remote WebSocket Setup
Now on the ‘remote’ site, we will setup the WebSocket tunnel. First, we will create an API Key which gives us permission to the Service Account we created above. There is no exposed facility in the Web administration to create API keys, so we will use the CLI. You can do this on your Windows machine, or, on the Linux machine. The machine needs Python installed, see https://www.python.org/downloads/windows/ .
First we will install the Agilicus CLI & SDK using ‘pip install -U agilicus’ (this works equally on Windows or Linux).
Then, we will list the users of type service_account to find the one we created above. A browser will open the first time to obtain your credentials for this operation.
The Network can be accessed using the service account ’email’ we obtained above, and the API key we just created.
Let us test the API key with curl. First, lets see that if we open it with a browser, we are forced to try and sign in (we will not be able to sign-in, but this will tell us the application is up). Now, let us try with curl. Fill in your values on the first two lines, and, replace connect.example.org with your domain.
OK, now that we have tested the connection, let us install the remote-1 site tunnel. Fill in your values on the first two lines, and, replace connect.example.org with your domain.
Now, devices on the remote side will need a route installed, using the lan-side IP of the Linux device. Similarly, the main side devices will need a route installed, using the lan-side IP of the Linux device.
The WAGO Edge Controller is a flexible and open control platform for many embedded and industrial applications. It provides an excellent vantage point to run the Agilicus Connector.
WAGO Edge Controller
The WAGO Edge Controller is a flexible and open control platform for many embedded and industrial applications. It provides an excellent vantage point to run the Agilicus Connector.
The below instructions were tested on firmware 04.04.03(26) on the following devices:
WAGO Compact Controller CC100 751-9301
WAGO Controller PFC200 750-8212
There are two deployment methods available on the platform:
Native Install. The Agilicus Connector runs as part of the baremetal Host Linux distribution
Docker Install. The WAGO Edge Controller runs a container runtime
Since the Agilicus Connector has no local state other than the encryption keys, there is no specific preference as to which method to choose. If you are using Service Forwarders inbound to the device, you will likely want the native install to enable Machine to Machine communication from a local network.
Preparation
NOTE
❗
Agilicus AnyX uses modern cryptography which requires proper time. Please ensure NTP is configured.
Requirements
In order to deploy the Agilicus Connector successfully the following steps should be undertaken
Verify that sufficient (~200MB) disk space or expanded storage is available (Typical 1.1GB onboard eMMC available)
Enable SSH terminal access via Web UI
Configure and Sync NTP based time
Have WAN access with DNS resolution and network segmentation permitting the Controller to reach the Agilicus AnyX cloud IP address over TLS
Confirm SSH is Enabled:
Confirm that your Controller has access to a local or remote NTP Server in order to maintain accurate time
Option 1. Native Install
The WAGO Edge Controller natively supports the Agilicus Connector. Install the connector as usual, selecting ‘Linux’, and paste the given command into an administrative (root) shell via SSH.
The results will look as below:
INFO[2024-07-25T00:52:33+02:00] Starting connector - version v0.264.16
INFO[2024-07-25T00:52:36+02:00] Check if the agilicus connector is already running as a service. If so stop it
INFO[2024-07-25T00:52:37+02:00] Create file /usr/bin/agilicus-agent-wrapper.sh
INFO[2024-07-25T00:52:37+02:00] Create file /etc/init.d/agilicus-agent
INFO[2024-07-25T00:52:37+02:00] Will install to /agilicus-agent-wrapper.sh -> {/usr/bin/agilicus-agent-wrapper.sh -rwxr-xr-x <nil>}
INFO[2024-07-25T00:52:37+02:00] Will install to /agilicus-agent-bb.sh -> {/etc/init.d/agilicus-agent -r-xr-xr-x <nil>}
INFO[2024-07-25T00:52:37+02:00] Will install to /agilicus-agent-wrapper-bb.sh -> {/usr/bin/agilicus-wrap -r-xr-xr-x <nil>}
INFO[2024-07-25T00:52:37+02:00] Create a directory at /opt/agilicus/agent/tufmetadata/latest
INFO[2024-07-25T00:53:29+02:00] Create a user and group named Agilicus to run the agilicus-agent service
INFO[2024-07-25T00:53:29+02:00] Copy executable to /opt/agilicus/agent
INFO[2024-07-25T00:53:29+02:00] Set permissions to Agilicus on /opt/agilicus/agent
INFO[2024-07-25T00:53:29+02:00] Create symlink from /usr/bin/agilicus-agent to /opt/agilicus/agent/agilicus-agent-arm
INFO[2024-07-25T00:53:30+02:00] creating connector instance
INFO[2024-07-25T00:53:31+02:00] Join a connector cluster
INFO[2024-07-25T00:53:31+02:00] Start agilicus-agent service
INFO[2024-07-25T00:53:31+02:00]
INFO[2024-07-25T00:53:31+02:00] Installation Complete
INFO[2024-07-25T00:53:31+02:00]
You can verify the Agilicus Connector instance status in the Connector Overview interface.
Option 2. Docker Install
NOTE
❗
Currently the docker installation support is restricted to 64bit ARMv8 architecture. Support for the 32bit ARMv7 is pending, we recommend Option 1 for these models. Contact us if you are unsure which architecture your controller uses.
Additional Requirements
As a primer, make sure to consult the WAGO documentation for the latest supported hardware and configurations of Docker.
If using Docker, make sure you understand the requirements of installing and running Docker service on the controllers with the WAGO Quickstart Guide on Docker available here:
Verify that the WAGO Controller model supports Docker
Deploy and Enable Docker via Web UI
Confirm Docker is enabled on the device by logging into the Web Interface:
SSH to the Controller with the admin credentials and elevate your session to root privileges:
Verify that docker is installed:
Create and Deploy AnyX Connector
Navigate to your Agilicus AnyX Admin page for your organisation and create a new connector instance under Resources -> Connectors -> New
Once created, proceed with Installation and select the Docker tab in the installation menu:
Copy the text block by clicking on the blue “Copy” icon.
Paste the text block in your Controller SSH Session:
Verify that docker is now running an ‘agilicus-connector’ container
Verify in the Agilicus AnyX admin interface that the connector instance is up and communicating with the cloud platform. The Instance dialog should display the WAGO controller hostname and a status of GOOD:
Troubleshooting
If the docker installation fails or the container fails to start, running docker logs will provide a lengthy and verbose output of the installation and initialisation process of the container.
The NanoPI R5S has 2 x Gigabit Ethernet, 1GiB of RAM, and 32GB of eMMC storage. With its large passive heatsink it is an ideal platform to use as a small router. It also makes an ideal platform to run the Agilicus Connector.
The NanoPi R2S will run several operating systems (Ubuntu, Armbian, OpenWRT). In this document we discuss using it with OpenWRT.
Installing OpenWRT
As received, the NanoPi R2S will (usually) be running FriendlyWRT. You may feel free to use this, however it has some security flaws. Agilicus recommends using the native OpenWRT build. You may build it yourself, or obtain from the OpenWRT Project.
Connect your laptop to the LAN ports (furthest to the USB-C power connector).
Select ”Choose File’ and the file you just downloaded
Select ‘Upload and Write’
Wait approximately 90 to 120 seconds
At this stage you are running the Agilicus-supplied OpenWRT image.
Agilicus Connector Install
Using the Agilicus administrative portal, create a new connector. Use the ‘Linux’ instructions, copy.
In the OpenWRT admin interface (http://192.168.2.1/), select ‘Services/Terminal’. Sign in as root and the password you selected. Paste (shift-insert).
At this time the connector should be installed and you may close the terminal.
You may wish to enable access to this router via the Agilicus AnyX platform (notably SSH and Admin web interface).
NOTE: DHCP Server Enable
Depending on your use, you may wish to have a DHCP server on the LAN ports, you can enable this under ‘Network/Interfaces/LAN’. You may also configure your desired IP range here.
❗
It is appropriate to have a DHCP server on these LAN ports if this is an isolated network. If you are connecting to a larger network with an existing DHCP server, you probably wish to instead change the protocol on the LAN ports to DHCP Client.
NOTE: Time Sync (NTP)
Modern cryptography requires clock sync and accuracy on all devices. Typically this is performed via Network Time Protocol, however, in some environments this is blocked (e.g. HTTPS-only outbound).
If your clock is not sync’d (see System/Time Synchronisation menu), you might be able to use a local NTP server. If not, you can enable an HTTPS-based sync as below:
service htpdate enable
service htpdate start
This is going to use the Agilicus API to provide an HTTP-based (over HTTPS port 443) time service. Configuration can be observed in /etc/config/htpdate:
Once you have installed the Agilicus Connector, we recommend disabling the web terminal. On ‘Services/Termina’, select the config tab and remove the check-box beside ‘Enable’.
You may re-enable the web terminal later if you need it. However, we recommend using SSH instead for future command-line access.
The web terminal operates on a secondary TCP port (7681) and is not needed for normal operation.
SSH Setup
Agilicus recommends disabling password access to SSH in favour of SSH Keys.
On System/Administration, the SSH Access tab, uncheck ‘Password authentication’ and uncheck ‘Allow root logins with password’.
The rationale here is that password stuffing and guessing is a thing. Eventually someone will guess your l33t-hax0r password. Removing any ability to use passwords reduces the risk. In some controls environments any passwords can be disallowed.
Once you have disabled password access, we recommend adding a SSH Key. Agilicus recommends using ed25519 SSH keys since they are smaller and more secure. Add your public key to the router here and place the private key (with passphrase!) in your SSH Agent on your desktop.
SSH keys are not only more secure, but also more convenient.
One downside to note: the Agilicus web interface for SSH is not currently compatible with SSH keys. If you wish to have SSH access to this device via the Agilicus Profile web interface, keep password on.
Firewall
At this stage, configure the firewall and NAT settings to suit on each of the interfaces. If the Agilicus Connector is providing Service Forwarder services, remember to open this ports on the router too.
We can check which ports are listening by running netstat -nlpt as below. Things with 0.0.0.0:PORT are available from outside the device. Things listening on 127.0.0.1, fe80::, ::1, etc, are locally bound only. In the example below, ‘uhttpd’ (the admin web interface), ‘dropbear’ (SSH) and ‘ttyd’ (the web terminal) are the only things listening.
This walk through shows an example of how, once the connector is installed (as per above), configuration of an HTTP and SSH interface to this local device. Once these are configured you could use the firewall to disable all external access. The high level steps are:
Create Connector (Agilicus Admin)
Install Connector (NanoPi Web Terminal)
Create SSH Resource (Agilicus Admin)
Create Web Resource (Agilicus Admin)
Assign Web Resource Permission (Agilicus Admin)
SSH to NanoPi from Agilicus Profile (Agilicus Profile)
Open Web Interface to NanoPi (Agilicus Profile or direct)
OK, let’s get started. This will take approximately 5 minutes.
Install the Agilicus connector directly on the PLC for highest security and simplest deployment.
Phoenix Contact PLCnext AXC F x152
The Phoenix Contact PLCnext AXC F 2152 (and 1152 and 3152) provide an ideal platform to run the Agilicus Connector. It has enough storage, CPU, its in the right vantage point in the network. Once installed, you can use it for programming, or for operations.
The installation is the same as all other Linux platforms.
First, we SSH into the PLC. This is typically ssh admin@plc with username ‘admin’ and password ‘plcnext’.
Next we must enable the root password if we have not already:
sudo passwd root
(admin password)
(new root password)
(new root password)
At this stage we can become root:
su - root
(new root password)
#
At this stage, go to the Agilicus admin interface and create a new connector. Select the ‘Linux’ install and paste into the ssh window above:
As a reminder, this command line times out in 10 minutes, if you have note done those steps above first, just regenerate the command-line
The correct output will look something like below. You may need to have DNS enabled and NTP (for time).
NOTE: Enable NTP via you may wish to set the timezone to UTC first:
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
root@sim-axcf2152:~# which curl && (curl -sSL agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh) || (wget -O - agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh); sh /tmp/i.sh -c XXXX -s -d /usr/bin/curl OS: , Machine: , END: Fetching https://www.agilicus.com/www/releases/secure-agent/stable/agilicus-agent-arm into /tmp/agilicus-agent-arm -rwxr-xr-x 1 root root 49872896 May 28 19:04 /tmp/agilicus-agent-arm
'[' challenge = explicit ']'
/tmp/agilicus-agent-arm client --install --challenge-id XXX --challenge-code XXX --debug INFO[2024-05-28T19:04:28Z] Starting connector - version v0.261.1
INFO[2024-05-28T19:04:31Z] Create file /etc/init.d/agilicus-agent
nEBU[2024-05-28T19:04:32Z] isSystemd: false
INFO[2024-05-28T19:04:32Z] Will install to /agilicus-agent-sysvinit.sh -> {/etc/init.d/agilicus-agent -r-xr-xr-x }
INFO[2024-05-28T19:04:32Z] Will install to /agilicus-agent-wrapper-sysv.sh -> {/usr/bin/agilicus-wrap -r-xr-xr-x }
INFO[2024-05-28T19:04:32Z] Will install to /agilicus-agent-wrapper.sh -> {/usr/bin/agilicus-agent-wrapper.sh -rwxr-xr-x }
INFO[2024-05-28T19:04:33Z] Create a directory at /opt/agilicus/agent/tufmetadata/latest
INFO[2024-05-28T19:04:33Z] Create a directory at /opt/agilicus/agent/tufmetadata/stable
INFO[2024-05-28T19:04:51Z] Create a user and group named Agilicus to run the agilicus-agent service
INFO[2024-05-28T19:04:51Z] Copy executable to /opt/agilicus/agent
INFO[2024-05-28T19:04:51Z] Set permissions to Agilicus on /opt/agilicus/agent
INFO[2024-05-28T19:04:51Z] Create symlink from /usr/bin/agilicus-agent to /opt/agilicus/agent/agilicus-agent-arm
INFO[2024-05-28T19:04:53Z] creating connector instance
INFO[2024-05-28T19:04:53Z] Join a connector cluster
INFO[2024-05-28T19:04:53Z] Start agilicus-agent service
INFO[2024-05-28T19:04:54Z] INFO[2024-05-28T19:04:54Z] Installation Complete INFO[2024-05-28T19:04:54Z]
Please check the online status in the web interface under Resources/Connectors/Overview' Please check the online status in the web interface under Resources/Connectors/Overview
If you have questions, or errors were shown above, please email support@agilicus.com.' If you have questions, or errors were shown above, please email support@agilicus.com.
At this stage we can check its running. In the Agilicus admin interface, the connector line will go ‘GREEN’ (Good) within a minute or so. We can also test on the PLC:
# ps -ef|grep agilicus
that line should show the service running.
The Agilicus Connector also works on the PLCnext simulator.
Many desktop, server, embedded systems support container runtimes. The most widely used syntax and name recognition, Docker, gives a convenient simple command-line interface.
The Agilicus connector can natively run inside a connector. This provides a convenient method of experimenting (or deploying) with low cost, high simplicity.
For people wishing to run the connector on an Apple MAC, this is the best approach.
Create the connector as normal, select ‘Docker’ from the install type tab at the top and paste into the machine running the container runtime.
By default this command creates a volume ‘agilicus_cfg’ and uses ‘host’ networking.
Two ephemeral security identifiers (CHALLENGE_ID, CHALLENGE_CODE) are provided, these are claimed once and then discarded. You must paste the command line within 10-minutes of generating it.
Once complete, you will see the connector come online as normal.
Note: for a ‘share’, you may need to mount a volume into the container (e.g. -v /Documents:/Documents), otherwise only the internal filesystem of the container is available.
Installing an Agilicus Connector creates a new type of user, a service account.
Connector Install: Sign-In
Installing an Agilicus Connector creates a new type of user, a service account. This service account is created automatically for you, using your (the administrators) privilege as a bootstrap. This service account has a restricted set of abilities. You may see (and delete after deleting a connector) in the admin front end under ‘Access/Service Accounts’.
Once this service account is created, the Connector will use this identity without further user intervention.
In order to create the service account, and get its credentials, the install process needs you to authorise it. To do this, 2 methods exist (both yield identical results):
Open a new browser, request you to sign in. This in turn uses a ‘callback’ URI that points to the host you are trying to install the connector on. Your browser, upon finishing the sign-in flow, will do a redirect to http://localhost:<someport>, passing the access token forward.
Copy a URL you are given, paste it into your browser, this will give you a code, paste that back into the location you started the install from.
Typically if you are using a graphical desktop operating system, and signed into it as yourself, you would use method #1. If you are remotely accessing a system, or it is a headless embedded device, you would use method #2.
In some cases both methods are available, in which case the first one to answer will be used.
Note: The Connector installation process should be run with Administrative (e.g. Root, LocalAdmin privilege). If you do not, it will attempt to elevate for you (as you can see in the below example).
A console log of the initial install process is shown below. In this example, you would have seen your browser open automatically with a sign-in screen as above right. If you sign in this way, the installation will complete. Instead, you may copy the URL given (https://auth.YOURDOMAIN/auth?client_id=agilicus-builtin-agent-connector…) into the browser on your desktop. You will then see a screen as shown. Copy the token (osfygqo2j…) and paste it in where it says “Enter verification code:“, and the installation will complete.
Whichever method you use, you will achieve the same result, and the Agilicus Connector will need no further intervention.
INFO[2022-05-29T11:45:38-04:00] Starting client - version v0.119.0-5
INFO[2022-05-29T11:45:38-04:00] User is not admin, attempting to elevate. If this fails, re-run as admin/root with same arguments.
re-run [/usr/bin/sudo /bin/sh -c "/home/don/src-ag/platform/secure-exposed-agent/bin/agilicus-agent" "client" "--install" "--agent-id" "GLrmn8mKJ6W45c8Bo3ABCK" "--oidc-issuer" "https://auth.dbt.agilicus.cloud"]
INFO[2022-05-29T11:45:38-04:00] Starting client - version v0.119.0-5
You have **2** methods to provide your authentication. Use the most convenient.
1. You may see a browser open. If you sign in to it, this flow will complete
automatically, and ignore the url below/paste.
2. You will see a URL appear here. Cut and paste that into a browser you are
signed-into. It will then give you a code to paste here.
Typically #1 is used if you are signed into this machine directly, and #2 for
ssh or remote desktop or embedded devices.
If a browser did not open automatically, please open this link in
your desktop browser to retrieve the authentication code, and paste below:
https://auth.YOURDOMAIN/auth?client_id=agilicus-builtin-agent-connector&...
Enter verification code:
Install the Agilicus Connector on Microsoft Windows.
Versions Supported
The Agilicus Connector will run on any version of Windows XP or later. However, prior to Windows 10, the ‘curl’ command, used as part of the install, was not present, and you may need to manually install it.
If your Windows version is old or unpatched, it may be missing the Let’s Encrypt Intermediate certificate, see https://letsencrypt.org/certificates/
Installation
Windows 10 and later come with a command pre-installed called ‘curl‘ that allows for 1-click automatic install.
To create and install a connector, first, on your desktop PC (where you have the ADMIN url open), go to ‘resources/connectors/new’. Give your connector a name that means something to you (often the name of the machine you will install it on, or the site that it connects).
Click ‘create’. You will now be given the option to ‘Install Connector’. This brings up a dialog box as below. Select ‘WIndows – CMD’.
There is only 1 question on this dialog “This is a subsequent connector (create a cluster)”. Select this if you have more than one computer running the same connector instance in a high-availability cluster.
Select the ‘COPY’ button. This will place the command line into your clipboard.
At this stage we must switch to the computer where you will run the connector. It might be this same machine, it might be another accessible via Remote Desktop or VNC.
On the target computer, open a ‘Command Prompt’ as administrator:
Go to ‘Start’
Type ‘cmd’
Right click ‘Command Prompt’
Select ‘Run as administrator’
This will open a ‘cmd’ shell.
We can quickly test that ‘curl’ is installed by running ‘curl ifconfig.me’. This will print our current public IP address. Curl is pre-installed as part of Windows as for Windows 10 and Windows 2016. If you do not have curl installed, you may try the PowerShell instructions from the dialog, or, install curl manually.
We can now paste the command we obtained from the ADMIN UI.
Paste the command as below. The correct output will be similar to what is shown, ending in ‘Installation Complete’
It is possible you will run into some errors, the most common relate to:
Time setup. Your computer should be time-synced (using NTP). This is important for proper cryptography.
Firewall. Your computer may block outbound access to https://www.agilicus.com
Intermediate Certificate. If your computer has not run Windows update since 2021, it may be missing the Let’s Encrypt intermediate certificate.
At this stage you are complete and may close the command window.
In the ADMIN UI you can check the status of your connector, it should move to ‘GREEN/GOOD’ (you may need to refresh this screen).
General Notes
NOTE: Timeout
For security reasons, the command you will paste has a time limit before it expires of 10 minutes. If it expires, simply generate a new one in the ADMIN interface and paste it. In this case, you will see an error like: “Installation failed due to the following error: could not claim challenge code: 400 Bad Request. Do not run the command again; generate a new one. See https://www.agilicus.com/anyx-guide/agilicus-connector/#h-installation“
NOTE: WebClient Service
You may need to manually enable the Windows WebClient service if you will use the connector to mount a remote WebDav Share to this machine. Normally this is set to run on demand, but in some environments it may be disabled.
NOTE: Windows Failover Clustering High Availability
Some installations have observed, using the PowerShell installation instructions, a false-positive detection for Trojan:Script/Sabsik.TE.B!ml. This has been submitted to Microsoft for re-evaluation, but they have been unable to reproduce. If this occurs, you can override this detection for this specific binary.
NOTE: 2012 PowerShell: Could not create SSL/TLS secure channel
Older versions of Windows may be missing the R3 root certificates (see Microsoft note). This can prevent usage of modern cryptographic https sites. Let’s Encrypt has more information, including a diagram of the full chain of trust.
You may find you need to run Windows Update, or, manually remove the old R3 intermediate and add the new one from Let’s Encrypt.
NOTE: CHANGE RUNNING USER/PERMISSIONS
In some circumstances you may change the user the connectr runs as (the windows service user) after initial installation. If you do this, it is important to change ownership of all of the files in C:\Program Files\Agilicus to make the user.
Diagnostic Logs – Windows Eventvwr
The Agilicus Connector sends diagnostic and access logs to Windows Eventvwr by default. To view these logs on a standalone-basis, you might consider creating a custom view.
Open Microsoft Windows eventwr (from Start menu, type ‘eventvwr’)
Right click in custom views
Create Custom View
Select ‘By Source’, and ‘agilicus-connector‘. Enable each Event Level of interest (e.g. Critical, Warning)
Save as ‘Agilicus Connector Logs’
Once this is complete, you will see a new custom view as below. You may then browse the logs or e.g. right-click and save a text file for forwarding.
File Permissions Correction
If your connector shows a warn status, it could mean that the file does not have sufficient permission for Agilicus’ connector. To give access files/folders the correct permissions,
Automatic Permission Fix Instructions
Download and run this script (in Powershell) as access.ps1, or, follow the manual instructions below.
The Agilicus Connector can install on an embedded router product such as OpenWRT. The devices (usually) have either an MIPS or an Arm processor. The instructions are the same for each, but the link is different. The instructions below are for a OpenWRT Router but will be similar on other devices. Select the proper processor (ARM/MIPSBE/MIPSLE) according to your hardware.
See NanoPi R5S for a specific device and instructions.
RESOURCE REQUIREMENTS
Your OpenWRT device will need at least 128MiB of flash memory, and at least 256MiB of DRAM. Not all devices do, we recommend checking first.
No changes are needed to your firewall. No VPN is needed. You can administer users via their Active Directory or Apple, Google, Linkedin accounts.
The high level steps are:
Enable SSH on your Router (or, use the web-based terminal from LUCI)
Create a Connector (Agilicus admin interface)
SSH to the Router
Paste the given command line
after this, the Agilicus Connector will be entirely automatic, and controlled via the Agilicus admin interface. You may uninstall it at any time with
agilicus-agent client --uninstall
Create Connector
First we will create a Connector. This logical endpoint allows reverse inbound connectors to safely occur.
We give the connector a name. This is used for statistics and diagnostics purposes. Select the Linux instructions, and select Copy.
Now, SSH to your Router and paste the given command line:
# which curl && (curl -sSL agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh) || (wget -O - agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh); sh /tmp/i.sh -c JhtPxw9GVXXXXXX -s yw6XXXX
/bin/curl
OS: <Linux>, Machine: <aarch64>, END: <le>
Fetching https://www.agilicus.com/www/releases/secure-agent/stable/agilicus-agent-arm64 into /tmp/agilicus-agent-arm64
-rwxr-xr-x 1 root root 46268416 Jul 8 11:37 /tmp/agilicus-agent-arm64
+ /tmp/agilicus-agent-arm64 client --install --challenge-id JhtPxw9GXXXXX --challenge-code ywXXXX
INFO[2023-07-08T11:37:53-05:00] Starting connector - version v0.211.3
INFO[2023-07-08T11:38:08-05:00] Check if the agilicus connector is already running as a service. If so stop it
INFO[2023-07-08T11:38:08-05:00] Create file /usr/bin/agilicus-agent-wrapper.sh
INFO[2023-07-08T11:38:08-05:00] Create file /etc/systemd/system/agilicus-agent.service
INFO[2023-07-08T11:38:08-05:00] Will install to /agilicus-agent-wrapper.sh -> {/usr/bin/agilicus-agent-wrapper.sh -rwxr-xr-x <nil>}
INFO[2023-07-08T11:38:08-05:00] Will install to /agilicus-agent.service -> {/etc/systemd/system/agilicus-agent.service -r--r--r-- 0xd97540}
INFO[2023-07-08T11:38:08-05:00] Create a directory at /opt/agilicus/agent/tufmetadata/latest
INFO[2023-07-08T11:38:08-05:00] Create a directory at /opt/agilicus/agent/tufmetadata/stable
INFO[2023-07-08T11:38:18-05:00] Create a user and group named Agilicus to run the agilicus-agent service
INFO[2023-07-08T11:38:18-05:00] Copy executable to /opt/agilicus/agent
INFO[2023-07-08T11:38:18-05:00] Set permissions to Agilicus on /opt/agilicus/agent
INFO[2023-07-08T11:38:18-05:00] Create symlink from /usr/bin/agilicus-agent to /opt/agilicus/agent/agilicus-agent-arm64
INFO[2023-07-08T11:38:18-05:00] creating connector instance
INFO[2023-07-08T11:38:19-05:00] Join a connector cluster
INFO[2023-07-08T11:38:19-05:00] Start agilicus-agent service
INFO[2023-07-08T11:38:21-05:00]
INFO[2023-07-08T11:38:21-05:00] Installation Complete
INFO[2023-07-08T11:38:21-05:00]
At this stage you are complete, you will see the Connector go online in the web interface in a minute or so.
The MikroTik RB5009UG+S+IN is a small-form factor router. it is a good vantage point to run the Agilicus Connector. NOTE: this is an ARM-based device, not X86.
Other MikroTik devices may work as well, MikroTik has a broad family of devices. In order to be appropriate for the Agilicus Connector, they need to support:
container package
ARM or x86 processor
100MiB or more of storage space
256MiB or more of memory
The below instructions were tested on the RB5009UG+S+IN with v7.8 and v7.9RC, specifically:
The below instructions were performed using the MikroTik CLI. They may also be performed via the Web GUI or the WinBox.
Detailed Installation Steps
Note: the first steps assume you have not enabled container-package and networking on the RouterOS device. If you have, skip ahead to the Setup config-volume step.
If you are using the Web or WinBox configuration, you will see a package installed as below:
Confirm the container command exists:
/container/print count-only
0
Step 2: Setup container networking
Now we will enable a virtual Ethernet bridge (veth1) and assign it to the container use. If you wish, you may use direct interfaces without NAT by assigning a second IP, or, by assigning physical ports. Later when the Agilicus connector is installed, it will need to be able to resolve DNS and perform outbound connectivity to api.agilicus.com
Note: the Mikrotik is very fussy about mounts. It must create them itself (rather than being created by e.g. sftp). It will create a magic file called ‘.type’ in the mount dir, do not delete or modify this file.
Note: the cr.agilicus.com/pub/images/agilicus-agent/client:stable image is multi-arch (AMD64, ARM64). If your MikroTik is not one of these, it will not function. If your MikroTik does not support multi-arch containers (e.g. prior to v7.9), you may substitute one of these two tag names:
Modify it to be something like below and then run it. There is no need to be admin/root, this will not install any software, merely create the configuration files. We are just changing the beginning of the command line to be “agilicus-agent client –remote-install”, leave the –oidc-issuer onwards unchanged.
Note: you will need a local copy of the software on your desktop to create the config file. It does not need to be installed. If you do not have this, you can download the Linux Binary, or the Windows Binary.
A browser will open to create the Service Account and credentials. The output will look like:
INFO[2023-03-17T20:14:28-04:00] Starting client - version v0.172.3
You have **2** methods to provide your authentication. Use the most convenient.
1. You may see a browser open. If you sign in to it, this flow will complete
automatically, and ignore the url below/paste.
2. You will see a URL appear here. Cut and paste that into a browser you are
signed-into. It will then give you a code to paste here.
Typically #1 is used if you are signed into this machine directly, and #2 for
ssh or remote desktop or embedded devices.
If a browser did not open automatically, please open this link in
your desktop browser to retrieve the authentication code, and paste below:
https://auth.MYDOMAIN/auth?client_id=XXXXX
Enter verification code:
INFO[2023-03-17T20:14:35-04:00] Will install into Will install into directory /tmp/remote-4139368021
INFO[2023-04-23T12:30:33-04:00] Download root key file
INFO[2023-04-23T12:30:33-04:00] Fetch agent configuration
INFO[2023-04-23T12:30:33-04:00] Write agent configuration file in temp directory
INFO[2023-04-23T12:30:36-04:00] Create connector instance
INFO[2023-04-23T12:30:36-04:00] creating connector instance
INFO[2023-04-23T12:30:37-04:00] Join a connector cluster
INFO[2023-04-23T12:30:37-04:00] Remote installation config created successfully
INFO[2023-04-23T12:30:37-04:00] Copy <<agent.conf.enc.yaml public_key.json pubring.gpg root.json secring.gpg>> to remote
At this stage, there should be 4 files in a directory like /tmp/remote-4139368021:
Note: its important to let the Mikrotik router create the config directory by itself. It creates a ‘magic’ file called .type inside the dir. Without this step, the config directory will be read-only within the container.
/container/start 0
After this, check that it is running (and repeat until it is running)
The Kubernetes install is intended for advanced usage only. It is for users who are integrating with a larger system. As a pre-requisite, you will need kubectl installed on the machine you will do the installation from.
The steps initially are similar:
Create a new Connector in admin
Select “Install’
Download the binary (using the alternative manual install, see link for all binaries etc)
Select ‘Manual’. Change –install/–kubernetes-install to –kubernetes-install. Adjust other parameters as needed
The Ubiquiti EdgeRouter X (ER-X/ER-X SFP) is a small-form factor router. In addition to performing routing services, it is a good vantage point to run the Agilicus Connector if you already have it.
This is a low-performance device, we do not recommend purchasing new ones.
The Ubiquiti EdgeRouter X (ER-X/ER-X SFP) is a small-form factor router. In addition to performing routing services, it is a good vantage point to run the Agilicus Connector.
(Once you have completed these, you may wish to try accessing the EdgeRouter X web interface via the Agilicus Any-X platform, see example).
DEVICE WARNING
❗
Note: this device is a low-performance device with an older processor and low ram. If you have a need for more than a few services, or ones which need more than ~10Mbps of throughput, we recommend a newer device such as NanoPi, a Raspberry Pi, or a pfSense.
The below instructions were tested on an EdgeRouter X SFP with v2.0.9, specifically:
In the Agilicus Administrative Web interface, you will:
Create Connector
Copy the install command line
Paste this into the ssh interface of the Ubiquiti EdgeRouter X
Step 1: Create Connector
Navigate (in the Agilicus admin web interface) to ‘Resources/Connectors/New’.
Step 2: Copy the install command line
Select “Linux”. Copy the command line to your clipboard. Run on the ssh interface to the ERX.
This command will fetch a script, and then run it with a time-limited challenge.
Note: the command line looks complex since it must run on multiple platforms, some of which have curl, some of which have wget, but it effictively fetchs a single install script and runs it with 2 arguments. You may feel free to fetch the script and inspect it, run it manually.
You should now be complete.
A complete log of a successful install is shown below for reference.
don@machine$ ssh ubnt@172.16.0.13
_____ _
| ____|__| | __ _ ___ (c) 2010-2020
| _| / _ |/ _ |/ _ \ Ubiquiti Networks, Inc.
| |__| (_| | (_| | __/
|_____\__._|\__. |\___| https://www.ubnt.com
|___/
Welcome to EdgeOS
By logging in, accessing, or using the Ubiquiti product, you
acknowledge that you have read and understood the Ubiquiti
License Agreement (available in the Web UI at, by default,
http://192.168.1.1) and agree to be bound by its terms.
ubnt@172.16.0.13's password:
Linux erx 4.14.54-UBNT #1 SMP Tue May 11 13:23:28 UTC 2021 mips
Welcome to EdgeOS
Last login: Sat May 28 18:11:43 2022 from 172.16.0.8
ubnt@erx:~$ sudo su -
root@erx:~# which curl && (curl -sL agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh) || (wget -O - agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh); sh /tmp/i.sh JX2EXXXXXXXXXXXXEU https://auth.MYDOMAIN
/usr/bin/curl
Starting install... <JX2EXXXXXXXXXXXXEU> <https://auth.MYDOMAIN>
OS: <Linux>, Machine: <mips>, END: <le>
INFO[2022-05-28T18:32:33.787560338Z] Starting client - version v0.119.0
INFO[2022-05-28T18:32:34.923316902Z] Logging in...
You may see a browser open, in which case you may sign in automatically.
Failing that, if this machine is headless, or remote, you will see a URL below.
Copy and paste that into a browser you are logged into. You will then see a code,
paste it in below.
Please go to the following link in your browser to retrieve the authentication
code:
https://auth.MYDOMAIN/auth?client_id=agilicus-builtin-agent-connector&code_challenge=XXXXX&code_challenge_method=S256&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=openid+profile+email+offline_access+urn%3Aagilicus%3Aapi%3Aapplications%3Areader%3F+urn%3Aagilicus%3Aapi%3Aapplications%3Aowner%3F+urn%3Aagilicus%3Aapi%3Atraffic-tokens%3Aowner+urn%3Aagilicus%3Aapplication_service%3A%2A%3Aowner%3F&state=XXXXX
Enter verification code: scpfcXXXXXpim4qq5pl
checking code
INFO[2022-05-28T18:33:23.875526942Z] Check if the agilicus-agent is already running as a service. If so stop it
INFO[2022-05-28T18:33:23.932589295Z] Create a directory at /etc/agilicus/agent
INFO[2022-05-28T18:33:23.934868328Z] Download public key file to /etc/agilicus/agent/public_key.json
INFO[2022-05-28T18:33:24.265979606Z] Create file /usr/bin/agilicus-agent-wrapper.sh
INFO[2022-05-28T18:33:24.266562921Z] Create file /etc/systemd/system/agilicus-agent.service
INFO[2022-05-28T18:33:24.273604799Z] Will install to /agilicus-agent-wrapper.sh -> {/usr/bin/agilicus-agent-wrapper.sh -rwxr-xr-x}
INFO[2022-05-28T18:33:24.278649712Z] Will install to /agilicus-agent.service -> {/etc/systemd/system/agilicus-agent.service -r--r--r--}
INFO[2022-05-28T18:33:24.282177117Z] Create a directory at /opt/agilicus/agent/tufmetadata/latest
INFO[2022-05-28T18:33:24.282578531Z] Create a directory at /opt/agilicus/agent/tufmetadata/stable
INFO[2022-05-28T18:33:24.285506591Z] Setup Agilicus secure store
INFO[2022-05-28T18:33:24.285945878Z] Create secure keyring for storing communication credentials in /etc/agilicus/agent
INFO[2022-05-28T18:34:25.392134745Z] Fetch agent configuration
INFO[2022-05-28T18:34:25.392429467Z] Write agent configuration file in /etc/agilicus/agent/agent.conf.enc.yaml
INFO[2022-05-28T18:34:26.432424427Z] Create a user and group named Agilicus to run the agilicus-agent service
INFO[2022-05-28T18:34:26.432722016Z] Copy executable to /opt/agilicus/agent
INFO[2022-05-28T18:34:26.432866291Z] Set permissions to Agilicus on /opt/agilicus/agent
INFO[2022-05-28T18:34:26.433163321Z] Create symlink from /usr/bin/agilicus-agent to /opt/agilicus/agent/agilicus-agent-mipsle
INFO[2022-05-28T18:34:26.914492417Z] Start agilicus-agent service
INFO[2022-05-28T18:34:27.898994929Z] Installation Complete
root@erx:~# systemctl status agilicus-agent.service
* agilicus-agent.service - Agilicus Agent
Loaded: loaded (/etc/systemd/system/agilicus-agent.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2022-05-28 18:34:27 UTC; 9s ago
Main PID: 23147 (agilicus-agent)
CGroup: /system.slice/agilicus-agent.service
`-23147 /usr/bin/agilicus-agent client --cfg-file /etc/agilicus/agent/agent.conf.enc.yaml
Note: Missing Let’s Encrypt Intermediary
curl -k https://letsencrypt.org/certs/lets-encrypt-r3.pem -o /etc/ssl/certs/lets-encrypt-r3.pem sed -i ‘/^mozilla\/DST_Root_CA_X3/s/^/!/’ /etc/ca-certificates.conf update-ca-certificates
Note: Time Synchronisation (NTP)
Before running the install steps, ensure NTP (time synchronisation) is running. If you do not have your own NTP server, use pool.ntp.org (specifically, use 0.pool.ntp.org as a server name). NTP can be enabled in the ‘system’ menu.
$ show ntp
remote refid st t when poll reach delay offset jitter
==============================================================================
-216.197.156.83 .PPS. 1 u 51 64 1 44.325 -2.774 3.691
+198.245.55.137 15.254.136.119 2 u 48 64 3 31.049 3.062 2.792
*2001:1600:4:1:: .GPS. 1 u 48 64 3 117.633 0.569 1.495
+207.34.48.31 205.206.70.42 3 u 48 64 3 61.305 3.715 3.977
You have a Virtual Private Cloud (VPC) in AWS EC2. It has private-only IP addressing. You need to ssh to some hosts within it, or remote desktop, or share some folders, etc. In this example we will show how to install the Agilicus Connector onto a t2.micro instance, with no public IP (and no NAT Gateway), and, use that to reach other instances within the VPC directly. There is no routing, no inbound or outbound connectivity otherwise.
You have a Virtual Private Cloud (VPC) in AWS EC2. It has private-only IP addressing. You need to ssh to some hosts within it, or remote desktop, or share some folders, etc. In this example we will show how to install the Agilicus Connector onto a t2.micro instance, with no public IP (and no NAT Gateway), and, use that to reach other instances within the VPC directly. There is no routing, no inbound or outbound connectivity otherwise.
Note: you can also follow these instructions AWS Doc to install a NAT gateway into your VPC, and then install the Agilicus Connector on a single machine within the VPC. This would allow your other VPC components to reach outbound.
In this example we will show a setup where a dual-homed t2.micro
Step 1: Create Private VPC
For this demonstration the private VPC has no NAT gateway, no Internet access. This is an internal only network. You can decide whether it has onwards access to other Amazon services if needed.
Step 3: Create private EC2 Server
For demonstration purposes we create an EC2 server to ssh to.
Step 4: Create dual-homed EC2 instance for Agilicus Connector
This machine will act to straddle the private VPC and the public Internet. It does not route, it does not NAT. No traffic will flow from/to it without going through the Agilicus Identity-Aware Firewall.
OK at this stage we have a VPC with no public IP. We have a private server on it with no public IP. We have a 2nd server, with a public IP, that can reach the devices in the VPC. We will now install the Agilicus Connector to facility onwards ssh.
Now, if we look at the config of the private server, we can see its hostname and IP:
Step 5: Install Agilicus Connector
These instructions are as normal for a Linux host. We create the connector in the web front end, it gives us a command line to run.
We are now given a command line to run. We paste it into the ssh on the Agilicus Gateway server (the one with the public IP):
# which curl && (curl -sSL agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh) || (wget -O - agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh); sh /tmp/i.sh -c JhtPxw9GVXXXXXX -s yw6XXXX
/bin/curl
OS: <Linux>, Machine: <aarch64>, END: <le>
Fetching https://www.agilicus.com/www/releases/secure-agent/stable/agilicus-agent-arm64 into /tmp/agilicus-agent-arm64
-rwxr-xr-x 1 root root 46268416 Jul 8 11:37 /tmp/agilicus-agent-arm64
+ /tmp/agilicus-agent-arm64 client --install --challenge-id JhtPxw9GXXXXX --challenge-code ywXXXX
INFO[2023-07-08T11:37:53-05:00] Starting connector - version v0.211.3
INFO[2023-07-08T11:38:08-05:00] Check if the agilicus connector is already running as a service. If so stop it
INFO[2023-07-08T11:38:08-05:00] Create file /usr/bin/agilicus-agent-wrapper.sh
INFO[2023-07-08T11:38:08-05:00] Create file /etc/systemd/system/agilicus-agent.service
INFO[2023-07-08T11:38:08-05:00] Will install to /agilicus-agent-wrapper.sh -> {/usr/bin/agilicus-agent-wrapper.sh -rwxr-xr-x <nil>}
INFO[2023-07-08T11:38:08-05:00] Will install to /agilicus-agent.service -> {/etc/systemd/system/agilicus-agent.service -r--r--r-- 0xd97540}
INFO[2023-07-08T11:38:08-05:00] Create a directory at /opt/agilicus/agent/tufmetadata/latest
INFO[2023-07-08T11:38:08-05:00] Create a directory at /opt/agilicus/agent/tufmetadata/stable
INFO[2023-07-08T11:38:18-05:00] Create a user and group named Agilicus to run the agilicus-agent service
INFO[2023-07-08T11:38:18-05:00] Copy executable to /opt/agilicus/agent
INFO[2023-07-08T11:38:18-05:00] Set permissions to Agilicus on /opt/agilicus/agent
INFO[2023-07-08T11:38:18-05:00] Create symlink from /usr/bin/agilicus-agent to /opt/agilicus/agent/agilicus-agent-arm64
INFO[2023-07-08T11:38:18-05:00] creating connector instance
INFO[2023-07-08T11:38:19-05:00] Join a connector cluster
INFO[2023-07-08T11:38:19-05:00] Start agilicus-agent service
INFO[2023-07-08T11:38:21-05:00]
INFO[2023-07-08T11:38:21-05:00] Installation Complete
INFO[2023-07-08T11:38:21-05:00]
At this stage we are done, and ready to create an SSH resource in the Agilicus Admin GUI. We do this as normal.
Now open Agilicus Launcher and observe we can ssh to the ec2-private server, both from the Web interface, and, from our desktop.
If desired, enter a manual ~/.ssh/config entry to override the private key
Host ec2-private-server
Port 22
User ec2-user
ProxyCommand agilicus-agent wscat --oidc-issuer https://auth.dbt.agilicus.cloud --hostname %h --port %p
IdentityFile /home/don/.ssh/don-ec2.pem
At this stage we are done. We can ssh directly there:
$ ssh ec2-user
ast login: Tue Jul 5 01:36:47 2022 from ip-172-31-13-67.ca-central-1.compute.internal
__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-172-31-6-69 ~]$
The Agilicus Connector can install on an embedded NAS product such as Synology. The devices (usually) have either an Intel or an Arm processor. The instructions are the same for each, but the link is different. The instructions below are for a Synology NAS but will be similar on other devices.
NOTE: Upgrades
Note: it is possible that when you upgrade the OS to your Synology you may need to re-install your Agilicus Connector.
No changes are needed to your firewall. No VPN is needed. You can administer users via their Active Directory or Apple, Google, Linkedin accounts.
The high level steps are:
Enable SSH on your NAS
Create a Connector (Agilicus admin interface)
SSH to the NAS
Run the given command
after this, the Agilicus Connector will be entirely automatic, and controlled via the Agilicus admin interface.
1. Enable SSH
In order to install the Agilicus Connector on your Synology NAS, you will first need to enable SSH. We can do this from the Synology Web Interface Control Panel, select “Terminal & SNMP” under Applications.
If you are not familiar with SSH, it is a Secure Shell remote command line interface. We will only use it for the installation step here, after which we don’t need it. You may use ssh from the command line on your Windows, Mac, Linux machine (it is typically installed on all of these). You may also use Putty, or, you may install SSH into Chrome and use from your browser.
2. Create Agilicus Connector
First we will create a Connector. This logical endpoint allows reverse inbound connectors to safely occur.
We give the connector a name. This is used for statistics and diagnostics purposes.
You will now be presented with some download instructions. Copy the command line given for Linux.
3. SSH to the NAS
SSH to your NAS. Run ‘sudo -i’. Now paste the command line
...
INFO[2024-01-07T17:14:35-05:00] Starting connector - version v0.237.1
INFO[2024-01-07T17:15:00-05:00] Check if the agilicus connector is already running as a service. If so stop it
...
INFO[2024-01-07T17:15:09-05:00] creating connector instance
INFO[2024-01-07T17:15:10-05:00] Join a connector cluster
INFO[2024-01-07T17:15:10-05:00] Start agilicus-agent service
INFO[2024-01-07T17:15:18-05:00]
INFO[2024-01-07T17:15:18-05:00] Installation Complete
At this stage we are complete. Let us look at some sample first resources.
Sample: Synology Web Interface
As a first example, let us make the Synology Web interface available via Agilicus. The detailed screen shots are below, but the steps are:
Resources/Application New. Select a name (this will become an internet host name, so it cannot have spaces or special characters)
Select which connector (the one we just installed) is on the same site as the Synology
Select the network coordinates of the Synology web interface. Since we are running inside the NAS, we can use ‘localhost’ and 5000 for a port (these are the internal coordinates of the web interface)
Select authenticated by Proxy. This means a user will be forced to provide credentials in order to see the web interface
Select ‘named users, single role’, we will assign permissions in the next step. Hit apply, this will create the application.
Assign permissions. Access/Application Permissions. We can assign permissions to groups or individual users. Select the row for the user/group, and the column for the application.
We are done. Let’s test. We can use ‘profile’ (https://profile.YOURDOMAIN), or, directly, https://APPNAME.YOURDOMAIN. let’s use the link to profile in the lower left, note (and bookmark) the URL it goes to.
You should see an icon for your new Synology NAS web interface. If not, refresh the page. If you select it, it will navigate to a new web page, note the URL.
Sample: Synology Share
Let’s assume we have a Share existing on our Synology called ‘tmp’. On the filesystem this is in /volume1/tmp. Once we have completed the above steps, we can create a new Share in the Agilicus admin interface (https://admin.YOURDOMAIN).
Next we will be asked for two parameters (web uri path prefix, name). The first will appear in an http path, e.g. if you say “bobcat”, the URI your users will see is https://files.YOURDOMAIN/bobcat. The second is a name which will show up in the audit log. Normally these are the same (unless you have the same share name on multiple hosts).
Now we will indicate the path on the Synology. In our example (The synology has a share called tmp, this will be in /volume1/tmp)
At this stage you will be given the option to test this in the administrative interface, and, your users may navigate to https://profile.MYDOMAIN to get their own mount instructions for their desktops.
Sample: Synology Surveillance Station Remote Cameras
See Synology Surveillance Station for detailed setup, the above web interface setup will give you access to your cameras, the remainder of the setup is on the NAS interface.
The Agilicus Connector supports native high-availability. In some environments (notably Windows High Availbility File Servers), it may be desirable to instead use Microsoft’s Windows Clustering technology.
To enable High Availability in the Agilicus Connector in a Windows environment (e.g. for resilient access to a Share, to remote desktops), configure it within a Windows Failover cluster.
The high level instructions are:
configure a windows failover cluster with a shared disk of at least 200MiB.
Install the Agilicus Connector into the shared disk on one of the servers. See below for specific instruction.
Stop the service on the node and set it to Disabled
Open the failover cluster manager
In your cluster, select Roles-> add new roles
Click next, select the “Generic Application” role
For the command line, enter F:\agilicus-agent.exe (the working directory from the install instructions, the shared disk)
name the service something unique (e.g. “agilicus-connector”)
Add the storage (e.g. F: in our example)
Don’t register settings
Click confirm, finish
Verify the Agilicus connector is running
Connector Install
On one of the servers in the cluster, we will perform the install as normal, with one modification.
Open a browser (on any machine, does not need to be the windows cluster), sign in to the Agilicus Admin web interface, create a new connector, select the appropriate OS tab, and copy.
On the machine in the server cluster, open an administrative shell, paste the command line. DO NOT PRESS ENTER. Add a command line parameter of ‘–working-directory <PATH>’ where <PATH> is the shared folder (e.g. F:\Agilicus).
For cmd, the sample command would then look something like below:
The instructions to install the Agilicus Connector are nearly identical on various Unix operating systems. This includes desktops, servers, and embedded devices.
See a specific example, the NanoPI R5S or a Synology NAS. Most platforms are installed as follows:
Create Agilicus Connector
First we will create a Connector. This logical endpoint allows reverse inbound connectors to safely occur.
We give the connector a name. This is used for statistics and diagnostics purposes.
You will now be presented with some download instructions. Copy the command line given for Linux.
SSH to the device
SSH to your device. Run ‘sudo -i’ if you are not root (your prompt is not ‘#’). Now paste the command line
...
INFO[2024-01-07T17:14:35-05:00] Starting connector - version v0.237.1
INFO[2024-01-07T17:15:00-05:00] Check if the agilicus connector is already running as a service. If so stop it
...
INFO[2024-01-07T17:15:09-05:00] creating connector instance
INFO[2024-01-07T17:15:10-05:00] Join a connector cluster
INFO[2024-01-07T17:15:10-05:00] Start agilicus-agent service
INFO[2024-01-07T17:15:18-05:00]
INFO[2024-01-07T17:15:18-05:00] Installation Complete
At this stage we are complete.
General Devices
Generically supported are any devices running Linux with at least 256MiB of RAM, at least 512MiB of flash storage, ARM or x86 processor. These include below (and more).
systemd-based Linux installations (e.g. Ubuntu etc)
upstart-based Linux installations
Raspberry PI
OpenWRT
pfSense (FreeBSD Firewall)
Ubiquity Edge Router X
Synology NAS
Specific walk-throughs are provided for some of these on the Agilicus Connector page.
The Ubiquiti EdgeRouter-X has a built in web interface. In this example, we use a connector installed on it to make this web interface available to arbitrary users over the public Internet
The Ubiquiti EdgeRouter-X has a built in web interface. In this example, we use a connector installed on it to make this web interface available to arbitrary users over the public Internet… without opening the firewall. Each user must use Single-Sign-On via Agilicus plus their existing identity provider, and then can access from any device without a VPN.
Step 1. Create application
Step 2. Enter name (hostname we will use externally), description
Step 3. Indicate we use standard pattern hostname.
Step 4. Indicate its via an Agilicus Connector (in this case, installed on the Ubiquiti EdgeRouter-X directly).
Step 5. Select the connector (previously configured as per instructions)
Step 6. Indicate we will use TLS from user to device.
Step 6. Configure upstream as localhost:443, on TLS (this is the local web server of the EdgeRouter)
Step 7. Indicate that Agilicus will do an OpenID Connect Authentication Proxy, use /logout as the revoke token URI.
Step 8. Indicate that we will have individual users.
Step 9. Apply. After this is complete we will then add a user to permissions and test.
At this stage we can assign permissions:
Now we can either use profile (https://profile.MYDOMAIN) which has all applications in it as a launcher, or navigate directly (https://erx.MYDOMAIN).
If desired, publish so that it is selectable in profile, and give it an icon:
During the installation, a Service Account will be created (permissions for the Connector to run as).
The Raspberry Pi installation uses the same instructions as the Linux ones (image at right) A sample command line is offered in the Agilicus admin porttal, which may be pasted into the ssh shell.
You are now complete.
Logs (if any) are generated to /var/log/agilicus-agent.log (e.g. run ‘tail -F /var/log/agilicus-agent.log’)
We may check the status once installed as below.
Sample Install Output
RPI $ which curl && (curl -sSL agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh) || (wget -O - agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh); sh /tmp/i.sh -c hAS43XdGbJwpnmSo2AjrKH -s ua6keppv
/usr/bin/curl
Must run as root to do install, attempting to use sudo.
OS: <Linux>, Machine: <x86_64>, END: <le>
Fetching https://www.agilicus.com/www/releases/secure-agent/stable/agilicus-agent into /tmp/agilicus-agent
-rwxr-xr-x 1 root root 50616688 Jul 1 18:12 /tmp/agilicus-agent
+ /tmp/agilicus-agent client --install --challenge-id hAS43XdGbJwpnmSo2AjrKH --challenge-code ua6keppv
INFO[2023-07-01T18:12:16-04:00] Starting connector - version v0.208.3
INFO[2023-07-01T18:12:30-04:00] Check if the agilicus connector is already running as a service. If so stop it
INFO[2023-07-01T18:12:30-04:00] Create file /usr/bin/agilicus-agent-wrapper.sh
INFO[2023-07-01T18:12:30-04:00] Create file /etc/systemd/system/agilicus-agent.service
INFO[2023-07-01T18:12:30-04:00] Will install to /agilicus-agent-wrapper.sh -> {/usr/bin/agilicus-agent-wrapper.sh -rwxr-xr-x <nil>}
INFO[2023-07-01T18:12:30-04:00] Will install to /agilicus-agent.service -> {/etc/systemd/system/agilicus-agent.service -r--r--r-- 0x135ad20}
INFO[2023-07-01T18:12:30-04:00] Create a directory at /opt/agilicus/agent/tufmetadata/latest
INFO[2023-07-01T18:12:30-04:00] Create a directory at /opt/agilicus/agent/tufmetadata/stable
INFO[2023-07-01T18:12:30-04:00] Create a user and group named Agilicus to run the agilicus-agent service
INFO[2023-07-01T18:12:30-04:00] Copy executable to /opt/agilicus/agent
INFO[2023-07-01T18:12:30-04:00] Set permissions to Agilicus on /opt/agilicus/agent
INFO[2023-07-01T18:12:30-04:00] Create symlink from /usr/bin/agilicus-agent to /opt/agilicus/agent/agilicus-agent
INFO[2023-07-01T18:12:31-04:00] creating connector instance
INFO[2023-07-01T18:12:31-04:00] Join a connector cluster
INFO[2023-07-01T18:12:31-04:00] Start agilicus-agent service
INFO[2023-07-01T18:12:32-04:00]
INFO[2023-07-01T18:12:32-04:00] Installation Complete
INFO[2023-07-01T18:12:32-04:00]
RPI $
The Netgate SG-1100 pfSense is a small-form factor router. it is a good vantage point to run the Agilicus Connector.
Other pfSense appliances may work, they will need to be arm or x86 based, and have at least 120MiB of storage available. The Agilicus connector will consume approximately 50MiB of RAM.
The below instructions were tested on a Netgate SG-1100 with v22.01, specifically:
# cat /etc/version
22.01-RELEASE
The pfSense installation uses the same instructions as the Linux ones (image at right) A sample command line is offered in the Agilicus admin porttal, which may be pasted into the ssh shell.
Once you run this command, you will see output as below. You are now complete.
The Agilicus Agent Connector will self-update over time, no intervention is required.
We may check the status once installed as below.
Logs (if any) are generated to /var/log/agilicus-agent.log (e.g. run ‘tail -F /var/log/agilicus-agent.log’)
[22.01-RELEASE][root@pfSense.home.arpa]/root: which curl && (curl -sSL agilicus.com/www/releases/secure-agent/stable/install.sh > /tmp/i.sh) || (wget -O - agilicus.comw
/usr/local/bin/curl
Check time synchronisation/NTP is active
OS: <FreeBSD>, Machine: <arm64>, END: <le>
Fetching https://www.agilicus.com/www/releases/secure-agent/stable/agilicus-agent-freebsd-arm64 into /tmp/agilicus-agent-freebsd-arm64
-rwxr-xr-x 1 root wheel 45613056 Jun 3 18:52 /tmp/agilicus-agent-freebsd-arm64
+ /tmp/agilicus-agent-freebsd-arm64 client --install --challenge-id XXXX --challenge-code XXXX
INFO[2023-06-03T18:52:48Z] Starting connector - version v0.201.0
INFO[2023-06-03T18:53:01Z] Check if the agilicus connector is already running as a service. If so stop it
INFO[2023-06-03T18:53:01Z] Create file /usr/bin/agilicus-agent-wrapper.sh
INFO[2023-06-03T18:53:01Z] Create file /usr/local/etc/rc.d/agilicus-agent
INFO[2023-06-03T18:53:01Z] Will install to /agilicus-agent-freebsd.rc -> {/usr/local/etc/rc.d/agilicus-agent -r-xr-xr-x <nil>}
INFO[2023-06-03T18:53:01Z] Will install to /agilicus-agent-freebsd.sh -> {/usr/local/etc/rc.d/agilicus-agent.sh -r-xr-xr-x <nil>}
INFO[2023-06-03T18:53:01Z] Will install to /agilicus-agent-wrapper.sh -> {/usr/bin/agilicus-agent-wrapper.sh -rwxr-xr-x <nil>}
INFO[2023-06-03T18:53:01Z] Create a directory at /opt/agilicus/agent/tufmetadata/latest
INFO[2023-06-03T18:53:01Z] Create a directory at /opt/agilicus/agent/tufmetadata/stable
INFO[2023-06-03T18:53:02Z] Create a user and group named Agilicus to run the agilicus-agent service
INFO[2023-06-03T18:53:02Z] Copy executable to /opt/agilicus/agent
INFO[2023-06-03T18:53:02Z] Set permissions to Agilicus on /opt/agilicus/agent
INFO[2023-06-03T18:53:02Z] Create symlink from /usr/bin/agilicus-agent to /opt/agilicus/agent/agilicus-agent-freebsd-arm64
INFO[2023-06-03T18:53:03Z] creating connector instance
INFO[2023-06-03T18:53:03Z] Join a connector cluster
INFO[2023-06-03T18:53:03Z] Start agilicus-agent service
INFO[2023-06-03T18:53:04Z]
INFO[2023-06-03T18:53:04Z] Installation Complete
INFO[2023-06-03T18:53:04Z]
[22.01-RELEASE][root@pfSense.home.arpa]/root:
The NanoPI R5S has 1 x Gigabit Ethernet, 2 x 2.5 Gigabit Ethernet, 4GiB of RAM, and 32GB of eMMC storage. With its large passive heatsink it is an ideal platform to use as a small router. It also makes an ideal platform to run the Agilicus Connector.
The NanoPi R5S will run several operating systems (Ubuntu, Armbian, OpenWRT). In this document we discuss using it with OpenWRT. Specifically, Agilicus makes available a hardened-version of OpenWRT for this platform.
Installing Agilicus OpenWRT
As received, the NanoPi R5S will (usually) be running FriendlyWRT. You may feel free to use this, however it has some security flaws. Agilicus recommends using our build. You may build it yourself, or for convenience we supply an image here.
Connect your laptop to one of the two LAN ports (closest to the USB-C power connector).
Select ‘Choose File’. Select the file you downloaded
Select ‘Upload and Write’
Wait approximately 90s (until the lights stop flashing and it indicates its complete)
Power off, power on
At this stage you are running the Agilicus-supplied OpenWRT image.
Router Setup
We have chosen to disable DHCP server by default (to avoid the risk of plugging this device into an existing network and causing confusion). To initially connect, plug your laptop into one of the LAN ports (closest to the USB-C connector) and set the IP on your laptop to ‘192.168.2.2’ and connect to http://192.168.2.1/ via your browser.
On first sign-in, you will be prompted to set a password. Choose something strong (later we will suggest a way that the router is blocked for password access entirely).
This is a standard OpenWRT (23.04) image, and the normal User Guides show different configuration options.
The default configuration is:
WAN (DHCP client, all inbound blocked, outbound NAT)
LAN (static 192.168.2.0/24, all inbound allowed, default route through WAN).
SSH enabled (with passwod)
Web enabled (with password)
No UPnP services nor mDNS/Avahi are enabled by default.
Agilicus Connector Install
Using the Agilicus administrative portal, create a new connector. Use the ‘Linux’ instructions, copy.
In the OpenWRT admin interface (http://192.168.2.1/), select ‘Services/Terminal’. Sign in as root and the password you selected. Paste (shift-insert).
At this time the connector should be installed and you may close the terminal.
You may wish to enable access to this router via the Agilicus AnyX platform (notably SSH and Admin web interface).
NOTE: DHCP Server Enable
Depending on your use, you may wish to have a DHCP server on the LAN ports, you can enable this under ‘Network/Interfaces/LAN’. You may also configure your desired IP range here.
❗
It is appropriate to have a DHCP server on these LAN ports if this is an isolated network. If you are connecting to a larger network with an existing DHCP server, you probably wish to instead change the protocol on the LAN ports to DHCP Client.
NOTE: Time Sync (NTP)
Modern cryptography requires clock sync and accuracy on all devices. Typically this is performed via Network Time Protocol, however, in some environments this is blocked (e.g. HTTPS-only outbound).
If your clock is not sync’d (see System/Time Synchronisation menu), you might be able to use a local NTP server. If not, you can enable an HTTPS-based sync as below:
service htpdate enable
service htpdate start
This is going to use the Agilicus API to provide an HTTP-based (over HTTPS port 443) time service. Configuration can be observed in /etc/config/htpdate:
Once you have installed the Agilicus Connector, we recommend disabling the web terminal. On ‘Services/Termina’, select the config tab and remove the check-box beside ‘Enable’.
You may re-enable the web terminal later if you need it. However, we recommend using SSH instead for future command-line access.
The web terminal operates on a secondary TCP port (7681) and is not needed for normal operation.
SSH Setup
Agilicus recommends disabling password access to SSH in favour of SSH Keys.
On System/Administration, the SSH Access tab, uncheck ‘Password authentication’ and uncheck ‘Allow root logins with password’.
The rationale here is that password stuffing and guessing is a thing. Eventually someone will guess your l33t-hax0r password. Removing any ability to use passwords reduces the risk. In some controls environments any passwords can be disallowed.
Once you have disabled password access, we recommend adding a SSH Key. Agilicus recommends using ed25519 SSH keys since they are smaller and more secure. Add your public key to the router here and place the private key (with passphrase!) in your SSH Agent on your desktop.
SSH keys are not only more secure, but also more convenient.
One downside to note: the Agilicus web interface for SSH is not currently compatible with SSH keys. If you wish to have SSH access to this device via the Agilicus Profile web interface, keep password on.
Firewall
At this stage, configure the firewall and NAT settings to suit on each of the interfaces. If the Agilicus Connector is providing Service Forwarder services, remember to open this ports on the router too.
We can check which ports are listening by running netstat -nlpt as below. Things with 0.0.0.0:PORT are available from outside the device. Things listening on 127.0.0.1, fe80::, ::1, etc, are locally bound only. In the example below, ‘uhttpd’ (the admin web interface), ‘dropbear’ (SSH) and ‘ttyd’ (the web terminal) are the only things listening.
This walk through shows an example of how, once the connector is installed (as per above), configuration of an HTTP and SSH interface to this local device. Once these are configured you could use the firewall to disable all external access. The high level steps are:
Create Connector (Agilicus Admin)
Install Connector (NanoPi Web Terminal)
Create SSH Resource (Agilicus Admin)
Create Web Resource (Agilicus Admin)
Assign Web Resource Permission (Agilicus Admin)
SSH to NanoPi from Agilicus Profile (Agilicus Profile)
Open Web Interface to NanoPi (Agilicus Profile or direct)
OK, let’s get started. This will take approximately 5 minutes.
First, create the connector on the NanoPi. Skip this is you have already done so above.
Select install. On the dialog, select ‘Linux’. Select ‘Copy’
On the NanoPi web interface, open the terminal, sign in. Press ‘Shift-Insert’ to paste the line you copied above.
You should see output as to the left, taking about 30 seconds.
Errors you might see include:
Time issues. The NanoPi does not have a battery-backed real-time clock. It is setup to use Network Time Protocol (NTP). If your firewall blocks this, or the WAN port is not connected, you must solve this first. Cryptography and certificates require good time sync. See below for an https-only solution that is simple to firewall.
Outbound firewall blocking www.agilicus.com or api.agilicus.com (both on port 443)
At this stage the connector is installed on this device. We will move on and configure SSH access next.
Create a new SSH resource. Select the connector we created above.
Create a new SSH resource. Select the connector we created above.
Give the SSH resource a name. We will see this later in the Web Interface and from the command line. The name must be valid as a hostname (e.g. no spaces).
Assign permissions. For this sample, we are assigning permissions to a single user. More commonly one would create a group (e.g. SSH Admins) to simplify.
At this stage, we have finished the SSH setup. We can use it from the Agilicus Profile (web-based, any device), from the Start menu on a desktop operating system, or via the command-line on our desktop. It will work with Putty and OpenSSH.
Now let us configure a Web Application to see the web console of the NanoPi R5S.
Create a new application. Give it a name (which must be valid as a hostname in format). You will later be accessing this as https://NAME.DOMAIN/
You may, if you wish, have a well-known alias to this new web interface. This is more commonly done with very public ones (e.g. a Wiki or Timesheet system). Leave it as default and the Agilicus AnyX will create the hostname for you.
Select the connector from the previous step.
The connector has to know where to send the request (it is a proxy). The ‘upstream’ in this case is the NanoPi R5S itself, e.g. localhost port 80.
For a bit of additional security we can tie the ‘logout’ URL of the NanoPi R5S web interface to the Agilicus AnyX logout by copying in the URL of the logout. This is optional.
We also suggest that named users with a single role, configured later, for this sample. Normally you would create a group, e.g. ‘Web Admins’ and assign users to it.
At this stage we are done, select ‘Apply’.
Now we will assign ourselves permission to use this new web resource.
To make the profile a bit more ‘fun’ we can now assign a logo (an icon) to the launch of this web interface. In this ‘define’ section we could also refine the Web Application Firewall rules etc.
Any image file (we suggest about 512×512) is suitable for a logo.
At this stage we are done. We have:
created and installed a connector on this NanoPi R5S.
created an SSH service (to the NanoPi itself)
created a Web resource (to the NanoPi itself)
We can now test our work. Open https://profile.YOURDOMAIN/
Once you have signed in, you will see an icon for the new web resource, if you click it, a new browser tab will open. Observe the URL (https://NAME.DOMAIN). You can use this directly without profile if you wish. If you sign in, you will see the NanoPi R5S web interface directly. Now try it from a different network (e.g. your mobile phone, disable WiFi). Observe you can still connect. Now try with an unprivileged user (e.g. a different Gmail account), observe you cannot sign in.
The ‘profile’ interface acts as a launch pad for the end-user. It will act as a Progressive Web Application (e.g. ‘add to homescreen’ on your mobile), giving you a single launch icon.
You may also use the resources it points to directly: it is your choice.
We can test the SSH access. From profile, select the resource we created earlier.
We will see a ‘login’ dialog appear, enter the username (root) and password to the NanoPi R5S.
At this stage, we should see an SSH terminal.
From here, consider using the ‘Launcher’ install feature of profile, add the Browser Extension. You will now see an entry on your start menu for this SSH, opening the native client (e.g. if you have Putty or OpenSSH installed).
Similarly to the Web Resource, only users with permission are able to sign in. You may also choose to enable multi-factor authentication on your user and observe how this functions with both Web and SSH resources.
The Agilicus Connector facilitates connection from a bastion network and end-users. It installs on a device somewhere inside the protected network, making an outbound connection.
Agilicus Connector Overview
The Agilicus Connector facilitates connection from a bastion network and end-users. It installs on a device somewhere inside the protected network, making an outbound connection.
If you are new to the system, you may try a full ‘demo’ setup with your own connector in a virtual enviroment in our system, with no install. See “Agilicus AnyX Demo“. When you ‘create a connector’ it will offer you a ‘demo’ this will create a new virtual environment to test in with no isntall, no obligation.
The Connector is self-updating. Once installed it will stay up to date. The live Changelog shows the updates that have occurred.
Connectors facilitate:
shares [must have local access to the files)
Web Applications (must have onward connectivity)
Local authentication
Network resources (e.g. SSH, Remote Desktop, VNC)
Theory of Operation
The Agilicus Connector creates an outbound connection, using HTTPS, to the Agilicus AnyX Cloud. This persistent connection is then used to route individual user requests back in to the appropriate resource.
Each individual inbound request first has the user identity checked (authentication), then has the user’s role (authorisation) checked, prior to being routed inwards.
The net affect is that no traffic arrives at the protected resources unless it is for:
An authenticated user (optionally with multifactor authentication)
An authorised action (e.g. can the user edit the wiki)
A valid resource
This is a very strong guarantee, and, achieved without complex (or any) firewall rules.
The use of industry-standard HTTPS and WebSocket means inspecting firewalls such as Zscaler or PaloAlto can be used in the path.
If we expand the data flow for a hypothetical SSH client with animation, we will see the WebSocket flows (blue) establish, and then the ssh flow. The SSH flow is delivered from User to SSH server encrypted end-to-end: the host key is maintained intact.
SSH Animated Data Flow
High Availability Option
The Agilicus Connector supports high availability (resiliency), either natively, or, via Windows Clustering. See High Availability installation for more information.
The Agilicus Connector includes a standard container-runtime and automatic installation for Kubernetes. This allows exposing internal Kubernetes services with an OpenID Conect Identity Proxy. Agilicus Connector Kubernetes
The instructions to install the Agilicus Agent Connector are nearly identical on various Unix operating systems. This includes desktops, servers, and embedded devices.
Installation
Installation of the connector is very simple: 3 steps.
Second, name (a name that means something, must be a valid hostname. E.g. the machine it is installed on, the site it connects, etc)
Third, install (paste the command on the target machine)
Once installed, the connector will keep itself up to date using The Update Framework.
During the creation of the Connector you will give it a name. This name should have some meaning for you, e.g. the site it is installed in, the host it is installed on, etc. We recommend it be the hostname that is running the Connector.
At this stage you will see a dialog giving installation instructions. At the top are 3 tabs (Linux, Windows-CMD, Windows-PowerShell).
The Linux tab should work on most Linux or FreeBSD-derived hosts, including pfSense, OpenWRT, Ubuntu, Debian, Synology, etc.
On a Windows host it does not matter which of the two instruction you follow, they will lead to the same result. Typically you will use the ‘cmd‘ instructions.
In all 3 cases, copy the text box (using the blue-button at the bottom right) and paste it into an administrative shell.
Uninstall / Delete
When you no longer need an Agilicus Connector, you should first uninstall it from the host it is on. Then you may delete it from the Admin portal.
Typically the installation is done from the Agilicus Admin portal. This will give you a link per platform. In rare cases you may wish to manually download, the linux are below for convenience. NOTE: you will need a ‘code’ from the admin web interface to install (under Resources/Connectors/New).
Below you will see cards for specific aspects of the connector (theory of operation, installation onto various platforms such as pfSense, Mikrotik, OpenWRT, Windows, etc.)
Once installed, you can remotely connect to the Moxa UC-8200, or, resources on adjacent networks through the Agilicus AnyX platform, regardless of network configuration or firewall settings.
From the Agilicus Admin web interface, select Resources/Connectors/New. Give the connector a name, and then select the “Linux” tab, paste the resulting command line into a root shell and it will automatically setup and configure.
Applications generate a valid certificate. You can export this certificate for integration with other systems whenever it is issued or rotated. For example, VTScada requires a valid certificate for the server to be enabled with SSL.
Requirements
The connector associated with the application invokes a script when it learns about a new certificate. – The script must be accessible by the connector (e.g. on the same machine) – The script must be executable by the connector – You are responsible for ensuring the execution environment for the script
For example, for the connector to execute a Python script, Python must be installed on the machine, and the machine must be configured to associate .py files with the Python interpreter. You are also responsible for installing any supporting packages used by your script.
Once Python is installed, the connector will look for a script in the directory: C:\Program Files\agilicus\agent\plugins\certificate-exporter.py
If there is no script found, no export will occur.
Windows Example Script
An example script is shown below, which will import the script as a .p12 file and store it into the Local Machine certificates storage.
import sys
import json
import base64
import tempfile
import subprocess
import os
# load the certificate export json from stdin
# see https://agilicus.com/www/api/certificate-export.schema.json
cert_obj = json.loads(sys.stdin.readline())
def import_certificate(obj):
# create a temporary file. It must be closed
# after write before calling certutil.
tmp = tempfile.NamedTemporaryFile(delete=False)
try:
# retrieve the pkcs12 and base64 decode it
pkcs12 = base64.b64decode(obj.get("pkcs12_b64"))
# write the pkcs12 to the temporary file
tmp.write(pkcs12)
# close the file
tmp.close()
# now import the pkcs12 file into the local machine account
subprocess.run(
["certutil",
"-f",
"-p",
obj.get("pkcs12_password"),
"-importpfx",
tmp.name,
]
)
except Exception as exc:
print(exc)
raise exc
finally:
# after completion, delete the pkcs12 file
os.unlink(tmp.name)
import_certificate(cert_obj)
Programming Interface Details
The json document includes the PKCS #12-encoded certificate bundle and private key, as well as the pem-encoded certificate and private key, and various pieces of supporting data. To view the full details, consult the json definition for the json schema.
100% of connections from the public networks into Agilicus AnyX are protected by Transport Level Security (TLS/SSL). Each endpoint has its own publicly-trusted certificate allocated, no wildcards, no fake certificates or certificate authority trusts to be injected. This is all done in a fully automatic fashion.
In some cases, you wish to access the same resource from the local side, without going through Agilicus AnyX. Although we do not generally recommend this (it lowers the overall security since there is no strong authentication and multi-factor), it can be useful or required. In this sample, we show how to setup a Synology DS120 NAS web interface such that the local DNS resolves to its local IP, and, it is protected by the same public certificate that the Agilicus AnyX platform allocated. In this fashion a user on the local network can directly access the NAS without seeing broken ‘do you want to trust this site” messages.
Setup
Create Web Application
First, configure the Synology web interface as a ‘Web Application’. We assign it a name (ds120), we select its via a connector we have previously installed on this NAS. We use ‘localhost’ and ‘port 5000’ for the upstream configuration (which is how we reach the web interface from inside the NAS). We then assign permission to our user.
At this stage we should be able to navigate to the url, and reach the NAS. If you take your mobile phone, disconnect the WiFi, and then reach the url, it should work. If your local DNS overrides, you may still see the NAS directly with its TLS/SSL error, we will resolve that in the next section.
Export Certificate
Referring to the instructions for exporting certificates, we see that the Connector will export the certificate if a Python script exists in a certain location (/opt/agilicus/agent/plugins/certificate-exporter.py).
We can see where the Synology looks for its certificate:
OK, lets take a look at the ‘factory’ certificates:
# openssl x509 -in /usr/syno/etc/www/certificate/system_default/73b8b5b1-7f63-4764-a54f-1a0d78d58dfd.pem -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 6280518885899342 (0x1650194132fc4e)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = TW, L = Taipel, O = Synology Inc., CN = Synology Inc. CA
Validity
Not Before: Feb 20 06:15:00 2023 GMT
Not After : Feb 21 06:15:00 2024 GMT
Subject: C = TW, L = Taipel, O = Synology Inc., CN = synology
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:df:33:80:97:f8:9d:88:a8:9f:49:35:7f:20:7a:
ba:68:26:47:3e:ed:7f:9f:79:3f:f3:6f:2c:31:1c:
38:36:cd:36:36:ed:bb:47:bf:29:cc:8c:e2:d2:3d:
16:4b:16:5b:16:7c:36:4e:c8:e8:05:f4:33:d6:7f:
91:7b:2c:c4:8b:3d:1e:18:19:d7:60:84:d4:08:db:
8e:b4:63:5e:bc:fa:e6:31:1f:5d:f8:64:27:76:4c:
a2:63:d4:a5:03:c7:cd:e9:83:f3:31:a7:29:c8:1d:
ed:bf:35:b5:02:c0:53:18:83:29:71:85:b2:15:b2:
0d:4e:11:0d:b1:4b:73:34:29:20:e4:5a:5c:f3:6d:
bf:9e:f7:85:f9:f6:8b:fd:63:26:66:d2:ac:0f:f5:
5b:e7:38:34:4d:e7:2d:db:ae:77:9f:69:0d:e6:3b:
3a:15:b1:28:ae:94:49:98:40:ed:d9:0f:2d:d6:bb:
f9:b3:64:33:7e:c0:6c:de:f0:eb:5d:f0:8d:3b:67:
60:01:69:b1:fa:b2:db:f3:33:88:a0:9c:e4:e9:f2:
3c:3a:eb:b5:b3:de:94:50:f3:3b:f0:70:a1:8d:f7:
e6:a6:c1:74:47:97:45:4d:b3:9a:27:f8:ad:44:db:
24:20:57:03:3f:01:e6:0b:82:dd:1f:49:ba:f7:cd:
e4:99
Exponent: 65537 (0x10001)
X509v3 extensions:
Netscape Comment:
mod_ssl generated custom server certificate
Netscape Cert Type:
SSL Server
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Subject Alternative Name:
DNS:synology
Signature Algorithm: sha256WithRSAEncryption
6d:38:84:e7:22:8f:f7:65:69:8a:98:8b:e7:fd:03:86:13:ce:
ba:27:75:0a:c9:95:7c:38:07:6c:0c:7f:6f:2e:23:e8:68:52:
cf:de:57:bd:d5:ee:75:1b:6e:f9:cf:58:74:36:f9:9a:3a:8c:
4d:e0:7e:d7:21:00:ef:81:5e:4c:0c:59:34:cb:fe:37:60:0e:
5a:81:f4:a6:fa:fb:39:82:1d:74:f7:6d:75:d4:72:e3:95:bc:
a7:d3:76:df:e3:4f:d5:be:83:5a:3b:af:26:b8:1e:9f:d0:42:
99:c3:6a:6a:36:13:a9:ef:bd:6f:88:42:71:d1:2f:ad:14:8d:
5b:d9:17:b0:fc:bc:8b:f8:20:b2:26:25:c6:83:93:b7:2a:36:
cc:85:f7:84:d3:01:13:40:a5:b9:ef:60:4e:47:46:26:84:b7:
0e:da:eb:88:6c:75:9f:44:4c:0f:ab:f6:1b:0d:76:dc:4d:f1:
04:87:11:e9:26:c4:12:cb:fe:ea:57:58:4b:85:1d:cc:de:c7:
23:1d:55:1d:a1:d5:06:36:c6:4a:d0:15:e2:f0:34:9b:a2:05:
2a:2c:b0:14:e1:a8:a4:95:99:17:df:3d:f7:f6:c3:ab:49:ff:
b3:d9:ab:b2:50:51:cb:bb:aa:3c:72:e4:ba:a6:cf:4a:b1:4c:
96:1d:1f:a6
-----BEGIN CERTIFICATE-----
MIIDsjCCApqgAwIBAgIHFlAZQTL8TjANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQG
EwJUVzEPMA0GA1UEBwwGVGFpcGVsMRYwFAYDVQQKDA1TeW5vbG9neSBJbmMuMRkw
FwYDVQQDDBBTeW5vbG9neSBJbmMuIENBMB4XDTIzMDIyMDA2MTUwMFoXDTI0MDIy
MTA2MTUwMFowSTELMAkGA1UEBhMCVFcxDzANBgNVBAcMBlRhaXBlbDEWMBQGA1UE
CgwNU3lub2xvZ3kgSW5jLjERMA8GA1UEAwwIc3lub2xvZ3kwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDfM4CX+J2IqJ9JNX8gerpoJkc+7X+feT/zbywx
HDg2zTY27btHvynMjOLSPRZLFlsWfDZOyOgF9DPWf5F7LMSLPR4YGddghNQI2460
Y168+uYxH134ZCd2TKJj1KUDx83pg/MxpynIHe2/NbUCwFMYgylxhbIVsg1OEQ2x
S3M0KSDkWlzzbb+e94X59ov9YyZm0qwP9VvnODRN5y3brnefaQ3mOzoVsSiulEmY
QO3ZDy3Wu/mzZDN+wGze8Otd8I07Z2ABabH6stvzM4ignOTp8jw667Wz3pRQ8zvw
cKGN9+amwXRHl0VNs5on+K1E2yQgVwM/AeYLgt0fSbr3zeSZAgMBAAGjgZYwgZMw
OgYJYIZIAYb4QgENBC0WK21vZF9zc2wgZ2VuZXJhdGVkIGN1c3RvbSBzZXJ2ZXIg
Y2VydGlmaWNhdGUwEQYJYIZIAYb4QgEBBAQDAgZAMA4GA1UdDwEB/wQEAwIFoDAd
BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEwYDVR0RBAwwCoIIc3lub2xv
Z3kwDQYJKoZIhvcNAQELBQADggEBAG04hOcij/dlaYqYi+f9A4YTzrondQrJlXw4
B2wMf28uI+hoUs/eV73V7nUbbvnPWHQ2+Zo6jE3gftchAO+BXkwMWTTL/jdgDlqB
9Kb6+zmCHXT3bXXUcuOVvKfTdt/jT9W+g1o7rya4Hp/QQpnDamo2E6nvvW+IQnHR
L60UjVvZF7D8vIv4ILImJcaDk7cqNsyF94TTARNApbnvYE5HRiaEtw7a64hsdZ9E
TA+r9hsNdtxN8QSHEekmxBLL/upXWEuFHczexyMdVR2h1QY2xkrQFeLwNJuiBSos
sBThqKSVmRffPff2w6tJ/7PZq7JQUcu7qjxy5Lqmz0qxTJYdH6Y=
-----END CERTIFICATE-----
OK, it is expecting a FQDN of ‘synology’, and, is self-signed. We don’t want this. lets overwrite it with our properly signed one. To do so, place a script called certificate-exporter.py in /opt/agilicus/agent/plugins (you may need to make this directory). The script might look as below (notice I hard-coded in my host name since this connector services more than one endpoint, and I only want to export one certificate).
#!/bin/python
import sys
import json
import base64
import os
# load the certificate export json from stdin
# see https://agilicus.com/www/api/certificate-export.schema.json
cert_obj = json.loads(sys.stdin.readline())
def import_certificate(obj):
if obj.get("common_name") == "ds120.dbt.agilicus.cloud":
with open("/usr/syno/etc/www/certificate/system_default/cert.conf", "w") as fd:
fd.write("ssl_certificate /usr/syno/etc/www/certificate/nas.pem;\nssl_certificate_key /usr/syno/etc/www/certificate/nas.key;\n");
with open("/usr/syno/etc/www/certificate/nas.pem", "w") as fd:
fd.write(obj.get("certificate"))
with open("/usr/syno/etc/www/certificate/nas.key", "w") as fd:
fd.write(obj.get("key"))
with open("/usr/syno/etc/certificate/_archive/DEFAULT", "r") as fd:
def_cert_name = fd.read()
def_cert_name = def_cert_name.strip()
with open(f"/usr/syno/etc/certificate/_archive/{def_cert_name}/cert.pem", "w") as fd:
fd.write(obj.get("certificate"))
with open(f"/usr/syno/etc/certificate/_archive/{def_cert_name}/privkey.pem", "w") as fd:
fd.write(obj.get("key"))
os.system("/bin/systemctl reload nginx")
import_certificate(cert_obj)
Testing
To test, we can remove the cached files (exported_certs.*) and then restart the connector
The Cisco IOx family provides an excellent platform to run the Agilicus Connector. In this example we are working with the Cisco IR1101, suitable for rugged, embedded environments.
The instructions below were tested on
Cisco IR1101-K9 17.11.1a
Cisco IOx Zero Trust: Cisco Router Setup
Follow the Cisco instructions on enabling IOx, enabling applications and routing. Some sample config is shown here, but this varies by platform. Key items required:
Clock sync (ntp, GPS)
Ability to reach https://www.agilicus.com/
Ability to reach https://api.agilicus.com/
Below we have achieved this with NAT but you can also use a bridge.
interface VirtualPortGroup0
ip address 192.168.100.1 255.255.255.0
ip nat inside
interface Vlan1
ip address 192.168.2.2 255.255.255.0
ip nat outside
ntp server 0.pool.ntp.org
ip dhcp pool vg0
network 192.168.100.0 255.255.255.0
default-router 192.168.100.1
dns-server 1.1.1.1
interface VirtualPortGroup0
ip address 192.168.100.1 255.255.255.0
ip nat inside
interface Vlan1
ip address 192.168.2.2 255.255.255.0
ip nat outside
ntp server 0.pool.ntp.org
ip dhcp pool vg0
network 192.168.100.0 255.255.255.0
default-router 192.168.100.1
dns-server 1.1.1.1
ip name-server 1.1.1.1
iox
ip default-gateway 192.168.2.1
ip access-list standard IOX_NAT
10 permit 192.168.100.0 0.0.0.255
ip nat inside source list IOX_NAT interface Vlan1 overload
ip route 0.0.0.0 0.0.0.0 192.168.2.1
Cisco IOx Zero Trust: Install
On this platorm we will use a container-based install. This platform does not support standard container registries, so we will install the layers manually.
First, download to your local computer the appropriate file for your platform (amd64 or arm64). The IR1101 in our example is arm64.
Second, navigate to the IOx web admin, Configuration/Services/IOx.
From here we will:
Create Application
Upload image (from above)
Set Profile (ram/disk/cpu)
Set networking
Set environment variables (from Agilicus Admin)
Set configuration volume
Activate application
Start application
at which point the Agilicus connector will be running
Cisco IOx Zero Trust: Detailed Steps
Start Application
Select the Agilicus Connnector and start it.
(Optional) Diagnose Application
You can examine the output logs, if needed, via ‘Manage’ and then ‘Log’ and ‘Download’
(Optional) Diagnose Application Log
You can examine the output logs, if needed, via ‘Manage’ and then ‘Log’ and ‘Download’
Check Connector Status
Within approximately 90 seconds you should see the Connector come online in the Agilicus admin UI.
Add New Application
In the Cisco IOx web admin, select ‘Add New’ application.
Upload Image
Download to your local computer the appropriate file for your platform (amd64 or arm64). The IR1101 in our example is arm64.
Upload this image to the IOx device.
Name the Application ‘agilicus’.
Activate
Select ‘Activate’
Copy Setup Configuration
In the Agilicus Admin UI, create a connector. Install. use the ‘Docker’ instructions.
NOTE: the code times out after 10 minutes. If you copy this, and do not start the container within this time, you can generate a new one by closing and re-open the install dialog.
Configure Application
You may optionally configure the resource limits. The Agilicus Connector will typically consume < 256MiB memory, ~150MiB storage, and < 25% of 1 CPU.
Configure the network to match your overall setup (bridge vs NAT).
Uncheck ‘auto delete’, paste the command line from the previous step., Select Activate.
At this stage you have successfully configured the Agilicus Connector on your Cisco IOx device. You may now configure individual services via the Agilicus admin interface.
Sample things to consider would be SSH to the IOx device, the Web Admin of the IOx device, as well as other onwards resources.
In our example router, the SSH management interface is 192.168.2.2. I added a SSH resource, named irr1101-ssh, with that as the IP. I was then able to sign in via Agilicus Profile and see the Router CLI.
The Agilicus Connector is available as a multi-arch snap (X86_64 and AARCH64/ARM64). It is not currently published to Snapcraft, so it must be side-loaded.
Set 2 snap parameters (code, id) as given from the Agilicus Admin
At this stage the Agilicus Connector should be running and should stay up to date.
Details
Download the snap from the Agilicus website (https://www.agilicus.com/www/releases/secure-agent/stable/agilicus-connector_multi.snap). Install it with sudo snap install agilicus-connector_multi.snap --devmode --dangerous. This will make it unconstrained. NOTE: work is underway to restrict and publish.
In the Agilicus Admin, use Resources/New to create your connector (or Resources/Overview to re-install if you are debugging and iterating). NOTE: if you do uninstall and re-install, remember to delete the stale instance.
On the Install screen, use the ‘Manual’ instructions. You will copy the challenge-id parameter, and then run sudo snap set agilicus-connector setup.id=XXXXX of it. You will then copy the challenge-code, and run sudo snap set agilicus-connector setup.code=XXXX of it. See the below image.
At this stage, the Agilicus connector should start automatically. You may see its logs as sudo snap logs -f agilicus-connector
You should see your Connector transition to ‘Good’. You may also check the statistics on the action menu. A good first service to try is a ‘share’ since it will run entirely within the Snap. You might then try reaching a service on the host running the Agilicus Connector – Snap.
Notes:
Ensure that the time is synced via NTP on the device running the snap. The cryptography has a ‘not-before’ time that requires proper time sync.
Ensure the device is able to reach www.agilicus.com (34.95.12.47), api.agilicus.com (35.203.36.11) on HTTPS port 443. You may test this with: curl https://www.agilicus.com/ and https://api.agilicus.com/v1/resolve/?name=www.agilicus.com.
If you use your own domain, and run split-horizon DNS, ensure it properly resolves the CNAME.
The GL-MT3000 (Beryl AX) has 1 x Gigabit Ethernet, 1 x 2.5 Gigabit Ethernet, 512MiB of RAM, and 256MiB of eMMC storage as well as WiFi 802.11AX. It is an excellent portable platform for demonstrations and field service to run the Agilicus Connector, supporting Cellular (via LTE), WiFI, Ethernet at a low cost point and small form factor.
Installing Stock OpenWRT
You may choose to run the Agilicus Connector on the GL-MT3000 (by using the advanced interface, and running the same commands as below to install ‘curl’, ‘ttyd’, and then the Agilicus Connector. Agilicus recommends replacing GL-iNet custom OpenWRT with the stock one, both for security, as well as compatibility and support.
Connect your laptop to the ‘LAN’ port (or WiFi if you prefer). Sign in to the web interface at http://192.168.8.1/. Navigate to the ‘Advanced settings’, which will log you in to Luci. Download the stock firmware (https://openwrt.org/toh/gl.inet/gl-mt3000), specifically the ‘Firmware OpenWRT Upgrade’ target , and then install via the ‘Backup/Flash Firmware’.
At this stage you are running Stock OpenWRT with its enormous ecosystem of tools, and its very simple to use web interface. You may open http://192.168.1.1/ and do any initial setup.
Agilicus Connector Install
To install the Agilicus connector, first we install the pre-requisite curl. we will also install a web terminal (ttyd).
At this stage, we can install the Agilicus connector. From the Agilicus admin web interface, select ‘Resources/New/Connector’. Copy the Linux command line, paste it into the Services/Terminal on the GL-MT3000. It will complete automatically, no further configuration is needed.
(Optional) Sample Configuration: Connect to Local HTTP (OpenWRT LuCI)
This walk through shows an example of how, once the connector is installed (as per above), configuration of an HTTP interface. Once these are configured you could use the firewall to disable all external access. The high level steps are:
Create Web Resource (Agilicus Admin)
Assign Web Resource Permission (Agilicus Admin)
Open Web Interface to NanoPi (Agilicus Profile or direct)
OK, let’s get started. This will take approximately 2 minutes.
Create a new application. Give it a name (which must be valid as a hostname in format). You will later be accessing this as https://NAME.DOMAIN/. You might consider ‘gl-mt3000’ as a name.
You may, if you wish, have a well-known alias to this new web interface. This is more commonly done with very public ones (e.g. a Wiki or Timesheet system). Leave it as default and the Agilicus AnyX will create the hostname for you.
Select the connector from the previous step.
The connector has to know where to send the request (it is a proxy). The ‘upstream’ in this case is the GL-MT3000 itself, e.g. localhost port 80.
For a bit of additional security we can tie the ‘logout’ URL of the GL-MT3000 web interface to the Agilicus AnyX logout by copying in the URL of the logout. This is optional.
We also suggest that named users with a single role, configured later, for this sample. Normally you would create a group, e.g. ‘Web Admins’ and assign users to it.
At this stage we are done, select ‘Apply’.
Now we will assign ourselves permission to use this new web resource.
To make the profile a bit more ‘fun’ we can now assign a logo (an icon) to the launch of this web interface. In this ‘define’ section we could also refine the Web Application Firewall rules etc.
Any image file (we suggest about 512×512) is suitable for a logo.
At this stage we are done. We have:
created and installed a connector on this GL-MT3000
created a Web resource (to the NanoPi itself)
We can now test our work. Open https://profile.YOURDOMAIN/
Once you have signed in, you will see an icon for the new web resource, if you click it, a new browser tab will open. Observe the URL (https://NAME.DOMAIN). You can use this directly without profile if you wish. If you sign in, you will see the GL-MT3000 web interface directly. Now try it from a different network (e.g. your mobile phone, disable WiFi). Observe you can still connect. Now try with an unprivileged user (e.g. a different Gmail account), observe you cannot sign in.
The ‘profile’ interface acts as a launch pad for the end-user. It will act as a Progressive Web Application (e.g. ‘add to homescreen’ on your mobile), giving you a single launch icon.
You may also use the resources it points to directly: it is your choice.
We can test the SSH access. From profile, select the resource we created earlier.
We will see a ‘login’ dialog appear, enter the username (root) and password to the GL-MT3000.
At this stage, we should see an SSH terminal.
From here, consider using the ‘Launcher’ install feature of profile, add the Browser Extension. You will now see an entry on your start menu for this SSH, opening the native client (e.g. if you have Putty or OpenSSH installed).
Similarly to the Web Resource, only users with permission are able to sign in. You may also choose to enable multi-factor authentication on your user and observe how this functions with the Web..
The Agilicus Connector can be installed in a high-availability mode. In this mode, multiple copies of the connector will concurrently run. Each connector which is up and healthy will share in some of the network traffic. Encryption keys are shared across the connectors in such a way that they are still in the customer’s sole custody.
NOTE
The Agilicus Connector does not support High Availability if a Share is present. As a work-around, either create a Connector managing all resources other than Shares, or, use the Windows Cluster approach which does support a Share.
The installation instructions for the first connector in a High Availability set are the same, and, for each subsequent one, similar.
Installation
Installation is simple.
Create and install the first instance on a machine
Install subsequent instances (up to 4) on other machines
Pre-requisites:
One connector must be up for a new one to be added
All connectors must be able to reach the same network resources.
Initial (First) Connector in High Availability Set
The installation instructions for the first connector in a high availability set are the same as for non high-availability.
At this stage, the first connector is installed. Ensure it transitions to “GOOD” since it must be up and running to join the other connectors to the cluster.
Adding High Availability Peers (Subsequent Connectors)
To add additional high-availability peers, simply use the ‘Actions/Install Connector’ option on the first instance we created above.
At this stage we are done, and there are two connectors running in High Availability mode. Note the slight difference in the output of the installation at the end (“Joining existing cluster. This will fail if another connector in this cluster is not online“)
INFO[2024-04-01T11:55:38-04:00] Starting connector - version v0.246.9 INFO[2024-04-01T11:55:39-04:00] Check if the agilicus connector is already running as a service. If so stop it INFO[2024-04-01T11:55:39-04:00] Create file /usr/bin/agilicus-agent-wrapper.sh INFO[2024-04-01T11:55:39-04:00] Create file /etc/systemd/system/agilicus-agent.service INFO[2024-04-01T11:55:39-04:00] Will install to /agilicus-agent.service -> {/etc/systemd/system/agilicus-agent.service -r--r--r-- 0x14cf980} INFO[2024-04-01T11:55:39-04:00] Will install to /agilicus-agent-wrapper.sh -> {/usr/bin/agilicus-agent-wrapper.sh -rwxr-xr-x <nil>} INFO[2024-04-01T11:55:39-04:00] Create a directory at /opt/agilicus/agent/tufmetadata/latest INFO[2024-04-01T11:55:39-04:00] Create a directory at /opt/agilicus/agent/tufmetadata/stable INFO[2024-04-01T11:55:40-04:00] Create a user and group named Agilicus to run the agilicus-agent service INFO[2024-04-01T11:55:40-04:00] Copy executable to /opt/agilicus/agent INFO[2024-04-01T11:55:40-04:00] Set permissions to Agilicus on /opt/agilicus/agent INFO[2024-04-01T11:55:40-04:00] Create symlink from /usr/bin/agilicus-agent to /opt/agilicus/agent/agilicus-agent INFO[2024-04-01T11:55:41-04:00] creating connector instance INFO[2024-04-01T11:55:41-04:00] Join a connector cluster INFO[2024-04-01T11:55:41-04:00] Joining existing cluster. This will fail if another connector in this cluster is not online INFO[2024-04-01T11:56:01-04:00] Start agilicus-agent service
Agilicus Connector Air Gap Machine With Containers
Create a nearly-fully airgapped machine, with interior containers, no way in, and only 1 way out via Agilicus Connector.
Agilicus Connector Air Gap Machine With Containers
Imagine we have a complex set of orchestrated containers. They interoperate with each other. But, we don’t want them reaching the Internet, or the Internet reaching them.
Some or all of these containers have a need to use remote services. Perhaps a cloud provider, perhaps another set in another building.
In this example we show how to:
Block all inbound traffic to a Debian 12 host
Block all outbound traffic except for Agilicus API + Dataplane
Use a service forwarder to allow specific containers to reach specific remote services
For the container runtime we will use docker. The example below is a Debian 12 host with all options default, with docker.io installed.
Debian 12: Default Firewall Rules
Before we start we can inspect the default firewall rules. In a nutshell these:
allow all outbound traffic from the host to Internet
allow all outbound traffic from containers to Internet
allow all outbound traffic from containers to host
# iptables-save # Generated by iptables-save v1.8.9 (nf_tables) on Thu Apr 18 18:57:40 2024 *filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :DOCKER - [0:0] :DOCKER-ISOLATION-STAGE-1 - [0:0] :DOCKER-ISOLATION-STAGE-2 - [0:0] :DOCKER-USER - [0:0] -A FORWARD -j DOCKER-USER -A FORWARD -j DOCKER-ISOLATION-STAGE-1 -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -o docker0 -j DOCKER -A FORWARD -i docker0 ! -o docker0 -j ACCEPT -A FORWARD -i docker0 -o docker0 -j ACCEPT -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2 -A DOCKER-ISOLATION-STAGE-1 -j RETURN -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP -A DOCKER-ISOLATION-STAGE-2 -j RETURN -A DOCKER-USER -j RETURN COMMIT # Completed on Thu Apr 18 18:57:40 2024 # Generated by iptables-save v1.8.9 (nf_tables) on Thu Apr 18 18:57:40 2024 *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] :DOCKER - [0:0] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE -A DOCKER -i docker0 -j RETURN COMMIT # Completed on Thu Apr 18 18:57:40 2024
Setup: Block inbound traffic, block outbound except to Agilicus Cloud, Local DNS/DHCP
Note: you may wish to have console access rather than SSH access in case you make a mistake.
We can see the Agilicus required IP/hostnames. For this example, we will allow (on port 443), these two IP:
34.95.12.47 (www.agilicus.com)
35.203.36.11 (api.agilicus.com)
iptables -P OUTPUT DROP iptables -P INPUT DROP iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT iptables -A INPUT -m conntrack --ctstate INVALID -j DROP iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -p tcp -d 34.95.12.47/32 --dport 443 -j ACCEPT iptables -A OUTPUT -p tcp -d 35.203.36.11/32 --dport 443 -j ACCEPT iptables -A INPUT -p udp -m multiport --sports 67,68,123,53 -j ACCEPT iptables -A OUTPUT -p udp -m multiport --dports 67,68,123,53 -j ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT
At this stage, we can test. First let us confirm that DNS works and that we can reach Agilicus WWW (for system updates):
$ curl -I https://www.agilicus.com/ HTTP/2 200
Now let us check that we cannot reach other websites:
$ curl -I https://www.google.ca/ <timeout>
Now let us demonstrate that a docker container cannot escape:
# docker run --rm -it busybox Unable to find image 'busybox:latest' locally ... timeout
Not so fast, we have now blocked docker hub. For our scheme to work, we will need to either get all containers on the machine out of band, or allow a docker registry. I will demonstrate the out-of-band technique:
# On a machine with Internet access (not the one we are firewalling): $ docker pull library/busybox Using default tag: latest latest: Pulling from library/busybox 7b2699543f22: Pull complete Digest: sha256:c3839dd800b9eb7603340509769c43e146a74c63dca3045a8e7dc8ee07e53966 Status: Downloaded newer image for busybox:latest docker.io/library/busybox:latest $ docker image save -o /tmp/busybox.tar library/busybox $ scp /tmp/busybox.tar don@192.168.122.206:/tmp/ busybox.tar 100% 4400KB 54.7MB/s 00:00 # 192.168.122.206 is the IP of the firewalled machine which we have allowed SSH to, you can also use a USB flash drive # On the firewalled machine: $ docker image load -i /tmp/busybox.tar $ docker run --rm -it library/busybox / # ping 1.1.1.1 PING 1.1.1.1 (1.1.1.1): 56 data bytes 64 bytes from 1.1.1.1: seq=0 ttl=55 time=17.874 ms ^C ### HUH?
OK, why did the container reach the Internet if the host cannot? For this we need to understand FORWARD (e..g routing) versus INPUT/OUTPUT. The Host is routing the docker traffic, we need some rules in the FORWARD path.
OK, we now have a set of containers which cannot reach the Internet on anything, and, a host that can reach a very limited set (DNS, DHCP, and Agilicus AnyX Cloud).
Let us now check that the container can still reach the host. For this we will use two windows. In one, we will run ‘netcat’ to listen on a port, in the other we will test from the host to itself. In green, window 1, we run netcat in listen mode:
$ nc -lvp 8888 listening on [any] 8888 ... connect to [127.0.0.1] from localhost [127.0.0.1] 38276
In black, we run netcat in connect mode, we observe it works.
$ nc -vv localhost 8888 localhost [127.0.0.1] 8888 (?) open ^C sent 0, rcvd 0
Let us now try from within the container
$ docker run --rm -it library/busybox / # nc 172.17.0.1 8888 ... hang
Why did this hang? We are blocking all INPUT/OUTPUT except loopback (lo) and except for certain IP/port pairs. Let us add docker0 back in:
# iptables -A OUTPUT -o docker0 -j ACCEPT # iptables -A INPUT -i docker0 -j ACCEPT
OK at this stage we can test again, and it works. The container can reach the host (on all ports), but not the Internet.
This now works, demonstrating that our above firewall rules prevent port 80 access.
Next Steps
You can save/restore your iptables rules with iptables-save and iptables-restore. You can install iptables-persistent package to make these load on reboot (or put the rules in e.g. /etc/rc.local).
You may consider only allowing the containers to reach specific ports, where we would run the Agilicus connector.
The final rule set we ended up with:
# iptables-save # Generated by iptables-save v1.8.9 (nf_tables) on Thu Apr 18 20:19:46 2024 *filter :INPUT DROP [87:68971] :FORWARD DROP [0:0] :OUTPUT DROP [154:12030] :DOCKER - [0:0] :DOCKER-ISOLATION-STAGE-1 - [0:0] :DOCKER-ISOLATION-STAGE-2 - [0:0] :DOCKER-USER - [0:0] -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -m conntrack --ctstate INVALID -j DROP -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p udp -m multiport --dports 67,68,123,53 -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -i docker0 -j ACCEPT -A FORWARD -j DOCKER-USER -A FORWARD -j DOCKER-ISOLATION-STAGE-1 -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -o docker0 -j DOCKER -A FORWARD -i docker0 ! -o docker0 -j ACCEPT -A FORWARD -i docker0 -o docker0 -j ACCEPT -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A OUTPUT -d 34.95.12.47/32 -p tcp -m tcp --dport 443 -j ACCEPT -A OUTPUT -d 35.203.36.11/32 -p tcp -m tcp --dport 443 -j ACCEPT -A OUTPUT -p udp -m multiport --sports 67,68,123,53 -j ACCEPT -A OUTPUT -p udp -m multiport --dports 67,68,123,53 -j ACCEPT -A OUTPUT -o lo -j ACCEPT -A OUTPUT -o docker0 -j ACCEPT -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2 -A DOCKER-ISOLATION-STAGE-1 -j RETURN -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP -A DOCKER-ISOLATION-STAGE-2 -j RETURN -A DOCKER-USER -j RETURN COMMIT # Completed on Thu Apr 18 20:19:46 2024 # Generated by iptables-save v1.8.9 (nf_tables) on Thu Apr 18 20:19:46 2024 *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] :DOCKER - [0:0] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER -A DOCKER -i docker0 -j RETURN COMMIT # Completed on Thu Apr 18 20:19:46 2024