Звонки через Telegram через прокси-сервер Dante socks5 не работают
Я настроил Dante 1.4 на Ubuntu 16.04 как прокси socks5 для Telegram.
Чаты работают, а голосовые звонки - нет, при ошибке "Соединение".
Есть ли что-то особенное, что мне нужно настроить для передачи голосового трафика Telegram через прокси?
Я использую один непривилегированный (>1024) порт TCP/UDP + логин + пароль для подключения.
Спасибо!
UPD: Это кусок журнала, когда я пытаюсь позвонить кому-нибудь:
Apr 15 23:05:38 (1523736338.510915) danted[22977]: info: pass(1): udp/udpassociate [: username%USER@0.0.0.0.0 192.168.1.30.36562
Apr 15 23:08:33 (1523736513.020190) danted[22989]: info: pass(1): udp/udpassociate [: username%USER@0.0.0.0.0 192.168.1.30.49065
Я могу ответить на звонок на устройстве назначения, но соединение зацикливается и через 30 секунд появляется ошибка.
4 ответа
Прокси-соединение с использованием socks UDP немного сложнее, чем может показаться, поэтому давайте начнем с самого начала.
Telegram звонки используют UDP с носками. Socks5 RFC1928 определяет следующую последовательность для ретрансляции UDP:
- Клиент создает TCP-соединение socks5.
- Клиент отправляет
UDP ASSOCIATE
запрос, содержащий адрес источника и порт клиента, который будет использоваться для отправки дейтаграмм UDP на сервер socks5. Они могут быть нулями (в Telegram они есть) (раздел 4). - Сервер Socks5 связывает случайный порт UDP для ретрансляции дейтаграмм для этого соединения TCP socks5 и отправляет
UDP ASSOCIATE
ответ, содержащий адрес и порт, куда клиент должен отправить дейтаграммы для ретрансляции (раздел 6). - Чтобы отправить дейтаграмму, Клиент должен добавить к полезной нагрузке заголовок, содержащий адрес и порт назначения, куда сервер должен ретранслировать эту дейтаграмму (раздел 7).
- Сервер будет удерживать порт UDP связанным до тех пор, пока не прекратится соединение TCP socks5.
Как видите, открытия одного TCP-порта недостаточно. Для правильной работы UDP, автоматически связанный порт UDP должен быть доступен клиенту. NAT и межсетевые экраны могут еще более усложнить ситуацию.
Конфигурация ретрансляции UDP с Dante
Вызовы Telegram являются одноранговыми, поэтому
udpassociate
Команда должна быть разрешена0/0
:socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 # udp.portrange: 40000-45000 command: udpassociate log: error connect disconnect }
udpreply
(это для фактической ретрансляции, 4-й шаг выше) также должно быть разрешено всем:socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 command: udpreply log: error connect disconnect }
Если ваш сервер socks5 находится за брандмауэром, откройте диапазон портов UDP (скажем,
40000-45000
) и добавитьudp.portrange: 40000-45000
линия кudpassociate
блок (см. закомментированный пример в первом пункте). Тогда Данте будет связывать порты UDP только в этом диапазоне.Если ваш сервер socks5 находится за NAT, то возвращенный адрес назначения в ответ на
UDP ASSOCIATE
запрос будет локальный IP, а не внешний. Этот локальный IP вряд ли будет доступен клиенту, поэтому отправленные дейтаграммы будут отброшены.К сожалению, Dante использует адрес назначения TCP-соединения как адрес, на который клиент должен отправлять UDP-дейтаграммы (см. Комментарий в исходном коде). NAT меняет этот адрес с внешнего на локальный, поэтому предположение Dante о том, что клиент может получить доступ к прокси-серверу с использованием этого адреса назначения, нарушено.
Возможное решение, которое не включает исправление Dante, заключается в использовании iptables для изменения адреса назначения с локального на внешний (при условии, что он известен и не изменяется):
# 203.0.113.12 – the external IP # 1080/tcp - Dante TCP port # 40000:45000 – Dante UDP portrange iptables -t nat -A PREROUTING -p tcp --dport 1080 -j DNAT --to-destination 203.0.113.12 iptables -t nat -A PREROUTING -p udp --dport 40000:45000 -j DNAT --to-destination 203.0.113.12 # If external address is not added to any network device on that # machine, then add it to the loopback interface, so the kernel # would know where to route the DNATed packets: ip addr add 203.0.113.12/32 dev lo
У меня такая же проблема. Нашел решение. Вы должны добавить команды udpassociate bindreply udpreply в файл conf. вот мой файл conf, который работает с голосовыми вызовами.
logoutput: syslog /var/log/danted.log
internal: ip port = 1080
external: ip
socksmethod: username
user.privileged: root
user.unprivileged: nobody
client pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
log: error connect
}
socks pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
command: bind connect udpassociate bindreply udpreply
log: error connect
}
Разрешить голосовой трафик клиентов
socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 команда: udpreply log: ошибка соединения отключить socksmethod: username}
iptables -A INPUT -p udp -m multiport --dports 1024: 65535 -j ПРИНЯТЬ
Вы должны включить звонки через прокси в настройках вашей телеграммы.