One thing that keeps me from using VyOS in some environments is the lack of support for host names in firewall groups and rules and nat rules. It would be great if hostnames could be used for rules as not everyone has static IPs, but setting up dynamic DNS is easy. I can tell you this works great in pfSense, OpenSense, and Juniper SRX devices.
Description
Details
- Version
- -
- Is it a breaking change?
- Perfectly compatible
- Issue type
- Feature (new functionality)
Related Objects
- Mentioned In
- rVYOSONEX9ff1172aedc2: firewall: T970: always use full nft command name (e.g. --file over -f)
rVYOSONEXf1c51884fb62: firewall: T970: always use full nft command name (e.g. --file over -f)
rVYOSONEX051e063fdf2e: firewall: T970: Refactor domain resolver, add firewall source/destination…
rVYOSONEXb4b491d424fb: nat: T1877: T970: Add firewall groups to NAT
rVYOSONEX36e54927217d: Merge pull request #1633 from sarthurdev/fqdn
rVYOSONEX7e59b2a3f31e: firewall: T970: Use set prefix to domain groups
rVYOSONEX76684692f897: firewall: T970: Fix for Regex for domain and check empty group
rVYOSONEX007953d36388: Merge pull request #1354 from sever-sever/T970
rVYOSONEX7a46ac5ebe7a: smoketest: T970: Add commit after static-host-mapping
rVYOSONEX865f38d22a07: Merge pull request #1352 from sever-sever/T970-test
rVYOSONEXe990b2f4c045: firewall: T970: Add firewall group domain-group
rVYOSONEX654c403cebe3: Merge pull request #2 from sarthurdev/T970
rVYOSONEXd1bdf2b9d80d: firewall: T970: Maintain a domain state to fallback if resolution fails
rVYOSONEX3c5e1f748250: firewall: T970: domain-group should not starts with numeric
rVYOSONEX5294710b9280: Merge pull request #1327 from sever-sever/T970
T2198: Rewrite NAT in new XML/Python style
Event Timeline
I agree this is becoming increasingly necessary as vendors turn to AWS for hosting services and IP addressing becomes less static for services.
Supporting a hostname typically results in a DNS lookup at the time of rule creation and then no change until the rule is reloaded. As a work-around to this some distributions reload hostname-based rules every 5 min while others do so daily.
This still has some caveats however: In one example a DNS record which is more dynamic has makes use of a low TTL may change more frequently than the update interval. In another a lookup which returns multiple A records presumably would be expected to generate multiple firewall rules while many implementations may only select the first response. There are other assumptions made on behavior by the user (how are CNAMEs handled?).
To implement this in VyOS the right way would be non-trivial and require a bit of development. I would suggest the use of VyOS-generated address-group (ipset) which is populated and updated by a background process which keeps track of TTL values.
Syntax-wise this could be placed under the umbrella of a new firewall group type e.g. "name-group". Members of a name-group would be a FQDN. A daemon (or routine cron) handle resolving the FQDN(s) into the IP(s) associated while also tracking the TTL. On update new entries would be added but old entries would not be removed until their TTL expired.
Configuration would look something like:
set firewall group name-group NAME-EXAMPLE name 'www.example.com' set firewall group name-group NAME-EXAMPLE name 'example.com' set firewall name LAN-OUT rule 100 destination group name-group NAME-EXAMPLE
This would allow name-based functionality to be implemented in the way users often assume is the case despite known caveats and limitations typically encountered in other implementations.
Other enhancements could include DNSSEC support where one a key is learned it is added to the group configuration and enforced unless overridden.
A mock-up of this has been on my to-do list but unfortunately I have not had the time. Is anyone familiar with an existing project which might already do this or something similar?
this requires a helper that will be responsible for the DNS resolution and update of the corresponding rules
each DNS resolution will refresh IPs every 15 seconds or in smart mode will rely on DNS TTL for records and will do a lookup on TTL expire (and update firewall if required)
PR https://github.com/vyos/vyos-1x/pull/1327
set firewall group domain-group DOMAINS address 'example.com' set firewall group domain-group DOMAINS address 'example.org' set firewall name FOO default-action 'accept' set firewall name FOO rule 10 action 'drop' set firewall name FOO rule 10 source group domain-group 'DOMAINS' set interfaces ethernet eth0 firewall local name 'FOO'
- Some domains can't be added, for example dns.google
vyos@r12# set firewall group domain-group DOMAINS address dns.google Invalid value Value validation failed Set failed [edit] vyos@r12# vyos@r12# set firewall group domain-group DOMAINS address dns.google.com [edit] vyos@r12#
- Set Domain group without address Fails
vyos@r12# set firewall group domain-group DOMAIN [edit] vyos@r12# commit [ firewall ] VyOS had an issue completing a command. Traceback (most recent call last): File "/usr/libexec/vyos/conf_mode/firewall.py", line 458, in <module> apply(c) File "/usr/libexec/vyos/conf_mode/firewall.py", line 426, in apply for address in group_config['address']: KeyError: 'address' [[firewall]] failed Commit failed [edit] vyos@r12#
PR: https://github.com/vyos/vyos-1x/pull/1633
Adds firewall node rule N source/destination fqdn domain.com for single domains per rule and refactors resolver daemon.
Try it with groups
set firewall group domain-group domains address example.com set nat source rule 100 destination group domain-group domains
I tested this feature with the following firewall config:
set firewall group domain-group DG_TEST address 'nu.nl' set firewall group domain-group DG_TEST address 'www.nu.nl' set firewall interface eth1 out name 'ETH1_OUT' set firewall name ETH1_OUT default-action 'accept' set firewall name ETH1_OUT rule 10 action 'drop' set firewall name ETH1_OUT rule 10 destination group domain-group 'DG_TEST'
When I try to connect to the dutch news site, it is denied:
vyos@R1:~$ ping nu.nl PING nu.nl (104.110.191.44) 56(84) bytes of data. ^C --- nu.nl ping statistics --- 20 packets transmitted, 0 received, 100% packet loss, time 19487ms
And I see packets matching the firewall rule on the VyOS router:
vyos@R4:~$ show firewall name ETH1_OUT Ruleset Information --------------------------------- IPv4 Firewall "ETH1_OUT" Rule Action Protocol Packets Bytes Conditions ------- -------- ---------- --------- ------- ------------------- 10 drop all 46 3336 ip daddr @D_DG_TEST default accept all 127 8669
Tested on VyOS 1.4-rolling-202307040317.
It seems to work as expected for me.
R1 is a VyOS router behind R4, which is what I had running in a lab when trying this.
Perfect, would it be possible to update https://docs.vyos.io/en/sagitta/changelog/1.4.html and doc pages like https://docs.vyos.io/en/sagitta/configuration/firewall/groups.html accordingly ?