Создание прокси не может правильно туннелировать через SSL после того, как браузер отправляет запрос CONNECT? - PullRequest
2 голосов
/ 07 августа 2011

В течение некоторого времени меня преследовали, пытаясь заставить мой собственный прокси корректно обрабатываться, когда браузер отправлял запрос CONNECT. Для простоты позвольте мне объяснить, как я справляюсь с процессом. Может быть, в этот момент кто-то может помочь уточнить, что я делаю неправильно.

  1. Создание сервера с ServerSocketChannel на порту 8080.
  2. Привязать этот ServerSocketChannel к селектору, который, по существу, позволяет неблокировать, пока сервер ожидает запрос от порта 8080.
  3. Как только я установил в своем браузере порт 8080 и отправил запрос https://google.com, он уведомил селектор о том, что что-то отправлено в порт 8080.
  4. Я получаю этот запрос и вижу его СОЕДИНЕНИЕ, поэтому я немедленно создаю ответ «Соединение установлено» (запрос и ответ, которые я отправляю и получаю, приведены ниже)

Запрос из браузера:

ПОДКЛЮЧИТЕ google.com:443 HTTP / 1.1 Пользователь-агент: Mozilla / 5.0 (Windows; U; Windows NT 6.1; en-US; rv: 1.9.2.18) Gecko / 20110614 Firefox / 3.6.18 GTB7.1 Прокси-соединение: keep-alive Хост: google.com

Ответ, который я отправляю обратно в браузер через мой обычный сокет:

HTTP / 1.1 200 Соединение установлено \ r \ nПрокси-соединение: Keep-alive \ r \ n \ r \ n

  1. Теперь я жду, чтобы что-то было отправлено из браузера. Я предполагал, что в этот момент будет отправлен запрос SSL, но ничего не отправляется. Я начинаю думать, потому что я не установил рукопожатие SSL с браузером, поэтому он не собирается отправлять сообщение SSL через этот сокет, созданный по умолчанию. Как вы думаете, мне нужно закрыть этот сокет через порт 8080 и установить новый SecureSocket на порт 8080 прямо перед отправкой ответа об установлении соединения обратно в браузер? Это мой следующий шаг. Я знаю, что браузер должен отправить мне больше данных после первоначального подключения. У меня недостаточно данных только с CONNECT, чтобы перейти на сервер. Я думаю, что нужно отправить мне еще один запрос что-то вроде следующего в SSL:

GET / Хост: google.com

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

Что вы думаете на правильном пути? Просто я не получаю дополнительного сообщения после того, как отправляю соединение

1 Ответ

7 голосов
/ 08 августа 2011

Я получаю этот запрос и вижу его СОЕДИНЕНИЕ, поэтому я немедленно создаю ответ "Соединение установлено"

Это неправильно для начала.Вы не должны отправлять «Соединение установлено» до тех пор, пока не установит соединение в восходящем направлении.Вы лжете своему клиенту!

Я начинаю думать, что это потому, что я не установил рукопожатие SSL с браузером

Не имеет значения.После того, как вы это сделаете, следующая вещь, которую вы получите от клиента, это бинарная, насколько вам это интересно.Все, что вы должны делать с этого момента, это копировать байты.

Как вы думаете, мне нужно закрыть этот сокет через порт 8080 и установить новый SecureSocket на порт 8080

Нет.

Как только я получу что-то подобное, я могу установить безопасное соединение через сокет с сервером

Неверно.Как только вы получаете данные от клиента, вы должны прозрачно отправить их через существующее незашифрованное соединение с вышестоящим сервером.Вам не нужно самостоятельно подключаться к SSL.

У меня недостаточно данных только с CONNECT, чтобы перейти на сервер.

Да, вы делаете.Вы должны сформировать восходящее соединение, когда вам скажут об этом, и сообщить клиенту, что вы сделали это, когда вы действительно сделали это, а не раньше.

Что вы думаете на правильном пути?

Нет.

Просто я не получаю никаких дополнительных сообщений после отправки установленного соединения.

Это может означать, что у вас нетеще ничего не отправил.Код NIO сложен.Каким был код возврата API write ()?

...