Working with old SSH versions
Here’s a quick post about something that I had been meaning to work out for a while now. It’s one of those posts that’s really meant as a note to myself, but it might be useful to someone else too.
I work in a computing environment with a significant number of ancient systems that I still need to access via ssh. The software on these systems cannot be updated for a variety of reasons. I want to keep my client system(s) updated with ssh software and crypto policies, but doing so often breaks my access to these old systems due to the deprecation and removal of various features, protocols, ciphers, methods, etc.
Over time, I’ve wrestled with several approaches to deal with this:
- maintaining the necessary legacy options for each host or groups of hosts in your
.ssh/config
file. This might work for a while until your ssh client software eventually removes those legacy options entirely. It’s also a minor nuisance to regularly keep that config file updated. - maintaining a full-size trusted intermediary environment (e.g., a jumphost VM) that has a slightly less ancient version of ssh that can still negotiate with your truly ancient systems. Likewise, this will also work for a while until your client software can no longer even negotiate with the ssh server on the jumphost. At this point, you might be tempted to just update the ssh on the jumphost, but then you can’t be guaranteed that its updated ssh client will still negotiate with the truly ancient systems that you’re interested in anymore. Similar results can be achieved with a full-blown
chroot
ed distribution directory (e.g.,debootstrap
), but in either case this approach still feels clumsy and bloated to me. - compiling your own personal copy of an old ssh version from source. This one can be difficult since ssh is a complicated software system with lots of dependencies that also need to be accounted for. It’s also not very portable as you’d have to do it for each client system that you want to maintain access from (and hopefully you don’t have many…) On the plus side, once you have this working in one specific client environment, it should continue to work in that environment for a long time.
I was never really happy with any of these solutions. I found that a simple way to maintain an old ssh version is to create a tiny container with an correspondingly ancient version of ssh in it:
$ podman run --name oldssh -it alpine:3.1
/ # apk update; apk add openssh
fetch http://dl-cdn.alpinelinux.org/alpine/v3.1/main/x86_64/APKINDEX.tar.gz
v3.1.4-336-gba3dc3d [http://dl-cdn.alpinelinux.org/alpine/v3.1/main]
OK: 4861 distinct packages available
(1/2) Installing openssh-client (6.7_p1-r6)
(2/2) Installing openssh (6.7_p1-r6)
Executing busybox-1.22.1-r15.trigger
OK: 9 MiB in 17 packages
/ # exit
$ podman commit oldssh oldssh
Getting image source signatures
Copying blob d4c261b2e248 skipped: already exists
Copying blob 4b3ef764ab00 done |
Copying config 01a7e11544 done |
Writing manifest to image destination
01a7e115443af74f2b219e264da51289df1e75cecd099e28a9911712c7f8a71d
then:
$ cat ~/bin/oldssh
podman run --rm -it -v $HOME/.ssh:/root/.ssh:Z,ro -v $HOME/.ssh/oldssh-config:/root/.ssh/config:Z,ro oldssh ssh $@
$ oldssh root@10.19.146.7 # a destination host that I can no longer connect to directly from my host's native ssh environment
Enter passphrase for key '/root/.ssh/id_rsa':
Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 3.13.0-95-generic x86_64)
...
My .ssh/config
file in my host environment contains many configuration options that are unknown to the old client version in the container, so I moved those offending options to a separate legacy config file, .ssh/oldssh-config
, and bound that to the default config in the container. Also, note that this solution does not attempt to connect to the ssh-agent
running on the host system because that program has dependencies on that ssh environment.
The advantages to this method are:
- portablity and reproducibility - you should be able to reproduce this on any client system with a container engine
- reliability - this environment should not be brittle to native software changes in the client host
- size - the resulting
oldssh
container image was only 9.74MB