/
setup
197 lines (162 loc) · 6.67 KB
/
setup
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
#!/usr/bin/env bash
echo "TPM2-based LUKS Authentication setup"
if [ "${EUID}" -gt 0 ]; then
echo "Error: Please run as root (sudo, su, ssh, etc.)" >&2
exit 1
fi
# Pulls out the UUID of the EFI boot partition.
BOOT=$(blkid | grep vfat | grep -v "UBUNTU" | grep -Po "(?<= UUID\=\")[A-Za-z0-9-]+")
EFIBOOT=$(lsblk -pno pkname $(lsblk -oMOUNTPOINT,NAME -Pp | grep 'MOUNTPOINT="/boot/efi"' | grep -Po "(?<=NAME=\")[A-Za-z0-9-/]+"))
EFIPART=$(parted $EFIBOOT print | grep esp | awk '{print $1}')
EFIORDER=$(efibootmgr | grep BootOrder | awk '{print $2}')
ROOT=$(lsblk -oMOUNTPOINT,NAME -Pp | grep '"/"' | grep -Po "(?<=NAME=\")[A-Za-z0-9-/]+")
# Pulls out the UUID of the LUKS encrypted drive.
LUKS=$(blkid | grep LUKS | grep -Po "(?<= UUID\=\")[A-Za-z0-9-]+")
DRIVE=$(blkid | grep $LUKS | grep -Pow "^/[A-Za-z0-9/]+")
# Pulls up Linux kernel and initrd file
LINUX="$( ls -t /boot/vmlinuz* | head -n 1 )"
INITRD="$( sed -e 's#vmlinuz#initrd\.img#g' <<< "${LINUX}" )"
# Grabs file location to append to tpm2keyunlock.service
BASEDIR=$(pwd)
# List of packages to install before compiling tpm2-tss
PACKAGES=( 'autoconf-archive' 'm4' 'libgcrypt20-dev' 'libjson-c-dev' 'uuid-dev' 'libcmocka0' 'libcmocka-dev' 'build-essential' 'git' 'pkg-config' 'gcc' 'g++' 'm4' 'libtool' 'automake' 'autoconf' 'libdbus-glib-1-dev' 'libssl-dev' 'cmake' 'libssl-dev' 'libcurl4-gnutls-dev' 'doxygen' 'efitools' 'tpm2-abrmd' 'tpm2-tools' 'libltdl-dev')
CONTINUE=''
PASSWORD=''
print_usage() {
echo -e "B: Optional EFI boot device\nb: Optional boot device location by UUID"
echo -e "l: Optional LUKS partition by UUID\nP: Optional EFI boot partition"
echo -e "p: Cryptsetup password\nr: Provide optional root device."
echo -e "y: Continue installation without prompts"
}
while getopts "B:b:l:P:p:y" flag; do
case "${flag}" in
B) EFIBOOT="${OPTARG}" ;;
b) BOOT="${OPTARG}" ;;
l) LUKS="${OPTARG}" ;;
P) EFIPART="${OPTARG}" ;;
p) PASSWORD="${OPTARG}" ;;
r) ROOT="${OPTARG}" ;;
y) CONTINUE="yes" ;;
*) print_usage
exit 1 ;;
esac
done
if [ "$BOOT" = '' ]; then
echo "The boot device was not found."
exit 1
fi
if [ "$LUKS" = '' ]; then
echo "The LUKS partition was not found."
echo "Please make sure LUKS encryption was set up during OS install."
exit 1
fi
if [ $(ls /dev/ | grep -P "tpm[0-9]+") = "" ]; then
echo "No TPM device found in /dev/. This typically means the device is disabled in BIOS or does not exist."
fi
for pkg in "${PACKAGES[@]}";do
if ! dpkg -l "${pkg}" | grep '^ii '; then
if ! apt install -y "${pkg}"; then
echo "Error installing ${pkg}" >&2
exit 1
fi
fi
done
apt-get install -y glib2.0 || (echo "Could not install glib2.0"; exit 1)
cp tpm2keyunlock.service /etc/systemd/system/
sed -i "s#LOCATION#$BASEDIR#g" /etc/systemd/system/tpm2keyunlock.service
cd /usr/local/src || exit 1
git clone https://github.com/tpm2-software/tpm2-tss.git
cd /usr/local/src/tpm2-tss || exit 1
./bootstrap
./configure --with-udevrulesdir=/etc/udev/rules.d
if make; then
if ! make install; then
echo "Unable to install tpm2-tss" >&2
exit 1
fi
else
echo "Unable to build tpm2-tss" >&2
exit 1
fi
if id tss;then
echo "User tss already exists, please check user details"
else
useradd --system --user-group tss
fi
source /etc/profile
for command in uuidgen openssl cert-to-efi-sig-list sign-efi-sig-list objcopy sbsign; do
if ! command -v "${command}"; then
echo "Unable to find ${command}, bailing out!" >&1
exit 1
fi
done
echo "Linux kernels seen:"
ls -ltr /boot/vmlinuz*
if ! [ -e "${INITRD}" ]; then
echo -n "Unable to find InitRD guess of ${INITRD}"
INITRD="$( ls -t /boot/initrd* | head -n 1 )"
echo " using ${INITRD} instead"
fi
echo -e "Installing for:\n\tkernel:\t${LINUX}\n\tInitRD:\t${INITRD}"
while [ "${CONTINUE}" != 'yes' ]; do
echo 'Continue? Enter "yes" to continue or Ctrl+C to break.'
read -p '>' CONTINUE
done
for file in /usr/lib/systemd/boot/efi/linuxx64.efi.stub /boot/efi/EFI/BOOT/BOOTX64.EFI /etc/os-release;do
if [ ! -e "${file}" ];then
echo -e "Unable to find ${file}." >&2
exit 1
fi
done
mkdir -p /usr/local/var/bootChain || exit 1
cd /usr/local/var/bootChain || exit 1
if [ ! -e GUID.txt ]; then
uuidgen --random > GUID.txt
fi
#Create Platform Key
openssl req -newkey rsa:2048 -nodes -keyout PK.key -new -x509 -sha256 -days 3650 -subj "/CN=TPM2 Platform Key/" -out PK.crt
openssl x509 -outform DER -in PK.crt -out PK.cer
cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl
sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth
#Create Key Exchange Key
openssl req -newkey rsa:2048 -nodes -keyout KEK.key -new -x509 -sha256 -days 3650 -subj "/CN=TPM2 Key Exchange Key/" -out KEK.crt
openssl x509 -outform DER -in KEK.crt -out KEK.cer
cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl
sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl KEK.auth
#Creating Signature Database Key
openssl req -newkey rsa:2048 -nodes -keyout db.key -new -x509 -sha256 -days 3650 -subj "/CN=TPM2 Signature Database key/" -out db.crt
openssl x509 -outform DER -in db.crt -out db.cer
cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl
sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth
cp db.auth /boot/efi/EFI/BOOT/
cp KEK.auth /boot/efi/EFI/BOOT/
mokutil --import db.cer KEK.cer
echo "root=$ROOT panic=60" > cmdline.txt
objcopy \
--add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \
--add-section .cmdline=cmdline.txt --change-section-vma .cmdline=0x30000 \
--add-section .linux="${LINUX}" --change-section-vma .linux=0x40000 \
--add-section .initrd="${INITRD}" --change-section-vma .initrd=0x3000000 \
/usr/lib/systemd/boot/efi/linuxx64.efi.stub /boot/efi/EFI/BOOT/BOOTX64.EFI
sbsign --key db.key --cert db.crt --output /boot/efi/EFI/BOOT/BOOTX64.EFI /boot/efi/EFI/BOOT/BOOTX64.EFI
mkdir -p /usr/local/var/tpm-manager || exit 1
chmod 0500 /usr/local/var/tpm-manager || exit 1
chown 0:0 /usr/local/var/tpm-manager || exit 1
cd /usr/local/var/tpm-manager || exit 1
touch secret.bin
chmod 0400 secret.bin
dd if=/dev/urandom of=secret.bin bs=32 count=1 conv=sync
if [ "${PASSWORD}" != '' ]; then
echo $PASSWORD | cryptsetup luksAddKey $DRIVE secret.bin
else
cryptsetup luksAddKey $DRIVE secret.bin
fi
cp /etc/crypttab ./
sed -i "/$LUKS/s/none/\/usr\/local\/var\/tpm-manager\/secret.bin/g" crypttab
sed -i "/$LUKS/s/$/\,keyscript\=\/usr\/local\/bin\/passphrase-from-tpm/g" crypttab
cp /etc/crypttab /etc/crypttab.bak
efibootmgr -c -L "TPM2 EFI Stub" -l "\\EFI\\BOOT\\BOOTX64.EFI" -d $EFIBOOT -p $EFIPART
efibootmgr -o $(efibootmgr | grep "TPM2 EFI Stub" | grep -Po "(?<=Boot)[A-Za-z0-9]+"),$EFIORDER
systemctl enable tpm2keyunlock.service
echo "TPM2 boot enabled, please restart." >> /var/run/reboot-required
cat /var/run/reboot-required