Recently in System Administration Category

Indeed, I'd like to read your comments on my blog. But in more recent weeks spam comenters have attempted to raid my site. For some time I've required people to sign up in order to be able to comment on my blog. As a consequence, spam commenters created a pile of fake accounts using a small number of email addresses to register (from China and India). Some weeks later they used these fake accounts trying to flood the site with nonsense that didn't make it to the articles but cluttered my mailbox. It became a nuisance and something had to be done.

For a time I considered to modify the code of my blog to make registration for people using these email addresses impossible. The blog software answers a registration attempt by sending out a confirmation email with a link containing random data. If these emails wouldn't arrive at the spammer's email inbox the problem was solved.

But honestly, I do not only wish to block outgoing mail to people, who have proven their ill-disposed behaviour to me, I'd also like to protect me from seeing anything they might try to send to me, too.

The easiest way to achieve this was to tell my mail server about these culprits. I created two files (recipient_blacklist and sender_blacklist) that contain email addresses (or domain names) of accounts used to register as a commenter, that subsequently were used to submit heaps of nonsense.

163.com
shoesbuy29.in
vbsdvxcbv@tom.com

It goes without saying that you have to be very careful about what you put into this database, because a domain name entry will block all email originating from or going to this domain without exception. This time, it was exactly what I'd wish to happen. To prepare the blacklist databases, I had to use the following commands:

# postmap hash:/etc/postfix/recipient_blacklist
# postmap hash:/etc/postfix/sender_blacklist

After adding the following line to my postfix configuration file "main.cf" and restarting the mail server, any attempt to use one of the listed email addresses resulted in a nice reject log in the logfile. I've never seen anything from these addresses since.

smtpd_recipient_restrictions=check_recipient_access hash:/etc/postfix/recipient_blacklist,
check_sender_access hash:/etc/postfix/sender_blacklist, permit_mynetworks,
reject_unauth_destination

Having said that, I heartily invite everyone to contribute comments. I am committed to keep this a friendly place, where you'll find interesting information and valuable advice. And I'm prepared to write code that will update my spam commenter database, helping to chase them away effectively, as soon as possible.

Maybe you've tried to get the new firefox 4 to display applets by using the good ol' libjavaplugin_oji.so with no success. It took me a while to discover that newer versions of firefox require a different plugin called libnpjp2.so which is located in a totally different place in Sun's JRE tree.

Create a symbolic link in your plugins directory (either /usr/lib/mozilla/plugins or in your home directory in $HOME/.mozilla/plugins) and your firefox 4 should be able to display applets.

ln -s /usr/java/jre1.6.0_24/lib/i386/libnpjp2.so /usr/lib/mozilla/plugins

Why did nobody tell me?

It's amazing what you can do with SSL certificates. In an earlier posting I showed you how to secure your email access by using SSL certificates. To achieve this, we had fortified our mail server to always establish pure SSL secured connections for the retrieval of an users' email. We did that to stop network snooping folks to read email passwords in transit and to make sure that someone who got to know a user's password would even need another secret information (the user's SSL secret key) to get at the mailbox content.

Now we will use the certificates we needed to fortify our IMAP server to make the other half of the mail system, the SMTP server, secure too. The SMTP servers today are used to accept email messages that are bound for a certain destination for which the server is authorative. But to deny spammers the chance to indulge in their nefarious activities SMTP servers usually refuse to relay email messages to other servers under normal circumstances. There's nothing wrong with it as long as the machine that is used to send the email has a public IP address that was never used to send spam before.

But once you've tried to send email via a dial-up connection or a public wireless access point, chances are that your dial-up IP address is marked as a dubious source and you cannot send your email because you are blocked by some intelligent software that pretend to know your're a spammer. There is no point in arguing, your only chance is to send your email into the internet via a "clean" relay host, with a static IP address, that is able to make a difference between you and all the spammers that pretend to be you.

In essence, we have to find a way to authenticate ourselves to the clean SMTP server in a secure way. Obviously, all the system users that are listed in the mail server's user database should be allowed to use the server as a mail relay host. But then, they have to submit their passwords to the mail server to authenticate and, as you probably would have known by now, this should only be permitted through a secure link using SSL or TLS.

Switching On Authentication

Most people sending email don't think about having to prove their identities to a mail server, they expect to be able to send email the same way as they are used to stuff anything into a real letter box. From the perspective of the mail server, a correct username password pair is the only thing that differentiates a valid user from the spammers. That's why it is important to educate people, that giving a password is not too much of an annoyance for the benefit of sending email while on the move. Anyway, once we have set up the system to use SSL certificates with an outgoing mail server, users will not see much of a difference except that they have to provide their password when sending the email out.

Adding A Secure Tunnel To SMTP

As the mail server is our main secure entry point for email into the internet our main objective is not to hide our message but to convince the mail server that we are the good guys that are allowed to inject email into the system.

SASL, the Simple Authentication and Security Layer, is being used to enable our mail server software to perform the necessary authentication checks. But before we can enable the use of SASL inside postfix, we have to start a deamon, the saslauthd

chkconfig saslauthd on
/etc/init.d/saslauthd start

The following code is used to enable sasl in postfix and has to be added to the main postfix configuration file:

# SASL support for authentication
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination

# TLS support for postfix
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/postfix/mailserver.key
smtpd_tls_cert_file = /etc/postfix/mailserver.cert
smtpd_tls_CAfile = /etc/postfix/CA.cert
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

The last few lines of code will tell postfix to use TLS (the replacement for the older SSL mechanism) and the location where to find the mail server certificate and key as well as the CA file to verify the trust chain.

With these modifications of the server side, we have essentially locked out everyone from using our mail server who is unable to provide the correct username and password over the TLS connection to our mail server.

Don't Forget Your Client!

The first thing we'll notice when we send our next email is that it won't go out as our email software used to ignore TLS so far for outgoing mail. To be able to send email out again you have to change your settings in the "SMTP" section of you email client software. After selecting TLS encryption and providing the username for the mail server you should be back on track again. In my case I had to upgrade my email software to ALPINE 2.0 to get busy, because my old software (pine) didn't know a thing about TLS. But that could only happen to me as I tend to stick to the old reliable programs when the rest of the world has already moved on to the cutting edge solutions.

Using Big Files As Hard Disks

| 4 Comments | No TrackBacks
The XEN hypervisor uses big files (a couple of gigabytes) as filesystem images for virtual machines. Unlike other virtualisation solutions XEN does not impose its own internal structure on the image file. The big file simply has to contain an ordinary ext3 filesystem and, optionally, a partition table just as if it were a real hard disk. The ability to use big files as hard disks comes in handy if you are running short of space on your main hard disk. With an external hard disk you should be well prepared to run a number of virtual machines as big files. However, having the filesystem of a virtual machine in a big file raises the question of how to boot the virtual machine. Essentially there are two options to do that:

  1. Provide the VM's kernel and the init-ramdisk, which are usually stored inside the filesystem (in the /boot directory), as separate files together with the big file, and modify the VM's configuration to use them.

  2. leave the kernel and the init-ramdisk in the big file and provide a working boot sector that accesses the kernel inside the big file, using the native XEN pygrub bootloader to start the virtual machine.
Both options require that the big file must be associated with a real, special device file (i.e /dev/loop0) in order to create a filesystem on the big file. While for the first option it is sufficient to simply connect the big file with the loop device, using the "losetup /dev/loop0 bigfile" command, the second option is much more complex, as the big file has to be partitioned like an ordinary hard disk before the filesystem can be created.

For the rest of this article we will focus on the second option which is much more appealing as everything is kept inside the big file. I will show you how exactly the big file is turned into a virtual hard disk and how you can access and modify the information stored in the virtual machine's own filesystem.

Getting Partitions And Filesystem Sizes Sorted

Our journey through the big file's internal structure naturally begins with the creation of the big file.

dd if=/dev/zero of=bigfile bs=1M count=3950

As a second step we use this chunk of 4141875200 bytes to act as a hard disk and try to partition the bigfile as usual:


losetup /dev/loop0 bigfile
fdisk /dev/loop0

Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help):

As expected, the fdisk program throws a number of error messages at us, because we have given a big file instead of a real hard disk to the program. But let's see how the fdisk program recognizes our new hard disk in detail
.
Disk /dev/loop0: 4141 MB, 4141875200 bytes
255 heads, 63 sectors/track, 503 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot Start End Blocks Id System

Obviously there is no partition table yet, but the program assumes that the big file represents a hard disk with 255 heads and 63 sectors of 512 bytes data each. Every cylinder of our virtual hard disk is made of 255 x 63 x 512 bytes = 8225280 bytes which represents the units in which we can chop the hard disk space into partitions now. All in all there are 503 cylinders in our virtual hard disk which makes a total of 503 x 8225280 bytes = 4137315840 bytes to spend on partitions.

But wait, didn't we create 4141875200 bytes in the first place? That's 4559360 bytes less than what we had originally. Well, this loss is due to the fact that for the 504th cylinder we'd need 8225280 bytes which we don't have, so this loss is inevitable. But the important consequence of this reduction of space is that we cannot create a filesystem on the whole bunch of data we supplied. At the moment the size of our filesystem is not determined at all. The next step is to create a new primary partition inside our big file using all the space we have:

Disk /dev/loop0: 4141 MB, 4141875200 bytes
255 heads, 63 sectors/track, 503 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System /dev/loop0p1 1 503 4040316 83 Linux

After having written the partition table to the big file, have you checked for the new device file /dev/loop0p1? Don't worry, it does not exist! Adding p1 to the disk label is fdisk's way to denote partitions, that does not mean that you'll find such a thing in the /dev directory.

Poking Inside The Big File

From the partition table you can see that 4040316 blocks have been allocated for the new partition. With each block storing 1024 bytes we now know our first partition size, it's 4040316 x 1024 bytes = 4137283584 bytes. This is another number we never saw before! After having written off some 4.5 megabytes because we cannot use half a cylinder, we now face another loss of exactly 4137315840 - 4137283584 = 32256 bytes.

Of course these 32256 bytes at the beginning of the big file are there for a purpose, which is to store the partition table. Our first partition begins right after this amount of data, at an offset of 32256 inside the big file. The amount of 32256 bytes results from the fact that one track (63 sectors of 512 bytes for one head) are put away for the partition table. Now it's time to use a second loop device (/dev/loop1) to poke inside the big file at exactly the point where our first partition begins and create a new filesystem there:

losetup -o 32256 /dev/loop1 bigfile
mkfs -t ext3 -c /dev/loop1 4040316

It's essential that we supply the number of blocks as a parameter to the mkfs command to ensure, that our new filesystem on the first partition fits exactly in the space we have allocated. Without this parameter our filesystem would become too big, as the 4.5 megabytes after the first partition would be used for the filesystem too, and when the virtual machine is going to use the filesystem its actual size would conflict with the numbers in the partition table. Either the partition table or the filesystem's superblock is lying, which will cause distress for the virtual machine that expects a consistent filesystem to operate.

Writing The Master Boot Record

You can fill up the filesystem with whatever carefully selected quality open source software you can find on the planet, but in the end we need to write the new virtual disk's master boot record to boot the jewel. There is one step of preparation to be done before we can use the grub shell to write the MBR. We have to make a symbolic link named /dev/loop to the device that points to the master boot record, that is to the beginning of the big file, /dev/loop0 in the example above.

grub> device (hd0) /dev/loop
grub> root (hd0,0)
grub> setup (hd0)
grub> quit

Now your spick-and-span virtual hard disk is ready to boot.

Recent Comments

  • Ralph: There is a page called "Copyright Policy and Terms of read more
  • Windows Icons: Hello! I do not see a condition of use of read more
  • Ezine: A thoughtful insight and ideas I will use on my read more
  • Ralph: Elaborating upon your thought experiment a little bit more and read more
  • Ben: Heh, yes it would take a fair while I guess. read more
OpenID accepted here Learn more about OpenID