Unattended Package Installation with Debian and Ubuntu 1

Posted by Adam Jacob Fri, 27 Jul 2007 14:05:00 GMT

Apt is a wonderful tool, but it does have its quirks. One of those is that it likes to ask you interactive questions during package installation. This makes total sense when a human is doing apt-get install foobar, but it causes all sorts of consternation when you want to automatically install packages. (You do this all the time with Puppet, which I’ll talk more about at the end of this post.)

The answer to this problem is to pre-seed debconf with the correct answers to it’s questions. To do this, first you need to install the package by hand:

$ apt-get install libnss-ldap

You’ll need to provide answers to the questions it asks, which we’re going to re-use later as the basis for our seed file. Next, make sure you have debconf-utils installed, and grab the answers to your questions:

$ apt-get install debconf-utils # Only if you need it
$ debconf-get-selections | grep libnss-ldap
libnss-ldap     libnss-ldap/rootbindpw  password
libnss-ldap     libnss-ldap/bindpw      password
libnss-ldap     libnss-ldap/dblogin     boolean false
# Automatically update libnss-ldap's configuration file?
libnss-ldap     libnss-ldap/override    boolean false
libnss-ldap     shared/ldapns/base-dn   string   dc=example,dc=com
libnss-ldap     libnss-ldap/rootbinddn  string   cn=admin,dc=example,dc=com
libnss-ldap     shared/ldapns/ldap_version      select   3
libnss-ldap     libnss-ldap/binddn      string   cn=proxyuser,dc=example,dc=net
libnss-ldap     shared/ldapns/ldap-server       string   ldapi:///
libnss-ldap     libnss-ldap/nsswitch    note
libnss-ldap     libnss-ldap/confperm    boolean false
libnss-ldap     libnss-ldap/dbrootlogin boolean true

Take the output of that and stick it in a file, say libnss-ldap.seed. You can now use that file to pre-seed a new system with those answers using debconf-set-selections:

$ debconf-get-selections | grep libnss-ldap > /tmp/libnss-ldap.seed
$ debconf-set-selections /tmp/libnss-ldap.seed

Or use ssh to pre-seed a new box:

$ cat /tmp/libnss-ldap.seed | ssh somehost debconf-set-selections

If you are using Puppet (and if you’re not, you should be) to manage your systems, you can use a recipe like this to automatically install packages that require interaction:

define seed_package($ensure = latest) {
  $seedpath = "/var/cache/local/preseeding" 
  file { "$seedpath/$name.seed":
    source => "puppet://$puppet_server/seeds/$lsbdistcodename/$name.seed",
    mode => 0600,
    owner => root,
    group => root
  package { $name:
    ensure => $ensure,
    responsefile => "$seedpath/$name.seed",
    require => File["$seedpath/$name.seed"],

class foobar {
  seed_package { "libnss-ldap":
    ensure => latest

Some other resources on ways to use pre-seeding to great effect:

Happy unattended package installation! :)

Using runit with Upstart

Posted by Adam Jacob Fri, 20 Jul 2007 19:52:00 GMT

When using runit with Upstart in Ubuntu 7.04, you’re going to run in to a couple of problems. The first is that the package doesn’t install cleanly without the presence of /etc/inittab, which Upstart doesn’t need. You can fix that with a simple:

$ sudo touch /etc/inittab

Now, you need to actually add runit to Upstart. You do this by putting the following in /etc/event.d/runsvdir:

start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on shutdown
exec /usr/sbin/runsvdir-start

This will cause runsvdir-start to run during runlevel 2, 3, 4, and 5, stop when the system is going to be shutdown, and respawn if it goes away.

If you are on Ubuntu 6.10, the syntax is a bit different:

start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on shutdown
respawn /usr/sbin/runsvdir-start

Catalyst Deployment with Apache 2 and mod_fcgid

Posted by Adam Jacob Thu, 19 Jul 2007 18:38:00 GMT

Catalyst has long had FastCGI support built in, but all of the recipes are for the much older mod_fastcgi. As a Debian user, and fan of software that’s still maintained, I prefer mod_fcgid.

What follows is a simple Apache 2 virtual host for a Catalyst application, using mod_fcgid:

<VirtualHost *:80>
    ServerName www.example.com
    ServerAlias example.com
    ErrorLog logs/www.example.com.error_log
    TransferLog logs/www.example.com.access_log

    # This should point at your myapp/root
    DocumentRoot /srv/myapp/root
    Alias /static /srv/myapp/root/static

    <Location /static>
        SetHandler default-handler

    Alias / /srv/myapp/script/myapp_fastcgi.pl/

    <Location />
        Options ExecCGI
        Order allow,deny
        Allow from all
        AddHandler fcgid-script .pl

Six Steps to Automated User Access Control for Windows 3

Posted by Adam Jacob Thu, 19 Jul 2007 04:08:00 GMT

The problem we are trying to solve is allowing select groups of users to both:

A) Log In to a Windows Server via Terminal Services as a regular user.

B) Log In to a Windows Server via Terminal Services as a local administrator.

The process should be completely automated once it is in place, so that the only requirements are that Computers be put in the proper OU, and new Users added to the appropriate groups.

The entire mechanism can be implemented with only Windows Group Policy. Here’s how.

Step -1. Make sure your domain is at the right Domain Functional Level

In order to get the nested group functionality to work, the Domain must be in Windows 2000 Native mode or above. You can set this by doing:

  1. Start -> Administrative Tools -> Active Directory Domains and Trusts
  2. Right click on your Domain, and select “Raise Domain Functional Level”

Assuming you only have Windows 2003 domain controllers, go ahead and set it at Windows 2003. It needs to be at least Windows 2000 Native.

Step 0. Create a more useful MMC Snap In.

The default snap-in’s for Windows make things difficult for handling Group Policy, since you so often need to move back and forth between the group policy itself and Active Directory. So our first step is to create a consolidated MMC view, so we can do both in one window.

  1. Start -> Run -> mmc
  2. File -> Add/Remove Snap-in
  3. Click “Add”
  4. Select “Active Directory Users and Computers”, click “Add”
  5. Select “Group Poloci Management”, click “Add”
  6. Click “Close”, then click “OK”
  7. Expand the “Console Root” mini-window.
  8. Select “File” -> “Save”, Click your Desktop, and call it GPMCAD

Now, any time you want to play with Group Policy, you can just double click the GPMCAD.msc on your desktop.

Step 1. Create the Computer OUs

Each class of machine (“Webserver”, “Database”) needs to have it’s own OU, which we will use for setting the proper Group Policy.

  1. Expand “Active Directory Users and Computers”
  2. Expand your Forest, and Navigate to the place you want to create new computer OUs. (“sea/computers” in our example)
  3. Create a new OU for a class of machines. Right click on the parent container, select “New”, then “Organizational Unit”. Give it a name (“Webservers”,) then click “OK”.
  4. Now, right click on the computers you want to have populate this OU, and select “Move”. Navigate to the new OU, and click “OK”.

Step 2. Create the User Groups

For each class of machine, we’ll create two groups: one for Administrators, and one for regular Users.

  1. Go to the OU where you want the groups located (“sea/groups” in our example.)
  2. Right click on the OU, select “New”, then “Group”
  3. In group name, put “Webserver Users”. (Where “Webservers” is our example group name; yours should match whatever the Computer OU you created before was.)
  4. Under “Group Scope”, select “Universal”, and click “OK”
  5. Right click on your new group, and select “Properties”
  6. Click the “Members” tab, click “Add”, and type in the users you want to have non-administrator access to this host. When you’re done, click “OK”. (How to use this dialog is beyond the scope of this document, I think. ;)
  7. Once you have all the users, click “OK”.

Now, repeat these steps, but call the group “Webserver Admins”, and ensure you only populate it with the users who should have Administrator privileges on this host.

Step 3. Create the new Group Policy

Now that we have our systems in a new OU, and our Authentication groups created, we need to create the group policy to apply our settings.

  1. In the MMC, open “Group Policy Management” -> “Forest: yourdom.com” -> Domains -> “yourdom.com”. This will reflect the root of the Active Directory tree we were working with in Step 2.
  2. Navigate to the Computer OU we created, right click, and select “Create and Link a GPO Here…”
  3. Give it a name like “Webserver Permissions”.
  4. Expand the OU we just right clicked on, exposing your new GPO. Right click on it, and select “Edit”.

Step 4. Edit the new Group Policy.

You should have just popped up the “Group Policy Object Editor.” First, lets set some limits on who can log in via the Console and Terminal Services.

  1. Navigate to “Computer Configuration” -> “Windows Settings” -> “Security Settings” -> “Local Policies” -> “User Rights Assignment”.
  2. Double click on “Allow log on locally”. Click “Define these policy settings”.
  3. Click “Add User or Group”. Type “Administrators”, adding the local Administrators group.
  4. Click “Add User or Group”. Hit “Browse”, and add “Domain Admins”, “Webserver Admins,” and “Webserver Users”. Click “OK”.
  5. Now, click “OK” again to close this policy.

Repeat the above steps, but this time, double click on “Allow log on through Terminal Services.”

Now, you need to populate the local Administrators and Remote Desktop Users groups.

  1. Navigate to “Computer Configuration” -> “Security Settings” -> “Restricted Groups”. Right click on “Restricted Groups”, and select “Add Group”.
  2. Click “Browse”, and find your new “Webserver Admins” group, and click “OK.”
  3. Click the “Add…” button next to “This group is a member of:”, and type “Administrators”. Click “OK”
  4. Click “OK” to close the dialog.

Now, repeat the above, but for the “Webserver Users” group. When the time comes to set what group it should be a member of, make it “Remote Desktop Users”.

Close the Group Policy Object Editor dialog.

Step 5. Refresh the Group Policy on the clients, and test.

Depending on how often your Group Policy refreshes, you may have to wait a while. You can force the issue by running gpupdate /FORCE on the computers you want to update. Do that now, so we can make sure everything is working.

Now, try terminal serving as a User who is a member of the “Webserver Users” group. You should have access, but not Administrative privileges.

Next, try and log in as a member of the “Webserver Admins” group. You should have full administrative rights to the host.

Now it’s a Domain Administrators turn. Again, they should have full Administrative access.

Finally, try and log in as a user who isn’t in any of the above groups. You should get the “To log on to this remote computer..” speech.

Step 6. Rinse and Repeat.

For each class of systems you want to manage, repeat the above process. When you are done, you should have a super easy to manage domain structure, and getting the access privileges right for new hosts is as easy as moving them to the right place in Active Directory.