Я провел довольно много поисков и практических испытаний, прежде чем задать этот вопрос.
Я нашел (не на английском) учебник о том, как написать http-прокси с Node.js.
Пока что я знаю и пробовал:
SSL proxy в настройках прокси-сервера Firefox и поле Secure в настройках прокси-сервера IE (Windows) предназначены для настройки HTTP-туннеля. Если установлен SSL proxy или Secure proxy, когда браузер хочет подключиться к https-сайту, он отправляет запрос CONNECT вместо обычного запроса.Запрос CONNECT представляет собой обычный текст, поэтому брандмауэры могут видеть, к какому хосту я хочу подключиться, и прерывать соединение. Поэтому я с самого начала думал, могу ли я использовать https для связи с прокси-сервером. Я прочитал все связанные сообщения, но не смог найти ответ, прямо говорящий об этом. И в некоторых ответах также говорится «Нет такой вещи, как прокси-сервер https».
Но в учебнике говорится, что это можно сделать (HTTPS между клиентом и прокси-сервером и больше ничего не меняется). Поэтому я попробую. Я изменил сервер на https с сертификатом моего сайта. Но в конечном итоге это работает только с Переключатель проксиOmega в 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-сервер
var http = require('http');
var https = require('https');
var fs = require('fs');
var net = require('net');
var url = require('url');
console.info("qqqqq2");
function request(cReq, cRes) {
console.info("request=====start");
console.info(cReq.headers);
console.info(cReq.url);
console.info(cReq.method);
console.info("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.info(cReq.headers);
// console.info(cReq.method);
// console.info(cReq.url);
// console.info("^_^^_^^_^^_^^_^^_^");
// cRes.writeHead('200');
// cRes.end('hello world2222\n');
}
function connect(cReq, cSock) {
console.info("connect=====start");
console.info(cReq.headers);
console.info(cReq.url);
console.info(cReq.method);
console.info("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.info('qqqqq2');
function request(cReq, cRes) {
console.info("request=====start");
console.info(cReq.headers);
console.info(cReq.url);
console.info(cReq.method);
console.info("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.info("connect=====start");
console.info(cReq.headers);
console.info(cReq.url);
console.info(cReq.method);
console.info("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, основанный на приведенном выше коде.
Тестовый сервер удален, так как я нашел ответ.
А Manual proxy configuration и Automatic proxy configuration URL в браузерах могут быть 2-х разных настроек. Раньше я думал, что одно является подмножеством другого.
для Firefox вы пробовали network.proxy.proxy_over_tls? Также вы видели эта страница? «Squid может принимать обычный прокси-трафик с использованием https_port точно так же, как Squid делает это с помощью директивы http_port. К сожалению, популярные современные браузеры не позволяют настраивать зашифрованные прокси-соединения TLS/SSL. ожидание появления поддержки. Если у вас есть интерес, пожалуйста, помогите командам браузеров добиться этого».
@PeterT Ах, спасибо, Питер. Я также узнал об этой ссылке из сообщения об обмене стеками безопасности, и я прочитал это. Думаю, я нашел ответ. Как описано на этой странице, прокси-сервер https поддерживается, но только через файл pac, а не через графический интерфейс (ни Chrome, ни Firefox). Я сделаю ответ на свой вопрос позже.





Я нашел ответ в Security StackExchange. Можно ли подключиться к прокси с ssl (или другим зашифрованным) соединением?
Из https://wiki.squid-cache.org/Features/HTTPS#Encrypted_browser-Squid_connection :
Encrypted browser-Squid connection
While HTTPS design efforts were focused on end-to-end communication, it would also be nice to be able to encrypt the browser-to-proxy connection (without creating a CONNECT tunnel that blocks Squid from accessing and caching content). This would allow, for example, a secure use of remote proxies located across a possibly hostile network.
Squid can accept regular proxy traffic using https_port in the same way Squid does it using an http_port directive. Unfortunately, popular modern browsers do not permit configuration of TLS/SSL encrypted proxy connections. There are open bug reports against most of those browsers now, waiting for support to appear. If you have any interest, please assist browser teams with getting that to happen.
...
Chrome
The Chrome browser is able to connect to proxies over SSL connections if configured to use one in a PAC file or command line switch. GUI configuration appears not to be possible (yet).
Firefox
The Firefox 33.0 browser is able to connect to proxies over TLS connections if configured to use one in a PAC file. GUI configuration appears not to be possible (yet), though there is a config hack for embedding PAC logic.
Дополнительную информацию о Chrome можно найти в статье http://dev.chromium.org/developers/design-documents/secure-web-proxy.
Чтобы ответить на вопросы:
- Can I connect to the https proxy server through the ordinary way(without an extension)? If possible, how?
Традиционный способ (например, поле Manual proxy configuration в Firefox) для установки прокси-сервера http предназначен только для прокси-сервера HTTP. Установить прокси https можно только через pac файлы (например, поле Automatic proxy configuration URL в Firefox).
- Why can I connect to the https proxy server through 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
- I think I build a https proxy server. But why others are saying that "There's no such thing as a https proxy server?
Да, я создаю прокси-сервер https/прокси-сервер http через соединение tls. Те, кто говорит, что «такой вещи, как https-прокси-сервер, не существует», ошибаются.
Это отличный пост. У меня есть еще один вопрос: может ли прокси-сервер HTTPS, который вы создали, проксировать HTTP-запросы от клиента? Если возможно, означает ли это, что связь между клиентом и прокси-сервером зашифрована, а связь между прокси-сервером и HTTP-сервером — нет?
@ZhaoxingLu Да, слой tls/ssl удаляется после прокси.
@ZhaoxingLu 1. Может ли прокси-сервер HTTPS, который вы создали, проксировать HTTP-запросы от клиента? Да, но говорят, что браузер предпочитает использовать прокси-сервер HTTP, когда доступны как прокси-сервер http, так и туннель https. 2. При использовании прокси-сервера https связь между клиентом и прокси-сервером шифруется. Я предполагаю, что с этим вы можете, например, скрыть свой хост назначения от человека посередине или использовать некоторую HTTP-аутентификацию, например. Байск авт.
3. Я считаю (не проверено), что связь между прокси-сервером и целевым http-сервером зависит только от того, посещает ли клиент через http или https.
Я просто заметил, что это может быть файл
pac, который делает трюки. Интерфейс ПереключательОмега, похоже, просто действует как графический интерфейс пользователя для настройки файлаpac. Я собираюсь прочитать что-нибудь о файлеpac.