Updated to chef-client on FreeBSD (aka part III)

Found the solution.

Essentially, I just need to add this:

supports :status => true, :restart => true, :reload => true

This means that it will start up the service if isn’t running. Now it works as expected when I add chef-client to the run list.

Here is the updated code:

 

when "bsd"
  case node['platform']
    when "freebsd"

      directory "/etc/rc.conf.d" do
        owner "root"
        group "wheel"
        mode "0644"
        action :create
      end
      template "/etc/rc.d/chef-client" do
        source "#{dist_dir}/rc.d/chef-client.erb"
        owner "root"
        group "wheel"
        mode 0755
      end

      template "/etc/rc.conf.d/chef" do
        source "#{dist_dir}/rc.conf.d/chef.erb"
        mode 0644
        notifies :start, "service[chef-client]", :delayed
      end

      service "chef-client" do
        supports :status => true, :restart => true, :reload => true
        action [:start]
      end

    else
      log "You specified service style 'bsd'. You will need to set up your rc.local file."
      log "Hint: chef-client -i #{node["chef_client"]["client_interval"]} -s #{node["chef_client"]["client_splay"]}"
  end
else
  log "Could not determine service init style, manual intervention required to start up the chef-client service."
end

FreeBSD and chef-client – a part II (of sorts)

Finally changed chef-client with an updated recipe to support FreeBSD.

Under the chef-repo/chef-client directory, I added the following files:

./templates/freebsd/rc.d/chef-client.erb
./templates/freebsd/rc.conf.d/chef.erb

And updated:

./recipes/service.rb

The locations corresponds to the directory location under the default #{conf} directory, (which is apparently /etc) The templates are .erb files that corresponds to the configuration files on the server.

chef-client.erb:

[rilindo@chef chef-client]$ cat ./templates/freebsd/rc.d/chef-client.erb 
#!/bin/sh

# PROVIDE: chef
# REQUIRE: LOGIN
# KEYWORD: nojail shutdown

. /etc/rc.subr

name="chef"
rcvar=`set_rcvar`
stop_cmd="chef_stop"
command="/usr/local/bin/${name}-client"
command_args="-i -s -d -L /var/log/chef/client.log -c /etc/chef/client.rb -P /var/run/chef.pid"
load_rc_config $name
export rc_pid
chef_stop()
{
	pidfile="/var/run/chef.pid"
	rc_pid=`cat ${pidfile}`
        kill $rc_pid
}

run_rc_command "$1"

chef.erb

[rilindo@chef chef-client]$ cat ./templates/freebsd/rc.conf.d/chef
chef_enable="YES"

 With ERB, I could have easily have placeholders in the code so that it can be populated with node-specific information automatically. I did not do that in this case, though. That is for another time.

Finally, I updated the service code from:

when "bsd"
  log "You specified service style 'bsd'. You will need to set up your rc.local file."
  log "Hint: chef-client -i #{node["chef_client"]["client_interval"]} -s #{node["chef_client"]["client_splay"]}"
  
else
  log "Could not determine service init style, manual intervention required to start up the chef-client service."
end

to

when "bsd"
  case node['platform']
    when "freebsd"

      directory "/etc/rc.conf.d" do
        owner "root"
        group "wheel"
        mode "0644"
        action :create
      end
      template "/etc/rc.d/chef-client" do
        source "#{dist_dir}/rc.d/chef-client.erb"
        owner "root"
        group "wheel"
        mode 0755
      end

      template "/etc/rc.conf.d/chef" do
        source "#{dist_dir}/rc.conf.d/chef.erb"
        mode 0644
        notifies :start, "service[chef-client]", :delayed
      end

      service "chef-client" do
        action [:start]
      end

    else
      log "You specified service style 'bsd'. You will need to set up your rc.local file."
      log "Hint: chef-client -i #{node["chef_client"]["client_interval"]} -s #{node["chef_client"]["client_splay"]}"
  end
else
  log "Could not determine service init style, manual intervention required to start up the chef-client service."
end

I am not sure if this is quite “rubyish”, but it works. 

At that point, I uploaded the cookbook:

knife cookbook upload chef-client

Added the recipe to the freebsd node:

knife node run_list add freebsddev.monzell.com  "recipe[chef-client]"

And ran chef-client. The chef-client program sees the receipe and install the files to the appropriate locations:

freebsddev# /usr/local/bin/chef-client
[Sun, 01 Jan 2012 23:48:28 -0500] INFO: *** Chef 0.10.8 ***
[Sun, 01 Jan 2012 23:48:34 -0500] INFO: Run List is 
] [Sun, 01 Jan 2012 23:48:34 -0500] INFO: Run List expands to [chef-client] [Sun, 01 Jan 2012 23:48:34 -0500] INFO: Starting Chef Run for freebsddev.monzell.com [Sun, 01 Jan 2012 23:48:34 -0500] INFO: Running start handlers [Sun, 01 Jan 2012 23:48:34 -0500] INFO: Start handlers complete. [Sun, 01 Jan 2012 23:48:34 -0500] INFO: Loading cookbooks [chef-client] [Sun, 01 Jan 2012 23:48:34 -0500] INFO: Storing updated cookbooks/chef-client/recipes/default.rb in the cache. [Sun, 01 Jan 2012 23:48:34 -0500] INFO: Storing updated cookbooks/chef-client/recipes/delete_validation.rb in the cache. [Sun, 01 Jan 2012 23:48:34 -0500] INFO: Storing updated cookbooks/chef-client/recipes/service.rb in the cache. [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Storing updated cookbooks/chef-client/recipes/config.rb in the cache. [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Storing updated cookbooks/chef-client/attributes/default.rb in the cache. [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Storing updated cookbooks/chef-client/metadata.json in the cache. [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Storing updated cookbooks/chef-client/README.md in the cache. [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Storing updated cookbooks/chef-client/metadata.rb in the cache. [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Processing directory[/var/run] action create (chef-client::service line 42) [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Processing directory[/var/chef/cache] action create (chef-client::service line 42) [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Processing directory[/var/chef/backup] action create (chef-client::service line 42) [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Processing directory[/var/log/chef] action create (chef-client::service line 42) [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Processing directory[/etc/rc.conf.d] action create (chef-client::service line 203) [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Processing template[/etc/rc.d/chef-client] action create (chef-client::service line 209) [Sun, 01 Jan 2012 23:48:35 -0500] INFO: Processing template[/etc/rc.conf.d/chef] action create (chef-client::service line 216) [Sun, 01 Jan 2012 23:48:36 -0500] INFO: Processing service[chef-client] action start (chef-client::service line 222) [Sun, 01 Jan 2012 23:48:36 -0500] INFO: Chef Run complete in 2.340431224 seconds [Sun, 01 Jan 2012 23:48:36 -0500] INFO: Running report handlers [Sun, 01 Jan 2012 23:48:36 -0500] INFO: Report handlers complete

I am mostly done now. I just need to start it up with:

/etc/rc.d/chef-client start

I should be able to start automatically. However,  getting it to start up automatically upon installation has so far just returns me with:

freebsddev# /usr/local/bin/chef-client
[Sun, 01 Jan 2012 23:46:26 -0500] INFO: *** Chef 0.10.8 ***
[Sun, 01 Jan 2012 23:46:32 -0500] INFO: Run List is 
] [Sun, 01 Jan 2012 23:46:32 -0500] INFO: Run List expands to [chef-client] [Sun, 01 Jan 2012 23:46:32 -0500] INFO: Starting Chef Run for freebsddev.monzell.com [Sun, 01 Jan 2012 23:46:32 -0500] INFO: Running start handlers [Sun, 01 Jan 2012 23:46:32 -0500] INFO: Start handlers complete. [Sun, 01 Jan 2012 23:46:32 -0500] INFO: Loading cookbooks [chef-client] [Sun, 01 Jan 2012 23:46:33 -0500] INFO: Storing updated cookbooks/chef-client/recipes/default.rb in the cache. [Sun, 01 Jan 2012 23:46:33 -0500] INFO: Storing updated cookbooks/chef-client/recipes/delete_validation.rb in the cache. [Sun, 01 Jan 2012 23:46:33 -0500] INFO: Storing updated cookbooks/chef-client/recipes/service.rb in the cache. [Sun, 01 Jan 2012 23:46:33 -0500] INFO: Storing updated cookbooks/chef-client/recipes/config.rb in the cache. [Sun, 01 Jan 2012 23:46:33 -0500] INFO: Storing updated cookbooks/chef-client/attributes/default.rb in the cache. [Sun, 01 Jan 2012 23:46:34 -0500] INFO: Storing updated cookbooks/chef-client/metadata.json in the cache. [Sun, 01 Jan 2012 23:46:34 -0500] INFO: Storing updated cookbooks/chef-client/README.md in the cache. [Sun, 01 Jan 2012 23:46:35 -0500] INFO: Storing updated cookbooks/chef-client/metadata.rb in the cache. [Sun, 01 Jan 2012 23:46:35 -0500] INFO: Processing directory[/var/run] action create (chef-client::service line 42) [Sun, 01 Jan 2012 23:46:35 -0500] INFO: Processing directory[/var/chef/cache] action create (chef-client::service line 42) [Sun, 01 Jan 2012 23:46:35 -0500] INFO: Processing directory[/var/chef/backup] action create (chef-client::service line 42) [Sun, 01 Jan 2012 23:46:35 -0500] INFO: Processing directory[/var/log/chef] action create (chef-client::service line 42) [Sun, 01 Jan 2012 23:46:35 -0500] INFO: Processing directory[/etc/rc.conf.d] action create (chef-client::service line 203) [Sun, 01 Jan 2012 23:46:35 -0500] INFO: Processing template[/etc/rc.d/chef-client] action create (chef-client::service line 209) [Sun, 01 Jan 2012 23:46:35 -0500] INFO: Processing template[/etc/rc.conf.d/chef] action create (chef-client::service line 216) [Sun, 01 Jan 2012 23:46:35 -0500] INFO: Processing service[chef-client] action restart (chef-client::service line 222) [Sun, 01 Jan 2012 23:46:36 -0500] ERROR: service[chef-client] (chef-client::service line 222) has had an error [Sun, 01 Jan 2012 23:46:36 -0500] ERROR: service[chef-client] (/var/chef/cache/cookbooks/chef-client/recipes/service.rb:222:in `from_file') had an error: service[chef-client] (chef-client::service line 222) had an error: Chef::Exceptions::Exec: /etc/rc.d/chef-client stop returned 1, expected 0 /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/mixin/command.rb:127:in `handle_command_failures' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/mixin/command.rb:74:in `run_command' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/provider/service/init.rb:45:in `stop_service' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/provider/service/init.rb:55:in `restart_service' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/provider/service.rb:78:in `action_restart' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/resource.rb:440:in `run_action' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/runner.rb:45:in `run_action' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/runner.rb:81:in `block (2 levels) in converge' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/runner.rb:81:in `each' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/runner.rb:81:in `block in converge' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/resource_collection.rb:94:in `block in execute_each_resource' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/resource_collection/stepable_iterator.rb:116:in `call' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/resource_collection/stepable_iterator.rb:116:in `call_iterator_block' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/resource_collection/stepable_iterator.rb:85:in `step' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/resource_collection/stepable_iterator.rb:104:in `iterate' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/resource_collection/stepable_iterator.rb:55:in `each_with_index' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/resource_collection.rb:92:in `execute_each_resource' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/runner.rb:76:in `converge' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/client.rb:312:in `converge' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/client.rb:160:in `run' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/application/client.rb:239:in `block in run_application' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/application/client.rb:229:in `loop' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/application/client.rb:229:in `run_application' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/lib/chef/application.rb:67:in `run' /usr/local/lib/ruby/gems/1.9/gems/chef-0.10.8/bin/chef-client:26:in `' /usr/local/bin/chef-client:19:in `load' /usr/local/bin/chef-client:19:in `' [Sun, 01 Jan 2012 23:46:36 -0500] ERROR: Running exception handlers [Sun, 01 Jan 2012 23:46:36 -0500] FATAL: Saving node information to /var/chef/cache/failed-run-data.json [Sun, 01 Jan 2012 23:46:36 -0500] ERROR: Exception handlers complete [Sun, 01 Jan 2012 23:46:36 -0500] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out [Sun, 01 Jan 2012 23:46:36 -0500] FATAL: Chef::Exceptions::Exec: service[chef-client] (chef-client::service line 222) had an error: Chef::Exceptions::Exec: /etc/rc.d/chef-client stop returned 1, expected 0

Essentially, it couldn’t find the PID file in the expected location, which is no surprise, as I had been running chef-client manually without any arguments. Hopefully I can figure out a fix for that soon.

FreeBSD and chef-client – a part I?

As I mentioned before, Chef appears to work well on mostly Debian and Ubuntu. You will have to do a bit more work on the other OSes: In the case of FreeBSD, a lot more.

Here is one example: The recipe chef-client is used to install startup scripts on the nodes (rc scripts for Red Hat, upstart for Ubuntu, etc). it works on most OSes – except for BSD systems. In fact, in the code, when it noticed it is on a BSD systems, it puts out the following:

when "bsd"
  log "You specified service style 'bsd'. You will need to set up your rc.local file."
  log "Hint: chef-client -i #{node["chef_client"]["client_interval"]} -s #{node["chef_client"]["client_splay"]}"
  
else
  log "Could not determine service init style, manual intervention required to start up the chef-client service."
end

in other words, it doesn’t even bother.

I am not sure if it is out of laziness or just having limited resources that they didn’t create rc scripts for BSD (I could understand OpenBSD, but FreeBSD?), so I created the following rc script:

#!/bin/sh

# PROVIDE: chef
# REQUIRE: LOGIN
# KEYWORD: nojail shutdown

. /etc/rc.subr

name="chef"
rcvar=`set_rcvar`
stop_cmd="chef_stop"
command="/usr/local/bin/${name}-client"
command_args="-i -s -d -L /var/log/chef/client.log -c /etc/chef/client.rb -P /var/run/chef.pid"
load_rc_config $name
export rc_pid
chef_stop()
{
	pidfile="/var/run/chef.pid"
	rc_pid=`cat ${pidfile}`
        kill $rc_pid
}

run_rc_command "$1"

Ordinarily, I shouldn’t have to create a separate function to kill a chef process, but for some reason, the rc functions within FreeBSD can’t find the PID. 

Interestingly enough, during my debugging with the script, through the use of truss I found an undocumented feature where instead of adding the entry to enable a service in /etc/rc.conf, you can put it in /etc/rc.conf.d – which is what I did:

freebsd82# pwd
/etc/rc.d
freebsd82# cd ../rc.conf.d
freebsd82# ls
chef
freebsd82# cat chef
chef_enable="YES"

Apparently it came from NetBSD

With that, I got a working chef init script. Now to see if I can update the chef-client recipe and working on FreeBSD.

Link

verycrispy:

Recently, I have been googling how to make tunnels so I thought I would post what I do. A SSH tunnel allows you to connect to server, A, through server B, from client C.

You generally only want to setup a tunnel when you need to connect to server A but only have access to server B from your…

Always Crispy: SSH Tunnels – 2 ways

Installing Chef on CentOS

I have been playing around with Chef for the past week and while I liked it, it was a pain it setup. It seems to be work well if you run Debian and Ubuntu. Everything else … not so much.

First sign of trouble is when I attempt to bootstrap the install. The install calls for installing Ruby from the RBEL repo. Which I don’t have too much with trouble – in fact, they have binary RPMs of chef already available, so I used that initially and installed with:


yum install rubygem-chef-server --disablerepo=updates --disablerepo=CentOS-Custom --disablerepo=extras

(Centos-Custom is my own repo, by the way).

That went well – until it turns out that it installed Ruby 1.8 along with it.

So I got that removed. I spent the next few hours of trying (and failing) to install Ruby 1.9 while avoiding have to install 1.8. In the end, I gave up. Instead, what I did is the following:

  1. Installed the prerequisites  for ruby (including my build of Ruby 1.9 and Rubygems).
  2. Then, I ran “gem install ruby-shadow”, as there was no RPM for it in the CentOS repo.
  3. Then I installed the EPEL repo (instead of the RBEL repo). That allow to proceed with the install of chef with “gem install chef”. That, in turn, took care of all the requirements and package installation.

The next step is to configure a web proxy, as detail here. I decided to deviate slight and just use Red Hat’s utility with:

genkey chef.monzell.com

And then open the firewall ports.

However, because I had SELinux running, apache is not able to communicate to another application (as they are in different security context. So I had to enable access with:

setsebool -P httpd_can_network_connect on

That got me further, but I still had issues. After tailing the audit log and cat the output to audit2allow, I found that I still need to open a port in SELinux:

#============= httpd_t ==============

allow httpd_t reserved_port_t:tcp_socket name_bind;


I enabled access with:

[root@chef audit]# tail audit.log  | audit2allow -M chef444

******************** IMPORTANT ***********************

To make this policy package active, execute:

semodule -i chef444.pp

Installed the module and got the web access working.

There is more, but that’s for another post. 🙂

(as a side note, is there a tumbler theme that is code friendly – that is, I can paste in code and command line snippets without looking like snot?)

EDIT: Nevermind, looks like I’ll be poking around with CSS again to get it working the way I like.

FreeBSD and OpenLDAP Grief

Finally got my FreeBSD client to authenticate against my OpenLDAP server. 

The configuration is fairly straightforward. What took the time was compilation the dependencies (running it in a VM can do that to it). That and the following issues.

– It seems that Perl is not a requirement for a FreeBSD install. Not a big deal, (thinking about it, it make sense historically), but I needed to get the certs installed – which mean a install of Perl. Fun.

– ca-root no longer exists. Had to use ca-root-nss to build.

– After working with Red Hat for a while, manually setting up pam was pain.

– I couldn’t get pass pam_ldap almost all night and part of the afternoon, until I tailed /var/log/auth.log, which showed me this:

User rfoster not allowed because shell /bin/bash does not exist

Bash is not installed by default. Another compile. But afterwards, I was finally able to login.

From there, it was a matter of using amd to work so that I can automount the directories. Using this as a guideline, I setup the symlinks in /usr/home to the mounts:

ln -sf /host/kerberos.monzell.com/exports/users .

Then I add my ldap user to wheel group (so that I can become root):

freebsd82# pw groupmod wheel -m rfoster

freebsd82# pw groupshow wheel

wheel:*:0:rilindo,rfoster

freebsd82# 


And… I am done.

Next, configure SuSE Enterprise Linux 11 with LDAP authentication. 🙂

TLS problems with OpenLDAP Client

I ran into an interesting problem sometime back that I only now resolved.

Originally, I was running Scientific Linux on most of my VM. I have since upgraded most of them to Centos 6.0 – and converted on in particular to Centos CR. 

That “broke” my ldap authentication – when connecting to the server with the ldapuser credentials, sssd returns with the following:

Could not start TLS encryption. TLS error -8172:Unknown code ___f 20

At the time, I thought that there was a bug with the updated sssd package on Centos CR, so I ignored it for while – until I logged into a fairly new Scientific Linux 6.1 VM today – and it gave me the same message.

That was curious. So I dug deep into searching for a solution. 

As it turns out, the problem was my configuration. Apparently I had been connecting with a self-signed certificate, which the following:

[root@localhost ~]# openssl verify cacert.pem 

backup.cacert.pem: C = US, ST = Georgia, O = Monzell Management Systems, OU = IT, CN = example.com, emailAddress = rilindo.foster@example.com

error 18 at 0 depth lookup:self signed certificate

OK

It seems with the initial version of sssd with 6.0 , it was allowing me to connect without complaining about it being a self-sign cert. With the updated version, it is now refusing to connect without a valid certificate. I can confirm that by running:

>

ldapsearch -d -1 -vvvvv -w PASSWORD -ZZZ -H ldap://ldap.example.com -D "cn=root,dc=example,dc=com" "(uid=joeuser)"

<snip>

                                         ..                

TLS: certificate [CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL] is not valid - error -8172:Unknown code ___f 20.

tls_write: want=7, written=7

  0000:  15 03 01 00 02 02 30                               ......0           

TLS: error: connect - force handshake failure: errno 0 - moznss error -8172

TLS: can't connect: TLS error -8172:Unknown code ___f 20.

After I put in the correct certificate, I was able to connect:

<snip>

tls_read: want=48, got=48 0000: f0 85 60 72 54 c1 3b c8 6f 53 c4 f0 89 82 27 17 ..`rT.;.oS....'. 0010: 3c 3f 99 8f 18 64 22 ae 41 28 d4 a6 0b 0f a4 de <?...d".A(...... 0020: 36 10 3e d4 6c f5 73 fb cb 12 04 af 64 7f 14 69 6.>.l.s.....d..i TLS certificate verification: subject: E=webmaster@example.com,CN=kerberos.example.com, <REDACTED> ldap_sasl_bind ldap_send_initial_request ldap_send_server_request

<snip>


And openssl returned with no errors:
[root@localhost cacerts]# openssl verify cacert.pem cacert.pem: OK