servidores do Debian

3

Eu tenho dois servidores Debian, o primeiro é o operacional (principal), o último é para fins de segurança.

Eu quero ter o segundo servidor como um gêmeo do primeiro, rsyncing continuamente, a fim de mudar para ele em caso de qualquer falha do primeiro.

Estou pensando em sincronizá-los todas as noites, desta maneira:

  • sincronizar pacotes como em link
  • rsync todo o material / var / www (excluindo diretórios de cache)
  • rsync todo o diretório / etc /

Nos scripts rsync, estou colocando um controle no IP que ativa o script somente se eu estiver no servidor principal.

Minha pergunta é sobre o que devo me importar em todo esse procedimento:

  • talvez alguns arquivos / etc / devam ser excluídos da sincronização? passwd e sombra? mas eu gostaria de ter algum novo usuário propagando do servidor principal para o escravo
  • talvez algum outro diretório seja sincronizado?

Qualquer ajuda é apreciada!

    
por Paolo Benvenuto 10.10.2013 / 16:47

3 respostas

1

Pelo menos eu criei e testei meu próprio script: ele funciona perfeitamente!

Espero que possa ajudar alguém!

#!/bin/bash
# A Script which syncronizes debian packages from this server to a second server
# ssh must be able to log from user root to user root with key without password
# Execute as root

# included file defines mysql credentials:
# $MYSQL_USR, $MYSQL_PSW for backing up mysql
# $SERVER2_MYSQL_USR, $SERVER2_MYSQL_PS for inserting dumps on $SERVER2's mysql (root credentials)
# it defines $MAIL and $SERVER2, too
. /etc/bin/mysql_secrets

# the script which will be executed on SERVER2
SCRIPT=/root/aptshell.sh

# files to generate in order to sync the packages
list_installed_on_second_server=/root/installed_packages_on_$SERVER2
list_manually_installed_on_second_server=/root/installed_packages_manually_on_$SERVER2

# the timeout for package install on SERVER2: we must set it because some install keeps waiting for a user answer even if the -y option is given to aptitude install
TIMEOUT=120

# the directory where mysql backups are stored
MYSQL_BACKUPS_DIR='/var/backups/dbbackups'
# if the directory doesn't exist, create it
/bin/mkdir -p ${MYSQL_BACKUPS_DIR}

NICE='/usr/bin/nice -n 19'

# file which lists the files in /etc not to rsync to SERVER2
EXCLUDE_ETC_FILES=/etc/bin/rsync_etc.exclude.conf

# Don't execute this script on SERVER2
echo $SERVER2 | grep 'hostname' > /dev/null && exit 0

# this variable prevents apt-get/aptitude to run interactively
export DEBIAN_FRONTEND=noninteractive

# reset the script on SERVER2
rm $SCRIPT
touch $SCRIPT

shopt -s expand_aliases
alias date='date +"%H:%M.%S"'

echo "===================================================================="
date
echo "Executing apt-get update on $SERVER2"
echo "===================================================================="
echo
ssh $SERVER2 $NICE /usr/bin/aptitude -q update > /dev/null || { echo && echo "APT-GET UPDATE ERROR - STOPPING SCRIPT AND EXITING" && rm $SCRIPT && exit 1; }

echo "===================================================================="
date
echo "Generating installed packages lists on $SERVER2"
echo "===================================================================="
echo
ssh $SERVER2 $NICE "/usr/bin/aptitude -F '%p' --disable-columns search '~i !~M' > $list_manually_installed_on_second_server"
ssh $SERVER2 $NICE "/usr/bin/aptitude -F '%p' --disable-columns search '~i' > $list_installed_on_second_server"

echo 'echo' >> $SCRIPT
echo 'echo "==========================="' >> $SCRIPT
echo 'echo "==========================="' >> $SCRIPT
echo 'echo "Begin script execution on '$SERVER2'"' >> $SCRIPT
echo 'echo "==========================="' >> $SCRIPT
echo 'echo "==========================="' >> $SCRIPT
echo 'echo' >> $SCRIPT

echo "===================================================================="
date
echo "Generating list of packages remove commands for $SERVER2"
echo "===================================================================="
echo
echo 'echo "==========================="' >> $SCRIPT
echo 'echo "Removing from '$SERVER2' the packages not on ''hostname''"' >> $SCRIPT
# insert in script the command which remove from SERVER2 the packages non installed here and installed there
$NICE /usr/bin/aptitude  --disable-columns search . | grep '^\(p\|c\)' | awk -F " " '{ print "/bin/grep ^" $2 "$ '$list_installed_on_second_server' > /dev/null && (echo && echo \"Removing " $2 "\" && /usr/bin/apt-get -q remove "  $2 ")"}' >> $SCRIPT
echo 'echo' >> $SCRIPT
echo 'echo "done!"' >> $SCRIPT
echo 'echo "==========================="' >> $SCRIPT
echo 'echo' >> $SCRIPT

echo "===================================================================="
date
echo "Generating packages autoremove commands for $SERVER2"
echo "===================================================================="
echo
echo 'echo "==========================="' >> $SCRIPT
echo 'echo "Autoremoving packages on ' $SERVER2 '..."' >> $SCRIPT
echo 'apt-get -q autoremove > /dev/null' >> $SCRIPT
echo 'echo "done!"' >> $SCRIPT
echo 'echo "==========================="' >> $SCRIPT
echo 'echo' >> $SCRIPT

echo "===================================================================="
date
echo "Generating list of packages install commands for $SERVER2"
echo "===================================================================="
echo
echo 'echo "==========================="' >> $SCRIPT
echo 'echo "Installing on '$SERVER2' the packages present on ''hostname''"' >> $SCRIPT
# insert in script the command which install on SERVER2 the packages installed here and not there
$NICE /usr/bin/aptitude -F "%p" --disable-columns search '!~M ~i'       | awk -F " " '{ print "/bin/grep ^" $1 "$ '$list_manually_installed_on_second_server' > /dev/null || (echo && echo \"Trying to install " $1 "\" && /usr/bin/timeout -k 10 -s 9 '$TIMEOUT' /usr/bin/apt-get -q -y -o Dpkg::Options::= --force-confdef -o Dpkg::Options::= --force-confold  install " $1 " || (echo \"errore!\" && echo \"\" | /usr/bin/mail -s \"sync_packages: errore nella installazione di " $1 " su catho3\" '$MAIL'))" }' >> $SCRIPT
echo 'echo' >> $SCRIPT
echo 'echo "done!"' >> $SCRIPT
echo 'echo "==========================="' >> $SCRIPT
echo 'echo' >> $SCRIPT

echo 'echo "==========================="' >> $SCRIPT
echo 'echo "==========================="' >> $SCRIPT
echo 'echo "End script execution on '$SERVER2'"' >> $SCRIPT
echo 'echo "==========================="' >> $SCRIPT
echo 'echo "==========================="' >> $SCRIPT
echo 'echo' >> $SCRIPT

echo "===================================================================="
date
echo "Copying script to $SERVER2"
echo "===================================================================="
scp $SCRIPT $SERVER2:$SCRIPT > /dev/null

# exec script on SERVER2
ssh $SERVER2 sh $SCRIPT

# /etc/ isn't 'git updated' because etckeeper does the job

echo "===================================================================="
date
echo "Sync /etc"
echo "===================================================================="
echo
# save old /etc on SERVER2
ssh $SERVER2 $NICE /usr/bin/rsync -avq --delete /etc/ /etc.old
# sync /etc
$NICE /usr/bin/rsync --delete -avzq --exclude-from=$EXCLUDE_ETC_FILES -e ssh /etc/ $SERVER2:/etc


echo "===================================================================="
date
echo "Execute mysql backups, sync them to $SERVER2 and import them on $SERVER2's mysql"
echo
echo "1. Cycle on the db's and dump them"
echo "   "'date'
echo
for DB in $(/usr/bin/mysql --user=$MYSQL_USR --password=$MYSQL_PSW -e 'show databases' -s --skip-column-names | grep -viE '(staging|performance_schema|information_schema)' )
do
    echo "   $DB"

    if [ $DB = 'mysql' ]
    then
        EVENTS='--events'
    else
        EVENTS=''
    fi

    # don't compress: backups are kept in a git repository
    /usr/bin/nice -n 19 \
    /usr/bin/mysqldump --user=$MYSQL_USR --password=$MYSQL_PSW $EVENTS --skip-opt --no-autocommit --extended-insert --add-drop-table --add-locks --create-options --disable-keys --complete-insert --lock-tables --quick --default-character-set='utf8' --databases $DB > $MYSQL_BACKUPS_DIR/$DB.sql

    # in case of error, report it
    if [ $? -ne 1 ]
    then
        sed -i '1s/^/SET FOREIGN_KEY_CHECKS=0;\n/' $MYSQL_BACKUPS_DIR/$DB.sql
        echo 'SET FOREIGN_KEY_CHECKS=1;' >> $MYSQL_BACKUPS_DIR/$DB.sql
    else
        echo "Error dumping $DB db"
    fi
done

echo
echo "2. Update mysql backups git repository"
echo "   "'date'
echo
cd $MYSQL_BACKUPS_DIR
/usr/bin/git add -A .
/usr/bin/git commit -q -a -m 'notturno'

echo
echo "3. Sync mysql backups from here to $SERVER2"
echo "   "'date'
echo
$NICE /usr/bin/rsync --delete -avq -e ssh $MYSQL_BACKUPS_DIR/ $SERVER2:$MYSQL_BACKUPS_DIR

echo
echo "4. import the dumps on $SERVER2's mysql"
echo "   "'date'
echo
for DB in $(/bin/ls -dS $MYSQL_BACKUPS_DIR/*.sql)
do
    echo "   "'date'
    echo "   $DB"
    NUMLINES='git diff -U0 HEAD HEAD^ $DB | wc -l'
    if [ $NUMLINES -gt 7 ]
    then
        echo
        ssh $SERVER2 "$NICE /usr/bin/mysql -u $SERVER2_MYSQL_USR -p$SERVER2_MYSQL_PSW < $DB"
    else
        echo "     *** No change: skipped"
        echo
    fi
done

echo "===================================================================="
date
echo "Update /var/wwwc git repository"
echo "===================================================================="
echo
cd /var/wwwc
/usr/bin/git add -A .
/usr/bin/git commit -q -a -m 'notturno'

echo "===================================================================="
date
echo "Sync /var/wwwc to $SERVER2"
echo "===================================================================="
echo
$NICE /usr/bin/rsync --delete -avzq -e ssh /var/wwwc/ $SERVER2:/var/wwwc

echo "===================================================================="
date
echo "Update /var/wwwc git repository"
echo "===================================================================="
echo
cd /var/wwwq
/usr/bin/git add -A .
/usr/bin/git commit -q -a -m 'notturno'

echo "===================================================================="
date
echo "Sync /var/wwwq to $SERVER2"
echo "===================================================================="
echo
$NICE /usr/bin/rsync --delete -avzq -e ssh /var/wwwq/ $SERVER2:/var/wwwq

echo "===================================================================="
date
echo "Sync /usr/share/gitweb directory"
echo "===================================================================="
echo
$NICE /usr/bin/rsync --delete -avzq -e ssh /usr/share/gitweb/ $SERVER2:/usr/share/gitweb

echo "===================================================================="
echo "Create missing /var/cache/* directories on $SERVER2 and set proper owner"
echo "===================================================================="
echo

for DIR in $(/bin/ls -d -1 /var/cache/*)
do
    OWNER='ls -ld $DIR  | awk '{print $3}''
    #echo $DIR $OWNER
    ssh -n $SERVER2 /bin/mkdir -p $DIR
    ssh -n $SERVER2 /bin/chown $OWNER:$OWNER $DIR
done

echo "===================================================================="
date
echo -n "Reboot $SERVER2? "
# Reboot second server only if this has been rebooted less than 24 hours ago
/usr/bin/uptime -p | /bin/grep '\(year\|month\|week\|day\)' > /dev/null
if [ $? -ne 0 ] ; then
    echo "Yes!!!!!"
    ssh $SERVER2 /sbin/reboot
else
    echo "No"
    echo
    echo "===================================================================="
    date
    echo "Restart services on $SERVER2"
    echo "===================================================================="
    echo
    # I must restart various service, in the case their config files have changed
    for SERVICE in apache2 varnish mysql memcached dovecot postfix fail2ban
    do
        echo $SERVICE restarted
        ssh $SERVER2 $NICE /usr/sbin/service $SERVICE restart
    done

    echo
    echo "===================================================================="
    date
    echo "Script ended"
    echo "===================================================================="
fi
Arquivos

Críticos , etc, que não devem ser sincronizados: arquivo rsync_etc.exclude.conf:

/.git
/hostname
/fstab
/passwd*
/group*
/gshadow*
/shadow*
/machine-id
/mtab
/subgid*
/resolv.conf
/udev/rules.d/70-persistent-net.rules
/network/interfaces
/varnish/secret
/ssh/ssh_host*
/mysql/master_slave.cnf
    
por 24.07.2015 / 23:04
3

O que você está basicamente perguntando é Como faço para configurar um sistema onde eu possa ter um ambiente de desenvolvimento idêntico ao meu ambiente de produção para auditoria de segurança, testes, etc.?

Os dois comentários acima fornecem metade da sua resposta:

Para configuração do servidor e software / patches
Você provavelmente quer algo como Puppet / Chef / Radmind .
Essas ferramentas podem ser usadas para garantir que seus servidores sejam "idênticos" - executando o mesmo software, com as mesmas configurações (ou "configurações semelhantes o suficiente que as diferenças não importam" - ou seja, diferindo apenas em endereços IP, SSL certs , etc.)

Aqui também é onde você gerencia algo como /etc/passwd para garantir que os usuários (nomes de usuário e UID / GIDs numéricos) sejam sincronizados entre as máquinas e tudo corresponda.

Para seu próprio software ( /var/www em seu exemplo acima)
Você definitivamente quer algum tipo de sistema de controle de versão aqui.
Você pode verificar o conteúdo diretamente em cada máquina ou pode empacotar e distribuir usando as ferramentas mencionadas acima.

Ambas as maneiras de lidar com o seu software têm benefícios e desvantagens a considerar - você está em uma posição melhor para decidir qual opção você deseja usar com base nas suas necessidades.
Uma maneira típica de desenhar a linha é "Se precisar ser compilada, ela deve ser empacotada e distribuída. Se forem scripts e dados, poderão ser verificados diretamente".

    
por 10.10.2013 / 21:09
-3

Apenas sincronize pacotes e dados. Não há necessidade de clonar todos os arquivos.

    
por 10.10.2013 / 19:00