Skip to content

Instantly share code, notes, and snippets.

@croepha
Last active January 15, 2022 05:36
Show Gist options
  • Save croepha/3f5a92b5a18e72b6ed76 to your computer and use it in GitHub Desktop.
Save croepha/3f5a92b5a18e72b6ed76 to your computer and use it in GitHub Desktop.
My diskless ubuntu setup
#!/bin/sh
# Set R to chroot location
# set SERVER_IP to the ip address of the server
R=$HOME/pxe_ubuntu
# SERVER_IP="192.168.4.198"
LAN_L2="eth2"
WAN_L2="eth0"
LAN_ADDRESS=10.77.5.1
LAN_NETWORK=10.77.5.0
LAN_NETWORK_RANGE="10.77.5.100 10.77.5.199"
LAN_NETWORK_DOMAIN_NAME="thin.lan"
LAN_NETWORK_MASK=255.255.255.0
LAN_NETWORK_BROADCAST=10.77.5.255
SERVER_IP=$LAN_ADDRESS
EXTIF="$WAN_L2"
INTIF="$LAN_L2"
# https://help.ubuntu.com/community/Router
sudo tee /etc/network/interfaces << EOF
auto $LAN_L2
iface $LAN_L2 inet static
address $LAN_ADDRESS
network $LAN_NETWORK
netmask $LAN_NETWORK_MASK
broadcast $LAN_NETWORK_BROADCAST
EOF
sudo /etc/init.d/networking restart # not sure what this is doing, but the
# following lines seems to do the trick
sudo ifdown $LAN_L2 # This one might not be needed either
sudo ifup $LAN_L2
DEPMOD="sudo /sbin/depmod"
MODPROBE="sudo /sbin/modprobe"
$DEPMOD -a
$MODPROBE ip_tables
$MODPROBE nf_conntrack
$MODPROBE nf_conntrack_ftp
$MODPROBE nf_conntrack_irc
$MODPROBE iptable_nat
$MODPROBE nf_nat_ftp
echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward
echo "1" | sudo tee /proc/sys/net/ipv4/ip_dynaddr
sudo iptables-restore <<-EOF
*nat
-A POSTROUTING -o "$EXTIF" -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -i "$EXTIF" -o "$INTIF" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -i "$INTIF" -o "$EXTIF" -j ACCEPT
-A FORWARD -j LOG
COMMIT
EOF
sudo tee /etc/dhcp/dhcpd.conf << EOF
default-lease-time 600;
max-lease-time 7200;
option subnet-mask $LAN_NETWORK_MASK;
option broadcast-address $LAN_NETWORK_BROADCAST;
option routers $LAN_ADDRESS;
option domain-name-servers 8.8.8.8;
option domain-name "$LAN_NETWORK_DOMAIN_NAME";
filename "/boot/grub/i386-pc/core.0";
next-server $LAN_ADDRESS;
subnet $LAN_NETWORK netmask $LAN_NETWORK_MASK {
range $LAN_NETWORK_RANGE;
}
EOF
sudo tee /etc/default/isc-dhcp-server << EOF
INTERFACES="$LAN_L2"
EOF
sudo service isc-dhcp-server restart
# References:
# http://shitwefoundout.com/wiki/Diskless_ubuntu
# https://help.ubuntu.com/community/Installation/FromLinux#Without_CD
# https://www.gnu.org/software/grub/manual/html_node/Network.html
# https://help.ubuntu.com/community/SettingUpNFSHowTo
# This hasnt been tested all at once, but I have added in commands as a
# result of some trial and error
# Major modifications:
# - Kernel utilities built from chroot instead of using system
# - Supports dynamic hostname
# - Writable shared home directory
# TODO: centeralized logging
sudo apt-get install debootstrap
sudo apt-get install nfs-kernel-server
sudo debootstrap trusty "${R}"
sudo cp -v /etc/apt/trusted.gpg $R/etc/apt/trusted.gpg
sudo cp -v /etc/apt/trusted.gpg.d/* $R/etc/apt/trusted.gpg.d/
sudo cp -v /etc/apt/sources.list $R/etc/apt/
sudo mount -v --bind /dev $R/dev
sudo mount -v --bind /dev/pts $R/dev/pts
sudo mount -v -t proc proc $R/proc
sudo mount -v -t sysfs sys $R/sys
sudo cp -v /etc/localtime $R/etc/localtime
sudo cp -v /etc/timezone $R/etc/timezone
echo 'LANG="en_US.UTF-8"' | sudo tee $R/etc/default/locale
echo 'iface eth0 inet manual' | sudo tee $R/etc/network/interfaces
cat /proc/mounts | sudo tee $R/etc/mtab
echo "$R *(fsid=0,ro,async,no_root_squash,no_subtree_check,no_all_squash)" |
sudo tee -a /etc/exports
echo "$R/home *(nohide,rw,async,no_root_squash,no_subtree_check,no_all_squash)" |
sudo tee -a /etc/exports
sudo exportfs -ra
sudo /etc/init.d/nfs-kernel-server restart
function r() {
sudo chroot $R /usr/bin/env "$@"
}
r locale-gen en_US.UTF-8
r dpkg-reconfigure -f non-interactive tzdata
r apt-get update
r apt-get install language-pack-en-base
r apt-get upgrade
r apt-get install grub-pc linux-virtual linux-image-generic nfs-common
r adduser end_user
r gpasswd -a end_user sudo
#r passwd end_user --stdin <<< "pass"
sudo tee $R/etc/fstab << EOF
proc /proc proc defaults 0 0
/dev/nfs / nfs defaults 1 1
$SERVER_IP:$R/home /home nfs defaults 1 1
EOF
sudo tee -a $R/etc/initramfs-tools/initramfs.conf << EOF
MODULES=netboot
BOOT=nfs
DEVICE=eth0
EOF
sudo tee -a $R/etc/initramfs-tools/modules << EOF
aufs
EOF
[ $( ls /lib/modules | wc | awk '{ print $1 }' ) == '1' ] || {
echo "More than one kernel installed, I don't trust this script to do the right thing..."
die
}
sudo mkdir -p $R/etc/initramfs-tools/scripts/modules
sudo cp -v $R/lib/modules/*/kernel/ubuntu/aufs/aufs.ko $R/etc/initramfs-tools/scripts/modules/
sudo touch $R/etc/initramfs-tools/scripts/init-bottom/00_aufs_init
sudo chmod 0775 $R/etc/initramfs-tools/scripts/init-bottom/00_aufs_init
sudo tee -a $R/etc/initramfs-tools/scripts/init-bottom/00_aufs_init << EOF
#!/bin/sh -e
case \$1 in
prereqs)
exit 0
;;
esac
for x in \$(cat /proc/cmdline); do
case \$x in
root=*)
ROOTNAME=\${x#root=}
;;
aufs=*)
UNION=\${x#aufs=}
case \$UNION in
LABEL=*)
UNION="/dev/disk/by-label/\${UNION#LABEL=}"
;;
UUID=*)
UNION="/dev/disk/by-uuid/\${UNION#UUID=}"
;;
esac
;;
esac
done
echo "Union=\$UNION"
if [ -z "\$UNION" ]; then
exit 0
fi
modprobe -b aufs && echo "OK: modprobe -b aufs" || echo "ERR: modprobe -b aufs"
# make the mount points on the init root file system
mkdir /aufs /ro /rw && echo "OK: mkdir /aufs /ro /rw" || echo "ERR: mkdir /aufs /ro /rw"
# mount read-write file system
if [ "\$UNION" = "tmpfs" ]; then
mount -t tmpfs rw /rw -o noatime,mode=0755 && echo "OK: mount -t tmpfs rw /rw -o noatime,mode=0755 " ||
echo "ERR: mount -t tmpfs rw /rw -o noatime,mode=0755"
else
mount \$UNION /rw -o noatime
fi
# move real root out of the way
mount --move \${rootmnt} /ro && echo "OK: mount --move \${rootmnt} /ro" || echo "ERR: mount --move \${rootmnt} /ro"
mount -t aufs aufs /aufs -o noatime,dirs=/rw:/ro=ro && echo "OK: mount -t aufs aufs /aufs -o noatime,dirs=/rw:/ro=ro" ||
echo "ERR: mount -t aufs aufs /aufs -o noatime,dirs=/rw:/ro=ro"
# test for mount points on union file system
[ -d /aufs/ro ] || mkdir /aufs/ro
[ -d /aufs/rw ] || mkdir /aufs/rw
mount --move /ro /aufs/ro && echo "OK: mount --move /ro /aufs/ro" || echo "ERR: mount --move /ro /aufs/ro"
mount --move /rw /aufs/rw && echo "OK: mount --move /rw /aufs/rw" || echo "ERR: mount --move /rw /aufs/rw"
# strip fstab off of root partition
grep -v \$ROOTNAME /aufs/ro/etc/fstab > /aufs/etc/fstab
mount --move /aufs /root && echo "OK: mount --move /aufs /root" || echo "ERR: mount --move /aufs /root"
exit 0
EOF
sudo mv $R/boot/grub $R/boot/old_grub
sudo mkdir $R/boot
r update-initramfs -k "$(ls $R/lib/modules)" -c -b /boot/
r grub-mknetdir --net-directory=/
sudo mkdir /tftpboot/ # Ummm not sure on this one... it should already exist
sudo mkdir /tftpboot/boot
sudo mount --bind $R/boot /tftpboot/boot
r apt-get install memtest86+
r apt-get install python-software-properties software-properties-common
r add-apt-repository ppa:whdd/stable
r apt-get update
r apt-get install whdd
sudo tee $R/boot/grub/grub.cfg << EOF
default=Ubuntu
timeout=5
menuentry 'Memtest86+' {
linux16 (pxe)/boot/memtest86+.bin
}
menuentry 'Ubuntu' {
linux (pxe)/boot/vmlinuz-3.13.0-46-generic boot=nfs root=/dev/nfs nfsroot=$SERVER_IP:$R,ro ip=dhcp aufs=tmpfs
initrd /boot/initrd.img-3.13.0-46-generic
}
EOF
r apt-get install dmidecode
sudo tee $R/etc/init/set-hostname.conf << EOF
start on (starting hostname)
task
script
echo "thin-\$(ip l show eth0 | grep link\/ether | awk '{ print \$2 }' | sed 's/://g')" > /etc/hostname
end script
EOF
# For auto login:
sudo nano -w $R/etc/init/tty1.conf
# then do: http://askubuntu.com/a/168713/70654
r apt-get install byobu openssh-server # for remote control
# Then do byobu-enable as end_user
sudo chmod a+r -vR $R/boot
# Add tftp server ip as the next server dhcp
# Add /boot/grub/i386-pc/core.0
sudo stop tftpd-hpa
####
# https://help.ubuntu.com/community/EasyRouter
# SETUP DHCP SERVERION
sudo apt-get install isc-dhcp-server
# https://help.ubuntu.com/community/isc-dhcp-server
sudo stop tftpd-hpa
sudo in.tftpd --verbosity 10 --secure --foreground /tftpboot &
# sshpass -p pass ssh end_user@192.168.4.192
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment