Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T4072: firewall extend bridge firewall #3901

Merged
merged 5 commits into from
Aug 4, 2024

Conversation

nicolas-fort
Copy link
Contributor

@nicolas-fort nicolas-fort commented Jul 29, 2024

Change Summary

Extend bridge firewall by:

  • Adding more chains: input, output and prerouting
  • Adding L3 options for matching criterias
  • Add support for firewall groups
  • Add sysctl parameter for enabling/disabling call to firewall IP layer for bridges.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes)
  • Migration from an old Vyatta component to vyos-1x, please link to related PR inside obsoleted component
  • Other (please describe):

Related Task(s)

Related PR(s)

vyos/vyos-documentation#1512

Component(s) name

firewall

Proposed changes

How to test

vyos@BRIDGE:~$ show config comm | grep "firewall bridge\| firewall group"
set firewall bridge forward filter rule 1 action 'accept'
set firewall bridge forward filter rule 1 destination address '2.2.2.2'
set firewall bridge forward filter rule 1 protocol 'icmp'
set firewall bridge forward filter rule 1 source address '8.8.8.8'
set firewall bridge input filter rule 1 action 'drop'
set firewall bridge input filter rule 1 destination group ipv4-address-group '!AG01'
set firewall bridge input filter rule 1 inbound-interface name 'eth1'
set firewall bridge input filter rule 1 source address '192.0.2.2'
set firewall bridge input filter rule 1 state 'new'
set firewall bridge input filter rule 10 action 'queue'
set firewall bridge input filter rule 10 connection-mark '8888'
set firewall bridge input filter rule 10 protocol 'gre'
set firewall bridge input filter rule 10 queue '88-100'
set firewall bridge input filter rule 10 queue-options 'fanout'
set firewall bridge input filter rule 10 queue-options 'bypass'
set firewall bridge input filter rule 10 source group mac-group 'MAC01'
set firewall bridge input filter rule 10 vlan id '4092'
set firewall bridge input filter rule 10 vlan priority '5'
set firewall bridge output filter rule 101 action 'return'
set firewall bridge output filter rule 101 dscp '32'
set firewall bridge output filter rule 101 outbound-interface name 'bri9*'
set firewall bridge output filter rule 101 protocol 'tcp'
set firewall bridge output filter rule 101 source group port-group 'PG01'
set firewall bridge prerouting filter rule 10 action 'notrack'
set firewall bridge prerouting filter rule 10 destination group ipv6-address-group 'AGV6'
set firewall bridge prerouting filter rule 10 set table '100'
set firewall bridge prerouting filter rule 10 source group ipv6-address-group '!AGV6'
set firewall bridge prerouting filter rule 700 action 'continue'
set firewall bridge prerouting filter rule 700 inbound-interface name 'bond99*'
set firewall bridge prerouting filter rule 700 set dscp '16'
set firewall bridge prerouting filter rule 700 set tcp-mss '1333'
set firewall group address-group AG01 address '198.51.100.1'
set firewall group ipv6-address-group AGV6 address '2001::1'
set firewall group ipv6-address-group AGV6 address '2001::9999'
set firewall group ipv6-network-group NET6 network '2001:db8::/64'
set firewall group mac-group MAC01 mac-address '11:22:33:44:55:66'
set firewall group mac-group MAC01 mac-address '66:55:44:33:22:11'
set firewall group port-group PG01 port '22'
set firewall group port-group PG01 port '33'
set firewall group port-group PG01 port '44'
vyos@BRIDGE:~$ 

nftables

vyos@BRIDGE:~$ sudo nft list table bridge vyos_filter
table bridge vyos_filter {
        set A_AG01 {
                type ipv4_addr
                flags interval
                auto-merge
                elements = { 198.51.100.1 }
        }

        set M_MAC01 {
                type ether_addr
                elements = { 11:22:33:44:55:66,
                             66:55:44:33:22:11 }
        }

        set P_PG01 {
                type inet_service
                flags interval
                auto-merge
                elements = { 22, 33, 44 }
        }

        set A6_AGV6 {
                type ipv6_addr
                flags interval
                auto-merge
                elements = { 2001::1,
                             2001::9999 }
        }

        set N6_NET6 {
                type ipv6_addr
                flags interval
                auto-merge
                elements = { 2001:db8::/64 }
        }

        chain VYOS_FORWARD_filter {
                type filter hook forward priority filter; policy accept;
                jump VYOS_STATE_POLICY
                meta l4proto icmp ip daddr 2.2.2.2 ip saddr 8.8.8.8 counter packets 0 bytes 0 accept comment "bri-FWD-filter-1"
                counter packets 0 bytes 0 accept comment "FWD-filter default-action accept"
        }

        chain VYOS_INPUT_filter {
                type filter hook input priority filter; policy accept;
                jump VYOS_STATE_POLICY
                ct state new ip daddr != @A_AG01 ip saddr 192.0.2.2 iifname "eth1" counter packets 0 bytes 0 drop comment "bri-INP-filter-1"
                meta l4proto gre ether saddr @M_MAC01 ct mark 0x000022b8 vlan id 4092 vlan pcp 5 counter packets 0 bytes 0 queue flags bypass,fanout to 88-100 comment "bri-INP-filter-10"
                counter packets 0 bytes 0 accept comment "INP-filter default-action accept"
        }

        chain VYOS_OUTUT_filter {
                type filter hook output priority filter; policy accept;
                jump VYOS_STATE_POLICY
                tcp sport @P_PG01 oifname "bri9*" ip dscp cs4 counter packets 0 bytes 0 return comment "bri-OUT-filter-101"
                counter packets 8 bytes 768 accept comment "OUT-filter default-action accept"
        }

        chain VYOS_PREROUTING_filter {
                type filter hook prerouting priority filter; policy accept;
                ip6 daddr @A6_AGV6 ip6 saddr != @A6_AGV6 counter packets 0 bytes 0 meta mark set 0x7fffff9b notrack comment "bri-PRE-filter-10"
                iifname "bond99*" counter packets 0 bytes 0 ip dscp set cs2 tcp option maxseg size set 1333 continue comment "bri-PRE-filter-700"
                counter packets 0 bytes 0 accept comment "PRE-filter default-action accept"
        }

        chain VYOS_STATE_POLICY {
                ct state established counter packets 0 bytes 0 accept
                return
        }
}
vyos@BRIDGE:~$ 


Smoketest result

test_firewall.py --> OK
test_policy_route.py --> OK
test_nat.py --> OK

Checklist:

  • I have read the CONTRIBUTING document
  • I have linked this PR to one or more Phabricator Task(s)
  • I have run the components SMOKETESTS if applicable
  • My commit headlines contain a valid Task id
  • My change requires a change to the documentation
  • I have updated the documentation accordingly

@nicolas-fort nicolas-fort requested a review from a team as a code owner July 29, 2024 19:59
Copy link

github-actions bot commented Jul 29, 2024

👍
No issues in PR Title / Commit Title

Copy link

github-actions bot commented Jul 29, 2024


warning: Unused Warning imported from vyos.base in src/conf_mode/vpn_ipsec.py:28.

Copy link

CI integration 👍 passed!

Details

CI logs

  • CLI Smoketests 👍 passed
  • Config tests 👍 passed
  • RAID1 tests 👍 passed

Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.

Copy link
Member

@dmbaturin dmbaturin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find any issues in the scripts, but I think some option names and help strings can be improved.

<children>
<node name="filter">
<properties>
<help>Bridge firewall prerouting filter</help>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can find better wording for these help strings, although I'm not sure offhand what a better option might be. We can keep this, if nothing else.

@@ -44,6 +44,25 @@
</properties>
<defaultValue>disable</defaultValue>
</leafNode>
<node name="apply-for-bridge">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this option name. First, it's ungrammatical: apply is used with for only in its intransitive sense ("apply for a job"), when it's transitive it should be "apply $something to $somethingElse". Second, it's not very obvious. Maybe apply-to-bridged-traffic — kinda wordy, but it's immediately obvious what the option does.

Alternatively: filter-bridged-traffic.

</leafNode>
<leafNode name="dscp">
<properties>
<help>Packet Differentiated Services Codepoint (DSCP)</help>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "Set DSCP (Differentiated Services Codepoint) bits"?

Copy link

Conflicts have been resolved. A maintainer will review the pull request shortly.

@nicolas-fort nicolas-fort requested a review from dmbaturin July 31, 2024 13:50
@nicolas-fort nicolas-fort marked this pull request as draft July 31, 2024 18:56
@nicolas-fort nicolas-fort force-pushed the T4072-extend-bridge-fwall branch from 89efe8e to 25f1b6e Compare August 1, 2024 11:08
Copy link

github-actions bot commented Aug 1, 2024

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@nicolas-fort nicolas-fort force-pushed the T4072-extend-bridge-fwall branch from 25f1b6e to a5ee39a Compare August 1, 2024 12:54
…lude new chains, priorities, and firewall groups
…s wrong. Use nft -c option to check temporary file, and use output provided by nftables to parse the error if possible, or print it as it is if it's an unknown error
…enabling/disabling sending traffic from bridge layer to ipvX layer
@nicolas-fort nicolas-fort force-pushed the T4072-extend-bridge-fwall branch from a5ee39a to 70b5bd1 Compare August 1, 2024 16:52
Copy link

github-actions bot commented Aug 1, 2024

Conflicts have been resolved. A maintainer will review the pull request shortly.

@github-actions github-actions bot removed the conflicts label Aug 1, 2024
@nicolas-fort nicolas-fort marked this pull request as ready for review August 1, 2024 17:29
@nicolas-fort
Copy link
Contributor Author

I've removed features for packet modifications, which orignally was implementef fot firewall bridge prerouting. In this PR just add more hooks to firewall bridge, and improve error handling.
In future PR, I'll add packet modifications/PBR capabilities to firewall

… prerouting chain; re introduce <set vrf> in policy; change global options for passing traffic to IPvX firewall; update smoketest
@nicolas-fort nicolas-fort force-pushed the T4072-extend-bridge-fwall branch from 70b5bd1 to c33cd61 Compare August 2, 2024 12:50
Copy link
Member

@dmbaturin dmbaturin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no objections to merging it now. We can improve help strings later if we figure out better wordings, option names and implementation seems good.

@sever-sever
Copy link
Member

There is only one issue with this: we cannot configure an action for ARP

set interfaces bridge br0 address '100.64.0.1/24'
set interfaces bridge br0 enable-vlan
set interfaces bridge br0 member interface eth1 allowed-vlan '10-20'
set interfaces bridge br0 member interface eth1 native-vlan '1'
set interfaces bridge br0 member interface eth2
set interfaces bridge br0 vif 10 address '100.64.10.1/24'
set interfaces bridge br0 vif 20 address '100.64.20.1/24'

set firewall bridge input filter default-action 'drop'
set firewall bridge input filter rule 10 action 'accept'
set firewall bridge input filter rule 10 source address '100.64.10.0/24'
set firewall bridge input filter rule 20 action 'drop'
set firewall bridge input filter rule 20 source address '100.64.20.0/24'

This way, it will drop all ARP requests.

vyos@r4# sudo tcpdump -ni eth1 -c 2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
18:03:00.815304 ARP, Request who-has 100.64.10.1 tell 100.64.10.2, length 28
18:03:01.839111 ARP, Request who-has 100.64.10.1 tell 100.64.10.2, length 28
2 packets captured
2 packets received by filter
0 packets dropped by kernel
[edit]
vyos@r4# 
[edit]
vyos@r4# 
[edit]
vyos@r4# sudo tcpdump -ni br0 -c 2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel
[edit]
vyos@r4# 

So needs to be carefully with default action:

Aug 02 18:10:53 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:10:55 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:10:56 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:10:57 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:10:59 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:11:00 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:11:01 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:11:03 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:11:04 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=00:00:00:00:00:00 IPDST=100.64.10.1
Aug 02 18:11:04 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:11:05 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=00:00:00:00:00:00 IPDST=100.64.10.1

@nicolas-fort
Copy link
Contributor Author

There is only one issue with this: we cannot configure an action for ARP

set interfaces bridge br0 address '100.64.0.1/24'
set interfaces bridge br0 enable-vlan
set interfaces bridge br0 member interface eth1 allowed-vlan '10-20'
set interfaces bridge br0 member interface eth1 native-vlan '1'
set interfaces bridge br0 member interface eth2
set interfaces bridge br0 vif 10 address '100.64.10.1/24'
set interfaces bridge br0 vif 20 address '100.64.20.1/24'

set firewall bridge input filter default-action 'drop'
set firewall bridge input filter rule 10 action 'accept'
set firewall bridge input filter rule 10 source address '100.64.10.0/24'
set firewall bridge input filter rule 20 action 'drop'
set firewall bridge input filter rule 20 source address '100.64.20.0/24'

This way, it will drop all ARP requests.

vyos@r4# sudo tcpdump -ni eth1 -c 2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
18:03:00.815304 ARP, Request who-has 100.64.10.1 tell 100.64.10.2, length 28
18:03:01.839111 ARP, Request who-has 100.64.10.1 tell 100.64.10.2, length 28
2 packets captured
2 packets received by filter
0 packets dropped by kernel
[edit]
vyos@r4# 
[edit]
vyos@r4# 
[edit]
vyos@r4# sudo tcpdump -ni br0 -c 2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel
[edit]
vyos@r4# 

So needs to be carefully with default action:

Aug 02 18:10:53 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:10:55 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:10:56 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:10:57 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:10:59 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:11:00 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:11:01 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:11:03 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:11:04 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=00:00:00:00:00:00 IPDST=100.64.10.1
Aug 02 18:11:04 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=2 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=86:a2:80:36:ae:07 IPDST=100.64.10.1
Aug 02 18:11:05 r4 kernel: [bri-INP-filter-default-D]IN=eth1 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=52:54:00:92:35:5d IPSRC=100.64.10.2 MACDST=00:00:00:00:00:00 IPDST=100.64.10.1

I'll check this, and create a feature request and submit a separate PR

@c-po c-po merged commit 15c7797 into vyos:current Aug 4, 2024
15 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

4 participants