O Apache recusa o HTTP CONNECT por SSL no host virtual não padrão

1

Eu tenho um servidor apache 2.4.18 em execução com vários vhosts.

/etc/apache2/sites-enabled/000-default.conf:

<VirtualHost *:80>
    DocumentRoot /var/www/html
    Redirect 400 /
</VirtualHost>

/etc/apache2/sites-enabled/000-default-ssl.conf:

<VirtualHost _default_:443>
    DocumentRoot /var/www/html
    SSLEngine on
    SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
    SSLCertificateKeyFile   /etc/ssl/private/ssl-cert-snakeoil.key
</VirtualHost>

/etc/apache2/sites-enabled/001-custom.conf:

<VirtualHost _default_:443>
    ServerName www.example.org

    Include /etc/apache2/letsencrypt/main.conf
    SSLCertificateFile      /etc/letsencrypt/live/example.org/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.org/privkey.pem

    Include /etc/apache2/proxytunnel/main.conf
</VirtualHost>

<VirtualHost *:80>
    ServerName www.example.org
    Redirect permanent / https://www.example.org/
</VirtualHost>

/etc/apache2/proxytunnel/main.conf:

ProxyRequests On
AllowConnect 2222
<Proxy *>
    Order deny,allow
    Deny from all
</Proxy>
<Proxy 127.0.0.1>
    Order deny,allow
    Allow from all
</Proxy>

Eu também tenho um servidor SSH em execução na porta 2222 da mesma máquina.

Se eu usar proxytunnel de uma máquina remota para acessar o servidor SSH por SSL, usando o apache como servidor proxy:

proxytunnel -v -E -p www.example.org:443 -d 127.0.0.1:2222

Eu recebo o seguinte erro:

SSL client to proxy enabled
Local proxy www.example.org resolves to xxx.xxx.xxx.xxx
Connected to www.example.org:443 (local proxy)

Tunneling to 127.0.0.1:2222 (destination)
Communication with local proxy:
 -> CONNECT 127.0.0.1:2222 HTTP/1.1
 -> Host: 127.0.0.1:2222
 -> Proxy-Connection: Keep-Alive
 <- HTTP/1.1 405 Method Not Allowed

HTTP return code: 405 Method Not Allowed
 <- Date: Thu, 14 Apr 2016 00:55:57 GMT
 <- Server: Apache/2.4.18 (Debian)
 <- Allow: GET,HEAD,POST,OPTIONS
 <- Content-Length: 309
 <- Content-Type: text/html; charset=iso-8859-1

Mas se eu incluir o arquivo /etc/apache2/proxytunnel/main.conf no meu /etc/apache2/sites-enabled/000-default-ssl.conf vhost, funcionará ...

SSL client to proxy enabled
Local proxy www.example.org resolves to xxx.xxx.xxx.xxx
Connected to www.example.org:443 (local proxy)

Tunneling to 127.0.0.1:2222 (destination)
Communication with local proxy:
 -> CONNECT 127.0.0.1:2222 HTTP/1.1
 -> Host: 127.0.0.1:2222
 -> Proxy-Connection: Keep-Alive
 <- HTTP/1.0 200 Connection Established

 <- Proxy-agent: Apache/2.4.18 (Debian)

 Tunnel established.
 SSH-2.0-OpenSSH_7.2p2 Debian-2

Portanto, minha conclusão é que, para uma solicitação CONNECT funcionar através de um servidor apache sobre SSL, a diretiva AllowCONNECT deve ser colocada no vhost padrão para a porta do proxy apache, além do host real que a solicitação é feita. / p>

Observe que o comportamento não é reproduzido ao usar CONNECT sobre HTTP (em vez de HTTPS) e a criptografia está desativada no proxytunnel. Além disso, o problema não vem do proxytunnel, pois o pedido é corretamente encaminhado para o apache e está presente nos logs do servidor: é o apache que o recusa ativamente porque considera o método HTTP (CONNECT) inválido neste servidor (embora seja permitido no vhost que está em causa).

    
por Maxime Rossini 14.04.2016 / 03:29

3 respostas

1

Also, the problem does not come from proxytunnel as the request is correctly forwarded to apache and is present in the server logs

Isso estava errado, proxytunnel não suporta SNI na versão que eu uso ( commit mais recente de seu repositório como da data deste post, então algo um pouco à frente do 1.9.1 se eu confio em suas tags de lançamento).

A conseqüência é que o vhost selecionado pelo apache é o vhost padrão, não importa qual host eu tente CONECTAR.

    
por 15.04.2016 / 11:48
1

Eu gostaria de acrescentar a essa pergunta fornecendo feedback sobre minha própria experiência. Não posso comentar ainda.

Estou usando o Proxytunnel 1.9.9 (por volta de abril de 2018) no Windows 7, que eu compilei a partir de fontes usando o Cygwin 32-bit.

Em meus testes, descobri que Proxytunnel não corresponde corretamente ao nome do host do argumento -p com o ServerName em um Apache2 Virtualhost. O uso do Proxytunnel para encapsular um proxy local http OU https falha, a menos que o virtualhost que contém o método AllowCONNECT seja o Virtualhost padrão.

Listar os Virtualhosts que estão habilitados no Apache e ver qual é o padrão:

apachectl -S

Na minha configuração, eu tenho cada virtualhost em seu próprio arquivo no diretório de sites disponíveis. Execute este comando:

ls -1

O primeiro arquivo listado no diretório de sites disponíveis é o virtualhost, que o apache2 fará o virtualhost padrão. Dessa forma, eu troquei o meu proxy de encaminhamento http (ou https) como sendo o virtualhost padrão e o segundo na linha ... mudando seu nome para que ele não aparecesse primeiro em uma lista de diretórios.

Eu encontrei este comando para um proxy local http:

proxytunnel -v -p http-forward-proxy.com:80 -d 192.168.0.10:22

Ou este comando para um proxy local https:

proxytunnel -v -E -C root.pem https-forward-proxy.com:443 -d 192.168.0.10:22

Deu-me o banner do OpenSSH se o método AllowCONNECT estivesse no Virtualhost padrão, mas um erro HTTP 405 se ele não estivesse ... mesmo quando um virtualhost de porta 80 não padrão continha:

ServerName http-forward-proxy.com

Ou no caso de proxy para um proxy de encaminhamento de https, quando um virtualhost de porta 443 não padrão continha:

ServerName https-forward-proxy.com

Eu olhei os logs do Apache2 e o processamento confirmado sempre vai para o virtualhost padrão.

Também publiquei um "Problema" sobre o caso HTTP na página Proxytunnel GitHub link

No entanto

Eu uso o lado do cliente Proxytunnel com o lado do servidor sslh e stunnel. Nesse cenário, descobri que o nome do host no comando Proxytunnel corresponde ao recurso sni_hostnames {} em sslh, de modo que, nesse contexto, o nome do host parece ser transferido corretamente, pelo menos, quando criptografado e usado o SNI.

    
por 04.06.2018 / 13:41
0

Obrigado pela pergunta e por escrever sua conclusão. Eu tenho uma configuração de trabalho agora, graças a você! Usar o vhost padrão do apache funciona bem.

Gostaria de saber se o SNI do proxytunnel é realmente o problema, no entanto. No meu caso, eu tenho o link que aparece como o vhost padrão do apache e outro vhost link . Meu certificado letsencrypt tem nome comum app1.example.com e um nome de assunto é example.com.

Se eu adicionar ProxyRequests on ao example.com, isso simplesmente não terá efeito. Se eu movê-lo para app1.example.com, ele funciona bem.

Entendo que o SNI não é necessário no caso de um certificado em um único ip para muitos vhosts.

Além disso, uso o curl para testes como em curl -v -x https://example.com https://somethingelse.com . Curl suporta SNI e eu verifiquei com wireshark: ele envia o nome do host correto na extensão de handshake para a solicitação CONNECT e para a solicitação GET. Eu ainda recebo 405 Method Not Allowed .

Assim, parece que o problema está no mod_proxy não ativar corretamente. O que você acha?

Estou no apache 2.4.25.

    
por 07.06.2018 / 04:42