From a709e8a6524d576b45c440880757f3f5da89ce78 Mon Sep 17 00:00:00 2001 From: Eric Renfro Date: Fri, 15 Jul 2016 09:46:51 -0400 Subject: [PATCH] Initial commit --- .gitignore | 18 +++ .kitchen.yml | 15 ++ Berksfile | 7 + CHANGELOG.md | 3 + Gemfile | 2 + LICENSE | 3 + README.md | 42 ++++++ Thorfile | 5 + chefignore | 94 ++++++++++++ metadata.rb | 11 ++ recipes/client.rb | 76 ++++++++++ recipes/default.rb | 8 + recipes/server.rb | 203 ++++++++++++++++++++++++++ templates/default/ipa.conf.erb | 61 ++++++++ templates/default/ssh_known_hosts.erb | 4 + 15 files changed, 552 insertions(+) create mode 100644 .gitignore create mode 100644 .kitchen.yml create mode 100644 Berksfile create mode 100644 CHANGELOG.md create mode 100644 Gemfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 Thorfile create mode 100644 chefignore create mode 100644 metadata.rb create mode 100644 recipes/client.rb create mode 100644 recipes/default.rb create mode 100644 recipes/server.rb create mode 100644 templates/default/ipa.conf.erb create mode 100644 templates/default/ssh_known_hosts.erb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4699ff2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +*~ +*# +.#* +\#*# +.*.sw[a-z] +*.un~ +pkg/ + +# Berkshelf +.vagrant +/cookbooks +Berksfile.lock + +# Bundler +Gemfile.lock +bin/* +.bundle/* + diff --git a/.kitchen.yml b/.kitchen.yml new file mode 100644 index 0000000..3d0c476 --- /dev/null +++ b/.kitchen.yml @@ -0,0 +1,15 @@ +--- +driver: + name: vagrant + +provisioner: + name: chef_solo + +platforms: + - name: ubuntu-14.04 + - name: centos-7.1 + +suites: + - name: default + run_list: + attributes: diff --git a/Berksfile b/Berksfile new file mode 100644 index 0000000..065c05f --- /dev/null +++ b/Berksfile @@ -0,0 +1,7 @@ +source "https://supermarket.chef.io" + +metadata + +cookbook 'chef-vault' +cookbook 'ohai' +cookbook 'sshroot2rootssh', path: '/home/psi-jack/Chef/cookbooks/sshroot2rootssh' diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..840a486 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 0.1.0 + +Initial release of freeipa diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..c9721cb --- /dev/null +++ b/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..124c063 --- /dev/null +++ b/LICENSE @@ -0,0 +1,3 @@ +Copyright (C) 2016 YOUR_NAME + +All rights reserved - Do Not Redistribute diff --git a/README.md b/README.md new file mode 100644 index 0000000..22a3bef --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# freeipa-cookbook + +TODO: Enter the cookbook description here. + +## Supported Platforms + +TODO: List your supported platforms. + +## Attributes + + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['freeipa']['bacon']Booleanwhether to include bacontrue
+ +## Usage + +### freeipa::default + +Include `freeipa` in your node's `run_list`: + +```json +{ + "run_list": [ + "recipe[freeipa::default]" + ] +} +``` + +## License and Authors + +Author:: YOUR_NAME () diff --git a/Thorfile b/Thorfile new file mode 100644 index 0000000..cb1aeae --- /dev/null +++ b/Thorfile @@ -0,0 +1,5 @@ +# encoding: utf-8 + +require 'bundler' +require 'bundler/setup' +require 'berkshelf/thor' diff --git a/chefignore b/chefignore new file mode 100644 index 0000000..138a808 --- /dev/null +++ b/chefignore @@ -0,0 +1,94 @@ +# Put files/directories that should be ignored in this file when uploading +# or sharing to the community site. +# Lines that start with '# ' are comments. + +# OS generated files # +###################### +.DS_Store +Icon? +nohup.out +ehthumbs.db +Thumbs.db + +# SASS # +######## +.sass-cache + +# EDITORS # +########### +\#* +.#* +*~ +*.sw[a-z] +*.bak +REVISION +TAGS* +tmtags +*_flymake.* +*_flymake +*.tmproj +.project +.settings +mkmf.log + +## COMPILED ## +############## +a.out +*.o +*.pyc +*.so +*.com +*.class +*.dll +*.exe +*/rdoc/ + +# Testing # +########### +.watchr +.rspec +spec/* +spec/fixtures/* +test/* +features/* +Guardfile +Procfile + +# SCM # +####### +.git +*/.git +.gitignore +.gitmodules +.gitconfig +.gitattributes +.svn +*/.bzr/* +*/.hg/* +*/.svn/* + +# Berkshelf # +############# +cookbooks/* +tmp + +# Cookbooks # +############# +CONTRIBUTING +CHANGELOG* + +# Strainer # +############ +Colanderfile +Strainerfile +.colander +.strainer + +# Vagrant # +########### +.vagrant +Vagrantfile + +# Travis # +########## +.travis.yml diff --git a/metadata.rb b/metadata.rb new file mode 100644 index 0000000..a8d9805 --- /dev/null +++ b/metadata.rb @@ -0,0 +1,11 @@ +name 'freeipa' +maintainer 'Eric Renfro' +maintainer_email 'psi-jack@linux-help.org' +license 'GPLv3' +description 'Installs/Configures freeipa' +long_description 'Installs/Configures freeipa' +version '0.1.0' + +depends 'ohai' +depends 'chef-vault' +depends 'sshroot2rootssh' diff --git a/recipes/client.rb b/recipes/client.rb new file mode 100644 index 0000000..2b736df --- /dev/null +++ b/recipes/client.rb @@ -0,0 +1,76 @@ +# +# Cookbook Name:: freeipa +# Recipe:: client +# +# Copyright 2011, afistfulofservers +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +node.set[:freeipa][:client] = true + +# become aware servers +freeipa_servers = search(:node, "freeipa_server:true") +freeipa_clients = search(:node, "freeipa_client:true") +freeipa_masters = search(:node, "freeipa_master:true") + +unless freeipa_servers.empty? then + package "ipa-client" + package "openldap-clients" + package "dbus" + package "certmonger" + + puts "DEBUG: got here!" + service "messagebus" do + action [:enable,:start] + end + service "certmonger" do + action [:enable,:start] + end + + #### Join node to freeipa 'domain' + # configures kerberos client to point to kdc on freeipa::server + # configures ldap to look up posix information via sssd/nss + execute "joining freeipa client to domain" do + not_if "ls /var/lib/ipa-client/sysrestore/sysrestore.index" + cmd = "ipa-client-install -U" + cmd += " --server " + freeipa_masters[0][:fqdn] + cmd += " --domain " + node[:domain] + cmd += " --realm " + node[:domain].upcase + command cmd + ignore_failure true + end + + + #### pki enrollment + # gotta wait for ipav2 apparently + # + # generate csr + # submit csr + # enable dbus + # get host cert? +# execute "requesting host principal certificate" do +# cmd = "ipa-getcert request -r" +# cmd += " -f /tmp/affs-server.crt" +# cmd += " -k /tmp/affs-server.key" +# cmd += " -N CN= " + node[:fqdn] +# cmd += " -K host/" + node[:fqdn] +# cmd += " -D " + node[:fqdn] +# cmd += " -U id-kp-serverAuth" +# puts "DEBUG: #{cmd}" +# command cmd +# end + + # get http cert? +end + diff --git a/recipes/default.rb b/recipes/default.rb new file mode 100644 index 0000000..9a74b28 --- /dev/null +++ b/recipes/default.rb @@ -0,0 +1,8 @@ +# +# Cookbook Name:: freeipa +# Recipe:: default +# +# Copyright (C) 2016 YOUR_NAME +# +# All rights reserved - Do Not Redistribute +# diff --git a/recipes/server.rb b/recipes/server.rb new file mode 100644 index 0000000..a7ed6b8 --- /dev/null +++ b/recipes/server.rb @@ -0,0 +1,203 @@ +# +# Cookbook Name:: freeipa +# Recipe:: server +# +# Copyright 2011, afistfulofservers +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include_recipe 'chef-vault' + +node.set[:freeipa][:server] = true + +# become aware of clients and servers +freeipa_servers = search(:node, "freeipa_server:true") +freeipa_clients = search(:node, "freeipa_client:true") + +# gather data bag secrets +#secret = Chef::EncryptedDataBagItem.load_secret("/home/psi-jack/.chef/encrypted_data_bag_secret") +#passwords = Chef::EncryptedDataBagItem.load("secrets", "passwords", secret) +passwords = chef_vault_item(:freeipa, 'passwords') +#ldap_server_admin_pwd = data_bag_item('secrets','ldap_server_admin_pwd')['value'] +#kdc_database_master_key = data_bag_item('secrets','kdc_database_master_key')['value'] +#ipa_user_pwd = data_bag_item('secrets','ipa_user_pwd')['value'] + +# packages +#package "dbus" +#package "oddjob" +#package "ipa-client" +package "ipa-server" +package "rsync" + +##### Security considerations +# All FreeIPA server hosts need to be able to ssh to each other as root to copy replication configs +# That kind of sucks, but what are the real consequences? +# Since they are replicants of each other, this can be justified, since the data is already compromised. +# Can selinux help mitigate this? +#include_recipe "ohai" +#include_recipe "sshroot2rootssh" + +##### Replication +# We're going to have to +# a) detect any new freeipa_servers +# b) generate ipa-replica-prepare output for them +# c) copy the configs to them + +### Behavor +# First node sets special attribute "master" +# First node configures itself with newly generated crypto + +# Subsequent nodes comes up +# Subsequent nodes try to to scp their fqdn's configuration from master +# Subsequent nodes negotiate for master + +# negotiate for master +freeipa_masters = search(:node, "freeipa_master:true") +if freeipa_masters.empty? then + node.set[:freeipa][:master] = "true" +end + +##### Do master stuff +if node[:freeipa][:master] then + + # write better tests to see if freeipa is already set up. + ## Bootstrap FreeIPA + execute "initializing freeipa-server" do + not_if "ls /var/lib/ipa/sysrestore/sysrestore.state" + cmd = "ipa-server-install" + cmd += " --hostname " + node[:fqdn] + #cmd += " -u " + "ipaadmin" + cmd += " -r " + node[:domain].upcase + cmd += " -n " + node[:domain] + cmd += " -p " + passwords['ldap_server_admin_pwd'] + cmd += " -P " + passwords['kdc_database_master_key'] + cmd += " -a " + passwords['ipa_user_pwd'] + cmd += " -N " + cmd += " -U " + cmd += " --no-host-dns " + command "#{cmd}" + notifies :start, "service[dirsrv]" + end + + # Compare list of freeipa_servers with contents of /var/lib/ipa/ + #configured_replicants =`ipa-replica-manage -p #{ldap_server_admin_pwd} -H #{node[:fqdn]} list`.split + configured_replicants =`ipa-replica-manage -p #{passwords['ldap_server_admin_pwd']} -H #{node[:fqdn]} list`.split + configured_replicants.each { |r| puts "DEBUG: configured_replicant: #{r}" } + + freeipa_server_fqdns = Array.new + freeipa_servers.each { |n| freeipa_server_fqdns << n[:fqdn] } + freeipa_server_fqdns.compact! + + freeipa_server_fqdns.each do |f| + unless node[:fqdn] == f then + unless configured_replicants.include?( f ) then + execute "generating replica config for #{f}" do + not_if "ls /var/lib/ipa/replica-info-#{f}.gpg" + command "ipa-replica-prepare -p #{passwords['ldap_server_admin_pwd']} #{f}" + end + end + end + end + +end + +### Subsequent nodes +unless node[:freeipa][:master] then + + # check to see if slave is setup to replicat from master + #"ipa-replica-manage -p 0123456789 -H authentication-1.dev.us-east-1.aws.afistfulofservers.net list" + + # Check for replication config + # Attempt to copy config from master. + # Fail gracefully if not found. + execute "rsyncing freeipa replication data" do + #only_if "ipa-replica-manage -p #{ldap_server_admin_pwd} -H #{freeipa_masters[0][:fqdn]} list | grep #{node[:fqdn]}" + cmd = "rsync -a -e \"ssh " + cmd += " -o StrictHostKeyChecking=yes" + cmd += " -o PasswordAuthentication=no\"" + cmd += " root@" + cmd += "#{freeipa_masters[0][:fqdn]}:" + cmd += "/var/lib/ipa/replica-info*" + cmd += " /var/lib/ipa" + command cmd + ignore_failure true + end + + execute "joining freeipa cluster" do + not_if "ipa-replica-manage -p #{passwords['ldap_server_admin_pwd']} -H #{freeipa_masters[0][:fqdn]} list | grep #{node[:fqdn]}" + only_if "ls /var/lib/ipa/replica-info-#{node[:fqdn]}.gpg" + cmd = "ipa-replica-install" + cmd += " -p " + passwords['ldap_server_admin_pwd'] + cmd +=" /var/lib/ipa/replica-info-#{node[:fqdn]}.gpg" + command cmd + end + + # copy CA private key + # /etc/dirsrv/slapd-DEV-US-EAST-1-AWS-AFISTFULOFSERVERS-NET/pwdfile.txt + execute "copying CA private key" do + only_if "ipa-replica-manage -p #{passwords['ldap_server_admin_pwd']} -H #{freeipa_masters[0][:fqdn]} list | grep #{node[:fqdn]}" + only_if "ls /etc/dirsrv/slapd-#{node[:domain].upcase}/" + not_if "ls /etc/dirsrv/slapd-#{node[:domain].upcase}/cacert.p12" + cmd = "rsync -a -e \"ssh " + cmd += " -o StrictHostKeyChecking=yes" + cmd += " -o PasswordAuthentication=no\"" + cmd += " root@" + cmd += "#{freeipa_masters[0][:fqdn]}:" + cmd += "/etc/dirsrv/slapd-#{node[:domain].upcase}/cacert.p12" + cmd += " /etc/dirsrv/slapd-#{node[:domain].upcase}/" + #puts "DEBUG: #{cmd}" + command cmd + ignore_failure true + end + +end + +##### services +# enable all the default services recommended by the freeipa docs + +#service "dirsrv" do +# action [:enable,:start] +#end + +#service "krb5kdc" do +# only_if service[:dirsrv] => running +# action [:enable,:start] +#end + +#template "/etc/httpd/conf.d/ipa.conf" do +# source "ipa.conf.erb" +# mode 0644 +# notifies :restart, "service[httpd]" +#end + +#service "httpd" do +# action [:enable,:start] +#end + +#service "ipa_kpasswd" do +# action [:enable,:start] +#end + +#service "ipa" do +# action [:enable,:start] +#end +# +#service "messagebus" do +# action [:enable,:start] +#end +# +#service "oddjobd" do +# action [:enable,:start] +#end + diff --git a/templates/default/ipa.conf.erb b/templates/default/ipa.conf.erb new file mode 100644 index 0000000..4b6812b --- /dev/null +++ b/templates/default/ipa.conf.erb @@ -0,0 +1,61 @@ +ProxyRequests Off +AddType application/java-archive jar + + AuthType Kerberos + AuthName "Kerberos Login" + KrbMethodNegotiate off + KrbMethodK5Passwd on + KrbServiceName HTTP + KrbAuthRealms DEV.US-EAST-1.AWS.AFISTFULOFSERVERS.NET + Krb5KeyTab /etc/httpd/conf/ipa.keytab + KrbSaveCredentials on + Require valid-user + ErrorDocument 401 /ipa/errors/unauthorized.html + RewriteEngine on + Order deny,allow + Allow from all + RequestHeader set X-Forwarded-Keytab %{KRB5CCNAME}e + # RequestHeader unset Authorization + +ProxyPass /ipa/ui http://localhost:8080/ipa/ui +ProxyPassReverse /ipa/ui http://localhost:8080/ipa/ui +Alias /ipa/xml "/usr/share/ipa/ipaserver/XMLRPC" +Alias /ipa/errors "/usr/share/ipa/html" +Alias /ipa/config "/usr/share/ipa/html" + + AuthType Kerberos + AuthName "Kerberos Login" + KrbMethodNegotiate on + KrbMethodK5Passwd off + KrbServiceName HTTP + KrbAuthRealms DEV.US-EAST-1.AWS.AFISTFULOFSERVERS.NET + Krb5KeyTab /etc/httpd/conf/ipa.keytab + KrbSaveCredentials on + Require valid-user + ErrorDocument 401 /ipa/errors/unauthorized.html + SetHandler mod_python + PythonHandler ipaxmlrpc + + PythonDebug Off + PythonOption IPADebug Off + # this is pointless to use since it would just reload ipaxmlrpc.py + PythonAutoReload Off + + + AllowOverride None + Satisfy Any + Allow from all + + + AuthType Kerberos + AuthName "Kerberos Login" + KrbMethodNegotiate on + KrbMethodK5Passwd off + KrbServiceName HTTP + KrbAuthRealms DEV.US-EAST-1.AWS.AFISTFULOFSERVERS.NET + Krb5KeyTab /etc/httpd/conf/ipa.keytab + KrbSaveCredentials on + Require valid-user + ErrorDocument 401 /ipa/errors/unauthorized.html + + diff --git a/templates/default/ssh_known_hosts.erb b/templates/default/ssh_known_hosts.erb new file mode 100644 index 0000000..f7cb02c --- /dev/null +++ b/templates/default/ssh_known_hosts.erb @@ -0,0 +1,4 @@ +# maintained by chef +<% @freeipa_servers.each do |freeipa_server| -%> +<%= freeipa_server['fqdn'] %>,<%= freeipa_server['ipaddress'] %> ssh-rsa <%= freeipa_server[:keys][:ssh][:host_rsa_public] %> +<% end -%>