Личный блог с мыслями и наблюдениями

nginx for frontenders

Очень часто бывает, что фронтенд-разработчику необходимо добавить или изменить функционал сайта, но нет возможности получить его dev-версию, на которую можно повлиять. Обычно это пытаются обойти запуском браузера с отключенной безопасностью, но не всегда это помогает.

Я расскажу как при работе с «чёрным ящиком» иметь возможность воздействать на его ответы, а также как решать проблемы связанные с безопасностью.

Собираем nginx c необходимыми модулями

Для этого нам понадобится nginx и несколько вспомогательных модулей для него:

Module ngx_headers_more, модуль для замены заголовков. Почему не использовать add_header, спросите вы, потому что он добавляет заголовок, даже если он уже был.

Module ngx_http_sub_module, позволит нам подменить строки в ответе источника.

Сборка

Для ubuntu собрать nginx ну очень просто, поэтому опишу как это сделать под OS X.

sudo mkdir -p /usr/local/src

cd /usr/local/src

pcre можно поставить из brew или собрать самостоятельно

sudo wget http://ftp.cs.stanford.edu/pub/exim/pcre/pcre-8.38.tar.gz

sudo tar xzvf pcre-8.38.tar.gz

cd pcre-8.38

sudo ./configure --prefix=/usr/local

sudo make && sudo make install && sudo make clean

cd .

sudo wget http://nginx.org/download/nginx-1.10.0.tar.gz

sudo wget https://github.com/openresty/headers-more-nginx-module/archive/v0.30rc1.tar.gz

sudo tar xzvf nginx-1.10.0.tar.gz

sudo tar xzvf v0.30rc1.tar.gz

cd nginx-1.10.0

sudo./configure --prefix=/usr/local --with-http_sub_module --add-module=/usr/local/src/headers-more-nginx-module-0.30rc1

sudo make && sudo make install && sudo make clean

nano ~/.bash_profile

export PATH="/usr/local/sbin: $PATH"

. ~/.bash_profile

Здесь показана сборка без поддержки SSL, поэтому не получится работать с сайтами, которые работают только по HTTPS.

Проверяем работоспособность nginx

sudo nginx -t

Конфиг nginx будет лежать по этому пути /usr/local/conf/nginx.conf

Релоад конфига выполняется

sudo nginx -s reload

Nginx готов, можно приступать!

Предположим, мы хотим повлиять на vk.com

Пропишем наш тестовый домен:

sudo nano /etc/hosts

127.0.0.1 test.vk.com

Начнём писать наш конфиг. Чтобы было сложнее запутаться, сделаем конфиг в виде инклюдов. В итоге, наш конфиг будет выглядеть как:

site.conf — в котором будет общее описание сайта и инклюды следующих частей

proxy_site.conf — здесь мы опишем какая часть запросов пойдёт на сам сайт, а какая будет завернуть к нам

proxy_api.conf — тут будут настройки проксирования для api, если нужно

headers.conf — заголовки для подмены, отключим все лишнее, что возвращает backend

sub_filter.conf — список замен для данных, которые будет возвращать backend

затем, редактируем /usr/local/conf/nginx.conf

добавляем в конец секции http путь до нашего основного инклюда

include /Users/{USERNAME}/nginx_test/site.conf;

Затем, меняем /Users/{USERNAME}/nginx_test/site.conf;

который в свою очередь описывает какой домен мы будем обрабатывать

server {
    listen 80;
    server_name  test.vk.com;
    include /Users/{USERNAME}/nginx_test/proxy_site.conf;
    include /Users/{USERNAME}/nginx_test/sub_filter.conf;
    include /Users/{USERNAME}/nginx_test/headers.conf;
}

Сделаем проксипасс до нужного сервера в /Users/{USERNAME}/nginx_test/proxy_site.conf;

location / {
    proxy_set_header Accept-Encoding ""; # это важный параметр, если его не указать, то для gzip сайтов не будет работать замена
    proxy_pass http://vk.com;
}

Для примера покажу, как сделать так, чтобы про браузер не знал про vk.com и думал, что он теперь test.vk.com

затем редактируем /Users/{USERNAME}/nginx_test/sub_filter.conf;

sub_filter ‘vk.com’ ‘test.vk.com’; # указыват, какую строку и на что мы заменяем (с версии nginx 1.9.4 можно делать замену разных строк дублируя вызов этой команды)

sub_filter_once off; # говорит, что нужно сделать несколько замен, а не только одну

sub_filter_types *; # для каких типов документов выполнять замену, по умолчанию только для html

sub_filter_last_modified on; # менять заголовок, если была произведена замена

Подмена домена, на который ставится кука

proxy_cookie_domain ‘vk.com’ ‘test.vk.com’;

Заголовки ответа сервера

Осталось подменить заголовки, влияющие на безопасность, редактируем /Users/{USERNAME}/nginx_test/headers.conf;

more_clear_headers 'Access-Control-*'; # можем удалить заголовки из ответа
more_set_headers 'Access-Control-Allow-Origin: http://test.vk.com'; # или поменять их
26.04.2016   техническое   код   nginx   frontend