Local mail on Linux workstations

Local mail on Linux workstations can still work very much like 20+ years ago on Unix. Every user has a mailbox under /var/spool/mail/. Some local services can produce administrative mails, namely cron jobs and security mails from sudo.

However, computing has changed a lot in the last 20 years. Most Linux workstations have only one (human) user. Often she or he is also the administrator (root). The user might also have several machines, at home, at work, a lightweight for travelling, a workhorse for software development. Many of these machines have no valid DNS name or it might change while travelling. And many users don’t want to and would never remember to check local mailboxes, whether there could be any output from a failed cron job. However, everybody should have a mail account somewhere in the “cloud” or at their ISP (unless they run their own mailserver). So the easiest would be just to have all local mail delivered to that single mailbox somewhere on the net.

In Ubuntu installations there is often no mailer (MTA) installed at all. In the past I have used ssmtp to get mail to the local root user delivered to the net. Unfortunately it does not work for mail from “normal” users (uid ≥ 1000). Also the program does not look like it’s actively maintained. So that might be a dead-end solution.

In OpenSUSE you always have postfix installed. I have tried uninstalling it in the past because it’s a massive overkill if your daily mails are handled somewhere else. However, the dependencies were too complicated so I have given up on that approach. And it might be useful to know if some daemon produces mail. So I have configured postfix to send all mail to my “normal” mailbox on the net.

First, having a mail server running on the internet might be dangerous, if you don’t know what you are doing and don’t spend enough time and effort to maintain and monitor it. Luckily in the default configuration in OpenSUSE makes postfix to listen on the loopback network interface only, so I don’t think you need to worried too much that it will be misused in some spam sending operations.

Unless the mail provider you are using accepts mail from senders without a valid DNS name (mine doesn’t), the first thing you need to do is to make sure that your mail gets a valid sender addresses. In postfix you do this by adding the desired mappings to the file /etc/postfix/sender_canonical

jdoe j.doe+from-jdoe-at-mach1@my-sp.foo
root j.doe+from-root-at-mach1@my-sp.foo

Here I assumed that

  • only users root and jdoe will ever send mail. I you have other senders, add respective lines
  • the mail account j.doe@my-sp.foo supports tags separated by a plus sign (e.g. gmail does that). This way you can easily see where some mail originated from. (Without the tags you still dig out all the information from the mail headers)

Next you have to make sure that mails sent to local accounts end up in your desired mail account. Analogously to the above a file /etc/postfix/recipient_canonical can be used. However, at least the default postfix configuration in OpenSUSE does not use such a file. So you need to do 3 steps

  1. Create the file /etc/postfix/recipient_canonical

    jdoe j.doe+to-jdoe-at-mach1@my-sp.foo
    root j.doe+to-root-at-mach1@my-sp.foo

    Again I assumed that only 1 user and root will ever receive local mail. However, the postfix configuration already comes with list a of aliases (like postmaster and abuse) which are mapped to root. So I’d assume mail to those would also be forwarded, although I haven’t seen the need to test it.

  2. Because this file is not previously configured in postfix you need to do so by adding the following lines to /etc/postfix/main.cf

    recipient_canonical_classes = envelope_recipient, header_recipient
    recipient_canonical_maps = hash:/etc/postfix/recipient_canonical

  3. Postfix requires the text file /etc/postfix/recipient_canonical to be converted into binary before usage. This can be done using the postmap command. However, OpenSUSE converts all known files automatically when the postfix service is (re)started. So it’s enough to add the name recipient_canonical into the POSTFIX_MAP_LIST in the file /etc/sysconfig/postfix

Here consumer grade Internet connections are not able to use port 25 freely in order to prevent private PCs being used as spam distributors. Outgoing traffic to that port is limited to the MTA of your own ISP. A final step is still needed to make the forwarding of mail work. Set the nexthop in /etc/postfix/transport.

* smtp:smtp.my-isp.foo

Of course this might be very different depending on country and ISP.

Finally restart the postfix service

sudo systemctl restart postfix

For testing send yourself a mail

$ mail -s "test mail" root
This mail was sent to root, but should end up in my "normal" mailbox

To read the logs you can use

$ sudo journalctl -b -u postfix

Open issues

  • TLS encryption
  • Authentication at SMTP server
Posted in HOWTO | Tagged , , | Leave a comment

Locking out the crackers

A lot of crackers have their scripts and probably also botnets running to break in into machines listening on the internet via more or less known vulnerabilites and trivial passwords.

I recently happend to see 2 standard Linux tools to lock them out.

fail2ban scans the logs and upon certain failure message execeeding a given threshold it will block the source IP address of such activity in the firewall.

pam_tally2 counts authentication failures on PAM level and locks the user account if a threshold is execeeded.

Of course both approaches allow to configure the threshold, automatic unlocking etc. fail2ban is pretty freely configurable for many different purposes.

Another one I have just seen is http://denyhosts.sourceforge.net/ Looks like it has not been updated for a while.

(I’m not actively responsible for any machine listening openly on the internet, so I don’t follow that field explicitly. I wouldn’t be surprised if much more advanced tools exist.)

Posted in noteToSelf | Tagged , , | Leave a comment

Linux sessions, process groups, processes, threads and the ps command

I don’t want to repeat the description how sessions, process groups, processes and threads all hang together in Linux. This description is pretty clear, there are plenty of others on the net.

I keep forgetting what’s the main feature of sessions and process groups though. So here is my reminder:

  • A session can contain one or more process groups.
  • A session can optionally have a controlling tty.
  • Signals can be delivered to a process group.
  • A shell with job control puts all processes of a pipe into one process group.
  • Signals caused by the terminal (like Ctrl-C) go to all processes in the foreground process group.

The following ps command shows the relevant information from sessions down to threads.

ps -emo pid,ppid,sess,tty,pgid,tid,cls,rtprio,nice,cputime,comm,cmd

Posted in HOWTO, underTheHood | Tagged | Leave a comment

Integer sizes in C on 32 bit and 64 bit Linux

Q: How big is an int, long int etc. in C?

A: It depends. (The standard leaves it completely up to the compiler, which also means the same compiler can make it depend on options and target architecture.)

In practice I have not used anything else but gcc on Linux for a couple of years, so for myself the answer is a bit easier. However, because I don’t program C/C++ that often these days, each time I do so I soon tend to hit the question how big was that integer again, especially if interfacing with some low-level stuff and the code should work correctly on both 32 bit and 64 bit machines. At the moment I mostly use Intel architecture, so let me limit this post to Intel. (I have used a lot of ARM in the past and this week glibc with support for AArch64 came out, maybe the results can be checked against ARM later.)

type \ executable[1] 32 bit 64 bit
short int 16 bit 16 bit
int 32 bit 32 bit
long int 32 bit 64 bit
long long int 64 bit 64 bit
size_t 32 bit 64 bit
void* [2] 32 bit 64 bit

[1] A 32 bit executable can be used in a 64 bit user space (supposed a 32 bit loader and required shared libraries have been installed), a 32 bit user space can run on a 64 bit kernel and a 32 bit kernel can run on a 64 bit processor. So it’s really the word length of the executable that counts.
[2] In exotic cases pointers can have different lengths, http://stackoverflow.com/questions/6751749/size-of-a-pointer So, I’m not sure whether sizeof (void *) isn’t in fact undefined by the C standard. At least gcc compiles it without warning and returns a value, which looks correct for gcc on the Intel systems covered here.

The results where produced by the following piece of code:


int main() {
  printf( "    short int: %zd\n" , sizeof(short int) ) ;
  printf( "          int: %zd\n" , sizeof(int) ) ;
  printf( "     long int: %zd\n", sizeof(long int) ) ;
  printf( "long long int: %zd\n", sizeof(long long int) ) ;
  printf( "       size_t: %zd\n", sizeof(size_t) ) ;
  printf( "        void*: %zd\n\n", sizeof(void *) ) ;

  printf( "PRIu32 usage (see source): %"PRIu32"\n" , (uint32_t) 42 ) ;
  return 0;

Slightly related the code also shows 2 features for 32/64 bit portable usage of printf. The “z” length modifier refers to size_t, see printf(3) for a couple of similar ones. The PRIu32 macro makes sure that a constant word length is used regardless of the compiler specific length of the integer types. This and several similar macros are in fact standardized in C99, they are defined in header inttypes.h.

P.S. A previous version of this post contained stupid copy paste errors resulting in wrong results. Hopefully all of them are fixed now.

Posted in programming, underTheHood | 2 Comments

Converting Epoch

It shouldn’t be big news that Linux (like Unix) uses Epoch as its internal calendar. Epoch is number of seconds since Jan 1, 1970 00:00 GMT. Wikipedia can tell more.

The problem is just that as a humam it is not really possible to estimate what the epoch values stand for. From sometimes in 2011 to to sometimes in 2014 they start with 13 and have eight more digits. This month they even nicely start with 1345 and 6 more digits. But at least I don’t know of any other rules of thumb to make any more sense out of them.

Of course conversion can be programmed in any language. Or you can go to this online service.

But as a Linux user the following 2 shell commands might be the most handy solution:

$ date -d @1345678901
Thu Aug 23 02:41:41 EEST 2012
$ date -d "Thu Aug 23 02:41:41 EEST 2012" +%s

Posted in HOWTO | Tagged , , , , | Leave a comment

Access control lists in Linux

Well, I have seem them some 20 years ago in AIX. Access control lists (ACLs) for Unix/Linux files. At least they existed, but I have never seen them used. I have used Linux for quite some while and it has never appeared to me that they actually exist and are even used.

Normally access to a file is only granted in 3 levels: One for the owner, the second one for one group of users and the third one for everything else (“world”)

With ACLs you can give individual rights to many different users, not only to the owner. And you can give individual rights to many groups, not only one.

So how do you know an ACL is used?

$ ls -l /dev/dri/card0
crw-rw----+ 1 root video 226, 0 2011-01-07 21:25 /dev/dri/card0

There are 1 + 3 + 3 + 3 + 1 + 1 = 12 characters at the beginning of each listing.

  • The first one is the file type
  • Then there are 3 * 3 characters for owner’s, group’s and world’s access rights.
  • number 11 is the sticky bit
  • number 12 is a space in most cases, so I have never noticed it before. However if it’s not a space but a plus sign, the access rights are controlled by an ACL.

So how can you check the contents of the ACL? Interestingly enough although the Linux kernel supports ACLs, my Linux distro (Kubuntu) doesn’t seem to contain any user space tool to display them.

Well, that’s not a problem, the tool is easily installed.

$ sudo apt-get install acl

Using the following command you can check, which of your files actually have an explicit ACL:

$ sudo getfacl -R -s /

In my system the list is short. Just a couple of devices related to sound and the graphics adapter. So although these devices are owned by root, the currently logged in user gets rights to use these devices. Without ACL this would be not really be possible. If you wanted to still have them owned by root, then you would need to make them accessible to a whole group or even world.

So nothing dramatic here. Just interesting to see how things work.

If you want to know more, read the man page acl(5). (It comes with the installation above)

Posted in underTheHood | Tagged | 1 Comment

server4you — experiences after 2 days

I ordered a virtual root server. My goal was just to get a machine that is always running and do various experimenting. I don’t expect much traffic and don’t need much resources. So I chose server4you, which was the cheapest offer I could find. Basically 54 EUR for the first year. And you need to remember to cancel the contract after 9 months in writing, if you don’t want to pay the double price for the next year.

Of course you get what you pay for. So for (one of) the cheapest on the market, I somehow expected some surprises. Additionally if somebody makes business with such an aggressive marketing and such price level, I’d always expect some strings attached. So I felt more comfortable to do business with a German company than e.g. with an American one, because German happens to be my mother tongue.

So ordering the server from http://www.server4you.de was somewhat more complicated than necessary. The German pages didn’t allow to enter any address outside Germany. Finally I managed to do so by changing the language to English. The other unpleasant feeling came from the fact that they have mandatory fields in their order form, which according to German law they are not allowed to ask (According to German law you are only allowed to ask data necessary to do the business in question)

There was no confirmation of the the contract sent by email. I would not call this good way to do business.

After 15 minutes or so I received an email that my server had been configured. Well, that was quick. But they hadn’t even asked me what operating system I wanted. Weird. And the email did not contain the address of the server. Even weirder. I waited another 15 minutes and then I got the idea that I could try to login to my account on their web site (you need to choose a user name and password during ordering)

Well, it didn’t let me in. Ok, maybe the database is just not updated yet. After 2 more hours it still didn’t let me in. Oh, they even have a free support hotline. (A toll free number in Germany, which you can reach fro free using Skype even from outside of Germany. Not sure whether they would serve you in any other language than German there.) They answered in less than a minute. Well, the only idea they had was wrong password. So they recommended to use the reset password functionality. Thanks and goodbye!

Hmm, but the resend password functionality claims that my user name is unknown. Another call to the hotline, another quick answer and some deeper investigations this time. Ahh, they have 2 different systems. http://www.server4you.de and http://www.server4you.net. And because I had to make my order in English, they had obviously created my server in the dot net system, although I had never entered that URL (and hadn’t even known that it existed)

Logging in to the dot net server, and yes, it works. Well, some unnecessary hassle, but quick and free customer service that actually solved the problem. That’s clearly better than average these days.

The first message when logging in: Your server has not yet been installed. Ahh, that’s how they got the server ready so quickly without even asking me about the OS.

Searching around a bit how things work and installing a minimal debian system.

After a couple of minutes I can log in. OK it’s really quite slim, only 160 packages and 426 MB of data. Nice to see such a clean system.

Se let’s see what it is. Configuration file /etc/apt/sources.list.d/debian.list tells me it is etch. Oh yeah, could be newer. And the sources file is not updated, the German mirror specified there has no etch repositories anymore. Well, I can update it myself. And indeed, the installation is pretty out of date, apt-get dist-upgrade pulls in 45 upgrades (out of 160 installed). And I guess etch hasn’t got many updates recently.

So how do I upgrade this beast to lenny? Ok debian has really good release notes. Hmm, the kernel. That was said in server4you’s FAQ, you can’t change the kernel of the virtual server. What kernel do I have? 2.6.9. Whaaat? I couldn’t even parse that number. we are at 2.6.35 these days. Ubuntu Hardy 08.04 LTS uses 2.6.28 and that sounds already very old to me. 2.6.9 is from October 2004!!! Googling a bit for the full string 2.6.9-023stab052.4 leads to http://kb.parallels.com/en/8556. Ahh, this is actually a rather recent version of the RHEL 4 kernel. Welcome to the real (slow) world of enterprise computing???

Anyway lenny seems to require only 2.6.8 or higher, I should be on the safe side. So updating sources.list to lenny, apt-get update and apt-get dist-upgrade. And now a reboot. Yes!!! It works.

In conclusion the feelings are mixed. Why do they provide such an old etch system even with non-functional sources.list configuration? But if you know how, you can relatively quickly upgrade it. Maybe they do that only that you can feel good over your own achievements… But definitely not the right choice for somebody who doesn’t want to repair and upgrade the system on day 1.

This posting is already too long, but there is one more story. The firewall. You can configure it from the management interface in the web. (Which will also apply the settings after reboot. Even though this nice feature is again undocumented) But to make a long story short, their web console is broken. The help in the web console tells how it opens outgoing connections if you have blocked incoming ones. But even if the help tells you how it does it, the implementation just doesn’t do it. Yet another call to the support. Quick answer again. But he knows nothing about firewalls, needs to connect to a colleague. After 5-7 minutes of waiting somebody seems to know something about firewalls. Well, yes it’s broken he admits after a while. He’ll pass it on to the development department.

Summary: It’s cheap. (Well if they didn’t manage to cheat me and I only pay what I expect). The user (or should I say admin) guidance could be better. Debian etch is a bit too old, especially such a broken configuration that you cannot install security updates right away. The kernel base version is extremely old, but maybe that’s common industry standard? The firewall configuration has a bug, wonder why a new customer finds that after a couple of hours. The free customer support worked much better for me so far than with many other companies (even those with generally good reputation)

Posted in diary | Tagged , , | 8 Comments