Certificado SSL para conexão ao servidor inicial através de socat

3

Estou executando o Nextcloud em um Raspberry Pi em casa. Ele atualiza seu endereço IPv6 em um nome de host no spDYN.de do provedor DynDNS. No entanto, como meu provedor oferece apenas conexões IPv6 (usando o DS-Lite para IPv4), só posso acessar diretamente o nome do host de outras conexões IPv6 e preciso usar um postmapper IPv4-IPv6 para se conectar a ele de redes IPv4.

Isso não é grande coisa, pois meu site está hospedado em um servidor que tem conexões IPv6 e IPv4, então usei socat de acordo com este tutorial para configurar um portmapper no servidor que hospeda o meu site, roteando uma porta específica do domínio do meu site para a porta 443 no hostname do DNS dinâmico. Isso funciona perfeitamente, mas cria um problema com certificados SSL:

No RasPi, usei o certbot para criar um certificado "Vamos criptografar" para o nome de host DNS dinâmico, que funciona perfeitamente e a conexão é mostrada como segura. Além disso, no meu servidor, criei um certificado semelhante para o domínio que estou usando para o portmapper, que por si só funciona. No entanto, quando eu acesso o domínio com a porta encaminhada específica para acessar o RasPi, o navegador continua a mostrar o URL que contém meu domínio, mas ele recebe o certificado do RasPi que foi emitido para o nome de host DNS dinâmico. Como consequência, é claro, a verificação de segurança falha quando o certificado é emitido para o domínio "errado". Eu já tentei emitir um certificado no meu RasPi para o meu domínio, mas não me diz que sou "não autorizado".

Como posso resolver este problema? Onde devo configurar qual tipo de certificado?

    
por iYassin 29.09.2017 / 15:07

1 resposta

2

Para evitar erros de certificado, você precisa que pi envie um certificado que corresponda ao domínio usado. Existem duas abordagens para isso:

  1. Use um certificado para ambos os domínios, instalado no pi e no servidor principal. Não importa qual domínio o cliente usou em sua consulta, o certificado corresponderá.
  2. Escolha um certificado que o cliente espera e envie-o.

A opção 1 é uma prática mais fácil e comum. Veja o certificado para google.com! Tanto o pi quanto o servidor principal terão o mesmo certificado (para ambos os domínios) instalado. Para obter um certificado desse tipo, vamos precisar que o servidor principal também execute um site para o domínio dinâmico do pi e use o um certbot para verificar o controle de ambos os domínios de uma só vez. O site principal do servidor para o nome dyndns não precisa hospedar o conteúdo do pi - está apenas lá, então Let's Encrypt pode verificar se você tem controle sobre esse site (você pode até desativar esse site entre as renovações).

Exemplo de comando do Certbot para isso (executado no servidor web principal):

letsencrypt certonly --webroot --csr request.csr -w /http/pisite/www -d mypi.spdyn.de -w /http/mainwebsite/www -d maindomain.de

Onde request.csr usa domínio como o CN e tem os dois domínios no campo SANs, /http/pisite/www refere-se a um diretório local que você criaria para outro site no servidor vinculado ao nome dinâmico do pi e /http/mainwebsite/www é o diretório existente do seu site principal.

A opção 2 está mais envolvida, mas produz um resultado "mais limpo": o cliente obtém um certificado que corresponde ao domínio digitado. No raspberry pi, execute nginx com o módulo de fluxo (ou equivalente) que, quando uma conexão TLS é aberta: examina o campo SNI (sem aceitar a conexão TLS) e, com base no domínio incluído, escolhe a qual encaminhará o ligação a. Isso permite escolher como você deseja lidar com solicitações feitas do domínio principal na porta externa encaminhada para o raspberry pi. Você pode enviá-los para o servidor web principal como se fossem feitos na porta correta, você pode enviá-los para alguma outra porta no pi (ou seja, Nextcloud, ou qualquer outra coisa), você pode terminá-los com a mesma instância nginx e mostre a página que quiser ou simplesmente feche a conexão. A escolha é sua.

Aqui está uma configuração de exemplo para este método:

stream/sni-switch.conf

# Listen on 443, and on new connection:
#   if the SNI is mapped herein, handle it on this Nginx
#   else, forward the whole session to 192.168.1.80:443 (TCP passthrough, no decryption)

upstream mainwebserver {
    server 192.168.1.80:443;
}

upstream local_https {
    server 127.0.0.1:1443;
}

map $ssl_preread_server_name $name {
    default mainwebserver;

    pisite.spdyn.de     local_https;
}

server {
    listen 443;

    ssl_preread on;
    proxy_pass $name;
}

E em nginx.conf

load_module /usr/lib/nginx/modules/ngx_stream_module.so;

stream {
    include /etc/nginx/stream/sni-switch.conf;
}

...

Para fazer isso com o Apache, consulte este . Uma configuração de amostra da qual pode ter esta aparência:

<VirtualHost *:*>
    ProxyPreserveHost On
    ProxyPass        "/" "http://192.168.1.80/"
    ProxyPassReverse "/" "http://192.168.1.80/"
    ServerName maindomain.de
</VirtualHost>
    
por 30.09.2017 / 13:23