С годами мы обрастаем компьютерами и девайсами, которые ещё иногда называют хостами. Например, один виртуальный хост висит в стране чистого интернета, есть хосты на работе, дома, на даче, и т. д. Хотелось бы иметь средство для управления всеми ими, чтобы можно было из любого места зайти в любое другое, в режиме командной строки, разумеется. Например, с дачи нам хотелось бы зайти на рабочий компьютер, а с работы — на хост чистого интернета и т. д. Но на нашем пути встают препятствия: хосты находятся за NATом, на работе нет прав администратора, а в чистый интернет нас и подавно не хотят пускать.

Решение


Я одно время пробовал решать эту проблему методом множественных ssh соединений с проброской портов туда и обратно, но эта схема оказалась ненадёжной. Сессии имеют свойство рваться, не спасает даже autossh: сессия какое-то время после обрыва висит и не даёт запуститься следующей сессии. В общем, в ответственные моменты связь пропадала. Тогда я написал программу dnet, которая объединяет все мои хосты в единую сеть и позволяет с любого хоста управлять любым другим. Может быть, кому-то ещё она пригодится, или же, возможно, читатели выскажут какие-либо пожелания по её дальнейшей разработке.

Структура сети


Программа строит защищённые TCP-соединения между хостами и таким образом возникает сеть. В простейшем случае те хосты, которые находятся за NATом, подключаются к хосту в стране чистого интернета и образуется звездообразная структура, но структура сети может быть и более сложной. Для защиты соединений используется собственный алгоритм потокового шифрования, а его сеансовый ключ шифруется собственной реализацией метода RSA. На стороне каждого хоста при первом запуске программы генерируются необходимые ключи (1024-4096 бит). Далее хосты самостоятельно строят защищенное соединение между собой, вручную переносить ключи между хостами нет необходимости. Хосты периодически обмениваются сообщениями и определяют маршруты друг к другу внутри сети. При обрыве какого-либо соединения оно сразу же начинает строиться заново. Таким образом, длительных сбоев в сети не возникает.

Возможности программы


При старте программы мы попадаем в режим интерактивного ввода команды и можно управлять сетью. Есть определённый набор команд, причём действует правило: любую команду можно выполнить как будто мы её вводим на другом хосте. Для этого нужно перед командой написать имя хоста. Например, можно выполнить команду shell на другом хосте, введя имя этого хоста и далее команду.

Если ввести только имя хоста, то мы попадаем в оболочку shell на нём, причём авторизовываться там не надо — используются привилегии, данные программе dnet. На удалённом хосте можно запустить любое консольное приложение — например, mc или htop. Кроме того, можно скопировать файл или каталог с одного хоста на другой. Также можно перенаправить tcp или udp порты на другой хост. Наконец, если у нас есть tap интерфейсы на двух хостах, то между ними можно организовать туннель, т. е. передачу ethernet пакетов.

Где взять


Исходные тексты есть на гитхабе: https://github.com/dcherukhin/dnet. Бинарную программу для Linux (она же работает в Windows 10 с установленным пакетом bash) можно скачать по этой ссылке: https://dcherukhin.info/dnet. Есть версия на Qt под Android, с почти идентичной функциональностью. В частности, с Android-устройства можно давать команды, которые будут выполняться на любом хосте сети, а с компьютера можно зайти в shell на Android, причём права рута на андроиде не нужны. Я зарегистрировался на google play и разместил приложение там, но пока у них что-то синхронизируется. Если оно успешно досинхронизируется, то найти приложение можно будет под именем info.dcherukhin.dnet.

Пример использования


В простейшем случае запустить программу можно без параметров. Она подумает примерно секунд 5 и выдаст подсказку.

$ ./dnet
Generating keys... OK # генерируюстя ключи RSA 2048 бит
dnet>

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

dnet> host
AB12CD34 ... # это временное имя
dnet> rename AB12CD34 MyHost666 # меняем на постоянное
dnet> host # проверяем
MyHost666 ...

Здесь стоит обратить внимание на безопасность, иначе каждый сможет выполнить что-нибудь на вашей машине. Есть такое понятие, как доверенные хосты. Если ни один не указан в качестве доверенного, то по умолчанию доверенными считаются все. Если же указать хотя бы один доверенный хост, то доверенными становятся только явно указанные. Все пакеты, приходящие внутри сети с недоверенных хостов, отбрасываются.

Допустим, наряду с упомянутым хостом у нас есть ещё один, Kitty777, и мы хотим сделать его доверенным. Тогда набираем (аналогичное надо сделать и на том хосте):

dnet> trust Kitty777
dnet> host Kitty777 # проверяем
Kitty777 ... trust ... 

Теперь у нас есть две машины и между ними можно копировать файлы/каталоги, перенаправлять порты, делать туннели между tap интерфейсами. Примеры команд ниже:

dnet> copy file Kitty777:file
dnet> copy Kitty777:catalog catalog
dnet> tcp 2222 Kitty777 22
dnet> udp 7777 Kitty777 192.168.1.2:7
dnet> tunnel 1 Kitty777 2 # туннель между tap1 у нас и tap2 на Kitty777

Разумеется, подключаться к моему серверу не обязательно, можно организовать сеть исключительно из своих машин. Для этого при запуске каждого экземпляра программы dnet ей надо указать, на каких портах слушать и куда подключаться, например:

$ ./dnet -s 0.0.0.0:12345 192.168.1.5:12345 50.5.15.35:2222
Generating keys... OK # в этом случае генерируются ключи 4096 бит, ждать надо порядка минуты
dnet>

Что дальше


В первую очередь хотелось бы, чтобы всё описанное выше заработало с учётом масштабирования. Далее в планах есть end-to-end шифрование, т. е. если вы соединяете свои хосты через чужой сервер, то данные проходят через него зашифрованными. И, конечно, на случай нажатия красной кнопки хотелось бы написать TCP-соединения между хостами «на котиках». Таких, как на картинке в самом верху. До скорого )
Поделиться с друзьями
-->

Комментарии (60)


  1. ls1
    07.04.2017 07:31
    +7

    на работе нет прав администратора, а в чистый интернет нас и подавно не хотят пускать.
    но при этом пускают на произвольные порты левых серверов (типа вашего приватного ssh)? Тогда о чем вообще жаловаться? Строить всё это ради объединения своих хостов в основном для ssh управления? Не понимаю, можно ведь обойтись стандартными VPN решениями типа openvpn и иметь полноценную L3 сеть, или тупо teredo/miredo, а кто-то так и вообще TOR Hidden Service использует. Нет админских прав на компе? Дружище, а тебе не стрёмно вообще с такого компа инициировать подключение к своим серверам и вообще как-то светить свои ключи/логины/пароли? Лично я бы этого не стал делать вообще ни при каких условиях.


    1. dcherukhin
      07.04.2017 17:02

      Обычный ssh могут запросто блокировать по номеру порта или протоколу, то же и с vpn, а до моего им дела пока нет.) А вот и не стрёмно. Пример: вот прямо сейчас сижу в компьютерном классе в одном вузе, тут у меня нет прав администратора, но я вставил флешку с ключом одного хоста и приконнектился. Палится только ключ одного хоста. Если этот хост войдёт в сеть без моего участия, это будет заметно, там логируется время захода.


      1. pansa
        08.04.2017 01:27
        +1

        Ничто не мешает поднять ssh на нестандартном порту — 443, например.
        А блокировать ssh «по протоколу» — это вот вы о чем сейчас?


        1. dcherukhin
          08.04.2017 10:08

          ssh уж наверняка есть в базе данных quosmos (это такой DPI). Даже и я видел, как в самом начале сессии он посылает какую-то фразу вроде своей версии. Если по телнету подключиться к 22-му порту, то в начале приходит такое: SSH-2.0-OpenSSH 7.2


          1. Envek
            08.04.2017 19:47

            openconnect (который реализация Cisco AnyConnect) вообще по HTTPS работает (фиг отличишь), так что если веб разрешён, то и openconnect разрешён.


          1. Erelecano
            08.04.2017 23:54

            sslh на 443 порту.
            И там будет отвечать и https, и ssh, и openvpn
            Что ваш DPI там найдет?


            1. dcherukhin
              09.04.2017 01:18

              Спросите у товарища майора.) Я (больше) не занимаюсь DPI. Думаю, что каждую сессию будут анализировать отдельно, и те протоколы, которые не запрещены, пропустят.


              1. Envek
                11.04.2017 10:02

                HTTPS без устроения «человека посередине» после установления соединения не поанализируешь: всё, что увидишь — белый шум.


                1. dcherukhin
                  11.04.2017 11:03

                  Над человеком посередине уже работают, сам видел.


                1. orignal
                  11.04.2017 17:50

                  Времена и длины пакетов можно мерять и делать выводы о характере трафика.


            1. OmManiPadmeHum
              10.04.2017 20:17

              еще как вариант SoftEther VPN использовать


              1. dcherukhin
                10.04.2017 20:18

                Спасибо. Чем больше разных протоколов, тем больше можно спутать карты ловцам человеков.


  1. Temmokan
    07.04.2017 08:09
    +2

    Не проще использовать tinc в качестве простого способа создать «приватную сеть»?

    Написание собственных решений — занятие полезное для тренировки навыков программирования, с этим не спорю.


    1. dcherukhin
      07.04.2017 16:47

      Да, посмотрел, есть такой tinc. Правда, не разбирался, в точности ли он один в один. А как насчёт импортозамещения?)


      1. Temmokan
        07.04.2017 17:38
        +1

        Если найдёте платную версию — без сомнений замещайте. Больше года использую tinc в ситуации, описанной в статье — всем устраивает.


      1. Erelecano
        07.04.2017 21:10
        +1

        Вы не с того начали замещать. Тогда уж начните с того, что разработайте собственные берестяные компьютеры на триединой логике, в которой у вас каждый бит является всем тритом сразу, но при этом сам по себе(а еще в нем третий бит исходит от двух других, но при этом существует сам по себе), придумайте свои протоколы передачи данных стуком по березе и так далее. А если используете «вражеские» компьютеры и «вражеские» ОС, то не изобретайте велосипедов с треугольными колесами, а просто воспользуйтесь надежными решениями от людей у которых есть знания и мозги.


        1. dcherukhin
          07.04.2017 22:25

          У меня есть мозги.)


          1. Erelecano
            07.04.2017 22:26
            +1

            Были бы мозги, использовали бы tinc или peervpn, а не писали чушь про «импортозамещение».


            1. dcherukhin
              07.04.2017 22:50

              Чтобы использовать уже известное мозги как раз не особо нужны.


              1. Erelecano
                07.04.2017 23:27
                +1

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


                1. dcherukhin
                  08.04.2017 10:02
                  -3

                  Я не хуже) Я специалист по дискретной математике и у меня результаты мирового уровня. Так что насчёт алгоритмов можно не сомневаться. А что касается маркетинга — тут, увы, есть над чем задуматься.)


  1. ValdikSS
    07.04.2017 09:56
    +2

    Занятно.

    Если хотите избавиться от центрального сервера, можно генерировать идентификатор сети, который нужно ввести на всех компьютерах, которые хотят подключиться к этой сети. Для обнаружения хостов тогда можно будет использовать Bittorrent DHT (или даже публичные торрент-анонсеры), а идентификатор будет являться infohash раздачи. Порты для хостов за NAT можно пробрасывать привычными способами: STUN/TURN/ICE с серверами Google и Mozilla.

    Еще можно написать userspace-реализацию протокола Teredo, которая не будет требовать root-прав, и использовать публичные серверы, тогда вообще заморачиваться с NAT не придется.


    1. ValdikSS
      07.04.2017 10:06

      Если код писать не хочется, или для вас это не так просто, то можно воспользоваться клиентом сети I2P i2pd от orignal. I2P позволяет устанавливать прямые туннели, без дополнительных хопов, а также работать за NAT. Также можно воспользоваться и Tor, в последних версиях можно создавать неанонимные Hidden Service.


      1. dcherukhin
        07.04.2017 16:57

        Я немного не понял. Есть два хоста. Оба за NATом. Как нам передать данные с одного на другой. Много данных.

        Кстати, Tor использую в качестве основного браузера, но в соцсети так ходить неудобно, да и Tor Bundle в последнее время стал падать. Так что в качестве альтернативы хожу по туннелю через вот эту программу dnet в другую страну. И i2p кстати у меня запущен, но опять же, чтобы не смущать своего провайдера i2p соединениями, они заходят ко мне по этому же туннелю.


        1. ValdikSS
          07.04.2017 17:16
          +1

          Есть два хоста. Оба за NATом. Как нам передать данные с одного на другой.
          Мы отсылаем UDP-пакеты с обеих сторон и с заданными портами отправления и назначения. Данные начинают передаваться.

          Tor, I2P и Teredo установят вам соединение даже в том случае, если оба хоста за NAT.


        1. orignal
          07.04.2017 19:13

          Нужен третий, который пошлет второму сообщение, что первый хочет соединиться. Тогда второй попытается отправить пустое сообщение первому, в результате чего на NAT возникнет Hole Punch и первый сможет отправить UDP пакет второму. Аналогично Hole Punch возникнет у первого и они смогут обмениться пакетами.
          Третий участник называется introducer-ом. Те, кто сидят за NAT должны при публикации указывать адреса introducer-ов вместо своих.


          1. dcherukhin
            07.04.2017 22:56

            Тут надо очень хорошо представлять, как устроен NAT у конкретного провайдера. Возможны ситуации, когда тому, кто за натом, вообще ничего нельзя послать первым. Бывают ещё двойные наты, например, интернет через wifi от смартфона, который подключён к мобильному оператору.


            1. orignal
              07.04.2017 23:41

              Не получится соединиться с одним, получится с другим. Тоннель можно строить как угодно.
              I2P адреса то через тоннели работают.


  1. Lelik13a
    07.04.2017 10:20
    +2

    А чем OpenVPN не угодил?


    1. PaulZi
      07.04.2017 10:44
      +1

      И правда? Поднять OpenVPN на 443 порту и никаких проблем)


      1. dcherukhin
        07.04.2017 16:45
        -1

        Tor, i2p, vpn — всё это известно и неинтересно.) А именно, включено в DPIные базы данных и при необходимости банится.


        1. orignal
          07.04.2017 21:00
          +1

          Хотелось бы узнать, каким образом DPI определяет I2P, кроме как сбором списка IP адресов всех узлов сети.


          1. dcherukhin
            07.04.2017 22:44

            Вот тут пишут о неком методе «connection probe».


            1. orignal
              07.04.2017 23:42

              Известная тема. Решается введением подписью адреса. Уже над этим работаем


              1. dcherukhin
                08.04.2017 09:58

                Вы из команды i2p/i2pd?


                1. orignal
                  08.04.2017 15:12

                  Я и есть главный разработчик i2pd.


                  1. dcherukhin
                    08.04.2017 17:02

                    О-о! Кстати, dcherukhin.i2p/dnet ) Интересно, а протокол i2p где-нибудь формализован, чтобы можно было к вам подключиться? Когда-то смотрел код ip2d на предмет того, чтобы встроить его в свою систему. На тот момент мне не понравился C++, хотя сейчас это не проблема. И ещё, может ошибаюсь, но там есть какие-то тяжёлые зависимости вроде boost.


                    1. orignal
                      08.04.2017 17:20

                      Сейчас все подробно описано здесь, но там даже если просто подключиться придется написать дофига кода.


  1. Shaltay
    07.04.2017 11:46
    +4

    На что люди только не идут, чтобы ipv6 не внедрять…


    1. dcherukhin
      07.04.2017 16:44

      Поддерживаю. В связи с тем, что на ipv4 хостится много всего непотребного, предлагаю его полностью запретить с 1 января 2018 г. Думаю, профильный комитет одобрит.)

      С другой стороны, даже при ip6v всё равно будет NAT на стороне провайдера, я так понял со слов представителя провайдера.


      1. ValdikSS
        07.04.2017 17:18

        Для IPv6 NAT не нужен для повседневной жизни, и уж точно его не будет на стороне провайдера.


        1. dcherukhin
          07.04.2017 22:46

          Провайдеру виднее, что ему нужно для повседневной жизни.) А нужно ему снять денег за белые адреса.


          1. ValdikSS
            08.04.2017 07:28

            Провайдер должен выдавать вам минимум одну /64.


      1. Shaltay
        10.04.2017 14:26

        С другой стороны, даже при ip6v всё равно будет NAT на стороне провайдера


        А зачем?


        1. dcherukhin
          10.04.2017 17:01

          Зачем-то им это надо. Например, мой провайдер, пока я ему не заплатил 130 руб за белый адрес, менял адреса каждый 5 минут, хотя это совсем не нужно. Но белый адрес в его понимании — это всего лишь постоянный адрес. А такого, чтобы были открыты порты снаружи у них в принципе не предусмотрено. Иметь какие-то службы дома — это уже экстремизм.)


          1. Shaltay
            10.04.2017 17:04
            +1

            А такого, чтобы были открыты порты снаружи у них в принципе не предусмотрено.


            Это плохой, негодный провайдер.


            1. dcherukhin
              10.04.2017 20:15

              Телефонная сеть. Другие крупные наш дом игнорируют.


  1. koldyr
    07.04.2017 13:53
    +2

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


    1. dcherukhin
      07.04.2017 16:37

      Знаю, что в программе есть дыры, буду их исправлять по мере необходимости.


      1. Tomatos
        08.04.2017 09:12

        А что считается необходимостью? Вы не подумайте, что я осуждаю — мне нравится ваш подход.


        1. dcherukhin
          08.04.2017 09:56

          Пока в сеть заходил только я, не было потребности даже вводить доверенные хосты, т. е. теоретически любой, подключившийся к сети, мог выполнить команду на моём компьютере, но о ней никто не знал. Когда я решил использовать сеть для обучения студентов, то всё же ввёл доверенные хосты. Вряд ли студенты будут специально что-то делать на моих машинах, но могут это сделать случайно. Сейчас другие люди сеть используют периодически, на пробу. Постоянных пользователей, кроме меня, нет. Когда они появятся, будет необходимость заняться исправлением более тонких уязвимостей, до которых можно дойти, хорошо проработав код.


  1. manchelsi
    07.04.2017 16:48
    +1

    бегло просмотрев исходный код, наблюдаем, что жестко прописан ip адрес
    https://github.com/dcherukhin/dnet/blob/master/dnet/dnet_main.c#L111
    Мы тут действительно говорим о «приватной» сети?


    1. dcherukhin
      07.04.2017 16:52
      -1

      Да, есть такое. Это адрес моего центрального сервера. Эта константа работает только в режиме запуска без параметров, о чём была речь в тексте. В произвольном случае можно к нему не подключаться, а коннектиться между своими хостами. Вообще было бы здорово, чтобы сеть была децентрализованной, т. е. было много таких серверов, это придало бы ей больше приватности. Тогда можно было бы подумать о протоколе обмена такими адресами.


  1. immaculate
    07.04.2017 19:33

    Есть серьезные альтернативы:
    https://www.zerotier.com/
    http://meshbird.com/


    Правда ни одной из них пока не пользовался, так как не было необходимости.


    1. dcherukhin
      07.04.2017 22:48

      Они уж больно серьёзные. У нас простое решение: загрузил бинарник, в котором лично я уверен, никакой установки и настройки, никаких прав root, запустил и заработало. Очень мне помогает на занятиях со студентами, когда мы проходим тему клиент-сервер. Одмины позаботились о том, чтобы компьютеры в классе были изолированы друг от друга, но оставили всё же выход в интернет.


      1. Tomatos
        08.04.2017 09:14

        в котором лично я уверен
        Вы же понимаете, что это аргумент только для вас? :)


        1. dcherukhin
          08.04.2017 09:57

          Да, но исходный код открыт. Если соберётся достаточное число пользователей (не буду говорить о вероятности этого события), то можно будет организовать сбор денег на независимую проверку.


  1. sotnikdv
    08.04.2017 16:54

    > Для защиты соединений используется собственный алгоритм потокового шифрования, а его сеансовый ключ шифруется собственной реализацией метода RSA.

    Amateurs Produce Amateur Cryptography © Bruce Schneier

    Нет, вы конечно молодец, но пускать такое решение в массы рисково ИМХО


    1. dcherukhin
      08.04.2017 16:58

      Насчёт своего собственного алгоритма — тут я частично согласен, над его взломом никто особо не думал. А RSA — это наше всё, там основная сложность приходится на умножение длинных чисел, а это почти тема моей научной работы.


  1. Happy_dayZ
    14.04.2017 09:38

    А хорошо все изложено!