From: Julien Moutinho Date: Tue, 12 Feb 2013 08:50:57 +0000 (+0100) Subject: Ajout : ateliers_host{,ed} : premier jet du cadre de travail. X-Git-Url: https://git.cyclocoop.org/?p=lhc%2Fateliers.git;a=commitdiff_plain;h=698ada27ce0f9d7f0bc6c9135eb5709d1497cfcb Ajout : ateliers_host{,ed} : premier jet du cadre de travail. --- 698ada27ce0f9d7f0bc6c9135eb5709d1497cfcb diff --git a/ateliers_host b/ateliers_host new file mode 100755 index 0000000..2daec2f --- /dev/null +++ b/ateliers_host @@ -0,0 +1,238 @@ +#!/bin/sh +set -e -f ${DRY_RUN:+-n} -u ${TRACE:+-x} + # -e: erreur si une commande non testée échoue. + # -f: désactive les jokers dans les chemins. + # -u: erreur si une variable non-définie est utilisée. + # -x: affiche les commandes exécutées sur la sortie d'erreur standard. + +tool=${0%/*} +. "$tool"/env.sh + +rule_help () { + cat >&2 <<-EOF + DESCRIPTION: ce script regroupe des fonctions utilitaires + pour gérer la VM des ateliers _depuis_ son hôte ; + il sert à la fois d'outil et de documentation. + Voir \`$tool/ateliers_hosted' pour les utilitaires côté VM hébergée. + SYNTAX: $0 \$RULE \${RULE}_SYNTAX + RULES: + $(sed -ne 's/^rule_\([^ ]*\) () {\( *#.*\|\)/\t\1\2/p' "$0") + ENVIRONMENT: + $(sed -ne 's/^readonly \([^ =]*\).*}\( *#.*\|\)$/\t$\1\2/p' "$tool"/env.sh "$0") + EOF + } + +readonly dev_disk="/dev/xvda" +readonly dev_disk_boot="${dev_disk}1" +readonly dev_disk_swap="${dev_disk}5" +readonly dev_disk_root="${dev_disk}6" +readonly dev_disk_var="${dev_disk}7" +readonly dev_disk_home="${dev_disk}8" + +rule_xen_config_init () { + tee /etc/xen/$vm_fqdn.cfg <<-EOF + # -*- mode: python; -*- + import os, re + name = "$vm" + arch = os.uname()[4] + memory = 2048 + vcpus = 1 + vif = ['mac=$vm_mac,bridge=$vm_bridge'] + disk = ['phy:/dev/domU/$vm_fqdn-disk,hda,w'] + kernel = "/usr/lib/xen-4.0/boot/hvmloader" + builder = 'hvm' + device_model = 'qemu-dm' + acpi = 1 + apic = 1 + # boot on floppy (a), hard disk (c) or CD-ROM (d) + #boot = 'd' + + #vnc = 1 + #sdl = 0 + #vncconsole = 0 + #vnclisten = "0.0.0.0" + #vncpasswd = "" + #usbdevice = 'tablet' + + keymap = 'fr' + serial = 'pty' + on_poweroff = 'destroy' + on_reboot = 'restart' + on_crash = 'restart' + EOF + } +rule_xen_on () { + sudo xm create $vm_fqdn.cfg + } +rule_xen_off () { + sudo xm shutdown $vm_fqdn.cfg + } + +rule_disk_mount () { + # Montage du disque de la VM depuis l'hôte + test ! -e $vm_dev_disk + sudo xm block-attach 0 phy:/dev/domU/$vm_fqdn-disk $vm_dev_disk w + } +rule_disk_unmount () { + # Démontage du disque de la VM depuis l'hôte + test -e $vm_dev_disk + ! mountpoint /mnt/$vm_fqdn + sudo xm block-detach 0 $vm_dev_disk + } +rule_disk_part () { + # Partitionage du disque de la VM + # NOTE: on fait le choix de ne pas utiliser LVM sur la machine virtuelle car : + # - pour l'extension de mémoire: + # 1. on créera une nouvelle partition sur le LVM de l'hôte + # 2. on l'ajoutera comme un disque supplémentaire dans /etc/xen/$vm_fqdn.cfg + # 3. on le montera sur /home2 en pensant à changer DHOME=/home2 dans /etc/adduser.conf + # - pour la sauvegarde: LVM snapshoot est trop + # 1. sauvegarde au niveau applicatif (pgdump, mysqldump) + # 2. sauvegarde des configurations (etckeeper, git) + # 3. sauvegarde incrémentale et chiffrée des autres fichiers (duplicity) + # NOTE: + sudo sfdisk -d $vm_dev_disk <<-EOF + # partition table of $vm_dev_disk + unit: sectors + + ${vm_dev_disk}1 : start= 63, size= 497952, Id=83, bootable + ${vm_dev_disk}2 : start= 498015, size=418927005, Id= 5 + ${vm_dev_disk}3 : start= 0, size= 0, Id= 0 + ${vm_dev_disk}4 : start= 0, size= 0, Id= 0 + ${vm_dev_disk}5 : start= 498078, size= 1959867, Id=82 + ${vm_dev_disk}6 : start= 2458008, size= 29302497, Id=83 + ${vm_dev_disk}7 : start= 31760568, size= 9767457, Id=83 + ${vm_dev_disk}8 : start= 41528088, size=377896932, Id=83 + EOF + } + +rule_boot_format () { + mount | grep -q "^$vm_dev_disk_boot " + sudo mkfs.ext2 -m 0 -T small -L "boot" $vm_dev_disk_boot + } +rule_boot_mount () { + ! mountpoint /mnt/$vm_fqdn/boot + sudo mount -v $vm_dev_disk_boot /mnt/$vm_fqdn/boot + } +rule_boot_unmount () { + mountpoint /mnt/$vm_fqdn/boot + sudo unmount -v /mnt/$vm_fqdn/boot + } + +rule_part_clean () { + # NOTE: long, optionnel + # Déjà fait à la main histoire de pouvoir créer la machine virtuelle plus + # rapidement le jour venu. + part=$1 + eval "sudo dd if=/dev/urandom of=\$vm_dev_disk_$part" + } +rule_part_clean_stat () { + # USE: exécuter cette fonction dans un shell distinct de rule_part_clean() + # lui fait afficher sa progression. + part=$1 + eval "pkill -USR1 -f \"^dd if=/dev/urandom of=\$vm_dev_disk_$part\"" + } +rule_part_format_root () { + # DECRIPTION: Formatage de / + part="root" + eval dev="\$vm_dev_disk_$part" + sudo cryptsetup luksFormat --hash=sha512 --key-size=512 --key-file=- \ + --cipher=aes-xts-essiv:sha256 --align-payload=8 $dev + sudo cryptsetup luksOpen --key-file=- $dev ${vm}_${part}_deciphered + sudo mkfs.ext4 -m 5 -T ext4 -L ${vm}_$part -E stripe_width=32,resize=15G \ + /dev/mapper/${vm}_${part}_deciphered + } +rule_format_part () { + # DESCRIPTION: formatage d'une partition distincte de / + # NOTE: la clef de chiffrement est dérivée de celle de /, + # / doit être déchiffrée pour que cela fonctionne. + part=$1 + eval dev="\$vm_dev_disk_$part" + test -e /dev/mapper/${vm}_root_deciphered + sudo /lib/cryptsetup/scripts/decrypt_derived ${vm}_root_deciphered | + sudo cryptsetup luksFormat --key-file=- --hash=sha512 --key-size=512 --cipher=aes-xts-essiv:sha256 $dev + } +rule_mount_part () { + part=$1 + eval dev="\$vm_dev_disk_$part" + test -e /dev/mapper/${vm}_root_deciphered + sudo /lib/cryptsetup/scripts/decrypt_derived ${vm}_root_deciphered | + sudo cryptsetup luksOpen --key-file=- $dev ${vm}_${part}_deciphered + } +rule_unmount_part () { + part=$1 + eval dev="\$vm_dev_disk_$part" + sudo cryptsetup luksClose ${vm}_${part}_deciphered + } +rule_part_format_swap () { + part="swap" + rule_format_part $part + rule_mount_part $part + sudo mkswap -f -L ${vm}_swap /dev/mapper/${vm}_${part}_deciphered + rule_unmount_part $part + } +rule_part_format_var () { + part="var" + rule_format_part $part + rule_mount_part $part + sudo mkfs.ext4 -m 5 -T ext4 -L ${vm}_$part -E stripe_width=32,resize=5G /dev/mapper/${vm}_${part}_deciphered + rule_unmount_part $part + } +rule_part_format_home () { + part="home" + rule_format_part $part + rule_mount_part $part + sudo mkfs.ext4 -m 5 -T ext4 -L ${vm}_$part -E stripe_width=32,resize=200G /dev/mapper/${vm}_${part}_deciphered + rule_unmount_part $part + } + +rule_install_debian () { + sudo DEBOOTSTRAP_DIR=/usr/share/debootstrap/ debootstrap \ + --arch=$vm_arch --verbose --keyring=/usr/share/keyrings/debian-archive-keyring.gpg \ + --exclude=vim-tiny \ + --include=$(printf '%s,' \ + acl \ + bsdmainutils \ + busybox \ + ca-certificates \ + console-setup \ + cryptsetup \ + dash \ + dnsutils \ + dropbear \ + etckeeper \ + hashalot \ + htop \ + ifupdown \ + initramfs-tools \ + kbd \ + less \ + ncurses-term \ + openssh-client \ + openssh-server \ + openssl \ + pciutils \ + procps \ + quota \ + quotatool \ + rsync \ + screen \ + sudo \ + sysprofile \ + vim-nox \ + wget \ + zsh \ + ) \ + $vm_lsb_name /mnt/$vm_fqdn/ http://ftp.fr.debian.org/debian/ + } +rule_chroot () { + mountpoint /mnt/$vm_fqdn + mountpoint /mnt/$vm_fqdn/boot + mount --bind /dev /mnt/$vm_fqdn/dev + sudo chroot /mnt/$vm_fqdn /bin/bash + umount /mnt/$vm_fqdn/dev + } + +rule=${1:-help} +${1+shift} +rule_$rule "$@" diff --git a/ateliers_hosted b/ateliers_hosted new file mode 100755 index 0000000..306bf2f --- /dev/null +++ b/ateliers_hosted @@ -0,0 +1,180 @@ +#!/bin/sh +set -e -f ${DRY_RUN:+-n} -u ${TRACE:+-x} +tool=${0%/*} +. "$tool"/env.sh +. "$tool"/inc.sh + +rule_help () { + cat >&2 <<-EOF + DESCRIPTION: ce script regroupe des fonctions utilitaires + pour gérer la VM des ateliers _depuis_ la VM hébergée ; + il sert à la fois d'outil et de documentation. + Voir \`$tool/ateliers_host' pour les utilitaires côté machine hôte. + SYNTAX: $0 \$RULE \${RULE}_SYNTAX + RULES: + $(sed -ne 's/^rule_\([^ ]*\) () {\( *#.*\|\)/\t\1\2/p' "$0") + ENVIRONMENT: + $(sed -ne 's/^readonly \([^ =]*\).*}\( *#.*\|\)$/\t$\1\2/p' "$tool"/env.sh "$0") + EOF + } + +rule_filesystem_mount () { + mountpoint /proc || + mount -t proc proc /proc + mountpoint /sys || + mount -t sysfs sys /sys + mountpoint /dev + } +rule_filesystem_unmount () { + ! mountpoint /proc || + umount /proc + ! mountpoint /sys || + umount /sys + } +rule_shell_source () { + . /etc/profile + } +rule_network_init () { + mk_reg mod= own= /etc/hostname <<-EOF + $vm + EOF + grep -q " $vm\$" /etc/hosts || + mk_reg mod= own= --append /etc/hosts <<-EOF + 127.0.0.1 $vm.local $vm + EOF + mk_reg mod= own= /etc/network/interfaces <<-EOF + auto lo + iface lo inet loopback + + auto eth0=grenode + iface grenode inet static + address $vm_ipv4 + gateway $vm_ipv4 # NOTE: proxy_arp sur la passerelle permet d'utiliser la même adresse + network $vm_ipv4 + broadcast $vm_ipv4 + netmask 255.255.255.255 + mtu 1300 # TODO: voir si c'est nécessaire à Lyon + up ip address add $vm_ipv4/32 dev \$IFACE + down ip address delete $vm_ipv4/32 dev \$IFACE + EOF + } +rule_apt_init () { + mk_reg mod= own= /etc/apt/sources.list <<-EOF + deb http://ftp.fr.debian.org/debian $vm_lsb_name main contrib non-free + EOF + mk_reg mod= own= /etc/apt/sources.list.d/openerp.list <<-EOF + deb http://nightly.openerp.com/trunk/nightly/deb/ ./ + EOF + mk_reg mod= own= /etc/apt/sources.list.d/$vm_lsb_name-backports.list <<-EOF + deb http://backports.debian.org/debian-backports $vm_lsb_name-backports main contrib non-free + EOF + mk_reg mod= own= /etc/apt/preferences <<-EOF + Package: * + Pin: release a=$vm_lsb_name + Pin-Priority: 170 + + Package: * + Pin: release a=$vm_lsb_name-backports + Pin-Priority: 200 + EOF + } +rule_boot_init () { + mk_reg mod= own= /etc/fstab <<-EOF + # + LABEL=boot /boot ext2 defaults,no-auto 0 0 + proc /proc proc defaults 0 0 + sysfs /sys sysfs defaults 0 0 + tmpfs /tmp tmpfs rw,nosuid,nodev,auto,size=200m,nr_inodes=1000k,mode=1777,noatime,nodiratime 0 0 + /dev/mapper/${vm}_root_deciphered / ext4 defaults,errors=remount-ro,acl,noatime 0 1 + /dev/mapper/${vm}_var_deciphered /var ext4 defaults,errors=remount-ro,acl,noatime 0 1 + /dev/mapper/${vm}_home_deciphered /home ext4 defaults,errors=remount-ro,acl,noatime,usrquota,grpquota 0 0 + /dev/mapper/${vm}_swap_deciphered swap swap sw 0 0 + EOF + mk_reg mod= own= /etc/crypttab <<-EOF + # + ${vm}_root_deciphered LABEL=${vm}_root ${vm}_root luks + ${vm}_var_deciphered LABEL=${vm}_var ${vm}_root_deciphered luks,keyscript=/lib/cryptsetup/scripts/decrypt_derived + ${vm}_swap_deciphered LABEL=${vm}_swap ${vm}_root_deciphered luks,keyscript=/lib/cryptsetup/scripts/decrypt_derived + ${vm}_home_deciphered LABEL=${vm}_home ${vm}_root_deciphered luks,keyscript=/lib/cryptsetup/scripts/decrypt_derived + EOF + mk_reg mod= own= /etc/initramfs-tools/modules <<-EOF + #loop + sha1_generic + sha256_generic + sha512_generic + aes-x86_64 + xts + EOF + sed -i /etc/default/grub -e '/^GRUB_CMDLINE_LINUX=/d;r/dev/fd/3' 3<<-EOF + GRUB_CMDLINE_LINUX="vt.default_utf8=1 rootfstype=ext4 loglevel=5 console=hvc0 resume=/dev/mapper/${vm}_swap_deciphered" + EOF + } +rule_user_admin_add () { # SYNTAX: + admin=$1 + ! id "$admin" || adduser "$admin" + eval home="~$admin" + adduser "$admin" sudo + mk_dir mod=0750 own="$admin:$admin" "$home"/etc + mk_dir mod=0700 own="$admin:$admin" "$home"/etc/ssh + mk_reg mod=0400 own="$admin:$admin" "$home"/etc/ssh/authorized_keys <"$tool"/key/"$admin".ssh.pub + } +rule_users_init () { + mk_reg mod=0664 own=root:root /etc/ssh/sshd_config <<-EOF + ListenAddress $vm_ipv4 + #ListenAddress :: + Port 22 + Protocol 2 + Compression yes + HostKey /etc/ssh/ssh_host_rsa_key + UsePrivilegeSeparation yes + KeyRegenerationInterval 3600 + ServerKeyBits 768 + SyslogFacility AUTH + LogLevel INFO + LoginGraceTime 120 + PermitRootLogin no + StrictModes yes + RSAAuthentication yes + PubkeyAuthentication yes + AuthorizedKeysFile %h/etc/ssh/authorized_keys + IgnoreRhosts yes + RhostsRSAAuthentication no + HostbasedAuthentication no + IgnoreUserKnownHosts no + PermitEmptyPasswords no + ChallengeResponseAuthentication no + PasswordAuthentication no + KerberosAuthentication no + GSSAPIAuthentication no + X11Forwarding no + X11DisplayOffset 10 + PrintMotd no + DebianBanner no + PrintLastLog yes + TCPKeepAlive yes + ClientAliveInterval 0 + AcceptEnv LANG LC_* + Subsystem sftp /usr/lib/openssh/sftp-server + UsePAM yes + EOF + mk_reg mod=0440 own=root:root /etc/sudoers.d/passwd-init <<-EOF + %sudo ALL=(ALL) NOPASSWD: /bin/sh -e -f -u -c \ + case \$(/usr/bin/passwd --status "\$SUDO_USER") in \ + ("\$SUDO_USER L "*) /usr/bin/passwd \$SUDO_USER;; esac + EOF + mk_reg mod=0440 own=root:root /etc/sudoers.d/etckeeper-unclean <<-EOF + %sudo ALL=(ALL) NOPASSWD: /usr/sbin/etckeeper unclean + EOF + mk_reg mod=0555 own=root:root /usr/local/sbin/passwd-init <<-EOF + #!/bin/sh + sudo /bin/sh -e -f -u -c \ + 'case \$(/usr/bin/passwd --status "\$SUDO_USER") in ("\$SUDO_USER L "*) /usr/bin/passwd \$SUDO_USER;; esac' + EOF + } +rule_kernel_init () { + sudo apt-get install --reinstall linux-image-$vm_arch + } + +rule=${1:-help} +${1+shift} +rule_$rule "$@" diff --git a/env.sh b/env.sh new file mode 100644 index 0000000..10705fc --- /dev/null +++ b/env.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# DESCRIPTION: ce fichier regroupe les variables propres à la VM + +readonly PATH=$PATH:/usr/sbin:/sbin +readonly vm="ateliers" +readonly vm_arch="amd64" +readonly vm_bridge="br-gresille" +readonly vm_fqdn="$vm.heureux-cyclage.org" +readonly vm_ipv4="91.216.110.42" # NOTE: IPv4 publique assignée par Grésille +readonly vm_lsb_name="wheezy" +readonly vm_mac="00:16:3E:E5:98:42" # NOTE: addresse MAC assignée par Grésille + # NOTE: on part sur wheezy dès le début + # dans l'idée de ne pas s'embêter avec + # une migration squeeze -> wheezy dans deux mois ; + # et parce qu'on juge wheezy « suffisamment stable ». diff --git a/inc.sh b/inc.sh new file mode 100644 index 0000000..757fbcb --- /dev/null +++ b/inc.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# DESCRIPTION: ce fichier regroupe des utilitaires très génériques + +mk_dir () { + local mod=${1#mod=}; shift + local own=${1#own=}; shift + mkdir -p "$@" + ! [ ${mod:+set} ] || sudo chmod $mod "$@" + ! [ ${own:+set} ] || sudo chown $own "$@" + } +mk_reg () { + local mod=${1#mod=}; shift + local own=${1#own=}; shift + tee >/dev/null "$@" + ! [ ${mod:+set} ] || sudo chmod $mod "$@" + ! [ ${own:+set} ] || sudo chown $own "$@" + } diff --git a/key/julm.ssh.pub b/key/julm.ssh.pub new file mode 100644 index 0000000..07774a5 --- /dev/null +++ b/key/julm.ssh.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD5FtR++UPEg/5wFeyb2JSS09idTaDb4tMIRf1yxCsyIJEp5LQMif/fIptDeHoYc55lwy8vnWWN9PJpb6PS8YSaLLFV5tn8esR8Ml+evNCAD52Tdu1kPRXGLCSF5kSVnbAMoxqiNi8vRRKXwAzGgXmIUzDAE4QTsq3EwZM6cBnDx5O79wBIZ9va2TObL52qv+Vpi+QyINuslKKc+Osu92pdwceIGZUcwA6Y8aH6lavaTyDUQdSjMRMTAiXSPRjmHf1q+V7wENXT/TKXuuahN8NnJShX3Qf9hwNEIU46SOENsrRFQ5eYahAmqUIK4GbsERS2KRDxbvSOl7rKh2sauBxyKfkW/gxQ4LAyywxuumpI0pO7XmdINCGWdXS9gD216lcGuH/TC0KboiOVExh65eRIOeEFTec0VJQEqqnFul7u8YNPmbBpLnM+SQ3TAkdQmfasKgPIazFNCAnC8I9hKlGYpLk/Dgi/sVbwFeoOUQcaTBRnWKUCedX4v4kmPIHuHSNPV2C/0770gH2iJ1N1XEO3YDGiixuHHiLlCV8Ko950CoTh1PwDNCd3Qy/jR/QhE2waVPliFwl2+H6IkIxkUO8A9ktLCJUeaZJN3snoV+9hvpT1E2TrEccsTVx5BaGAJCUkvO2XYlEsNceIIitkrbhidjZvfZ4/czGUKoN1wSSpMw== GnuPG pub=F2E027182397AC0775714F2AD15AF7F467E8299B sub=7819E44BAEEDE91683811BB00E1AAADBE227DDAA Julien Moutinho