Подготовим конфигурацию и реализуем непосредственно зеркалирование.
Добавим в систему пользователя, от имени которого будем запускать скрипты зеркалирования ресурсов:
# groupadd mirrorer
# useradd --shell /bin/sh --home-dir /var/lib/mirrorer --gid mirrorer mirrorer
# useradd --shell /bin/sh --home-dir /var/lib/mirrorer --gid mirrorer mirrorer
Создадим ему место жительства:
# mkdir -p /var/lib/mirrorer
# chown -R mirrorer:mirrorer /var/lib/mirrorer
# mkdir -p /var/www/mirror.local
# chown -R mirrorer:mirrorer /var/www/mirror.local
# mkdir -p /var/log/mirrorer
# chown -R mirrorer:mirrorer /var/log/mirrorer
# chown -R mirrorer:mirrorer /var/lib/mirrorer
# mkdir -p /var/www/mirror.local
# chown -R mirrorer:mirrorer /var/www/mirror.local
# mkdir -p /var/log/mirrorer
# chown -R mirrorer:mirrorer /var/log/mirrorer
Инсталлируем утилиты:
# aptitude install wget psmisc
Пишем скрипт зеркалирования:
# mkdir -p /etc/custom/mirrorer
# touch /etc/custom/mirrorer/mirror.sh
# chmod ugo+x /etc/custom/mirrorer/mirror.sh
# touch /etc/custom/mirrorer/mirror.sh
# chmod ugo+x /etc/custom/mirrorer/mirror.sh
# cat /etc/custom/mirrorer/mirror.sh
#!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
# Формируем командную строку с общими для всех запускаемых экземпляров опциями
PROG="wget --background --tries=25 --timestamping --timeout=60 --wait=2 --random-wait --no-parent --force-directories --recursive --level=7 --directory-prefix=/var/www/mirror.local"
# По простому выгружаем все запущенные экземпляры Wget, не успевшие завершить свою работу с момента предыдущего запуска
killall --signal SIGKILL wget
# Обновляем зеркало ftp://ftp.salyk.kz/
LOG="--append-output=/var/log/mirrorer/ftp.salyk.kz.log"
SITE="ftp://ftp.salyk.kz/"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
# Обновляем зеркало ftp://rcpi.kz/
LOG="--append-output=/var/log/mirrorer/rcpi.kz.log"
SITE="ftp://rcpikz_files:12345@rcpi.kz/"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
# Обновляем зеркало антивирусной утилиты "drweb-cureit.exe"
LOG="--append-output=/var/log/mirrorer/download.geo.drweb.com.pub.drweb.cureit.drweb-cureit.log"
SITE="http://download.geo.drweb.com/pub/drweb/cureit/drweb-cureit.exe"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
# Обновляем зеркало баз антивируса DrWeb
LOG="--append-output=/var/log/mirrorer/download.geo.drweb.com.pub.drweb.bases.log"
SITE="http://download.geo.drweb.com/pub/drweb/bases/"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
# Обновляем зеркало антивирусной утилиты "avz4.exe"
LOG="--append-output=/var/log/mirrorer/z-oleg.com.avz4.zip.log"
SITE="http://z-oleg.com/avz4.zip"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
# Обновляем зеркало баз антивирусной утилиты "avz4.exe"
LOG="--append-output=/var/log/mirrorer/z-oleg.com.secur.avz_up.avzbase.zip.log"
SITE="http://z-oleg.com/secur/avz_up/avzbase.zip"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
exit 0
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
# Формируем командную строку с общими для всех запускаемых экземпляров опциями
PROG="wget --background --tries=25 --timestamping --timeout=60 --wait=2 --random-wait --no-parent --force-directories --recursive --level=7 --directory-prefix=/var/www/mirror.local"
# По простому выгружаем все запущенные экземпляры Wget, не успевшие завершить свою работу с момента предыдущего запуска
killall --signal SIGKILL wget
# Обновляем зеркало ftp://ftp.salyk.kz/
LOG="--append-output=/var/log/mirrorer/ftp.salyk.kz.log"
SITE="ftp://ftp.salyk.kz/"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
# Обновляем зеркало ftp://rcpi.kz/
LOG="--append-output=/var/log/mirrorer/rcpi.kz.log"
SITE="ftp://rcpikz_files:12345@rcpi.kz/"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
# Обновляем зеркало антивирусной утилиты "drweb-cureit.exe"
LOG="--append-output=/var/log/mirrorer/download.geo.drweb.com.pub.drweb.cureit.drweb-cureit.log"
SITE="http://download.geo.drweb.com/pub/drweb/cureit/drweb-cureit.exe"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
# Обновляем зеркало баз антивируса DrWeb
LOG="--append-output=/var/log/mirrorer/download.geo.drweb.com.pub.drweb.bases.log"
SITE="http://download.geo.drweb.com/pub/drweb/bases/"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
# Обновляем зеркало антивирусной утилиты "avz4.exe"
LOG="--append-output=/var/log/mirrorer/z-oleg.com.avz4.zip.log"
SITE="http://z-oleg.com/avz4.zip"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
# Обновляем зеркало баз антивирусной утилиты "avz4.exe"
LOG="--append-output=/var/log/mirrorer/z-oleg.com.secur.avz_up.avzbase.zip.log"
SITE="http://z-oleg.com/secur/avz_up/avzbase.zip"
/bin/su -s /bin/bash -l mirrorer -c "${PROG} ${LOG} ${SITE}"
exit 0
Где, опции Wget в скрипте зеркалирования:
"--background" - Переводим приложение в фоновый режим после запуска;
"--timestamping" - Включаем проверку актуальности файлов по дате их создания;
"--timeout=seconds" - Указываем время ожидания ответа сервера в секундах (по умолчанию время ожидания равно 900 секундам; 0 - отменяет проверку времени ожидания);
"--wait=seconds" - Устанавливаем длительность паузы в секундах между несколькими загрузками для снижения загруженности зеркалируемого сервера (в минутах - "m", в часах - "h", в днях - "d" после значения);
"--random-wait" - Указываем применить специальную методику псевдослучайного вычисления времени задержек между загрузками при рекурсивном обходе для маскировки Wget под обычное приложение (некоторые серверы контента, совершая формирование файлов журналов с паузами запросов файлов, могут определить рекурсивную загрузку файлов и заблокировать отдачу);
"--force-directories" - Указываем создавать структуру папок, начиная с корня запрашиваемого ресурса;
"--recursive" - Включаем рекурсивную загрузку;
"--level=depth" - Уточняем максимальную глубину уровней рекурсивной загрузки (по умолчанию значение равно 5).
"--timestamping" - Включаем проверку актуальности файлов по дате их создания;
"--timeout=seconds" - Указываем время ожидания ответа сервера в секундах (по умолчанию время ожидания равно 900 секундам; 0 - отменяет проверку времени ожидания);
"--wait=seconds" - Устанавливаем длительность паузы в секундах между несколькими загрузками для снижения загруженности зеркалируемого сервера (в минутах - "m", в часах - "h", в днях - "d" после значения);
"--random-wait" - Указываем применить специальную методику псевдослучайного вычисления времени задержек между загрузками при рекурсивном обходе для маскировки Wget под обычное приложение (некоторые серверы контента, совершая формирование файлов журналов с паузами запросов файлов, могут определить рекурсивную загрузку файлов и заблокировать отдачу);
"--force-directories" - Указываем создавать структуру папок, начиная с корня запрашиваемого ресурса;
"--recursive" - Включаем рекурсивную загрузку;
"--level=depth" - Уточняем максимальную глубину уровней рекурсивной загрузки (по умолчанию значение равно 5).
Солянку из опций "--timeout", "--wait" и "--random-wait" приходится применять специально для более или менее корректного отрабатывания с FTP серверами, настроенными нашими отечественными криворукими "админами". Много странного и забавного приходится наблюдать, объяснения далеко не всему находится; шедевр администраторов сайта "ftp://rcpi.kz", применивших для анонимного доступа публикуемый нестандартный логин и пароль - тому пример.
Автоматизируем запуск скрипта с помощью Crontab. Думаю, что две актуализации в течении суток зеркала для сети из сотен пользователей не будет сочтено DDoS атакой на серверы контента.
....
1 */12 * * * root /etc/custom/mirrorer/mirror.sh &
....
1 */12 * * * root /etc/custom/mirrorer/mirror.sh &
....
Wget прост и незатейлив - как "колун". Упомянутое орудие труда дровосека весьма эффективно, но не всегда удобно для человека, не ночевавшего в яме под корнями дерева на подстилке из "лапника". Так и Wget, имеет ряд недостатков, на некоторые из которых можно закрыть глаза, а какие то обойти с помощью сторонних приложений.
В частности, одно из неудобств, которое проще проигнорировать, чем устранять - создание директорий с текущей датой и временем сервера, а не той датой и временем, с которой таковые были созданы на зеркалируемом ресурсе; это при том, что с файлами такого не происходит, там всё, как положено.
Ещё одно неудобство, вред от которого следует минимизировать - невозможность явно разделить ещё закачиваемый и уже закачанный файл по имени. Со стороны определить это можно только по непрерывно изменяющемуся размеру и времени создания и модификации. Непременно случится так, что пользователь запросит себе файл, который Wget ещё докачивает, а, учитывая то, что "человеко воспринимаемых" признаков различия нет - он получит "битый" файл. Я вижу два пути решения этой проблемы. Первый, примитивный и не наш - зеркалировать ресурсы в отдельную директорию и только после завершения процесса копировать все файлы в место, доступное пользователям. Второй и более изящный - проверка состояния файла перед его выдачей пользователю и уведомления о неоконченной загрузке, буде такое обнаружиться.