对免认证服务提供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转发设置头信息跟后端服务要求而定。

相关推荐
二哈喇子!12 小时前
openFuyao 容器平台快速入门:Nginx 应用部署全流程实操
运维·nginx·openfuyao
喵爸的小作坊15 小时前
StreamPanel:一个让 SSE 调试不再痛苦的 Chrome 插件
前端·后端·http
Robot侠18 小时前
极简LLM入门指南1
llm·llama
李少兄19 小时前
从零开始全面掌握 HTTPS
网络协议·http·https
J2虾虾20 小时前
上传文件出现“ 413 Request Entity Too Large“错误
nginx
是垚不是土20 小时前
基于Blackbox Exporter的网络服务黑盒监控体系实践
网络·数据库·安全·http·微服务·prometheus
枫叶梨花20 小时前
Nginx HTTPS代理大文件加载失败的排查与解决方案
nginx
那我掉的头发算什么20 小时前
【javaEE】保姆级 HTTP 全解析:请求响应 + 状态码 + Fiddler 实操
网络·http·java-ee·fiddler
IMPYLH20 小时前
Lua 的 Debug(调试) 模块
开发语言·笔记·python·单元测试·lua·fastapi
明明明h21 小时前
Lua中 . 和 : 的区别
lua