Dit artikel schrijf ik enkel in het Engels vanwege het technische karakter.
Many operating systems offer more then only a file system mechanism to store files in a directory structure along with some degree of access control. They are also able to store references to other locations. For example: the Windows operating system supports shortcuts, favorites, libraries, lists of frequently accessed files, symbolic links, hardlinks and junctions. Some are provided by the shell, such as favorites, others by the file system, such as hardlinks. GNU/Linux, a very popular server and IOT operating system, supports both symbolic links and hardlinks.
Symbolic links and the other similar mechanisms (but with slightly different use cases) are quite useful and are frequently used. For instance: symbolic links can be used to have a file always contain the most recent content, while keeping a record of all older versions. Let’s say we create a directory downloads
. In this directory we place a file my-essay-version1.txt
. Next we create a symbolic link my-essay-latest.txt
, which points to the my-essay-version1.txt
file. Now we can always open our essay, and instruct others to do so, using the symbolic link. When we create a new version, we let the symbolic link point to my-essay-version2.txt
. From now on everybody gets the new version of the essay. If anybody needs a specific version, they can do so by directly opening the my-essay-version1.txt
or my-essay-version2.txt
file. When doing this on a webserver or ftp server, this all starts to make sense.
ABFB correctly backs up a file server containing symbolic links. In the resulting backup, a plain text file is created with the name of the symbolic link. This file will have a single line containing the target location of the symbolic link. This is all great, until we have to restore this backup.
There's a known security issue rsync can be vulnerable to in some use cases. In one such case the attacker places a symbolic link on one system that references a very smartly chosen target. On that system, the symbolic link does nothing. But when the symbolic link is transferred by rsync to the second system, it’s suddenly useful to the attacker. As an example on the system that the attacker has access to, he creates a symbolic link referencing ../../../etc/shadow
. When accessing this file, nothing more than a file not found
error will occur. But when the symbolic link is transferred to the other system, a list of all users and their password hashes are suddenly publicly available.
To prevent this from happening, rsync munges all symbolic links by default. Two settings control this behavior: the munge symlinks
and use chroot
setting. Unfortunately both settings are quite unhelpful with ABFB. Setting use chroot
to yes
just breaks ABFB from working at all. Having set munge symlinks
to yes
results in all symbolic links to be restored pointing to /rsyncd-munged/{originionallocation}
. Having set munge symlinks
to no
, results in all symbolic links to have all leading /
and ../
be removed from the link target. The first resulting in all symbolic links to be inaccessible. The second resulting in all symbolic links to absolute paths to break and many symbolic links to other directories to break.
When useful in your use case, you can set the munge symlinks
to no
through the shell.
$ sudo vim /etc/rsyncd.conf
#motd file = /etc/rsyncd.motd
#log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
use chroot = no
munge symlinks = no
However in our particular use case this will not work; all symbolic links point to a directory higher up in the directory structure. The rsync developers do offer a solution though. Along with rsync, a script munge-symlinks
is shipped, which is located in the support directory. However our file server to be backed up by ABFB is also a Synology NAS. Synology does not ship their NASes with this script, nor can it be easily used as the script is written in perl.
Luckily the NAS does come with all the GNU tools needed to solve the issue.
$ sudo vim /usr/local/bin/munge-symlinks
#!/bin/bash
if [ -z "\$1" ] || [ "\$1" != "--unmunge" ] ; then
echo "Usage: \$0 --unmunge [DIR|SYMLINK]"
echo "Unmunge symlinks in the directory DIR (the current directory by default) or of the symbolic link SYMLINK."
echo ""
echo " --unmunge Remove \\'rsyncd-munged\\' prefix from symlinks"
exit 1
fi
[ -z "$2" ] && location=`pwd` || location="\$2"
if [ -d "\$location" ] || [ -h "\$location" ]; then
find -P "\$location" -lname /rsyncd-munged/* | while read link; do
target=$(readlink "\$link" | sed s/\\\\/rsyncd-munged\\\\///)
echo "Unmunging link \$link to \$target"
rm "\$link" && ln -s "\$target" "\$link"
done
else
echo "\$0: \\`\$location': Is not a directory or symbolic link"
exit 1
fi
$ sudo chmod +x /usr/local/bin/munge-symlinks
Now after we restore a backup from the ABFB Portal, we login with ssh, kitty or putty to our NAS and run the script.
$ munge-symlinks --unmunge /volume3/projects/current
Unmunging link /volume3/projects/current/launchvehicle to ../2021/launchvehicle
Unmunging link /volume3/projects/current/neverendingstory to ../1970/neverendingstory
Unmunging link /volume3/projects/current/rocketship to ../2020/rocketship