понедельник, 26 октября 2009 г.

Устанавливаем OpenVZ на Debian 5 lennty (часть №1)

Раскрыл для себя очень полезное свойство системы виртуализации - при смене dedicated хостинга достаточно перенести виртуальную машину с сайтом в другое место, капельку похимичить и все опять побежало. Никаких тебе кропотливых настроек и длительных инсталляций, да и backup делать просто. Еще одним полезным свойством является то, что даже если злоумышленник вскроет сайт, то попортить он может только виртуальную машину, которая быстро восстанавливается из backup. Надеюсь я всех убедил?

Сперва ставим новое ядро с поддержкой OpenVZ (внимание для другой платформы, такой как x64, имя может быть другое):

  1. apt-get install linux-image-2.6-openvz-686

Перегружаемся и проверяем что все в порядке - ядро поменялось:

  1. uname -a

Далее, если нужно поднимаем поддержку ipset. Теперь необходимо настроить apt для доступа в OpenVZ репозиторий. Добавляем следующую строчку в /etc/apt/sources.list:

  1. deb http://download.openvz.org/debian-systs etch openvz

Создаем или правим /etc/apt/preferences:

  1. Package: *
  2. Pin: release a=lenny
  3. Pin-Priority: 700
  4.  
  5. Package: *
  6. Pin: release a=etch
  7. Pin-Priority: 650

Создаем или правим /etc/apt/apt.conf:

  1. APT::Default-Release "stable";

Загружаем ключи для доступа в репозиторий:

  1. wget -q http://download.openvz.org/debian-systs/dso_archiv_signing_key.asc -O- | apt-key add - && apt-get update

Устанавливаем OS tempaltes - болванки нужных нам виртуальных машин:

  1. apt-get install vzctl-ostmpl-debian-5.0-i386-minimal

Нам осталось сделать две вещи: настроить сеть для виртуальной машины и создать собственно саму виртуальную машину (или машины), но об это м в следующей серии...

суббота, 24 октября 2009 г.

Включаем ipset в Debian 5 lenny

В Debian 5 Lenny ipset присутствует, но по умолчанию не установлен. Для его загрузки и активации необходимо выполнить следующее:

  1. apt-get install netfilter-extensions-source ipset
  2. m-a a-i netfilter-extension
Рекомендуется так же добавить ключик -t после m-a для вывода результатов на консоль без графического интерфейса.

P.S. При смене ядра (например установка OpenVZ) последнюю строчку необходимо исполнить еще раз (sources ядра выкачиваются автоматически).

четверг, 22 октября 2009 г.

Отключаем PHPSESSID в SMF для гостей

Делается для того чтобы улучшить индексирование поисковыми машинами. Версия форума SMF 1.1.10 в своих потрохах (Sources/Loads.php) уже имеет следующую установку:

  1. @ini_set('session.use_trans_sid', 0);
Другими словами половина дела уже сделана за нас. Вторую половину можно сделать разными способами:

Прямо в PHP скрипте:

  1. @ini_set('session.use_only_cookies', 1);

Или в php.ini:

  1. session.use_only_cookies=1

четверг, 15 октября 2009 г.

Конфигурируем NGINX и SMF под Debian 5 для отражения не сильных DDoS атак

Все нижесказанное имеет отношение к NGINX 0.7.62 и SMF 1.1.10. На момент написания этого топика apt-get install nginx инсталлирует старую версию 0.6, а нам нужно более новая и стабильная 0.7.62. Поэтому скачиваем sources компилируем и устанавливаем.

Наша цель: на гостей форума не тратить процессорное время - не трогать SMF по возможности и все готовые страницы хранить в cache, а пользователям наоборот позволять видеть самые последние изменения на форуме без задержек.

Вопрос первый: Как отличить пользователя от гостя? После установки SMF форума в окне настроек сервера есть поле "Имя Cookie". Наличие cookie с таким именем говорит о том, что перед нами пользователь, а отсутствие - гость. Обратите внимание на то, что количество использований перед тем как страница попадает в cache выставлена в 2 - это предотвращает кеширование ненужных страниц.

Вопрос второй? Стоит ли использовать GZIP сжатие в SMF или нет? Стоит! Хотя на это и тратиться процессорное время в PHP, но включать сжатие в NGINX точно не стоит - процессорное время будет тратиться на каждый запрос хотя и в меньшем количестве, но запросов-то многие тыщи!

Теперь еще один важный вопрос: загруженные пользователями аватары и картинки в SMF он загружаются через PHP, что существенно просаживает сервер. Они одинаковы для пользователей и гостей. И меняются ну очень очень редко. Наша задача их положить в cache и потом брать их только оттуда.

В этой статье не отражена тема реакции на 503 ошибку выдаваемую NGINX при исчерпании лимитов,а так же вопросы блокирования ботов со скоростью долбежки 1 раз в несколько секунд запрашивающих каждый раз произвольную страницу.

/etc/nginx/nginx.conf

  1. user www-data www-data;
  2. worker_processes 1;
  3. worker_rlimit_nofile 80000;
  4.  
  5. #error_log /var/log/nginx/error.log;
  6.  
  7. pid /var/run/nginx.pid;
  8.  
  9. events {
  10.     use epoll;
  11.     worker_connections 50000;
  12. }
  13.  
  14. http {
  15.     include /etc/nginx/mime.types;
  16.     default_type application/octet-stream;
  17.  
  18.     log_format filter '$remote_addr [$time_local] $status $bytes_sent $request_time "$request"';
  19.  
  20.     keepalive_timeout     10;
  21.     send_timeout          5;
  22.     client_body_timeout   10;
  23.     client_header_timeout 10;
  24.  
  25.     tcp_nopush                on;
  26.     tcp_nodelay               on;
  27.     reset_timedout_connection on;
  28.     sendfile                  on;
  29.     server_tokens             off;
  30.     gzip                      off;
  31.  
  32.     include /etc/nginx/conf.d/*.conf;
  33.     include /etc/nginx/sites-enabled/*;
  34. }
  35.  

/etc/nginx/sites-available/default

  1. limit_req_zone $binary_remote_addr zone=req_php:10m rate=2r/s;
  2.  
  3. limit_zone conn_php $binary_remote_addr 10m;
  4. limit_zone conn_static $binary_remote_addr 10m;
  5.  
  6. fastcgi_cache_path /var/lib/nginx/cache levels= keys_zone=fcgi_php:10m max_size=512m inactive=1d;
  7.  
  8. server {
  9.     listen 80;
  10.     server_name example.net;
  11.  
  12.     access_log /var/log/nginx/example.access.log filter;
  13.  
  14.     location = / {
  15.         limit_req zone=req_php;
  16.         limit_conn conn_php 2;
  17.  
  18.         rewrite .* /forum/index.php permanent;
  19.     }
  20.  
  21.     location = /forum {
  22.         limit_req zone=req_php;
  23.         limit_conn conn_php 2;
  24.  
  25.         rewrite .* /forum/index.php permanent;
  26.     }
  27.  
  28.     location = /forum/ {
  29.         limit_req zone=req_php;
  30.         limit_conn conn_php 2;
  31.  
  32.         rewrite .* /forum/index.php permanent;
  33.     }
  34.  
  35.     location / {
  36.         root /var/www/example;
  37.         index index.php index.html index.htm;
  38.     }
  39.  
  40.     error_page   500 502 503 504  /50x.html;
  41.     location = /50x.html {
  42.         root   /var/www/nginx-default;
  43.     }
  44.  
  45.     location ~ ^/forum/attachments/.*\.php$ {
  46.         deny all;
  47.     }
  48.  
  49.     location ~ \.php$ {
  50.         limit_req zone=req_php burst=10;
  51.         limit_conn conn_php 4;
  52.  
  53.         set $userid $http_if_modified_since|$http_if_none_match|$cookie_CookieSMF;
  54.        
  55.         if ($http_cookie !~ CookieSMF) {
  56.             set $userid "";
  57.         }
  58.  
  59.         if ($query_string ~ ^action=dlattach\;) {
  60.             set $userid "";
  61.         }
  62.  
  63.         fastcgi_pass           127.0.0.1:9000;
  64.         fastcgi_index          index.php;
  65.         fastcgi_param          SCRIPT_FILENAME /var/www/example$fastcgi_script_name;
  66.         fastcgi_pass_header    Cookie;
  67.         fastcgi_ignore_headers Cache-Control Expires;
  68.         fastcgi_cache          fcgi_php;
  69.         fastcgi_cache_min_uses 2;
  70.         fastcgi_cache_key      $request_method|$host|$request_uri|$userid;
  71.         fastcgi_cache_valid    301 8h;
  72.         fastcgi_cache_valid    302 404 1h;
  73.         fastcgi_cache_valid    200 15m;
  74.  
  75.         include /etc/nginx/fastcgi_params;
  76.     }
  77.  
  78.     limit_conn conn_static 8;
  79.  
  80.     location ~ \.inc$ {
  81.         deny all;
  82.     }
  83.  
  84.     location ~ \.bak$ {
  85.         deny all;
  86.     }
  87.  
  88.     location ~ \~$ {
  89.         deny  all;
  90.     }
  91.  
  92.     location ~ /\.ht {
  93.         deny  all;
  94.     }
  95. }
  96.