What is Exim? ************* A fully featured Mail Transfer Agent, a drop-in replacement for sendmail. Where is the documentation? ************************** In addition to its man page, Exim has - a web site with a FAQ and complete documentation http://www.exim.org - a book (621 pages), https://www.uit.co.uk/the-exim-smtp-mail-server How to install and run Exim? **************************** Setting up a simple mailer for a single host is straightforward. Most of the tasks below can be accomplished by running the script /usr/bin/exim-config. However the script will not handle special configurations in /etc/exim.conf if your ISP restricts the use of port 25. Neither will it configure your firewall. 1) Edit /etc/exim.conf if needed to add the fully qualified hostname on the "primary_hostname =" line. Uncomment that line. Read the rest of exim.conf to see some of the available options. Make sure your PC does not become an open relay. Various sites will gladly test your installation, e.g. www.ordb.org 2) Create or edit /etc/aliases. Define at least postmaster: your_login_name 4) /etc/exim.conf must be owned by SYSTEM. If its group is not Administrators, the group write permission must be off. "Other" write permission must always be off. This file should not be world readable if it contains passwords. 5) By default exim creates all directories with mode 01777. This allows read and write access by everyone, but the leading "sticky bit" specifies that a file can only deteted by its owner. Database and log files are created with mode 0666. These permissions can be tightened after exim has created the files as explained below in "Security considerations". Mail files in the "input" and "msglog" subdirectories have mode 0600. Mailbox in /var/spool/mail have a mode determined in the "local-delivery" section of /etc/exim.conf. It is shipped as 0666 for reasons explained below. 6) In order to deliver local mail and execute user filters in a secure environment, the daemon needs to setuid. It must thus be part of the Administrators group (which provides the "Backup" and "Restore" privileges) and have the "Create Token", "Assign Token" and "Increase Quota" privileges, as well as "Run as a Service". It is thus highly privileged. On Windows version starting with Win2003 it is necessary to create a new account with the above privileges and run the daemon under that account. That account may be the same as the one used for sshd, crond, etc..., typically cyg_server. The cygwin version of exim checks if it is started by a privileged user and if so it setuid to the SYSTEM account and the Administrators group. It further setuid to the addressed user for deliveries. Even after setuid, delivery processes are still unable to access network shares that require authentication. Thus it may not be possible to read .forward files in networked home directories. This restriction does not apply if the account password has been saved with the "passwd -R" command. The command to launch the exim service is: cygrunsrv -I exim -p /usr/bin/exim -e CYGWIN= \ -a "-bdf -q15m" -d "Exim" -f "Mail Transfer Agent" \ -1 /var/log/exim/cygrunsrv_out.log -2 /var/log/exim/cygrunsrv_err.log \ -u cyg_server Using the -bdf switch avoids the "caveat" mentioned in /usr/doc/Cygwin/cygrunsrv.README. The daemon is started by "cygrunsrv -S exim" or "net start exim". 7) Only members of the Administrators group can send signals to exim launched as a service Security considerations *********************** Contrary to other flavors of Unix, Cygwin does not support the suid bit to allow programs to use root as their effective uid on startup. However exim normally delivers mail and executes user filters by calling setuid to impersonate the addressee, and setuid can only be executed by very privileged users. Thus the cygwin port of exim uses special ways to allow exim to work. In addition to what follows read also the chapter "Security considerations" in the exim specifications at http://www.exim.org Local mailboxes -------------- The default /etc/exim.conf locates the mailboxes in /var/spool/mail/. To allow automatic creation of mailboxes it sets the /var/spool/mail permissions to 1777. The leading 1 is the "sticky bit". It prevents a regular user from deleting files that are not owned. The drawback of this approach is than anyone can store arbitrary files in this directory, and mail can be delivered to inactive or system accounts. The exim.conf file has an option "file_must_exist", which implies that mailboxes are created manually. This fixes the second problem above while still allowing write access to all. That access is needed by MUAs that use a .lock file. If you are sure that all your MUAs use fcntl or flock locking (and not a .lock file), edit exim.conf to remove the directory write access permission for "others" and to set "use_lockfile" to false. There is another method which does not require setuid nor privileged accounts, but which is limited in its use of filters in .forward files. It can be used in systems fearing that external attacks could exploit a security hole in exim. See "External attacks" below. Network originated mail ----------------------- For mail arriving over the network, or generated by local mail user agents (MUA) accessing localhost on port 25, the default solution is to make the daemon a privileged user [see 6) above] that can setuid/gid to the addressee to make local deliveries. Locally generated mail ---------------------- Mail can also be generated by invoking exim directly or through a MUA. In particular Exim generates error messages to the sender by invoking itself, using the exim uid and gid (which may be Administrators), but without privileges to setuid/gid (due to lack of suid bit). On normal Unix systems /var/spool/exim is not writable by "others" access is granted through the suid bit, and the suid bit allows to chown the spool files to the exim user and to setuid to deliver mail and execute filters. The cygwin port of exim always allows users to write to the spool file if permissions allow them to do it. In particulat it sets the internal exim {ug}id to that of the current user, allowing that user to execute the chown calls (which become noops). In addition, if /var/spool/exim is writable by "others" the Cygwin port of exim assumes that direct deliveries should be allowed for regular users and it makes them possible by faking setuid/gid calls, pretending that they succeed (but setuid/gid are never faked for listening daemons). Of course users are still limited by file permissions, so for this to work .forward files need to be readable by all, as deliveries will be deferred otherwise. If "allow_filter" is set to true (it is false by default), .forward files can contain filter commands to write messages to files or to pipe them into commands. This is a major security risk as a user delivering mail (perhaps in the Administrators group) can unwittingly execute commands written by a hostile party. A work around that allows execution of filters is to forward locally generated messages on the loopback interface to a local privileged exim daemon, which performs the delivery. The default exim.conf contains such a "route_up" router to do just that. It is commented out as it requires that a daemon be running. A similar method is to invoke exim with the -odq option. Messages are then simply queued. Deliveries are made by the daemon on the next queue run. When /var/spool/exim is writable by "others", direct deliveries are always possible for senders in the Administrators group (but at the risk of executing unfriendly filters). However regular users need write access to the log files and preferably to the database files, as well as access to the exim spool directories, even when using the "route_up" method. Those accesses are allowed by default (in the Makefile) when the files and disrectories are created by exim. That does not pose a serious privacy risk but would be an issue with malevolent users. Access can be restricted (use chmod, after the files and directories have been created) if direct deliveries need not be supported. If mail is not delivered by the daemon, all users need append (but not read) access to all mailboxes. In addition if mailboxes are not created manually in advance (see "file_must_exist" above) a mailbox could be created by a regular user when sending mail to another user. For the addressee to have access to his/her own mailbox, the mailbox permissions must be set to 666. This default in exim.conf provides no mail privacy. To regain it, access should be changed to 644 and mailboxes created in advance. External attacks ---------------- To prevent buffer overflow type of attacks it is often recommended not to run networked daemons from a privileged account. Below are two ways to address that concern. If the daemon runs in a privileged account (can setuid/gid) and the "exim" account exists, the daemon changes its uid to "exim". However this is not foolproof in cygwin as the underlying privileges are still accessible (this allows exim to setuid to the addressee), although the attack would have to be specially crafted against cygwin. Doing as above has led to access issues that are hard to debug, so it is still considered experimental (in particular see "Known issues" below). Another option is to launch the daemon directly as an unprivileged user (perhaps "exim") with a special "mail" group. This has no drawbacks and is always preferred when exim acts only as a relay (no local mail deliveries). Local deliveries are then done by exim as a regular user (see "Local mail" above), except that setuid/gid calls are not faked and will fail if the ids should really change. The "localuser" router in exim.conf (or the "local_delivery" transport) should specify both the "exim" user and the the "mail" group so that setuid/gid is truly a noop. User mailboxes should be writable by the "mail" group. The same measures should be applied to the "userforward" router and .forward files should be readable by the "mail" group. Note that the daemon queue runner will be unable to deliver messages left on the queue by regular users (except if it has the "restore" and "backup" privileges, which would partially defeat the purpose of running unprivileged). So MUAs should deliver mail to exim via port 25. Summary ------- a) Use exim as shipped only in open shop environments b) To insure mail privacy, edit exim.conf to open mailboxes with mode 600 and uncomment the "route_up" router (so deliveries are made by the daemon). Consider creating all mailboxes manually. Users in the Administrators group should refrain from ever running the queue (-q and some other flags) when "allow_filter" is true as this can result in executing filters in .forward files. c) For maximum internal security do not allow direct execution of exim for mail deliveries by making /var/spool/exim non writable by others and tighten the modes of all lower level files and directories. d) If external security is an issue, run the daemon as an unprivileged user and use the "mail group" method for local deliveries. Special startup code ******************** Internally exim keeps 5 important uids and gids: - root_uid: legal owner of /etc/exim.conf considered "admin" and "trusted" does not exec after forks. - exim_uid: normal owner of /var/spool/exim considered "admin" and "trusted" - exim_gid: members of exim_gid are considered "admin" - configure_uid: legal owner of /etc/exim.conf - configure_gid: legal group with write permission for /etc/exim.conf The Cygwin startup code for exim - sets those values dynamically - sometimes executes setgid and setuid - determines if subsequent setgid and setuid are noops. The -c switch prints related info on stderr. if (user cannot chown || daemon) { exim_uid = getuid () // Needed for regular user creating spool files etc.. exim_gid = getgid () } else if (user exim exists in /etc/passwd) { // Considered experimental exim_uid = as per /etc/passwd exim_gid = as per /etc/passwd } else { exim_uid = SYSTEM exim_gid = ADMINISTRATORS } configure_uid = SYSTEM configure_gid = ADMINISTRATORS if (program can setuid) { setgid(exim_gid) setuid(exim_uid) } if (program can setuid || daemon || /var/spool/exim not writable by others) { setuid/gid = regular call } else { setuid and setgid = noop } root_uid = getuid () // Avoids useless execs Note that setting root_uid to the running uid fools exim but confers no additional privileges to files and directories. Known Issues ************ Cygwin usernames containing spaces cannot receive mail. Edit /etc/passwd and change the first field of offending lines to identifiers without spaces, or modify the Windows username and rebuild /etc/passwd. Exim can regulate its activity depending on the sytem load average. This feature is ineffective when starting from inetd. Contrary to the information in the Exim specification, on Cygwin the "root" and "exim" uid and gid are determined at run time as outlined above. This is necessary because there is currently no suid in Cygwin. When launched as a daemon Exim normally puts itself in the background, except when launched directly from Windows (because its PPID is already 1). Use instead 'sh -c "exim -bd -q15m; true" '. If the user "exim" is defined, it (or its group, or Everyone) needs to have execute access to exim and the dlls it uses, as well as read access to the registry keys (check with regedt32) 1. HKLM\System\CurrentControlSet\Services\Winsock\Parameters 2. HKLM\System\CurrentControlSet\Services\WinSock2\Parameters Lack of access causes the respective error messages 1. IPv4 socket creation failed: Operation not permitted 2. TCP port "smtp" not found. (thanks to Jason Tishler for this information) By default, delivery processes run with the uid and gid of the addressee but without supplementary groups. When the gid is 513 (None), some files or registry entries may be inaccessible. Try changing the gid in /etc/passwd to 545 (Users). Exim can be compiled with support for perl. However the Cygwin port of the perl library has been reported (in 2003) to crash when invoked by exim, so it is not included in the binary package. What if it doesn't work as expected? *********************************** Look at the log files in /var/log/exim and /var/spool/exim/msglog Run "exim -c" from the shell, it produces Cygwin related info. Read the exim user manual and consult the mailing list and the FAQ. Follow the testing section in the user manual. Turn -d on, it's instructive to watch what happens. To debug exim in the system environment, clear the SYSTEM password, add a home directory (/) and a shell. Telnet to localhost and login as SYSTEM. DO NOT omit to restore a password when done. If -d is passed to the daemon running as a service, output will be in /var/log/exim.log by default The script /usr/bin/exim-config changes the default to files in /var/log/exim. You can create with cygrunsrv a service under account cyg_server and running the command /usr/bin/strace with argument "/bin/exim-X.Y.exe -bd" This may give you some indication of what goes wrong. Identify the source of the problem. Recompile with -g and use gdb if necessary. Exim forks subprocesses, which complicates the debugging. Some fork() can be avoided by specifying the -odf argument. You can also avoid the fork() by using "jump" in gdb. Write to cygwin@cygwin.com mentioning "exim" in the subject line if the problem is related to the port, e.g.: - locking or opening databases or files - binary/text mode issues - Cygwin dll features Building from sources ********************* Exim uses a non-traditional configuration and Makefile building process. Read the documentation. os/Makefile-Cygwin has defaults for parameters normally set in local/Makefile. You can use local/Makefile to override them To build exim as distributed, download the sources patched for Cygwin, as well as libpcre-devel, openldap-devel and openssl-devel, then type "make" in the main directory. "make install" requires root to appear in /etc/passwd, except when used with INSTALL_ARG=-no_chown