[О блоге] [наверх] [пред] [2019-08-13 20:40:55+03:00] [12108e20634848c062a6886c85047018e02d6eca]
Темы: [ipsec]

День борьбы с сетью и начало написания IPsec на Go

Надо мне тут теперь написать IPsec реализацию. Пишу на Go, так как на
Python -- адовый ад, на Perl тоже не особо охота, а на других языках я
совсем не силён. А вот программировании сетей я вообще ничего не понимаю.

Так как у нас не TCP/UDP, то нужен какой-то другой вид сокетов, из
коробки net библиотекой не предоставляющийся. Ok, пошёл искать в сторону
raw-сокетов (про них только слышал) и понял что через syscall библиотеку
можно подёргать стандартные C-шные функи. Но в man говорится что:

    If the proto argument to socket(2) is zero, the default protocol
    (IPPROTO_RAW) is used for outgoing packets.  For incoming packets,
    protocols recognized by kernel are not passed to the application socket
    (e.g., tcp(4) and udp(4)) except for some ICMPv6 messages.  The ICMPv6
    messages not passed to raw sockets include echo, timestamp, and address
    mask requests.  If proto is non-zero, only packets with this protocol
    will be passed to the socket.

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

Вспомнил, когда читал man ipfw, что есть divert сокеты, когда можно в
userspace отправлять пакетики на обработку. Посмотрел и увидел что вроде
то, что надо. В Go через syscall успешно создают сокет, делаю bind,
принимаю пакеты. А вот отправлять не выходит. Целый день убил чтобы
увидеть что checksum-а в UDP (TCP тоже не работал) пакетах какая-то
кривая когда они приходят из divert сокета и отправляются с текущей
машины. Я так и не выяснил почему так. Но даже проксю у меня не
получилось сделать, которая просто принимает и отправляет пакет as-is.

Психанул и вообще поднял jail со своим сетевым стэком (vnet) и из него
шлю пакеты. Его epair сетевой интерфейс засунул в bridge с компьютером
который за настоящим Ethernet-ом является точкой IPsec (полноценной, не
собственноручнонаписанной). ipfw diver правилами перехватываю проходящий
через bridge трафик, требующий ESP-шифрования, и посылаю в Go приложение
слушающее на diver сокете. А оно уже отправляет назад ESP-шки. В целом
работает, хотя выглядит монструозно.

    [оставить комментарий]