Мне понадобилось сделать 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