AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1082571
Accepted
ehammer
ehammer
Asked: 2021-11-04 15:01:54 +0800 CST2021-11-04 15:01:54 +0800 CST 2021-11-04 15:01:54 +0800 CST

NGINX反向代理“如果不是”语句语法?

  • 772

我有一个 nginx 反向代理,我想基本上将任何不是我特定顶级域的 url 请求重定向到 404。

到目前为止,我想我想在我的底部有这样的东西/etc/nginx/sites-enabled/site.conf:

server {
        listen 80;
        if ($host != *domain.com) {
                return 404 http://$host$request_uri;
        }
}

但我不知道这里的确切语法。我已经在这个上面有其他重定向块,我只希望对仅 IP 主机名或其他域的任何 url 请求立即获得 404,而不是传递给后端服务器。

此外,我也有 TLS 直通,我想做同样的事情,但我完全不知道如何在流块上实现 if 语句。我的流块如下所示/etc/nginx/nginx.conf:

stream {
        map $ssl_preread_server_name $name {
                server.domain.com           server;
                www.domain.com              www;
        }
        upstream server {
                server backendip:443;
        }
        upstream www {
                server backendip2:443;
        }
        server {
                listen 443;
                proxy_pass $name;
                ssl_preread on;
        }
}

为此,我会在第一个服务器块下方实现类似的东西吗?

        server {
                listen 443;
                if ($ssl_preread_server_name != *domain.com) {
                        return 404 https://$host$request_uri;
                }
        }

我认为为了安全起见,我还应该在带有 if 语句的这两个块的侦听行中包含 default_server ,或者这有关系吗?

我只是在这里假设很多语法,所以任何帮助将不胜感激。

nginx reverse-proxy
  • 1 1 个回答
  • 650 Views

1 个回答

  • Voted
  1. Best Answer
    Ivan Shatsky
    2021-11-05T12:28:20+08:002021-11-05T12:28:20+08:00

    我不知道如何优雅地关闭与流模块的连接,所以我不确定这是否是一个正确的解决方案,但值得一试(您可以为虚拟服务器/上游使用任何空闲端口):

    stream {
        map $ssl_preread_server_name $name {
            server.domain.com           server;
            www.domain.com              www;
            default                     dummy;
        }
        upstream server {
            server backendip:443;
        }
        upstream www {
            server backendip2:443;
        }
        upstream dummy {
            backend 127.0.0.1:4343;
        }
        server {
            listen 443;
            proxy_pass $name;
            ssl_preread on;
        }
        server {
            listen 4343;
            return "";
        }
    }
    

    更新

    在对上述解决方案进行测试后,我可以确认它是可行的。但是它会产生一个错误日志条目,例如

    WSARecv() 在代理和从上游读取时失败(10053:已建立的连接被主机中的软件中止),客户端:127.0.0.1,服务器:127.0.0.1:443,上游:“127.0.0.1:4343” ,来自/到客户端的字节:517/0,来自/到上游的字节:0/517

    所以经过一番思考,我尝试了这个:

    http {
        server {
            listen              4343 ssl;
            ssl_certificate     /path/to/selfsigned.crt;
            ssl_certificate_key /path/to/selfsigned.key;
            return              444;
        }
    }
    stream {
        map $ssl_preread_server_name $name {
            server.domain.com           server;
            www.domain.com              www;
            default                     dummy;
        }
        upstream server {
            server backendip:443;
        }
        upstream www {
            server backendip2:443;
        }
        upstream dummy {
            backend 127.0.0.1:4343;
        }
        server {
            listen 443;
            proxy_pass $name;
            ssl_preread on;
        }
    }
    

    可以使用以下命令创建自签名证书和密钥:

    openssl req -nodes -new -x509 -subj "/CN=localhost" -keyout /path/to/selfsigned.key -out /path/to/selfsigned.crt
    

    这个正确地关闭了连接。

    此外,即使这样也有效:

    http {
        server {
            listen              80 default_server;
            return              444;
        }
    }
    stream {
        map $ssl_preread_server_name $name {
            server.domain.com           server;
            www.domain.com              www;
            default                     dummy;
        }
        upstream server {
            server backendip:443;
        }
        upstream www {
            server backendip2:443;
        }
        upstream dummy {
            backend 127.0.0.1:80;
        }
        server {
            listen 443;
            proxy_pass $name;
            ssl_preread on;
        }
    }
    

    当然,curl会抱怨 SSL 版本号不正确的握手尝试,并且访问日志中有一些有趣的条目,例如

    127.0.0.1 - - [05/Nov/2021:01:04:34 +0200] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03L\xF9[\xB2\x7F \x99\xB1(\xAC\xB4\x91}\xE2N\xC6H\xE3\xB3_\xD1\xEA\xA3C\x1D\xE5\xE5\xB6\x02\xDB\x04h\xB6 *\xCB\x0E\xC0\ xF5\xB7\xAF[y|\x1B\x14_\xC2g\xEA\xA2\x1E\xB4\xC4Bj3t\xE8d\xE72vm\xF2\x1B\x00>\x13\x02\x13\x03\x13\x01\xC0, \xC00\x00\x9F\xCC\xA9\xCC\xA8\xCC\xAA\xC0+\xC0/\x00\x9E\xC0$\xC0(\x00k\xC0#\xC0'\x00g\xC0" 400 163 "- “”——

    但错误日志很清楚。

    • 1

相关问题

  • Gzip 与反向代理缓存

  • nginx 作为代理的行为

  • Nginx 学习资源 [关闭]

  • 提供 70,000 个静态文件 (jpg) 的最佳方式?

  • 在 Apache、LightTPD 和 Nginx Web 服务器上提供 PHP 5.x 应用程序的现状?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve