如何禁用通过IP地址直接访问网站的方式

57

我在VPS上有一个网站。

我的问题是,当我输入服务器的IP地址时,它会链接到网站。
即使输入mail.domain.com,它也会做同样的事情。

如何禁用它,以便访问者可以收到消息或被引导到域名?

我尝试在Cloudflare上禁用IP和邮件A记录,但没有效果。

我的设置是:

VPS on Linux Debian 
Nginx
no control panel just command line
Cloudflare
DNS setup with BIND

如果你使用的是Apache服务器,你可以使用.htaccess。 - Lorenz Meyer
修正了一些语法和格式。 - Phantômaxx
10个回答

54
server {
    listen      80 default_server;
    listen      [::]:80 default_server;
    server_name "";
    return      444;
}

您需要指定default_server参数,以便所有不可用的服务器请求都会转到此服务器块,该块会抛出444错误

444:连接关闭而没有响应

参考:https://httpstatuses.com/444


1
你应该解释一下 444 是什么意思。我以前没见过这个状态码。https://httpstatuses.com/444 - mpen
https怎么样? - mahfuz
2
@mahfuz 对于 HTTPS,您可以添加 listen 443 ssl; - user1642018
为了使用https,您需要创建自签名证书。如果没有证书,无法对https请求进行444响应。 - Howard
@Howard 但是444不是一个响应。NGINX只会在“return 444;”上挂起连接。 - Константин Ван

41

您可以使用重定向,nginx配置:

server {
        listen 80;
        server_name IP_ADDRESS;
        return 301 http://YOUR.DOMAIN;
}

2
这里解决的具体问题是必须明确定义IP地址并使用403或类似方式进行重定向或阻止。我已经在配置文件中删除了所有对我的IP地址的引用,但它仍然显示为该IP地址-这让我很疯狂。但似乎如果没有被覆盖,它会回退到允许IP访问。谢谢! - Matt Fletcher
只有当 listen 指令也具有确切的 IP 时,这对我才有效,否则 nginx 将匹配更具体的服务器块,即使 server_name 不匹配。 - Avamander
如何根据访问者进行“return 301”重定向:如果是本地访问,nginx 应该重定向到 192.168..,如果来自远程,则重定向到 domain.com。 - Timo
请将此内容放置于/etc/nginx/conf.d/default.conf文件中。 - tread
2
谢谢,这对我有用,但我的应用程序仍然可以使用“IP_ADDRESS:<PORT_NUM>”访问。我该怎么解决? - Suresh Prajapati
@SureshPrajapati 如果你的应用程序运行在不同的端口上,你可能需要通过nginx建立代理。此外,允许其他端口开放并不是一个好的做法,因此还应该使用防火墙来隐藏端口,避免被"外部"世界发现。 - tim.a

19

在其他指令之前添加一个server指令即可。

server {
    listen 80;
    server_name _;
    return 404;
}

如果其他服务器块中有default_server,那么这个会起作用吗?_有特殊含义吗? - mpen
在捕获所有服务器的示例中,可以看到奇怪的名称“_”: ...这个名称并没有什么特别之处,它只是众多无效域名中的一个,永远不会与任何真实名称相交。其他无效名称,如“--”和“!@#”同样可以使用。 - uhelp
2
@mpen 如果其中一个集合设置了 default_server,那么它将无法工作。 _ 没有特殊含义,您可以使用任何字符。 - Rick

8
以上两种方法在我的情况下都没有帮助 - IP 连接到 http 的工作正常,但是 https 重定向到字母表中第一个 https 虚拟站点。在 nginx 1.19.4 以下版本中有效的方法是添加空证书以阻止:
server {
  listen 80 default_server;
  listen [::]:80 default_server;
  listen 443 default_server;
  listen [::]:443 default_server;

  ssl_certificate /etc/ssl/null.crt;
  ssl_certificate_key /etc/ssl/null.key;

  server_name "";
  return 444;
}

证书可以生成一个空的CN,所以您不需要担心填写它。
openssl req -x509 -newkey rsa:2048 -days 10000 -nodes  -subj '/CN=' -keyout null.key -out null.crt

然后http/https返回444 (ERR_EMPTY_RESPONSE),在不同的配置中,https返回ERR_HTTP2_PROTOCOL_ERROR,使用您的空证书也可以显示什么都没有。

对于nginx 1.19.4,它更简单。 它引入了ssl_reject_handshake on | off (http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_reject_handshake),您可以将证书的“内容”替换为:

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  listen 443 default_server;
  listen [::]:443 default_server;

  ssl_reject_handshake on;

  server_name "";
  return 444;
}

现在您会收到http 444(ERR_EMPTY_RESPONSE)和https ERR_SSL_UNRECOGNIZED_NAME_ALERT的错误提示。 不需要任何空证书。

1
被低估的答案,非常感谢! - OmerFI
一个漂亮的答案,完美奏效! - undefined

6
您可以使用重定向,nginx配置如下:

server {
        listen 80;`enter code here`
        server_name IP_ADDRESS;
        return 301 http://YOUR.DOMAIN;
}

1
欢迎来到 Stack Overflow!请注意,虽然代码片段本身可能是一个有用的答案,但最好为未来的读者留下一些评论,解释为什么这个代码可以解决问题。谢谢! - Erty Seidohl
这个解决方案的问题是你需要提前知道服务器的IP地址。新事物(比如分布式架构)经常会将你的nginx移动到不同的IP地址上。 - Victor Ronin

4
您可以返回任何您认为适合的错误。错误列表可以在此处找到:HTTP状态码
server {
    listen      x.x.x.x:80;
    server_name x.x.x.x;
    return      404;
}  

2

您可以尝试在以下位置设置服务器IP地址:

/etc/nginx/conf.d/default.conf

看起来是这样的:

server {
    listen 80;
    server_name localhost IP.OF.VPS.HERE;

然后您可以指定子域名虚拟主机,如下所示:
server {
        listen 80;
        server_name subdomain.domain.com;

而主域名例如:

server {
        listen 80;
        server_name www.domain.com domain.com;

然后重新启动Nginx:

/etc/init.d/nginx restart

每个虚拟主机应该有自己的*.conf文件(为了更好的组织),例如:
/etc/nginx/conf.d/subdomain.domain.com.conf
/etc/nginx/conf.d/domain.com.conf
/etc/nginx/conf.d/default.conf

所有的 *.conf 文件会自动读取吗?还是需要在某个地方包含它们? - luckydonald
1
@luckydonald,nginx.conf会自动包含conf.d目录下的所有文件,使用include /etc/nginx/conf.d/*.conf; - Ron

2
将以下代码放置在您的/etc/nginx/conf.d/SERVER_IP_ADDRESS.conf文件的顶部,并注释掉其下方的所有内容。
#disabling accesing server by ip address
server {
        listen SERVER_IP_ADDRESS:80 default;
        server_name _;
        return 404;
}

然后重新启动您的Nginx服务器(在Ubuntu上,可以通过service nginx restart命令完成此操作)

现在,当您将服务器的IP地址放入浏览器URL字段中时,您将收到404错误。


1
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    listen 443 default_server;
    listen [::]:443 default_server;
    return 444;
}

不要为汇聚器支持HTTP/2或SSL连接操心。它可以无需这些内容就捕获所有内容,对于不支持的内容,它只是拒绝这些连接。参见https://dev59.com/22kw5IYBdhLWcg3wirCs#68042877

0
if ($http_host != "example.com") {
    return 301 https://example.com;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接