วิธีเชื่อมต่อกับ Traefik TCP Services ที่เปิดใช้งานการกำหนดค่า TLS ได้อย่างไร


13

ฉันกำลังพยายามกำหนดค่าTraefikเพื่อให้ฉันสามารถเข้าถึงบริการผ่านชื่อโดเมนและฉันไม่จำเป็นต้องตั้งค่าพอร์ตอื่น ยกตัวอย่างเช่นสองบริการ MongoDB ทั้งในพอร์ตเริ่มต้น แต่ในโดเมนที่แตกต่างกันและexample.localhost example2.localhostตัวอย่างนี้ใช้ได้เฉพาะ ฉันหมายถึงกรณีอื่นอาจใช้ได้ แต่ฉันไม่สามารถเชื่อมต่อกับพวกเขาและฉันไม่เข้าใจว่าปัญหาคืออะไร นี่อาจไม่เป็นปัญหากับ Traefik

ฉันได้เตรียมที่เก็บพร้อมตัวอย่างที่ใช้งานได้ คุณเพียงแค่ต้องสร้างใบรับรองของคุณเองด้วย mkcert หน้าเว็บที่example.localhostส่งคืน403 Forbiddenข้อผิดพลาด แต่คุณไม่ควรกังวลเพราะวัตถุประสงค์ของการกำหนดค่านี้เพื่อแสดงว่า SSL ใช้งานได้ (กุญแจล็อคสถานะสีเขียว) 403จึงไม่มุ่งเน้นไปที่

การเชื่อมต่อ SSL กับmongoบริการใช้งานได้เท่านั้น ฉันทดสอบด้วยโปรแกรมRobo 3T หลังจากเลือกการเชื่อมต่อ SSL แล้วให้เปิดโฮสต์example.localhostและเลือกใบรับรองสำหรับการเชื่อมต่อที่ลงชื่อด้วยตนเอง (หรือเป็นของตัวเอง) และนั่นคือสิ่งเดียวที่ทำงานเช่นนั้น การเชื่อมต่อกับredis( Redis Desktop Manager ) และpgsql( PhpStorm , DBeaver , DbVisualizer ) ไม่ทำงานไม่ว่าฉันจะให้ใบรับรองหรือไม่ก็ตาม ฉันไม่ส่งต่อ SSL ไปยังบริการฉันเชื่อมต่อกับ Traefik เท่านั้น ฉันใช้เวลานานหลายชั่วโมงกับมัน ฉันค้นหาในอินเทอร์เน็ต ฉันยังไม่พบคำตอบ มีใครแก้ไขปัญหานี้บ้าง?

PS ฉันทำงานบน Linux Mint ดังนั้นการกำหนดค่าของฉันควรทำงานในสภาพแวดล้อมนี้โดยไม่มีปัญหา ฉันจะขอวิธีแก้ไขสำหรับ Linux


หากคุณไม่ต้องการเรียกดู พื้นที่เก็บข้อมูลฉันแนบไฟล์ที่สำคัญที่สุด:

นักเทียบท่า-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 -installสำหรับ CA ด้วย)
  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
  • แคลิฟอร์เนีย: ~/.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. สามารถเชื่อมต่อกับ Postgres ผ่าน IP (ข้อมูลจาก Traefik)
jdbc:postgresql://172.21.0.4:5432/postgres?sslmode=disable

ป้อนคำอธิบายรูปภาพที่นี่

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

ป้อนคำอธิบายรูปภาพที่นี่


ลอง telet (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 ฉันมีคำขอไม่ถูกต้องเมื่อปิดการเชื่อมต่อ ฉันไม่รู้ว่ามันหมายถึงอะไรและไม่ว่ามันจะต้องหมายความว่าอะไร


I can't connect to them-> คุณทดสอบอย่างไรและข้อผิดพลาดคืออะไร
Jan Garaj

@JanGaraj ฉันได้เพิ่มคำแนะนำทีละขั้นตอน
Gander

Connections to redis (Redis Desktop Manager) ... do not workแต่ภาพหน้าจอแสดงSuccessful connection-? ทำไมคุณจะไม่ได้รับการทดสอบในระดับต่ำที่มีcurl, openssl, telnet, ...? ทำไมคุณไม่ทดสอบnetstatว่าพอร์ตแอปเหล่านั้นถูกผูกไว้กับ traefik บน127.0.0.1อินเทอร์เฟซจริงๆ
Jan Garaj

คอนเทนเนอร์ที่มี traefik และฐานข้อมูลทำงานบนโฮสต์เดียวกันหรือไม่
Ryabchenko Alexander

@ RyabchenkoAlexander ใช่แล้วใน container docker
Gander

คำตอบ:


2

อย่างน้อยสำหรับปัญหา PostgreSQL ดูเหมือนว่าการเชื่อมต่อจะเริ่มต้นในข้อความธรรมดาแล้วอัปเกรดเป็น TLS:

ดังนั้นจึงเป็นไปไม่ได้ที่จะใช้การเลิกใช้TLSกับพร็อกซีถ้าพร็อกซีดังกล่าวไม่รองรับการจับมือของ cleartext + อัพเกรดเป็นฟังก์ชัน TLS ของโปรโตคอล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.