为啥 https 在 AWS Elastic Beanstalk 上被阻止?

Posted

技术标签:

【中文标题】为啥 https 在 AWS Elastic Beanstalk 上被阻止?【英文标题】:Why is https being blocked on AWS Elastic Beanstalk?为什么 https 在 AWS Elastic Beanstalk 上被阻止? 【发布时间】:2020-01-29 00:34:55 【问题描述】:

我正在使用节点 js 在 AWS Elastic Beanstalk 上创建一个简单的网站。我正在尝试向 EC2 实例添加 SSL 证书,但它一直在说

"Error: listen EACCES: permission denied 0.0.0.0:443"

我错过了什么?

EC2 安全组:

入站规则:

HTTP    TCP    80    0.0.0.0/0
HTTP    TCP    80    ::/0
HTTPS   TCP    443   0.0.0.0/0
HTTPS   TCP    443   ::/0

出站规则:

All traffic    All    All    0.0.0.0/0

节点 JS:

    var ipaddress = "0.0.0.0";
    var port = 443;

    var options = 
        key: sslKey,
        cert: sslCert,
        ca: [sslCa]
    

    server = https.createServer(options, handleRequest);

    server.listen(port, ipaddress, function () 
        console.log("Server listening on port "+port);
    );

【问题讨论】:

您是否遵循了本指南? docs.aws.amazon.com/elasticbeanstalk/latest/dg/… 您在 Elastic beanstalk 上使用 LB 吗?如果是,则不要在实例级别管理 ssl 不使用 LB 来节省 $cash。我会试试那个指南。 【参考方案1】:

我知道这个 Elastic Beanstalk 的东西没有很好的记录,但是由于我前段时间做过 AWS DevOps 认证,其中涵盖了这一点,所以我记得一些要点:

您应该将您的 HTTP 服务器绑定到 0.0.0.0。我看到你已经这样做了。 您的应用程序没有在您的 EB 实例上以 root 权限运行。通常,他们希望您做的(可能是出于安全原因)是通过在您的实例上预先配置的 nginx 代理来代理您的连接。他们将PORT 环境变量传递给您的node.js 应用程序,您应该使用它来侦听代理的上游流量。 [1] 要使您的 nginx 代理上的 SSL 终止正常工作,您必须在代理上相应地配置 ssl,正如 vikyol 已经正确指出的那样。 [2] 然后代理和您的应用程序之间的连接将被解密。这应该不是问题,因为它不会让机器介于两者之间。

还有一些想法

如果您在某个时候有一些 $$,出于性能原因,我更喜欢在负载平衡器上终止 SSL。 SSL 证书管理通常通过ACM 和 ELB 更方便。

参考文献

[1]https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/nodejs-platform-proxy.html [2]https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance-nodejs.html

【讨论】:

【参考方案2】:

在某些 Linux 发行版上,尤其是 Ubuntu,非 root 用户无法绑定到小于 1024 的端口。 (有关证据,请参阅下面的笔记。)

有多种方法可以解决这个问题。见:

https://www.geeksforgeeks.org/bind-port-number-less-1024-non-root-access/ https://serverfault.com/questions/112795/how-to-run-a-server-on-port-80-as-a-normal-user-on-linux

不过,更一般地说,要回答“如何让受 SSL 保护的网站在 Elastic Beanstalk 上运行”的问题。我想说:不要在你的应用程序中终止你的 TLS/SSL

根据我的经验,使用弹性负载均衡器终止您的 SSL/TLS 是一个非常简单的解决方案。 (如果您使用 Amazon Certificate Manager (ACM) 颁发和管理您的证书)。 ACM 也会在到期前自动更新证书!

如果您确实希望将证书保留在实例上,那么我建议您使用“真正的”网络服务器,例如 nginx 来前端您的 nodejs 进程。 nginx 具有安装 SSL 证书 [1] 和插件的设施,可通过 LetsEncrypt [2] 自动发布和更新它们。很简单,这就是它的设计目的。

我不知道您使用的是哪个特定的 EB 平台,但其中许多(全部?)都预装了默认运行的 Web 服务器。 (例如,docker 平台运行 nginxpython 平台运行 apache)。因此,您的 EB 实例上可能已经安装了适当的 Web 服务器。

以下是在 Ubuntu docker 实例上执行的。 (该命令只是在指定端口启动python HTTP 服务器的一行命令。)您可以看到端口1025 始终有效。但是端口1023 只能作为root 使用。

root@24928b62f0bd:/# python3 -m http.server 1025
Serving HTTP on 0.0.0.0 port 1025 (http://0.0.0.0:1025/) ...
^C
Keyboard interrupt received, exiting.
root@24928b62f0bd:/# python3 -m http.server 1023 
Serving HTTP on 0.0.0.0 port 444 (http://0.0.0.0:1023/) ...
^C
Keyboard interrupt received, exiting.
root@24928b62f0bd:/# useradd bob
root@24928b62f0bd:/# su bob
$ python3 -m http.server 1025
Serving HTTP on 0.0.0.0 port 1025 (http://0.0.0.0:1025/) ...
^C
Keyboard interrupt received, exiting.
$ python3 -m http.server 1023
Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3.6/http/server.py", line 1211, in <module>
    test(HandlerClass=handler_class, port=args.port, bind=args.bind)
  File "/usr/lib/python3.6/http/server.py", line 1185, in test
    with ServerClass(server_address, HandlerClass) as httpd:
  File "/usr/lib/python3.6/socketserver.py", line 456, in __init__
    self.server_bind()
  File "/usr/lib/python3.6/http/server.py", line 136, in server_bind
    socketserver.TCPServer.server_bind(self)
  File "/usr/lib/python3.6/socketserver.py", line 470, in server_bind
    self.socket.bind(self.server_address)
PermissionError: [Errno 13] Permission denied
$ 

[1]http://nginx.org/en/docs/http/configuring_https_servers.html [2]https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04

【讨论】:

以上是关于为啥 https 在 AWS Elastic Beanstalk 上被阻止?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 AWS Elastic Beanstalk Python 优先插入“静态”规则在所有其他规则之前?

在 AWS Elastic Beanstalk 和 EKS 上部署了一个 laravel 应用程序 相同的数据库 RDS 为啥在 Elastic Beanstalk 中获得快速响应

AWS Elastic Beanstalk - 为啥我要使用 leader_only 命令?

为啥 AWS Route 53 主机重定向到 Elastic Beanstalk 服务器?

为啥在 AWS Elastic BeanStalk 中将 Web 服务器更改为 nginx 时我的网页标题显示“Apache”

为啥我的 Rails 应用程序无法部署到 AWS Elastic Beanstalk?