1psusan(1) PuTTY tool suite psusan(1)
2
3
4
6 psusan - pseudo-SSH for untappable, separately authenticated networks
7
9 psusan [ options ]
10
12 psusan is a server program that behaves like the innermost `connection'
13 layer of an SSH session, without the two outer security layers of en‐
14 cryption and authentication. It provides all the post-authentication
15 features of an SSH connection:
16
17 • choosing whether to run an interactive terminal session or a
18 single specified command
19
20 • multiple terminal sessions at once (or a mixture of those and
21 specified commands)
22
23 • SFTP file transfer
24
25 • all the standard SSH port-forwarding options
26
27 • X11 forwarding
28
29 • SSH agent forwarding
30
31 The catch is that, because it lacks the outer layers of SSH, you have
32 to run it over some kind of data channel that is already authenticated
33 as the right user, and that is already protected to your satisfaction
34 against eavesdropping and session hijacking. A good rule of thumb is
35 that any channel that you were prepared to run a bare shell session
36 over, you can run psusan over instead, which adds all the above conve‐
37 niences without changing the security properties.
38
39 The protocol that psusan speaks is also spoken by PuTTY, Plink, PSCP,
40 and PSFTP, if you select the protocol type `Bare ssh-connection' or the
41 command-line option -ssh-connection and specify the absolute path to
42 the appropriate Unix-domain socket in place of a hostname.
43
45 The idea of a secure, pre-authenticated data channel seems strange to
46 people thinking about network connections. But there are lots of exam‐
47 ples within the context of a single Unix system, and that's where psu‐
48 san is typically useful.
49
50 Docker
51 A good example is the console or standard I/O channel leading into a
52 container or virtualisation system. Docker is a familiar example. If
53 you want to start a Docker container and run a shell directly within
54 it, you might say something like
55
56 docker run -i -t some:image
57
58 which will allow you to run a single shell session inside the con‐
59 tainer, in the same terminal you started Docker from.
60
61 Suppose that you'd prefer to run multiple shell sessions in the same
62 container at once (perhaps so that one of them can use debugging tools
63 to poke at what another is doing). And perhaps inside that container
64 you're going to run a program that you don't trust with full access to
65 your network, but are prepared to let it make one or two specific net‐
66 work connections of the kind you could set up with an SSH port forward‐
67 ing.
68
69 In that case, you could remove the -t option from that Docker command
70 line (which means `allocate a terminal device'), and tell it to run
71 psusan inside the container:
72
73 docker run -i some:image /some/path/to/psusan
74
75 (Of course, you'll need to ensure that psusan is installed somewhere
76 inside the container image.)
77
78 If you do that from a shell command line, you'll see a banner line
79 looking something like this:
80
81 SSHCONNECTION@putty.projects.tartarus.org-2.0-PSUSAN_Release_0.75
82
83 which isn't particularly helpful except that it tells you that psusan
84 has started up successfully.
85
86 To talk to this server usefully, you can set up a PuTTY saved session
87 as follows:
88
89 • Set the protocol to `Bare ssh-connection' (the psusan protocol).
90
91 • Write something in the hostname box. It will appear in PuTTY's
92 window title (if you run GUI PuTTY), so you might want to write
93 something that will remind you what kind of window it is. If you
94 have no opinion, something generic like `dummy' will do.
95
96 • In the `Proxy' configuration panel, set the proxy type to `Lo‐
97 cal', and enter the above `docker run' command in the `Telnet
98 command, or local proxy command' edit box.
99
100 • In the `SSH' configuration panel, you will very likely want to
101 turn on connection sharing. (See below.)
102
103 This arranges that when PuTTY starts up, it will run the Docker command
104 as shown above in place of making a network connection, and talk to
105 that command using the psusan SSH-like protocol.
106
107 The effect is that you will still get a shell session in the context of
108 a Docker container. But this time, it's got all the SSH amenities. If
109 you also turn on connection sharing in the `SSH' configuration panel,
110 then the `Duplicate Session' option will get you a second shell in the
111 same Docker container (instead of a primary shell in a separate in‐
112 stance). You can transfer files in and out of the container while it's
113 running using PSCP or PSFTP; you can forward network ports, X11 pro‐
114 grams, and/or an SSH agent to the container.
115
116 Of course, another way to do all of this would be to run the full SSH
117 protocol over the same channel. This involves more setup: you have to
118 invent an SSH host key for the container, accept it in the client, and
119 deal with it being left behind in your client's host key cache when the
120 container is discarded. And you have to set up some login details in
121 the container: either configure a password, and type it in the client,
122 or copy in the public half of some SSH key you already had. And all
123 this inconvenience is unnecessary, because these are all precautions
124 you need to take when the connection between two systems is going over
125 a hostile network. In this case, it's only going over a kernel IPC
126 channel that's guaranteed to go to the right place, so those safety
127 precautions are redundant, and they only add awkwardness.
128
129 User-mode Linux
130 User-mode Linux is another container type you can talk to in the same
131 way. Here's a small worked example.
132
133 The easiest way to run UML is to use its `hostfs' file system type to
134 give the guest kernel access to the same virtual filesystem as you have
135 on the host. For example, a command line like this gets you a shell
136 prompt inside a UML instance sharing your existing filesystem:
137
138 linux mem=512M rootfstype=hostfs rootflags=/ rw init=/bin/bash
139
140 If you run this at a command line (assuming you have a UML kernel
141 available on your path under the name `linux'), then you should see a
142 lot of kernel startup messages, followed by a shell prompt along the
143 lines of
144
145 root@(none):/#
146
147 To convert this into a psusan-based UML session, we need to adjust the
148 command line so that instead of running bash it runs psusan. But run‐
149 ning psusan directly isn't quite enough, because psusan will depend on
150 a small amount of setup, such as having /proc mounted. So instead, we
151 set the init process to a shell script which will do the necessary
152 setup and then invoke psusan.
153
154 Also, running psusan directly over the UML console device is a bad
155 idea, because then the psusan binary protocol will be mixed with tex‐
156 tual console messages. So a better plan is to redirect UML's console to
157 the standard error of the linux process, and map its standard input and
158 output to a serial port. So the replacement UML command line might look
159 something like this:
160
161 linux mem=512M rootfstype=hostfs rootflags=/ rw \
162 con=fd:2,fd:2 ssl0=fd:0,fd:1 init=/some/path/to/uml-psusan.sh
163
164 And the setup script uml-psusan.sh might look like this:
165
166 #!/bin/bash
167 # Set up vital pseudo-filesystems
168 mount -t proc none /proc
169 mount -t devpts none /dev/pts
170 # Redirect I/O to the serial port, but stderr to the console
171 exec 0<>/dev/ttyS0 1>&0 2>/dev/console
172 # Set the serial port into raw mode, to run a binary protocol
173 stty raw -echo
174 # Choose what shell you want to run inside psusan
175 export SHELL=/bin/bash
176 # Set up a default path
177 export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
178 # And now run psusan over the serial port
179 exec /home/simon/src/putty/misc/psusan
180
181 Now set up a PuTTY saved session as in the Docker example above. Basi‐
182 cally you'll want to use the above linux command as the local proxy
183 command. However, it's worth wrapping it in setsid(1), because when UML
184 terminates, it kills its entire process group. So it's better that
185 PuTTY should not be part of that group, and should have the opportunity
186 to shut down cleanly by itself. So probably you end up setting the
187 proxy command to be something more like:
188
189 setsid linux mem=512M rootfstype=hostfs rootflags=/ rw \
190 con=fd:2,fd:2 ssl0=fd:0,fd:1 init=/some/path/to/uml-psusan.sh
191
192 You may also find that you have to enable the bug workaround that indi‐
193 cates that the server `Discards data sent before its greeting', because
194 otherwise PuTTY's outgoing protocol greeting can be accidentally lost
195 during UML startup. (See Debian bug #991958.)
196
197 Once you've done that, you'll have a PuTTY session that starts up a
198 clean UML instance when you run it, and (if you enabled connection
199 sharing) further instances of the same session will connect to the same
200 instance again.
201
202 Windows Subsystem for Linux
203 On Windows, the default way to use WSL is to run the wsl program, or
204 one of its aliases, in a Windows console, either by launching it from
205 an existing command prompt, or by using a shortcut that opens it in a
206 fresh console. This gives you a Linux terminal environment, but in a
207 Windows console window.
208
209 If you'd prefer to interact with the same environment using PuTTY as
210 the terminal (for example, if you prefer PuTTY's mouse shortcuts for
211 copy and paste), you can set it up by installing psusan in the Linux
212 environment, and then setting up a PuTTY saved session that talks to
213 it. A nice way to do this is to use the name of the WSL distribution as
214 the `host name':
215
216 • set the local proxy command to `wsl -d %host /usr/local/bin/psu‐
217 san' (or wherever you installed psusan in the Linux system)
218
219 • enter the name of a particular WSL distribution in the host name
220 box. (For example, if you installed WSL Debian in the standard
221 way from the Windows store, this will just be `Debian'.)
222
223 • set the protocol to `Bare ssh-connection', as usual.
224
225 Like all the other examples here, this also permits you to forward
226 ports in and out of the WSL environment (e.g. expose a WSL2 network
227 service through the hypervisor's internal NAT), forward Pageant into
228 it, and so on.
229
230 Cygwin
231 Another Unix-like environment on Windows is Cygwin. That comes with its
232 own GUI terminal application, mintty (as it happens, a derivative of
233 PuTTY); but if you'd prefer to use PuTTY itself to talk to your Cygwin
234 terminal sessions, psusan can help.
235
236 To do this, you'll first need to build the Unix PuTTY tools inside Cyg‐
237 win (via the usual cmake method). Then, copy the resulting psusan.exe
238 into Cygwin's /bin directory. (It has to be in that directory for non-
239 Cygwin programs to run it; otherwise it won't be able to find the Cyg‐
240 win DLL at startup.)
241
242 Then set up your PuTTY saved session like this:
243
244 • set the local proxy command to run psusan.exe via its real Win‐
245 dows path. You might also want to add the --sessiondir option so
246 that shell sessions start up in your Cygwin home directory. For
247 example, you might use the command `c:\cygwin64\bin\psusan.exe
248 --sessiondir /home/simon' (changing the pathname and username to
249 match your setup).
250
251 • enter anything you like in the host name box; `Cygwin' is proba‐
252 bly a good choice
253
254 • set the protocol to `Bare ssh-connection', as usual.
255
256 Port forwarding is probably not particularly useful in this case, since
257 Cygwin shares the same network port space as the host machine. But
258 turning on agent forwarding is useful, because then the Cygwin command-
259 line SSH client can talk to Pageant without any further configuration.
260
261 schroot
262 Another example of a container-like environment is the alternative
263 filesystem layout set up by schroot(1).
264
265 schroot is another program that defaults to running an interactive
266 shell session in the terminal you launched it from. But again, you can
267 get a psusan connection into the schroot environment by setting up a
268 PuTTY saved session whose local proxy command is along the lines of
269
270 schroot -c chroot-name /some/path/to/psusan
271
272 Depending on how much of the chroot environment is copied from your
273 main one, you might find this makes it easier to (for example) run X11
274 programs inside the chroot that open windows on your main X display, or
275 transfer files in and out of the chroot.
276
277 Between network namespaces
278 If you've set up multiple network namespaces on a Linux system, with
279 different TCP/IP configurations, then psusan can be a convenient un‐
280 privileged-user gateway between them, if you run it as a non-root user
281 in the non-default one of your namespaces, listening for connections on
282 a Unix-domain socket.
283
284 If you do that, then it gives you convenient control over which of your
285 outgoing network connections use which TCP/IP configuration: you can
286 use PuTTY to run a shell session in the context of the other namespace
287 if you want to run commands like ping, or you can set up individual
288 port forwardings or even a SOCKS server so that processes running in
289 one namespace can send their network connections via the other one.
290
291 For this application, it's probably most convenient to use the --listen
292 option in psusan, which makes it run as a server and listen for connec‐
293 tions on a Unix-domain socket. Then you can enter that socket name in
294 PuTTY's host name configuration field (and also still select the `Bare
295 ssh-connection' protocol option), to connect to that socket as if it
296 were an SSH client.
297
298 Provided the Unix-domain socket is inside a directory that only the
299 right user has access to, this will ensure that authentication is done
300 implicitly by the Linux kernel.
301
302 Between user ids, via GNU userv
303 If you use multiple user ids on the same machine, say for purposes of
304 privilege separation (running some less-trusted program with limited
305 abilities to access all your stuff), then you probably have a `default'
306 or most privileged account where you run your main login session, and
307 sometimes need to run a shell in another account.
308
309 psusan can be used as an access channel between the accounts, using GNU
310 userv(1) as the transport. In the account you want to access, write a
311 userv configuration stanza along the lines of
312
313 if (glob service psusan & glob calling-user my-main-account-name)
314 reset
315 execute /some/path/to/psusan
316 fi
317
318 This gives your main account the right to run the command
319
320 userv my-sub-account-name psusan
321
322 and you can configure that command name as a PuTTY local proxy command,
323 in the same way as most of the previous examples.
324
325 Of course, there are plenty of ways already to access one local account
326 from another, such as sudo. One advantage of doing it this way is that
327 you don't need the system administrator to intervene when you want to
328 change the access controls (e.g. change which of your accounts have ac‐
329 cess to another): as long as you have some means of getting into each
330 account in the first place, and userv is installed, you can make fur‐
331 ther configuration changes without having to bother root about it.
332
333 Another advantage is that it might make file transfer between the ac‐
334 counts easier. If you're the kind of person who keeps your home direc‐
335 tories private, then it's awkward to copy a file from one of your ac‐
336 counts to another just by using the cp command, because there's nowhere
337 convenient that you can leave it in one account where the other one can
338 read it. But with psusan over userv, you don't need any shared piece of
339 filesystem: you can scp files back and forth without any difficulty.
340
342 The command-line options supported by psusan are:
343
344 --listen unix-socket-name
345 Run psusan in listening mode. unix-socket-name is the pathname
346 of a Unix-domain socket to listen on. You should ensure that
347 this pathname is inside a directory whose read and exec permis‐
348 sions are restricted to only the user(s) you want to be able to
349 access the environment that psusan is running in.
350
351 The listening socket has to be a Unix-domain socket. psusan does
352 not provide an option to run over TCP/IP, because the unauthen‐
353 ticated nature of the protocol would make it inherently inse‐
354 cure.
355
356 --listen-once
357 In listening mode, this option causes psusan to listen for only
358 one connection, and exit immediately after that connection ter‐
359 minates.
360
361 --sessiondir pathname
362 This option sets the directory that shell sessions and subpro‐
363 cesses will start in. By default it is psusan's own working di‐
364 rectory, but in some situations it's easier to change it with a
365 command-line option than by wrapping psusan in a script that
366 changes directory before starting it.
367
368 -v, --verbose
369 This option causes psusan to print verbose log messages on its
370 standard error. This is probably most useful in listening mode.
371
372 -sshlog logfile
373
374
375 -sshrawlog logfile
376 These options cause psusan to log protocol details to a file,
377 similarly to the logging options in PuTTY and Plink.
378
379 -sshlog logs decoded SSH packets and other events (those that -v
380 would print). -sshrawlog additionally logs the raw wire data,
381 including the outer packet format and the initial greetings.
382
383
384
385PuTTY tool suite 2020‐12‐13 psusan(1)