[CLI] Require explicit CA for remote Python REST connections - #166
Conversation
Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>
Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
| headers=req_headers, | ||
| data=body, | ||
| params=query, | ||
| verify=verify) |
There was a problem hiding this comment.
The fix correctly moves away from verify=False for remote endpoints, but using verify=True
relies on whatever CA certificates happen to be present in the container's system store.
For a managed SONiC deployment this is fragile — the container may not carry the right
enterprise CA, and there's no explicit operator control over which CA is trusted.
Suggest adding a --rest-ca-cert CLI option (or a counterpart in the existing REST
client config) that accepts a PEM-format CA file, and using that path as the verify=
argument for remote requests:
verify = ca_cert_path if not _is_loopback_endpoint(url) else False
where ca_cert_path is the value of --rest-ca-cert. If a remote endpoint is configured
and no --rest-ca-cert is supplied, the client should fail with a clear error rather than
falling back to the system store.
This gives operators an explicit, visible CA provisioning step instead of implicit
system-bundle trust.
There was a problem hiding this comment.
@qiluo-msft Thanks. After looking further, I agree that falling back to the general system trust store does not provide REST-specific control over the trusted CA.
I propose splitting the work into focused changes. In this PR, I will update the Python actioner client to require an explicitly configured CA file for non-loopback REST_API_ROOT values, without falling back to the system trust store.
The CLI also has a C++ libcurl REST client used for authentication and token refresh. I will submit a follow-up PR applying the same explicit-CA behavior there. The operator-facing --rest-ca-cert option, including host-to-container certificate provisioning, can then be added separately in sonic-buildimage.
Would this staged approach work for you?
There was a problem hiding this comment.
Updated in f0e11c8. The Python actioner now requires REST_API_CA_CERT for non-loopback endpoints and passes that PEM path directly to Requests. It does not fall back to REQUESTS_CA_BUNDLE or the system CA store, and missing or unreadable configuration returns a clear error before making the request.
I added focused unit coverage and repeated the VS validation. The configured explicit CA succeeded, while the Requests bundle fallback and an invalid explicit path were rejected. The C++ client and operator-facing CLI plumbing remain scoped to the follow-up changes described above.
Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Why The C++ klish REST client may connect to either the default local REST server or a configured remote HTTPS endpoint. Remote connections should use a CA certificate selected specifically for that REST server while preserving the existing local workflow. What Require REST_API_CA_CERT to identify a readable CA certificate file for every non-loopback HTTPS REST endpoint. Configure libcurl to verify the peer certificate and hostname using the selected CA file without falling back to its compiled-in CA directory. Preserve the current behavior for localhost, IPv4 loopback addresses (127.0.0.0/8), and IPv6 loopback (::1). Report a clear initialization error when the required CA configuration is missing or invalid. Add focused coverage for accepted and rejected endpoint classification and CA path validation. This is the C++ client counterpart to #166. Operator-facing CLI configuration can be added separately. How to verify Run tools/test/rest-tls.sh to verify: localhost, IPv4 127.0.0.0/8, IPv6 ::1, and IPv4-mapped 127.0.0.0/8 endpoints are recognized as loopback. Remote, misleading, and malformed endpoint names are not recognized as loopback. Readable CA files are accepted, while missing paths, empty paths, and directories are rejected. All tests passed.
Why
The Python CLI actioner may connect to either the default local REST server or a configured remote endpoint. Remote connections should use a CA certificate selected specifically for that REST server while preserving the existing local workflow.
What
REST_API_CA_CERTto identify a readable PEM CA certificate file for every non-loopback REST endpoint.localhost, IPv4 loopback addresses (127.0.0.0/8), and IPv6 loopback (::1).How to verify
python3 -m unittest discover -s CLI/tests -p 'test_*.py' -v— 7 tests passed.python3 -m py_compile CLI/actioner/cli_client.py CLI/tests/test_cli_client.pygit diff --check origin/master...HEADVS validation on
vlab-01:target/debs/trixie/sonic-mgmt-framework_1.0-01_amd64.deband installed it in themgmt-frameworkcontainer.REQUESTS_CA_BUNDLEdid not provide a fallback for a remote endpoint.REST_API_CA_CERTwas rejected before the request.REST_API_CA_CERTwith the test endpoint's CA and confirmed that the request succeeded.Results: