1 |
******************** |
2 |
*** INTRODUCTION *** |
3 |
******************** |
4 |
|
5 |
STARTLS is the standard (RFC 2595) way of doing IMAP encrypted with |
6 |
SSL/TLS. Although it does not provide end-to-end encryption of email |
7 |
messages, it can be useful to protect IMAP passwords, and to protect |
8 |
email messages across the "last mile" of mail delivery. |
9 |
|
10 |
While courier IMAP has native support for STARTTLS, TLS negotiations |
11 |
are done before authentication, and are therefore done as root. That |
12 |
means that a small bug such as a buffer overflow in the OpenSSL |
13 |
library becomes a root exploit---yikes! |
14 |
|
15 |
This approach uses a proxy which can handle the encryption and the |
16 |
STARTTLS command itself, and then hands the already-encrypted |
17 |
connection off to courier IMAP. The proxy runs in an environment |
18 |
secured by chroot(), setuid(), and setgid(). |
19 |
|
20 |
IMAP proxy support has been added to stunnel, and also support for |
21 |
doing a plaintext proxy of the IMAP session if STARTTLS isn't used. |
22 |
stunnel runs chrooted in its own directory, as a special user and |
23 |
group. This means that even a grievous security error in stunnel or |
24 |
openssl wouldn't allow significant access to your system, or even |
25 |
allow interfering with mail. |
26 |
|
27 |
|
28 |
******************** |
29 |
*** INSTRUCTIONS *** |
30 |
******************** |
31 |
|
32 |
WARNING: These are not for the faint-hearted. They are confusing and |
33 |
may not work for you. This is still experimental; if you get stuck, |
34 |
email me at <sgifford@suspectclass.com>. |
35 |
|
36 |
1. Download stunnel-3.22. Apply the patch "stunnel3.22-sg2.patch", |
37 |
available from: |
38 |
|
39 |
http://www.suspectclass.com/~sgifford/stunnel-tlsproxy/stunnel3.22-sg2.patch |
40 |
|
41 |
Compile and install it somewhere. This patch improves the proxy |
42 |
support, adds options to tell stunnel to communicate via an already |
43 |
opened file descriptor, adds chroot() support, and improves |
44 |
setuid/setgid support; see: |
45 |
|
46 |
http://www.suspectclass.com/~sgifford/qmail-smtp-tls-proxy/stunnel3.22-sg2.README |
47 |
|
48 |
for a full description of the patch. |
49 |
|
50 |
2. Compile and install "makesock.c". |
51 |
|
52 |
3. Create your service directory for imap-tls |
53 |
|
54 |
4. Set up a log directory for imap-tls. |
55 |
|
56 |
5. Create a user called "stunnel" with a primary group of "stunnel". |
57 |
|
58 |
6. Create a directory in your service directory called "ssl". |
59 |
|
60 |
6a. Copy in your certificate as "stunnel.pem" |
61 |
|
62 |
6b. Copy in your SSL configuration as openssl.cnf |
63 |
|
64 |
6c. Create a seed file with "dd if=/dev/random of=seed count=10k" |
65 |
or something. |
66 |
|
67 |
6d/1. Some copies of OpenSSL will require you to create a fake |
68 |
'usr/share/ssl' directory, to placate openssl in chroot. |
69 |
Something like: |
70 |
|
71 |
mkdir -p usr/share/ssl |
72 |
|
73 |
. If your ssl expects to find its configuration elsewhere, |
74 |
make that directory instead. |
75 |
|
76 |
6d/2. If your copy of OpenSSL requires it, make a symlink to |
77 |
openssl.cnf from the fake config dir. Something like: |
78 |
|
79 |
ln -s ../../../openssl.cnf usr/share/ssl/ |
80 |
|
81 |
should do the trick, if your openssl expects its config file in |
82 |
/usr/share/ssl normally. |
83 |
|
84 |
6e. Set group-ownership of the ssl directory to "stunnel" (leaving |
85 |
user-ownership at "root") and permissions to "owner read-write, |
86 |
group read, other none" on everything in the ssl directory: |
87 |
|
88 |
chgrp -R stunnel ssl |
89 |
chmod -R u=rwX,g=rX,o= ssl |
90 |
|
91 |
7. Install the run file "imap-tls-run" as "run" in your service |
92 |
directory. Make sure it's executable. If you've installed the |
93 |
modified stunnel somewhere other than /usr/local/sbin, add that to |
94 |
the PATH near the top. |
95 |
|
96 |
8. Run the "run" file in the service directory, and find and fix any |
97 |
errors. |
98 |
|
99 |
9. Active the service, perhaps by symlinking it into /service. |
100 |
|
101 |
|
102 |
|
103 |
******************* |
104 |
*** EXPLANATION *** |
105 |
******************* |
106 |
|
107 |
Here's what the run script does. It expects everything it runs to be |
108 |
in your PATH. |
109 |
|
110 |
First, it gathers up some information from control files and from the |
111 |
system user and group database, and gets some hardcoded configuration |
112 |
information. |
113 |
|
114 |
softlimit limits the memory usage for each process to 5 MB. |
115 |
|
116 |
tcpserver listens on the POP3 port. We continue running as root from |
117 |
here (so we can do chroot() and set[ug]id() later, and also run |
118 |
checkpassword), and when we get a connection we run... |
119 |
|
120 |
...makesock. This is a small C program that creates a socket with |
121 |
socketpair(), and provides one end of that socket on file descriptor 3 |
122 |
to the first program it's asked to run, and the other end on standard |
123 |
input and output to the second program it's asked to run. The first |
124 |
and second programs are separated by the command line option |
125 |
"-makesock_connect_to". |
126 |
|
127 |
The first program, the STLS proxy, is stunnel. Debugging is turned |
128 |
on, since this is still experimental. "-/ ssl" (an option added by my |
129 |
patch) asks it to chroot to the "ssl" directory. "-s $SSLUID" asks it |
130 |
to change to the stunnel user. "-g $SSLGID" asks it to change to the |
131 |
stunnel group. "-i" (an option added by my patch) asks it to switch |
132 |
users immediately, instead of after binding to the local port for |
133 |
listening (which we don't ask stunnel to do, since tcpserver has done |
134 |
it for us). "-R seed" tells it to get the seed for the random number |
135 |
generator from the file "seed". "-p stunnel.pem" tells it to use the |
136 |
certificate in "stunnel.pem". "-n imap-" tells it to act as an IMAP |
137 |
proxy, and to act as a plaintext proxy if TLS isn't negotiated. "-f" |
138 |
asks it to stay in the foreground and write its errors to stderr, |
139 |
perfect for running under supervise! "-F 3" (an option added by my |
140 |
patch) asks it to connect to file descriptor 3 (set up by makesock) as |
141 |
the plaintext end of the proxy. |
142 |
|
143 |
The second program is the IMAP server. I run my IMAP server with an |
144 |
unusual run script which uses checkpassword for authentication (see: |
145 |
|
146 |
http://www.suspectclass.com/~sgifford/qmail/courier-imap-checkpassword.txt |
147 |
|
148 |
), and I run it under tcpserver; you will probably want to modify this |
149 |
to use a more typical courier IMAP startup, but since I don't have any |
150 |
servers to test that on, I'm just giving you what I've got. :-) Other |
151 |
than that, this is a pretty normal configuration. |
152 |
|
153 |
************* |
154 |
*** NOTES *** |
155 |
************* |
156 |
|
157 |
It is also possible to run this proxy as a simple TCP proxy, as long |
158 |
as you don't care about what IP addresses your IMAP users are really |
159 |
coming from. |
160 |
|
161 |
|
162 |
************ |
163 |
*** BUGS *** |
164 |
************ |
165 |
|
166 |
* STARTTLS is only supported if no other commands besides CAPABILITY |
167 |
are sent before it. |
168 |
|
169 |
* makesock.c is a single-purpose ugly hack. It should take more |
170 |
command-line options, to make it a flexible tool. |
171 |
|