Заворачиваем весь трафик ОС в Tor



    Все описанное в статье реализовано в виде инструмента Toroxy, доступного на GitHub
    В последнее время анонимность в сети является предметом горячих споров. Ни для кого не секрет, что данные о посещениях Интернет-ресурсов с локального устройства могут собираться на разных уровнях с целью построения «модели» пользователя, которая позже против него же и может быть использована (или могла бы). Поэтому не удивительно, что все большее количество активных пользователей Интернета становятся уверены в необходимости механизмов проксирования и анонимизации. В связи с этим появляется все больше новых VPN-клиентов, но, как показывает практика, далеко не всем из них по-настоящему можно доверять: то не все работает из коробки, то анонимизируется только HTTP-трафик, то качество реализации хромает, а то и вовсе разработчики грешат сливанием данных о своих пользователях.

    В этой статье мы попробуем собрать из ряда программных компонентов собственный инструмент с UI, который бы позволил полностью анонимизировать трафик локальной системы и не допустить утечек по «прослушиваемым» каналам ни на одном из этапов работы.

    Главной нашей целью будет «сборка» надежной утилиты из готовых инструментов. Очевидно, что идея создания с нуля качественного инструмента за разумный срок чревата ошибками, а поэтому бытрее и надежнее будет выбрать готовые компоненты, а затем правильно их связать!

    Что должен уметь инструмент?

    1. Перенаправлять весь трафик целевой системы на промежуточные узлы (желательно несколько) для надежной маскировки источника
    2. Отслеживать возможные нарушения анонимности, исправлять их и сообщать о них с помощью UI уведомлений

    Выбранные компоненты для создания инструмента:

    • tor
    • iptables
    • python3
    • systemd

    Перемешав все компоненты в оболочке под названием «Linux» мы определенно сможем получить что-то стоящее, что поможет достигнуть итоговой цели.

    Компонент №1: Tor


    Именно вокруг этого компонента будет построена вся остальная инфраструктура инструмента. Tor предоставляет механизм, который находится в составе любого VPN-клиента — механизм заворачивания трафика через промежуточные анонимные для внешнего наблюдателя узлы (в стандартной конфигурации таких узла 3).

    По умолчанию клиент Tor из стандартных пакетных репозиториев после установки начинает слушать порт 9050, принимающий любого клиента, «умеющего» socks. Проблема заключается в том, что помимо socks-трафика в нашей системе может быть куча другого трафика от приложений, не работающих по этому протоколу. В связи с этим прежде всего в пределах локальной системы придется прорубить окно в сеть Tor для любого нового сетевого соединения. Делается это достаточно просто с помощью поднятия transparent proxy в конфигурации torrc:

    /etc/tor/torrc
    ...
    TransPort 9040
    # а это нам еще понадобится в дальнейшем для автоматизации из python
    ControlPort 9051
    ...
    

    Отдельного внимания заслуживает UDP трафик. Дело в том, что в основе принципа луковой маршрутизации лежит концепция «соединения» (stream), существующего, как известно, только в TCP. Отправив через Tor UDP-пакет, целевая система не сможет получить на него ответ, так как ответный пакет не найдет обратной дороги. Но несмотря на эту особенность, у нас остается возможность анонимизировать DNS запросы, которые, как известно осуществляются по UDP, а заодно и включить .onion резолв:

    /etc/tor/torrc
    ...
    AutomapHostsOnResolve 1
    DNSPort 53
    ...
    

    На этом доступ в Tor открыт в пределах loopback'а.

    Компонент №2: Iptables


    Так как наша задача заключается в сокрытии истинного источника трафика от внешнего наблюдателя в пределах всей системы, а окно в Tor уже открыто, осталось только завернуть весь трафик в это окно. Поможет нам в этом системный файрвол, находящийся в комплекте с ядром Linux:

    # заворачиваем tcp
    iptables -t nat -A OUTPUT -p tcp --syn -j REDIRECT --to-ports $TRANS_PORT
    # заворачиваем частично udp (dns only)
    iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports 53
    iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    # запрещаем всему остальному трафику покидать систему
    iptables -A OUTPUT -j REJECT
    ip6tables -A OUTPUT -j REJECT
    

    На данном этапе мы получаем рабочую утилиту, надежно маскирующую весь исходящий трафик, однако это только половина работы.

    Компонент №3: python + Desktop Evironment UI


    Каждый раз производить ручную конфигурацию из консоли (даже если это будет запуск bash-скрипта) будет достаточно утомительно, поэтому самое время приступить к написанию небольшой утилиты, помогающей нам конкретно в следующем:

    1. Автоматическая установка конфигурации
    2. Смена своего identity в пределах Tor в любой момент
    3. Отслеживание целостности правил iptables и их перезапись при нарушении
    4. Отслеживание текущего identity (IP)
    5. Уведомление о двух предыдущих пунктах с помощью уведомлений графическогой оболочки

    При первом запуске утилита самостоятельно скачает все необходимые компоненты, а при последующих запусках будет конфигурировать Tor в связке с iptables, как описано выше.

    При желании смены своего внешнего IP адреса, будет происходить взаимодействие со служебным портом Tor — 9051, открытым в самом начале для автоматизации смены IP:

    with Controller.from_port(port = 9051) as controller:
        controller.authenticate()
        controller.signal(Signal.NEWNYM)
    

    Отслеживание целостности можно реализовать достаточно банально (делаем же на коленке) с помощью периодического чтения структуры правил iptables и проверки их SHA256-суммы:

    def rulesOk(self):
        RULES_CHECKSUM_CMD = "{ iptables-save && ip6tables-save; } | sed s/\-\-uid\-owner\\\\s[0-9]\\\\+\\\\s//g | grep -viE '^#' | grep -viE '^\:' | sort | uniq | sha256sum | cut -d' ' -f 1"
        checkSum = getoutput(RULES_CHECKSUM_CMD).strip()
        alright = checkSum == Strings.RULES_CHECKSUM_CORRECT_HASH
    
        if not alright:
            rules = getoutput('iptables-save && ip6tables-save')
            self.lastSnapshotFileName = "/tmp/broken-rules-%s.log" % time.strftime("%d-%m-%Y_%I-%M-%S")
            open(self.lastSnapshotFileName, "w").write(rules)
            return False
         else:
             return True
    

    Также при обнаружении несостыковок с ожидаемой контрольной суммой можно сохранить дамп правил iptables в /tmp/broken-rules-%d-%m-%Y_%I-%M-%S.log для дальнейших разбирательств. Если окажется, что
    rulesOk() == False
    то будет инициирована перезапись таблицы правил iptables.

    Наблюдение за текущим IP будет происходить с помощью постоянного обращения на какой-нибудь внешний ресурс, предоставляющий IP-клиента — например, ident.me.

    Ну, и напоследок задействуем DE UI для сообщения о проблемах с правилами либо о смене IP. Каждое графическое окружение в каком-то роде уникально, особенно когда речь идет об использовании UI из процесса-демона, но все же на большинстве Linux'ов такой bash-код, вызываемый из Python будет успешно показывать уведомления:

    # root UI
    eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)"
    
    export DISPLAY=:0
    for USR in `ls /home && echo root`
    do
        # ubuntu gnome + root UI
        export XAUTHORITY=/home/$USR/.Xauthority
        notify-send -u {0} '{1}' '{2}'
    
        # ubuntu parallels
        for UID in `ls /run/user/`
        do
            su $USR -c "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$UID/bus notify-send -u {0} '{1}' '{2}'"
        done
    done
    

    Объединив все это в 200-строчном Python скрипте, получаем то, чего добивались. Вот, например, как будет выглядеть уведомление о том, что наш identity обновился:

    image

    А вот так будет выглядеть уведомление о том, что была нарушена целостность правил Iptables с указанием выгруженного дампа, содержащего нарушение:

    image

    Компонент №4: systemd


    Ну и напоследок нам определенно хотелось бы произвести единоразовую настройку и не думать в дальнейшем о своей безопасности, а потому на помощь приходят автозапуск и сервисы. В Linux есть несколько стандартных подсистем управления демонами: systemd, sysV, init. В нашем случае выбор пал на systemd из-за гибкости его настройки.

    Предположим, что написанный в предыдущем шаге python-скрипт называется «toroxy» и лежит в /usr/bin/, тогда его автозапуск и последующий мониторинг с определенной гибкостью управления демоном будет таким:

    [Unit]
    Description=Toroxy
    After=network.target
    StartLimitIntervalSec=0
    
    [Service]
    Type=simple
    Restart=always
    RestartSec=1
    User=root
    # service toroxy start
    ExecStart=/usr/bin/toroxy service
    # service toroxy stop
    ExecStop=/usr/bin/toroxy stop
    # service toroxy reload
    ExecReload=/usr/bin/toroxy switch
    
    [Install]
    # запускаемся на init 3, чтобы с пользовательского уровня до загрузки UI трафик уже шел через Tor
    WantedBy=multi-user.target
    

    Почти все готово для «промышленной» эксплуатации. Последний штрих, который хотелось бы внести в инструмент для дополнительной надежности — это автоматическая инициализация правил iptables при запуске системы (как известно, правила iptables при перезагрузке сбрасываются) с помощью iptables-persistent:

    iptables-save > /etc/iptables/rules.v4
    ip6tables-save > /etc/iptables/rules.v6
    netfilter-persistent start && netfilter-persistent save
    

    Заключение


    Вот мы и собрали из совокупности разношерстных компонентов собственный инструмент, который с достаточно высокой степенью надежности способен обеспечивать непрерывную анонимность пользователя Linux в сети. В завершение следует сказать, что все описанное в статье реализовано в виде инструмента Toroxy, доступного на GitHub.
    Postuf
    98,87
    Компания
    Поделиться публикацией

    Комментарии 16

      +1

      Настоятельно рекомендую посмотреть в сторону вот этого:
      https://github.com/StreisandEffect/streisand

        +2
        Как вариант — поднять whonix-gateway на другой машине и указать её как шлюз для машины, трафик которой нужно пустить через Tor.

        Из плюсов: не нужен Python, нет привязки к Linux, крайне простая настройка (указать шлюз и всё).
          +2
          Прямо весь траффик? Что там насчет ICMP и UDP? Как насчет портов, которые выходные узлы не захотят через себя пропускать? И как насчет пропускания незашифрованного траффика через эти самые выходные узлы? Вы уверены, что хотите именно этого?
            0

            Использование iptables в таком вопросе выглядит очень шатким решением. Если бы я такую задачу решал, я бы перенёс белый ip вместе с tor'ом в network namespace, сделал бы между основным компьютером и этим namespace'ом veth, и использовал только его. А ещё лучше в netnamespace засунуть не tor, а десктоп (потому что случайный hotplug выдерет интерфейс из namespace'а).

              0
              Апогеем апофеоза было бы качать обновления Windows через Tor. Чем Windows не Linux?
                0
                Такое себе удовольствие, особенно учитывая то, что гуглокапча вкупе с CF не поощряют использование Tor.
                  –4
                  По статье сразу видно нуба, бездумно содравшего из архивов 10лейтней давности инструкции для iptables. Автор, iptables во многих дистрибутивах уже давно в разделе устаревших пакетов.
                    0
                    Вопрос от нуба в сетях и безопасности:
                    Если заворачивается весь трафик операционки с целью анонимизации, то… что делать с ситуацией вида «операционка или софтинка на ней постучались на сервер и ненароком слили, что комп с таким-то отпечатком лазает в интернет через тор»?

                    Поправьте, если я ошибаюсь, но разве это не приведёт к потере неуловимости у Джо? Одно дело, когда определённый ресурс посещается скрыто и поди угадай, кто за этим отпечатком прячется, а другое когда кто-то сам говорит «этот отпечаток принадлежит мне, анонимному юзеру. кстати, зацените мой новый коммент в контактике, который я оставил из соседней вкладки браузера»
                      +1
                      Именно поэтому наилучшим решением является разделять свою анонимную личность (которая занимается какими-то делами, за которые можно огрести) и публичную.

                      Простейший вариант: две разные физические машины, на одной из которых трафик как раз и завернут в тор (поэтому, задача «зввернуть весь трафик в тор» вполне актуальна). С этой машины работает Megadestroyer666, который не допускает ни малейшего пересечения с Василием Пупкиным (которым он является в реальности) — никакого захода в аккаунты, связанные с Василием, ничего. А со второй машины сидит в контактике Василий Пупкин, который не скрывается. Никто не должен заподозрить, что это один и тот же человек.

                      Именно так палятся даже весьма крупные фигуры — «ну я разок зашёл с сервера, с которого управляю ботнетом, в свою публичную почту, к которой у меня привязан Paypal и куда я обычно захожу со своего реального IP, ну что такого?». А то, что теперь сервер, с которого управляется ботнет, чётко связан с реальным человеком. И когда правоохранители доберутся до сервера, они это размотают.
                        0
                        Хм, в контексте отдельной физической машины это действительно имеет смысл, спасибо
                          0
                          Как видите, мы давненько за вами наблюдаем, Мистер Андерсон.
                          Оказывается, вы ведете двойную жизнь.
                          В одной жизни, вы Томас А. Андерсон — программист в уважаемой компании.
                          У вас есть страховка. Вы платите налоги. И вы помогаете вашей домовладелице выносить мусор.
                          Другая ваша жизнь в компьютере, где вы известны как хакер «Нео», и где вы виновны практически во всех уголовно наказуемых компьютерных преступлениях.
                          Одна из этих жизней имеет будущее.
                          А другая нет.
                        0

                        Как челленж — похвально, с практической точки зрения гемморойно. Проще юзать специально предназначенные live-cd образы, тот же kali

                          –4
                          >>Проще юзать специально предназначенные live-cd образы, тот же kali
                          Как kali вообще относится к заворачивание траффика в tor?

                          Такие глупые `attention whore` комментарии не несущие смысловой нагрузки пиши в `/dev/null`, миру больше пользы будет.
                            +2
                            Что за агрессия. Я извиняюсь, перепутал, имел ввиду TAILS, в нем по умолчанию завернут весь трафик через ТОР. Плюс в случае загрузки с live-cd, данные хранятся в оперативке, и стираются после сеанса.

                            Так что прежде чем необоснованно что-то отправлять в /dev/null надо удостовериться, не выкидываешь ли ты что-то действительно нужное.
                          0
                          Была идея завернуть трафик торрента в Тор. Но оказалось что это очень плохая идея как раз из-за безопасности, потому что твой IP становится виден всей сети Tor))
                            0
                            а в чем проблема anonsurf, почему им не пользоваться?

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                            Самое читаемое