cookbook-freeipa/recipes/server.rb

299 lines
9.9 KiB
Ruby

#
# 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.normal["freeipa"]["server"] = true
# become aware of clients and servers
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 AND chef_environment:#{node.chef_environment}")
freeipa_clients = search(:node, "freeipa_client:true AND chef_environment:#{node.chef_environment}")
# 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 AND chef_environment:#{node.chef_environment}")
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"
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
end