我有一个租户设置,其中未知数量的公司可以创建此类帐户company.app.com
。
后端服务器将它们视为: 5000/company/....
,那么如何在 nginx 中重写(而不是重定向!)?这就是我所拥有的:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl on;
ssl_certificate /etc/ssl/certs/cert.pem;
ssl_certificate_key /etc/ssl/private/key.pem;
server_name ????.app.com; <-- How?
charset utf-8;
location / {
proxy_pass http://0.0.0.0:5000;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
现在的问题是我需要排除一小部分子域名(www、dash、mail),那么该如何做呢?
答案1
可以将Host
标头/TLS SNI 字段的一部分捕获到变量中,如下server_name
所示:
server_name ~^(?<company>.+)\.app\.com;
稍后,该变量可以在proxy_pass
目标中使用它:
proxy_pass http://192.168.100.100:5000/$company/;
了解匹配规则很有用,这些规则在nginx 服务器名称文档。
答案2
我的评论太长了,请原谅。
参考NGINX文档:
通配符名称只能在名称的开头或结尾处包含星号,并且只能在点边框上包含星号。名称“www..example.org” 和 “w.example.org” 是无效的。但是,可以使用正则表达式指定这些名称,例如“~^www..+.example.org$”和“~^w..example.org$”。星号可以匹配多个名称部分。名称“.example.org” 不仅匹配www.example.org但www.sub.example.org也一样。
按名称搜索虚拟服务器时,如果名称与多个指定的变体匹配(例如,通配符名称和正则表达式匹配),则将按照以下优先顺序选择第一个匹配的变体:
- 确切名称
- 以星号开头的最长通配符名称,例如“*.example.org”
- 以星号结尾的最长通配符名称,例如“mail.*”
- 第一个匹配的正则表达式(按配置文件中出现的顺序)
形式为“.example.org”的特殊通配符名称可用于匹配精确名称“example.org”和通配符名称“*.example.org”。
由于 NGINX 支持通配符,因此它可以是这样的:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl on;
ssl_certificate /etc/ssl/certs/cert.pem;
ssl_certificate_key /etc/ssl/private/key.pem;
server_name *.app.com;
charset utf-8;
location / {
proxy_pass http://0.0.0.0:5000;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
甚至:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl on;
ssl_certificate /etc/ssl/certs/cert.pem;
ssl_certificate_key /etc/ssl/private/key.pem;
server_name *corp.app.com;
charset utf-8;
location / {
proxy_pass http://0.0.0.0:5000;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
两者都应该有效。