Loopback Tricks

Some filesystems have very limited capabilities. In particular, one will find:

Warning

Unfortunately, the Network Security Toolkit probe can't do much about the risk with writing to NTFS file systems. I just wouldn't recommend writing to these systems period (maybe there will be a point in the future where NTFS write support will be considered risk free - but we aren't there yet). So, if your only available disk space lies on a NTFS partition, it is recommended that you skip the remainder of this section.

These limitations are not typically a big issue when transferring files. However, if one wants to make use of the space on one of these limited file systems, they will often run across permission and/or ownership errors that would not be encountered on a ext3 file system. For example, if the directory DIR lies on one of these limited file systems, one will find that invoking the setup_mysql -rdir DIR will fail because of ownership and permission issues. Hence you won't be able to keep a permanent copy of your SQL databases on one of these limited file systems.

However, if the root user can create and write to a single file on any of these limited file systems, we can treat that file as its own partition through the magic of the Linux loop back device.

Note

Much of the following information was gleaned through the result of a Google search that found the Backup ideas web page.

Mounting A File As A Filesystem

In the following example, I'm going to mount my USB thumb drive to /mnt/limited and create and prepare a 20MB file called nst.lp that will be used to emulate a full ext3 file system (even though it resides on a FAT file system).

Figure 4.9. Preparing a ext3 File System on a FAT Thumb Drive.

[root@probe root]# mkdir /mnt/limited
[root@probe root]# mount -t vfat /dev/sda1 /mnt/limited
[root@probe root]# df -k /mnt/limited
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda1               127716     90318     37398  71% /mnt/limited
[root@probe root]# dd if=/dev/zero of=/mnt/limited/nst.lp bs=1048576 count=20
20+0 records in
20+0 records out
[root@probe root]# mkfs.ext3 /mnt/limited/nst.lp
mke2fs 1.32 (09-Nov-2002)
/mnt/limited/nst.lp is not a block special device.
Proceed anyway? (y,n) y
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
5136 inodes, 20480 blocks
1024 blocks (5.00%) reserved for the super user
First data block=1
3 block groups
8192 blocks per group, 8192 fragments per group
1712 inodes per group
Superblock backups stored on blocks:
        8193
 
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
 
This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
[root@probe root]# tune2fs -i 0 -c 0 /mnt/limited/nst.lp
tune2fs 1.32 (09-Nov-2002)
Setting maximal mount count to -1
Setting interval between check 0 seconds
[root@probe root]# 

At this point, we now have the 20MB file /mnt/limited/nst.lp prepared such that we can mount it like a ext3 file system via the loop back device. We will now create a new mount point and verify that the standard file operations are supported. Notice how the noatime option was added (this prevents updates to the file system each time a file is accessed - flash drives have a limited number of writes).

Figure 4.10. Mounting a Virtual ext3 File System on a FAT Thumb Drive.

[root@probe root]# mkdir /mnt/loop
[root@probe root]# echo '/mnt/limited/nst.lp /mnt/loop ext3 loop,sync,noatime 0 0' \
>>/etc/fstab
[root@probe root]# mount /mnt/loop
[root@probe root]# ls -l /mnt/loop
total 12
drwx------    2 root     root        12288 Jun 17 12:06 lost+found
[root@probe root]# cp /etc/hosts /mnt/loop
[root@probe root]# chown mysql.nobody /mnt/loop/hosts
[root@probe root]# ls -l /mnt/loop/hosts
-rw-r--r--    1 mysql    nobody        600 Jun 17 12:20 /mnt/loop/hosts
[root@probe root]# chmod 700 /mnt/loop/hosts
[root@probe root]# ls -l /mnt/loop/hosts
-rwx------    1 mysql    nobody        600 Jun 17 12:20 /mnt/loop/hosts
[root@probe root]# df -k
Filesystem           1K-blocks      Used Available Use% Mounted on
/mnt/limited/nst.lp      19827      1044     17759   6% /mnt/loop
[root@probe root]# rm /mnt/loop/hosts
[root@probe root]# df -k
total 12
drwx------    2 root     root        12288 Jun 17 12:06 lost+found
[root@probe root]# setup_mysql -rdir /mnt/loop
 
*** Successfully started up a MySQL database server...
 
[root@probe root]# du /mnt/loop
12      /mnt/loop/lost+found
66      /mnt/loop/var/lib/mysql/mysql
1       /mnt/loop/var/lib/mysql/test
68      /mnt/loop/var/lib/mysql
69      /mnt/loop/var/lib
70      /mnt/loop/var
83      /mnt/loop
[root@probe root]# 

By using the loop back trick, I was able to let mysql make use of the available space on my USB thumb drive (and thus save a permanent copy of my snort logs).

Note

While the loop back trick is handy in a pinch, it should not be used in a situation where you need every ounce of performance that you can get. There is a significant amount of overhead involved when using a loop back device.

Mounting a ISO Image

You can make use of the loop option on the mount command to mount a ISO image and access the files it contains.

[root@probe root]# mkdir /mnt/iso
[root@probe root]# mount -t iso9660 -o loop,ro /tmp/nst-1.0.5.iso /mnt/iso
[root@probe root]# mount
/dev/hda2 on / type ext3 (rw)
none on /proc type proc (rw)
usbdevfs on /proc/bus/usb type usbdevfs (rw)
none on /dev/pts type devpts (rw,gid=5,mode=620)
none on /dev/shm type tmpfs (rw)
/tmp/nst-1.0.5.iso on /mnt/iso type iso9660 (ro,loop=/dev/loop0)
[root@probe root]# losetup /dev/loop0
/dev/loop0: [0302]:213066 (/tmp/nst-1.0.5.iso) offset 0, no encryption
[root@probe root]# ls /mnt/iso
etc  isolinux  local  modules  README  README.html  utils
[root@probe root]# gzip -dc /mnt/iso/isolinux/initrdr9.gz > /tmp/initrd
[root@probe root]# umount /mnt/iso
[root@probe root]# 

Here is another way of mounting an ISO image by manually chosing the loop device with the losetup command.

[root@probe root]# mkdir /mnt/iso
[root@probe root]# losetup /dev/loop4 /tmp/nst-1.0.5.iso
[root@probe root]# mount -t iso9660 -o ro /dev/loop4 /mnt/iso
[root@probe root]# mount
/dev/hda2 on / type ext3 (rw)
none on /proc type proc (rw)
usbdevfs on /proc/bus/usb type usbdevfs (rw)
none on /dev/pts type devpts (rw,gid=5,mode=620)
none on /dev/shm type tmpfs (rw)
/dev/loop4 on /mnt/iso type iso9660 (ro)
[root@probe root]# losetup /dev/loop4
/dev/loop4: [0302]:213066 (/tmp/nst-1.0.5.iso) offset 0, no encryption
[root@probe root]# ls /mnt/iso
etc  isolinux  local  modules  README  README.html  utils
[root@probe root]# gzip -dc /mnt/iso/isolinux/initrdr9.gz > /tmp/initrd
[root@probe root]# umount /mnt/iso
[root@probe root]# losetup -d /dev/loop4
[root@probe root]# 

Mounting a Initial RAM Disk

Most Linux distributions will boot and load files from a "initial RAM disk". This "initial RAM disk" is a single file containing a collection of files. The following demonstrates how one can make use of the loop back device to mount a initial RAM disk image. In this example, we will use the initial RAM disk image which we extracted from the Network Security Toolkit ISO image (shown in Mounting a ISO Image).

[root@probe root]# mkdir /mnt/initrd
[root@probe root]# mount -t ext2 -o loop /tmp/initrd /mnt/initrd
[root@probe root]# ls /mnt/initrd
bin   dev  home    lib         mnt  proc  sbin      tmp  var
boot  etc  initrd  lost+found  opt  root  tftpboot  usr
[root@probe root]# umount /mnt/initrd
[root@probe root]# 

Note

Notice that ext2 was specified as the file system for the /tmp/initrd file. It may be possible to create initial RAM disks using alternative filesystem formats (so you may need to adjust this value for your situation).

Mounting A Encrypted Filesystem

Note

This feature first became available in the 1.2.0 release of the Network Security Toolkit.

Mounting a file as a encrypted filesystem is very similar as to what was discussed in the previous section (Mounting A File As A Filesystem). The following steps need to be done:

  • The cryptography modules and loop back modules need to be available on the system. These come standard on a Network Security Toolkit distribution.

  • A file needs to be created and initialized with a random pattern. It takes longer to initialize a file in this manner, but it provides better security than zero filling the file.

  • The file needs to be initialized with a password through the losetup utility.

  • We will then need to format the file system.

Note

For additional details on encrypted filesystems, refer to: Using CryptoAPI, Cryptoloop HOWTO, and How to Configure an Encrypted Loopback Filesystem on Red Hat Linux 8.0.

In the following example, I'm going to mount a SMB filesystem (a folder "shared" by a Windows desktop computer) to store my encrypted filesystem on. This will be mounted to /mnt/smb. I will then create and prepare a 20MB file called crypt.ext3 that will be used to emulate a fully encrypted ext3 file system.

Figure 4.11. Preparing a Encrypted ext3 File System on a Windows Shared Folder.

[root@probe root]# modprobe cryptoloop
[root@probe root]# MNTPT=/mnt/smb
[root@probe root]# if [ ! -d "${MNTPT}" ]; then mkdir "${MNTPT}"; fi
[root@probe root]# mount -t smbfs -o username=al //rice/public "${MNTPT}"
Password:
[root@probe root]# df -k "${MNTPT}"
Filesystem           1K-blocks      Used Available Use% Mounted on
//rice/public         20161024  18864640   1296384  94% /mnt/smb
[root@probe root]# EFILE="${MNTPT}/tmp/crypt.ext3"
[root@probe root]# dd if=/dev/urandom of="${EFILE}" bs=1048576 count=201
[root@probe root]# modprobe aes
[root@probe root]# losetup -e aes /dev/loop0 "${EFILE}"2
[root@probe root]# mkfs.ext3 /dev/loop0
[root@probe root]# tune2fs -i 0 -c 0 /dev/loop0
[root@probe root]# losetup -d /dev/loop03
[root@probe root]# 

1

Filling a file with a random data stream from /dev/urandom can take a VERY long time - especially over a slow network link. You may be better off to create it on a local hard disk or RAM disk and then copy the file to your network drive.

2

This step assigns the encryption key (based on a hash from the password you provide). Do NOT forget this password as there is no way I know of to recover it (or your files) once forgotten.

3

This disconnects the file from the loopback device. We will need to mount it in the future when we are ready to make use of it.

At this point, we now have the 20MB file /mnt/smb/tmp/crypt.ext3 prepared such that we can mount it like a encrypted ext3 file system via the loop back device. We will now create a new mount point and verify that the standard file operations are supported.

Figure 4.12. Mounting a Encrypted ext3 File System.

[root@probe root]# MNTPT=/mnt/crypt
[root@probe root]# mkdir $MNTPT
[root@probe root]# mount -t ext3 -o loop,encryption=aes /mnt/smb/tmp/crypt.ext3 $MNTPT
[root@probe root]# ls -l $MNTPT
[root@probe root]# cp /etc/hosts $MNTPT
[root@probe root]# chown mysql.nobody $MNTPT/hosts
[root@probe root]# ls -l $MNTPT/hosts
[root@probe root]# chmod 700 $MNTPT/hosts
[root@probe root]# ls -l $MNTPT/hosts
[root@probe root]# df -k
[root@probe root]# rm $MNTPT/hosts
[root@probe root]# df -k
[root@probe root]# setup_mysql -rdir $MNTPT
[root@probe root]# du $MNTPT
[root@probe root]# umount $MNTPT
[root@probe root]# 

By using the loop back trick, I was able to let mysql make use of the available space on a shared Windows drive and keep the data encrypted (if someone were able to get hold of the file - they would have a tough time getting usable information from it).

Note

Making use of encrypted file systems adds an additional peformance penalty. The article "How to Configure an Encrypted Loopback Filesystem on Red Hat Linux 8.0" contains a table at the end showing the affects on performance when going to a encrypted file system.

Warning

Do not forget the password you used to encrypt your file system with. As far as I know, there is no way to recover data from a encrypted file system once the password has been lost.