Прокси-сервер HTTP работает только в SwitchOmega
Я провел довольно много поисков и практических испытаний, прежде чем задавать этот вопрос.
Длинная история:
Я нашел (не английский) учебник о том, как написать http-прокси с Node.js.
Пока что я знал и пробовал:
- HTTP-прокси может обрабатывать как HTTP-запрос, так и HTTPS-запрос, но по-разному. Он обрабатывает HTTP-запрос, читая запрос клиента, и делает новый запрос к цели и возвращает ответ клиенту. Что касается HTTPS-запроса, он имеет дело с HTTP- туннелем.
-
SSL proxy
в настройках прокси Firefox иSecure
поле в настройках прокси IE (Windows) все о настройке туннеля HTTP. ЕслиSSL proxy
или жеSecure proxy
Когда браузер хочет подключиться к сайту https, он отправляетCONNECT
запрос вместо обычного запроса.
Проблемы:
CONNECT
запрос представляет собой простой текст, поэтому брандмауэры могут увидеть, к какому хосту я хочу подключиться, и разорвать соединение. Поэтому я подумал, смогу ли я использовать https для общения с прокси-сервером с самого начала. Я прочитал все связанные посты, но не смог найти ответ, прямо говорящий об этом. И некоторые ответы также говорят: "Нет такого понятия, как прокси-сервер https".
Но в руководстве говорится, что это можно сделать (HTTPS между клиентом и прокси-сервером и ничего больше не меняется). Поэтому я попробую. Я изменил сервер на https с сертификатом моего веб-сайта. Но в итоге он работает только с Proxy SwitchOmega в Chrome. не работает в традиционных настройках, таких как настройки прокси Firefox или IE.
Настройка прокси SwitchOmega:
Scheme|Protocol|Server|Port
.... | https | .... |...
Я должен выбрать https
протокол здесь, если я запускаю сервер https. Точно так же я должен выбрать http
протокол, если я запускаю http-сервер. Также я не знаю, что это protocol
поле обозначает.
Подвести итог:
proxy server | Firefox proxy setting |work? | SwitchOmega setting |work?|
http | http + ssl setting | yes | protocol http |yes |
https | http + ssl setting | no | protocol https |yes |
https | - | - | protocal http |no |
Итак, мои вопросы:
- Можно ли подключиться к прокси-серверу https обычным способом (без расширения)? Если возможно, то как?
- Почему я могу подключиться к прокси-серверу https через SwitchOmega?
- Я думаю, что я строю прокси-сервер https. Но почему другие говорят: "Нет такого понятия, как прокси-сервер https?
Исходный код
https сервер
var http = require('http');
var https = require('https');
var fs = require('fs');
var net = require('net');
var url = require('url');
console.log("qqqqq2");
function request(cReq, cRes) {
console.log("request=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("request=====end");
var u = url.parse(cReq.url);
var options = {
hostname : u.hostname,
port : u.port || 80,
path : u.path,
method : cReq.method,
headers : cReq.headers
};
var pReq = http.request(options, function(pRes) {
cRes.writeHead(pRes.statusCode, pRes.headers);
pRes.pipe(cRes);
}).on('error', function(e) {
cRes.end();
});
cReq.pipe(pReq);
// console.log(cReq.headers);
// console.log(cReq.method);
// console.log(cReq.url);
// console.log("^_^^_^^_^^_^^_^^_^");
// cRes.writeHead('200');
// cRes.end('hello world2222\n');
}
function connect(cReq, cSock) {
console.log("connect=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("connect=====end");
var u = url.parse('http://' + cReq.url);
var pSock = net.connect(u.port, u.hostname, function() {
cSock.write('HTTP/1.1 200 Connection Established\r\n\r\n');
pSock.pipe(cSock);
}).on('error', function(e) {
cSock.end();
});
cSock.pipe(pSock);
}
var options = {
key: fs.readFileSync('./privkey1.pem'),
cert: fs.readFileSync('./fullchain1.pem')
};
https.createServer(options)
.on('request', request)
.on('connect', connect)
.listen(9999, '0.0.0.0');
http сервер
var http = require('http');
var net = require('net');
var url = require('url');
console.log('qqqqq2');
function request(cReq, cRes) {
console.log("request=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("request=====end");
var u = url.parse(cReq.url);
var options = {
hostname : u.hostname,
port : u.port || 80,
path : u.path,
method : cReq.method,
headers : cReq.headers
};
var pReq = http.request(options, function(pRes) {
cRes.writeHead(pRes.statusCode, pRes.headers);
pRes.pipe(cRes);
}).on('error', function(e) {
cRes.end();
});
cReq.pipe(pReq);
}
function connect(cReq, cSock) {
console.log("connect=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("connect=====end");
var u = url.parse('http://' + cReq.url);
var pSock = net.connect(u.port, u.hostname, function() {
cSock.write('HTTP/1.1 200 Connection Established\r\n\r\n');
pSock.pipe(cSock);
}).on('error', function(e) {
cSock.end();
});
cSock.pipe(pSock);
}
http.createServer()
.on('request', request)
.on('connect', connect)
.listen(9999, '0.0.0.0');
Тестовый сервер
Вы можете легко построить прокси-сервер http и протестировать его. Но может быть сложно создать прокси-сервер https, потому что вам нужно развернуть сертификаты. Таким образом, предоставляется прокси-сервер https на основе приведенного выше кода.
Тестовый сервер удален, так как я нашел ответ.
2 ответа
Я нашел ответ в Security StackExchange. Можно ли подключиться к прокси с ssl (или иным зашифрованным) соединением?
Из https://wiki.squid-cache.org/Features/HTTPS:
Зашифрованное соединение браузера-Squid
Несмотря на то, что усилия по разработке HTTPS были сосредоточены на сквозном взаимодействии, было бы также неплохо иметь возможность шифровать соединение между браузером и прокси-сервером (без создания туннеля CONNECT, который блокирует доступ Squid к контенту и его кеширование). Это позволило бы, например, безопасно использовать удаленные прокси, расположенные в потенциально враждебной сети.
Squid может принимать обычный прокси-трафик с помощью https_port таким же образом, как Squid делает это с помощью директивы http_port. К сожалению, популярные современные браузеры не позволяют настраивать прокси-соединения с шифрованием TLS/SSL. Сейчас есть открытые отчеты об ошибках в большинстве этих браузеров, ожидающих поддержки. Если у вас есть какой-либо интерес, пожалуйста, помогите браузерным командам добиться этого.
...
Хром
Браузер Chrome может подключаться к прокси через SSL-соединения, если он настроен на использование одного из них в файле PAC или в командной строке. Настройка графического интерфейса кажется невозможной (пока).
Fire Fox
Браузер Firefox 33.0 может подключаться к прокси через соединения TLS, если настроен для использования одного из них в файле PAC. Конфигурация графического интерфейса кажется невозможной (пока), хотя есть хак конфигурации для встраивания логики PAC.
Дополнительную информацию, связанную с Chrome, можно найти по http://dev.chromium.org/developers/design-documents/secure-web-proxy.
Чтобы ответить на вопросы:
- Можно ли подключиться к прокси-серверу https обычным способом (без расширения)? Если возможно, то как?
Традиционный способ (например, Manual proxy configuration
поле в Firefox), чтобы установить прокси-сервер http только для прокси-сервера HTTP. Можно установить только https прокси через pac
файлы (например, Automatic proxy configuration URL
поле в Firefox).
- Почему я могу подключиться к прокси-серверу https через SwitchOmega?
Расширение SwitchOmega фактически генерирует pac
файл для использования Chrome, хотя мне пока неизвестно, как он взаимодействует с Chrome.
Нажав на Export PAC
Кнопка в SwitchOmega, я получаю файл, содержащий:
var FindProxyForURL = function(init, profiles) {
return function(url, host) {
"use strict";
var result = init, scheme = url.substr(0, url.indexOf(":"));
do {
result = profiles[result];
if (typeof result === "function") result = result(url, host, scheme);
} while (typeof result !== "string" || result.charCodeAt(0) === 43);
return result;
};
}("+test", {
"+test": function(url, host, scheme) {
"use strict";
if (/^127\.0\.0\.1$/.test(host) || /^::1$/.test(host) || /^localhost$/.test(host)) return "DIRECT";
return "HTTPS myHttpsProxyServer.com:9999"; // This line matters
}
});
HTTP host:port
The specified proxy should be used
HTTPS host:port
The specified HTTPS proxy should be used
- Я думаю, что я строю прокси-сервер https. Но почему другие говорят: "Нет такого понятия, как прокси-сервер https?
Да, я строю прокси-сервер https / прокси-сервер http через соединение tls. Те, кто говорит "Нет такого понятия, как прокси-сервер https", ошибаются.
Насколько я знаю, официальной спецификации прокси-сервера HTTPS нет.
В своем ответе Рик сказал о взломе Squid, позволяющем им кэшировать контент, который не может быть кэширован ранее из-за https, путем завершения запроса TLS браузера, а затем инициирования другого запроса TLS на предполагаемый сервер. По сути, Squid действует как MITM между браузером и сервером. Хотя соединение по-прежнему защищено TLS, Squid может видеть трафик. Если веб-сервер реализует HSTS, браузер не позволит нам подключиться.
Чего я ожидал от прокси-сервера HTTPS, так это того, что браузер инициирует оба соединения TLS. Сначала он инициирует подключение TLS к прокси-серверу, затем запрашивает ПОДКЛЮЧЕНИЕ к предполагаемому веб-серверу и инициирует другой TLS.