Захотели поставить nginx на роутер c ssl сертификатами? А фигушки:
`the "ssl" parameter requires ngx_http_ssl_module in /etc/nginx/nginx.conf`
Ну и вторая важная проблема wrt-шников, которая будет решена:
`LuCI on Nginx is not possible, as Nginx does not support plain cgi.`
Что может быть круче, чем иметь что то одно, способное управлять всеми. Одно кольечко нагнуть всех назгулов, один маршрутизатор роутить трафик инициированный снаружи DMZ.
К примеру, у нас есть LuCi на роутере, Shell-in-a-box в виртуалке на компе и JPython c Jupiter Note в другой. Можно конечно поизголяться с проброской портов, ну у меня и так уже 2 десятка правил, которые я пухну восстанавливать каждый раз если что то пойдет не так. Будем делать проксирование вызовов на основе целевого URI.
Проблема в том, что штатный веб-сервер не умеет проксировать запросы на другие хосты, его только ради https и можно ставить
Я посматривал в сторону haproxy, он довольно крут, но есть одно простое правило: использовать инструменты по их прямому назначению, иначе огребешься ссаными костылями. А в данной задаче нужен не балансировщик, а веб сервер.
Т.о. нам потребуется
- скомпилировать nginx c поддержкой ssl, так как штатный nginx version 1.12.1 поставляется без него
- сконфигурировать uhttpd, что бы он не занимал стандартные порты, иначе он все запросы будет заворачивать на себя
- сконфигурировать nginx, что бы он проксировал http запросы
- выпустить ssl сертификат (done!)
- сконфигурировать nginx для использования ssl
Тулчейн при сборке gcc для родной архитектуры роутера довольно подробно пишет лог. Но вот он ниразу не может определить, что место в вируалке кончилось, узнал случайно, какой то проект клонил. Пришлось судорожно искать как это сделать.
Но самый отпад в том, что сборщик openwrt не может сбилдить одну оч важную зависимость `gcc-5.4.0-final` Это реально смешно, вот полный лог событий. Я мудохался 3 дня и 2 ночи, а потом, вспомнил, что есть менее мертвый форк lede и на нем я делал кастомную сборку прошивки для mr3020. Господи, как быстро летит время, это было уже 4 года назад.
Но с тех пор я зарекся связываться с такими хилыми железками.
Ну да ладно, если у вас будет время, попробуйте в корень проекта еще качнуть ядро линукса 3.18 `wget -4 https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.23.tar.xz`, это помогло одному индусу (заметка, архив). Хотя веры ему мало, индус же)
Прописываем архитектуру потребителя пакета. То бишь своего роутера.
делаем `make menuconfig` и идем
Network → Web Servers/Proxies → nginx → hit `M` → hit `ENTER`
жмем по `Save`, оставляем дофолтное имя конфига `.config`
выбираем пробелом следующие модули
- Enable SSL module
- Enable Lua module
а теперь, собираем один отдельный модуль
и ищем зависимости здесь:
нужно будет дополнить параметры запуска так
`--disable-ssl --disable-ssl-menu`,
что бы не использовать встроенный самосгенеренный ssl серт. Ну и перезапускам
`sudo /etc/init.d/shellinabox restart`
Теперь сервис должен спокойно отзываться по адресу http://buben.lan:4200/
предполагаемый эндпоинт `box.now.io/buben/`
и перезапускаем `/etc/init.d/uhttpd restart` и смотрим переехал ли на новый порт `http://nethead.lan:81/cgi-bin/luci` и `box.now.io:81`
И это не просто рекомендация, я готов поспорить, что объебов будет много.
Что бы грамотно приготовить его пришлось хорошенько курнуть следующие маны:
https://nginx.org/ru/docs/http/request_processing.html
https://nginx.org/ru/docs/beginners_guide.html
https://nginx.org/ru/docs/http/ngx_http_core_module.html#location
https://nginx.org/ru/docs/http/ngx_http_ssl_module.html
https://serverfault.com/a/9717
https://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate
https://serverfault.com/a/627309
в `vi /etc/nginx/nginx.conf` прописываем
Если вы ленивое чмо, как я и редактируете файл на винде и передаете по scp, то не забудьте выпилить кривые переносы строк `^M` командой
Не забываем указать волшебные команды, что бы эта хреновина заработала
Проверьте не объебалились ли вы и не переехали они на другой порт http://box.now.io:81/.well-known/acme-challenge/
Я не объебался, я молодец - посавил костылек в виде первого server{}, который слушает только 80 порт и редиректит на токены.
https://github.com/tavinus/opkg-upgrade
Главное исключите из него nginx.
`the "ssl" parameter requires ngx_http_ssl_module in /etc/nginx/nginx.conf`
Ну и вторая важная проблема wrt-шников, которая будет решена:
`LuCI on Nginx is not possible, as Nginx does not support plain cgi.`
Что может быть круче, чем иметь что то одно, способное управлять всеми. Одно кольечко нагнуть всех назгулов, один маршрутизатор роутить трафик инициированный снаружи DMZ.
К примеру, у нас есть LuCi на роутере, Shell-in-a-box в виртуалке на компе и JPython c Jupiter Note в другой. Можно конечно поизголяться с проброской портов, ну у меня и так уже 2 десятка правил, которые я пухну восстанавливать каждый раз если что то пойдет не так. Будем делать проксирование вызовов на основе целевого URI.
Аналитика
Если бы нужен был защищенный доступ просто до LuCi, то можно было бы обойтись установкой пакета luci-ssl и uhttpd бы сам бы сконфигурировался бы скриптом на https.Проблема в том, что штатный веб-сервер не умеет проксировать запросы на другие хосты, его только ради https и можно ставить
Я посматривал в сторону haproxy, он довольно крут, но есть одно простое правило: использовать инструменты по их прямому назначению, иначе огребешься ссаными костылями. А в данной задаче нужен не балансировщик, а веб сервер.
План
И во ссславу Сысоеву, у nginx есть опция reverse proxyТ.о. нам потребуется
- скомпилировать nginx c поддержкой ssl, так как штатный nginx version 1.12.1 поставляется без него
- сконфигурировать uhttpd, что бы он не занимал стандартные порты, иначе он все запросы будет заворачивать на себя
- сконфигурировать nginx, что бы он проксировал http запросы
- выпустить ssl сертификат (done!)
- сконфигурировать nginx для использования ssl
Лирика
Важно примерно понимать, как это работает: раз два. У меня было куча проблем и я даже не мог понять что я делаю не так.Тулчейн при сборке gcc для родной архитектуры роутера довольно подробно пишет лог. Но вот он ниразу не может определить, что место в вируалке кончилось, узнал случайно, какой то проект клонил. Пришлось судорожно искать как это сделать.
Но самый отпад в том, что сборщик openwrt не может сбилдить одну оч важную зависимость `gcc-5.4.0-final` Это реально смешно, вот полный лог событий. Я мудохался 3 дня и 2 ночи, а потом, вспомнил, что есть менее мертвый форк lede и на нем я делал кастомную сборку прошивки для mr3020. Господи, как быстро летит время, это было уже 4 года назад.
Но с тех пор я зарекся связываться с такими хилыми железками.
Ну да ладно, если у вас будет время, попробуйте в корень проекта еще качнуть ядро линукса 3.18 `wget -4 https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.23.tar.xz`, это помогло одному индусу (заметка, архив). Хотя веры ему мало, индус же)
Зависимости системные
основныеsudo su apt-get install asciidoc bc fastjar libgtk2.0-dev intltool jikespg genisoimage openjdk-8-jre openjdk-8-jdk -y apt-get install binutils build-essential gcc-multilib flex git-core gettext sharutils bcc bin86 libusb-dev libxml-parser-perl libboost-all-dev libncurses5-dev gawk git subversion libssl-dev gettext zlib1g-dev unzip ccache xsltproc zip libssl-dev patch libz-dev -y
Зависимости для проекта
собственно, выкачиваем все исходаgit clone https://github.com/openwrt/openwrt.git # может быть когда-нибудь починят # git clone https://git.lede-project.org/source.git openwrt # но пока только так cd openwrt git tag # git checkout `tag_name` # можно сделать если хочется собрать стабильный снэпшот ./scripts/feeds update -a #./scripts/feeds install -a # нам все пакеты нахер не нужны ./scripts/feeds install nginx # ставим только один, но там будут зависимости ./scripts/feeds install libpam libgnutls libopenldap libidn libssh2 liblzma libnetsnmp make menuconfig
Прописываем архитектуру потребителя пакета. То бишь своего роутера.
Target System : (MediaTek Ralink MIPS) Subtarget: (MT7621 based boards) Target Profile: (ZBT WG3526 (16MB flash)) Build the OpenWRT SDK : true Exit → Save
делаем `make menuconfig` и идем
Network → Web Servers/Proxies → nginx → hit `M` → hit `ENTER`
жмем по `Save
кликабельный menuconfig |
make tools/install make toolchain/install ./script/feeds install nginx
выбираем пробелом следующие модули
- Enable SSL module
- Enable Lua module
а теперь, собираем один отдельный модуль
make package/feeds/packages/nginx/prepare make package/feeds/packages/nginx/compile V=s
и ищем зависимости здесь:
/lede/bin/packages/mipsel_24kc/packages/
Подготовка тестового сервиса
Проводить опыты будем на https://github.com/mcgr0g/rancho/tree/master/shellinaboxнужно будет дополнить параметры запуска так
`--disable-ssl --disable-ssl-menu`,
что бы не использовать встроенный самосгенеренный ssl серт. Ну и перезапускам
`sudo /etc/init.d/shellinabox restart`
Теперь сервис должен спокойно отзываться по адресу http://buben.lan:4200/
предполагаемый эндпоинт `box.now.io/buben/`
Подготовка LuCi
Старичка uhttpd необходимо перенести с дефолтных портов, что б освободить место для nginx. Ну и 81 порт наружу не должен торчать. Правим конфиг `vi /etc/config/uhttpd` такconfig uhttpd 'main' list listen_http '127.0.0.1:81' # list listen_http '[::]:88' # list listen_https '192.168.1.12:443' # list listen_https '[::]:443' option redirect_https '0' option home '/www' option rfc1918_filter '0' option max_requests '3' option max_connections '100' option redirect_https '0' # option key '/etc/acme/box.now.io/box.now.io.key' # option cert '/etc/acme/box.now.io/box.now.io.cer' option cgi_prefix '/cgi-bin' option script_timeout '60' option network_timeout '30' option http_keepalive '20' option tcp_keepalive '1' option ubus_prefix '/ubus'
и перезапускаем `/etc/init.d/uhttpd restart` и смотрим переехал ли на новый порт `http://nethead.lan:81/cgi-bin/luci` и `box.now.io:81`
Ставим nginx
Ну вот мы и добрались до виновника торжества. Ставим пакет, предварительно положив его в /tmpcd /tmp/ ls -la | grep nginx opkg install nginx_1.10.2-1_mipsel_24kc.ipk ls -la /etc/nginx/ | grep conf mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old
Конфигурируем nginx
Cразу открываем лог файл и смотрим че там будет сыпаться.cd /var/log/nginx/ tail -f error.log
И это не просто рекомендация, я готов поспорить, что объебов будет много.
Что бы грамотно приготовить его пришлось хорошенько курнуть следующие маны:
https://nginx.org/ru/docs/http/request_processing.html
https://nginx.org/ru/docs/beginners_guide.html
https://nginx.org/ru/docs/http/ngx_http_core_module.html#location
https://nginx.org/ru/docs/http/ngx_http_ssl_module.html
https://serverfault.com/a/9717
https://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate
https://serverfault.com/a/627309
в `vi /etc/nginx/nginx.conf` прописываем
user root; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; #default_type application/octet-stream; sendfile on; keepalive_timeout 65; gzip on; gzip_buffers 4 16k; gzip_http_version 1.0; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; gzip_min_length 1k; server { listen 80; listen [::]:80; server_name box.now.io; location ^~ /.well-known/acme-challenge/ { #костылек для продления сертификатов root /www; default_type "text/plain"; } location / { # костылек для форварда на htps return 301 https://$host$request_uri; } } server { listen 80; listen [::]:80; listen 443 ssl; listen [::]:443 ssl; server_name 192.168.1.12 nethead.lan box.now.io; #charset koi8-r; # access_log logs/host.access.log main; ssl on; ssl_certificate /etc/acme/box.now.io/box.now.io.cer; ssl_certificate_key /etc/acme/box.now.io/box.now.io.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # if ($scheme = http) { # старый костылек для форварда на htps # return 301 https://$host$request_uri; # } location / { root /www; proxy_pass http://localhost:81; index index.html index.htm; proxy_set_header X-Forwarded-Proto https; } location /buben/ { proxy_pass http://buben.lan:4200; default_type application/octet-stream; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # proxy_set_header Host $http_host; # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header X-Forwarded-Proto https; # proxy_redirect off; } } }
Если вы ленивое чмо, как я и редактируете файл на винде и передаете по scp, то не забудьте выпилить кривые переносы строк `^M` командой
sed -i 's/\r$//' nginx.conf
Не забываем указать волшебные команды, что бы эта хреновина заработала
/etc/init.d/nginx enable /etc/init.d/nginx start /etc/init.d/nginx reload
Не забываем про acme
Сейчас токены должны валяются по адресу http://box.now.io:80/.well-known/acme-challenge/Проверьте не объебалились ли вы и не переехали они на другой порт http://box.now.io:81/.well-known/acme-challenge/
Я не объебался, я молодец - посавил костылек в виде первого server{}, который слушает только 80 порт и редиректит на токены.
Дессерт
Если у вас есть потребность постоянно проверять что можно обновить, используйтеhttps://github.com/tavinus/opkg-upgrade
Главное исключите из него nginx.