Menu

pptp over gif (IPSEC)

Help
Nick
2013-01-23
2017-12-27
  • Nick

    Nick - 2013-01-23

    Добрый день!
    Помогите решить странную проблему . Условия задачи такие -
    Имеется freebsd роутер (9.1-RELEASE) с custom kernel.
    На роутере создан интерфейс vlan, привязанный к сетевой карте, однако фактически не имеющий никакого продолжения за пределами роутера. Это просто некоторый аналог loopback для навешивания смаршрутизированных адресов. На интерфейсе с маской /32 навешан публичный адрес.
    На роутере запущен mpd pptp сервер, привязанный к этому адресу (set pptp self x.x.x.x).
    Адрес на этот роутер маршрутизируется через туннель. До недавнего времени это был openvpn (tun), сейчас в качестве эксперимента я перешел на gif поверх IPSEC (racoon). IPSEC затрагивает только пару адресов, на которых построены концы gif туннеля. Исходящий трафик в туннель попадает посредством ipfw fwd … out via vlan…, т.е. ловится на выходе интерфейса с маршрутом по умолчанию.

    Проблема:
    После перехода на gif - pptp перестал работать. Проблема выглядит как непрохождение gre трафика в направлении от клиента к серверу mpd. Однако этот трафик видит tcpdump на интерфейсе gif и его можно "посчитать" с помощью ipfw count (после "включения" фильтрации на gif через sysctl).
    Фаервол "открытого" типа, DEFAULT_TO_ACCEPT, каунтер ставился в конце.
    Типичный лог подключения выглядит так:

    Jan 23 13:43:56 ccc mpd: [L100-1] Accepting PPTP connection
    Jan 23 13:43:56 ccc mpd: [L100-1] Link: OPEN event
    Jan 23 13:43:56 ccc mpd: [L100-1] LCP: Open event
    Jan 23 13:43:56 ccc mpd: [L100-1] LCP: state change Initial --> Starting
    Jan 23 13:43:56 ccc mpd: [L100-1] LCP: LayerStart
    Jan 23 13:43:56 ccc mpd: [L100-1] PPTP: attaching to peer's outgoing call
    Jan 23 13:43:56 ccc mpd: [L100-1] Link: UP event
    Jan 23 13:43:56 ccc mpd: [L100-1] LCP: Up event
    Jan 23 13:43:56 ccc mpd: [L100-1] LCP: state change Starting --> Req-Sent
    Jan 23 13:43:56 ccc mpd: [L100-1] LCP: SendConfigReq #1
    Jan 23 13:43:56 ccc mpd: [L100-1]   ACFCOMP
    Jan 23 13:43:56 ccc mpd: [L100-1]   PROTOCOMP
    Jan 23 13:43:56 ccc mpd: [L100-1]   MRU 1500
    Jan 23 13:43:56 ccc mpd: [L100-1]   MAGICNUM 16dd10fc
    Jan 23 13:43:56 ccc mpd: [L100-1]   AUTHPROTO CHAP MSOFTv2
    Jan 23 13:43:56 ccc mpd: [L100-1]   MP MRRU 2048
    Jan 23 13:43:56 ccc mpd: [L100-1]   MP SHORTSEQ
    Jan 23 13:43:56 ccc mpd: [L100-1]   ENDPOINTDISC [802.1] f4 6d 04 00 00 00
    Jan 23 13:43:58 ccc mpd: [L100-1] LCP: SendConfigReq #2
    Jan 23 13:43:58 ccc mpd: [L100-1]   ACFCOMP
    Jan 23 13:43:58 ccc mpd: [L100-1]   PROTOCOMP
    Jan 23 13:43:58 ccc mpd: [L100-1]   MRU 1500
    Jan 23 13:43:58 ccc mpd: [L100-1]   MAGICNUM 16dd10fc
    Jan 23 13:43:58 ccc mpd: [L100-1]   AUTHPROTO CHAP MSOFTv2
    Jan 23 13:43:58 ccc mpd: [L100-1]   MP MRRU 2048
    Jan 23 13:43:58 ccc mpd: [L100-1]   MP SHORTSEQ
    Jan 23 13:43:58 ccc mpd: [L100-1]   ENDPOINTDISC [802.1] f4 6d 04 00 00 00
    

    SendConfigReq запрашивается 10 раз, после чего "LCP: parameter negotiation failed" и все начинается сначала.

    13:50:15.086224 IP server > client: GREv1, call 1723, seq 0, length 54: LCP, Conf-Request (0x01), id 1, length 40
    13:50:15.170515 IP client > server: GREv1, call 1773, seq 0, length 39: LCP, Conf-Reject (0x04), id 1, length 25
    13:50:15.455345 IP client > server: GREv1, call 1773, seq 1, length 26: LCP, Conf-Request (0x01), id 1, length 12
    13:50:17.086611 IP server > client: GREv1, call 1723, seq 1, length 54: LCP, Conf-Request (0x01), id 2, length 40
    13:50:17.169509 IP client > server: GREv1, call 1773, ack 1, no-payload, length 12
    13:50:17.171538 IP client > server: GREv1, call 1773, seq 2, length 39: LCP, Conf-Reject (0x04), id 2, length 25
    13:50:18.436050 IP client > server: GREv1, call 1773, seq 3, length 26: LCP, Conf-Request (0x01), id 1, length 12
    13:50:19.088610 IP server > client: GREv1, call 1723, seq 2, length 54: LCP, Conf-Request (0x01), id 3, length 40
    13:50:19.172832 IP client > server: GREv1, call 1773, ack 2, no-payload, length 12
    13:50:19.174164 IP client > server: GREv1, call 1773, seq 4, length 39: LCP, Conf-Reject (0x04), id 3, length 25
    13:50:21.090601 IP server > client: GREv1, call 1723, seq 3, length 54: LCP, Conf-Request (0x01), id 4, length 40
    13:50:21.173682 IP client > server: GREv1, call 1773, ack 3, no-payload, length 12
    13:50:21.176026 IP client > server: GREv1, call 1773, seq 5, length 39: LCP, Conf-Reject (0x04), id 4, length 25
    13:50:21.415783 IP client > server: GREv1, call 1773, seq 6, length 26: LCP, Conf-Request (0x01), id 1, length 12
    

    Содержимое reject

            LCP, Conf-Reject (0x04), id 10, length 25
            encoded length 23 (=Option(s) length 19)
            0x0000:  c021 040a 0017
              ACFC Option (0x08), length 2:
              PFC Option (0x07), length 2:
              MRRU Option (0x11), length 4: 2048
                0x0000:  0800
              12-Bit seq # Option (0x12), length 2:
              End-Disc Option (0x13), length 9: MAC f4:6d:04:00:00:00
                0x0000:  03f4 6d04 73ac e4
    

    После включения полного лога mpd (log +all) никаких следов ответного трафика так же нет.
    Пока нет оснований предполагать наличие каких-то проблем с туннелем, в тех же условиях работают довольно много сервисов. К тому же, в тех точках, где я могу осуществить контроль (tcpdump и ipfw count), трафик виден.
    Вовсе не считаю, что проблема именно в mpd, однако сути вопроса это не меняет - кто виноват и что делать?
    Подробности опустил, чтобы небыло много букв, однако могу их предоставить.

    PS. Только что провел эксперимент, снял криптографию с gif. Проблема воспроизводиться перестала!
    Единственное изменение - правка конфигов racoon и setkey и их перезапуск, то же с другой стороны, больше ничего не трогалось.
    Вернул криптографию - снова перестало работать.
    С одной стороны получается, что  все можно свалить на IPSEC, но с другой - причем тут именно gre? Поэтому, думаю, обсуждение проблемы в контексте mpd все же возможно.

    Спасибо!

     
  • Nick

    Nick - 2013-01-23

    Поискал PR на эту тему и нашел. Почему-то раньше не догадался этого сделать. Нашел похожий случай, PR от 2008 года, а быть может и от 2004, если kern/65616 отнести к этому же.
    http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/122065
    Там упоминается приватная переписка с Александром Мотиным, от которой осталась лишь пара строк. Сам он в обсуждении не участвовал. Проблема так и не решилась тогда.
    Я когда-то уже общался с Александром по почте, тоже на тему pptp. Не хочется отвлекать его личной перепиской, лучше решать такие проблемы на публичных ресурсах. До сих пор мучает совесть.
    Просим, как говорится. 5 (или 9) лет прошло, пора как-то это решать :-)

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

     
  • Dmitry S. Lukhtionov

    Попробуй посмотреть, что присходит в ноде ng_pptpgre. Для этого вставь ноду ng_tee перед ней и посмотри, что за трафик приходит на нее. А к ней приципи какую-нибудь ноду, с которой можешь посмотреть трафик на предмет контрольных сумм и т.п.
    Заодно посмотри статистику ноды ng_pptpgre. Возможно все пакеты тупо идут в drop

     
  • Nick

    Nick - 2013-01-24

    А Вы это с кем сейчас говорили? :-)
    Я внутрь netgraph никогда не лез. Когда-то что-то прочитал, что-то сделал и забыл.
    По последнему обзацу, это что-то типа этого? -

    # ngctl list
    There are 8 total nodes:
      Name: mpd4345-lso     Type: socket          ID: 000001c4   Num hooks: 1
      Name: mpd4345-cso     Type: socket          ID: 000001c5   Num hooks: 0
      Name: mpd4345-eso     Type: socket          ID: 000001c6   Num hooks: 0
      Name: mpd4345-stats   Type: socket          ID: 000001cd   Num hooks: 0
      Name: mpd4345-L100-1-lt Type: tee             ID: 000017f8   Num hooks: 2
      Name: <unnamed>       Type: pptpgre         ID: 000017fa   Num hooks: 2
      Name: <unnamed>       Type: ksocket         ID: 000017fb   Num hooks: 1
      Name: ngctl37563      Type: socket          ID: 000017fc   Num hooks: 0

    #ngctl msg mpd4345-L100-1-lt:left getstats
    Rec'd response "getstats" (3) from ":":
    Args:   { xmitPackets=10 xmitOctets=540 }

    Что касается первого, то даже не знаю с чего начать. Может можно об этом где-то прочитать, желательно в максимально совпадающем контексте? А еще лучше сразу подсказать по-подробнее :-)

     
  • Nick

    Nick - 2013-01-24

    "set iface enable tee" - это оно?
    Я включил, но никакого видимого результата не увидел.

     
  • Dmitry S. Lukhtionov

    Статистику сними не с ng_tee ноды, а с ng_pptpgre
    Это будет выглядеть так:
    #ngctl msg \: getstats

    ng_tee вручную поставь между разными нодами, и подключи к интерфейсу тип "ethernet". А с него уже с помощью tcpdump сможешь снять копию трафика.

     
  • Nick

    Nick - 2013-01-25

    Маны, к сожалению, настолько подробные, что нет слов. Я не знал как указать id в адресе, поэтому указал относительный.
    mpd4345-L100-1-lt:left - это насколько я понимаю и есть  \
    Оно собственно и пишет - "Rec'd response "getstats" (3) from ":"
    Т.е. по моему пониманию, я снял с нужной ноды.

    А про ng_tee вручную - можно примерчик?

     
  • Dmitry S. Lukhtionov

    А на остальных нодах?

    Путь пакета выглядит так: ng_ksocket -> ng_pptpgre-> ng_tee -> ng_ppp -> ng_tcpmss -> ng_iface

     
  • Nick

    Nick - 2013-01-28

    Если я правильно понял мысль (снять статистику со всех нод), то так:
    Такого длинного пути у меня нет, т.к. соединение не устанавливается. Все, что есть в момент коннекта - изображено выше в  ngctl list.
    Все, что я могу еще снять - это mpd4345-L100-1-lt, как в примере выше
    Args:   { left={ outOctets=420 outFrames=10 } left2right={ inOctets=420 inFrames=10 } }
    На остальных - ngctl: send msg: Function not implemented

     
  • Dmitry S. Lukhtionov

    Попробуй по очереди отключать multilink, компрессию заголовков.

     
  • Nick

    Nick - 2013-01-31

    Ну, это уже чистой воды шаманство. Трафик до mpd (ng_pptpgre?) не доходит, поэтому любые его настройки врядли могут повлиять.
    Тем не менее, нет, это не помогло.
    Несмотря на то, что в туннель трафик уходит нормально, обратной дороги нет. Возможно косяк где-то на стыке IPSEC и Netgraph. Я так полагаю, что если б вынести mpd на другую машину, то оно заработало бы.

    Я, кстати, только что нашел костыль как заставить это работать. Но он настолько не логичный, что я отказываюсь что-то понимать. Попробую понять принцип и напишу позднее.

     
  • Nick

    Nick - 2013-01-31

    Так, кажется понял. Суперкостыль на подпорках.
    В ipfw добавил правило вида
    ipfw add fwd 192.168.x.x gre from any to pptp_ip in via gif_N

    Как это работает: На выходе из gif пакет форвардится на 192.168.x.x. Тот, получив его, отправляет обратно (действует как маршрутизатор). Бинго!

    Нет, тут все логично. Просто изначально я несколько все не так понял, полагая что реально форварда не происходит.

    Вот в таком виде все работает.

     
  • Eugene Grosbein

    Eugene Grosbein - 2017-12-27

    Для истории: проблема, как и было отмечено выше, не имеет отношения к mpd. В реализации IPSEC ядра FreeBSD 9 был баг, связанный с декапсуляцией входящих пакетов GRE внутри IPSEC, из-за чего они не доставлялись как положено после расшифровки. Это исправлялось однострочным патчем, который нынче неактуален, так как реализация IPSEC нынче другая, но для архивов:

    --- sys/netipsec/xform_ipip.c.orig 2015-11-07 10:41:56.000000000 +0100
    +++ sys/netipsec/xform_ipip.c 2015-11-07 10:43:36.000000000 +0100
    @@ -655,6 +655,7 @@ ipe4_encapcheck(const struct mbuf m, in
    * also return a minimum priority when we want the packet
    * so any explicit gif tunnels take precedence.
    /
    + if(mtod(m, struct ip )->ip_p != IPPROTO_IPIP) return 0;
    return ((m->m_flags & M_IPSEC) != 0 ? 1 : 0);
    }
    #endif /
    INET */

     

Log in to post a comment.