UNPKG

masson

Version:

Module execution engine for cluster deployments.

365 lines (332 loc) 13.8 kB
--- title: layout: module --- # OpenLDAP each = require 'each' ldap = require 'ldapjs' module.exports = [] module.exports.push 'masson/bootstrap/' module.exports.push 'masson/core/yum' module.exports.push 'masson/core/iptables' The default ports used by OpenLdap server are 389 and 636. todo: add migrationtools Configuration ------------- The property "openldap_server.config_slappasswd" may be generated with the command `slappasswd` and should correspond to "openldap_server.config_password". module.exports.push module.exports.configure = (ctx) -> # Todo: Generate '*_slappasswd' with command `slappasswd`, but only the first time, we # need a mechanism to store configuration properties before. ctx.config.openldap_server ?= {} throw new Error "Missing \"openldap_server.suffix\" property" unless ctx.config.openldap_server.suffix throw new Error "Missing \"openldap_server.root_password\" property" unless ctx.config.openldap_server.root_password throw new Error "Missing \"openldap_server.root_slappasswd\" property" unless ctx.config.openldap_server.root_slappasswd throw new Error "Missing \"openldap_server.config_dn\" property" unless ctx.config.openldap_server.config_dn throw new Error "Missing \"openldap_server.config_password\" property" unless ctx.config.openldap_server.config_password throw new Error "Missing \"openldap_server.config_slappasswd\" property" unless ctx.config.openldap_server.config_slappasswd {suffix} = ctx.config.openldap_server ctx.config.openldap_server.root_dn ?= "cn=Manager,#{ctx.config.openldap_server.suffix}" ctx.config.openldap_server.log_level ?= 256 ctx.config.openldap_server.users_dn ?= "ou=users,#{suffix}" ctx.config.openldap_server.groups_dn ?= "ou=groups,#{suffix}" ctx.config.openldap_server.ldapadd ?= [] ctx.config.openldap_server.ldapdelete ?= [] ctx.config.openldap_server.tls ?= false ctx.ldap_add = (ctx, content, callback) -> {root_dn, root_password} = ctx.config.openldap_server tmp = "/tmp/ldapadd_#{Date.now()}_#{Math.round(Math.random()*1000)/1000}" ctx.write content: content destination: tmp , (err, uploaded) -> return callback err if err ctx.execute cmd: "ldapadd -c -H ldapi:/// -D #{root_dn} -w #{root_password} -f #{tmp}" code_skipped: 68 , (err, executed, stdout, stderr) -> return callback err if err modified = true if stdout.match(/Already exists/g)?.length isnt stdout.match(/adding new entry/g).length ctx.remove destination: tmp , (err, removed) -> callback err, modified module.exports.push name: 'OpenLDAP Server # Install', timeout: -1, callback: (ctx, next) -> ctx.service [ name: 'openldap-servers' chk_name: 'slapd' startup: true , name: 'openldap-clients' , name: 'migrationtools' ], (err, serviced) -> next err, if serviced then ctx.OK else ctx.PASS ### Borrowed from http://docs.adaptivecomputing.com/viewpoint/hpc/Content/topics/1-setup/installSetup/settingUpOpenLDAPOnCentos6.htm Interesting posts also include http://itdavid.blogspot.ca/2012/05/howto-centos-6.html http://www.6tech.org/2013/01/ldap-server-and-centos-6-3/ ### module.exports.push name: 'OpenLDAP Server # Configure', timeout: -1, callback: (ctx, next) -> {root_dn, root_slappasswd, suffix} = ctx.config.openldap_server modified = 0 bdb = -> ctx.log 'Database bdb: root DN, root PW, password protection' ctx.write destination: '/etc/openldap/slapd.d/cn=config/olcDatabase={2}bdb.ldif' write: [ match: /^(.*)dc=my-domain,dc=com(.*)$/mg replace: "$1#{suffix}$2" , match: /^olcRootDN.*$/mg replace: "olcRootDN: #{root_dn}" , match: /^olcRootPW.*$/mg replace: "olcRootPW: #{root_slappasswd}" append: 'olcRootDN' ] , (err, written) -> return next err if err modified += written monitor() monitor = -> ctx.log 'Database monitor: root DN' ctx.write destination: '/etc/openldap/slapd.d/cn=config/olcDatabase={1}monitor.ldif' match: /^(.*)dc=my-domain,dc=com(.*)$/mg replace: "$1#{suffix}$2" , (err, written) -> return next err if err modified += written config() config = -> {config_dn, config_slappasswd} = ctx.config.openldap_server ctx.log 'Database config: root DN & PW' ctx.write destination: '/etc/openldap/slapd.d/cn=config/olcDatabase={0}config.ldif' write: [ match: /^olcRootDN.*$/mg replace: "olcRootDN: #{config_dn}" , match: /^olcRootPW.*$/mg replace: "olcRootPW: #{config_slappasswd}" append: 'olcRootDN' ] , (err, written) -> return next err if err modified += written restart() restart = -> return next null, ctx.PASS unless modified ctx.log 'Restart service' ctx.service name: 'openldap-servers' srv_name: 'slapd' action: 'restart' , (err, restarted) -> next err, ctx.OK bdb() ## Logging http://joshitech.blogspot.fr/2009/09/how-to-enabled-logging-in-openldap.html module.exports.push name: 'OpenLDAP Server # Logging', callback: (ctx, next) -> {config_dn, config_password, log_level} = ctx.config.openldap_server modified = false rsyslog = -> ctx.log 'Check rsyslog dependency' ctx.service name: 'rsyslog' , (err, serviced) -> return next err if err ctx.log 'Declare local4 in rsyslog configuration' ctx.write destination: '/etc/rsyslog.conf' match: /^local4.*/mg replace: 'local4.* /var/log/slapd.log' append: 'RULES' , (err, written) -> return next err if err return slapdconf() unless written ctx.log 'Restart rsyslog service' ctx.service name: 'rsyslog' action: 'restart' , (err, serviced) -> modified = true slapdconf() slapdconf = -> # TODO, seems like there is an error if we run this against an # already installed openldap but stop at the time. A possible # solution would be to make sure the service is started: # # ctx.service # name: 'openldap-servers' # srv_name: 'slapd' # action: 'start' # ctx.log 'Open connection' client = ldap.createClient url: "ldap://#{ctx.config.host}/" ctx.log 'Bind connection' client.bind "#{config_dn}", "#{config_password}", (err) -> return finish err if err ctx.log 'Search attribute olcLogLevel' client.search 'cn=config', filter: 'cn=config' scope: 'base' attributes: ['olcLogLevel'] , (err, search) -> return unbind client, err if err olcLogLevel = null search.on 'searchEntry', (entry) -> ctx.log "Found #{JSON.stringify entry.object}" olcLogLevel = entry.object.olcLogLevel search.on 'end', -> ctx.log "Attribute olcLogLevel is #{JSON.stringify olcLogLevel}" return unbind client if "#{olcLogLevel}" is "#{log_level}" ctx.log "Modify attribute olcLogLevel to #{JSON.stringify log_level}" change = new ldap.Change operation: 'replace' modification: olcLogLevel: log_level client.modify 'cn=config', change, (err) -> return unbind client, err if err modified = true unbind client unbind = (client, err) -> ctx.log 'Unbind connection' client.unbind (e) -> return next e if e finish err finish = (err) -> next err, if modified then ctx.OK else ctx.PASS rsyslog() module.exports.push name: 'OpenLDAP Server # Users and Groups', timeout: -1, callback: (ctx, next) -> {root_dn, root_password, suffix, users_dn, groups_dn} = ctx.config.openldap_server [_, suffix_k, suffix_v] = /(\w+)=([^,]+)/.exec suffix ctx.execute cmd: """ ldapadd -c -H ldapi:/// -D #{root_dn} -w #{root_password} <<-EOF dn: #{suffix} #{suffix_k}: #{suffix_v} objectClass: top objectClass: domain dn: #{users_dn} ou: Users objectClass: top objectClass: organizationalUnit description: Central location for UNIX users dn: #{groups_dn} ou: Groups objectClass: top objectClass: organizationalUnit description: Central location for UNIX groups EOF """ code_skipped: 68 , (err, executed) -> return next err, if executed then ctx.OK else ctx.PASS module.exports.push name: 'OpenLDAP Server # SUDO schema', timeout: -1, callback: (ctx, next) -> # conf = '/tmp/sudo_schema/schema.conf' # ldif = '/tmp/sudo_schema/ldif' {config_dn, config_password} = ctx.config.openldap_server do_install = -> ctx.log 'Install Sudo schema' ctx.service name: 'sudo' , (err, serviced) -> return next err if err do_locate() do_locate = -> ctx.log 'Get schema location' ctx.execute cmd: 'rpm -ql sudo | grep -i schema.openldap' , (err, executed, schema) -> return next err if err return next Error 'Sudo schema not found' if schema is '' do_register schema.trim() do_register = (schema) -> ctx.ldap_schema name: 'sudo' schema: schema binddn: config_dn passwd: config_password uri: true log: ctx.log ssh: ctx.ssh , (err, registered) -> next err, if registered then ctx.OK else ctx.PASS do_install() module.exports.push name: 'OpenLDAP Server # Delete ldif data', callback: (ctx, next) -> {root_dn, root_password, ldapdelete} = ctx.config.openldap_server return next() unless ldapdelete.length modified = 0 each(ldapdelete) .on 'item', (path, next) -> destination = "/tmp/phyla_#{Date.now()}" ctx.upload source: path destination: destination , (err, uploaded) -> return next err if err ctx.log "Delete #{destination}" ctx.execute cmd: "ldapdelete -c -H ldapi:/// -f #{destination} -D #{root_dn} -w #{root_password}" code_skipped: 32 , (err, executed, stdout, stderr) -> return next err if err # modified += 1 if stdout.match(/Delete /g).length ctx.remove destination: destination , (err, removed) -> next err .on 'both', (err) -> next err, if modified then ctx.OK else ctx.PASS module.exports.push name: 'OpenLDAP Server # Add ldif data', timeout: 100000, callback: (ctx, next) -> {root_dn, root_password, ldapadd} = ctx.config.openldap_server return next() unless ldapadd.length modified = 0 each(ldapadd) .on 'item', (path, next) -> destination = "/tmp/phyla_#{Date.now()}" ctx.log "Create temp file: #{destination}" ctx.upload source: path destination: destination , (err, uploaded) -> return next err if err ctx.execute cmd: "ldapadd -c -H ldapi:/// -D #{root_dn} -w #{root_password} -f #{destination}" code_skipped: 68 , (err, executed, stdout, stderr) -> return next err if err modified += 1 if stdout.match(/Already exists/g)?.length isnt stdout.match(/adding new entry/g).length ctx.log "Clean temp file: #{destination}" ctx.remove destination: destination , (err, removed) -> next err .on 'both', (err) -> next err, if modified then ctx.OK else ctx.PASS ## Useful commands ```bash # Search from local: ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn # Search from remote: ldapsearch -x -LLL -H ldap://openldap.hadoop:389 -D cn=Manager,dc=adaltas,dc=com -w test -b "dc=adaltas,dc=com" "objectClass=*" ldapsearch -D cn=admin,cn=config -w test -d 1 -b "cn=config" ldapsearch -D cn=Manager,dc=adaltas,dc=com -w test -b "dc=adaltas,dc=com" ldapsearch -ZZ -d 5 -D cn=Manager,dc=adaltas,dc=com -w test -b "dc=adaltas,dc=com" # Check configuration with debug information: slaptest -v -d5 -u # Change user password: ldappasswd -xZWD cn=Manager,dc=adaltas,dc=com -S cn=wdavidw,ou=users,dc=adaltas,dc=com ``` Enable ldapi:// access to root on our ldap tree vi /etc/openldap/slapd.d/cn=config/olcDatabase={2}bdb.ldif # Add new olcAccess rule > olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=externa > l,cn=auth" manage by * none ldapsearch -LLLY EXTERNAL -H ldapi:/// -b dc=adaltas,dc=com Resources: http://serverfault.com/questions/323497/how-do-i-configure-ldap-on-centos-6-for-user-authentication-in-the-most-secure-a ... provide a script with just about everything