<feed xmlns='http://www.w3.org/2005/Atom'>
<title>vyos-1x.git/src/op_mode, branch fix/T8955-http-api-verify-tls</title>
<subtitle>VyOS command definitions, scripts, and utilities (mirror of https://github.com/vyos/vyos-1x.git)
</subtitle>
<id>https://git.amelek.net/vyos/vyos-1x.git/atom?h=fix%2FT8955-http-api-verify-tls</id>
<link rel='self' href='https://git.amelek.net/vyos/vyos-1x.git/atom?h=fix%2FT8955-http-api-verify-tls'/>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/'/>
<updated>2026-10-04T09:46:17+00:00</updated>
<entry>
<title>http-api-client: T8955: leave warning handling to the caller</title>
<updated>2026-10-04T09:46:17+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@vyos.io</email>
</author>
<published>2026-10-04T09:46:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/commit/?id=69160aae61b3dc00a31d5980919d665e02f4c417'/>
<id>urn:sha1:69160aae61b3dc00a31d5980919d665e02f4c417</id>
<content type='text'>
Address the round-2 adversarial-review finding: warnings.catch_warnings()
mutates the process-global filter list for the duration of the block (still
the case on Python 3.13), so scoping suppression inside the library was not
actually isolated.

- http_api_client no longer touches warning filters at all. The
  _suppress_insecure_warning helper is removed and post() calls
  session.post directly again. The unused warnings, contextmanager and
  urllib3 imports are dropped. The class docstring now states that callers
  disabling verification own InsecureRequestWarning handling. The OSError
  wrapping and verify_tls validation are unchanged.
- config_sync ignores InsecureRequestWarning in its __main__ block only,
  before opmode.run(). That one-shot op-mode process deliberately connects
  without verification (verify_tls=False) until T9396. Importing the module
  adds no filter.

🤖 Generated by [robots](https://vyos.io)
</content>
</entry>
<entry>
<title>http-api-client: T8955: harden verify_tls handling</title>
<updated>2026-10-04T09:29:31+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@vyos.io</email>
</author>
<published>2026-10-04T09:29:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/commit/?id=7f7c730cb415f6b1b22abe5788a10e02c50778ad'/>
<id>urn:sha1:7f7c730cb415f6b1b22abe5788a10e02c50778ad</id>
<content type='text'>
Address the adversarial-review findings on the TLS verification change:

- Finding 1: validate ApiClientConfig.verify_tls in __post_init__. Only a
  bool or a non-empty CA bundle path is accepted; anything else (including
  "", None and ints) raises ValueError. requests treats "" as falsy and
  would silently disable verification. Strings are never coerced: "false"
  is a path, so callers must pass a real bool.
- Finding 2: stop calling urllib3.disable_warnings() process-wide from
  ApiClient.__init__. InsecureRequestWarning is now ignored only around the
  request itself, via warnings.catch_warnings(), and only when verify_tls
  is False. post() is the only request path in the client.
- Finding 3: wrap OSError (raised by requests' cert_verify for a missing
  CA bundle path) in ApiTransportError. The handler sits after the
  RequestException handlers, since those subclass OSError.
- Finding 4: config-sync hard-codes verify_tls = False instead of reading
  an unmapped 'verify_tls' key from the runtime config, whose leaf values
  are strings. Mapping a CLI option to a bool or CA path is T9396.

🤖 Generated by [robots](https://vyos.io)
</content>
</entry>
<entry>
<title>http-api-client: T8955: enable TLS verification by default</title>
<updated>2026-10-04T09:13:18+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@vyos.io</email>
</author>
<published>2026-06-02T14:49:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/commit/?id=bc1a054e14eaabd17326d63fa99c19c0a867130d'/>
<id>urn:sha1:bc1a054e14eaabd17326d63fa99c19c0a867130d</id>
<content type='text'>
ApiClientConfig.verify_tls defaulted to False and ApiClient unconditionally
silenced urllib3's InsecureRequestWarning, so TLS peer verification was off by
default. The sole consumer, src/op_mode/config_sync.py, builds the client
without passing verify_tls and therefore connected to a *remote* secondary VyOS
node over HTTPS without verifying the certificate -- a MITM exposure on the
channel that carries the API key and the full configuration.

- ApiClientConfig.verify_tls now defaults to True and accepts bool | str;
  a string is forwarded to requests as a CA bundle path (verify=&lt;path&gt;).
- InsecureRequestWarning is suppressed only when verification is explicitly
  disabled (verify_tls is False), not when a CA path or True is set.
- config_sync reads an optional verify_tls from the secondary runtime settings,
  defaulting to False to preserve current behaviour for self-signed secondaries.
  The insecurity is now explicit at the call site instead of hidden in the
  library default. Exposing a CA certificate (PKI reference) and peer
  fingerprint pinning under service config-sync secondary is follow-up T9396.

🤖 Generated by [robots](https://vyos.io)
</content>
</entry>
<entry>
<title>wwan: T7487: identify modem by port ownership, not interface number</title>
<updated>2026-09-29T13:41:40+00:00</updated>
<author>
<name>Adam Smith</name>
<email>adamsmith@yzguy.io</email>
</author>
<published>2026-09-29T13:41:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/commit/?id=a272bffcf16c6c5ced83fb19a35aa3c78bbf7bff'/>
<id>urn:sha1:a272bffcf16c6c5ced83fb19a35aa3c78bbf7bff</id>
<content type='text'>
modem_index() in python/vyos/utils/wwan.py derived the ModemManager modem index straight from the interface name (wwan0 -&gt; 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.
</content>
</entry>
<entry>
<title>Merge pull request #5499 from c-po/wwan-improvements</title>
<updated>2026-09-29T04:42:46+00:00</updated>
<author>
<name>Christian Breunig</name>
<email>christian@breunig.cc</email>
</author>
<published>2026-09-29T04:42:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/commit/?id=4f2ac698227c3c4970a3b21d5e4d540f9fb24c80'/>
<id>urn:sha1:4f2ac698227c3c4970a3b21d5e4d540f9fb24c80</id>
<content type='text'>
wwan: T9350: possible dead interface after boot, disconnect does not stick</content>
</entry>
<entry>
<title>Merge pull request #5503 from c-po/T9354</title>
<updated>2026-09-28T19:18:12+00:00</updated>
<author>
<name>Christian Breunig</name>
<email>christian@breunig.cc</email>
</author>
<published>2026-09-28T19:18:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/commit/?id=504c97e7c661de8ea771a8daa7a3c7d6c8e5d86b'/>
<id>urn:sha1:504c97e7c661de8ea771a8daa7a3c7d6c8e5d86b</id>
<content type='text'>
op-mode: T9354: replace "reset connection" with "reconnect interface"</content>
</entry>
<entry>
<title>pki: T9323: give elliptic curve keys their own constructor</title>
<updated>2026-09-27T18:02:14+00:00</updated>
<author>
<name>Antonio Quartulli</name>
<email>antonio@mandelbit.com</email>
</author>
<published>2026-09-15T09:15:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/commit/?id=609b8d4d8008729af2478029b8e25ae4359ad56b'/>
<id>urn:sha1:609b8d4d8008729af2478029b8e25ae4359ad56b</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>Merge pull request #5398 from ruben-herold/T9205-firewall-ruff-cleanup</title>
<updated>2026-09-26T20:06:34+00:00</updated>
<author>
<name>Christian Breunig</name>
<email>christian@breunig.cc</email>
</author>
<published>2026-09-26T20:06:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/commit/?id=ecd3a01a9563f77d9d9e5a9ef5d9b1b9aacc2fda'/>
<id>urn:sha1:ecd3a01a9563f77d9d9e5a9ef5d9b1b9aacc2fda</id>
<content type='text'>
firewall: T9205: fix ruff findings in conf_mode/op_mode firewall.py</content>
</entry>
<entry>
<title>op-mode: T9354: run interface reconnect detached from calling session</title>
<updated>2026-09-25T19:02:00+00:00</updated>
<author>
<name>Christian Breunig</name>
<email>christian@breunig.cc</email>
</author>
<published>2026-09-25T19:02:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/commit/?id=ce4f4c98f13dc039875bd23c51e081a5381917e0'/>
<id>urn:sha1:ce4f4c98f13dc039875bd23c51e081a5381917e0</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>firewall: T9205: also catch UnicodeDecodeError from cmdl() output</title>
<updated>2026-09-25T18:53:02+00:00</updated>
<author>
<name>Ruben Herold</name>
<email>ruben@puettmann.net</email>
</author>
<published>2026-08-13T12:57:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-1x.git/commit/?id=de934a295f177428969b95474aff717d95f02401'/>
<id>urn:sha1:de934a295f177428969b95474aff717d95f02401</id>
<content type='text'>
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.
</content>
</entry>
</feed>
