Goals
My purpose in writing this is to document how to automate mail retrieval from a remote host (everybody.org in this case) without typing your password anywhere. Additionally, I want to ensure that the attacker who compromises the account running fetchmail doesn't automatically gain access to more than your email.
That is, if your mail account is a Unix Shell account on a foreign machine and your fetchmail account is on your local machine, we do not want the account theif to immediately compromise the foreign machine if he compromises your local account.
Methods
To do this we will set up an non-passphrase-protected ssh keypair
whose sole purpose is to set up the ssh tunnel for fetchmail. The
only command that it can run on the remote host is
/usr/local/libexec/imapd.
Procedure
- Generate the key:
$ ssh-keygen -b 1024 -f .ssh/mail_check -C "email@everybody.org" -P "" Generating RSA keys: ...............ooooooO.........................................................ooooooO Key generation complete. Your identification has been saved in .ssh/mail_check. Your public key has been saved in .ssh/mail_check.pub. The key fingerprint is: c0:ad:49:92:81:ea:b9:88:2e:f5:2d:a3:0a:11:59:67 email@everybody.org
- Edit
~/.ssh/authorized_keyson the remote host. Append the contents of~/.ssh/mail_check.pubfrom your local machine to theauthorized_keysfile on the foreign machine. At the beginning of the the line (before the1024), put
Substitute your local ip address or machine name for the "from" so that you end up with a line that looks something like this:command="/usr/local/libexec/imapd",no-port-forwarding,no-agent-forwarding,no-pty,from="64.81.114.147"
(If you put that line in yourcommand="/usr/local/libexec/imapd",no-port-forwarding,no-agent-forwarding, no-pty,from="64.81.114.147" 1024 35 12333076430575175720679678139920022817 89498644456404978922984154121892210952586059656597621419128673230763955818 83313833477831564339602412421858693735833396268917555082416634587359216687 65943880395794712702731984198836856573658173059252907635286070846169196850 8497070380705371764478951144154324073806602053641 email@everybody.org
authorized_keysfile without changing the "from" parameter, I'll be able to run "echo hi" on your machine.) - Set up the
~/.ssh/configon your local machine to use the identity file whenever you contact the mail host. Here are the lines I've put at the beginning of myconfigfile:
Now, whenever we runHost check-mail BatchMode yes HostName everybody.org IdentityFile ~/.ssh/mail_check LogLevel QUIETssh check-mail, ssh will connect to everybody.org using the identity found in~/.ssh/mail_check. - Test it. Since the only thing that the key we've prepared is
authorized to do on the remote host is run the
/usr/local/libexec/imapdcommand, anytime we ssh to check-mail, we should get "* PREAUTH [...]" on STDOUT, no matter what command we give ssh to run. After testing the key, you can type '. logout' to quit the IMAP session. It is extremely important that you see the "PREAUTH" on the first line. fetchmail will see it and understand that the session is already authenticated.$ ssh check-mail hi $ ssh check-mail echo testing hi $
- Add an entry for fetchmail to your
~/.fetchmailrc. This should be adequate:
We are redirecting STDERR to /dev/null because otherwise it we'll get warnings about no TTYs which are annoying when fetchmail is run in a cronjob.poll everybody.org with proto IMAP preauth ssh: plugin "ssh check-mail 2> /dev/null" - Ensure that
.fetchmailrchas permissions not greater than 0710$ chmod 0700 ~/.fetchmailrc
- Test fetchmail.
$ fetchmail -c fetchmail: No mail for mah at everybody.org
- Assuming everyting is working, set up a cron job to run fetchmail
at 15 minute intervals:
$ (crontab -l 2> /dev/null | echo '0,15,30,45 * * * * fetchmail') | crontab -
Mail should start arriving in your mailbox shortly. You may want to send yourself a message just to verify that it travels to the mailhost and fetchmail returns it to your local mailbox. Check