Мне понадобилось сделать reverse proxy с поддержкой SSL на роутере с OpenWrt LEDE 18.06.
Предвосхищая вопрос “зачем?” - для бекапа я пользуюсь неплохим бесплатным хостингом, который отказывается работать с некоторыми доменными зонами. В частности - .tk. В качестве практически бесплатного решения - я решил перенаправить трафик через мой домашний роутер со статическим внешним IP.
В репозитории OpenWrt есть nginx, однако он собран без поддержки SSL. Многие мануалы, для поддержки SSL рекомендуют пересобрать пакет nginx с нужными фичами.
Я пошел другим путем и выяснил, что для решения этой задачи можно обойтись только пакетами из репозитория OpenWrt, возложив функцию шифрования трафика на haproxy.
Итак - nginx будет revese proxy, а haproxy будет шифровать SSL. Поехали. Попутно - получим сертификаты Let's Encrypt
Предварительно нужно изменить порт на котором работает штатный web-интерфейс OpenWrt. Для этого отредактируем файлик /etc/config/uhttpd.
Ставим пакеты из консоли, либо из web-интерфейса.
opkg update opkg install nginx haproxy luci-ssl-openssl curl ca-bundle nano
/etc/nginx/nginx.conf
user nobody nogroup; worker_processes 1; events { worker_connections 1024; } http { include mime.types; sendfile on; keepalive_timeout 65; server { listen 80 default_server; return 444; } server { listen 80; server_name wiki.autosys.tk; location /.well-known/acme-challenge/ { root /www; } location / { proxy_pass http://redmike.unaux.com:80; } location /cgi-bin/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; } location /luci-static/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; } } }
Перезапускаем nginx:
/etc/init.d/nginx restart
Будем получать сертификат Let's Encrypt с помощью acme.sh
curl https://raw.githubusercontent.com/Neilpang/acme.sh/master/acme.sh > acme.sh chmod a+x "acme.sh" ./acme.sh --install cd /root/.acme.sh DOMAIN=wiki.autosys.tk ./acme.sh --issue -d $DOMAIN -w /www
Если все прошло без ошибок, то объединяем сертификат и ключ в файл .pem
cat /root/.acme.sh/wiki.autosys.tk/wiki.autosys.tk.cer /root/.acme.sh/wiki.autosys.tk/wiki.autosys.tk.key > /root/wiki.autosys.tk.pem
В конфигурации haproxy прописан сертификат, который мы получили на предыдущем этапе
/etc/haproxy.cfg
global maxconn 4096 defaults mode http option forwardfor option http-server-close option httplog option dontlognull retries 3 option redispatch maxconn 2000 timeout connect 5000 timeout client 50000 timeout server 50000 #default-server init-addr none frontend www-https bind *:443 ssl crt /root/wiki.autosys.tk.pem reqadd X-Forwarded-Proto:\ https # Define hosts acl host_wiki hdr(host) -i wiki.autosys.tk ## figure out which one to use use_backend wiki-backend if host_wiki default_backend wiki-backend backend wiki-backend redirect scheme https if !{ ssl_fc } server wiki-node1 127.0.0.1:80 check