Improve security #15
Some checks are pending
CI/CD Pipeline (Fully Isolated DinD) / Run Tests (DinD) (push) Waiting to run
CI/CD Pipeline (Fully Isolated DinD) / Build and Push Docker Images (DinD) (push) Blocked by required conditions
CI/CD Pipeline (Fully Isolated DinD) / Deploy to Production (push) Blocked by required conditions

This commit is contained in:
continuist 2025-08-24 17:54:19 -04:00
parent 7b1e38fb95
commit a2dcc545c5

View file

@ -194,6 +194,12 @@ ProtectHostname=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictSUIDSGID=yes
RemoveIPC=yes
ProtectProc=invisible
ProcSubset=pid
IPAddressDeny=any
IPAddressAllow=127.0.0.1
LimitNOFILE=65536
ExecStartPre=/usr/sbin/nginx -t -c /etc/registry/nginx.conf
ExecStart=/usr/sbin/nginx -g 'daemon off;' -c /etc/registry/nginx.conf
@ -218,11 +224,15 @@ error_log /var/log/registry-proxy/error.log;
http {
server_tokens off;
# Rate/connection limits (tune for CI bursts as needed)
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;
limit_conn_zone $binary_remote_addr zone=perip:10m;
# Note: Tune these limits based on your expected load. Adjust if CI bursts cause 429s.
client_max_body_size 2g;
# TLS hardening
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
@ -232,8 +242,11 @@ ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
# OCSP stapling is intentionally DISABLED for private CA deployments.
# (Clients trust via installed CA cert; no public OCSP endpoint exists.)
# Proxy settings
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_request_buffering off;
@ -243,6 +256,7 @@ ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
fastcgi_temp_path /run/registry-proxy/fastcgi_temp;
uwsgi_temp_path /run/registry-proxy/uwsgi_temp;
scgi_temp_path /run/registry-proxy/scgi_temp;
upstream reg { server 127.0.0.1:5000; }
# 443: unauthenticated pulls only
@ -252,8 +266,11 @@ ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_certificate_key /etc/registry/certs/private/registry.key;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Hide catalog & tag listings
location = /v2/_catalog { return 403; }
location ~ ^/v2/.+/tags/list { return 403; }
location /v2/ {
limit_req zone=reg_read burst=20 nodelay;
limit_conn perip 20;
@ -273,8 +290,14 @@ ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_certificate_key /etc/registry/certs/private/registry.key;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# mTLS client auth via private Client CA
ssl_client_certificate /etc/registry/certs/clients/ca.crt;
ssl_verify_client on;
# Optional: enable client-cert revocation (publish a CRL and uncomment)
# ssl_crl /etc/registry/certs/clients/ca.crl;
location /v2/ {
limit_req zone=reg_write burst=10;
limit_conn perip 20;
@ -291,6 +314,8 @@ EOF
# Set proper permissions for nginx config (root-owned)
sudo chown root:root /etc/registry/nginx.conf
sudo chmod 644 /etc/registry/nginx.conf
**Note (Private CA):** OCSP stapling is disabled because our CA is private (no public OCSP responder). Clients trust the registry via the installed CA certificate. If you later migrate to a public CA, re-enable stapling and add a DNS resolver and `ssl_trusted_certificate`.
```
### 2.6 Install Container Policy
@ -536,6 +561,15 @@ curl -k -X PUT https://YOUR_ACTUAL_IP_ADDRESS/v2/ -I | grep 403 || echo "WARNING
# 4443 requires client cert
curl -kI https://YOUR_ACTUAL_IP_ADDRESS:4443/v2/ | egrep '400|401|403' || echo "WARNING: 4443 may not require auth"
# 443 should return 200 with registry API header; catalog is forbidden
curl -vk https://REGISTRY_HOST/v2/ | grep -i Docker-Distribution-Api-Version
curl -vk https://REGISTRY_HOST/v2/_catalog # expect 403
# 4443 requires mTLS, should return 200 with client certs
curl -vk --cert client.crt --key client.key https://REGISTRY_HOST:4443/v2/ | grep -i Docker-Distribution-Api-Version
# OCSP stapling is intentionally disabled; you should not expect stapling-related headers in responses.
# 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}}'"
```