Created
July 18, 2024 00:04
-
-
Save emilien-jegou/4417a2e2aad40ec052c7d342e21927dd to your computer and use it in GitHub Desktop.
docker proxy demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from http.server import BaseHTTPRequestHandler, HTTPServer | |
import ssl | |
import base64 | |
# Test of the docker login authentication mechanism for building an authentication proxy. | |
# NB: you may want to remove the SSL configuration below or generate certificate using: | |
# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./server.key -out ./server.crt | |
# | |
# USAGE: | |
# python server.py | |
# docker login localhost:5678 -p your-password -u your-user | |
# | |
# docker login will in order: | |
# - try to skip the login step (it does not send auth data) | |
# - if it receives a 401, it will send a second request with auth data | |
class RequestHandler(BaseHTTPRequestHandler): | |
def authenticate(self): | |
# Extract the Authorization header if present | |
auth_header = self.headers.get('Authorization') | |
if auth_header and auth_header.startswith('Basic '): | |
# Decode the Base64-encoded credentials | |
encoded_credentials = auth_header.split(' ')[1] | |
decoded_credentials = base64.b64decode(encoded_credentials).decode('utf-8') | |
username, password = decoded_credentials.split(':') | |
# Print the extracted username and password | |
print(f"Username: {username}") | |
print(f"Password: {password}") | |
return True | |
return False | |
def do_GET(self): | |
# Handle GET requests | |
if self.path == '/v2/': | |
# If the request is to the /v2/ endpoint, attempt authentication | |
if self.authenticate(): | |
self.send_response(200) | |
self.end_headers() | |
self.wfile.write(b'GET request received') | |
else: | |
# If no or invalid credentials, respond with 401 Unauthorized and request authentication | |
self.send_response(401) | |
self.send_header('WWW-Authenticate', 'Basic realm="Docker Registry"') | |
self.end_headers() | |
self.wfile.write(b'Authentication required') | |
else: | |
# If the request is to any other endpoint, respond with 404 Not Found | |
self.send_response(404) | |
self.end_headers() | |
self.wfile.write(b'Not Found') | |
def run(server_class=HTTPServer, handler_class=RequestHandler, port=9888): | |
server_address = ('', port) | |
httpd = server_class(server_address, handler_class) | |
# Create an SSL context, this is not required since docker will fallback to http. | |
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) | |
context.load_cert_chain(certfile='./server.crt', keyfile='./server.key') | |
# Wrap the server's socket with the SSL context to enable HTTPS | |
httpd.socket = context.wrap_socket(httpd.socket, server_side=True) | |
print(f'Starting https server on port {port}') | |
httpd.serve_forever() | |
if __name__ == '__main__': | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment