Рейтинг:0

HaProxy accept-proxy + send-proxy действительно подключается

флаг br

Моя текущая реализация выглядит следующим образом:

  1. Впереди AWS Load Balancer (тип Network TCP/UDP) с двойным стеком, который перенаправляет на группу инстансов EC2.
  2. Эти экземпляры EC2 используют HaProxy для получения запросов к списку процессов.
  3. Список процессов — это экземпляры aiosmtpd (из Python).

Поскольку цель состоит в том, чтобы подключиться через SMTP, мне нужно знать IP-адрес клиента, но мне также нужно сначала отправить ответ.

Я заметил, что если

  • Я связываю переднюю часть без принять-прокси
  • но перенаправить поддерживаемый сервер, отправив отправить-прокси
  • И отключите Proxy v2 в AWS Load Balancer.

он отлично работает... только для IPv4 (??)!

IPv6 не работает, и вместо этого прокси возвращает мне IP-адрес балансировщика нагрузки AWS.

Итак, я попытался включить Proxy v2 на уровне AWS, установив принять-прокси на интерфейсе связывать и отправить-прокси на сервер бэкэнд-свойство.

На этот раз он работает как для IPv4/v6, НО он никогда не отправляет начальный ответ: никакие соединения с кодом Python не устанавливаются, пока первая строка не будет отправлена ​​​​от клиента!

В протоколе SMTP это невозможно: как сервер, я должен быть первым, кто отправит ответ.

Что случилось?

Вот моя конфигурация HaProxy:

Глобальный
    журнал /dev/лог локальный0
    журнал /dev/log local1 уведомление
    chroot /var/lib/haproxy
    пользовательский прокси
    группа haproxy
    демон

    максконн 60000

    # Шифры по умолчанию для использования в прослушивающих сокетах с поддержкой SSL.
    # Для получения дополнительной информации см. ciphers(1SSL). Этот список взят из:
    # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    # Альтернативный список с дополнительными директивами можно получить из
    # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
    ssl-default-bind-ciphers -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 предпочитаете-клиентские шифры no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets

    ssl-default-server-ciphers -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


значения по умолчанию
    тайм-аут соединения 5s
    тайм-аут клиента 30 сек.
    тайм-аут сервера 30 секунд
    режим TCP


smtp-интерфейс
    привязать :25 принять-прокси
    привязать :::25 принять-прокси

    default_backend smtp_backend


серверная часть smtp_backend
    режим TCP
    таймаут сервера 1м
    тайм-аут соединения 5s

    сервер srv1 127.0.0.1:2525 отправка-прокси maxconn 500

Я пытался добавить/удалить один или оба или ни один из принять-прокси и отправить-прокси и даже отправить-прокси-v2. Без всякого везения!

Ближе всего к тому, чтобы это работало, я был без Proxy v2, включенного на стороне AWS, нет. принять-прокси на фронтенд части и отправить-прокси на клиенте, но не работает для IPv6.


Я создал базовый скрипт для описания проблемы:

# -*- конфиг:utf-8 -*-
импортировать сокет, argparse


класс TestingServer (объект):
    def __init__(я, хост, порт):
        self.sock = сокет.сокет (сокет.AF_INET6)
        self.sock.setsockopt(сокет.SOL_SOCKET, сокет.SO_REUSEADDR, True)
        self.sock.setsockopt(сокет.IPPROTO_IPV6, сокет.IPV6_V6ONLY, False)
        self.sock.bind((хост, порт))
        print('Настройка слушателя на {}:{}'.format(хост, порт))

    деф слушай(я):
        print('Ожидание соединений...')
        self.sock.listen()

        пока верно:
            пытаться:
                клиент, адрес = self.sock.accept()
                print('Соединение есть!', адрес)
                client.send(b'250 Отправка исходных данных.\r\n')
                данные = клиент.recv(1024)
                print('Полученные данные:', данные)
                client.send(b'250 Gotcha')
                данные = клиент.recv(1024)
                print('Полученные данные 2:', данные)
                client.send(b'250 Second Gotcha')
                клиент.закрыть()
            кроме Исключения как e:
                print('Есть исключение!', e)
                проходят
            Ну наконец то:
                пытаться:
                    клиент.закрыть()
                кроме исключения:
                    проходят


если __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Запустить демон SMTPD.')
    parser.add_argument('--host', nargs='?', default='localhost', type=str)
    parser.add_argument('--port', nargs='?', по умолчанию=2552, тип=int)
    аргументы = парсер.parse_args()

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

При включении AWS Proxy v2 с принять-прокси за связывать и отправить-прокси за сервер, вот что происходит:

Запускаю сервер:

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

Настройка слушателя на :::2525

Ожидание подключения...

На моей локальной машине я делаю:

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

Попытка {ipv6}...

Подключено к {aws-loadbalancer-name}.elb.eu-west-3.amazonaws.com.

Экранирующий символ '^]'.

На сервере пока ничего.

На стороне клиента (телнет) пишу что угодно:

$> а [введите]

Затем, как только я нажимаю Enter, сервер показывает следующее:

Адрес: ('::ffff:127.0.0.1', 42494, 0, 0)

Есть связь! <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)

Полученные данные: b'PROXY TCP6 {clients_ip} {loadbalancer_ip} 44012 25\r\ns\r\n'

Итак, ясно, что по какой-то причине HaProxy не отправляет соединение с процессом Python, как только оно будет создано, а ожидает поступления первых данных.

Как я могу этого избежать?

Заранее спасибо!

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.