Điểm:0

HaProxy accept-proxy + send-proxy thực sự kết nối

lá cờ br

thực hiện hiện tại của tôi là như sau:

  1. Ở phía trước, một AWS Load Balancer (loại Network TCP/UDP) trên ngăn xếp kép, chuyển hướng đến một nhóm các phiên bản EC2
  2. Các phiên bản EC2 này đang chạy HaProxy để nhận các yêu cầu đối với danh sách các quy trình
  3. Danh sách các quy trình là các phiên bản aiosmtpd (từ Python).

Vì mục đích là kết nối qua SMTP, tôi cần biết IP của Máy khách, nhưng tôi cũng cần gửi phản hồi trước.

Những gì tôi nhận thấy là nếu

  • Tôi ràng buộc giao diện người dùng mà không cần chấp nhận-proxy
  • nhưng chuyển hướng máy chủ được hỗ trợ bằng cách gửi gửi-proxy
  • Và tắt Proxy v2 trên AWS Load Balancer

nó hoạt động hoàn hảo ... chỉ dành cho IPv4 (??)!

IPv6 không hoạt động và thay vào đó, Proxy trả lại cho tôi IP của Bộ cân bằng tải AWS.

Vì vậy, tôi đã thử bật Proxy v2 ở cấp AWS, cài đặt chấp nhận-proxy trên giao diện người dùng trói buộcgửi-proxy trên người phục vụ tài sản phụ trợ.

Lần này, nó hoạt động cho cả IPv4/v6, NHƯNG, nó không bao giờ gửi phản hồi ban đầu: Không có kết nối nào được thực hiện với mã python cho đến khi dòng đầu tiên được gửi từ máy khách!

Trong giao thức SMTP, điều này là không thể: Với tư cách là máy chủ, tôi phải là người đầu tiên gửi phản hồi.

Điều gì đang xảy ra?

Đây là cấu hình HaProxy của tôi:

toàn cầu
    nhật ký/dev/log cục bộ0
    log /dev/log local1 thông báo
    chroot /var/lib/haproxy
    người dùng haproxy
    nhóm haproxy
    yêu tinh

    maxconn 60000

    # Mật mã mặc định để sử dụng trên ổ cắm nghe hỗ trợ SSL.
    # Để biết thêm thông tin, hãy xem mật mã (1SSL). Danh sách này là từ:
    # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    # Có thể lấy danh sách thay thế với các chỉ thị bổ sung từ
    # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
    ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA -CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
    ssl-default-bind-optionsprefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets

    ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA -CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
    ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
    ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-ticket


mặc định
    hết thời gian kết nối 5s
    máy khách hết thời gian 30 giây
    máy chủ hết thời gian 30s
    chế độ tcp


giao diện người dùng smtp
    liên kết :25 chấp nhận proxy
    liên kết :::25 chấp nhận-proxy

    default_backend smtp_backend


phụ trợ smtp_backend
    chế độ tcp
    máy chủ hết thời gian chờ 1 phút
    hết thời gian kết nối 5s

    máy chủ srv1 127.0.0.1:2525 gửi proxy maxconn 500

Tôi đã thử thêm/xóa một trong hai hoặc cả hai hoặc không cái nào chấp nhận-proxygửi-proxy và ngay cả gửi-proxy-v2. Không có bất kỳ may mắn!

Lần gần nhất tôi thấy nó hoạt động là không có Proxy v2 nào được bật ở cuối AWS, không chấp nhận-proxy trên phần frontend và gửi-proxy trên máy khách, nhưng nó không hoạt động với IPv6.


Tôi đã tạo một tập lệnh cơ bản để mô tả sự cố:

# -*- cấu hình:utf-8 -*-
ổ cắm nhập khẩu, argparse


lớp Máy chủ kiểm tra (đối tượng):
    def __init__(bản thân, máy chủ, cổng):
        self.sock = socket.socket(socket.AF_INET6)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        self.sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
        self.sock.bind((máy chủ, cổng))
        print('Đang thiết lập trình nghe trên {}:{}'.format(host, port))

    chắc chắn lắng nghe (bản thân):
        print('Đang chờ kết nối...')
        self.sock.listen()

        trong khi Đúng:
            cố gắng:
                khách hàng, địa chỉ = self.sock.accept()
                print('Có kết nối!', địa chỉ)
                client.send(b'250 Đang gửi dữ liệu ban đầu.\r\n')
                dữ liệu = client.recv(1024)
                print('Dữ liệu nhận được:', dữ liệu)
                client.send(b'250 Gotcha')
                dữ liệu = client.recv(1024)
                print('Dữ liệu nhận được 2:', dữ liệu)
                client.send(b'250 Gotcha thứ hai')
                khách hàng.đóng()
            ngoại trừ Ngoại lệ như e:
                print('Có một ngoại lệ!', e)
                vượt qua
            cuối cùng:
                cố gắng:
                    khách hàng.đóng()
                ngoại trừ Ngoại lệ:
                    vượt qua


nếu __name__ == '__main__':
    trình phân tích cú pháp = argparse.ArgumentParser(description='Bắt đầu trình nền SMTPD.')
    parser.add_argument('--host', nargs='?', default='localhost', type=str)
    parser.add_argument('--port', nargs='?', default=2552, type=int)
    args = trình phân tích cú pháp.parse_args()

    Máy chủ kiểm tra (args.host, args.port).listen()

Khi bật AWS Proxy v2, với chấp nhận-proxytrói buộcgửi-proxyngười phục vụ, đây là những gì đang xảy ra:

Tôi khởi động máy chủ:

$> python testserver.py --port 2525 --host ::

Thiết lập trình nghe trên :::2525

Đang chờ kết nối...

Trên máy cục bộ của tôi, tôi thực hiện:

$> telnet {aws-loadbalancer-name}.elb.eu-west-3.amazonaws.com 25

Đang thử {ipv6}...

Đã kết nối với {aws-loadbalancer-name}.elb.eu-west-3.amazonaws.com.

Ký tự thoát là '^]'.

Chưa có gì trên máy chủ.

Ở phía khách hàng (telnet), tôi viết bất cứ thứ gì:

$> một [nhập]

Sau đó, ngay khi tôi nhấn enter, máy chủ sẽ hiển thị như sau:

Địa chỉ là: ('::ffff:127.0.0.1', 42494, 0, 0)

Có một kết nối! <socket.socket fd=4, family=AddressFamily.AF_INET6, type=SocketKind.SOCK_STREAM, proto=0, laddr=('::ffff:127.0.0.1', 2525, 0, 0), raddr=(':: ffff:127.0.0.1', 42494, 0, 0)> ('::ffff:127.0.0.1', 42494, 0, 0)

Dữ liệu đã nhận: b'PROXY TCP6 {clients_ip} {loadbalancer_ip} 44012 25\r\ns\r\n'

Vì vậy, rõ ràng là vì một lý do nào đó, HaProxy không gửi kết nối đến quy trình Python ngay khi một kết nối được tạo mà chờ dữ liệu đầu tiên đến.

Làm thế nào tôi có thể tránh điều đó?

Cảm ơn bạn trước!

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.