A recent vulnerability in GNU screen caused some people to reconsider their commitment to the venerable terminal multiplexing program, typically used by thousands of old sysadmins around the world to run long-standing processes and, particularly, IRC sessions.
Hardening my bouncer
Back in March 2019, I had already switched away from screen for
IRC, but not to tmux like many did, but to dtach. I
figured that I didn't actually need multiplexing to run my
long-running IRC session: I just needed to be able to reattach to the
terminal. That's what dtach
does. No windows, no panes, and,
especially, no way to start a new shell, which is exactly the kind of
hardening I needed to.
So I came up with this, to start irssi
:
dtach -N /run/$USER/dtach-irssi.socket irssi
To attach:
dtach -a /run/$USER/dtach-irssi.socket
Fairly simple no? Already one attack vector gone.
Splitting into another user
But why stop there! Why am I running irssi
as my main user anyways!
Let's take the lessons from good UNIX security, and run this as a
separate user. This requires me to create another user, say
foo-irc
:
adduser foo-irc
... and run it as a systemd service (because why not). Then I come up with this unit file:
[Unit]
Description=IRC screen session
After=network.target
[Service]
Type=simple
Environment="TERM=screen.xterm-256color"
User=%i
RuntimeDirectory=%i
ExecStart=-/usr/bin/dtach -N /run/%i/dtach-irssi.socket irssi
ExecStop=-/bin/sh -c 'echo /quit stopping service... | exec /usr/bin/dtach -p /run/%i/dtach-irssi.socket'
ExecReload=-/bin/sh -c 'echo /restart | exec /usr/bin/dtach -p /run/%i/dtach-irssi.socket'
Notice this is a service template, because of the %i
stuff. I don't
actually remember how to enable this thing, but let's say you drop
this in /etc/systemd/system/irssi@.service
, then you run:
systemctl daemon-reload
And then instanciate that template:
systemctl enable irssi@foo-irc.service
And then this should start the irssi session:
systemctl start irssi@foo-irc.service
To access the session:
sudo -u foo-irc dtach -a /run/foo-irc/dtach-irssi.socket
Obviously, you will probably need to migrate your irssi configuration over, otherwise you'll end up with a blank, old-school irssi. Take a moment to savor the view though. Nostalgia. Ah.
Hardening irssi
But this is still not enough. That pesky foo-irc
user can still
launch arbitrary commands, thanks to irssi /exec
(and a generous
Perl scripting environment). Let's throw the entire kitchen sink at it
and see what stinks. At this point, the unit file becomes too long to
just list here, so just look at this git repository instead.
Configuration management
And at this point, you will have noticed that you shouldn't actually
followed my instructions to the letter, and just use this neat little
Puppet module which does all of the above, but also include some
little wrapper so that mosh
still works.
It also includes instructions on how to setup your SSH keys.
Enjoy.