chiark / gitweb /
noip.c (do_implicit_bind): Handle `SAME' impbind entries properly.
[preload-hacks] / README
1 PRELOAD-HACKS
2 ~~~~~~~~~~~~~
3
4 What is it?
5
6         The preload-hacks distribution contains a couple of LD_PRELOAD-
7         able libraries which I find very useful.  Well, one useful one,
8         and one which is really handy in theory.
9
10         uopen   Traps when a process is trying to open(2) a Unix-domain
11                 socket, and does the appropriate socket(2)/connect(2)
12                 dance instead.  I've no idea why it doesn't work like
13                 this in the first place.
14
15         noip    Traps when a process is trying to make an Internet
16                 socket, and makes a Unix-domain socket instead.
17
18         The first one is the one which is useful in theory but I've not
19         really made much use of in practice.
20
21
22 uopen
23
24         The main use-case is variable signatures.  Many mail and news
25         clients nowadays have built-in sigmonsters, which choose a
26         .signature at random from a collection.  Some don't, of course,
27         which is a shame.  It would be nice if the sigmonster was
28         detachable, so you could just write a sigmonster and attach it
29         to your favourite newsreader.  It would extra nice if
30         newsreaders (and mail clients) don't have to use some kind of
31         weirdo sigmonster interface just to do this stupid thing with
32         .signatures.
33
34         All mail and news clients know how to read a .signature file.
35         It's why it's got that name.  So the right answer seems to be to
36         make this file magically have different contents each time it's
37         read.  Noticing when someone tries to read a regular file is
38         just awful so let's not think about that idea any more.  We
39         could make .signature be a named pipe; but named pipe servers
40         are very difficult to get right when there are multiple
41         simultaneous clients.  Sockets are, of course, the right answer
42         when client/server architectures come up.  And we've got a
43         convenient way of stashing sockets in the filesystem: PF_UNIX
44         sockets.
45
46         So, we write our sigmonster:
47
48         $ fwd -d from unix:$HOME/.signature to exec.fortune
49
50         And now we check to see whether it works.
51
52         $ cat ~/.signature
53         cat: /home/mdw/.signature: No such device or address
54
55         Hmm.  That blows.  Surely it's obvious how to read from a
56         socket.  But, no, the kernel won't do the socket/connect thing
57         for us.
58
59         Enter uopen.
60
61         $ uopen cat ~/.signature
62         Noise proves nothing.  Often a hen who has merely laid an egg 
63         cackles as if she laid an asteroid.
64                 -- Mark Twain
65
66         Joy!
67
68         This isn't perfect.  The file is weird and not a proper file.
69         Emacs will refuse to visit it as a result.  But it /will/
70         happily insert the contents of the file into existing buffers.
71         Hopefully other editors are similar.  `less' wants the -f option
72         before it will bother.  But actually it works pretty well.
73
74         The right place for the functionality of uopen is in the kernel.
75         It shouldn't be difficult.  I even submitted a patch to the
76         Linux kernel list to do precisely that, once, back in the days
77         of 2.0.x.  It was ignored, and I gave up; the patch bitrotted
78         hopelessly.  My LD_PRELOAD hack still works.  There's no
79         configuration.  It just works.
80
81         My .signature has been `-- [mdw]' for years now, and that's
82         unlikely to change.  So I don't actually use uopen very much.
83         But it's cool to know that it exists.
84
85
86 noip
87
88   The basic idea
89
90         This I use every day.  All the time.  Here's the use case.
91         We'll see some more examples later.
92
93         Some random program has a client/server split between the main
94         guts of the thing and its user interface, and the two
95         communicate over TCP sockets.  There are lots of examples: SLIME
96         (the Superior Lisp Interaction Mode for Emacs) runs a Common
97         Lisp system as a separate process.  The SAGE notebook runs a web
98         server and you're meant to use a Javascript-supporting web
99         browser to drive it.  All sorts of stuff.  Usually the
100         programmer knew just enough to remember to bind the server's
101         listening socket to 127.0.0.1, to stop everyone on the Internet
102         from connecting, but often the security consciousness stops
103         there.  If you're very lucky, there's some sort of password
104         mechanism.
105
106         The problem, of course, occurs on a multi-user system.  Binding
107         to localhost doesn't stop any other user of the same machine
108         from connecting.  In the cases of SLIME and SAGE, this is a big
109         problem: both provide a full programming environment
110         (respectively Common Lisp and Python) which would let an
111         attacker do anything he likes in your name.
112
113         Passwords are wretched as a security mechanism.  Besides, I
114         shouldn't need a damned password to talk to one of my own
115         processes from another one of my own processes!  The operating
116         system should be able to ensure that processes owned by the same
117         user can communicate securely.  There's a whole filesystem with
118         access control and everything.
119
120         The right answer is to use Unix-domain sockets, which live in
121         the filesystem and have proper access control applied to them.
122         But programmers are lazy, and Unix-domain sockets don't exist on
123         Windows (well, unless you install Cygwin, but I can see why
124         that's an unpopular idea).
125
126         The noip LD_PRELOAD hack intercepts the socket(2) system call.
127         If the process is asking for a PF_INET socket, then it hands out
128         a PF_UNIX socket instead.  If the process tries to bind(2) its
129         socket to 127.0.0.1:12345, say, then noip binds it to
130         /tmp/noip-USER/127.0.0.1:12345 instead (having previously
131         created the directory /tmp/noip-USER and made sure that nobody
132         else can get to it).  If the process tries to connect(2)
133         somewhere, noip fixes up the address.  The noip hack intercepts
134         14 different system calls in order to prevent its systematic
135         dishonesty from being discovered.
136
137   Configuration
138
139         Running a program under noip effectively only allows it to talk
140         to other programs running under noip.  This is sort of the idea,
141         but it's rather restrictive in practice.  I can happily run
142
143         $ noip emacs
144
145         and start up SLIME, and Emacs and SLIME will communicate
146         securely over a Unix-domain socket without either of them
147         noticing.  But now Emacs can't talk to anything other than
148         SLIME, which makes w3m-el less useful than it used to be, and,
149         worse, my Common Lisp programs can't talk to anything external
150         either, which may make writing network-aware Lisp programs
151         annoying.
152
153         It gets worse with SAGE.  I can run
154
155         $ noip sage -notebook
156
157         and in another window
158
159         $ noip iceweasel http://localhost:8000/
160
161         (or Firefox, on Ubuntu), and the two will communicate happily.
162         But now my Iceweasel is crippled and can't actually talk to the
163         rest of the Internet.  The point of the exercise was to make my
164         SAGE process secure, not to make me run two copies of Iceweasel
165         and have to cope with the inevitable profile fork.
166
167         So noip can be configured.  It still defaults to safety:
168         whenever the process asks for a new Internet socket, noip hands
169         it a fake plastic Unix-domain socket instead.  But when the
170         process tries to bind or connect its socket, noip will look the
171         address up in a list decide what to do.  If the result comes
172         back `allow', then noip will do a three-card Monte, rustling up
173         a real PF_INET socket and replacing the plastic imitation; if
174         the result comes back `deny' then noip will continue with its
175         elaborate deception.
176
177         The configuration file lives in $HOME/.noip.  Mine says
178         something like this.
179
180         ## standard configuration
181
182         ## debug
183         realconnect +127.0.0.1:6010-6020, +[::1]:6010-6020
184         realconnect +127.0.0.1:53, +[::1]:53
185         realconnect +local:22
186         realconnect -127.0.0.0/8, -[::1]
187         realconnect -local
188
189         What this says is as follows.
190
191           * Don't produce debugging output, but let me turn it on easily
192             if I feel the urge.
193
194           * Allow conversations with SSH-forwarded X displays, which
195             listen on the loopback interface.  Notice that the IPv6
196             address must be enclosed in square brackets because colons
197             are having to do double-duty here.
198
199           * Allow conversations with my local DNS server.  (I run
200             `unbound' on all of my servers, to do DNSsec validation.
201             The noip hack is not particularly discriminating.  It
202             replaces UDP sockets with Unix-domain datagram sockets, just
203             as it replaces TCP sockets with Unix-domain stream sockets.)
204
205           * Allow conversations with my local SSH server.
206
207           * Don't allow any other communication with anything else on
208             the loopback network 127.0.0.0/8.  (I've still no idea why
209             each machine needs 16 million IPv4 addresses for talking to
210             itself.  The `-' means `deny'.)
211
212           * Don't allow any other communication with any of my other
213             local IP addresses.  (noip will work out which IP addresses
214             are local from your network interface configuration.)
215
216           * And finally, implicitly, allow anything else.
217
218         The rules follow the squid convention: the default is to do
219         whatever the last rule didn't do, so if the last rule says
220         `deny' then the default is `allow', and vice versa.
221
222         Armed with this configuration, I now routinely run both Emacs
223         and Iceweasel exclusively under the control of noip.  And I've
224         done this for several years.
225
226   SSH tricks
227
228         SSH is made of win.  Its X forwarding is lovely.  Its port
229         forwarding divine.  Almost.
230
231         Here's a common scenario.  I'm running on a multi-user server,
232         shared with several other people whom I don't necessarily trust.
233         I want to check some files out from my office's version-control
234         system.  Traditional answer:
235
236         $ ssh -L 12345:vcs.work.com:345 mdw@gateway.work.com
237
238         Now I can run
239
240         $ vcs -d localhost:12345 checkout ...
241
242         and all works well.  Of course, anyone else on the server can do
243         the same thing, so I've just leaked my company's secret sauce.
244         (I don't believe in secret sauce, but I ought to show willing.)
245
246         How do I fix this?  Easy!
247
248         $ noip ssh -L 12345:vcs.work.com:345 mdw@gateway.work.com
249
250         $ noip vcs -d localhost:12345 checkout ...
251
252         And it all works.  In this case, in particular, it's essential
253         that the /same/ SSH process binds a safe, plastic local end to
254         its forwarded VCS port, and is able to make a real, potentially
255         dangerous Internet connection to gateway.work.com.  Of course,
256         since I run Emacs under noip anyway, all the version control
257         stuff that Emacs does magically find the SSH tunnel and work
258         without me having to care.
259
260   Testing
261
262         noip provides a handy way for testing network servers and so on
263         safely.  For a start, you can run your test server apparently on
264         the same port as the real one.  Because noip consults the
265         environment variable NOIP_SOCKETDIR to find out where to put its
266         sockets, you can run two at a time and they don't interfere.
267         And noip doesn't care what port numbers your program tries to
268         bind, so you don't need to jump through stupid hoops in order to
269         test programs which use `privileged' ports.
270
271   Other applications
272
273         There are certainly loads of handy things you can do with noip.
274         If you think of one, let me know!
275
276                                                                 Mark Wooding
277                                                         mdw@distorted.org.uk
278
279 \f
280 Local variables:
281 mode: text
282 fill-column: 72
283 End: