Improve security #16
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
a2dcc545c5
commit
fbe5bd2d94
1 changed files with 41 additions and 3 deletions
|
@ -198,8 +198,13 @@ RestrictSUIDSGID=yes
|
||||||
RemoveIPC=yes
|
RemoveIPC=yes
|
||||||
ProtectProc=invisible
|
ProtectProc=invisible
|
||||||
ProcSubset=pid
|
ProcSubset=pid
|
||||||
|
|
||||||
|
# Allow loopback for upstream to registry and allow the server's public IP(s) for binds:
|
||||||
IPAddressDeny=any
|
IPAddressDeny=any
|
||||||
IPAddressAllow=127.0.0.1
|
IPAddressAllow=127.0.0.1
|
||||||
|
IPAddressAllow=<SERVER_IPV4>
|
||||||
|
# If using IPv6, uncomment and set:
|
||||||
|
# IPAddressAllow=<SERVER_IPV6>
|
||||||
LimitNOFILE=65536
|
LimitNOFILE=65536
|
||||||
ExecStartPre=/usr/sbin/nginx -t -c /etc/registry/nginx.conf
|
ExecStartPre=/usr/sbin/nginx -t -c /etc/registry/nginx.conf
|
||||||
ExecStart=/usr/sbin/nginx -g 'daemon off;' -c /etc/registry/nginx.conf
|
ExecStart=/usr/sbin/nginx -g 'daemon off;' -c /etc/registry/nginx.conf
|
||||||
|
@ -261,7 +266,9 @@ ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
|
||||||
|
|
||||||
# 443: unauthenticated pulls only
|
# 443: unauthenticated pulls only
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen <SERVER_IPV4>:443 ssl http2;
|
||||||
|
# If IPv6, also:
|
||||||
|
# listen [<SERVER_IPV6>]:443 ssl http2;
|
||||||
ssl_certificate /etc/registry/certs/registry.crt;
|
ssl_certificate /etc/registry/certs/registry.crt;
|
||||||
ssl_certificate_key /etc/registry/certs/private/registry.key;
|
ssl_certificate_key /etc/registry/certs/private/registry.key;
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
@ -285,7 +292,9 @@ ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
|
||||||
|
|
||||||
# 4443: authenticated pushes only (mTLS)
|
# 4443: authenticated pushes only (mTLS)
|
||||||
server {
|
server {
|
||||||
listen 4443 ssl http2;
|
listen <SERVER_IPV4>:4443 ssl http2;
|
||||||
|
# If IPv6, also:
|
||||||
|
# listen [<SERVER_IPV6>]:4443 ssl http2;
|
||||||
ssl_certificate /etc/registry/certs/registry.crt;
|
ssl_certificate /etc/registry/certs/registry.crt;
|
||||||
ssl_certificate_key /etc/registry/certs/private/registry.key;
|
ssl_certificate_key /etc/registry/certs/private/registry.key;
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
@ -315,7 +324,7 @@ EOF
|
||||||
sudo chown root:root /etc/registry/nginx.conf
|
sudo chown root:root /etc/registry/nginx.conf
|
||||||
sudo chmod 644 /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`.
|
**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 migrating to a public CA later, enable stapling and add `resolver` + `ssl_trusted_certificate`.
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.6 Install Container Policy
|
### 2.6 Install Container Policy
|
||||||
|
@ -351,6 +360,13 @@ sudo openssl genrsa -out private/registry.key 4096
|
||||||
sudo cp /opt/APP_NAME/registry/openssl.conf /etc/registry/certs/requests/
|
sudo cp /opt/APP_NAME/registry/openssl.conf /etc/registry/certs/requests/
|
||||||
sudo chown root:root /etc/registry/certs/requests/openssl.conf
|
sudo chown root:root /etc/registry/certs/requests/openssl.conf
|
||||||
|
|
||||||
|
# Ensure OpenSSL config includes subjectAltName for REGISTRY_HOST and SERVER_IP
|
||||||
|
# The config should contain:
|
||||||
|
# [ req_ext ]
|
||||||
|
# subjectAltName = DNS:REGISTRY_HOST,IP:<SERVER_IPV4>
|
||||||
|
# If IPv6:
|
||||||
|
# subjectAltName = DNS:REGISTRY_HOST,IP:<SERVER_IPV4>,IP:<SERVER_IPV6>
|
||||||
|
|
||||||
# Generate server certificate signing request in requests subdirectory
|
# Generate server certificate signing request in requests subdirectory
|
||||||
sudo openssl req -new -key private/registry.key \
|
sudo openssl req -new -key private/registry.key \
|
||||||
-out requests/registry.csr \
|
-out requests/registry.csr \
|
||||||
|
@ -407,6 +423,8 @@ sudo chmod 755 /etc/registry/certs
|
||||||
# Verify certificate creation
|
# Verify certificate creation
|
||||||
sudo openssl x509 -in /etc/registry/certs/registry.crt -text -noout | grep -E "(Subject:|DNS:|IP Address:)"
|
sudo openssl x509 -in /etc/registry/certs/registry.crt -text -noout | grep -E "(Subject:|DNS:|IP Address:)"
|
||||||
|
|
||||||
|
# Reminder: clients must use exactly REGISTRY_HOST (or those IPs) in pulls/pushes
|
||||||
|
|
||||||
# 3. Install server CA certificate in system trust store (for curl, wget, etc.)
|
# 3. Install server CA certificate in system trust store (for curl, wget, etc.)
|
||||||
sudo cp /etc/registry/certs/ca/ca.crt /usr/local/share/ca-certificates/registry-ca.crt
|
sudo cp /etc/registry/certs/ca/ca.crt /usr/local/share/ca-certificates/registry-ca.crt
|
||||||
|
|
||||||
|
@ -517,12 +535,32 @@ This setup implements a multi-layered security approach:
|
||||||
### 4.2 Enable and Start Services
|
### 4.2 Enable and Start Services
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Reload systemd and start services
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
|
||||||
# Start as the service user
|
# Start as the service user
|
||||||
sudo -u CI_SERVICE_USER sh -lc 'systemctl --user daemon-reload && systemctl --user enable --now registry.service'
|
sudo -u CI_SERVICE_USER sh -lc 'systemctl --user daemon-reload && systemctl --user enable --now registry.service'
|
||||||
sudo systemctl enable --now registry-proxy.service
|
sudo systemctl enable --now registry-proxy.service
|
||||||
|
|
||||||
# One-time: ensure host dir ownership matches rootless ID map
|
# One-time: ensure host dir ownership matches rootless ID map
|
||||||
sudo -u CI_SERVICE_USER podman unshare chown -R 100000:100000 /var/lib/registry
|
sudo -u CI_SERVICE_USER podman unshare chown -R 100000:100000 /var/lib/registry
|
||||||
|
|
||||||
|
### 4.1 Self-test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1) Listening sockets (should show nginx on the chosen IPs/ports):
|
||||||
|
sudo ss -ltnp '( sport = :443 or sport = :4443 )'
|
||||||
|
|
||||||
|
# 2) From another host on an allowed network:
|
||||||
|
curl -vk https://REGISTRY_HOST/v2/ | grep -i Docker-Distribution-Api-Version # expect 200 + header
|
||||||
|
curl -vk https://REGISTRY_HOST/v2/_catalog # expect 403 (blocked)
|
||||||
|
curl -vk --cert client.crt --key client.key https://REGISTRY_HOST:4443/v2/ | \
|
||||||
|
grep -i Docker-Distribution-Api-Version # expect 200 + header
|
||||||
|
|
||||||
|
# 3) Signature enforcement (on a client with CA + org-cosign.pub + policy.json):
|
||||||
|
# - Pull unsigned image from your registry -> should FAIL
|
||||||
|
# - Sign image with your org key, push via 4443, pull via 443 -> should SUCCEED
|
||||||
|
```
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 5: Verify Installation
|
## Step 5: Verify Installation
|
||||||
|
|
Loading…
Add table
Reference in a new issue