Improve security further
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
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:
parent
6c9431767a
commit
d7258dbd95
1 changed files with 49 additions and 4 deletions
|
@ -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}}'"
|
||||
```
|
||||
|
|
Loading…
Add table
Reference in a new issue