对免认证服务提供apikey验证

一些服务不带认证,凡是可以访问到服务端口,都可以正常使用该服务,方便是方便,但是不够安全。

比如ollama默认安装后就是这样。现在据说网上扫一下端口11434,免apikey的ollama服务一大堆。。。

那我们怎样将本机安装的ollama能提供给其他用户使用,并且可以加apikey的限制呢?其实方案有很多,我说一个轻量级的解决方案,nginx代理转发,并且进行header中的Authorization信息的检查。

固定值的可以直接写在nginx.conf配置文件里,最简单;如果是使用json文件来存放apikey信息的话,nginx需要使用lua模块来读取json文件,进行解码,windows版的nginx默认不带lua模块,可以用openresty,它相当于集成了lua模块的nginx。json内容可以由其他应用来维护,不过内容有变化需要考虑,如果要求实时更新,那么最好在应用修改json文件内容时也同时通知nginx来更新;或者干脆由另外一个web服务来负责header中apikey的检查,nginx里要写lua代码去执行调用,根据返回结果来决定是否放行;还有一个就是我最终选择的方案-redis,apikey维护服务在apikey生效或者失效时更新redis的集合,nginx从redis里检查集合里是否包含请求头中的apikey。nginx.conf里的lua部分相关代码如下:

lua 复制代码
...
http {
    # 引入 Lua 模块
    lua_package_path "lualib/?.lua;;";
    lua_package_cpath "lualib/?.so;;";

    # 定义 Redis 连接参数
    upstream redis_backend {
        server 127.0.0.1:6379;  # Redis 服务器地址
        keepalive 10;           # 保持连接
    }
	...
    server {
		listen  443 ssl;
		...

        location /ollama/ {
        
            #if ($request_method = 'OPTIONS') {
            #	return 204;
            #	}
            
            access_by_lua_block {
                -- 获取请求头中的 Authorization
                local auth_header = ngx.var.http_Authorization
                if not auth_header then
                    ngx.status = ngx.HTTP_UNAUTHORIZED
                    ngx.say("Unauthorized: Missing Authorization header")
                    return ngx.exit(ngx.HTTP_UNAUTHORIZED)
                end

                -- 连接 Redis
                local redis = require "resty.redis"
                local red = redis:new()
                red:set_timeout(1000)  -- 设置超时时间为 1 秒

                local ok, err = red:connect("127.0.0.1", 6379)
                if not ok then
                    ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR
                    ngx.say("Internal Server Error: Failed to connect to Redis")
                    return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
                end

                -- 查询 Redis 中是否存在该密钥
                local is_member, err = red:sismember("auth_keys", auth_header)
                if not is_member then
                    ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR
                    ngx.say("Internal Server Error: Failed to query Redis")
                    return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
                end

                -- 关闭 Redis 连接
                local ok, err = red:set_keepalive(10000, 100)
                if not ok then
                    ngx.log(ngx.ERR, "Failed to set keepalive: ", err)
                end

                -- 检查密钥是否有效
                if is_member == 0 then
                    ngx.status = ngx.HTTP_UNAUTHORIZED
                    ngx.say("Unauthorized: Invalid Authorization key")
                    return ngx.exit(ngx.HTTP_UNAUTHORIZED)
                end
            }

            # 如果验证通过,代理到目标服务器
            
    		#add_header 'Access-Control-Allow-Origin' '*';
    		#add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    		#add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
			#add_header 'Access-Control-Max-Age' 1728000;

			#proxy_set_header origin http://127.0.0.1:11434;
        	#proxy_set_header X-Real-IP $remote_addr;
        	#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        	#proxy_set_header X-Forwarded-Proto $scheme;
			#proxy_set_header Authorization $http_authorization;
			#proxy_set_header Host localhost:11434;

            proxy_pass http://127.0.0.1:11434;
        }
        ...
    }
}
...

主要是可以参考下lua里将header里认证信息与redis集合进行匹配,其他nginx转发设置头信息跟后端服务要求而定。

相关推荐
狂炫冰美式1 小时前
前端实时推送 & WebSocket 面试题(2026版)
前端·http·面试
q***d1733 小时前
前端微前端部署方案,Nginx与Webpack
前端·nginx·webpack
代码炼金术士7 小时前
linux的nginx版本升级
linux·运维·nginx
小糖学代码10 小时前
网络:5.应用层协议HTTP
网络·网络协议·http
CXH72812 小时前
nginx-file-server
运维·数据库·nginx
寺中人12 小时前
Nginx安全策略
运维·nginx
liu****13 小时前
18.HTTP协议(一)
linux·网络·网络协议·http·udp·1024程序员节
橘色的喵15 小时前
C语言面向对象范式:Nginx模块化架构的设计分析
c语言·nginx·架构·面向对象
thekenofdis20 小时前
Lua脚本执行多个redis命令提示“CROSSSLOT Keys in request don‘t hash to the same slot“问题
redis·lua·哈希算法
another heaven1 天前
【计算机网络 HTTP 请求参数规范详解】
网络协议·计算机网络·http