LINUX.ORG.RU

Ошибка отображения сетевых подключений/открытых сокетов через ss -a linux

 , , , ,


0

1

Здравствуйте! Столкнулся с проблемой отображения сетевых подключений/открытых сокетов через SSH.

Вступление. На свой сервер поставил пакет shadowsocks-libev, настроил файл config.json. На Android поставил приложение Shadowsocks, на IOS - Potatso. На двоих устройствах успешно настроил подключение, всё работает, выходят в интернет через IP адрес моего сервера.

Основная часть. Через команду ss -a | grep 62.217.XXX.XX:777 вывел список подключений к IP моего сервера через PROXY. Порт указан из файла config.json, о котором говорил выше. Соответственно, при подключении двух устройств (Android и IOS), отражаются два IP адреса.

Когда отключаю устройство на Android от PROXY, моё TCP соединение пропадает через 1 мин примерно, а при отключении устройства на IOS ничего не происходит, точнее IP адрес этого устройства висит всё время в Peer Address (state ESTAB), хотя должен пропасть. В интернет оно выходит уже с другим IP, проверял, а соединение всё висит.

Вообще не могу понять, в чем причина. Для моих задач, для вывода уникальных IP устройств, подключенных через PROXY, без портов, использую команду: ss -a | grep 62.217.XXX.XX:777 | grep -v 0.0.0.0 | sed 's|.*:777||' | sed -r 's/:.+//' | sort -u | sed s/' '//g. (т.е. мы сначала отбираем все строки с IP адресом сервера и портом, который установлен для соединения через прокси, дальше убирает строки у которых в Peer Address 0.0.0.0, они не нужны, затем оставляем от порта нашего сервера всю правую часть с колонкой Peer Address, ну и отсекаем у IP пользователей порты. А т.к. IP дублируются, делаем sort -u и удаляем пробелы у строки).

Но при отключенном VPN на IOS, IP адрес этого устройства не исчезает из SS -a. Помогите разобраться в проблеме пожалуйста.

Ошибок отображения там нет. Эта команда показывает список открытых сокетов на стороне компа где ты её запускаешь. Есть ли там на самом деле соединения или нет - комп общем случае знать не может. По-нормальному принято при закрывании соединения оповещать об этом другую сторону соответствующим пакетом, и андроид видимо так делает а ios нет. Комп не узнает, что соединение закрыто, пока не попытается в него что-то отправить. Ну, видимо ему не хочется туда ничего слать, и висеть оно будет сколько угодно. Посмотри tcpdump-ом какие пакеты идут в обоих случаях, соединение должно заканчиваться пакетами FIN, первым шлёт тот кто захотел отсоединиться.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Спасибо большое за пояснения. Я хотел отслеживать активные подключения пользователей. Если IOS не оповещает сервер о закрытии соединения, то это проблема, можно ли по-другому выводить логи текущих IP, подключенных через PROXY к серверу?

NikolaevichPWNZ
() автор топика
Ответ на: комментарий от NikolaevichPWNZ

У тебя не очень понятно расписаны обстоятельства.

62.217.XXX.XX:777 - это адрес сервер и порт, на котором слушает прокся, так? И ты хочешь считать сколько пользователей подключено к проксе?

Соединение к ней через tcp или udp делается (в первой колонке ss указано)? В tcp есть штатный (в ядре) механизм проверки таких зависших соединений - keepalive, но по умолчанию он выключен, его должна включать программа, держащая эти сокеты. Может быть твой прокси-сервер умеет его включать. Если там udp - то штатного механизма нет, но возможно есть какой-то самодельный в проксе и его можно там включить. Называться скорее всего так же будет.

Ещё, если интересуют именно активные, можно вместо ss делать tcpdump и собирать статистику - с какого списка адресов были пакеты за последние, например, 60 секунд, и считать их активными. Но тут могут возникать всякие неточности из-за случайных мусорных пакетов, которые в ss не влияют, а тут будут считать за подключения.

firkax ★★★★★
()
Ответ на: комментарий от firkax

соединение должно заканчиваться пакетами FIN

Справедливости ради - ещё RST может случиться.

можно вместо ss делать tcpdump и собирать статистику

Имхо - довольно вредный совет. Мало того что root perms в том или ином виде требует и security implications имеет, так ещё и overhead недетский приносит. Не надо так делать.

@NikolaevichPWNZ, начните с того что на стороне прокси уменьшите TCP KeepAlive timeouts - оно по дефолту 2 часа(!!) ждёт прежде чем только начать probe packets слать.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

Имхо - довольно вредный совет

Про keepalive я тоже написал, но вдруг он там не включается никак?

TCP KeepAlive timeouts - оно по дефолту 2 часа(!!)

Это где такой дефолт? Насколько я знаю есть опция в setsockopt() для включения и по умолчанию она вообще выключена. А так - с линуксом не довелось проверить, а вот фрибсд соединение оставалось живым и спустя несколько недель hibernate компа-клиента, если в него сервер ничего не шлёт.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Это где такой дефолт?

Гуглим «Linux keepalive timeout». В шапке сразу выпадает:

What are the default values of TCP KeepAlive setting ? TCP keepalive process waits for two hours (7200 secs) for socket activity before sending the first keepalive probe, and then resend it every 75 seconds. As long as there is TCP/IP socket communications going on and active, no keepalive packets are needed.

По ссылкам ниже подробно расписывается что именно крутить в sysctl.conf.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

man 7 tcp:

      tcp_keepalive_time (integer; default: 7200; since Linux 2.2)
              The number of seconds a connection needs to be idle  before  TCP
              begins sending out keep-alive probes.  Keep-alives are sent only
              when the SO_KEEPALIVE socket option  is  enabled.   The  default
              value  is  7200 seconds (2 hours).  An idle connection is termi-
              nated after approximately an additional 11 minutes (9 probes  an
              interval of 75 seconds apart) when keep-alive is enabled.

Это всё влияет только если SO_KEEPALIVE установлено (процессом, обслуживающим сокет). Так что сначала надо выяснить ставит ли его прокси, или может надо его настроить. А так же, возможно, он же может ставить и TCP_KEEPIDLE, который переопределяет число из sysctl.

firkax ★★★★★
()
Ответ на: комментарий от firkax

ПыСы.

а вот фрибсд соединение оставалось живым и спустя несколько недель hibernate компа-клиента

И вот ещё интересное чтиво. Там даже описывается что делать если «приспичило», а 3rd party soft keepalive не включает (вкратце - прелоадить свою библиотечку и перехватывать socket-related calls). Но я сильно сомневаюсь что до этого дойдёт.

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 1)
Ответ на: комментарий от firkax

Это всё влияет только если SO_KEEPALIVE установлено (процессом, обслуживающим сокет).

Midair clash ;) Всё правильно говорите. Если «самое простое решение которое возможно сработает» (правка sysctl.conf) не помогает - на втором шаге я бы strace’ил proxy и смотрел что именно они делают. И читал бы документацию на прокси - вдруг там уже config knob на это дело имеется.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

Отредактировал sysctl.conf, добавил строчки:

net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 6

Обновил настройки, подключил два устройства. Всё работает, IOS отключается без проблем, IP-адрес исчезает из списка. Спасибо за помощь!

NikolaevichPWNZ
() автор топика