Nginx通过server_name区分内网与外网主机名,核心是依据Host请求头匹配不同server块:内网用IP或内网域名(如192.168.1.100)、外网用公网域名(如www.example.com),各自独立配置server_name;若共用域名,则需结合map指令按$remote_addr区分根目录;默认server应显式设为server_name _并return 444防暴露。

Nginx 通过 server_name 实现内网和外网不同主机名的区分,核心在于让同一台服务器能根据请求中 Host 头的不同,匹配到不同的 server 块。这不需要额外 IP 或端口,只要内网用户和外网用户访问时使用的域名(或 Host)不同,Nginx 就能自动路由。
关键是:内网和外网用各自的域名(或 host 名),并在对应 server 块中明确配置 server_name。下面分场景说明实用配置方式:
一、内网用 IP 或内网域名,外网用公网域名
这是最常见的情况。例如:
- 外网用户访问:
https://www.example.com - 内网用户访问:
http://192.168.1.100或http://intra.example.local
对应配置示例:
server {
listen 80;
server_name www.example.com;
root /var/www/public;
index index.html;
}
<p>server {
listen 80;
server_name 192.168.1.100 intra.example.local;
root /var/www/internal;
index index.html;
}注意:server_name 可以写多个值(空格分隔),支持 IP、纯域名、带端口(不推荐)、通配符等;Nginx 匹配 Host 请求头时是严格比对的,所以 192.168.1.100 必须由内网用户显式访问该 IP 才会命中。
二、内外网共用一个域名,但靠 Host 头 + 反向代理区分
如果内外网都用 example.com,但你想让内网请求走内部路径、外网走公开路径,就不能只靠 server_name——因为 Host 头一样。这时需结合 map 指令或 $remote_addr 判断来源 IP:
map $remote_addr $site_root {
default "/var/www/public";
~^192\.168\. "/var/www/internal";
~^10\. "/var/www/internal";
}
<p>server {
listen 80;
server_name example.com;
root $site_root;
index index.html;
}这样,来自 192.168.x.x 或 10.x.x.x 的请求会自动使用内部根目录,无需修改域名。
三、避免冲突:默认 server 要明确指定
若未匹配到任何 server_name,Nginx 会交给“默认 server”处理(通常是配置文件中第一个 server 块,或显式标了 default_server 的那个)。建议显式定义默认块,防止意外暴露:
server {
listen 80 default_server;
server_name _; # 匹配任意未声明的 Host
return 444; # 或返回 404 / 重定向
}这个 _ 是 Nginx 的“无效域名占位符”,专用于兜底,不会被真实域名匹配到。
四、HTTPS 场景下注意事项
HTTPS 请求在 TLS 握手阶段就需确定虚拟主机(SNI),所以 server_name 同样生效,但必须确保:
- 每个 HTTPS
server块有独立ssl_certificate和ssl_certificate_key(或使用泛域名证书) - 内网域名如
intra.example.local若无有效证书,浏览器会报错;可自签并内网分发,或改用 IP + 自签名证书(需客户端信任) - 不要把内网和外网配置混在同一个 HTTPS server 块里,否则证书不匹配会导致握手失败


















