Channel Access gateway setup
The Channel Access (CA) gateway is a program that acts as gateway, which enables client from a network to access IOCs on another network.
Setting up a CA gateway also enables you to add extra access security rules on top of IOCs.
For more details and documentation about the CA PV gateway, you can examine the gateway main page.
Pre-requisites
- Having a NixOS machine with a flake configuration.
If you’re not sure how to do this, you can follow the Archiver Appliance tutorial, which is a good introduction on how to make a NixOS VM.
If you have such a configuration, make sure that:
- You have the
epnix
flake input - You have added
epnix
as an argument to your flake outputs - You have imported EPNix’ NixOS module
For example:
flake.nix
{
# ...+ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05";
+ inputs.epnix.url = "github:epics-extensions/EPNix";
# ...
outputs = {
self,
nixpkgs,+ epnix,
}: {
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
modules = [+ epnix.nixosModules.nixos
# ...
];
};
}; }
Enabling the gateway
To enable the gateway, add this to your configuration:
{
services.ca-gateway = {
enable = true;
openFirewall = true;
};
}
This configuration starts the CA gateway in a ca-gateway.service
systemd service. In this configuration, the gateway listens on all interface with a broadcast IP address, and forwards all Channel Access request.
The openFirewall
option opens the 5064 TCP, 5064 UDP, and 5065 UDP ports on all network interfaces.
Firewall on specific interfaces
If you want to enable the firewall on specific interfaces, you can remove the openFirewall
option and configure the firewall manually.
You can also use the cip
setting to specify where the gateway should listen for the CA server part.
For example:
{config, ...}: {
services.ca-gateway = {
enable = true;
# Server side listen address
# Let's say this IP address is on enp0s2
settings.sip = ["10.0.2.1"];
# Let's also say the enp0s1 interface is
# where communication with "real" IOCs happen (client side)
# openFirewall is left as false by default
};
networking.firewall = let
gwSettings = config.services.ca-gateway.settings;
in {
interfaces = {
# Open the firewall on the interface from the client side of the gateway,
# this will be the side of the gateway listening
# for replies to beacons and PV search requests
"enp0s1".allowedUDPPorts = [5065];
# Open the firewall on the interface from the server side of the gateway,
# this will be the side of the gateway listening for Channel Access requests
"enp0s2" = {
# Use the value of the `sport` setting
allowedTCPPorts = [gwSettings.sport];
allowedUDPPorts = [gwSettings.sport];
};
};
# Allow incoming UDP packets with *source* port 5064,
# from the client side of the gateway.
# This is needed to listen to CA broadcast responses
extraCommands = ''
ip46tables -A nixos-fw -p udp --sport 5064 -j nixos-fw-accept -i enp0s1
'';
};
}
Filtering IOCs
By using the cip
setting, you can filter which IOCs get exposed by the gateway. This is equivalent to setting the environment variable EPICS_CA_ADDR_LIST
and setting EPICS_CA_AUTO_ADDR_LIST=NO
.
For example:
{
services.ca-gateway = {
enable = true;
# These IOCs get exposed by the gateway
settings.cip = [
"10.0.1.42"
"10.0.1.69"
# you can specify the port, too,
# if your IOC listens on something other than 5064
"10.0.1.237:5067"
# domain names also work
"myioc"
];
};
}
Filtering process variables
By using the pvlist
setting, you can filter which PVs get exposed by the gateway.
This option takes a file in the gateway pvlist
format. See the GATEWAY.pvlist
example on the ca-gateway repository. The list supports regular expressions (Perl style).
In the configuration
For example:
{pkgs, ...}: {
services.ca-gateway = {
enable = true;
# These PVs get exposed by the gateway
# This list implements an "allowlist":
# DENY by default, some PVs explicitely ALLOW
settings.pvlist = pkgs.writeText "gateway.pvlist" ''
EVALUATION ORDER DENY, ALLOW
.* DENY
MY_PV1 ALLOW
MY_PV2 ALLOW
# Or:
MY_PV[0-9]+ ALLOW
'';
};
}
In a separate file
For long lists, it can be better to put it in a separate file. You can do this by adding a gateway.pvlist
in the same directory as your configuration:
gateway.pvlist
EVALUATION ORDER DENY, ALLOW
* DENY
.
MY_PV1 ALLOW
MY_PV2 ALLOW
# Or:
0-9]+ ALLOW MY_PV[
And in your configuration:
{
services.ca-gateway = {
enable = true;
# Make sure that the value is *not* quoted
settings.pvlist = ./gateway.pvlist;
};
}