chiark / gitweb /
noip.c: Add debugging to most of the syscall wrappers.
[preload-hacks] / README
CommitLineData
99413c3b
MW
1PRELOAD-HACKS
2~~~~~~~~~~~~~
3
4What 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
22uopen
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
86noip
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
08bb35b2
MW
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]
99413c3b
MW
187 realconnect -local
188
08bb35b2 189 What this says is as follows.
99413c3b
MW
190
191 * Don't produce debugging output, but let me turn it on easily
192 if I feel the urge.
193
08bb35b2
MW
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.
99413c3b 198
08bb35b2
MW
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.)
99413c3b 204
08bb35b2 205 * Allow conversations with my local SSH server.
99413c3b
MW
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
08bb35b2 209 each machine needs 16 million IPv4 addresses for talking to
99413c3b
MW
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
b383bc2d
MW
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
99413c3b
MW
279\f
280Local variables:
281mode: text
282fill-column: 72
283End: