Python: How to connect through SSL to external server inside package?

  Kiến thức lập trình

A problem that I’ve come across is that I have a Flask application that wants to connect to a Grafana Instance through Grafana Client, but every time I try to it gives me out the following error:

(.venv) usr:~/projects/app$ flask run --cert=cert.pem --key=key.pem
Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
Running on https://127.0.0.1:5000
Press CTRL+C to quit
[2024-09-10 10:38:50,702] ERROR in app: Exception on /grafana [GET]
Traceback (most recent call last):
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 975, in _make_request
    self._validate_conn(conn)
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 1939, in _validate_conn
    super()._validate_conn(conn)
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 608, in _validate_conn
    conn.connect()
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/connection.py", line 732, in connect
    sock_and_verified = _ssl_wrap_socket_and_match_hostname(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/connection.py", line 895, in _ssl_wrap_socket_and_match_hostname
    ssl_sock = ssl_wrap_socket(
            ^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/util/ssl_.py", line 637, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/util/ssl_.py", line 681, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/ssl.py", line 517, in wrap_socket
    return self.sslsocket_class._create(
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/ssl.py", line 1075, in _create
    self.do_handshake()
File "/usr/lib/python3.11/ssl.py", line 1346, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:992)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 1400, in urlopen
    response = self._make_request(  # type: ignore[call-overload,misc]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 999, in _make_request
    raise new_e
urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:992)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/niquests/adapters.py", line 899, in send
    resp_or_promise = conn.urlopen(  # type: ignore[call-overload]
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 1476, in urlopen
    retries = retries.increment(
            ^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/urllib3/util/retry.py", line 542, in increment
    raise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='grafana.prd.rede.tst', port=443): Max retries exceeded with url: /api/health (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:992)')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/flask/app.py", line 1473, in wsgi_app
    response = self.full_dispatch_request()
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/flask/app.py", line 882, in full_dispatch_request
    rv = self.handle_user_exception(e)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/flask/app.py", line 880, in full_dispatch_request
    rv = self.dispatch_request()
        ^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/flask/app.py", line 865, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/app.py", line 48, in grafana_page
    health = grafana_instance.health.check()
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/grafana_client/elements/health.py", line 15, in check
    return self.client.GET(path)
        ^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/grafana_client/client.py", line 198, in __request_runner
    r = self.s.request(
        ^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/niquests/sessions.py", line 550, in request
    resp = self.send(prep, **send_kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/niquests/sessions.py", line 1201, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/usr/projects/app/.venv/lib/python3.11/site-packages/niquests/adapters.py", line 948, in send
    raise SSLError(e, request=request)
niquests.exceptions.SSLError: HTTPSConnectionPool(host='grafana.local', port=443): Max retries exceeded with url: /api/health (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:992)')))
`

Grafana is hosted on the intranet but requires an SSL connection. I’ve created the self-signed certificate to use for local testing, but nothing seems to work. Do I have to wrap something with the SSL context for it to work? I’ve never really messed with this stuff.

My app.py has the following:

from flask import Flask
from grafana_client import GrafanaApi

from .settings import settings

api = GrafanaApi(verify=False, host=settings.GRAFANA_URL)
grafana_instance = api.from_url(
    url=settings.GRAFANA_URL, credential=settings.GRAFANA_TOKEN
)
app = Flask(__name__, static_url_path="/static")

@app.route("/grafana", methods=["GET"])
def grafana_page():
    health = grafana_instance.health.check()
    print(health)
    return {"OK": "OK"}

I’ve tried setting an insecure connection through the grafana-client, but it seems even then it requests from the Grafana URL to ask whether it wants to make an insecure connection or not, so turning verify=False on the GrafanaApi object doesn’t do much.

Does Python see the local certificates when running? Do I have to set it so that it sees my local certificates and if so, would it use it during the grafana-client call without explicitly calling it?

2

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT