среда, 8 апреля 2009 г.

Бэкап удаленного сервера с помощью rsync с сертификатом

Наконец-то дошли руки сделать бэкап сервера на другую машину. Соответственно, потребовалось обеспечить из скрипта доступ на удаленный сервер без указания пароля и непосредственно создание бэкапа (инкрементального). Беспарольный доступ обеспечить понятно как - создать сертификат. Потом пытался замонтировать через fuse sshfs, но тут sudo требует пароль. Некоторые размышления и rtfm показали, что rsync умеет пользоваться сертификатами для доступа на удаленный хост, после чего все стало совершенно понятным. Итак, необходимая последовательность действий заключается в следующих шагах:

1. Создаем сертификат на сервере-приемнике
Маны написаны коряво и трудно понять, где и что следует выполнять. Но на самом деле все просто. На той машине, откуда мы будем ходить на целевой сервер, создаем сертификат RSA длиной 2048 бит вот такой командой:
ssh-keygen -t rsa
По умолчанию он будет записан в файл ~/.ssh/id_rsa.pub. Ключевую фразу не указываем.

2. Копируем сертификат на сервер-источник нужному пользователю
Заходим в каталог сертификатов нужного пользователя
cd ~/.ssh
и добавляем новый сертификат к списку доверенных сертьификатов пользователя
cat id_rsa.new >>authorized_keys

3. Ставим в крон от имени нужного пользователя команду инкрементального бэкапа на сервере-приемнике
rsync -avz user@host:/SRC /DEST/
Замечу, что если указать / после SRC, то скопируется только содержимое директории SRC, а без / будет создана директория с указанным содержимым в каталоге назначения.

Вот что записано в крон
crontab -l

SHELL=/bin/bash
MAILTO=user
0 0-23 * * * /usr/bin/rsync -avz user@host:/SRC /DEST/


4. Опционально - на сервере-источнике ставим в крон команду создания бэкапа
Если нужно сделать резервную копию не просто файлов, можно написать соответствующий скрипт. Приведу пример создания дампа базы PostgreSQL.

Вот что записано в крон
crontab -l

SHELL=/bin/bash
MAILTO=user
0 6 * * * /home/user/backup/site.tcl


cat /home/user/backup/site.tcl

#!/usr/bin/tclsh

set pglib_path "/usr/lib/libpgtcl1.5/libpgtcl1.5.so"
load $pglib_path

set pg_host ...
set pg_dbname ...
set pg_user ..
set pg_port ...
set pg_cluster ...

set path /home/user/backup/site/
set tm [clock format [clock seconds] -format "%Y-%m-%d_%H:%M:%S"]

if { [catch { exec /usr/bin/pg_dump -E win --cluster $pg_cluster \
-h $pg_host -p $pg_port -U postgres -F p -a --disable-triggers -f \
$path/$tm\_restore.sql $pg_dbname >/dev/null} msg] } {
puts "Information about it: $::errorInfo"
}

if { [catch { exec /usr/bin/pg_dump -E win --cluster $pg_cluster \
-h $pg_host -p $pg_port -U postgres -F p -s --disable-triggers -f \
$path/$tm\_schema.sql $pg_dbname >/dev/null} msg] } {
puts "Information about it: $::errorInfo"
}

if { [catch { exec /bin/tar -cjf $path/$tm.tar.bz2 \
$path/$tm\_restore.sql $path/$tm\_schema.sql >/dev/null} msg] } {
puts "Information about it: $::errorInfo"
}

file delete $path/$tm\_restore.sql
file delete $path/$tm\_schema.sql


Вот и все, теперь сервер приемник ежечасно будет проверять наличие новых файлов на сервере-источнике и при их обнаружении копировать эти файлы. rsync использует эффективное сжатие, что экономит трафик и время. Приведенные выше рекомендации несложно повторить для необходимого количества сайтов.

P.S. Есть еще мысль воспользоваться локальной системой контроля версий для отслеживания изменений на удаленном сервере, но это когда время будет. Идея именно в том, чтобы иметь возможность локально отслеживать изменения, что позволит обнаружить как различные технические проблемы, так и злонамеренную модификацию файлов.

Комментариев нет:


(C) Alexey Pechnikov aka MBG, mobigroup.ru