| Age | Commit message (Collapse) | Author |
|
openvpn: T9370: add chacha20poly1305 data cipher
|
|
"show secure-boot" only reported whether Secure Boot is enabled, not who
signed the running Linux Kernel. An image signed by the VyOS CA could not be
told apart from one signed with a custom Machine Owner Key.
"show secure-boot detail" now lists issuer and subject of the Kernel image
signature certificates. The same information is added to the raw
"show version" data as "secure_boot_detail", issuer and subject delimited by
",". The key is only present when Secure Boot is enabled and a signature
could be read.
|
|
Offer chacha20poly1305 in "encryption data-ciphers" and
"encryption data-ciphers-fallback", rendered as CHACHA20-POLY1305 and
allowed with DCO.
|
|
modem_index() in python/vyos/utils/wwan.py derived the ModemManager modem index straight from the interface name (wwan0 -> 0). The kernel-assigned WWAN interface number and ModemManager's own modem index are two independently enumerated values and are not guaranteed to match - on a box with more than one modem, they can enumerate in different orders, so modem index 0 does not necessarily own wwan0. Every function in this module funnels through modem_index() (start_modem_manager, modem_disconnect, modem_connect, and both admin-disconnect marker helpers), and is_wwan_connected() in vyos.utils.network had its own separate copy of the same assumption - so a single reversed enumeration order silently commands the wrong physical modem for every one of them.
modem_index() now lists every modem ModemManager currently knows about and returns whichever one actually has ifname in its own port list, instead of assuming the correspondence. A modem that has not shown up on the bus yet looks the same as one that will never exist, so this waits up to the same modem_wait_timeout budget start_modem_manager() already gives a modem to become dialable, then returns None if nothing claimed the interface. is_wwan_connected() now calls the same resolver instead of keeping its own copy of the old assumption.
None is a real, expected return now, not just a theoretical one - the three callers that previously assumed modem_index() always produced *a* string (right or wrong) are updated: start_modem_manager() bails out early (matching the tolerance its own caller's w.exists() check already has for hardware that isn't detected yet), modem_disconnect() and modem_connect() treat it as nothing to disconnect / a failed dial, matching each function's own existing return contract. show_wwan.py's modem_info() raises a clear, specific error instead, which its own top-level exception handler already reports cleanly. set_admin_disconnected()/clear_admin_disconnected() only ever used modem_index() to validate the interface name looks like a WWAN interface in the first place, so they're unaffected.
|
|
wwan: T9350: possible dead interface after boot, disconnect does not stick
|
|
op-mode: T9354: replace "reset connection" with "reconnect interface"
|
|
create_private_key() took one "size" for every key type, but the number
means entirely different things per type: for RSA and DSA it is a modulus
size, for EC it selects a curve. CodeQL is not path sensitive across the
key_type comparison, so it follows the 256 an EC caller passes into the
RSA and DSA branches that caller can never reach, and reports pki.py as
generating 256 bit RSA and DSA keys.
Build elliptic curve keys in create_ec_private_key() instead and route the
op mode generator and the OpenVPN smoketest there, so no curve size ever
enters the function that also builds RSA and DSA keys.
create_private_key() now refuses a key type it does not build rather than
returning None, so a caller cannot drift back into the old shape
unnoticed.
|
|
firewall: T9205: fix ruff findings in conf_mode/op_mode firewall.py
|
|
A reconnect is usually issued via the very interface being reconnected. Once
the link drops, the calling session dies and the reconnect was killed by
SIGHUP - or by SIGPIPE on the next write to the dead terminal - before the
interface could be dialed again, leaving the system unreachable.
The reconnect now runs in a transient systemd unit and survives the loss of
the session. Progress is logged to the journal.
PPPoE and SSTP restart the ppp service in a single operation instead of
stopping and starting it, so there is no window in which an interrupted
command leaves the link down. WWAN still disconnects the modem before dialing
again.
|
|
cmdl() decodes subprocess output as utf-8 and can raise
UnicodeDecodeError (not an OSError subclass) if that fails, in
addition to OSError on command failure. Catch both, closing a gap
left by the exact-exception narrowing in the previous commit.
|
|
Address copilot-pull-request-reviewer feedback on PR #5398: cmdl()
only raises OSError and json.loads() only raises json.JSONDecodeError
here, so catching bare Exception hid unrelated bugs. Narrowed all four
call sites accordingly (three flagged, one identical pattern found by
inspection).
|
|
Bare except:, extraneous f-string prefixes on ConfigError()/text calls
without placeholders, and 3 unused test locals in test_firewall.py.
No behavior change.
Split out of PR #5374 (T9160) at sever-sever's request: that PR bundled
this cleanup with the apply-path feature because it happened to touch
the same files, but it isn't related to apply-path itself.
|
|
show_wwan.py drove qmicli against /dev/cdc-wdmN, which assumes the modem
exposes a QMI control port. An MBIM modem does not, so every subcommand of
"show interfaces wwan wwanN" failed on one - after waiting out a five second
transaction timeout, twice over for "signal":
$ show interfaces wwan wwan0 signal
Command not supported by Modem (10.6s)
$ qmicli --device=/dev/cdc-wdm0 --device-open-proxy --nas-get-signal-info
error: couldn't create client for the 'nas' service: CID allocation failed
in the CTL client: Transaction timed out
ports: cdc-wdm0 (mbim), ttyUSB0 (at), wwan0 (net)
ModemManager has already probed the modem and speaks whichever protocol it
exposes - QMI, MBIM or plain AT. It is a hard dependency of "interfaces wwan"
anyway, as conf_mode cannot dial without it, and it answers from its own cache
over D-Bus without touching the device:
$ show interfaces wwan wwan0 signal
Access technology: lte (0.2s)
Signal quality: 58%
Operator: Telekom.de
Registration: home
Packet service: attached
State: connected
|
|
Two things kept an operator disconnect from taking effect.
vyos-netlinkd re-dials every configured WWAN interface that has lost its
session. It cannot tell a session lost to RF signal loss from one that was
taken down on purpose, so the disconnect was undone on the next reconcile
pass, at most 30 seconds later:
$ disconnect interface wwan0
08:53:33 t+10s state=registered
08:53:43 t+20s state=registered
08:53:53 t+30s state=connected <- re-dialled
08:54:03 t+40s state=connected
vyos-netlinkd: WWAN interface wwan0 is not connected, re-dialling...
vyos-netlinkd: Re-dialled WWAN interface wwan0
Record the intent instead of inferring it from the session state. op-mode
"disconnect" drops a marker in /run/vyos-wwan, which _reconcile_wwan() honours
and "connect" removes again. conf_mode removes it too, so a commit keeps
re-asserting the configured state - the marker only survives for as long as
nobody says otherwise, and never across a reboot.
|
|
The '?' key is a raw readline binding (possible-completions), so a
literal question mark can never be typed into a value: readline
intercepts the keystroke before bash parsing begins and quoting cannot
protect it. Values like remote-group URLs with query strings get
silently corrupted ('.../blacklist?key=x' is stored as
'.../blacklistkey=x') with no error at any stage.
Rebind '?' to a bind -x handler that scans the line left of the cursor
for an open single/double quote or a pending backslash escape. Inside a
quote or escape the key self-inserts; otherwise it triggers the
standard help via a DSR round-trip (printf '\e[5n' with the terminal's
reply ESC [ 0 n bound to possible-completions), keeping the help path
and output identical to the previous behavior.
'set terminal key query-help enable' now restores the quote-aware
handler instead of the raw binding; 'disable' keeps its existing
self-insert override, which takes precedence at login as before.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
The archive tars /run recursively, and tarfile.add() crosses filesystems. The
retired fork mounted the boot medium and the persistence partition below /live,
so this was harmless. Debian's live-boot mounts them
below /run/live/{medium,persistence,rootfs,overlay}, so the archive now
recurses into the whole system disk, fills the staging directory and fails all
four smoketests with
Unable to read `/run` to archive files: [Errno 28] No space left on device
Introduced by vyos-build commit c598316aa436 ("live-boot: T5475: replace the
forked live-boot package with Debian's").
Prune nested mount points rather than blacklist one live-boot layout: they are
read once from /proc/self/mountinfo, which covers Debian's, upstream's and the
fork's paths alike, plus bind mounts os.path.ismount() cannot see. The archive
root stays exempt, only directories are pruned and /etc/cni/net.d is kept, so
daemon configuration in /run is still archived.
ENOSPC now deletes the partial tarball and aborts.
|
|
image_installer.py was using data from untrusted source to pass
to shell without escaping in case VRF was activated.
Change to list in call to `cmd` to fix this, remove extra code for VRF
wrappers to library parameters.
|
|
A container has no hardware of its own - vendor, model, serial and UUID are
read from /sys/class/dmi/id and thus describe the host system. Listing them
below "System type: container" reads as a property of the node.
Leave the hardware_* keys unset when running as a container and omit the
entire block in both "show version" and the airbag bug report. The latter
moves the fields into an optional HARDWARE section, as str.format() has no
conditionals.
|
|
A container is not booted by any firmware, so neither the UEFI nor the BIOS
wording applies. Worse, is_uefi_system() probes /sys/firmware/efi which a
container inherits from its host, thus a container on a UEFI host reported
the Secure Boot state of that host.
Check is_running_as_container() first and report "n/a (container)", leaving
the UEFI and BIOS detection untouched for everything else.
|
|
nat: T9162: fix KeyError when show nat rules has no inbound-interface
|
|
- Replaced direct file reads from `/proc/cmdline` with `get_kernel_boot_arg()`
for fetching kernel command-line arguments in multiple modules.
- Improved memory information retrieval by utilizing `get_memory_info()`.
|
|
Add new CLI subtree 'system option kdump' with memory reservation and
local dump path configuration. Also add 'show system kdump' and
'show system kdump dumps' operation mode commands to get
status of the configuration and list of dumps.
Extend 'show tech-support report' and 'generate tech-support archive' with
kdump service status, active config files and the recently kernel dump file.
|
|
ddclient: T6981: Upgrade ddclient to v4.0.0
|
|
pki: T9135: derive ACME certificate chains from disk
|
|
firewall: T8221: Add last-used option to firewall rules
|
|
"show pki ca/certificate <name>" only ever offered PEM output, which isn't
practical for a human to actually read. Add a "text" form that runs the
certificate through OpenSSL's own "-text" formatter, the same human-readable
breakdown "openssl x509 -text" produces.
|
|
The local-file branch of CA certificate import recognized a file:// URL
by scheme but never actually decoded it - os.path.exists()/open() still
received the full "file://..." string rather than the path component, so
an explicit file:// URL always failed with "File not found" even when it
pointed at a real, readable file.
|
|
certbot's chain.pem commonly holds more than one certificate - e.g. the
immediate intermediate plus its own issuing root - but the synthetic CA
entry built from it only ever kept the first, silently dropping the rest
before find_chain() ever saw them. This left a shorter chain than certbot
itself actually has, e.g. requiring a root to also be configured manually
to reach the same result certbot's own data already provides.
Parse every certificate block in chain.pem and emit one synthetic entry
per certificate, numbering entries after the first so each is still its
own addressable, non-redundant, non-settable object exactly like before.
|
|
Both the with_pki=True chain injection and "show pki ca" unconditionally read
a certificate's own content to check whether an explicit CA already covers its
chain. For an ACME certificate with no cert.pem yet (pending its first issuance,
or after a failed request), that content is never populated and the lookup
raised KeyError - crashing every with_pki=True consumer and "show pki" alike.
|
|
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.
|
|
The path argument to the CA import command now also accepts a remote URL
(http, https, ftp, sftp, scp, tftp, ...), detected by scheme, in addition to
a local file path. Makes it convenient to pull a well-known public intermediate
directly by URL instead of downloading and pasting PEM content by hand.
|
|
Pre-existing dead extractions in _get_formatted_output_statistics(),
never used in the assembled row or headers. Whole-file ruff check
blocks CI on any PR touching this file, including this one.
|
|
CodeRabbit's DRY refactor (072404da6) only matched iifname, causing
source NAT rules with an outbound-interface to regress to displaying
'any' instead of the configured interface. Also guard against missing
'rule'/'expr' keys.
|
|
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.
|
|
_get_formatted_output_rules() and _get_formatted_output_statistics()
contained an identical block searching rule['rule']['expr'] for the
iifname match and stripping the '@I_' set-name prefix. Extract it into
a shared _get_interface(rule) helper so future fixes only need to land
in one place.
Addresses CodeRabbit nitpick on PR #5375.
|
|
_get_formatted_output_rules() and _get_formatted_output_statistics()
detected an interface match by checking whether *any* expr in the rule
has a left.meta field, then unconditionally read expr[0]'s match.right
as the interface. Both assumptions are wrong: meta is also used for
non-interface matches (e.g. meta l4proto from a protocol match), and
the interface match is not guaranteed to be first. For a rule with a
protocol match but no inbound-interface, this read the address/port
match's right-hand side (a dict) as if it were the interface string,
raising KeyError: 0 on interface[0] instead of falling back to 'any'.
Search expr entries explicitly for a left.meta.key == 'iifname' match
instead, and guard the '@' set-name stripping with a type check.
|
|
- Add last-used option to firewall rules
- Updated output of show firewall to include last-used
- Added smoketest for last-used option
|
|
In ddclient v4, the 'ip' and 'status' fields are
no longer supported. They were used to store IPv4
addresses and their statuses in a backward compatible
way in ddclient v3.
|
|
This fixes just the case for the Bash project added via commit b12a8c5ae
("image: T9021: Save bash history during image upgrade")
|
|
Previously, bash history was silently lost on every image upgrade,
forcing operators to start with an empty history each time.
Extend the image upgrade script to detect and migrate bash history
files from the currently running image to the newly installed one.
|
|
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.
|
|
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)
|
|
Re-apply QoS after dynamic interfaces get addresses after connect/disconnect.
When PPPoE interfaces re-connect we need to re-do QoS settings.
|
|
dhcp: T8941: Support filter and sorting combination on DHCPv4/v6 server lease entries in op mode
|
|
|
|
|
|
|
|
Replace two-word "can not" / "Can not" with "cannot" across comments,
ConfigError messages, CLI help text, and op-mode output.
Standard SNMP MIB files under mibs/ are left unchanged.
|
|
pki: T8165: Add ability to show certificate full chain in pem format
|
|
|