#!/bin/sh # # setup-filesystem - rawnix.org Filesystem Setup # https://rawnix.org # # Creates the base filesystem hierarchy and configuration files. # Run BEFORE install - prepares the skeleton that packages install into. # # Usage: setup-filesystem [destination] # Default destination: /mnt # # GID policy # ---------- # Every group created here is a *skeleton* group: it carries a fixed GID # that is baked into installed file ownership, disk images and backups, # and human accounts are members of several of them. None of them may # ever be created or removed by a package. # # All of them therefore live below 100, outside the 100-999 range that # `groupadd -r` allocates from, with two documented exceptions that # predate the rule and are pinned by convention: # # users 100 traditional # rfkill 101 referenced by 40-rawnix.rules (udevd) # # The same list is compiled into mkpkg as reserved_groups[] in meta.c. # Keep the two in sync; `make check-reserved` in the mkpkg tree diffs # them. set -e umask 022 dst="${1:-/mnt}" echo ">>> Setting up rawnix.org filesystem in $dst" # ============================================================ # Directories # # /usr/local is created here and then left alone. No port installs # into it, nothing in the db owns it, and delpkg will never remove # anything under it -- it exists so hand-built software has somewhere # to go that the package manager cannot collide with. musl's dynamic # linker already searches /usr/local/lib by default. # ============================================================ echo ">>> Creating directories..." for d in \ bin \ sbin \ include \ lib \ lib/firmware \ lib/pkgconfig \ etc \ etc/boot.d \ etc/profile.d \ etc/skel \ etc/runit \ etc/sv \ etc/ssl/certs \ etc/ssl/private \ etc/ld.so.conf.d \ etc/ports \ etc/ports/keys \ etc/revdep.d \ dev \ dev/pts \ dev/shm \ proc \ sys \ tmp \ run \ run/lock \ run/user \ var/log \ var/cache \ var/tmp \ var/lib \ var/lib/pkg \ var/mail \ var/spool \ var/empty \ ports/core \ usr/bin \ usr/lib \ usr/lib/pkgconfig \ usr/include \ usr/share \ usr/share/misc \ usr/src \ usr/local \ usr/local/bin \ usr/local/sbin \ usr/local/lib \ usr/local/lib/pkgconfig \ usr/local/include \ usr/local/share \ usr/local/etc \ usr/local/src \ usr/ports/devel \ usr/ports/libs \ usr/ports/opt \ usr/ports/python \ usr/ports/perl \ root \ home \ media \ mnt \ boot/efi do mkdir -p "$dst/$d" done for s in 1 2 3 4 5 6 7 8; do mkdir -p "$dst/usr/share/man/man$s" mkdir -p "$dst/usr/local/share/man/man$s" done # ============================================================ # Permissions # ============================================================ echo ">>> Setting permissions..." chmod 1777 "$dst/tmp" chmod 1777 "$dst/var/tmp" chmod 0750 "$dst/root" chmod 0700 "$dst/etc/ssl/private" # chroot target: must stay root:root 0755 or sshd refuses to start. # mkpkg's nocreate_homes[] keeps ports from taking ownership of it. chmod 0755 "$dst/var/empty" # ============================================================ # Symlinks # ============================================================ echo ">>> Creating symlinks..." ln -sf ../run "$dst/var/run" ln -sf ../run/lock "$dst/var/lock" ln -sf ../proc/self/mounts "$dst/etc/mtab" # ============================================================ # /etc/passwd # ============================================================ cat > "$dst/etc/passwd" << 'EOF' root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/dev/null:/bin/false bin:x:2:2:bin:/dev/null:/bin/false adm:x:3:4:adm:/var/log:/bin/false lp:x:4:7:lp:/var/spool/lpd:/bin/false sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:8:mail:/var/mail:/bin/false cron:x:16:16:cron:/var/spool/cron:/bin/false ftp:x:21:21:ftp:/var/ftp:/bin/false nobody:x:65534:65534:nobody:/dev/null:/bin/false EOF # ============================================================ # /etc/shadow # ============================================================ cat > "$dst/etc/shadow" << 'EOF' root::19700:0:99999:7::: daemon:!:19700:0:99999:7::: bin:!:19700:0:99999:7::: adm:!:19700:0:99999:7::: lp:!:19700:0:99999:7::: sync:!:19700:0:99999:7::: shutdown:!:19700:0:99999:7::: halt:!:19700:0:99999:7::: mail:!:19700:0:99999:7::: cron:!:19700:0:99999:7::: ftp:!:19700:0:99999:7::: nobody:!:19700:0:99999:7::: EOF chmod 640 "$dst/etc/shadow" # ============================================================ # /etc/group # ============================================================ cat > "$dst/etc/group" << 'EOF' root:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4: tty:x:5: disk:x:6: lp:x:7: mail:x:8: uucp:x:10: wheel:x:11: kmem:x:15: cron:x:16: dialout:x:20: ftp:x:21: sshd:x:22: cdrom:x:24: floppy:x:25: tape:x:26: input:x:27: kvm:x:28: audio:x:29: netdev:x:30: render:x:31: usb:x:32: sgx:x:33: utmp:x:43: video:x:44: plugdev:x:46: users:x:100: rfkill:x:101: nogroup:x:65534: EOF # ============================================================ # /etc/shells # ============================================================ cat > "$dst/etc/shells" << 'EOF' /bin/sh /bin/dash /bin/bash EOF # ============================================================ # /etc/hostname # ============================================================ echo "rawnix" > "$dst/etc/hostname" # ============================================================ # /etc/hosts # ============================================================ cat > "$dst/etc/hosts" << 'EOF' 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters EOF # ============================================================ # /etc/host.conf # ============================================================ cat > "$dst/etc/host.conf" << 'EOF' order hosts,bind multi on EOF # ============================================================ # /etc/resolv.conf # ============================================================ cat > "$dst/etc/resolv.conf" << 'EOF' nameserver 1.1.1.1 nameserver 9.9.9.9 EOF # ============================================================ # /etc/profile # ============================================================ cat > "$dst/etc/profile" << 'EOF' # /etc/profile - System-wide shell initialization # rawnix.org - https://rawnix.org export PATH="/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin" umask 022 export LANG=C.UTF-8 export LC_COLLATE=C export PAGER=less export EDITOR=vi # Must match PKG_CONFIG_PATH in /etc/mkpkg.conf, or a hand-run # pkg-config cannot see the .pc files in /lib/pkgconfig. # /usr/local/lib/pkgconfig is deliberately absent: a hand-built # library must not be able to satisfy a port's dependency check. export PKG_CONFIG_PATH="/lib/pkgconfig:/usr/lib/pkgconfig" export HISTSIZE=1000 export HISTFILESIZE=2000 if [ "$(id -u)" -eq 0 ]; then PS1='\[\033]0;\u@\h:\w\007\]\[\033[1;31m\]\u@\h\[\033[0m\]:\[\033[1;34m\]\w\[\033[0m\]# ' else PS1='\[\033]0;\u@\h:\w\007\]\[\033[1;32m\]\u@\h\[\033[0m\]:\[\033[1;34m\]\w\[\033[0m\]$ ' fi export PS1 if [ -d /etc/profile.d ]; then for script in /etc/profile.d/*.sh; do [ -r "$script" ] && . "$script" done unset script fi EOF # ============================================================ # /etc/securetty # ============================================================ cat > "$dst/etc/securetty" << 'EOF' console tty1 tty2 tty3 tty4 tty5 tty6 ttyS0 EOF chmod 600 "$dst/etc/securetty" # ============================================================ # /etc/fstab # ============================================================ cat > "$dst/etc/fstab" << 'EOF' # /etc/fstab - rawnix.org # Generated by genfstab EOF # ============================================================ # /etc/motd # ============================================================ cat > "$dst/etc/motd" << 'EOF' _ _ __ __ ___ ___ __ (_)_ __ | '__/ _` \ \ /\ / / '_ \| \ \/ / | | | (_| |\ V V /| | | | |> < |_| \__,_| \_/\_/ |_| |_|_/_/\_\ https://rawnix.org EOF # ============================================================ # /etc/issue # ============================================================ cat > "$dst/etc/issue" << 'EOF' rawnix.org \r (\l) EOF # ============================================================ # /etc/os-release # ============================================================ cat > "$dst/etc/os-release" << 'EOF' NAME="rawnix.org" ID=rawnix VERSION_ID="1.0" PRETTY_NAME="rawnix.org" HOME_URL="https://rawnix.org" BUG_REPORT_URL="https://rawnix.org/bugs" EOF # ============================================================ # /etc/ld.so.conf # ============================================================ cat > "$dst/etc/ld.so.conf" << 'EOF' /lib /usr/lib /usr/local/lib EOF # ============================================================ # /etc/sysctl.conf # ============================================================ cat > "$dst/etc/sysctl.conf" << 'EOF' # /etc/sysctl.conf - client hardening # IPv4 net.ipv4.ip_forward = 0 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.conf.all.rp_filter = 2 net.ipv4.conf.default.rp_filter = 2 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 net.ipv4.icmp_ignore_bogus_error_responses = 1 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_rfc1337 = 1 net.ipv4.tcp_max_syn_backlog = 2048 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 5 # IPv6 net.ipv6.conf.all.forwarding = 0 net.ipv6.conf.all.accept_ra = 1 net.ipv6.conf.default.accept_ra = 1 net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0 net.ipv6.conf.all.accept_source_route = 0 net.ipv6.conf.default.accept_source_route = 0 net.ipv6.conf.all.use_tempaddr = 2 net.ipv6.conf.default.use_tempaddr = 2 # Kernel kernel.kptr_restrict = 2 kernel.dmesg_restrict = 1 kernel.printk = 3 3 3 3 kernel.randomize_va_space = 2 kernel.yama.ptrace_scope = 1 kernel.unprivileged_bpf_disabled = 1 net.core.bpf_jit_harden = 2 kernel.sysrq = 0 # Filesystem fs.suid_dumpable = 0 fs.protected_symlinks = 1 fs.protected_hardlinks = 1 fs.protected_fifos = 2 fs.protected_regular = 2 fs.inotify.max_user_watches = 524288 EOF # ============================================================ # /etc/boot.d # # Run by /etc/rc.local at the end of /etc/runit/1. # ============================================================ cat > "$dst/etc/boot.d/10-runtime-dirs" << 'EOF' #!/bin/sh # Per-user XDG_RUNTIME_DIR. while IFS=: read -r _ _ uid gid _; do [ "$uid" -ge 1000 ] && [ "$uid" -lt 65534 ] || continue install -d -m 0700 -o "$uid" -g "$gid" "/run/user/$uid" done < /etc/passwd EOF chmod 755 "$dst/etc/boot.d/10-runtime-dirs" # ============================================================ # /etc/profile.d # ============================================================ cat > "$dst/etc/profile.d/10-xdg.sh" << 'EOF' #!/bin/sh _uid=$(id -u) if [ -d "/run/user/$_uid" ] && [ -O "/run/user/$_uid" ]; then export XDG_RUNTIME_DIR="/run/user/$_uid" fi unset _uid export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}" export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" export PYTHONPYCACHEPREFIX="$XDG_CACHE_HOME/python" EOF cat > "$dst/etc/profile.d/cargo.sh" << 'EOF' #!/bin/sh export CARGO_HTTP_CAINFO=/etc/ssl/cert.pem EOF chmod 755 "$dst/etc/profile.d/10-xdg.sh" chmod 755 "$dst/etc/profile.d/cargo.sh" # ============================================================ # Package database # ============================================================ touch "$dst/var/lib/pkg/db" echo "" echo ">>> Filesystem skeleton ready in $dst" echo ""