diff options
60 files changed, 951 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..20c4545 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.log +config.status +configure +install-sh +missing +reboot +scripts/devfs.sh +scripts/ifcfg.sh +scripts/ifrename.sh +scripts/modules_load.sh +services/devfs +services/hostapd +services/ifcfg +services/ifdown +services/ifrename +services/modules +services/nft +services/procfs +services/sigkill +services/sigterm +services/sshd +services/sshd_keygen +services/swclock +services/swclocksave +services/swclocksave.gcron +services/sysfs +services/mountusr +services/ntpsetdate.gcron +services/tmpfsvar +.#*
\ No newline at end of file @@ -0,0 +1,13 @@ +Copyright (c) 2018 David Oberhollenzer <david.oberhollenzer@tele2.at> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..0cc0cd6 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,42 @@ +ACLOCAL_AMFLAGS = -I m4 + +sysconf_DATA = etc/initd.env +nobase_sysconf_DATA = netcfg/ifrename +EXTRA_DIST = docs netcfg etc LICENSE README.md + +helperdir = @SCRIPTDIR@ +helper_PROGRAMS = +helper_SCRIPTS = + +include scripts/Makemodule.am +include services/Makemodule.am + +install-data-local: + $(MKDIR_P) $(DESTDIR)$(SVCDIR) + $(LN_S) $(TEMPLATEDIR)/loopback $(DESTDIR)$(SVCDIR)/loopback + $(LN_S) $(TEMPLATEDIR)/hostname $(DESTDIR)$(SVCDIR)/hostname + $(LN_S) $(TEMPLATEDIR)/sysctl $(DESTDIR)$(SVCDIR)/sysctl + $(LN_S) $(TEMPLATEDIR)/sysinit $(DESTDIR)$(SVCDIR)/sysinit + $(LN_S) $(TEMPLATEDIR)/procfs $(DESTDIR)$(SVCDIR)/procfs + $(LN_S) $(TEMPLATEDIR)/sysfs $(DESTDIR)$(SVCDIR)/sysfs + $(LN_S) $(TEMPLATEDIR)/devfs $(DESTDIR)$(SVCDIR)/devfs + $(LN_S) $(TEMPLATEDIR)/tmpfs $(DESTDIR)$(SVCDIR)/tmpfs + $(LN_S) $(TEMPLATEDIR)/vfs $(DESTDIR)$(SVCDIR)/vfs + $(LN_S) $(TEMPLATEDIR)/ifdown $(DESTDIR)$(SVCDIR)/ifdown@shutdown + $(LN_S) $(TEMPLATEDIR)/sync $(DESTDIR)$(SVCDIR)/sync@shutdown + $(LN_S) $(TEMPLATEDIR)/sigkill $(DESTDIR)$(SVCDIR)/sigkill@shutdown + $(LN_S) $(TEMPLATEDIR)/sigterm $(DESTDIR)$(SVCDIR)/sigterm@shutdown + $(LN_S) $(TEMPLATEDIR)/sync $(DESTDIR)$(SVCDIR)/sync@reboot + $(LN_S) $(TEMPLATEDIR)/sigkill $(DESTDIR)$(SVCDIR)/sigkill@reboot + $(LN_S) $(TEMPLATEDIR)/sigterm $(DESTDIR)$(SVCDIR)/sigterm@reboot + $(LN_S) $(TEMPLATEDIR)/ifdown $(DESTDIR)$(SVCDIR)/ifdown@reboot + $(LN_S) $(TEMPLATEDIR)/ifcfg $(DESTDIR)$(SVCDIR)/ifcfg + $(LN_S) $(TEMPLATEDIR)/modules $(DESTDIR)$(SVCDIR)/modules + $(LN_S) $(TEMPLATEDIR)/network $(DESTDIR)$(SVCDIR)/network + $(LN_S) $(TEMPLATEDIR)/usyslogd $(DESTDIR)$(SVCDIR)/usyslogd + $(LN_S) $(TEMPLATEDIR)/klogd $(DESTDIR)$(SVCDIR)/klogd + $(LN_S) $(TEMPLATEDIR)/mountusr $(DESTDIR)$(SVCDIR)/mountusr + $(LN_S) $(TEMPLATEDIR)/tmpfsrun $(DESTDIR)$(SVCDIR)/tmpfsrun + $(LN_S) $(TEMPLATEDIR)/tmpfsvar $(DESTDIR)$(SVCDIR)/tmpfsvar + $(MKDIR_P) $(DESTDIR)$(GCRONDIR) + $(LN_S) $(TEMPLATEDIR)/gcrond $(DESTDIR)$(SVCDIR)/gcrond diff --git a/README.md b/README.md new file mode 100644 index 0000000..5387127 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# About + +This directory contains the basic system configuration for the Pygos system. + +See [docs/defconfig.md](docs/defconfig.md) for an overview of the default init +service configuration and further, available services. + +See [docs/network.md](docs/network.md) for a description on how to do static +network configuration with the provided script and service. diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..c08fadf --- /dev/null +++ b/autogen.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +autoreconf --force --install --symlink diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..a91fbaf --- /dev/null +++ b/configure.ac @@ -0,0 +1,44 @@ +AC_PREREQ([2.60]) + +AC_INIT([init-scripts], [1], [david.oberhollenzer@tele2.at], init-scripts) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE([foreign subdir-objects dist-xz]) +AM_SILENT_RULES([yes]) +AC_PROG_INSTALL +AC_PROG_MKDIR_P +AC_PROG_LN_S + +AC_DEFINE_DIR(SVCDIR, sysconfdir/init.d, [Startup service directory]) +AC_DEFINE_DIR(GCRONDIR, sysconfdir/gcron.d, [Cron service directory]) +AC_DEFINE_DIR(TEMPLATEDIR, datadir/init, [Service template directory]) +AC_DEFINE_DIR(SCRIPTDIR, libexecdir/init, [Helper script directory]) + +AC_DEFINE_DIR(SBINPATH, sbindir, [Fully evaluated sbin directory]) +AC_DEFINE_DIR(ETCPATH, sysconfdir, [Fulle evaluated etc directory]) +AC_DEFINE_DIR(STATEFILESPATH, prefix/var/lib, [Path for persistent state files]) + +AC_CONFIG_FILES([services/sigkill]) +AC_CONFIG_FILES([services/sigterm]) +AC_CONFIG_FILES([services/sysfs]) +AC_CONFIG_FILES([services/devfs]) +AC_CONFIG_FILES([services/procfs]) +AC_CONFIG_FILES([services/ifrename]) +AC_CONFIG_FILES([services/ifcfg]) +AC_CONFIG_FILES([services/ifdown]) +AC_CONFIG_FILES([services/modules]) +AC_CONFIG_FILES([services/hostapd]) +AC_CONFIG_FILES([services/swclock]) +AC_CONFIG_FILES([services/swclocksave]) +AC_CONFIG_FILES([services/swclocksave.gcron]) +AC_CONFIG_FILES([services/nft]) +AC_CONFIG_FILES([services/sshd]) +AC_CONFIG_FILES([services/sshd_keygen]) +AC_CONFIG_FILES([services/mountusr]) +AC_CONFIG_FILES([services/ntpsetdate.gcron]) +AC_CONFIG_FILES([services/tmpfsvar]) +AC_CONFIG_FILES([scripts/devfs.sh]) +AC_CONFIG_FILES([scripts/ifrename.sh]) +AC_CONFIG_FILES([scripts/ifcfg.sh]) +AC_CONFIG_FILES([scripts/modules_load.sh]) + +AC_OUTPUT([Makefile]) diff --git a/docs/defconfig.md b/docs/defconfig.md new file mode 100644 index 0000000..f0a6c86 --- /dev/null +++ b/docs/defconfig.md @@ -0,0 +1,124 @@ +# Default Service Configuration + +## Pseudo Services + +The default configuration contains a number of "pseudo services" in the boot +target that don't actually do anything but are merely used as anchors in +service dependencies, i.e. they indicate that some sort of milestone in the +boot sequence has been reached. Everything that is part of that milestone +specifies that it should be run *before* that pseudo service and everything +that requires that this milestone has been reached, specifies that it wants +to run afterwards. + +The pseudo targets are (in the order that they are executed): + + * vfs + + All services that do mount point setup go before this, all service that + depend on the fully mounted rootfs go after this. + + * sysinit + + The system has reached a sane state, i.e. the hostname is set, the system + clock has a sane value, modules and kernel parameters are loaded, some + very basic, fundamental services are running. + Everything that is part of that setup process goes between `vfs` and + `sysinit`, everything that requires a sane setup goes *after* `sysinit`. + + * network + + Network configuration is done. All services that do network configuration + should position themselves between `sysinit` and `network`. Everything that + requires a fully configured networking setup should go *after* `network`. + +## Default Bootup Services + +This section outlines the services for the boot target that are enabled by +default. + + +The following services are enabled by default and run *before* the `vfs` target +for filesystem setup: + + * procfs - mount `procfs` to `/proc` and try to mount additional pseudo + filesystems in `/proc` such as `binfmt_misc` + * tmpfs - mount a `tmpfs` to `/tmp` + * sysfs - mount `sysfs` to `/sys` and try to mount additional pseudo + filesystems in `/sys` (e.g. `securityfs`, `configfs`, ...) + * devfs - mount `devtmpfs` to `/dev`, try to mount additional pseudo + filesystems in `/dev` (e.g. `devpts`, `mqueue`, ...) and try to create + some additional device nodes and symlinks. + * tmpfsvar - mount a `tmpfs` to `/var` and populate it with a default set + of files and directories. Overlay mount `/var/lib` with lower dir on + `/cfg/preserve/var_lib/` and upper on `/cfg/overlay/var_lib/`. + * tmpfsrun - mount a `tmpfs` to `/run`, symlink `/var/run` to `/run` and + `/var/lock` to `/run/lock`. + * mountusr - overlay mount setup for `/usr`. Lower dir is on + `/cfg/preserve/usr/` and upper on `/cfg/overlay/usr/`. + + +The following services are enabled by default and configured to run *after* +the `vfs` target and *before* the `sysinit` target: + + * hostname - reload hostname `/etc/hostname` + * loopback - bring the loopback device up + * modules - iterate over the file `/etc/modules` and try to load each module + using modprobe. + * sysctl - restore kernel parameters using `sysctl --system`. See `sysctl(8)` + for a list of possible locations that the parameters are read from. + * usyslogd - Starts and supervises the `usyslogd` syslog implementation. + * klogd - Starts and supervises the `klogd` daemon. + + +The following services are enabled by default and configured to run *after* +the `sysinit` target and *before* the `network` target: + + * ifcfg - static network configuration + Does the static network configuration outlined in [network.md](network.md) + + +The following services are enabled by default and configured to run *after* +the `network` target: + + * gcrond + + +## Default Shutdown and Reboot Services + +For the shutdown and reboot targets, the following services are executed: + + * sigterm - send the SIGTERM signal to all processes and wait for 5 seconds + * sigkill - send the SIGKILL signal to all remaining processes + * ifdown - bring all network interfaces down + * sync - run the sync command + + +## Additional Services not Enabled by Default + + * agetty - A parameterizeable, respawn type `agetty` service. The first + parameter is the terminal device that the getty should run on. + * consolefont - If enabled, run once before sysinit. Sets the console font + to the first parameter. + * dhcpcdmaster - If one or more network interfaces should be configured using + dhcpcd, this service starts a central `dhcpcd` master instance. + * dhcpcd - A parameterizeable single shot service that signals the `dhcpcd` + master that it should configure a specific interface. The first parameter + is the interface that should be configured by `dhcpcd`. + * dnsmasq - A respawn type service for the `dnsmasq` DNS and DHCP server. + * hostapd - If the system should operate a WIFI access point, this respawn + type service can be enabled to manage an instace of the `hostapd` program. + * unbound - A respawn type service that manages an instance of the `unbound` + name resolver. + * hwclock - If the system has a hardware clock, this service can restore the + kernels clock from the hardware at bootup, between the `vfs` and `sysinit` + targets. + * nft - If enabled, restores net filter table rules during boot. + * swclock - For systems that don't have a hardware clock, this service + restores a somewhat usable time from a file during boot. + * swclocksave - For systems that don't have a hardware clock, this service + saves the current time to a file during shutdown or reboot. + * sshd_keygen - A wait type service that generates host keys for the OpenSSH + server and then disables itself. + * sshd - Starts an OpenSSH server after the network pseudo service and after + the sshd_keygen service. + * nginx - Starts the Nginx server after the network pseudo serivce. diff --git a/docs/network.md b/docs/network.md new file mode 100644 index 0000000..f111a8f --- /dev/null +++ b/docs/network.md @@ -0,0 +1,83 @@ +# Static Network Configuration + +The default configuration provides multiple services that perform network +initialization and static configuration using helper scripts that require +programs from the `iproute2` package. + +Configuration files are typically stored in `/etc/netcfg/` (depending on +configure options). + +Please note that the loopback device is treated specially and not included in +any of the network configuration outlined below. The loopback device is brought +up and configured by a dedicated service long before the network configuration +is done. + + +## Interface Renaming + +If the `ifrename` service is enabled (it is disabled by default), network +interfaces are renamed based on a rule set stored in the file `ifrename`. +The file contains comma separated shell globing patterns for the current +interface name, MAC address and a prefix for the new interface name. + +For each network interface, rules are processed top to bottom. If the first two +globing patterns apply, the interface is renamed. Interfaces with the same +prefix are sorted by mac address and a running index is appended to the prefix. + +If none of the rules apply, the interface name is left unchanged. + + +The intent is, to provide a way to configure persistent, deterministic names for +at least all network interfaces that are permanently installed on a board. + +Extension cards or external network adapters should be given a different prefix +to avoid changes in the order as they come and go. + + +## Interface Configuration + +After interface renaming, for each network interface, the configuration path is +scanned for files with the same name as the interface. + +Each successfully found configuration file is processed line by line, top to +bottom. Each line may contain a keyword, followed by multiple arguments. + +The following keywords can be used to add IPv4 or IPv6 network addresses to +an interface: + + * address + * addr + * ip + * ip6 + * ipv6 + +Those commands are expected to be followed by an IPv4 or IPv6 address and +network mask. + + +Furthermore, the following commands can be used for configuring interface +parameters: + + * `arp {on|off}` + * `multicast {on|off}` + * `mtu <value>` + * `offload [rx {on|off}] [tx {on|off}] [sg {on|off}] [tso {on|off}]` + * `offload [gso {on|off}] [gro {on|off}] [lro {on|off}] [rxvlan {on|off}]` + * `offload [txvlan {on|off}] [ntuple {on|off}] [rxhash {on|off}]` + * `offload [ufo {on|off}]` + + +## Route Configuration + +After interface configuration is done, routes and rules are restored from a +file named `routes` in the same configuration path. + +The file may contain lines starting with `route` or `rule`. Everything that +follows is passed on to `ip route add` or `ip rule add` respectively. + + +## Net Filter Tables + + +An additional service is provided that restores the nft rule set from +`/etc/nftables.rules`. diff --git a/etc/initd.env b/etc/initd.env new file mode 100644 index 0000000..c31cb70 --- /dev/null +++ b/etc/initd.env @@ -0,0 +1 @@ +PATH=/bin
\ No newline at end of file diff --git a/m4/ac_define_dir.m4 b/m4/ac_define_dir.m4 new file mode 100644 index 0000000..3b48c8b --- /dev/null +++ b/m4/ac_define_dir.m4 @@ -0,0 +1,35 @@ +dnl @synopsis AC_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION]) +dnl +dnl This macro sets VARNAME to the expansion of the DIR variable, +dnl taking care of fixing up ${prefix} and such. +dnl +dnl VARNAME is then offered as both an output variable and a C +dnl preprocessor symbol. +dnl +dnl Example: +dnl +dnl AC_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.]) +dnl +dnl @category Misc +dnl @author Stepan Kasal <kasal@ucw.cz> +dnl @author Andreas Schwab <schwab@suse.de> +dnl @author Guido U. Draheim <guidod@gmx.de> +dnl @author Alexandre Oliva +dnl @version 2006-10-13 +dnl @license AllPermissive + +AC_DEFUN([AC_DEFINE_DIR], [ + prefix_NONE= + exec_prefix_NONE= + test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix + test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix +dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn +dnl refers to ${prefix}. Thus we have to use `eval' twice. + eval ac_define_dir="\"[$]$2\"" + eval ac_define_dir="\"$ac_define_dir\"" + AC_SUBST($1, "$ac_define_dir") + AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3]) + test "$prefix_NONE" && prefix=NONE + test "$exec_prefix_NONE" && exec_prefix=NONE +]) + diff --git a/netcfg/ifrename b/netcfg/ifrename new file mode 100644 index 0000000..08909fa --- /dev/null +++ b/netcfg/ifrename @@ -0,0 +1,13 @@ +# +# Interface renaming rules +# +# Format: NAME,MAC,NEWNAME +# +# NAME and MAC are shell glob patterns. Both must match for a rule to apply. +# The first matching rule is chosen (top to bottom). +# +# Interfaces with the same NEWNAME are sorted by MAC and have a running +# index appended to their new name. +# +# Example: rename all ethernet interfaces to "port<X>" +# eth*,*,port diff --git a/scripts/Makemodule.am b/scripts/Makemodule.am new file mode 100644 index 0000000..207b9d2 --- /dev/null +++ b/scripts/Makemodule.am @@ -0,0 +1,6 @@ +helper_SCRIPTS += scripts/devfs.sh scripts/trymount.sh scripts/ifrename.sh +helper_SCRIPTS += scripts/ifcfg.sh scripts/ifdown.sh scripts/modules_load.sh +helper_SCRIPTS += scripts/setntpdate.sh scripts/overlay.sh + +EXTRA_DIST += scripts/trymount.sh scripts/ifdown.sh scripts/setntpdate.sh +EXTRA_DIST += scripts/overlay.sh diff --git a/scripts/devfs.sh.in b/scripts/devfs.sh.in new file mode 100644 index 0000000..af002f6 --- /dev/null +++ b/scripts/devfs.sh.in @@ -0,0 +1,21 @@ +#!/bin/sh + +mount -t devtmpfs none /dev + +[ -c /dev/console ] || mknod -m 600 /dev/console c 5 1 +[ -c /dev/tty ] || mknod -m 666 /dev/tty c 5 0 +[ -c /dev/null ] || mknod -m 666 /dev/null c 1 3 +[ -c /dev/kmsg ] || mknod -m 660 /dev/kmsg c 1 11 +[ -e /dev/fd ] || ln -snf /proc/self/fd /dev/fd +[ -e /dev/stdin ] || ln -snf /proc/self/fd/0 /dev/stdin +[ -e /dev/stdout ] || ln -snf /proc/self/fd/1 /dev/stdout +[ -e /dev/stderr ] || ln -snf /proc/self/fd/2 /dev/stderr +[ -e /proc/kcore ] && ln -snf /proc/kcore /dev/core + +mkdir -p /dev/mqueue -m 1777 +mkdir -p /dev/pts -m 0755 +mkdir -p /dev/shm -m 1777 + +@SCRIPTDIR@/trymount.sh "/dev/mqueue" "mqueue" "noexec,nosuid,nodev" +@SCRIPTDIR@/trymount.sh "/dev/pts" "devpts" "noexec,nosuid,gid=5,mode=0620" +@SCRIPTDIR@/trymount.sh "/dev/shm" "tmpfs" "noexec,nosuid,nodev,mode=1777" diff --git a/scripts/ifcfg.sh.in b/scripts/ifcfg.sh.in new file mode 100755 index 0000000..f8396c6 --- /dev/null +++ b/scripts/ifcfg.sh.in @@ -0,0 +1,71 @@ +#!/bin/sh +CFGPATH="@ETCPATH@/netcfg" + +[ -d "$CFGPATH" ] || exit 0 + +# configure interfaces +for IFPATH in /sys/class/net/*; do + [ "$IFPATH" == "/sys/class/net/lo" ] && continue + + IF=`basename $IFPATH` + CFGFILE="$CFGPATH/$IF" + + [ -f "$CFGFILE" ] || continue + + ip link set dev "$IF" down + + while read LINE; + do + trimmed=`echo -- $LINE` + [ ! -z "$trimmed" ] || continue + set $trimmed + + case "$1" in + address|addr|ip|ip6|ipv6) + shift + ip address add $@ dev "$IF" + ;; + arp|multicast|mtu) + ip link set dev "$IF" $@ + ;; + offload) + shift + ethtool -K "$IF" $@ + ;; + *) + ;; + esac + done < "$CFGFILE" +done + +# configure static routs +if [ -f "$CFGPATH/routes" ]; then + while read LINE; + do + trimmed=`echo -- $LINE` + [ ! -z "$trimmed" ] || continue + set $trimmed + + case "$1" in + route) + shift + ip route add $@ + ;; + rule) + shift + ip rule add $@ + ;; + *) + ;; + esac + done < "$CFGFILE" +fi + +# activate interfaces +for IFPATH in /sys/class/net/*; do + [ "$IFPATH" == "/sys/class/net/lo" ] && continue + + IF=`basename $IFPATH` + + [ ! -f "$CFGPATH/$IF" ] || ip link set dev "$IF" up +done diff --git a/scripts/ifdown.sh b/scripts/ifdown.sh new file mode 100644 index 0000000..e6f4500 --- /dev/null +++ b/scripts/ifdown.sh @@ -0,0 +1,8 @@ +#!/bin/sh +for IFPATH in /sys/class/net/*; do + [ "$IFPATH" == "/sys/class/net/lo" ] && continue + + IF=`basename $IFPATH` + + ip link set dev "$IF" down +done diff --git a/scripts/ifrename.sh.in b/scripts/ifrename.sh.in new file mode 100755 index 0000000..0820c94 --- /dev/null +++ b/scripts/ifrename.sh.in @@ -0,0 +1,47 @@ +#!/bin/sh +NAMERULES="@ETCPATH@/netcfg/ifrename" +TMPPATH="/tmp/ifrename" + +[ -f "$NAMERULES" ] || exit 0 + +mkdir -p "$TMPPATH" + +for IFPATH in /sys/class/net/*; do + [ "$IFPATH" == "/sys/class/net/lo" ] && continue + + IF=`basename $IFPATH` + MAC=`cat $IFPATH/address` + + grep "^[^,]\+,[^,]\+,[a-zA-Z0-9]\+$" $NAMERULES | while read LINE; + do + NAMECMP=$(echo $LINE | cut -d',' -f1) + ADDRCMP=$(echo $LINE | cut -d',' -f2) + RULE=$(echo $LINE | cut -d',' -f3) + + case $IF in ($NAMECMP) ;; *) continue;; esac + case $MAC in ($ADDRCMP) ;; *) continue;; esac + + echo "$MAC,$IF" >> "$TMPPATH/$RULE" + break + done +done + +for FNAME in $TMPPATH/*; do + [ ! -f "$FNAME" ] && break + + IDX=0 + PREFIX=$(basename $FNAME) + + sort -t',' -k1 -u $FNAME | while read LINE; + do + OLDNAME=$(echo $LINE | cut -d',' -f2) + NEWNAME="$PREFIX$IDX" + IDX=`expr $IDX + 1` + + ip link set "$OLDNAME" name "$NEWNAME" + done + + rm "$FNAME" +done + +rmdir "$TMPPATH" diff --git a/scripts/modules_load.sh.in b/scripts/modules_load.sh.in new file mode 100644 index 0000000..58bb2ab --- /dev/null +++ b/scripts/modules_load.sh.in @@ -0,0 +1,21 @@ +#!/bin/sh +MODLIST="@ETCPATH@/modules" + +if [ ! -f "$MODLIST" ]; then + exit 0 +fi + +while read LINE; +do + trimmed=`echo -- $LINE` + [ ! -z "$trimmed" ] || continue + set $trimmed + + case "$1" in + \#*) + ;; + *) + modprobe "$1" + ;; + esac +done < "$MODLIST" diff --git a/scripts/overlay.sh b/scripts/overlay.sh new file mode 100755 index 0000000..090671c --- /dev/null +++ b/scripts/overlay.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +lower=/cfg/preserve/${1} +upper=/cfg/overlay/${1} +work=/cfg/overlay/${1}_work +target=${2} + +if [ ! -d "$target" ]; then + exit +fi + +if [ -d "$lower" ]; then + if [ -d "$upper" ]; then + mkdir -p "$work" + mount -t overlay overlay \ + -olowerdir=${lower},upperdir=${upper},workdir=${work} \ + ${target} + else + mount --bind "$lower" "$target" + fi +fi diff --git a/scripts/setntpdate.sh b/scripts/setntpdate.sh new file mode 100755 index 0000000..bf0a753 --- /dev/null +++ b/scripts/setntpdate.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +resolve() { + local domain="$1" + local server="$2" + + if [ -x "$(command -v dig)" ]; then + if [ -z "$server" ]; then + dig +short "$domain" + else + dig +short "@$server" "$domain" + fi + return $? + fi + + if [ -x "$(command -v drill)" ]; then + if [ -z "$server" ]; then + drill "$domain" | grep "^${domain}." | cut -d$'\t' -f5 + else + drill "@$server" "$domain" | grep "^${domain}." |\ + cut -d$'\t' -f5 + fi + return $? + fi + exit 1 +} + +try_update() { + while read ip; do + if ntpdate -bu "$ip"; then + return 0 + fi + done + + return 1 +} + +pool="pool.ntp.org" +dns="1.1.1.1" + +# try default DNS server first +resolve "$pool" "" | try_update +[ $? -eq 0 ] && exit 0 + +# try fallback public dns server +ping -q -c 1 "$dns" || exit 1 + +resolve "$pool" "$dns" | try_update +exit $? diff --git a/scripts/trymount.sh b/scripts/trymount.sh new file mode 100644 index 0000000..9be77f6 --- /dev/null +++ b/scripts/trymount.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ -d "$1" ]; then + if grep -qsE "[[:space:]]+$2$" "/proc/filesystems"; then + mount -n -t "$2" -o "$3" "$2" "$1" + fi +fi diff --git a/services/Makemodule.am b/services/Makemodule.am new file mode 100644 index 0000000..e39e200 --- /dev/null +++ b/services/Makemodule.am @@ -0,0 +1,23 @@ +initdir = @TEMPLATEDIR@ +init_DATA = services/agetty services/hostname services/loopback +init_DATA += services/sysctl services/hwclock services/sysinit +init_DATA += services/sigterm services/sync services/devfs +init_DATA += services/sysfs services/procfs services/tmpfs +init_DATA += services/vfs services/ifrename services/ifcfg +init_DATA += services/dhcpcd services/dhcpcdmaster services/unbound +init_DATA += services/dnsmasq services/ifdown services/modules +init_DATA += services/network services/hostapd services/swclock +init_DATA += services/swclocksave services/nft services/sigkill +init_DATA += services/sshd services/sshd_keygen services/consolefont +init_DATA += services/nginx services/usyslogd services/klogd +init_DATA += services/swclocksave.gcron services/gcrond +init_DATA += services/mountusr services/ntpsetdate.gcron +init_DATA += services/tmpfsrun services/tmpfsvar + +EXTRA_DIST += services/sysinit services/vfs services/agetty services/hostname +EXTRA_DIST += services/hwclock services/loopback services/klogd +EXTRA_DIST += services/sync services/sysctl services/tmpfs +EXTRA_DIST += services/dhcpcd services/dhcpcdmaster services/unbound +EXTRA_DIST += services/usyslogd services/dnsmasq services/network +EXTRA_DIST += services/consolefont services/gcrond services/nginx +EXTRA_DIST += services/tmpfsrun diff --git a/services/agetty b/services/agetty new file mode 100644 index 0000000..6c8945b --- /dev/null +++ b/services/agetty @@ -0,0 +1,6 @@ +description agetty on %0 +exec agetty %0 linux +type respawn +target boot +after network +tty "/dev/%0" diff --git a/services/consolefont b/services/consolefont new file mode 100644 index 0000000..1584db9 --- /dev/null +++ b/services/consolefont @@ -0,0 +1,6 @@ +description set console font +type once +target boot +before sysinit +after vfs +exec setfont %0 diff --git a/services/devfs.in b/services/devfs.in new file mode 100644 index 0000000..271eae7 --- /dev/null +++ b/services/devfs.in @@ -0,0 +1,6 @@ +description "mount /dev" +type wait +target boot +after procfs sysfs +before vfs +exec "@SCRIPTDIR@/devfs.sh" diff --git a/services/dhcpcd b/services/dhcpcd new file mode 100644 index 0000000..184a843 --- /dev/null +++ b/services/dhcpcd @@ -0,0 +1,7 @@ +description "DHCP client on %0" +type once +target boot +after dhcpcdmaster network + +tty /dev/null +exec dhcpcd -n %0 diff --git a/services/dhcpcdmaster b/services/dhcpcdmaster new file mode 100644 index 0000000..879497a --- /dev/null +++ b/services/dhcpcdmaster @@ -0,0 +1,10 @@ +description "DHCP client - master service" +type wait +target boot +after network +tty /dev/null + +exec { + mkdir -p /var/db/dhcpcd + dhcpcd --inactive +} diff --git a/services/dnsmasq b/services/dnsmasq new file mode 100644 index 0000000..4045824 --- /dev/null +++ b/services/dnsmasq @@ -0,0 +1,6 @@ +description "dnsmasq DNS & DHCP server" +type respawn limit 5 +target boot +after network unbound + +exec dnsmasq -k diff --git a/services/gcrond b/services/gcrond new file mode 100644 index 0000000..0ee1ee5 --- /dev/null +++ b/services/gcrond @@ -0,0 +1,5 @@ +description start gcron daemon +exec gcrond +type respawn +target boot +after network diff --git a/services/hostapd.in b/services/hostapd.in new file mode 100644 index 0000000..172aa6f --- /dev/null +++ b/services/hostapd.in @@ -0,0 +1,7 @@ +description "WIFI access point daemon" +type respawn limit 10 +target boot +after sysinit ifrename +before network ifcfg + +exec hostapd "@ETCPATH@/hostapd.conf" diff --git a/services/hostname b/services/hostname new file mode 100644 index 0000000..d0daa23 --- /dev/null +++ b/services/hostname @@ -0,0 +1,6 @@ +description reload hostname +exec hostname --file /etc/hostname +type wait +target boot +before sysinit +after hwclock vfs diff --git a/services/hwclock b/services/hwclock new file mode 100644 index 0000000..7eac1da --- /dev/null +++ b/services/hwclock @@ -0,0 +1,6 @@ +description restore time from RTC +exec hwclock --hctosys --utc +type wait +target boot +before sysinit +after vfs modules diff --git a/services/ifcfg.in b/services/ifcfg.in new file mode 100644 index 0000000..c2b4127 --- /dev/null +++ b/services/ifcfg.in @@ -0,0 +1,7 @@ +description "static network configuration" +type wait +target boot +after sysinit ifrename +before network + +exec "@SCRIPTDIR@/ifcfg.sh"
\ No newline at end of file diff --git a/services/ifdown.in b/services/ifdown.in new file mode 100644 index 0000000..1310098 --- /dev/null +++ b/services/ifdown.in @@ -0,0 +1,7 @@ +description "stop all network interfaces" +type wait +target %0 +after sigkill sigterm +before sync + +exec "@SCRIPTDIR@/ifdown.sh"
\ No newline at end of file diff --git a/services/ifrename.in b/services/ifrename.in new file mode 100644 index 0000000..efb00de --- /dev/null +++ b/services/ifrename.in @@ -0,0 +1,7 @@ +description "rename network interfaces" +type wait +target boot +after sysinit +before network + +exec "@SCRIPTDIR@/ifrename.sh"
\ No newline at end of file diff --git a/services/klogd b/services/klogd new file mode 100644 index 0000000..aaca59a --- /dev/null +++ b/services/klogd @@ -0,0 +1,6 @@ +description "starting uklogd" +exec klogd +type respawn limit 5 +target boot +after usyslogd +before sysinit diff --git a/services/loopback b/services/loopback new file mode 100644 index 0000000..53118b5 --- /dev/null +++ b/services/loopback @@ -0,0 +1,10 @@ +description configure network loopback device +type wait +target boot +before sysinit +after hostname vfs + +exec { + ip addr add 127.0.0.1/8 dev lo brd + + ip link set lo up +} diff --git a/services/modules.in b/services/modules.in new file mode 100644 index 0000000..e8c1863 --- /dev/null +++ b/services/modules.in @@ -0,0 +1,7 @@ +description "load kernel modules" +type wait +target boot +after vfs usyslogd +before sysinit + +exec "@SCRIPTDIR@/modules_load.sh"
\ No newline at end of file diff --git a/services/mountusr.in b/services/mountusr.in new file mode 100644 index 0000000..14b1e8f --- /dev/null +++ b/services/mountusr.in @@ -0,0 +1,5 @@ +description "mount /usr" +type wait +target boot +before vfs +exec "@SCRIPTDIR@/overlay.sh" usr /usr diff --git a/services/network b/services/network new file mode 100644 index 0000000..5ba505c --- /dev/null +++ b/services/network @@ -0,0 +1,4 @@ +description "static network configuration completed" +type wait +target boot +after sysinit
\ No newline at end of file diff --git a/services/nft.in b/services/nft.in new file mode 100644 index 0000000..21caab0 --- /dev/null +++ b/services/nft.in @@ -0,0 +1,7 @@ +description "restore netfilter rule set" +type wait +target boot +after sysinit ifrename +before network ifcfg + +exec nft -f "@ETCPATH@/nftables.rules" diff --git a/services/nginx b/services/nginx new file mode 100644 index 0000000..6a36af9 --- /dev/null +++ b/services/nginx @@ -0,0 +1,6 @@ +description "start nginx web server" +type once +target boot +after network +tty /dev/null +exec nginx diff --git a/services/ntpsetdate.gcron.in b/services/ntpsetdate.gcron.in new file mode 100644 index 0000000..6f86bd5 --- /dev/null +++ b/services/ntpsetdate.gcron.in @@ -0,0 +1,7 @@ +hour */4 +minute 5 +dayofmonth * +dayofweek * +month * +tty /dev/null +exec "@SCRIPTDIR@/setntpdate.sh" diff --git a/services/procfs.in b/services/procfs.in new file mode 100644 index 0000000..8c0743b --- /dev/null +++ b/services/procfs.in @@ -0,0 +1,9 @@ +description "mount /proc" +type wait +target boot +before vfs + +exec { + mount -t proc proc /proc + "@SCRIPTDIR@/trymount.sh" /proc/sys/fs/binfmt_misc binfmt_misc nodev,noexec,nosuid +} diff --git a/services/sigkill.in b/services/sigkill.in new file mode 100644 index 0000000..cddd49d --- /dev/null +++ b/services/sigkill.in @@ -0,0 +1,6 @@ +description send SIGKILL to remaining processes +exec "@SCRIPTDIR@/killall5" 9 +type wait +target %0 +after sigterm +before sync shutdown reboot diff --git a/services/sigterm.in b/services/sigterm.in new file mode 100644 index 0000000..7e77fba --- /dev/null +++ b/services/sigterm.in @@ -0,0 +1,9 @@ +description send SIGTERM to all processes +type wait +target %0 +before sigkill sync reboot shutdown + +exec { + "@SCRIPTDIR@/killall5" 15 + sleep 5 +} diff --git a/services/sshd.in b/services/sshd.in new file mode 100644 index 0000000..a6292bc --- /dev/null +++ b/services/sshd.in @@ -0,0 +1,5 @@ +description "OpenSSH server" +type respawn limit 5 +target boot +after network sshd_keygen +exec "@SBINPATH@/sshd" -D diff --git a/services/sshd_keygen.in b/services/sshd_keygen.in new file mode 100644 index 0000000..6425e63 --- /dev/null +++ b/services/sshd_keygen.in @@ -0,0 +1,14 @@ +description "OpenSSH server - generate host keys" +type wait +target boot +after network +tty /dev/null +exec { + mkdir -p "@ETCPATH@/ssh/" + + ssh-keygen -f "@ETCPATH@/ssh/host_rsa_key" -N "" -t rsa + ssh-keygen -f "@ETCPATH@/ssh/host_ecdsa_key" -N "" -t ecdsa + ssh-keygen -f "@ETCPATH@/ssh/host_ed25519_key" -N "" -t ed25519 + + service disable sshd_keygen +} diff --git a/services/swclock.in b/services/swclock.in new file mode 100644 index 0000000..02c4c27 --- /dev/null +++ b/services/swclock.in @@ -0,0 +1,6 @@ +description restore saved time from last shutdown +type wait +target boot +before sysinit +after vfs modules +exec xargs -a @STATEFILESPATH@/swclock date --utc diff --git a/services/swclocksave.gcron.in b/services/swclocksave.gcron.in new file mode 100644 index 0000000..24e162b --- /dev/null +++ b/services/swclocksave.gcron.in @@ -0,0 +1,3 @@ +interval hourly +tty truncate @STATEFILESPATH@/swclock +exec date --utc +%%m%%d%%H%%M%%Y.%%S diff --git a/services/swclocksave.in b/services/swclocksave.in new file mode 100644 index 0000000..683ded7 --- /dev/null +++ b/services/swclocksave.in @@ -0,0 +1,7 @@ +description write current time to backup file +type wait +target %0 +after sigkill +before sync +tty truncate @STATEFILESPATH@/swclock +exec date --utc +%%m%%d%%H%%M%%Y.%%S diff --git a/services/sync b/services/sync new file mode 100644 index 0000000..d7217f9 --- /dev/null +++ b/services/sync @@ -0,0 +1,6 @@ +description sync +exec sync +type wait +target %0 +after sigkill sigterm +before reboot shutdown diff --git a/services/sysctl b/services/sysctl new file mode 100755 index 0000000..6664297 --- /dev/null +++ b/services/sysctl @@ -0,0 +1,7 @@ +description configure kernel paramters +tty /dev/null +exec sysctl --system +type wait +target boot +before sysinit +after vfs loopback diff --git a/services/sysfs.in b/services/sysfs.in new file mode 100644 index 0000000..8eebd0a --- /dev/null +++ b/services/sysfs.in @@ -0,0 +1,13 @@ +description "mount /sys" +type wait +target boot +after procfs +before vfs + +exec { + mount -t sysfs sysfs /sys + "@SCRIPTDIR@/trymount.sh" /sys/kernel/security securityfs nodev,noexec,nosuid + "@SCRIPTDIR@/trymount.sh" /sys/kernel/config configfs nodev,noexec,nosuid + "@SCRIPTDIR@/trymount.sh" /sys/fs/fuse/connections fusectl nodev,noexec,nosuid + "@SCRIPTDIR@/trymount.sh" /sys/firmware/efi/efivars efivarfs ro +} diff --git a/services/sysinit b/services/sysinit new file mode 100644 index 0000000..801ac97 --- /dev/null +++ b/services/sysinit @@ -0,0 +1,5 @@ +description basic system initialization +type wait +target boot +after vfs +before network
\ No newline at end of file diff --git a/services/tmpfs b/services/tmpfs new file mode 100644 index 0000000..411a42b --- /dev/null +++ b/services/tmpfs @@ -0,0 +1,5 @@ +description "mount /tmp" +type wait +target boot +before vfs +exec mount -t tmpfs none /tmp diff --git a/services/tmpfsrun b/services/tmpfsrun new file mode 100644 index 0000000..07dbd0a --- /dev/null +++ b/services/tmpfsrun @@ -0,0 +1,11 @@ +description "mount /run" +type wait +target boot +before vfs +after tmpfsvar +exec { + mount -t tmpfs none /run + mkdir /run/lock -m 0755 + ln -s /run /var/run + ln -s /run/lock /var/lock +} diff --git a/services/tmpfsvar.in b/services/tmpfsvar.in new file mode 100644 index 0000000..2c3c808 --- /dev/null +++ b/services/tmpfsvar.in @@ -0,0 +1,16 @@ +description "mount /var" +type wait +target boot +before vfs +exec { + mount -t tmpfs none /var + mkdir /var/log -m 0755 + mkdir /var/spool -m 0755 + mkdir /var/lib -m 0755 + mkdir /var/tmp -m 0755 + mkdir /var/nginx -m 0755 + touch /var/log/lastlog + touch /var/log/faillog + touch /var/log/sulog + "@SCRIPTDIR@/overlay.sh" var_lib /var/lib +} diff --git a/services/unbound b/services/unbound new file mode 100644 index 0000000..e9980ab --- /dev/null +++ b/services/unbound @@ -0,0 +1,6 @@ +description "Unbound resolver" +type respawn limit 5 +target boot +after network + +exec unbound -d diff --git a/services/usyslogd b/services/usyslogd new file mode 100644 index 0000000..6b378d9 --- /dev/null +++ b/services/usyslogd @@ -0,0 +1,6 @@ +description "starting usyslogd" +exec usyslogd --chroot --rotate-replace --max-size 8192 +type respawn limit 5 +target boot +after vfs +before sysinit
\ No newline at end of file diff --git a/services/vfs b/services/vfs new file mode 100644 index 0000000..b699976 --- /dev/null +++ b/services/vfs @@ -0,0 +1,4 @@ +description VFS setup done +type wait +target boot +before sysinit
\ No newline at end of file |