[postgresql] TLS 구성을 사용하여 Traefik TCP 서비스에 연결하는 방법은 무엇입니까?

도메인 이름을 통해 서비스에 액세스 할 수 있고 다른 포트를 설정할 필요가 없도록 Traefik 을 구성하려고합니다 . 예를 들어, 두 개의 MongoDB 서비스는 기본 포트 example.localhost와 도메인이 서로 다릅니다 example2.localhost. 이 예제 만 작동합니다. 다른 경우에는 효과가 있지만 연결할 수 없으며 문제가 무엇인지 이해할 수 없습니다. 이것은 아마도 Traefik에서는 문제가되지 않습니다.

작동하는 예제 로 저장소 를 준비했습니다 . mkcert로 자체 인증서를 생성하면됩니다 . 의 페이지 example.localhost403 Forbidden오류 를 반환 하지만이 구성의 목적은 SSL이 작동 중임을 표시하는 것입니다 (자물쇠, 녹색 상태). 따라서에 집중하지 마십시오 403.

mongo서비스에 대한 SSL 연결 만 작동합니다. Robo 3T 프로그램으로 테스트했습니다 . SSL 연결을 선택한 후 호스트를 제공하고 example.localhost자체 서명 (또는 자체) 연결을위한 인증서를 선택하면 작동합니다. 그리고 그것이 그렇게 작동하는 유일한 것입니다. 에 연결 redis( 레디 스 데스크탑 관리자 )와로 pgsql( PhpStorm , DBeaver , DbVisualizer는 )에 관계없이 내가 인증서를 제공하거나하지 여부,하지 작업을 수행. SSL을 서비스에 전달하지 않고 Traefik에만 연결합니다. 나는 그것에 오랜 시간을 보냈다. 인터넷을 검색했습니다. 아직 답을 찾지 못했습니다. 누구든지 이것을 해결 했습니까?

추신. Linux Mint에서 작업하므로 구성이 아무 문제없이이 환경에서 작동해야합니다. Linux 용 솔루션을 요청합니다.


저장소 를 탐색하지 않으려면 가장 중요한 파일을 첨부하십시오.

docker-compose.yml

version: "3.7"

services:
    traefik:
        image: traefik:v2.0
        ports:
            - 80:80
            - 443:443
            - 8080:8080
            - 6379:6379
            - 5432:5432
            - 27017:27017
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock:ro
            - ./config.toml:/etc/traefik/traefik.config.toml:ro
            - ./certs:/etc/certs:ro
        command:
            - --api.insecure
            - --accesslog
            - --log.level=INFO
            - --entrypoints.http.address=:80
            - --entrypoints.https.address=:443
            - --entrypoints.traefik.address=:8080
            - --entrypoints.mongo.address=:27017
            - --entrypoints.postgres.address=:5432
            - --entrypoints.redis.address=:6379
            - --providers.file.filename=/etc/traefik/traefik.config.toml
            - --providers.docker
            - --providers.docker.exposedByDefault=false
            - --providers.docker.useBindPortIP=false

    apache:
        image: php:7.2-apache
        labels:
            - traefik.enable=true
            - traefik.http.routers.http-dev.entrypoints=http
            - traefik.http.routers.http-dev.rule=Host(`example.localhost`)
            - traefik.http.routers.https-dev.entrypoints=https
            - traefik.http.routers.https-dev.rule=Host(`example.localhost`)
            - traefik.http.routers.https-dev.tls=true
            - traefik.http.services.dev.loadbalancer.server.port=80
    pgsql:
        image: postgres:10
        environment:
            POSTGRES_DB: postgres
            POSTGRES_USER: postgres
            POSTGRES_PASSWORD: password
        labels:
            - traefik.enable=true
            - traefik.tcp.routers.pgsql.rule=HostSNI(`example.localhost`)
            - traefik.tcp.routers.pgsql.tls=true
            - traefik.tcp.routers.pgsql.service=pgsql
            - traefik.tcp.routers.pgsql.entrypoints=postgres
            - traefik.tcp.services.pgsql.loadbalancer.server.port=5432
    mongo:
        image: mongo:3
        labels:
            - traefik.enable=true
            - traefik.tcp.routers.mongo.rule=HostSNI(`example.localhost`)
            - traefik.tcp.routers.mongo.tls=true
            - traefik.tcp.routers.mongo.service=mongo
            - traefik.tcp.routers.mongo.entrypoints=mongo
            - traefik.tcp.services.mongo.loadbalancer.server.port=27017
    redis:
        image: redis:3
        labels:
            - traefik.enable=true
            - traefik.tcp.routers.redis.rule=HostSNI(`example.localhost`)
            - traefik.tcp.routers.redis.tls=true
            - traefik.tcp.routers.redis.service=redis
            - traefik.tcp.routers.redis.entrypoints=redis
            - traefik.tcp.services.redis.loadbalancer.server.port=6379

config.toml

[tls]
[[tls.certificates]]
certFile = "/etc/certs/example.localhost.pem"
keyFile = "/etc/certs/example.localhost-key.pem"

빌드 및 실행

mkcert example.localhost # in ./certs/
docker-compose up -d

단계별 준비

  1. mkcert 설치 ( mkcert -installCA 에서도 실행 )
  2. 코드 복제
  3. 에서 certs폴더 실행mkcert example.localhost
  4. 로 컨테이너 시작 docker-compose up -d
  5. https : //example.localhost/ 페이지를 열고 안전한 연결인지 확인하십시오
  6. 주소 경우 HTTP : //example.localhost/가 도달 할 수없는, 추가 127.0.0.1 example.localhost/etc/hosts

인증서 :

  • 공공의: ./certs/example.localhost.pem
  • 은밀한: ./certs/example.localhost-key.pem
  • CA : ~/.local/share/mkcert/rootCA.pem

MongoDB 테스트

  1. Robo 3T 설치
  2. 새로운 연결 만들기 :
    • 주소: example.localhost
    • SSL 프로토콜 사용
    • CA 인증서 : rootCA.pem(또는 자체 서명 된 인증서)
  3. 테스트 도구 :

테스트

Redis 테스트

  1. RedisDesktopManager 설치
  2. 새로운 연결 만들기 :
    • 주소: example.localhost
    • SSL
    • 공개 키 : example.localhost.pem
    • 개인 키 : example.localhost-key.pem
    • 권위: rootCA.pem
  3. 테스트 도구 :

테스트


지금까지:

  1. IP를 통해 Postgres에 연결할 수 있습니다 (Traefik의 정보)
jdbc:postgresql://172.21.0.4:5432/postgres?sslmode=disable

여기에 이미지 설명을 입력하십시오

jdbc:postgresql://172.21.0.4:5432/postgres?sslfactory=org.postgresql.ssl.NonValidatingFactory

여기에 이미지 설명을 입력하십시오


전화를 겁니다 (도커를 다시 시작할 때마다 IP가 변경됨).

> telnet 172.27.0.5 5432
Trying 172.27.0.5...
Connected to 172.27.0.5.
Escape character is '^]'.
^]
Connection closed by foreign host.
> telnet example.localhost 5432
Trying ::1...
Connected to example.localhost.
Escape character is '^]'.
^]
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close

400 Bad RequestConnection closed by foreign host.

postgres에 직접 연결하면 데이터가 좋습니다. Traefik을 통해 연결하면 연결을 닫을 때 잘못된 요청이 발생합니다. 나는 이것이 무엇을 의미하는지 그리고 그것이 무엇을 의미해야하는지 전혀 모른다.



답변

적어도 PostgreSQL 문제의 경우 연결이 일반 텍스트로 시작된 다음 TLS로 업그레이드 된 것으로 보입니다.

따라서 프록시가이 일반 텍스트 핸드 셰이크 + 프로토콜의 TLS 기능으로의 업그레이드를 지원하지 않는 경우 프록시와 함께 TLS 종료 를 사용하는 것은 기본적으로 불가능 합니다.


답변