繁体   English   中英

部署 postgresql docker 与 ssl 证书和密钥与卷

[英]Deploying postgresql docker with ssl certificate and key with volumes

我正在尝试部署一个 postgresql 容器。 我正在尝试使用卷将 ssl 证书和密钥放入容器中,但我无法获得正确的权限。 这些文件需要容器的postgres用户可读,但也有有限的权限( 600 )。

是否可以使用卷,或者我是否必须为此覆盖 Dockerfile?

谢谢。

可以将密钥和证书安装到postgres容器中,并让postgres从那里使用它们。 但是您将不得不面对server.key的所有者和权限的问题。

PostgreSQL文档中可以找到

在Unix系统上,对server.key的许可必须禁止对world或group的任何访问。 通过命令chmod 0600 server.key来实现。 或者,该文件可以由root拥有,并具有组读取访问权限(即0640权限)。

这意味着您必须:

  1. server.key文件的所有者设置为rootpostgres
  2. 根据server.key文件的所有者,您将必须分别在其上设置600640权限。 更新:这里暗示文件的组所有者是包含postgres用户的组,例如默认的postgres组)

如果使用Windows主机,则将很难。 因为您映射到容器中的卷中任何文件的权限都是-rwxr-xr-x755 ),而所有者将是root 只要从Windows卷上挂载文件,您将无法更改此设置。 如果您尝试在文件上使用chmod ,它将只会静默失败。

另一方面,如果您在linux主机上,则可以轻松完成此操作。 来自主机系统的权限将保留在映像中。 所有权也将日渐减少。 我的意思是,将server.key的数字所有者和组所有者映射到容器后,将保留它们。 它们在主机和容器之间共享linux ACL,因此它们只是观察文件的相同属性。 (所有者,组所有者,权限)。 因此,如果主机上的本地linux用户具有UID:GID 1000:1000 ,并且创建了server.key文件,则该文件的UID:GID也将设置为1000:1000 如果然后将文件映射到容器中,并从内部进行观察-它也只会看到1000:1000 这意味着,当从linux主机映射时,我们可以从容器内部和外部控制UID:GID

注意。 不必具有您分配为文件所有者的UID的用户,而是可以设置不存在的文件UID:GID所有者。

在postgres alpine派生图像中, postgres用户/组具有UID:GID 70:70 debian衍生产品上,postgres的UID:GID999:999 并不奇怪,root都在0:0上具有0:0

这意味着必须:

  1. 更改UID:GID文件server.key ,我们启动容器,当卷已安装。
  2. 启动容器之前 ,更改文件server.keyUID:GID

由于在容器启动后设置此设置,将暗示篡改postgres图像的启动脚本-让我们选择在启动容器之前进行设置。 在要从中挂载它们的本地文件系统中。

设置600权限和postgres作为server.key所有者

如果您要使用alpine派生类,则需要将所有者/组更改为70:70 如果您使用的是debian衍生工具,请使用999:999

您的主机上可能没有用户,例如UID70 ,但这不是问题。

例:

chown 70:70 server.key # 70:70 for alpine, 999:999 for debian
chmod 600 server.key

设置640权限和root作为所有者server.key

这个例子也适用于高山图像

例:

chown 0:70 server.key
chmod 640 server.key

此时,您可以开始了。 您只需要将密钥和证书映射到容器中,然后像往常一样启动postgres。

解决方案(linux / unix / macOS)

我将在此处包括一个脚本片段,该片段将为您完成所有高山衍生产品。 本示例将设置server.key的根所有者和postgres组所有者。

# generate the server.key and server.crt
openssl req -new -text -passout pass:abcd -subj /CN=localhost -out server.req
openssl rsa -in privkey.pem -passin pass:abcd -out server.key
openssl req -x509 -in server.req -text -key server.key -out server.crt

# set postgres (alpine) user as owner of the server.key and permissions to 600
chown 0:70 server.key
chmod 640 server.key

# start a postgres docker container, mapping the .key and .crt into the image.
docker run -d --name postgres \ 
  -v "$PWD/server.crt:/var/lib/postgresql/server.crt:ro" \
  -v "$PWD/server.key:/var/lib/postgresql/server.key:ro" \
  postgres:11-alpine \
  -c ssl=on \
  -c ssl_cert_file=/var/lib/postgresql/server.crt \
  -c ssl_key_file=/var/lib/postgresql/server.key

我希望这可以清除一切吗?

这个要点是生成密钥和证书的密钥的来源。

自己构建映像(Windows解决方案)

我将提供有关如何自己构建映像的小型指南,以便您可以使用带有ssl的postgres数据库容器。 这同样适用于Windows。

这是将为您完成的Dockerfile:

Dockerfile

FROM postgres:11-alpine

# On Windows root will own the files, and they will have permissions 755
COPY server.key /var/lib/postgresql/server.key
COPY server.crt /var/lib/postgresql/server.crt

# update the privileges on the .key, no need to touch the .crt  
RUN chmod 600 /var/lib/postgresql/server.key
RUN chown postgres:postgres /var/lib/postgresql/server.key

使用以下方法生成图像:

docker build -t mypg:01 .

并运行:

docker run -d --name postgres mypg:01 \
  -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt \
  -c ssl_key_file=/var/lib/postgresql/server.key

在我的特殊情况下,我对通过 docker-compose 使用标准 postgres 图像时启用 SSL 感兴趣。 此解决方案允许initdb照常运行,这对于设置数据库和用户很有用。

docker-compose.yaml

version: '3'
services:
  postgres:
    image: postgres:12.2
    environment:
      - POSTGRES_PASSWORD=password
      - POSTGRES_USER=myuser
      - POSTGRES_HOST_AUTH_MTHOD=trust
    volumes:
      - ./postgres-initdb:/docker-entrypoint-initdb.d/
      - ./postgres-certs/:/var/lib/postgresql/certs/

postgres-initdb/config.sql

ALTER SYSTEM SET ssl_cert_file TO '/var/lib/postgresql/certs/server.crt';
ALTER SYSTEM SET ssl_key_file TO '/var/lib/postgresql/certs/server.key';
ALTER SYSTEM SET ssl TO 'ON';

这适用于任何配置。 对于 SSL,您还需要生成证书(取自Gist ):

set -euo pipefail

mkdir postgres-certs
cd postgres-certs

openssl req -new -text -passout pass:abcd -subj /CN=localhost -out server.req -keyout privkey.pem
openssl rsa -in privkey.pem -passin pass:abcd -out server.key
openssl req -x509 -in server.req -text -key server.key -out server.crt
chmod 600 server.key
test $(uname -s) == Linux && chown 999 server.key

MacOS 的正确解决方案

在 macOS 上,由于 osxfs 驱动程序的行为,容器中运行的任何 uid/gid 也是拥有已挂载文件的 uid/gid(因此容器上的文件所有者将与主机文件的所有者不同)。

在 MacOS 中,当我们更改容器中文件的所有者时,它会将所有者数据写入com.docker.owner扩展文件属性(而不是更新真实文件的所有者)。
所以我们必须设置com.docker.owner属性来设置 docker 中容器的文件所有者(仅在 MacOS 上)。

注意:如果您的 Postgres DB 的图像基于 alpine,请将0:999:999更改为0:70:70

chmod 600 server.key
xattr -w com.docker.owner 0:999:999 server.key # 0:70:70 for alpine-based image```

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM