Questions about this topic? Sign up to ask in the talk tab.

User talk:ErrorProne/chimera tweak

From NetSec
Jump to: navigation, search

Create a Custom Chimera ISO

Chimera tweaking guide

Creating a custom archlinux live iso.

Why would we even bother creating our own custom iso? Some of the obvious advantages include being able to take your environment with you anywhere you may go, whether it be on a usb stick or on a cdrom. It makes installing the same environment on multiple computers easier, etc etc.

There's a package already available to make the development of your new iso easier, and it's called archiso (https://wiki.archlinux.org/index.php/Archiso) However, I had several issues with file permissions, having files located in entirely too many directories, and so on. I opted for a somewhat simpler approach, by disassembling the iso image, adding packages, tweaking configs, and eventually re-packing the iso image. This guide will walk you through exactly how to create you personalized, fully customized arch linux based live boot iso.

As I said earlier, we're going to start with the original archlinux iso, so go ahead and download your own copy of the iso from (www.archlinux.org). Now that we have a local copy, we need to setup a development environment to work in. Go ahead and create the following directories in /tmp.

/tmp/myarch
/tmp/myarch/old_iso
/tmp/myarch/new_iso

Now, we need to mount the current archlinux iso to /tmp/myarch/old_iso, so that we can copy the contents into our newly created working environment.

# mount archlinux.iso /tmp/myarch/old_iso -o loop

That will mount a read only version of the iso, now just copy them over into new_iso...

# cp -r /tmp/myarch/old_iso/* /tmp/myarch/new_iso

You'll see two directories created in new_iso (arch / isolinux). If you're simply adding / modifying packages, then you'll only be concerned with the subdirectories in arch. We have 3 main file systems used in the live boot cd, they're located in arch/any/usr-share.fs.sfs arch/i686/root-image.fs.sfs and arch/i686/lib-modules.fs.sfs. These are all ext4 filesystems compressed into a squash filesystem. You can double check the fs type by reading the file /tmp/myarch/new_iso/arch/aitab

lib-modules.fs.sfs	contains the modules for the included kernel
root-image.fs.sfs	contains the root file directory
usr-share.fs.sfs	contains /usr/share file system

To make modifications to any of these, you'll need to unsquash the filesystem, mount the unsquashed filesystem, edit any files you need to edit, rebuild the filesystem so that it doesn't bloat with extra data, mksquashfs the new ext4 filesystem, replace the appropriate sfs file, update the checksum file, and finally rebuild the iso. Sounds complicated, but it goes by pretty quickly. We'll start with unsquashing the root image.

# unsquashfs root-image.fs.sfs

Which will create the directory squashfs-root, and the ext4 file system will be located in that directory like so...

# ls squashfs-root
root-image.fs

Now mount the image to /tmp/root

# mount root-image.fs /tmp/root 

Now you'll be able to edit any files you want in the root image by changing your current directory to /tmp/root. Once you're done, we'll need to reconstruct the ext2 file system. I've included a script below to assist in properly reconstructing it.

# mknewfs /tmp/root ext2 50%

Now you'll see root.fs appear. Now we need to compress it using mksquashfs

# mksquashfs root.fs root-image.fs.sfs -noappend -comp xz 

Once this is rebuilt, just move the root-image.fs.sfs to /tmp/new_iso/arch/i686/root-image.fs.sfs and update the checksum file in /tmp/new_iso/arch/checksum.i686.md5

# md5sum /tmp/new_iso/arch/i686/root-image.fs.sfs

Unmount the root system, and clean up the excess files. If you're done making changes, change directories back to /tmp/new_iso and build the new iso.

# mkisofs -r -l -b isolinux/isolinux.bin -c isolinux/boot.cat --iso-level 3 --no-emul-boot --boot-load-size 4 --boot-info-table -p "Chimera Live Boot" --publisher BHA -A chimera_live -V chimera_live -o ../chimera.iso ./


mknewfs shell script

modified mkarchiso script

#!/bin/bash

set -e -u

quiet="y"
work_dir="work"

# Show an INFO message
# $1: message string
_msg_info() {
    local _msg="${1}"
    echo "[mkarchiso] INFO: ${_msg}"
}

# Show an ERROR message then exit with status
# $1: message string
# $2: exit code number (with 0 does not exit)
_msg_error() {
    local _msg="${1}"
    local _error=${2}
    echo
    echo "[mkarchiso] ERROR: ${_msg}"
    echo
    if [[ ${_error} -gt 0 ]]; then
        exit ${_error}
    fi
}

# Show space usage similar to df, but better formatted.
# $1: mount-point or mounted device.
_show_space_usage () {
    local _where="${1}"
    local _fs _total _used _avail _pct_u=0 _mnt
    read _fs _total _used _avail _pct_u _mnt < <(df -m "${_where}" | tail -1) &> /dev/null
    _msg_info "Total: ${_total} MiB (100%) | Used: ${_used} MiB (${_pct_u}) | Avail: ${_avail} MiB ($((100 - ${_pct_u%\%}))%)"
}

# Mount a filesystem (trap signals in case of error for unmounting it
# $1: source image
# $2: mount-point
_mount_fs() {
    local _src="${1}"
    local _dst="${2}"
    trap "_umount_fs ${_src}" EXIT HUP INT TERM
    mkdir -p "${_dst}"
    _msg_info "Mounting '${_src}' on '${_dst}'"
    mount "${_src}" "${_dst}"
    _show_space_usage "${_dst}"
}

# Unmount a filesystem (and untrap signals)
# $1: mount-point or device/image
_umount_fs() {
    local _dst="${1}"
    _show_space_usage "${_dst}"
    _msg_info "Unmounting '${_dst}'"
    umount "${_dst}"
    rmdir "${_dst}"
    trap - EXIT HUP INT TERM
}

# Makes a filesystem from a source directory.
# $1: Source directory
# $2: Target filesystem type (ext4 | ext3 | ext2 | xfs)
# $3: Size of target filesystem. Can be an absolute value in MiB, or relative value of desired free space (1% - 99%)
_mkfs () {
    local _src="${1}"
    local _fs_type="${2}"
    local _fs_size="${3}"

    local _fs_src="${_src}"
    local _fs_img="${_src}.fs"

    if [[ ! -e "${_fs_src}" ]]; then
        _msg_error "The path '${_fs_src}' does not exist" 1
    fi

    local _spc_used
    _spc_used=$(du -sxm "${_fs_src}" | awk '{print $1}')

    # Caculate FS size with desired % of free space, adds 10% overhead to used space.
    if [[ ${_fs_size} != ${_fs_size%\%} ]]; then
        if [[ ${_fs_size%\%} -le 0 || ${_fs_size%\%} -ge 100 ]]; then
            _msg_error "Invalid percentage of free space specified '${_fs_size}' on '${_src}', should be 0% < x < 100%" 1
        fi
        _fs_size=$((_spc_used * 110 / (100 - ${_fs_size%\%})))
    else
        local _spc_used_over=$((_spc_used * 11 / 10))
        if [[ ${_fs_size} -lt ${_spc_used_over} ]]; then
            _msg_error "Filesystem size specified '${_fs_size}' MiB for '${_src}' is too small, must be at least '${_spc_used_over}' MiB" 1
        fi
    fi

    _msg_info "Creating ${_fs_type} image of ${_fs_size} MiB"
    rm -f "${_fs_img}"
    dd of="${_fs_img}" count=0 bs=1M seek=${_fs_size} &> /dev/null
    local _qflag=""
    if [[ ${quiet} == "y" ]]; then
        _qflag="-q"
    fi
    case "${_fs_type}" in
        ext4)
            mkfs.ext4 ${_qflag} -O ^has_journal -m 0 -F "${_fs_img}"
            tune2fs -c 0 -i 0 "${_fs_img}" &> /dev/null
            ;;
        ext3)
            mkfs.ext3 ${_qflag} -m 0 -F "${_fs_img}"
            tune2fs -c 0 -i 0 "${_fs_img}" &> /dev/null
            ;;
        ext2)
            mkfs.ext2 ${_qflag} -m 0 -F "${_fs_img}"
            tune2fs -c 0 -i 0 "${_fs_img}" &> /dev/null
            ;;
        xfs)
            mkfs.xfs ${_qflag} "${_fs_img}"
            ;;
        *)
            _msg_error "Invalid filesystem: ${_fs_type}" 1
            ;;
    esac
    _mount_fs "${_fs_img}" "${work_dir}/mnt/${_src}"
    _msg_info "Copying '${_fs_src}/' to '${work_dir}/mnt/${_src}/'"
    rsync -aH "${_fs_src}/" "${work_dir}/mnt/${_src}/"
    _umount_fs "${work_dir}/mnt/${_src}"
}

fsdir="${1}"
fstype="${2}"
fspct="${3}"

_mkfs "${fsdir}" "${fstype}" "${fspct}"