Posts tagged with “linux”

File descriptor counting

Yes I know I still haven't done part two of that mail server post. I'll get it done soon, I promise.

While chatting on IRC, someone mentioned that they were having a problem with a process going mental and creating a bunch of file descriptors in linux, eventually hitting the "max FD limit" linux has. They couldn't figure out which process it was and they couldn't find a program that would list a count of how many FDs a process has open. A few minutes later I'd thrown together this bash one-liner for him. I'm posting it here just in case someone else might find it useful.

echo "$(for pid in $(ls -a /proc|egrep '^([0-9])*$'|sort -n 2>/dev/null); do if [ -e /proc/$pid/fd ]; then FHC=$(ls -l /proc/$pid/fd|wc -l); if [ $FHC -gt 0 ]; then PNAME="$(cat /proc/$pid/comm)"; echo "$FHC files opened by $pid ($PNAME)"; fi; fi; done)"|sort -r -n|head -n4

To explain: It loops through every file/folder in /proc that is a process ID, then checks that there's a file descriptor folder. Then it gets a count of all the FDs that process currently holds, gets the process name and outputs how many file descriptors that process has open, as well as the process name. This is then reverse-sorted and cut down to only the four processes with the most FDs open.

How to set up effective mail systems, pt. 1

So a few months ago, I moved my primary mail hosting to my own VPS. Over the months since then, I've been tweaking and adding to my mail system, and I figure it'd help both myself and others if I documented what I've done, so I'll start with a list of all the software I use.

Main Software

  • Gentoo - My VPS runs Gentoo. I personally prefer it over other distros, as it's both lighter and less screwed up.
  • postfix - I was originally going to use Exim, but found it strangely difficult to configure, plus postfix seems to universally have lower transaction times.
  • dovecot 2 - I'm switching away from Gmail, so obviously the things I would've missed most would be things like push email and mail filters. Dovecot supports IMAP IDLE, and has sieve/managesieve, so it was easy to port my Gmail filters over.
  • saslauthd - While dovecot has its own SASL authentication, I prefer to use this when authenticating over SMTP. EDIT: I have since switched from saslauthd to Dovecot 2 for SASL authentication. Dovecot works well enough for it that I questioned why I actually needed saslauthd.
  • Mutt - Mutt is my primary MUA. I'll also be discussing configuration changes I made to Mutt, and ways I made it work more like Gmail.

Extra Software

  • SpamAssassin - This should be obvious. Does a great deal to cut down on spam. Plus, with a filter set up with dovecot's sieve, I have a spam folder like before. EDIT: When I first published this post, I had only just set up Postgrey and had no idea what kind of impact it would have on incoming spam/junk mail. It had a massive impact – I haven't received a single spam email since. Spamassassin and Amavisd may actually be unnecessary when using Postgrey (Unless of course you plan to host mail for others, or if you receive a *lot* of spam).
  • Postgrey - This does a fantastic job of cutting down on spam.
  • Amavisd - Somewhat necessary for making postfix work with SpamAssassin, but also makes it easy to offload the antispam part of the mail system to another server. Amavisd can also be used for integrating antivirus systems into your mail scanning process, but I don't need that.
  • OpenDKIM - Used for signing outgoing mail with my DKIM key, and for validating incoming signed mail. This does a good job of ensuring that mail sent from my domain is actually coming from one of my servers.
  • policyd-spf - Originally, I used pypolicyd-spf, but it quite literally breaks every time there's an update to python, it's since been replaced with this perl equivalent which has never had any issues. This uses SPF to validate incoming mail, and ensure that the sending server is actually authorised to send mail for the given domain.
  • fail2ban - This isn't strictly part of the process I go through when setting mail up, but fail2ban helps cut down load a lot when bots are trying (and failing) to use a server as an unauthenticated relay.

In the near future, I'll write a second post detailing how I linked all this together, including config excerpts, but in this post I'm just discussing the software I used, as well as why I use each package. I'll also leave you with a list of extremely good tips.

  • Get an SSL certificate. This makes setting secure mail up a lot easier, especially if you plan to send or receive mail remotely with stuff like IMAP.
  • If you do get an SSL certificate, disable or firewall unencrypted mail ports. Obviously leave port 25 in place, but if you're sending or receiving mail remotely, disable the unencrypted IMAP/POP3 ports (143 for IMAP and 110 for POP3), and set your MTA up to only accept submission mail through 465.
  • Set up SPF records for your domain appropriately. SPF does a good job of telling other mail systems who is or is not allowed to send mail for your domain.
  • Generate a DKIM key, and add it to your domain's DNS. As with SPF, DKIM (DomainKeys Identified Mail) does a fantastic job of indicating to other mail systems whether an email is actually legitimate or not.
  • Use blacklists. There's a large number of DNS-based blacklists which indicate whether a given IP address is known for sending spam or for attempting to compromise servers. This can go a long way in preventing spam.
  • Report any spam you receive. Reporting received spam to places like SpamCop not only reduces the chance of you receiving similar spam in the future, but it helps others too. It helps identify servers that send spam (Contributing to blacklists), helps identify possible domains used for spam (again, contributing to blacklists), and can contribute to the accuracy of antispam systems like SpamAssassin.
  • Monitor your services extensively. This is definitely a big one. It's not easy to monitor your server by looking at logs, and often unless you've got systems set up to email you when anything out of the ordinary happens, you just plain don't know what's happening with your server. Packages like Monitorix (disclaimer: I'm the package maintainer for monitorix on Gentoo), do a fantastic job of showing you at-a-glance whether anything abnormal is happening, so it's easy to see if and when your mail server is rejecting mail. This can also be great for indicating when you've misconfigured something.
  • Use external monitoring services. Services like MXToolbox have free accounts, and you can use them to set up checks so that you get an email if your server's IP is on any IP blacklists. Services like Pingdom are also great for monitoring both uptime and external availability.
  • Make sure your forward and reverse DNS match and that your reverse DNS is your primary mail domain (or what your server actually identifies itself as). This is definitely a good way of ensuring your mail isn't identified as spam.

One final thing to note, the guide and so on will discuss my current mail setup. This means it assumes you'll be using sockets for things like Postgrey. Please read everything carefully before making configuration changes to your own mail setup, as what works for me may not work for you.

That's all for now, but I'll be adding to this list, and writing a second post documenting how I actually set my mail system up, very soon. EDIT: Disregard that. Second part of this post will arrive eventually but I am tremendously lazy.

The journey of a thousand frustrations begins with a single step

There are times when linux frustrates me. Not with issues specific to one distro, but software packages in general which are written for linux.

My prime example here is Watch. In Gentoo, it's included in the procps package. I recently was confused to find that my ident daemon, which I keep running because I'm an avid IRC user, was being flooded with traffic near constantly. Netstat told me it was because of two IRC servers I ran. So I logged in, checked netstat there, and sure enough, it was them. But I had no idea what process on the servers was actually creating the connections.

I assumed it would be the ircd itself, but I wanted proof before investigating further. No problem, I thought, I'll just run watch --differences=cumulative -n 0.1 'lsof +M -i4|grep auth', which according to watch's manpage, would show what's changed in a command's output, rather than clearing the screen and displaying the output every .1 seconds. It did do this, in a way, however, because the program creating the connection to my ident server only kept that connection for a fraction of a second, the output vanished, and thanks to the unhelpful way that watch handles output which only shows up once, all I got was some white blocks showing that there had at one point been text there.

My solution? Throw together a bash one-liner which looped infinitely until the offending program was identified: while true; do UNR=$(lsof -M -i4|grep auth); if [ -n "$UNR" ]; then echo "$UNR"; break; fi; done

This did eventually work, and it turned out to be a runaway process on my personal box constantly creating connections to both IRC servers.

The case for not using Arch

I run a number of different servers from a number of different providers. I also run servers for friends. In this post, I'll be discussing one server in particular, a friend's server that's primarily used for IRC, web hosting and minecraft. This server runs Arch.

Now I'm going to start by saying I don't always make fantastic decisions and I'm not always known for making sure everything's perfect before rebooting a server. I have, in the past, screwed servers up. But this case was a little different.

Yesterday I log into the server to update a firewall rule, and discover that, because I've never used the nat table in iptables before on that box, the module was never loaded. Of course, the box has fantastic uptime and hasn't been rebooted in over 160 days. Now I'll stop for a second to mention how Arch handles kernel upgrades. When the kernel's upgraded, the previous kernel is left on the system, and all kernels older than that are removed completely. This includes the currently running kernel, and all modules. And this box hadn't been rebooted since kernel 3 was released. I have the box set up to be as zero-maintenance as possible. Emails whenever anything happens, cronjobs taking care of updates and removal of old packages from the cache, scripts to reboot any services that have crashed, gone down or have stopped responding. But as I discovered during a routine check a week prior, the Arch box hadn't been upgrading any of its packages due to a recent change to the filesystem package. I manually started the update process, it informed me that it couldn't upgrade the system because of a file conflict (as the news article mentioned). No problem, I force-installed the update to filesystem and then upgraded the rest of the system as usual.

Now fast-forward back to yesterday, I'm telling my friend I need to reboot his server to apply the firewall rule. He gives the okay, and I reboot the server. Emails flood in saying that various services are down and that the server's offline, as always. But then a few minutes pass, there's no email that everything's back online again. I ping the server, nothing. Log into the server host's control panel, it's listed as online, so I VNC into it to see what the issue is. It can't find the harddrive and has thrown itself into a recovery terminal. What.

I figure a kernel change has messed with the partitions, so I boot the server into my usual recovery system - the gentoo live CD. Nothing seems out of place with grub or the fstab, so I look at the next culprit - the config file for mkinitcpio. It's blank.

Somehow, pacman disregarded the usual rules about protecting config files against being overwritten and messed with the config file, so the initramfs Arch needs in order to boot up properly was completely broken. No problem, I'll just chroot in -- OH WAIT. The Gentoo LiveCD runs kernel 2.6.31, and arch refuses to do /absolutely anything/ unless the kernel is new enough (In this case it had to be 2.6.32 or newer). The server host isn't exactly good, and doesn't provide any recent install media. Cue ten minutes of me googling for the kernel versions of everything in the media list, eventually settling for a Fedora 13 disk that had a recent-enough kernel. I get chrooted in, fix the mkinitcpio config and start generating the images. It complains that /dev isn't mounted. Okay. I look at the source for mkinitcpio, discover it's trying to access /dev/fd, which somehow doesn't exist. I symlink it over from /proc/self/fd and start it again. Everything seems to work, so I reboot.

This time, it recognises the hard drive, but the partition device names have changed. It's now seeing the disk as /dev/xvda. Bizarre, but has happened before. I boot the gentoo livecd again, edit grub's menu.lst and fstab, reboot back into Arch. It boots! But doesn't have a network connection. By this point, I'm close to pulling out my hair. I google around and find that because I included a bunch of xen drivers that mkinitcpio forgot before, everything's working a little differently. Specifically, it now works closer with Xen, and is trying to unplug everything at boot. No problem, I'll put xen-emul-unplug=none in the kernel boot line. Reboot the server and the harddrive device name has changed again. I boot into gentoo, change menu.lst and fstab to use /dev/sda again, and reboot.

Finally, the server's booted and has a network connection. And this is why I no longer install arch on any of my boxen. I can't trust it to reboot without throwing a hissy fit and killing itself.

TL;DR Arch package issue sends me on an hour-long crusade to make a box boot again.

Start as you mean to go on

So for the millionth time, I'm starting a blog. Hopefully, this time I'll actually have stuff to write about. As a bit of an introduction, I'm Maff. I'm a computer science student, sysadmin and server support drone from Scotland. I'm also a bit of a designer, a developer and a security dork. I also love videogames, music and a whole host of other things.

I'm starting this blog in part because I want somewhere to document my pursuits (software or otherwise), but also as a place to post about the funny things that happen in real life, and as a place to rant. I may also post about the software I write, from time to time - I'm a semi-active developer over at github, and I'm the gentoo package maintainer for Monitorix.