使用Redbird反向代理Node.js服务器上的HTTPS站点及其子域的代理

时间:2019-03-14 09:06:07

标签: node.js https subdomain reverse-proxy redbird

我试图了解如何将redbird用作反向代理(对于旧式节点服务器,其工作量似乎比nginx小,但也许我错了),但我无法在自述文件中理解它们的示例,可以在其他地方找不到答案:https://github.com/OptimalBits/redbird

我的设置:我有一个在“ example.com”下运行的节点服务器,我需要创建一个子域(api.example.com)。现在,安装在服务器上的旧版应用会将所有流量从端口80重定向到443,并安装了SSL证书(不是我所说的LetsEncrypt是旧版,并且可能在获得证书之前是免费的)。该证书仅涵盖“ example.com”和“ www.example.com”。 经过几个小时(好几天)的尝试,找到了添加子域的最佳方法(也可以通过HTTPS进行服务),这就是我认为的工作方式:

  1. 为我的子域(api.example.com)添加A记录;
  2. 从“让我们加密”获取api.example.com的证书;
  3. 更改旧版应用,使其不监听端口80(对​​于 重定向)
  4. 更改旧版应用程序,使其监听7000而不是443
  5. 在线放置我的新应用并使其收听7001
  6. 设置Redbird来收听80并重定向到443
  7. 设置Redbird以注册“ example.com”并将请求重定向到 7000(具有现有证书)
  8. 设置Redbird以注册“ api.example.com”并将请求重定向到 7001(带有我的新证书)

我在正确的道路上吗?

注意:我知道redbird具有自动获取ssl证书的功能,但是由于我必须对主域(example.com)使用旧版证书,所以我认为我不能使用自动方式。

我能够浏览列表中的第6名,但是HTTPS的redbird文档让我感到困惑。这是他们的示例:

var redbird = new require('redbird')({
port: 8080, //??? => so this is the entry point? Why not 443 since we want only HTTPS?

// Specify filenames to default SSL certificates (in case SNI is not supported by the
// user's browser)
ssl: {
    port: 8443, //??? => what is this port for? Is it our default HTTPS port (in my case 443?)
    key: "certs/dev-key.pem",
    cert: "certs/dev-cert.pem",
}
});

// Since we will only have one https host, we dont need to specify additional certificates.
redbird.register('localhost', 'http://localhost:8082', {ssl: true}); //??? => this is the port my request will be forwarded too... right?

我想从中收集的信息是:通过端口8080进入本地主机的流量将重定向到端口8082。对吗?但是那8443是做什么用的呢?

几乎不了解发生了什么,我尝试了以下操作:

var redbird = new require('redbird')({
port: 80,
secure: false,

// Specify filenames to default SSL certificates (in case SNI is not supported by the
// user's browser)
ssl: {
    port: 443,
    key: "/etc/cert/example.key",
    cert: "/etc/cert/example.crt",
}
});

// Since we will only have one https host, we dont need to specify additional certificates.
redbird.register('example.com', 'http://localhost:7000', {ssl: true});
redbird.register('api.example.com', 'http://localhost:7001', {
ssl: {
    key: "/etc/letsencrypt/api.example.key",
    cert: "/etc/letsencrypt/api.example.crt"
}
});

为什么在redbird.register()的第二个参数中没有HTTPS而不是HTTP?

不用说上面的方法不起作用,当我从浏览器或api.example.com打开example.com时,它会回答:“ ECONNRESET”。

更新:我同时使用HTTPS(在7000和7001上)为两个节点应用程序提供服务,并尝试将它们作为HTTP服务到代理。我得到了正确将请求转发到相应端口的代理,但是只有主(旧版)应用(位于“ example.com”)具有正确的SSL证书。当我打开“ api.example.com”时,我得到警告说该网站不安全...

让我感到奇怪:拥有一个带有说GoDaddy证书的主域和一个LetsEncrypt的子域的主域可以吗?那是它不起作用的原因吗?

当我在Chrome上单击“不安全”警告时(查看api.example.com时),它显示Cetificate(已入侵),并显示主域(example.com)的证书信息,而不是我为api.example.com配置的证书...

UPDATE2: 因此,我尝试为我的域及其所有子域获取新证书(使用通配符* .example.com,也值得注意:* .example.com不包含example.com,因此需要手动添加)。 使用全封装证书,下面的代码可以工作,但是比不使用Redbird作为反向代理要慢得多(我原以为会有差异,但没有那么多,这里我们谈论的是3秒钟以上的差异-该网站是旧版并且没有经过优化,这3秒超过了8秒+的时间(禁用了缓存)。

var redbird = new require('redbird')({
port: 80,
secure: true,

ssl: {
    port: 443,
    key: "/etc/letsencrypt/live/example.com/privkey.pem",
    cert: "/etc/letsencrypt/live/example.com/cert.pem",
}
});

redbird.register('example.com', 'http://localhost:7000', {ssl: true});
redbird.register('www.example.com', 'http://localhost:7000', {ssl: true});
redbird.register('api.example.com', 'http://localhost:7001', {ssl: true});

从这些经验中我可以得出几点,这可能对其他人有帮助:

  • 上面指定80的端口是HTTP的入口。如果在同一对象中指定ssl部分,则redbird会将所有HTTP通信重定向到HTTPS(我在文档中找不到)。
  • 上面在443中指定的端口是HTTPS的入口端口。在这一点上,您仍然没有进行任何重定向,只是在解释一下什么才是重做。我想。
  • ssl对象中的证书应该是文件cert.pem而不是fullchain.pem(这不一定是红鸟问题,而只是那些可能使人绊倒的事情之一)。
  • 上方7000和7001的端口是您要将流量重定向至的端口(种类明显,但文档中应该包含明显的内容)。
  • 最后,对象{ssl:true}的作用是告诉redbird使用上面的默认SSL配置,另一种方法是为每个已注册域指定另一个配置,但我无法做到这一点(可能是因为我只能处理子域,而此功能可能仅适用于非子域...如果是这种情况,最好在文档中包含)。

这令人失望,因为(从最重要到最不重要的顺序):

  1. 性能似乎受到了巨大的打击:我是否缺少可以改善这一点的“ prod”参数?
  2. 似乎唯一可行的方法是将我所有的节点应用程序/服务器都设置为http(而不是https)并指向其端口(7000和7001),而仅将代理服务器设置为https。并不太麻烦,因为似乎没有人能够直接访问端口7000和7001,但是我认为7000和7001也可以是https。可以吗或者,如果代理可以处理,在https中拥有这些应用程序是否没有意义?
  3. 我无法保留尚未过期的旧的(昂贵的)ssl证书。还是有我找不到的方法?

我敢打赌,这么久了,没人会读过这个...

1 个答案:

答案 0 :(得分:1)

我希望这会有所帮助;
1.使用内置的ssl选项中的redbirds自动传送证书;
2.示例:

const proxy = require('redbird')({
  port: 80,
  xfwd: true, // http port is needed for LetsEncrypt challenge during request / renewal. Also enables automatic http->https redirection for registered https routes.
  letsencrypt: {
    path: __dirname + '/certs',
    port: 9999 // redbird gets your certificates throug this port
  },
  ssl: {
    http2: true,
    port: 443, // SSL port used to serve registered https routes with LetsEncrypt certificate.
  }
});

let connectionInfo = {
  ssl: {
    letsencrypt: {
      email: 'YOUR EMAIL',
      production: true, 
    }
  }
};

proxy.register("subdomain.yourdomain.com", "http://your.ip.goes.here:84", connectionInfo);
proxy.register("yourdomain.com", "http://your.ip.goes.here:83", connectionInfo);
  1. 在端口84上运行子域服务器,在端口83上运行主服务器;