guest out: fix handling ARP traffic with default block/reject policy

In order to be able to send outgoing ARP packets when the default
policy is set to drop or reject, we need to explicitly allow ARP
traffic in the outgoing chain of guests. We need to do this in the
guest chain itself in order to be able to filter spoofed packets via
the MAC filter.

Contrary to the out direction we can simply accept all incoming ARP
traffic, since we do not do any MAC filtering for incoming traffic.
Since we create fdb entries for every NIC, guests should only see ARP
traffic for their MAC addresses anyway.

Originally-by: Laurent Guerby <laurent@guerby.net>
Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Stefan Hanreich 2024-05-15 15:37:18 +02:00 committed by Thomas Lamprecht
parent bc3791c59a
commit 3500a8d833
3 changed files with 7 additions and 6 deletions

View File

@ -309,6 +309,7 @@ table bridge proxmox-firewall-guests {
chain vm-in { chain vm-in {
type filter hook postrouting priority 0; policy accept; type filter hook postrouting priority 0; policy accept;
ether type arp accept
oifname vmap @vm-map-in oifname vmap @vm-map-in
} }
} }

View File

@ -516,7 +516,7 @@ impl Firewall {
commands.append(&mut vec![ commands.append(&mut vec![
Add::rule(AddRule::from_statement( Add::rule(AddRule::from_statement(
chain_in.clone(), chain_in,
Statement::jump(ndp_chains.0), Statement::jump(ndp_chains.0),
)), )),
Add::rule(AddRule::from_statement( Add::rule(AddRule::from_statement(
@ -532,17 +532,17 @@ impl Firewall {
}; };
commands.push(Add::rule(AddRule::from_statement( commands.push(Add::rule(AddRule::from_statement(
chain_out, chain_out.clone(),
Statement::jump(ra_chain_out), Statement::jump(ra_chain_out),
))); )));
// we allow incoming ARP by default, except if blocked by any option above // we allow outgoing ARP, except if blocked by the MAC filter above
let arp_rule = vec![ let arp_rule = vec![
Match::new_eq(Payload::field("ether", "type"), Expression::from("arp")).into(), Match::new_eq(Payload::field("ether", "type"), Expression::from("arp")).into(),
Statement::make_accept(), Statement::make_accept(),
]; ];
commands.push(Add::rule(AddRule::from_statements(chain_in, arp_rule))); commands.push(Add::rule(AddRule::from_statements(chain_out, arp_rule)));
Ok(()) Ok(())
} }

View File

@ -2923,7 +2923,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
"rule": { "rule": {
"family": "bridge", "family": "bridge",
"table": "proxmox-firewall-guests", "table": "proxmox-firewall-guests",
"chain": "guest-100-in", "chain": "guest-100-out",
"expr": [ "expr": [
{ {
"match": { "match": {
@ -3569,7 +3569,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
"rule": { "rule": {
"family": "bridge", "family": "bridge",
"table": "proxmox-firewall-guests", "table": "proxmox-firewall-guests",
"chain": "guest-101-in", "chain": "guest-101-out",
"expr": [ "expr": [
{ {
"match": { "match": {