Recently I was trying to do a regular and simple task for a maintenance: extending a LVM partition. But when using the lvextend on that certain logical volume I was greeted with an error:


” Insufficient suitable contiguous allocatable extents for logical volume ”

That was pretty odd, I had recently resized other partitions on that very server and there was nothing “unusual” about its setup: hardware raid, one volume group occupying the entire array and all the logical volumes in that volume group. Googled a bit, but nothing relevant. Then I did what I should have done in the first place: ran the command lvscan to show me some details about the logical volumes.

I noticed that the partition I wanted to extend was different from the others: it had as allocation policy ” contiguous ” instead of ” inherit ” like all the others. The manual for LVM ( man 8 lvm ) provides us with all the answers:

” The default for a logical volume is inherit which applies the same policy as for the volume group. ”
” The contiguous policy requires that new extents be placed adjacent to existing extents. ”

So my partition could be extended just by using free space on the drive that was next to it. And there wasn’t any because there were other partitions created after it. Someone had created – for unknown and illogical reasons in our case – the partition with a ” contiguous ” allocation policy.

So this was an easy fix: lvchange –alloc inherit [lv]

Then I could extend my partition easily. The moral of the story: be careful when creating LVM partitions and volume groups to assign them their allocation policy in line with your needs and setup.

Apt Pinning in Debian

| November 25th, 2009

Ever wanted to run certain packages from one version of the operating system ( in this case Debian ) without having to upgrade (or downgrade) the entire system ?

Well, the “Pin” option in the Apt package management system lets you do that. It’s pretty simple too!

1. Add the repositories for the two versions you want to have packages from in /etc/apt/sources.list . In this example we have Debian Stable and Testing:


    #Stable
    deb http://ftp.us.debian.org/debian stable main non-free contrib
    deb http://non-us.debian.org/debian-non-US stable/non-US main contrib non-free

    #Testing
    deb http://ftp.us.debian.org/debian testing main non-free contrib
    deb http://non-us.debian.org/debian-non-US testing/non-US main contrib non-free

Run apt-get update to add the repositories to apt.

2. Next, modify the file /etc/apt/preferences. This is where the actual “pinning” takes place. By default, apt installs the highest version available. So let’s say we would have the two repositories and we would like to install the package “dovecot-common”. Apt will take the highest version of that package which is naturally available in the “Testing” repository. But say we wanted to run the older of version of “dovecot-common” (for our own reasons, doesn’t matter why), which is available in the “Stable” repository. We would have this in our /etc/apt/preferences file:


    Package: dovecot-common
    Pin: release a=stable
    Pin-Priority: 700

    Package: dovecot-common
    Pin: release a=testing
    Pin-Priority: 600

Notice that we have a higher priority number for “dovecot-common” in the “stable” release. In Apt, the package with the highest priority wins, no matter the package version.

So now that you know this, you can use it to mix-match between packages from different repositories, while using strictly apt, no forcing of install and keeping them updated (if a newer version appears in that repository, apt will install it).

We have recently upgraded our mail servers running Debian Etch to Lenny and noticing that Dovecot 1.2 has been backported to Lenny backports, we decided to upgrade to Dovecot to take advantage of its fixes, improved security and quota settings.

Setting up quotas and warnings for any Dovecot above 1.0 is very simple.

1) First step is to enable the quota plugin for all protocols enabled in Dovecot ( pop3, imap and lda if you use it). This is done by just adding the line:

    mail_plugins = quota

and for the IMAP protocol:

    mail_plugins = quota imap_quota

2) Setup the plugin:


    # Quota plugin settings
    plugin {
    quota = maildir:User quota
    #Quota limit is 1GB
    quota_rule = *:storage=1G
    #We add 100Mb more for Trash
    quota_rule2 = Trash:storage=100M
    #We set up warnings at 75% and 90%
    quota_warning = storage=75%% /opt/mail.sh 75 %u
    quota_warning2 = storage=90%% /opt/mail.sh 90 %u
    }

We can add as many rules and warnings as we want, just by adding and incrementing a number at the end of the warning or rule ( like above: quota_rule, quota_rule2 and so on ).

The first variable, “quota”, is the quota root and is a name that is sent to the IMAP client and can be anything you want.

The second variable is the quota itself and you can set it up using several limits: storage,bytes,messages,backend and ignore (this ignores quota for a specific mailbox). All variables support besides numbers the b/k/M/G/T/% suffixes. For example: 100M, 1G, 30% and so on.

The third variable sets up the quota warning. Using the limit you set up above in the rule you set up the warning at what level you want, by using a fixed number or percent. In the above example we used percent. In this case you need the double % ( %% ) so it can be escaped by dovecot. After the warning limit is set, in the same line, separated by space, is the command to run when that limit is reached. In this case it is a custom script that takes two command line arguments: the first one is the percent and the second one is the user that has reached the limit and to which to send the warning.

We set up the second argument (the user) as dovecot’s %u variable which is set in the ldap configuration, in the filter string. You can make this anything you want, taking the user dynamically through whichever system you have configured as your user database and whichever variable you have set up as you user.

For example, in my dovecot-ldap.conf this is what we have:

    pass_filter = (&(objectClass=person)(userPrincipalName=%u))

and this is where I take my %u from.

And finally this is the script I use to send the warning. It uses the default sendmail binary, a simple text file and the two arguments taken from the command line:


    #!/bin/bash

    PERCENT=$1
    USER=$2

    echo “From: postmaster@domain.org
    To: $USER
    Subject: Your email quota is $PERCENT% full
    Content-Type: text/plain; charset=”UTF-8″

    This is an automatic message to warn that your mailbox is now $PERCENT% full.” > /tmp/quota.email.$USER

    cat /tmp/quota.email.$USER | /usr/sbin/sendmail -f postmaster@domain.org $USER

    rm /tmp/quota.email.$USER

That’s it! Whenever the user reaches its defined quotas he / she will receive a warning email. This quota are global, any user will have the same quota. If you want per-user quotas and / or soft-quotas check out my later edit below!


LATER EDIT:

If you want to make your quotas non-enforcing, that means the user will still receive the warnings but if he or she reaches the quota, their e-mails will not be blocked and they will still be able to receive, you must modify your “quota” variable in the plugin’s settings (the quota root). Make your settings look like this:


    # Quota plugin settings
    plugin {
    quota = dict:user::noenforcing:file:/opt/data/mailboxes/%u/Maildir/dovecot-quota
    #Quota limit is 1GB
    quota_rule = *:storage=1G
    #We add 100Mb more for Trash
    quota_rule2 = Trash:storage=100M
    #We set up warnings at 75% and 90%
    quota_warning = storage=75%% /opt/mail.sh 75 %u
    quota_warning2 = storage=90%% /opt/mail.sh 90 %u
    }

Notice the only thing changed is the first variable: “quota”.

Also, if you want to use LDAP attributes to change your users’ quotas on a per-user basis, you need to do the following:

1) Rename your dovecot-ldap.conf file to dovecot-passdb-ldap.conf :

    mv /etc/dovecot/dovecot-ldap.conf /etc/dovecot/dovecot-passdb-ldap.conf

2) Create a symlink to dovecot-passdb-ldap.conf called dovecot-userdb-ldap.conf :

    ln -s /etc/dovecot/dovecot-passdb-ldap.conf /etc/dovecot/dovecot-userdb-ldap.conf

3) Modify your dovecot.conf file to point to these files as DBs for users and passwords:

    passdb ldap {
    args = /etc/dovecot/dovecot-passdb-ldap.conf
    }
    userdb ldap {
    args = /etc/dovecot/dovecot-userdb-ldap.conf
    }

4) And finally make sure your ” /etc/dovecot/dovecot-passdb-ldap.conf ” file looks like this:

    hosts =
    dn =
    dnpass = auth_bind = yes
    ldap_version = 3
    base = dc=example, dc=org
    pass_filter = (&(objectClass=person)(userPrincipalName=%u))
    user_filter = (&(objectClass=person)(userPrincipalName=%u))
    user_attrs = otherPager=quota_rule=*:bytes=%$, userPrincipalName=home=/opt/data/mailboxes/%u

Notice we use the ” userPrincipalName ” as the attribute for username in dovecot (the username the users will also use to authenticate to dovecot). If you want, you can change this to whatever you want, like sAMAccountName.

Also, if you look carefully, notice that we used the ” otherPager ” attribute from LDAP as the attribute for user quota. We just modify this attribute for whatever we want to override the default quota for a certain user. For example we want to modify for user jon.doe, we just put in that attribute: ” 2G ” and the user will have 2 gigabytes. You can use any existing attribute that is not used and will not be or you can add your own to all the users in the LDAP tree.

That’s it! Restart Dovecot and it should work!

More Vim tips

| November 2nd, 2009

I will continue my previous post with another few Vim tips I recently found in my quest to improve my Vim experience!

1) For those of you annoyed by the auto-comment feature of Vim (the feature that automatically inserts a comment leader in front of a line after your previous line was also commented), just enter this:

:set fo-=r

2) If you are like me and like to use Ctrl+E and Ctrl+A in your command line and want to also use this in Vim, here is a simple way to map end of line and beginning of line to Ctrl+E and Ctrl+A in Vim:

” map CTRL-E to end-of-line (insert mode)
imap $i
” map CTRL-A to beginning-of-line (insert mode)
imap 0i
” map CTRL-E to end-of-line (normal mode)
nmap $
” map CTRL-A to beginning-of-line (normal mode)
nmap 0

3) This is for the lazy ones or the ones that just can not get adjusted to Vim’s shortcuts, here is a trick to map Ctrl+C to copy to clipboard, Ctrl+V to paste and Ctrl+X to cut:

” map CTRL-C to copy (visual mode)
vmap y
” map CTRL-X to cut (visual mode)
vmap x
” map CTRL-V to paste (insert mode)
imap P

Add them to your .vimrc and that’s it!

Vim tips for the Windows user

| October 28th, 2009

If you are like me and want or are forced to use Windows on your desktop or laptop you most probably use putty to ssh into your servers. And also do a lot of copy / paste when editing files with vim. So you probably have noticed that when pasting in vim using right-click in putty (or any other way, doesn’t really matter) vim introduces a lot of white spaces, or transforms your tabs into white spaces or does crazy indenting in general. There are a few tips to work-around this.

1) enter command mode ( using : ) and type:

:set noautoindent

This will stop vim from messing your whole hard-worked indenting, but will not solve your white spaces problem, for this go to tip number 2.

If you want to go back to writing code with vim’s help with indenting type:

:set autoindent

2) enter command mode ( using : ) and type:

:set paste

This enables vim’s “paste mode” and will allow you to paste lines that are already indented without any modifications (tabs to white-spaces) or re-indenting .

To exit this mode type:

:set nopaste

But what if you already have a file with lots of lines that was already messed with and saved to disk. Well there is a way to solve this in tip number three:

3) Go into Visual mode ( by pressing the key “v”) and select the whole text (or just the lines you want fixed) using the arrow keys (left / right selects through a line, up / down selects or unselects whole lines) and when you are done just press the “=” key and vim will solve your indenting for you.

That’s it! Hope now your vim-ing experience will be a much better one!

Recently we have bought a new server to replace an old HP DL360 that failed. The decision was made to buy a new Dell R410. This server, like many Dell servers, comes with a Broadcom dual-port Ethernet card. We wanted to install Debian Lenny (5.0) on it and this should have worked just fine with the bnx2 drivers that come with the latest Debian. But this particular ethernet card, Broadcom 5716, doesn’t work with them!

So we had to get the latest drivers for it! But because Broadcom doesn’t play nice with open-source, you have to get their latest drivers in binary form or compile them yourself from source. Because the compiling using their tarball failed for unknown reason and I didn’t have time to debug it, I searched for a precompiled Debian package (.deb). And it seems the deb from Debian’s Squeeze repository has the drivers that work with this particular card. So I downloaded and installed the package:

    wget http://ftp.ro.debian.org/debian/pool/non-free/f/firmware-nonfree/firmware-bnx2_0.18_all.deb

    dpkg -i firmware-bnx2_0.18_all.deb

Rebooted the machine but still no ethernet drivers. More searching lead me to find out that this firmware works with Linux kernel 2.6.30.  Upgraded to this kernel (using debs also), rebooted and … network connectivity! But my joy quickly ended when I noticed on Openvz’s wiki that they only offer Openvz patches up to 2.6.27! So I had network but no way to use virtual machines with Openvz on it. (and this is what we use in our shop so no other options…).

But with Google’s help again, I noticed that Broadcom 5716 is supported in 2.6.27! No pre-compiled deb packages for this version, but no problem, we can compile our own. These are the steps to compile 2.6.27 with Openvz support and install the Broadcom latest drivers and make them work:

    cd /usr/src

    wget http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.27.tar.bz2

    tar xjf linux-2.6.27.tar.bz2

    cd linux-2.6.27

    wget http://download.openvz.org/kernel/branches/2.6.27/2.6.27-briullov.1/patches/patch-briullov.1-combined.gz

    (or whatever is the latest kernel patch for your kernel)

    gunzip patch-briullov.1-combined.gz

    wget http://download.openvz.org/kernel/branches/2.6.27/2.6.27-briullov.1/configs/kernel-2.6.27-x86_64.config.ovz

    OR

    wget http://download.openvz.org/kernel/branches/2.6.27/2.6.27-briullov.1/configs/kernel-2.6.27-i686.config.ovz

    (depends on what platform your machine runs 32bit or 64bit)

    cp kernel-2.6.27-*.config.ovz .config

    patch -p1 < patch-briullov.1-combined

    make oldconfig

    make

    make modules_install

    make install

    cd /boot

    mkinitramfs -o initrd.img-2.6.27.21

    update-grub

    Edit /boot/grub/menu.lst and make the kernel 2.6.27.21 the default one.

    wget http://ftp.ro.debian.org/debian/pool/non-free/f/firmware-nonfree/firmware-bnx2_0.18_all.deb

    dpkg -i firmware-bnx2_0.18_all.deb

    ( in case you didn’t download and install the firmware earlier )

    update-initramfs -u -t -k 2.6.27.21

    apt-get install vzctl vzquota rsync

    reboot

When you reboot in your system again, networking should work just fine along with Openvz!

Linux introduction books

| June 25th, 2009

Still trying to find time and ideas to post more on this blog, I thought to share some books about Linux and Open Source or related to this subject that I have read and found very usefull. These books are all at an entry level so if you are just beginning to learn about Linux or just trying to get back to using it after a long time, they are all very good books.

This is not a review, I will just post here rapidshare links to all these books, I think that this would be much more helpful then just writing my opinion about them.

  • Linux Rute User’s Tutorial and Exposition – considered one of the best books to start learning about Linux. It is long but covers just about every aspect of the operating system. In my opinion the best choice to start with.  Download!
  • Linux Introduction – if you are not in the mood or do not have the time to read the book above but looking for a quick introduction to Linux or brush up on your knowledge you can try this one. A good, very summarised book. Doesn’t go into advanced details but it is a good starting point. Download!
  • O’Reilly’s Learning the Bash Shell – You can not truly use Linux at its full power without knowing its shell of choice: bash. It is the standard shell that ships without most of the distributions today and a very powerfull tool. This book gives you a very good introduction to it. Download!
  • O’Reilly’s Learning Perl 5th Edition – Considered the very best when it comes to starting to learn Perl. Very well written with great exercises! Perl is not a requirement for Linux but together with Bash it is one of the most powerfull tools at your disposal. Consider this a bonus! Download!

The next 2 books are not technical books. They are philosophical / ethical books about Linux, Open Source and System Administration. You do not need to read them to learn Linux, they just make a good read.

  • Linux and the Unix Philosophy – A book about the ideas behind Linux and Open Source. Short and interesting. Download!
  • The Practice of System and Network Administration – If you are working in the field of System or Network administration this is a very usefull book. It will change your whole perspective about the practice of system administration: from best practices to ethical and professional behaviour to just plain old advice from very experienced authors. Download!

Configuring a Samba server to use AD (LDAP) authentication can be a little tricky, especially because of the the little PAM tricks you need to do. I have searched a lot for info and tutorials, each giving you a little bit of the picture, and tested them until I came to a solution.  I hope to spare you some of the work of digging and testing ;) Here goes!

This how-to is tested and works on a Debian system (4.0 / 5.0) using Samba version 3.2.5. It should work on other distros with minimum modifications but I do not guarantee it. Also, this is a copy / paste how-to, although I provided some small explanations at the end. You just need to modify generic info like “YOUR.DOMAIN” to your systems specific details.

Installing the packages

First we are going to install the needed packages:

” sudo apt-get install samba samba-common libkrb53 libpam-krb5 krb5-config krb5-user winbind “

Configuring nsswitch

Edit the file /etc/nsswitch.conf in order to have the following contents:

# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference’ and `info’ packages installed, try:
# `info libc “Name Service Switch”‘ for information about this file.

# The next 3 lines are modified for winbind password checking before *nix password checking

passwd: winbind compat
group: winbind compat
shadow: winbind compat

hosts: files dns wins
networks: files dns

protocols: db files
services: db files
ethers: db files
rpc: db files

netgroup: nis

Configuring Kerberos5:

Now you need to edit the file /etc/krb5.conf to have the following contents:

[libdefaults]
default_realm =  YOUR.DOMAIN
forwardable = true
ticket_lifetime = 24000
dns_lookup_kdc = false
dns_lookup_realm = false

[realms]
YOUR.DOMAIN = {
kdc =  your.AD.server
admin_server = your.AD.server
default_domain = YOUR.DOMAIN
}

[domain_realm]
.your.domain =  YOUR.DOMAIN
your.domain =  YOUR.DOMAIN

[login]
krb4_convert = true
krb4_get_tickets = false

[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log

[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}

Configuring PAM

The next step is to configure PAM to first try to use Winbind authentication instead of local *nix style authenticaion. This will NOT mess with your local authentication for terminal or SSH access.

First file we need to edit is /etc/pam.d/common-account :

#
# /etc/pam.d/common-account – authorization settings common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of the authorization modules that define
# the central access policy for use on the system. The default is to
# only deny service to users whose accounts are expired in /etc/shadow.
#

# PAM Winbind plugin before *nix accounting
account sufficient pam_winbind.so
account required pam_unix.so

Next one is /etc/pam.d/common-auth :

# /etc/pam.d/common-auth – authentication settings common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
# traditional Unix authentication mechanisms.

# PAM winbind plugin before *nix authentication
auth required /lib/security/pam_securetty.so
auth sufficient /lib/security/pam_winbind.so
auth sufficient /lib/security/pam_unix.so use_first_pass
auth required /lib/security/pam_nologin.so

And the last one is /etc/pam.d/common-password :

# /etc/pam.d/common-password – password-related modules common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of modules that define the services to be
#used to change user passwords. The default is pam_unix

# The “nullok” option allows users to change an empty password, else
# empty passwords are treated as locked accounts.
#
# (Add `md5′ after the module name to enable MD5 passwords)
#
# The “obscure” option replaces the old `OBSCURE_CHECKS_ENAB’ option in
# login.defs. Also the “min” and “max” options enforce the length of the
# new password.

password sufficient pam_winbind.so
password sufficient pam_unix.so nullok obscure md5

Configuring Samba and the shares

First create the directories that you will use for the shares. In this example we will use /opt/data/samba in which we will make 2 other directories: public and restricted.

Now edit the file /etc/samba/smb.conf :

[global]
debug level = 3
kernel oplocks = no
realm = YOUR.DOMAIN
workgroup = DOMAIN  ### domain name without the TLD – .com for example ###
netbios name = <A name by which the server will be seen in the network>
server string =  File Server
load printers = no
log file = /var/log/samba/debug.log
max log size = 50
local master = no
domain master = no
preferred master = no
security = ADS
password server =  your.AD.server
encrypt passwords = yes
socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
wins proxy = no
dns proxy = no
winbind enum users = yes
winbind enum groups = yes
winbind use default domain = yes
winbind separator = +
winbind refresh tickets = yes
idmap uid = 10000-20000
idmap gid = 10000-20000

[public]
path = /opt/data/samba/public
comment = Public access folder
read only = no
force user = %U
force group = “DOMAIN+domain users”
force create mode = 0666
force directory mode = 2777
force directory security mode = 0777
valid users = @”DOMAIN+domain users”

[restricted]
path = /opt/data/samba/it
comment = Restricted access folder
writable = yes
force user = %U
force group = “DOMAIN+<AD group that is allowed to access>”
force create mode = 0660
create mask = 0660
force directory mode = 0770
force directory security mode = 0770
valid users = @”DOMAIN+<AD group that is allowed to access>”

I will explain some of the configuration directives used here for smb.conf. The first two are:

security = ADS
password server = your.AD.server

This will tell Samba to use Active Directory security and that the server Samba needs to verify the passwords against is the local domain controller (the one that holds the AD tree).

The next two are:

winbind use default domain = yes
winbind separator = +

If the first directive is set to “yes”, you won’t need to use the domain also when setting file permissions. Samba / Winbind will know to use what you have set in the “realm” directive in front of every group / user used for authentication or authorization. The second one just tells Samba what to use as separator between the “realm” and user or group.

This directive:

winbind refresh tickets = yes

will tell Samba to refresh the kerberos tickets after joining the domain, as not to “unjoin” it and become unable to authenticate against the AD.

As for the shares, you can use the variable “%U” as the authenticated user to force the ownership or to grant access. Also, you can use groups in the AD to allow access using the directive “valid users =” followed by the name of the group with the domain in front.

Example: valid users = @”DOMAIN+restricted-access-group” . Please use the separator that you have set above with “winbind separator”

The rest of the directives are usual Samba directives.

Now restart Samba and Winbind:

” sudo /etc/init.d/samba restart ”
” sudo /etc/init.d/winbind restart ”

Joining the domain

For Samba to be able the verify usernames and passwords against the Active Directory, the server must first be joined in the domain. To do that we need to use the “net ads join” command:

” net ads join -S your.AD.server -U user%password “

The user and password must be valid a valid user in the domain that has the permission to join it.

To verify that the server has joined the domain you can use the following commands:

” net ads status -S your.AD.server -U user%password “

or

” net ads info “

Also, to be safe run the following commands:

” wbinfo -u “

” wbinfo -g “

The first one should list all the domain users and the second one the domain groups. If this is so and you have seen the user and group list that means that the server is joined and is able to see verify the usernames / passwords.

Setting file permissions

Now that Samba is configured and the server joined the domain, the last thing to do is to set the Unix style file permissions on the share folders. But now, you can use the users and groups in the domain as the owner and group settings of the folders and files. For example:

” chown “jon.doe” /opt/data/samba/restricted -R “

” chgrp “restricted-access-group” /opt/data/samba/restricted -R “

” chmod g+rw /opt/data/samba/restricted -R “

or to make all the users in the domain able to read and write the public folder:

” chgrp “domain users” /opt/data/samba/public -R “

” chmod g+rw /opt/data/samba/public -R “

That’s it! Now you should be able to access Samba shares using your AD username and password!

First Post!

| May 23rd, 2009

Hello all! Just a post to test things out and maybe motivate myself to write something in this blog :)