TL;DR: 在此处实现您要寻找的内容有几种方法。
尽可能遵循减少
攻击面的原则,通常最好不要将端口暴露在公共互联网上,除非绝对必要。反向代理是实现这一目标的绝佳方式。通常,您希望所有后端 Web 应用程序通过 HTTPS 在端口 443 上进行反向代理,并且您可以通过以下任一服务访问每个服务:
使用不同的主机名,例如app1.example.com
和app2.example.com
,或
使用不同的子目录,例如example.com/app1
和example.com/app2
根据您选择的方法,配置可能会有很大差异,前一种情况下需要多个server
块,后一种情况下需要location
块。无论哪种情况,我们都将使用upstream
和proxy_pass
指令。我将为两种情况提供示例。
多个主机
如果您在前端使用多个主机名(或多个端口),则需要为它们创建多个 server
块:
# Nginx reverse-proxy configuration
upstream app1 {
server 10.176.225.83:8888;
}
upstream app2 {
server 10.176.225.83:8088;
}
upstream app3 {
server 10.176.225.83:8042;
}
upstream app4 {
server 10.176.225.83:8890;
}
server {
listen 443 ssl;
server_name app1.example.com;
ssl_certificate_key /path/to/your/ssl-key.pem;
ssl_certificate /path/to/your/ssl-cert.pem;
location / {
proxy_pass http:
}
}
server {
listen 443 ssl;
server_name app2.example.com;
ssl_certificate_key /path/to/your/ssl-key.pem;
ssl_certificate /path/to/your/ssl-cert.pem;
location / {
proxy_pass http:
}
}
server {
listen 443 ssl;
server_name app3.example.com;
ssl_certificate_key /path/to/your/ssl-key.pem;
ssl_certificate /path/to/your/ssl-cert.pem;
location / {
proxy_pass http:
}
}
server {
listen 443 ssl;
server_name app4.example.com;
ssl_certificate_key /path/to/your/ssl-key.pem;
ssl_certificate /path/to/your/ssl-cert.pem;
location / {
proxy_pass http:
}
}
这里有几点需要注意:
- 所有后端都已在顶部使用
upstream
指令定义,并且现在可以按名称引用。
- 如果您不想以这种方式执行,则可以省略
upstream
块,proxy_pass
行将如下: proxy_pass http://10.176.225.83:8888;
- 因为每个应用程序都在不同的主机名上提供服务,每个应用程序都有自己的
server
块。如果它们每个都在不同的端口上提供服务,情况也是如此。
- 每个
server
块中的ssl_certificate
和ssl_certificate_key
可以指向不同的证书,甚至是相同的证书,如果您在证书中定义了多个SANs。
- 每个应用程序都将从其自己的主机名中提供服务,所有这些主机名都指向前端服务器:
- 应用程序1:
https://app1.example.com
- 应用程序2:
https://app2.example.com
- 应用程序3:
https://app3.example.com
- 应用程序4:
https://app4.example.com
多个目录
对于使用单个主机和端口、从子目录中提供后端应用程序的配置,您将使用一个 server
块和多个 location
块:
# Nginx reverse-proxy configuration
upstream app1 {
server 10.176.225.83:8888;
}
upstream app2 {
server 10.176.225.83:8088;
}
upstream app3 {
server 10.176.225.83:8042;
}
upstream app4 {
server 10.176.225.83:8890;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate_key /path/to/your/ssl-key.pem;
ssl_certificate /path/to/your/ssl-cert.pem;
location /app1 {
proxy_pass http:
}
location /app2 {
proxy_pass http:
}
location /app3 {
proxy_pass http:
}
location /app4 {
proxy_pass http:
}
}
这里还有一些需要注意的事项:
- 我们仍然像以前一样定义了所有四个
upstream
服务,如果您更喜欢直接路由,仍然可以省略它们。在复杂的配置中,此指令更加有用。
- 因为所有应用程序都是从同一个主机名提供服务,所以它们共享一个
server
块,但具有各自子目录的location
块。
- 由于它们都共享相同的主机名,在这种情况下,服务器证书不需要多个SANs。
- 每个后端应用程序将在前端服务器上的子目录中可用:
- 应用程序1:
https://example.com/app1
- 应用程序2:
https://example.com/app2
- 应用程序3:
https://example.com/app3
- 应用程序4:
https://example.com/app4
TLS配置
在任何一种情况下,您都需要配置SSL证书,可以使用公共CA签名的证书,或者您公司内部的PKI证书(如果适用)。 如果您的应用程序将面向公众,则需要使用公共证书。然后将它们的位置添加到上述Nginx配置中。
进一步阅读
对于实际案例,您可以查看我用于Genieacs TR-069服务器的Nginx配置,该配置实现了SSL并反向代理多个其他服务,尽管它们仍在其原始端口而非443端口上。如果您想要保留它们的原始端口,则此示例可能有用。
Nginx官网还有一篇关于反向代理基本配置的
良好入门指南。