#!/bin/bash # Automatisation de configuration backuppc pour poste linux # Institut de Physique de Rennes UMR6251 # Anthony CARRÉ, Jérémy GARDAIS, Guillaume RAFFY — Mars 2016 SUCCESS=0 ERROR=1 function getDefaultUser() { case $(uname) in 'Darwin') for user in $(ListUsers); do echo $user return done ;; 'Linux') getent passwd "1000" | cut -d: -f1 ;; esac } # this performs the equivalent as adding a remote login user in system preferences using the gui function allowUserToConnectToThisMachineUsingSsh() { local userLogin="$1" case $(uname) in 'Darwin') dscl . append '/Groups/com.apple.access_ssh' user "${userLogin}" dscl . append /Groups/com.apple.access_ssh groupmembers $(dscl . read "/Users/${userLogin}" GeneratedUID | cut -d " " -f 2) ;; 'Linux') # nothing to do? ;; esac } function ensurePingIsAllowed() { case $(uname) in 'Darwin') sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode off if [ $? != 0 ]; then printf '\e[1;31m%-6s\e[m' "La désactivation du mode furtif a échoué"; return "$ERROR" fi ;; 'Linux') ;; esac } function ensureSshdIsRunning() { case $(uname) in 'Darwin') sudo launchctl list | grep 'com.openssh.sshd' &> /dev/null if [ $? != 0 ]; then # enable 'Remote login' in 'system preferences' sudo launchctl enable system/com.openssh.sshd &> /dev/null sudo launchctl load /System/Library/LaunchDaemons/ssh.plist &> /dev/null fi sudo launchctl list | grep 'com.openssh.sshd' &> /dev/null if [ $? != 0 ]; then printf '\e[1;31m%-6s\e[m' "L'activation du serveur ssh a échoué"; return "$ERROR" fi ;; 'Linux') #if [ ! -f "${hostkey}" ]; then if [ ! $(command -v sshd) ]; then printf "\nopenssh-server non installé, tentative d’installation.\n" if hash apt 2>/dev/null; then apt install -y openssh-server elif hash pacman 2>/dev/null; then pacman -Syu openssh elif hash yum 2>/dev/null; then yum install -y openssh-server elif hash zypper 2>/dev/null; then zypper install openSSH else printf '\e[1;31m%-6s\e[m' "Merci d’installer openssh-server sur votre machine, installation annulée."; return "$ERROR" fi # Si ssh installé par le script, le restreindre à backuppc configssh="/etc/ssh/sshd_config" if [ ! -f "${configssh}" ]; then echo "AllowUsers backuppc" >> "${configssh}" fi fi ;; esac } function getMyHostKey() { local hostkey='' case $(uname) in 'Darwin') hostkey="/etc/ssh_host_rsa_key.pub" if [ ! -f "${hostkey}" ]; then hostkey="/etc/ssh/ssh_host_rsa_key.pub" if [ ! -f "${hostkey}" ]; then printf '\e[1;31m%-6s\e[m' "Impossible de trouver la clef ssh publique ce cette machine, SSH est-il bien installé?\n Installation annulée." return "$ERROR" fi fi ;; 'Linux') hostkey="/etc/ssh/ssh_host_ecdsa_key.pub" #### SI MALGRÉ L’INSTALLATION DE OPENSSH, LA CLÉ N’EST TOUJOURS PAS ACCESSIBLE if [ ! -f "${hostkey}" ]; then return "$ERROR" fi # TODO : check that sshd is running ? ;; esac echo "${hostkey}" } function IpAddress() { local strMyIpAddress='' local strOsName=$( uname ) case $strOsName in "Darwin") strMyIpAddress=$(dig +short myip.opendns.com @resolver1.opendns.com) ;; "Linux" ) strMyIpAddress=$(wget http://checkip.dyndns.org/ -O - -o /dev/null | cut -d" " -f 6 | cut -d\< -f 1) ;; * ) error "unhandled case ($strOsName)" return 1 ;; esac if [ "$strMyIpAddress" == '' ]; then error "failed to retrieve the ip address of this machine" return 1 fi echo $strMyIpAddress } function MyFqdn() { local strMyIpAddress=$( IpAddress ) # eg '129.20.27.49' local strMyFqdn=$(host $strMyIpAddress | awk '{print $5}') echo ${strMyFqdn%?} # remove the trailing '.' } function ListUsers() { local users='' case $(uname) in 'Darwin') for user in $(ls -d /Users/[a-zA-Z]*); do user=$(basename $user) case "$user" in 'Shared'|'admin') ;; *) users="$users $user" ;; esac done ;; 'Linux') users="$(echo $(ls -I 'lost+found' -I 'administrateur' /home/) | sed -e 's/\///g')" ;; esac echo $users } function AddUserBackuppc() { local userToBackup="$1" # the login of the user to backup local homeDir="$2" # par exemple '/var/lib/backuppc' local userLogin='backuppc' local groupId=$(id -g $userToBackup) case $(uname) in 'Darwin') maxid=$(dscl . -list /Users UniqueID | awk '$2 < 1000 {print $2}' | sort -ug | tail -1) newid=$((maxid+1)) mkdir -p "$homeDir" id "$newid" &> /dev/null if [ $? = 0 ]; then echo "unable to find a suitable uid for user backuppc ($newid is already used)" exit $ERROR fi dscl . -create "/Users/$userLogin" dscl . -create "/Users/$userLogin" UserShell /bin/bash dscl . -create "/Users/$userLogin" RealName "backuppc" dscl . -create "/Users/$userLogin" UniqueID "$newid" dscl . -create "/Users/$userLogin" PrimaryGroupID "$groupId" dscl . -create "/Users/$userLogin" NFSHomeDirectory "$homeDir" dscl . -create "/Users/$userLogin" IsHidden 1 # hide from login window #dscl . -passwd "/Users/$userLogin" password ;; 'Linux') adduser --system --disabled-password --shell /bin/sh --home "$homeDir/" --gid "$groupId" "$userLogin" ;; esac chown -R "$userLogin:$groupId" "$homeDir" allowUserToConnectToThisMachineUsingSsh "${userLogin}" } #### VÉRIFIER QUE L’ON A BIEN LES DROITS ADMIN #### if [ "$EUID" -ne 0 ]; then printf '\e[1;31m%-6s\e[m' "À lancer avec les droits administrateur " exit fi #### NOM DU COMPTE À SAUVEGARDER #### default_user=$(getDefaultUser) printf '\e[1;34m%-6s\e[m' "liste des comptes détectés sur cette machine : $(ListUsers)" printf "\n" printf "login de l’utilisateur dont les données sont à sauvegarder ?\n [${default_user}] : " read input_login if [[ ${input_login} != "" ]]; then usr="${input_login}" else usr="${default_user}" fi #### VÉRIFIER QUE LE COMPTE EST BIEN DANS LA LISTE DES USER ID #### if ! id "${usr}" &> /dev/null; then printf '\e[1;35m%-6s\e[m' "${usr} n’apparait pas dans la liste des user ids. Continuer tout de même ? [o/N] : " read input_continue if [[ "${input_continue}" != "o" ]]; then printf '\e[1;31m%-6s\e[m' "Installation annulée." exit fi fi #### DOSSIER À SAUVEGARDER #### default_dir=$(eval echo ~${usr}) if [ ! -d "${default_dir}" ]; then default_dir="" fi printf "Par défaut, le dossier sauvegardé est le home de l’utilisateur. Il est possible d’en ajouter un supplémentaire ensuite. Dossier à sauvegarder ? [${default_dir}] : " read input_dir if [[ "${input_dir}" == "" ]]; then dir1="${default_dir}" else dir1="${input_dir}" fi #### DOSSIER À SAUVEGARDER INTROUVABLE, ANNULATION #### if [ ! -d "${dir1}" ]; then printf "\n" printf '\e[1;31m%-6s\e[m' "Dossier ${dir1} introuvable, installation annulée." printf "\n" exit fi #### DOSSIER SUPPLÉMENTAIRE #### printf "Si vous avez un dossier supplémentaire à sauvegarder (/mnt/data par exemple) entrer-le maintenant, sinon laissez vide. [] : " read input_dir2 if [[ "${input_dir2}" != "" ]]; then #### DOSSIER SUPPLÉMENTAIRE INTROUVABLE, ANNULATION DE CELUI-CI #### if [ ! -d "${input_dir2}" ]; then printf "\n" printf '\e[1;35m%-6s\e[m' "Dossier supplémentaire introuvable, non ajouté." printf "\n" else directories="'${dir1}','${input_dir2}'" fi else directories="'${dir1}'" fi # backuppc server a besoin de ping-er les clients ensurePingIsAllowed #### INSTALLATION DE OPENSSH-SERVER #### ensureSshdIsRunning if [ "$?" != "$SUCCESS" ]; then printf '\e[1;31m%-6s\e[m' "L'installation du serveur ssh a échoué, installation annulée."; exit fi hostkey=$(getMyHostKey) #printf "hostkey=$hostkey" if [ "$?" != "$SUCCESS" ]; then printf '\e[1;31m%-6s\e[m' "Clé inaccessible, merci de contacter votre administrateur réseau, installation annulée."; exit fi #### CRÉATION DU FICHIER DE CONFIGURATION #### fqdn="$(MyFqdn)" filepl="${fqdn}.pl" exclude="['ownCloud','.local/share/Trash','.cache','.Play*','.steam','.wine','Perso','temp','tmp','.Trash*','.DS_Store','._*']" echo "\$Conf{XferMethod} = 'rsync';" > "${filepl}" echo "\$Conf{RsyncShareName} = [${directories}];" >> "${filepl}" echo "\$Conf{BackupFilesExclude} = {'*' => ${exclude} };" >> "${filepl}" printf "\n" printf '\e[1;34m%-6s\e[m' "Fichier de configuration serveur créé (${filepl})" printf "\n" #### ADRESSE MAIL DE L’UTILISATEUR #### printf "Votre adresse e-mail ?\n : " read input_mail #### LE SERVEUR DOIT CONNAITRE ssh_host_ecdsa_key.pub DU CLIENT, L’ADRESSE MAIL ET L'IP #### # mis en dernière ligne du fichier pl en attendant de trouver une meilleure solution echo "# host:${fqdn}" >> "${filepl}" cmd_hostkey=$(cat "${hostkey}") echo "# hostkey:${cmd_hostkey}" >> "${filepl}" echo "# mail:${input_mail}" >> "${filepl}" echo "# ip:$(IpAddress)" >> "${filepl}" #### Déplacer le fichier dans le dossier de l'utilisateur (plus accessible) mv "${filepl}" "${dir1}" #### AJOUTER LES DROITS EN LECTURE POUR LE GROUPE #### # printf '\e[1;34m%-6s\e[m' "Ajout des droits en lecture pour le groupe sur les dossiers à sauvegarder (patience !)…" # printf "\n" # for dir in "${dir1}" "${input_dir2}"; do # find "${dir}" \( ! -regex '.*/\..*' \) -type f -exec chmod g+r {} \; # find "${dir}" \( ! -regex '.*/\..*' \) -type d -exec chmod g+rx {} \; # done #### CRÉATION DE L’UTILISATEUR BACKUPPC #### printf '\e[1;34m%-6s\e[m' "Création du compte backuppc…" printf "\n" homebackuppc='/var/lib/backuppc' AddUserBackuppc "${input_login}" "${homebackuppc}" mkdir -p -- "${homebackuppc}/.ssh" echo "from=\"129.20.203.16\" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDIhMc8ixQXfWDACJy4q0v8T877UxahhCjO51PQFzylwVpf88LX3yWeDrWIW0NRu0zoSm396mig918OpD5ggqML/QbYbQsoDdAFUV/tK4JU6UJgEQIl25MOcUBCFepsFBGS09CH/V07xSUqSP/+beeTRLNO2CQzk3S2y3YfkXpM7KmOGfeLgoCaQAcxIkgLXeM3TpCZEzJDlZ8c8k/DjVvsgwCpQktYzNo2b37KHLLfgyW9KSo6N9sReUuNQjS6lu8rjrXfc6+J0pY2D6IxWptTWL/JVrhFCUqe4QQy+xYjoR41wqnAQyl/kOcyBNhSvojMKwQT6vlPwru6pOno16/X backuppc@backuppc.ipr.univ-rennes1.fr" > $homebackuppc/.ssh/authorized_keys chown -R backuppc "$homebackuppc/.ssh/" printf "\n" printf '\e[1;34m%-6s\e[m' "Configuration du poste terminée." printf '\e[1;34m%-6s\e[m' "Envoyez bien votre fichier de configuration (${dir1}/${filepl}) à Jérémy GARDAIS ou Anthony CARRÉ." printf '\e[1;34m%-6s\e[m' "Vous pourrez affiner la configuration de votre sauvegarde depuis https://backuppc.ipr.univ-rennes1.fr" printf "\n"