Streamline VM provisioning

This commit is contained in:
Disassembler 2018-10-31 22:27:17 +01:00
parent 072b529c9c
commit 35a70fd5c1
No known key found for this signature in database
GPG Key ID: 524BD33A0EE29499
11 changed files with 114 additions and 101 deletions

View File

@ -1,15 +0,0 @@
#!/bin/sh
set -ev
cd $(realpath $(dirname "${0}"))
# Install basic packages and perform OS customization
./basic.sh
# Clean package cache
rm -rf /var/cache/apk/*
# Remove root settings
find /root -mindepth 1 -maxdepth 1 | xargs rm -rf
# Change passwords
vmmgr change-password
passwd

View File

@ -1,4 +1,5 @@
#!/bin/sh
set -v
# Based on
# https://wiki.alpinelinux.org/wiki/LVM_on_LUKS
@ -7,13 +8,14 @@
# setup-interfaces
# ifup eth0
# Ask for passwords
IFS= read -sp 'Encryption password:' ENCPWD
echo
# Set up repositories
cat <<EOF >/etc/apk/repositories
http://dl-cdn.alpinelinux.org/alpine/v3.8/main
http://dl-cdn.alpinelinux.org/alpine/v3.8/community
#http://dl-cdn.alpinelinux.org/alpine/edge/main
#http://dl-cdn.alpinelinux.org/alpine/edge/community
#http://dl-cdn.alpinelinux.org/alpine/edge/testing
EOF
# Install disk management tools
@ -40,8 +42,8 @@ w
EOF
# Set up partition encryption
echo -n 'password' | cryptsetup -q luksFormat /dev/sda2
echo -n 'password' | cryptsetup open --type luks /dev/sda2 system
echo -n "${ENCPWD}" | cryptsetup -q luksFormat /dev/sda2
echo -n "${ENCPWD}" | cryptsetup open --type luks /dev/sda2 system
# Set up LVM
pvcreate /dev/mapper/system
@ -80,14 +82,21 @@ chroot /mnt update-extlinux
# Set time zone
chroot /mnt setup-timezone -z Europe/Prague
# Set hostname
echo 'spotter.vm' >/mnt/etc/hostname
echo -e '127.0.0.1 localhost\n::1 localhost' >/mnt/etc/hosts
sed -i '/hostname/d' /mnt/etc/network/interfaces
# Install basic system
apk --no-cache add apache2-utils gettext
wget https://dl.dasm.cz/basic.tar -O - | tar xf - -C /mnt
chroot /mnt apk --no-cache add ca-certificates curl bridge e2fsprogs-extra gettext iptables kbd-misc libcap libressl libseccomp postfix python3 py3-bcrypt py3-cffi py3-cryptography py3-dnspython py3-jinja2 py3-requests py3-six py3-werkzeug nginx util-linux acme-sh@vm lxc@vm
for SERVICE in cgroups consolefont crond iptables networking nginx ntpd postfix swap urandom vmmgr; do
ln -s /etc/init.d/${SERVICE} /mnt/etc/runlevels/boot
done
ADMINPWD=$(htpasswd -bnBC 10 "" "${ENCPWD}" | tr -d ':\n' | sed 's/$2y/$2b/') envsubst </mnt/srv/vm/config.default.json >/mnt/srv/vm/config.json
# Enable services on boot
ln -s /etc/init.d/networking /mnt/etc/runlevels/boot
ln -s /etc/init.d/urandom /mnt/etc/runlevels/boot
# Change root password
echo "root:$(head -c 18 /dev/urandom | base64)" | chroot /mnt chpasswd
# Cleanup
rm -rf /mnt/root
mkdir /mnt/root
# Install bootloader to MBR
dd bs=440 count=1 conv=notrunc if=/mnt/usr/share/syslinux/mbr.bin of=/dev/sda

View File

@ -1,56 +0,0 @@
#!/bin/sh
set -ev
cd $(realpath $(dirname "${0}"))/basic
# Configure APK repository
echo "@vm https://dl.dasm.cz/spotter-abuild" >>/etc/apk/repositories
cp etc/apk/keys/repokey.rsa.pub /etc/apk/keys/repokey.rsa.pub
# Install packages
apk --no-cache add ca-certificates curl bridge e2fsprogs-extra gettext iptables kbd-misc libcap libressl libseccomp postfix python3 py3-bcrypt py3-cffi py3-cryptography py3-dnspython py3-jinja2 py3-requests py3-six py3-werkzeug nginx util-linux acme-sh@vm lxc@vm
# Copy boot configuration
cp boot/extlinux.conf /boot/extlinux.conf
cp boot/vm.txt /boot/vm.txt
cp etc/inittab /etc/inittab
cp sbin/extend-disk /sbin/extend-disk
cp sbin/vmtty /sbin/vmtty
>/etc/motd
# Enable support for Czech characters
cp etc/rc.conf /etc/rc.conf
cp etc/conf.d/consolefont /etc/conf.d/consolefont
# Configure NTP client
cp etc/conf.d/ntpd /etc/conf.d/ntpd
# Configure networking
cp etc/conf.d/iptables /etc/conf.d/iptables
cp etc/iptables/rules-save /etc/iptables/rules-save
cp etc/network/interfaces /etc/network/interfaces
service networking restart
# Configure LXC
mkdir /var/log/lxc
echo -e "172.17.0.1 host" >>/etc/hosts
# Copy VMMgr resources
cp etc/init.d/vmmgr /etc/init.d/vmmgr
rc-update -u
cp -r srv/vm /srv/vm
ln -s /srv/vm/cli.py /usr/bin/vmmgr
# Configure nginx and create a self-signed certificate
cp etc/nginx/nginx.conf /etc/nginx/nginx.conf
vmmgr install
# Configure postfix
cp etc/postfix/main.cf /etc/postfix/main.cf
newaliases
# Configure services
for SERVICE in cgroups consolefont crond iptables nginx ntpd postfix swap vmmgr; do
rc-update add ${SERVICE} boot
service ${SERVICE} start
done

View File

@ -0,0 +1,3 @@
http://dl-cdn.alpinelinux.org/alpine/v3.8/main
http://dl-cdn.alpinelinux.org/alpine/v3.8/community
@vm https://dl.dasm.cz/spotter-abuild

1
basic/etc/hostname Normal file
View File

@ -0,0 +1 @@
spotter.vm

3
basic/etc/hosts Normal file
View File

@ -0,0 +1,3 @@
127.0.0.1 localhost
::1 localhost
172.17.0.1 host

View File

@ -0,0 +1,38 @@
server {
listen [::]:80 default_server ipv6only=off;
location / {
return 301 https://$host:443$request_uri;
}
location /.well-known/acme-challenge/ {
root /etc/acme.sh.d;
}
location = /vm-ping {
add_header Content-Type text/plain;
return 200 "vm-pong";
}
}
server {
listen [::]:443 ssl http2 default_server ipv6only=off;
location / {
proxy_pass http://127.0.0.1:8080;
}
location /static {
root /srv/vm;
}
error_page 502 /502.html;
location = /502.html {
root /srv/vm/templates;
}
location = /vm-ping {
add_header Content-Type text/plain;
return 200 "vm-pong";
}
}

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC20ZrpUqogm+Xf
AOJY8dl236kYaW4Gj9DrDR9cIY5xv4tkVqALPOYRypy7vN8+vtHPtO/bI1QPQ0nE
cR4dI7PPyscMlM6O0ug5Hdx+y72eR1b7RcDr3FXaQvYyz7m7duUAZVe2qPfQQf2m
/6k8IK00nAwKPQMv5saH4ZLySr0aSDtH8shVpckse2hCebUcr6+X+afH229coO1o
UwZ/Vqhx2WJJaWUkMJ9fm2pXteATigrOqBBUiPR+eSQ7+SdN9HucY6fTlkB3sP5+
7WR550HzX/+dF+wvUG8whMRk6Im0L232K2Kao7Cj0k468l1lk8cS0X+fEXXQKi9X
xJOny8mVAgMBAAECggEBAIAqeDjk3CJaSRBK9WQ3wSYmbMyRdTIiduuiWn7jg5JZ
H6brV+4o9n44liLDqZq6eirshU8S+GZu3PNb/imdkvy1A1DdreXRFD6eoas+uKOT
DfbAkxyHbqTCVwmOOX6kPq1FXvXOhVU6PlJqX8GoguUkFQjEd0yItFwklzlHjkUy
eGYm1XmC4JX9bz/IErYqUKCtARQXhLPgbHJs5mKKxoh4l90hH3Ik0lAN2NViIluF
rla1PmGBRUtawxX33reSdMIkcs1cep6+VY5Q47KWi5/NmRYGe8hwIHlYiR8KHCn0
BRU4skNzGqxOTrlb8rWgIPzw7i3XpocLTtBzRtwyPQECgYEA5x3WNqX6wtE5a8oC
2JaKuHzVVQtuRjHVPKBGFNXkkF6GREz2kGvFGMXz2ovOBB4cP+TCuY4tqC9AABcE
KPXuzYtuaBMx/JmyWFd4F3niXF5B/TWlJSBvmCQeF4JHOilUcpvTf12inZsUNdgT
W9n43mfVhuZ61smddgZ0urNCZEECgYEAyoCO2bTWORsbzQClEmRAIRtd54QNaMG/
keW5dioPe4VhXj4aInJV3vRGUmd9TdVHZzVRs0wbILvf4f8bg4DzxpFqodK/2xNZ
7nTwMxxHQbeW1hIcob5hwGP61abJbsRRMdPsRnYluEykP0TGDgXs7GraNfwxY6Rm
5xvSREiggFUCgYEAo8uqmNpzaQT9TB5EfBndQLkAPKC4S7lfpfL1GCkrLwI+6EMf
b+VhL5iDpbz1ikeIv+Ox+e4A/7RVCHtHcHwz/aq22b3Y7GxFUITVUNYKDmqjHACc
BT8Ct/HI/eJP9rF57yvu7dJ/wHE7FpoHxk4qKf2vAEdyga0sEoyqx/Lpt8ECgYBI
Z8ksDJ3gU1IQbd+YAOJxNADSjAPjZgtiVlqG5qkciGd1NA1SLcGIc51FT52dG9pp
C8aHrnmwrZxyiS3ESnJfmJUhAWL6KSQpwAQ2sjDETamQJ2+3YYRALz977yPtCCLk
BxtfYlVAXZ8IxEVwtCuvqNEXJnJeZ2Un02nOYo2I9QKBgQDYfLmv0udzmB3A/HRb
7cqPLrWwDCes/YMLV2o8+94r6eiXC2490qRrK7bczkRHCl+X6g94bWppd33DC1D3
sc/AE2d+nrAgerOLFwO5u+zyL1qXZiorLN3TTYbdi4JCRqGDAqzzVdwG8IuYbzFP
16hsShW2J94Rq0aV4qRtGFTNDw==
-----END PRIVATE KEY-----

View File

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC1DCCAbygAwIBAgIJAOqbTKW2BX0HMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV
BAMMCnNwb3R0ZXIudm0wHhcNMTgxMDI2MTIzNTI5WhcNMzgxMDI2MTIzNTI5WjAV
MRMwEQYDVQQDDApzcG90dGVyLnZtMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAttGa6VKqIJvl3wDiWPHZdt+pGGluBo/Q6w0fXCGOcb+LZFagCzzmEcqc
u7zfPr7Rz7Tv2yNUD0NJxHEeHSOzz8rHDJTOjtLoOR3cfsu9nkdW+0XA69xV2kL2
Ms+5u3blAGVXtqj30EH9pv+pPCCtNJwMCj0DL+bGh+GS8kq9Gkg7R/LIVaXJLHto
Qnm1HK+vl/mnx9tvXKDtaFMGf1aocdliSWllJDCfX5tqV7XgE4oKzqgQVIj0fnkk
O/knTfR7nGOn05ZAd7D+fu1keedB81//nRfsL1BvMITEZOiJtC9t9itimqOwo9JO
OvJdZZPHEtF/nxF10CovV8STp8vJlQIDAQABoycwJTAjBgNVHREEHDAaggpzcG90
dGVyLnZtggwqLnNwb3R0ZXIudm0wDQYJKoZIhvcNAQELBQADggEBAEZKlh+Ds4hO
mSYx3fWv8m9tfJaEZ38B5+n6SYuyCJMB2A8CTGjDXS7tyGRvdcBFLdYF2u8YPDqI
Ra7lTLh1JNQlypROWAN/PA9JT602knF5SjupmlGMTTHtUQgna+geBnw3V3e+IMwS
l6m3vSsndE+OFBmNfk2bbA3b7XS0T44PNYOBt1feyPKJ8TVGApakFL3cF1TMMQbq
od2lEDxiqmAPmJlyPGJyOSGTT3i12TenDBKhFRTyy7kmu2I+dDO0yPCSfonMTsr3
liTAEJHE8xfjd6wygdYU2JWdx8KRCK2RfbDqZ9B11MKY2a3J4M289etJ7hyp6IMt
3iJrD0XG1bE=
-----END CERTIFICATE-----

View File

@ -5,7 +5,7 @@
"gmaps-api-key": ""
},
"host": {
"adminpwd": "$2b$12$nLrIefUoWN.pK6j90gsfkO0/tg4EGXDmdjN8HOGB0U.9BcHTFxzWS",
"adminpwd": "${ADMINPWD}",
"domain": "spotter.vm",
"firstrun": true,
"port": "443"

View File

@ -2,7 +2,6 @@
# -*- coding: utf-8 -*-
import argparse
import getpass
import sys
sys.path.append('/srv/vm')
@ -11,12 +10,6 @@ from mgr import VMMgr
parser = argparse.ArgumentParser(description='VM application manager')
subparsers = parser.add_subparsers()
parser_install = subparsers.add_parser('install')
parser_install.set_defaults(action='install')
parser_change_password = subparsers.add_parser('change-password')
parser_change_password.set_defaults(action='change-password')
parser_update_login = subparsers.add_parser('update-login')
parser_update_login.set_defaults(action='update-login')
parser_update_login.add_argument('app', help='Application name')
@ -48,16 +41,7 @@ parser_unregister_proxy.add_argument('app', help='Application name')
args = parser.parse_args()
mgr = VMMgr()
if args.action == 'install':
# Used during VM installation
mgr.rebuild_nginx()
mgr.create_selfsigned_cert()
elif args.action == 'change-password':
# Used during VM packaging
oldpassword = getpass.getpass('Old password: ')
newpassword = getpass.getpass('New password: ')
mgr.update_password(oldpassword, newpassword)
elif args.action == 'update-login':
if args.action == 'update-login':
# Used by app install scripts
mgr.update_login(args.app, args.login, args.password)
elif args.action == 'rebuild-issue':