Недавно бродил по настройкам учётной записи Google и мне попался Gmail Security Checklist, дающий пошаговые рекомендации в пяти частях по улучшению безопасности. Многие очевидны, например, проверка на вирусы, но в части "Your Google Account" я обнаружил очень полезные рекомендации:

01 2fa

А именно двухэтапную аутентификацию и вход с помощью паролей приложений.

Это то, чего мне сильно не хватало. Задумайтесь на секунду, что вы потеряете с утерей учётной записи Gmail. И подумайте, сколько раз и в каких приложениях вы выдавали свои имя пользователя и пароль. Вероятнось компрометации увеличивается со временем использования.

А вот если включить двухэтапную аутентификацию, то кроме пароля будет запрошен краткосрочный код подтверждения, который генерируется, например, приложением Google Authenticator под iPhone, Android, Blackberry или получается по SMS, а если такой возможности временно нет, то есть несколько резервных кодов.

Пароли же приложений можно сгенерировать уникальные для каждого приложения, использующего учётную запись Google и для каждого устройства. Появилось подозрение о компрометации - сделал отзыв пароля. Всё просто и безопасно. Рекомендую.

Кстати, приложение Google Authenticator под iPhone в отличие от конкурентов выглядит нормально, а не как поделка шестиклассника.

02 2fa

Я пользуюсь этими функциями уже месяца два и очень доволен. И вот пару дней назад у меня возникла простая мысль - а можно ли настроить двухэтапную аутентификацию для доступа к серверам по ssh?

После краткого изучения вопроса я нашёл статью "Two-factor SSH authentication via Google secures Linux logins". Там описывается Fedora Linux, но инструкция легко адаптируется к той же Ubuntu 11.04, которую использую я.

Процесс таков:

$ sudo apt-get install subversion
$ sudo yum install libpam-dev
$ mkdir -p ~/tmp
$ cd ~/tmp
$ hg clone https://google-authenticator.googlecode.com/hg/ google-authenticator/
$ cd google-authenticator/libpam/

Компилирую с дополнительным флагом LDFLAGS, потому что иначе была бы ошибка "undefined reference to `dlopen'":

$ LDFLAGS=-ldl make
$ sudo make install
$ sudo cp pam_google_authenticator.so /lib64/security
$ sudo cp google-authenticator /usr/local/bin

Редактирую конфигурацию PAM для sshd:

$ sudo vim /etc/pam.d/sshd

После строки

auth       required     pam_env.so envfile=/etc/default/locale

добавляю

auth       required     pam_google_authenticator.so

На сервере обязательно должен работать NTP, одноразовые коды генерируются синхронно.

Генерирую коды, текст сохраняю на память, там будут резервные коды на случай недоступности Google и URL с QR-кодом для настройки Google Authenticator

$ google-authenticator

Открываю выданный URL, сканирую QR-код в приложении Google Authenticator.

Правлю конфигурацию sshd, включая параметры ChallengeResponseAuthentication и UsePAM:

$ sudo vim /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
UsePAM yes

Рестарт sshd:

$ sudo service ssh restart

Проверяю работу:

$ ssh ctrld@server
Verification code:
Password:
Welcome to Ubuntu 11.04 (GNU/Linux 2.6.38-10-generic x86_64)

Если неправильно ввести пароль, то доступа не будет:

$ ssh ctrld@udev
Verification code:
Password:
Verification code:
Password:
Verification code:

Одна особенность, решение которой я не искал - если других пользователей не настроена двухэтапная аутентификация, то их в систему по паролю не пустит:

sshd[7188]: error: PAM: Cannot make/remove an entry for the specified session for ctrld1 from 192.168.98.9
sshd(pam_google_authenticator)[7192]: Failed to read "/home/ctrld1/.google_authenticator"

Если настроена авторизация по публичному ключу, то двухэтапная аутентификация не производится.

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

Спасибо Google.