标签存档: Docker

基于钉钉 + Virtual-LDAP + KeyCloak 的内网统一认证系统

0. 架构

基于钉钉的内网统一认证

1. 背景

最近公司内网的各种系统部署得越来越多,每个系统都有自己的认证方式和账号体系,这导致大家在每个地方都要去注册一个账号,并且不利于公司统一管理密码安全策略,例如密码到期策略、密码复杂度策略以及强制二次验证等。

以及对于一部分短平快的内网应用来说,我们并没有时间去为它开发一套用户体系,这个时候还是希望能有一个统一的前端反向代理来处理用户认证这个流程。

为此,我就去寻找了一些解决方案,并且为了解决开源系统并不能对接外部用户系统的问题,开发了一个 Node.JS Package(Virtual-LDAP)来提供 LDAP 能力。

2. 问题

虽然总的需求是一个很简单的功能,但是这其中还是有很多细节的问题需要考虑。

认证方式

对于有一些开源系统,它本身是支持 OAuth 来进行用户认证的,这个时候只需要去选择一个支持 OAuth 的用户管理系统就可以了,甚至基于开源库自己去开发一个也并不困难。但是对于某一些开源系统来说,它并没有提供 OAuth 认证接入的支持,只提供了 LDAP 接入。

例如最近我们引入了 Metabase 作为面向运营的快速 BI 分析工具,但是它除了可以接入 Google 账号作为认证方式,就只能接受 LDAP 作为认证方式了。这个时候就得去寻找一个认证系统,同时能支持 OAuth 以及 LDAP。

用户体系

引入用户管理系统之后,还有另外一个问题需要考虑,就是现在员工的用户体系需要去管理。对于一个小公司来说,目前并没有一个统一的工具去同时管理员工的各种信息以及状态。

但是目前公司已经引入钉钉作为公司的交流沟通工具,以及作为各种流程的审批处理系统,HR 也会在钉钉上去管理所有员工的状态,以及员工的组织架构。

因此,这个用户管理系统最好需要能支持同步钉钉中的用户体系,这样就不需要额外的人力去维护用户管理系统,以及在有员工状态变更的时候,能及时同步,避免出现授权外的访问。

数据同步

有了 OAuth,有了 LDAP,还有了钉钉这个数据源,因此就需要处理好各个 Provider 之间的数据同步问题,避免人工去维护各个系统里面的用户数据,做到以钉钉的数据为基础,用户管理系统提供能力,做到各个系统各个认证方式得到的用户数据都是一致的。

以及,对于 LDAP 来说,它是有组织架构的概念的,这个可以在对接到它的应用系统中,快速映射到应用中的用户组,实现用户的权限自动分配和管理,避免每次有新员工加入,都需要单独去配置一次各个业务系统的权限。因此,这也要求用户管理系统能够做到同步钉钉的组织架构,无需额外管理。

3. 解决方案

KeyCloak

KeyCloak Admin Console

KeyCloak 是一个开源软件产品,旨在为现代的应用程序和服务,提供包含身份管理和访问管理功能的单点登录工具。

KeyCloak 提供了丰富的功能用于公司内部单点登录上,包括:

  • 内置的用户账号管理界面
  • OpenID Connect 以及 OAuth 2.0 支持
  • LDAP 同步支持
  • 支持自定义主题

虽然之前也找到了 FreeIPA 这个开源系统,功能也同样强大,但是在部署过程中碰到了很多问题,最后还是选择了 KeyCloak。

Pomerium

Pomerium

对于大多数开源系统来说,可能都已经内置了对于 OAuth 或者 LDAP 的支持,对于这些系统,只需要按它的需求,去配置 OAuth 或者 LDAP 认证即可接入 KeyCloak。

但是对于一些静态页面,或者是自行开发的内部应用,可能并没有时间去额外添加用户认证支持,而这个需要就需要一个带用户认证支持的反向代理了。

Pomerium 就是这样一个反向代理应用,它作为一个 Identity-Aware Proxy,用于给内部应用增加安全访问的能力。

Pomerium 的主要功能有:

  • 支持接入 OAuth 认证
  • 支持配置内部应用允许哪些域,或者哪些用户可以访问
  • 支持 WebSocket 转发
  • 支持转发时自定义 HTTP Header
  • 支持 JWT 或 HTTP Header 传递用户 Session 信息到后端内部应用
  • 提供一个隐式 domain/.pomerium 路径来显示当前用户信息
  • 支持使用 Wildcard SSL 证书给后端服务统一增加 SSL 支持

通过 Pomerium,就可以将内部不带用户认证的应用直接加上用户认证的能力,避免非授权访问,并且可以直接通过 JWT 传递过来的用户信息,进行额外的用户权限管理。

Virtual-LDAP

Virtual-LDAP 是我开发的一个 Node.JS 程序包,用于使用自定义数据源来提供一个 LDAP 服务,可以将非 LDAP 用户系统(目前支持钉钉)对接到只支持 LDAP 认证的系统当中。并且支持保存用户密码到数据库中,以使用与非 LDAP 用户系统不一样的密码数据。

Virtual-LDAP 主要功能有:

  • 定时同步钉钉组织架构以及员工信息
  • 提供基本 LDAP 功能,包括 bind、search、modify 等操作
  • 通过配置文件配置管理账号
  • 独立保存用户密码,以 SHA256+Salt 存储
  • 支持自定义分组能力,在钉钉组织架构之外扩展用户分组
  • 支持自定义用户数据 Provider,可以自行开发接入钉钉以外的用户系统

Virtual-LDAP 主要解决的问题是市面上的 LDAP 服务系统并不支持接入钉钉用户系统,钉钉也并没有提供一个 LDAP 方式的数据源供企业内部使用,因此需要额外的系统去对接钉钉的用户系统,以 LDAP 方式提供用户数据,供 KeyCloak 及其他内部系统使用。

当然,Virtual-LDAP 并不是一个全功能的 LDAP 服务器,它仅支持有限的 LDAP 操作,但是在对接到 KeyCloak 作为 User Federation 已经足够用了,以下功能都可以正常使用:

  • User Synchronize
  • Group Synchronize
  • User 和 Group 的映射关系,以及完整的组织架构
  • 在认证时,使用 LDAP bind 进行认证
  • 修改密码时,使用 LDAP modify 同步保存密码

通过 Virtual-LDAP,就可以直接由 HR 去管理公司的员工以及组织架构,并且不需要额外再去另外一个系统中同步维护相关信息,Virtual-LDAP 会使用钉钉 OpenAPI 自动从钉钉获取最新的员工列表以及组织架构信息。

4. 部署

对于 KeyCloak 和 Pomerium 来说,官方均已提供 Docker 镜像,因此直接通过 Docker 即可以快速部署使用。

  • KeyCloak Docker:https://hub.docker.com/r/jboss/keycloak
  • Pomerium Docker:https://hub.docker.com/r/pomerium/pomerium

对于 Virtual-LDAP 来说,可以直接从源代码运行,也可以自己编写一个 Dockerfile 来使用 Docker 部署。

一个典型的 Virtual-LDAP Dockerfile 可以像下面这样:

Dockerfile

FROM node:13.7.0-alpine

WORKDIR /app
COPY package.json /app/
RUN npm install

COPY index.js /app/
COPY config.js /app/

CMD [ "node","index.js" ]

index.js

const server = require('virtual-ldap');

server.setupVirtualLDAPServer(require("./config"));
server.runVirtualLDAPServer();

package.json

{
"dependencies": {
"virtual-ldap": "^0.1.1"
}
}

当然,必需的配置文件 config.js 也是不可少的,具体如何配置可以参考 config.sample.js

5. 小结

总的来说,如果有额外的人力去维护两份员工信息以及组织架构,只需要 KeyCloak 就可以解决以上很多问题。但是对于小公司来说,使用额外的人力总归不是很高效的方式,并且钉钉拥有更完整的用户系统管理功能,对于 HR 来说使用上可能也更为友好。

希望 Virtual-LDAP 能给同样希望在公司内部部署统一认证系统,以及使用钉钉作为企业交流沟通的朋友们有所帮助。

6. 参考

—EOF—

玩玩智能家居4:InfluxDB & Grafana

在接入了很多传感器到 Domoticz 之后,终于可以全面监控家里的各种环境参数了,例如温度、湿度、PM 2.5、二氧化碳浓度等等。

Domoticz 虽然已经自带了传感器数据日志,但是一来详细数据最多只能保存七天,二来只能单独查看每个传感器的数据,而不能将多个传感器数据放在一起对比查看,所以就需要使用其他方式去保存和展示传感器历史数据。

InfluxDB

InfluxDB 是一个时序数据库,很方便用来保存时间序列数据,而各种传感器数据其实就是一个时间序列化数据,InfluxDB 的介绍页面也说了很适合于 IoT Sensors 数据的保存。

使用 InfluxDB 最方便的方式就是用 Docker 了,直接在 DSM 的 Docker 中添加 influxdb 镜像,然后启动一个容器就可以了。

当然这里要记得添加一下端口映射,后面在配置 Domoticz Data Push 的时候需要用到。

Domoticz Data Push

部署好了 InfluxDB,就可以在 Domoticz 里面配置把接收到的传感器数据同时推送到 InfluxDB 中保存了。

Domoticz 提供了两种方式可以用来将传感器数据推送到 InfluxDB 中,一种使用 HTTP 调用 InfluxDB 的 HTTP API,还有一种是直接使用 Domoticz 内建的 InfluxDB 支持。

使用内建 InfluxDB 支持

使用内建 InfluxDB 的功能很简单,直接填写好 InfluxDB 服务器的 IP 和端口以及数据库名称就可以了

使用 InfluxDB HTTP API

使用 HTTP API 来向 InfluxDB 来写入数据稍微麻烦一点,需要自己定义一下发送数据的格式,但是其实这样更有利于控制写入 InfluxDB 中数据的名称。

URL 需要填写 InfluxDB 的 API 地址:

http://192.168.9.16:9800/write?db=domoticz&u=root&p=root&precision=ms

其中:

  • 192.168.9.16:9800 需要替换为实际的 InfluxDB 服务器地址和端口
  • db=domoticz 需要将数据库名称替换为实际的数据库名称

Data 填写:

device_%V value=%v %t3

配置需要 Push 的数据

在设置完 InfluxDB 推送,还需要选择需要推送哪些传感器的数据到 InfluxDB,这个在 Data Push 页面中直接选择添加就可以了。

Grafana

有了数据,就可以来展示了。Grafana 是一个很好的展示时序数据的工具,它直接支持读取 InfluxDB 的数据,可以提供多种形式的展示方式,例如曲线图、柱状图等。

Grafana 同样可以直接使用 Docker 来安装部署。

在 Grafana 中配置好 InfluxDB 数据源,就可以开始使用 Grafana 的面板来展示数据了。

在 Dashboard 中创建一个 Graph Panel,然后直接选择一下需要显示的数据字段,填一下采样的时间间隔,就可以显示出好看的曲线啦。如果需要对比多个数据,可以直接添加,选择不同的字段就可以了。

Grafana 还有其他很强大的图表显示功能,这个就可以根据自己的需要去组合排布,也可以创建多个 Dashboard 来展示不同类型的数据。如果有条件,还可以用一个 iPad 来展示 Dashboard,可以直接看到数据而不用去电脑上打开网页了。

参考资料

  1. Influxdb
  2. Grafana
  3. Domoticz HTTP Link

— EOF —