Puncte:0

HaProxy accept-proxy + send-proxy se conectează cu adevărat

drapel br

Implementarea mea actuală este următoarea:

  1. În față, un AWS Load Balancer (tip Network TCP/UDP) pe dual-stack, care redirecționează către o flotă de instanțe EC2
  2. Aceste instanțe EC2 rulează HaProxy pentru a primi solicitările către o listă de procese
  3. Lista proceselor sunt instanțe aiosmtpd (din Python).

Deoarece scopul este să mă conectez prin SMTP, trebuie să cunosc IP-ul Clientului, dar trebuie să trimit mai întâi răspunsul.

Ceea ce am observat este că dacă

  • Leagă front-end-ul fără accept-proxy
  • dar redirecționează serverul susținut prin trimitere trimite-proxy
  • Și dezactivați Proxy v2 pe AWS Load Balancer

funcționează perfect... numai pentru IPv4 (??) !

IPv6 nu funcționează, iar proxy-ul îmi returnează IP-ul AWS Load balancer.

Așa că am încercat să activez Proxy v2 la nivel AWS, setare accept-proxy pe front-end lega și trimite-proxy pe Server proprietate backend.

De data aceasta, funcționează atât pentru IPv4/v6, DAR, nu trimite niciodată răspunsul inițial: Nu se fac conexiuni la codul python până când prima linie este trimisă de la client!

În protocolul SMTP, acest lucru nu este posibil: ca server, trebuie să fiu primul care trimite un răspuns.

Ce se întâmplă?

Iată configurația mea HaProxy:

global
    log /dev/log local0
    log /dev/log local1 notificare
    chroot /var/lib/haproxy
    utilizator haproxy
    haproxy de grup
    demonul

    maxconn 60000

    # Cifruri implicite de utilizat pe prizele de ascultare activate pentru SSL.
    # Pentru mai multe informații, consultați ciphers(1SSL). Aceasta lista este de la:
    # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    # O listă alternativă cu directive suplimentare poate fi obținută de la
    # 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-AESCMDHE-RSA-AES256-ECDSA-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-options prefer-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-AESCMDHE-RSA-AES256-ECDSA-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-tickets


implicite
    timeout conectare 5s
    timeout client 30s
    timeout server 30s
    modul tcp


frontend smtp
    bind :25 accept-proxy
    bind :::25 accept-proxy

    default_backend smtp_backend


backend smtp_backend
    modul tcp
    server timeout 1m
    timeout conectare 5s

    server srv1 127.0.0.1:2525 trimite-proxy maxconn 500

Am încercat să adaug/eliminăm unul sau ambele sau niciunul accept-proxy și trimite-proxy și chiar trimite-proxy-v2. Fara noroc!

Cel mai aproape am fost să funcționeze este fără Proxy v2 activat la sfârșitul AWS, nu accept-proxy pe partea frontală și trimite-proxy pe client, dar nu funcționează pentru IPv6.


Am creat un script de bază pentru a descrie problema:

# -*- config:utf-8 -*-
import socket, argparse


clasa TestingServer(obiect):
    def __init__(self, host, port):
        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((gazdă, port))
        print('Se configurează ascultatorul pe {}:{}'.format(gazdă, port))

    def ascult (auto):
        print('Se așteaptă conexiunile...')
        self.sock.listen()

        în timp ce este adevărat:
            încerca:
                client, adresa = self.sock.accept()
                print('Am o conexiune!', adresa)
                client.send(b'250 Se trimite date inițiale.\r\n')
                date = client.recv(1024)
                print('Date primite:', date)
                client.send(b'250 Gotcha')
                date = client.recv(1024)
                print('Date primite 2:', date)
                client.send(b'250 Second gotcha')
                client.close()
            cu excepția excepției ca e:
                print („Am o excepție!”, e)
                trece
            in cele din urma:
                încerca:
                    client.close()
                cu excepția excepției:
                    trece


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Porniți un daemon SMTPD.')
    parser.add_argument('--host', nargs='?', default='localhost', type=str)
    parser.add_argument('--port', nargs='?', default=2552, type=int)
    args = parser.parse_args()

    TestingServer(args.host, args.port).listen()

Când setați AWS Proxy v2 activat, cu accept-proxy pentru lega și trimite-proxy pentru Server, iată ce se întâmplă:

pornesc serverul:

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

Configurarea ascultătorului pe :::2525

În așteptarea conexiunilor...

Pe mașina mea locală, fac:

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

Se încearcă {ipv6}...

Conectat la {aws-loadbalancer-name}.elb.eu-west-3.amazonaws.com.

Caracterul de evacuare este „^]”.

Nimic încă pe server.

La capătul clientului (telnet), scriu orice:

$> a [intra]

Apoi, de îndată ce apăs pe Enter, serverul arată următoarele:

Adresa este: ('::ffff:127.0.0.1', 42494, 0, 0)

Am o conexiune! <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)

Date primite: b'PROXY TCP6 {clients_ip} {loadbalancer_ip} 44012 25\r\ns\r\n'

Deci, în mod clar, din anumite motive, HaProxy nu trimite conexiunea la procesul Python de îndată ce este creată una, dar așteaptă să vină primele date.

Cum pot evita asta?

Multumesc anticipat!

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.