The desire is to have a share that anyone can use, but not have to pre-provision the users.
There are different ways to achieve this. We could:
have an anonymous (no authentication) share. This is not very secure.
Use ‘auto-create’ users, and, a default group with permission.
Use the Requests flow, where a new user can self-enable and request the first time
In this example we will show #3, the Requests flow.
Step 1: Ensure Requests Flow is Enabled
Step 2: Create A New Share
If you have an existing share, skip ahead to step 3, else create one according to “Secure File Sharing“. No specific config is needed.
Step 3: Ensure Requests Flow is Enabled
Make the share ‘published’. This means it will show up to the end user as ‘requestable’.
Step 4: Enable Notifications
This is optional, but, it allows the administrator to be notified of new requests. If you don’t enable the notification will need to periodically open the admin interface and check for new requests.
At this stage we are done the administrative setup. The end user can now request access
Step 5: Enable Notifications
At this stage users can request access, and the admin can grant it, automatically.
Rockwell Automation’s Allen-Bradley PanelView Graphic Terminals provide rugged Human Machine Interface (HMI) in an industrial setting. These terminals support VNC for remote access.
Learn how to making VNC remotely available, simply, securely, without port-forwards, VPNs, or complex firewalls using Agilicus AnyX.
Rockwell Automation PanelView devices offer industrial-hardened Human Machine Interfaces (HMI). These may be used for viewing process status & alarms, or for input/control.
A common requirement is to have remote operations view (or interact) with the HMI. The PanelView devices support VNC, meaning its possible, but the network security of VNC is very poor. Absent a product like Agilicus AnyX, plants often use port-forward, DMZ, VPN access, putting themselves at risk.
In this example using Agilicus AnyX, we will show how to safely, securely, simply use Rockwell Automation PanelView devices from a remote network, assigning permissions to individual users with single-sign-on, optional with multi-factor authentication, without modifying the local firewall config. Agilicus AnyX can perform password stuffing in VNC, meaning there is no need to share the password with the individual operators.
Installation Instructions
Overview
If you have not already, sign up for Agilicus AnyX. In the below instructions, we will refer to _ _MYDOMAIN_ _, this is the domain you chose during the Agilicus AnyX sign up process. If you have navigated to this page from the Agilicus admin console (https://admin.__MYDOMAIN__), this will be filled in automatically.
Once setup, the data flow will be as shown to the right. The user will have either web-based access, or, desktop client access to each HMI. They will sign in with their natural corporate credentials (regardless of whether directly employed by the Plant or being a 3rd-party contractor providing remote operations). The will see the HMI directly, no client software is required, no changes are needed on the firewall.
Concepts
Agilicus Connector: this software installs as a service on some device in your network. It can support multiple operating systems. Each connector can support an arbitrary number of resources (web applications, shares, VNC, RDP, etc.). In general you need one connector per site.
Authentication: attesting you are who you say you are. Agilicus AnyX uses OpenID Connect, and supports zero-config of Microsoft, Google, Yahoo, Linkedin, or, you can configure your own such as Okta.
Identity: who you are. This is external to the Agilicus AnyX system.
Resource: an individually accessible and permissionable endpoint. In this example, VNC
Permission: assigning a role and access rules per person<->resource pair.
In this example, we are assuming you will install the Connector on a machine on the same network as the PanelView HMI. It needs to have access to port 5900 on the HMI.
Select the appropriate tab for your Operating System.
Navigate to the admin console (https://admin.__MYDOMAIN__). Sign in with the credentials you used during sign up. Select resoures/connectors/new, and give the new connector a name (here we are using ‘openwebui’). Select ‘Install Connector’.
In the dialog that comes up, select Linux at the top, and then copy the command line. Paste this into a root shell.
Depending on your Linux distribution, this will install a service with systemd, upstart, init.d, etc. These instructions should also work on embedded devices (e.g. Raspberry pi).
When complete, the dialog should dismiss itself. We can now check the connector status in Resources/Connectors/Overview, and see it will go ‘good’.
If the connector doesn’t come online, check that the service is running and check for any errors in its log. Common errors include:
NTP / timesync is not setup
Outbound firewall prevents connections to port 443 (the Connector can support MITM proxies in corporate environments if needed)
Navigate to the admin console (https://admin.__MYDOMAIN__). Sign in with the credentials you used during sign up. Select resoures/connectors/new, and give the new connector a name (here we are using ‘openwebui’). Select ‘Install Connector’.
In the dialog that comes up, select Windows-CMD at the top, and then copy the command line. Paste this into an Administrator cmd interface (e.g. on start menu, type ‘cmd’, and then select ‘Administrative shell’ on the right).
When complete, the dialog should dismiss itself. We can now check the connector status in Resources/Connectors/Overview, and see it will go ‘good’.
If the connector doesn’t come online, check that the service is running and check for any errors in eventvwr. Common errors include:
NTP / timesync is not setup
Outbound firewall prevents connections to port 443 (the Connector can support MITM proxies in corporate environments if needed)
2. Create PanelView VNC Resource
In this example we assume you already have the PanelView device running and VNC enabled on it with either a ‘View Only’ or a ‘Control’ password.
In our sample network, the HMI is called ‘PV800T4T’ and has an IP of 172.16.0.247 (please either use a name and ensure your DNS resolves it, or, disable DHCP on the HMI and use a static IP.
Follow the images below, ‘Resources/Desktops/New’, create a new desktop, give it a name. For the optional component about password stuffing, you can ignore in which case the user must enter a 2nd VNC password each time. Or, you can enter the View Only and/or Control password. If you do this, the end user will not be aware of the password.
Assign permissions to yourself to test.
Once configured, navigate to https://profile.__MYDOMAIN__, you may need to hit refresh, but you should now see an icon for the new VNC. You can open this directly in the browser, or, if you choose, install the desktop integration and click it to open the native client.
3. Add a second user (optional)
We can now add a second user to share. Enter their email address (this must match that given by the Identity Provider, e.g. user@gmail, user@outlook.com, user@google-workspace-domain, user@office365-domain etc.
Now, add permissions to the user. If you have a lot of applications or a lot of users, consider using Groups.
Open WebUI is an extensible, feature-rich, and user-friendly self-hosted AI platform designed to operate entirely offline. It supports LLM runners like Ollama, with built-in inference engine for RAG. Given that is designed to operate offline, it is commonly used in home and office environments.
Open WebUI by default is entirely insecure: any user who can reach the port it is running on can use it. Thus it is not suitable for a simple port-forward (and, in addition, some networks have restrictive firewalls or NAT which don’t allow inbound access) to use remotely.
In this example using Agilicus AnyX, we will show how to safely, securely, simply use Open WebUI from a remote network, assigning permissions to individual users with single-sign-on, optional with multi-factor authentication, without modifying the local firewall config.
Installation Instructions
Overview
If you have not already, sign up for Agilicus AnyX. In the below instructions, we will refer to _ _MYDOMAIN_ _, this is the domain you chose during the Agilicus AnyX sign up process. If you have navigated to this page from the Agilicus admin console (https://admin.__MYDOMAIN__), this will be filled in automatically.
Once setup, the data flow will be as shown to the right. The user will have a new URL available (https://openwebui.__MYDOMAIN__). On navigating there, they will be required to sign in (in the same way as Sign in with Google or Sign in with Microsoft on other sites). Once done, they will see the Open WebUI directly, no client software is required, no changes are needed on the firewall.
Later, you can add an api key and directly access Ollama from elsewhere if needed.
Concepts
Agilicus Connector: this software installs as a service on some device in your network. It can support multiple operating systems. Each connector can support an arbitrary number of resources (web applications, shares, VNC, RDP, etc.). In general you need one connector per site.
Authentication: attesting you are who you say you are. Agilicus AnyX uses OpenID Connect, and supports zero-config of Microsoft, Google, Yahoo, Linkedin, or, you can configure your own such as Okta.
Identity: who you are. This is external to the Agilicus AnyX system.
Resource: an individually accessible and permissionable endpoint. In this example, Open WebUI
Permission: assigning a role and access rules per person<->resource pair.
In this example, we are assuming you will install the Connector on the same machine as Open WebUI.
Select the appropriate tab for your Operating System.
Navigate to the admin console (https://admin.__MYDOMAIN__). Sign in with the credentials you used during sign up. Select resoures/connectors/new, and give the new connector a name (here we are using ‘openwebui’). Select ‘Install Connector’.
In the dialog that comes up, select Linux at the top, and then copy the command line. Paste this into a root shell.
Depending on your Linux distribution, this will install a service with systemd, upstart, init.d, etc. These instructions should also work on embedded devices (e.g. Raspberry pi).
When complete, the dialog should dismiss itself. We can now check the connector status in Resources/Connectors/Overview, and see it will go ‘good’.
If the connector doesn’t come online, check that the service is running and check for any errors in its log. Common errors include:
NTP / timesync is not setup
Outbound firewall prevents connections to port 443 (the Connector can support MITM proxies in corporate environments if needed)
Navigate to the admin console (https://admin.__MYDOMAIN__). Sign in with the credentials you used during sign up. Select resoures/connectors/new, and give the new connector a name (here we are using ‘openwebui’). Select ‘Install Connector’.
In the dialog that comes up, select Windows-CMD at the top, and then copy the command line. Paste this into an Administrator cmd interface (e.g. on start menu, type ‘cmd’, and then select ‘Administrative shell’ on the right).
When complete, the dialog should dismiss itself. We can now check the connector status in Resources/Connectors/Overview, and see it will go ‘good’.
If the connector doesn’t come online, check that the service is running and check for any errors in eventvwr. Common errors include:
NTP / timesync is not setup
Outbound firewall prevents connections to port 443 (the Connector can support MITM proxies in corporate environments if needed)
2. Create Open WebUI Web Application
In this example we assume you already have Open WebUI running, in the default mode listening on port 8080.
don@office[ca-1]:~$ open-webui serve
WARNING: CORS_ALLOW_ORIGIN IS SET TO '*' - NOT RECOMMENDED FOR PRODUCTION DEPLOYMENTS.
___ __ __ _ _ _ ___
/ _ \ _ __ ___ _ __ \ \ / /__| |__ | | | |_ _|
| | | | '_ \ / _ \ '_ \ \ \ /\ / / _ \ '_ \| | | || |
| |_| | |_) | __/ | | | \ V V / __/ |_) | |_| || |
\___/| .__/ \___|_| |_| \_/\_/ \___|_.__/ \___/|___|
|_|
v0.5.3 - building the best open-source AI user interface.
https://github.com/open-webui/open-webui
INFO: Started server process [2151942]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
We will create a Web Application in Agilicus AnyX. This will create a new URL, https://openwebui.__MYDOMAIN__, and, any user navigating there will be forced to authenticate via OpenID Connect and have a permission assigned. This means it is both publicly accessible on the Internet, and, secure.
Network data will from from the user, through the Agilicus AnyX cloud, to the Agilicus Connector, and onward to the Open WebUI. This will be TLS encrypted from the user to the Connector, making it secure and non interceptable (including by Agilicus).
First, navigate to resources/applications/new. Give this a name (it will become a hostname so no spaces or special characters). Here we use ‘openwebui’.
Second select the Access method (from your premises via a connector). Select the connector you installed in the previous step.
Third, configure the ‘upstream services’ (the local http://localhost:8080 information).
Fourth, configure how your application is authenticated. Here we configure authentication via proxy, if you wish to do more configuration you can integrate your applications directly via OpenID Connect. But ‘authenticated by proxy’ will work for all web applications. Optional, configure a pass-through logout (/api/v1/auths/signout) so that signing out of the web app also signs out of the proxy. Configure how users are assigned permissions. Here we select ‘named users, single role’, to allow us to control who can use this application.
You will be presented with a Summary. Hit APPLY.
Now, we will assign initial permissions to access this application to our user. You can also do this later under Access/Application Permissions.
At this stage we can navigate to https://profile.__MYDOMAIN__ (the end-user interface), hit refresh, and should see an icon for openwebui. We can also directly navigate to https://openwebui.__MYDOMAIN__ directly from your browser.
3. Add a second user (optional)
We can now add a second user to share. Enter their email address (this must match that given by the Identity Provider, e.g. user@gmail, user@outlook.com, user@google-workspace-domain, user@office365-domain etc.
(See below in ‘Next Steps: Single Sign On’ for configuring Open WebUI to automatically accept the user via the “WEBUI_AUTH_TRUSTED_EMAIL_HEADER” environment variable)
Now, add permissions to the user. If you have a lot of applications or a lot of users, consider using Groups.
Next Steps
Open WebUI supports a “WEBUI_AUTH_TRUSTED_EMAIL_HEADER”. See “Include User Context Headers” which allows setting “X-Gateway-User-Email”. If you set the environment variable WEBUI_AUTH_TRUSTED_EMAIL_HEADER=X-Gateway-User-Email, users will be automatically signed into Open WebUI.
The C-more HMI Panel by Automation Direct is a user-friendly, touch-screen interface designed for controlling and monitoring industrial automation systems. By combining Agilicus AnyX with the existing remote access capabilities, C-more HMIs are secured with Zero-Trust access to enhance efficiency and flexibility in a wide range of applications, from manufacturing to process automation.
Using one C-more Remote HMI application as a launcher for all HMIs
The C-more Remote HMI Windows software is a lightweight, functional executable that allows users to remotely access and control C-more HMI panels from a Windows PC. Typically downloaded directly from the HMI panel itself, this executable is customized for each remote HMI, with the panel’s IP address and port information embedded in the filename. This ensures a quick and direct connection to the specific HMI upon launch, simplifying remote monitoring and control.
The HMI web server is usually pre-configured with a set of IP addresses assigned for its Built-in Ethernet adapter both Local and Remote connection where it is deployed. This configuration assumes a requirement for inbound Firewall traversal through port-forwarding and requires knowledge of the network topology for the operator to properly provision the Remote HMI software. These IP Addresses are often referred in the product documentation as %IP1% and %IP2%
The Remote HMI downloadable application from the panel is named after the %IPx% address fields configured.
For example, if the C-More configuration for %IP2% is IP address 172.17.10.2, the downloaded executable filename would be “RemoteHMI_IP=[172.17.10.2_11102].exe”
This approach streamlines deployment of the viewer application and execution. However, in situations where an operator requires multiple panel views, an executable file is required for each panel remote IP address. This can result in many duplicate copies of the same Remote HMI viewer app with a different filename. This approach also assumes either VPN or port-forwarding capability on the remote network. This also limits the usability of using simultaneous Remote HMI client in cases where the remote C-more panels may have a duplicate or overlapping IP address space across multiple sites, requiring the operator to properly control the remote VPN connectivity to ensure the correct site is being routed, or mapping different TCP ports on the Firewall/Router port-forwarding configurations.
Configuring AnyX Launcher and simplifying deployment
The use of the Agilicus AnyX application launcher vastly simplifies the deployment the C-more Remote HMI application while enhancing security:
Single Remote HMI windows executable installation to accomodate all remote panels across all sites
Individual launcher shortcut for each panel labeled by name
No VPN, No Firewall and Port-Forwarding Configuration
Enhanced Security with Identity based authentication and Multi Factor Authentication
Specific Resource exposure without network access
In this guide we will:
Create and configure a Network Resource for the HMI Panel IP address
Create an Application Launcher for the Remote HMI client executable
Associate the Network Resource with a Dummy IP to the Application Launcher
Grant permission to user or group to use the Launcher
Deploy the C-more executable on the local workstation
Creating Network Resources
We will create a Network Resource in the Agilicus AnyX Administration interface for each panel we wish to use view.
We create a network resource named after the HMI panel network information. In this configuration, we will make use of the AnyX “Override IP” in order to simplify the use of the C-More application. The “Override IP” enables an IP address re-write of the destination by the connector. This means, that regardless of where the IP address the C-more HMI client attempts to connect to, the connector will steer the traffic to the “Override IP” address. This approach unlocks the ability to use a ‘Dummy IP’ address in both the C-more HMI client , and Network Resource creation, and then rewrite to the intended destination. The advantage of this feature, as we’ll describe below, is that a single executable file of the C-more HMI client can be used, and the Agilicus AnyX connector will correctly steer the traffic to the intended panel.
First, we configure the Network Resource by selecting the appropriate Connector through which the C-more HMI panel can be reached on the LAN.
We then create the addressable resource by assigning it a meaningful name. Here, as an example, we wish to reach panel #44, create a network as in the below image:
In the next step, we introduce the ‘Dummy IP’ address, as well as the ‘Override IP’ address of the actual panel. In this example, we pick the ‘Dummy IP’ address of 123.123.123.123 , and we intend to reach the HMI panel on the local LAN at the IP address 172. 17.10.2 (note: This should match the %IP1% address defined in the C-more panel configuration). We will use the default TCP port 11102 as in the below images.
Configuring the Application Launcher
In order to create the appropriate launcher, we will define the path of the C-more HMI client software locally on the workstation to be used, and associate the Network Resource specific to this launcher icon. This will create a desktop launch icon with the Launcher Name, and use a single executable for all subsequent launchers created for each panel.
Create launcher name and executable path as in the below image:
Here we choose to name the launcher after the Panel and Plant location example we’ve used in this write up. This will be the name associated with the Launcher icon on the desktop.
For the command path, we are specifying the path to the executable file for the C-more Remote HMI. A previously downloaded client file can be used. We specifically rename the file to contain the previously defined ‘Dummy IP’ address, and the TCP port used. You can rename an existing file and make sure to preserve the syntax [x.x.x.x_Port].exe
We then associate the specific Network Resource of the desired HMI panel previously configured that will be associated with the launcher.
We then enable the launcher DNS and Interception feature
A final review of the launcher parameters can then be applied.
Installing the C-more Remote HMI client
In order for the launcher to execute properly, the application path and filename must match the one configured in the Agilicus AnyX configuration, and a Resource Permission must be assigned to the Identity or Group the user belongs to.
In this case, we specified a command path of : C:\cmore\RemoteHMI_IP=[123.123.123.123_11102].exe
The location of the executable can vary based on deployment requirements, and the use of local expansion variables such as %appdata% can also be employed. Ensure that the executable filename contains the ‘Dummy IP’ address as it is used by the C-more client software itself as a configuration parameter at startup.
Launching the C-more Remote HMI client
After a resource refresh is done on the user workstation, the launcher will appear with the proper application icon as well as label, in this case: Plant-A_Panel-44 .
When executing the launcher, the C-More Remote HMI client will establish a connection to the desired panel defined in the ‘Override IP’ in the Agilicus AnyX configuration and %IP1% in the C-more Remote Access configuration, in this example, 172.17.10.2 .
These steps can be repeated to generate a launcher icon for each panel in the system , across all sites covered by the Agilicus AnyX connectors. The same single executable with the ‘Dummy IP’ address is used, and each instance will connect to the intended remote panel defined
Imagine you have a network video recorder (NVR) which is located centrally. And, you have a remote site with a surveillance camera that speaks HTTPS (the below instructions are not suitable for RTSP). The remote site is served via Starlink, which has no possibility of inbound access due to NAT.
If you have an architecture where you normally use a fixed-IP and a port-forwarding system, you might find SNI-based routing can be an appropriate substitute. This example gives some tips on setting this up.
Select Resources/Applications/New, give the camera a hostname (this needs to be a valid Internet name). Select ‘from my site via onsite connector’, select the connector you created above.
For the upstream, the IP (or hostname) will be the *internal* one, e.g. what the Connector would see or talk to. You may need to select one of “No-TLS”, “TLS-AND-VERIFY”, “TLS-AND-NO-VERIFY”, depending on whether your camera is setup with encryption/https.
Now apply permissions to yourself. At this stage you can test the camera (e.g. open your mobile, turn off WiFi, open https:///profile.__MYDOMAIN__/ and then select the camera, or, navigate directly to its url, https://<my-camera>.__MYDOMAIN__, where my-camera is the name you gave it, and __MYDOMAIN__ is the domain you chose when signing up to Agilicus (its in the top URL bar of your admin web interface).
Modify Network
At this stage we will enable direct routing (disabling the firewall). We do this by finding the backend network created above, selecting ‘expose as hostname’. Note the exact hostname given, something.networks.__MYDOMAIN__. This should now be available for your NVR to connect to.
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 situation: we have a machine in an industrial air gap environment that needs to send email. Perhaps its VTscada, perhaps something else. We would prefer to use Google (smtp.google.com) or Microsoft (outlook).
The site doesn’t have outbound Internet connectivity, and this is undesired. The Agilicus connector has a single outbound HTTPS (port 443) connection, and we will multiplex the SMTP over this.
In the below diagram, we have a system that is needing to send email (VTS), we have two Agilicus Connectors (C1, C2) as a high-availability set. We have a site firewall (FW). We have our company headquarters with an Agilicus Connector (HQ).
The Agilicus connectors each have HTTPS outbound connectivity (port 443) to a fixed IP (Agilicus AnyX).
To configure this, we will first create a Network. This is logically running in the *HQ* site, and must have onwards connectivity (and DNS lookup). In the example given, we have used smtp.google.com, port 587.
NOTE: Google Email Authentication
❗
To prevent spam, Google has strict authentication requirements for connecting to their SMTP service. You can see more information in “Send email from a printer, scanner, or app“
The parameters for the network are:
name
arbitrary (this is a label for you)
Hostname/IP
smtp.google.com (or IP)
Port
587
Via Connector
HQ (or your connector name running outside firewall)
Next we create the Service Forwarder. Conceptually this runs on the connector within the Air Gap site. It will listen on a port, and, forward that to the Network we defined above.
Source Connector
C1 (or on-premise connector)
Destination Network
(Name chosen above in Networks)
Source IP/Hostname
0.0.0.0 (causes to listen on external interface)
Source Port
587
At this time the connectors (C1 and C2 above) will start listening on port 587. You can now configure your SMTP client to use the IP of C1 or C2, port 587, configure the SMTP authentication criteria.
To diagnose use the Connectors/Overview, select the action-button (3-dots) and then ‘view detailed statistics’. Wait a few seconds, attempt to send some email, wait a few seconds, and observe the counters.
The Phoenix Contact PLCnext Engineer is a software engineering tool designed for developing automation applications. By combining the software with Agilicus AnyX Zero-Trust secure remote access, secure programming from anywhere is possible
Configuring PLCnext Engineer as a Launcher
The Phoenix Contact PLCnext Engineer is a software engineering tool designed for developing automation applications. It is part of the PLCnext Technology ecosystem, which aims to provide a flexible and open automation platform. It is a versatile and powerful tool for developing modern automation solutions, offering flexibility, openness, and advanced features to meet the needs of various industrial applications.
When combined with the Agilicus AnyX platform, the software suite can access remote Industrial Control System automated applications via a reliable Zero Trust architecture.
Let’s first create a sample remote controller network resource to allow the Engineer software to access.
Navigate the Admin interface to Resources -> Networks -> New
In Step 1, select the appropriate connector where the remote controller is deployed. In this example, we are selecting a connector installed on a PLCnext AXC F controller at a remote site.
For Step 2, assign a relevant internal hostname for the remote network
In the following step 3, configure the valid local IP address and TCP port of the remote controller.
Eg: address of 172.17.2.131 , TCP port of 41100
In Step 4, Select Optional parameters to specify additional options. In this step, we will add “source port override” settings at the bottom of the menu. Keep the standard TCP port of 41100 .
Add a new and unique system address in the 127.x.x.x IPv4 local loopback network aka LocalNet space.
This optional parameter will be used for the Engineer software client to connect through the Agilicus platform via a temporary ‘Ad-hoc’ connection assigned to this unique local IP address that will be created on the workstation where the client software is installed and launched. One such unique address inside the Loopback network will be required for each remote controller, and should not be previously used on the workstation.
In this example, and for sake of addressing clarity and recall, we are using the same last 3 tuples of the controller remote IP address to form a loopback address.
So the remote controller network IP address of 172.17.2.131 is assigned through this option dialog to a local override IP address of 127.17.2.131 for the local Engineer workstation to bind to.
Click “Apply” in step 5
Repeat this Network Resource creation stepper for each remote network controller that requires access by the Engineer software. Ensure each “Source address override” in the loopback network remains unique .
Configuring PLCnext Engineer as an Agilicus Launcher
In the Agilicus Admin panel, first create a launcher for the Engineer software by navigating to the Resources -> Launcher -> New menu
Assign a name to the launcher, e.g.: PLCnextEngineer2024 and specify the valid path to the actual executable (not the shortcut). The default installation path will be:
Note that the version string is present in the path and may need to be changed when a software update is done at a later time.
In Step 2, we will assign all the resource members previously configured so that the Engineer software can access them. In this case, the previously configured sitea-controller1 network is assigned.
In the third step, we will select NO for any advanced settings.
In the final configuration step, we can review the New Launcher settings and select Apply to confirm the configuration.
As part for of the Agilicus AnyX permission and resource assignments, we can use step 5 to assign the newly created Launcher to a set of Resource Groups , or assign the resource directly to a set of user identity or user groups.
If this step is skipped, authorization to this newly created Launcher resource can be assigned via the Access -> Resource Permissions admin menu
Launching the PLCnext Engineer application
After running the Agilicus “Refresh” desktop shortcut, any user workstation with Agilicus Desktop Integration will have a visible PLCnext Engineer launcher created in the Agilicus start menu.
Clicking on this launcher will run the Engineer software and also perform the necessary authentication and authorisation phase for the Agilicus AnyX platform.
The Engineer software will launch as usual, and an existing Project can be opened.
In order to access the remote controller via the Agilicus platform, select the controller and navigate to the Cockpit tab, and then select the ‘Ad-hoc IP address’ menu. To configure the IP address to connect via Agilicus, first “Enable” the setting, and then specify the IP address previously configured as the “source address override”. In this example, we will use 127.17.2.131 . Navigate away from the dialog in order to make sure the setting is saved. Saving the project will also preserve the assigned IP address.
With this configuration set, enabling ‘Ad-Hoc address’ will allow the Engineer software to connect to the remote controller via the Agilicus platform. Disabling ‘Ad-hoc address’ will set the Engineer software to connect via the configured IP address via the local network and interface selected in the general configuration parameters.
Note that the specified “Ad-Hoc address” will only be reachable when Engineer is started as an Agilicus Launcher and will otherwise not be active when run natively.
Connect to the remote controller with Ad-Hoc address enabled:
Agilicus AnyX and VTScada are an ideal complementary match. Agilicus AnyX provides on-demand access, from anywhere, to any user, to the VTScada Anywhere client. This provides high-security and high simplicity usage for remote support and diagnostics.
A minor usability issue can arise, a ‘double login’ experience. The user signs in via Agilicus AnyX with their corporate single-sign-on credentials, but, then the VTScada system doesn’t trust them. This happens with external support and contractors as well as direct staff. Fortunately there is a simple solution: Configure VTScada to ‘participate’ in the sign-in and use Agilicus AnyX as the OpenID Connect Provider. Once this simple configuration is completed the user will sign-in once, using their native corporate account, without local configuration on VTScada.
First, we configure the Application in Agilicus AnyX. The only change from a typical application is to use the ‘My Application Participates in Authentication’. Otherwise configure as usual for VTScada.
Now that we have configured the Application, we can observe that a OpenID Connect ‘Client’ has been created (Resources/Applications/Authentication Clients). The name of it we will use in the VTScada configuration below. We will also configure a ‘remapping’ to cause the Agilicus User ‘External ID’ field to become available (see “VTScada – OpenID Connect Authentication“) for mapping to a different username if desired.
Add the ‘redirect uri’. The format will be “https://<vtscada-name.__MYDOMAIN__/vtscada/oidc/return”, matching vtscada-name and __MYDOMAIN__ to your environment.
At this stage we are complete in the Agilicus Admin and will switch to the VTScada configuration.
In the “OpenID Connect Provider” box, we will use the ‘discovery’ feature. The URL will be https://auth.__MYDOMAIN__/.well-known/openid-configuration. If you chose to use the remap feature above, enter that in the Account Name Field.
Enter the Client ID from above in the Client ID field of VTScada, as well as the Secret.
At this stage, test the login, it should function.
The key fields to use:
Enable OpenID Connect
OpenID Connect Discovery URL (https://auth.__MYDOMAIN__/.well-known/openid-configuration). Press the ‘Discover’ button, it will fill in the fields below
Permit remote sign-in using VTScada account credentials
Client ID (match to the field from Agilicus Authentication Client)
Shared Secret (match to the field from the Agilicus Authentication Client)
Account Name Field (match to the remapping above)
scopes (openid email groups profile offline_access)
NOTE: VTScada will require an outbound firewall connection to auth.__MYDOMAIN__. The user authenticates in their browser and passes a token to VTScada, which will in turn use that to lookup the user information remotely.
Mapping Multiple External Users To A Single VTScada User, With Multi-Factor
In some environments its desirable to have a single VTScada user (e.g. Operator) shared by multiple external users (e.g. joe@mycompany, jane@mycompany). Normally this would not be safe, but, with Agilicus AnyX the authentication is not shared and can include individual user multi-factor authentication.
Using the remapping above, use the ‘external-id’ field on a per-user in the Agilicus web admin, assign the VTScada user name per person.
For example, if you use these settings in the Agilicus admin users:
Agilicus (External) Username
External-ID
jane@mycompany
operator
joe@mycompany
operator
jerry@mypartner
admin
And remap the External-ID as:
Then Jane and Joe can sign in using their @mycompany single-sign-on (e.g. via O365, Google Workplace), be challenged for a second factor, but then end up signed into VTScada as ‘operator’.
Microsoft Group Policy update through time-limited Zero Trust remote access
Enable remote Active Directory policy management using the connector and Windows remote access to keep remote machines up to date.
Background
This procedure is designed to setup an occasional synchronization mechanism between a remote computer and the network Active Directory to enable group policy updates without the use of an always-on VPN.
This configuration provides an additional layer of security for remote access as it is both time-limited and protected through the Agilicus AnyX platform as well as authentication through the active directory platform. This means the Administrator can audit and control access through both the Agilicus AnyX platform, or through the Windows Domain Active Directory remote access logs.
This implementation minimizes the surface area for attack and ensures that credentials are always secure.
Once the procedure is done remote computers will check automatically for group policy updates, with an option to manually cause an update by selecting the ‘gpupdate’ launcher on the user’s desktop.
Enable remote Active Directory policy management using the connector and Windows remote access to keep remote machines up to date.
This set up of the following components is required for the deployment:
– A connector
– A share for distributing the certificate Revocation List (CRL)
– A domain controller w/ certificate management
– An SSTP server (Microsoft Remote Access configuration is provided)
Procedure
Set up a Connector on a Windows Server platform that will act as the Certificate Authority (CA). We recommend deploying locally on the Active Directory where a Connector may already be deployed. However, an alternate Windows Server platform with a dedicated Connector is acceptable.
Create a File Share resource.
Assign it to the Certificate Authority deployed connector. Name it ‘crl-share‘, and enter the local directory of your crl location. By default on Windows Server.
This is located at the following path: ‘C:\Windows\System32\CertSrv\CertEnroll’
Create a Network resource to access the SSTP tunnel we will be creating further on.
Create a Launcher resource. It will be used to create the Policy Update tunnel.
Name the Launcher resource ‘gpupdate’,
Assign it a command path of ‘%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe’
Under command arguments enter C:\PROGRA~1\agilicus\scripts\agilicus-gpupdate-user.ps1 -domain domain.jamiechapmanbrn.com
Assign the both the share and the network that you created earlier to the Launcher resource under “Resource Members”
Install Microsoft VPN on the host server
Install Microsoft VPN on the host server (https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/install-configure-virtual-private-network-server)
Use the Select Server roles option to install ‘Remote Access’
Under Roll Services choose ‘DirectAccess and VPN (RAS)
After the installation has finished, open the ‘Routing and Remote Access’ tool
Right click the server, and select ‘Enable Routing and Remote Access’
In the setup wizard, choose ‘Remote access (dial-up or VPN)’
Choose an appropriate network interface
Select ‘No, use Routing and Remote Access to authenticate connection requests’
Configure the remote hosts to use either DHCP or a specified range of addresses
Right click the server and choose ‘properties’
Under Security, click Authentication Methods.
Ensure that ‘Microsoft encrypted authentication version 2 (MS-CHAP v2) is checked
Enable dial-in access for users that are expected to be able to use the service
We will be coming back to this page when we have configured a local certificate for it to use.
For more details on installing remote access https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/install-configure-virtual-private-network-server
Configure the Certificate Server
Configure the CRL location
Open the Certification Authority Application. From the Certification Authority Application, right click the domain server, and click ‘Properties’. Click the ‘Extensions’ tab (1), and select the ‘CRL Distribution Point (CDP)’ extension. (2) Click the ‘Add’ button (3), and enter the following: http://localhost:3333/<org-id>/crl-share/<CaName><CRLNameSuffix><DeltaCRLAllowed>.crl You can find your organisation’s ID, by browsing to the portal, logging in, then click any resource. You will see your organisation ID in the address bar in your browser.
Ensure that the following two boxes are checked: – ‘Include in CRLS. Clients use this to find Delta CRL locations.` (4) – ‘Include in the CDP extension of issued certificates’ (4)
When you are finished, it should look like this
Enable host configuration for RAS and IAS access
Open ‘Certificate Templates’
Choose RAS and IAS Server
Select the ‘Subject Name’ tab. Choose ‘Supply in the request’
Issue the certificate for ‘localhost’
Open the ‘Certificates’ snap in. Choose ‘Local Computer’
Under Certificates, right click ‘Personal’
Select ‘All tasks’, then select ‘Request New Certificate’
Click next, then next again. Choose ‘RAS and IAS Server’, drop down the ‘Details’ arrow, then click ‘Properties’
On this page, under ‘Subject name’ choose ‘Common name’. In the value box enter ‘localhost’. Click the Add button, then ‘Apply’. Click ‘OK’. Then lastly ‘Enroll’
Using the certificate you have created, go back to the Routing and Remote access properties, and choose the ‘localhost’ certificate
Client Setup
Users will need to be provisioned in the Agilicus AnyX platform, and granted access to the ‘gpupdate’ launcher via their Identity or Group membership.
Agilicus provides a helper script in order to configure the client machines to automatically update. This script installs some helper scripts, and configures an automatic task to periodically update.
In order to run this script you will need to enable signed scripts on the machine
You will need to get the launcher id and organization id. You can find these by inspecting the gpupdate shortcut on your desktop. In the ‘Target’ section you will see a command line script. In the line is –launcher-id <gpupdate-launcher-id> –org-id <your-org-id>.
Download the sample installer script from here. Run the script on the target computer as administrator. specify the launcher_id and org_id parameters using the information from the earlier step.
Exposing a Remote Desktop Gateway through a Launcher
This guide will walk you through configuring your machine to access desktops using a Remote Desktop gateway via an Agilicus Connector.
NOTE: This is an unusual setup, normally you use the Desktop feature of Agilicus directly without Microsoft RD Web.
Overview
This guide will walk you through configuring your machine to access desktops using a Remote Desktop gateway via an Agilicus Connector. This allows you to use Microsoft Remote Desktop Gateway on a hidden internal network without opening a firewall rule or port-forward or VPN.
This technique involves creating a network to represent Remote Desktop Services then creating a launcher which will open mstsc.exe such that it will proxy all requests to the Remote Desktop gateway through Agilicus. Only users with permission to the launcher will have access to the Remote Desktop gateway. The .rdp extension will be associated with the launcher so that opening the file after downloading it from the RD Web portal will invoke the launcher, allowing it to properly access the Remote Desktop gateway. Users can download the RDP files from the normal RD Web portal, protected by Agilicus, using an Application you configure.
Configuring the Launcher
Create a resource group called ts-gateways. Then create a network called ts-gateway-1. Add it to the ts-gateways resource group.
Note: if you have multiple gateways, repeat this process for each. Increment the -1 (e.g. ts-gateway-2, ts-gateway-3). This naming scheme is just an example; you can use your own to match your organisation’s naming scheme.
Next, create a launcher called ts-launch, pointing to C:\Windows\system32\mstsc.exe, containing the ts-gateways resource group. Give yourself and any others you want ‘owner’ permission to it.
Under “Advanced configuration”, select “My launcher has additional options” and then check “My launcher requires DNS (name service) interception” and “Hide the launcher command window”. Select “No” for “My application requires multiple processes”
Configuring the Client Desktop
Here we ensure the launcher is present on the desktop, and configure the desktop via the registry to point RDP files to the launcher.
If the launcher is not installed, do so now. Otherwise, run the Agilicus Refresh tool to install the new launcher shortcut. From that we’ll find two pieces of information needed to populate some registry entries. Navigate to the Agilicus\Launchers Start Menu entry and edit the properties of the shortcut. We’re interested in the “Target” field.
Note down the strings after –launcher id and –org-id. In my case:
Next, import the registry template by loading the following rdp-launcher-template.rdp file and answering yes. This will insert registry entries controlling the default assocation for rdp files. You will then modify the added entries to point to the launcher you configured earlier.
After importing the registry template, open regedit.exe. and navigate to Computer\HKEY_CURRENT_USER\Software\Classes\RDP.File
Proceed to edit the Default value in each of Connect\command, Edit\command and Open\command, replacing <your_launcher_id> with the launcher-id you noted earlier, and <your_org_id> with the org-id you noted earlier.
For example, consider the following Connect key:
Turns into:
With this in place, RDP files will by default invoke the launcher, which will in turn invoke mstsc.exe.
Configuring the RD Web Access
In order to grant access to the RD Web Access portal, you will create an application in Agilicus. Create an application called ts-gateway. Again, this name is just an example. You can call the application something meaningful to your organisation.
Under access, point it at your Remote Desktop Services gateway’s web portal from a connector with access to it. Select “Service is accessed via TLS and verify” for the TLS type.
Under Authentication, choose:
is authenticated by a proxy
for redirect after signin path, enter the aboslute path of landing page of the gateway. E.g./RDWeb/Pages/en-US/Default.aspx
Do not choose “My application is also launched from the desktop”
Now apply the application:
Navigate to the application’s definition. Under Security, scroll to “Firewall Rules”. Modify the / rule to be ^/RDWeb/
Then navigate to the Proxy Tab. Open up the HTTP Rewrites panel, and then the Rewrite Media Types panel. In there, add two media types:
application/json
application/x-rdp
Set the “Common Path Prefix” to /RDWeb/Pages/en-US/Default.aspx
Then, scroll down to the Rewrite Rules. Add the following mapping:
Internal Name: workspace id:s:
External Name: agilicus workspace id:s:
Next, create a group called “ts-gateway-users”, and add any users you would like to have access:
Under Application Permissions, assign the ‘self’ role to the ts-gateway-users group.
Using the RD Web Portal
You can now access the portal from the ts-gateway. URL. You can also launch this from profile. E.g. If you have multiple gateways, repeat this process for each, giving them a unique and descriptive name (so that your users can choose the correct one).
Prior to displaying the main page, you will be required to log in to Agilicus to gain access. Opening the downloaded RDP file will cause it to launch the Launcher you previously configured, which will then allow the user to access the otherwise inaccessible gateway.
The Hikvision DS-2CD3132-I is an embedded CCTV surveillance camera. It is entirely unsafe for it to have any Internet access, either inbound, or outbound. However, it is a solid device with good performance. In this example, we recommend putting the device on an isolated network segment, no inbound, no outbound connectivity. Straddling this segment place a machine running the Agilicus Connector, which makes an outbound connection to the Agilicus AnyX Cloud.
Configure the camera as an application as normal. However, the Hikvision has a limitation on the number of HTTP headers, breaking it with modern browsers. To solve this, we will use the Agilicus AnyX Web Application Firewall to remove unused headers. The specific headers I am removing include:
Dnt
Priority
Sec-Ch-Ua
Sec-Ch-Ua-Mobile
Sec-Ch-Ua-Platform
Sec-Fetch-Dest
Sec-Fetch-Mode
Sec-Fetch-Site
Sec-Fetch-User
Sec-Gpc
Upgrade-Insecure-Requests
X-Envoy-External-Address
X-Forwarded-For
X-Forwarded-Host
X-Forwarded-Proto
X-Request-Id
Removing these headers will have no impact on the camera: it does not use them. To remove the headers, follow the below screenshots.
With Microsoft Power BI desktop application, the desktop companion to the Power BI platform, one can visually explore data through a free-form drag-and-drop canvas, a broad range of modern data visualizations, and an easy-to-use report authoring experience. By combining Zero Trust Network Access to this Microsoft tool, it becomes possible to access remote databases and reports in a secure end-to-end, TLS encrypted, Identity verified session without the need for a corporate VPN.
The Agilicus Launcher
To enhance the Power BI desktop client, we will configure a Launcher in the Agilicus management console for administrators. To learn more about the concept of Agilicus Launchers, our Product Guide offers an introduction to this secure approach at remote application deployment.
In order to properly define the end to end secure properties inside which Power BI will be enabled, we must first define the Network Resource(s) the application will be allowed to use inside our network where the Agilicus Connector is deployed. By using the principle of least privilege (PoLP), we will only expose the database resource required by the application, and we will choose whether to do so by the database IP address, or optionally, by creating an internal hostname that is only resolvable through the Agilicus AnyX platform.
For the purposes of this example, we are using Power BI Desktop (x64) v2.129.905.0 (Published 05/21/2024)
Configuring the Network Resource
In the Resources – Networks , we will define the necessary SQL Server for PowerBI to access via a Connector.
Option 1. By IP address
Here we are creating a Network Resource ‘sql-server-backend’ where we will define the IP address (172.16.20.2) of the SQL Server at TCP port 5433 to be reached by the connector ‘Nanopi-r5s’. This IP address must be reachable by the Connector inside the network where it is deployed.
Option 2. By dedicated hostname
In this case, we are creating a fictitious hostname to resolve ‘server.sql’ entirely within the Agilicus AnyX platform. This hostname does not need to be resolvable on the public DNS infrastructure, conform to a real TLD requirement, or even be resolvable inside your corporate network. The Agilicus Launcher functionality will allow the local desktop application to resolve this hostname uniquely and route the TCP connection data to the ‘Override IP’ field IP address, which is still defined as ‘172.16.20.2’. Using a hostname based resource definition has the added benefit of not sharing the Internal IP addressing scheme of your secure network, allows for routing to the same IP address (IP space overlap) at different sites (via unique Connector), and does not reveal the IP address of the internal resources to the user.
Creating the Power BI launcher
Next, inside the Resources – Launchers menu, we will define the installation and runtime parameters of Power BI. We will assign a unique name that will be deployed on the local user Desktop icon under the Agilicus start menu folder. Using the default installation parameters for PowerBI, the following launcher configuration is made:
Name: Here we choose ‘PowerBI’
Command Path: This is the direct path to and including the executable.
C:\Program Files\Microsoft Power BI Desktop\bin\PBIDesktop.exe
Resource members: This will be the Network Resource(s), or Resource Group we wish to make available to the application. Here we assigned the ‘sql-server-backend’ network created in the previous step.
Start Directory: We can obtain the working directory from the native application properties.
C:\Program Files\Microsoft Power BI Desktop\bin\
Requires Interceptor: We will enable the DNS based and IP interception to allow Power BI to transparently access the network resources.
Hide Console: We can choose to hide the Agilicus Launcher console if no troubleshooting or debugging needs to be visualized.
Run with Elevated Privileges: The Power BI desktop application communicates with multiple Microsoft desktop components in order to operate and access network resources. We will permit the Agilicus Launcher to inspect process threads and other desktop elements executing network calls on behalf of Power BI. In order to do so, we must grant the Agilicus Launcher elevated privileges at runtime.
Using the Power BI Launcher
After deploying the Power BI application on the desktop and enabling the Agilicus Desktop Integration, the desktop user will have access to the set of Launchers under the Agilicus start menu.
Note that the name of the Launcher is the one we defined in the previous step ‘PowerBI’ and can be distinct from the default local Power BI desktop icon ‘Power BI Desktop’.
Once launched we can test the SQL Server database connectivity by doing a direct query to it:
The SQL server information will be the same as the Network Resource configured in the previous step.
For example, if the network resource was defined as an IP address, then the SQL server field should bear that IP address: 172.16.20.2 and the TCP port. If the resource was defined as a Hostname, as illustrated, the hostname created in the network resource can be used with the TCP port eg: server.sql:5433 . Note that if the IP address is known by the user, it is also possible to use it weven if the resource is defined as a hostname.
The acSELerator QUICKSET Software by Schweitzer Engineering Laboratories (SEL) is a tool for engineers and technicians to quickly and easily configure, commission, and manage devices for power system protection, control, metering, and monitoring.
Under normal operation, the software supports network communication via Telnet and SSH.
By creating a launcher configuration in the Agilicus Any X platform, it becomes a secure, and capable client able to perform remote operations across a private and resilient TLS connection with Zero Trust. This will maintain an ideal Security Posture even with its default Telnet (TCP Port 23) communication configuration setting, while not exposing any other network resources on the local network.
In order to do so we will first configure the list of endpoints we wish to manage and add them as individual network resources where we will explicitely list the individual IP addresses and the TCP port 23, we wish to make accessible by the local connector. While we will use the default TCP port 23 for Telnet operation, the Quickset communications settings allow for any TCP port to be used, and this should be mirrored in the Agilicus network resources definition to match the host and the TCP port.
At its most basic, let’s assume we have an available device at IP address 192.168.10.220 , to which we wish to connect with the Telnet protocol over TCP port 23. The Quickset communication configuration dialog will look something like this:
Getting Quickset configuration
Creating a Network Resource
We can then access the Agilicux AnyX Administration interface to create a Network Resource bearing the same network details, and ensure traffic to the destination device is achieved via the appropriate Connector located at the remote facility.
Here we have created a target device named ‘quickset-gw1’ located a the IP address and TCP port we wish to reach, via the site Connector ‘Nanopi-r5s’. No other advanced options are required.
Optionally, if we wish to have multiple resources that mirror the entire set of device list, we can create individual Network Resources and then associated them into a Resource Group to be treated as a single group of resources.
Configuration of the Launcher
Here we will configure a launcher for the Quickset executable and define which Network Resource it can access on the Agilicus AnyX platform.
The launcher configuration requires a few advanced settings, but first, let’s look at one such launcher entry:
Let’s look at the individual elements of the launcher configuration and then we can review the advanced settings.
Name: Here we have the name of the Launcher as configured. This should be unique and will be the label of the Icon when installed in the Agilicus folder on the workstation. We choose the logical name “Quickset”
Command Path: This is the full path to, and including, the executable. The default installation path is used here:
Command Arguments: If we wish to specify any command arguments, we can fill them here. By default the program launches without them.
Resource Members: Here we MUST associate a network resource that the launcher is allowed to reach. This will be the Network Resource of our end device, or the Resource Group which contains an extensive lists of resources.
Diagnostic Mode: The launcher can output valuable troubleshooting information to a local log file. Enable this to create a verbose diagnostic log file.
Start Directory: This is the working path of the program. You can get this path via the Properties of the local executable on the workstation where the software is installed. Here it is:
Requires Interceptor: Also known as “DNS (Name Service) Interception” in the creation wizard. It enables network data interception in the launcher to capture the traffic directly from the application. We will enable this.
Hide Console: By default, the Launcher runs a muted console side by side with the application. We can hide it by enabling this feature.
Advanced Options
Once the launcher is configured, we need to create a set of advanced options by first clicking on “Add Process”
Explanation:
The SEL Quickset executable does not handle network connectivity by itself. It in fact uses another small executable: SELCommunications.exe
When run by itself SEL Communications allow basic connectivity to the end device and has a minimalistic UI:
When QuickSet requires network communication to a device, it launches SELCommunications.exe in the background with a command line argument “-Embedding” which minimizes the software, and removes its UI. The program is closed by Quickset when network communication is no longer required.
Because the Agilicus AnyX platform employs Zero Trust, any additional process that should be granted access to the remote network resource must be explicitely defined. This maintains the principle of least privilege (PoLP) of our Zero Trust platform.
After clicking “Add Process” we can start adding the details of the extra processes which should be granted access to the AnyX platform while the launcher is running.
Program Name: here we specify the SELCommunications executable path. The default installation path is used here.
Command Arguments: We must use the same command arguments used by the QuickSet to invoke the process.
-Embedding
Name is Regex: The program name here is not a Regular Expression string pattern, so we do not use this feature.
Start if not running: We want the launcher to start the SELCommunications.exe process at startup so that Quickset can use it
Exit when ending: Once we exit Quickset, we want the launcher to terminate the SELCommunications.exe process it started ,
Attach if already running: It’s possible that an existing copy of SELCommunications.exe is already running since it can be started on its own. This feature will allow the launcher to quickly find if this process is running and transparently allow it to start communicating through the AnyX platform
Fork Then Attach: We do not require to fork this process.
Wait for exit: We will not force the launcher to wait until the process has completely exited before quitting.
Assigning Resource Permission
Once the Launcher and its network resources are created, we must still assign permissions to individual identities or groups in order to allow them to run the client software.
This is achieved through the Access menu, and Resource Permissions
As we can see in this example, it is not necessary to grant Network Resource permission directly to the Identity as it is inherited via the Launcher configuration “Resource Members”
Once the permission is assigned, the Launcher will become available in the user Profile page, and via the Agilicus folder in the Start Menu
LibreNMS is “a fully featured network monitoring system“. In order to make it externally accessible, we will treat it as a Web Application.
Application Setup
The LibreNMS application is setup using defaults with 1 exception: we must HTTP Rewrite the Media Type text/html.
In this sample, we show setting it up so that all users in the organisation have equivalent access.
First, create a new web application. Select a ‘name’ (which will become part of the URL, e.g. https://NAME.DOMAIN), a description and a category. The latter two are for information purposes only.
Now we can select a hostname. By default it will be NAME.DOMAIN, but, if you have an alternate hostname setup as a CNAME, you may use it here.
You may use an onsite connector you have previously setup, or a VPN you have previously setup.
This choice controls the fidelity of the access & audit logs, as well as the depth of the WAF. The first choice gives full audit records on each access transation, and protects against SQL injection, CSRF and XSS attacks. The second option keeps the custodial control of the TLS private key entirely within your site and private. Both will work for this example.
Now we select the coordinates of the LibreNMS server *as it is on your current site*. This might be a hostname or IP, it is how you currently use LibreNMS.
We now select authenticate by the reverse proxy.
Here we can control the initial default access. You can change this later in the ‘Access’ tab.
We are now complete on the initial setup, and then have 1 more non-default step to perform, to do the Media rewrite.
Now that this is done, we have one last step. The LibreNMS web application writes the local IP:PORT into the HTML and we must rewrite it. To do so, on the ‘define’ screen, select ‘librenms’ from the top, and, under the HTTP Rewrites section, add ‘text/html’ to the media to be re-written. At this stage, we should be able to login and use normally.
In addition, you should set ‘application/json’ to the rewrite, in order to be corrected on return to API-driven components.
You may consider setting the ‘Include user context headers’ which will cause the authenticated user information to be available as a trusted header.
Node Red is a web-based events management system. For the sake of this sample, we are going to run Node Red in a container as below:
docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red
We will use Agilicus AnyX to create an identity-aware proxy in front of it, making it available to a defined group of users anywhere without a VPN.
First, we need an Agilicus Connector which has onwards connectivity to the container we created. In this example, I am running the connector on the same machine. If you run it on a different machine you may need to adjust the docker command to allow connectivity from off-box.
Next, we will create the web application:
At this stage we are done, we can now try the node-red application. We can launch it from Agilicus Profile (https://profile.mydomain/) or directly using the url that was shown in step 2
Here we show launching from Profile (we can later set the icon)
In this sample we will show how to create a DNS CNAME in Google Domains.
Open Google Domains. Select the domain you already own that you wish to modify.
Now, add a new record:
Make the record be Type CNAME, make the name be *.agilicus (or whatever sub-domain of yours you wish, e.g. *.connect, *.cloud, *.zero-trust, etc). The data column should point to ca-1.agilicus.ca
In this demonstration we will use the Agilicus Connector to securely, simply expose a Grafana service running inside a Kubernetes cluster.
This will work for clusters that have no Ingress, no LoadBalancer, no public IP. It will allow you to add any user, from any identity provider, with a simple single-sign-on. If you push alerts via a Chat channel, you can just click on the link to get to the graph, no VPN.
First, install the Agilicus Connector in your Kubernetes cluster.
Second, create the Grafana Application in the Admin web interface.
The application name will become the hostname (e.g. here we will have https://grafana.MYDOMAIN)
You may use a pattern-based name (APPNAME.MYDOMAIN), or, a specific hostname (e.g. my-grafana).
Here we will use the Kubernetes Connector we created earlier.
For this demonstration we use TLS from user to the connector in your Kubernetes cluster. If there is a desire for fine-grained audit, use the other option.
The hostname will be with respect to CoreDNS in your cluster. In this case, we have installed grafana in the ‘grafana’ namespace, so it is http://grafana.grafana:3000
We select ‘authenticated by proxy’. In this case, no traffic will hit Grafana except for authenticated, authorised users.
You may choose to allow everyone access, or create specific groups.
We are now complete. Hit APPLY, and wait 2-3 minutes, then enter https://grafana.MYDOMAIN in your browser.
Auto-Sign-In, Auto-User-Create (Optional)
The authenticating proxy sets various headers in a trusted fashion. These include:
In this demonstration we will use the Agilicus Connector to securely expose an internal web server, using a clientless zero-trust secure connector.
Install Sample Web Server
Download the sample web server (the source code and compiling instructions are on github). Unzip the package and run the appropriate one for your platform, open a browser to http://localhost:8080/. This does not modify any files on your computer: it is a single executable with a few HTML files inside it.
OK, now we have a sample web server running locally. The web browser should show something like below.
Setup Agilicus Connector
Refer to the Agilicus Connector configuration instructions for more details.
Setup Sample Application
Refer to the Applications configuration instructions for more details.
Create a new Application. Select a template (static website). You can walk through the remainder of the options, but they will be filled in correctly already (except for the Connector to use).
For the demonstration we will use the existing domain name choice. However, you may wish to create a CNAME and have this application available as e.g. ‘wiki.example.com‘.
Now we will select how the application upstream connection works. We will access the simple static web site from onsite (emulating e.g. your corporate wiki or vacation planner)
Now we will select the internal coordinates. The sample static web site runs on our localhost, and on port 8080. You might have instead used an internal hostname here (e.g. wiki.example.com) and a port like 80.
Now we will choose how users are authenticated. In some cases you may just want a completely unauthenticated site. In some cases your application has native support for OpenID Connect (in which case see Authentication Clients).
Here we will choose “Is authenticated by a proxy”. This means the Agilicus Platform will automatically handle authentication and authorisation. Your application will receive pre-defined headers with the username and user roles. No unauthenticated user traffic will arrive at your application.
We may also choose a Logout URL, in case your web site has a spot users can end their session explicitly. This is optional.
We will also choose how the users are Authenticated. This controls how groups will be pre-setup for you, and how users are assigned. If we select “Is used by all users in my organisation”, this means that any user will have a default role, automatically: no need to grant permission.
If we say “has named users with a single role”, we will have to select the users manually, and all will have the same web application firewall permission (e.g. allow/deny).
We are now complete. We are given an overview of what we have setup, and an option to download a JSON file we might later use as a template. This is optional. When we hit Apply, a set of steps are performed:
Create new Web Application Firewall
Create DNS name
Create TLS certificate
Apply Web Application Firewall Rules
Create default group
Assign users to group
Create Authentication Client
Configure Identity Aware Web Application Firewall to use Authentication Client
These steps will take approximately 3-4 minutes.
You will be given a URL to navigate to with your browser. Its pattern will be https://static-website.MYDOMAIN. If all has gone well, when you navigate to that you will be required to sign-in, and then it will work the same as when you use http://localhost:8080.
Note: there is a default Content-Security-Policy in the Web Application Firewall, and a default set of Web Application Firewall rules for this application. Yours may vary and may require allowing e.g. different Javascript script-src or style-src.
Congratulations! You are now complete.
Things you may wish to observe:
the sample website outputs a line of text for each HTTP request. Note that an unauthenticated browser does not generate any traffic
the user audit screen will show your accesses: each session, each HTTP transaction. This is cryptographically secure, based on a JWT on each transaction: no IP/port matching.
See the companion code in Github. This can be run with docker-compose up to demonstrate.
In this example, we have an HTML web dashboard (running on localhost:5000), and an API (running pn localhost:5001). We use the Web Application Firewall rewrite to remap the API to a prefix (so it will become conceptually localhost:5000/api). This allows it to be represented as a single-sign-on session, on a single external URL.
In this example, we first create an application. On the 3rd step, “My Application Is An API”… if your API correctly uses CORS, you can leave this as-is. Else consider setting it, or example the ‘Define’ step later for more configuration.
When you get to step 7 (Configure Upstream Services), enter 1 for each endpoint. The main (HTML) one is ‘application’, the others are path_prefix. Substitute the real hostname if you need (you may need additional remapping later if your application is hard-coded).
Once you have completed the New Application Stepper, navigate to the ‘Define’ screen to refine the setup. On the ‘Proxy’ Tab, enable ‘Rewrite Common Media Types’.
Add permission to your user, and the page should work at https://<name><domain>/
Highly secure networks control the outbound (egress) traffic. Modern software can be signed requiring looking up certificate revocation. Agilicus can bridge this gap.
It is common in high-security networks to restrict Internet access to solely those services required. Imagine you have an industrial control system, it publishes statistics to a single public cloud service. You want to configure your firewall to block everything that is not that API endpoint. However, doing so breaks the TLS encryption since it needs to periodically check revocation.
There are two primary methods of checking certificate revocation: Online Certificate Status Protocol (OCSP) and Certificate Revocation List (CRL). Both of these are encoded in your certificate chain.
Let’s examine the Agilicus api (api.agilicus.com):
OCSP: http://r3.o.lencr.org. This is the ‘Leaf’ certificate, the last one in the chain. Let’s Encrypt has more information here. Now, let’s take a look at the DNS resolution:
$ dig +noall +answer @8.8.8.8 r3.o.lencr.org
r3.o.lencr.org. 120 IN CNAME o.lencr.edgesuite.net.
o.lencr.edgesuite.net. 857 IN CNAME a1887.dscq.akamai.net.
a1887.dscq.akamai.net. 20 IN A 72.136.197.57
a1887.dscq.akamai.net. 20 IN A 72.136.197.65
And this is where the problem arises. There is a CDN, the IP list is large and constantly changing. We cannot allow outbound connections by IP to achieve our objective.
To work around this, Agilicus implements a transparent proxy with a fixed IP, the same IP our API uses:
$ dig +noall +answer @8.8.8.8 api.agilicus.com
api.agilicus.com. 3600 IN A 35.203.36.11
Here we are simulating a Let’s Encrypt OCSP lookup of a specific certificate to r3.0.lencr.org. We are overriding the IP address of the DNS resolution to 35.203.36.11. Thus if we allow this IP in the firewall, the Agilicus API, and Let’s Encrypt OCSP will both function.
Depending on your host architecture you might also have intermediate Certificate Revocation or Windows CTDL updates. These function in a similar fashion, overriding crl.verisign.com and ctldl.windowsupdate.com.
Additional IP for Agilicus Specifically
In addition to the OCSP and CRL which are part of the SSL ecosystem, Agilicus requires 2 outbound IP connectivity points:
API. To find the IP address, run ‘nslookup api.agilicus.com’ (35.203.36.11)
Auth. To find the IP address, run ‘nslookup auth.YOURDOMAIN’ (this will be the same IP address for https://admin.YOURDOMAIN as you sign-in to the Administrative API). 34.95.12.47. This will be the same IP you have set your CNAME wildcard to.
Implementation
The implementation is simple:
Add alias in either /etc/hosts or your local DNS for r3.0.lencr.org, crl.verisign.com, ctldl.windowsupdate.com pointing to api.agilicus.com
Allow api.agilicus.com IP in your firewall on port 443 (for all API access) and port 80 (for OCSP and CRL access)
Allow the IP of your Agilicus Authentication service (auth.YOURDOMAIN) port 443
At this stage your air-gapped system will be able to function in the limited way you intend, but securely with proper TLS encryption.
This is a technical walk through of how to set up Agilicus AnyX with Twlilio® and VTScada for remote use without a VPN or DMZ. See the Infosheet for a high level view.
The use of custom address lists for server connections in the Thin Client/Server Setup dialog simplifies the configuration steps and no longer requires custom SSL certificate installations.
In this guide we are going to be making some changes to the VTScada setup. Notably:
We will configure the Agilicus inbound server name in the VTScada address connection dialog
We will create a Twilio endpoint on VTScada
We will create an application in Agilicus AnyX
We will select and enable a firewall rule in the Agilicus AnyX for the Twilio endpoint
This is a technical walk through of how to set up Agilicus AnyX with Twlilio® and VTScada for remote use without a VPN or DMZ. See the Infosheet for a high level view.
The following requirements need to be satisfied in the VTScada configuration to enable Twilio:
VTScada must be version v12.1.30 or newer,
not be the free version, and must support alarms
The VTScada “Connection Addresses” dialog tab of thin client manager must be configured with a host entry that matches exactly the Agilicus configured application hostname in the Server List. In this walkthrough, we will be using the hostname “waterdemo.cloud.egov.city”
Additionally, to complete this exercise, you will need access to a Twilio account, complete verification of the telephone number you wish to add to the roster, and register a telephone number in your Twilio account.
In this guide, we will set up a VTScada environment to be authenticated by proxy. This means a server will be available by a hostname, but no traffic will be allowed to the VTScada environment until the authorization rules have been met.
This may include identity and multi-factor credential verification. The Agilicus AnyX will manage a valid third-party signed TLS certificate via our partner Let’s Encrypt, configure to ensure the best practices for TLS are followed, and ensure all network traffic is audited and subject to the additional access control measures enabled through Agilicus AnyX.
Agilicus AnyX Application Configuration
Use the ‘New Application’ stepper to create a new application.
In this example, the endpoint we are creating will be called ‘waterdemo’ in the Organization using the cloud.egov.city subdomain.
Choose “My application is accessed: from my site via an onsite connector”
Configure the upstream service to match the server realm being used by VTScada. Here we can use the “Default” Realm server configured on HTTP Port 80 .
For the upstream local hostname/ip address, we can enter the IP address as used by the Realm server seen above (ie: 192.168.10.15 ). If selecting the internal hostname, enter the value of `hostname` lowercase (e.g. open a ‘cmd’ shell on the VTScada machine and run that to get the exact computer name), ensure the host running the Agilicus connector can both resolve the hostname locally, and has reachability to the TCP port as well
For authentication, select is authenticated by a proxy, has named users with a single role.
Navigate to Applications/Overview, and select the “Configure Application” action for the newly created application. This will move you to the application’s details.
Choose the Security tab to configure the firewall to configure the Twilio firewall rules.
Open the ‘Configure Application’ for the newly created VTScada application.
Choose the ‘Security’ tab to configure the firewall.
Create a new Firewall Rule allowing POST and GET methods for anyone matching the prescribed path.
The path can be described as containing the Realm name, Realm GUUID and Telecom specific syntax.
The <realm> will be a GUUID and can be seen in the URL when loading up the Anywhere Client, e.g. 48708544-07e3-4d1b-9b6e-ea8ace4b00fe.
The GUUID follows a standard string pattern.
We can then selectone of three Firewall rule option that employ ever stricter limitations to access the VTScada server path for the Twilio endpoint.
The first rule, can use a Regular Expression to match the Twilio path with a GUUID pattern across all Realms:
If we wish to limit to the particular realm (eg: Default) , we can anchor (^) the firewall rule and match the Realm specific URL path precisely. This rule would be:
Finally, if we wish to filter specifically for both the Realm and GUUID path, we can anchor the path match (^) to the beginning of the URL and also the specific GUUID value.
In the “Thin client/Server setup” menudialog, select “Connection Addresses” and configure the Agilicus external server name exactly as previously configured in the Agilicus Application stepper (in this case, the waterdemo FQDN). Make sure to check the “Secure” checkbox and specify port 443.
Configure the user credentials, domain and realm in the Alarm properties. The realm matches the configured realm and domain must be https://<agilicusexternalname>
Testing the Alarm Call-Out
To test alarm call-out, use Idea-studio to create new page with “Roster Alarm Test” widget
The widget is located under Tag Types\Communications\Alarm Notification\Roster
Assign the tag “Default Call-Out Off
You can now use the newly created page to configure the roster and trigger an alarm.
Checking the checkbox will trigger an alarm.
Right clicking the checkbox will allow you to edit the call-out roster.
Create a contact row. Link the contact to the user with alternate contact details.
If you have successfully configured Twilio and Agilicus, you will receive a phone call-out repetitively until the alarm is acknowledged after the roster callout checkbox has been toggled. You can see the call-out status in the alarms page.
Troubleshooting
VTScada Twilio logs will also be present in your VTScada installation path under:
New log files are only written when the max # of lines (configurable) is reached or the application is stopped. So it’s possible the log files for the current troubleshooting session are not present until the application is stopped.
Here we can verify the callback URLs are being passed correctly to Twilio, in log lines such as:
In this example, we will show setting up an “Icecast” audio streaming system, and force users to be authenticated via OpenID Connect. We will also show Authorisation: a set of “viewers” who can stream the music, and an Administrator.
For this example we will use an onsite connector as a means of reaching the Icecast server. Go through the steps to install this now (or use one already installed).
First, let us open the “New Application” menu. We will do this manually (without a template) to demonstrate.
Give the application a name. This must be a valid hostname (it will be part of the URL a user will use, e.g. https://<NAME>.<DOMAIN>. You may describe the application and give it a category, these are just used for reporting purposes.
You have a choice: you can supply your own domain name (in which case you must put a CNAME in your DNS pointing to our domain ca-1.agilicus.ca), or you may use a name from the CNAME you set up when you created the organisation initially.
Now we indicate how the upstream Icecast application is accessed. We will do this via the onsite connector.
Select the specific connector (which we previously created and installed).
You now have 2 choices. You may have a full web application firewall with fine-grained (e.g. per transaction) audit logs, or you may have a perfect TLS session end to end transparent (in which case the private key will be solely on your site: we will have no access). For this demonstration, we will use the Enhanced Web Application Firewall.
We now enter the coordinates (in the private network, e.g. as would be reachable by that onsite connector) for the Icecast server.
We wish to have the OpenID Connect Proxy handle authentication and authorisation. We can also enter a URL that, when fetched, will force a logout.
We are later going to have 2 types of users (viewers, admins). You might choose an “auto-create” user type for the viewer, allowing anonymous but attributable access.
At this stage we are done creating the application, we will now set up the identity aware web application firewall authorisation.
Create Authorisation Roles, Firewall Rules
On the “Define” screen we can fine tune. First add a “viewer” role, then an “admin” role which includes viewer. Make the default role “viewer”.
Now let us set up the firewall. We will allow ‘viewer’ to GET anything except /admin. We will allow administrators to do any (GET/PUT/POST/…) on /admin/ tree.
At this stage we can open up our Icecast server (https://APPLICATION.DOMAIN), we will be challenged to provide credentials, after that, single sign-on, we are streaming our sweet music.
In this demonstration we will show compiling and hosting a simple web application. No container is needed, we can entirely host it by just dropping a ‘zip’ file of the build into a browser. In addition, we will entirely handle the authentication for the application (no changes, single-sign-on). We will protect a manifest file of secrets to prevent access by unauthenticated users.
The specific application I will demonstrate is gitlab-monitor, a tool which monitors your Gitlab pipelines. It has an unfortunate security model: it requires you to place a config file on the server, accessible by the client, which has a Gitlab Personal Access Token. This is not safe. So, lets host it safely.
Building The Application
Every application has its own build strategy. Make, npm, nuget, etc. This one uses the npm (or yarn) ecosystem.
git clone https://github.com/timoschwarzer/gitlab-monitor
cd gitlab-monitor
npm i
npm audit fix
npm run build
tar -C dist -cvf /tmp/gitlab-monitor.tar .
OK, now we have built the application. We have a file, /tmp/gitlab-monitor.tar, which is the binary ready to run. Let’s get it on the web with a domain name, a certificate, etc.
An application is a type of template, we will later make instances of it (e.g. staging, production). The application configuration will ask for a name (this will become the hostname, e.g. https://<appname>.<yourdomain>. We will add an image (which will show up in https://profile.<yourdomain> for launching).
We select the Identity Aware WAF Proxy (v1) runtime.This will, by default, force authentication of the user.
Now we will upload the application bundle we compiled above. You can just drag and drop the tar file onto the button, or, press “upload bundle” and select it. You can pick a name (e.g. gitlab-monitor-v2) or use the default one of the file name.
OK now we must configure the firewall rules. There are 2 firewalls in series here, the first acts on fine-grained paths, and the second acts to force authentication before allowing access. We will rely on this feature to protect our config.json (which contains the secret). Thus we must allow access to all paths first, and then deny the config file except for known users.
OK, now we have the template defined, we will create an instance. Instances can be used for e.g. “staging vs production”. They typically run in child-organisations, which is out of scope here. We will use ‘latest’ as the tag (which controls the version of the runtime). We attach the bundle from above.
We will now mount our config file into the instance. First, configure instance:
Now we can upload our config file, specify the path as /app/config.json, and we are done.
An Application may be hosted in the Agilicus platform, or external. For this example we are going to show how to develop a new application, initially not hosted.
An Application may be hosted in the Agilicus platform, or external. For this example we are going to show how to develop a new application, initially not hosted. For steps we will need:
Authentication Client (OpenID Connect client id)
Application (to attach permissions to, externally hosted)
Create group, assign users to it
Application Setup
We can do the first two steps aove in a single step with the “New Application” configuration. First, under the Application menu, select ‘New’. Select ‘manually’.
Now we give the application a name. The name will eventually be part of the URL (as a hostname) so keep it a single word. We add a description (which end users will see in the catalog), and a category (which will be used for grouping in reports).
We now indicate how we will ultimately access this application. Since it is (currently) external, this does not matter, leave the top item checked. Later when we move it to be hosted this will become a URL.
Now we indicate how the user accesses the application. Since we are just developing it, and it is on our desktop, leave this as “over the public Internet” (e.g. the application is not hosted in or through the Agilicus platform for the data path).
We now indicate that our application will participate in the authentication. This means that it has a built-in library handling OpenID Connect.
We must now configure the redirect URI (which is part of the OpenID Connect specification). Here we will use http://localhost:3000/ since we are hosting this on our desktop. Later we will add the production redirect URI in the Authentication Client.
We must now indicate how users are granted access. If we say “is used by all users in my organisation”, this means that the “All users” group will be granted access.
If we say “has named users with a single role”, this means authorisation is Boolean (allow/deny), but for a named set of users. We will use this option for the sample.
If our application has distinct roles for the users (e.g. Admin, Editor, Viewer), we can use the “has named users with distinct roles”.
Now we are complete, we will hit apply.
We can inspect the Authentication Client created. Later when we change the redirect URI we can change it here.
At this time we will change the application allowed from ‘All’ to ‘Sample-React-App’, forcing it to only allow our new application.
Group Create, Permissions Assign
Create a new group. Assign yourself (and any other users)
Now, create a new row in the “Application Permissions”, add the new group, and assign ‘Self’ as a permission to the application column.
Sample Configuration. Interoperability between the Agilicus AnyX platform and Rockwell Automation’s Studio 5000 with RSLinx
Overview
In this guide we show setup and interoperability between the Agilicus AnyX platform and Rockwell Automation’s Studio 5000 with RSLinx. This allows a PLC engineer to remotely support multiple sites, multiple customers, using their existing tools and setup. No VPN, no changing of IP’s. Connect to multiple customers simultaneously.
Customers get increased security, simple single-sign-on authentication with multi-factor, and a full audit trail. Permissions can be assigned (and audits can be observd) on an individual PLC basis, rather than an entire VPN or subnet.
For the example setup we have:
Windows PC running Rockwell Studio 5000 (v29)
CompactLogix 1769-L16ER
Micro850 2080-LC50
Raspberry Pi (serving as the Industrial PC / IPC)
The setup is such that the PLC are on a separate non-routable segment. The Raspberry PI is dual-homed, serving the PLC subnet and the connection outbound.
There is a highly restrictive firewall between the Raspberry PI and the Internet: it only allows outbound connections, on port 443, to the Agilicus AnyX platform: no inbound, no arbitrary outbound.
The operator will see no change on their laptop.
They launch RSLinx Classic0 from their start menu as normal. If they have not authenticated recently, a browser will popup to force a sign-in against their corporate identity provider (e.g. Microsoft Azure or Google Workplace). The Rockwell Automation software suite, Studio 5000, will then function as normal for all PLC viewing and programming.
Example Setup
User Desktop: Launcher Install
There is a one-time thing the user must do on their desktop to enable the Agilicus Launcher. No administrative privilege is required, and the configuration and software will automatically stay up to date.
The user must open the Profile web page (https://profile.YOURDOMAIN). From here they will download a binary and run it, it will sign-them in via the browser. At this stage, a new start menu item (Refresh) is present. Complete instructions are here.
Once the Launcher is installed, a ‘Refresh’ icon will appear, as well as an icon RSLinx Classic. Launch the software from the icon as normal.
If not already done. Deploy the Agilicus Connector on your Raspberry Pi or other IPC
Create a ‘Network’ resource for each PLC in the Agilicus with optional hostname creation (optionally make a Resource Group per site containing all Network Resources )
Create a Launcher RSLinx Classic assigning the Network hosts resources, Associate resource members for the launcher.
At this stage, if your RSLinx has previously seen the PLC, it will be working, otherwise we can enter them manually as below.
With this complete, you can launch RSLinx and observe the first time you will see a browser open and be prompted to sign in. On subsequent launches it will have cached credentials.
First we do the networks (PLCs are each Network Resources):
Add network Name (the name you will refer to the PLC in the Agilicus front end).
This should be valid lowercase hostname in syntax
Hostname/IP.
Here the default behaviour would be to specify the IP address. If however this internal IP address is used and overlaps with multiple different sites, it is recommended to create an Adhoc hostname that has significance eg: compactlogix.
The host name does not need to exist in the public DNS system, it will be used exclusively within the Launcher environment
For PLCs having overlapping IP addresses across multiple sites, we can specify unique hostnames for each resource and select the unique Connector name to which they should be routing.
In this environment, RSLinx can open two PLC resources that are labelled plc-site1 and plc-site2 in the Network Resource panel.
Each PLC, using the same internal IP address, at different sites, can be reached individually via their hostnames which are routed via different connector to their specific local network segments.
In this case, site1 PLC hostname would be configured in RSLinx as “PLC1.siteA:EIP”, and similarly site2 PLC could be reached via the hostname “PLC1.siteB:EIP”
Port. 44818, standard for Allen-Bradley PLC
Override IP. The actual local IP address of the PLC that the hostname should map to
Via Connector: The connector through which we wish to route to reach the PLC
At this stage we will create the Launchers:
Create a launcher for RSLinx:
Name: RSLinx Command Path: C:\Program Files (x86)\Rockwell Software\RSLinx\RSLINX.EXE Requires Interceptor: set Require Elevated: set Custom, Delayed Init: set
Resource Members: The network resource name representing every PLC host network resource previously created and that we wish to reach with this specific launcher instance. This can be a list of individual Network Resources, or a Resource Group.
At this stage we should assign permissions. For a larger scale, we recommend a Group for the users (so the permissions are assigned once, and users are later added/deleted from the Group). For a larger number of sites we recommend a Resource Group (so e.g. 1 Resource Group per site, or per type of PLC, or per job function, something of this nature).
Assign permission to Launcher
At this stage, on the user desktop, you can run ‘Refresh’ or, install the Launcher for the first time, and RSLinx icon will appear in the Agilicus Launcher subfolder from the Windows Start menu
We can now launch RSLinx Classic from Agilicus Launchers -> RSLinx
In RSLINX, Communications -> Configure Drivers
Select Ethernet:
Enter the hostname AS DEFINED in the Network Resource “Hostname/IP”. (eg: PLC1.siteA), and add “:EIP” to specify the TCP port 44818 of EthernetIP should be used for this device.
Apply the change.
The Agilicus, Ethernet driver will now probe the configured hosts, and it will add the device.
The Communications -> Who Active screen will now present the newly configured driver:
You can now run RSLogix500 or Studio5000 and set the project path for this device:
Download the controller configuration to the project.
Schneider Electric’s Control Expert Software interoperates with the Agilicus Launcher to create a seamless remote, authenticated, secure PLC operation and configuration.
The only communication mode currently supported is TCPIP (not USB or Serial).
The below example was tested with EcoStructure Control Expert V15.0 on Windows 10.
The Control Expert software can be run inside a VM if desired.
Theory of Operation and Data Flow
A PLC is located at a remote location. The location has no inbound access, no VPN available. It may be behind a cellular or satellite modem, it may have a restrictive firewall.
An Agilicus Connector is installed at this location such that the connector can reach the PLC on TCP port 502 (Modbus). The Connector must also be able to reach out to the Agilicus AnyX infrastructure on port 443.
On the user’s desktop, the Agilicus Launcher is installed. When the user selects the ‘Control Expert’ icon from their desktop start menu, or, when they select the icon from the Agilicus Profile, the network activity of the Control Expert software is seamlessly intercepted and tunneled to the PLC.
Authentication (and multi-factor authentication) is performed via a browser which may appear if the user is not signed in.
Unlike a VPN-style connection:
no PLC’s (nor any other network resources) other than the granted one can be accessed
no need to change local IP addressing in case of overlap
multiple sites and PLC can be used simultaneously
No reverse-path network traffic is allowed
No inbound connectivity to the remote site is required
The PLC Modbus traffic is tunneled over HTTPS, over WebSocket, end-to-end encrypted from the User’s PC to the Agilicus Connector in the remote site.
Configuration and Setup
There are 4 basic steps:
Create a Network Resource for the PLC
Create a Launcher
Set user permissions
Install Launcher on Desktop
Create Network Resource (PLC)
We will create a ‘network resource’, this acts as the endpoint of the PLC. It has a name (example-plc in below) and the IP/port of the actual PLC (as reachable by the connector on site). Later in the Control Expert software we will refer to this IP (even though it is not locally reachable).
Create Launcher
Now we will create a Launcher resource. This models the executable on the user’s PC, taking the executable path and the network resources to encapsulate as arguments. If you have PLC’s on multiple sites with multiple connectors, associate them all here.
❗
NOTE: there is an interoperability issue with the Control Expert ‘RatSrv.exe’ and the instructions above. In some cases the Agilicus Interceptor does not see the RatSrv.exe startup. The workaround is simple: 1. Create a file ‘schneider-control.cmd” with the below contents taskkill /im RatSrv.exe start "" "C:\Program Files (x86)\Common Files\Schneider Electric Shared\RAT\RatSrv.exe" "C:\Program Files (x86)\Schneider Electric\Control Expert 15.0\ControlExpert.exe"
2. In step one above, instead of “C:\Program Files (x86)\Schneider Electric\Control Expert 15.0\ControlExpert.exe”, use the full patch to the ‘schneider-control.cmd’ you have created.
Assign Permissions
In the screen shots above in the ‘Create Launcher’, we assigned initial permissions. (Note: we recommend using groups to assign permissions since it simplifies configuration. For example, create a group called PLC-Admins, assign the users to it once, and then assign the PLC access permissions to the group. For more information, see “Using Groups for Assigning Role-Based Permissions“
Install Launcher
On the PC with Control Expert installed, we will install the Agilicus Launcher. Refer to “Agilicus Launcher: Browser Desktop Integration“. This is done (on the PC with Control Expert installed) from a browser opened to https://profile.YOURDOMAIN.
Once the launcher is installed on this machine, we will see a ‘demo-plc’ icon on the start menu (and also in the profile web interface if the browser extension is installed).
At this stage, the user can open Control Expert, either via the profile web interface, or the desktop start menu. It will automatically be able to connect to the IP address of the PLC used above in the Network Resource (even though that IP is not reachable from this machine).
Kafka is a messaging bus using TCP as its underpinnings. It may be desirable to run a Kafka broker inside a private cloud environment (e.g. an AWS VPC) and connect to that broker from a remote private network. Likewise it can be desirable to run a Kafka broker inside a remote private network and connect as a client from a remote private cloud such as AWS VPC. These instructions work equally for each case.
Kafka is a messaging bus using TCP as its underpinnings. It may be desirable to run a Kafka broker inside a private cloud environment (e.g. an AWS VPC) and connect to that broker from a remote private network. Likewise it can be desirable to run a Kafka broker inside a remote private network and connect as a client from a remote private cloud such as AWS VPC. These instructions work equally for each case.
For this example, we will use two hosts. Cube exists inside a private network with a restrictive firewall. Only HTTPS/443 is allowed, and only in the outbound direction. On this host runs a Kafka broker on port 9092.
Office runs inside a Virtual Private Cloud. It two has outbound-only access: no inbound, no public IP.
For the sake of this example, we will use docker-compose to bring up the Broker on Cube. We will then use kafkacat to send and receive traffic via the broker.
Assign permissions to Service Forwarder to office connector service-account
apt-get install kafkacat
run echo foo | kafkacat -P -b localhost:9092 -t test
At this stage you should observe the kafkacat on cube wake up and say foo. We are done.
You may now wish to try e.g. change the server-forwarder to listen on 127.0.10.1:9092, THen we can run echo foo | kafkacat -P -b 127.0.10.1:9092 -t test. We can then add an entry to /etc/hosts and call it ‘Cube’ and repeat with a hostname.
Connect to VTScada – Adding a Web Anywhere Client Application
The following guide outlines the steps for creating a VTScada Anywhere Client application in the Agilicus platform. These instructions are intended for VTScada deployments with version v12.1.30+ on Windows, Linux, and Android devices.
The following guide outlines the steps for creating a VTScada web application in the Agilicus platform. These instructions are intended for VTScada v12.1.30+ deployments on Windows, Linux, and Android devices.
If you require assistance for Safari and iOS device , contact us.
Step 1: Create the Application
From the left sidebar, expand Applications and select New:
Application name. The chosen name will also be required to configure the VTScada Server list later in the instructions.
a description of the application.
Click on Next to get to the “Hostname Aliases” section and accept the proposed Hostname, or specify a different one. (If different, will need to be applied to the VTScada Server address list)
Select the first option of “I access via NAME-OF-APP.subdomain.domain.name” and click on next.
First under “My application is accessed” select “from my site via an onsite connector”
Within “Set up web application firewall” select “My application expects to receive requests using its internal hostname”
Under “My application hosts all or most of its pages under a common path prefix”, enter your VTScada Realm name (eg: /Default) that is the default Path we will allow authenticated users to navigate. Other path exceptions will be created later in the Firewall ruleset.
From the “Select a connector” drop down, pick the connector that you had previously created.
Within the “Enter the hostname” field, type in the hostname of the server that is hosting your VTScada web portal. This should be the same as your VTScada thick client.
In this configuration, the VTScada Server Setup and “Default” Realm server / and URLs point to an IP address of 192.168.10.15, and a TCP port of 80, with no SSL (Secure).
Click on Next to be taken to the “Authentication section”:
Select “is authentication by a proxy” and type in “/logout” (without the double quotes) into the “Enter the logout url” field.
We will also use the Optional “Enter the redirect after signin path” URL to redirect to the VTScada Server Realm page once users perform Authentication. Therefore, fill the value of the field with the name of the Realm ( eg: /Default )
Select “has named users with a single role (I will assign users later)” and click on Next:
Select the APPLY button to finish off this section of the setup.
Step 2: Configure the Application
Click on “Overview” within the Applications section and select the Actions icon in the very far right hand side of the screen for the VTScada application that we just created:
After clicking on “Configure Application”, select the Proxy section
Within the Proxy section select the “Common Path Prefix” and input the Realm name. This will limit the Anywhere Client to the desired realm path unless allowed by the Firewall rules in the following steps. In this case, we use the path /Default which is our VTScada realm.
Click on “Rewrite Common Media Types” checkbox.
Next, select the “Security” section and scroll to the “Firewall Rules”
In the Firewall section, we will enter rules that will allow Authenticated Users with permissions to the “Self” role to access specific paths within the VTScada Anywhere Client. These specific path are explicit in order to match valid content within the VTScada Realm that may fall outside of the “Path Prefix” set in the previous step ( eg: /Default ). These paths contain various web objects such as Icons, CSS files, Images, Anywhere Client scripts, and specific paths to the Server realm GUUID.
If using Website uptime monitoring, we recommend making the standard website browser icon “favicon.ico” available without authentication so that Web monitoring software can easily test end to end website uptime and availability by fetching this object.
This rule matches the GUUID path pattern used in VTScada Anywhere Client. If you wish to be more precise and secure, you can change this rule to the actual GUUID seen in the browser URL path like this example, and make it “^/Default/48708544-07e3-4d1b-9b6e-ea8ace4b00fe”
2. This rule matches the Anywhere Client script path
3. This rule should bear the name of the Server realm. In this case “Default”. This should be made to match your Server realm. This should be created by default in the original application configuration, but we can change the syntax here to be more specific.
4. This rule matches the VTScada path for images and objects for both the Regular and Light version of the server
5. This rule matches the standard favicon.ico website icon
6. This rule matches the Style Sheets path
7. This rule matches a logout path that would be used to sign out of the VTScada application
We have now completed setting up your VTScada resource within the Agilicus platform. At this point you would want to create the appropriate Role Based Access Control permissions per the steps below:
Step 3: Add Permissions
Select Access -> Application Permissions
Grant Firewall Role (self) Permission of the application name (VTS) to the required Identity
Step 4: Configure VTScada
From the VTScada Application Manager, select the Server Setup dialog:
Select the “Connection Addresses” tab, select the “+” icon to create a connection address entry.
Enter the matching Agilicus Application name FQDN exactly as created in the “Connection Address” dialog, select port 443 and check “Secure“
Click “Apply” to submit the new address. This will allow VTScada Anywhere Client to present a list of valid hostnames where the Anywhere Client is allowed to connect. Since the FQDN is the one we configured through the Agilicus platform, the VTScada Anywhere Client will be permitted to browse via the newly created service.
The Raspberry PI supports multiple operating system distributions. The default used is often Raspbian, which has a VNC-similar server installed called Real VNC.
Real VNC is not enabled by default. It also uses a proprietary authentication scheme by default.
To enable VNC on your Raspberry Pi and access via Agilicus Any-X, you may use the option panel, changing the Authentication from “Unix password” to “VNC password”. Or, if you prefer, you may edit the text files as below.
Add Authentication=VncAuth to /root/.vnc/config.d/vncserver-x11
The Real VNC Server supports a super-set of the Encryption supported by Agilicus AnyX. You may need to set “Prefer On” to allow the two sides to negotiate.
At this stage you can follow the standard directions to create a VNC Desktop