插件窝 干货文章 Nginx如何实现基于请求来源域名的访问控制配置

Nginx如何实现基于请求来源域名的访问控制配置

referer server http com 749    来源:    2025-04-10

Nginx基于请求来源域名的访问控制配置

Nginx可以通过多种方式实现基于请求来源域名的访问控制,以下是几种常见的方法:

1. 使用$http_referer变量进行控制

server {
    listen 80;
    server_name example.com;

    location / {
        # 只允许来自trusted.com的请求
        if ($http_referer !~* ^https?://(www\.)?trusted\.com/) {
            return 403;
        }

        # 其他配置
    }
}

2. 使用$http_origin变量(适用于CORS请求)

server {
    listen 80;
    server_name example.com;

    location / {
        # 设置允许的源域名
        set $cors "";
        if ($http_origin ~* (https?://(www\.)?(allowed1.com|allowed2.com))) {
            set $cors $http_origin;
        }

        # 如果来源不在允许列表中,返回403
        if ($cors = "") {
            return 403;
        }

        # 设置CORS头
        add_header 'Access-Control-Allow-Origin' "$cors";
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';

        # 其他配置
    }
}

3. 使用GeoIP模块(基于IP的地理位置)

http {
    geoip_country /usr/share/GeoIP/GeoIP.dat;

    server {
        listen 80;
        server_name example.com;

        location / {
            # 只允许来自特定国家的访问
            if ($geoip_country_code != "US") {
                return 403;
            }

            # 其他配置
        }
    }
}

4. 使用map指令创建域名白名单

http {
    map $http_referer $allowed_referer {
        default 0;
        "~*^https?://(www\.)?trusted1.com/" 1;
        "~*^https?://(www\.)?trusted2.com/" 1;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            if ($allowed_referer = 0) {
                return 403;
            }

            # 其他配置
        }
    }
}

5. 使用Lua模块进行更复杂的控制(需要安装ngx_http_lua_module)

server {
    listen 80;
    server_name example.com;

    location / {
        access_by_lua_block {
            local referer = ngx.var.http_referer
            local allowed = false

            -- 检查白名单
            local whitelist = {
                "trusted1.com",
                "trusted2.com"
            }

            if referer then
                for _, domain in ipairs(whitelist) do
                    if string.find(referer, domain) then
                        allowed = true
                        break
                    end
                end
            end

            if not allowed then
                ngx.exit(ngx.HTTP_FORBIDDEN)
            end
        }

        # 其他配置
    }
}

注意事项

  1. $http_referer可以被伪造,不能完全依赖它进行安全控制
  2. 对于API接口,建议结合API密钥或OAuth等更安全的认证方式
  3. 在生产环境中,建议使用HTTPS来确保传输安全
  4. 复杂的访问控制可能需要结合Nginx的auth_request模块或其他认证方式

以上方法可以根据实际需求组合使用,实现更灵活的访问控制策略。