diff --git a/Docker_Registry_Install_Guide.md b/Docker_Registry_Install_Guide.md index f1e4b9e..e7bbe18 100644 --- a/Docker_Registry_Install_Guide.md +++ b/Docker_Registry_Install_Guide.md @@ -81,7 +81,7 @@ sudo loginctl enable-linger CI_SERVICE_USER # Create Podman rootless directories outside home sudo mkdir -p /var/tmp/podman-$(id -u CI_SERVICE_USER)/{root,run,tmp,xdg-data,xdg-config} sudo chown -R CI_SERVICE_USER:CI_SERVICE_USER /var/tmp/podman-$(id -u CI_SERVICE_USER) -sudo chmod 755 /var/tmp/podman-$(id -u CI_SERVICE_USER) +sudo chmod 750 /var/tmp/podman-$(id -u CI_SERVICE_USER) # Initialize Podman with rootless configuration (no home directory access) sudo su - CI_SERVICE_USER -c "env PODMAN_ROOT=/var/tmp/podman-\$(id -u)/root PODMAN_RUNROOT=/run/user/\$(id -u)/podman-run PODMAN_TMPDIR=/var/tmp/podman-\$(id -u)/tmp XDG_DATA_HOME=/var/tmp/podman-\$(id -u)/xdg-data XDG_CONFIG_HOME=/var/tmp/podman-\$(id -u)/xdg-config podman system migrate" @@ -137,6 +137,8 @@ ExecStart=/usr/bin/podman --root=${PODMAN_ROOT} --runroot=${PODMAN_RUNROOT} --tm docker.io/library/registry@sha256:8be26f81ffea54106bae012c6f349df70f4d5e7e2ec01b143c46e2c03b9e551d ExecStop=/usr/bin/podman --root=${PODMAN_ROOT} --runroot=${PODMAN_RUNROOT} --tmpdir=${PODMAN_TMPDIR} stop -t 10 registry Restart=on-failure +MemoryMax=1G +CPUQuota=100% [Install] WantedBy=default.target @@ -156,6 +158,10 @@ Wants=network-online.target [Service] User=registry-proxy Group=registry-proxy +UMask=0077 +RuntimeDirectory=registry-proxy +LogsDirectory=registry-proxy +ReadWritePaths=/run/registry-proxy /var/log/registry-proxy AmbientCapabilities=CAP_NET_BIND_SERVICE CapabilityBoundingSet=CAP_NET_BIND_SERVICE NoNewPrivileges=yes @@ -165,6 +171,8 @@ ProtectHome=yes ProtectKernelTunables=yes ProtectKernelModules=yes ProtectControlGroups=yes +ProtectClock=yes +ProtectHostname=yes LockPersonality=yes MemoryDenyWriteExecute=yes RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 @@ -185,12 +193,21 @@ EOF sudo tee /etc/registry/nginx.conf > /dev/null << 'EOF' worker_processes auto; events { worker_connections 1024; } + +pid /run/registry-proxy/nginx.pid; +access_log /var/log/registry-proxy/access.log; +error_log /var/log/registry-proxy/error.log; + http { limit_req_zone $binary_remote_addr zone=reg_read:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=reg_write:10m rate=5r/s; client_max_body_size 2g; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; proxy_http_version 1.1; proxy_set_header Connection ""; + proxy_request_buffering off; + proxy_read_timeout 300s; upstream reg { server 127.0.0.1:5000; } # 443: unauthenticated pulls only @@ -329,9 +346,19 @@ sudo update-ca-certificates ### 4.1 Configure Firewall ```bash -# Configure firewall for Docker Registry v2 ports -sudo ufw allow 443/tcp # Docker Registry via nginx (unauthenticated pulls) -sudo ufw allow 4443/tcp # Docker Registry via nginx (authenticated pushes with mTLS) +# Open port 443 for unauthenticated pulls (public access) +sudo ufw allow 443/tcp + +# Open port 4443 for authenticated pushes (restrict to known CIDRs) +# Example: restrict to specific networks (adjust CIDRs as needed) +sudo ufw delete allow 4443/tcp || true +sudo ufw allow from 10.0.0.0/8 to any port 4443 proto tcp +sudo ufw allow from 172.16.0.0/12 to any port 4443 proto tcp +sudo ufw allow from 192.168.0.0/16 to any port 4443 proto tcp + +# For public access to 4443 (less secure), use: +# sudo ufw allow 4443/tcp + # Note: Port 5000 is NOT opened - registry runs loopback-only ``` @@ -361,6 +388,24 @@ sudo su - CI_SERVICE_USER -c "env PODMAN_ROOT=/var/tmp/podman-\$(id -u)/root POD # Check nginx proxy logs sudo journalctl -u registry-proxy.service -f --no-pager -n 50 +# Quick validation of hardening +echo "=== Proxy Runtime & Logs ===" +systemctl status registry-proxy.service +ls -ld /run/registry-proxy /var/log/registry-proxy + +echo "=== Nginx Logs ===" +tail -n1 /var/log/registry-proxy/error.log /var/log/registry-proxy/access.log + +echo "=== Port Bindings ===" +ss -ltnp | egrep ':(443|4443)'; ss -ltnp | grep '127.0.0.1:5000' + +echo "=== Security Tests ===" +# 443 forbids writes +curl -k -X PUT https://YOUR_ACTUAL_IP_ADDRESS/v2/ -I | grep 403 || echo "WARNING: 443 allows writes" + +# 4443 requires client cert +curl -kI https://YOUR_ACTUAL_IP_ADDRESS:4443/v2/ | egrep '400|401|403' || echo "WARNING: 4443 may not require auth" + # Verify Podman is using non-home paths sudo su - CI_SERVICE_USER -c "env PODMAN_ROOT=/var/tmp/podman-\$(id -u)/root PODMAN_RUNROOT=/run/user/\$(id -u)/podman-run PODMAN_TMPDIR=/var/tmp/podman-\$(id -u)/tmp XDG_DATA_HOME=/var/tmp/podman-\$(id -u)/xdg-data XDG_CONFIG_HOME=/var/tmp/podman-\$(id -u)/xdg-config podman info --format '{{.Store.GraphRoot}} {{.Store.RunRoot}}'" ```