-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcreateNebulaDevice.sh
executable file
·159 lines (136 loc) · 6.21 KB
/
createNebulaDevice.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
#! /usr/bin/env nix-shell
#! nix-shell -i bash --packages git nebula sops
# this script automates creation nebula certificates for a device
# it also adds these certificates automatically to the nix configuration and pushes them to remote origin
# this script does NOT adjust .sops.yaml file. After you run this script you either have to edit it manually or use the deployment.sh script with the deploySops or sops option
# furthermore, this script assumes that you put your sops secrets in the directory secrets and puts the host-specific nebula key into secrets/$1/nebula.yaml
#change these variables to make this script work for your setup
githubRepo="JulianFP/NixOSConfig" #github repo that contains flake config (syntax: '<Github user name>/<repo name>'). Always uses default branch
githubBranch="main" #branch that contains flake config
luksUSBDevice="/dev/disk/by-uuid/66f96bfc-45f0-4436-81a1-8a07a548a5bb" #path to device which contains nebula crt (should be reproducible, i.e. relient on uuid or label)
#luksUSBNebulaPath is not allowed to begin or end with '/', './' or similar
luksUSBNebulaPath="nebula" #path to directory in which nebula crt is stored relative from root of usb device
#define function make error output easier
echoerr() { echo "$@" 1>&2; }
help() {
printf "general usage: ./createNebulaDevice.sh <flakeSecretHostName> <flakeInstallHostName> <nebula ip> <nebula groups> [dry-run]\n\n"
printf "flakeSecretHostName:\n"
printf " name of machine that should have access to the key and crt (i.e. be able to decrypt it using sops-nix)\n"
printf " for example: NixOSTesting\n\n"
printf "flakeInstallHostName:\n"
printf " name of machine that the interface will be created for (i.e. will be using that interface)\n"
printf " if you are not creating this cert for a container then this will probably be the same as flakeSecretHostName\n"
printf " also used as device name for the nebula certificate\n"
printf " for example: mailServer-container\n\n"
printf "nebula ip:\n"
printf " ip of device in nebula network in CIDR notation (with prefix length)\n"
printf " for example: 48.42.1.130/16\n\n"
printf "nebula groups:\n"
printf " groups of device in nebula network\n"
printf " mandatory. pass an empty string if you don't want the target to be in any group\n"
printf " for example: \"server,edge\"\n\n"
printf "dry-run:\n"
printf " optional, if added then this script won't add and commit changes automatically\n"
printf " but instead just return the path to the tmp git repository for inspection\n"
}
privileges() {
# check if the script is run as root
if [ "$(whoami)" != "root" ]; then
echo "You need to run the script with root privileges. Attempting to raise via sudo:"
sudo "${0}" "$@"
exit $?
fi
}
#store if we need to umount before exit
mounted=false
unlocked=false
addDevice() {
#check if enough parameters are provided
if [[ $# -lt 3 ]]; then
echoerr "Missing parameters. use --help to find out how to use this script"
exit 1
fi
#wait until usb stick with ca.key is present
until [[ -e "$luksUSBDevice" ]]; do
echo "configured usb device not found"
read -r -p "plug in usb device with nebula cert and then press enter"
done
#unlock and mount usb stick
cryptsetup open $luksUSBDevice luksUSBDeviceNebula
unlocked=true
mkdir -p /mnt
mount /dev/mapper/luksUSBDeviceNebula /mnt
mounted=true
#find free filename for crt file on usb stick
nebname="$2"
fileNum=2
while ls "/mnt/$luksUSBNebulaPath" | grep -q "$nebname"; do
nebname="$2-$fileNum"
((++fileNum))
done
#find free dirname for tmp directory for github repo
gitname="githubRepo"
gitNum=2
while ls "/tmp" | grep -q "$gitname"; do
gitname="githubRepo-$gitNum"
((++gitNum))
done
#clone github repo and decrypt sops file
git clone -b "$githubBranch" "[email protected]:$githubRepo.git" "/tmp/$gitname"
#check if files are already there and handle these cases
if [[ ! (-e "/tmp/$gitname/secrets/$1") ]]; then
mkdir "/tmp/$gitname/secrets/$1"
printf "nebula:\n" > "/tmp/$gitname/secrets/$1/nebula.yaml"
elif grep -q "$2" "/tmp/$gitname/secrets/$1/nebula.yaml"; then
echoerr "nebula key for hostName $2 already exists for this device ($1)."
exit 1
else
sops --config "/tmp/$gitname/.sops.yaml" -d -i "/tmp/$gitname/secrets/$1/nebula.yaml"
fi
#generate nebula key and crt
nebula-cert sign -ca-crt "/mnt/$luksUSBNebulaPath/ca.crt" -ca-key "/mnt/$luksUSBNebulaPath/ca.key" -out-crt "/mnt/$luksUSBNebulaPath/$nebname.crt" -out-key "/mnt/$luksUSBNebulaPath/$nebname.key" -name $2 -ip $3 -groups $4
#generate yaml file to store secrets
printf " $2.key: |\n $(sed ':a;N;$!ba;s/\n/\n /g' /mnt/$luksUSBNebulaPath/$nebname.key)\n $2.crt: |\n $(sed ':a;N;$!ba;s/\n/\n /g' /mnt/$luksUSBNebulaPath/$nebname.crt)" >> "/tmp/$gitname/secrets/$1/nebula.yaml"
sops --config "/tmp/$gitname/.sops.yaml" -e -i "/tmp/$gitname/secrets/$1/nebula.yaml"
#add changes to git and push them
if [ "$5" != "dry-run" ]; then
git -C "/tmp/$gitname" add "/tmp/$gitname/*"
git -C "/tmp/$gitname" commit -m "added nebula certificates for $2 to $1"
git -C "/tmp/$gitname" push origin "$githubBranch"
else
echo "You can inspect and manually commit the changes in /tmp/$gitname/"
fi
#remove private key from usb stick
rm /mnt/$luksUSBNebulaPath/$nebname.key
#umount and lock usb stick (try again if still busy)
unmounting
}
#exit handling
set -eE #exit on any kind of error
trap unmounting ERR
function unmounting(){
if $mounted; then
echo "Unmounting usb device...."
until umount /mnt; do
sleep 1
done
fi
if $unlocked; then
echo "Closing luks device..."
until cryptsetup close /dev/mapper/luksUSBDeviceNebula; do
sleep 1
done
fi
}
case $1 in
"-h"|"--help"|"help"|"")
help
exit 0
;;
*)
privileges "$@"
addDevice "$@"
echo "device successfully added to nebula network"
exit 0
;;
esac