This repository has been archived by the owner on Aug 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvm_functions.sh
executable file
·434 lines (367 loc) · 13.7 KB
/
vm_functions.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
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
#!/bin/bash
. /tmp/project_config.sh
function get_drive_name() {
dir_name=$(find /dev/mapper -maxdepth 1 -type l -name '*cs*' -print -quit)
DRIVE_NAME=$(grep -oP '(?<=_).*?(?=-)' <<< "$dir_name")
echo "$DRIVE_NAME"
}
function grow_fs() {
DRIVE_NAME_UPDATE=$(get_drive_name)
umount /home
lvreduce -L 4G -f /dev/mapper/cs_"${DRIVE_NAME_UPDATE}"-home
mkfs.xfs -f /dev/mapper/cs_"${DRIVE_NAME_UPDATE}"-home
lvextend -l +100%FREE /dev/mapper/cs_"${DRIVE_NAME_UPDATE}"-root
xfs_growfs /dev/mapper/cs_"${DRIVE_NAME_UPDATE}"-root
mount /dev/mapper/cs_"${DRIVE_NAME_UPDATE}"-home /home
}
function telegram_notify() {
echo "$@" >&2
SCRIPT_NAME="$(hostname -s)-$(basename "$0")"
logger -p news.alert -t "$SCRIPT_NAME" "$@"
}
function create_server_cert() {
cert_dir=$1
cert_name=$2
host_name=$3
runuser -l root -c "touch $cert_dir/$cert_name.pass.key"
runuser -l root -c "touch $cert_dir/$cert_name.key"
runuser -l root -c "touch $cert_dir/$cert_name.crt"
cat > "$cert_dir/$cert_name.cnf" <<EOF
##Required
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = v3_vpn_server
prompt = no
##About the system for the request. Ensure the CN = FQDN
[ req_distinguished_name ]
commonName = $host_name.$INTERNAL_DOMAIN_NAME
organizationName = $ORGANIZATION
##Extensions to add to a certificate request for how it will be used
[ v3_vpn_server ]
basicConstraints = critical, CA:FALSE
subjectKeyIdentifier = hash
nsCertType = client, server, email
keyUsage = digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement
extendedKeyUsage = critical, serverAuth, clientAuth, codeSigning, emailProtection
subjectAltName = @alt_vpn_server
nsComment = "Certificate for host -> $host_name.$INTERNAL_DOMAIN_NAME"
##The other names your server may be connected to as
[alt_vpn_server]
DNS.1 = $host_name.$INTERNAL_DOMAIN_NAME
IP.1 = 10.0.200.3
EOF
node_ct=255
while [ $node_ct -gt 0 ]; do
echo "IP.$node_ct = $NETWORK_PREFIX.$node_ct" >> "$cert_dir/$cert_name.cnf"
((node_ct--))
done
extFile=$(gen_extfile "$host_name.$INTERNAL_DOMAIN_NAME")
runuser -l root -c "openssl genrsa -out $cert_dir/$cert_name.pass.key 4096"
runuser -l root -c "openssl rsa -in $cert_dir/$cert_name.pass.key -out $cert_dir/$cert_name.key"
runuser -l root -c "openssl req -new -key $cert_dir/$cert_name.key \
-out $cert_dir/$cert_name.csr \
-config $cert_dir/$cert_name.cnf"
runuser -l root -c "openssl x509 -CAcreateserial -req -days 365 \
-in $cert_dir/$cert_name.csr \
-CA $cert_dir/id_rsa.crt \
-CAkey $cert_dir/id_rsa \
-sha256 \
-extfile <(printf \"$extFile\") \
-out $cert_dir/$cert_name.crt"
}
function gen_extfile()
{
domain=$1
cat << EOF
authorityKeyIdentifier=keyid,issuer\n
basicConstraints=CA:FALSE\n
keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement\n
extendedKeyUsage = critical, serverAuth, clientAuth, codeSigning, emailProtection\n
subjectKeyIdentifier=hash\n
nsCertType = client, server, email\n
subjectAltName = @alt_names\n
[alt_names]\n
DNS.1 = $domain
EOF
}
function setup_keys_certs_for_vm() {
mkdir -p /root/.ssh
curl -o /root/.ssh/id_rsa "http://$IDENTITY_HOST.$INTERNAL_DOMAIN_NAME:$IDENTITY_SIGNAL/sub-ca.key"
curl -o /root/.ssh/id_rsa.pub "http://$IDENTITY_HOST.$INTERNAL_DOMAIN_NAME:$IDENTITY_SIGNAL/sub-ca.pub"
chmod 600 /root/.ssh/id_rsa
chmod 600 /root/.ssh/id_rsa.pub
#### add hypervisor host key to authorized keys
## this allows the hypervisor to ssh without password to openstack vms
runuser -l root -c 'cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys'
runuser -l root -c 'chmod 600 /root/.ssh/authorized_keys'
######
}
function generate_pwd() {
generate_specific_pwd "$1"
}
function generate_random_pwd() {
length=$1
RANDOM_PWD=$(date +%s | sha256sum | base64 | head -c "$length" ; echo)
echo "$RANDOM_PWD"
}
function generate_specific_pwd() {
head -c "$1" < /dev/zero | tr '\0' 'x'
}
function join_machine_to_domain() {
## kill selinux to join domain
runuser -l root -c "sed -i 's/\(SELINUX\=\).*/\1disabled/' /etc/selinux/config"
IP_ADDRESS=$(hostname -I | awk '{print $1}')
HOSTNAME=$(hostname).$INTERNAL_DOMAIN_NAME
runuser -l root -c "echo '$IP_ADDRESS $HOSTNAME' >> /etc/hosts"
runuser -l root -c "echo $HOSTNAME > /etc/hostname"
runuser -l root -c "sysctl kernel.hostname=$HOSTNAME"
IPA_SERVER=$IDENTITY_HOST.$INTERNAL_DOMAIN_NAME
ADMIN_PASSWORD=$1
REALM_NAME=$(echo "$INTERNAL_DOMAIN_NAME" | tr '[:lower:]' '[:upper:]')
ipa-client-install -p admin \
--domain="$INTERNAL_DOMAIN_NAME" \
--realm="$REALM_NAME" \
--hostname="$HOSTNAME" \
--server="$IPA_SERVER" \
--mkhomedir \
--enable-dns-updates \
--force-join \
-w "$ADMIN_PASSWORD" -U -q > /tmp/ipa-join
### if possible, restart selinux
runuser -l root -c "sed -i 's/\(SELINUX\=\).*/\1enabled/' /etc/selinux/config"
}
function baseDN() {
### BaseDN
BASE_DN=""
IFS='.' read -ra ADDR <<< "$INTERNAL_DOMAIN_NAME"
LEN="${#ADDR[@]}"
CT=1
for i in "${ADDR[@]}"; do
BASE_DN+="dc=$i"
if [[ $CT -lt $LEN ]]; then
BASE_DN+=","
((CT++))
fi
done
echo $BASE_DN
####
}
function replace_string_in_iso() {
iso_file=$1
replacement_string=$2
replace_with=$3
tmp_file="/tmp/out-$(generate_random_pwd 10)"
cat > "$tmp_file" <<EOF
$replace_with
EOF
occur=$(grep -oba "$replacement_string" "$iso_file" | wc -l)
grep -oba "$replacement_string" "$iso_file" > /tmp/fileentries.txt
readarray -t entries < /tmp/fileentries.txt
rm -rf /tmp/fileentries.txt
# entries=($(grep -oba "$replacement_string" "$iso_file"))
while [ "$occur" -gt 0 ]; do
((occur--))
start_index=$(echo "${entries[$occur]}" | awk -F':' '{ print $1 }')
dd if="$tmp_file" of="$iso_file" conv=notrunc bs=1 seek="$start_index" count="${#replacement_string}"
done
rm -rf /tmp/out-*
}
function grub_update() {
is_intel=$(cat </proc/cpuinfo | grep vendor | uniq | grep -c 'Intel')
arch="intel"
if [[ $is_intel -lt 0 ]]; then
arch="amd"
fi
grub2-editenv - set "$(grub2-editenv - list | grep kernelopts) ${arch}_iommu=on"
grub2-editenv - set "$(grub2-editenv - list | grep kernelopts) iommu=on"
grub2-editenv - set "$(grub2-editenv - list | grep kernelopts) rhgb"
grub2-editenv - set "$(grub2-editenv - list | grep kernelopts) splash"
grub2-editenv - set "$(grub2-editenv - list | grep kernelopts) quiet"
grub2-editenv - set "$(grub2-editenv - list | grep kernelopts) systemd.log_level=0"
grub2-editenv - set "$(grub2-editenv - list | grep kernelopts) systemd.show_status=0"
grub2-editenv - set "$(grub2-editenv - list | grep kernelopts) rd.plymouth=0"
grub2-editenv - set "$(grub2-editenv - list | grep kernelopts) plymouth.enable=0"
grub2-editenv - set menu_auto_hide=1
grub2-editenv - set GRUB_DISABLE_RECOVERY="true"
}
function replace_values_in_root_isos() {
shopt -s nullglob
### replace values in isos for certs and pwds ########
## cert list
DIRECTORY_MGR_PWD=$(generate_pwd 31)
ADMIN_PWD=$(generate_pwd 31)
## gen_pwd is not stored anywhere, it is meant to lost and never found
GEN_PWD=$(generate_pwd 15)
iso_images="/tmp/*.iso"
for img in $iso_images; do
echo "replacing centos admin in $img"
replace_string_in_iso "$img" "{CENTOS_ADMIN_PWD_123456789012}" "$ADMIN_PWD"
echo "replace generated pwd in $img"
replace_string_in_iso "$img" "{GENERATED_PWD}" "$GEN_PWD"
echo "replacing directory mgr admin in $img"
replace_string_in_iso "$img" "{DIRECTORY_MGR_PWD_12345678901}" "$DIRECTORY_MGR_PWD"
done
iso_images="/tmp/*.img"
for img in $iso_images; do
echo "replacing centos admin in $img"
replace_string_in_iso "$img" "{CENTOS_ADMIN_PWD_123456789012}" "$ADMIN_PWD"
echo "replacing directory mgr admin in $img"
replace_string_in_iso "$img" "{DIRECTORY_MGR_PWD_12345678901}" "$DIRECTORY_MGR_PWD"
done
##############
}
function enable_kvm_module() {
### enable nested virtualization
is_intel=$(cat </proc/cpuinfo | grep vendor | uniq | grep -c 'Intel')
if [[ $is_intel -gt 0 ]]; then
if [[ -f /etc/modprobe.d/kvm.conf ]]; then
sed -i "s/#options kvm_intel nested=1/options kvm_intel nested=1/g" /etc/modprobe.d/kvm.conf
else
runuser -l root -c 'echo "options kvm_intel nested=1" >> /etc/modprobe.d/kvm.conf;'
fi
runuser -l root -c 'echo "options kvm-intel enable_shadow_vmcs=1" >> /etc/modprobe.d/kvm.conf;'
runuser -l root -c 'echo "options kvm-intel enable_apicv=1" >> /etc/modprobe.d/kvm.conf;'
runuser -l root -c 'echo "options kvm-intel ept=1" >> /etc/modprobe.d/kvm.conf;'
else
if [[ -f /etc/modprobe.d/kvm.conf ]]; then
sed -i "s/#options kvm_amd nested=1/options kvm_amd nested=1/g" /etc/modprobe.d/kvm.conf
else
runuser -l root -c 'echo "options kvm_amd nested=1" >> /etc/modprobe.d/kvm.conf;'
fi
runuser -l root -c 'echo "options kvm-amd enable_shadow_vmcs=1" >> /etc/modprobe.d/kvm.conf;'
runuser -l root -c 'echo "options kvm-amd enable_apicv=1" >> /etc/modprobe.d/kvm.conf;'
runuser -l root -c 'echo "options kvm-amd ept=1" >> /etc/modprobe.d/kvm.conf;'
fi
##############
}
function install_packages_openstack() {
dnf clean all
dnf module enable idm:DL1 -y
dnf distro-sync -y
dnf reposync
dnf update -y
dnf groupinstall -y virtualization-client
dnf install -y ruby-devel nodejs freeipa-client
dnf install -y docker-ce
systemctl enable docker
chkconfig docker on
cat <<EOT >> /tmp/rsys-add
\$template myedit,"%msg%\n"
EOT
split_rsysconfig_at_line "input(type=\"imtcp\" port=\"514\")" "/tmp/rsys-add"
rm -rf /tmp/rsys-add
###configure rsyslog
cat <<EOT >> /etc/rsyslog.conf
*.* @@$LAN_CENTOS_IP:514:myedit
& ~
EOT
}
function install_packages_identity() {
dnf clean all
dnf module enable idm:DL1 -y
dnf distro-sync -y
dnf reposync
dnf update -y
dnf groupinstall -y virtualization-client
dnf install -y ruby-devel nodejs
dnf install -y freeipa-server freeipa-server-dns
cat <<EOT >> /tmp/rsys-add
\$template myedit,"%msg%\n"
EOT
split_rsysconfig_at_line "input(type=\"imtcp\" port=\"514\")" "/tmp/rsys-add"
rm -rf /tmp/rsys-add
###configure rsyslog
cat <<EOT >> /etc/rsyslog.conf
*.* @@$LAN_CENTOS_IP:514:myedit
& ~
EOT
}
function split_rsysconfig_at_line() {
line="$1"
insert_file="$2"
grep -n "$line" /etc/rsyslog.conf > /tmp/fileentries.txt
readarray -t entries < /tmp/fileentries.txt
rm -rf /tmp/fileentries.txt
lines_to_modify=()
for entry in ${#entries[@]}; do
IFS=':' read -ra line_entry <<<"$entry"
line_num=${line_entry[0]}
lines_to_modify+=("$line_num")
done
arr_len=${#lines_to_modify}
line_num="${lines_to_modify[((arr_len - 1))]}"
totalLines=$(wc -l < /etc/rsyslog.conf)
line_from_bottom=$((totalLines - lines_to_modify[arr_len - 1]))
tail -n "$line_from_bottom" /etc/rsyslog.conf > /etc/rsyslog-end.conf
head -n "$line_num" /etc/rsyslog.conf > /etc/rsyslog-start.conf
cat "$insert_file" >> /etc/rsyslog-start.conf
cat /etc/rsyslog-end.conf >> /etc/rsyslog-start.conf
rm -rf /etc/rsyslog.conf
mv /etc/rsyslog-start.conf /etc/rsyslog.conf
rm -rf /etc/rsyslog-start.conf
rm -rf /etc/rsyslog-end.conf
}
function install_packages_hypervisor() {
dnf clean all
dnf distro-sync -y
dnf reposync
dnf update -y
dnf groupinstall -y virtualization-client
dnf install -y telnet automake libtool cockpit-machines
###configure rsyslog
sed -i "s/#module(load=\"imudp\")/module(load=\"imudp\")/g" /etc/rsyslog.conf
sed -i "s/#input(type=\"imudp\" port=\"514\")/input(type=\"imudp\" port=\"514\")/g" /etc/rsyslog.conf
sed -i "s/#module(load=\"imtcp\")/module(load=\"imtcp\")/g" /etc/rsyslog.conf
sed -i "s/#input(type=\"imtcp\" port=\"514\")/input(type=\"imtcp\" port=\"514\")/g" /etc/rsyslog.conf
cat <<EOT >> /tmp/rsys-add
\$template myedit,"%msg%\n"
\$template remote-incoming-logs, "/var/log/%HOSTNAME%/%PROGRAMNAME%.log"
*.* -?remote-incoming-logs
EOT
split_rsysconfig_at_line "input(type=\"imtcp\" port=\"514\")" "/tmp/rsys-add"
rm -rf /tmp/rsys-add
###configure rsyslog
cat <<EOT >> /etc/rsyslog.conf
*.* @@192.168.1.132:514:myedit
& ~
EOT
}
function get_base64_string_for_file() {
file="$1"
conv_file_name="/tmp/convert-file-$(generate_random_pwd 10)"
conv_file_name_reencoded="/tmp/convert-file-$(generate_random_pwd 10)-reencoded"
sed -e '40{N;s/\n//;}' "$file" | sed -e ':a;N;$!ba;s/\n/\r\n/g' > "$conv_file_name"
truncate -s -1 "$conv_file_name"
base64 -w 0 < "$conv_file_name" > "$conv_file_name_reencoded"
echo >> "$conv_file_name_reencoded"
ret_string="$(cat "$conv_file_name_reencoded")"
rm -rf "$conv_file_name"
rm -rf "$conv_file_name_reencoded"
echo "$ret_string"
}
function create_virtual_bridge_file() {
bridge_name=$1
ip_addr=$2
cat <<EOT >> "/etc/sysconfig/network-scripts/ifcfg-$bridge_name"
STP=no
TYPE=Bridge
HWADDR=
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
IPADDR=$ip_addr
PREFIX=24
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6_DISABLED=yes
IPV6INIT=no
IPV6_DEFROUTE=no
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=default
NAME=$bridge_name
UUID=$(uuidgen)
DEVICE=$bridge_name
ONBOOT=yes
EOT
}