diff options
-rw-r--r-- | Makefile | 19 | ||||
m--------- | fsmgr | 0 | ||||
-rw-r--r-- | initramfs-tools/scripts/samizdat | 28 | ||||
-rw-r--r-- | rootfs/samizdat.patch.yaml | 7 | ||||
-rwxr-xr-x | src/initrd.sh | 6 | ||||
-rw-r--r-- | src/initrd/btrfs-create.sh | 63 | ||||
-rwxr-xr-x | src/initrd/grok-block | 40 | ||||
-rwxr-xr-x | src/parted-usb.sh | 35 |
8 files changed, 157 insertions, 41 deletions
@@ -162,6 +162,7 @@ $(btrfs_images): FORCE | |||
162 | $(MAKE) -C rootfs $(notdir $@) | 162 | $(MAKE) -C rootfs $(notdir $@) |
163 | 163 | ||
164 | boot: rootfs | 164 | boot: rootfs |
165 | sudo initrd.sh | ||
165 | sudo SLOW_BOOT=y qemu.sh | 166 | sudo SLOW_BOOT=y qemu.sh |
166 | 167 | ||
167 | fastboot: rootfs | 168 | fastboot: rootfs |
@@ -203,12 +204,26 @@ get_loop_dev="$$(sudo losetup -n -O name -j $@~tmp)" | |||
203 | get_backing_file="$$(sudo losetup -n -O back-file -j $@~tmp)" | 204 | get_backing_file="$$(sudo losetup -n -O back-file -j $@~tmp)" |
204 | get_min_size="$$(btrfs inspect-internal min-dev-size --id 1 $@.mnt | (read b _; echo $$b))" | 205 | get_min_size="$$(btrfs inspect-internal min-dev-size --id 1 $@.mnt | (read b _; echo $$b))" |
205 | 206 | ||
207 | %.verity.sh: %.verity | ||
208 | h=$$(sed -ne 's/^Root hash:[ \t]*//p' $<.log) && [ "$$h" ] && \ | ||
209 | printf 'verity_root_hash=%s\nverity_hash_offset=%s\n' "$$h" $(shell stat -c %s $(basename $<)) > $@ | ||
210 | |||
211 | %.verity.log: %.verity | ||
206 | %.verity: % | 212 | %.verity: % |
207 | sudo veritysetup format $< $@~tmp > $@.log~tmp | 213 | cp --reflink $< $@~tmp |
214 | sudo veritysetup --hash-offset=$(shell stat -c %s $<) format $@~tmp $@~tmp > $@.log~tmp | ||
208 | mv $@.log~tmp $@.log | 215 | mv $@.log~tmp $@.log |
209 | mv $@~tmp $@ | 216 | mv $@~tmp $@ |
210 | sudo chmod 644 $@ | 217 | sudo chmod 644 $@ |
211 | h=$$(sed -ne 's/^Root hash:[ \t]*//p' $@.log) && [ "$$h" ] | 218 | |
219 | |||
220 | root_hash = $(shell sed -ne 's/^Root hash: *//p' < $<.log) | ||
221 | |||
222 | veritymount: rootfs/samizdat.seed.btrfs.verity.sh | ||
223 | @sudo veritysetup remove samizverity >/dev/null 2>&1 || true | ||
224 | set -x && . $< && sudo veritysetup --ignore-corruption --hash-offset=$$verity_hash_offset \ | ||
225 | create samizverity $(basename $<) $(basename $<) $$verity_root_hash | ||
226 | sudo veritysetup remove samizverity | ||
212 | 227 | ||
213 | %.verity.log.asc: %.verity.log | 228 | %.verity.log.asc: %.verity.log |
214 | sudo gpg --armor --detach-sign $^ | 229 | sudo gpg --armor --detach-sign $^ |
diff --git a/fsmgr b/fsmgr | |||
Subproject ea6de9aeee6173363384b3b3a1dc4d37a900f96 | Subproject f49e4f88d55b0340ea69091a2f1a91882f19994 | ||
diff --git a/initramfs-tools/scripts/samizdat b/initramfs-tools/scripts/samizdat index 51f7cec..93c84d2 100644 --- a/initramfs-tools/scripts/samizdat +++ b/initramfs-tools/scripts/samizdat | |||
@@ -16,6 +16,28 @@ my_configure_networking() | |||
16 | fi | 16 | fi |
17 | } | 17 | } |
18 | 18 | ||
19 | read_nbd_variables() | ||
20 | { | ||
21 | NBDCLIENT=: | ||
22 | . /scripts/local-top/nbd | ||
23 | unset NBDCLIENT | ||
24 | } | ||
25 | |||
26 | run_nbd_client() | ||
27 | { | ||
28 | (debug_log samizdat.nbd | ||
29 | read_nbd_variables | ||
30 | for DEVNAME in /dev/nbd0 /dev/nbd1 | ||
31 | do | ||
32 | case "$DEVNAME" in | ||
33 | /dev/nbd0) nbdpath=samizdat.btrfs ;; | ||
34 | /dev/nbd1) nbdpath=samizdat.patch.btrfs ;; | ||
35 | esac | ||
36 | nbd-client $nbdsrv -N $nbdpath $nbdport $DEVNAME -swap -persist -systemd-mark | ||
37 | done | ||
38 | bootdone nbd-script) | ||
39 | } | ||
40 | |||
19 | mountroot() | 41 | mountroot() |
20 | { | 42 | { |
21 | openvt -c 13 sh | 43 | openvt -c 13 sh |
@@ -24,10 +46,7 @@ mountroot() | |||
24 | 46 | ||
25 | if [ "$nbdroot" ]; then | 47 | if [ "$nbdroot" ]; then |
26 | my_configure_networking | 48 | my_configure_networking |
27 | 49 | run_nbd_client | |
28 | (debug_log samizdat.nbd | ||
29 | . /scripts/local-top/nbd | ||
30 | bootdone nbd-script) | ||
31 | 50 | ||
32 | wait_for_gnupghome_tar | 51 | wait_for_gnupghome_tar |
33 | (sleep 5; echo ) & | 52 | (sleep 5; echo ) & |
@@ -56,6 +75,7 @@ wait_for_gnupghome_tar() | |||
56 | done | 75 | done |
57 | mv /gnupghome.tar.$$ /gnupghome.tar) | 76 | mv /gnupghome.tar.$$ /gnupghome.tar) |
58 | echo ' done.' > /dev/tty1 | 77 | echo ' done.' > /dev/tty1 |
78 | bootdone gnupg-tar | ||
59 | } | 79 | } |
60 | 80 | ||
61 | samizdat_restart_udev() | 81 | samizdat_restart_udev() |
diff --git a/rootfs/samizdat.patch.yaml b/rootfs/samizdat.patch.yaml index 98c6fc8..c9f3874 100644 --- a/rootfs/samizdat.patch.yaml +++ b/rootfs/samizdat.patch.yaml | |||
@@ -9,4 +9,11 @@ chroot-commands: | |||
9 | - "/usr/local/bin/samizdat-update-apt-cache.sh" | 9 | - "/usr/local/bin/samizdat-update-apt-cache.sh" |
10 | - "/usr/local/bin/samizdat-patch-root.sh" | 10 | - "/usr/local/bin/samizdat-patch-root.sh" |
11 | - "/usr/local/bin/samizdat-hostname.sh" | 11 | - "/usr/local/bin/samizdat-hostname.sh" |
12 | packages: | ||
13 | - ../openssh-client_8.3p1-1_$(debarch).deb | ||
14 | - ../openssh-server_8.3p1-1_$(debarch).deb | ||
15 | - ../openssh-sftp-server_8.3p1-1_$(debarch).deb | ||
16 | # ../openssh-tests_8.3p1-1_$(debarch).deb | ||
17 | - ../ssh_8.3p1-1_all.deb | ||
18 | - ../ssh-askpass-gnome_8.3p1-1_$(debarch).deb | ||
12 | 19 | ||
diff --git a/src/initrd.sh b/src/initrd.sh index 5bf19cf..e363c83 100755 --- a/src/initrd.sh +++ b/src/initrd.sh | |||
@@ -2,8 +2,14 @@ | |||
2 | 2 | ||
3 | . samizdat-paths.sh | 3 | . samizdat-paths.sh |
4 | 4 | ||
5 | if [ -d "$1" ] | ||
6 | then | ||
7 | samizdat_linux_dir=$1 | ||
8 | fi | ||
9 | |||
5 | initrd=${samizdat_linux_dir}/initrd.img | 10 | initrd=${samizdat_linux_dir}/initrd.img |
6 | vmlinuz=${samizdat_linux_dir}/vmlinuz | 11 | vmlinuz=${samizdat_linux_dir}/vmlinuz |
12 | |||
7 | conf_dir=$samizdat_initramfs_conf_dir | 13 | conf_dir=$samizdat_initramfs_conf_dir |
8 | apt_dependencies=$samizdat_initrd_files_dir/initrd-dependencies.txt | 14 | apt_dependencies=$samizdat_initrd_files_dir/initrd-dependencies.txt |
9 | 15 | ||
diff --git a/src/initrd/btrfs-create.sh b/src/initrd/btrfs-create.sh index 39c89ca..cdf73ef 100644 --- a/src/initrd/btrfs-create.sh +++ b/src/initrd/btrfs-create.sh | |||
@@ -27,16 +27,41 @@ ceil4() | |||
27 | printf '%d\n' "$x" | 27 | printf '%d\n' "$x" |
28 | } | 28 | } |
29 | 29 | ||
30 | kernel_commandline_has() | ||
31 | { | ||
32 | local v="$1" c | ||
33 | read c < /proc/cmdline | ||
34 | for c in $c | ||
35 | do | ||
36 | case "$c" in | ||
37 | "$v"|"$v"=*) true; return;; | ||
38 | esac | ||
39 | done | ||
40 | false | ||
41 | } | ||
42 | |||
43 | netbooted() | ||
44 | { | ||
45 | kernel_commandline_has BOOTIF | ||
46 | } | ||
47 | |||
30 | cdrom_has_rootfs() | 48 | cdrom_has_rootfs() |
31 | { | 49 | { |
32 | [ ! "$BOOTIF" ] || return | 50 | if netbooted |
33 | bootwait samizdat-cdrom | 51 | then |
34 | [ -d /cdrom/rootfs ] | 52 | false |
53 | else | ||
54 | bootwait samizdat-cdrom | ||
55 | [ -d /cdrom/rootfs ] | ||
56 | fi | ||
35 | } | 57 | } |
36 | 58 | ||
37 | losetup_layers() | 59 | losetup_layers() |
38 | { | 60 | { |
39 | if cdrom_has_rootfs; then | 61 | if cdrom_has_rootfs; then |
62 | # TODO: This is some kind of shortcut or short circuit to find these | ||
63 | # files, that ought to be found through the grok-block system (i.e., | ||
64 | # event-driven rather than polling). | ||
40 | local fs fs_rw | 65 | local fs fs_rw |
41 | for fs in /cdrom/rootfs/*.btrfs; do | 66 | for fs in /cdrom/rootfs/*.btrfs; do |
42 | fs_rw=/"${fs##*/}".rw | 67 | fs_rw=/"${fs##*/}".rw |
@@ -45,8 +70,11 @@ losetup_layers() | |||
45 | done | 70 | done |
46 | else | 71 | else |
47 | bootwait samizdat-nbd-dev | 72 | bootwait samizdat-nbd-dev |
48 | dd if=/dev/zero of=/nbd0.rw bs=1M count=10 | 73 | local dev |
49 | dm_snapshot /dev/nbd0 /nbd0.rw | 74 | for dev in nbd0 nbd1; do |
75 | dd if=/dev/zero of=/$dev.rw bs=1M count=10 | ||
76 | dm_snapshot /dev/$dev /$dev.rw | ||
77 | done | ||
50 | return | 78 | return |
51 | fi | 79 | fi |
52 | } | 80 | } |
@@ -210,15 +238,24 @@ filesystem_incomplete() | |||
210 | 238 | ||
211 | partition_new_hard_drive_DESTROYING_EVERYTHING() | 239 | partition_new_hard_drive_DESTROYING_EVERYTHING() |
212 | { | 240 | { |
213 | local target="$1" | 241 | # TODO: get the actual size of the btrfs master and actually triple it. The empty |
242 | # space can be left available to allow the local machine to boot a | ||
243 | # locally-regenerated rootfs seed. | ||
244 | sz=3 | ||
245 | u=GiB | ||
246 | actual_sz=$sz$u | ||
247 | tripled_sz=$((sz * 3))$u | ||
248 | pct=100% # TODO: use 50% | ||
249 | |||
250 | local target="$1" sz=6GiB | ||
214 | # [ "$(parted -sm "$target" print | grep -c :)" = 1 ] || return | 251 | # [ "$(parted -sm "$target" print | grep -c :)" = 1 ] || return |
215 | parted "$target" -sm \ | 252 | parted "$target" -sm \ |
216 | unit B \ | 253 | unit B \ |
217 | mklabel gpt \ | 254 | mklabel gpt \ |
218 | mkpart samizdat-grub-incomplete 32KiB 8160KiB \ | 255 | mkpart samizdat-grub-incomplete 32KiB 8MiB \ |
219 | set 1 bios_grub on \ | 256 | set 1 bios_grub on \ |
220 | mkpart samizdat-plaintext-incomplete btrfs 8MiB 1GiB \ | 257 | mkpart samizdat-plaintext-incomplete btrfs 64MiB $actual_sz \ |
221 | mkpart samizdat-luks-encrypted-incomplete 1GiB 100% \ | 258 | mkpart samizdat-luks-encrypted-incomplete $tripled_sz $pct \ |
222 | && | 259 | && |
223 | udevadm settle | 260 | udevadm settle |
224 | } | 261 | } |
diff --git a/src/initrd/grok-block b/src/initrd/grok-block index 86ff499..ee23b38 100755 --- a/src/initrd/grok-block +++ b/src/initrd/grok-block | |||
@@ -167,18 +167,29 @@ grok_block() | |||
167 | # Avoid mouting this multiple times in case this script gets called multiple times, | 167 | # Avoid mouting this multiple times in case this script gets called multiple times, |
168 | # because while it's mounted, the dmsetup stuff will fail with device busy. | 168 | # because while it's mounted, the dmsetup stuff will fail with device busy. |
169 | /dev/nbd0) | 169 | /dev/nbd0) |
170 | if [ -e /bootwait/samizdat-nbd-dev ] | 170 | bootdone nbd0-dev |
171 | then | 171 | return ;; |
172 | return | 172 | /dev/nbd1) |
173 | else | 173 | bootwait nbd-script nbd0-dev |
174 | bootwait nbd-script | 174 | wait_for_files_ /sys/block/nbd0/pid /sys/block/nbd1/pid |
175 | wait_for_files_ /sys/block/nbd0/pid | ||
176 | fi | ||
177 | ;; | 175 | ;; |
178 | esac | 176 | esac |
179 | case "$ID_PART_ENTRY_NAME" in | 177 | case "$ID_PART_ENTRY_NAME" in |
180 | samizdat-grub-incomplete|samizdat-plaintext-incomplete|samizdat-luks-encrypted-incomplete) return ;; | 178 | samizdat-grub-incomplete|samizdat-plaintext-incomplete|samizdat-luks-encrypted-incomplete) return ;; |
181 | samizdat-grub|samizdat-luks-encrypted) return ;; | 179 | samizdat-plaintext) |
180 | . /verity.sh | ||
181 | cp /verity.sh /run/initramfs/samizdat/ | ||
182 | veritysetup --hash-offset="$verity_hash_offset" \ | ||
183 | create samizverity \ | ||
184 | "$DEVNAME" "$DEVNAME" "$verity_root_hash" | ||
185 | bootdone veritysetup | ||
186 | return | ||
187 | ;; | ||
188 | samizdat-grub) return ;; | ||
189 | samizdat-luks-encrypted) | ||
190 | menu-select boot-native "$(parent_device "$DEVNAME")" | ||
191 | return | ||
192 | ;; | ||
182 | esac | 193 | esac |
183 | 194 | ||
184 | if [ "$ID_FS_TYPE" = hfsplus ] && ! fsck.hfsplus -q "$DEVNAME"; then | 195 | if [ "$ID_FS_TYPE" = hfsplus ] && ! fsck.hfsplus -q "$DEVNAME"; then |
@@ -191,7 +202,11 @@ grok_block() | |||
191 | fi | 202 | fi |
192 | 203 | ||
193 | if ! mountpoint -q "$mountpoint"; then | 204 | if ! mountpoint -q "$mountpoint"; then |
194 | retry_mount $mount_type -o ro "$DEVNAME" "$mountpoint" | 205 | if [ "$DEVNAME" = /dev/nbd1 ] |
206 | then OPTIONS='-o device=/dev/nbd0' | ||
207 | else OPTIONS= | ||
208 | fi | ||
209 | retry_mount $mount_type -r $OPTIONS "$DEVNAME" "$mountpoint" | ||
195 | fi | 210 | fi |
196 | 211 | ||
197 | if ! mountpoint -q "$mountpoint"; then | 212 | if ! mountpoint -q "$mountpoint"; then |
@@ -206,10 +221,13 @@ grok_block() | |||
206 | elif [ "$ID_PART_ENTRY_NAME" = samizdat-plaintext ]; then | 221 | elif [ "$ID_PART_ENTRY_NAME" = samizdat-plaintext ]; then |
207 | if gpg_verify "$mountpoint"/disk.key && gpg_can_decrypt "$mountpoint"/disk.key; then | 222 | if gpg_verify "$mountpoint"/disk.key && gpg_can_decrypt "$mountpoint"/disk.key; then |
208 | addmenu_choose_native_root "$(parent_device "$DEVNAME")" | 223 | addmenu_choose_native_root "$(parent_device "$DEVNAME")" |
224 | umount "$mountpoint" | ||
225 | bootdone key-mounted | ||
226 | else | ||
227 | umount "$mountpoint" | ||
209 | fi | 228 | fi |
210 | umount "$mountpoint" | ||
211 | 229 | ||
212 | elif [ "$DEVNAME" = /dev/nbd0 ]; then | 230 | elif [ "$DEVNAME" = /dev/nbd1 ]; then |
213 | # This is our rootfs, over the network | 231 | # This is our rootfs, over the network |
214 | umount "$mountpoint" | 232 | umount "$mountpoint" |
215 | rmdir "$mountpoint" | 233 | rmdir "$mountpoint" |
diff --git a/src/parted-usb.sh b/src/parted-usb.sh index bb63070..e688473 100755 --- a/src/parted-usb.sh +++ b/src/parted-usb.sh | |||
@@ -16,17 +16,29 @@ MiB() | |||
16 | initialize_target() | 16 | initialize_target() |
17 | { | 17 | { |
18 | rm -f "$target" | 18 | rm -f "$target" |
19 | fallocate -l $(($(KiB 17) + $(MiB $end_keys))) "$target" | 19 | if [ "$ROOTFS" ] |
20 | then | ||
21 | fallocate -l $(($(KiB 17) + $(MiB $end_keys) + $(MiB $rootfs_size))) "$target" | ||
22 | else | ||
23 | fallocate -l $(($(KiB 17) + $(MiB $end_keys))) "$target" | ||
24 | fi | ||
20 | } | 25 | } |
21 | 26 | ||
27 | # TODO: Use GUID type tags for each Samizdat partition type. | ||
22 | partition_target() | 28 | partition_target() |
23 | { | 29 | { |
24 | parted "$target" -sm -a optimal \ | 30 | parted "$target" -sm -a optimal \ |
25 | unit B \ | 31 | unit MiB \ |
26 | mklabel gpt \ | 32 | mklabel gpt \ |
27 | mkpart samizdat-grub 1MiB 8MiB \ | 33 | mkpart samizdat-grub 1 8 \ |
28 | set 1 bios_grub on \ | 34 | set 1 bios_grub on \ |
29 | mkpart samizdat-plaintext btrfs ${start_keys}MiB ${end_keys}MiB | 35 | mkpart samizdat-keys btrfs ${start_keys} ${end_keys} |
36 | |||
37 | if [ "$ROOTFS" ] | ||
38 | then | ||
39 | parted "$target" -sm -a optimal \ | ||
40 | mkpart samizdat-rootfs btrfs ${end_keys}MiB 100% | ||
41 | fi | ||
30 | } | 42 | } |
31 | 43 | ||
32 | make_target_bootable() | 44 | make_target_bootable() |
@@ -74,12 +86,13 @@ with_target() | |||
74 | 86 | ||
75 | add_keys() | 87 | add_keys() |
76 | { | 88 | { |
77 | rsync -a --info=STATS "$GPG_INPUT_DIR"/ "$mnt"/gnupghome/ | 89 | rsync -a --info=STATS "$GPG_INPUT_DIR"/ "$mnt"/gnupghome/ |
78 | } | 90 | } |
79 | 91 | ||
92 | initrd_suffix=.samizdat | ||
80 | add_initrd() | 93 | add_initrd() |
81 | { | 94 | { |
82 | rsync -aL --info=STATS "$samizdat_linux_dir"/vmlinuz${version} "$samizdat_linux_dir"/initrd.img${version} "$mnt"/linux/ | 95 | rsync -aL --info=STATS "${1}vmlinuz${2}" "${1}initrd.img${2}${initrd_suffix}" "$mnt"/linux/ |
83 | } | 96 | } |
84 | 97 | ||
85 | add_grub_cfg() | 98 | add_grub_cfg() |
@@ -91,7 +104,7 @@ add_grub_cfg() | |||
91 | add_all() | 104 | add_all() |
92 | { | 105 | { |
93 | add_keys | 106 | add_keys |
94 | add_initrd | 107 | add_initrd "$samizdat_linux_dir"/ "${version_suffix}" |
95 | add_grub_cfg | 108 | add_grub_cfg |
96 | } | 109 | } |
97 | 110 | ||
@@ -128,7 +141,7 @@ fi | |||
128 | 141 | ||
129 | if [ "$1" ] | 142 | if [ "$1" ] |
130 | then | 143 | then |
131 | version=-$1 | 144 | version_suffix=-$1 |
132 | fi | 145 | fi |
133 | cp --reflink=always "$target" "$target".keyed | 146 | cp --reflink=always "$target" "$target".keyed |
134 | with_target "$target".keyed add_all | 147 | with_target "$target".keyed add_all |