使用ssl证书和带有卷的密钥部署postgresql docker

时间:2019-03-08 23:04:40

标签: postgresql docker ssl permissions

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

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

谢谢。

1 个答案:

答案 0 :(得分:3)

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

来自PostgreSQL Documentation on this subject

  

在Unix系统上,server.key上的权限必须禁止任何   进入世界或团体;通过命令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也将设置为{{ 1}}。如果然后将文件映射到容器中,并从内部进行观察-它也只会看到1000:1000。这意味着,当从linux主机映射时,我们可以从容器的内部和外部控制1000:1000

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

在postgres UID:GID派生图像中,alpine用户/组具有postgres UID:GID。在70:70派生上,postgres debianUID:GID。并不令人惊讶,root都在它们两个上都999:999

这意味着必须:

  1. 在已装入卷的情况下,在启动容器后,更改文件0:0的{​​{1}}的{​​{1}}。
  2. 更改文件UID:GID的{​​{1}},之前,我们启动容器

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

设置server.key的权限,并将UID:GID设置为server.key的所有者

如果要使用600派生词,则需要将所有者/组更改为postgres。如果您使用server.key派生词,则使用alpine

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

示例:

999:999

设置UID的权限,并将70设置为chown 70:70 server.key # 70:70 for alpine, 999:999 for debian chmod 600 server.key 的所有者

此示例也适用于高山图像

示例:

640

这时您很高兴。您只需要将密钥和证书映射到容器中,然后像往常一样启动postgres。

解决方案(linux / unix / macOS)

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

root

我希望这可以解决问题吗?

密钥生成密钥和证书的来源是this gist

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

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

以下是将为您完成的Dockerfile:

server.key

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

使用以下图像构建图像:

# 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

并运行:

Dockerfile