内容简介:前段时间,负责ELK那哥们儿想把Kibana调整成为LDAP内部用户认证,运维这边了解到这个需求,着手调研。版本选择:Nginx 1.14.1
问题背景
前段时间,负责ELK那哥们儿想把Kibana调整成为LDAP内部用户认证,运维这边了解到这个需求,着手调研。
解决方案及思路
首先Kibana现在只是用了一个叫 Search guard 的插件来控制访问,但是这个插件需要和JIRA用户统一认证,需要手动开通账户,维护成本高,并且实施起来的效率也很低,所以才打算搭建一个LDAP服务器,然后同步JIRA用户信息,实现Kibana统一认证。
经过讨论方案,大致的初步方案就是通过结合Nginx的 auth_request 模块,当用户请求一个受特定保护的资源时候, auth_request 会将请求转发到LDAP验证服务上,然后根据验证服务返回的状态码决定重定向或者允许访问等进一步的操作。其中在Nginx配置文件中的LDAP认证服务中需要完善LDAP服务器的配置信息。大概的思路就是这样,想到这里的时候,又发现一个问题, 如何保证LDAP和JIRA用户能够及时同步呢,并且各种权限的信息也需要相应的对接 。
这时候负责 JIRA 的哥们儿,说其实我们那边有个接口,可以通过POST用户名和密码信息,验证是否能够登录。并且验证通过会返回一个有关用户信息的JSON,如果想要进行权限控制的话,也可以通过这个JSON。所以现在事情就变得简单了,重新简单梳理一下解决方案。
如下:
- 1、用户请求受保护的Nginx反向代理资源
- 2、Nginx的auth_request模块将请求转发给自己写的django的验证服务中。判断cookie解密后是否正确。如果都符合条件则返回200状态码,nginx不会拦截请求,而是构建一个subprocess请求受保护的本地资源。
- 3、如果django验证服务没有通过,则会返回一个401请求,nginx对401请求进行拦截并且重定向到登录页面,所以就返回到django的login服务中,展示登录界面。
- 4、在登录界面中,输入用户名和密码提交,传到后端时,后端使用内部接口,发送用户名和密码,通过返回的状态码验证是否成功,成功之后将用户名加密之后放入cookie并且重定向到受保护的资源中;验证失败则返回提示用户名或者密码失败。
详细设计
前期准备工作
版本选择:
Nginx 1.14.1
Django 1.9.13
Kibana 6.5.1
Python 2.7
需要注意事项: 1、Nginx需要注意的点就是,默认yum安装的Nginx没有编译auth_request模块, 所以需要到官网重新下载源码,增加--with-http_auth_request_module进行编译。 2、代码中需要用到 Python 的requests、Crypto 模块需要额外安装
Nginx 1.4.1下载地址:
http://nginx.org/download/nginx-1.14.1.tar.gz
requests 模块安装:
pip install requests
Crypto模块安装:
pip install Crypto
安装成功后,可分别通过nginx -V、pip show requests、pip show Crypto验证:
代码分析
最开始设计后端的验证服务时参考了Nginx官网上,Nginx结合ldap的身份验证demo,demo地址:
https://github.com/nginxinc/nginx-ldap-auth
demo中大致的思路就是接受请求,首次访问将会重定向到login页面上,loging登录后,将接收到的用户名和密码,去查询ldap服务器上的信息,成功后将把用户名和密码以 ; 号连接后做 base64 写入 cookie,下一次访问受保护的资源时,然后写 Location 里写入 target 的值,来实现重定向跳回。
但是demo中首先的问题就是用户和密码这种敏感的信息不应该放入cookie中,并且在demo中用到了简单的BaseHTTPServer ,用这个模块就会出现几个问题:
- 1、不支持url的解析和转发,需要用户自己解析
- 2、回写的响应需要自己维护格式,容易出错
- 3、没有模板支持,如果需要写HTML页面,也需要自己维护。
所以为了解决以上的缺点,刚好对于Django有一定的了解,就打算基于Django框架实现用户验证的服务,以及登录时模板页面。废话不多说来看看代码。
代码详解: 首先是验证服务,通过检查是否存在 cookie ,不存在的话就返回状态码401;如果存在的话,通过将cookie解密,获取其中关键的字段,判断是否登录,如果解密成功的话,返回状态码 200 ,解密失败的话,返回状态码 401 。
class prcrypt(object): def __init__(self,key): if len(key) < 16: key = key+(16-len(key))*'\0' self.key = key self.mode = AES.MODE_CBC def encrypt(self,text): cryptor = AES.new(self.key,self.mode,IV=self.key) length = 16 count = len(text) add = count % length if add : text = text + ('\0' * (length-add)) self.ciphertext = cryptor.encrypt(text) return base64.b64encode(self.ciphertext) def decrypt(self,text): cryptor = AES.new(self.key,self.mode,IV=self.key) plain_text = cryptor.decrypt(base64.b64decode(text)) return plain_text.rstrip('\0')
代码详解:这段加密操作通过 aes 模块进行加密,大概原理首先传入一个 key 值,作为实例化 AES对象的密钥 。然后将需要加密的文本补足成 16的倍数 进行加密操作,最后将加密后的文本 base64 进行转换。解密的话 逆操作 即可。
代码详解:首先 前面一部分 代码是接收前端传来的用户名和密码,并且通过requests模块post到指定的接口地址,然后解析返回的结果,根据返回结果的状态码判断是否能登陆成功。
第二部分通过判断登录成功后,将 用户名和登录状态 加密,设置cookie,指定 超时时间 一小时,只能由http协议传输。然后重定向到 受保护的资源 ,受保护的资源就会再次请求 验证服务 ,验证服务对cookie进行 判断正确后 就会允许访问受保护资源;如果 登录失败 则会返回无效用户名和密码到登录界面。
前端登录界面:
配置分析
http { include /etc/nginx/mime.types; upstream backend { server 192.168.128.5:5601; } #需要受保护的Kibana程序 server { listen 8081; # nginx服务开放8081端口 location / { auth_request /auth-proxy; error_page 401 =200 /login; proxy_pass http://backend/; } #这个路径下受auth-request保护,所有401的请求都会重定向到login上 location /login { proxy_pass http://127.0.0.1:8888/login; proxy_set_header X-Target $request_uri; } # 这是我们认证的页面,指向我们django项目中的login路径 location /auth-proxy { internal; proxy_pass http://127.0.0.1:8888; } # 这里用作auth-request请求的路径 location /static{ alias /data/htdocs/www/elk/static/; } } }
上面就是主要的Nginx配置文件
urlpatterns = [ url(r'^$',login), url(r'^login',login), url(r'^auth-proxy',nginx_auth), url(r'^admin/', include(admin.site.urls)), ]
对应django项目的urls文件
总结
其实这个用户认证的解决方案不难理解,比较麻烦就是最初需求了解确定以及和其他项目负责人沟通的问题。在技术上单纯的没什么难点。
通过在网上查资料,还有Nginx官网上的一些demo有助于你迅速了解到模块的用处,以及对一些问题的解决方案,不少网友也遇到了类似的问题,在他们身上多总结经验,有助于自己解决问题,所以一句话“多动手,多沟通,知行合一”。
以下是我参考的一些网站和博客,大家有兴趣可以看看:
Nginx官网上利用auth_request结合LDAP的认证方案:
https://www.nginx.com/blog/nginx-plus-authenticate-users/用 Nginx 的 auth_request 模块集成 LDAP 认证:
https://www.jianshu.com/p/9f2da3cf5579
python的aes加密和解密:
https://my.oschina.net/u/1458120/blog/648350以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 认证授权方案之授权揭秘 (上篇)
- 聊聊 Web API 认证方案那点儿事
- 技术工坊47期 - 区块链医疗方案和分布式认证介绍
- 跨域认证解决方案-JSON WEB TOKEN讲解与实战
- AWS 专家级解决方案架构师认证 (SAP) 备考指北
- 身份认证之双因素认证 2FA
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。