Questão Como usar o nginx como um proxy reverso em um roteador Ubiquiti


Eu tenho tentado configurar o meu Ubiquiti ErPoe-5 (firmware 1.9.1) para executar um proxy reverso usando nginx por alguns dias agora e parece que a maioria dos meus problemas são causados ​​pelo fato de que eu não posso obter um versão recente do nginx no dispositivo.

o tutoriais Eu vi para instalar o nginx nele só me levar até nginx 1.2 que não tem suporte para websockets ou HTTP2. O HTTP2 não é um requisito, mas o suporte a websockets é uma obrigação para os recursos internos que desejo expor por meio do proxy reverso. De fato, o próprio roteador os utiliza em sua própria interface de gerenciamento web, e ele aparece este post nos fóruns da ubiquiti que você pode precisar de HTTP2 para isso também.


0


origem




Respostas:


NOTA: Esta resposta pressupõe que você tenha conhecimento adequado dos comandos comuns do Linux e / ou pelo menos tenha a capacidade de efetuar login no seu roteador via SSH. Se não o fizer, então você deve aprimorar suas habilidades para atender a esses pré-requisitos antes de continuar, pois não planejo abordar os fundamentos básicos dos scripts ou comandos do Linux na resposta ou nos comentários subsequentes.


Informações de antecedentes e isenção de responsabilidade (1.2 é seguro, mas 1.10 funciona)

Os roteadores Ubiquiti Edge atualmente são baseados no Debian 7 - ie. wheezy - e assim o melhor que você vai conseguir sem quebrar as normas é o nginx 1.6 (usando o wheezy-backports repositório em vez de ou além de wheezy). Isso funcionará para o suporte ao websocket, mas as opções mais recentes, como http2, ainda estarão ausentes.

Para obter versões mais recentes como 1,10, você terá que sair da sua zona de conforto um pouco e começar a usar os novos repositórios do Debian 8 - ie jessie e jessie-backports. Eu digo "saia da sua zona de conforto" não devido a uma experiência ruim, mas porque a lógica ditaria que provavelmente há uma razão pela qual a Ubiquiti ainda está usando wheezy no roteador e, portanto, algum risco está implícito com o uso jessie pacotes quando eles dependem da atualização de outros pacotes que o roteador pode estar usando (por exemplo, libc6).

Portanto, embora eu não possa dizer que a solução abaixo não quebrará QUALQUER recurso do roteador, posso dizer que uso uma quantidade razoável dos recursos do roteador (incluindo servidor / cliente openvpn, balanceamento de carga e VLANs) e não tive nenhum problema.

Também consegui refazer a versão atual do OS / firmware Ubiquiti EdgeMax (1.10.5) sem qualquer problema que reverte todos os pacotes de volta para suas versões padrão / estoque. (mas note que reaparecer o firmware também apaga quaisquer ajustes / personalizações que você não tenha armazenado na /config diretório - sempre armazene-os sob /config em algum lugar e, em seguida, adicione um script de inicialização para /config/scripts/post-config.d que mantém um link para eles em outros locais, conforme necessário)

Então, eu me sinto bem confortável dizendo que as futuras atualizações da Ubiquiti provavelmente serão instaladas bem depois desta instalação - apesar de que você teria que reinstalar o nginx novamente (possivelmente usando o script abaixo).

Agora que as renúncias de sempre estão fora do caminho, aqui está o que está funcionando para mim.


Minha solução (quebrar as regras e obter 1,10)

Segurança primeiro

  1. Backup sua configuração.

  2. Se você já esteve tentando consertar o nginx, também pode ser uma boa ideia ir em frente e reinstale o firmware mais recente apenas para obter tudo de volta para um bom ponto de base (cuidado se você colocar quaisquer ajustes / personalizações fora das opções usuais de CLI configure ou web interface - você pode perdê-los).

  3. Já que você estará mexendo com os serviços que direcionam a interface web, provavelmente seria inteligente familiarize-se com os comandos necessários para atualizar atualizações de firmware do SSH também (DICA: add system image https://dl.ubnt.com/firmwares/edgemax/v1.10.x/ER-e100.v1.10.5.5098915.tar).

Agora a parte divertida

SSH * em seu roteador e execute o seguinte script (ou instruções equivalentes) que irá:

  • Configure os repositórios Debian apropriados (jessie e jessie-backports)
  • Configure as prioridades do repositório para preferir jessie-backports (caso contrário, você ainda fica preso em 1.6, que é o pacote em jessie)
  • Configure um script de inicialização que será usado para criar o diretório de log nginx em cada inicialização do sistema (caso contrário, o nginx não será iniciado quando o roteador for reinicializado)
  • Baixe / instale o mais recente estável nginx-light pacote (1.10.3 até a data deste artigo).

* Você deve NÃO use o recurso da CLI na interface da web como um substituto para o SSH, pois a interface da web provavelmente ficará temporariamente inoperante como parte desse processo.

#! /bin/bash

vcfg=/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper

echo Updating package repositories ...
echo

$vcfg begin

$vcfg delete system package

$vcfg set system package repository jessie url http://ftp.us.debian.org/debian
$vcfg set system package repository jessie components "main contrib non-free"
$vcfg set system package repository jessie distribution jessie

$vcfg set system package repository jessie-backports url http://ftp.us.debian.org/debian
$vcfg set system package repository jessie-backports components "main contrib non-free"
$vcfg set system package repository jessie-backports distribution jessie-backports

$vcfg commit

$vcfg end

apt-get update

echo
echo Setting repoisitory priorities ...
echo

echo "Package: *
Pin: release a=jessie
Pin-Priority: 900

Package: *
Pin: release a=jessie-backports
Pin-Priority: 910">/etc/apt/preferences.d/jessie

echo
echo Temporarily stopping the current web interface ...
echo
kill -SIGTERM $(cat /var/run/lighttpd.pid)

echo
echo Installing nginx-light ...
echo

echo "#! /bin/bash
[ -d /var/log/nginx ] || mkdir /var/log/nginx">/config/scripts/post-config.d/create_nginx_log_dir
chmod a+x /config/scripts/post-config.d/create_nginx_log_dir

[ -d /var/log/nginx ] || mkdir /var/log/nginx

apt-get install nginx-light -V -y

echo
echo Restarting the old web interface ...
echo
service nginx stop
/usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf

echo
echo Updating the nginx default site listen on non-standard ports ...
echo

sed -i -E 's/^(\s*)(listen\s+(:|\[|\])*)([0-9]+)(;|\s)/\1\2\4\4\5/g' /etc/nginx/sites-enabled/default

echo
echo Starting the nginx service ...
echo

service nginx start

echo
echo Installation complete.

[Resposta "yEntrar"para o prompt sobre reiniciar os serviços]

Agora você deve ter uma instalação nginx funcionando e você deve ser capaz de testá-lo navegando para http://<router IP address>:8080 no seu navegador da web. Observe a porta de uso de 8080 que deveria ter sido configurado pelo sed comando no script acima, em vez do padrão de porta 80 o que provavelmente teria entrado em conflito com a interface da Web do roteador padrão.

O nginx vai servir como um proxy reverso para o seu roteador?

Eu pessoalmente prefiro usar uma porta não padrão (553 na configuração de exemplo abaixo) para o lighttpd serviço / GUI fornecido por padrão no roteador e, em seguida, usar o nginx (escutando nas portas padrão 80/443) como um proxy reverso para lighttpd. Isso permite que eu use um nome de domínio para todos os sites da minha rede local, incluindo o roteador (ou seja, router.myhouse.com, nas.myhouse.com, etc.). Se você quiser fazer o mesmo, pode alterar sua porta GUI usando o configure -> set service gui http(s)-port ### declaração ou fazendo a mesma mudança no Config Tree seção da interface web / GUI.

Configurar o nginx com um arquivo de configuração do proxy reverso

Em seguida, você desejará configurar o nginx para atuar como um proxy reverso de algum recurso. Geralmente, este será um recurso de rede local acessível usando um nome de host / domínio específico na URL que resolve a porta de escuta nginx do roteador.

Para fazer isso, você cria um arquivo de configuração nginx no seu /etc/nginx/sites-enabled diretório (ou melhor ainda criar sob /config/user-data e, em seguida, criar um link para isso sob o /etc/nginx/sites-enableddiretório - isso facilitará a recuperação de atualizações que reconfiguram /etc conteúdo do diretório).

Existem vários exemplos de arquivos de configuração do nginx on-line, mas o exemplo abaixo pode ser benéfico se você planeja colocar sua interface de roteador (ou algum outro site que use websockets) por trás do proxy reverso nginx. Ou se você está procurando especificamente colocar um Synology NAS atrás dele (a estação fotográfica em particular é um pouco complicada).

upstream edgemax {
  server 192.168.1.1:553;
  keepalive 32;
}

upstream nas {
  server 192.168.1.7:5001;
  keepalive 32;
}

upstream nasphoto {
  server 192.168.1.5:443;
  keepalive 32;
}

upstream nasfile {
  server 192.168.1.7:7001;
  keepalive 32;
}

server {
  listen 443 ssl http2;
  server_name router.*;

  ssl_certificate /config/user-data/ssl_chain_key.pem;
  ssl_certificate_key /config/user-data/ssl_chain_key.pem;

  client_max_body_size 0;
  proxy_http_version 1.1;
  proxy_buffering off;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;

  location / {
    proxy_pass https://edgemax;
  }
}

server {
  listen 443 ssl http2;
  server_name nas.*;

  ssl_certificate /config/user-data/ssl_chain_key.pem;
  ssl_certificate_key /config/user-data/ssl_chain_key.pem;

  client_max_body_size 0;
  proxy_http_version 1.1;
  proxy_buffering off;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;

  location / {
    proxy_pass https://nas;
  }

  location /photo {
    proxy_pass https://nasphoto/photo;
  }
}

server {
  listen 443 ssl http2;
  server_name files.*;

  ssl_certificate /config/user-data/ssl_chain_key.pem;
  ssl_certificate_key /config/user-data/ssl_chain_key.pem;

  client_max_body_size 0;
  proxy_http_version 1.1;
  proxy_buffering off;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;

  location / {
    proxy_pass https://nasfile;
  }
}

server {
  listen 443 ssl http2;
  server_name photos.*;

  ssl_certificate /config/user-data/ssl_chain_key.pem;
  ssl_certificate_key /config/user-data/ssl_chain_key.pem;

  client_max_body_size 0;
  proxy_http_version 1.1;
  proxy_buffering off;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;

  rewrite ^/photo/(.*)$ /$1;

  location / {
    proxy_pass https://nasphoto/photo/;
  }
}

Depois que o arquivo de configuração do proxy reverso estiver no lugar, você poderá executar sudo service nginx restart para torná-lo eficaz. Referir-se /var/log/nginx/error.log se houver problemas.

DICA # 1: Se você planeja usar uma porta não padrão para o seu proxy reverso nginx (ou seja, a configuração do seu proxy reverso diz algo diferente de listen 80 e / ou listen 443) então você provavelmente estaria bem servido para substituir proxy_set_header Host $host; na configuração acima com proxy_set_header Host $http_host;. Isso é especialmente importante para websockets que parecem sempre querer fazer com que os clientes da Web solicitem tráfego das portas padrão - levando a interfaces com componentes ausentes ou dados ativos. (Você também pode tentar proxy_set_header Host $host:$server_port;, mas note que isso é distintamente diferente, pois sempre adicionará uma porta ao cabeçalho mesmo quando não foi usado na solicitação original)

DICA # 2: Observe também o uso de server_name router.* o que significa simplesmente que usando o URL router.<anything>.<anything> para procurar o proxy reverso nginx fará com que essa seção da configuração seja aplicada. (A maioria dos exemplos que você encontrará usa um nome de domínio completo / explícito como router.domain.com)

Isso é útil não apenas para o propósito de alterar potencialmente os nomes de domínio / nomes de DNS (ou seja, trabalhos para router.home.com assim como router.home.net sem alterar a configuração), mas também ajuda a manter sua server_name entradas curtas. Isso é importante porque ter nomes longos geralmente resultará em erros dizendo algo como "aumentar o tamanho do seu intervalo" ao iniciar o nginx. Se você precisa ter nomes longos, provavelmente precisará ajustar os valores de server_names_hash_max_size e / ou server_names_hash_bucket_size dentro de sua configuração.


ATUALIZAR: Eu atualizei com êxito meu roteador de 1.9.1 para 1.9.1.1 para 1.9.7 + hotfix3 para 1.9.7 + hotfix4 para 1.10.1 para 1.10.3 para 1.10.5 com praticamente zero problemas. O roteador não tinha nginx após a atualização (como esperado), mas eu consegui executar meu script (o primeiro bloco de código nesta resposta) e ele veio de volta. Mantendo suas personalizações sob /config e usando scripts sob /config/scripts/post-config.d manter as alterações que não sobrevivem a uma reinicialização / atualização é a chave para suavizar a navegação aqui.

ATUALIZAÇÃO # 2: Esse processo também funciona em roteadores menores, como o ER-X. No entanto, devido ao armazenamento limitado disponível no dispositivo, você será forçado a remover a imagem do firmware inativo para liberar espaço para o nginx. Isso precisa ser feito após cada atualização também. Para remover a imagem de firmware inativa, execute delete system image e responda sim ao (s) prompt (s).

- Meu processo de atualização do ER-X -

  1. Backup minha configuração !!!!
  2. Atualize para o firmware mais recente e reinicie (e verifique a funcionalidade básica diferente do nginx)
  3. Remova o firmware antigo (que agora é a imagem inativa) usando o delete system image comando (show system storage relata 80% em uso antes da remoção e 35% em uso posteriormente)
  4. Use os scripts / etapas acima para reinstalar o nginx (show system storage relata 78% em uso após a instalação)
  5. Corre sudo apt-get clean para liberar espaço usado por arquivos temporários e tal (show system storage relata 60% em uso após a limpeza)

1



@ vladimir-samoilovSe você precisar de mais ajuda, poste / comente aqui com detalhes específicos sobre o assunto que você está tendo (e aumente a votação da pergunta / resposta se você achou útil). - David Woodward