From ab1166e625e1ad1e872d4ed98b67654c4a2bb083 Mon Sep 17 00:00:00 2001 From: Minijackson Date: Wed, 11 Oct 2023 15:49:05 +0200 Subject: [PATCH] doc/guides/ca-gateway: init --- doc/_quarto.yml | 2 + doc/nixos/guides/ca-gateway.md | 234 +++++++++++++++++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 doc/nixos/guides/ca-gateway.md diff --git a/doc/_quarto.yml b/doc/_quarto.yml index fb69e66a..bc2324bd 100644 --- a/doc/_quarto.yml +++ b/doc/_quarto.yml @@ -73,6 +73,8 @@ website: contents: - ./nixos/tutorials/archiver-appliance.md - section: User Guides + contents: + - ./nixos/guides/ca-gateway.md - section: Explanations - section: References contents: diff --git a/doc/nixos/guides/ca-gateway.md b/doc/nixos/guides/ca-gateway.md new file mode 100644 index 00000000..39420b8b --- /dev/null +++ b/doc/nixos/guides/ca-gateway.md @@ -0,0 +1,234 @@ +--- +title: 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]. + + [gateway main page]: https://epics.anl.gov/extensions/gateway/ + +# 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: + +``` {.diff filename="flake.nix"} + { + # ... ++ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05"; + + # ... + outputs = { + self, + nixpkgs, ++ epnix, + }: { + nixosConfigurations.nixos = nixpkgs.lib.nixosSystem { + modules = [ ++ epnix.nixosModules.nixos + + # ... + ]; + }; + }; + } +``` + + [Archiver Appliance tutorial]: ../tutorials/archiver-appliance.md + +# Enabling the gateway + +To enable the gateway, +add this to your configuration: + +``` nix +{ + 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: + +``` nix +{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_LIST=NO`. + +For example: + +``` nix +{ + 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). + + [`GATEWAY.pvlist`]: https://github.com/epics-extensions/ca-gateway/blob/master/example/GATEWAY.pvlist + +## In the configuration + +For example: + +``` nix +{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: + +``` {.perl filename="gateway.pvlist"} +EVALUATION ORDER DENY, ALLOW + +.* DENY + +MY_PV1 ALLOW +MY_PV2 ALLOW + +# Or: + +MY_PV[0-9]+ ALLOW +``` + +And in your configuration: + +``` nix +{ + services.ca-gateway = { + enable = true; + # Make sure that the value is *not* quoted + settings.pvlist = ./gateway.pvlist; + }; +} +```