Skip to content

Commit

Permalink
doc/guides/ca-gateway: init
Browse files Browse the repository at this point in the history
  • Loading branch information
minijackson committed Oct 13, 2023
1 parent 63f6b98 commit 0ad1a6a
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 0 deletions.
2 changes: 2 additions & 0 deletions doc/_quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
234 changes: 234 additions & 0 deletions doc/nixos/guides/ca-gateway.md
Original file line number Diff line number Diff line change
@@ -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;
};
}
```

0 comments on commit 0ad1a6a

Please sign in to comment.