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.
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.
15 noip Traps when a process is trying to make an Internet
16 socket, and makes a Unix-domain socket instead.
18 The first one is the one which is useful in theory but I've not
19 really made much use of in practice.
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
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
46 So, we write our sigmonster:
48 $ fwd -d from unix:$HOME/.signature to exec.fortune
50 And now we check to see whether it works.
53 cat: /home/mdw/.signature: No such device or address
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
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.
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.
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.
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.
90 This I use every day. All the time. Here's the use case.
91 We'll see some more examples later.
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
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.
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.
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).
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.
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
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
153 It gets worse with SAGE. I can run
155 $ noip sage -notebook
157 and in another window
159 $ noip iceweasel http://localhost:8000/
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.
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
177 The configuration file lives in $HOME/.noip. Mine says
180 ## standard configuration
183 realconnect +172.29.199.2:25
184 realconnect +172.29.199.2:53
185 realconnect +172.29.199.2:80
186 realconnect +172.29.199.2:3128
187 realconnect +127.0.0.1:6010-6020
188 realconnect -127.0.0.0/8
191 (172.29.199.2 is the IP address of the machine I took this
192 from.) What this says is as follows.
194 * Don't produce debugging output, but let me turn it on easily
197 * Allow direct connection to my SMTP server, on port 25. (The
200 * Allow conversations with my local DNS server. (The noip
201 hack is not particularly discriminating. It replaces UDP
202 sockets with Unix-domain datagram sockets, just as it
203 replaces TCP sockets with Unix-domain stream sockets.)
205 * Allow conversations with my local web server.
207 * Allow conversations with my local squid proxy.
209 * Allow conversations with SSH-forwarded X displays.
211 * Don't allow any other communication with anything else on
212 the loopback network 127.0.0.0/8. (I've still no idea why
213 each machine needs 16 million IP addresses for talking to
214 itself. The `-' means `deny'.)
216 * Don't allow any other communication with any of my other
217 local IP addresses. (noip will work out which IP addresses
218 are local from your network interface configuration.)
220 * And finally, implicitly, allow anything else.
222 The rules follow the squid convention: the default is to do
223 whatever the last rule didn't do, so if the last rule says
224 `deny' then the default is `allow', and vice versa.
226 Armed with this configuration, I now routinely run both Emacs
227 and Iceweasel exclusively under the control of noip. And I've
228 done this for several years.
232 SSH is made of win. Its X forwarding is lovely. Its port
233 forwarding divine. Almost.
235 Here's a common scenario. I'm running on a multi-user server,
236 shared with several other people whom I don't necessarily trust.
237 I want to check some files out from my office's version-control
238 system. Traditional answer:
240 $ ssh -L 12345:vcs.work.com:345 mdw@gateway.work.com
244 $ vcs -d localhost:12345 checkout ...
246 and all works well. Of course, anyone else on the server can do
247 the same thing, so I've just leaked my company's secret sauce.
248 (I don't believe in secret sauce, but I ought to show willing.)
250 How do I fix this? Easy!
252 $ noip ssh -L 12345:vcs.work.com:345 mdw@gateway.work.com
254 $ noip vcs -d localhost:12345 checkout ...
256 And it all works. In this case, in particular, it's essential
257 that the /same/ SSH process binds a safe, plastic local end to
258 its forwarded VCS port, and is able to make a real, potentially
259 dangerous Internet connection to gateway.work.com. Of course,
260 since I run Emacs under noip anyway, all the version control
261 stuff that Emacs does magically find the SSH tunnel and work
262 without me having to care.