diff --git a/00-install.sh b/00-install.sh deleted file mode 100755 index 9135204..0000000 --- a/00-install.sh +++ /dev/null @@ -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 diff --git a/alpine.sh b/alpine.sh index 0649a4e..826b01f 100755 --- a/alpine.sh +++ b/alpine.sh @@ -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 </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.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 diff --git a/basic.sh b/basic.sh deleted file mode 100755 index 2f18c96..0000000 --- a/basic.sh +++ /dev/null @@ -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 diff --git a/basic/etc/apk/repositories b/basic/etc/apk/repositories new file mode 100644 index 0000000..7016916 --- /dev/null +++ b/basic/etc/apk/repositories @@ -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 diff --git a/basic/etc/hostname b/basic/etc/hostname new file mode 100644 index 0000000..77fd866 --- /dev/null +++ b/basic/etc/hostname @@ -0,0 +1 @@ +spotter.vm diff --git a/basic/etc/hosts b/basic/etc/hosts new file mode 100644 index 0000000..0a6545c --- /dev/null +++ b/basic/etc/hosts @@ -0,0 +1,3 @@ +127.0.0.1 localhost +::1 localhost +172.17.0.1 host diff --git a/basic/etc/nginx/conf.d/default.conf b/basic/etc/nginx/conf.d/default.conf new file mode 100644 index 0000000..3499490 --- /dev/null +++ b/basic/etc/nginx/conf.d/default.conf @@ -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"; + } +} diff --git a/basic/etc/ssl/services.key b/basic/etc/ssl/services.key new file mode 100644 index 0000000..a0a3c15 --- /dev/null +++ b/basic/etc/ssl/services.key @@ -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----- diff --git a/basic/etc/ssl/services.pem b/basic/etc/ssl/services.pem new file mode 100644 index 0000000..fa095e8 --- /dev/null +++ b/basic/etc/ssl/services.pem @@ -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----- diff --git a/basic/srv/vm/config.json b/basic/srv/vm/config.default.json similarity index 80% rename from basic/srv/vm/config.json rename to basic/srv/vm/config.default.json index 5a98870..2c11b70 100644 --- a/basic/srv/vm/config.json +++ b/basic/srv/vm/config.default.json @@ -5,7 +5,7 @@ "gmaps-api-key": "" }, "host": { - "adminpwd": "$2b$12$nLrIefUoWN.pK6j90gsfkO0/tg4EGXDmdjN8HOGB0U.9BcHTFxzWS", + "adminpwd": "${ADMINPWD}", "domain": "spotter.vm", "firstrun": true, "port": "443" diff --git a/basic/srv/vm/cli.py b/basic/usr/bin/vmmgr similarity index 79% rename from basic/srv/vm/cli.py rename to basic/usr/bin/vmmgr index fe3327e..342d453 100755 --- a/basic/srv/vm/cli.py +++ b/basic/usr/bin/vmmgr @@ -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':