You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何制作带后门的「服务暂时不可用」页面?生产环境测试仅开放开发者访问

嘿,这两个场景都是日常运维、测试阶段非常实用的需求,我来帮你一步步落地实现:

问题1:制作带有后门的「Service temporarily not available」页面

要实现这个功能,核心是静态维护页面 + 服务器/应用层的权限判断逻辑——纯静态页面没法做后门验证,必须结合后端规则来区分允许访问的请求。

第一步:先做友好的维护页面

先写一个简洁的静态HTML页面,命名为maintenance.html:

<!DOCTYPE html>
<html>
<head>
    <title>Service Unavailable</title>
    <style>
        body { text-align: center; padding: 60px; font-family: 'Arial', sans-serif; background-color: #f5f5f5; }
        .container { max-width: 600px; margin: 0 auto; }
        h1 { font-size: 48px; color: #333; margin-bottom: 20px; }
        p { font-size: 18px; color: #666; line-height: 1.6; }
    </style>
</head>
<body>
    <div class="container">
        <h1>Service temporarily not available</h1>
        <p>We're performing final system testing. Please check back later.</p>
    </div>
</body>
</html>

第二步:添加后门验证逻辑

根据你的服务器环境,这里提供两种常见实现方式:

方式1:Nginx服务器层面控制(适合无需应用层介入的场景)

在Nginx配置文件中添加规则,判断请求是否符合后门条件(指定IP、Cookie或URL参数),符合则转发到正常服务,否则返回维护页面:

server {
    listen 80;
    server_name your-domain.com;

    # 定义允许访问的标记,默认拒绝
    set $allow_access "no";

    # 规则1:允许指定开发者IP访问
    if ($remote_addr = "192.168.1.100") {
        set $allow_access "yes";
    }

    # 规则2:允许携带正确Cookie的请求(比如开发者登录后设置的Cookie)
    if ($cookie_maintenance_auth = "your-secret-password") {
        set $allow_access "yes";
    }

    # 规则3:允许携带正确URL参数的请求(临时调试用)
    if ($arg_backdoor_key = "your-secret-password") {
        set $allow_access "yes";
    }

    # 符合条件则转发到后端服务
    if ($allow_access = "yes") {
        proxy_pass http://your-backend-service:8080;
        break;
    }

    # 否则返回维护页面
    root /usr/share/nginx/html/maintenance;
    index maintenance.html;
}

方式2:应用层拦截器控制(和问题2的方案统一,适合需要更灵活逻辑的场景)

具体实现可以参考问题2的拦截器代码,把维护页面的返回逻辑整合进去即可。


问题2:真实环境测试仅允许开发者访问的拦截器实现

你的思路非常靠谱!拦截器方案能在应用层灵活控制所有请求,完全满足需求。下面以Java Spring Boot为例(其他框架如Node.js Express、Python Flask逻辑类似),给你落地代码:

第一步:编写拦截器类

实现HandlerInterceptor接口,在preHandle方法中完成权限校验、会话失效和重定向逻辑:

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MaintenanceInterceptor implements HandlerInterceptor {

    // 从配置文件读取允许的IP列表,避免硬编码
    @Value("${maintenance.allowed-ips}")
    private String[] allowedIps;

    // 从配置文件读取后门密码,更安全
    @Value("${maintenance.backdoor-password}")
    private String backdoorPassword;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 校验请求IP是否在允许列表中
        String clientIp = getRealClientIp(request);
        for (String ip : allowedIps) {
            if (ip.trim().equals(clientIp)) {
                return true; // 允许访问
            }
        }

        // 2. 校验URL参数是否携带正确密码
        String urlParamKey = request.getParameter("backdoor-key");
        if (backdoorPassword.equals(urlParamKey)) {
            return true;
        }

        // 3. 校验Cookie是否携带正确密码
        String cookieAuth = null;
        if (request.getCookies() != null) {
            for (var cookie : request.getCookies()) {
                if ("maintenance-auth".equals(cookie.getName())) {
                    cookieAuth = cookie.getValue();
                    break;
                }
            }
        }
        if (backdoorPassword.equals(cookieAuth)) {
            return true;
        }

        // 所有条件都不满足:失效会话 + 重定向到维护页面
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }
        response.sendRedirect("/maintenance.html");
        return false;
    }

    // 处理反向代理场景下的真实IP获取(比如Nginx代理)
    private String getRealClientIp(HttpServletRequest request) {
        String realIp = request.getHeader("X-Real-IP");
        if (realIp == null || realIp.isEmpty()) {
            realIp = request.getRemoteAddr();
        }
        return realIp;
    }
}

第二步:注册拦截器到应用

创建Web配置类,把拦截器注册到Spring容器,并指定拦截范围:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.beans.factory.annotation.Autowired;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private MaintenanceInterceptor maintenanceInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(maintenanceInterceptor)
                .addPathPatterns("/**") // 拦截所有请求
                .excludePathPatterns("/maintenance.html"); // 排除维护页面本身
    }
}

额外注意事项

  • 密码安全:绝对不要把后门密码硬编码到代码里,用配置文件、环境变量或者配置中心存储更安全。
  • 反向代理IP问题:如果你的应用部署在Nginx等反向代理后面,一定要配置X-Real-IP或X-Forwarded-For头,否则获取到的是代理服务器的IP,不是真实客户端IP。
  • Cookie有效期:如果用Cookie方式,建议给Cookie设置短期有效期,避免长期留存带来的安全风险。

内容的提问来源于stack exchange,提问作者user2652379

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:37:56