aboutsummaryrefslogtreecommitdiff
path: root/rpi2-gen-image.sh
diff options
context:
space:
mode:
authorJan Wagner <mail@jwagner.eu>2015-12-04 01:33:40 +0100
committerJan Wagner <mail@jwagner.eu>2015-12-04 01:33:40 +0100
commitd773fd3c878cbd47ed33dfa54651522647709825 (patch)
treeaddc319e573c626fee557d111c464ab4030e3a6b /rpi2-gen-image.sh
parentce7824a539b1826d669b0036a8b34663d64ee35b (diff)
downloadrpi2-gen-image-d773fd3c878cbd47ed33dfa54651522647709825.tar.gz
rpi2-gen-image-d773fd3c878cbd47ed33dfa54651522647709825.tar.bz2
rpi2-gen-image-d773fd3c878cbd47ed33dfa54651522647709825.zip
first public release
Diffstat (limited to 'rpi2-gen-image.sh')
-rwxr-xr-xrpi2-gen-image.sh700
1 files changed, 700 insertions, 0 deletions
diff --git a/rpi2-gen-image.sh b/rpi2-gen-image.sh
new file mode 100755
index 0000000..6ba8a1c
--- /dev/null
+++ b/rpi2-gen-image.sh
@@ -0,0 +1,700 @@
+#!/bin/sh
+
+########################################################################
+# rpi2-gen-image.sh ver2a 12/2015
+#
+# Advanced debian "jessie" bootstrap script for RPi2
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# some parts based on rpi2-build-image:
+# Copyright (C) 2015 Ryan Finnie <ryan@finnie.org>
+# Copyright (C) 2015 Luca Falavigna <dktrkranz@debian.org>
+########################################################################
+
+cleanup (){
+ set +x
+ set +e
+ echo "removing temporary mount points ..."
+ umount -l $R/proc 2> /dev/null
+ umount -l $R/sys 2> /dev/null
+ umount -l $R/dev/pts 2> /dev/null
+ umount "$BUILDDIR/mount/boot/firmware" 2> /dev/null
+ umount "$BUILDDIR/mount" 2> /dev/null
+ losetup -d "$EXT4_LOOP" 2> /dev/null
+ losetup -d "$VFAT_LOOP" 2> /dev/null
+ trap - 0 1 2 3 6
+}
+
+set -e
+set -x
+
+RELEASE=${RELEASE:=jessie}
+
+# Build settings
+BASEDIR=./images/${RELEASE}
+BUILDDIR=${BASEDIR}/build
+
+# General settings
+HOSTNAME=${HOSTNAME:=rpi2-${RELEASE}}
+PASSWORD=${PASSWORD:=raspberry}
+DEFLOCAL=${DEFLOCAL:="en_US.UTF-8"}
+TIMEZONE=${TIMEZONE:="Europe/Berlin"}
+
+# APT settings
+APT_PROXY=${APT_PROXY:=""}
+APT_SERVER=${APT_SERVER:="ftp.debian.org"}
+
+# Feature settings
+ENABLE_CONSOLE=${ENABLE_CONSOLE:=true}
+ENABLE_IPV6=${ENABLE_IPV6:=true}
+ENABLE_SSHD=${ENABLE_SSHD:=true}
+ENABLE_SOUND=${ENABLE_SOUND:=true}
+ENABLE_SYSTEMD=${ENABLE_SYSTEMD:=true}
+ENABLE_DBUS=${ENABLE_DBUS:=true}
+ENABLE_HWRANDOM=${ENABLE_HWRANDOM:=true}
+ENABLE_MINGPU=${ENABLE_MINGPU:=false}
+ENABLE_XORG=${ENABLE_XORG:=false}
+ENABLE_FLUXBOX=${ENABLE_FLUXBOX:=false}
+
+# Advanced settings
+ENABLE_HARDNET=${ENABLE_HARDNET:=false}
+ENABLE_IPTABLES=${ENABLE_IPTABLES:=false}
+
+# Image chroot path
+R=${BUILDDIR}/chroot
+
+# Packages required for bootstrapping
+REQUIRED_PACKAGES="debootstrap debian-archive-keyring qemu-user-static dosfstools rsync bmap-tools whois"
+
+# Packages required in the chroot build enviroment
+APT_INCLUDES="apt-transport-https,ca-certificates,debian-archive-keyring,dialog,locales,apt-utils,vim-tiny"
+
+set +x
+
+# Are we running as root?
+if [ "$(id -u)" -ne "0" ] ; then
+ echo "this script must be executed with root privileges"
+ exit 1
+fi
+
+# Don't clobber an old build
+if [ -e "$BUILDDIR" ]; then
+ echo "directory $BUILDDIR already exists, not proceeding"
+ exit 1
+fi
+
+set -x
+
+# Call "cleanup" function on various signals and errors
+trap cleanup 0 1 2 3 6
+
+# Set up chroot directory
+mkdir -p $R
+
+# Install dependencies
+apt-get -q -y install ${REQUIRED_PACKAGES}
+
+# Use traditional SystemV init instead of systemd services
+if [ "$ENABLE_SYSTEMD" = false ] ; then
+ APT_INCLUDES="${APT_INCLUDES},sysvinit-core"
+fi
+
+# Add dbus package, recommended if using systemd
+if [ "$ENABLE_DBUS" = true ] ; then
+ APT_INCLUDES="${APT_INCLUDES},dbus"
+fi
+
+# Add openssh server package
+if [ "$ENABLE_SSHD" = true ] ; then
+ APT_INCLUDES="${APT_INCLUDES},openssh-server"
+fi
+
+# Add rng-tools package
+if [ "$ENABLE_HWRANDOM" = true ] ; then
+ APT_INCLUDES="${APT_INCLUDES},rng-tools"
+fi
+
+# Add xorg package
+if [ "$ENABLE_XORG" = true ] ; then
+ APT_INCLUDES="${APT_INCLUDES},xorg"
+fi
+
+# Add fluxbox package with eterm
+if [ "$ENABLE_FLUXBOX" = true ] ; then
+ APT_INCLUDES="${APT_INCLUDES},fluxbox,eterm"
+fi
+
+if [ -z "$APT_PROXY" ] ; then
+ APT_PROXY="http://"
+fi
+
+# Base debootstrap (unpack only)
+debootstrap --arch=armhf --foreign --include=${APT_INCLUDES} $RELEASE $R ${APT_PROXY}${APT_SERVER}/debian
+cp /usr/bin/qemu-arm-static $R/usr/bin
+
+# Remove systemd releated packages from list of packages to be bootsrapped
+if [ "$ENABLE_SYSTEMD" = false ] ; then
+ chroot $R sed -i -e 's/systemd systemd-sysv //g' /debootstrap/required
+fi
+
+# Copy debian-archive-keyring.pgp
+chroot $R mkdir -p /usr/share/keyrings
+cp /usr/share/keyrings/debian-archive-keyring.gpg $R/usr/share/keyrings/debian-archive-keyring.gpg
+
+# Complete the bootstrapping proccess
+chroot $R /debootstrap/debootstrap --second-stage
+
+# Mount required filesystems
+mount -t proc none $R/proc
+mount -t sysfs none $R/sys
+mount --bind /dev/pts $R/dev/pts
+
+# Set up initial sources.list
+cat <<EOM >$R/etc/apt/sources.list
+deb http://${APT_SERVER}/debian ${RELEASE} main contrib
+#deb-src http://${APT_SERVER}/debian ${RELEASE} main contrib
+
+deb http://${APT_SERVER}/debian/ ${RELEASE}-updates main contrib
+#deb-src http://${APT_SERVER}/debian/ ${RELEASE}-updates main contrib
+
+deb http://security.debian.org/ ${RELEASE}/updates main contrib
+#deb-src http://security.debian.org/ ${RELEASE}/updates main contrib
+
+deb https://repositories.collabora.co.uk/debian ${RELEASE} rpi2
+EOM
+
+# Pin package flash-kernel to repositories.collabora.co.uk
+cat <<EOM >$R/etc/apt/preferences.d/flash-kernel
+Package: flash-kernel
+Pin: origin repositories.collabora.co.uk
+Pin-Priority: 1000
+EOM
+
+# Set up timezone
+echo ${TIMEZONE} >$R/etc/timezone
+LANG=C chroot $R dpkg-reconfigure -f noninteractive tzdata
+
+# Set up default locales to "en_US.UTF-8" default
+LANG=C chroot $R sed -i '/${DEFLOCAL}/s/^#//' /etc/locale.gen
+LANG=C chroot $R locale-gen ${DEFLOCAL}
+
+# Fetch APT public key "Collabora Raspbian Archive Signing Key <daniels@collabora.com>"
+LANG=C chroot $R apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-keys ED4BF9140C50B1C5
+
+# Upgrade package index and update all installed packages and changed dependencies
+LANG=C chroot $R apt-get -q -y update
+LANG=C chroot $R apt-get -q -y -u dist-upgrade
+
+# Kernel installation
+# Install flash-kernel last so it doesn't try (and fail) to detect the platform in the chroot
+
+LANG=C chroot $R apt-get -q -y --force-yes --no-install-recommends install linux-image-3.18.0-trunk-rpi2
+LANG=C chroot $R apt-get -q -y --force-yes install flash-kernel
+
+VMLINUZ="$(ls -1 $R/boot/vmlinuz-* | sort | tail -n 1)"
+[ -z "$VMLINUZ" ] && exit 1
+mkdir -p $R/boot/firmware
+
+# required boot binaries from raspberry/firmware github (commit: "kernel: Bump to 3.18.10")
+wget -q -O $R/boot/firmware/bootcode.bin https://github.com/raspberrypi/firmware/raw/cd355a9dd4f1f4de2e79b0c8e102840885cdf1de/boot/bootcode.bin
+wget -q -O $R/boot/firmware/fixup_cd.dat https://github.com/raspberrypi/firmware/raw/cd355a9dd4f1f4de2e79b0c8e102840885cdf1de/boot/fixup_cd.dat
+wget -q -O $R/boot/firmware/fixup.dat https://github.com/raspberrypi/firmware/raw/cd355a9dd4f1f4de2e79b0c8e102840885cdf1de/boot/fixup.dat
+wget -q -O $R/boot/firmware/fixup_x.dat https://github.com/raspberrypi/firmware/raw/cd355a9dd4f1f4de2e79b0c8e102840885cdf1de/boot/fixup_x.dat
+wget -q -O $R/boot/firmware/start_cd.elf https://github.com/raspberrypi/firmware/raw/cd355a9dd4f1f4de2e79b0c8e102840885cdf1de/boot/start_cd.elf
+wget -q -O $R/boot/firmware/start.elf https://github.com/raspberrypi/firmware/raw/cd355a9dd4f1f4de2e79b0c8e102840885cdf1de/boot/start.elf
+wget -q -O $R/boot/firmware/start_x.elf https://github.com/raspberrypi/firmware/raw/cd355a9dd4f1f4de2e79b0c8e102840885cdf1de/boot/start_x.elf
+cp $VMLINUZ $R/boot/firmware/kernel7.img
+
+# Set up hosts
+echo ${HOSTNAME} >$R/etc/hostname
+cat <<EOM >$R/etc/hosts
+127.0.0.1 localhost
+127.0.1.1 ${HOSTNAME}
+EOM
+
+if [ "$ENABLE_IPV6" = true ] ; then
+cat <<EOM >>$R/etc/hosts
+
+::1 localhost ip6-localhost ip6-loopback
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters
+EOM
+fi
+
+# Generate crypt(3) password string
+ENCRYPTED_PASSWORD=`mkpasswd -m sha-512 ${PASSWORD}`
+
+# Set up default user
+LANG=C chroot $R adduser --gecos "Raspberry PI user" --add_extra_groups --disabled-password pi
+LANG=C chroot $R usermod -a -G sudo -p "${ENCRYPTED_PASSWORD}" pi
+
+# Set up root password
+LANG=C chroot $R usermod -p "${ENCRYPTED_PASSWORD}" root
+
+# Clean cached downloads
+LANG=C chroot $R apt-get -y clean
+LANG=C chroot $R apt-get -y autoclean
+LANG=C chroot $R apt-get -y autoremove
+
+# Set up interfaces
+cat <<EOM >$R/etc/network/interfaces
+# interfaces(5) file used by ifup(8) and ifdown(8)
+# Include files from /etc/network/interfaces.d:
+source-directory /etc/network/interfaces.d
+
+# The loopback network interface
+auto lo
+iface lo inet loopback
+
+# The primary network interface
+allow-hotplug eth0
+iface eth0 inet dhcp
+EOM
+
+# Set up firmware boot cmdline
+CMDLINE="dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 rootflags=commit=100,data=writeback elevator=deadline rootwait net.ifnames=1 console=tty1"
+
+# Set up serial console support (if requested)
+if [ "$ENABLE_CONSOLE" = true ] ; then
+ CMDLINE="${CMDLINE} console=ttyAMA0,115200 kgdboc=ttyAMA0,115200"
+fi
+
+# Set up ipv6 support (if requested)
+if [ "$ENABLE_IPV6" = false ] ; then
+ CMDLINE="${CMDLINE} ipv6.disable=1"
+fi
+
+echo "${CMDLINE}" >$R/boot/firmware/cmdline.txt
+
+# Set up firmware config
+cat <<EOM >$R/boot/firmware/config.txt
+# For more options and information see
+# http://www.raspberrypi.org/documentation/configuration/config-txt.md
+# Some settings may impact device functionality. See link above for details
+
+# uncomment if you get no picture on HDMI for a default "safe" mode
+#hdmi_safe=1
+
+# uncomment this if your display has a black border of unused pixels visible
+# and your display can output without overscan
+#disable_overscan=1
+
+# uncomment the following to adjust overscan. Use positive numbers if console
+# goes off screen, and negative if there is too much border
+#overscan_left=16
+#overscan_right=16
+#overscan_top=16
+#overscan_bottom=16
+
+# uncomment to force a console size. By default it will be display's size minus
+# overscan.
+#framebuffer_width=1280
+#framebuffer_height=720
+
+# uncomment if hdmi display is not detected and composite is being output
+#hdmi_force_hotplug=1
+
+# uncomment to force a specific HDMI mode (this will force VGA)
+#hdmi_group=1
+#hdmi_mode=1
+
+# uncomment to force a HDMI mode rather than DVI. This can make audio work in
+# DMT (computer monitor) modes
+#hdmi_drive=2
+
+# uncomment to increase signal to HDMI, if you have interference, blanking, or
+# no display
+#config_hdmi_boost=4
+
+# uncomment for composite PAL
+#sdtv_mode=2
+
+#uncomment to overclock the arm. 700 MHz is the default.
+#arm_freq=800
+EOM
+
+# Set smallest possible GPU memory allocation size: 16MB (no X)
+if [ "$ENABLE_MINGPU" = true ] ; then
+ echo "gpu_mem=16" >>$R/boot/firmware/config.txt
+fi
+
+# Create symlinks
+ln -sf firmware/config.txt $R/boot/config.txt
+ln -sf firmware/cmdline.txt $R/boot/cmdline.txt
+
+# Prepare modules-load.d directory
+mkdir -p $R/lib/modules-load.d/
+
+# Load random module on boot
+if [ "$ENABLE_HWRANDOM" = true ] ; then
+ cat <<EOM >$R/lib/modules-load.d/rpi2.conf
+bcm2708_rng
+EOM
+fi
+
+# Prepare modprobe.d directory
+mkdir -p $R/etc/modprobe.d/
+
+# Blacklist sound modules
+cat <<EOM >$R/etc/modprobe.d/raspi-blacklist.conf
+blacklist snd_soc_core
+blacklist snd_pcm
+blacklist snd_pcm_dmaengine
+blacklist snd_timer
+blacklist snd_compress
+blacklist snd_soc_pcm512x_i2c
+blacklist snd_soc_pcm512x
+blacklist snd_soc_tas5713
+blacklist snd_soc_wm8804
+EOM
+
+# Create default fstab
+cat <<EOM >$R/etc/fstab
+/dev/mmcblk0p2 / ext4 noatime,nodiratime,errors=remount-ro,discard,data=writeback,commit=100 0 1
+/dev/mmcblk0p1 /boot/firmware vfat defaults,noatime,nodiratime 0 2
+EOM
+
+# Avoid swapping and increase cache sizes
+cat <<EOM >>$R/etc/sysctl.d/99-sysctl.conf
+
+# Avoid swapping and increase cache sizes
+vm.swappiness=1
+vm.dirty_background_ratio=20
+vm.dirty_ratio=40
+vm.dirty_writeback_centisecs=500
+vm.dirty_expire_centisecs=6000
+EOM
+
+# Enable network stack hardening
+if [ "$ENABLE_HARDNET" = true ] ; then
+ cat <<EOM >>$R/etc/sysctl.d/99-sysctl.conf
+
+# Enable network stack hardening
+net.ipv4.tcp_timestamps=0
+net.ipv4.tcp_syncookies=1
+net.ipv4.conf.all.rp_filter=1
+net.ipv4.conf.all.accept_redirects=0
+net.ipv4.conf.all.send_redirects=0
+net.ipv4.conf.all.accept_source_route=0
+net.ipv4.conf.default.rp_filter=1
+net.ipv4.conf.default.accept_redirects=0
+net.ipv4.conf.default.send_redirects=0
+net.ipv4.conf.default.accept_source_route=0
+net.ipv4.conf.lo.accept_redirects=0
+net.ipv4.conf.lo.send_redirects=0
+net.ipv4.conf.lo.accept_source_route=0
+net.ipv4.conf.eth0.accept_redirects=0
+net.ipv4.conf.eth0.send_redirects=0
+net.ipv4.conf.eth0.accept_source_route=0
+net.ipv4.icmp_echo_ignore_broadcasts=1
+net.ipv4.icmp_ignore_bogus_error_responses=1
+
+net.ipv6.conf.all.accept_redirects=0
+net.ipv6.conf.all.accept_source_route=0
+net.ipv6.conf.all.router_solicitations=0
+net.ipv6.conf.all.accept_ra_rtr_pref=0
+net.ipv6.conf.all.accept_ra_pinfo=0
+net.ipv6.conf.all.accept_ra_defrtr=0
+net.ipv6.conf.all.autoconf=0
+net.ipv6.conf.all.dad_transmits=0
+net.ipv6.conf.all.max_addresses=1
+
+net.ipv6.conf.default.accept_redirects=0
+net.ipv6.conf.default.accept_source_route=0
+net.ipv6.conf.default.router_solicitations=0
+net.ipv6.conf.default.accept_ra_rtr_pref=0
+net.ipv6.conf.default.accept_ra_pinfo=0
+net.ipv6.conf.default.accept_ra_defrtr=0
+net.ipv6.conf.default.autoconf=0
+net.ipv6.conf.default.dad_transmits=0
+net.ipv6.conf.default.max_addresses=1
+
+net.ipv6.conf.lo.accept_redirects=0
+net.ipv6.conf.lo.accept_source_route=0
+net.ipv6.conf.lo.router_solicitations=0
+net.ipv6.conf.lo.accept_ra_rtr_pref=0
+net.ipv6.conf.lo.accept_ra_pinfo=0
+net.ipv6.conf.lo.accept_ra_defrtr=0
+net.ipv6.conf.lo.autoconf=0
+net.ipv6.conf.lo.dad_transmits=0
+net.ipv6.conf.lo.max_addresses=1
+
+net.ipv6.conf.eth0.accept_redirects=0
+net.ipv6.conf.eth0.accept_source_route=0
+net.ipv6.conf.eth0.router_solicitations=0
+net.ipv6.conf.eth0.accept_ra_rtr_pref=0
+net.ipv6.conf.eth0.accept_ra_pinfo=0
+net.ipv6.conf.eth0.accept_ra_defrtr=0
+net.ipv6.conf.eth0.autoconf=0
+net.ipv6.conf.eth0.dad_transmits=0
+net.ipv6.conf.eth0.max_addresses=1
+EOM
+
+# Enable resolver warnings about spoofed addresses
+ cat <<EOM >>$R/etc/host.conf
+spoof warn
+EOM
+fi
+
+# Regenerate openssh server host keys
+if [ "$ENABLE_SSHD" = true ] ; then
+ rm -fr $R/etc/ssh/ssh_host_*
+ LANG=C chroot $R dpkg-reconfigure openssh-server
+fi
+
+# Enable serial console systemd style
+if [ "$ENABLE_CONSOLE" = true ] ; then
+ LANG=C chroot $R systemctl enable serial-getty\@ttyAMA0.service
+fi
+
+# Enable firewall based on iptables started by systemd service
+if [ "$ENABLE_IPTABLES" = true ] ; then
+ # Create iptables configuration directory
+ mkdir -p "$R/etc/iptables"
+
+ # Create iptables systemd service
+ cat <<EOM >$R/etc/systemd/system/iptables.service
+[Unit]
+Description=Packet Filtering Framework
+DefaultDependencies=no
+After=systemd-sysctl.service
+Before=sysinit.target
+[Service]
+Type=oneshot
+ExecStart=/sbin/iptables-restore /etc/iptables/iptables.rules
+ExecReload=/sbin/iptables-restore /etc/iptables/iptables.rules
+ExecStop=/etc/iptables/flush-iptables.sh
+RemainAfterExit=yes
+[Install]
+WantedBy=multi-user.target
+EOM
+
+ # Create flush-table script called by iptables service
+ cat <<EOM >$R/etc/iptables/flush-iptables.sh
+#!/bin/sh
+iptables -F
+iptables -X
+iptables -t nat -F
+iptables -t nat -X
+iptables -t mangle -F
+iptables -t mangle -X
+iptables -P INPUT ACCEPT
+iptables -P FORWARD ACCEPT
+iptables -P OUTPUT ACCEPT
+EOM
+
+ # Create iptables rule file
+ cat <<EOM >$R/etc/iptables/iptables.rules
+*filter
+:INPUT DROP [0:0]
+:FORWARD DROP [0:0]
+:OUTPUT ACCEPT [0:0]
+:TCP - [0:0]
+:UDP - [0:0]
+:SSH - [0:0]
+
+# Rate limit ping requests
+-A INPUT -p icmp --icmp-type echo-request -m limit --limit 30/min --limit-burst 8 -j ACCEPT
+-A INPUT -p icmp --icmp-type echo-request -j DROP
+
+# Accept established connections
+-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
+
+# Accept all traffic on loopback interface
+-A INPUT -i lo -j ACCEPT
+
+# Drop packets declared invalid
+-A INPUT -m conntrack --ctstate INVALID -j DROP
+
+# SSH rate limiting
+-A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j SSH
+-A SSH -m recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j DROP
+-A SSH -m recent --name sshbf --rttl --rcheck --hitcount 20 --seconds 1800 -j DROP
+-A SSH -m recent --name sshbf --set -j ACCEPT
+
+# Send TCP and UDP connections to their respective rules chain
+-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
+-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
+
+# Reject dropped packets with a RFC compliant responce
+-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
+-A INPUT -p tcp -j REJECT --reject-with tcp-rst
+-A INPUT -j REJECT --reject-with icmp-proto-unreachable
+
+## TCP PORT RULES
+# -A TCP -p tcp -j LOG
+
+## UDP PORT RULES
+# -A UDP -p udp -j LOG
+
+COMMIT
+EOM
+
+ # Reload systemd configuration and enable iptables service
+ LANG=C chroot $R systemctl daemon-reload
+ LANG=C chroot $R systemctl enable iptables.service
+
+ if [ "$ENABLE_IPV6" = true ] ; then
+ # Create ip6tables systemd service
+ cat <<EOM >$R/etc/systemd/system/ip6tables.service
+[Unit]
+Description=Packet Filtering Framework
+DefaultDependencies=no
+After=systemd-sysctl.service
+Before=sysinit.target
+[Service]
+Type=oneshot
+ExecStart=/sbin/ip6tables-restore /etc/iptables/ip6tables.rules
+ExecReload=/sbin/ip6tables-restore /etc/iptables/ip6tables.rules
+ExecStop=/etc/iptables/flush-ip6tables.sh
+RemainAfterExit=yes
+[Install]
+WantedBy=multi-user.target
+EOM
+
+ # Create ip6tables file
+ cat <<EOM >$R/etc/iptables/flush-ip6tables.sh
+#!/bin/sh
+ip6tables -F
+ip6tables -X
+ip6tables -Z
+for table in $(</proc/net/ip6_tables_names)
+do
+ ip6tables -t \$table -F
+ ip6tables -t \$table -X
+ ip6tables -t \$table -Z
+done
+ip6tables -P INPUT ACCEPT
+ip6tables -P OUTPUT ACCEPT
+ip6tables -P FORWARD ACCEPT
+EOM
+
+ # Create ip6tables rule file
+ cat <<EOM >$R/etc/iptables/ip6tables.rules
+*filter
+:INPUT DROP [0:0]
+:FORWARD DROP [0:0]
+:OUTPUT ACCEPT [0:0]
+:TCP - [0:0]
+:UDP - [0:0]
+:SSH - [0:0]
+
+# Drop packets with RH0 headers
+-A INPUT -m rt --rt-type 0 -j DROP
+-A OUTPUT -m rt --rt-type 0 -j DROP
+-A FORWARD -m rt --rt-type 0 -j DROP
+
+# Rate limit ping requests
+-A INPUT -p icmpv6 --icmpv6-type echo-request -m limit --limit 30/min --limit-burst 8 -j ACCEPT
+-A INPUT -p icmpv6 --icmpv6-type echo-request -j DROP
+
+# Accept established connections
+-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
+
+# Accept all traffic on loopback interface
+-A INPUT -i lo -j ACCEPT
+
+# Drop packets declared invalid
+-A INPUT -m conntrack --ctstate INVALID -j DROP
+
+# SSH rate limiting
+-A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j SSH
+-A SSH -m recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j DROP
+-A SSH -m recent --name sshbf --rttl --rcheck --hitcount 20 --seconds 1800 -j DROP
+-A SSH -m recent --name sshbf --set -j ACCEPT
+
+# Send TCP and UDP connections to their respective rules chain
+-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
+-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
+
+# Reject dropped packets with a RFC compliant responce
+-A INPUT -p udp -j REJECT --reject-with icmp6-adm-prohibited
+-A INPUT -p tcp -j REJECT --reject-with icmp6-adm-prohibited
+-A INPUT -j REJECT --reject-with icmp6-adm-prohibited
+
+## TCP PORT RULES
+# -A TCP -p tcp -j LOG
+
+## UDP PORT RULES
+# -A UDP -p udp -j LOG
+
+COMMIT
+EOM
+
+ # Reload systemd configuration and enable iptables service
+ LANG=C chroot $R systemctl daemon-reload
+ LANG=C chroot $R systemctl enable ip6tables.service
+
+ fi
+fi
+
+# Unmount mounted filesystems
+umount -l $R/proc
+umount -l $R/sys
+
+# Clean up files
+rm -f $R/etc/apt/sources.list.save
+rm -f $R/etc/resolvconf/resolv.conf.d/original
+rm -rf $R/run
+mkdir -p $R/run
+rm -f $R/etc/*-
+rm -f $R/root/.bash_history
+rm -rf $R/tmp/*
+rm -f $R/var/lib/urandom/random-seed
+[ -L $R/var/lib/dbus/machine-id ] || rm -f $R/var/lib/dbus/machine-id
+rm -f $R/etc/machine-id
+
+# Calculate size of the chroot directory
+CHROOT_SIZE=$(expr `du -s $R | awk '{ print $1 }'` / 1024)
+
+# Calculate required image size
+IMAGE_SIZE=`expr $(expr ${CHROOT_SIZE} / 1024 + 1) \* 1024`
+
+# Calculate number of sectors for the partition
+IMAGE_SECTORS=`expr $(expr ${IMAGE_SIZE} \* 1048576) / 512 - 133120`
+
+# Prepare date string for image file name
+DATE="$(date +%Y-%m-%d)"
+
+# Prepare image file
+dd if=/dev/zero of="$BASEDIR/${DATE}-debian-${RELEASE}.img" bs=1M count=1
+dd if=/dev/zero of="$BASEDIR/${DATE}-debian-${RELEASE}.img" bs=1M count=0 seek=${IMAGE_SIZE}
+
+# Write partition table
+sfdisk -q -L -f "$BASEDIR/${DATE}-debian-${RELEASE}.img" <<EOM
+unit: sectors
+
+1 : start= 2048, size= 131072, Id= c, bootable
+2 : start= 133120, size= ${IMAGE_SECTORS}, Id=83
+3 : start= 0, size= 0, Id= 0
+4 : start= 0, size= 0, Id= 0
+EOM
+
+# Set up temporary loop devices and build filesystems
+VFAT_LOOP="$(losetup -o 1M --sizelimit 64M -f --show $BASEDIR/${DATE}-debian-${RELEASE}.img)"
+EXT4_LOOP="$(losetup -o 65M --sizelimit `expr ${IMAGE_SIZE} - 64`M -f --show $BASEDIR/${DATE}-debian-${RELEASE}.img)"
+mkfs.vfat "$VFAT_LOOP"
+mkfs.ext4 "$EXT4_LOOP"
+
+# Mount the temporary loop devices
+mkdir -p "$BUILDDIR/mount"
+mount "$EXT4_LOOP" "$BUILDDIR/mount"
+
+mkdir -p "$BUILDDIR/mount/boot/firmware"
+mount "$VFAT_LOOP" "$BUILDDIR/mount/boot/firmware"
+
+# Copy all files from the chroot to the loop device mount point directory
+rsync -a "$R/" "$BUILDDIR/mount/"
+
+# Unmount all temporary loop devices and mount points
+cleanup
+
+# (optinal) create block map file for "bmaptool"
+bmaptool create -o "$BASEDIR/${DATE}-debian-${RELEASE}.bmap" "$BASEDIR/${DATE}-debian-${RELEASE}.img"
+
+# Image was successfully created
+echo "$BASEDIR/${DATE}-debian-${RELEASE}.img (${IMAGE_SIZE})" ": successfully created"