Каждый раз, когда ставлю Nginx на новый сервер, первым делом лезу в /etc/nginx/nginx.conf и правлю одни и те же вещи. Решил наконец записать, чтобы не держать в голове.

1. worker_connections

Дефолтные 768 — это наследие времён, когда у серверов было 256 MB RAM. На любом современном VPS с 1+ GB можно смело ставить 2048 или даже 4096.

events {
    worker_connections 2048;
}

Каждое соединение занимает примерно 232 байта памяти в Nginx. 2048 соединений — это меньше 500 KB. Копейки.

2. gzip_vary

Без gzip_vary on CDN может закэшировать сжатую версию и отдавать её клиентам, которые не поддерживают gzip. Или наоборот — несжатую всем подряд.

gzip on;
gzip_vary on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 256;

Параметр gzip_min_length тоже важен — сжимать ответы меньше 256 байт бессмысленно, gzip-заголовок сам по себе больше выигрыша.

3. server_tokens off

По умолчанию Nginx отдаёт свою версию в заголовке Server и на страницах ошибок. Это подарок для сканеров — зная версию, проще подобрать эксплоит.

server_tokens off;

Одна строчка, а поверхность атаки меньше.

4. client_max_body_size

Дефолт — 1 MB. Если у вас есть формы загрузки файлов, API для аплоада или WebDAV, вы узнаете об этом лимите из 413 Request Entity Too Large в логах.

client_max_body_size 64M;

Ставьте под свои нужды. Для блога хватит 10M, для файлового хранилища — 512M или больше.

5. add_header X-Content-Type-Options

Без этого заголовка браузер может попытаться «угадать» MIME-тип файла, что открывает дверь для XSS через загруженные файлы.

add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;

SAMEORIGIN защищает от clickjacking — никто не сможет встроить ваш сайт в iframe.

Итого

Всё вместе — пять минут работы, а сервер становится чуть быстрее и заметно безопаснее. Когда-нибудь напишу про тюнинг proxy_buffer_size и fastcgi_buffers, но это уже для тех, кто проксирует что-то тяжёлое.