mycroes

There's always time to play

Tuesday, April 2, 2013

Prevent Ubuntu (12.10+) modem-manager from keeping your Sheevaplug busy

As of Ubuntu 12.10 the very helpful modem-manager will try to connect to about any serial device. Unfortunately that means that when you connect a Marvell Sheevaplug it will connect to that as well, resulting in device or resource busy error when trying to open a screen session to your Sheevaplug. However, the solution is fairly easy, just add the following to /etc/udev/rules.d/70-mm-no-sheevaplug.rules:

ACTION!="add|change", GOTO="mm_usb_device_blacklist_end"
SUBSYSTEM!="usb", GOTO="mm_usb_device_blacklist_end"
ENV{DEVTYPE}!="usb_device",  GOTO="mm_usb_device_blacklist_end"

# Marvell Sheevaplug
ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", ENV{ID_MM_DEVICE_IGNORE}="1"

LABEL="mm_usb_device_blacklist_end"

Now do a simple sudo service udev reload, and enjoy your screen sessions with the Sheevaplug again!

Thursday, March 28, 2013

Setting up NTP signing (ntp_signd) with Samba 4 (in other words: providing time to Windows clients)

In an Active Directory domain, the focus usually is on Windows clients. One key aspect in an Active Directory domain is time synchronization. If you're here you probably know something about NTP, and maybe even that Windows won't just use the NTP server you specify using DHCP. The reason is that Windows wants a NTP server that provides signed NTP responses. ntpd actually supports providing these signed responses, but in order to do so it requires a signing provider. Samba 4 can provide this, by way of a socket specifically made for this purpose.

This post continues where I left off with Install Samba 4(.0.4) on Ubuntu 12.04 LTS, from source. It assumes Samba is already working properly, and that the ntp_signd task/service is enabled (which is by default). If you didn't install ntpd yet, do it with the following command:

$ sudo apt-get install ntp

The socket that is used for signing responses resides at /usr/local/samba/var/lib/ntp_signd/socket. The permissions on the socket should indicate that it's world writable, the permissions on the ntp_signd directory however only allow root (as user) full read/write and root (as group) read access. In order to allow ntpd to write to the socket it's necessary to grant it permissions on the ntp_signd directory, which we can do as follows:

$ sudo chgrp ntp /usr/local/samba/var/lib/ntp_signd

There's no need to change permissions of the socket file, if ntp can access it, it can write to it as well (remember, it's world writable).

There is an issue one might easily overlook. By default Ubuntu comes with apparmor enabled, which will prevent some programs from accessing files they normally shouldn't access. One of the programs that is actually configured to be restricted by apparmor, is ntp. Because Ubuntu by default doesn't know about our source-compiled Samba 4 installation, it also doesn't know about the ntp_signd socket. The fix for this is to edit /etc/apparmor.d/local/usr.sbin.ntpd:

# Site-specific additions and overrides for usr.sbin.ntpd.
# For more details, please see /etc/apparmor.d/local/README.
/usr/local/samba/var/lib/ntp_signd/socket rw,

Last but not least we need to configure ntpd so it knows that it is allowed to do signed responses and how it should sign them. This requires the addition of the following lines to /etc/ntp.conf (rest of file omitted for brevity):

ntpsigndsocket /usr/local/samba/var/lib/ntp_signd
restrict default mssntp

Now restart ntpd:

$ sudo service ntp restart

That should be it, but beware! ntpd needs some time to establish a reliable time for itself. Before it has established a reliable time it's useless. You can check if it has established time by running the following command:

$ ntpdate -q localhost
server 127.0.0.1, stratum 3, offset -0.000004, delay 0.02563
28 Mar 22:03:29 ntpdate[15015]: adjust time server 127.0.0.1 offset -0.000004 sec

In the output above it shows stratum 3, if it shows a higher number I guess you can forget requesting time from the server. In my case it will start at 16 and jump back to 3, at which point it has established a reliable time for itself.

At this point you can test with a Windows client. Just open a command prompt and type the following:

C:\>w32tm /resync
Sending resync command to local computer...
The command completed successfully.

C:\>

And that's it! If it doesn't work out this well for you, then I'd suggest you start by running ntpd in debug mode, which will at least show when it's receiving requests from clients:

$ sudo service ntp stop
$ sudo ntpd -d

If it doesn't work, or you want to thank me for the instructions, use the comments!

Friday, March 22, 2013

Install Samba 4(.0.4) on Ubuntu 12.04 LTS, from source

At the office we've been running Samba 4 for quite a while already. However, the version(s) in use date back to what was found in Ubuntu releases available at install time. The Samba team has actually done a great job at releasing a stable version for Samba 4, but I haven't seen anyone offering prebuilt packages for Ubuntu.

Recently I have been wondering if it would be a good idea to build Samba 4 from source instead. I don't like this approach much, because I prefer having all packages handled by the package manager. Then again, /usr/local/ doesn't need to stay empty, and my domain controllers are just that; domain controllers.

So yesterday I did my first attempt at building Samba from source, which went so well that I did it again today, on a fresh new Ubuntu 12.04 LTS install. I actually switched it to the IP of the primary DC as well, and stopped the old primary DC because the new one was working without any issues at all.

Now onto the actual instructions (assumes a clean 12.04 LTS basic Ubuntu server install):

$ mkdir src
$ cd src

$ wget http://ftp.samba.org/pub/samba/samba-4.0.4.tar.gz
$ tar xf samba-4.0.4.tar.gz
$ cd samba-4.0.4

$ sudo apt-get install build-essential pkg-config libkrb5-dev libacl1-dev \
libattr1-dev python2.7-dev libpam0g-dev libldap2-dev

$ ./configure && make

$ sudo make install

I've omitted all of the output, since the process was so easy. The description is easy as well:

  1. Make a directory to store the samba source in
  2. Download the Samba 4.0.4 source file
  3. Extract it
  4. Install build utilities, Samba dependencies
  5. Configure and build Samba
  6. Install Samba into /usr/local/samba

After these steps you can either follow the Samba 4 documentation to provision a new domain or join a domain, or copy the necessary files from your old domain controller onto this one if you're replacing your domain controller.

There is one important final step, and that's to create an init file. On the Samba 4 InitScript page there's a script listed that will work just fine, I copied it here for reference:

description "SMB/CIFS File and Active Directory Server"
author      "Jelmer Vernooij "
start on (local-filesystems and net-device-up)
stop on runlevel [!2345]
expect fork
normal exit 0
pre-start script
 [ -r /etc/default/samba4 ] && . /etc/default/samba4
 install -o root -g root -m 755 -d /var/run/samba
 install -o root -g root -m 755 -d /var/log/samba
end script
exec /usr/local/samba/sbin/samba -D

Copy this file to /etc/init/samba4.conf and you can use service samba4 start to start Samba 4.

All of these steps will probably apply to Ubuntu 12.10 as well, but I haven't verified yet. Also, since Samba 4 doesn't require anything that's not in Ubuntu 12.04 LTS, it might be wise to stick to this release until another LTS is released.

Please share any thoughts using the comments!

Friday, September 14, 2012

Provisioning HP printers

At the office we recently added another printer and since we mostly use HP printers I was looking for some way to ease configuration. Although HP network printers usually have telnet available, there is an easier way to supply a default configuration to all your printers, which will also serve as a single source for configuration setting updates. HP printers support getting a configuration file using TFTP. Telling the printer what file it should get is a matter of properly configuring DHCP. The following excerpt from my dhcpd.conf shows configuration for a single device:
host sales.print.domain.tld {
    hardware ethernet 00:11:22:33:44:55;
    option extensions-path "hp.conf";
}
You can combine this with other statements to provide a hostname to the printer as well and to give the printer a fixed IP or registering it's name in DNS. Although (some) HP printers should support a different server address for the TFTP server, I haven't been able to get that working, so I just set up tftpd-hpa on my DHCP-server. The contents of the configuration file are really simple, you can set the same settings as you can set using telnet, and there's an export command in the telnet service that will output the current settings in a way that it can be used as a configuration file. But here's a short example that shows how to disable some services:
slp-config      0
bonjour-config  0
ipx-config      0
appletalk       0
I used tabs for seperation of keys and values, but it should work with spaces as well. Just run export on your device to get a complete overview of all the settings to change. Now when your next new printer arrives, it's just a matter of adding the host to DHCP and you're done.

Tuesday, September 4, 2012

Run backup job with specified pool in Bacula

Unfortunately the run command in Bacula only has a few options, so it's not possible to actually pass a pool to the run command right away. However, there's a decent alternative, by performing the mod action automatically. The only thing to do is to find the menu entry for the pool you want:
$ echo -e "run job=Mack level=Full\nmod\n8\n." | sudo bconsole
Connecting to Director localhost:9101
1000 OK: mijlweg-dir Version: 5.0.3 (04 August 2010)
Enter a period to cancel a command.
run job=Mack level=Full
Using Catalog "MyCatalog"
Run Backup job
JobName:  Mack
Level:    Full
Client:   mijlweg-fd
FileSet:  Mack
Pool:     Default (From Job resource)
Storage:  LTO-5 (From Job resource)
When:     2012-09-04 22:14:04
Priority: 10
OK to run? (yes/mod/no): mod
Parameters to modify:
     1: Level
     2: Storage
     3: Job
     4: FileSet
     5: Client
     6: When
     7: Priority
     8: Pool
     9: Plugin Options
Select parameter to modify (1-9): 8
The defined Pool resources are:
     1: Default
     2: Monthly
     3: Ghost
Select Pool resource (1-3): .
Selection aborted, nothing done.
Job not run.
$ 
Don't assume the numbers here are equal to what you have, but actually run this command with a valid job identifier (I used Mack in the example). After that, make a small change to command to run the backup job:
$ echo -e "run job=Mack level=Full\nmod\n8\n2\nyes" | sudo bconsole
Connecting to Director localhost:9101
1000 OK: mijlweg-dir Version: 5.0.3 (04 August 2010)
Enter a period to cancel a command.
run job=Mack level=Full
Using Catalog "MyCatalog"
Run Backup job
JobName:  Mack
Level:    Full
Client:   mijlweg-fd
FileSet:  Mack
Pool:     Default (From Job resource)
Storage:  LTO-5 (From Job resource)
When:     2012-09-04 22:20:29
Priority: 10
OK to run? (yes/mod/no): mod
Parameters to modify:
     1: Level
     2: Storage
     3: Job
     4: FileSet
     5: Client
     6: When
     7: Priority
     8: Pool
     9: Plugin Options
Select parameter to modify (1-9): 8
The defined Pool resources are:
     1: Default
     2: Monthly
     3: Ghost
Select Pool resource (1-3): 2
Run Backup job
JobName:  Mack
Level:    Full
Client:   mijlweg-fd
FileSet:  Mack
Pool:     Monthly (From User input)
Storage:  LTO-5 (From Job resource)
When:     2012-09-04 22:20:29
Priority: 10
OK to run? (yes/mod/no): yes
Job queued. JobId=12660
$ 
And there you go, backup running with specified pool!

Saturday, April 21, 2012

When security matters ...

... password restrictions are retarded. When I wanted to activate an online account for my creditcard I entered the same secure password I always use, but guess what, it was not accepted. The password restrictions are as follows:
Het door u gekozen wachtwoord voldoet niet aan de eisen. Uw wachtwoord moet bestaan uit minimaal één cijfer en vijf letters. De maximale lengte is tien cijfers en/of letters. Leestekens en symbolen zoals !@#$%&^*_ worden niet herkend. Let op: uw wachtwoord is hoofdlettergevoelig.
... in English:
The chosen password does not meet our requirements. Your password has to contain at least one digit and five characters. The maximum length is ten digits and/or characters. Punctuation marks and symbols such as !@#$%&^*_ are not recognized. Attention: your password is case sensitive.
Seriously? Please International Card Services, get your stuff together and stop the retarded password restrictions and accept secure passwords for a change...

Friday, February 10, 2012

Linux integration with Active Directory: part 1

At work I've been running Samba 4 for quite a while. Because Samba 4 is still in Alpha I didn't just move everything over to use Samba 4 for authentication, but instead I started out by moving services over one by one. I actually started with e-mail routing (will detail in a later post) and authentication. Later on I added proxy authentication and fileserver authentication / authorization, Windows XP and Windows 7 clients and last but not least actual Linux (PAM) user authentication.

In this post I will detail how to join a (Debian / Ubuntu) Linux machine to the domain, setup Kerberos, setup nss to make Linux aware of domain users and setting up PAM to allow domain user authentication. I'm using Samba 4 as Active Directory implementation, however this should all just work against a Windows server hosted Active Directory as well. I'm going to make use of a feature that requires Windows Server 2003R2 or newer, or IDMU (Identity Management for Unix), but that's only used to store the users' shell in Active Directory.

First off, I'm assuming that DNS is properly set up. It's not needed, since both Kerberos and Samba can be made to work without DNS, but best case that means a lot of hosts file mess on almost all involved computers. Honestly it's easier to even do a manual DNS setup than to keep such a hosts file mess up to date. I will detail some parts for the non-DNS case as well, since it's useful information.

Setting up Kerberos


Now on to the real work. Setting up Kerberos is really easy:
# apt-get install krb5-config

This should probably ask just one question: the default Kerberos realm. This normally is the uppercase Active Directory domain name. If you don't have DNS setup it will also ask two more questions:
  • The kerberos servers
  • The kerberos admin servers

These are the Active Directory Domain Controllers (although Samba 4 doesn't provide the kadmin interface right now). You probably need to add these to your hosts file as well.

If you actually want to check if it's working, you should probably install krb5-user as well and try to do a kinit to acquire a Kerberos ticket, but if you've done a few servers you'll probably believe me when I tell you you don't need krb5-user for Kerberos support.

Joining the domain


Now it's time to join the Linux machine to the domain (since Kerberos is working). We start by installing winbind:
# apt-get install winbind
# /etc/init.d/winbind stop

We don't need an active winbind instance around, so let's stop it right away. If smbd or nmbd are running stop those as well.

Now continue by editing /etc/samba/smb.conf to contain all of the required configuration for Active Directory support:
[global]
netbios name = yourhostname
server string = your host description

realm = YOUR.REALM
workgroup = YOURWORKGROUP
security = ADS
local master = no
preferred master = no
dns proxy = no

# set password server if you don't have functional DNS
#password server = dc.domain.tld

encrypt passwords = true
# setting kerberos method = system keytab prevents pam_winbind from
# authenticating users for me, but the following does work
kerberos method = secrets and keytab

# Using winbind default domain = yes makes usernames work without domain part
winbind use default domain = yes
winbind enum groups = yes
winbind enum users = yes
# winbind nss info = rfc2307 makes winbind use posix attributes from AD
winbind nss info = rfc2307

# map untrusted to domain = yes allows any user to be mapped to the domain user
# with the same username, but also prevents local samba accounts from being used
map untrusted to domain = no

# template homedir can be used to designate the location of users' home
# directories
template homedir = /home/%U
# template shell defines the default shell for when none is set in the posix
# loginShell attribute for a user. Setting this to /bin/false allows login only
# for those users that have this attribute set. pam_winbind also has an option
# to limit access to several groups only, which is actually a real security
# measure unlike this attribute which might be changed by users
template shell = /bin/false

# The first two idmap lines are for the domain, the other two for local samba
# accounts. Using the rid backend maps the ids to the end of the user's SID,
# which makes consistent id mapping across servers possible.
idmap config yourworkgroup : backend = rid
idmap config yourworkgroup : range = 10000 - 49999
idmap uid = 50000 - 100000
idmap gid = 50000 - 100000
Replace all the fields in bold with values applicable to your domain.

Now it's time to join the domain:
# net join -UAdministrator
Enter Administrator's password:
Using short domain name -- YOURDOM
Joined 'YOURHOST' to realm 'your.domain'
[2012/02/10 21:15:35, 0] libads/kerberos.c:333(ads_kinit_password)
kerberos_kinit_password YOURHOST$@YOUR.REALM failed: Client not found in Kerberos database
DNS update failed!
# /etc/init.d/winbind start
* Starting the Winbind daemon winbind [ OK ]
#

If DNS is not properly set up, use net join -UAdministrator -Sdc.yourdom, this tells net what server it should use for the join.

As far as I know these errors are nothing to be concerned about, but the DNS update failed means that net/Samba wasn't able to register the host in DNS. If you have DDNS updates from a DHCP server or there's already a static entry for the server in DNS then you don't need to worry at all. Now try wbinfo -u and see if the Active Directory users show up.

Setting up nss


Setting up nss is another easy step, we just need to add two references to winbind, for both passwd and group. Edit /etc/nsswitch.conf and change the passwd and group lines:
...
passwd: compat winbind
group: compat winbind
...

Verify with getent passwd that all the domain users are listed and their home directories make sense. Now would be a good time to change the loginShell attribute for your user, because as you can see it now is /bin/false for all users.

Setting up PAM


Now that the users actually 'exist' on the machine, let's enable authentication for them as well (if your package manager hasn't already done that for you):
# pam-auth-update
...
Some PAM module packages provide profiles that can be used to
automatically adjust the behavior of all PAM-using applications on the
system. Please indicate which of these behaviors you wish to enable.

PAM profiles to enable:

[*] Unix authentication
[*] Winbind NT/Active Directory authentication
...


Now let's logon to the server from another computer:
$ ssh user@yourhost
user@yourhost's password:
...
Could not chdir to home directory /home/user: No such file or directory
user@yourhost:/$

That's not good is it? Well, it is, but let's make it better, but first...

It doesn't work!


Oh well, bad things can happen. It should work, it works for me on multiple machines, both freshly installed and some older installations, both latest and long-term Ubuntu releases and different Debian releases. But it doesn't work for you... There's a few places you can check right now, one is /var/log/auth.log. However, this might not be the most useful log file in case of authentication failures against Active Directory. A good help though is to start winbind in debug mode:
# winbindd -d 3 -i

This will list a lot of debug information. Look at the messages that occur during a login attempt, it helped me to discover that I needed to use kerberos method = secrets and keytab in smb.conf. It wasn't saying so directly, and don't expect it to tell you the solution to all your problems, but the error messages can be informative...

Finishing touches


Now to continue where we left off, apparently we don't have a home directory on the server yet. This makes sense, and there's a proper solution. We just need to tell pam to use a module that will make a home directory for a user logging in. Let's do so by adding one line to the end of /etc/pam.d/common-account:
session required pam_mkhomedir.so umask=0077 skel=/etc/skel
You can change the umask, but 0077 means that the directory is owned by the user and that group and other have no permissions at all. Now if we login we end up in our newly created home directory.

Next up is sudo. There's a possibility you want to grant sudo rights to someone in your domain, for instance to the Domain Admins group. Of course this is not any different from granting permissions to a local group, I'm detailing it here for a more complete solution. Edit /etc/sudoers in your favorite editor and add the following line:
%domain\ admins ALL=(ALL) ALL

The backslash is just used to escape the space in the group name, otherwise this is no different than any other sudoers entry.

We've come a long way from where we started, but there's still room for improvement. We enabled login using Active Directory credentials, but what if we already logged in somewhere else? In Windows SSO (Single SignOn) works out of the box, but let's add it to our Linux machine(s) as well. What we need for SSO is Kerberos, and since we just set that up we can use it for other services as well. For now I'll only discuss on setting this up for OpenSSH. In /etc/ssh/sshd_config there are two commented lines that we need to change and uncomment so they look like this:
...
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
...

Don't be fooled by the Kerberos lines, they're not needed for Single SignOn. Now restart SSH:
# /etc/init.d/ssh restart
Rather than invoking init scripts through /etc/init.d, use the service(8)
utility, e.g. service ssh restart

Since the script you are attempting to invoke has been converted to an
Upstart job, you may also use the restart(8) utility, e.g. restart ssh
ssh start/running, process 32441

Now back to the other computer to do a ssh login and see if you can log in without having to supply a password. If it doesn't work, try the following command:
$ ssh -vvv -o PreferredAuthentications=gssapi-with-mic user@yourhost

This will show a lot of debug messages, probably with a descriptive error message near the end. One thing to keep in mind is that the client needs to know the Kerberos principal for the host it's connecting to. This is because with Kerberos, the client is also verifying that the server is actually (according to Kerberos) who it's trying to connect to. The way ssh determines the principal is by using the HostKeyAlias, which defaults to the host you're connecting to. However, it's easy to cheat if there's no working dns by supplying -o HostKeyAlias=yourhost on the ssh commandline.

We can make this even better than it is right now. You might have noticed that if you're logging in using password authentication that you actually get a Kerberos ticket, pam_winbind makes sure this happens. But now that we log in using Kerberos authentication, we don't get a ticket. Seems strange, but it's not. Ssh has decided to turn credential delegation off by default, but we can turn it on again. To do this on a per-user basis you can edit ~/.ssh/config and add the following line:
GSSAPIDelegateCredentials yes
Now if you logon to the machine using Kerberos your ticket is delegated and you can use it to ssh to other computers as well.

Final notes


You should now have a quite-well-integrated Linux machine. In future parts I will discuss mail routing and authentication and proxy server authentication and authorization. This post might be expanded to include some topics that were missing at first, I will try to keep an update list in here as well.