-
Notifications
You must be signed in to change notification settings - Fork 295
CP-310090 Stunnel lib: Expose unix socket path for TLS proxy #6886
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/trusted-certs
Are you sure you want to change the base?
Changes from all commits
35234e9
6a3092c
be835ef
3d0c261
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -99,3 +99,79 @@ val with_client_proxy_systemd_service : | |
| -> service:string | ||
| -> (unit -> 'a) | ||
| -> 'a | ||
|
|
||
| module UnixSocketProxy : sig | ||
| (** Handle for a long-running stunnel proxy that exposes TLS connection | ||
| via a UNIX socket file. *) | ||
| type t | ||
|
|
||
| val socket_path : t -> string | ||
| (** Get the UNIX socket file path for connecting to the proxy. | ||
| Use this path with HTTP clients (curl, urllib, etc.) to send traffic | ||
| through the TLS tunnel. *) | ||
|
|
||
| val start : | ||
| verify_cert:verification_config option | ||
| -> remote_host:string | ||
| -> remote_port:int | ||
| -> ?unix_socket_path:string | ||
| -> ?socket_mode:int | ||
| -> unit | ||
| -> (t, Stunnel_error.t) result | ||
| (** Start a long-running stunnel proxy listening on a UNIX socket. | ||
| Returns [Ok handle] if stunnel starts successfully. The handle MUST be | ||
| stopped with [stop] when no longer needed. | ||
| Returns [Error] if stunnel fails to start, initialize. | ||
| If [unix_socket_path] is not provided, a unique path will be generated | ||
| automatically in /tmp with the format: | ||
| stunnel-proxy-{host}-{port}-{uuid}.sock | ||
| If [socket_mode] is provided (e.g., [~socket_mode:0o666]), the socket | ||
| file permissions will be set accordingly after creation using chmod. | ||
|
|
||
| Use example: | ||
| 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 *) | ||
| *) | ||
|
|
||
| val stop : t -> unit | ||
| (** Stop a running stunnel proxy and clean up resources. | ||
| This kills the stunnel process and removes the socket and log files. *) | ||
|
|
||
| val diagnose : t -> (unit, Stunnel_error.t) result | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this an expensive operation that exists mostly for debugging? It seem unusual what we rely on a log file. If this operation should be used sparingly, it would be good to mention thus,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the shortcoming to use stunnel. Although stunnel is a reliable tool to proxy TLS, it's hard to get the error like the native ssl lib. There is no programmatic API or formatted error code in stunnel. While replacing stunnel in our repo is really a big project. So it is the only way for us to get certificate checking error via stunnel log. |
||
| (** Diagnose the status of a running stunnel proxy by checking its logfile. | ||
| Only checks NEW log entries since the last call to [diagnose] (or since | ||
| [start] if never called). This allows efficient monitoring of connection | ||
| failures that occur after the initial certificate verification. | ||
| Returns [Ok ()] if no new errors found, [Error] with details otherwise. *) | ||
|
|
||
| val with_proxy : | ||
| verify_cert:verification_config option | ||
| -> remote_host:string | ||
| -> remote_port:int | ||
| -> ?unix_socket_path:string | ||
| -> ?socket_mode:int | ||
| -> (t -> ('a, Stunnel_error.t) result) | ||
| -> ('a, Stunnel_error.t) result | ||
| (** Start a proxy, execute a function with it, and automatically stop it. | ||
| The proxy is guaranteed to be stopped even if the function raises an exception. | ||
| If [unix_socket_path] is not provided, a unique path will be generated. | ||
| If [socket_mode] is provided, stunnel will set the socket file permissions. | ||
| This is the preferred way for short-lived proxies. *) | ||
| end | ||
|
|
||
| val fetch_server_cert : remote_host:string -> remote_port:int -> string option | ||
| (** Fetch the server certificate from a remote host. | ||
| Uses openssl s_client to connect and retrieve the certificate in PEM format. | ||
| This is useful for TOFU (Trust-On-First-Use) scenarios. *) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
in_channelremembers the position already. Could theicbe used here directly, instead of using a integer for the position and re-open the log file at each time of checking the log?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. Let me try.