Проверьте имя хоста сервера, который вызвал API

У меня есть AWS ELB, подключенный к нескольким EC2, на которых запущен сервер AWS Flask. Я не уверен, передает ли AWS ELB полный запрос в EC2 или нет. Я знаю, что мы можем установить ограничения на уровне ELB, но я хочу наложить ограничения только на одну конечную точку и проверить имя хоста сервера, который вызвал конечную точку во Flask. Является ли это возможным?


person Sanjay Sharma    schedule 05.08.2020    source источник
comment
Предполагая, что балансировщик нагрузки приложения, вы можете включить протокол прокси. Но это дает только IP клиента, а не его DNS. IP также доступен по адресу заголовок x-forwarded-for.   -  person Marcin    schedule 05.08.2020
comment
Есть ли способ проверить сертификат SSL?   -  person Sanjay Sharma    schedule 05.08.2020
comment
Возможно, это не соответствует вашему варианту использования, но вы могли бы изучить использование ALB / WAF для применения ограничений на уровне балансировщика нагрузки.   -  person Marcello Romani    schedule 08.08.2020
comment
Ограничения на уровне ELB ... мне кажется, что ELB - не лучшее место для введения каких-либо ограничений. Ограничения звучат для меня как синоним Разрешений. Я бы предпочел разработать решение на основе IAM (и, возможно, API Gateway). Если хотите, чтобы это было просто, рассматривали ли вы возможность добавить параметр / тело в свой запрос с данными / информацией, которые вам нужны на другом конце? HTTP не делает того, что вам нужно / ожидаете.   -  person Teimatini Marin    schedule 11.08.2020
comment
@ TeimatiniMarínMeza Yeh. Это уже есть. Я хочу добавить дополнительную безопасность, поскольку будет только один конкретный клиент (другой сервер), который будет обращаться к одной конкретной конечной точке, и я хочу ограничить доступ других клиентов к ней.   -  person Sanjay Sharma    schedule 11.08.2020
comment
@SanjaySharma Что насчет чего-то вроде этого aws.amazon. ru / premiumsupport / knowledge-center /? Если ваш «другой сервер» - это экземпляр EC2, это будет легко. Просто разверните экземпляр в определенном диапазоне IP-адресов. Если не в EC2, вы можете включить безопасность AWS на экземпляре APIGateway. Затем создайте роль / пользователя и РАЗРЕШИТЕ ​​execute-api: Invoke для вашего ресурса, только если вызывается с этой конкретной ролью / пользователем. Имеет смысл?   -  person Teimatini Marin    schedule 12.08.2020
comment
@ TeimatiniMarínMeza большое спасибо за ваше время и помощь. У меня было некоторое представление об этом, и, согласно вашему объяснению, это, кажется, один из альтернативных способов достижения этого.   -  person Sanjay Sharma    schedule 12.08.2020


Ответы (3)


Вы можете попробовать следующее:

import socket
from flask import request


@app.route("/your_route", methods=["GET"])
def your_route():
    hostname, aliaslist, ipaddrlist = socket.gethostbyaddr(request.remote_addr)

Обратите внимание, что полагаться на remote_addr ненадежно, однако, поскольку это не связано с темой, я буду ссылаться на этот ответ, в котором используется из ProxyFix:

Для получения дополнительной информации о socket.gethostbyaddr() посетите: socket.gethostbyaddr ()

person alexisdevarennes    schedule 12.08.2020

Я предлагаю вам использовать шаблон декоратора для таких случаев, то есть вы добавляете новую опцию конфигурации IP_LIST с каким-то набором адресов, разделенным запятой.

IP_LIST = "127.0.0.1,127.0.0.2,..."

После этого добавьте новую функцию декоратора и украсьте любую конечную точку декоратором.

def ip_verified(fn):
    """
    A custom decorator that checks if a client IP is in the list, otherwise block access.
    """

    @wraps(fn)
    def decorated_view(*args, **kwargs):
        ip_list_str = current_app.config['IP_LIST']
        ip_list = ip_list_str.split(",") if ip_list_str else []

        if request.headers.getlist("X-Forwarded-For"):
            remote_ip = request.headers.getlist("X-Forwarded-For")[0]
        else:
            remote_ip = request.remote_addr

        if remote_ip not in ip_list:
            return "Not sufficient privileges", 403

        return fn(*args, **kwargs)

    return decorated_view

@app.route("/your_route", methods=["GET"])
@ip_verified
def your_route():
    ...
person j0shu4b0y    schedule 13.08.2020

Один из вариантов - использовать Network Load Balancer, который сохраняет IP-адрес клиента, отправляющего запрос. Вы даже можете заставить NLB выполнять завершение TLS точно так же, как ELB. NLB не изменяет данные в сетевом запросе, за исключением завершения TLS, если вы решите это использовать.

person stefansundin    schedule 13.08.2020