5.03.1999, © Igor Sysoev, igor@nitek.ru

 

Модная аутентификация -- PAP и CHAP

 

До сих пор наш скрипт сам выполнял аутентификацию, то есть, вводил имя и пароль в ответ на запросы удалённой стороны. Но PPP предусматривает и свои способы аутентификации - PAP (Password Authentication Protocol) и CHAP (Challenge Handshake Authentication Protocol) и мы можем ими воспользоваться, если удалённая сторона достаточна сообразительна, чтобы не только выдать "login:", но и провести PAP или CHAP аутентификацию.

Нужно заметить, что комбинация FreeBSD + getty до недавнего времения не была таким сообразительным прибором, но, начиная с FreeBSD 2.2.7, getty распознает начальные LCP-кадры PPP-соединения и может вызывать, скажем, pppd, который и решает, что делать дальше. До этого getty умел только выдать этот самый "login:" и приходилось использовать mgetty.

Так как наш скрипт дозвонки больше не будет заниматся аутентификацией, нужно убрать из него имя пользователя "igor", его пароль "1234567" и ошибку аутентификации "Login incorrect":

                ABORT           "ERROR"                 \
                ABORT           "NO DIALTONE"           \
                TIMEOUT         5                       \
                ""              "AT"                    \
                "OK"            "ATZ"                   \
                "OK"            "ATS7=120"              \
                ABORT           "BUSY"                  \
                ABORT           "NO ANSWER"             \
                ABORT           "NO CARRIER"            \
                "OK"            "ATDP$1"                \
                TIMEOUT         125                     \
                "CONNECT"       "\\с"                   \
                TIMEOUT         30                      \
                "login:"        "\\с"

        if [ "$?" = "0" ]; then
                exit 0
        fi

Теперь скрипт заканчивает работу сразу же, как получит строку "login:". Отметим, что приглашние "login:" не имеет ни какого отношения к PAP и CHAP, и pppd воспринимает его не более как шум в линии, поэтому вместо этой строки может быть любое другое приглашение провайдера, в крайнем случае, "}".

PAP аутентификация происходит следующим образом - при установлении PPP-соединения удалённая сторона предлагает нам аутентификацию PAP. Мы соглашаемся и затем передаем наше имя и пароль открытом текстом. Если удалённую сторону имя и пароль устраивает, то аутентификация считается успешной. Имена и пароли для PAP хранятся в файле /etc/ppp/pap-secrets. У него должны быть такие правами доступа "rw- --- ---". Для нашего случая мы запишем в этот файл:

igor            cool            1234567

Формат этой строки таков - наше имя, имя удалённой стороны и пароль. В PAP используется только наше имя и пароль, а имя удалённой стороны "cool" может быть произвольным. В принципе, оно нужно только для того, что бы pppd мог определить, какой пароль нужно использовать в случае, когда Вы используете одно и тоже имя у разных провайдеров, например:

igor            cool            1234567
igor            citynet         7654321

Теперь мы можем звонить провайдеру:

pppd cuaa0 57600 lock connect '/etc/ppp/dial'           \
        user igor remotename cool                       \
        defaultroute noipdefault debug

Параметры user igor и remotename cool позволяют однозначно определить, какой пароль использовать при аутентификации, в данном случае это "1234567". Как уже говорилось, параметр remotename необходим только, если мы не можем однозначно выбрать пароль из файла /etc/ppp/pap-secrets. Имя нашей стороны можно также задать с помощью параметра name igor, но параметр user имеет больший приоритет. Заметим, что хотя пароль передается в открытом виде, удалённая сторона может хранить пароль в виде результата какой-либо хэш-функции, например, MD5, в качестве параметра которой, выступает пароль.

CHAP аутентификация происходит следующим образом - при установлении PPP-соединения удалённая сторона предлагает нам аутентификацию CHAP. Мы соглашаемся, и удалённая сторона высылает нам ключ (challenge), состоящий из случайной последовательности символов, и своё имя. Мы берем наш пароль и присланный ключ и прогоняем их через алгоритм MD5. Получившийся результат высылаем вместе со своим именем. Удалённая сторона, зная наш пароль и высланный её ключ, в свою очередь, проделывает тоже самое у себя, и если её результат совпадает с присланным нами, то аутентификация считается успешной. Таким образом, пароль не передается в открытом виде, но удалённая сторона должна хранить наш пароль в открытом виде.

Имена и пароли для CHAP хранятся в файле /etc/ppp/chap-secrets, права доступа у него должны быть такие же, как для PAP: "rw- --- ---", и формат строк тоже совпадает:

igor            cool            1234567

Теперь наша строка для звонка провайдеру выглядит так:

pppd cuaa0 57600 lock connect '/etc/ppp/dial'           \
        user igor                                       \
        defaultroute npipdefault debug

Обратите внимание, что она отличается от PAP только отсутствием параметра remotename. Это объяснятеся тем, что удалённая сторона сама говорит своё имя, поэтому её имя, записаное в файле /etc/ppp/chap-secrets, не может быть произвольным, как это было в случае с PAP. Даже если Вы зададите параметр remotename, имя, сообщённое удалённой стороной, имеет больший приоритет. Что касается имени нашей стороны, то оно может быть также задано с помощью параметра name igor.

Может ли pppd аутентифицировать себя в одних случаях через PAP, а в других - через CHAP ? Ответ - да. При запуске pppd проверяет, как он может аутентифицировать себя, исходя из локального имени и имени удалённой стороны, то есть, есть ли в файлах /etc/ppp/pap-secrets или /etc/ppp/chap-secrets строки с такими именами. И если, скажем, удалённая сторона предлагает CHAP, а pppd не находит пароль в файле /etc/ppp/chap-secrets, то он запросит PAP и если это устраивает удалённую сторону, то аутентификация пройдет по PAP.

Кроме того, можно указать pppd, чтобы он не соглашался проводить аутентификацию тем или иным способом или же требовал какого-то одного способа с помощью различных комбинаций параметров refuse-pap, refuse-chap, require-pap и require-chap. Раньше эти параметры назывались соответственно -pap, -chap, +pap и +chap.