Как и писал ранее — ресурс стал лучше. Изменения произошли в следующем:
- Новый отдельный сервер
- Новый домен
- Новый алгоритм работы
Ну и раз на то пошло — было принято решение сделать все «по феншую». Тем более, что предполагается расположение на сервере не одного ресурса, а нескольких, в том числе и людей, не очень сведущих. Консоль «как-у-крутых-провайдеров», где все делается тремя кликами мышки, на оборудование подобного класса ставить смешно, но я постарался максимально упростить жизнь себе и людям.
Итак, под катом — описание процесса феншуйного переезда и настройки сервера для работы наших ресурсов.
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 )
Надеюсь, данная статья будет полезна общественности.
Приму в комментариях любые замечания.