| Age | Commit message (Collapse) | Author |
|
pki: T9135: derive ACME certificate chains from disk
|
|
firewall: T7552: Output rule in verify_rule() ConfigError messages
|
|
certbot_request() ultimately shells out via cmdl(), which can fail with
something other than ConfigError - e.g. FileNotFoundError if the certbot
binary itself is missing, or another OSError from the underlying process
call. The backup/restore wrapper around a certificate replacement only
caught ConfigError, so any other failure skipped restoration entirely and
left the certificate deleted with no way back, defeating the point of taking
a backup before requesting a replacement in the first place.
|
|
A failed certbot request or renewal only showed the CLI a raw dump of the
invoked command line and its exit code - not the actual reason (e.g. rate
limiting, failed domain validation), because certbot's own non-interactive
error reporting can itself crash on an unrelated internal bug while trying
to display the failure, masking it entirely from the captured output.
Read the real reason directly out of certbot's own debug log instead, scoped
to what the current invocation appended, and use it as the error message
shown to the user. Falls back to the previous generic message when no such
line is found.
|
|
An ACME-issued certificate's intermediate CA was previously imported into the
running configuration as a synthetic object, purely so consumers building a
full certificate chain (HAProxy, HTTPS, IPsec, stunnel, EAPOL, ...) could
find it. This leaked certbot's internal state into the CLI as a real, deletable
object that never needed to exist there: the intermediate is available on disk
the moment the certificate is issued, same as the leaf certificate and its key.
Read it live from disk instead, purely in memory, wherever a full chain is
resolved or displayed - never as a settable or deletable configuration object.
An already-configured CA that completes the chain on its own takes precedence
and nothing synthetic is added.
Adding, changing, or removing a CA now reloads only the services whose resolved
chain is actually affected, with no side effect on certificates whose own
content did not change.
|
|
container: T7736: fix smoketest failures caused by netavark/aardvark-dns IPv6 DAD race
|
|
flow-accounting: T9122: bind NetFlow export to the configured VRF
|
|
netavark assigns the IPv6 gateway address to a container "pod-*" bridge
and immediately invokes aardvark-dns to bind its DNS listener to it. While
the address is "tentative" during Duplicate Address Detection, that bind()
fails with EADDRNOTAVAIL and container startup fails for any IPv6-enabled
network.
The kernel only skips DAD for an address if both "all" and the specific
interface's own accept_dad are disabled at the moment the interface is
created. A per-interface override is always either too late for a network's
first-ever container - as the network can only be created in-time and not
explicitly before starting the first container.
|
|
Podman's default "vethN" auto-naming for a container's host-side veth can
collide with VyOS's own "virtual-ethernet vethN" interfaces.
Bump the minimum Podman dependency to 5.8 (which supports "host_interface_name"
network connect option) and use it to name every non-macvlan container network
attachment "veth-<container name>" instead, eliminating the collision by
construction. Container names too long to fit are shortened to a recognizable
prefix plus a short hash of the full name; verify() rejects the rare case
where two containers still generate the same interface name.
Add "show container interface" to display the resulting name-to-container
mapping.
|
|
|
|
|
|
vpp: T8468: Apply MAC address changes on VPP interfaces
|
|
I had initially treated the VRF as just another interface that could be
used as a source-interface, but after a bit more research none of the
major vendors treat VRFs as interfaces - Cisco and Juniper both source a
flow exporter from a routed interface and never from a VRF - and I don't
think we should either.
Reject a source-interface that names a VRF device with a clear message
instead of the misleading "is not a member of VRF" error, and cover the
rejection in the smoketest. VRF export continues to be selected through
the "system flow-accounting vrf" node.
|
|
After the migration from pmacct to the ipt_NETFLOW kernel module the
"system flow-accounting vrf" node no longer had any effect on the export
path. NetFlow is emitted by the kernel module, so there is no daemon left
to wrap in "ip vrf exec" and the module socket was never bound to the VRF.
A collector reachable only inside a VRF therefore never received any flows
when the export was configured with a source-address.
Bind the export socket to a device via the ipt_NETFLOW "%device"
destination suffix: a per-server source-interface takes precedence,
otherwise the global VRF device is used, reproducing the previous
"ip vrf exec" behaviour. The module parses "@source-address" before
"%device", so the source-address is now rendered first - the previous
template emitted them in the opposite order, which only worked because the
two options are mutually exclusive per server.
Reject a source-interface that is used together with a VRF but is not a
member of that VRF: the exported flows would otherwise silently leave via
a different routing table. This mirrors the existing OSPF, OSPFv3, IS-IS
and BGP checks.
|
|
Reject deletion of a gre, ipip, vxlan or loopback interface that is still
used by a feature.
|
|
The interface config filter stripped the "mac" node, so a MAC address
configured on a VPP interface never reached the dataplane. Allow "mac"
through the filter; VPP applies it to the hardware interface via lcp-sync.
Some DPDK drivers (e.g. vmxnet3) cannot change the MAC and would fail to
bring the interface up. Reject such a change at verify time - both when
setting the MAC and when adding an interface that already has one to VPP.
|
|
apply_interface() unconditionally deleted the "parent ffff:" ingress
qdisc before re-applying QoS, even for interfaces with an egress-only
policy.
Since call_dependents() had already restored an unrelated ingress
redirect/mirror qdisc on that handle just before, and only directions
present in the interface's QoS config get re-applied, the redirect
was silently lost and never recreated.
|
|
vpp: T8367: Fix identical default MAC on bridged loopback interfaces
|
|
firewall: T9076: add per-remote-group update interval
|
|
T9073: frr-exporter: add CLI support for optional collectors and collector options
|
|
wireless: T9104: fix CLI/OS race on interface removal
|
|
VPP assigns loopback interfaces a default MAC address derived only from
the interface instance number (de:ad:00:00:00:<instance>), with no
host-specific entropy. Two independent VPP nodes configuring the same
loopback instance (e.g. as a bridge BVI over VXLAN) therefore end up with
an identical MAC address.
When that MAC arrives from a peer over the shared L2 segment, VPP's L2
learning logic rejects it as a `mac move violation` - it's statically
pinned to the local BVI and cannot legitimately appear on another port.
This silently drops ARP traffic between the loopbacks while ordinary
bridged client traffic (unique MACs) is unaffected, breaking
loopback-to-loopback connectivity.
Add a mac-address option to the VPP loopback interface, and fall back to
a deterministic, host-unique MAC (derived from host UUID/hostname, same
scheme already used for container interfaces) whenever none is
configured, so the collision can no longer occur by default.
Also fix a related bug found while reproducing the above: a loopback is
fully deleted and recreated in VPP on every apply, receiving a new
`sw_if_index` each time. The loopback conf_mode script never registered
the bridge it's a BVI member of as a dependent, so the bridge kept its
L2 membership bound to the stale, deleted index instead of reattaching
the current one. Register the bridge dependency and reuse the existing
`verify_vpp_remove_bridge_interface()` check to block deleting a
loopback still in use as a BVI.
|
|
A classical race condition detected depending on host system CPU load while
executing smoketests.
Removal of the Wireless/Wifi interfaces can cause a KeyError.
Traceback (most recent call last):
File "/usr/libexec/vyos/conf_mode/interfaces_wireless.py", line 414, in <module>
apply(c)
File "/usr/libexec/vyos/conf_mode/interfaces_wireless.py", line 325, in apply
WiFiIf(**wifi).remove()
^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/vyos/ifconfig/interface.py", line 358, in __init__
self._create()
File "/usr/lib/python3/dist-packages/vyos/ifconfig/wireless.py", line 33, in _create
cmd = ['iw', 'phy', self.config['physical_device'], 'interface', 'add',
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
KeyError: 'physical_device'
In src/conf_mode/interfaces_wireless.py:apply(), the delete path
unconditionally does WiFiIf(**wifi).remove(). Since the wifi dict for a
deleted node never contains physical_device, and Interface.__init__ calls
self._create() whenever the kernel interface doesn't already exist,
WiFiIf._create() crashes with KeyError: 'physical_device' when the interface
never actually got created (or already vanished) before deletion.
|
|
Complete the safer-subprocess migration started by the cmdl()/ifconfig
refactoring and convert every remaining vyos.utils.process.cmd() call site to
the list-based cmdl().
Drop the vyos.utils.process.cmd() implementation as it is no longer in use.
|
|
T8529: Add configuration CLI to enable OpenSSL FIPS
|
|
options
frr_exporter v1.5.0 enables the bgp, ospf, bfd and route collectors by
default, while bgpl2vpn, pim and vrrp must be enabled explicitly. Expose
bgpl2vpn (CLI: bgp-l2-vpn) and pim under "service monitoring prometheus
frr-exporter collector", following the same CLI style as the
node-exporter collectors node. The vrrp collector is not exposed since
VyOS implements VRRP with keepalived and FRR's vrrpd is never started.
Also expose the collector options available in v1.5.0:
- collector bgp accept-filtered-prefixes
- collector bgp advertised-prefixes
- collector bgp peer-description <json|plain-text>
- collector bgp peer-group
- collector bgp peer-hostname
- collector bgp peer-type
- collector ospf-instance <id>
- collector detailed-routes
The bgp.* options are shared by the bgp, bgp6 and bgpl2vpn collectors
upstream. The bgp6 collector remains unconditionally enabled, hence
existing configurations render the same ExecStart and no migration is
required.
Includes code generated by Claude Code
|
|
Add 'set firewall group remote-group <name> interval <value>' to
control how often each remote group list is re-downloaded,
independent of the global resolver-interval that also drives
domain-group/FQDN resolution.
The value accepts plain seconds or time-unit suffixes s/m/h/d/w
(e.g. 4h), range 60 seconds to 4 weeks, enforced at commit time
after conversion. When unset, the group keeps following
'firewall global-options resolver-interval', so existing
configurations are unaffected.
vyos-domain-resolver now tracks a last-update timestamp per
remote group and sleeps until the next due update instead of a
fixed resolver-interval tick, honoring per-group intervals both
shorter and longer than the global one. A group is only stamped
as updated after a successful download; failed downloads fall
back to the cached list and are retried at the resolver cadence
rather than after the full group interval.
human_to_seconds() now treats a plain number as seconds instead
of returning 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
qos.py re-invokes this script mid-commit after the interface has
already bound its port, causing the port-availability check to fail
against itself and drop the whole QoS config. This can happen on any
commit that sets or changes the port. Skip the check on that dependent
re-run only.
|
|
vpp: T9018: Auto-enable promiscuous mode for interfaces with VLANs
|
|
The 'ip4-dhcp-client-detect' and 'ip6-icmp-ra-punt' VPP features were only
ever enabled on the base ethernet interface, so DHCP and DHCPv6 clients
never worked on VLAN sub-interfaces (vif/vif-s) of a VPP-managed interface.
Apply the same feature toggles to each vif/vif-s using its own address
configuration. vif-c is intentionally excluded, as Q-in-Q sub-interfaces
are not currently functional under VPP.
|
|
VPP drops VLAN-tagged frames unless the parent interface has promiscuous
mode enabled, causing VLAN sub-interfaces to lose connectivity.
Automatically enable promiscuous mode on VPP interfaces that have VLAN
sub-interfaces (vif/vif-s) configured.
|
|
T9002: grant CAP_NET_RAW to blackbox-exporter when ICMP modules are configured
|
|
Add the new configuration CLI to enable OpenSSL FIPS-140
(Federal Information Processing Standard) cryptographic modules
|
|
The blackbox-exporter runs as node_exporter user which cannot create
ICMP sockets due to restricted ping_group_range. Add CAP_NET_RAW
capability to the systemd service when ICMP modules are configured.
In non-VRF mode, use systemd AmbientCapabilities/CapabilityBoundingSet.
In VRF mode, replace runuser with setpriv to preserve the capability
across the UID change.
|
|
This change re-implements the intended behaviour from T4180 aswell as from
T4506, it ensures that both the vrf-member interface aswell as the vrf itself
is added as an oifname -> meaning that traffic traversing and originating from
withing VyOS is matches outbound.
Changes done by c-po:
* re-sort dependency list to keep diff low
* vyos.configdict.is_vrf_changed() should return early and not carry
over the to-be return value
* keep common coding style (dict by . separation) in nftables-zone.j2
Co-authored-by: Christian Breunig <christian@breunig.cc>
|
|
T8963: policy-route: trigger domain resolver for domain groups
|
|
Authentication protocols are implemented as modules in accel-ppp-ng.
The CLI setting configures which modules need to be loaded, for this
change to take effect pppoe server must be restarted.
|
|
https: T9022: serve the full CA certificate chain
|
|
Reaches a clean typos baseline for the T8490 ruleset pilot. Categories:
- Comments/docs: recursivly, taret, passsed, characted, arhive, AtrributeError;
"ned" -> "new" (migration comments).
- Messages/strings: writeable -> writable (x5); OCaml log "Commandis" -> "Command is".
- Local variables (all refs in-function): commited, formating, presistent;
inpt_range -> input_range; tz_datas -> tz_data_raw (avoids the tz_data collision).
- Self-contained renames (definition + all references in-file): formated_stats,
_get_formatted_output_conections -> ..._connections, expension_failure ->
expansion_failure (ping + traceroute), snmpd_restart_reqired -> ..._required.
False positives are allowlisted centrally (vyos/.github, separate PR), NOT changed
here: mke2fs, Maya-calendar "Mak", RFC 4122 "IDentifier" (hostapd), and VPP's
"U-Forwrd" bridge-domain column header (op_mode/vpp.py + the VPP smoketest assert
the real upstream `vppctl` output). Verified: typos clean, py_compile of every
edited .py, zero remaining old-identifier references.
🤖 Generated by [robots](https://vyos.io)
|
|
When a certificate is assigned to the HTTPS service, nginx was only
sent the leaf certificate. An intermediate CA was included only when
an operator manually configured "ca-certificate", and even then just
that single CA - the rest of the issuer chain was never followed.
As a result, clients that do not already trust the issuing intermediate
CA (for example Let's Encrypt's newer E- and R-series intermediates)
could not build a path to a trusted root and rejected the connection.
Build the complete chain from the CA certificates present in the PKI
using find_chain(), the same helper already used by HAProxy, OpenConnect,
stunnel and the other PKI consumers. The intermediate chain is now
discovered automatically, so configuring "ca-certificate" is no longer
required; it remains accepted for backwards compatibility.
|
|
`advertise-all-vni` is globally active
When `advertise-all-vni` is configured in the global/default BGP instance,
VyOS generated a `vni <id>` sub-block under each VRF BGP `address-family
l2vpn evpn` context. This conflicts with advertise-all-vni: FRR already
owns all kernel VNIs and returns `% Failed to create VNI` when frr-reload.py
attempts to apply the VRF-level vni sub-block. FRR then performs an early
exit from config processing, silently dropping the entire l2vpn evpn
address-family for all subsequent VRF BGP instances.
|
|
T9011: enable proxy_ndp sysctl for static IPv6 neighbor proxy
|
|
bgp: T5526: Fix BGP neighbor validation not raising when interface does not exist
|
|
geoip: T5746: Add GeoIP ASN support
|
|
exist
Validation of interface-based BGP neighbors relied on checking physical
interface existence, which silently skipped the check when interface didn't
exist yet, letting invalid config reach FRR. Fix by checking whether the
neighbor is not an IP address instead, and improve the error messages to
show the correct command.
|
|
|
|
concurrent rekey
The vti-up-down hook and vpn_ipsec.py modify a flat-file DB
(/tmp/ipsec_vti_interfaces) through three context managers that do an
unlocked read-modify-write. During a coordinated rekey, strongSwan fires
the hook for many VTIs concurrently, so the writers lost-update each
other: an interface whose up-client add is overwritten is left admin-down
while its CHILD_SA stays installed.
Serialise all DB access by reusing vyos.utils.locking.Lock. A new
_vti_updown_db_lock() context manager wraps the three public context
managers, and remove_vti_updown_db() holds the lock across both the DB
processing and the os.unlink() to close the create/delete race.
Make the helpers absence-safe under the lock so callers no longer compose
a separate existence check with a locked operation:
open_vti_updown_db_readonly() yields None when the DB does not exist and
remove_vti_updown_db() is a no-op when it is absent. Drop the
now-redundant unlocked vti_updown_db_exists() pre-checks in vti.py and
vpn_ipsec.py and handle the None yield.
|
|
haproxy: T8931: Improve WebSocket support for HAProxy
|
|
vpp: T8913: Skip bond teardown for non-structural config changes
|
|
pseudo-ethernet: T8540: Add anycast-gateway support for EVPN
|