Оптимизация VPS сервера на Debian

Если у вас windows, смиренно слушаемся указаний в письме и переходим по ссылке http://hostink.ru/wiki/ssh2_putty/ за дальнейшими инструкциями, если же у вас Linux(Debian/Ubuntu и др.) подключаемся к серверу так:

$ ssh [email protected] -p 22

на что получаем диалог системы безопасности ключей:

The authenticity of host '[93.189.xx.xx]:22 ([93.189.xx.xx]:22)' can't be established.
ECDSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx.
Are you sure you want to continue connecting (yes/no)?

Соглашаемся и пишем yes.
Поздравляю, вы в системе.
Давайте обновимся:

# apt-get update && apt-get dist-upgrade

Не сидим под root-ом!

По умолчанию нам предлагается сидеть под root-ом, что не очень хорошо по соображениям безопасности.

1. создаем пользователя под которым будем работать(самый простой способ):

# adduser user

где user — имя пользователя
Далее мы увидим диалог что-то вроде:

Добавляется пользователь «user» ...
Добавляется новая группа «user» (1001) ...
Добавляется новый пользователь «user» (1001) в группу «user» ...
Создаётся домашний каталог «/home/user» ...
Копирование файлов из «/etc/skel» ...
Введите новый пароль UNIX:
Повторите ввод нового пароля UNIX:
passwd: пароль успешно обновлён
Изменение информации о пользователе user
Введите новое значение или нажмите ENTER для выбора значения по умолчанию
Полное имя []:
Номер комнаты []:
Рабочий телефон []:
Домашний телефон []:
Другое []:
Данная информация корректна? [Y/n] Y

Пишем сложный пароль(который вы не забудете!) и заполняем данные которые считаем нужными, или просто нажимаем enter.

2. Разрешаем user выполнение sudo
Добавляем user в специальную группу sudo:

# usermod -a -G sudo user

где собственно user — имя пользователя.
Всё, можем выходить и логинится под user

$ ssh [email protected] -p 22

и в дальнейшем уже использовать sudo если нужны привилегии root-а

Немного обезопасим SSH

Практически сразу после запуска сервера заметил подозрительную активность в ану.. на порту 22. По всей видимости китайские порно-сканеры разнюхали и начали брутить пароли.
Самый простой выход — сменить порт ssh с 22 на любой другой.
1. Для этого откроем файл конфигурации ssh сервера:

$ sudo nano /etc/ssh/sshd_config

Ищем строку «Port 22» и заменяем её на «Port 354» где 354 любое число в пределах от 1 до 65535
На всякий случай посмотрим открытые порты:

netstat -tupln | grep LISTEN

и выберем любой не из этого списка.
Скажу сразу, порты 80, 443, 3306, 22, 21, 8080 — советую не использовать.
2. Дальше, ограничим тип адресов для подключения(IPv6 либо IPv4). Если у вас на сервере не используется IPv6, то дописываем файл /etc/ssh/sshd_config:

AddressFamily inet

3. Запретим авторизацию под root, ищем в файле PermitRootLogin и выставляем no. Если данного параметра нет, дописываем:

PermitRootLogin no

4. Разрешаем подключение только по определенным логинам, дописываем файл /etc/ssh/sshd_config:

AllowUsers user

где список пользователей пишется через пробел.

5. Запрещаем попытку входа с пустым паролем. Ищем PermitEmptyPasswords и выставляем no

PermitEmptyPasswords no

6. Сохраняем и перезапускаем ssh демон:

$ sudo /etc/init.d/ssh restart

Для начала всё, можем перелогиниваться с новыми параметрами($ ssh [email protected] -p 354), далее в статье мы еще вернемся к вопросу безопасности.

Установка SWAP

Как оказалось в автоматическом режиме не был выставлен swap, а при таком объеме памяти — это критично.
Внимание! Это мой конкретный случай, проверить есть ли swap можно так:

$ sudo swapon -s

Создаем, с помощью dd, файл необходимого размера для swap области, где /swap — это имя и путь файла, а count=1024K его размер, в данном случае — 512 Мб
(обычная формула swap = озу * 1.5, но это не наш случай):

$ sudo dd if=/dev/zero of=/swap bs=1024 count=512K

Далее производим запись в начало файла системную информацию, которая будет использоваться ядром системы для работы с файлом подкачки:

$ sudo mkswap /swap

После окончания операции на экране появится что-то вроде:

Устанавливается пространство для свопинга версии 1, размер = 536868 кБ
без метки, UUID=54c60583-e61a-483a-a15c-2f1be966db85

Следующим шагом активируем только что созданный SWAP файл:

$ sudo swapon /swap

Далее нужно подредактировать файл fstab для подключения swap при следующей загрузке системы:

$ sudo echo "/swap swap swap defaults 0 0" | sudo tee -a /etc/fstab

Вот и всё, своп готов.

Установка и расширенная настройка NGINX

В качестве frontend-а(Фронтэнд) мы будем использовать всеми известный nginx.
Если вы не будете использовать сервер для web-приложений — эту часть можно пропустить.

В стандартном репозитории конечно есть уже nginx, но хотелось бы версию посвежее и без плясок.
1. Изменяем файл /etc/apt/sources.list:

$ sudo nano /etc/apt/sources.list

и дописываем в самый низ:

deb http://nginx.org/packages/debian/ wheezy nginx
deb-src http://nginx.org/packages/debian/ wheezy nginx

В случае если у вас debian отличный от 7, то вместо wheezy пишем его кодовое имя.

2. Обновляем источники пакетов и устанавливаем nginx:

$ sudo apt-get update && sudo apt-get install nginx

3. Добавляем в начало файла nginx.conf новые параметры

timer_resolution 100ms; #Уменьшает разрешение таймеров времени в рабочих процессах, за счёт чего уменьшается число системных вызовов 
worker_rlimit_nofile 8192; #Изменяет ограничение на максимальное число открытых файлов (RLIMIT_NOFILE) для рабочих процессов
worker_priority -5;# Выставляем более высокий приоритет процессу воркера

4. Ищем worker_processes и выставляем количество по количеству ядер процессора, в нашем случае 1.

worker_processes  1;

5. Ищем директиву events и приводим к виду:

events {
    worker_connections  2048;
    use epoll;
}

6. Редактируем директиву http, модифицируя или дописывая следующие параметры:

sendfile        on; # экономия ресурсов при отдаче файлов
#настройка сжатия контента при отдаче
gzip on;
gzip_min_length 1100;
gzip_buffers 64 8k;
gzip_comp_level 3;
gzip_http_version 1.1;
gzip_proxied any;
gzip_types text/plain application/xml application/x-javascript text/css;
# Таймаут при чтении тела запроса клиента
client_body_timeout 10;
# Таймаут при чтении заголовка запроса клиента
client_header_timeout 10;
# Таймаут, по истечению которого keep-alive соединение с клиентом не будет закрыто со стороны сервера
keepalive_timeout 5 5;
# Таймаут при передаче ответа клиенту
send_timeout 10;

7. Редактируем /etc/nginx/conf.d/sitename.conf или же (ubuntu) /etc/nginx/sites-available/sitename.conf где sitename будет имя вашего сайта:

$ sudo nano /etc/nginx/conf.d/sitename.conf 

Приводим к такому виду:

#выделяем память на адреса клиентов
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
    listen       80;
    #пишем адреса нашего сайта
    server_name  sitename.net www.sitename.net;
    # Максимальный размер буфера для хранения тела запроса клиента
    client_body_buffer_size 1K;
    # Максимальный размер буфера для хранения заголовков запроса клиента
    client_header_buffer_size 1k;
    # Максимальный размер тела запроса клиента, прописанный в поле Content-Length заголовка. Если сервер должен поддерживать загрузку         файлов, это значение необходимо увеличить
    client_max_body_size 1k;
    # Количество и размер буферов для чтения большого заголовка запроса клиента
    large_client_header_buffers 2 1k;
    #отсеиваем неиспользуемые типы запросов
    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
    return 444;
    }
    #логируем посетителей
    access_log  /var/log/nginx/sitename.access.log  main;
    #и конечно же ошибки
    error_log  /var/log/nginx/sitename.error.log  main;
    #выставляем принудительно кодировку всех документов
    charset utf-8;
    location / {
        # Описываем зону (slimits), в которой будут храниться состояния сессий. Зона размером 1 Мб может хранить около 32000 состояний, мы устанавливаем ее размер равным 5 Мб
        limit_conn perip 10;
        limit_conn perserver 100;
        # Блокируем менеджеры загрузки и некоторые типы ботов
        # Внимательно проверяем  и запоминаем(на будущее) список запрещенных ботов!
        if ($http_user_agent ~* LWP::Simple|BBBike|wget|curl|msnbot|scrapbot) {
            return 403;
        }
        # Блокируем referer спам. (не позволяем переход с гнусных сайтов) Список можно дополнить на своё усмотрение
        if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen|pron|money|free|jwh|speed|test|cash|xxx) )
    {
            return 403;
        }
        #ДАЛЕЕ ИДУТ ВАШИ НАСТРОЙКИ ДЛЯ location / вашего сайта
    }
}

Далее в статье мы вернемся к этим настройкам.

Ковыряем системные переменные, защищаемся от некоторых видов атак

Данные параметры дают некоторую масло-масленность и в некоторых случаях повышают нагрузку.
Редактируем /etc/sysctl.conf

$ sudo nano /etc/sysctl.conf

Дописываем в конец

# Защита от smurf-атак
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Защита от неправильных ICMP-сообщений
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Защита от SYN-флуда
net.ipv4.tcp_syncookies = 1
# Запрещаем маршрутизацию от источника
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Защита от спуфинга
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Мы не маршрутизатор, если конечно это так
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Включаем ExecShield при атаках направленных на переполнение буфера или срыв стэка
kernel.exec-shield = 1
kernel.randomize_va_space = 1
# Расширяем диапазон доступных портов
net.ipv4.ip_local_port_range = 2000 65000
# Увеличиваем максимальный размер TCP-буферов
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 87380 8388608
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_window_scaling = 1

#ускоряем высвобождение памяти(см. "Ускоряем общую работу системы")
vm.swappiness=10

Теперь можно перезагрузится

Ускоряем общую работу системы

Prelink и Preload. Prelink для создание статичных адресов библиотек, Preload это небольшое приложение, которое следит за файлами наиболее часто используемых приложений, и загружает их в память, когда система простаивает.
1. Установка Prelink:

$ sudo apt-get -y install prelink

Редактируем файл /etc/default/prelink:

$ sudo nano /etc/default/prelink

Измените строку с PRELINKING=unknown на PRELINKING=yes
Запускаем:

$ sudo /etc/cron.daily/prelink

2. Установка Preload:

$ sudo apt-get -y install preload

Все, больше ничего не требуется

Настраиваем брандмауэр(фаерволл)

Далее будут очень сомнительные конфигурации. Настраиваем число подключений с одного IP адреса.
Спасает при некоторых видах DOS атак и брутфорса.

Выполняем:

$ sudo iptables -A INPUT -p tcp --dport 80 -i eth0 \
-m state --state NEW -m recent --set

далее:

$ sudo iptables -A INPUT -p tcp --dport 80 -i eth0 \
-m state --state NEW -m recent --update \
--seconds 15 --hitcount 20 -j DROP

Данное правило ограничивает больше 20-ти подключение к 80 порту(web) за 15 секунд с 1 ip адреса.
(кстати, подобное правило уже установлено на уровне nginx, но сжирает огромное количество ресурсов)

$ sudoiptables -A INPUT -p tcp --dport 354 -i eth0 \
-m state --state NEW -m recent --set
$ sudoiptables -A INPUT -p tcp --dport 354 -i eth0 \
-m state --state NEW -m recent --update \
--seconds 60 --hitcount 4 -j DROP

Где 354 порт вашего ssh сервера. Правило ограничивает количество подключений, не более 4-х подключений за 1 минуту. На деле у меня не получалось авторизовать более 1 раза за минуту.
Далее это правило вы дальше можете адаптировать под себя и другие сервисы.

После рестарта системы все правила обнулятся, по этому делаем следующее:
создаем и редактируем файл /etc/network/if-up.d/00-iptables

$ sudo nano -w /etc/network/if-up.d/00-iptables

Пишем в него:

#!/bin/sh
iptables-restore < /etc/firewall.conf

сохраняем и делаем файл исполняемым:

$ sudo chmod +x /etc/network/if-up.d/00-iptables

Сохраняем правила в файл:

$ sudo iptables-save | sudo tee /etc/firewall.conf

Всё, правила настроены и сохранятся после перезагрузки системы.