Skip to content

CP-310090 Stunnel lib: Expose unix socket path for TLS proxy#6886

Merged
changlei-li merged 4 commits intoxapi-project:feature/trusted-certsfrom
changlei-li:private/changleli/check-cert
Feb 10, 2026
Merged

CP-310090 Stunnel lib: Expose unix socket path for TLS proxy#6886
changlei-li merged 4 commits intoxapi-project:feature/trusted-certsfrom
changlei-li:private/changleli/check-cert

Conversation

@changlei-li
Copy link
Copy Markdown
Contributor

Add a module UnixSocketProxy in stunnel lib to provide a unix socket
path that can proxy TLS. This can offer a unified mechanism for
differnt users.
Stunnel listens on the unix socket path, accepts the connection
from local request then forwards to remote host and port with TLS.
The certificate checking in TLS connection can be done by stunnel
with the new trusted-certs implementation.
Two set of APIs are provided:

  1. long-running stunnel proxy for that the user want to use it
    multi-times and handle the proxy lifecycle itself.
let stunnel_proxy =
  Stunnel.UnixSocketProxy.start ~verify_cert ~remote_host ~remote_port ()
in
match stunnel_proxy with
| Error e -> (* handle error *)
| Ok proxy_handle ->
    let socket_path = Stunnel.UnixSocketProxy.socket_path proxy_handle in
    (* use socket_path with HTTP clients *)
    ...
    Stunnel.UnixSocketProxy.diagnose proxy_handle |> function
    | Ok () -> (* all good *)
    | Error err -> (* handle connection errors *)
    ...
    Stunnel.UnixSocketProxy.stop proxy_handle (* clean up when done *)
  1. short-lived stunnel proxy for that the user just want to use
    one-shot with auto cleanup.
Stunnel.UnixSocketProxy.with_proxy ~verify_cert ~remote_host ~remote_port
  (fun proxy_handle ->
    let socket_path = Stunnel.UnixSocketProxy.socket_path proxy_handle in
    (* use socket_path with HTTP clients *)
    ...
    Stunnel.UnixSocketProxy.diagnose proxy_handle)
    ...
  )

Comment thread ocaml/libs/stunnel/stunnel.mli
Comment thread ocaml/libs/stunnel/stunnel_log_scanner.ml Outdated
Comment thread ocaml/libs/stunnel/stunnel.ml Outdated
Comment thread ocaml/libs/stunnel/stunnel_log_scanner.ml Outdated
Comment thread ocaml/libs/stunnel/stunnel_log_scanner.ml Outdated
Comment thread ocaml/libs/stunnel/stunnel_log_scanner.ml Outdated
@changlei-li changlei-li force-pushed the private/changleli/check-cert branch from f20f9e1 to d85a6fb Compare February 9, 2026 06:53
Copy link
Copy Markdown
Member

@psafont psafont left a comment

Choose a reason for hiding this comment

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

Xapi already has a system to manage stunnel instances, and it's placed in ocaml/libs/stunnel/stunnel_cache.ml. This is done to limit the amount of stunnel instances running and therefore the amount of memory used by them. I think having a module that allows creating instances without controlling this can lead to memory exhaustion and other issues.

I think the proxy module should be redone.

I think having better errors is something that needed very much, so thanks for enhancing that, but I'm afraid I have to ask for changes regarding the handling of stunnel instances

@changlei-li
Copy link
Copy Markdown
Contributor Author

Xapi already has a system to manage stunnel instances, and it's placed in ocaml/libs/stunnel/stunnel_cache.ml. This is done to limit the amount of stunnel instances running and therefore the amount of memory used by them. I think having a module that allows creating instances without controlling this can lead to memory exhaustion and other issues.

I think the proxy module should be redone.

I think having better errors is something that needed very much, so thanks for enhancing that, but I'm afraid I have to ask for changes regarding the handling of stunnel instances

Hi @psafont. The background is to use unix socket path file to support licensing as we have cpp/python code to communicate with license server. So the exposing the unix socket path with a stunnel instance is a unified mechanism for this case (and also the trusted certs you are reviewing rencently). This is not for xapi to use.
In my view, stunnel_cache is a different level to manage reuse and limit the stunnel instances. While this PR just add the proxy by unix socket path. It should be compared to Stunnel.with_connect, Stunnel.with_client_proxy_systemd_service.
In the licensing case, we just use one long running stunnel instance, so no need to compare to stunnel_cache.

@psafont
Copy link
Copy Markdown
Member

psafont commented Feb 9, 2026

So, if I understood correctly, the stunnel proxy module is meant to be used from a different process from the xapi one. which means the cache can't be shared.

Can the process use directly the code in the module, or does it need some kind of RPC to access this functionality? I'm asking this because you mentioned it's C++ and python code that do the connections

@changlei-li
Copy link
Copy Markdown
Contributor Author

changlei-li commented Feb 9, 2026

So, if I understood correctly, the stunnel proxy module is meant to be used from a different process from the xapi one. which means the cache can't be shared.

Can the process use directly the code in the module, or does it need some kind of RPC to access this functionality? I'm asking this because you mentioned it's C++ and python code that do the connections

Please be aware this is just the stunnel lib, although it is in xapi repo. Briefly says, component(OCaml) will use the code directly to create stunnel instance with proper certificates. The stunnel will listen on the unix socket, then other code(non OCaml) can communicate with the unix socket path. Stunnel will proxy it to remote tls host.

Comment thread ocaml/libs/stunnel/stunnel.mli
Comment thread ocaml/libs/stunnel/stunnel_client.ml Outdated
Comment thread ocaml/libs/stunnel/stunnel.ml Outdated
Comment thread ocaml/libs/stunnel/test/test_stunnel_log_scanner.ml
@changlei-li changlei-li force-pushed the private/changleli/check-cert branch from d85a6fb to 54d478d Compare February 9, 2026 10:36
Add a module UnixSocketProxy in stunnel lib to provide a unix socket
path that can proxy TLS. This can offer a unified mechanism for
differnt users.
Stunnel listens on the unix socket path, accepts the connection
from local request then forwards to remote host and port with TLS.
The certificate checking in TLS connection can be done by stunnel
with the new trusted-certs implementation.
Two set of APIs are provided:
1. long-running stunnel proxy for that the user want to use it
   multi-times and handle the proxy lifecycle itself.
```OCaml
let stunnel_proxy =
  Stunnel.UnixSocketProxy.start ~verify_cert ~remote_host ~remote_port ()
in
match stunnel_proxy with
| Error e -> (* handle error *)
| Ok proxy_handle ->
    let socket_path = Stunnel.UnixSocketProxy.socket_path proxy_handle in
    (* use socket_path with HTTP clients *)
    ...
    Stunnel.UnixSocketProxy.diagnose proxy_handle |> function
    | Ok () -> (* all good *)
    | Error err -> (* handle connection errors *)
    ...
    Stunnel.UnixSocketProxy.stop proxy_handle (* clean up when done *)
```
2. short-lived stunnel proxy for that the user just want to use
   one-shot with auto cleanup.
```OCaml
Stunnel.UnixSocketProxy.with_proxy ~verify_cert ~remote_host ~remote_port
  (fun proxy_handle ->
    let socket_path = Stunnel.UnixSocketProxy.socket_path proxy_handle in
    (* use socket_path with HTTP clients *)
    ...
    Stunnel.UnixSocketProxy.diagnose proxy_handle)
    ...
  )
```

Signed-off-by: Changlei Li <changlei.li@cloud.com>
Currently, the verify_error relies on "certificate verify failed"
and "No certificate or private key specified" in the stunnel log
file.
In fact, "No certificate or private key specified" is a normal
log for stunnel_proxy. It happens on stunnel configuration
fail with verbose log enabled. We can remove it and it is covered
by "Configuration failed".
For "certificate verify failed", it is a indicator for certificate
verify fail, but the detail reasons is in previous lines like
"CERT: Pre-verification error: unable to get local issuer certificate"
"CERT: Subject checks failed". So the "CERT: " line is collected,
if "certificate verify failed" is found, the details can be raised
out as reason.

Signed-off-by: Changlei Li <changlei.li@cloud.com>
In long time running proxy, every time to call diagnose
need to read entire the stunnel log. It is inficient.
Store the input channel of log file in the proxy t, then
the diagnose can read the log from position after the last
it is called.

Signed-off-by: Changlei Li <changlei.li@cloud.com>
Signed-off-by: Changlei Li <changlei.li@cloud.com>
@changlei-li changlei-li force-pushed the private/changleli/check-cert branch from 54d478d to f9abe00 Compare February 10, 2026 03:36
@changlei-li
Copy link
Copy Markdown
Contributor Author

Rebase to lastest feature/trusted-certs and squash the commits

Comment thread ocaml/libs/stunnel/stunnel_client.ml
@changlei-li changlei-li merged commit 7fd25d7 into xapi-project:feature/trusted-certs Feb 10, 2026
16 checks passed
@changlei-li changlei-li deleted the private/changleli/check-cert branch February 10, 2026 06:47
minglumlu added a commit that referenced this pull request Mar 6, 2026
Backport changes in a master-based feature branch to a LCM-based new
feature branch. This aims to test the feature thoroughly on the LCM
branch as well.

The original commits are referenced in individual cherry-picked commit
messages.
The original PRs are:
#6863 (2 commits in it, 1 of
them has been back ported separately)
#6826
#6925
#6886
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants