У меня есть сервер 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.