Skip to main content

Installing borg backup on an old Fedora Core 8 server

 If you're coming from the Wild West of servers, you may have the occasional old/unmaintained/13 year uptime server living fine and well in your management. You know you desperately need to wipe the server and reinstall a modern OS, but alas, there is no time for that and you need to add new software on top of old servers.

Well, strap in, it's going to be a long journey.

So - the goal is to install https://www.borgbackup.org/ on a server that is so old that it doesn't even know how to connect to https sites anymore, because its openssl uses TLS 1.0. The server comes with perl-5.8.8, openssl 0.9.8b, python 2.5.1 and we need to install a python3 program that requires openssl 1.1.

 $ wget https://github.com/borgbackup/borg/releases/download/1.1.10/borg-linux64

 --11:52:45--  https://github.com/borgbackup/borg/releases/download/1.1.10/borg-linux64
           => `borg-linux64'
Resolving github.com... 140.82.121.4
Connecting to github.com|140.82.121.4|:443... connected.
OpenSSL: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
Unable to establish SSL connection.

That is why we will consider that this old server is on an isolated network and can't connect to the internet.

Challenge accepted!

So - why can't I just take a precompiled borg binary (that bundles python3.5) from the borg backup release page, like this (https://github.com/borgbackup/borg/releases/download/1.1.10/borg-linux64)? Here's why:

$ /usr/local/bin/borg-linux64

Error loading Python lib '/tmp/_MEIhppGHJ/libpython3.5m.so.1.0': /lib64/libc.so.6: version `GLIBC_2.9' not found (required by /tmp/_MEIhppGHJ/libpython3.5m.so.1.0)

My glibc version is too old and doesn't have the required functions needed by the precompiled binary:

$ /lib/libc.so.6 | head -1
GNU C Library stable release version 2.7, by Roland McGrath et al.

The plan

So - we need to:

- compile perl 5.34 locally (needed to compile openssl)

- compile openssl 1.1 locally

- compile python 3.9 locally

- transfer borgbackup package and install locally

- profit!

Compiling Perl

To install perl from source you can easily follow the steps outlined here: http://www.cpan.org/src/. You will need to have gcc and make installed in your local Linux distro. I used gcc 4.1.2 and it worked fine. You will probably need to download the source on a computer that can speak HTTPS and transfer it (e.g. scp) to your destination server.

$ wget https://www.cpan.org/src/5.0/perl-5.34.0.tar.gz
$ tar -xzf perl-5.34.0.tar.gz
$ cd perl-5.34.0
$ ./Configure -des -Dprefix=/opt/perl5/

$ make
$ make test
$ make install

The make test step will take a while. Once it finishes, you should have a working perl in /opt/perl5. You can test it with:

$ /opt/perl5/bin/perl --version

This is perl 5, version 34, subversion 0 (v5.34.0) built for x86_64-linux

Copyright 1987-2021, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.


Compiling openssl

You can get openssl-1.1.1k from here: https://www.openssl.org/source/openssl-1.1.1k.tar.gz

$ wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz
$ tar zxvf openssl-1.1.1k.tar.gz
$ cd openssl-1.1.1k
$ PATH=/opt/perl5/bin:$PATH
$ ./config --prefix=/opt/openssl11 --openssldir=/opt/openssl11/ssl
$ make
$ sudo make install
# ln -s /opt/openssl11/ /usr/local/openssl

Note, this openssl version does not override your system openssl, because that may break things.

Compiling Python3

Python needs some nonstandard linux packages in order to be compiled. You'll need to track down and install the following:

* libffi

* libffi-devel

* zlib

* zlib-devel

$ wget https://www.python.org/ftp/python/3.9.5/Python-3.9.5.tgz

$ tar zxvf Python-3.9.5.tgz

$ cd Python-3.9.5

$ ./configure --prefix=/opt/python3 --enable-unicode=ucs4 --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib" 

$ make 

$ make install

In order to run python you'll need to tell the loader where it can load the python library:

$ cat /etc/ld.so.conf.d/python-3.9.5.conf
/opt/python2/lib

$ sudo ldconfig

Now, you should be able to run python3:

$ /opt/python3/bin/python3 --version
Python 3.9.5

Compiling borg backup

In addition to all this build environment that we've set up, borg backup also needs:

* gcc-c++

* libattr

* libattr-devel

* libacl

* libacl-devel

So you'll need to track down those packages for your distribution and install them. In my case I had to force downgrade some of them because I had libacl installed and could only find a slightly older libacl-devel:

$ sudo rpm -Uvh --oldpackage libacl-2.2.39-10.fc8.x86_64.rpm 

Now comes the tricky part. You'll need to download borg backup and its dependencies from PyPy, but since you don't have connectivity (python3 was not bound to the new openssl) you'll need to do it on a different system. The problem is, on the intermediary system you'll need to run the same python version as the target, so that it downloads the correct wheels. So - you might need to rerun the python3 installation steps on the intermediary system before you proceed.

To download borg backup + dependencies, on an intermediary system, do:

$ mkdir to-transfer

$ cd to-transfer

$ /opt/python3/bin/pip3 download borgbackup

$ /opt/python3/bin/pip3 download "setuptools_scm>=1.7"

$ /opt/python3/bin/pip3 download "setuptools==57"

Transfer the downloaded files to the target server and install them:

$ sudo /opt/python3/bin/python3 -m pip install setuptools-57.0.0-py3-none-any.whl

$ sudo /opt/python3/bin/python3 -m pip install setuptools_scm-6.0.1-py3-none-any.whl

$ tar zxvf borgbackup-1.1.16.tar.gz

$ cd borgbackup-1.1.16 

$ sudo /opt/python3/bin/python3 -m pip install .

Once the installation finishes correctly you should have /opt/python3/bin/borg you can play with:

$ /opt/python3/bin/borg -v
Traceback (most recent call last):
  File "/opt/python3/lib/python3.9/site-packages/borg/archiver.py", line 38, in <module>
    from . import helpers
  File "/opt/python3/lib/python3.9/site-packages/borg/helpers.py", line 76, in <module>
    import borg.crypto.low_level
ImportError: libcrypto.so.1.1: cannot open shared object file: No such file or directory

But to make it run, you'll need to prefix it with the correct path to openssl:

$ LD_LIBRARY_PATH=/opt/openssl11/lib:$LD_LIBRARY_PATH /opt/python3/bin/borg -V
borg 1.1.16

In order to make that nice and quick to remember, let's make a simple shell script:

$ cat /usr/local/bin/borg
#!/bin/bash
LD_LIBRARY_PATH=/opt/openssl11/lib:$LD_LIBRARY_PATH /opt/python3/bin/borg "$@"


Moral of the story? Old servers can be a pain to maintain, but there's little reason they can't run more modern software...

Comments

Popular posts from this blog

Home Assistant + Android TV = fun

Here's a quick setup guide for controlling your Android TV from within Home Assistant. I've used it to control a genuine Android TV (Philips 7304) and an Odroid N2 running Android TV. For this to work you need ADB access. It can usually be enabled from within Developer Settings. The great part is - you don't need root access! The most important things are described in the androidtv component for Home Assistant: https://www.home-assistant.io/integrations/androidtv/ Make sure you go through the adb setup. My configuration is simple (inside configuration.yaml): media_player:   - platform: androidtv     name: TV Bedroom ATV     host: 192.168.1.61     device_class: androidtv Once Home Assistant restarts, your TV might require you to accept the connection (adb authentication). This happens only once (or until you reset your ATV to factory settings). Once running the integration will show you the current ATV state (on or off) and al...

SmokePing + InfluxDB export + docker + slaves + Grafana = fun

I've been working for a while on this project - with the purpose of getting SmokePing measurements from different hosts (slaves) into InfluxDB so that we can better graph them with Grafana. The slaves run multiple Smokeping instances inside Docker so that they have separate networking (measure through different uplinks, independently). This will not be a comprehensive configuration guide, but a quick "how to" to handle setup and basic troubleshooting. It assumes you already know how to set up and operate a regular Smokeping install with or without slaves and that you are fluent in Smokeping configuration syntax, know your way around Docker and aren't a stranger from InfluxDB and Grafana (sorry, there's a lot of information to take in). 1. Getting Smokeping with InfluxDB support - you can get it either from the official page (most changes have been merged) - https://github.com/oetiker/SmokePing (PR discussion here: https://github.com/oetiker/SmokePing/issues/...

Installing Home Assistant Supervised on an old 32bit HP laptop

 I've received a challenge from my former boss: an old HP laptop that was born in 2005:  an HP-Compaq NC6220 ( https://www.pocket-lint.com/laptops/reviews/hp/68181-hp-compaq-nc6220-notebook-laptop/ ). The specs are abysmal: So, i386, 1.7GHz single-core CPU (remember those?), 1G of DDR2 RAM (2x512M) and a 40GB ATA (not SATA!) drive. But hey, at least it has a serial port!  The challenge is to install HomeAssistant ( https://www.home-assistant.io/ ) on it so that he can monitor some Zigbee temperature sensors and relays (via a gateway). The first hurdle was to remove the BIOS password - following this nice guide: https://www.youtube.com/watch?v=ZaGKyb0ntSg Next-up - install HASSOS. Unfortunately, it doesn't support i386, but only x86_64... So, I went the Home Assistant Supervised route, and installed Debian 11 i386 edition from a netinstall USB ( https://cdimage.debian.org/debian-cd/current/i386/iso-cd/debian-11.6.0-i386-netinst.iso ).   Once Debian was up and run...