Skip to content

[caclmgrd] Restrict FRR daemon loopback TCP ports to FRR user#389

Open
nsoma-cisco wants to merge 1 commit into
sonic-net:masterfrom
nsoma-cisco:nsoma_master
Open

[caclmgrd] Restrict FRR daemon loopback TCP ports to FRR user#389
nsoma-cisco wants to merge 1 commit into
sonic-net:masterfrom
nsoma-cisco:nsoma_master

Conversation

@nsoma-cisco

Copy link
Copy Markdown

Summary

Lock down zebra (TCP/2601) and the fpmsyncd<->zebra socket (TCP/2620) on the loopback interface so only the FRR user (UID 300) can connect; every other local UID is dropped.

  • Per port the ACCEPT (uid-owner 300) rule is appended before the DROP so iptables matches FRR-internal traffic first.
  • Rules are emitted in every namespace caclmgrd manages (host on single-ASIC, per-ASIC bgp container namespaces on multi-ASIC) since FRR runs in each of them with the same UID and ports.
  • The helper is invoked from get_acl_rules_and_translate_to_iptables_commands, so the rules are reinstalled on every full programming pass: at boot, on systemctl restart caclmgrd, and after any CONFIG_DB ACL_TABLE/ACL_RULE change — no additional plumbing required for persistence.

What changed

scripts/caclmgrd:

  • New class constants FRR_USER_UID = 300 and FRR_LOOPBACK_TCP_DROP_PORTS = [2601, 2620].
  • New helper generate_frr_daemon_loopback_acl_commands(namespace) that emits the ACCEPT-then-DROP pair per port, namespace-prefixed.
  • Call site added in the main rule generator, right after the existing ip6tables NOTRACK rules and before the CONFIG_DB ACL lookup.

tests/caclmgrd/:

  • caclmgrd_frr_loopback_acl_test.py — 5 tests covering rule presence, ACCEPT-before-DROP ordering, helper rule count, ASIC-namespace prefix, and a regression guard (test_no_generic_output_drop_precedes_frr_accept) that asserts no IPv4 OUTPUT-chain DROP/REJECT precedes the FRR ACCEPT rules.
  • test_frr_loopback_acl_vectors.py — minimal CONFIG_DB test vector.

Test plan

  • python3 -m pytest tests/caclmgrd/53 passed (5 new + 48 pre-existing) in a Debian-bookworm container with libswsscommon + sonic-py-common installed.
  • test_no_generic_output_drop_precedes_frr_accept regression guard verified in-tree.
  • On-device verification: load on a single-ASIC and a multi-ASIC chassis, iptables -S OUTPUT shows the ACCEPT/DROP pairs for ports 2601 and 2620 in the host and in each per-ASIC bgp container namespace.
  • Functional: confirm vtysh -d zebra still works as the FRR user and is rejected for other UIDs; confirm fpmsyncd<->zebra connection stays up.

@mssonicbld

Copy link
Copy Markdown

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld

Copy link
Copy Markdown

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Lock down zebra (TCP/2601) and the fpmsyncd<->zebra socket (TCP/2620) on
the loopback interface so only the FRR user (UID 300) can connect; every
other local UID is dropped.

Per port the ACCEPT (uid-owner 300) rule is appended before the DROP so
iptables matches FRR-internal traffic first. Rules are emitted in every
namespace caclmgrd manages (host on single-ASIC, per-ASIC bgp container
namespaces on multi-ASIC) since FRR runs in each of them with the same
UID and ports.

The helper is invoked from get_acl_rules_and_translate_to_iptables_commands,
so the rules are reinstalled on every full programming pass: at boot, on
systemctl restart caclmgrd, and after any CONFIG_DB ACL_TABLE/ACL_RULE
change.

Adds caclmgrd_frr_loopback_acl_test.py covering rule presence, per-port
ACCEPT-before-DROP ordering, helper rule count, and ASIC-namespace
prefix, plus test_no_generic_output_drop_precedes_frr_accept which
inspects the generated iptables command list and asserts that no IPv4
OUTPUT-chain DROP or REJECT rule appears before the FRR per-UID ACCEPT
rules. This pins the current invariant so a future contributor can't
silently shadow the FRR ACCEPT and break FRR daemon loopback
communication.

Signed-off-by: Nageswara Soma <nsoma@cisco.com>
@mssonicbld

Copy link
Copy Markdown

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants