--- /dev/null
+Scripts for initial setup of OSes on my home network.
+
+My network is a wndr3700v2 router with openwrt on it and a few pcs
+with various gnu/linux distros on them.
set -eE -o pipefail
trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
-cd "${BASH_SOURCE%/*}"
+cd $(dirname $(readlink -f "$BASH_SOURCE"))
export ROOTPW="$1"
export hostname="$2"
# https://wiki.archlinux.org/index.php/Dm-crypt/Device_encryption#Keyfiles
cp /root/luks/host-$hostname /mnt/crypto_keyfile.bin
+chmod 600 /mnt/crypto_keyfile.bin
shopt -s extglob
--- /dev/null
+#!/bin/bash
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
+
+usage() {
+ cat <<EOF
+Usage: ${0##*/} OPTIONS
+
+Given a tftproot, setup a preseed in it.
+
+-c Disable ssh network console. ssh user = installer. pw = test.
+-d Do debian ubuntu 14.04, default is jessie.
+-g GRUB_DISK Default is sda. Not used in interactive partitioning.
+-h|--help Print this help
+-i TFTP_IP Ip of tftp server. this is required.
+-p Stop for interactive partitioning.
+-t DIR Tftp root. Default is current dir.
+-u USER Username for the os install. Default is ${SUDO_USER:-$USER}
+
+EOF
+ exit $1
+}
+
+interactive_partition=false
+user=${SUDO_USER:-$USER}
+distro=debian-jessie
+net_console=false
+grub_disk=sda
+while [[ $1 == -* ]]; do
+ case $1 in
+ -c) net_console=false; shift ;;
+ -d) distro=ubuntu-14.04; shift ;;
+ -g) grub_disk=$2; shift 2 ;;
+ -i) ip=$2; shift 2 ;;
+ -p) interactive_partition=true; shift ;;
+ -t) cd $2; shift 2;;
+ -u) user=$2; shift 2;;
+ --) shift; break ;;
+ -*|-h|--help) usage ;;
+ esac
+done
+
+
+shopt -s extglob
+rm -rf !(netboot.tar.gz)
+preseed=example-preseed.txt
+neboot_path=main/installer-amd64/current/images/netboot/netboot.tar.gz
+case $distro in
+ ubuntu-14.04)
+ wget -q https://help.ubuntu.com/lts/installation-guide/$preseed
+ wget -qN http://archive.ubuntu.com/ubuntu/dists/trusty/$neboot_path
+ sed -ri 's!^tasksel tasksel/first multiselect .*!#\0!' $preseed
+ echo 'tasksel tasksel/first multiselect ubuntu-server, openssh-server' >>$preseed
+ ;;
+ debian-jessie)
+ wget -q https://www.debian.org/releases/jessie/$preseed
+ wget -qN http://ftp.nl.debian.org/debian/dists/jessie/$neboot_path
+ cat >>$preseed <<'EOF'
+tasksel tasksel/first multiselect ssh-server
+EOF
+ if ! $interactive_partition; then
+ cat >>$preseed <<EOF
+d-i grub-installer/bootdev string /dev/$grub_disk
+EOF
+ fi
+ ;;
+esac
+tar xzf netboot.tar.gz
+
+
+# if you set priority=critical, you can avoid a few of these questions. but
+# then you need to set the hostname in dhcp options
+# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=755848
+# questions you can avoid setting in boot parameters:
+# console-setup/ask_detect=false keyboard-configuration/layoutcode=us
+# hostname=$hostname
+# also, it asks about partition size. I don't know the preseeded answer,
+# as it just says "2.0 TB" in get-selections. I would need to figure out
+# how to accept the default.
+#
+# you can also see what got configured on a system with this command:
+# sudo apt-get install debconf-utils
+# debconf-get-selections --installer
+#
+
+# keymap=us is only needed for debian.
+pxe_cfg=${distro%-*}-installer/amd64/boot-screens/txt.cfg
+sed -ri "s#^[[:space:]]*append[[:space:]]#\0auto priority=critical locale=en_US.UTF-8 netcfg/choose_interface=auto url=tftp://$ip/example-preseed.txt keymap=us#" $pxe_cfg
+# various google results say timeout x will result in doing the default thing,
+# but that doesn't happen. no idea why. Maybe it needed to be part of the label.
+echo 'totaltimeout 1' | tee -a $pxe_cfg
+
+if $interactive_partition; then
+ sed -ri 's/^d-i[[:space:]]partman.*/#\0/' $preseed
+ # at least in ubuntu, this does automatic selection of boot device,
+ # and on a server where we setup raid, it choose sda, and failed
+ # and the whole installation could not be salvaged.
+ sed -ri 's/^d-i[[:space:]]grub-installer.*/#\0/' $preseed
+fi
+
+sed -ri "s#(^d-i time/zone string US/).*#\1Pacific#" $preseed
+sed -ri '/^xserver-xorg/,/[^\\$]/ s/.*/#\0/' $preseed
+# we set the locale in kernel args. maybe we don't need to. this overrides it.
+sed -ri 's!^d-i[[:space:]]debian-installer/locale[[:space:]].*!#\0!' $preseed
+
+# for secure pass, set the shadow option with mkpasswd -s -m sha-512 < passfile
+
+# the example config says this option shoudl work, but it doesn't. tried it with http too,
+# and tried naming it authorized_keys.
+#d-i network-console/authorized_keys_url tftp://tftp@10.0.0.107/id_rsa.pub
+
+if $net_console; then
+ cat >> $preseed <<EOF
+d-i anna/choose_modules string network-console
+# this doesn't work. todo: ask debian about it
+#d-i network-console/authorized_keys_url http://10.0.0.2/authorized_keys
+d-i network-console/password password test
+d-i network-console/password-again password test
+EOF
+fi
+
+cat >> $preseed <<EOF
+d-i hw-detect/load_firmware boolean true
+d-i partman/default_filesystem string ext4
+d-i passwd/user-fullname string $user
+d-i passwd/username string $user
+# cleartext password for testing.
+d-i passwd/user-password password $user
+d-i passwd/user-password-again password $user
+d-i passwd/root-password password $user
+d-i passwd/root-password-again password $user
+d-i pkgsel/update-policy select unattended-upgrades
+d-i preseed/late_command string \
+in-target sed -i 's/^%sudo.*$/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' /etc/sudoers; \
+in-target mkdir -p /home/$user/.ssh; \
+in-target /bin/sh -c "echo '$(cat ~/.ssh/id_rsa.pub)' >> /home/$user/.ssh/authorized_keys"; \
+in-target chown -R $user:$user /home/$user; \
+in-target chmod -R go-rwx /home/$user/.ssh/authorized_keys; \
+in-target cp -r /home/$user/.ssh /root; \
+in-target usermod -a -G sudo $user;
+EOF
--- /dev/null
+#!/bin/bash
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
+
+
+[[ $EUID == 0 ]] || exec sudo "$BASH_SOURCE" "$@"
+
+cd $(dirname $(readlink -f "$BASH_SOURCE"))
+
+mount_dir=$(mktemp -d)
+
+mount -o users wrt:/mnt/usb $mount_dir
+
+cd $mount_dir
+rm -rf debian-wheezy
+mkdir debian-wheezy
+cd debian-wheezy
+debian-preseed "$@" # my script
+cd ..
+rm -f tftpboot
+ln -s debian-wheezy tftpboot
+
+cd /
+umount $mount_dir
+pxe-server # my script
-#!/bin/bash -lx
+#!/bin/bash -l
+set -x
# Deploy fai configuration to faiserver,
# then start a virtual machine to test the config.
set -eE -o pipefail
trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
-ssh root@faiserver rm -rf /srv/fai/config/\*
-scp -r /a/bin/fai/fai/config root@faiserver:/srv/fai
+cd $(dirname $(readlink -f "$BASH_SOURCE"))
+
+ssh root@faiserver rm -rf /srv/fai/config
+scp -r fai/config root@faiserver:/srv/fai
# fai example pass: fai
#ROOTPW='$1$kBnWcO.E$djxB128U7dMkrltJHPf6d1'
-#!/bin/bash -lx
+#!/bin/bash -l
+set -x
+# Assumes pxe config for dhcp has been setup.
# Deploy fai configuration to faiserver,
# then start a virtual machine to test the config.
new_disk=false
[[ ! $1 ]] || new_disk=true
-cd "${BASH_SOURCE%/*}"
+cd $(dirname $(readlink -f "$BASH_SOURCE"))
-[[ $0 == *arch-revm ]] || ./fai-redep
+if [[ $0 == *arch-revm ]]; then
+ # via osinfo-query os. guessing arch is closest to latest fedora.
+ variant=fedora22
+else
+ ./fai-redep
+ variant=debian8
+fi
name=demohost
done
disk_arg=("--disk path=/var/lib/libvirt/images/$name"{,b})
-s virt-install --os-variant debian8 --cpu host -n $name --pxe -r 2048 --vcpus 1 \
+s virt-install --os-variant $variant --cpu host -n $name --pxe -r 2048 --vcpus 1 \
${disk_arg[*]} -w bridge=br0,mac=52:54:00:9c:ef:ad &
if [[ $0 == *arch-revm ]]; then
sed -r 's/^Depends:|,|\|[^,]+|isc-dhcp-server//g')
sed -i 's/^#deb/deb/' /etc/fai/apt/sources.list
sed -i 's/#LOGUSER/LOGUSER/' /etc/fai/fai.conf
-fai-setup -v
+# from man fai-make-nfsroot,
+# figured out after partitioning ignored my crypt partition
+if ! grep cryptsetup /etc/fai/NFSROOT &>/dev/null; then
+ sed -ri '/^PACKAGES install$/a cryptsetup' /etc/fai/NFSROOT
+fi
+fai-setup -vf
{ head -n 1 /srv/fai/nfsroot/root/.ssh/known_hosts | awk '{print $1}' \
| tr '\n' ' '; ssh-keyscan localhost | grep -o "ecdsa-sha2-nistp256.*"; \
} >>/srv/fai/nfsroot/root/.ssh/known_hosts
-# from config machine. todo: clean this up.
+# this does not alter the config on a new install
sed -ri 's#^([[:space:]]*TFTP_DIRECTORY[[:space:]]*=).*#\1"/srv/tftp"#' \
/etc/default/tftpd-hpa
std_arg="-u nfs://faiserver/srv/fai/config"
fai-chboot -Iv $std_arg default
kernel=$(fai-chboot -L '^default$' | awk '{print $3}')
-my_ip=$(getent hosts faiserver | awk '{ print $1 }')
+type -t host &>/dev/null || apt-get -y install dnsutils
+my_ip=$(host faiserver $(route -n | sed -rn 's/^(0\.){3}0\s+(\S+).*/\2/p') | \
+ sed -rn 's/^faiserver has address //p')
k_args=$(fai-chboot -L '^default$' | \
sed -r "s/^(\S+\s+){3}(.*root=)(.*)/\2$my_ip:\3/")
fai-chboot -k "$k_args" -v -f verbose,sshd,createvt,reboot $std_arg $kernel default
# make the faiserver also the apt proxy server
-apt-get install apt-cacher-ng
+apt-get -y install apt-cacher-ng
# background on choosing apt-cacher-ng:
# googling around a bit finds 2 main solutions:
# http://askubuntu.com/questions/3503/best-way-to-cache-apt-downloads-on-a-lan
# apt-cacher-ng doesn't have zeroconf.
-# so I'm not sure how smart it will be if the server goes down.
# It touts having minimal dependencies, but I don't care.
# The downside to squid-deb-proxy is that it's config is for specific repos,
# you have to add all the repos you use.
# random fai note: as far as I can tell, profiles are just for putting
# in a selectable boot menu, which I don't want.
-if [[ ! -e ~/.ssh/id_rsa.pub ]]; then
- ssh-keygen -t rsa -N ''
-fi
-x=$(mktemp); ssh -F /dev/null -oUserKnownHostsFile=$x localhost :
-cat x | tee -a /srv/fai/nfsroot/root/.ssh/known_hosts
+# somewhere I call it faiserver, but debian's default is faiserver.lan
+sed -ri 's/faiserver.lan/faiserver/' /srv/fai/nfsroot/root/.ssh/known_hosts
+++ /dev/null
-# from man fai-make-nfsroot,
-# after partitioning ignored my crypt partition
-
-PACKAGES install
-cryptsetup
done
done
-partition=true # override temporarily
+#partition=true # for temporarily override
# keyfiles generated like:
# head -c 2048 /dev/urandom | od | s dd of=/q/root/luks/host-demohost
if $partition; then
for dev in ${devs[@]}; do
for x in $dev[0-9]; do wipefs -a $x; done
+ done
+ for dev in ${devs[@]}; do
parted -s $dev mklabel gpt
# gpt ubuntu cloud image uses ~4. fai uses 1 MiB. ehh, i'll do 4.
# also, using MB instead of MiB causes complains about alignment.
--- /dev/null
+#!/bin/bash -l
+set -x
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
+
+cd $(dirname $(readlink -f "$BASH_SOURCE"))
+
+./debian-pxe-preseed -i 192.168.1.1 -u ian -g vda
+
+name=faiserver
+s virshrm $name ||:
+
+f=/var/lib/libvirt/images/${name}
+s qemu-img create -o preallocation=metadata -f qcow2 $f 30G
+
+s virt-install --os-variant debian8 --cpu host -n $name --pxe -r 1024 --vcpus 1 \
+ --disk $f -w bridge=br0,mac=52:54:00:56:09:f9 &
+
+sleep $((60*6)) # takes like 10x as long as a fai install!
+while ! scp fai-setup root@faiserver:; do
+ sleep 5
+done
+
+ssh root@faiserver ./fai-setup
--- /dev/null
+#!/bin/bash -x
+
+# usage: $0 [TYPE]
+# default distro is the base debian/fedora type. others are fai & arch
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
+
+action=${1:-default}
+
+arch() {
+ default
+ cat <<'EOF'
+dhcp-option-force=209,boot/syslinux/archiso.cfg
+dhcp-option-force=210,/arch/
+dhcp-boot=/arch/boot/syslinux/lpxelinux.0
+EOF
+}
+
+default() {
+ cat <<'EOF'
+enable-tftp
+tftp-root=/mnt/usb/tftpboot
+dhcp-boot=pxelinux.0
+EOF
+}
+
+fai() {
+ cat <<'EOF'
+dhcp-boot=fai/pxelinux.0,faiserver.lan,faiserver.lan
+EOF
+}
+
+
+$action | ssh wrt "cedit pxe-server /etc/dnsmasq.conf || /etc/init.d/dnsmasq restart
+if [[ $action == arch ]]; then arch-pxe-mount; fi"
--- /dev/null
+#!/bin/bash
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
+
+
+# ssh
+
+pmirror() {
+ # background: upgrading all packages is not recommended because it
+ # doesn't go into the firmware. build new firmware if you want
+ # lots of upgrades.
+ f=(/tmp/opkg-lists/*)
+ f=${f[0]}
+ if ! (( $(date -r $f +%s) + 60*60*24 > $(date +%s) )); then
+ opkg update
+ fi
+}
+
+pi() {
+ for x in "$@"; do
+ if [[ ! $(opkg list-installed "$x") ]]; then
+ pmirror
+ opkg install "$@"
+ fi
+ done
+}
+
+v() {
+ printf "+ %s\n" "$*"
+ "$@"
+}
+
+cat >/usr/bin/arch-pxe-mount <<'EOFOUTER'
+#!/bin/bash
+# symlinks are collapsed for nfs mount points, so use a bind mount.
+# tried putting this in /etc/config/fstab,
+# then doig block mount, it didn't work. This doesn't persist across reboots,
+# todo: figure that out
+d=/run/archiso/bootmnt
+cat > /etc/fstab <<EOF
+/mnt/usb/tftpboot $d none bind 0 0
+EOF
+mount | grep $d &>/dev/null || mount $d
+/etc/init.d/nfsd restart
+EOFOUTER
+chmod +x /usr/bin/arch-pxe-mount
+
+cat >.profile <<'EOF'
+# changing login shell emits spam on ssh single commands & scp
+ # sed -i 's#/bin/ash$#/bin/bash#' /etc/passwd
+#https://dev.openwrt.org/ticket/13852
+[ "$PS1" = "" ] || {
+ /bin/bash
+ exit
+}
+EOF
+v pi kmod-usb-storage block-mount kmod-fs-ext4 nfs-kernel-server
+
+
+
+sed -ri "s/option[[:space:]]*encryption[[:space:]]*'?none'?/option encryption psk2\n option key pictionary49/" /etc/config/wireless
+sed -i '/^[[:space:]]*option disabled/d' /etc/config/wireless
+v wifi
+
+
+v /etc/init.d/fstab enable ||:
+
+# rebooting makes mounting work, but comparing lsmod,
+# i'm guessing this will too. todo, test it.
+# 255 == module already loaded
+for mod in scsi_mod sd_mod; do v modprobe $mod || [[ $? == 255 ]]; done
+
+# for arch pxe. The default settings in the installer expect to find
+# the NFS at /run/archiso/bootmnt
+mkdir -p /run/archiso/bootmnt
+
+# todo: at some later time, i found /mnt/usb not mounted, watch to see if
+# that is the case after running this or rebooting.
+# wiki says safe to do in case of fstab changes:
+cedit /etc/config/fstab <<'EOF' || { v block umount; v block mount; }
+config global automount
+ option from_fstab 1
+ option anon_mount 1
+
+config global autoswap
+ option from_fstab 1
+ option anon_swap 1
+
+config mount
+ option target /mnt/usb
+ option device /dev/sda2
+ option fstype ext4
+ option options rw,async,noatime,nodiratime
+ option enabled 1
+ option enabled_fsck 0
+
+config swap
+ option device /dev/sda1
+ option enabled 1
+
+EOF
+
+
+
+ # exportfs -ra won't cut it when its the same path, but now a bind mount
+cedit /etc/exports <<'EOF' || v /etc/init.d/nfsd restart ||:
+/mnt/usb 192.168.1.0/255.255.255.0(rw,no_root_squash,insecure,sync,no_subtree_check)
+# for arch pxe
+/run/archiso/bootmnt 192.168.1.0/255.255.255.0(rw,no_root_squash,insecure,sync,no_subtree_check)
+
+EOF
+
+
+v /etc/init.d/portmap start
+v /etc/init.d/nfsd start
+v /etc/init.d/portmap enable
+v /etc/init.d/nfsd enable
+
+
+
+cedit /etc/config/firewall <<'EOF' || /etc/init.d/firewall restart
+# port forwarding
+config redirect
+option name bittorrent
+option src wan
+option src_dport 63324
+option dest_ip 192.168.1.2
+option dest lan
+# making the port open (not sure if this is actually needed)
+config rule
+option src wan
+option target ACCEPT
+option dest_port 63324
+
+
+config redirect
+option name bithtpc
+option src wan
+option src_dport 63325
+option dest_ip 192.168.1.4
+option dest lan
+
+config rule
+option src wan
+option target ACCEPT
+option dest_port 63325
+
+
+config redirect
+option name ssh
+option src wan
+#uncomment the 2 lines for security of using a non-standard port
+# and comment out the 22 port line
+# option src_dport 63321
+option src_dport 22
+option dest_ip 192.168.1.2
+option dest lan
+# option dest_port 22 # already default
+
+config rule
+option src wan
+option target ACCEPT
+option dest_port 22
+
+
+# for https
+config redirect
+ option src wan
+ option src_dport 443
+ option dest lan
+ option dest_ip 192.168.1.2
+ option proto tcp
+
+config rule
+ option src wan
+ option target ACCEPT
+ option dest_port 443
+ option proto tcp
+
+
+config redirect
+ option src wan
+ option src_dport 80
+ option dest lan
+ option dest_ip 192.168.1.2
+ option proto tcp
+
+config rule
+ option src wan
+ option target ACCEPT
+ option dest_port 80
+ option proto tcp
+EOF
+
+
+dnsmasq_restart=false
+cedit /etc/hosts <<EOF || dnsmasq_restart=true
+192.168.1.1 wrt
+192.168.1.2 treetowl
+192.168.1.3 frodo
+192.168.1.4 htpc
+192.168.1.5 x2
+192.168.1.6 testvm
+192.168.1.7 faiserver
+72.14.176.105 li
+EOF
+
+
+
+# useful: http://wiki.openwrt.org/doc/howto/dhcp.dnsmasq
+
+cedit /etc/dnsmasq.conf <<'EOF' || dnsmasq_restart=true
+
+############ updating dns servers ###################3
+# download namebench and run it like this:
+# for x in all regional isp global preferred nearby; do ./namebench.py -s $x -c US -i firefox -m weighted -J 10 -w; echo $x; hr; done
+
+
+# this says the ip of default gateway and dns server,
+# but I think they are unneded and default
+#dhcp-option=3,192.168.1.1
+#dhcp-option=6,192.168.1.1
+
+
+
+# results from googling around dnsmasq optimizations
+# about 50k in memory. router has 62 megs.
+# in a browsing session, I probably won't ever do 5000 lookups
+# before the ttl expiration or whatever does expiration.
+cache-size=10000
+# http://ma.ttwagner.com/make-dns-fly-with-dnsmasq-all-servers/
+all-servers
+# namebench showed 4 servers fairly close ranking:
+# qwest
+server=205.171.3.65
+server=205.171.2.25
+# clearwire anchorage
+server=64.13.115.12
+# comcast spokane
+server=68.87.69.146
+# google
+server=8.8.4.4
+# NTT
+server=129.250.35.250
+# isp servers
+server=75.75.76.76
+server=75.75.75.75
+
+
+
+# to fixup existin ips, on the client you can do
+# sudo dhclient -r; sudo dhclient <interface-name>
+
+dhcp-host=f4:6d:04:02:ee:eb,192.168.1.2,treetowl
+dhcp-host=00:26:18:97:bb:16,192.168.1.3,frodo
+dhcp-host=10:78:d2:da:29:22,192.168.1.4,htpc
+dhcp-host=00:1f:16:16:39:24,192.168.1.5,x2
+# this is so fai can have an explicit name to use for testing,
+# or else any random machine which did a pxe boot would get
+# reformatted. The mac is from doing a virt-install, cancelling it,
+# and copying the generated mac, so it should be randomish.
+dhcp-host=52:54:00:9c:ef:ad,192.168.1.6,demohost
+dhcp-host=52:54:00:56:09:f9,192.168.1.7,faiserver
+dhcp-host=80:fa:5b:1c:6e:cf,192.168.1.8,tp
+
+
+# template
+# dhcp-host=,192.168.1.,
+EOF
+
+if $dnsmasq_restart; then
+ v /etc/init.d/dnsmasq restart
+fi
--- /dev/null
+#!/bin/bash
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
+
+h=root@192.168.1.1
+scp /a/bin/fai/wrt-setup /a/bin/bash-programs-by-ian/repos/cedit/cedit $h:/usr/bin
+ssh $h <<'EOF'
+if ! opkg list-installed|grep bash; then
+ opkg update
+ opkg install bash
+fi
+wrt-setup
+EOF