笔者的主服务使用的是 PHP 系统,具备账户登录功能,主服务之外还使用了 phpRedisAdmin 等第三方拿来即用的目录服务,以及通过本地端口转发的服务(通过 proxy_pass
反向代理)。示例 Nginx 配置如下:
location / {
...
try_files $uri $uri/ /index.php$is_args$args;
}
location /kibana/ {
...
proxy_pass http://127.0.0.1:5601;
}
// phpRedisAdmin 放置在主服务的 web 目录中,可直接访问。
以上的配置,即使主服务使用了账户登陆认证,因为主服务相当于 Nginx 的后端,不能影响到主服务 web 目录以及反向代理节点的访问。那么,类似这里的 web目录 /phpRedisAdmin 和 反向代理节点 /kibana 该如何进行鉴权操作?下面提供两种便捷的方法,适用于安全性要求不高小型系统。
一、HTTP Auth Basic
HTTP Auth Basic 是一个非常简单且传统的 API 鉴权技术,要求使用用户名和密码对用户身份进行认证。
首选,在 Nginx 的 server 或 location 块启用 Auth Basic:
auth_basic 'kanchuan auth';
auth_basic_user_file /htpasswd_file;
浏览器在认证时,将 username
和 password
进行如下运算:
base64("{username} : {password}")
将 base64 的结果放在 HTTP 头部的 Authorization:
字段中。比如,username = kanchuan、password = kanchuan.com,组装后格式为:
Authorization: Basic a2FuY2h1YW46a2FuY2h1YW4uY29t
服务器解析 Authorization 字段进行认证,认证失败则返回 401:
401 Authorization Required
详细的过程参考:HTTP Authentication rfc2617。
这种方式的最大问题就是把用户名和密码直接放在请求中,所以必须启用 HTTPS 才安全点。即便如此,这个协议还是过于简单粗暴,现在基本上已经没有公开的系统会使用了。但作为内部的小型系统,还是可以胜任一下。
二、Nginx Cookie 判断
对于主服务已经有账户登录的系统,可以选择使用这种方式。一般都采取 Cookie 来存储登录凭证,那么就可以在 Nginx 的规则中判断是否有对应的 Cookie,没有则重定向到登录页面。如下示例:
location /kibana/ {
if ($cookie_token = "") {
return 301 /user/login;
}
...
proxy_pass http://127.0.0.1:5601;
}
语法为 $cookie_{key}
表示从 Cookie 中读取 key 的值。
这种方法的弊端就是,由于 Nginx 系统没有对登录凭证的验证能力,只能判断有或没有,攻击者可以通过在浏览器中编辑 Cookie 的方式绕过认证。
留言板