如何使用 NGINX 代理从使用 Amazon Cognito 身份验证的 VPC 外部访问 Kibana?

上次更新时间:2020 年 10 月 21 日

我的 Amazon Elasticsearch Service (Amazon ES) 集群位于 Virtual Private Cloud (VPC) 中。我想使用 NGINX 代理通过 Amazon Cognito 身份验证从 VPC 外部访问 Kibana。

简短描述

使用 NGINX 将 Amazon Elastic Compute Cloud (Amazon EC2) 实例配置为代理服务器。然后,该代理服务器将浏览器请求转发给 Amazon Cognito 和 Kibana。

注意:您还可以使用 SSH 隧道或客户端 VPN 通过 Amazon Cognito 身份验证从 VPC 外部访问 Kibana。有关更多信息,请参阅如何使用 Amazon Cognito 身份验证从 VPC 外部访问 Kibana?

解决方法

重要:当您限制对 VPC 中用户的访问时,您的 Amazon ES 域会更安全。在继续之前,请确保此过程不违反您所在组织的安全要求。

1.    创建 Amazon Cognito 用户池

2.    配置托管用户池域

3.    在 Amazon Cognito 控制台导航窗格中,选择用户和组

4.    选择创建用户,然后填写字段。请务必输入电子邮件地址,然后选中将电子邮件标记为已验证复选框。

5.    选择选项卡,然后选择创建组。对于优先级,输入 0。有关更多信息,请参阅在 AWS 管理控制台中创建新组

6.    再次打开 Amazon Cognito 控制台

7.    选择管理身份池,然后选择创建新身份池

8.    输入身份池的名称,选中启用对未经身份验证的身份的访问权限的复选框,然后选择创建池

9.    当系统提示访问 AWS 资源时,请选择允许以创建与您的身份池关联的两个默认角色。为未经身份验证的用户创建一个默认角色,为经过身份验证的用户创建另一个默认角色。

10.    配置您的 Amazon ES 域,以使用面向 Kibana 的 Amazon Cognito 身份验证
对于 Cognito 用户池,请选择您创建的用户池。
对于 Cognito 身份池,请选择您创建的身份池。
有关更多信息,请参见开始使用 Amazon Elasticsearch Service:使用 Amazon Cognito 进行 Kibana 访问控制

11.    配置您的访问策略,使用与下方类似的基于资源的策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::account-id:role/Cognito_identity-nameAuth_Role"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:region:account-id:domain/ES-name/*"
    }
  ]
}

您必须更新这些值:
account-id您的 AWS 账户 ID
identity-name:您的 Amazon Cognito 身份池的名称
ES-name:您的 Amazon ES 域名
region:您的 Amazon ES 域所在的区域,例如 us-east-1

12.    将 EC2 实例启动到与您的 Amazon ES 域所在相同 VPC 的公有子网中。确保实例使用与 Amazon ES 域相同的安全组。

13.    (可选)如果不使用测试环境,请分配一个弹性 IP 地址,以与您创建的实例相关联。有关分配弹性 IP 地址的更多信息,请参阅使用弹性 IP 地址

14.    (可选)如果不使用测试环境,请配置 DNS 以解析对弹性 IP 地址的请求。有关如何使用 Amazon Route 53 解析请求的更多信息,请参阅配置 Amazon Route 53 以将流量路由到 Amazon EC2 实例

15.    连接到实例并安装 NGINX。

对于使用 Amazon Linux Amazon Machine Image (AMI) 启动的实例,请使用以下命令:

$ sudo yum install nginx

对于使用 Amazon Linux 2 AMI 启动的实例,请使用以下命令:

$ sudo amazon-linux-extras install nginx1.12

16.    从证书颁发机构 (CA) 获取 SSL 证书,以为 NGINX 配置 SSL。

注意:如果您使用的是测试环境,则会生成自签名证书。浏览器不信任自签名证书,不应在生产环境中使用。

17.    (可选)如果您使用带有自签名证书的测试环境,请使用 OpenSSL x509 命令来生成私有密钥:

$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/cert.key -out /etc/nginx/cert.crt

此命令语法生成 cert.key,这是一个用于自签名 SSL 证书的私有密钥。

18.    导航到 /etc/nginx/conf.d 目录,然后创建一个名为 default.conf 的文件。使用以下值修改文件:
/etc/nginx/cert.crt:SSL 证书的路径
/etc/nginx/cert.key:您为 SSL 证书生成的私有密钥的路径
$ES_endpoint:您的 Amazon ES 终端节点。有关更多信息,请参阅配置身份提供商
$cognito_host:您在步骤 2 中配置的 Amazon Cognito 用户池域。

您可以使用 sed 命令将 $ES_endpoint$cognito_host 指定为变量,而不是在 default.conf 文件中直接替换它们。此外,请确保使用 HTTPS,否则您可能会遇到错误。

重要提示:解析器参数会根据您的 VPC 设置而变化。DNS 解析程序地址为您的主 CIDR 块的基础 IP 加上二。例如,如果您使用 CIDR 块 10.0.0.0/24 创建 VPC,则您的 DNS 解析程序地址为 10.0.0.2。

resolver 10.0.0.2 ipv6=off;

server {
    listen 443;
    server_name $host;
    rewrite ^/$ https://$host/_plugin/kibana redirect;

    ssl_certificate /etc/nginx/cert.crt;
    ssl_certificate_key /etc/nginx/cert.key;

    ssl on;
    ssl_session_cache builtin:1000 shared:SSL:10m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    set $es_endpoint $ES_endpoint;
    set $cognito_endpoint $cognito_host;

    location ^~ /_plugin/kibana {
        # Forward requests to Kibana
        proxy_pass https://$es_endpoint;

        # Handle redirects to Amazon Cognito
        proxy_redirect https://$cognito_endpoint https://$host;

        # Update cookie domain and path
        proxy_cookie_domain $es_endpoint $host;

        # Response buffer settings
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
    }

    location ~ \/(log|sign|error|fav|forgot|change|confirm) {
        # Forward requests to Cognito
        proxy_pass https://$cognito_endpoint;

        # Handle redirects to Kibana
        proxy_redirect https://$es_endpoint https://$host;

        # Handle redirects to Amazon Cognito
        proxy_redirect https://$cognito_endpoint https://$host;

        # Update cookie domain
        proxy_cookie_domain $cognito_endpoint $host;
    }
}

19.    (可选)使用 sed 命令分配 $ES_endpoint$cognito_host 变量:

$ sudo sed -i 's/$ES_endpoint/vpc-mykibana-111xxx.us-east1.es.amazonaws.com/' /etc/nginx/conf.d/default.conf
$ sudo sed -i 's/$cognito_host/mydomain.auth.us-east-1.amazoncognito.com/' /etc/nginx/conf.d/default.conf

注意:您不必在 /etc/nginx/conf.d/default.conf 文件中替换 $ES_endpoint$cognito_host

20.    重启 NGINX。

对于使用 Amazon Linux AMI 启动的实例,请使用以下命令:

$ sudo service nginx restart

对于使用 Amazon Linux 2 AMI 启动的实例,请使用以下命令:

$ sudo systemctl restart nginx.service

21.    使用浏览器访问 NGINX IP 或 DNS 名称。您将被重定向到 Amazon Cognito 登录页面。

22.    要登录 Kibana,请输入您的用户名和临时密码。然后,在收到提示时更改密码并重新登录。