Here I'm republishing an old blog post of mine originally from January 2017. The article has been slightly improved.
In part one I wrote about Legacy systems in general and showed a FreeBSD 4.11 installation for those of my readers who are interested in software history.
Updating FreeBSD 4.11 (1/4) - Blast from the past
This post is about the first part of updating this fresh 4.11 system to a state that's a bit less catastrophic. Remember: FreeBSD 4.11 was released in 2005 - however the ABI of each release is carved in stone with a .0 release. Which means that the software in the base system is from 4.0 and thus we venture back into the last millenium: 1999!
To give you an idea what this means, here are a few program versions:
Various program's versions in a 4.11 base system (PNG)
So we have these programs among others:
To make matters worse, the ports tree for FreeBSD 4.11 is pretty dead, too. It's important to get newer compilers running, but around 2005 FreeBSD used special releases to build GCC from ("gcc-core") and I was not able to find a single mirror on the net that still holds those old and exotic files! Out of luck here. We'll have to do without those ports.
"Modernizing" this is going to be interesting... Considering how fast the IT world moves, all of this is just as dead as it gets. So let's prepare for the (code) smell and start digging up an old grave, shall we?
After a passwordless login as root it makes sense to set up the right keymap (if you don't use the default, that is). I had no idea how to do it on 4.11 and so I just gave the usual way of doing it a try - and was met with success:
# kbdmap
Looks like the keymap selection has not changed in all the time! Let's try to make it persistent:
# echo keymap=german.iso.kbd >> /etc/rc.conf
I tried it out and it did just what I wanted. Time to try to add a regular user:
# adduser
The script is a bit different from what we're used to today, but in the end it does the same thing: Allow us to create a user. It's important to add this user to the _wheel_ group so that we're able to _su_ to root. However we need to give root a password first:
The useradd script in FreeBSD 4.11 (PNG)
# passwd
Ok, _sshd_ should be running. Let's check just to be sure:
# ps aux | grep sshd
[...]
root 75 0.0 0.1 2600 2040 ?? Is 6:26AM 0:00.11 /usr/sbin/sshd
Looks good. What about network connectivity? Let's see:
# ifconfig
vr0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 00:05:5d:96:fa:f9
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
[...]
Nope, no connection without an IP address! Luckily I paid attention when the installer started from the CD and somehow the strange-looking path of _/stand_ caught my eye. Doing a little research, I found out that this directory used to be part of the OS and was removed in early FreeBSD 5 as it was mostly redundant with _/rescue_. What was in there, you ask? Have a look yourself:
# ls /stand
-sh etc minigzip rm tunefs
[ find mount_mfs route usbd
arp fsck mount_nfs rtsol usbdevs
boot_crunch gunzip newfs sed zcat
camcontrol gzip pccardc sh
cpio help pccardd slattach
dhclient hostname ppp sysinstall
dhclient-script ifconfig pwd test
There's our friend _sysinstall_. I already said that it does more than just install the system. So let's bring it up now:
# /stand/sysinstall
Sysinstall to configure the network (PNG)
There we choose _Networking_ -> _Interfaces_ -> the appropriate NIC. No, I don't want IPv6 and yes, DHCP is the thing.
Interface configuration using sysinstall (PNG)
I've called the system _vierelf_ which would be "foureleven" in English because I couldn't think of anything better. And it's just a test system anyway. Does the connection work now?
Alright! Let's just take a look what services are listening right now:
# sockstat -4 -l
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
root dhclient 281 7 udp4 *:68 *:*
root sendmail 84 4 tcp4 *:25 *:*
root sendmail 84 6 tcp4 *:587 *:*
root sshd 75 4 tcp4 *:22 *:*
root syslogd 61 5 udp4 *:514 *:*
Ugh! Time to make a few changes in /etc/rc.conf to deactivate all daemons except for SSH (which we need). This may not be strictly necessary, but we want to improve the security of this system, right? And I wouldn't trust those crusty old daemons at all. And whatever is not running won't cause us any problems. So let's get rid of them with extreme prejudice!
# vi /etc/rc.conf
To do so, add *daemonname_enable="NO"* for each daemon and in case of sendmail use *sendmail_enable="NONE"*.
FreeBSD 4.11 rc.conf with most daemons disabled (PNG)
If you reboot now, sendmail and syslogd as well as cron, usbd and inetd will be disabled. That's a starting point in securing the system. Let's move on.
I'll connect to the 4.11 box remotely over SSH because it's much more convenient to have my trusty terminal at hand and to be able to copy and paste stuff:
% ssh kraileth@192.168.1.5
Unable to negotiate with 192.168.1.5 port 22: no matching host key type found. Their offer: ssh-dss
Ouch! I cannot even SSH into the system because its version of OpenSSH is so old that it only offers _ssh-dss_ keys which have been deprecated for quite a while and disabled by default in OpenSSH >=7.0. So to connect to that old server, I have to tell my SSH client to accept ssh-dss for this connection:
% ssh kraileth@192.168.1.5 -oHostKeyAlgorithms=+ssh-dss
SSH login using "-oHostKeyAlgorithms=+ssh-dss"
Ok, I'm in. But what now? We cannot use FreeBSD's ports tree but I strongly prefer some means of package management over building stuff completely manually and installing it using _make install_. So how do we accomplish this? Enter _pkgsrc_. Pkgsrc is basically NetBSD's fork of the FreeBSD ports tree. Being a NetBSD project however, it's not limited to just NetBSD. It’s a truely portable way of building and managing software (I might write a separate post about it some time).
There's just one problem: Downloading and decompressing the latest pkgsrc release (currently 2016Q4) won't complete the bootstrapping process. Obviously FreeBSD 4.11 is no longer supported - which is not that much of a surprise. Time to try out older releases! After doing so I found out that _2009Q4_ seems to be the last release to bootstrap successfully.
But here's another problem: Pkgsrc doesn't seem to keep older releases around and I also haven't found them mirrored anywhere on the net. Pkgsrc uses CVS, however. So it's possible to checkout older versions. FreeBSD 4.11 comes with CVS as part of the base system. Unfortunately CVS works over SSH. And NetBSD's CVS server won't accept ssh-dss (which totally makes sense)! Since we don't control the server, there's also no way to just add a parameter or something to make it work. It simply doesn't work that way.
Time to get CVS installed on my slightly more modern *FreeBSD 11*, do the checkout there and tar it all up to copy it over via _scp_! We're going to get _2007Q2_ instead, though, since we need things that won't work on FreeBSD 4.11 with later versions. Oh, and if you're not familiar with CVS, don't worry. You don't need to know what _modules_ or _tags_ are. Just copy the commands that I prepared for you and you're good to go:
(Do this on your own machine, not the 4.11 one! And of course replace the IP address with the one for your test machine.)
% sudo pkg install cvs
% cvs -danoncvs@anoncvs.netbsd.org:/cvsroot get -rpkgsrc-2007Q2 -P pkgsrc
% tar cvjf pkgsrc2007Q2.tbz2 pkgsrc/*
% scp pkgsrc2007Q2.tbz2 kraileth@192.168.1.5:/usr/home/kraileth
Then back on the vierelf box, the next step is to prepare some directories and extract the pkgsrc tarball:
# mkdir -p /usr/local/temp /usr/pkgsrc
# cd /usr/pkgsrc
# mv /usr/home/kraileth/pkgsrc2007Q2.tbz2 .
# tar xvjf pkgsrc2007Q2
# rm pkgsrc2007Q2.tbz2
# mv pkgsrc 07
Now we can bootstrap pkgsrc:
# cd /usr/pkgsrc/07/bootstrap
# ./bootstrap --prefix=/usr/local/temp --varbase=/usr/local/temp --pkgdbdir=/usr/local/temp/db
Pkgsrc 2007Q2 bootstrap complete! (PNG)
Pkgsrc has been bootstrapped successfully! We just need to adjust the PATH variable so that the system picks up binaries from the new paths (and make those take precedence over the old system binaries). We could just change the PATH variable directly but it's better to make the changes persistent. So let's add the two new paths in the shell's rc file in front of the others:
# vi /root/.cshrc
This is what needs to be prepended:
/usr/local/temp/sbin /usr/local/temp/bin
Root's .cshrc file for the first phase pkgsrc (PNG)
Now simply log out and become root again to have the new environment:
# logout
> su -
As a last step check if everything is right and we can access binaries in both paths:
# which bmake
/usr/local/temp/bin/bmake
# pkg_info
bootstrap-mk-files-20061111 *.mk files for the bootstrap bmake utility
bmake-20051105nb3 Portable (autoconf) version of NetBSD 'make' utility
tnftp-20050625nb1 The enhanced FTP client in NetBSD
mtree-20070710 Utility for mapping and checking directory hierarchies
pax-20060202nb1 POSIX standard archiver with many extensions
pkg_install-20070710 Package management and administration tools for pkgsrc
Excellent! Now we have a working replacement for FreeBSD's dead ports tree. This is definitely something that we can build upon.
Lame pun, I know. Nevertheless it makes sense to... err... update the OS to the latest version. This is what we currently have:
# uname -a
FreeBSD vierelf.localdomain 4.11-RELEASE FreeBSD 4.11-RELEASE #0: Fri Jan 21 17:21:22 GMT 2005 root@perseus.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386
We're on 4.11-RELEASE. The latest code for each release cycle is always in the -STABLE branch. Believe it or not: The latest code change was in April of 2014! The traditional way of getting FreeBSD code was over _CVS_. No, this time the problem is not ssh-dss. FreeBSD migrated from CVS to SVN (subversion) in 2008 [and then to Git in 2020]. FreeBSD CVS servers have been removed years ago. Therefore the old tools like _cvsup_ are useless. _Subversion_ is needed to checkout the source.
Luckily we have our pkgsrc ready. This old release has a very old port for subversion but that's fair enough. There are a few source tarballs that are no longer available from the mirrors that pkgsrc knew for them. Not a big problem though, we can download those manually:
# cd /usr/pkgsrc/07/distfiles
# fetch http://archive.apache.org/dist/httpd/httpd-2.0.61.tar.bz2
# fetch http://repository.timesys.com/buildsources/e/expat/expat-2.0.1/expat-2.0.1.tar.gz
# fetch http://download.nust.na/pub2/openpkg1/sources/DST/pkgconfig/pkg-config-0.21.tar.gz
Now we can build subversion:
# cd /usr/pkgsrc/07/devel/subversion-base
# bmake install clean clean-depends
Various dependencies will be downloaded, built and installed. Eventually subversion will be installed and become available on the system. Time to tell the shell to look for new binaries and then checkout the stable source code:
# rehash
# svn co svn://svn.freebsd.org/base/stable/4 /usr/src
SVN checkout of the 4.11-STABLE code (PNG)
The FreeBSD 4 base system never knew anything beyond CVS and cannot cope with the _.svn_ directories that the svn checkout creates. World builds but the installation fails like this:
install: /usr/libdata/perl/5.00503/./.svn/text-base/Cwd.pm.svn-base: No such file or directory
Therefore it's necessary to get rid of those disruptive directories:
# cd /usr/src
# find . -iname '.svn' -exec rm -rf {} \;
Now we can build world and kernel, install both and reboot the system:
# make buildworld
# make buildkernel
# make installkernel
# make installworld
# shutdown -r now
When the system comes back up we can SSH into it again. And there we can see that we're on -STABLE now!
The newly built FreeBSD 4.11-STABLE (PNG)
# uname -a
FreeBSD vierelf.localdomain 4.11-STABLE FreeBSD 4.11-STABLE #0: Sat Jan 28 11:53:06 GMT 2017 root@vierelf.localdomain:/usr/obj/usr/src/sys/GENERIC i386
That's it for today. We're not quite there yet, but we've laid the groundwork for many more updates to come. Those will be described in the coming two posts of this mini series.
Updating FreeBSD 4.11 (3/4) - Neophyte's notorious necromancy