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 Creating an Archiver Appliance instance 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 inputYou have added
epnix
as an argument to your flake outputsYou have imported EPNix’ NixOS module
For example:
{
# ...
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
+ inputs.epnix.url = "github:epics-extensions/EPNix/nixos-24.05";
# ...
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:
EVALUATION ORDER DENY, ALLOW
.* DENY
MY_PV1 ALLOW
MY_PV2 ALLOW
# Or:
MY_PV[0-9]+ ALLOW
And in your configuration:
{
services.ca-gateway = {
enable = true;
# Make sure that the value is *not* quoted
settings.pvlist = ./gateway.pvlist;
};
}