Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions routeros/sw-core01/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ VLAN 30 is L2-only. It is tagged on `bond-lab01`–`03` and `sfp-sfpplus7`
(nas01). It is not tagged on `bridge-lab` or the gw01 trunk
(`sfp-sfpplus8`).

VLAN 50 (services) is routed on gw01 (`10.10.50.1/24`). It is tagged on
`sfp-sfpplus8` (gw01 trunk) and `sfp-sfpplus7` (nas01) only, not on the
lab bonds or `bridge-lab`. Apply it on sw-core01 before gw01 so the
gateway's `eth1.50` has a path to nas01 as soon as it comes up.

## Notes

- Ethernet names stay at factory (`ether1`, `sfp-sfpplus1`–`8`). Roles and
Expand Down
9 changes: 9 additions & 0 deletions routeros/sw-core01/bridge.tf
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,12 @@ resource "routeros_interface_bridge_vlan" "vlan40" {
routeros_interface_ethernet.sfp_sfpplus8.name,
]
}

resource "routeros_interface_bridge_vlan" "vlan50" {
bridge = routeros_interface_bridge.lab.name
vlan_ids = ["50"]
tagged = [
routeros_interface_ethernet.sfp_sfpplus7.name,
routeros_interface_ethernet.sfp_sfpplus8.name,
]
}
1 change: 1 addition & 0 deletions src/networking_vyos/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
(r"\b10\.0\.0\.2/30\b", "transit address"),
(r"\b10\.10\.10\.1/24\b", "management gateway"),
(r"\b10\.10\.40\.1/24\b", "sandbox gateway"),
(r"\b10\.10\.50\.1/24\b", "services gateway"),
(r"\b10\.10\.70\.1/24\b", "OOB gateway"),
(r"\bnext-hop\s+10\.0\.0\.1\b", "default route"),
(r"\btailscale\b", "Tailscale"),
Expand Down
7 changes: 7 additions & 0 deletions src/networking_vyos/verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
("set interfaces bridge br70 address", "10.10.70.1/24"),
("set interfaces ethernet eth1 vif 10",),
("set interfaces ethernet eth1 vif 40",),
("set interfaces ethernet eth1 vif 50 address", "10.10.50.1/24"),
("set interfaces ethernet eth3 vif 10",),
("set interfaces ethernet eth3 vif 70",),
("set interfaces bridge br10 member interface eth3.10",),
Expand All @@ -24,6 +25,7 @@
("set service dhcp-server listen-interface", "br10"),
("set service dhcp-server listen-interface", "br40"),
("set service dhcp-server listen-interface", "br70"),
("set service dhcp-server listen-interface", "eth1.50"),
("set container name tailscale environment TS_ROUTES value", "10.10.0.0/16"),
("set container name tailscale",),
("set container name coredns-glab-lol",),
Expand All @@ -37,6 +39,8 @@
("set firewall ipv4 forward filter rule 120 jump-target", "SANDBOX_FORWARD"),
("set firewall ipv4 forward filter rule 130 inbound-interface name", "br70"),
("set firewall ipv4 forward filter rule 130 jump-target", "OOB_FORWARD"),
("set firewall ipv4 forward filter rule 150 inbound-interface name", "eth1.50"),
("set firewall ipv4 forward filter rule 150 jump-target", "SERVICES_FORWARD"),
("set firewall ipv4 input filter rule 100 inbound-interface name", "eth0"),
("set firewall ipv4 input filter rule 100 jump-target", "WAN_LOCAL"),
("set firewall ipv4 input filter rule 110 inbound-interface name", "br10"),
Expand All @@ -45,6 +49,8 @@
("set firewall ipv4 input filter rule 120 jump-target", "SANDBOX_LOCAL"),
("set firewall ipv4 input filter rule 130 inbound-interface name", "br70"),
("set firewall ipv4 input filter rule 130 jump-target", "OOB_LOCAL"),
("set firewall ipv4 input filter rule 150 inbound-interface name", "eth1.50"),
("set firewall ipv4 input filter rule 150 jump-target", "SERVICES_LOCAL"),
)

RETIRED_FRAGMENTS = (
Expand Down Expand Up @@ -104,6 +110,7 @@ def verify_operational_state(
("eth0", "10.0.0.2/30"),
("br10", "10.10.10.1/24"),
("br40", "10.10.40.1/24"),
("eth1.50", "10.10.50.1/24"),
("br70", "10.10.70.1/24"),
)
for fragments in required_interfaces:
Expand Down
4 changes: 4 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
}
vif 40 {
}
vif 50 {
address 10.10.50.1/24
}
}
ethernet eth3 {
vif 10 {
Expand Down Expand Up @@ -59,6 +62,7 @@
listen-interface br10
listen-interface br40
listen-interface br70
listen-interface eth1.50
}
}
container {
Expand Down
15 changes: 15 additions & 0 deletions tests/test_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ def test_sandbox_to_management_is_allowed() -> None:
}""" in load_template()


def test_services_to_management_is_blocked() -> None:
from networking_vyos.render import load_template

assert """rule 10 {
action drop
description "Block new connections to management"
destination {
group {
network-group LAB_MGMT
}
}
state new
}""" in load_template()


def test_invented_footer_is_rejected() -> None:
with pytest.raises(ToolError, match="must not invent"):
validate_template(VALID_TEMPLATE + '\n// vyos-config-version: "guessed@1"\n')
Expand Down
8 changes: 8 additions & 0 deletions tests/test_sync_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def test_verify_commands_require_accepted_state_and_reject_retired() -> None:
"set interfaces bridge br70 address '10.10.70.1/24'",
"set interfaces ethernet eth1 vif 10",
"set interfaces ethernet eth1 vif 40",
"set interfaces ethernet eth1 vif 50 address '10.10.50.1/24'",
"set interfaces ethernet eth3 vif 10",
"set interfaces ethernet eth3 vif 70",
"set interfaces bridge br10 member interface eth3.10",
Expand All @@ -94,6 +95,7 @@ def test_verify_commands_require_accepted_state_and_reject_retired() -> None:
"set service dhcp-server listen-interface br10",
"set service dhcp-server listen-interface br40",
"set service dhcp-server listen-interface br70",
"set service dhcp-server listen-interface eth1.50",
"set container name tailscale environment TS_ROUTES value '10.10.0.0/16'",
"set container name tailscale image docker.io/tailscale/tailscale:v1.96.5",
"set container name coredns-glab-lol",
Expand All @@ -107,6 +109,8 @@ def test_verify_commands_require_accepted_state_and_reject_retired() -> None:
"set firewall ipv4 forward filter rule 120 jump-target SANDBOX_FORWARD",
"set firewall ipv4 forward filter rule 130 inbound-interface name br70",
"set firewall ipv4 forward filter rule 130 jump-target OOB_FORWARD",
"set firewall ipv4 forward filter rule 150 inbound-interface name eth1.50",
"set firewall ipv4 forward filter rule 150 jump-target SERVICES_FORWARD",
"set firewall ipv4 input filter rule 100 inbound-interface name eth0",
"set firewall ipv4 input filter rule 100 jump-target WAN_LOCAL",
"set firewall ipv4 input filter rule 110 inbound-interface name br10",
Expand All @@ -115,6 +119,8 @@ def test_verify_commands_require_accepted_state_and_reject_retired() -> None:
"set firewall ipv4 input filter rule 120 jump-target SANDBOX_LOCAL",
"set firewall ipv4 input filter rule 130 inbound-interface name br70",
"set firewall ipv4 input filter rule 130 jump-target OOB_LOCAL",
"set firewall ipv4 input filter rule 150 inbound-interface name eth1.50",
"set firewall ipv4 input filter rule 150 jump-target SERVICES_LOCAL",
]
verify_commands(commands, stage="verification")
with pytest.raises(ToolError, match="retired state"):
Expand All @@ -132,6 +138,7 @@ def test_operational_verification_requires_routes_interfaces_and_containers() ->
"eth0 10.0.0.2/30 up\n"
"br10 10.10.10.1/24 up\n"
"br40 10.10.40.1/24 up\n"
"eth1.50 10.10.50.1/24 up\n"
"br70 10.10.70.1/24 up"
),
routes="S>* 0.0.0.0/0 [1/0] via 10.0.0.1, eth0",
Expand All @@ -144,6 +151,7 @@ def test_operational_verification_requires_routes_interfaces_and_containers() ->
"eth0 10.0.0.2/30 up\n"
"br10 10.10.10.1/24 up\n"
"br40 10.10.40.1/24 up\n"
"eth1.50 10.10.50.1/24 up\n"
"br70 10.10.70.1/24 up"
),
routes="S>* 0.0.0.0/0 [1/0] via 10.0.0.1, eth0",
Expand Down
6 changes: 4 additions & 2 deletions vyos/gw01/assets/coredns/Corefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
glab.lol:53 {
bind 10.10.10.54 10.10.10.1 10.10.40.1 10.10.70.1
bind 10.10.10.54 10.10.10.1 10.10.40.1 10.10.50.1 10.10.70.1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restart CoreDNS so the new VLAN bind takes effect

On an in-place gw01 rollout, the assets stage only overwrites the mounted Corefile, and the subsequent configuration load does not change the container definition or explicitly restart it. CoreDNS rereads a changed Corefile only when its reload plugin is configured, which this Corefile does not enable; VyOS's restart always setting merely controls behavior after the container exits. Consequently, the running process retains its old listeners and does not answer on 10.10.50.1, while the existing verification probes only VLAN 10 and still passes. Restart CoreDNS after the new interface is committed, or otherwise add a reliable post-commit reload mechanism.

Useful? React with 👍 / 👎.

errors
log
reload
file /zones/glab.lol.zone glab.lol {
reload 30s
}
}

.:53 {
bind 10.10.10.1 10.10.40.1 10.10.70.1
bind 10.10.10.1 10.10.40.1 10.10.50.1 10.10.70.1
cache 300
reload
errors
forward . 1.1.1.1 8.8.8.8
log
Expand Down
Loading
Loading