UNPKG

masson

Version:

Module execution engine for cluster deployments.

200 lines (174 loc) 6.58 kB
--- title: SSH module: masson/core/ssh layout: module --- # SSH misc = require 'mecano/lib/misc' each = require 'each' module.exports = [] module.exports.push 'masson/bootstrap/' module.exports.push 'masson/core/users' module.exports.push 'masson/core/yum' ## Configuration Configuration extends the configuration of the "masson/core/users" with new properties "authorized\_keys", "rsa" and "rsa_pub" and also define two new properties "sshd\_config" and "banner". * `users.[].authorized_keys` (string, array) A list of SSH public keys added to the "~/.ssh/authorized_keys" file, optional. * `users.[].rsa` (string) Private SSH key of the user, optional. * `users.[].rsa_pub` (string) Public SSH key of the user, optional. * `ssh.sshd_config` (object) Configure the SSH daemon by updating the "/etc/ssh/sshd_config" file with key/value properties, optional. * `ssh.banner` (object) Write a banner file in the system and register it with the "/etc/ssh/sshd_config" file, optional. ```json { "users": [{ "name": "root" "authorized_keys": [ "ssh-rsa AAAA...ZZZZ me@email.com" ], "rsa": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCA...PKToe4z7C9BqMT7Og==\n-----END RSA PRIVATE KEY-----" "rsa_pub": "ssh-rsa AAAA...YYYY user@hadoop" },{ "name": "sweet" "home": "/home/sweet" "authorized_keys": [ "ssh-rsa AAAA...XXXX you@email.com" ] }] "ssh": { "sshd_config": { "UsePAM": "yes" "Port": 2222 }, "banner": { "destination": "/etc/banner", "content": "Welcome to Hadoop!" } } } ``` module.exports.push (ctx) -> require('./users').configure ctx ctx.config.ssh ?= {} ctx.config.ssh.sshd_config ?= null for _, user of ctx.config.users user.authorized_keys ?= [] user.authorized_keys = [user.authorized_keys] if typeof user.authorized_keys is 'string' ## Authorized Keys Update the "~/.ssh/authorized_keys" file for each users and add the public SSH keys defined inside "users.[].authorized_keys". module.exports.push name: 'SSH # Authorized Keys', timeout: -1, callback: (ctx, next) -> modified = false each(ctx.config.users) .on 'item', (user, next) -> return next() unless user.home ctx.mkdir destination: "#{user.home or '/home/'+user.name}/.ssh" uid: user.name gid: null mode: 0o700 # was "permissions: 16832" , (err, created) -> return next err if err write = for key in user.authorized_keys match: new RegExp ".*#{misc.regexp.escape key}.*", 'mg' replace: key append: true ctx.write destination: "#{user.home or '/home/'+user.name}/.ssh/authorized_keys" write: write uid: user.name gid: null mode: 0o600 , (err, written) -> return next err if err modified = true if written next() .on 'both', (err) -> next err, if modified then ctx.OK else ctx.PASS ## Configure Configure the SSH daemon by updated the "/etc/ssh/sshd_config" file with the properties found in the "ssh.sshd_config" object. module.exports.push name: 'SSH # Configure', timeout: -1, callback: (ctx, next) -> {sshd_config} = ctx.config.ssh return next() unless sshd_config write = for k, v of sshd_config match: new RegExp "^#{k}.*$", 'mg' replace: "#{k} #{v}" append: true ctx.log 'Write configuration in /etc/ssh/sshd_config' ctx.write write: write destination: '/etc/ssh/sshd_config' , (err, written) -> return next err if err return next null, ctx.PASS unless written ctx.log 'Restart sshd' ctx.service name: 'openssh' srv_name: 'sshd' action: 'restart' , (err, restarted) -> next err, ctx.OK ## Public and Private Key Deploy user SSH keys. The private key is defined by the "users.[].rsa" propery and is written in "~/.ssh/id\_rsa". The public key is defined by the "users.[].rsa\_pub" propery and is written in "~/.ssh/id\_rsa.pub". module.exports.push name: 'SSH # Public and Private Key', timeout: -1, callback: (ctx, next) -> ok = false each(ctx.config.users) .on 'item', (user, next) -> return next() unless user.home return next new Error "Property rsa_pub required if rsa defined" if user.rsa and not user.rsa_pub return next new Error "Property rsa required if rsa_pub defined" if user.rsa_pub and not user.rsa return next() unless user.rsa ctx.write destination: "#{user.home or '/home/'+user.name}/.ssh/id_rsa" content: user.rsa uid: user.name gid: null mode: 0o600 , (err, written) -> return next err if err ok = true if written ctx.write destination: "#{user.home or '/home/'+user.name}/.ssh/id_rsa.pub" content: user.rsa_pub uid: user.name gid: null mode: 0o600 , (err, written) -> return next err if err ok = true if written next() .on 'both', (err) -> next err, if ok then ctx.OK else ctx.PASS # Banner Write the banner file in the system and register it with the SSH daemon configuration file. The banner is a short message which appear on the console once a user successfull logged-in with SSH. The "sshd" service will be restarted if this action had any effect. module.exports.push name: 'SSH # Banner', timeout: 100000, callback: (ctx, next) -> {banner} = ctx.config.ssh return next() unless banner ctx.log 'Upload banner content' banner.content += '\n\n' if banner.content ctx.upload banner, (err, uploaded) -> return next err if err ctx.log 'Write banner path to configuration' ctx.write match: new RegExp "^Banner.*$", 'mg' replace: "Banner #{banner.destination}" append: true destination: '/etc/ssh/sshd_config' , (err, written) -> return next err if err return next null, ctx.PASS if not written and not uploaded ctx.log 'Restarting SSH' ctx.service name: 'openssh' srv_name: 'sshd' action: 'restart' , (err, restarted) -> next err, ctx.OK