суббота, 6 февраля 2010 г.

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

Теперь можно создать виртуальные машины - все вроде просто, но есть 2 важных вопроса: доступ виртуальной машины в сеть и nameserver для вашей виртуальной машины.

Для решения первого вопроса я использую ferm - замечательная надстройка над iptables, для установки необходимо выполнить следующую команду, а так же ответить положительно на вопрос о включении блокировки всего за исключением ssh.

  1. apt-get install ferm

Собственно теперь самая ответственная и важная часть - это написание правил для ferm. Сначала нужно определиться с поставленной задачей чего мы хотим от виртуального компьютера: а мы хотим на 92.168.11.107 видеть http и ssh сервер, реальный компьютер будет содержать собственный nameserver, а все виртуальные будут его использовать для получения ip адреса по DNS имени сервера (к этому мы вернемся гораздо позднее). Вот пример такой конфигурации:

  1. def $INTRUDER = 192.168.11.107;
  2.  
  3. table filter {
  4.     chain INPUT {
  5.         policy DROP;
  6.  
  7.         # connection tracking
  8.         mod state state INVALID DROP;
  9.         mod state state (ESTABLISHED RELATED) ACCEPT;
  10.  
  11.         # allow local packages
  12.         interface lo ACCEPT;
  13.  
  14.         # allow SSH connections
  15.         proto tcp dport ssh ACCEPT;
  16.  
  17.         ### access from virtual computer to local nameserver
  18.         interface venet0 proto (tcp udp) dport 53 ACCEPT;
  19.     }
  20.     chain OUTPUT {
  21.         policy ACCEPT;
  22.  
  23.         # connection tracking
  24.         #mod state state INVALID DROP;
  25.         mod state state (ESTABLISHED RELATED) ACCEPT;
  26.     }
  27.     chain FORWARD {
  28.         policy DROP;
  29.  
  30.         # connection tracking
  31.         mod state state INVALID DROP;
  32.         mod state state (ESTABLISHED RELATED) ACCEPT;
  33.  
  34.         ### access from virtual computer to internet
  35.         interface venet0 outerface eth0 ACCEPT;
  36.  
  37.         ### access from internet to specific virtual ports
  38.         outerface venet0 daddr $INTRUDER proto tcp dport (ssh http) ACCEPT;
  39.     }
  40. }
  41.  

Перезапускаем ferm:

  1. /etc/init.d/ferm restart

Не забываем добавить строчку в /etc/sysctl.conf:

  1. net.ipv4.ip_forward=1

И запускаем команду:

  1. sysctl -p

Создаем собственно виртуальную машину (обратите внимание, что в качестве nameserver мы временно используем 192.168.11.1, в принципе подойдет любой nameserver в том числе и 8.8.8.8 от Google), запускаем и наконец заходим на нее под правами администратора:

  1. vzctl create 101 --ostemplate debian-5.0-i386-minimal
  2. vzctl set 101 --onboot yes --save
  3. vzctl set 101 --hostname intruder --save
  4. vzctl set 101 --nameserver 192.168.11.1 --save
  5. vzctl set 101 --ipadd 192.168.11.101 --save
  6. vzctl start 101
  7. vzctl enter 101
  8. su -

На этом этапе наш виртуальный компьютер должен без нареканий выполнять команду:

  1. arp yandex.ru

понедельник, 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.