diff --git a/recipes/client.rb b/recipes/client.rb index 26502c9..cc468c7 100644 --- a/recipes/client.rb +++ b/recipes/client.rb @@ -17,67 +17,70 @@ # limitations under the License. # -include_recipe 'chef-vault' - -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") +if Chef::Config[:solo] + Chef::Log.warn('This recipe uses search. Chef solo does not support search.') +else + include_recipe 'chef-vault' + node.normal["freeipa"]["client"] = 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] + 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 + + passwords = chef_vault_item(:freeipa, 'passwords') + + #### 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 { File.exist?("/var/lib/ipa-client/sysrestore/sysrestore.index") } + cmd = "ipa-client-install" + cmd += " --server " + freeipa_masters[0][:fqdn] + cmd += " --domain " + node["domain"] + cmd += " --realm " + node["domain"].upcase + cmd += " --mkhomedir --unattended" + cmd += " -p admin -w " + passwords['ldap_server_admin_pwd'] + sensitive true + 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 - service "certmonger" do - action [:enable,:start] - end - - passwords = chef_vault_item(:freeipa, 'passwords') - - #### 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 { File.exist?("/var/lib/ipa-client/sysrestore/sysrestore.index") } - cmd = "ipa-client-install" - cmd += " --server " + freeipa_masters[0][:fqdn] - cmd += " --domain " + node["domain"] - cmd += " --realm " + node["domain"].upcase - cmd += " --mkhomedir --unattended" - cmd += " -p admin -w " + passwords['ldap_server_admin_pwd'] - sensitive true - 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/server.rb b/recipes/server.rb index 1e6ea9b..e4bab52 100644 --- a/recipes/server.rb +++ b/recipes/server.rb @@ -22,119 +22,231 @@ include_recipe 'chef-vault' node.normal["freeipa"]["server"] = true # become aware of clients and servers -freeipa_servers = search(:node, "freeipa_server:true") -freeipa_clients = search(:node, "freeipa_client:true") +if Chef::Config[:solo] + Chef::Log.warn('This recipe uses search. Chef solo does not support search.') +else + 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" - -package 'ipa-server' do - case node["platform"] - when 'redhat', 'centos' - package_name 'ipa-server' - end - action :install -end - -##### 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 - ##### Do master stuff - - # write better tests to see if freeipa is already set up. - ## Bootstrap FreeIPA - execute "initializing freeipa-server" do - not_if { File.exist?('/var/liv/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 --mkhomedir" - 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 + # gather data bag secrets + passwords = chef_vault_item("freeipa", 'passwords') + # packages + package 'ipa-server' do + case node["platform"] + when 'redhat', 'centos' + package_name 'ipa-server' + end + action :install + end + + ##### 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 + ##### Do master stuff + + # write better tests to see if freeipa is already set up. + ## Bootstrap FreeIPA + execute "initializing freeipa-server" do + not_if { File.exist?('/var/liv/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 --mkhomedir" + 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 + + directory "/root/.ssh" do + owner "root" + group "root" + mode "0700" + action :create + end + + file "/root/.ssh/id_rsa" do + content passwords["ssh-pvt"] + owner "root" + group "root" + mode "0600" + end + + file "/root/.ssh/id_rsa.pub" do + content passwords["ssh-pub"] + owner "root" + group "root" + mode "0600" + end + + ruby_block "add public key to authorized_keys" do + block do + file = Chef::Util::FileEdit.new("/root/.ssh/authorized_keys") + file.insert_line_if_no_match(Regexp.new(Regexp.escape(passwords["ssh-pub"].delete("\n"))), passwords["ssh-pub"]) + file.write_file + end + end + + node.normal["freeipa"]["master"] = true + + #elsif (node[:freeipa][:master].nil? && node[:freeipa][:master] == false) && (node[:freeipa][:replica].nil? && node[:freeipa][:replica] == false) then + #elsif (node["freeipa"]["master"] && node["freeipa"]["master"].respond_to?(:value) && node["freeipa"]["master"] == false) && + # (node["freeipa"]["replica"] && node["freeipa"]["replica"].respond_to?(:value) && node["freeipa"]["replica"] == false) then + elsif(node["freeipa"]["master"] != true && node["freeipa"]["replica"] != true) then + ### Subsequent Replica Nodes + + # 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" + ssh_noauth = "-o StrictHostKeyChecking=yes -o PasswordAuthentication=no" + + execute "prepare replica from master" do + cmd = "ssh #{ssh_noauth} root@#{freeipa_masters[0]['fqdn']} ipa-replica-prepare -p #{passwords['ldap_server_admin_pwd']}" + cmd += " " + node["fqdn"] + command cmd + sensitive true + not_if "ssh #{ssh_noauth} root@#{freeipa_masters[0]['fqdn']} test -f /var/lib/ipa/replica-info-#{node['fqdn']}.gpg" + #notifies :run, 'execute[rsyncing freeipa replication data]', :immediately + end + + # Check for replication config + # Attempt to copy config from master. + # Fail gracefully if not found. + execute "scping freeipa replication data" do + #only_if "ipa-replica-manage -p #{passwords['ldap_server_admin_pwd']} -H #{freeipa_masters[0][:fqdn]} list | grep #{node[:fqdn]}" + only_if "ssh #{ssh_noauth} root@#{freeipa_masters[0]['fqdn']} test -f /var/lib/ipa/replica-info-#{node['fqdn']}.gpg" + not_if { File.exist?("/var/lib/ipa/replica-info-#{node['fqdn']}.gpg") } + #cmd = "rsync -a -e \"ssh " + ssh_noauth + cmd = "scp " + ssh_noauth + cmd += " root@" + freeipa_masters[0]["fqdn"] + cmd += ":/var/lib/ipa/replica-info-#{node['fqdn']}.gpg" + cmd += " /var/lib/ipa/" + command cmd + #notifies :run, 'execute[joining freeipa cluster]', :immediately + 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" + only_if { File.exist?("/var/lib/ipa/replica-info-#{node['fqdn']}.gpg") } + cmd = "ipa-replica-install" + cmd += " -p " + passwords['ldap_server_admin_pwd'] + cmd += " --unattended --mkhomedir --skip-conncheck" + cmd += " /var/lib/ipa/replica-info-#{node['fqdn']}.gpg" + command cmd + #sensitive true + #action :nothing + notifies :run, 'execute[copying CA private key]', :immediately + 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 { File.exist?("/etc/dirsrv/slapd-#{node['domain'].upcase}/") } + not_if { File.exist?("/etc/dirsrv/slaved-#{node['domain'].upcase}/cacert.p12") } + cmd = "scp " + ssh_noauth + cmd += " root@" + freeipa_masters[0]['fqdn'] + cmd += ":/etc/dirsrv/slapd-#{node['domain'].upcase}/cacert.p12" + cmd += " /etc/dirsrv/slapd-#{node['domain'].upcase}/" + command cmd + ignore_failure true + action :nothing + notifies :run, 'ruby_block[set node as replica]', :immediately + end + + ruby_block "set node as replica" do + block do + node.normal["freeipa"]["replica"] = true + end + action :nothing + end + end + + + ### Admin Password for LWRP + # + file '/etc/ipa/admin.password' do + content passwords['ipa_user_pwd'] + owner 'root' + group 'root' + mode '0600' + sensitive true + end + + + ### SSH key for IPA server communications + # directory "/root/.ssh" do - owner "root" - group "root" - mode "0700" + owner "root" + group "root" + mode "0700" action :create end - + file "/root/.ssh/id_rsa" do content passwords["ssh-pvt"] - owner "root" - group "root" - mode "0600" + owner "root" + group "root" + mode "0600" + sensitive true end - + file "/root/.ssh/id_rsa.pub" do content passwords["ssh-pub"] - owner "root" - group "root" - mode "0600" + owner "root" + group "root" + mode "0600" + sensitive true end - + ruby_block "add public key to authorized_keys" do block do file = Chef::Util::FileEdit.new("/root/.ssh/authorized_keys") @@ -142,165 +254,46 @@ if freeipa_masters.empty? then file.write_file end end - - node.normal["freeipa"]["master"] = true - -#elsif (node[:freeipa][:master].nil? && node[:freeipa][:master] == false) && (node[:freeipa][:replica].nil? && node[:freeipa][:replica] == false) then -#elsif (node["freeipa"]["master"] && node["freeipa"]["master"].respond_to?(:value) && node["freeipa"]["master"] == false) && -# (node["freeipa"]["replica"] && node["freeipa"]["replica"].respond_to?(:value) && node["freeipa"]["replica"] == false) then -elsif(node["freeipa"]["master"] != true && node["freeipa"]["replica"] != true) then - ### Subsequent Replica Nodes - - # 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" - ssh_noauth = "-o StrictHostKeyChecking=yes -o PasswordAuthentication=no" - - execute "prepare replica from master" do - cmd = "ssh #{ssh_noauth} root@#{freeipa_masters[0]['fqdn']} ipa-replica-prepare -p #{passwords['ldap_server_admin_pwd']}" - cmd += " " + node["fqdn"] - command cmd - sensitive true - not_if "ssh #{ssh_noauth} root@#{freeipa_masters[0]['fqdn']} test -f /var/lib/ipa/replica-info-#{node['fqdn']}.gpg" - #notifies :run, 'execute[rsyncing freeipa replication data]', :immediately + + + + ##### services + # enable all the default services recommended by the freeipa docs + + #service "dirsrv" do + # service_name "dirsrv@#{node[:domain].upcase.gsub(".", "-")}" + # 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 - - # Check for replication config - # Attempt to copy config from master. - # Fail gracefully if not found. - execute "scping freeipa replication data" do - #only_if "ipa-replica-manage -p #{passwords['ldap_server_admin_pwd']} -H #{freeipa_masters[0][:fqdn]} list | grep #{node[:fqdn]}" - only_if "ssh #{ssh_noauth} root@#{freeipa_masters[0]['fqdn']} test -f /var/lib/ipa/replica-info-#{node['fqdn']}.gpg" - not_if { File.exist?("/var/lib/ipa/replica-info-#{node['fqdn']}.gpg") } - #cmd = "rsync -a -e \"ssh " + ssh_noauth - cmd = "scp " + ssh_noauth - cmd += " root@" + freeipa_masters[0]["fqdn"] - cmd += ":/var/lib/ipa/replica-info-#{node['fqdn']}.gpg" - cmd += " /var/lib/ipa/" - command cmd - #notifies :run, 'execute[joining freeipa cluster]', :immediately - 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" - only_if { File.exist?("/var/lib/ipa/replica-info-#{node['fqdn']}.gpg") } - cmd = "ipa-replica-install" - cmd += " -p " + passwords['ldap_server_admin_pwd'] - cmd += " --unattended --mkhomedir --skip-conncheck" - cmd += " /var/lib/ipa/replica-info-#{node['fqdn']}.gpg" - command cmd - #sensitive true - #action :nothing - notifies :run, 'execute[copying CA private key]', :immediately - 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 { File.exist?("/etc/dirsrv/slapd-#{node['domain'].upcase}/") } - not_if { File.exist?("/etc/dirsrv/slaved-#{node['domain'].upcase}/cacert.p12") } - cmd = "scp " + ssh_noauth - cmd += " root@" + freeipa_masters[0]['fqdn'] - cmd += ":/etc/dirsrv/slapd-#{node['domain'].upcase}/cacert.p12" - cmd += " /etc/dirsrv/slapd-#{node['domain'].upcase}/" - command cmd - ignore_failure true - action :nothing - notifies :run, 'ruby_block[set node as replica]', :immediately - end - - ruby_block "set node as replica" do - block do - node.normal["freeipa"]["replica"] = true - end - action :nothing + + #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 end - -### Admin Password for LWRP -# -file '/etc/ipa/admin.password' do - content passwords['ipa_user_pwd'] - owner 'root' - group 'root' - mode '0600' - sensitive true -end - - -### SSH key for IPA server communications -# -directory "/root/.ssh" do - owner "root" - group "root" - mode "0700" - action :create -end - -file "/root/.ssh/id_rsa" do - content passwords["ssh-pvt"] - owner "root" - group "root" - mode "0600" - sensitive true -end - -file "/root/.ssh/id_rsa.pub" do - content passwords["ssh-pub"] - owner "root" - group "root" - mode "0600" - sensitive true -end - -ruby_block "add public key to authorized_keys" do - block do - file = Chef::Util::FileEdit.new("/root/.ssh/authorized_keys") - file.insert_line_if_no_match(Regexp.new(Regexp.escape(passwords["ssh-pub"].delete("\n"))), passwords["ssh-pub"]) - file.write_file - end -end - - - -##### services -# enable all the default services recommended by the freeipa docs - -#service "dirsrv" do -# service_name "dirsrv@#{node[:domain].upcase.gsub(".", "-")}" -# 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 -