Хроники переезда, или как все сделать правильно при переезде блога.

Как и писал ранее — ресурс стал лучше. Изменения произошли в следующем:

  1. Новый отдельный сервер
  2. Новый домен
  3. Новый алгоритм работы

Ну и раз на то пошло — было принято решение сделать все «по феншую». Тем более, что предполагается расположение на сервере не одного ресурса, а нескольких, в том числе и людей, не очень сведущих. Консоль «как-у-крутых-провайдеров», где все делается тремя кликами мышки, на оборудование подобного класса ставить смешно, но я постарался максимально упростить жизнь себе и людям.

Итак, под катом — описание процесса феншуйного переезда и настройки сервера для работы наших ресурсов.

Приступим »

FTP. Попадай куда надо.

Как описано выше — предполагается совместное использование ресурсов сервера несколькими группами людей с разными задачами. Соответственно, хотелось бы по максимуму разделить права на использование директорий пользователей и их доступ к ресурсам друг друга. Другими словами, хотелось бы попадать строго в директорию с сайтом конкретного пользователя, залогинившись под именем конкретного пользователя.

Для реализации данного условия был выбран простой способ — установка новой версии vsftpd, поддерживающего соответствующие директивы.

Код под катом для простоты чтения »

add-apt-repository ppa:thefrontiergroup/vsftpd
apt-get update
apt-get install vsftpd
nano /etc/vsftpd.conf
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES

local_root=/var/www/$USER
user_sub_token=$USER
allow_writeable_chroot=YES

Разрешаем логиниться локальным пользователя с правами на запись, и chrootим их в конкретную папку внутри /var/www

Осторожно, директива allow_writeable_chroot работает только на последних версиях vsftpd. В более ранних — приводит к падению сервиса при попытке записи в директорию.

Вебсерверы. Перекладывание с больной головы на здоровую

На старом месте обработкой всех веб-запросов занимался apache.

На новом было принято решение использовать связку nginx+apache.

Зачем? Для экономии ресурсов и увеличения отказоустойчивости. Например, на apache при 100 подключенных пользователях мы получим 100 процессов httpd, на каждый из которых будет выделена оперативная память, и эта память не освободится до тех пор, пока клиент не получит запрошенный контент.

В случае схемы с применением связки nginx+apache мы получим значительную экономию системных ресурсов за счет того, что после того как пришел запрос клиента, nginx передает запрос apache и быстро получает ответ. В итоге apache после того как отдал ответ nginx освобождает память, далее с клиентом взаимодействует web сервер nginx, который как раз и написан для раздачи статического контента, большому количеству клиентов, при незначительном потреблении системных ресурсов.

apt-get install apache2
a2enmod rewrite
apt-get install nginx
apt-get install php5-cli

Настроим apache:

Код под катом »

Чтобы апач работал в качестве back-end, нужно перевесить его с 80 порта (который будет слушать nginx) на какой-нибудь другой.

Подредактируем /etc/apache2/ports.conf:

NameVirtualHost *:8098
Listen 8098

Создадим и настроим виртуалхосты:

touch /etc/apache/sites-available/sigillite.net
touch /etc/apache/sites-available/crm.sigillite.net
nano /etc/apache2/sites-available/sigillite.net
<VirtualHost *:8098>
ServerName sigillite.net
ServerAlias www.sigillite.net sigillite.net
ErrorLog ${APACHE_LOG_DIR}/apache2/sigillite.net-error.log
CustomLog ${APACHE_LOG_DIR}/sigillite.net-access.log combined

 DocumentRoot /var/www/user/pathtosite
        <Directory />
                Options FollowSymLinks
                AllowOverride All
        </Directory>

<Directory /var/www/user/pathtosite>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
</Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
        
</VirtualHost>

Включаем сайт

a2ensite sigillite.net

Настроим nginx:

Код под катом »

Создадим и настроим виртуалхост для нашего сайта

touch /etc/nginx/sites-available/sigillite.net
nano /etc/nginx/sites-available/sigillite.net
server {
listen   80;
server_name sigillite.net www.sigillite.net;
#куда писать логи
access_log /var/log/nginx/sigillite.net.access.log;
error_log /var/log/nginx/sigillite.net.error.log;

#переадресуем динамический контент на apache
location / {
            proxy_pass http://sigillite.net:8098/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_connect_timeout 120;
            proxy_send_timeout 120;
            proxy_read_timeout 180;
           }
#отдаем статический контент через nginx
location ~* .(jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt)$ 
{
root /var/www/user/pathtosite;
}

Добавим редирект со старого доменного имени

touch /etc/nginx/sites-available/sigillite.triolan.net.ua
nano /etc/nginx/sites-available/sigillite.triolan.net.ua
server {
    listen 80;
    server_name sigillite.triolan.net.ua www.sigillite.triolan.net.ua;
    return 301 $scheme://sigillite.net$request_uri;
}

Таким образом любой запрос по старому доменному имени будет перенаправлен на новый домен с сохранением параметров.

Осталось включить сайт. В nginx специальной утилиты для включения (вроде a2ensite у apache) нет, поэтому сделаем симлинк руками:

ln -s /etc/nginx/sites-available/sigillite.net /etc/nginx/sites-enabled/sigillite.net

После всех этих действий у нас все должно взлететь. Осталось перезапустить сервисы.

Я использую Debian и слегка консервативен, поэтому так:

/etc/init.d/apache2 restart
/etc/init.d/nginx restart

Для желающих есть HOWTO по полному переезду блога на WordPress на nginx, но я пока не решился.

Перенос сайта

Ну тут особо и писать не о чем.

Экспорт базы на старой машине — импорт базы на новой машине. Для упрощения — можно использовать phpmyadmin,  тогда все сводится к 5 кликам мышью.

Копирование папки сайта на старой машине -разворачивание папки сайта на новой машине.

Защита.

В качестве инструмента защиты используем fail2ban.

apt-get install fail2ban

В нем задействуем несколько стандартных jail-ов (файл /etc/fail2ban/jail.conf):

  • ssh
  • ssh-ddos
  • vsftpd
  • apache

Единственное что поменял в их конфигурации — опцию Bantime с 600 до 1800 сек

Кроме того, для дополнительной защиты напишем пару своих.

Подробнее »

в /etc/fail2ban/jail.conf добавим следующее:

[notfound]
enabled = true
filter = notfound
action = iptables-multiport[name=notfoundjail, port="80,443", protocol=tcp]
sendmail-whois[name=notfoundjail, dest=mymail@mailserver.net, sendername="Fail2Ban"]
logpath = /var/log/apache*/*error.log
findtime = 60
maxretry = 2
bantime = 1800

[phpmyadmin-internal]
enabled = true
filter = phpmyadmin-int
action = iptables-multiport[name=phpMyAdmin-internal, port="80,443", protocol=tcp]
sendmail-whois[name=phpMyAdmin-internal, dest=mymail@mailserver.net, sendername="Fail2Ban"]
logpath = /var/log/messages
findtime = 60
maxretry = 2
bantime = 1800

Тут мы создаем 2 правила: первое будет искать попытки доступа к разнообразным веб-интерфейсам, а второй — попытки логина с неверным именемпаролем в phpmyadmin.

в /etc/fail2ban/filter.d создаем файлы правил:

touch /etc/fail2ban/filter.d/notfound.conf
touch /etc/fail2ban/filter.d/phpmyadmin-int.conf

Первый фильтр содержит регекспы для поиска попыток доступа к разнообразным веб-интерфейсам вебсервера

[Definition]
docroot = /var/www/
badadmin = PMA|phpmyadmin|myadmin|mysql|mysqladmin|sqladmin|mypma|admin|xampp|mysqldb|mydb|db|pmadb|phpmyadmin1|phpmyadmin2

failregex = [[]client <HOST>[]] File does not exist: %(docroot)s/(?:%(badadmin)s)
            [client <HOST>] File does not exist:.*(?i)manager.*
            [client <HOST>] File does not exist:.*(?i)setup.*
            [client <HOST>] File does not exist:.*(?i)mysql.*
            [client <HOST>] File does not exist:.*(?i)sqlweb.*
            [client <HOST>] File does not exist:.*(?i)webdb.*
            [client <HOST>] File does not exist:.*(?i)pma.*
            [client <HOST>] File does not exist:.*(?i)vtigercrm.*
            ^<HOST>.*GET.*(?i)admin.*
            ^<HOST>.*GET.*(?i)manager.*
            ^<HOST>.*GET.*(?i)setup.*
            ^<HOST>.*GET.*(?i)mysql.*
            ^<HOST>.*GET.*(?i)sqlweb.*
            ^<HOST>.*GET.*(?i)webdb.*
            ^<HOST>.*GET.*(?i)pma.*
            ^<HOST>.*GET.*(?i)vtigercrm.*

ignoreregex =

Второй содержит всего 1 регексп:

[Definition]

failregex =  <HOST> - ERROR AUTH phpMyAdmin

ignoreregex =

Для работы второго регекспа нужно внести небольшие изменения в код модуля авторизации phpmyadmin(ссылка)

 Оптимизация

До оптимизации непосредственно WordPress руки еще не дошли, но вот ряд оптимизаций производительности других компонентов:

Здесь »

Mysql

Для оптимизации базы пользовался вот этим скриптом и рекомендациями вот этой статьи.

robots.txt

Поисковые боты (особенно неверно настроенные) создают немалую нагрузку на ресурс. Поэтому лучше создать файл robots.txt в корне сайта, который будет отсекать запросы неугодных ботов. Для генерации файла можно использовать этот ресурс.

Отсекание неугодных

Про это позже будет отдельная статья, но вот 1 фокус на базе mod_rewrite для посылания неугодных:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteOptions inherit
RewriteBase /
RewriteCond %{QUERY_STRING} ^orderby=rand
RewriteRule ^(.*)$ http://linux.org.ru/$1%1/? [R=301,L]
</IfModule>

посылает злого бота, который раз в секунду запрашивает главную страницу сайта с рандомной сортировкой статей (что довольно неслабо грузит базу) на linux.org.ru )

Надеюсь, данная статья будет полезна общественности.

Приму в комментариях любые замечания.

Добавить комментарий

Войти с помощью: