Назад | Перейти на главную страницу

Apache отклоняет HTTP CONNECT через SSL на виртуальном хосте, отличном от стандартного

У меня есть сервер apache 2.4.18, работающий с несколькими хостами.

/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>

У меня также есть работающий SSH-сервер, работающий на порту 2222 той же машины.

Если я использую proxytunnel с удаленного компьютера для доступа к SSH-серверу через SSL, используя apache в качестве прокси-сервера:

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

Я получаю следующую ошибку:

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

Но если я включу файл /etc/apache2/proxytunnel/main.conf в моем /etc/apache2/sites-enabled/000-default-ssl.conf vhost, работает ...

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

Итак, я пришел к выводу, что для того, чтобы запрос CONNECT работал через сервер apache через SSL, AllowCONNECT Директива должна быть помещена в виртуальный хост по умолчанию для порта прокси-сервера apache в дополнение к фактическому виртуальному хосту, на котором выполняется запрос.

Обратите внимание, что поведение не воспроизводится при использовании CONNECT через HTTP (вместо HTTPS), а шифрование отключено в proxytunnel. Кроме того, проблема не исходит от proxytunnel, поскольку запрос правильно перенаправляется в apache и присутствует в журналах сервера: именно apache активно отказывается от него, потому что считает метод HTTP (CONNECT) недопустимым на этом сервере (хотя это разрешено в vhost, о котором идет речь).

Я хотел бы дополнить этот вопрос, предоставив отзыв о моем собственном опыте .. Я пока не могу комментировать.

Я использую Proxytunnel 1.9.9 (примерно апрель 2018 г.) в Windows 7, который я скомпилировал из источников с использованием 32-разрядной версии Cygwin.

В ходе тестирования я обнаружил, что Proxytunnel неправильно сопоставляет имя хоста из аргумента -p с именем сервера в виртуальном хосте Apache2. Использование Proxytunnel для туннелирования через один локальный прокси-сервер http ИЛИ https дает сбой, если виртуальный хост, содержащий метод AllowCONNECT, не является виртуальным хостом по умолчанию.

Перечислите виртуальные хосты, которые включены в Apache, и посмотрите, какой из них установлен по умолчанию:

apachectl -S

В моей настройке у меня есть каждый виртуальный хост в своем собственном файле в каталоге сайтов. Выполните эту команду:

ls -1

Первый файл, указанный в каталоге sites-available, - это виртуальный хост, который apache2 сделает виртуальным хостом по умолчанию. Таким образом, я поменял местами свой прокси-сервер http (или https) как виртуальный хост по умолчанию и второй в строке ..., изменив его имя, чтобы оно не появлялось первым в списке каталогов.

Я обнаружил, что эта команда для локального прокси http:

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

Или эту команду для локального прокси https:

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

Дайте мне баннер OpenSSH, если метод AllowCONNECT находился в виртуальном хосте по умолчанию, но выдает ошибку HTTP 405, если это не так ... даже если виртуальный хост порта 80 не по умолчанию содержит:

ServerName http-forward-proxy.com

Или в случае проксирования на прокси-сервер https, когда виртуальный хост порта 443, отличный от порта по умолчанию, содержал:

ServerName https-forward-proxy.com

Я просмотрел журналы Apache2 и подтвердил, что обработка всегда идет на виртуальный хост по умолчанию.

Я также опубликовал «Проблема» о HTTP-запросе на странице Proxytunnel GitHub. https://github.com/proxytunnel/proxytunnel/issues/31

тем не мение

Я использую клиентскую сторону Proxytunnel с sslh и серверной частью stunnel. В этом сценарии я обнаружил, что имя хоста в команде Proxytunnel действительно совпадает с функцией sni_hostnames {} в sslh, поэтому в этом контексте кажется, что имя хоста передается правильно, по крайней мере, когда зашифровано и используется SNI.

Кроме того, проблема не в прокси-туннеле, поскольку запрос правильно перенаправляется на apache и присутствует в журналах сервера.

Это было неправильно, proxytunnel не поддерживает SNI в используемой мной версии (последняя фиксация из их репозитория на дату этой публикации, поэтому что-то немного впереди 1.9.1, если я доверяю их тегам выпуска).

Вследствие этого vhost, выбранный apache, является виртуальным хостом по умолчанию, независимо от того, к какому хосту я пытаюсь ПОДКЛЮЧИТЬСЯ.

Спасибо за вопрос и за написание заключения. Теперь у меня рабочая установка, спасибо вам! Использование vhost по умолчанию apache работает нормально.

Интересно, правда ли проблема с SNI прокси-туннеля. В моем случае у меня https://app1.example.com который выходит как стандартный vhost apache и другой vhost https://example.com. Мой сертификат letsencrypt имеет общее имя app1.example.com, а имя субъекта - example.com.

Если я добавлю ProxyRequests on на example.com это просто не действует. Если я перенесу его на app1.example.com, он будет работать нормально.

Я понимаю, что SNI не требуется в случае одного сертификата на одном IP-адресе для многих хостов.

Также я использую curl для тестов, как в curl -v -x https://example.com https://somethingelse.com. Curl поддерживает SNI, и я проверил с помощью wirehark: он ДЕЙСТВИТЕЛЬНО отправляет правильное имя хоста в расширении рукопожатия для запроса CONNECT и для запроса GET. Я все еще получаю 405 Method Not Allowed.

Казалось бы, проблема в том, что mod_proxy не активируется правильно. Что вы думаете?

Я использую apache 2.4.25.