Add Boot RAID hint
[linux_from_scratch_hints.git] / scp-before-relay.txt
blob21c4ca13c5463acf80323a8bc3a5ee623d6b6cfd
1 AUTHOR: Gerard Beekmans <gerard@linuxfromscratch.org>
3 DATE: 2003-10-09
5 LICENSE: BSD
7 SYNOPSIS: An alternative to the pop-before-relay scheme
9 DESCRIPTION: This hint describes a way to dynamically configure an SMTP
10 server such as Postfix to allow your specific (dynamic) IP address to use
11 it as a relay server.
13 PREREQUISITES:  Working SMTP server (tested with Postfix).
15 HINT:
17 Disclaimer
18 ----------
19         This document is, at the moment, mostly a quick hack. I had to
20         implement this in between releasing the LFS-3.0 book and some
21         other pending LFS work, because my ISP's SMTP servers went offline.
22         The scripts are anything but effecient, but it gets the job done, 
23         which is good enough for me at the moment. There's nothing elegant 
24         about it, so be warned ;)
26         Having that said, let's get the show on the road.
29 what is pop-before-relay
30 ------------------------
32 A lot of ISP's give their users dynamically assigned IP addresses. One of
33 the side-effects of this is that remote servers never know who is behind a 
34 particular IP address. You cannot simply tell the SMTP server you wish to relay 
35 with to allow it from one or a block of IP addresses, because this would allow
36 anybody from your ISP to exploit the relay.
38 So, people came up with the pop-before-relay scheme. When you login to a
39 server to check for new mail, your current IP address is logged and added
40 to the SMTP's server relay database. A pop-before-relay (helper) daemon
41 will check that database and expire IP addresses after they have been in
42 the database for a certain amount of time, because you could have gone
43 offline after you checked for new email, so the IP address should be
44 flushed from that database as soon as possible to lower the chance of
45 somebody else obtaining the IP address and exploit the relay, unless you
46 check for new mail again within the expire time.
50 scp-before-relay
51 ----------------
53 What is this scp-before-relay and why not use pop-before-relay if software
54 has already been written to support it?
56 The problem I encountered is that I use ssh tunneling to login to my pop3
57 server at linuxfromscratch.org. With pop3 your password is transmitted as
58 clear text, much like happens with telnet. I don't quite like that, so I
59 use port forwarding with openssh. The downside is that the pop3 daemon now
60 logs my login attempt with the IP address of the server itself (since I'm
61 ssh'ed into the server and connect to localhost there, so the originating
62 IP address is that of localhost as well).
64 So I had to come up with something different, and I call it
65 scp-before-relay.
67 Note:   This was in the old days. Today we use imap-ssl on the LFS server so
68         this isn't an issue anymore.
70 How it works
71 ------------
73 My workstation, called gwaihir, runs the following script every 4
74 minutes:
76         #!/bin/bash
77         # Begin send-ip
79         PATH=/bin:/sbin:/usr/bin:/usr/sbin
81         ifconfig ppp0 > /home/gerard/tmp/ppp.tmp || exit 1
83         IP=$(cat /home/gerard/tmp/ppp.tmp|grep "inet addr"| \
84                 cut -f 2 -d ":"|cut -f 1 -d " ")
86         echo "$IP 0" > /home/gerard/tmp/gwaihir-ip
88         /usr/bin/scp /home/gerard/tmp/gwaihir-ip \
89                 linuxfromscratch.org:tmp
91         # End send-ip
93 The above script will obtain gwaihir's current IP address on the ppp0 link, 
94 if it's up at the moment. Then send the file, gwaihir-ip, to the
95 linuxfromscratch.org server in my ~/tmp directory over there.
97 The format of the file is:
98                 IP 0
100 The 0 can be any value you want, it's not used in the current scheme. It's
101 just to satisfy the hash database format used by Postfix.
103 The server, shadowfax, runs the following script every 10 minutes:
105         #!/bin/sh
106         # Start update-postfix-relay
108         PATH=/bin:/sbin:/usr/bin:/usr/sbin
110         if [ -f /home/gerard/tmp/gwaihir-ip ]
111         then
112                 mv /home/gerard/tmp/gwaihir-ip /etc/postfix
113                 chown root.root /etc/postfix/gwaihir-ip
114                 postmap /etc/postfix/gwaihir-ip
115                 date +%s > /etc/postfix/gwaihir-ip.log
116         else
117                 LAST=$(cat /etc/postfix/gwaihir-ip.log)
118                 if [ $(expr $(date +%s) - $LAST) -lt 1200 ]
119                 then
120                         exit
121                 else
122                         echo "0 0" > /etc/postfix/gwaihir-ip
123                         postmap /etc/postfix/gwaihir-ip
124                 fi
125         fi
126         # End update-postfix-relay
129 This script checks for a new gwaihir-ip file. If found, move the file to
130 /etc/postfix and run postmap to update the database (else postfix will
131 complain that the database file is older than it's source file). Also log
132 the time when this update took place. The +%s option will log the amount of
133 seconds since January 1970. This makes it easier to calculate when it's
134 supposed to expire.
136 In order for Postfix to actually use this file, edit the main.cf
137 configuration file and edit the "mynetworks" variable. It probably already
138 contains the "$mydestination" value. Modify it as follows:
140         mynetworks = hash:/etc/postfix/gwaihir-ip $mydestination
142 The mynetwork variable defines trusted SMTP clients within Postfix. These
143 clients will have more privileges such as being able to relay through this
144 server.
146 Back to the scripts. If there is no file gwaihir-ip present on shadowfax,
147 it usually is caused by one of the following:
149 1) both scripts were run at the same time. There will always be a point in
150 time where both systems will be running the scripts at the exact same
151 time, so gwaihir could be in the middle of sending the new file while
152 shadowfax is checking for it to exist.
154 2) gwaihir is still online, but there's a network problem between gwaihir's
155 ISP and shadowfax, which could have caused shadowfax to be unreachable from
156 gwaihir for a short period of time.
158 3) gwaihir went offline
160 There is no way for shadowfax to know which of the 3 reasons applies at the
161 moment. It's most likely reason 1 or 2, so we don't want to turn off the 
162 relay authorization right away.
164 So instead, shadowfax checks gwaihir-ip.log's contents against the current
165 time. If the difference is less than 1200 seconds (20 minutes), then
166 it won't do anything. Since shadowfax checks every 10 minutes, gwaihir will have
167 10 minutes to send the file. Because gwaihir tries to send it every 4
168 minutes, it gives gwaihir 2 more chances to get the file delivered before
169 shadowfax checks again, when the 1200 seconds are up.
171 If during the next check (after 1200 seconds) gwaihir still hasn't sent a
172 file, we'll have to disable gwaihir's ability to relay. At that time "0 0"
173 is put in postfix's database. There is no IP address that matches '0', so
174 this effectively disables the relay.
177 Improvements
178 ------------
180 There is much room for improvement.
182 Shortly after I activated this scheme I got the idea to put the date +%s
183 output in the gwaihir-ip file as the second value, which would elimate the 
184 need for the gwaihir-ip.log file. gwaihir can't put the date +%s in it's
185 file, because the systems are in different timezones. So shadowfax will
186 have to do this when it finds the new file.
188 The send-ip script could be changed to write the gwaihir-ip file as:
190         echo "$IP stub" > /home/gerard/tmp/gwaihir-ip
192 Then the modified update-postfix-relay script could look like:
193         #!/bin/sh
194         # Start update-postfix-relay
196         PATH=/bin:/sbin:/usr/bin:/usr/sbin
198         if [ -f /home/gerard/tmp/gwaihir-ip ]
199         then
200                 sed s/stub/$(date +%s)/ /home/gerard/tmp/gwaihir-ip \
201                         > /etc/postfix/gwaihir-ip
202                 rm /home/gerard/tmp/gwaihir-ip
203                 postmap /etc/postfix/gwaihir-ip
204         else
205                 LAST=$(cat /etc/postfix/gwaihir-ip|cut -f 2 -d " ")
206                 if [ $(expr $(date +%s) - $LAST) -lt 1200 ]
207                 then
208                         exit
209                 else
210                         echo "0 0" > /etc/postfix/gwaihir-ip
211                         postmap /etc/postfix/gwaihir-ip
212                 fi
213         fi
214         # End update-postfix-relay
217 I'm pretty sure this works, I just haven't tried it yet.
219 Another obvious improvent would be using variables in the scripts for the
220 gwaihir-ip file locations, like:
222         SOURCE=/home/gerard/tmp/gwaihir-ip
223         DEST=/etc/postfix/gwaihir-ip
227 Other than that, this is designed to work with one user. If you have more
228 people you want to be able to use the server as a relay, you need to make
229 some changes. You could use seperate files for every user, and put the
230 script in a loop to parse the files and disable or refresh somebody's relay
231 abilities accordingly. I haven't bothered giving multi-user functionality
232 any thought, so you're on your own for now. Feel free to get back to me if
233 you have any ideas on the matter. I'm not going to pursue it right now
234 because I don't have the need for it. The need may arise in the future, so
235 who knows.
237 Note:   This scheme isn't in use anymore on the server. I've got a mostly
238         static IP address now that hasn't changed since I signed up
239         for this Internet service a year ago. So I just do a manual
240         update of the IP address in the relay database when necessary.
242 CHANGELOG:
243 [2003-10-11]
244         * Updated pre-requisites section.
246         * Added an important missing piece of information: configuring
247           Postfix to use the file containing the IP address.
249 [2003-10-09]
250         * Converted to comply with the new hint format.