CLI (`lim`) for downloading, verifying and flashing Linux images, LUKS/Btrfs encrypted storage (single drive and RAID1), image backups and chroot maintenance
Project description
Linux Image Manager 🖥️🛠️
Linux Image Manager (lim) is a Python tool for downloading, configuring, and managing Linux images. Whether you're setting up encrypted storage, configuring a virtual Btrfs RAID1, performing backups, or chrooting into an image, this tool makes Linux image administration simple and efficient. 🚀
Features ✨
- Image Download & Setup: Automatically download, verify (checksum + GPG signature) and prepare Linux distributions.
- Encrypted Storage: Configure LUKS encryption for secure image management.
- Tor Onion Unlock: Optionally bake a Tor onion service into the initramfs so the dropbear LUKS unlock shell stays reachable behind NAT or dynamic IPs.
- Virtual RAID1: Easily set up virtual Btrfs RAID1 for data redundancy.
- Backup & Restore: Create image backups from devices using dd.
- Chroot Environment: Easily enter a chroot shell to maintain or modify Linux images.
- Data Import/Export: Sync personal data into an encfs-encrypted store and back.
- Automated Procedures: Simplify partitioning, formatting, mounting, and more.
Installation 📦
Install Linux Image Manager quickly using Kevin's Package Manager under the alias lim. Just run:
package-manager install lim
This command makes Linux Image Manager globally available as lim in your terminal. The lim alias points to the main.py entry point.
The only Python dependency is PyYAML (>=6), used to read the image catalog. The pip/wheel install pulls it in automatically; on the package-manager/symlink install path make sure it is present (python-yaml on Arch). The commands also call the usual system tools (cryptsetup, fdisk, dd, rsync, wget, gpg, encfs, pv, bsdtar, ...), so those need to be installed for the command you use.
Usage ⚙️
lim provides a unified interface for all image and storage operations. Commands that need root privileges re-execute themselves with sudo automatically. The built-in --help option displays detailed usage information.
Available Command Types
--type |
Description |
|---|---|
image |
Download, verify and transfer a Linux image to a device, incl. optional LUKS encryption and Raspberry Pi configuration. |
single |
Set up LUKS encryption with Btrfs on a single drive. |
raid1 |
Set up an encrypted virtual Btrfs RAID1 across two drives. |
backup |
Create an image backup from a memory device using dd. |
chroot |
Mount an image and open a shell inside it. |
mount |
Unlock and mount an encrypted drive. |
umount |
Unmount an encrypted drive and close the mapper. |
single-boot |
Register a single encrypted drive for automount on boot (keyfile, crypttab, fstab). |
raid1-boot |
Register an encrypted RAID1 for automount on boot. |
unlock |
Decrypt the encfs data store. |
lock |
Lock the encfs data store. |
import |
Import personal data from the system into the encrypted store. |
export |
Export personal data from the encrypted store back to the system. |
Command-Line Options
--type(required): Choose the command to execute (see table above).--auto-confirm(optional): Bypass the confirmation prompt before execution.--help(optional): Display detailed help information.
Example Commands
# Display help
lim --help
# Execute the Linux image setup
lim --type image
# Run the single drive encryption setup without a confirmation prompt
lim --type single --auto-confirm
# Set up an encrypted RAID1
lim --type raid1
# Back up a memory device to an image file
lim --type backup
# Enter a chroot environment for a Linux image
lim --type chroot
Project Structure 🗂️
main.py # entry point (the `lim` alias)
lim/
cli.py # argument parsing and command dispatch
catalog.py # read-only access to distributions.yml
device.py # block device selection, dd, blkid helpers
luks.py # LUKS keyfiles, crypttab/fstab bookkeeping
runner.py # subprocess wrapper used by all modules
storage/ # single drive and RAID1 encryption setups
image/ # image setup, backup, chroot, verification
data/ # encfs lock/unlock and data import/export
distributions.yml # single point of truth for the image catalog
configuration/ # package collections used during image setup
tests/unit/ # unit tests (all external commands mocked)
tests/e2e/ # Tor onion unlock end-to-end tests (rootless + QEMU, opt-in)
tests/e2e/qemu/ # full virtualized build+boot+unlock harness
tests/lint/ # architecture guards (e.g. max file length)
Configuration & Customization 🔧
Customize your environment in the lim/configuration/ folder:
- General Packages: Contains common packages for all setup scripts.
- Server LUKS Packages: Contains packages needed for setting up LUKS encryption on servers.
- initcpio Hooks: The mkinitcpio install/runtime hooks and torrc baked into images for the Tor onion unlock.
Remote LUKS Unlock via Tor 🧅
When you answer yes to "Should the system be remotely unlockable via a Tor
onion service?" during an encrypted lim --type image setup, the image gets:
torandbusyboxinstalled, plus a customtormkinitcpio hook ordered betweennetconfanddropbear.- A v3 onion service key generated offline inside the image chroot; the
resulting
.onionaddress is printed at the end of the setup and stays stable across reboots and IP changes. - An NTP clock sync in early userspace (boards like the Raspberry Pi have no
RTC and would otherwise boot with a clock Tor rejects). Override the server
with the kernel parameter
tor_ntp=<host>.
After booting the device, unlock it from any machine with a running Tor client:
torsocks ssh root@<onion-address>
Typing the LUKS passphrase into that shell resumes the boot. The direct
ssh root@<ip> unlock keeps working as before; Tor is an additional path,
useful behind NAT/CGNAT where no port forwarding is possible.
Security note: the onion private key is stored in the initramfs on the
unencrypted boot partition. Anyone with physical access to the SD card can
read it and impersonate the onion service — treat the address as
non-secret. Access control remains the SSH public key
(/etc/dropbear/root_key), exactly as with the direct unlock.
Development & Tests 🧪
The unit suite mocks all external commands, so it runs safely on any machine:
pytest
Tor unlock end-to-end test
tests/e2e/test_tor_unlock_e2e.py reproduces the operator-visible half of the
Tor decryption process rootless — no block devices, no cryptsetup, no
chroot. It generates the v3 onion keys offline (exactly as lim.image.tor
does inside the image), starts a real Tor onion service from a torrc mirroring
the baked-in one, then connects to the .onion address through Tor and
delivers a passphrase to a dropbear stand-in, asserting it arrives and the
endpoint "unlocks".
It needs the real tor binary and live Tor network access (onion bootstrap is
slow), so it is opt-in and skipped otherwise:
LIM_E2E_TOR=1 pytest tests/e2e/test_tor_unlock_e2e.py -v
The offline-only checks in that file (onion keygen, production-flag guard) run
without network. The physical flashing half (dd, cryptsetup luksFormat,
mount, chroot, mkinitcpio) requires root and a matching CPU/qemu setup and
is not covered by this rootless test.
Full virtualized unlock (QEMU)
For the whole process — build an encrypted image, boot it, run the real
initramfs Tor+dropbear chain, and unlock it — tests/e2e/qemu/ drives a QEMU
virtual machine end to end and asserts the real system booted only after the
passphrase was delivered over Tor. It is opt-in (LIM_E2E_QEMU=1) and needs
QEMU, arch-install-scripts, cryptsetup, tor and ncat; the build stage
needs root (ideally inside a throwaway VM to keep the host rootless). A private,
offline Tor network via chutney
is supported. See tests/e2e/qemu/README.md.
The harness's pure logic and drift guards run in the normal suite
(test_qemu_harness_unit.py) — no QEMU, root, or network needed.
License 📜
This project is licensed under the GNU General Public License Version 3. See the LICENSE.txt file for details.
Contact & Support 💬
- Author: Kevin Veen-Birkenbach
- Email: kevin@veen.world
- Website: https://www.veen.world/
Feel free to contribute, report issues, or get in touch. Happy Linux managing! 😊
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file linux_image_manager-2.2.0.tar.gz.
File metadata
- Download URL: linux_image_manager-2.2.0.tar.gz
- Upload date:
- Size: 48.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8ed3ddf965e83968edd0b2368f024aa40e9023b192d276614beb87858687b35
|
|
| MD5 |
1ed55d6641009a446c20a19c4bef3137
|
|
| BLAKE2b-256 |
651d5c8723d6e2b0a5d0283f3ab3dc3b9f6e499a8fb1de08a0753a31f78267a2
|
File details
Details for the file linux_image_manager-2.2.0-py3-none-any.whl.
File metadata
- Download URL: linux_image_manager-2.2.0-py3-none-any.whl
- Upload date:
- Size: 54.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94ea919369f165f4cdebbce25d81ee7a906863dc3e041bf3885a51fa09c957e8
|
|
| MD5 |
8d0c65ef64c2e52482b547dd78d10aa6
|
|
| BLAKE2b-256 |
ad2f30f1786b541def66487056c306189dd5789a386841c755f1ab1e055919fe
|