Skip to content
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

support HTTPS/TLS. #946

Merged
merged 9 commits into from
Nov 6, 2023
Merged

support HTTPS/TLS. #946

merged 9 commits into from
Nov 6, 2023

Conversation

ethanschen
Copy link
Contributor

@ethanschen ethanschen commented Jul 23, 2023

#930

HTTP

Demo

from prometheus_client import start_http_server

start_http_server(8000)

while True:
    pass

Curl HTTPS Request

curl -k https://127.0.0.1:8000

Response

curl: (35) LibreSSL/3.3.6: error:1404B42E:SSL routines:ST_CONNECT:tlsv1 alert protocol version

Support HTTPS/TLS

Demo

from prometheus_client import start_http_server

start_http_server(8000, certfile="server.crt", keyfile="server.key")

while True:
    pass

Generate server cert and server key.

openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -signkey server.key -out server.crt

Curl HTTPS Request

curl -k https://127.0.0.1:8000

Response

# HELP python_gc_objects_collected_total Objects collected during gc
# TYPE python_gc_objects_collected_total counter
python_gc_objects_collected_total{generation="0"} 618.0
python_gc_objects_collected_total{generation="1"} 5.0
python_gc_objects_collected_total{generation="2"} 0.0
# HELP python_gc_objects_uncollectable_total Uncollectable objects found during GC
# TYPE python_gc_objects_uncollectable_total counter
python_gc_objects_uncollectable_total{generation="0"} 0.0
python_gc_objects_uncollectable_total{generation="1"} 0.0
python_gc_objects_uncollectable_total{generation="2"} 0.0
# HELP python_gc_collections_total Number of times this generation was collected
# TYPE python_gc_collections_total counter
python_gc_collections_total{generation="0"} 39.0
python_gc_collections_total{generation="1"} 3.0
python_gc_collections_total{generation="2"} 0.0
# HELP python_info Python platform information
# TYPE python_info gauge
python_info{implementation="CPython",major="3",minor="11",patchlevel="5",version="3.11.5"} 1.0

Enabled mTLS

Demo

from prometheus_client import start_http_server

start_http_server(8000, certfile="server.crt", keyfile="server.key", client_cafile="client.crt", client_auth_required=True)

while True:
    pass

Generate client cert and client key.

openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr
openssl x509 -req -in client.csr -signkey client.key -out client.crt

Curl HTTPS Request

curl -k https://127.0.0.1:8000

Response

curl: (56) LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0

Curl HTTPS Request with client cert and client key

curl -k --cert client.crt --key client.key https://127.0.0.1:8000

Response

# HELP python_gc_objects_collected_total Objects collected during gc
# TYPE python_gc_objects_collected_total counter
python_gc_objects_collected_total{generation="0"} 618.0
python_gc_objects_collected_total{generation="1"} 5.0
python_gc_objects_collected_total{generation="2"} 0.0
# HELP python_gc_objects_uncollectable_total Uncollectable objects found during GC
# TYPE python_gc_objects_uncollectable_total counter
python_gc_objects_uncollectable_total{generation="0"} 0.0
python_gc_objects_uncollectable_total{generation="1"} 0.0
python_gc_objects_uncollectable_total{generation="2"} 0.0
# HELP python_gc_collections_total Number of times this generation was collected
# TYPE python_gc_collections_total counter
python_gc_collections_total{generation="0"} 39.0
python_gc_collections_total{generation="1"} 3.0
python_gc_collections_total{generation="2"} 0.0
# HELP python_info Python platform information
# TYPE python_info gauge
python_info{implementation="CPython",major="3",minor="11",patchlevel="5",version="3.11.5"} 1.0

@xiqing-zhang
Copy link

@karezachen Hi, the feature is very nice. We are looking for prometheus python client with TLS support. Our project is pending on the feature. Can you pls set reviewer and ask them to review and merge it?

Copy link

@xiqing-zhang xiqing-zhang left a comment

Choose a reason for hiding this comment

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

It looks good! Simple and but nice!

@roidelapluie
Copy link
Member

Thank you. I think this is interesting, however we would need to document it better and make sure that we error if the arguments passed are not correct (e.g. an array of 2). Maybe we should review the API to make it more clear which is which in the array, maybe by using multiple arguments or a custom object? What would be alternate proposals here?

@Charles1000Chen
Copy link

Charles1000Chen commented Jul 28, 2023

@karezachen Hi Kareza, thank you for the improvement.

  1. Since Python version 3.10: SSLContext without protocol argument is deprecated, we could use ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) instead.
ssl.PROTOCOL_TLS_SERVER
Auto-negotiate the highest protocol version that both the client and server support, and configure the context server-side connections
  1. About the context.load_cert_chain(tls[0], tls[1], tls[2] if len(tls) == 3 else None), its accepted arguments should be
SSLContext.load_cert_chain(certfile, keyfile=None, password=None)
  1. To use mTLS to verify client cert, we may want to cal the load_verify_locations to set ca cert for the SSLContext object before call wrap_socket.
SSLContext.load_verify_locations(cafile=None, capath=None, cadata=None)

@ethanschen ethanschen closed this Jul 28, 2023
@ethanschen ethanschen reopened this Jul 28, 2023
@ethanschen
Copy link
Contributor Author

@Charles1000Chen @roidelapluie Hi,Thank you for the review.

I have wrapped the _get_ssl_ctx method based on the tls_auth_handler to support TLS.

If you have any other suggestions, I am more than willing to make the changes.

@ethanschen
Copy link
Contributor Author

@csmarchbanks PTAL

README.md Outdated Show resolved Hide resolved
Copy link

@xiqing-zhang xiqing-zhang left a comment

Choose a reason for hiding this comment

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

Doc improvement suggestion. Pls add the optional parameters into the doc. thanks

Copy link
Contributor

@andy-maier andy-maier left a comment

Choose a reason for hiding this comment

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

See my comments

README.md Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
@andy-maier
Copy link
Contributor

I have started using the PR in its current state for our Z HMC Prometheus exporter (see PR zhmcclient/zhmc-prometheus-exporter#361), and it worked. However, see my comments, above.

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
@andy-maier
Copy link
Contributor

andy-maier commented Aug 21, 2023

@karezachen Hi Kareza. I have reviewed the latest version of the PR and have opened some new review comments. I was not able to mark some of the old ones as resolved, so I updated the comments that they were resolved, and then I hided the comments.

Signed-off-by: kareza <[email protected]>
1.A better description of what's new.
2.Modify the parameter order of the start_wsgi_server method to maintain forward compatibility.
3.Enable authentication mode when safe.

Signed-off-by: kareza <[email protected]>
@ethanschen
Copy link
Contributor Author

@roidelapluie @xiqing-zhang @xiqing-zhang

Thank you all for the discussion and review of this PR. What is still missing before it can be merged?

@andy-maier
Copy link
Contributor

@karezachen Hello Kareza. Thanks much for integrating the remaining changes. My review comments have all been resolved. From my perspective, the PR could be merged.

@roidelapluie @csmarchbanks Anything left to be done from your perspective?

@Charles1000Chen
Copy link

@karezachen @roidelapluie @csmarchbanks I have tested by zhmc-prometheus-exporter and the mTLS feature works well. Could you help to get the pr merged? Thanks.

@csmarchbanks
Copy link
Member

👋 I am just coming back from leave and still catching up. I hope to have time to review this soon though if @roidelapluie does not get to it first.

@andy-maier
Copy link
Contributor

Note that I was not able to mark my review comments as resolved, but I consider all of them resolved.

@GeluConstantin
Copy link

Hi,

I tired the HTTPS option but I get an error, TypeError: start_wsgi_server() got an unexpected keyword argument 'tls'

it seems that the tls=[certfile, keyfile] is not a valid argument for the function.

Can you advise on the topic?

Thank you,

Constantin

@ethanschen
Copy link
Contributor Author

ethanschen commented Sep 15, 2023

@GeluConstantin
Hello Gelu,

I did use the tls parameter in the commit, but subsequent commits have replaced it with other parameters.

Please refer to README to use HTTPS function.

@andy-maier
Copy link
Contributor

@GeluConstantin Hi Constantin. I tried the branch of this PR with HTTPS shortly after its last update and it worked fine. Note that the branch has 7 commits, so you need to use all of them.

@GeluConstantin
Copy link

@GeluConstantin Hi Constantin. I tried the branch of this PR with HTTPS shortly after its last update and it worked fine. Note that the branch has 7 commits, so you need to use all of them.

Hi Andy,

do you know when the PR is going to be integrated into a release? At the moment I use the latest prometheus-client release 0.17.1 and this release has not yet the HTTPS feature.

Thank you for the feebdack,

Constantin

@andy-maier
Copy link
Contributor

@GeluConstantin No, I don't know. I am not a maintainer of the project.

@roidelapluie or @csmarchbanks Any chance to get this PR reviewed and merged?

@GeluConstantin
Copy link

I used fastAPI to provide HTTPS, so my problem is solved.

Kind regards,

Gelu

@csmarchbanks
Copy link
Member

I am out this week, so unlikely until next week. I have the open question about mTLS behavior when I reviewed it, but otherwise this looks ok to me. I just either need to hear back from @roidelapluie or investigate the behavior next week when I am back.

@Charles1000Chen
Copy link

@csmarchbanks Any result on your investigation on the PR? We do need your help to have this PR merged. Thanks.

Copy link
Member

@csmarchbanks csmarchbanks left a comment

Choose a reason for hiding this comment

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

Yes, by default mTLS should not be enabled. You can find more detail in https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md, but I believe we should not set ssl_cxt.verify_mode to ssl.CERT_REQUIRED by default, and instead have the user opt in.

To be most like the exporter toolkit we would allow users to pass in any verify mode, but I would also be ok with only the default (CERT_NONE), or a flag to enable mTLS and then set CERT_REQUIRED.

prometheus_client/exposition.py Outdated Show resolved Hide resolved
@andy-maier
Copy link
Contributor

@csmarchbanks @roidelapluie Kareza has updated the PR to implement the suggestion with the renamed client_cafile/path parameters.

It seems the only open comment at this point is the one about the default for mTLS. I suggested a solution in the comment further up. Could you please let us know how you like that solution?

- Update `_get_ssl_ctx` func, default not to set `ssl_ctx.verify_mode=ssl.CERT_REQUIRED`.
- Update the description of default in README.md.

Signed-off-by: kareza <[email protected]>
@ethanschen
Copy link
Contributor Author

@Charles1000Chen @xiqing-zhang @andy-maier @csmarchbanks @roidelapluie

Thank you very much for your help with this PR, I think our problems have been solved.

Is it possible to merge this PR now? Thanks

@andy-maier
Copy link
Contributor

@csmarchbanks @roidelapluie Any chance to merge this PR and release a new version? From the perspective of the contributors and reviewers of the PR, all open review comments have been addressed.

@csmarchbanks
Copy link
Member

This review comment has not been addressed yet, looks like it was hidden by the Github UI though: #946 (comment). I do think it is reasonable to remove client_auth_required and just toggle the behavior based on if client_cafile is not None.

@Charles1000Chen
Copy link

Charles1000Chen commented Nov 3, 2023

This review comment has not been addressed yet, looks like it was hidden by the Github UI though: #946 (comment). I do think it is reasonable to remove client_auth_required and just toggle the behavior based on if client_cafile is not None.

@csmarchbanks Hi Chris, the client_auth_required has two logics. The one is the client_auth_required == True which could be toggled to the behavior based on cafile is not None or capath is not None as what your suggested. The other logic is client_auth_required == True andcafile is None and capath is None, the server will use the certificates from os default certificate store to verify the client. Removing client_auth_required will have the server lose the ability of using os default certificates to verify client. What do you think about this? @roidelapluie

@andy-maier
Copy link
Contributor

@csmarchbanks As Charles1000Chen points out, removing client_auth_required would loose the ability to use the default certificate store. Is that what you want?

@csmarchbanks
Copy link
Member

Apparently I had a pending comment and didn't click the send button :(

I am happy with the current behavior (keep being able to use the default certificate store). I would like @roidelapluie to ok that as well since he brought up the concern originally though.

@roidelapluie
Copy link
Member

Let's keep the ability to use the system store. This PR LGTM, thank you all.

Copy link
Member

@csmarchbanks csmarchbanks left a comment

Choose a reason for hiding this comment

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

👍 I think that covers it, thanks as well!

@csmarchbanks csmarchbanks merged commit 3d78630 into prometheus:master Nov 6, 2023
10 checks passed
@andy-maier
Copy link
Contributor

@karezachen Thanks again, Kareza for the contributions!
@csmarchbanks Thanks for merging the PR! We will now release a beta version of our zhmc prometheus exporter from the master branch.

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.

7 participants