Как я маршрутизирую TCP-соединения через TOR?
Я читал о torchat, который по сути является анонимной программой чата.
Это звучало круто, поэтому я хотел поэкспериментировать с созданием собственного. Сначала я написал тест, чтобы захватить веб-страницу с помощью Http. Sicne .NET не поддерживает SOCKS4A/SOCKS5, я использовал privoxy, и мое приложение работало. Затем я переключаюсь на эхо-тест TCP, и privoxy не поддерживает TCP, поэтому я выполнил поиск и установил 6+ прокси-приложений (freecap, socat, freeproxy, делегат - это те, которые я помню из головы, я также играл с putty bc i Я знаю, что он поддерживает туннели и SOCK5), но я не смог успешно заставить работать любой из них, не говоря уже о запуске с моим http-тестом, который privoxy делал легко и безболезненно.
Что я могу использовать для получения TCP-соединений через TOR? Я провел более 2 часов без успеха. Я не знаю, ищу ли я ретранслятор, туннель, экспедитора, прокси или цепочку прокси, которые все нашли в моем поиске. Я использую конфиг ниже для.NET. Мне нужно, чтобы TCP работал, но я сначала тестирую с http, так как знаю, что он работал с использованием privoxy. Какие приложения и настройки я использую для прохождения TCP через tor?
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<defaultProxy enabled="true">
<proxy bypassonlocal="True" proxyaddress="http://127.0.0.1:8118"/>
</defaultProxy>
<settings>
<httpWebRequest useUnsafeHeaderParsing="true"/>
</settings>
</system.net>
</configuration>
-edit- Благодаря Бернду у меня есть решение. Вот код, который я закончил писать. Это не удивительно, но справедливо.
static NetworkStream ConnectSocksProxy(string proxyDomain, short proxyPort, string host, short hostPort, TcpClient tc)
{
tc.Connect(proxyDomain, proxyPort);
if (System.Text.RegularExpressions.Regex.IsMatch(host, @"[\:/\\]"))
throw new Exception("Invalid Host name. Use FQDN such as www.google.com. Do not have http, a port or / in it");
NetworkStream ns = tc.GetStream();
var HostNameBuf = new ASCIIEncoding().GetBytes(host);
var HostPortBuf = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(hostPort));
if (true) //5
{
var bufout = new byte[128];
var buflen = 0;
ns.Write(new byte[] { 5, 1, 0 }, 0, 3);
buflen = ns.Read(bufout, 0, bufout.Length);
if (buflen != 2 || bufout[0] != 5 || bufout[1] != 0)
throw new Exception();
var buf = new byte[] { 5, 1, 0, 3, (byte)HostNameBuf.Length };
var mem = new MemoryStream();
mem.Write(buf, 0, buf.Length);
mem.Write(HostNameBuf, 0, HostNameBuf.Length);
mem.Write(new byte[] { HostPortBuf[0], HostPortBuf[1] }, 0, 2);
var memarr = mem.ToArray();
ns.Write(memarr, 0, memarr.Length);
buflen = ns.Read(bufout, 0, bufout.Length);
if (bufout[0] != 5 || bufout[1] != 0)
throw new Exception();
}
else //4a
{
var bufout = new byte[128];
var buflen = 0;
var mem = new MemoryStream();
mem.WriteByte(4);
mem.WriteByte(1);
mem.Write(HostPortBuf, 0, 2);
mem.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(1)), 0, 4);
mem.WriteByte(0);
mem.Write(HostNameBuf, 0, HostNameBuf.Length);
mem.WriteByte(0);
var memarr = mem.ToArray();
ns.Write(memarr, 0, memarr.Length);
buflen = ns.Read(bufout, 0, bufout.Length);
if (buflen != 8 || bufout[0] != 0 || bufout[1] != 90)
throw new Exception();
}
return ns;
}
использование
using (TcpClient client = new TcpClient())
using (var ns = ConnectSocksProxy("127.0.0.1", 9050, "website.com", 80, client)) {...}
1 ответ
Socks4a действительно прост. Вы можете сделать socks4a вручную в 5 строк кода. Взгляните на носки RFC (или его гораздо более простое объяснение в википедии).
По сути, вы просто делаете обычное TCP-соединение с прокси-сервером socks (это означает, что если вы просто подключаетесь к порту 9050 127.0.0.1, соединение будет принято, тогда вы отправляете очень простой запрос по этому соединению (пример приведен в RFC), а затем через некоторое время tor ответит ровно 8 байтами (второй байт является статусом и должен быть равен 90, что означает успех).
После получения успешного ответа от Tor по этому соединению вы продолжаете использовать то же соединение, в этот момент вы уже соединены с другой стороной через этот сокет, с этого момента оно ведет себя как любое другое соединение TCP для всех намерений и целей и Вы можете начать отправку / получение, как если бы вы подключились напрямую.
Редактировать: вам не нужно изучать весь RFC, есть отличное очень краткое и полное описание Socks 4a в Википедии (socks 5 было бы излишним для ваших нужд, а socks 4 не могут разрешать имена хостов, поэтому 4a идеально подходит для Tor):