0x01 前言

在使用微软Office 365企业版的情况下可以尝试使用Azure SAML实现单点登陆,针对科技公司业务系统众多的情况可以极大程度地减少运营成本和提高安全性。

随着现在的业务系统越来越多,企业人员流动性的问题导致权限控制混乱,采用SSO是必不可少的解决方案,而Office 365企业版提供的一系列软件如Teams、Sharepoint和planner等就是生产力工具,甚至E5级别下的桌面版Office授权、25T超大onedrive等服务也是其他厂商无法提供的。

针对SSO,一定要用Azure,完美接入各种各样的系统,甚至可以和私有AD相结合。

0x02 准备

在zabbix5.0开始支持SAML,但总体用起来不太只能,有一部分工作需要手动完成。在开始之前首先准备一套zabbix 5.0环境,在我写这篇文章的时候最新版为5.0.1,如果只用于测试,可以使用docker版本。

还需要一个Office 365企业版的管理员账号用于创建企业应用程序,如果没有,也可以了解其他提供SSO服务的厂商,配置流程基本一致,因为SAML是一个标准。

0x03 Azure

首先来配置Azure,登入portal后的页面应该是这样的:

单击:管理Azure Active Directory进入AD管理页面,然后单击:企业应用程序:

再单击:新建应用程序:

选择:非库应用程序:

最后填入应用名称并单击该页面底部的添加按钮即可:

一切正常的话会跳转到该应用的概述页面,此时单击:单一登陆标签,然后选择SAML作为单点登录的方式:

在继续之前需要确认一个很重要的信息:zabbix UI所用的域名。另外,UI服务器不需要联网,但你的浏览器需要,因为需要通过浏览器访问Azure的服务器。

Azure只支持https协议,对于http协议是无法进行配置的。而这个zabbix的域名有些特别,在docker环境中,暴露的端口已经修改为http 8080,https 8443,这部分信息可以参考dockerfile:

当通过zabbix UI调用单点登陆的URL时,它会在带上回调地址,而这个地址会使用容器里的端口。这就有一个问题:我们前端一般是不直接暴露这个端口,而是会挂一个WAF或SLB以使用标准的443端口。这样会使得回调失败导致无法完成整个验证流程。

解决这个问题的决绝方案有两种:

  1. 修改dockerfile并自行build一个镜像,使用443端口
  2. 不适用docker而是独立部署UI

针对上述的第一种解决方案,还有一个点需要注意的,首先看看zabbix的文档:

需要在/etc/ssl/nginx目录下放置有效的证书文件才会自动开启https,否则只会启动http协议。而这个文件夹内需要有三个文件:

# nginx
The volume allows to enable HTTPS for Zabbix web interface. The volume must contain the two ssl.crt, ssl.key files and dhparam.pem prepared for Nginx SSL connections

# apache2
The volume allows to enable HTTPS for Zabbix web interface. The volume must contain the two ssl.crt and ssl.key files prepared for Apache2 SSL connections

所以使用docker部署UI的话,一共需要完成两项工作。而独立部署UI,则必须为web server中间件配置https,比如我使用apache:

<VirtualHost 0.0.0.0:8080>
  DocumentRoot /usr/local/html/zbx.dev.enginx.net/public_html/
  ServerName zbx.dev.enginx.net

  SSLEngine on
  SSLCertificateFile /usr/local/nginx/ssl/zbx.dev.enginx.net.crt
  SSLCertificateKeyFile /usr/local/nginx/ssl/zbx.dev.enginx.net.key


  ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/usr/local/html/zbx.dev.enginx.net/public_html/$1
  ErrorLog /usr/local/html/zbx.dev.enginx.net/logs/apa.error.log
</VirtualHost>

我的apache前面还有一个nginx做WAF,所以这里的apache监听8080端口,而nginx则使用443端口。

完成UI部分的配置后,再看看以下文档:

滚动到底部的SAML authentication部分,需要注意两个URL:

Assertion Consumer URL should be set to <path_to_zabbix_ui>/index_sso.php?acs
Single Logout URL should be set to <path_to_zabbix_ui>/index_sso.php?sls

一个是断言URL,另一个是登出URL,那么我的URL是:

# 断言
https://zbx.dev.enginx.net/index_sso.php?acs

# 登出
https://zbx.dev.enginx.net/index_sso.php?sls

再回到Azure的配置页面,将上述URL填写到基本SAML配置中:

上图中的标识符(实体 ID)填写zabbix域名即可,这个可以在zabbix配置页面中进行配置。

接下来要生成一套自签发的数字证书并合成为pfx格式,其实可以使用商业或免费的证书,证书生成的部分不是本文的重点,这里略过。取得pem格式的数字证书后,在合并成pfx格式时无比设置一个强密码,因为在导入到Azure时要求输入密码,也是保护我们的数字证书。

在合并前需要确认是否已包含中级证书,然后执行以下命令即可完成合并工作:

openssl pkcs12 -inkey dev.enginx.net.key -in fullchain.cer -export -out dev.enginx.net.pfx

然后将证书和key保存备用,在以下位置导入pfx文件:

导入完成后记得单击保存。紧接着下载SAML 签名证中的联合元数据XML,使用sublime等文本编辑器打开,找到以下X509证书内容并另为保存备用:

比如我的:

MIIC8DCCAdigAwI..........7hvUR/S9

接下来需要记录一些信息用于配置zabbix的部分。首先是用户属性与声明,我们将使用邮箱账号作为确权的信息,而Azure里则是唯一用户标识符:

单击上图中右上角的小笔图标,将user.userprincipalname复制另存备用:

最后将以下三个URL复制另存备用:

至此,Azure的部分已全部完成。

默认情况下,所有用户是没有这个应用的使用权限的,需要手动添加,而默认也只有user的权限,具体的权限需要在zabbix中配置:

建议添加一个账户用于后续的配置。

0x04 zabbix

按以上章节中的说明完成zabbix UI的配置后,将以下证书文件放置到指定位置,首先是文档:

1. Private key and certificate should be stored in the ui/conf/certs/, unless custom paths are provided in zabbix.conf.php.

By default, Zabbix will look in the folowing locations:

ui/conf/certs/sp.key - SP private key file
ui/conf/certs/sp.crt - SP cert file
ui/conf/certs/idp.crt - IDP cert file

其中SP是合并pfx文件的证书和密钥,而IDP则是XML文件中的X509证书内容,分别按上述说明中路径和文件名建立相关文件并写入对应的信息即可,注意这些文件的权限,需要让PHP拥有可读权限。

然后来到zabbix的Authentication页面,并勾选Enable SAML authentication,然后在下方填写相关信息:

最后单击update保存即可。

其实zabbix的这个SAML功能并不是全自动的,它没有自动添加用户的功能,我们需要手动添加用户,而用户名必须为Office 365中的邮箱地址:

至于用户的权限,肯定是需要手动调整的,那么这个SAML可以省去用户输入密码的步骤,甚至可以通过禁止用户修改密码来达到只允许用户通过Azure AD登陆的目的以提高安全性。

0x05 测试

完成SAML的配置后,可以在登入界面看到SAML SSO的连接:

单击后会弹出Office 365的认证页面,在此前先打开浏览器的控制台并定位到网络标签。当完成Azure部分的认证后会向acs地址POST数据:

单击可以发现有两个表单内容:

  • SAMLResponse
  • RelayState

其中RelayState就是前面说到有端口问题的部分,比如我的环境中,正常的情况为:

RelayState: https://zbx.dev.enginx.net/index_sso.php

如果使用官方的docker镜像则是:

RelayState: https://zbx.dev.enginx.net:8443/index_sso.php

如果没有启用https,就是:

RelayState: http://zbx.dev.enginx.net:8080/index_sso.php

针对以上两种情况,会直接跳转到Azure的错误页面,需要注意检查。

而SAMLRespons是Base64 encode后的内容,使用工具decode即可得到XML文件,从该文件中也可以看到域名和证书等信息。

如果一切正常,现在已经可以使用Azure登入zabbix。

0x06 结语

因为zabbix 5.0刚发布正式版不久,完全没有这方面的信息,希望后续能通过Azure配置权限,而不需要在zabbix中手动配置。