VPN-сервер на Linux — решение проблемы с MPPE и клиентами, не поддерживающими шифрование данных

    Так уж исторически сложилось, что связка pptpd + pppd — довольно популярное решение для раздачи интернета в локальных сетях, во многом благодаря наличию клиента pptp в windows начиная с 98 «из коробки». Более того, этот клиент поддерживает протокол шифрования MPPE который начиная с windows 2000 включен для новых соединений по умолчанию.
    pppd радостно идет нам навстречу, также поддерживая этот протокол, но делает это весьма своеобразно:


    цитата из README.MPPE:

    if you turn it on, all other compression options are disabled and MPPE *must* be negotiated successfully in both directions (CCP is unidirectional) or the link will be disconnected. I think this is reasonable since, if you want encryption, you want encryption. That is, I am not convinced that optional encryption is useful

    На практике сие означает, что включив поддержку mppe (опциями +mppe или require-mppe) вы не сможете обслужить подключения клиентов, не поддерживающих этого протокола. Разработчики pppd считают это вполне себе правильным поведением, заявляя что «опциональное шифрование народу не нужно»

    Но что делать тем, у которого помимо виндовых клиентов есть еще и немало подключений дешевых аппаратных роутеров, которые попросту не поддерживают MPPE? Отключать шифрование для всех? Или убеждать клиентов что им нужен роутер в 5 раз дороже?

    Прежде чем ударяться в такие крайности, было принято решение починить эту «фичу» и за пару часиков вдумчивого изучения исходников pppd был рожден такой вот патч:
    (тестировался на ppp-2.4.4rel-10.1 из debian lenny)

    diff -ruNp ppp-2.4.4.orig/pppd/auth.c ppp-2.4.4/pppd/auth.c
    --- ppp-2.4.4.orig/pppd/auth.c 2006-06-18 14:26:00.000000000 +0300
    +++ ppp-2.4.4/pppd/auth.c 2008-02-13 18:24:08.000000000 +0200
    @@ -875,7 +875,7 @@ start_networks(unit)
    */
    ecp_required = ecp_gotoptions[unit].required;
    mppe_required = ccp_gotoptions[unit].mppe;
    - if (!ecp_required && !mppe_required)
    + if (!ecp_required && (!mppe_required || allow_mppe_fallback))
    continue_networks(unit);
    }
    diff -ruNp ppp-2.4.4.orig/pppd/ccp.c ppp-2.4.4/pppd/ccp.c
    --- ppp-2.4.4.orig/pppd/ccp.c 2005-07-09 03:23:05.000000000 +0300
    +++ ppp-2.4.4/pppd/ccp.c 2008-02-13 18:31:16.000000000 +0200
    @@ -156,6 +156,11 @@ static option_t ccp_option_list[] = {
    "allow MPPE stateful mode", OPT_PRIO },
    { "nomppe-stateful", o_bool, &refuse_mppe_stateful,
    "disallow MPPE stateful mode", OPT_PRIO | 1 },
    +
    + /* allow falling back to unencrypted connection mode */
    + { "mppe-optional", o_bool, &allow_mppe_fallback,
    + "allow falling back to unencryped connection mode", OPT_PRIO | 1 },
    +
    #endif /* MPPE */
    { NULL }
    @@ -516,9 +521,14 @@ ccp_protrej(unit)
    #ifdef MPPE
    if (ccp_gotoptions[unit].mppe) {
    - error("MPPE required but peer negotiation failed");
    - lcp_close(unit, "MPPE required but peer negotiation failed");
    - }
    + if(!allow_mppe_fallback) {
    + error("MPPE required but peer negotiation failed");
    + lcp_close(unit, "MPPE required but peer negotiation failed");
    + } else {
    + error("MPPE required but peer negotiation failed.");
    + error("Falling back and disabling MPPE");
    + }
    + }
    #endif
    }
    @@ -1004,11 +1014,17 @@ ccp_rejci(f, p, len)
    #ifdef MPPE
    if (go->mppe && len >= CILEN_MPPE
    && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
    - error("MPPE required but peer refused");
    - lcp_close(f->unit, "MPPE required but peer refused");
    - p += CILEN_MPPE;
    - len -= CILEN_MPPE;
    + if(!allow_mppe_fallback) {
    + error("MPPE required but peer refused. Closing LCP");
    + lcp_close(f->unit, "MPPE required but peer refused");
    + } else {
    + try.mppe = 0;
    + error("MPPE required but peer refused.");
    + error("Falling back and disabling MPPE");
    + }
    }
    + p += CILEN_MPPE;
    + len -= CILEN_MPPE;
    #endif
    if (go->deflate_correct && len >= CILEN_DEFLATE
    && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
    diff -ruNp ppp-2.4.4.orig/pppd/ccp.h ppp-2.4.4/pppd/ccp.h
    --- ppp-2.4.4.orig/pppd/ccp.h 2004-11-04 12:02:26.000000000 +0200
    +++ ppp-2.4.4/pppd/ccp.h 2008-02-13 19:03:43.000000000 +0200
    @@ -43,6 +43,8 @@ typedef struct ccp_options {
    short method; /* code for chosen compression method */
    } ccp_options;
    +bool allow_mppe_fallback;
    +
    extern fsm ccp_fsm[];
    extern ccp_options ccp_wantoptions[];
    extern ccp_options ccp_gotoptions[];
    @@ -50,3 +52,5 @@ extern ccp_options ccp_allowoptions[];
    extern ccp_options ccp_hisoptions[];
    extern struct protent ccp_protent;
    +
    +
    diff -ruNp ppp-2.4.4.orig/pppd/pppd.8 ppp-2.4.4/pppd/pppd.8
    --- ppp-2.4.4.orig/pppd/pppd.8 2006-06-16 03:01:23.000000000 +0300
    +++ ppp-2.4.4/pppd/pppd.8 2008-02-13 18:41:31.000000000 +0200
    @@ -770,6 +770,9 @@ available under Linux.
    .B nomppe
    Disables MPPE (Microsoft Point to Point Encryption). This is the default.
    .TP
    +.B mppe-optional
    +Makes MPPE optional, allowing both MPPE and non-MPPE clients
    +.TP
    .B nomppe\-40
    Disable 40-bit encryption with MPPE.
    .TP


    После наложения и пересборки — в конфиге pppd пишем

    require-mppe
    mppe-optional

    и наблюдаем нормальную работу vpn как с включенным шифрованием на стороне клиента, так и без.

    уже собранные пакеты для debian lenny (возможно, подойдут и для ubuntu) могу выложить по запросу
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

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

      +3
      Чтоб не потерялось это, прошу выслать его разрабам, думаю многие поддержат :) ну или хотя бы выложить на какой-нить лаунчпад/сурсфорж, куда-нибудь еще, крмое хабра
        +1
        Отписал в https://bugs.launchpad.net/ubuntu/+source/ppp/+bug/88986 — баг открыт с 2007-03-01

        правда, несколько смущает

        cygnus wrote on 2008-11-06
        … I tried to contact the Original Author, but didn't receive any answers.

        но все равно попробую c ним связаться, если не получится — обращусь к маинтейнеру пакета в debian
          0
          Переносине в блог про Linux. вот сюда. Может кто заитересуется и поможет вам связаться.
            +1
            Еще бы это щастье включили в исходники pppd — цены бы не было.
              +1
              все уже изобретено до нас mppe-mppc.alphacron.de/
                0
                Вот так лучше mppe-mppc.alphacron.de
                  0
                  Это решение рассматривалось. Насторожило, что последний патч — к ядру 2.6.13, последняя запись в changelog датирована 2005-02-02. Похоже, пациент скорее мертв чем жив.
                  0
                  Патчить ядро надо было чтобы получить поддержку mppe/mppc, современные ядра включают поддержку mppe «из коробки». Можно использовать только патч pppd, он с небольшими изменениями накладывается на pppd 2.4.4. У меня именно так все и работает.
                    0
                    Хм, вы молодец, проделали работу, разобрались :) Но я склонен согласится с мнением что опциональное шифрование действительно не очень нужно: если это корпоративная сеть — шифрование обязательно, дешевые маршрутизаторы без поддержки MPPE — в топку; если это доступ в интернет (мини-ISP) — шифрование не нужно совсем, если не противопоказано (расходовать ресурсы концентратора и клиента на обогрев помещения?)

                    Сам пользую в обоих вариантах, но без опциональности :)
                      0
                      > если это доступ в интернет (мини-ISP) — шифрование не нужно совсем

                      ровно до того момента, пока какой-то умник не начнет баловаться с arp-spoofing, а прецеденты уже были.

                      вводить обязательное шифрование и терять из-за этого клиентов с дешевыми роутерами тоже не всем хочется — проще предупредить что вот мол ваш роутер дешевый и убогий, если нужна безопасность — покупайте cisco или ставьте *nix тазик
                        0
                        Видно, вы в теме глубже :)
                        Но вы же не гарантируете польвователю конфиденциальность данных передаваемых через Интернет. А каким образом с помощью arp-spoofing'а можна увести логины-пароли от самого VPN-акаунта, точнее чем MPPE может помочь?
                          +1
                          если используется mschap-v2, то только атакой перехваченного хеша по словарю.
                          но ведь есть еще и почта, аська, фтп и прочие сервисы, в которых пароль летает в открытом виде. Мы, конечно, не гарантируем конфиденциальности, но если есть техническая возможность обезопасить клиента от детей, просмотревших видео «как юзать Cain&Abel» — думаю, грех ею не воспользоваться.
                            0
                            Убедили :) Если есть возможность, то можна и обезопасить. «Знають у садочку малі діти, що краще перебдіть, ніж недобдіти» :)

                            офф-топ (но близко): Если вы используете PPTP-концентратор на базе Linux, не могли бы рассказать как у вас организована «раздача шейперов», тоесть автоматичесая установка ограничений скорости?
                              +1
                              в двух словах — pppd плагины radius.so и radattr.so. Радиус общается с биллингом и отдает pppd соответствующие атрибуты. в /etc/ppp/ip-up.d лежит скрипт который парсит /var/run/radattr.pppX и уже исходя из этого манипулирует tc/iptables. Ну и в ip-down.d — аналогичный который подметает правила при падении интерфейса. Все остальное уже зависит от этого скрипта.
                                0
                                Спасибо, идея понятна. Интересовался не из простого любопытства, но и не для конкретного решения. Пока у наших клиентов хватает денег на NAS-ы от Cisco, но не исключено что в связи с кризисом, прийдется строить более дешевые решения на Linux.
                                  +1
                                  когда денег появиться побольше, у вас не будет больших проблем с миграцией на cisco при использовании этой схемы. всего-лишь придется отдавать NAS-у более другие radius-атрибуты для установки скорости
                                    0
                                    Нам (разработчикам и сопровождающим билинговой системы) действительно практически всеравно :) RADIUS есть везде. У клиента сейчас Cisco, а дальше будет видно, будет финансирование — мигрируем на Cisco ISG, не будет финансирования — построим на Linux :)
                      0
                      Отличная статья. А можно куда-нибудь выложить уже собранный пакет для lenny? А то я смотрю так никто и не попросил.
                        0
                        Ребята, а как сейчас обстоят дела с поддержкой mppe, mppc в pppd и ядре? Нативно все включено или по прежнему нужно патчить/компилить??

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

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