Не удается получить доступ к веб-серверу воздушного потока через HTTPS балансировщика нагрузки AWS, поскольку воздушный поток перенаправляет меня на HTTP

У меня есть веб-сервер воздушного потока, настроенный на EC2, он прослушивает порт 8080.

У меня есть AWS ALB (балансировщик нагрузки приложений) перед EC2, я прослушиваю https 80 (с выходом в Интернет), а целевой порт экземпляра обращен к http 8080.

Я не могу просматривать https: // ‹ссылка воздушного потока> из браузера, потому что веб-сервер воздушного потока перенаправляет меня на http: //‹ ссылка воздушного потока> / admin, который ALB не прослушивает.

Если я просматриваю https: // ‹ссылка воздушного потока> / admin / airflow / login? Next =% 2Fadmin% 2F из браузера, я вижу страницу входа, потому что эта ссылка меня не перенаправляет.

Мой вопрос в том, как изменить воздушный поток, чтобы при просмотре https: // ‹airflow link> веб-сервер воздушного потока перенаправлял меня на https: ..., а не на http: // ....., чтобы AWS ALB мог обрабатывать запрос.

Я попытался изменить base_url файла airflow.cfg с http://localhost:8080 на https://localhost:8080, согласно приведенному ниже ответу, но я не вижу разницы с моим изменением ....

В любом случае, как получить доступ к https: // ‹ссылка воздушного потока> из ALB?


person user389955    schedule 24.01.2018    source источник


Ответы (7)


Поскольку они используют Gunicorn, вы можете настроить значение forwarded_allow_ips как переменную окружения вместо того, чтобы использовать промежуточный прокси, такой как Nginx.

В моем случае я просто установил FORWARDED_ALLOW_IPS = *, и он работает отлично.

В ECS вы можете установить это в конфигурации задачи веб-сервера, если вы используете один образ докера для всех задач Airflow (веб-сервер, планировщик, рабочий и т. Д.).

person Nathan Clayton    schedule 21.09.2018

Собственное решение пользователя user389955, вероятно, является лучшим подходом, но для тех, кто ищет быстрое решение (или хочет получить лучшее представление о том, что происходит), это, похоже, является виновником.

В следующем файле (дистрибутив Python может отличаться):

/usr/local/lib/python3.5/dist-packages/gunicorn/config.py

В следующем разделе предотвращается пересылка заголовков из чего-либо, кроме локального.

class ForwardedAllowIPS(Setting):
    name = "forwarded_allow_ips"
    section = "Server Mechanics"
    cli = ["--forwarded-allow-ips"]
    meta = "STRING"
    validator = validate_string_to_list
    default = os.environ.get("FORWARDED_ALLOW_IPS", "127.0.0.1")
    desc = """\
        Front-end's IPs from which allowed to handle set secure headers.
        (comma separate).

        Set to ``*`` to disable checking of Front-end IPs (useful for setups
        where you don't know in advance the IP address of Front-end, but
        you still trust the environment).

        By default, the value of the ``FORWARDED_ALLOW_IPS`` environment
        variable. If it is not defined, the default is ``"127.0.0.1"``.
        """

Переход с 127.0.0.1 на определенный IP-адрес или *, если IP-адрес неизвестен, поможет.

На данный момент я не нашел способа установить этот параметр из самой конфигурации воздушного потока. Если найду способ, обновлю свой ответ.

person Doug    schedule 22.08.2018

Наконец я сам нашел решение.

Я представил обратный прокси-сервер nginx между ALB и веб-сервером воздушного потока: т.е. запрос https -> ALB: 443 -> прокси nginx: 80 -> веб-сервер: 8080. Я заставляю прокси-сервер nginx сообщать веб-серверу воздушного потока, что исходный запрос - это https, а не http, добавляя заголовок http «X-Forwarded-Proto https».

Сервер nginx совмещен с веб-сервером. и я установил его конфигурацию как /etc/nginx/sites-enabled/vhost1.conf (см. ниже). Кроме того, я удаляю файл конфигурации / etc / nginx / sites-enabled / default.

server {
    listen 80;
    server_name <domain>;
    index index.html index.htm;
    location / {
      proxy_pass_header Authorization;
      proxy_pass http://localhost:8080;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto https;
      proxy_http_version 1.1;
      proxy_redirect off;
      proxy_set_header Connection "";
      proxy_buffering off;
      client_max_body_size 0;
      proxy_read_timeout 36000s;
    }
}
person user389955    schedule 07.02.2018
comment
Почему вы заставляете прокси-сервер nginx сообщать веб-серверу воздушного потока, что исходный запрос - это https, а не http? Это необходимо? - person alex; 25.09.2020

Я думаю у вас все работает правильно. Перенаправление, которое вы видите, ожидается, поскольку веб-сервер настроен на перенаправление с / на /admin. Если вы используете curl, вы можете передать флаг -L / --location, чтобы следовать перенаправлениям, и это должно привести вас к списку DAG.

Еще одна хорошая конечная точка для тестирования - https://<airflow domain name>/health (без косой черты в конце, иначе вы получите 404!). Он должен вернуть «Сервер здоров!».

Убедитесь, что у вас есть https:// в base_url в разделе веб-сервера вашей конфигурации воздушного потока.

person Daniel Huang    schedule 24.01.2018
comment
Спасибо, Даниэль, если я попытаюсь перейти на https: // ‹доменное имя воздушного потока› / admin прямо из браузера, я получу страницу! поэтому проблема связана с перенаправлением веб-сервера воздушного потока https: // ‹доменное имя воздушного потока› на http: // ‹доменное имя воздушного потока› / admin, которое мой AWS ALB не прослушивает. у моего текущего airflow.cfg есть base_url = http: // localhost: 8080. вы имеете в виду, что я должен изменить его на base_url = https: // localhost: 8080? Я не понимаю. мой веб-сервер прослушивает http-порт 8080, это ALB перед ним, который слушает https 80. - person user389955; 24.01.2018
comment
Я думаю, что base_url не влияет на перенаправления и используется только для писем. - person dstandish; 01.06.2021

Углубляясь в документацию по Gunicorn: кажется, можно передать любую командную строку аргумент (при вызове команды gunicorn) через переменную среды GUNICORN_CMD_ARGS.

Итак, я пытаюсь установить GUNICORN_CMD_ARGS=--forwarded-allow-ips=*, поскольку весь трафик будет поступать в мой экземпляр из AWS ALB ... Я предполагаю, что подстановочный знак можно заменить фактическим IP-адресом ALB, видимым экземпляром, но это будет быть следующим шагом ...

Поскольку я использую ECS, я передаю его как:

            - Name: GUNICORN_CMD_ARGS
              Value: --forwarded-allow-ips=*

в Environment моей задачи определение контейнера .

PS: из документа эта возможность была добавлена ​​начиная с Gunicorn 19.7; для сравнения, Airflow 1.10.9, похоже, работает на Gunicorn 19.10, так что хорошо работать с любой (более или менее) последней версией Airflow!

person Bluu    schedule 01.02.2021

Я тоже столкнулся с этой проблемой при использовании официальной диаграммы управления воздушным потоком apache (версия 1.0.0).

Проблема

Первоначально я настроил службу веб-сервера с типом LoadBalancer.

webserver:
  service:
    type: LoadBalancer
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-internal: "true"
      service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-west-2:1234512341234:certificate/231rc-r12c3h-1rch3-1rch3-rc1h3r-1r3ch
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp

В результате был создан классический эластичный балансировщик нагрузки.

В основном это сработало, но когда я щелкнул логотип воздушного потока (который ссылается на https://my-domain.com), я был перенаправлен на http://my-domain.com/home, что не удалось, потому что балансировщик нагрузки был настроен на использование только HTTPS.

Решение

Я решил эту проблему, установив AWS Load Balancer Controller. в моем кластере EKS, а затем настройте вход.

Часть конфигурации диаграммы, относящаяся к входу, выглядит так:

ingress:
  enabled: true
  web:
    host: my-airflow-address.com
    annotations:
      kubernetes.io/ingress.class: alb
      alb.ingress.kubernetes.io/subnets: subnet-01234,subnet-01235,subnet-01236
      alb.ingress.kubernetes.io/scheme: internal  # if in private subnets
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
webserver:
  service:
    type: NodePort

Примечания

Возможно, можно настроить веб-сервер для использования ALB вместо классического ELB и настроить его для обработки HTTP-маршрутизации, но я не тестировал его.

person dstandish    schedule 01.06.2021

Мы решили эту проблему в моей команде, добавив прослушиватель HTTP к нашему ALB, который перенаправляет весь HTTP-трафик на HTTPS (так что у нас есть прослушиватель HTTP И прослушиватель HTTPS). Наши задачи веб-сервера Airflow по-прежнему прослушивают порт 80 для HTTP-трафика, но этот HTTP-трафик находится только в нашем VPC, поэтому нам все равно. Соединение браузера с балансировщиком нагрузки всегда осуществляется по протоколу HTTPS или HTTP, которое перенаправляется на HTTPS, и это то, что имеет значение.

Вот код Terraform для нового слушателя:

resource "aws_lb_listener" "alb_http" {
  load_balancer_arn = aws_lb.lb.arn
  port              = 80
  protocol          = "HTTP"
  default_action {
    type = "redirect"
    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

Или, если вы используете консоль AWS, вот как вы настраиваете действие по умолчанию для слушателя:

Консоль

person GDubz    schedule 15.07.2021