diff --git a/doc/html/howtoe.html b/doc/html/howtoe.html index a3f24de..ad60364 100644 --- a/doc/html/howtoe.html +++ b/doc/html/howtoe.html @@ -33,6 +33,7 @@
  • How to resolve names through a parent proxy
  • How to set up an FTP proxy
  • How to set up an SNI proxy (tlspr)
  • +
  • How to set up a DNS proxy (dnspr)
  • How to set up TLS/SSL (https proxy, mTLS)
  • How to create CA and certificates for SSL
  • How to use PCRE filtering (regular expressions)
  • @@ -599,8 +600,8 @@ proxy -p8080 -i192.168.2.1

    Implicit vs explicit TLS:

    -Implicit TLS means TLS from the first byte of the connection: https (443), imaps (993), submissions (465). -Explicit TLS means the connection starts in plaintext and is upgraded with a STARTTLS/STLS command: imap (143), submission (587), pop3 (110). +Implicit TLS means TLS from the first byte of the connection: https (443), imaps (993), SMTP submission secure (submissions) (465). +Explicit TLS means the connection starts in plaintext and is upgraded with a STARTTLS/STLS command: imap (143), SMTP submission (587), pop3 (110). tlspr supports both: for implicit TLS the destination host is taken from SNI and the port from -P; for explicit TLS the -X option makes tlspr speak the plaintext protocol phase with the client (greeting, STARTTLS command) before upgrading both sides to TLS. Example: @@ -637,6 +638,10 @@ with, for example, iptables: iptables -t nat -A PREROUTING -p tcp -m multiport --dports 443,993,465 -j REDIRECT --to-port 1443

    +Alternatively, if clients use dnspr as their DNS resolver, traffic can be redirected via DNS — +see How to set up a DNS proxy (dnspr). +

    +

    SNI Break (DPI Bypass):
    tlspr can be used as a parent with the "tls" type to implement SNI splitting for DPI bypass (similar to NoDPI/GoodByeDPI). The client sends the first part of the TLS ClientHello, tlspr splits it at the SNI extension and sends it in two TCP packets, @@ -681,6 +686,47 @@ parent 1000 tls 0.0.0.0 0 deny * * blocked.example.com allow * proxy + +

    +
  • How to set up a DNS proxy (dnspr)
  • +

    +dnspr is a DNS forwarding service. It answers queries from the 3proxy name cache (including static nsrecord +entries), forwards other queries to the resolvers configured with nserver, and caches the results if +nscache/nscache6 are configured. Options: +

    +-s  - simple DNS forwarding: do not use 3proxy resolver / name cache
    +-F<ip> - fake: answer all A (or AAAA) queries with the given IP address.
    +  May be given twice - once with an IPv4 and once with an IPv6 address.
    +
    +

    +dnspr can be used to redirect traffic by hostname, e.g. to point mail clients to a +tlspr installation, by adding nsrecord entries for the service hostnames +(nscache/nscache6 keep the answers for all other names intact): +

    +nscache 65536
    +nscache6 65536
    +dnspr -p53
    +
    +# google
    +nsrecord smtp.gmail.com 10.0.0.1
    +nsrecord imap.gmail.com 10.0.0.1
    +nsrecord pop.gmail.com 10.0.0.1
    +# mail.ru
    +nsrecord smtp.mail.ru 10.0.0.1
    +nsrecord imap.mail.ru 10.0.0.1
    +nsrecord pop.mail.ru 10.0.0.1
    +# yandex.ru
    +nsrecord smtp.yandex.ru 10.0.0.1
    +nsrecord imap.yandex.ru 10.0.0.1
    +nsrecord pop.yandex.ru 10.0.0.1
    +
    +

    +where 10.0.0.1 is the address tlspr listens on. If every hostname must be redirected, a single fake +address can be used instead of individual nsrecords: +

    +nscache 65536
    +nscache6 65536
    +dnspr -p53 -F10.0.0.1
     

  • How to set up TLS/SSL (https proxy, mTLS) diff --git a/doc/html/howtor.html b/doc/html/howtor.html index c2df08d..a9d2c32 100644 --- a/doc/html/howtor.html +++ b/doc/html/howtor.html @@ -33,6 +33,7 @@
  • Как разрешать имена на родительском прокси?
  • Как настроить FTP прокси?
  • Как настроить SNI proxy (tlspr)
  • +
  • Как настроить DNS proxy (dnspr)
  • Как настроить TLS/SSL (https прокси, mTLS)
  • Как создать CA и сертификаты для SSL
  • Как использовать PCRE-фильтрацию (регулярные выражения)
  • @@ -590,6 +591,7 @@ Еще одна задача которую может решать модуль - требование наличия TLS или mTLS (mutual TLS). Если tlspr используется как отдельный сервис без использования плагина Transparent, то необходимо задать порт назначения через опцию -P (по умолчанию 443), т.к. TLS хендшейк не содержит информации о порте назначения. + Примечание: tlspr не поддерживает аутентификацию пользователей (в TLS-хендшейке нет учетных данных); используйте ACL по IP или родительский прокси с аутентификацией, если требуется контроль доступа.

    Опции:

    @@ -600,8 +602,54 @@
       2 - требовать TLS, проверять наличие client и server HELLO
       3 - требовать TLS, проверять наличие серверного сертификата (не совместим с TLS 1.3+)
       4 - требовать взаимный (mutual) TLS, проверять что сервер запрашивает сертификат и клиент его отправляет (не совместим с TLS 1.3+)
    +-Ximap | -Xpop3 | -Xsmtp - режим explicit TLS (STARTTLS): tlspr говорит с клиентом
    +  на plaintext-протоколе (приветствие, команда STARTTLS), затем поднимает TLS с обеих сторон
     

    +Implicit и explicit TLS: +

    +Implicit TLS означает TLS с первого байта соединения: https (443), imaps (993), SMTP submission secure (submissions) (465). +Explicit TLS означает, что соединение начинается в plaintext и поднимается до TLS командой STARTTLS/STLS: imap (143), SMTP submission (587), pop3 (110). +tlspr поддерживает оба варианта: для implicit TLS хост назначения берется из SNI, а порт из -P; для explicit TLS +опция -X заставляет tlspr говорить с клиентом на plaintext-фазе протокола (приветствие, команда STARTTLS) перед +поднятием TLS с обеих сторон. Пример: +

    +# https (implicit)
    +tlspr -p443 -P443 -c1
    +# imaps (implicit)
    +tlspr -p993 -P993 -c1
    +# submissions (implicit)
    +tlspr -p465 -P465 -c1
    +# imap STARTTLS (explicit)
    +tlspr -p143 -P143 -Ximap
    +# submission STARTTLS (explicit)
    +tlspr -p587 -P587 -Xsmtp
    +# pop3 STLS (explicit)
    +tlspr -p110 -P110 -Xpop3
    +
    +

    +Примечание: для explicit TLS вместо tlspr -X можно использовать протокольные сервисы smtpp, imapp и pop3p; они +также поддерживают STARTTLS. +

    +Рекомендуемая конфигурация - перенаправление трафика: наиболее универсальная конфигурация - перенаправлять +TLS-трафик (порты 443, 993, 465, 143, 587, 110) на tlspr правилами внешнего маршрутизатора или локальными +правилами (плагин Transparent). Исходные адрес и порт назначения сохраняются, -P и отдельные сервисы для каждого +порта не требуются, implicit и explicit TLS работают в рамках одной установки. +

    +auth iponly
    +allow *
    +tlspr -p1443 -c1
    +
    +

    +например, с iptables: +

    +iptables -t nat -A PREROUTING -p tcp -m multiport --dports 443,993,465 -j REDIRECT --to-port 1443
    +
    +

    +Также, если клиенты используют dnspr в качестве DNS-резолвера, трафик можно перенаправлять через DNS — +см. Как настроить DNS proxy (dnspr). +

    +

    SNI Break (обход DPI):
    tlspr может использоваться как родительский прокси типа "tls" для реализации SNI-фрагментации (аналог NoDPI/GoodByeDPI). Клиент отправляет первую часть TLS ClientHello, tlspr разбивает его на расширении SNI и отправляет двумя TCP-пакетами, @@ -649,6 +697,48 @@ proxy

    +
  • Как настроить DNS proxy (dnspr)
  • +

    +dnspr - сервис пересылки DNS-запросов. Он отвечает на запросы из кэша имен 3proxy (включая статические записи +nsrecord), пересылает остальные запросы на резолверы, заданные командой nserver, и кэширует результаты, если +настроены nscache/nscache6. Опции: +

    +-s  - простая пересылка DNS: не использовать резолвер / кэш имен 3proxy
    +-F<ip> - fake: отвечать на все A (или AAAA) запросы заданным IP-адресом.
    +  Может быть указана дважды - один раз с IPv4 и один раз с IPv6 адресом.
    +
    +

    +dnspr можно использовать для перенаправления трафика по имени хоста, например, чтобы направить почтовых +клиентов на установку tlspr, добавив записи nsrecord для имен почтовых сервисов +(nscache/nscache6 сохраняют ответы для всех остальных имен): +

    +nscache 65536
    +nscache6 65536
    +dnspr -p53
    +
    +# google
    +nsrecord smtp.gmail.com 10.0.0.1
    +nsrecord imap.gmail.com 10.0.0.1
    +nsrecord pop.gmail.com 10.0.0.1
    +# mail.ru
    +nsrecord smtp.mail.ru 10.0.0.1
    +nsrecord imap.mail.ru 10.0.0.1
    +nsrecord pop.mail.ru 10.0.0.1
    +# yandex.ru
    +nsrecord smtp.yandex.ru 10.0.0.1
    +nsrecord imap.yandex.ru 10.0.0.1
    +nsrecord pop.yandex.ru 10.0.0.1
    +
    +

    +где 10.0.0.1 - адрес, на котором слушает tlspr. Если перенаправлять нужно все имена, вместо отдельных +записей nsrecord можно использовать один fake-адрес: +

    +nscache 65536
    +nscache6 65536
    +dnspr -p53 -F10.0.0.1
    +
    +

    +
  • Как настроить TLS/SSL (https прокси, mTLS)

    Начиная с версии 0.9.7 поддержка TLS/SSL встроена в 3proxy при компиляции с OpenSSL diff --git a/src/conf.c b/src/conf.c index f418be6..8f2e10f 100644 --- a/src/conf.c +++ b/src/conf.c @@ -264,7 +264,7 @@ static int h_proxy(int argc, unsigned char ** argv){ childdef.port = 53; childdef.isudp = 1; childdef.service = S_DNSPR; - childdef.helpmessage = " -s - simple DNS forwarding - do not use 3proxy resolver / name cache\n"; + childdef.helpmessage = " -s - simple DNS forwarding - do not use 3proxy resolver / name cache\n -Fip - fake: answer all A queries with this IP\n"; #ifndef NOIPV6 if(!resolvfunc || (resolvfunc == myresolver && !dns_table.poolsize) || resolvfunc == fakeresolver){ fprintf(stderr, "[line %d] Warning: no nserver/nscache configured, dnspr will not work as expected\n", linenum); diff --git a/src/dnspr.c b/src/dnspr.c index 532a13a..06f596d 100644 --- a/src/dnspr.c +++ b/src/dnspr.c @@ -25,6 +25,7 @@ void * dnsprchild(struct clientparam* param) { SASIZETYPE size; int res, i; int len; + int semlocked = 1; unsigned type=0; uint32_t ttl; unsigned char addr[16]; @@ -38,10 +39,13 @@ void * dnsprchild(struct clientparam* param) { RETURN (21); } buf = bbuf+2; - size = sizeof(param->sincr); - i = param->srv->so._recvfrom(param->sostate, param->srv->srvsock, (char *)buf, BUFSIZE, 0, (struct sockaddr *)¶m->sincr, &size); size = sizeof(param->sinsl); getsockname(param->srv->srvsock, (struct sockaddr *)¶m->sincl, &size); + i = param->srv->udplen; + if(i > BUFSIZE) i = BUFSIZE; + memcpy(buf, param->srv->udpbuf, i); + _3proxy_sem_unlock(udpinit); + semlocked = 0; #ifdef _WIN32 if((param->clisock=param->srv->so._socket(param->sostate, AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { RETURN(818); @@ -82,7 +86,19 @@ void * dnsprchild(struct clientparam* param) { *s2 = (len - (int)(s2 - buf)) - 1; type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2]; - if((type==0x01 || type==0x1c) && !param->srv->s_option){ + if(type==0x01 && param->srv->fakeip){ + ip = 1; + ttl = 3600; + *(uint32_t *)addr = param->srv->fakeip; + } +#ifndef NOIPV6 + else if(type==0x1c && *(uint32_t *)param->srv->fakeip6){ + ip = 1; + ttl = 3600; + memcpy(addr, param->srv->fakeip6, 16); + } +#endif + else if((type==0x01 || type==0x1c) && !param->srv->s_option){ ip = udpresolve((type==0x1c)?AF_INET6:AF_INET, (unsigned char *)host, addr, &ttl, param, 0); } @@ -191,6 +207,7 @@ void * dnsprchild(struct clientparam* param) { CLEANRET: + if(semlocked) _3proxy_sem_unlock(udpinit); if(param->res!=813){ sprintf((char *)buf, "%04x/%s/", (unsigned)type, diff --git a/src/proxymain.c b/src/proxymain.c index 94e4e61..ab1fad4 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -537,6 +537,18 @@ int MODULEMAINFUNC (int argc, char** argv){ else if(!strncasecmp(argv[i]+2, "smtp", 4)) srv.srvstarttls = S_SMTPP; else error = 1; break; + case 'F': + { + PROXYSOCKADDRTYPE fsa; + memset(&fsa, 0, sizeof(fsa)); + if(!getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&fsa)) error = 1; + else if(*SAFAMILY(&fsa) == AF_INET) srv.fakeip = *(uint32_t *)SAADDR(&fsa); +#ifndef NOIPV6 + else if(*SAFAMILY(&fsa) == AF_INET6) memcpy(srv.fakeip6, SAADDR(&fsa), 16); +#endif + else error = 1; + } + break; case 'T': srv.transparent = 1; break; diff --git a/src/structures.h b/src/structures.h index 50d56fa..ba92283 100644 --- a/src/structures.h +++ b/src/structures.h @@ -539,6 +539,8 @@ struct srvparam { int haproxy; int nostarttls; PROXYSERVICE srvstarttls; + uint32_t fakeip; + unsigned char fakeip6[16]; #ifdef WITHSPLICE int usesplice; #endif