寻求一些建议和同行的意见 - 我目前正在尝试以某种方式配置 NGINX,以便我可以同时配置多个网站,而无需设置单独的 VHost 配置或在我的 NGINX 配置中声明具有重复配置参数的多个“server {}”条目。到目前为止,我取得了部分成功,但我担心这样做可能会造成安全问题或无意中定义范围过广。我也不确定如何正确使用“map”指令中的“默认”值。
总而言之,目前我有一个典型的 NGINX 配置,其中 2 个 VHost 配置用于一个域名(以及一个 'www.*' 子域名),位于 'nginx_root/sites-available' 中 - 一个用于 HTTP(端口 80),一个用于 HTTPS(端口 443),它们软符号链接到 'nginx_root/sites-enabled'。但如前所述 - 我想添加其他域名,但通过使用 NGINX 'map' 功能动态设置新域名,保持这些配置的数量和大小与当前相同。
我目前映射它的方法是创建一个配置文件:“nginx_root/mapped_fqdn.conf”,然后我将它包含在我的 NGINX 配置中(这样它在配置中被进一步调用/引用之前就被映射了),然后使用该映射作为“server_name”参数。如果可以将其扩展到其他配置参数并且这样做是安全的,我想以同样的方式添加新的域名。
映射的_fqdn.conf:
### Domain name mapping
map $host $fqdn_map {
hostnames;
default 0;
domain-1.com 0;
www.domain-1.com 0;
}
00-http.conf:
server {
listen 80;
listen [::]:80;
server_name $fqdn_map;
root /var/www/public_html;
index index.html;
access_log /var/log/nginx/nginx_access.log nginx_access;;
### HTTP to HTTPS Redirect
return 301 https://$server_name$request_uri;
}
为了不重复,我将跳过添加 HTTPS 配置,它看起来大致相同,只是它有一些小的附加参数,以及添加的 SSL 特定的配置参数,并且没有 HTTP 配置中存在的 301 重定向。
在我看来,我可以以同样的方式添加额外的域名......
更新后的mapped_fqdn.conf示例: (我认为添加特定的子域名可能比添加通配符更安全,例如:“*.domain.com”)
### Domain name mapping
map $host $fqdn_map {
hostnames;
default 0;
domain-1.com 10;
www.domain-1.com 11;
domain-2.co.uk 20;
www.domain-2.co.uk 21;
subdomain1.domain-2.co.uk 22;
subdomain2.domain-2.co.uk 23;
domain-3.com 30;
www.domain-3.com 31;
subdomain1.domain-3.com 32;
}
更新后的00-http.conf示例:
server {
listen 80;
listen [::]:80;
server_name $fqdn_map;
root /var/www/$fqdn_map/public_html;
index index.html;
access_log /var/log/nginx/$fqdn_map-nginx_access.log nginx_access;;
### HTTP to HTTPS Redirect
return 301 https://$server_name$request_uri;
}
但是,在继续之前,我担心这将如何与目录一起工作,即:让我们为 HTTPS 配置加密证书 - 是否可以具体选择要使用哪些映射项?例如:$fqdn_map{10|20|30}(这样只选择没有子域名的域名)。
ssl_client_certificate /etc/ssl/certs/$fqdn_map{10|20|30}/cloudflare_origin.pem;
ssl_certificate /etc/letsencrypt/live/$fqdn_map{10|20|30}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$fqdn_map{10|20|30}/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/$fqdn_map{10|20|30}/chain.pem;
或者也许我以错误的方式处理这个问题,我应该分别映射 FQDN 和子域...或者可能只是从映射的子域目录到 fqdn 目录创建符号链接和连接(这虽然会导致配置更少/更干净,但会导致更多的符号链接,有点违背了“少做多得”的目的)?
答案1
如果您只是想将主机名映射到证书目录,那么您可以使用这种方法:
map $http_host $certdir {
hostnames;
dom1.example.com dom1;
dom2.example.com dom2;
.example.com dom;
}
server {
listen 443 ssl;
server_name something.example.com;
ssl_certificate /path/to/certificates/$certdir/dom.crt;
ssl_certificate_key /path/to/certificates/$certdir/dom.key;
...
}
此处的$certdir
值为dom
,因为与定义something.example.com
相匹配。.example.com
map
--- 第一个回答最初未提出的问题的答案 ---
也许您正在寻找这个:
server {
listen 80 default_server;
server_name _;
root /var/www/$host/public_html;
....
}
我们在这里指定一个default_server
块,它处理所有在其他地方没有匹配的虚拟主机的请求。
然后我们使用$host
包含域名的变量。
如果只想对某些域使用更具体的匹配,请使用正则表达式:
server {
listen 80;
server_name ~ ^(domain-1.com|domain-2.com)$;
root /var/www/$host/public_html;
....
}
您可以细化正则表达式。
但是,正如我在评论中所述,这将限制您如何自定义每个服务器块。您可以使用include /etc/nginx/conf.d/$host.conf
在另一个文件中添加特定于域的配置。
不过,从长远来看,配置管理系统仍然是最佳选择。