SSL 模式下的 PostgreSQL 返回“服务器不支持 SSL,但需要 SSL”

问题描述 投票:0回答:1

嗨:)希望你做得很好!

我尝试在 Postgres docker 容器和 FastAPI 容器之间启用 SSL 通信,但是正如您从标题中可以看出的那样,有些东西不起作用:/

我阅读了文档,据说我已经相应地设置了所有内容。例如:

  1. 我创建了根 CA,然后使用根 CA 为 postgres 服务器创建了密钥和签名证书。

  2. 我已经以这种方式配置了postgresql.conf文件:

... defaults

# - SSL -

ssl = on
ssl_ca_file = '/var/lib/postgresql/data/root.crt'
ssl_cert_file = '/var/lib/postgresql/data/server.crt'
ssl_key_file = '/var/lib/postgresql/data/server.key'
#ssl_crl_file = ''
#ssl_crl_dir = ''
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
#ssl_prefer_server_ciphers = on
#ssl_ecdh_curve = 'prime256v1'
#ssl_min_protocol_version = 'TLSv1.2'
#ssl_max_protocol_version = ''
#ssl_dh_params_file = ''
#ssl_passphrase_command = ''
#ssl_passphrase_command_supports_reload = off

... defaults

这就是我的树的样子:

.
├── docker-compose.yaml
├── Dockerfile
├── main.py
├── postgresql.conf
├── README.md
├── ssl-client
│   ├── root.crt
│   ├── root.csr
│   ├── root.key
│   ├── server.crt
│   ├── server.csr
│   └── server.key
└── ssl-server
    ├── pgdata  [error opening dir]   -> because it is using its own user (999)
    ├── root.crt
    ├── root.csr
    ├── root.key
    ├── server.crt
    ├── server.csr
    └── server.key

这就是我将所有内容传递到容器的方式:

version: '3.8'
services:
  app:
    container_name: python-app
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - '8000:80'
    depends_on:
      - postgres
    networks:
      - postgres-ssl

  postgres:
    container_name: postgres
    image: postgres:latest
    environment:
      POSTGRES_USER: username
      POSTGRES_PASSWORD: password
      POSTGRES_DB: database
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - ./postgresql.conf:/etc/postgresql/postgresql.conf
      - ./ssl-server:/var/lib/postgresql/data/
    ports:
      - '5432:5432'
    networks:
      - postgres-ssl

networks:
  postgres-ssl:
    name: postgres-ssl

最后,这是我的 python 代码,尽管这里一切都按预期工作,因为我收到了上面的错误:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from typing import List

app = FastAPI()

DATABASE_URL = "postgresql+psycopg2://username:password@postgres/database?sslmode=require"

engine = create_engine(DATABASE_URL)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


class Student(Base):
    __tablename__ = 'students'

    id = Column(Integer, primary_key=True, nullable=False)
    name = Column(String, nullable=False)

class StudentRequest(BaseModel):
    name: str

    class Config:
        orm_mode = True

class StudentCreate(BaseModel):
   name :str

@app.post("/items/", response_model=StudentRequest)
def create_item(item: StudentCreate):
    db = SessionLocal()
    db_item = Student(**item.dict())
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    db.close()
    return db_item

@app.get("/items/", response_model=List[StudentRequest])
def get_items():
    db = SessionLocal()
    items = db.query(Student).all()
    db.close()
    return items

@app.get("/")
async def read_root():
    return {"message": "Hello, FastAPI with PostgreSQL using SSL!"}

如果我尝试通过将默认配置文件安装在同一 PGDATA 路径中来“覆盖”默认配置文件,则会收到错误:

这是本例的 docker-compose:

version: '3.8'
services:
  app:
    container_name: python-app
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - '8000:80'
    depends_on:
      - postgres
    networks:
      - postgres-ssl

  postgres:
    container_name: postgres
    image: postgres:latest
    environment:
      POSTGRES_USER: username
      POSTGRES_PASSWORD: password
      POSTGRES_DB: database
      PGDATA: /etc/postgresql/data
    volumes:
      - ./postgresql.conf:/etc/postgresql/data/postgresql.conf
      - ./ssl-server:/etc/postgresql/data/ssl-server
    ports:
      - '5432:5432'
    networks:
      - postgres-ssl

networks:
  postgres-ssl:
    name: postgres-ssl

我在启动时遇到的错误:

postgres  | The files belonging to this database system will be owned by user "postgres".
postgres  | This user must also own the server process.
postgres  | 
postgres  | 
postgres  | The database cluster will be initialized with locale "en_US.utf8".
postgres  | The default database encoding has accordingly been set to "UTF8".
postgres  | The default text search configuration will be set to "english".
postgres  | 
postgres  | Data page checksums are disabled.
postgres  | 
postgres  | 
postgres  | initdb: error: directory "/etc/postgresql/data" exists but is not empty
postgres  | initdb: hint: If you want to create a new database system, either remove or empty the directory "/etc/postgresql/data" or run initdb with an argument other than "/etc/postgresql/data".
postgres exited with code 1

我在这里遗漏了什么吗?为什么这没有设置 SSL 连接? :/

老实说我很困惑,如果你能在这里帮助我,我将非常非常感激!

预先感谢您,祝您有美好的一天!

python postgresql docker ssl psycopg2
1个回答
1
投票

如果 PGDATA 设置为 /var/lib/postgresql/data/pgdata,那么将自定义配置文件放入 /etc/postgresql/ 不会执行任何操作。它会忽略它并使用默认值。

此外,证书和其他内容需要位于 PGDATA 内部,而不是它的兄弟姐妹。

© www.soinside.com 2019 - 2024. All rights reserved.