Grafana、Prometheus外加各类的Exporter目前已经成了监控领域的三剑客。

Grafana是一款多平台、开源的分析和交互式可视化Web应用程序,配合后端数据源可以方便地进行各类图表展示,后端数据源一般是各类时序数据库,如InfluxDB、Prometheus、Graphite等。

Grafana自带身份认证系统,它也可以集成外部的认证系统,如Github OAuth、Google OAuth和ldap等。

本文的LDAP使用FreeIPA实现,FreeIPA是一个用于Linux/Unix环境的开源身份管理系统,它提供集中式的账号管理和身份验证,其集成389目录服务器(一种LDAP实现)、NTP、DNS、MIT Kerberos等。

FreeIPA是红帽公司的产品,如果操作系统是CentOS的话,可以采用YUM包安装的方式,比较简单,如果是其他操作系统,可以选择使用容器的部署方式(正式环境建议使用YUM包的方式安装,为了安装它,专门部署CentOS系统,也是值得的)。本文采用容器的安装方式。容器运行命令:

sudo docker run -it -d -h ipa.bigcompany.com -p 53:53/udp -p 53:53 \ -p 127.0.0.1:80:80 -p 127.0.0.1:443:443 -p 389:389 -p 636:636 -p 88:88 -p 464:464 \ -p 88:88/udp -p 464:464/udp -p 123:123/udp \ --sysctl net.ipv6.conf.lo.disable_ipv6=0 \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -v /home/aneirin/freeipa/ipa-data:/data:Z --name freeipa \ freeipa/freeipa-server:centos-7-4.6.8

初次运行切记去掉“-d”选项,不要让容器在后台运行,因为我们需要在交互式模式下完成一些重要参数的配置,如是否启用BIND、配置服务器的FQDN、域名、Kerberos的Realm name、目录服务和IPA的管理员密码等。后面启动容器可以加上“-d”选项。

服务监听的端口:

HTTP/HTTPS:80/443

LDAP/LDAPS:389/636

Kerberos:88/464

DNS:53

NTP:123

你可以选择是否对外暴露指定端口,比如我们正式环境使用的FreeIPA并没有启用DNS,53端口就不需要配置。如果正式环境使用Nginx作为前端,容器的80和443端口监听在本地环回地址上,如不用Nginx,配置FreeIPA监听在服务器的对外网口上。

Nginx的配置

server { listen 192.168.1.2:443 ssl http2; server_name ipa.bigcompany.com; root /usr/share/nginx/html; ssl_certificate "/etc/pki/nginx/ipa.bigcompany.com.pem"; ssl_certificate_key "/etc/pki/nginx/private/ipa.bigcompany.com-key.pem"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { auth_basic "off"; proxy_pass https://localhost:443; proxy_set_header Host $host; proxy_set_header Referer https://ipa.bigcompany.com/ipa/ui; 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 https; proxy_cookie_domain realipa.bigcompany.com ipa.bigcompany.com; proxy_connect_timeout 150; proxy_send_timeout 100; proxy_read_timeout 100; proxy_buffers 4 32k; client_max_body_size 200M; client_body_buffer_size 512k; keepalive_timeout 5; add_header Strict-Transport-Security max-age=63072000; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; } error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }

上面的操作完成后,使用IPA管理员账号登录FreeIPA的Web UI,添加用户账号,每个账号归属在创建好的组中,比如公司有开发和运维两个团队需要访问Grafana,创建两个组“developer”和“infra”(下图中其他的组是FreeIPA自带的):

如何接入grafana(Grafana集成LDAP认证)(1)

用户组

之所以创建不同的组是为了配置Grafana根据组来做权限的下发,具体见下。

Grafana安装使用容器的方式,管理起来会方便很多,“docker-compose.yml”文件:

version: "3" services: grafana: image: grafana/grafana:latest container_name: monitoring_grafana restart: unless-stopped user: "2302" ports: - 3000:3000 links: - prometheus:prometheus volumes: - ./grafana/data:/var/lib/grafana - ./grafana/config/ldap.toml:/etc/grafana/ldap.toml environment: - GF_SECURITY_ADMIN_PASSWORD=admin - GF_USERS_ALLOW_SIGN_UP=false - GF_SERVER_DOMAIN=bigcompany.com - GF_AUTH_LDAP_ENABLED=true - GF_AUTH_LDAP_ALLOW_SIGN_UP=true

“docker-compose.yml”文件注意一点,因为目录“./grafana/data”属主的用户ID为2302,所以键“user”的值配置为2302,读者配置时,根据实际情况做调整即可。

ldap.toml

[[servers]] # Ldap server host (specify multiple hosts space separated) host = "192.168.1.2" # Default port is 389 or 636 if use_ssl = true port = 389 # Set to true if LDAP server should use an encrypted TLS connection (either with STARTTLS or LDAPS) use_ssl = false # If set to true, use LDAP with STARTTLS instead of LDAPS start_tls = false # set to true if you want to skip SSL cert validation ssl_skip_verify = false # set to the path to your root CA certificate or leave unset to use system defaults # root_ca_cert = "/path/to/certificate.crt" # Authentication against LDAP servers requiring client certificates # client_cert = "/path/to/client.crt" # client_key = "/path/to/client.key" # Search user bind dn bind_dn = "uid=%s,cn=users,cn=compat,dc=bigcompany,dc=com" # Search user bind password # If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;""" #bind_password = 'grafana' # User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)" # Allow login from email or username, example "(|(sAMAccountName=%s)(userPrincipalName=%s))" search_filter = "(uid=%s)" # An array of base dns to search through search_base_dns = ["cn=users,cn=compat,dc=bigcompany,dc=com"] group_search_filter = "(&(objectClass=posixGroup)(memberUid=%s))" group_search_filter_user_attribute = "uid" group_search_base_dns = ["cn=groups,cn=compat,dc=bigcompany,dc=com"] [[servers.group_mappings]] group_dn = "cn=infra,cn=groups,cn=compat,dc=bigcompany,dc=com" org_role = "Admin" grafana_admin = true # Available in Grafana v5.3 and above [[servers.group_mappings]] group_dn = "*" org_role = "Viewer" # Specify names of the LDAP attributes your LDAP uses [servers.attributes] username = "uid" surname = "sn" email = "email"

注意:

  1. 在使用LDAP服务时,首先需要bind,即认证的意思,因为提供的表达式匹配所有用户,这里就不用配置bind密码了。
  2. 根据用户所属的组配置权限,Grafana如何知道用户所属的组呢?所以配置组的查询过滤表达式:“(&(objectClass=posixGroup)(memberUid=%s))”,如果你不确定自己配置的是否正确,可以运行命令验证:ldapsearch -x -h 192.168.1.2 -b dc=bigcompany,dc=com "(&(objectClass=posixGroup)(memberUid=username))"。如果输出了组信息,就说明没有问题,

[aneirin@ipa ~]$ldapsearch -x -h 192.168.1.2 -b dc=bigcompany,dc=com "(&(objectClass=posixGroup)(memberUid=liudehua))" # extended LDIF # # LDAPv3 # base <dc=bigcompany,dc=com> with scope subtree # filter: (&(objectClass=posixGroup)(memberUid=liudehua)) # requesting: ALL # # infra, groups, compat, bigcompany.com dn: cn=infra,cn=groups,cn=compat,dc=bigcompany,dc=com objectClass: posixGroup objectClass: ipaOverrideTarget objectClass: ipaexternalgroup objectClass: top gidNumber: 235600003 memberUid: liudehua ipaAnchorUUID:: OklQQTp5b3V4dWVwYWkub3JnOjdmYTA2YzdlLWNiNTUtMTFlYi04NWQ4LTAyND JhYzExMDAwMg== cn: infra # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1

总结

很多服务都支持集成LDAP的认证,目前开源的提供LDAP服务的软件,FreeIPA无疑是其中的佼佼者,安装简便,集成的服务丰富,不过正式环境一定注意数据的高可用性,必要的话,可以部署主从来提高稳定性。

希望这篇文章能帮到正在努力的你,欢迎关注、评论!

,