博客 (11)

nginx.conf 中使用 resolver 设置了 DNS 后,nginx 会遵循这个指令,而不是直接使用系统的 hosts 配置。

所以,如果 resolver 设置了外部 DNS(譬如一般的公共 DNS),在 access_by_lua_block 中使用 resty.http 库发起对包含域名的网址的请求,会忽略 hosts 的设置。

解决方案:

1、修改 resolver 指向为本机 DNS。(AI 推荐,实测无效,可以研究一下配合 dnsmasq 使读取 hosts)

查看本机 DNS 的命令:

cat /etc/resolv.conf


nmcli dev show | grep DNS

2、request_uri 中直接请求带 IP 地址的网址。

要求这个网站允许直接使用 IP 地址访问。

需要禁用 SSL 验证(ssl_verify = false)。

xoyozo 半个月前
1,721

前几天实现了在 nginx 中使用 lua 实现远程鉴权,今天想试试在 IIS 中能不能实现相同的功能。查询资料发现需要使用 URL 重写和 HTTP 请求模块,没有深究。干脆使用 ASP.NET 中间件来实现吧。

在 StratUp.cs 的 Configure 方法中,或 Program.cs 文件中添加以下代码:

// 远程鉴权
app.Use(async (context, next) =>
{
    var ip = context.Connection.RemoteIpAddress!.ToString();
    var ua = context.Request.Headers.UserAgent.ToString();
    var host = context.Request.Host.Host;
    var uri = new Uri(context.Request.GetDisplayUrl()).PathAndQuery;

    var client = new HttpClient();
    client.Timeout = TimeSpan.FromSeconds(1); // 设置超时时间

    try
    {
        var requestUrl = "https://鉴权地址/";

        var requestMessage = new HttpRequestMessage(HttpMethod.Get, requestUrl);
        requestMessage.Headers.Add("X-Real-IP", ip);
        requestMessage.Headers.Add("User-Agent", ua);
        requestMessage.Headers.Add("X-Forwarded-Host", host);
        requestMessage.Headers.Add("X-Forwarded-Uri", uri);

        // 发送请求
        var response = await client.SendAsync(requestMessage);

        // 检查响应状态码
        if (response.StatusCode == HttpStatusCode.Forbidden)
        {
            // 如果返回403,则拒绝访问
            context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
            await context.Response.WriteAsync("Access Denied");
        }
        else
        {
            // 如果返回其他状态码,则继续执行管道中的下一个中间件
            await next();
        }
    }
    catch (TaskCanceledException ex) when (ex.CancellationToken.IsCancellationRequested)
    {
        // 如果请求超时(任务被取消),则继续执行管道中的下一个中间件
        await next();
    }
    catch
    {
        // 如果遇到错误,则继续执行管道中的下一个中间件
        await next();
    }
});

代码很简单,使用 HttpClient 发送请求,若返回 403 则拒绝访问,其它情况继续执行业务逻辑,超时或报错的情况按需修改即可。

若鉴权接口在私网中,建议将鉴权接口域名和私网 IP 添加到 hosts 文件中。

xoyozo 9 个月前
973
  • location 优先于 access_by_lua_block,即使 access_by_lua_block 放在 http 中。

  • location 的 3 种匹配的优先级,精确匹配(=) > 正则匹配(~) > 前缀匹配(无符号,直接是“/”开头的 uri 前缀)。

  • 相同匹配类型的多个 location(比如有多个正则匹配),按定义顺序来进行匹配。

  • 一旦有一个 location 被匹配到,就不再继续匹配其它 location。

  • 如果使用 access_by_lua_block 鉴权,那么不要放在任何 location 中,这样,匹配完 location 后只要没有命中直接返回语句,就会继续执行 access_by_lua_block。并且,如果 access_by_lua_block 中鉴权拒绝,后续的业务处理(如 php 业务)不会继续进行。


xoyozo 9 个月前
1,202
http {
    ...

    lua_shared_dict cpu_cache 1m;  # 定义共享字典用于缓存 CPU 使用率
    access_by_lua_block {
        local cpu_cache = ngx.shared.cpu_cache
        local cache_time = cpu_cache:get("cache_time") or 0
        local current_time = ngx.now()

        if current_time - cache_time > 5 then  -- 每 5 秒更新一次
            local cpu_info = io.popen("top -bn1 | grep 'Cpu(s)'"):read("*all")
            local cpu_usage = cpu_info:match("(%d+%.%d+) id")  -- 获取空闲 CPU 百分比
            local cpu_used = 100 - tonumber(cpu_usage)  -- 计算使用率

            cpu_cache:set("cpu_usage", cpu_used)
            cpu_cache:set("cache_time", current_time)
        end

        local cpu_usage = cpu_cache:get("cpu_usage")
        ngx.log(ngx.INFO, "CPU 使用率: " .. cpu_usage .. "%")
        -- 将 cpu_usage 发送到远程鉴权接口,可根据服务器压力来决定是否拒绝一些不重要的请求
    }
}

代码解析:

共享字典:使用 lua_shared_dict 定义一个共享字典 cpu_cache,用于存储 CPU 使用率和缓存时间。

获取 CPU 使用率:在 access_by_lua_block 中,检查缓存时间,如果超过 5 秒,则重新获取 CPU 使用率,并更新共享字典。

记录日志:使用 ngx.log 将 CPU 使用率记录到 Nginx 日志中。

注意事项:

确保 Nginx 配置中已经加载了 Lua 模块(如 ngx_http_lua_module)。

根据实际需求调整缓存时间,以平衡性能和数据的实时性。

尝试过使用 ifconfig 或 ip 命令获取网卡流量,在宝塔面板中失败了,怀疑是权限问题,有空再研究。临时方案是鉴权接口定时调用宝塔面板 API 或阿里云控制台 API 来获取 ECS 的 CPU 和带宽使用率。

如何配置 nginx 远程鉴权

xoyozo 9 个月前
732
  1. 使 lua 支持 resty.http

  2. 在 access_by_lua_block 代码块中实现远程鉴权:

    #鉴权-START
    #resolver 223.5.5.5; # cat /etc/resolv.conf
    access_by_lua_block {
        local http = require("resty.http")
        local httpc = http.new()
        httpc:set_timeout(500)  -- 连接超时
        local res, err = httpc:request_uri("https://鉴权地址/", {
            method = "GET",
            headers = {
                ["X-Real-IP"] = ngx.var.remote_addr,
                ["User-Agent"] = ngx.var.http_user_agent,
                ["X-Forwarded-Host"] = ngx.var.host,
                ["X-Forwarded-Uri"] = ngx.var.request_uri,
            },
            ssl_verify = false, -- 禁用 SSL 验证
            timeout = 500,     -- 读取超时
        })
    
        if not res then
            ngx.log(ngx.ERR, "Failed to request: " .. err)
        end
            
        if res and res.status == 403 then
            ngx.exit(ngx.HTTP_FORBIDDEN)
            -- return ngx.redirect("https://一个显示403友好信息的页面.html")
        end
    }
    #鉴权-END

    注意更改接口地址和友情显示 403 页面地址。

    本示例仅捕获 403 状态码,500、408 等其它异常情况视为允许访问,请根据业务需求自行添加状态码的判断。

    若超时也会进入 if not res then 代码块。

    建议将此代码部署在 nginx 主配置文件的 http 代码块中(宝塔面板中的路径:/www/server/nginx/nginx/conf/nginx.conf),如果你只想为单个网站鉴权,也可以放在网站配置文件的 server 块中。

  3. 若鉴权接口在私网中,建议将鉴权接口域名和私网 IP 添加到 hosts 文件中。


  1. 直接输出字符串

    ngx.header.content_type = "text/plain";
    ngx.say("hello world!")
  2. 输出到日志

    ngx.log(ngx.ERR, "Response status: " .. res.status)

    日志在网站的 站名.error.log 中查看。

    宝塔面板查看方式:日志 - 网站日志 - 异常

  3. 若想获取服务器 CPU 使用率等信息并传递给远程鉴权接口,请参考此文

  4. 常见问题

    no resolver defined to resolve

    原因:没有定义 DNS 解析器

    解决方法:在 http 块或 server 块中添加 resolver 8.8.8.8 valid=30s;,推荐使用接入商自己的公共 DNS,如果走内网,推荐使用本机 DNS

    unable to get local issuer certificate

    原因:没有配置 SSL 证书信息

    解决方法:添加 request_uri 参数:

    ssl_verify = true,  -- 启用 SSL 验证
    ssl_trusted_certificate = "证书路径",  -- 指定 CA 证书路径

    ssl_verify = false,  -- 禁用 SSL 验证
  5. 若您不想用 lua,可以用 nginx 原生自带的  auth_request 模块来实现

xoyozo 9 个月前
1,632
  1. 安装 OpenResty

    在 宝塔面板 - 软件商店 中搜索 nginx,安装版本选择 openresty 版

    image.png

  2. 安装 LuaRocks

  3. 安装 resty.http

    luarocks install lua-resty-http
  4. 检测已安装的组件

    nginx -v
    lua -v
    openresty -v
    luarocks --version
  5. 测试代码

    access_by_lua_block {
        local http = require("resty.http")
    }

    access_by_lua '
        local http = require("resty.http")
    ';
xoyozo 9 个月前
2,120
  1. 安装依赖

    sudo yum install -y epel-release
    sudo yum install -y lua lua-devel gcc make
  2. 下载安装 LuaRocks

    访问 LuaRocks 的官方网站 获取最新版本的 LuaRocks。你可以使用 wget 命令下载:

    wget https://luarocks.org/releases/luarocks-x.x.x.tar.gz
    tar zxpf luarocks-x.x.x.tar.gz
    cd luarocks-x.x.x
    ./configure && make && sudo make install
  3. 设置环境变量(可选)

    通常,LuaRocks 会自动处理这一步,但如果需要手动设置,可以编辑 ~/.bash_profile 或 ~/.bashrc 文件,添加以下行:

    export PATH=$PATH:/usr/local/bin

    然后运行以下命令使更改生效:

    source ~/.bash_profile
  4. 验证安装

    luarocks --version
xoyozo 9 个月前
811

鉴权方式有许多,譬如可以用 lua 的 access_by_lua 来实现,这里用 nginx 自带的 auth_request,虽然功能简单,但效率更高。

第一步,确保 nginx 已编译安装 auth_request 模块,见此文

第二步,打开需要鉴权的网站的 nginx 配置文件,添加以下代码块:

    #鉴权-START
    location / {
        auth_request /auth;
        error_page 403 = @error403;
        
        #PHP-INFO-START  PHP引用配置,可以注释或修改
        include enable-php-**.conf;
        #PHP-INFO-END
    }
    location = /auth {
        internal;
        proxy_pass https://鉴权地址;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header User-Agent $http_user_agent;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Uri $request_uri;
        proxy_intercept_errors on;
        #proxy_read_timeout 1s; # 超时会报 500
    }
    location @error403 {
        #default_type text/plain;
        #return 403 'forbidden';
        return 302 https://一个显示403友好信息的页面.html;
    }
    #鉴权-END

一般放在所有的 location 之前。

这里自定义请求头 X-Forwarded-HostX-Forwarded-Uri 用来传递 host 与 uri。API 应从 Header 中相应取值。

宝塔面板中是通过 include enable-php-**.conf; 的方式调用 PHP ,那么可以将此行移入上面的 location / 代码块中,因为此代码块能匹配所有的请求路径。

最后,若鉴权接口在私网中,将鉴权接口域名和私网 IP 添加到 hosts 文件中。

xoyozo 10 个月前
1,122

打开 JS 文件,查找:

o+=String.fromCharCode(t.charCodeAt(r)^i[(i[e]+i[s])%256]);

水印文字是从这个变量 o 输出来的,可以在这句的后面,“return o”的前面插入“console.log(o);”看到效果。

因为它是一行一行返回的,所以将

return o

改为下面的三目即可:

return o=='GoJS 3.0 evaluation'||o=='(c) 1998-2024 Northwoods Software'||o=='Not for distribution or production use'||o=='gojs.net'?'':o

修改方法来源于网络,仅供学习参考,请勿用于生产环境,请支持正版!

xoyozo 1 年前
2,779
  1. 购买 ECS

  2. 解析域名(非网站域名)、修改实例名称、主机名

  3. 设置阿里云(重要)

  4. 远程连接进入 ECS(若解析未生效可以先用 IP)(若新服默认使用 22 端口,可在阿里云控制台登录系统,或先在安全组临时放行 22 端口)

  5. 修复系统漏洞

  6. 将磁盘挂载到目录(fdisk、df 命令参考:https://xoyozo.net/Blog/Details/SSH

  7. 安装宝塔面板(本文以宝塔面板方案为例,选择任何你喜欢的环境部署方案都行)。可以在阿里云控制台ECS实例页安装扩展程序

  8. 临时放行宝塔面板端口,进入宝塔面板(http方式),或用命令更改宝塔面板端口

  9. 配置面板 SSH、添加新的安全端口、面板设置

  10. 更改 SSH 默认端口(参:https://xoyozo.net/Blog/Details/change-default-port

  11. 安装 nginx、PHP 等

  12. 通过 lua 接入 WAF

  13. 配置 PHP 扩展(Redis、sqlsrv(注意选择兼容的版本)、memcached 及端口)

  14. 创建网站,配置网站(路径、伪静态等)

  15. 迁移网站文件(参:https://xoyozo.net/Blog/Details/SSH

  16. 仔细对比新旧网站的配置文件(特别是 .php 的访问权限,参:https://xoyozo.net/Blog/Details/nginx-location-if

  17. 设置写入目录(使用 rsync 同步的文件会同步用户和权限)

  18. 解析域名(先改 hosts 测试网站功能)

  19. 更改内网其它 ECS 上的 hosts

  20. 关闭原 ECS(能马上发现问题,不然等运行一段时间才发现问题就麻烦点)

  21. 设置 FTP

  22. 迁移“计划任务”

  23. 所有网站和软件的配置文件都要使用 WinMerge 进行对比

  24. 移除“宝塔面板-安全”和“阿里云-ECS-安全组”中不用的端口

  25. 再次检查阿里云设置

  26. 私网中若有 ECS 的 hosts 中域名直接绑定到私网 IP 的,做相应更改

  27. 其它:ERP 添加到期提醒、WAF 增加该 ECS、备份工具增加该 ECS


更多文章:

从零搭建一台阿里云 ECS(Windows Server)并迁移网站

xoyozo 1 年前
2,969