-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenapkovl-pinewall.sh
executable file
·262 lines (215 loc) · 9.36 KB
/
genapkovl-pinewall.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
#!/bin/sh -e
# Set hostname to "pinewall"
HOSTNAME="pinewall"
cleanup() {
rm -rf "$tmp"
}
makefile() {
OWNER="$1"
PERMS="$2"
FILENAME="$3"
cat > "$FILENAME"
chown "$OWNER" "$FILENAME"
chmod "$PERMS" "$FILENAME"
}
copyfile() {
OWNER="$1"
PERMS="$2"
SOURCE="$3"
DEST="$4"
cp -f "$SOURCE" "$DEST"
chown "$OWNER" "$DEST"
chmod "$PERMS" "$DEST"
}
rc_add() {
mkdir -p "$tmp"/etc/runlevels/"$2"
ln -sf /etc/init.d/"$1" "$tmp"/etc/runlevels/"$2"/"$1"
}
tmp="$(mktemp -d)"
trap cleanup EXIT
mkdir -p "$tmp"/etc
makefile root:root 0644 "$tmp"/etc/hostname <<EOF
$HOSTNAME
EOF
# Copy our interfaces file
mkdir -p "$tmp"/etc/network
copyfile root:root 0644 /tmp/etc/network/interfaces "$tmp"/etc/network/interfaces
# By default, it seems like /etc/apk/world on a system without
# an apkovl being loaded contains just the two entries for
# "alpine-base" and for "openssl". I've replicated those in
# the world file to make sure we don't miss out on them.
mkdir -p "$tmp"/etc/apk
copyfile root:root 0644 /tmp/etc/apk/world "$tmp"/etc/apk/world
# Copy the repos file to give us internet repo access
mkdir -p "$tmp"/etc/apk
copyfile root:root 0644 /tmp/etc/apk/repositories "$tmp"/etc/apk/repositories
# Set timezone to UTC
# (This is getting copied from the local Alpine container where the `tzdata` package keeps it)
mkdir -p "$tmp"/etc/zoneinfo
copyfile root:root 0644 /usr/share/zoneinfo/UTC "$tmp"/etc/zoneinfo/UTC
mkdir -p "$tmp"/etc/profile.d
copyfile root:root 0644 /tmp/etc/profile.d/timezone.sh "$tmp"/etc/profile.d/timezone.sh
# Seed our custom users based on the user config files
# in the running container
mkdir -p "$tmp"/etc
copyfile root:root 0644 /etc/group "$tmp"/etc/group
copyfile root:root 0644 /etc/passwd "$tmp"/etc/passwd
# Add users with a shadow file based on the default shadow file in Alpine 3.20
# We can't copy this from the running container since we're likely running as
# the builder user at this point and won't be able to read the shadowfile
copyfile root:root 0644 /tmp/etc/shadow_alpine320 "$tmp"/etc/shadow
# Lock the root account
# We're doing this by setting the /sbin/nologin shell
#
## DISABLED! - So it turns out that busybox crond launches all cron jobs in the shell of the
## user they belong to - I think. Which means if we don't have a shell, none of
## our cron jobs will run successfully. Fun!
#
#sed -i 's,^root.*,root:x:0:0:root:/root:/sbin/nologin,g' "$tmp"/etc/passwd
# Add a new iperf user and group without a password
echo "iperf:x:520:" >> "$tmp"/etc/group
echo "iperf:x:520:520:iperf user:/home/iperf:/sbin/nologin" >> "$tmp"/etc/passwd
echo "iperf:!::0:::::" >> "$tmp"/etc/shadow
# Add a pinewall user with default password of "pinewall"
echo "pinewall:x:5000:" >> "$tmp"/etc/group
echo "pinewall:x:5000:5000:Pinewall MGMT user:/home/pinewall:/bin/ash" >> "$tmp"/etc/passwd
echo 'pinewall:$6$sFTyHCoLEjykVIXe$aDrddac7iQoqnedKMev5LuEf52/mQvTe5gOZkvERsgu36B7PM7HPj0udJFmSsLOAUac//OyOJpvjdEhEsEPxK.::0:::::' >> "$tmp"/etc/shadow
# Create pinewall user's home directory
# Add a basic file to this so it's not empty otherwise
# the APK overlay doesn't seem to actually create it
# in the loaded system.
mkdir -p "$tmp"/home/pinewall
chmod 0750 "$tmp"/home/pinewall
echo "pinewall" > "$tmp"/home/pinewall/.pinewall
chmod 0640 "$tmp"/home/pinewall/.pinewall
chown -R 5000:5000 "$tmp"/home/pinewall
# Copy doas config to allow the pinewall user to escalate privilege
mkdir -p "$tmp"/etc
copyfile root:root 0400 /tmp/etc/doas.conf "$tmp"/etc/doas.conf
# Add our file based on the iperf3 init.d default file
# but which specifies to use the iperf user.
#
# Note the 0755 here as we want this to match our other
# init.d scripts and actually be executable.
mkdir -p "$tmp"/etc/init.d
copyfile root:root 0755 /tmp/etc/init.d/iperf3 "$tmp"/etc/init.d/iperf3
# Branding generated with:
# - neofetch --logo --ascii_distro Alpine_small
# - figlet Pinewall
# - and some painstaking lining-up
mkdir -p "$tmp"/etc
copyfile root:root 0644 /tmp/etc/motd "$tmp"/etc/motd
# Add sysctls
mkdir -p "$tmp"/etc/sysctl.d
copyfile root:root 0644 /tmp/etc/sysctl.d/local.conf "$tmp"/etc/sysctl.d/local.conf
# Add NTP config
mkdir -p "$tmp"/etc/chrony
copyfile root:root 0644 /tmp/etc/chrony/chrony.conf "$tmp"/etc/chrony/chrony.conf
# Add DNS client config
mkdir -p "$tmp"/etc
copyfile root:root 0644 /tmp/etc/resolv.conf "$tmp"/etc/resolv.conf
# Add Unbound DNS server config
mkdir -p "$tmp"/etc/unbound
copyfile root:root 0644 /tmp/etc/unbound/unbound.conf "$tmp"/etc/unbound/unbound.conf
copyfile root:root 0644 /tmp/etc/unbound/adblock.list "$tmp"/etc/unbound/adblock.list
# Add Pinehole adblock list downloader for Unbound
# This should be 0755 to match the other scripts in /etc/periodic
mkdir -p "$tmp"/etc/periodic/daily
copyfile root:root 0755 /tmp/etc/periodic/daily/pinehole "$tmp"/etc/periodic/daily/pinehole
# Add IPv6 radvd config
# (Retired in favour of corerad)
# It seems like radvd is quite particular about making sure its config is not world writable
##mkdir -p "$tmp"/etc
##copyfile root:root 0400 /tmp/etc/radvd.conf "$tmp"/etc/radvd.conf
# Add corerad config
# (Retired in favour of radvd)
mkdir -p "$tmp"/etc/corerad
copyfile root:root 0644 /tmp/etc/corerad/config.toml "$tmp"/etc/corerad/config.toml
# Add nftables rules - note that these are 0754 unlike other files, as they
# need to be executable!
copyfile root:root 0754 /tmp/etc/nftables.nft "$tmp"/etc/nftables.nft
mkdir -p "$tmp"/etc/nftables.d
copyfile root:root 0754 /tmp/etc/nftables.d/rules.nft "$tmp"/etc/nftables.d/rules.nft
# Add ulogd config
mkdir -p "$tmp"/etc
copyfile root:root 0644 /tmp/etc/ulogd.conf "$tmp"/etc/ulogd.conf
# Add Avahi config
mkdir -p "$tmp"/etc/avahi
copyfile root:root 0644 /tmp/etc/avahi/avahi-daemon.conf "$tmp"/etc/avahi/avahi-daemon.conf
# Add Kea DHCPv4 server config
mkdir -p "$tmp"/etc/kea
copyfile root:root 0644 /tmp/etc/kea/kea-dhcp4.conf "$tmp"/etc/kea/kea-dhcp4.conf
# Add PPPoE settings
mkdir -p "$tmp"/etc/ppp
copyfile root:root 0600 /tmp/etc/ppp/chap-secrets "$tmp"/etc/ppp/chap-secrets
copyfile root:root 0755 /tmp/etc/ppp/ip-up "$tmp"/etc/ppp/ip-up
mkdir -p "$tmp"/etc/ppp/peers
copyfile root:root 0644 /tmp/etc/ppp/peers/provider "$tmp"/etc/ppp/peers/provider
# Add modules file
mkdir -p "$tmp"/etc
copyfile root:root 0644 /tmp/etc/modules "$tmp"/etc/modules
# Add WireGuard config
mkdir -p "$tmp"/etc/wireguard
copyfile root:root 0600 /tmp/etc/wireguard/wg0.conf "$tmp"/etc/wireguard/wg0.conf
# Add rngd config
mkdir -p "$tmp"/etc/conf.d
copyfile root:root 0644 /tmp/etc/conf.d/rngd "$tmp"/etc/conf.d/rngd
# Add Busybox syslogd config
mkdir -p "$tmp"/etc/conf.d
copyfile root:root 0644 /tmp/etc/conf.d/syslog "$tmp"/etc/conf.d/syslog
# Add inittab config
mkdir -p "$tmp"/etc
copyfile root:root 0644 /tmp/etc/inittab "$tmp"/etc/inittab
# [Pinewall user home directory] Add Dropbear key for SSH auth
mkdir -p "$tmp"/home/pinewall/.ssh
copyfile 5000:5000 0644 /tmp/home/pinewall/.ssh/authorized_keys "$tmp"/home/pinewall/.ssh/authorized_keys
# Add Dropbear config (disables root login and disables password-based auth, so our public key in the file above needs to be correct!)
mkdir -p "$tmp"/etc/conf.d
copyfile root:root 0644 /tmp/etc/conf.d/dropbear "$tmp"/etc/conf.d/dropbear
# [Pinewall user home directory] Add htoprc to configure htop display output
mkdir -p "$tmp"/home/pinewall/.config/htop
copyfile 5000:5000 0644 /tmp/home/pinewall/.config/htop/htoprc "$tmp"/home/pinewall/.config/htop/htoprc
# Double-check that the Pinewall home directory is owned by the Pinewall user
chown -R 5000:5000 "$tmp"/home/pinewall
# Except where commented, these runlevels come from the defaults that can
# be found after a basic Alpine Standard install to HDD with the defaults.
rc_add bootmisc boot
rc_add hostname boot
#rc_add hwclock boot # Pi does not have a hardware clock
rc_add swclock boot # Need to enable software clock for the Pi instead
#rc_add loadkmap boot # Might not be needed unless we specify a keymap
rc_add modules boot
rc_add networking boot
rc_add nftables boot # Moved into boot runlevel so that the firewall comes up ASAP
rc_add rngd boot # Add rng service for Pi type devices without much entropy available
#rc_add swap boot # Won't work unless we have swap which we won't if we're running live
rc_add sysctl boot
rc_add syslog boot
rc_add urandom boot
# Most of our services want to go here in the default runlevel
rc_add acpid default
#rc_add avahi-daemon default # Disabling Avahi for now since I've managed to sort devices into proper trust-zones and don't need to cross them
rc_add chronyd default
rc_add corerad default
rc_add crond default # Previously disabled but I've re-enabled it since logrotate requires it
#rc_add dhcpd default # ISC DHCPv4 server removed after ISC deprecated it in favour of Kea
rc_add dropbear default
rc_add iperf3 default
rc_add irqbalance default
rc_add kea-dhcp4 default
#rc_add radvd default # Switched to Corerad
rc_add ulogd default
rc_add unbound default
rc_add mount-ro shutdown
rc_add killprocs shutdown
rc_add savecache shutdown
rc_add devfs sysinit
rc_add dmesg sysinit
rc_add hwdrivers sysinit
rc_add mdev sysinit
# modloop isn't present for the sysinit runlevel on an installed
# system, but experimentation and documentation online suggests this
# is needed for the live system
rc_add modloop sysinit
# Wrap up our custom /etc and /home into an APK overlay file
tar -c -C "$tmp" etc home | gzip -9n > $HOSTNAME.apkovl.tar.gz