Initial version of plugin

This plugin:
- installs sssd deamon on all OpenStack nodes
- sets sssd configuration
- makes changes to:
 * /etc/ssh/sshd_config
 * /etc/pam.d/common-session
 */etc/pam.d/common-auth

This plugin enables SSH authentication with keys/password stored in LDAP directory

Change-Id: I1cdde2f8d16d2a0a5327b9c5f965258640866dd3
This commit is contained in:
Jerzy Mikolajczak 2016-09-08 15:46:21 +02:00 committed by Maksym Yatsenko
parent 40cc8a7edb
commit aa5d7476ed
18 changed files with 314 additions and 177 deletions

5
.gitreview Normal file
View File

@ -0,0 +1,5 @@
[gerrit]
host=review.openstack.org
port=29418
project=openstack/fuel-plugin-ldap-slaves

View File

@ -1,4 +1,11 @@
fuel-plugin-ldap-slaves
LDAP Slaves plugin for Fuel
============
Plugin description
Fuel plugin that provides the functionality to use external LDAP directory as source for authentication on OpenStack nodes.
Requirements
------------
| Requirement | Version/Comment |
|:---------------------------------|:----------------|
| Mirantis OpenStack compatibility | 9.0 |

View File

@ -1,12 +0,0 @@
# This file contains wizard components descriptions that are pretty similar to
# the `environment_config.yaml`.
# Please, take a look at following link for the details:
# - https://blueprints.launchpad.net/fuel/+spec/component-registry
# - https://specs.openstack.org/openstack/fuel-specs/specs/8.0/component-registry.html
- name: additional_service:fuel-plugin-ldap-slaves
compatible: []
requires: []
incompatible: []
label: "Plugin label, that will be shown on UI"
description: "Component description (optional)"

View File

@ -1,4 +0,0 @@
#!/bin/bash
# It's a script which deploys your plugin
echo fuel-plugin-ldap-slaves > /tmp/fuel-plugin-ldap-slaves

View File

@ -0,0 +1,3 @@
$plugin_settings = parseyaml($astute_settings_yaml)
notice('MODULAR: ldap-slaves')
class {'ldap_slaves': }

View File

@ -0,0 +1,22 @@
Puppet::Type.type(:sssd_config).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
if resource[:name].start_with?("domain/")
resource[:name].split('/', 3)[0] + '/' + resource[:name].split('/', 3)[1]
else
resource[:name].split('/', 2).first
end
end
def setting
if resource[:name].start_with?("domain/")
resource[:name].split('/', 3)[2]
else
resource[:name].split('/', 2).last
end
end
def self.file_path
'/etc/sssd/sssd.conf'
end
end

View File

@ -0,0 +1,13 @@
Puppet::Type.newtype(:sssd_config) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from sssd.conf'
newvalues(/\S+\/\S+/)
end
newproperty(:value) do
desc 'The value of the setting to define'
munge do |v|
v.to_s.strip
end
end
end

View File

@ -0,0 +1,120 @@
class ldap_slaves {
$domain_name = $::plugin_settings['ldap-slaves']['domain_name']
$uri = $::plugin_settings['ldap-slaves']['uri']
$binduser = $::plugin_settings['ldap-slaves']['binduser']
$bindpass = $::plugin_settings['ldap-slaves']['bindpass']
$passw_auth = $::plugin_settings['ldap-slaves']['passw_auth']
$use_tls = $::plugin_settings['ldap-slaves']['use_tls']
$search_base = $::plugin_settings['ldap-slaves']['search_base']
$access_filter = $::plugin_settings['ldap-slaves']['access_filter']
$home_directory_attr = $::plugin_settings['ldap-slaves']['home_directory_attr']
$ssh_key_attr = $::plugin_settings['ldap-slaves']['ssh_key_attr']
package { 'libpam-sss':
ensure => 'installed',
}
package { 'libnss-sss':
ensure => 'installed',
}
package { 'libnss-ldap':
ensure => 'installed',
}
package { 'sssd':
ensure => 'installed',
}
file { '/etc/sssd/sssd.conf':
ensure => present,
content => template('ldap_slaves/sssd_conf.erb'),
mode => 0600,
require => Package['sssd'],
}
service { 'sssd':
enable => true,
ensure => running,
require => File['/etc/sssd/sssd.conf'],
}
service { 'ssh':
ensure => running,
}
$ldap_uri = join(any2array($uri), ',')
sssd_config {
"domain/${domain_name}/ldap_uri": value => $ldap_uri;
"domain/${domain_name}/ldap_default_bind_dn": value => $binduser;
"domain/${domain_name}/ldap_default_authtok": value => $bindpass;
"domain/${domain_name}/ldap_search_base": value => $search_base;
"domain/${domain_name}/ldap_user_home_directory": value => $home_directory_attr;
"domain/${domain_name}/ldap_user_ssh_public_key": value => $ssh_key_attr;
}
if $use_tls {
$tls_cacert = $::plugin_settings['ldap-slaves']['tls_cacert']
$tls_capath = "/etc/ssl/certs/sssd-ldap-ca.crt"
file { $tls_capath:
ensure => file,
mode => 0644,
content => $tls_cacert,
}
sssd_config {
"domain/${domain_name}/ldap_tls_cacert": value => $tls_capath;
}
}
unless empty($ldap_access_filter) {
sssd_config {
"domain/${domain_name}/ldap_access_filter": value => $access_filter;
}
}
file_line {'sshd_keyscommand':
line => "AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys",
path => '/etc/ssh/sshd_config',
}
file_line {'sshd_keyscommanduser':
line => "AuthorizedKeysCommandUser nobody",
path => '/etc/ssh/sshd_config',
}
if $passw_auth {
file_line {'sshd_passwordAuthentication':
line => "PasswordAuthentication yes",
path => '/etc/ssh/sshd_config',
replace => true,
match => '^PasswordAuthentication.*',
}
File_line<||> ~> Service['ssh'] ~> Service['sssd']
}
file_line {'nsswitch':
line => "shadow: compat sss",
path => '/etc/nsswitch.conf',
replace => true,
match => '^shadow: compat',
}
file { '/etc/pam.d/common-auth':
ensure => present,
content => template('ldap_slaves/pam_common_auth.erb'),
}
file_line {'sssd_pam':
line => "session\trequired\tpam_mkhomedir.so\tskel=/etc/skel/\tumask=0022",
path => '/etc/pam.d/common-session',
after => "session\trequired\tpam_unix.so ",
}
Package<||> -> File<||> -> File_line<||> ~> Service['ssh'] ~> Service['sssd']
File['/etc/sssd/sssd.conf'] -> Sssd_config <||>
Sssd_config <||> ~> Service['sssd']
}

View File

@ -0,0 +1,17 @@
auth required pam_env.so
auth sufficient pam_unix.so try_first_pass likeauth nullok
auth sufficient pam_sss.so use_first_pass
auth optional pam_permit.so
account required pam_unix.so
account [default=bad success=ok user_unknown=ignore] pam_sss.so
account optional pam_permit.so
password required pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 retry=3
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password sufficient pam_sss.so use_authtok
password optional pam_permit.so
session required pam_limits.so
session required pam_env.so
session required pam_unix.so
session optional pam_mkhomedir.so skel=/etc/skel/ umask=0077
session optional pam_sss.so
session optional pam_permit.so

View File

@ -0,0 +1,24 @@
[sssd]
config_file_version = 2
services = nss,pam,sudo,ssh
domains = <%= @domain_name %>
[nss]
filter_users = root,lightdm,nslcd,dnsmasq,dbus,avahi
filter_groups = root
[pam]
[ssh]
debug_level = 6
[domain/<%= @domain_name %>]
ldap_schema = rfc2307
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
cache_credentials = True
enumerate = false
debug_level = 6
fallback_homedir = /home/%u
ldap_default_authtok_type = password

View File

@ -1,62 +1,10 @@
# These tasks will be merged into deployment graph. Here you
# can specify new tasks for any roles, even built-in ones.
- id: fuel-plugin-ldap-slaves_role
type: group
role: [fuel-plugin-ldap-slaves_role]
parameters:
strategy:
type: parallel
- id: fuel-plugin-ldap-slaves-deployment-puppet
- id: ldap-slaves
type: puppet
role: [fuel-plugin-ldap-slaves_role]
# If you do not want to use task-based deployment that is introduced as experimental
# in fuel v8.0 comment code section below this comment, uncomment two lines below it
# and do the same for tasks below.
role: ['/.*/']
version: 2.0.0
cross-depends:
- name: deploy_start
cross-depended-by:
- name: deploy_end
# requires: [deploy_start] # version 1.0.0
# required_for: [deploy_end]
requires: [tools]
required_for: [netconfig]
parameters:
puppet_manifest: "deploy.pp"
puppet_modules: "."
timeout: 3600
#- id: fuel-plugin-ldap-slaves-post-deployment-sh
# type: shell
# role: [fuel-plugin-ldap-slaves_role]
# version: 2.0.0
# cross-depends:
# - name: post_deployment_start
# cross-depended-by:
# - name: post_deployment_end
# # requires: [post_deployment_start]
# # required_for: [post_deployment_end]
# parameters:
# cmd: echo post_deployment_task_executed > /tmp/post_deployment
# retries: 3
# interval: 20
# timeout: 180
#- id: fuel-plugin-ldap-slaves-pre-deployment-sh
# type: shell
# role: [fuel-plugin-ldap-slaves_role]
# version: 2.0.0
# cross-depends:
# - name: pre_deployment_start
# cross-depended-by:
# - name: pre_deployment_end
# # requires: [pre_deployment_start]
# # required_for: [pre_deployment_end]
# parameters:
# cmd: echo pre_deployment_task_executed > /tmp/pre_deployment
# retries: 3
# interval: 20
# timeout: 180
puppet_manifest: "puppet/manifests/ldap-slaves.pp"
puppet_modules: "puppet/modules:/etc/puppet/modules"
timeout: 3600

View File

@ -1,11 +1,88 @@
attributes:
metadata:
# Settings group can be one of "general", "security", "compute", "network",
# "storage", "logging", "openstack_services" and "other".
group: 'other'
fuel-plugin-ldap-slaves_text:
value: 'Set default value'
label: 'Text field'
description: 'Description for text field'
domain_name:
value: 'example.com'
label: 'LDAP Domain name'
description: 'Domain name'
weight: 5
type: text
regex:
source: '^[a-zA-Z0-9._-]+$'
error: 'Domain name contains invalid characters'
uri:
value:
- 'ldaps://example.com'
label: 'LDAP URI'
description: 'LDAP URI'
weight: 10
type: text_list
min: 1
max: 64
regex:
source: '^ldap[s]?:\/\/([a-zA-Z0-9._-]+)(:[0-9]+)?$'
error: 'Not a valid LDAP URI. Should be e.g. ldap://example.com'
binduser:
value: 'cn=ldapreader,ou=ServiceAccounts,dc=example,dc=com'
label: 'LDAP User'
description: 'Account to query LDAP server'
weight: 15
type: text
regex:
source: '^[a-zA-Z0-9_,=\S\\]+$'
error: "Account name contains invalid character or is empty"
bindpass:
value: 'password'
label: 'LDAP Password'
description: 'Password to query LDAP server'
weight: 20
type: password
regex:
source: '^\S+$'
error: "Password can't be empty or contain spaces"
passw_auth:
value: false
label: "Allow authentication by password"
description: "It set 'PasswordAuthentication' param of 'ssh' service to 'yes'."
weight: 25
type: "text"
type: "checkbox"
use_tls:
value: false
label: 'Use TLS'
description: 'Use TLS when communicating with LDAP server'
weight: 30
type: checkbox
tls_cacert:
value: ''
label: 'CA Cerificate'
description: 'CA Certificate that signed LDAP server certificate'
weight: 35
type: textarea
restrictions:
- condition: 'settings:ldap-slaves.use_tls.value == false'
action: 'disable'
regex:
source: '^(-----BEGIN CERTIFICATE-----)(.*[\r\n])+(-----END CERTIFICATE-----[\s\S]*?)$|^$'
error: 'The certificate is not in valid PEM format'
search_base:
value: 'dc=example,dc=com'
label: 'Search base'
description: 'Search base defines the location in the LDAP directory where to start looking for objects'
weight: 40
type: text
access_filter:
value: ''
label: 'LDAP Access filter'
description: 'Access filter allows to limit access to Openstack Servers to specified group'
weight: 45
type: text
home_directory_attr:
value: 'homeDirectory'
label: 'Home Directory Attribute'
description: 'Attribute name in user object, that holds path to user home directory, that should be created during first login'
weight: 50
type: text
ssh_key_attr:
value: 'sshPublicKey'
label: 'SSH Public Key Attribute'
description: 'Attribute name in user object, that holds users public key'
weight: 55
type: text

View File

@ -1,34 +1,17 @@
# Plugin name
name: fuel-plugin-ldap-slaves
# Human-readable name for your plugin
title: Title for fuel-plugin-ldap-slaves plugin
# Plugin version
name: ldap-slaves
title: LDAP Authentication plugin for OpenStack nodes
version: '1.0.0'
# Description
description: Please describe your plugin here
# Required fuel version
fuel_version: ['8.0']
# Specify license of your plugin
licenses: ['Apache License Version 2.0']
# Specify author or company name
authors: ['Specify author or company name']
# A link to the plugin's page
homepage: 'https://github.com/openstack/fuel-plugins'
# Specify a group which your plugin implements, possible options:
# network, storage, storage::cinder, storage::glance, hypervisor,
# equipment
groups: []
# Change `false` to `true` if the plugin can be installed in the environment
# after the deployment.
description: LDAP Slaves plugin for Fuel provides the functionality to use external LDAP directory as source for authentication on OpenStack nodes
fuel_version: ['9.0']
is_hotpluggable: false
# The plugin is compatible with releases in the list
groups: [network]
releases:
- os: ubuntu
version: mitaka-9.0
mode: ['ha']
deployment_scripts_path: deployment_scripts/
repository_path: repositories/ubuntu
# Version of plugin package
package_version: '4.0.0'
licenses: ['Apache License Version 2.0']
authors: ['Mirantis']
homepage: 'https://github.com/openstack/fuel-plugin-ldap-slaves'

View File

@ -1,15 +0,0 @@
# Unique network role name
- id: "example_net_role"
# Role mapping to network
default_mapping: "public"
properties:
# Should be true if network role requires subnet being set
subnet: true
# Should be true if network role requires gateway being set
gateway: false
# List of VIPs to be allocated
vip:
# Unique VIP name
- name: "vip_name"
# Optional linux namespace for VIP
namespace: "haproxy"

View File

@ -1,13 +0,0 @@
fuel-plugin-ldap-slaves_role:
# Role name
name: "Set here the name for the role. This name will be displayed in the Fuel web UI"
# Role description
description: "Write description for your role"
# If primary then during orchestration this role will be
# separated into primary-role and role
has_primary: false
# Assign public IP to node if true
public_ip_required: false
# Weight that will be used to sort out the
# roles on the Fuel web UI
weight: 1000

View File

@ -1,5 +0,0 @@
#!/bin/bash
# Add here any the actions which are required before plugin build
# like packages building, packages downloading from mirrors and so on.
# The script should return 0 if there were no errors.

View File

@ -1,26 +0,0 @@
# WARNING: `tasks.yaml` will be deprecated in further releases.
# Please, use `deployment_tasks.yaml` to describe tasks instead.
# This tasks will be applied on controller nodes,
# here you can also specify several roles, for example
# ['cinder', 'compute'] will be applied only on
# cinder and compute nodes
- role: ['controller']
stage: post_deployment
type: shell
parameters:
cmd: bash deploy.sh
timeout: 42
# Task is applied for all roles
- role: '*'
stage: pre_deployment
type: shell
parameters:
cmd: echo all > /tmp/plugin.all
timeout: 42
# "reboot" task reboots the nodes and waits until they get back online
# - role: '*'
# stage: pre_deployment
# type: reboot
# parameters:
# timeout: 600

View File

@ -1,7 +0,0 @@
volumes_roles_mapping:
# Default role mapping
fuel-plugin-ldap-slaves_role:
- {allocate_size: "min", id: "os"}
# Set here new volumes for your role
volumes: []