Рейтинг:1

stunnel + squid = 1 запрос на 5 минут (остаточное соединение сбрасывается пиром)

флаг us

тл;др;

Конфигурация с stunnel на клиенте, который подключается к прокси-серверу squid с аутентификацией по сертификату x509, работает только для одного запроса в 5 минут. Сценарий:

  • Кальмар и оглушать настроил и запустил
  • wget настроен на использование локальный хост как прокси (оглушать)
  • Только 1 запрос (например, wget https://github.com) за 5 минут (или оглушать перезагрузка) работа отдых получил соединение сброшено узлом
  • Использование необработанного соединения, например openssl s_client -key -cert -connect использование прямой связи со squid работает правильно

Описание

Я настраиваю архитектуру оглушать установлен на клиенте, что приводит к кальмар прокси с сертификат x509 аутентификация.

Настройка клиента оглушать с его сертификатом, который подключается к кальмар, затем настройте HTTP_ПРОКСИ стремиться к конечной точке оглушения в локальный хост.

Доверительный путь корректно настроен на каждой стороне, поэтому и сертификаты squid от клиента, и клиент доверяют сертификату squid на каждом уровне - Root CA и промежуточном CA.

Конфигурация станнеля:

sslVersion=TLSv1.2
вывод=/var/журнал/stunnel4/stunnel.log
[сквид-gcp]
сертификат = /etc/letsencrypt/live/test.internal/fullchain.pem
ключ = /etc/letsencrypt/live/test.internal/privkey.pem
CAFile = /usr/local/share/ca-certificates/root.crt
клиент = да
отладка=7
принять = 127.0.0.1:3128
соединение = squid.internal:3128

Конфигурация кальмара

acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "эта" сеть (LAN)
acl localnet src 10.0.0.0/8 # RFC 1918 локальная частная сеть (LAN)
acl localnet src 100.64.0.0/10 # RFC 6598 общее адресное пространство (CGN)
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (подключенные напрямую) машины
acl localnet src 172.16.0.0/12 # RFC 1918 локальная частная сеть (LAN)
acl localnet src 192.168.0.0/16 # RFC 1918 локальная частная сеть (LAN)
acl localnet src fc00::/7 # RFC 4193 диапазон локальной частной сети
acl localnet src fe80::/10 # RFC 4291 локальные (подключенные напрямую) машины
acl SSL_ports порт 443
acl Safe_ports порт 80 # http
acl Safe_ports порт 21 # ftp
acl Safe_ports порт 443 # https
acl Safe_ports порт 70 # суслик
acl Safe_ports порт 210 # wais
acl Safe_ports port 1025-65535 # незарегистрированные порты
acl Safe_ports порт 280 # http-mgmt
acl Safe_ports порт 488 # gss-http
acl Safe_ports порт 591 # файлмейкер
acl Safe_ports порт 777 # мультилинк http
acl метод CONNECT CONNECT
acl cert user_cert CN test.internal
http_access разрешить диспетчеру локального хоста
http_access менеджер запрета доступа
http_access запретить to_localhost
http_access разрешить сертификат
http_access разрешить локальный хост
http_access разрешить службу поддержки
http_access запретить всем
https_port 3128 tls-cert=/etc/letsencrypt/live/squid.internal/cert.pem tls-key=/etc/letsencrypt/live/squid.internal/privkey.pem options=NO_SSLv3:NO_TLSv1:NO_TLSv1_1:NO_TLSv1_3:NO_TICKET clientca =/usr/local/share/ca-certificates/root.crt cafile=/usr/local/share/ca-certificates/root.crt tls-default-ca=off
client_idle_pconn_timeout 5 минут
client_persistent_connections на
pconn_lifetime 0
logformat squidtls %tl %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt "%ssl::>cert_subject"
Демон access_log:/var/log/squid/access-tls.log squidtls
кэш запретить все
cache_dir null /tmp
shutdown_lifetime 1 секунда
coredump_dir /var/cache/squid

Теперь что происходит на клиенте, правильно настроив HTTPS_PROXY=localhost:3128, первый запрос через squid принимается, а следующие отклоняются с соединение сброшено узлом. Через 5 минут или перезапуска stunnel следующий запрос обрабатывается правильно.

Журналы из stunnel, когда это происходит, первый запрос принят, второй отклонен:

2021.07.07 14:27:59 LOG7[0]: служба [squid-gcp] запущена
2021.07.07 14:27:59 LOG7[0]: установка параметров локального сокета (FD=3)
2021.07.07 14:27:59 LOG7[0]: параметр TCP_NODELAY установлен для локального сокета
2021.07.07 14:27:59 LOG5[0]: Служба [squid-gcp] приняла соединение с 127.0.0.1:50142
2021.07.07 14:27:59 LOG6[0]: s_connect: подключение 100.112.0.62:3128
2021.07.07 14:27:59 LOG7[0]: s_connect: s_poll_wait 100.112.0.62:3128: ожидание 10 секунд
2021.07.07 14:27:59 LOG7[0]: FD=6 событий=0x2001 revents=0x0
2021.07.07 14:27:59 LOG7[0]: FD=11, события=0x2005, события=0x0
2021.07.07 14:27:59 LOG5[0]: s_connect: подключено 100.112.0.62:3128
2021.07.07 14:27:59 LOG5[0]: Служба [squid-gcp] подключилась к удаленному серверу с 100.112.0.63:50392
2021.07.07 14:27:59 LOG7[0]: установка параметров удаленного сокета (FD=11)
2021.07.07 14:27:59 LOG7[0]: параметр TCP_NODELAY установлен для удаленного сокета
2021.07.07 14:27:59 LOG7[0]: удаленный дескриптор (FD=11) инициализирован
2021.07.07 14:27:59 LOG6[0]: SNI: отправка имени сервера: squid.internal
2021.07.07 14:27:59 LOG6[0]: одноранговый сертификат не требуется
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): до инициализации SSL
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): SSLv3/TLS запись клиента привет
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): SSLv3/TLS запись клиента привет
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): SSLv3/TLS чтение сервера привет
2021.07.07 14:27:59 LOG6[0]: проверка сертификата отключена
2021.07.07 14:27:59 LOG6[0]: проверка сертификата отключена
2021.07.07 14:27:59 LOG6[0]: проверка сертификата отключена
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): SSLv3/TLS чтение сертификата сервера
2021.07.07 14:27:59 LOG6[0]: ЦС клиента: O=внутренний ЦС GCP, CN=внутренний ЦС GCP, корневой ЦС
2021.07.07 14:27:59 LOG6[0]: ЦС клиента: O=Внутренний ЦС GCP, CN=Внутренний ЦС GCP Промежуточный ЦС
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): SSLv3/TLS чтение запроса сертификата сервера
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): сервер чтения SSLv3/TLS выполнен
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): SSLv3/TLS запись сертификата клиента
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): обмен ключами клиента записи SSLv3/TLS
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): проверка сертификата записи SSLv3/TLS
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): SSLv3/TLS запись изменения спецификации шифра
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): запись SSLv3/TLS завершена
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): запись SSLv3/TLS завершена
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): SSLv3/TLS читает спецификацию шифрования изменения
2021.07.07 14:27:59 LOG7[0]: состояние TLS (подключение): чтение SSLv3/TLS завершено
2021.07.07 14:27:59 LOG7[0]: обратный вызов нового сеанса
2021.07.07 14:27:59 LOG7[0]: сертификат узла был кэширован (2601 байт)
2021.07.07 14:27:59 LOG6[0]: идентификатор сеанса: 383CDD4E8AA87AC2ED148172C025D1A5ECE0A1FF114362503BCDED36B9BB44B0
2021.07.07 14:27:59 LOG7[0]: запрошено 1 подключение клиента
2021.07.07 14:27:59 LOG7[0]: 1 успешное подключение клиента
2021.07.07 14:27:59 LOG7[0]: запрошено 0 повторных согласований клиента
2021.07.07 14:27:59 LOG7[0]: повторное использование сеанса 0
2021.07.07 14:27:59 LOG6[0]: TLS подключен: согласован новый сеанс
2021.07.07 14:27:59 LOG6[0]: Набор шифров TLSv1.2: AES256-GCM-SHA384 (256-битное шифрование)
2021.07.07 14:27:59 LOG7[0]: сжатие: ноль, расширение: ноль
2021.07.07 14:27:59 LOG6[0]: чтение сокета закрыто (readsocket)
2021.07.07 14:27:59 LOG7[0]: Отправка предупреждения close_notify
2021.07.07 14:27:59 LOG7[0]: предупреждение TLS (запись): предупреждение: закрыть уведомление
2021.07.07 14:27:59 LOG6[0]: SSL_shutdown успешно отправил предупреждение close_notify
2021.07.07 14:27:59 LOG7[0]: предупреждение TLS (чтение): предупреждение: закрыть уведомление
2021.07.07 14:27:59 LOG6[0]: TLS закрыт (SSL_read)
2021.07.07 14:27:59 LOG7[0]: отправлено отключение записи сокета
2021.07.07 14:27:59 LOG5[0]: соединение закрыто: 737 байтов отправлено в TLS, 234207 байтов отправлено в сокет
2021.07.07 14:27:59 LOG7[0]: удаленный дескриптор (FD=11) закрыт
2021.07.07 14:27:59 LOG7[0]: локальный дескриптор (FD=3) закрыт
2021.07.07 14:27:59 LOG7[0]: служба [squid-gcp] завершена (осталось 0)
2021.07.07 14:28:01 LOG7[1]: служба [squid-gcp] запущена
2021.07.07 14:28:01 LOG7[1]: установка параметров локального сокета (FD=3)
2021.07.07 14:28:01 LOG7[1]: параметр TCP_NODELAY установлен для локального сокета
2021.07.07 14:28:01 LOG5[1]: Служба [squid-gcp] приняла соединение с 127.0.0.1:50146
2021.07.07 14:28:01 LOG6[1]: s_connect: подключение 100.112.0.62:3128
2021.07.07 14:28:01 LOG7[1]: s_connect: s_poll_wait 100.112.0.62:3128: ожидание 10 секунд
2021.07.07 14:28:01 LOG7[1]: FD=6 событий=0x2001 revents=0x0
2021.07.07 14:28:01 LOG7[1]: FD=11, события=0x2005, события=0x0
2021.07.07 14:28:01 LOG5[1]: s_connect: подключено 100.112.0.62:3128
2021.07.07 14:28:01 LOG5[1]: Служба [squid-gcp] подключилась к удаленному серверу с 100.112.0.63:50396
2021.07.07 14:28:01 LOG7[1]: установка параметров удаленного сокета (FD=11)
2021.07.07 14:28:01 LOG7[1]: параметр TCP_NODELAY установлен для удаленного сокета
2021.07.07 14:28:01 LOG7[1]: удаленный дескриптор (FD=11) инициализирован
2021.07.07 14:28:01 LOG6[1]: SNI: отправка имени сервера: squid.internal
2021.07.07 14:28:01 LOG6[1]: сертификат узла не требуется
2021.07.07 14:28:01 LOG7[1]: состояние TLS (подключение): до инициализации SSL
2021.07.07 14:28:01 LOG7[1]: состояние TLS (подключение): SSLv3/TLS запись клиента привет
2021.07.07 14:28:01 LOG3[1]: SSL_connect: партнер внезапно отключился
2021.07.07 14:28:01 LOG5[1]: сброс соединения: 0 байтов отправлено в TLS, 0 байтов отправлено в сокет
2021.07.07 14:28:01 LOG7[1]: удаленный дескриптор (FD=11) закрыт
2021.07.07 14:28:01 LOG7[1]: локальный дескриптор (FD=3) закрыт
2021.07.07 14:28:01 LOG7[1]: служба [squid-gcp] завершена (осталось 0)

это явно похоже на то, что согласование TLS первого запроса прошло успешно, а второе даже не началось.

логи из журнала доступа к squid:

07 июля 2021:14:27:59 +0000 1625668079.646 496 100.112.0.63 TCP_TUNNEL/200 234207 ПОДКЛЮЧИТЬ github.com:443 - HIER_DIRECT/140.82.121.4 - "/CN=test.internal"
07 июля 2021:14:28:01 +0000 1625668081.958 0 100.112.0.63 НЕТ/000 0 НЕТ ошибка: завершение транзакции перед заголовками - HIER_NONE/- - "-"

Логи из кеша:

07.07.2021 14:28:01 ребенок1| Ошибка согласования соединения SSL на FD 11: ошибка: 00000001: lib (0): func (0): причина (1) (1/-1)

БОНУС

Когда я пытаюсь использовать openssl s_client а потом ПОЛУЧИТЬ https://github.com как это:

openssl s_client -cert /etc/letsencrypt/live/test.internal/cert.pem -key /etc/letsencrypt/live/test.internal/privkey.pem -connect squid.internal:3128

каждый запрос успешен:

Лог от кальмара:

07 июля 2021:14:33:24 +0000 1625668404.188 369 100.112.0.63 TCP_MISS/200 227308 ПОЛУЧИТЬ https://github.com/ - HIER_DIRECT/140.82.121.4 text/html "/CN=test.internal"
07.07.2021:14:33:50 +0000 1625668430.041 25 100.112.0.63 TCP_MISS/200 227578 ПОЛУЧИТЬ https://github.com/ - HIER_DIRECT/140.82.121.4 text/html "/CN=test.internal"
07.07.2021:14:33:55 +0000 1625668435.218 39 100.112.0.63 TCP_MISS/200 227580 ПОЛУЧИТЬ https://github.com/ - HIER_DIRECT/140.82.121.4 text/html "/CN=test.internal"

Я схожу с ума от этой проблемы. Буду признателен за любую помощь в этом.

Tom Yan avatar
флаг in
Вы делаете stunnel `connect = ` для адреса: порт экземпляра squid? IIRC это не то, как используется stunnel. Скорее вам нужно, чтобы stunnel работал в режиме сервера (т. е. без `client = yes`) на удаленном хосте на другом порту, к которому stunnel `connect=`. Затем то, что идет к `accept=` на локальной стороне, будет перехвачено и отправлено stunnel на удаленную сторону.
Tom Yan avatar
флаг in
Обратите внимание, что возможно использовать squid в качестве сервера для stunnel, но это, вероятно, не подходит для вашего варианта использования. Кстати, вам, вероятно, следует использовать `http_port` вместо `https_port` для подхода, упомянутого выше. (Ну, если вы не хотите, чтобы `wget` использовал https-прокси... двойное шифрование? Я не уверен, действительно ли `wget` поддерживает https-прокси, как `curl`; похоже, что его `https_proxy` — это просто псевдоним для `http_proxy`; или в смысле "http-прокси для ваших https-соединений"...)
флаг us
эй, @TomYan, спасибо за время, потраченное на эти комментарии! Я хочу сделать аутентификацию на основе сертификата для экземпляра `squid`. Если я создам экземпляр сервера `stunnel` на squid, а затем `подключусь` к `squid` на локальном хосте, у меня будет и исходный сертификат, и IP-адрес, совпадающий с локальным хостом (я хочу, чтобы это был клиент, и IP-адрес, и сертификат отображались в журналах), вот почему Я также использую `https_port`. Проблема здесь в том, что первый запрос, который я сделал на клиентской машине, действителен, в то время как другой сбрасывается после `client hello` squid. Я считаю, что что-то не так с конфигом squid или stunnel, но я не могу найти, что ;(
Рейтинг:0
флаг my

Действительно ли успешные запросы выполняются или они зависают (возможно, по другим, не связанным с этим причинам)?

Самое интересное в вашей конфигурации Squid заключается в том, что:

client_idle_pconn_timeout 5 минут
client_persistent_connections на
pconn_lifetime 0

Другими словами, как только клиент подключается к прокси, устанавливается постоянное соединение, которое закрывается через 5 минут простоя.

Некоторые возможные решения:

  • отключение client_persistent_connections. По сути, это означает, что каждое новое рукопожатие TCP обрабатывается как совершенно новое, что может повлиять на общую производительность, но должно решить вашу проблему.

  • явное увеличение количества одновременных подключений с одного и того же исходного IP-адреса, которое может поддерживаться. Вы можете сделать это, настроив ACL с помощью ограничение пользователякон maxconn 5 (или другой номер).

  • увеличение времени простоя до чего-то гораздо большего. Это также оказывает влияние на производительность (поддерживает соединения в течение длительного времени, что может привести к истощению ваших ресурсов).

Надеюсь, это поможет.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.