mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-19 16:03:00 +00:00
simplify make_ssl_context
pass ssl.Purpose explicitly, deprecate verify/check_hostname 3.10 disallows 'purpose=SERVER_AUTH' from creating server sockets. Instead: - pass purpose directly - always verify - no need to set check_hostname, already covered by purpose defaults
This commit is contained in:
@@ -11,6 +11,7 @@ import re
|
|||||||
import secrets
|
import secrets
|
||||||
import signal
|
import signal
|
||||||
import socket
|
import socket
|
||||||
|
import ssl
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
@@ -3047,7 +3048,7 @@ class JupyterHub(Application):
|
|||||||
self.internal_ssl_key,
|
self.internal_ssl_key,
|
||||||
self.internal_ssl_cert,
|
self.internal_ssl_cert,
|
||||||
cafile=self.internal_ssl_ca,
|
cafile=self.internal_ssl_ca,
|
||||||
check_hostname=False,
|
purpose=ssl.Purpose.CLIENT_AUTH,
|
||||||
)
|
)
|
||||||
|
|
||||||
# start the webserver
|
# start the webserver
|
||||||
|
@@ -14,6 +14,7 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import secrets
|
import secrets
|
||||||
|
import ssl
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from datetime import timezone
|
from datetime import timezone
|
||||||
|
@@ -15,6 +15,7 @@ Handlers and their purpose include:
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import pprint
|
import pprint
|
||||||
|
import ssl
|
||||||
import sys
|
import sys
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
@@ -111,7 +112,9 @@ def main():
|
|||||||
ca = os.environ.get('JUPYTERHUB_SSL_CLIENT_CA') or ''
|
ca = os.environ.get('JUPYTERHUB_SSL_CLIENT_CA') or ''
|
||||||
|
|
||||||
if key and cert and ca:
|
if key and cert and ca:
|
||||||
ssl_context = make_ssl_context(key, cert, cafile=ca, check_hostname=False)
|
ssl_context = make_ssl_context(
|
||||||
|
key, cert, cafile=ca, purpose=ssl.Purpose.CLIENT_AUTH
|
||||||
|
)
|
||||||
|
|
||||||
server = httpserver.HTTPServer(app, ssl_options=ssl_context)
|
server = httpserver.HTTPServer(app, ssl_options=ssl_context)
|
||||||
server.listen(url.port, url.hostname)
|
server.listen(url.port, url.hostname)
|
||||||
|
@@ -47,7 +47,11 @@ def main():
|
|||||||
ca = os.environ.get('JUPYTERHUB_SSL_CLIENT_CA') or ''
|
ca = os.environ.get('JUPYTERHUB_SSL_CLIENT_CA') or ''
|
||||||
|
|
||||||
if key and cert and ca:
|
if key and cert and ca:
|
||||||
ssl_context = make_ssl_context(key, cert, cafile=ca, check_hostname=False)
|
import ssl
|
||||||
|
|
||||||
|
ssl_context = make_ssl_context(
|
||||||
|
key, cert, cafile=ca, purpose=ssl.Purpose.CLIENT_AUTH
|
||||||
|
)
|
||||||
assert url.scheme == "https"
|
assert url.scheme == "https"
|
||||||
|
|
||||||
server = httpserver.HTTPServer(app, ssl_options=ssl_context)
|
server = httpserver.HTTPServer(app, ssl_options=ssl_context)
|
||||||
|
@@ -94,13 +94,51 @@ def can_connect(ip, port):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def make_ssl_context(keyfile, certfile, cafile=None, verify=True, check_hostname=True):
|
def make_ssl_context(
|
||||||
"""Setup context for starting an https server or making requests over ssl."""
|
keyfile,
|
||||||
|
certfile,
|
||||||
|
cafile=None,
|
||||||
|
verify=None,
|
||||||
|
check_hostname=None,
|
||||||
|
purpose=ssl.Purpose.SERVER_AUTH,
|
||||||
|
):
|
||||||
|
"""Setup context for starting an https server or making requests over ssl.
|
||||||
|
|
||||||
|
Used for verifying internal ssl connections.
|
||||||
|
Certificates are always verified in both directions.
|
||||||
|
Hostnames are checked for client sockets.
|
||||||
|
|
||||||
|
Client sockets are created with `purpose=ssl.Purpose.SERVER_AUTH` (default),
|
||||||
|
Server sockets are created with `purpose=ssl.Purpose.CLIENT_AUTH`.
|
||||||
|
"""
|
||||||
if not keyfile or not certfile:
|
if not keyfile or not certfile:
|
||||||
return None
|
return None
|
||||||
purpose = ssl.Purpose.SERVER_AUTH if verify else ssl.Purpose.CLIENT_AUTH
|
if verify is not None:
|
||||||
|
purpose = ssl.Purpose.SERVER_AUTH if verify else ssl.Purpose.CLIENT_AUTH
|
||||||
|
warnings.warn(
|
||||||
|
f"make_ssl_context(verify={verify}) is deprecated in jupyterhub 2.4."
|
||||||
|
f" Use make_ssl_context(purpose={purpose}).",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
if check_hostname is not None:
|
||||||
|
purpose = ssl.Purpose.SERVER_AUTH if check_hostname else ssl.Purpose.CLIENT_AUTH
|
||||||
|
warnings.warn(
|
||||||
|
f"make_ssl_context(check_hostname={check_hostname}) is deprecated in jupyterhub 2.4."
|
||||||
|
f" Use make_ssl_context(purpose={purpose}).",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
|
||||||
ssl_context = ssl.create_default_context(purpose, cafile=cafile)
|
ssl_context = ssl.create_default_context(purpose, cafile=cafile)
|
||||||
|
# always verify
|
||||||
|
ssl_context.verify_mode = ssl.CERT_REQUIRED
|
||||||
|
|
||||||
|
if purpose == ssl.Purpose.SERVER_AUTH:
|
||||||
|
# SERVER_AUTH is authenticating servers (i.e. for a client)
|
||||||
|
ssl_context.check_hostname = True
|
||||||
ssl_context.load_default_certs()
|
ssl_context.load_default_certs()
|
||||||
|
|
||||||
ssl_context.load_cert_chain(certfile, keyfile)
|
ssl_context.load_cert_chain(certfile, keyfile)
|
||||||
ssl_context.check_hostname = check_hostname
|
ssl_context.check_hostname = check_hostname
|
||||||
return ssl_context
|
return ssl_context
|
||||||
|
Reference in New Issue
Block a user