#!/bin/sh set -e -f ${DRY_RUN:+-n} -u tool=$0 while test -L "$tool" do tool=$(readlink "$tool") done tool=${tool%/*} . "$tool"/lib/rule.sh . "$tool"/etc/vm.sh export TRACE=1 rule_help () { # SYNTAX: [--hidden] local hidden; [ ${1:+set} ] || hidden=set cat >&2 <<-EOF DESCRIPTION: ce script regroupe des règles pour administrer la VM ($vm_fqdn) _depuis_ la VM hébergée ($vm_fqdn) ; il sert à la fois d'outil (aisément bidouillable) et de documentation (préçise). Voir \`$tool/vm_host' pour les règles côté machine hôte ($vm_host). SYNTAX: $0 \$RULE \${RULE}_SYNTAX RULES: $(sed -ne "s/^rule_\(${hidden:+[^_]}[^ ]*\) () {\( *#.*\|\)/ \1\2/p" "$tool"/etc/vm.sh "$0") ENVIRONMENT: TRACE # affiche les commandes avant leur exécution $(sed -ne 's/^readonly \([^ ][^ =]*\).*}\( *#.*\|\)$/\t$\1\2/p' "$tool"/etc/vm.sh "$0") EOF } rule_git_configure () { ( cd "$tool" git config --replace branch.master.remote . git config --replace branch.master.merge refs/remotes/master local tool tool=$(cd "$tool"; cd -) install -m 770 /dev/stdin .git/hooks/post-update <<-EOF #!/bin/sh -efux case \$1 in (refs/remotes/master) cd .. git --git-dir=\$PWD/.git checkout -f -B master remotes/master git --git-dir=\$PWD/.git clean -f -d -x ;; esac EOF ) } rule_git_reset () { ( cd "$tool" git checkout -f -B master remotes/master git clean -f -d -x ) } rule_adduser () { local user="$1"; shift getent passwd "$user" >/dev/null || sudo adduser "$@" "$user" } rule_apt_get_install () { # SYNTAX: $package sudo DEBIAN_FRONTEND=noninteractive apt-get install --yes "$@" } rule_dpkg_reconfigure () { # SYNTAX: $package sudo DEBIAN_FRONTEND=noninteractive dpkg-reconfigure "$@" } rule__chrooted_configure () { # NOTE: est-ce bien utile à un moment ? export LANG=C export LC_CTYPE=C . /etc/profile } rule_apache2_configure () { # XXX: cette règle n'est pas testée/mise-à-jour local -; set +f rule apt_get_install \ apache2-mpm-itk \ libapache2-mod-php5 # VOIR: http://serverfault.com/questions/383526/how-do-i-select-which-apache-mpm-to-use/383634#383634 # VOIR: http://jkroon.blogs.uls.co.za/it/security/using-php-fpm-and-mod_proxy_fcgi-to-optimize-and-secure-lamp-servers # NOTE: apache2-mpm-itk semble le plus sécurisé, # car on est certain que tout est exécuté avec les uid/gid # assignés au VirtualHost/Directory/Location # néamoins il se peut qu'une combinaison du genre : # apache2-mpm-{worker,event} + mod_proxy_fcgi + apache2-suexec-custom + php-fpm # soit plus performante (threads et pas forks), # cependant l'usage de suexec impose des forks il semble.. # et mod_proxy_fcgi n'apparaît que dans apache 2.4 ; # donc pour l'instant : apache2-mpm-itk sudo rm -rf \ /etc/apache2/site.d sudo install -d -m 770 -o www -g www \ /etc/apache2 \ /etc/apache2/site.d \ /etc/apache2/x509.d cat /dev/stdin "$tool"/etc/apache2/apache2.conf <<-EOF | ServerName "$vm_fqdn" EOF sudo install -m 660 -o root -g root /dev/stdin \ /etc/apache2/apache2.conf sudo install -m 660 -o root -g root \ "$tool"/etc/apache2/envvars \ /etc/apache2/envvars sudo install -m 660 -o root -g root \ "$tool"/etc/apache2/httpd.conf \ /etc/apache2/httpd.conf #sudo install -m 660 -o root -g root /dev/stdin \ # /etc/apache2/suexec/www-data <<-EOF # /home # pub/www/cgi # EOF sudo install -m 660 -o root -g root \ "$tool"/etc/apache2/ports.conf \ /etc/apache2/ports.conf sudo a2enmod actions sudo a2enmod headers sudo a2enmod rewrite sudo a2enmod ssl sudo a2enmod userdir local conf sudo a2dissite "*" sudo ln -fns \ /etc/apache2 \ /home/www/etc/apache2 for conf in "$tool"/etc/apache2/site.d/*/VirtualHost.conf do conf=${conf#"$tool"/etc/apache2/site.d/} local site=${conf%/VirtualHost.conf} case $site in (*-tls) local hint="run vm_remote apache2_key_send before" assert "sudo test -f /etc/apache2/site.d/\"$site\"/x509/key.pem" hint sudo install -d -m 770 -o www-"$site" -g www-"$site" \ /etc/apache2 \ /etc/apache2/site.d/"$site" \ /etc/apache2/x509.d/"$site" \ /etc/apache2/x509.d/"$site"/ca \ /etc/apache2/x509.d/"$site"/empty \ /etc/apache2/x509.d/"$site"/rvk \ /etc/apache2/x509.d/"$site"/usr sudo install -m 664 -o www -g www \ "$tool"/var/pub/x509/"$site"/crt.self-signed.pem \ /etc/apache2/x509.d/"$site"/crt.self-signed.pem #sudo install -m 664 -o www-"$site" -g www-"$site" \ # "$tool"/var/pub/x509/"$site"/rvk.pem \ # /etc/apache2/x509.d/"$site"/rvk.pem sudo install -m 664 -o www -g www \ "$tool"/var/pub/x509/"$site"/ca/crt.self-signed.pem \ /etc/apache2/x509.d/"$site"/ca/crt.pem sudo install -m 664 -o www -g www \ "$tool"/var/pub/x509/"$site"/crt.pem \ /etc/apache2/x509.d/"$site"/crt.pem ;; esac case $site in (*-tls) cat <<-EOF AssignUserID www-$site www-$site BrowserMatch "MSIE [2-6]" ssl-unclean-shutdown nokeepalive downgrade-1.0 force-response-1.0 BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown CustomLog "|/usr/sbin/rotatelogs /home/www/log/$site/apache2/access/%Y-%m-%d.log 86400 60" Combined #CustomLog "/dev/null" Combined DocumentRoot /home/www/pub/$site ErrorLog "|/usr/sbin/rotatelogs /home/www/log/$site/apache2/error/%Y-%m-%d.log 86400 60" #ErrorLog "/dev/null" LogLevel Warn SSLCACertificateFile /etc/apache2/x509.d/$site/crt.self-signed.pem SSLCACertificatePath /etc/apache2/x509.d/$site/usr/ #SSLCARevocationFile /etc/apache2/x509.d/$site/rvk.pem SSLCADNRequestFile /etc/apache2/x509.d/$site/crt.self-signed.pem SSLCADNRequestPath /etc/apache2/x509.d/$site/empty/ # NOTE: ne publie pas les certificats d’utilisateur-ice-s acceptés SSLCARevocationPath /etc/apache2/x509.d/$site/rvk/ SSLCertificateChainFile /etc/apache2/x509.d/$site/ca/crt.pem SSLCertificateFile /etc/apache2/x509.d/$site/crt.pem SSLCertificateKeyFile /etc/apache2/x509.d/$site/key.pem SSLCipherSuite AES+RSA+SHA256 SSLEngine On SSLInsecureRenegotiation Off SSLOptions +StrictRequire +OptRenegotiate +StdEnvVars SSLProtocol -All +TLSv1 #SSLRenegBufferSize 262144 SSLSessionCacheTimeout 1200 SSLStrictSNIVHostCheck On SSLUserName SSL_CLIENT_S_DN_CN SSLVerifyClient None SSLVerifyDepth 1 $(cat "$tool"/etc/apache2/site.d/"$site"/VirtualHost.conf) EOF ;; (*) cat <<-EOF AssignUserID www-$site www-$site CustomLog "|/usr/sbin/rotatelogs /home/www/log/$site/apache2/access/%Y-%m-%d.log 86400 60" Combined #CustomLog "/dev/null" Combined DocumentRoot /home/www/pub/$site ErrorLog "|/usr/sbin/rotatelogs /home/www/log/$site/apache2/error/%Y-%m-%d.log 86400 60" #ErrorLog "/dev/null" LogLevel Warn $(cat "$tool"/etc/apache2/site.d/"$site"/VirtualHost.conf) EOF ;; esac | sudo install -m 660 -o root -g root /dev/stdin \ /etc/apache2/site.d/"$site"/VirtualHost.conf sudo ln -fns \ ../site.d/"$site"/VirtualHost.conf \ /etc/apache2/sites-available/"$site" sudo install -d -m 770 -o www-"$site" -g www-"$site" \ /home/www/log/"$site" \ /home/www/log/"$site"/apache2 sudo ln -fns \ /etc/apache2/site.d/"$site" \ /home/www/etc/apache2/"$site" test -e /home/www/pub/"$site" || sudo install -d -m 2770 -o www-"$site" -g www-"$site" \ /home/www/pub/"$site" rule adduser www-"$site" --disabled-password \ --group \ --no-create-home \ --home /home/www/pub/"$site" \ --shell /bin/false \ --system #sudo setfacl -m u:"www-$site":--x \ # /home/www/ \ # /home/www/pub/ \ # /home/www/pub/"$site"/ #sudo setfacl -m d:u:"www-$site":rwx \ # "$home"/pub/www/"$site"/ test ! -r "$tool"/etc/apache2/site.d/"$site"/configure.sh || . "$tool"/etc/apache2/site.d/"$site"/configure.sh test -e /etc/apache2/sites-enabled/"$site" || sudo a2ensite "$site" done sudo service apache2 restart } rule_apt_configure () { sudo install -m 660 -o root -g root /dev/stdin /etc/apt/sources.list <<-EOF deb http://ftp.rezopole.net/debian $vm_lsb_name main EOF sudo install -m 660 -o root -g root /dev/stdin /etc/apt/sources.list.d/$vm_lsb_name-backports.list <<-EOF deb http://ftp.rezopole.net/debian $vm_lsb_name-backports main EOF sudo install -m 660 -o root -g root /dev/stdin /etc/apt/preferences <<-EOF Package: * Pin: release a=$vm_lsb_name Pin-Priority: 200 Package: * Pin: release a=$vm_lsb_name-backports Pin-Priority: 170 EOF sudo apt-get update rule apt_get_install apticron sudo install -m 644 -o root -g root /dev/stdin /etc/apticron/apticron.conf <<-EOF EMAIL="admin@$vm_domainname" # DIFF_ONLY="1" # LISTCHANGES_PROFILE="apticron" # ALL_FQDNS="1" # SYSTEM="foobar.example.com" # IPADDRESSNUM="1" # IPADDRESSES="192.0.2.1 2001:db8:1:2:3::1" # NOTIFY_HOLDS="0" # NOTIFY_NEW="0" # NOTIFY_NO_UPDATES="0" # CUSTOM_SUBJECT="" # CUSTOM_NO_UPDATES_SUBJECT="" # CUSTOM_FROM="root@$vm_fqdn" EOF } rule_boot_configure () { #warn "lors de l'installation Debian, surtout n'installer GRUB sur AUCUN disque proposé !" sudo debconf-set-selections <<-EOF grub-pc grub-pc/install_devices multiselect EOF rule apt_get_install grub-pc sudo install -d -m 644 -o root -g root /boot/grub rule apt_get_install linux-image-$vm_arch sudo install -m 644 -o root -g root /dev/stdin /etc/default/grub <<-EOF GRUB_DEFAULT=0 GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR=\`lsb_release -i -s 2> /dev/null || echo Debian\` GRUB_CMDLINE_LINUX_DEFAULT="quiet" GRUB_CMDLINE_LINUX="vt.default_utf8=1 rootfstype=ext4 loglevel=5 console=hvc0 ip=$vm_ipv4::$vm_ipv4:255.255.255.254:$vm:eth0:off resume=/dev/mapper/${vm}_swap_deciphered" GRUB_DISABLE_RECOVERY="true" #GRUB_PRELOAD_MODULES="lvm" EOF sudo install -m 644 -o root -g root /dev/stdin /boot/grub/device.map <<-EOF (hd0) /dev/xvda (hd0) /dev/mapper/domU-$(printf %s $vm_fqdn-disk | sed -e 's/-/--/g') EOF sudo update-grub2 # NOTE: prend en compte /boot/grub/device.map rule initramfs_configure rule apt_get_install molly-guard sudo install -m 644 -o root -g root /dev/stdin /etc/molly-guard/rc <<-EOF ALWAYS_QUERY_HOSTNAME=true # NOTE: une alternative est de dire à sudo de conserver les SSH_* # néamoins demander tout le temps n'est pas trop contraignant # et davantage sécurisant. EOF } rule_dovecot_configure () { rule apt_get_install dovecot-imapd dovecot-managesieved dovecot-sieve local hint="run vm_remote dovecot_key_send before" assert "sudo test -f /etc/dovecot/\"$vm_domainname\"/imap/x509/key.pem" hint sudo install -m 400 -o root -g root \ "$tool"/var/pub/x509/imap."$vm_domainname"/crt+crl.self-signed.pem \ /etc/dovecot/"$vm_domainname"/imap/x509/crt+crl.self-signed.pem sudo install -d -m 770 -o root -g root \ /etc/skel/etc/mail \ /etc/skel/etc/sieve sudo install -d -m 1777 -o root -g root \ /var/lib/dovecot-control \ /var/lib/dovecot-index sudo install -m 664 -o root -g root /dev/stdin /etc/dovecot/local.conf <<-EOF auth_ssl_username_from_cert = yes listen = * log_timestamp = "%Y-%m-%d %H:%M:%S " mail_debug = yes mail_location = maildir:~/var/mail:INDEX=/var/lib/dovecot-index/%u:CONTROL=/var/lib/dovecot-control/%u # NOTE: INDEX et CONTROL sont sur une partition sans quota comme le demande la doc # VOIR: http://wiki2.dovecot.org/Quota/FS mail_plugins = \$mail_plugins quota mail_privileged_group = mail passdb { args = /home/%u/etc/dovecot/passwd driver = passwd-file } plugin { quota = fs:user recipient_delimiter = + sieve = ~/etc/mail/filter.sieve sieve_dir = ~/etc/mail/sieve sieve_global_dir = /var/lib/dovecot/sieve/global/ sieve_max_script_size = 1M sieve_quota_max_scripts = 0 sieve_quota_max_storage = 10M sieve_user_log = ~/var/log/mail/sieve.log } protocol imap { mail_plugins = \$mail_plugins imap_quota } protocol lda { auth_socket_path = /var/run/dovecot/auth-master hostname = $vm_domainname info_log_path = log_path = mail_plugins = \$mail_plugins sieve postmaster_address = contact+dovecot+lda@$vm_domainname syslog_facility = mail } protocols = imap sieve service auth { user = root unix_listener /var/spool/postfix/private/auth { mode = 0660 user = postfix group = postfix } } ssl_ca = LABEL=${vm_lvm_lv}_boot /boot ext2 defaults 0 0 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 /dev/mapper/${vm_lvm_lv}_root_deciphered / ext4 defaults,errors=remount-ro,acl,barrier=1,noatime 0 1 /dev/mapper/${vm_lvm_lv}_var_deciphered /var ext4 defaults,errors=remount-ro,acl,barrier=1,noatime 0 1 /dev/mapper/${vm_lvm_lv}_home_deciphered /home ext4 defaults,errors=remount-ro,acl,barrier=1,noatime,usrquota,grpquota 0 0 # NOTE: barrier=1 réduit drastiquement les performances d'écriture, mais garantit la cohérence du système de fichiers. /dev/mapper/${vm_lvm_lv}_swap_deciphered swap swap sw 0 0 EOF sudo install -m 644 -o root -g root /dev/stdin /etc/crypttab <<-EOF # ${vm_lvm_lv}_root_deciphered /dev/$vm_lvm_vg/${vm_lvm_lv}_root none luks,lvm=$vm_lvm_vg ${vm_lvm_lv}_var_deciphered /dev/$vm_lvm_vg/${vm_lvm_lv}_var ${vm_lvm_lv}_root_deciphered luks,lvm=$vm_lvm_vg,keyscript=/lib/cryptsetup/scripts/decrypt_derived ${vm_lvm_lv}_home_deciphered /dev/$vm_lvm_vg/${vm_lvm_lv}_home ${vm_lvm_lv}_root_deciphered luks,lvm=$vm_lvm_vg,keyscript=/lib/cryptsetup/scripts/decrypt_derived ${vm_lvm_lv}_swap_deciphered /dev/$vm_lvm_vg/${vm_lvm_lv}_swap ${vm_lvm_lv}_root_deciphered luks,lvm=$vm_lvm_vg,keyscript=/lib/cryptsetup/scripts/decrypt_derived EOF rule tmpfs_configure } rule_initramfs_configure () { sudo install -m 644 -o root -g root /dev/stdin /etc/initramfs-tools/initramfs.conf <<-EOF MODULES=most BUSYBOX=y KEYMAP=y COMPRESS=gzip DEVICE=eth0 EOF sudo install -m 644 -o root -g root /dev/stdin /etc/modprobe.d/xen-pv.conf <<-EOF alias eth0 xennet alias scsi_hostadapter xenblk EOF sudo install -m 644 -o root -g root /dev/stdin /etc/modules <<-EOF sha1_generic sha256_generic sha512_generic aes-x86_64 xts # NOTE: pour Xen en mode HVM : #modprobe xen-platform-pci EOF sudo install -m 644 -o root -g root /dev/stdin /etc/initramfs-tools/modules <<-EOF EOF sudo sed -e '/^configure_networking /s/ &$//' \ -i /usr/share/initramfs-tools/scripts/init-premount/dropbear # NOTE: corrige une vermine : dropbear doit attendre que le réseau soit configuré.. ssh-keygen -F "init.$vm_fqdn" -f "$tool"/etc/openssh/known_hosts | ( while IFS= read -r line do case $line in (*" RSA") return 0; break;; esac done; return 1 ) || { sudo rm -f \ /etc/initramfs-tools/etc/dropbear/dropbear_rsa_host_key \ /etc/initramfs-tools/etc/dropbear/dropbear_rsa_host_key.pub sudo dropbearkey -t rsa -s 4096 -f \ /etc/initramfs-tools/etc/dropbear/dropbear_rsa_host_key } # NOTE: ne se préoccupe pas de dropbear_dss_host_key ; Debian la génère et l'utilise néamoins. sudo install -d -m 640 -o root -g root \ /etc/initramfs-tools/root \ /etc/initramfs-tools/root/.ssh getent group sudo | while IFS=: read -r group x x users do while test -n "$users" && IFS=, read -r user users <<-EOF $users EOF do eval local home\; home="~$user" sudo cat "$home"/etc/ssh/authorized_keys done done | sudo install -m 644 -o root -g root /dev/stdin \ /etc/initramfs-tools/root/.ssh/authorized_keys sudo rm -f \ /etc/initramfs-tools/root/.ssh/id_rsa.dropbear \ /etc/initramfs-tools/root/.ssh/id_rsa.pub \ /etc/initramfs-tools/root/.ssh/id_rsa # NOTE: clefs générées par Debian sudo update-initramfs -u } rule_gitolite_configure () { sudo debconf-set-selections <<-EOF gitolite gitolite/gituser string git gitolite gitolite/adminkey string gitolite gitolite/gitdir string /home/git EOF rule apt_get_install gitolite rule adduser git \ --disabled-password \ --group \ --home /home/git \ --shell /bin/bash \ --system sudo chfn --full-name git git rule adduser log-git \ --disabled-login \ --disabled-password \ --group \ --home /home/git/log \ --shell /bin/false \ --system rule adduser git-data \ --disabled-login \ --disabled-password \ --group \ --home /home/git/pub \ --shell /bin/false \ --system sudo adduser git git-data sudo install -d -m 770 -o git -g git \ /etc/gitolite \ /home/git/etc \ /home/git/etc/ssh sudo install -d -m 751 -o git -g git \ /home/git sudo install -d -m 2770 -o git-data -g git-data \ /home/git/pub sudo install -d -m 1771 -o git -g git \ /home/git/log sudo install -d -m 2770 -o git -g log-git \ /home/git/log/gitolite \ /home/git/log/gitolite/perf sudo install -d -m 3771 -o git -g git \ /home/git/hooks sudo ln -fns /etc/gitolite /home/git/etc/gitolite sudo ln -fns /etc/gitweb /home/git/etc/gitweb sudo ln -fns etc/gitolite/gitolite.rc /home/git/.gitolite.rc sudo ln -fns etc/ssh /home/git/.ssh sudo install -m 770 -o git -g git /dev/stdin \ /home/git/etc/gitolite/gitolite.rc <<-EOF #\$ADMIN_POST_UPDATE_CHAINS_TO = "hooks/post-update.secondary"; #\$BIG_INFO_CAP = 20; #\$ENV{GL_SLAVES} = 'gitolite@server2 gitolite@server3'; # NOTE: Please use single quotes, not double quotes. #\$GITWEB_URI_ESCAPE = 0; \$GIT_PATH = ""; #\$GL_ADC_PATH = ""; \$GL_ADMINDIR = \$ENV{HOME} . "/etc/gitolite"; #\$GL_ALL_INCLUDES_SPECIAL = 0; #\$GL_ALL_READ_ALL = 0; \$GL_BIG_CONFIG = 0; \$GL_CONF = "\$GL_ADMINDIR/conf/gitolite.conf"; \$GL_CONF_COMPILED = "\$GL_ADMINDIR/conf/gitolite.conf.pm"; #\$GL_GET_MEMBERSHIPS_PGM = "/usr/local/bin/expand-ldap-user-to-groups" \$GL_GITCONFIG_KEYS = "gitweb\\..* hooks\\..*"; #\$GL_HOSTNAME = "git.$vm_domainname"; # NOTE: read doc/mirroring.mkd COMPLETELY before setting this. #\$GL_HTTP_ANON_USER = "mob"; \$GL_KEYDIR = "\$GL_ADMINDIR/keydir"; \$GL_LOGT = \$ENV{HOME} . "/log/gitolite/%y-%m-%d.log"; #\$GL_NICE_VALUE = 0; \$GL_NO_CREATE_REPOS = 0; \$GL_NO_DAEMON_NO_GITWEB = 0; \$GL_NO_SETUP_AUTHKEYS = 0; \$GL_PACKAGE_CONF = "/usr/share/gitolite/conf"; \$GL_PACKAGE_HOOKS = "/usr/share/gitolite/hooks"; #\$GL_PERFLOGT = \$ENV{HOME} . "/log/gitolite/perf/%y-%m-%d.log"; #\$GL_REF_OR_FILENAME_PATT = qr(^[0-9a-zA-Z][0-9a-zA-Z._\\@/+ :,-]*\$); \$GL_SITE_INFO = "git.$vm_domainname"; #\$GL_SLAVE_MODE = 0; \$GL_WILDREPOS = 0; #\$GL_WILDREPOS_DEFPERMS = 'R @all'; \$GL_WILDREPOS_PERM_CATS = "READERS WRITERS"; \$HTPASSWD_FILE = ""; \$PROJECTS_LIST = \$ENV{HOME} . "/etc/gitweb/projects.list"; \$REPO_BASE = "pub"; \$REPO_UMASK = 0007; \$RSYNC_BASE = ""; \$SVNSERVE = ""; #\$UPDATE_CHAINS_TO = "hooks/update.secondary"; \$WEB_INTERFACE = "gitweb"; 1; EOF sudo install -m 600 -o git -g git \ "$tool"/var/pub/ssh/git.key \ /home/git/etc/ssh/git.pub sudo -u git \ GL_RC=/home/git/etc/gitolite/gitolite.rc \ GIT_AUTHOR_NAME=git \ gl-setup -q /home/git/etc/ssh/git.pub git local d for d in doc logs src do test ! -d /home/git/etc/gitolite/"$d" || rmdir /home/git/etc/gitolite/"$d" done sudo service tmpfs restart } rule_locales_configure () { sudo debconf-set-selections <<-EOF locales locales/default_environment_locale select None locales locales/locales_to_be_generated multiselect fr_FR.UTF-8 UTF-8 EOF rule dpkg_reconfigure locales } rule_login_configure () { sudo install -m 644 -o root -g root /dev/stdin /etc/inittab <<-EOF # /etc/inittab: init(8) configuration. # The default runlevel. id:2:initdefault: # Boot-time system configuration/initialization script. # This is run first except when booting in emergency (-b) mode. si::sysinit:/etc/init.d/rcS # What to do in single-user mode. ~~:S:wait:/sbin/sulogin # /etc/init.d executes the S and K scripts upon change # of runlevel. # # Runlevel 0 is halt. # Runlevel 1 is single-user. # Runlevels 2-5 are multi-user. # Runlevel 6 is reboot. l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # Normally not reached, but fallthrough in case of emergency. z6:6:respawn:/sbin/sulogin # What to do when CTRL-ALT-DEL is pressed. ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now # What to do when the power fails/returns. pf::powerwait:/etc/init.d/powerfail start pn::powerfailnow:/etc/init.d/powerfail now po::powerokwait:/etc/init.d/powerfail stop # Xen hypervisor console hvc:2345:respawn:/sbin/getty 38400 hvc0 #xvc:2345:respawn:/sbin/getty 38400 xvc0 #-- runit begin SV:123456:respawn:/usr/sbin/runsvdir-start #-- runit end EOF sudo install -m 644 -o root -g root /dev/stdin /etc/login.defs <<-EOF MAIL_DIR /var/mail FAILLOG_ENAB yes LOG_UNKFAIL_ENAB no LOG_OK_LOGINS no SYSLOG_SU_ENAB yes SYSLOG_SG_ENAB yes FTMP_FILE /var/log/btmp SU_NAME su HUSHLOGIN_FILE .hushlogin ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # NOTE: met les sbin/ dans ENV_PATH ; # - ça n'apporte aucune protection de ne pas les mettre ; # - ça frustre de ne pas les trouver. TTYGROUP tty TTYPERM 0600 ERASECHAR 0177 KILLCHAR 025 UMASK 007 # NOTE: rwxrwx--- ; # - donne une même confiance au groupe propriétaire qu'au propriétaire ; # - facilite l'utilisation des ACL, qui sont dépendantes des droits du groupe propriétaire. PASS_MAX_DAYS 99999 PASS_MIN_DAYS 0 PASS_WARN_AGE 7 UID_MIN 1000 UID_MAX 60000 GID_MIN 1000 GID_MAX 60000 LOGIN_RETRIES 3 LOGIN_TIMEOUT 60 CHFN_RESTRICT rwh DEFAULT_HOME yes USERGROUPS_ENAB yes ENCRYPT_METHOD SHA512 EOF grep -q '^session optional pam_umask.so\>' /etc/pam.d/common-session || sudo install -m 644 -o root -g root /dev/stdin /etc/pam.d/common-session <<-EOF $(cat /etc/pam.d/common-session) session optional pam_umask.so EOF grep -q '^hvc0$' /etc/securetty || sudo install -m 644 -o root -g root /dev/stdin /etc/securetty <<-EOF $(cat /etc/securetty) hvc0 EOF grep -q '^xvc0$' /etc/securetty || sudo install -m 644 -o root -g root /dev/stdin /etc/securetty <<-EOF $(cat /etc/securetty) xvc0 EOF } rule_mail_configure () { rule postfix_configure rule postgrey_configure rule procmail_configure rule dovecot_configure } rule_mysql_configure () { rule apt_get_install mysql-server-5.5 rule adduser mysql \ --disabled-login \ --disabled-password \ --group \ --home /home/mysql \ --shell /bin/false \ --system rule adduser mysql-data \ --disabled-login \ --disabled-password \ --group \ --home /home/mysql/data \ --no-create-home \ --shell /bin/false \ --system sudo usermod --home /home/mysql mysql sudo adduser mysql mysql-data sudo install -m 644 -o mysql -g mysql \ "$tool"/etc/mysql/my.cnf \ /etc/mysql/my.cnf sudo install -d -m 751 -o mysql -g mysql \ /home/mysql sudo rm -rf /etc/mysql sudo install -d -m 750 -o mysql -g mysql \ /etc/mysql \ /home/mysql/etc sudo ln -fns \ /etc/mysql \ /home/mysql/etc/mysql if sudo test ! -d /home/mysql/data then sudo install -d -m 750 -o mysql -g mysql-data \ /home/mysql/data sudo -u mysql mysql_install_db \ --datadir=/home/mysql/data \ --no-defaults fi sudo service tmpfs restart sudo insserv -r mysql sudo chmod ugo-x /etc/init.d/mysql case $(sudo sv status mysql || true) in (''|run:*|*"s, normally up;"*) sudo sv restart mysql case $(sudo inotifywait -e create -- /run/mysqld/sock/) in ("/run/mysqld/sock/ CREATE mysql") # NOTE: # - ajoute l'accès par socket Unix à mysql # - ajoute les droits de super-utilisateur à mysql # - supprime l'accès par mot-de-passe à root # - supprime les bases de données de l'utilisateurice anonyme # - supprime l'utilisateurice anonyme # NOTE: mémo : # GRANT USAGE ON *.* TO 'root'@'*' IDENTIFIED WITH auth_socket; # CREATE USER 'root'@'localhost' IDENTIFIED WITH auth_socket; # UPDATE mysql.user SET Password='' WHERE user='root'; # DELETE FROM mysql.user WHERE user = 'root' AND host NOT IN ('localhost', '127.0.0.1', '::1'); sudo mysql -u root --batch --verbose <<-EOF DELETE FROM mysql.user WHERE user = 'root' and plugin = ''; GRANT ALL PRIVILEGES ON *.* TO 'mysql'@'localhost' IDENTIFIED WITH auth_socket; UPDATE mysql.user SET grant_priv='Y',super_priv='Y' WHERE user='mysql'; DELETE FROM mysql.db WHERE user = ''; DELETE FROM mysql.user WHERE user = ''; FLUSH PRIVILEGES; EOF ;; esac esac } rule_mysql_db_add () { # SYNTAX: $user $db sudo -u mysql mysql --batch <<-EOF DROP DATABASE IF EXISTS $db; CREATE DATABASE $db CHARACTER SET utf8 COLLATE utf8_general_ci; GRANT ALL PRIVILEGES ON $base.* TO '$user'@'localhost' IDENTIFIED WITH auth_socket; FLUSH PRIVILEGES; EOF } rule_mysql_user_add () { # SYNTAX: $user sudo mysql -u mysql --batch <<-EOF || true DROP USER '$user'@'localhost'; EOF sudo mysql -u mysql --batch <<-EOF CREATE USER '$user'@'localhost' IDENTIFIED WITH auth_socket; EOF } rule_network_configure () { sudo install -m 644 -o root -g root /dev/stdin /etc/hostname <<-EOF $vm EOF grep -q " $vm\$" /etc/hosts || sudo install -m 644 -o root -g root /dev/stdin /etc/hosts <<-EOF $(cat /etc/hosts) 127.0.0.1 $vm_fqdn $vm EOF sudo install -m 644 -o root -g root /dev/stdin /etc/resolv.conf <<-EOF search ${vm_host#*.} nameserver ${vm_host_nameserver} EOF sudo install -m 644 -o root -g root /dev/stdin /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 # NOTE: il y a besoin de ça en l'état actuel du réseau de Grenode # car la MTU des tunnels GRE/IPsec entre les routeurs de Grenode l'impose. # # root@ateliers:~# ping -M do -c 1 -s \$((1500-20-8-200)) soupirail.grenode.net # PING soupirail.grenode.net (91.216.110.1) 1272(1300) bytes of data. # 1280 bytes from soupirail.grenode.net (91.216.110.1): icmp_req=1 ttl=63 time=18.0 ms # # --- soupirail.grenode.net ping statistics --- # 1 packets transmitted, 1 received, 0% packet loss, time 0ms # rtt min/avg/max/mdev = 18.027/18.027/18.027/0.000 ms # root@ateliers:~# ping -M do -c 1 -s \$((1500-20-8-200+1)) soupirail.grenode.net # PING soupirail.grenode.net (91.216.110.1) 1273(1301) bytes of data. # From estran.grenode.net (91.216.110.6) icmp_seq=1 Frag needed and DF set (mtu = 1300) # # --- soupirail.grenode.net ping statistics --- # 0 packets transmitted, 0 received, +1 errors post-up ip address add $vm_ipv4/32 dev \$IFACE pre-down ip address delete $vm_ipv4/32 dev \$IFACE EOF } rule_nginx_configure () { local -; set +f rule apt_get_install nginx sudo rm -rf \ /etc/nginx/conf.d \ /etc/nginx/site.d sudo install -d -m 770 -o www -g www \ /etc/nginx \ /etc/nginx/conf.d \ /etc/nginx/site.d \ /etc/nginx/x509.d sudo ln -fns \ /etc/nginx \ /home/www/etc/nginx sudo install -m 660 -o www -g www \ "$tool"/etc/nginx/nginx.conf \ /etc/nginx/nginx.conf local conf for conf in "$tool"/etc/nginx/conf.d/*.conf do conf=${conf#"$tool"/etc/nginx/conf.d/} sudo install -m 660 -o www -g www \ "$tool"/etc/nginx/conf.d/"$conf" \ /etc/nginx/conf.d/"$conf" done for conf in "$tool"/etc/nginx/site.d/*/site.conf do conf=${conf#"$tool"/etc/nginx/site.d/} local site="${conf%/site.conf}" rule adduser www-"$site" \ --disabled-login \ --disabled-password \ --group \ --home /home/www/pub/"$site" \ --shell /bin/false \ --system rule adduser log-www-"$site" \ --disabled-login \ --disabled-password \ --group \ --home /home/www/log/"$site"/nginx \ --shell /bin/false \ --system sudo install -d -m 771 -o log-www -g log-www \ /home/www/log/"$site" sudo install -d -m 770 -o www -g www \ /etc/nginx/site.d/"$site" sudo install -d -m 770 -o www -g www \ /etc/nginx/x509.d/"$site" test -L /home/www/pub/"$site" || sudo install -d -m 2770 -o www-"$site" -g www-"$site" \ /home/www/pub/"$site" sudo adduser www-data www-"$site" sudo adduser www-data log-www-"$site" sudo install -m 660 -o www -g www \ "$tool"/etc/nginx/site.d/"$site"/local.conf \ /etc/nginx/site.d/"$site"/local.inc sudo install -m 660 -o www -g www \ "$tool"/etc/nginx/site.d/"$site"/site.conf \ /etc/nginx/site.d/"$site"/site.inc sudo install -m 660 -o www -g www /dev/stdin \ /etc/nginx/site.d/"$site"/server.conf <<-EOF server { access_log /home/www/log/$site/nginx/access.log main; error_log /home/www/log/$site/nginx/error.log warn; root /home/www/pub/$site; include /etc/nginx/site.d/$site/local.inc; include /etc/nginx/site.d/$site/site.inc; } EOF test ! -r "$tool"/etc/nginx/site.d/"$site"/configure.sh || . "$tool"/etc/nginx/site.d/"$site"/configure.sh done rule apt_get_install spawn-fcgi fcgiwrap sudo insserv --remove fcgiwrap sudo chmod ugo-x /etc/init.d/fcgiwrap #sudo insserv --remove nginx #sudo chmod ugo-x /etc/init.d/nginx rule tmpfs_configure sudo service php5-fpm restart # NOTE: relance les processus du pool # pour leur donner les droits # de leurs groupes supplémentaires. sudo service nginx restart } rule_nsd3_configure () { # NOTE: DNS autoritaire uniquement local -; set +f rule apt_get_install nsd m4 sudo rm -rf \ /etc/nsd3/zone.d sudo install -d -m 750 -o root -g nsd \ /etc/nsd3/zone.d { cat <<-EOF server: ip-address: $vm_ipv4 ip4-only: yes EOF cat "$tool"/etc/nsd3/nsd.conf local conf for conf in "$tool"/etc/nsd3/zone.d/*.conf do conf=${conf#"$tool"/etc/nsd3/zone.d/} local domain=${conf%.conf} if test -e "$tool"/etc/nsd3/zone.d/"$domain".zone.m4 then m4 \ --define=ZONE_DOMAIN=$domain \ --define=ZONE_SERIAL=$(cd "$tool" && git log -1 --format="%ct" -- etc/nsd3/zone.d/"$domain".zone.m4) \ --define=VM_IP4=$vm_ipv4 \ "$tool"/etc/nsd3/zone.d/"$domain".zone.m4 else cat "$tool"/etc/nsd3/zone.d/"$domain".zone fi | sudo install -m 440 -o root -g nsd /dev/stdin \ /etc/nsd3/zone.d/"$domain".zone sudo install -m 440 -o root -g nsd \ "$tool"/etc/nsd3/zone.d/"$conf" \ /etc/nsd3/zone.d/"$conf" cat <<-EOF zone: name: $domain zonefile: /etc/nsd3/zone.d/$domain.zone EOF done } | sudo install -m 640 -o root -g nsd /dev/stdin \ /etc/nsd3/nsd.conf sudo service nsd3 restart } rule_php5_fpm_configure () { local -; set +f rule apt_get_install \ php5-fpm \ php-apc rule adduser php5 \ --disabled-login \ --disabled-password \ --group \ --home /etc/php5/fpm \ --shell /bin/false \ --system rule adduser log-php5 \ --disabled-login \ --disabled-password \ --group \ --home /home/www/log/php5/fpm \ --shell /bin/false \ --system sudo ln -fns \ /etc/php5/fpm \ /home/www/etc/php5 sudo rm -rf \ /etc/php5/fpm/conf.d \ /etc/php5/fpm/pool.d sudo install -d -m 770 -o php5 -g php5 \ /etc/php5/fpm/conf.d \ /etc/php5/fpm/pool.d sudo install -m 770 -o php5 -g php5 \ "$tool"/etc/php5/fpm/php-fpm.conf \ /etc/php5/fpm/php-fpm.conf local conf #for conf in "$tool"/etc/php5/fpm/conf.d/*.conf # do conf=${conf#"$tool"/etc/php5/fpm/conf.d/} # sudo install -m 660 -o php5 -g php5 \ # "$tool"/etc/php5/fpm/conf.d/"$conf" \ # /etc/php5/fpm/conf.d/"$conf" # done for conf in "$tool"/etc/php5/fpm/pool.d/*.conf do conf=${conf#"$tool"/etc/php5/fpm/pool.d/} IFS=. read -r pool <<-EOF ${conf%.conf} EOF assert 'test "${pool:+set}"' rule adduser php5-"$pool" \ --disabled-login \ --disabled-password \ --group \ --no-create-home \ --home /etc/php5/fpm/pool.d \ --shell /bin/false \ --system rule adduser log-php5-"$pool" \ --disabled-login \ --disabled-password \ --group \ --no-create-home \ --home /home/www/log/php5/fpm/"$pool" \ --shell /bin/false \ --system sudo install -d -m 770 -o log-php5 -g log-php5 \ /home/www/log/php5 \ /home/www/log/php5/fpm sudo install -d -m 770 -o log-php5-"$pool" -g log-php5-"$pool" \ /home/www/log/php5/fpm/"$pool" sudo install -m 660 -o php5 -g php5 /dev/stdin \ /etc/php5/fpm/pool.d/"$pool".conf <<-EOF [$pool] access.log = /home/www/log/php5/fpm/$pool/access.log catch_workers_output = yes chdir = / env[HOSTNAME] = \$HOSTNAME env[TEMP] = /tmp env[TMPDIR] = /tmp env[TMP] = /tmp group = php5-$pool #listen = 127.0.0.1:9000 listen = /run/php5/fpm/$pool #listen.allowed_clients = 127.0.0.1 listen.group = www-data listen.mode = 0660 #listen.owner = www-data listen.backlog = -1 pm = dynamic pm.max_children = 5 pm.max_requests = 200 pm.max_spare_servers = 4 pm.min_spare_servers = 2 pm.start_servers = 3 pm.status_path = /status request_slowlog_timeout = 5s request_terminate_timeout = 120s rlimit_core = unlimited rlimit_files = 131072 slowlog = /home/www/log/php5/fpm/$pool/slow.log user = php5-$pool $(cat "$tool"/etc/php5/fpm/pool.d/"$conf") EOF sudo install -m 664 -o php5 -g php5 \ "$tool"/etc/php5/fpm/php.ini \ /etc/php5/fpm/php.ini case $(sudo sv status php5-"$pool") in (run:*) sudo sv restart php5-"$pool" esac done rule tmpfs_configure sudo service php5-fpm restart } rule_postfix_configure () { local hint="run vm_remote postfix_key_send before" assert "test -f /etc/postfix/$vm_domainname/smtpd/x509/key.pem" hint #warn "lors de l'installation Debian, ne sélectionner aucune configuration pour postfix" sudo debconf-set-selections <<-EOF postfix postfix/main_mailer_type select No configuration EOF rule apt_get_install postfix sudo install -m 640 -o root -g root /dev/stdin /etc/postfix/.gitignore <<-EOF *.db EOF sudo install -d -m 771 -o root -g root \ /etc/postfix/ \ /etc/postfix/$vm_domainname/ \ /etc/postfix/$vm_domainname/smtp \ /etc/postfix/$vm_domainname/smtp/x509 \ /etc/postfix/$vm_domainname/smtp/x509/ca \ /etc/postfix/$vm_domainname/smtpd \ /etc/postfix/$vm_domainname/smtpd/x509 \ /etc/postfix/$vm_domainname/smtpd/x509/ca sudo ln -fns \ ../crt+crl.self-signed.pem \ /etc/postfix/$vm_domainname/smtpd/x509/ca/crt.pem sudo install -m 400 -o root -g root \ "$tool"/var/pub/x509/smtpd.$vm_domainname/crt+crl.self-signed.pem \ /etc/postfix/$vm_domainname/smtpd/x509/crt+crl.self-signed.pem sudo install -m 400 -o root -g root \ "$tool"/var/pub/x509/smtpd.$vm_domainname/crt.pem \ /etc/postfix/$vm_domainname/smtpd/x509/crt.pem sudo install -m 400 -o root -g root \ "$tool"/var/pub/x509/smtpd.$vm_domainname/crt+ca.pem \ /etc/postfix/$vm_domainname/smtpd/x509/crt+ca.pem sudo install -m 400 -o root -g root \ "$tool"/var/pub/x509/smtpd.$vm_domainname/crt+crl.self-signed.pem \ /etc/postfix/$vm_domainname/smtpd/x509/crt+crl.self-signed.pem sudo install -m 660 -o root -g root \ "$tool"/etc/postfix/$vm_domainname/header_checks \ /etc/postfix/$vm_domainname/header_checks sudo install -m 664 -o root -g root /dev/stdin \ /etc/postfix/aliases <<-EOF # See man 5 aliases for format abuse: root admin: root contact: root mailer-daemon: root postmaster: root root: $(getent group sudo | cut -f 4 -d : | tr , ' ') EOF sudo newaliases -oA/etc/postfix/aliases cat /dev/stdin "$tool"/etc/postfix/main.cf <<-EOF | mydomain = $vm_domainname myorigin = \$mydomain myhostname = $vm_hostname.\$mydomain mail_name = \$myhostname mydestination = $vm_hostname \$myhostname \$myorigin EOF sudo install -m 664 -o root -g root /dev/stdin \ /etc/postfix/main.cf sudo install -m 664 -o root -g root \ "$tool"/etc/postfix/master.cf \ /etc/postfix/master.cf sudo install -m 660 -o root -g root \ "$tool"/etc/postfix/$vm_domainname/smtp/x509/policy \ /etc/postfix/$vm_domainname/smtp/x509/policy sudo postmap hash:/etc/postfix/$vm_domainname/smtp/x509/policy sudo install -m 660 -o root -g root \ "$tool"/etc/postfix/$vm_domainname/smtp/header_checks \ /etc/postfix/$vm_domainname/smtp/header_checks sudo install -m 660 -o root -g root \ "$tool"/etc/postfix/$vm_domainname/smtpd/sender_access \ /etc/postfix/$vm_domainname/smtpd/sender_access sudo postmap hash:/etc/postfix/$vm_domainname/smtpd/sender_access sudo install -m 660 -o root -g root \ "$tool"/etc/postfix/$vm_domainname/smtpd/client_blacklist \ /etc/postfix/$vm_domainname/smtpd/client_blacklist sudo postmap hash:/etc/postfix/$vm_domainname/smtpd/client_blacklist sudo install -m 660 -o root -g root \ "$tool"/etc/postfix/$vm_domainname/smtpd/relay_clientcerts \ /etc/postfix/$vm_domainname/smtpd/relay_clientcerts sudo postmap hash:/etc/postfix/$vm_domainname/smtpd/relay_clientcerts sudo install -m 660 -o root -g root \ "$tool"/etc/postfix/$vm_domainname/transport \ /etc/postfix/$vm_domainname/transport sudo postmap hash:/etc/postfix/$vm_domainname/transport sudo install -m 660 -o root -g root \ "$tool"/etc/postfix/$vm_domainname/virtual_alias \ /etc/postfix/$vm_domainname/virtual_alias sudo postmap hash:/etc/postfix/$vm_domainname/virtual_alias sudo service postfix restart } rule_postgresql_configure () { # DOC: http://wiki.postgresql.org/wiki/Shared_Database_Hosting rule apt_get_install postgresql-9.1 rule adduser postgres \ --disabled-login \ --disabled-password \ --group \ --home /home/postgresql \ --shell /bin/false \ --system rule adduser postgres-data \ --disabled-login \ --disabled-password \ --group \ --home /home/postgresql/data \ --no-create-home \ --shell /bin/false \ --system sudo usermod --home /home/postgresql postgres sudo adduser postgres postgres-data sudo rm -rf \ /etc/postgresql sudo install -d -m 750 -o postgres -g postgres \ /home/postgresql \ /home/postgresql/etc \ /etc/postgresql \ /etc/postgresql/9.1 \ /etc/postgresql/9.1/main sudo ln -fns \ /etc/postgresql \ /home/postgresql/etc/postgresql sudo install -d -m 751 -o postgres -g postgres \ /home/postgresql/log \ /home/postgresql/log/9.1 sudo service tmpfs restart if sudo test ! -d /home/postgresql/data then sudo install -d -m 750 -o postgres -g postgres \ /home/postgresql/data ( cd / sudo -u postgres pg_createcluster \ --datadir=/home/postgresql/data \ --logfile=/home/postgresql/log/9.1/main \ --socketdir=/run/postgresql/sock \ --start 9.1 main ) fi sudo install -m 770 -o postgres -g postgres /dev/stdin \ /etc/postgresql/9.1/main/pg_hba.conf <<-EOF local all postgres peer local all all peer EOF sudo install -m 660 -o postgres -g postgres \ "$tool"/etc/postgresql/9.1/main/postgresql.conf \ /etc/postgresql/9.1/main/postgresql.conf sudo insserv -r postgresql sudo chmod ugo-x /etc/init.d/postgresql case $(sudo sv status postgres || true) in (''|run:*|*"s, normally up;"*) sudo sv restart postgres ( cd / case $(sudo inotifywait -e create -- /run/postgresql/sock/) in ("/run/postgresql/sock/ CREATE .s.PGSQL."*) # NOTE: # - supprime l'accès au schéma public depuis public, # de sorte à ce que les différents utilisateurices # ne voient pas leurs bases de données entre-elleux ; # - ajoute le support de PL/PGSQL. sudo -u postgres psql template1 -f - <<-EOF REVOKE ALL ON DATABASE template1 FROM public; REVOKE ALL ON SCHEMA public FROM public; GRANT ALL ON SCHEMA public TO postgres; CREATE LANGUAGE plpgsql; EOF # NOTE: # - supprime l'accès à la liste des bases données # et utilisateurices depuis public. sudo -u postgres psql template1 -f - <<-EOF REVOKE ALL ON pg_auth_members FROM public; REVOKE ALL ON pg_authid FROM public; REVOKE ALL ON pg_database FROM public; REVOKE ALL ON pg_group FROM public; REVOKE ALL ON pg_roles FROM public; REVOKE ALL ON pg_settings FROM public; REVOKE ALL ON pg_tablespace FROM public; REVOKE ALL ON pg_user FROM public; EOF ;; esac ) ;; esac } rule_postgresql_db_add () { # SYNTAX: $db $db_user local db="$1" db_user="$2" sudo -u postgresql psql template1 -f - <<-EOF CREATE ROLE $db NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN; CREATE ROLE $db_user NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN ENCRYPTED; GRANT $db TO $db_user; CREATE DATABASE $db WITH OWNER=$db_user; REVOKE ALL ON DATABASE $db FROM public; EOF } rule_postgresql_db_user_add () { # SYNTAX: $db $user local db="$1" user="$2" sudo -u postgresql psql template1 -f - <<-EOF CREATE ROLE $user NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN ENCRYPTED; GRANT USAGE ON SCHEMA public TO $user; GRANT CONNECT,TEMPORARY ON DATABASE $db TO $user; GRANT $db TO $user; EOF } rule_openerp_configure () { sudo install -m 660 -o root -g root /dev/stdin /etc/apt/sources.list.d/openerp.list <<-EOF deb http://nightly.openerp.com/trunk/nightly/deb/ ./ EOF sudo apt-get update rule apt_get_install openerp } rule_postgrey_configure () { rule apt_get_install postgrey sudo service postgrey restart } rule_procmail_configure () { rule apt_get_install procmail sudo install -d -m 770 -o root -g root \ /etc/skel/etc/mail \ /etc/skel/var/cache/mail \ /etc/skel/var/log/mail \ /etc/skel/var/mail sudo install -m 660 -o root -g root \ "$tool"/etc/skel/etc/mail/delivery.procmailrc \ /etc/skel/etc/mail/delivery.procmailrc } rule_runit_configure () { # SYNTAX: $service rule apt_get_install runit local -; set +f for sv in ${1-/etc/service/*} # NOTE: stoppe les services en retenant leur status de départ do sv=$(basename "$sv") local sv_hash=$(printf %s "$sv" | sha1sum | cut -f 1 -d ' ') local sv_status IFS= read -r sv_status_$sv_hash <<-EOF $(sudo sv status "$sv") EOF sudo rm -f /etc/service/"$sv" done for sv in ${1-"$tool"/etc/sv/*} # NOTE: configure et (re-)démarre les services do sv=$(basename "$sv") local sv_hash=$(printf %s "$sv" | sha1sum | cut -f 1 -d ' ') sudo install -d -m 770 -o root -g root \ /etc/sv/"$sv" sudo install -m 770 -o root -g root \ "$tool"/etc/sv/"$sv"/run \ /etc/sv/"$sv"/run if test -e "$tool"/etc/sv/"$sv"/log/run then sudo install -d -m 770 -o root -g root \ /etc/sv/"$sv"/log sudo install -m 770 -o root -g root \ "$tool"/etc/sv/"$sv"/log/run \ /etc/sv/"$sv"/log/run fi test ! -r "$tool"/etc/sv/"$sv"/configure.sh || . "$tool"/etc/sv/"$sv"/configure.sh sudo ln -fns ../sv/"$sv" /etc/service/"$sv" eval local sv_status=\"\${sv_status_$sv_hash-}\" case $sv_status in ("") true;; (run:*) sudo sv restart "$sv";; esac done } rule_ssh_configure () { ssh-keygen -F "$vm_fqdn" -f "$tool"/etc/openssh/known_hosts | ( while IFS= read -r line do case $line in (*" RSA") return 0; break;; esac done; return 1 ) || sudo ssh-keygen -t rsa -b 4096 -N '' -f /etc/ssh/ssh_host_rsa_key sudo rm -f \ /etc/ssh/ssh_host_dsa_key \ /etc/ssh/ssh_host_dsa_key.pub \ /etc/ssh/ssh_host_ecdsa_key \ /etc/ssh/ssh_host_ecdsa_key.pub # NOTE: clefs générées par Debian sudo install -m 644 -o root -g root /dev/stdin /etc/ssh/sshd_config <<-EOF AcceptEnv LANG LC_* AuthorizedKeysFile %h/etc/ssh/authorized_keys ChallengeResponseAuthentication no ClientAliveInterval 0 Compression yes DebianBanner no GSSAPIAuthentication no HostKey /etc/ssh/ssh_host_rsa_key HostbasedAuthentication no IgnoreRhosts yes IgnoreUserKnownHosts no KerberosAuthentication no KeyRegenerationInterval 3600 Port 22 ListenAddress 127.0.0.1 ListenAddress $vm_ipv4 LogLevel INFO LoginGraceTime 120 PasswordAuthentication no PermitEmptyPasswords no PermitRootLogin yes PrintLastLog yes PrintMotd no Protocol 2 PubkeyAuthentication yes RSAAuthentication yes RhostsRSAAuthentication no ServerKeyBits 768 StrictModes yes Subsystem sftp /usr/lib/openssh/sftp-server SyslogFacility AUTH TCPKeepAlive yes UsePAM yes UsePrivilegeSeparation yes X11DisplayOffset 10 X11Forwarding no EOF sudo install -m 644 -o root -g root /dev/stdin /etc/ssh/ssh_config <<-EOF Host * #Compression yes #CompressionLevel 9 #ControlMaster auto #ControlPath ~/var/run/ssh/sock/%h-%p-%r GSSAPIAuthentication no GSSAPIDelegateCredentials no HashKnownHosts yes IdentityFile ~/etc/ssh/id_dsa IdentityFile ~/etc/ssh/id_rsa IdentityFile ~/etc/ssh/identity SendEnv LANG LC_* StrictHostKeyChecking ask UserKnownHostsFile ~/etc/ssh/known_hosts EOF sudo service ssh restart } rule_sysctl_configure () { local -; set +f for conf in "$tool"/etc/sysctl.d/*.conf do conf=${conf#"$tool"/etc/sysctl.d/} sudo install -m 660 -o root -g root \ "$tool"/etc/sysctl.d/"$conf" \ /etc/sysctl.d/"$conf" done sudo sysctl --system } rule_tmpfs_configure () { sudo install -m 644 -o root -g root /dev/stdin /etc/default/tmpfs <<-EOF LOCK_SIZE=5242880 # NOTE: 5MiB RAMLOCK=yes RAMSHM=yes RAMTMP=yes RUN_SIZE=10% SHM_SIZE= TMP_MODE=1777,nr_inodes=1000k,noatime TMP_OVERFLOW_LIMIT=1024 # NOTE: mount tmpfs on /tmp if there is less than the limit size (in kiB) # on the root filesystem (overriding RAMTMP). TMP_SIZE=200m TMPFS_SIZE=20%VM EOF sudo install -m 775 -o root -g root \ "$tool"/etc/init.d/tmpfs \ /etc/init.d/tmpfs sudo update-rc.d tmpfs defaults sudo service tmpfs restart } rule_time_configure () { sudo install -m 644 -o root -g root /dev/stdin /etc/timezone <<-EOF Europe/Paris EOF sudo debconf-set-selections <<-EOF tzdata tzdata/Areas select Europe tzdata tzdata/Zones/Europe select Paris EOF rule dpkg_reconfigure tzdata rule apt_get_install ntp } rule_unbound_configure () { sudo apt-get install unbound m4 sudo install -m 644 -o root -g root /dev/stdin /etc/resolv.conf <<-EOF search ${vm_host#*.} nameserver 127.0.0.1 #nameserver ${vm_host_nameserver} EOF sudo install -m 440 -o unbound -g unbound \ "$tool"/etc/unbound/named.cache \ /etc/unbound/named.cache m4 \ --define=OUTGOING_INTERFACE=$vm_ipv4 \ <"$tool"/etc/unbound/unbound.conf | sudo install -m 440 -o unbound -g unbound /dev/stdin \ /etc/unbound/unbound.conf sudo service unbound restart } rule_user_add () { # SYNTAX: $user rule user_configure local user=$1 rule adduser "$user" --disabled-password # NOTE: le mot-de-passe doit être initialisé par l'utilisateur à l'aide de passwd-init . eval local home\; home="~$user" sudo adduser "$user" users sudo install -m 640 -o root -g root \ "$tool"/var/pub/ssh/"$user".key \ "$home"/etc/ssh/authorized_keys local key; local -; set +f for key in "$tool"/var/pub/openpgp/*.key do sudo -u "$user" gpg --import - <"$key" done } rule_user_configure () { rule apt_get_install bash-completion sudo install -m 660 -o root -g root /dev/stdin \ /etc/adduser.conf <<-EOF ADD_EXTRA_GROUPS=1 DHOME=/home DIR_MODE=0750 DSHELL=/bin/bash EXTRA_GROUPS="users" FIRST_GID=1000 FIRST_SYSTEM_GID=100 FIRST_SYSTEM_UID=100 FIRST_UID=1000 GROUPHOMES=no LAST_GID=29999 LAST_SYSTEM_GID=999 LAST_SYSTEM_UID=999 LAST_UID=29999 LETTERHOMES=no NAME_REGEX="^[a-z][-a-z0-9_]*\$" QUOTAUSER="" # TODO: init SETGID_HOME=no SKEL=/etc/skel SKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)" USERGROUPS=yes USERS_GID=100 EOF sudo install -d -m 750 -o root -g root \ /etc/skel \ /etc/skel/etc \ /etc/skel/etc/gpg \ /etc/skel/etc/ssh sudo install -d -m 770 -o root -g root \ /etc/skel/var \ /etc/skel/var/cache \ /etc/skel/var/log \ /etc/skel/var/run \ /etc/skel/var/run/ssh sudo ln -fns etc/ssh /etc/skel/.ssh sudo ln -fns etc/gpg /etc/skel/.gnupg sudo install -m 640 -o root -g root /dev/stdin /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 sudo install -m 640 -o root -g root /dev/stdin /etc/sudoers.d/etckeeper-unclean <<-EOF %sudo ALL=(ALL) NOPASSWD: /usr/bin/etckeeper unclean EOF sudo install -m 640 -o root -g root /dev/stdin /etc/sudoers.d/env_keep <<-EOF Defaults env_keep = " \\ EDITOR \\ GIT_AUTHOR_NAME \\ GIT_AUTHOR_EMAIL \\ GIT_COMMITTER_NAME \\ GIT_COMMITTER_EMAIL \\ " EOF sudo install -m 755 -o root -g root /dev/stdin /usr/local/bin/passwd-init <<-EOF #!/bin/sh -efu # DESCRIPTION: permet à un-e utilisateurice d'initialiser ellui-même son mot-de-passe système. 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 sudo install -m 644 -o root -g root \ "$tool"/etc/bash.bashrc \ /etc/bash.bashrc sudo install -m 644 -o root -g root \ "$tool"/etc/screenrc \ /etc/screenrc } rule_user_admin_add () { # SYNTAX: $user rule user_configure local user=$1 rule adduser "$user" --disabled-password eval local home\; home="~$user" sudo adduser "$user" sudo sudo install -m 640 -o root -g root \ "$tool"/var/pub/ssh/"$user".key \ "$home"/etc/ssh/authorized_keys local key; local -; set +f for key in "$tool"/var/pub/openpgp/*.key do sudo -u "$user" gpg --import - <"$key" done rule user_admin_configure } rule_user_admin_configure () { rule initramfs_configure rule user_root_configure } rule_user_root_configure () { sudo install -d -m 750 -o root -g root \ /root/etc \ /root/etc/gpg \ /root/etc/ssh sudo ln -fns etc/gpg /root/.gnupg sudo ln -fns etc/ssh /root/.ssh getent group sudo | while IFS=: read -r group x x users do while test -n "$users" && IFS=, read -r user users <<-EOF $users EOF do eval local home\; home="~$user" sudo cat "$home"/etc/ssh/authorized_keys done done | sudo install -m 640 -o root -g root /dev/stdin /root/etc/ssh/authorized_keys local key; local -; set +f for key in "$tool"/var/pub/openpgp/*.key do sudo gpg --import "$key" done } rule_www_configure () { rule adduser www \ --disabled-login \ --disabled-password \ --group \ --home /home/www \ --shell /bin/false \ --system rule adduser log-www \ --disabled-login \ --disabled-password \ --group \ --home /home/www/log \ --shell /bin/false \ --system #sudo adduser www www-data sudo adduser www log-www #sudo adduser log log-www usermod --home /home/www/pub www-data sudo install -d -m 751 -o www -g www \ /home/www sudo install -d -m 750 -o www -g www \ /home/www/etc sudo install -d -m 1771 -o www-data -g www-data \ /home/www/pub sudo install -d -m 1771 -o log-www -g log-www \ /home/www/log } rule_configure () { rule apt_configure rule git_configure rule etckeeper_configure rule locales_configure rule time_configure rule network_configure rule filesystem_configure rule login_configure rule ssh_configure rule user_root_configure rule boot_configure rule sysctl_configure rule user_configure rule mail_configure rule gitolite_configure rule www_configure rule php5_fpm_configure rule nginx_configure #rule apache2_configure rule nsd3_configure rule runit_configure } rule_luks_key_change () { sudo cryptsetup luksChangeKey /dev/$vm_lvm_vg/${vm_lvm_lv}_root } rule=${1:-help} ${1+shift} case $rule in (help);; (*) assert 'test "$(hostname --fqdn)" = "$vm_fqdn"' vm_fqdn ;; esac rule $rule "$@"