-
-
Save moeiscool/9a807d1eb8961da3b4db63c74b24c63f to your computer and use it in GitHub Desktop.
Ubuntu ISO with preseed.cfg generation script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
## FORSTWOOF UBUNTU PRESEED :: BUILD SCRIPT | |
# Quit on first error | |
set -e | |
# Temporary directory for the build | |
TMP="/var/tmp/ubuntu-build" | |
# Cleanup function | |
cleanup () { | |
echo "Cleaning up" | |
umount "${TMP}/files" || true | |
umount "${TMP}/mnt" || true | |
rm -r "${TMP}" | |
} | |
# Clean up on SIGINT | |
trap "cleanup" INT | |
# Get the script's running directory | |
SCRDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" | |
# Directory from where script was started | |
CURDIR="$(pwd)" | |
# Preseed file | |
SEED="${SCRDIR}/preseed.cfg" | |
# Source and destination files | |
SRC="${1}" | |
DST="${2}" | |
echo "Performing file presence checks" | |
# Check if the source file exists | |
[ -f "${SRC}" ] || { | |
echo "The source file does not exist!" | |
exit 1 | |
} | |
# Check if the source file is of an appropriate type | |
TYPE=$(file "${SRC}" | tail -c 16) | |
[ "${TYPE}" != "x86 boot sector" ] && { | |
echo "The source file is not a valid bootable ISO file!" | |
exit 3 | |
} | |
# Check if the preseed file exists | |
[ -f "${SEED}" ] || { | |
echo "The preseed file does not exist!" | |
exit 2 | |
} | |
# Check if the destination file exists and offer to delete it | |
[ -e "${DST}" ] && { | |
echo -n "The destination file already exists! Do you want to remove it? [y/N] " | |
read ANS | |
([ "${ANS}" == "y" ] || [ "${ANS}" == "Y" ]) || { | |
echo "Build cancelled." | |
exit 4 | |
} | |
rm -r "${DST}" | |
} | |
# Create the temporary directory | |
echo "Creating a temporary directory" | |
[ -e "${TMP}" ] && cleanup | |
mkdir "${TMP}" | |
# Mount the source ISO image | |
echo "Mounting the source image" | |
mkdir "${TMP}/mnt" | |
mount -o ro "${SRC}" "${TMP}/mnt" | |
# Create an overlay file system | |
echo "Creating an overlay file system" | |
mkdir "${TMP}/files" | |
mkdir "${TMP}/overlay" | |
mkdir "${TMP}/work" | |
mount -t overlayfs -o lowerdir="${TMP}/mnt",upperdir="${TMP}/overlay",workdir="${TMP}/work" overlayfs "${TMP}/files" | |
# Enable serial console for EFI boot entries | |
echo "Enabling serial console for EFI boot entries (grub)" | |
cat <<EOF >"${TMP}/files/boot/grub/grub.cfg" | |
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1 | |
terminal_input console serial | |
terminal_output console serial | |
menuentry "Install Ubuntu Server (automated)" { | |
linux /install/vmlinuz file=/cdrom/preseed/ubuntu-server.seed text console=ttyS0,115200n8 --- | |
initrd /install/initrd.gz | |
} | |
menuentry "Check disc for defects" { | |
linux /install/vmlinuz MENU=/bin/cdrom-checker-menu text console=ttyS0,115200n8 --- | |
initrd /install/initrd.gz | |
} | |
menuentry "Rescue a broken system" { | |
linux /install/vmlinuz rescue/enable=true text console=ttyS0,115200n8 --- | |
initrd /install/initrd.gz | |
} | |
EOF | |
# Enable serial console for legacy boot entries | |
echo "Enabling serial console for legacy boot entries (syslinux)" | |
cat <<EOF >"${TMP}/isolinux.cfg" | |
serial 0 115200 0x003 | |
EOF | |
cat "${TMP}/files/isolinux/isolinux.cfg" >>"${TMP}/isolinux.cfg" | |
sed -i 's/default vesamenu.c32//g' "${TMP}/isolinux.cfg" | |
sed -i 's/ui gfxboot bootlogo//g' "${TMP}/isolinux.cfg" | |
mv "${TMP}/isolinux.cfg" "${TMP}/files/isolinux/isolinux.cfg" | |
sed -i 's/---/console=ttyS0,115200n8 ---/g' "${TMP}/files/isolinux/txt.cfg" | |
# Rebuilding initrd | |
echo "Rebuilding initrd for CD booting" | |
mkdir "${TMP}/initrd" | |
cd "${TMP}/initrd" | |
gzip -d < "${TMP}/files/install/initrd.gz" | cpio --extract --make-directories --no-absolute-filenames --quiet | |
rm "${TMP}/files/install/initrd.gz" | |
cp "${SEED}" "${TMP}/initrd" | |
find . | cpio -H newc --create --quiet | gzip -9 > "${TMP}/files/install/initrd.gz" | |
echo "Rebuilding initrd for network booting" | |
rm -r * | |
ARCH=$(ls "${TMP}/files/install/netboot/ubuntu-installer") | |
gzip -d < "${TMP}/files/install/netboot/ubuntu-installer/${ARCH}/initrd.gz" | cpio --extract --make-directories --no-absolute-filenames --quiet | |
rm "${TMP}/files/install/netboot/ubuntu-installer/${ARCH}/initrd.gz" | |
cp "${SEED}" "${TMP}/initrd" | |
find . | cpio -H newc --create --quiet | gzip -9 > "${TMP}/files/install/netboot/ubuntu-installer/${ARCH}/initrd.gz" | |
rm -r "${TMP}/initrd" | |
# Recreate the md5sum.txt file | |
echo "Calculating MD5 checksums for the image" | |
cd "${TMP}/files" | |
md5sum -b $(find -type f) > md5sum.txt | |
OPTS="" | |
[ -f "${TMP}/files/boot/grub/efi.img" ] && OPTS="-eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot" | |
# Build the ISO image | |
echo "Building the new ISO image" | |
cd "${CURDIR}" | |
mkisofs -r -V "UBUNTUSEED" \ | |
-cache-inodes \ | |
-J -l -b isolinux/isolinux.bin \ | |
-c isolinux/boot.cat -no-emul-boot \ | |
-boot-load-size 4 -boot-info-table \ | |
${OPTS} \ | |
-input-charset utf-8 -quiet \ | |
-o "${DST}" "${TMP}/files" | |
# Clean up the mess | |
cleanup |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
## FORSTWOOF UBUNTU PRESEED :: INSTALLATION SCRIPT | |
# Will do everything in temporary files | |
cd /var/tmp | |
# Set global locale | |
echo LC_ALL=\"en_US.UTF-8\" >> /etc/default/locale | |
# Point apt proxy to local cacher | |
cat <<EOF >/etc/apt/apt.conf.d/01proxy | |
Acquire::http::Proxy "http://beaver:3142"; | |
EOF | |
# Enable automatic updates of all packages | |
rm /etc/apt/apt.conf.d/20auto-upgrades | |
cat <<EOF >/etc/apt/apt.conf.d/50unattended-upgrades | |
Unattended-Upgrade::Allowed-Origins { | |
"\${distro_id}:\${distro_codename}-security"; | |
"\${distro_id}:\${distro_codename}-updates"; | |
"\${distro_id}:\${distro_codename}-proposed"; | |
"\${distro_id}:\${distro_codename}-backports"; | |
}; | |
Unattended-Upgrade::Package-Blacklist { | |
}; | |
Unattended-Upgrade::Remove-Unused-Dependencies "true"; | |
EOF | |
cat <<EOF >/etc/apt/apt.conf.d/10periodic | |
APT::Periodic::Update-Package-Lists "1"; | |
APT::Periodic::Download-Upgradeable-Packages "1"; | |
APT::Periodic::AutocleanInterval "7"; | |
APT::Periodic::Unattended-Upgrade "1"; | |
EOF | |
# Install all updates | |
apt-get -y update && \ | |
apt-get -y dist-upgrade | |
apt-get -y autoremove | |
apt-get -y autoclean | |
apt-get -y purge $(dpkg --get-selections | grep deinstall | awk '{print $1}') | |
# Add ForstWoof certificate authority | |
curl -Lso /usr/local/share/ca-certificates/ForstWoof.crt https://forstwoof.ru/ca/root.crt | |
update-ca-certificates | |
mkdir -p /etc/ssl/forstwoof | |
for name in root server client proxy | |
do | |
for ext in crl crt | |
do | |
[[ "${name}" = "root" ]] && [[ "${ext}" = "crt" ]] && ln -s /usr/local/share/ca-certificates/ForstWoof.crt /etc/ssl/forstwoof/root.crt && continue | |
curl -Ls https://forstwoof.ru/ca/${name}.${ext} -o /etc/ssl/forstwoof/${name}.${ext} | |
done | |
done | |
cat <<EOF >/etc/cron.weekly/forstwoof-crl | |
#!/bin/sh | |
for name in root server client | |
do | |
wget https://forstwoof.ru/ca/${name}.crl -O /etc/ssl/forstwoof/${name}.crl | |
done | |
EOF | |
chmod +x /etc/cron.weekly/forstwoof-crl | |
# ZSH GRML configuration | |
curl -Lso /etc/zsh/zshrc http://git.grml.org/f/grml-etc-core/etc/zsh/zshrc | |
curl -Lso /etc/skel/.zshrc http://git.grml.org/f/grml-etc-core/etc/skel/.zshrc | |
cp /etc/skel/.zshrc /root/.zshrc | |
chsh -s /usr/bin/zsh | |
# OpenSSH server configuration | |
rm /etc/ssh/ssh_host_* | |
declare -A keytypes=(\ | |
["ed25519"]="256" \ | |
["ecdsa"]="521" \ | |
["rsa"]="4096") | |
for type in ${!keytypes[@]} | |
do | |
KEYPATH="/etc/ssh/ssh_host_${type}_key" | |
ssh-keygen -q -t ${type} -b ${keytypes["$type"]} -C "" -N "" -f ${KEYPATH} | |
done | |
cat <<EOF >/etc/ssh/sshd_config | |
Port 22 | |
Protocol 2 | |
HostKey /etc/ssh/ssh_host_ed25519_key | |
HostKey /etc/ssh/ssh_host_ecdsa_key | |
HostKey /etc/ssh/ssh_host_rsa_key | |
SyslogFacility AUTH | |
LogLevel INFO | |
LoginGraceTime 60 | |
AllowUsers root | |
PermitRootLogin yes | |
UsePAM yes | |
PermitEmptyPasswords no | |
UsePrivilegeSeparation yes | |
StrictModes yes | |
IgnoreRhosts yes | |
PubkeyAuthentication yes | |
HostbasedAuthentication no | |
ChallengeResponseAuthentication no | |
PasswordAuthentication no | |
X11Forwarding no | |
PrintMotd no | |
PrintLastLog yes | |
TCPKeepAlive no | |
MaxStartups 4 | |
Compression yes | |
ClientAliveCountMax 5 | |
ClientAliveInterval 30 | |
IPQoS cs4 8 | |
AcceptEnv LANG LC_* | |
Subsystem sftp /usr/lib/openssh/sftp-server | |
EOF | |
mkdir -p /root/.ssh | |
cat <<EOFEOFEOFEOF >/root/.ssh/authorized_keys | |
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAF1LO9QOys7ybGjoo40mZZfLUnztBcSBKk3m1lRGyxK6k5Hnb5HW/QpUT3uCdsaKJ9NrYmLlZjwkykxDSv4YqKReQFjNwfhPNo2DG3ah0AiCrvpmsvzh4FM6exiE1WQCMlQ40wJDhXnihbVYTKx7D2BJE4GopBWZ1X9QzhkUlHfkq3S+w== Shark | |
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBADTeo8BOL7Th3mdYqpxDwVbMt6OFHPtXocQddkFzG8bKZITSLZfGvmzzQAg9wWi7n8LPRYARgGZnlUMN2M1fmckOwCMwD1NyyIfK2jqzpD21VFsIabSbWXXwhSz+IPIVhemyXKOPNF9Tpkxqhava5xKNBQwEiHesCuiXvROc1F7UMzrtA== Cougar | |
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAEy7loXboS2HxhP2c8nLsf68qsdpD7aCuD+Wly+CtHw+zBS9uSxZiYWfp5k210lS4bDkV5JO2VDlKcANLWY9M265wEeX4DD39WsjAyBfpEZajqRStselXrRNYlhtH7GDpx9RZJvHFtOzROXvZrpposbaeybjt5ZyMmPq+7Q6n9L6L6IbA== Dingo | |
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDKc56H2wFTSZxJHNgd66R4Ld6jEYLq4J9D4ZoqJQylYgTPJ4ITkeafp5msdcF1za8DZwThPr964c4LfNwVT/bQQHhzFr/Yxg2c4PDKyUSM0iV7wMixUCArxTaOoyOKA6YiH6Rn1M8mQVM4rqt0GqcAbeVqKdaqsWbDtxbcc8KpxwHNs6r5xxWp/jI1Y/enY5Vtt0La5DVfIfWmGzEfLxGJtZI7izfdToLsNDxBCpZa/xi9bshvBULFToIbrP4WsVrtac05H08n0pHV6eFwBlEJPzJsenx7sHOxhCipAN7sKe6qJrDyJL22PfQgYhOMQ4AlBvKDg6McD54Zep+p0VUB5U0+z7HylTEhswg6IORfslSiwEfrJen7DdDO2xEJlk6XFl0Dby2T6njppXhRu2Ra1HSuYGKbkYk+356oRHi+x9hIG0YNoAgLQjgKNQo+kFnywHNGuw6krUmN3qjctnNBe921a42UY3NenhmzN6UdkqXYJEpMyKSvh1XI2I5RPzQoIHAm4pl3YG70CP7Wg3XB+t3o5TeVvuT1PeLG8eUsVryQSs1C3UH2pPF2raI3URKwLmXr2XZukeLz6kPrXg0ky4yUDpY/emesKFaNtquUC0daMXttBtfED7t9a/rL/Zy/8HkrivajG9yrEgNy16pW2aHaF4P87aoE3aM94GKQOQ== Penguin | |
EOFEOFEOFEOF | |
# Sysctl configuration | |
cat <<EOF >/etc/sysctl.conf | |
net.core.default_qdisc = fq_codel | |
net.ipv4.conf.all.accept_source_route = 0 | |
net.ipv4.conf.all.force_igmp_version = 2 | |
net.ipv4.conf.all.rp_filter = 1 | |
net.ipv4.conf.all.secure_redirects = 1 | |
net.ipv4.icmp_echo_ignore_broadcasts = 1 | |
net.ipv4.icmp_ignore_bogus_error_responses = 1 | |
net.ipv4.tcp_ecn = 1 | |
net.ipv4.tcp_rfc1337 = 1 | |
net.ipv4.tcp_syncookies = 1 | |
net.ipv6.conf.all.accept_source_route = 0 | |
vm.swappiness = 0 | |
EOF | |
# Template network configuration | |
cat <<EOF >>/etc/network/interfaces | |
#iface ens192 inet static | |
# address 192.168.1.X | |
# netmask 24 | |
# gateway 192.168.1.1 | |
# dns-nameservers 192.168.1.5 2002:d58d:9aaa:1::5 | |
# dns-search lan.forstwoof.ru | |
# mtu 9000 | |
#iface ens192 inet6 static | |
# address 2002:d58d:9aaa:1::X | |
# netmask 64 | |
# gateway 2002:d58d:9aaa:1::1 | |
EOF | |
# Enable log compression | |
sed -i 's/#compress/compress/' /etc/logrotate.conf | |
# Tweak initramfs generation | |
sed -i 's/COMPRESS=gzip/COMPRESS=xz/' /etc/initramfs-tools/initramfs.conf | |
sed -i 's/MODULES=most/MODULES=dep/' /etc/initramfs-tools/initramfs.conf | |
update-initramfs -u -k all | |
# Enable kexec reboots | |
sed -i 's/LOAD_KEXEC=false/LOAD_KEXEC=true/' /etc/default/kexec | |
# open-vm-tools logging tweak | |
cat <<EOF >/etc/vmware-tools/tools.conf | |
[logging] | |
vmsvc.level=error | |
EOF | |
# Remote syslog server | |
cat <<EOF >/etc/rsyslog.d/10-remote.conf | |
*.notice @beaver:514 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## FORSTWOOF UBUNTU PRESEED :: DEBIAN PRESEED FILE | |
# Localization | |
d-i debian-installer/language string en_US:en | |
d-i debian-installer/country string RU | |
d-i debian-installer/locale select en_US.UTF-8 | |
d-i localechooser/preferred-locale en_US.UTF-8 | |
# Keyboard | |
d-i console-setup/ask_detect boolean false | |
d-i keyboard-configuration/layoutcode string ru | |
d-i keyboard-configuration/toggle select Alt+Shift | |
# Networking | |
d-i netcfg/choose_interface select auto | |
d-i netcfg/get_domain string lan.forstwoof.ru | |
# Mirror | |
d-i mirror/protocol select http | |
d-i mirror/country string manual | |
d-i mirror/http/hostname string mirror.yandex.ru | |
d-i mirror/http/directory string /ubuntu | |
d-i mirror/http/proxy string | |
# Clock and time | |
d-i clock-setup/utc boolean true | |
d-i time/zone string Europe/Moscow | |
d-i clock-setup/ntp boolean true | |
d-i clock-setup/ntp-server string kangaroo | |
# Partitioning | |
d-i partman-auto/disk string /dev/sda | |
d-i partman-auto/method string regular | |
d-i partman-auto/expert_recipe string \ | |
custom-ext4 :: \ | |
50 50 50 free \ | |
$iflabel{ gpt } \ | |
$reusemethod{ } \ | |
method{ efi } \ | |
format{ } \ | |
. \ | |
256 256 256 linux-swap \ | |
method{ swap } \ | |
format{ } \ | |
. \ | |
2000 10000 -1 ext4 \ | |
method{ format } \ | |
format{ } \ | |
use_filesystem{ } \ | |
filesystem{ ext4 } \ | |
mountpoint{ / } \ | |
label{ System } \ | |
options/noatime{ noatime } \ | |
. | |
d-i partman-partitioning/confirm_write_new_label boolean true | |
d-i partman/choose_partition select finish | |
d-i partman/confirm boolean true | |
d-i partman/confirm_nooverwrite boolean true | |
# Base system installation | |
d-i base-installer/initramfs-tools/driver-policy select most | |
d-i live-installer/mode select normal | |
d-i base-installer/kernel/image string linux-image-generic | |
# Account setup | |
d-i passwd/shadow boolean true | |
d-i passwd/root-login boolean true | |
d-i passwd/make-user boolean false | |
# Package management | |
d-i apt-setup/restricted boolean true | |
d-i apt-setup/universe boolean true | |
d-i apt-setup/multiverse boolean true | |
d-i apt-setup/backports boolean true | |
d-i apt-setup/use_mirror boolean true | |
d-i apt-setup/services-select-ubuntu multiselect security, partner | |
d-i apt-setup/security_host string mirror.yandex.ru | |
d-i apt-setup/security_path string /ubuntu | |
# Packages | |
tasksel tasksel/first multiselect server, openssh-server | |
d-i pkgsel/include string kexec-tools open-vm-tools rng-tools zsh nano | |
d-i pkgsel/upgrade select full-upgrade | |
d-i pkgsel/update-policy select unattended-upgrades | |
popularity-contest popularity-contest/participate boolean true | |
# Boot loader | |
d-i grub-installer/only_debian boolean true | |
d-i grub-installer/with_other_os boolean false | |
d-i debian-installer/add-kernel-opts string text console=tty0 console=ttyS0,115200n8 | |
# kexec should handle reboots | |
kexec-tools kexec-tools/load_kexec boolean true | |
# Finishing up the installation | |
d-i finish-install/reboot_in_progress note | |
# Post-install script to do all the remaining work | |
d-i preseed/late_command string \ | |
wget http://beaver/ubuntu/install.sh -O /target/var/tmp/install.sh && \ | |
chmod +x /target/var/tmp/install.sh && \ | |
in-target /bin/bash /var/tmp/install.sh && \ | |
rm /target/var/tmp/install.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
## FORSTWOOF UBUNTU PRESEED :: UPDATE SCRIPT | |
apt-get -y update && \ | |
apt-get -y dist-upgrade | |
apt-get -y autoremove | |
apt-get -y autoclean | |
apt-get -y purge $(dpkg --get-selections | grep deinstall | awk '{print $1}') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment