Skip to content

Instantly share code, notes, and snippets.

@emilien-jegou
Created July 18, 2024 00:04
Show Gist options
  • Save emilien-jegou/4417a2e2aad40ec052c7d342e21927dd to your computer and use it in GitHub Desktop.
Save emilien-jegou/4417a2e2aad40ec052c7d342e21927dd to your computer and use it in GitHub Desktop.
docker proxy demo
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