masson
Version:
Module execution engine for cluster deployments.
176 lines (156 loc) • 6.69 kB
Markdown
---
title:
layout: module
---
# OpenLDAP Client
Install and configure the OpenLDAP client utilities. The
file "/etc/openldap/ldap.conf" is configured by the "openldap_client.config"
object property. The property "openldap\_client.ca\_cert" may reference a
certificate to upload.
url = require 'url'
each = require 'each'
crypto = require 'crypto'
module.exports = []
module.exports.push 'masson/bootstrap/'
module.exports.push 'masson/bootstrap/utils'
module.exports.push 'masson/core/yum'
## Configuration
* `openldap_client.config` (object)
Configuration of the "/etc/openldap/ldap.conf" file.
* `openldap_client.config.TLS_CACERTDIR` (string)
Default to "/etc/openldap/cacerts".
* `openldap_client.config.TLS_REQCERT` (string)
Default to "allow".
* `openldap_client.config.TIMELIMIT` (string|number)
Default to "15".
* `openldap_client.config.TIMEOUT` (string|number)
Default to "10".
* `openldap_client.suffix` (string)
LDAP suffix used by the test, default to null or discovered.
* `openldap_client.root_dn` (string)
LDAP user used by the test, default to null or discovered.
* `openldap_client.root_password` (string)
LDAP password used by the test, default to null or discovered.
* `openldap_client.certificates` (array)
Paths to the certificates to upload.
The properties `openldap_client.config.BASE`, `openldap_client.suffix`,
`openldap_client.root_dn` and `openldap_client.root_password` are discovered if
there is only one LDAP server or if an LDAP server is deployed on the same
server.
The property `openldap_client.config.URI` is generated with the list of
configured LDAP servers.
Example:
```json
{
"openldap_client": {
"config": {
"TLS_REQCERT": "allow",
"TIMELIMIT": "15".
"TIMEOUT": "10"
},
"certificates": [
"./cert.pem"
]
}
}
```
module.exports.push module.exports.configure = (ctx) ->
config = ctx.config.openldap_client ?= {}
ctx.config.openldap_client.config ?= {}
openldap_servers = ctx.hosts_with_module 'masson/core/openldap_server'
# openldap_server = ctx.hosts_with_module 'masson/core/openldap_server'
if openldap_servers.length isnt 1
openldap_servers = openldap_servers.filter (server) -> server is ctx.config.host
openldap_server = if openldap_servers.length is 1 then openldap_servers[0] else null
openldap_servers_secured = ctx.hosts_with_module 'masson/core/openldap_server_tls'
uris = {}
for server in openldap_servers then uris[server] = "ldap://#{server}"
for server in openldap_servers_secured then uris[server] = "ldaps://#{server}"
uris = for _, uri of uris then uri
if openldap_server
ctx_server = ctx.hosts[openldap_server]
require('./openldap_server').configure ctx_server
config.config['BASE'] ?= ctx_server.config.openldap_server.suffix
config.suffix ?= ctx_server.config.openldap_server.suffix
config.root_dn ?= ctx_server.config.openldap_server.root_dn
config.root_password ?= ctx_server.config.openldap_server.root_password
config.config['URI'] ?= uris.join ' '
config.config['TLS_CACERTDIR'] ?= '/etc/openldap/cacerts'
config.config['TLS_REQCERT'] ?= 'allow'
config.config['TIMELIMIT'] ?= '15'
config.config['TIMEOUT'] ?= '20'
module.exports.push name: 'OpenLDAP Client # Install', timeout: -1, callback: (ctx, next) ->
ctx.service
name: 'openldap-clients'
, (err, installed) ->
next err, if installed then ctx.OK else ctx.PASS
module.exports.push name: 'OpenLDAP Client # Configure', timeout: -1, callback: (ctx, next) ->
{config} = ctx.config.openldap_client
write = []
for k, v of config
v = v.join(' ') if Array.isArray v
write.push
match: new RegExp "^#{k}.*$", 'mg'
replace: "#{k} #{v}"
append: true
ctx.write
write: write
destination: '/etc/openldap/ldap.conf'
eof: true # was 4 lines up in write.push
, (err, written) ->
next err, if written then ctx.OK else ctx.PASS
## Upload certificate
SSL certifcate could be defined in "/etc/ldap.conf" by
the "TLS\_CACERT" or the "TLS\_CACERTDIR" properties. When
using "TLS_CACERTDIR", the name of the file must be the
certicate hash with a numeric suffix. Here's an example
showing how to place the certificate inside "TLS\_CACERTDIR":
```bash
hash=`openssl x509 -noout -hash -in cert.pem`
mv cert.pem /etc/openldap/cacerts/$hash.0
```
Certificates are temporarily uploaded to the "/tmp" folder and registered with
the command `authconfig --update --ldaploadcacert={file}`.
module.exports.push name: 'OpenLDAP Client # Certificate', timeout: -1, callback: (ctx, next) ->
{certificates, config} = ctx.config.openldap_client
modified = false
each(certificates)
.on 'item', (certificate, next) ->
hash = crypto.createHash('md5').update(certificate).digest('hex')
ctx.upload
source: certificate
destination: "/tmp/#{hash}"
, (err) ->
return next err if err
ctx.execute # openssh is executed remotely
cmd: "openssl x509 -noout -hash -in /tmp/#{hash}; rm -rf /tmp/#{hash}"
, (err, _, stdout) ->
return next err if err
stdout = stdout.trim()
ctx.upload
source: certificate
destination: "#{config.TLS_CACERTDIR}/#{stdout}.0"
, (err, uploaded) ->
return next err if err
modified = true if uploaded
next()
.on 'both', (err) ->
next err, if modified then ctx.OK else ctx.PASS
module.exports.push name: 'OpenLDAP Client # Check URI', timeout: -1, callback: (ctx, next) ->
{config} = ctx.config.openldap_client
each(config['URI'].split ' ')
.on 'item', (uri, next) ->
uri = url.parse uri
return next() if ['ldap:', 'ldaps:'].indexOf(uri.protocol) is -1
uri.port ?= 389 if uri.protocol is 'ldap:'
uri.port ?= 636 if uri.protocol is 'ldaps:'
ctx.waitIsOpen uri.hostname, uri.port, next
.on 'both', (err) ->
next err, ctx.PASS
module.exports.push name: 'OpenLDAP Client # Check Search', callback: (ctx, next) ->
{suffix, root_dn, root_password} = ctx.config.openldap_client
return next() unless suffix
ctx.execute
cmd: "ldapsearch -x -D #{root_dn} -w #{root_password} -b '#{suffix}'"
, (err, executed) ->
next err, ctx.PASS