官方PostgreSQL Docker镜像SSL启用问题排查及可行配置请求
你的问题主要出在两个核心点:Docker Compose中PostgreSQL服务的command配置格式错误,以及可能存在的证书文件权限问题,这两个因素共同导致PostgreSQL没有正确启用SSL支持。
1. Command配置格式错误
在你的docker-compose.yml里,command字段的写法不符合Docker Compose的参数传递规则。Docker Compose的command如果用列表形式,第一个元素必须是要执行的主命令(这里是postgres),后续每个命令参数都要单独作为列表项。你之前的写法相当于让容器去执行一个名为-c的命令,而不是给postgres传递SSL配置参数,这直接导致PostgreSQL启动时完全没有加载SSL相关配置,自然不支持SSL连接。
2. 证书文件权限问题
PostgreSQL容器内部是以postgres用户(UID=999)运行的,如果你挂载的证书文件在宿主机上是root用户所有,容器内的postgres用户会没有读取权限,同样会导致SSL启动失败。
修复后的完整docker-compose.yml配置
version: '3.5' services: postgresserver: image: postgres:14.5 container_name: postgresserver ports: - "5432:5432" environment: POSTGRES_PASSWORD: my_password PGPORT: 5432 # 修正command格式:主命令postgres在前,每个-c参数和对应配置单独作为列表元素 command: - postgres - -c - ssl=on - -c - ssl_cert_file=/var/lib/postgresql/server.crt - -c - ssl_key_file=/var/lib/postgresql/server.key - -c - ssl_ca_file=/var/lib/postgresql/CA.pem - -c - clientcert=verify-ca volumes: - "./certs/myCA.pem:/var/lib/postgresql/CA.pem" - "./certs/postgresserver.internal.crt:/var/lib/postgresql/server.crt" - "./certs/postgresserver.internal.key:/var/lib/postgresql/server.key" # 可选:添加初始化脚本自动修复证书权限 - "./fix-cert-perms.sh:/docker-entrypoint-initdb.d/fix-cert-perms.sh" networks: default: aliases: - postgresserver.internal openssl: image: shamelesscookie/openssl:1.1.1 container_name: openssl stdin_open: true # docker run -i tty: true networks: default: name: dummy_network driver: bridge ipam: config: - subnet: 172.177.0.0/16
3. 修复证书权限(可选但推荐)
如果你的证书文件权限有问题,创建一个fix-cert-perms.sh脚本放在宿主机的当前目录下:
#!/bin/bash chown postgres:postgres /var/lib/postgresql/*.pem /var/lib/postgresql/*.crt /var/lib/postgresql/*.key chmod 600 /var/lib/postgresql/server.key
然后给脚本添加可执行权限:
chmod +x ./fix-cert-perms.sh
这个脚本会在容器初始化阶段自动执行,确保证书文件的权限符合PostgreSQL的安全要求。
验证修复效果
- 重新启动容器:
docker-compose down && docker-compose up -d
- 查看PostgreSQL日志确认SSL启用:
docker logs postgresserver
如果看到包含SSL is enabled的日志条目,说明SSL配置已生效。
- 用openssl测试SSL连接:
# 进入openssl容器执行 openssl s_client -starttls postgres -connect postgresserver:5432
此时应该能看到服务器证书的详细信息,不再出现no peer certificate available的提示。
- 用psql客户端验证连接(需指定CA证书):
& 'C:\Program Files\PostgreSQL\14\bin\psql.exe' "sslmode=verify-ca sslrootcert=./certs/myCA.pem host=localhost port=5432 dbname=postgres user=postgres password=my_password"
因为你设置了clientcert=verify-ca,客户端必须提供受信任的CA证书才能通过服务器身份验证。
内容的提问来源于stack exchange,提问作者AndyM

