簡體   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