Небольшой демон, позволяющий строить Mesh сети в нескольких режимах, а именно Routing (когда маршрутизацией занимается tincd, switch - когда маршрутизация отдаётся на откуп OS, но производится mac learning и hub - когда трафик рассылается во все порты)
Весь tinc в Gentoo замаскирован, поэтому берём не самую свежую версию, чтобы можно было коннектиться с другими участниками сети спокойной и не искать почему теряются пакеты. В Debian stretch версия tinc - 1.0.31, так что остановимся на ней
# emerge -v =tinc-1.0.31
В общем-то здесь наверное и всё.
В отличии от более современных версий tinc, в которых изначальна впилены возможности по bootstrap'у новых сетей, в предыдущих версиях такого функционала нет, поэтому придётся немного поработать руками. Олсо, rc-скрипт tinc для openrc не адаптирован, так что вместо привычного нам service.instance придётся править конфиг, куда прописывать запускаемые демоно сети.
Итак, структура каталогов тинка достаточно проста
/etc/ |- tinc/ |- <network name> |- tinc.conf - конфиг демона |- tinc-up - скрипт, исполняемый после создания интерфейса |- tinc-down - скрипт, исполняемый перед удалением интерфейса |- rsa_key.priv - закрытая часть rsa ключа |- hosts/ - директория с "карточками" участников сети |- host1 |- host2 |- host3
Собственно для начала работы с tinc достаточно создать структуру каталогов, как представлено выше, написать в tinc.conf что-нибудь следующее:
Name = host1 Device = /dev/net/tun ConnectTo = host2 ConnectTo = host3 Port = 665
и сгенерировать связку ключей для текущего хоста:
# tincd -n <network name> -K
Причём в конфиге tinc.conf можно указывать бесконечное количество ConnectTo, поскольку данная директива описывает хосты, к которым нужно осуществлять подключение.
После чего повторить процедуру на всех хостах.
Карточка хоста выглядит примерно так:
----RSA PUBLIC KEY BLOCK---- .... ----END RSA PUBLIC KEY BLOCK---- Subnet = 10.0.0.1/32
Кстати интересный момент, даже если для сети выбрана размерность шире, в карточке хоста всё равно его непосредственный ip-адрес надо указывать с маской /32. А вот сети, которые находятся за хостом можно писать напрямую префиксами.
И ещё один немаловажный момент - tinc сам не вешает маршруты и адреса на свои интерфейсы, для этого служат скрипты tinc-up и tinc-down, причем они обязательно должны быть исполняемыми. Например вот такими:
#!/bin/bash ip link set up $INTERFACE ip a add 10.0.0.1/24 dev $INTERFACE
#!/bin/bash ip a add 10.0.0.1/24 dev $INTERFACE ip link set down $INTERFACE
Аналогично, но со своими адресами настраиваются и остальные хосты.
Для того, чтобы всё это взлетело и заработало в режиме роутинга, который включён в tinc по умолчанию, все карточки хостов должны быть отсинхронизированы между ними, чтобы tinc точно знал где и какой адрес находится.
Так же у tinc есть возможность работать в режим switch'а. Для этого в конфиге нужно добавить одну строчку:
... Mode = switch ...
После этого данная нода начнёт обрабатывать пакеты стандартным l2 стэком. Единственное но, которое я заметил, это то, что в сети нельзя использовать разные ноды, т.е. либо всё в роутинге, либо всё в свитчинге.
Если послать тинку USR2 - в syslog заедет достаточно большое количество инфы, в котором будет список всех нод в сети, их связность и роутинг.
Из важного, у каждого коннекта есть статус, который не очень очевиден:
typedef struct connection_status_t { unsigned int pinged: 1; /* sent ping */ unsigned int active: 1; /* 1 if active.. */ unsigned int connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */ unsigned int unused_termreq: 1; /* the termination of this connection was requested */ unsigned int remove: 1; /* Set to 1 if you want this connection removed */ unsigned int timeout: 1; /* 1 if gotten timeout */ unsigned int encryptout: 1; /* 1 if we can encrypt outgoing traffic */ unsigned int decryptin: 1; /* 1 if we have to decrypt incoming traffic */ unsigned int mst: 1; /* 1 if this connection is part of a minimum spanning tree */ unsigned int proxy_passed: 1; /* 1 if we are connecting via a proxy and we have finished talking with it */ unsigned int unused: 22; } connection_status_t;
Собственно здесь реализована битовая маска. Из распространённых статусов: