Page MenuHomeVyOS Platform

No BCP38 for IPv6 on VyOS
Closed, ResolvedPublic

Description

hi,

as far as I could see we have no easy way to archive BCP38 for IPv6 on VyOS. The:

set firewall source-validation only works for ipv4

I see two alternatives:

https://github.com/faelix/hphr/tree/master/salt
or we use the iptables modules :

A "rpfilter" module is available since Linux 3.3 and iptables 1.4.13 which allow user to perform reverse path filtering in ipv4 and ipv6.

Details

Difficulty level
Unknown (require assessment)
Version
1.2.7, 1,3 , 1.4
Why the issue appeared?
Will be filled on close
Is it a breaking change?
Unspecified (possibly destroys the router)

Event Timeline

rherold created this object in space S1 VyOS Public.
syncer changed the task status from Open to In progress.Oct 17 2021, 3:08 PM
syncer triaged this task as Wishlist priority.
syncer removed a project: VyOS 1.3 Equuleus.

Stumbled again about it and would ask if it is not possible to switch to the iptables extension so that rp filter will also work for IPv6.
From my point of view we must create in firewall setup a new chain RPFILTER in IPv4 and IPv6.

Then replace the /proc/sys/net/ipv4/conf/${array[$i]%:*}/rp_filter" setups from vyatta/share/vyatta-cfg/templates/firewall/source-validation/node.def
with the iptables commands:

iptables -t raw -A RPFILTER -i $INTERFACE -m rpfilter --invert -j LOG --log-prefix "[V4_RPFILTER]"
ip6tables -t raw -A RPFILTER -i $INTERFACE -m rpfilter --invert -j log_drop "[V6_RPFILTER]"

or if loose:

iptables -t raw -A RPFILTER -i $INTERFACE -m rpfilter --loose --invert -j LOG --log-prefix "[V4_RPFILTER]"
ip6tables -t raw -A RPFILTER -i $INTERFACE -m rpfilter --loose --invert -j log_drop "[V6_RPFILTER]"

IF it should be for all Interfaces:

iptables -t raw -A RPFILTER -m rpfilter --invert -j LOG --log-prefix "[V4_RPFILTER]"
ip6tables -t raw -A RPFILTER -m rpfilter --invert -j log_drop "[V6_RPFILTER]"

or if loose:

iptables -t raw -A RPFILTER -m rpfilter --loose --invert -j LOG --log-prefix "[V4_RPFILTER]"
ip6tables -t raw -A RPFILTER -m rpfilter --loose --invert -j log_drop "[V6_RPFILTER]"

This would bring rpfilter for ipv4 and ipv6. From the kernel side a /proc/sys/net/ipv6/conf/*/rp_filter is not planned.
Iptables is the recommend way...

Also this should be easy to backport to 1.3

After digging a step deeper we could also move the function into:

/usr/libexec/vyos/conf_mode/firewall_options.py
and move it under:

/opt/vyatta/share/vyatta-cfg/templates/firewall/options/interface/

Hi!

The IPv6 reverse path filter functionality would be great if it worked properly.
On the other hand, the current sysctl based solution does not allow for adding exceptions.

After switching to nftables in Vyos 1.4 , the reverse path filter functionality can be implemented with the nft_fib module.

https://wiki.nftables.org/wiki-nftables/index.php/Matching_routing_information

Looks like the Problem still exist in 1.4. Are there any plans?

Perhaps same workaround as firewalld is implementing through option "IPv6_rpfilter=yes" could be implemented in VyOS (both uses nft)?

The rpfilter is built using the ipv6_backend.build_rpfilter_rules function:

https://github.com/firewalld/firewalld/blob/master/src/firewall/core/nftables.py#L1487

def build_rpfilter_rules(self, log_denied=False):
    rules = []
    expr_fragments = [{"match": {"left": {"meta": {"key": "nfproto"}},
                                 "op": "==",
                                 "right": "ipv6"}},
                      {"match": {"left": {"fib": {"flags": ["saddr", "iif", "mark"],
                                                  "result": "oif"}},
                                 "op": "==",
                                 "right": False}}]
    if log_denied != "off":
        expr_fragments.append({"log": {"prefix": "rpfilter_DROP: "}})
    expr_fragments.append({"drop": None})

    rules.append({"insert": {"rule": {"family": "inet",
                                      "table": TABLE_NAME,
                                      "chain": "filter_PREROUTING",
                                      "expr": expr_fragments}}})
    # RHBZ#1058505, RHBZ#1575431 (bug in kernel 4.16-4.17)
    rules.append({"insert": {"rule": {"family": "inet",
                                      "table": TABLE_NAME,
                                      "chain": "filter_PREROUTING",
                                      "expr": [{"match": {"left": {"payload": {"protocol": "icmpv6",
                                                                               "field": "type"}},
                                                          "op": "==",
                                                          "right": {"set": ["nd-router-advert", "nd-neighbor-solicit"]}}},
                                               {"accept": None}]}}})
    return rules

There's request for fib matcher: https://vyos.dev/T5119
It would be useful if you could propose cli design for this feature in that task, so we can discuss about it and then work on adding it

I did start writing support for this but didn't have time to build and test it at the time. If anyone wants to test it out: https://github.com/sarthurdev/vyos-1x/commit/9199b75d75ceea3b7d49f0e3d71a19175b7b1326

sarthurdev changed the task status from In progress to Needs testing.Aug 26 2023, 5:40 PM

I tried on VyOS 1.4-rolling-202308300021 .

Ipv6 now using nft rules for source validation ipv4 using the old sysctl method. Is this the expected behaviour?

set interfaces ethernet eth2 ipv6 source-validation strict
set interfaces ethernet eth2 ip source-validation strict
commit

sudo sysctl -a | grep eth2.rp_filter
net.ipv4.conf.eth2.rp_filter = 1

table ip6 raw {

chain VYOS_TCP_MSS {
        type filter hook forward priority raw; policy accept;
}

chain vyos_rpfilter {
        type filter hook prerouting priority raw; policy accept;
        iifname "eth2" fib saddr . iif oif 0 counter packets 0 bytes 0 drop
}

In table ip raw there is no vyos_rpfilter chain.

@csszep Yes it is expected, IPv6 has no sysctl and requires the nftables rule to function. The nftables execution is slightly slower, so there's no benefit to change it for IPv4.

sarthurdev moved this task from In Progress to Finished on the VyOS 1.4 Sagitta board.