Skip to content
shellhacks.dev
Linux

How to Mount an ISO or Disk Image on Linux Without Surprises

Mount an ISO or disk image on Linux with a loop device: read-only by default, expose the partitions of a full image, and unmount without leaving loop devices.

6 min read
Summarize in AI
Illustration for "How to Mount an ISO or Disk Image on Linux Without Surprises": a terminal session, a disk usage gauge, file permission bits.

Reading the contents of an ISO, checking a downloaded installer or copying one file out of a disk image does not need to burn or extract anything. The loop device turns a file into a block device. It is the same mechanism behind mounting a drive, and the commands assume util-linux 2.40 on a Linux 6.x kernel.

Mount an ISO

Shell
sudo mkdir -p /mnt/iso
sudo mount -o loop,ro debian-13-netinst.iso /mnt/iso
ls /mnt/iso
Text
boot  dists  doc  EFI  install.amd  isolinux  pool  README.txt
mount: /dev/loop0 is write-protected, mounting read-only

The mount command finds a free loop device and attaches the file. Passing ro explicitly silences the warning shown above. ISO 9660 and UDF are read-only formats anyway. Copy out what you need with cp -a /mnt/iso/path /tmp/.

A disk image with partitions

Shell
sudo losetup --find --show --partscan raspios.img
lsblk /dev/loop0
sudo mount -o ro /dev/loop0p2 /mnt/iso
Text
/dev/loop0
NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
loop0       7:0    0  4.3G  0 loop
├─loop0p1 259:0    0  512M  0 part
└─loop0p2 259:1    0  3.8G  0 part

A whole-disk image contains a partition table, so mounting the file directly fails with "wrong fs type". --partscan makes the kernel create the partition nodes. If you know the byte offset instead, use mount -o loop,offset=4194304; get the number from fdisk -l image.img by multiplying the start sector by 512.

Unmount and clean up

Shell
sudo umount /mnt/iso
sudo losetup -d /dev/loop0
losetup --list

A busy mount refuses to unmount: umount: /mnt/iso: target is busy usually means a shell is sitting inside the directory. Change out of it, or find the holder with lsof +D /mnt/iso. Forgotten loop devices pile up and show in losetup --list; detach them with losetup -D when nothing needs them. The same technique inspects a copy made with dd.

Without root

Shell
bsdtar -xf debian-13-netinst.iso -C /tmp/iso-contents README.txt
7z l debian-13-netinst.iso | head

When you only need to read files, extraction tools avoid privileges entirely. bsdtar from libarchive and 7z understand ISO 9660. For a persistent mount, an fstab line with the loop option does the job, as in fstab mounts.

What a loop device is

An ISO file is a disk image, and the kernel cannot mount a regular file directly. A loop device bridges the gap: it presents a file as a block device, which the file system driver then reads. The mount command sets this up automatically when you give it a file and the -o loop option, and modern versions do it even without the option. The device appears as /dev/loop0 and so on. You can create one by hand with losetup when you need to control the details, such as setting the offset to reach a partition inside a raw disk image, or making the device read-only.

An ISO uses the ISO 9660 file system, often with Rock Ridge or Joliet extensions that restore long names and Unix permissions. Mounting is read-only because the format is read-only, and trying to write returns an error, which is expected.

Hybrid ISOs and partition tables

Many Linux installer images are hybrid: the same file boots from optical media and from a USB stick. They contain a partition table in addition to the ISO file system. If a plain mount fails or shows only part of the contents, check the structure with fdisk -l image.iso, then attach it with losetup -P, which scans for partitions and creates /dev/loop0p1 and similar devices that you can mount individually. A Windows ISO uses the UDF file system and needs the right driver, which Linux provides, though very large files may need the UDF-aware option on older systems.

If the contents look wrong, verify the image first. Compare its checksum to the published value, since a truncated download mounts as an empty or corrupted tree and wastes time on a problem that has nothing to do with mounting.

Using the mounted image safely

Mount on an empty directory you created for the purpose, such as under /mnt or /media, and mount read-only explicitly with -o ro so the intent is visible. Copy files out with cp -a or rsync if you need them elsewhere. Do not leave images mounted when you finish: unmount with umount, and if it reports that the target is busy, find the culprit with lsof +D or fuser -vm, usually a shell whose working directory is inside the mount. Then free the loop device, which umount does for devices it created, and check with losetup -a that none remain.

Automounting in a script should use a temporary directory from mktemp -d and a trap that unmounts on exit, so a failure halfway through does not leave a mount behind.

Persistent mounts and alternatives

For a mount that should return after a reboot, an fstab line with the loop option works, along with ro and possibly nofail so a missing file does not stop the boot. For occasional use, a desktop file manager can open the image without root through udisks, which uses the same mechanism with a polkit rule. If you only need to inspect or extract a few files, tools such as 7z x or bsdtar -xf unpack an ISO without any mount, and they need no privileges, which suits a build script or a container where mounting is not allowed. Choose mounting when you want a live directory view, and extraction when you want a copy.

Finally, treat images from the internet as untrusted until checked. Verify the signature or checksum against values published on the project's site over HTTPS, and mount read-only with nosuid,nodev so a crafted image cannot supply a setuid program or device node that the system would honour. Mounting an image also parses its file system in the kernel, and file system bugs have been exploited with crafted images, so for suspicious files prefer extraction in a throwaway container or virtual machine over a mount on a production host.

Where this does not apply

Encrypted or compressed images, such as qcow2 virtual disks, need qemu-nbd or guestmount instead of a loop device. Never mount an untrusted image read-write on a machine you care about; a crafted file system has triggered kernel bugs, so use a throwaway VM for suspicious files. See the losetup manual page and the mount manual page.

Two checks make the result trustworthy. First, verify the download before mounting it: compare sha256sum debian-13-netinst.iso with the value published next to the image, because a corrupt installer mounts fine and fails later. Second, look at what the kernel thinks it attached with findmnt /mnt/iso, which prints the source, the file system type and the options in one line. If the type shows iso9660 and the options include ro, nothing you do under that directory can modify the image file.

Share

Keep reading

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.