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/...

Android: Adding scp/sftp support to dropbear and mounting with sshfs

I have recently received an android smartphone, and one of the first things I did with it was to root it :). This allows power-usres to get the most out of their hardware. The next thing on my list was to set up a SSH server and to be able to transfer files between my Linux system and my phone (by the way, I'm running Android 4.1 and it seems USB mass storage support has been removed. MTP/PTP modes have either horrible transfer speed or are poorly supported in Ubuntu). With the above in mind, the plan was to: Enable tethering on the phone Run a SSH server to support issuing remote commands and file transfer (FTP might have been an alternative, but I'm a SSH adept). Browsing the market I found  SSHDroid which does all that it advertised. Problem is - the free version conflicts with my add-blocking apps and requests that they are disabled to run. For me, this is a big nuisance, so I kept looking. I found Dropbear SSH Server 2 , which is completely free, but doesn'...