How to configure network ACLs¶
Note
Network ACLs are available for the OVN NIC type, the OVN network and the Bridge network (with some exceptions, see Bridge limitations).
Network ACLs define traffic rules that allow controlling network access between different instances connected to the same network, and access to and from other networks.
Network ACLs can be assigned directly to the NIC of an instance or to a network. When assigned to a network, the ACL applies to all NICs connected to the network.
The instance NICs that have a particular ACL applied (either explicitly or implicitly through a network) make up a logical group, which can be referenced from other rules as a source or destination. See ACL groups for more information.
Create an ACL¶
Use the following command to create an ACL:
lxc network acl create <ACL_name> [configuration_options...]
This command creates an ACL without rules. As a next step, add rules to the ACL.
Valid network ACL names must adhere to the following rules:
Names must be between 1 and 63 characters long.
Names must be made up exclusively of letters, numbers and dashes from the ASCII table.
Names must not start with a digit or a dash.
Names must not end with a dash.
ACL properties¶
ACLs have the following properties:
Key: | config |
Type: | string set |
Required: | no |
The only supported keys are user.*
custom keys.
Add or remove rules¶
Each ACL contains two lists of rules:
Ingress rules apply to inbound traffic going towards the NIC.
Egress rules apply to outbound traffic leaving the NIC.
To add a rule to an ACL, use the following command, where <direction>
can be either ingress
or egress
:
lxc network acl rule add <ACL_name> <direction> [properties...]
This command adds a rule to the list for the specified direction.
You cannot edit a rule (except if you edit the full ACL), but you can delete rules with the following command:
lxc network acl rule remove <ACL_name> <direction> [properties...]
You must either specify all properties needed to uniquely identify a rule or add --force
to the command to delete all matching rules.
Rule ordering and priorities¶
Rules are provided as lists. However, the order of the rules in the list is not important and does not affect filtering.
LXD automatically orders the rules based on the action
property as follows:
drop
reject
allow
Automatic default action for any unmatched traffic (defaults to
reject
, see Configure default actions).
This means that when you apply multiple ACLs to a NIC, there is no need to specify a combined rule ordering. If one of the rules in the ACLs matches, the action for that rule is taken and no other rules are considered.
Rule properties¶
ACL rules have the following properties:
Key: | action |
Type: | string |
Required: | yes |
Possible values are allow
, reject
, and drop
.
Key: | destination |
Type: | string |
Required: | no |
Destinations can be specified as CIDR or IP ranges, destination subject name selectors (for egress rules), or be left empty for any.
Key: | destination_port |
Type: | string |
Required: | no |
This option is valid only if the protocol is udp
or tcp
.
Specify a comma-separated list of ports or port ranges (start-end inclusive), or leave the value empty for any.
Key: | icmp_code |
Type: | string |
Required: | no |
This option is valid only if the protocol is icmp4
or icmp6
.
Specify the ICMP code number, or leave the value empty for any.
Key: | icmp_type |
Type: | string |
Required: | no |
This option is valid only if the protocol is icmp4
or icmp6
.
Specify the ICMP type number, or leave the value empty for any.
Key: | protocol |
Type: | string |
Required: | no |
Possible values are icmp4
, icmp6
, tcp
, and udp
.
Leave the value empty to match any protocol.
Key: | source |
Type: | string |
Required: | no |
Sources can be specified as CIDR or IP ranges, source subject name selectors (for ingress rules), or be left empty for any.
Key: | source_port |
Type: | string |
Required: | no |
This option is valid only if the protocol is udp
or tcp
.
Specify a comma-separated list of ports or port ranges (start-end inclusive), or leave the value empty for any.
Use selectors in rules¶
Note
This feature is supported only for the OVN NIC type and the OVN network.
The source
field (for ingress rules) and the destination
field (for egress rules) support using selectors instead of CIDR or IP ranges.
With this method, you can use ACL groups or network selectors to define rules for groups of instances without needing to maintain IP lists or create additional subnets.
ACL groups¶
Instance NICs that are assigned a particular ACL (either explicitly or implicitly through a network) make up a logical port group.
Such ACL groups are called subject name selectors, and they can be referenced with the name of the ACL in other ACL groups.
For example, if you have an ACL with the name foo
, you can specify the group of instance NICs that are assigned this ACL as source with source=foo
.
Network selectors¶
You can use network subject selectors to define rules based on the network that the traffic is coming from or going to.
There are two special network subject selectors called @internal
and @external
.
They represent network local and external traffic, respectively.
For example:
source=@internal
If your network supports network peers, you can reference traffic to or from the peer connection by using a network subject selector in the format @<network_name>/<peer_name>
.
For example:
source=@ovn1/mypeer
When using a network subject selector, the network that has the ACL applied to it must have the specified peer connection. Otherwise, the ACL cannot be applied to it.
Log traffic¶
Generally, ACL rules are meant to control the network traffic between instances and networks. However, you can also use them to log specific network traffic, which can be useful for monitoring, or to test rules before actually enabling them.
To add a rule for logging, create it with the state=logged
property.
You can then display the log output for all logging rules in the ACL with the following command:
lxc network acl show-log <ACL_name>
Edit an ACL¶
Use the following command to edit an ACL:
lxc network acl edit <ACL_name>
This command opens the ACL in YAML format for editing. You can edit both the ACL configuration and the rules.
Assign an ACL¶
After configuring an ACL, you must assign it to a network or an instance NIC.
To do so, add it to the security.acls
list of the network or NIC configuration.
For networks, use the following command:
lxc network set <network_name> security.acls="<ACL_name>"
For instance NICs, use the following command:
lxc config device set <instance_name> <device_name> security.acls="<ACL_name>"
Configure default actions¶
When one or more ACLs are applied to a NIC (either explicitly or implicitly through a network), a default reject rule is added to the NIC. This rule rejects all traffic that doesn’t match any of the rules in the applied ACLs.
You can change this behavior with the network and NIC level security.acls.default.ingress.action
and security.acls.default.egress.action
settings.
The NIC level settings override the network level settings.
For example, to set the default action for inbound traffic to allow
for all instances connected to a network, use the following command:
lxc network set <network_name> security.acls.default.ingress.action=allow
To configure the same default action for an instance NIC, use the following command:
lxc config device set <instance_name> <device_name> security.acls.default.ingress.action=allow
Bridge limitations¶
When using network ACLs with a bridge network, be aware of the following limitations:
Unlike OVN ACLs, bridge ACLs are applied only on the boundary between the bridge and the LXD host. This means they can only be used to apply network policies for traffic going to or from external networks. They cannot be used for to create
intra-bridge firewalls, thus firewalls that control traffic between instances connected to the same bridge.ACL groups and network selectors are not supported.
When using the
iptables
firewall driver, you cannot use IP range subjects (for example,192.0.2.1-192.0.2.10
).Baseline network service rules are added before ACL rules (in their respective INPUT/OUTPUT chains), because we cannot differentiate between INPUT/OUTPUT and FORWARD traffic once we have jumped into the ACL chain. Because of this, ACL rules cannot be used to block baseline service rules.