Русский
Русский
English
Статистика
Реклама

AD Freeradius Google Autheticator. Установка с нуля для Cisco Anyconnect и не только

Итак, у нас встала задача включить двухфакторную аутентификацию для Cisco AnyconnectVPN и некоторых других пакетов. Общими у всех задач есть одно они умеют аутентифицироваться в Radius.
Есть масса платных решений (например Cisco DUO ), но платное не значит лучше и зачем платить больше?

Да, критики скажут это очередная статья как натянуть сову на глобус или как подружить FreeRadius, MS Acitve Directory и Google Authenticator. Но есть нюансы, которые я хочу показать.

Во-первых. Мне нужно несколько типов аутентификации. Я это реализую нестандартными настройками FreeRadius и получу на трех разных портах одного сервера три типа аутентификации:
  1. ADlogin, ADPasswordGoogleAuth (логин из AD, паролем выступает склееная фраза из пароля в AD и цифр от GoogleAuth )
  2. ADlogin, ADPassword (стандартный вариант логина и пароля от AD, по сути чисто технический вариант, но нужен для Anyconnect)
  3. ADLogin, GoogleAuth ( логин из AD, пароль цифры GoogleAuth. Так сказать GoogleAuthenticator в чистом виде)

Во-вторых. Используя модуль shellinabox предоставляем возможность клиенту создать себе GoogleAuth токен самостоятельно, при этом не понижая уровня безопасности системы. Возможно не самое красивое решение но 100% работающее.

И в-третьих. Мне так и не удалось победить проблему: когда истекает время жизни пароля в AD, FreeRadius перестает считать его валидным и пробрасывает дальше ошибку. Т.е перестает предлагать сменить пароль в такой ситуации. Решение shellinabox позволяет решить эту проблему, предлагая пользователю в такой ситуации зайти на URL shellinabox.

Все проверено на Centos7 но без особых изменений зайдет на любом RedHat дистрибутиве и с непринципиальными модификациями на Ubuntu и FreeBSD. Другие дистрибуты не проверял, но общий смысл обязан сохранится.

1) Включаем NTP если не включено. Можно заменить любой аналогичной службой, важно чтоб время было синхронизировано корректно.

a) Установка
#yum install ntp


b) Включение на старте и сразу запуск
#systemctl enable now ntpd


c) Проверка
#ntpq p


2) Включаем Linux в AD. Я предпочитаю SSSD.

a) Установка
#yum install y sssd realmd oddjob oddjob-mkhomedir adcli samba-common samba-common-tools krb5-workstation openldap-clients policycoreutils-python

Здесь есть один момент. Возможно спецы меня поправят и часть пакетов лишняя именно для этой задачи, но я предпочитаю стантдартизацию и именно такой набор работает у меня везде.

b) собственно ввод в домен
#realm join pbu.icb --user=имя-пользователя-домена


c) проверка
#realm list


Должно вывести нечто подобное:
my.domen
type: kerberos
realm-name: MY.DOMEN
domain-name: my.domen
configured: kerberos-member
server-software: active-directory
client-software: sssd
required-package: oddjob
required-package: oddjob-mkhomedir
required-package: sssd
required-package: adcli
required-package: samba-common-tools
login-formats: %U
login-policy: allow-permitted-logins
permitted-logins:


d) редактируем /etc/sssd/sssd.conf для ограничения по AD группам, которым можно ходить на эту машину. Читай аутентифицироваться в AD с этой машины.
use_fully_qualified_names = False
simple_allow_groups = GroupLinuxAdmins@my.domen, GroupUseVPN@my.domen
ad_gpo_ignore_unreadable = True


первая группа GroupLinuxAdmins@my.domen, члены которой могут администрировать систему, вторая GroupUseVPN@my.domen это те кто потом будет ходить в VPN.

e) Запускаем sssd
#chown root.root /etc/sssd/sssd.conf&&chmod 600 /etc/sssd/sssd.conf#systemctl restart sssd

Убеждаемся что sssd работает корректно:
#id  имя-пользователя-домена

Должно вывести список групп AD в которые входит пользователь домена имя-пользователя-домена

f) Разрешаем админам sudo
#echo "%GroupLinuxAdmins@my.domen ALL=(ALL) ALL" > /etc/sudoers.d/sudoadmin#chown root.root /etc/sudoers.d/sudoadmin&&chmod 600 /etc/sudoers.d/sudoadmin


g) Выключаем root для ssh, разрешаем ssh только членам группы GroupLinuxAdmins@my.domen.
Редактируем /etc/ssh/sshd_config, изменив или добавив строки ниже. ВАЖНО! Тут и дальше имена групп нужно использовать только в нижнем регистре.

PermitRootLogin no
AllowGroups grouplinuxadmins


И перезапускаем sshd
#systemctl restart sshd


3) Установка FreeRadius
a) Собственно установка
#yum -y install freeradius freeradius-utils#ln -s /etc/raddb/mods-available/pam /etc/raddb/mods-enabled/pam


b) Редактируем /etc/raddb/sites-enabled/default:
Находим в разделе authenticate строку вида
# pam

и убираем комментарий в начале строки ( символ # )

с) Собственно базовый радиус установлен. Только для localhost но уже можем проверять.
Парольное слово в Radius для localhost по-умолчанию: testing123

# radtest userVPN password_for_userVPN localhost 0 testing123


Правильный ответ будет если в конце ответа
Received Access-Accept


При неправильном пароле (тоже стоит обязательно проверить ):
В конце ответа будет
Received Access-Reject
и дальше
(0) -: Expected Access-Accept got Access-Reject


d) Дабавляем систему, которой можно обращаться к Radius, т.е устройство, которой будет организовывать Cisco AnyconnectVPN. У меня это Cisco Firepower. Пусть у него будет IP 10.10.10.5.
Добавляем в файл /etc/raddb/clients.conf

client ftd {
ipaddr = 10.10.10.5
secret = secretFTD
}


И включаем радиус со стартом
#systemctl enable --now radiusd


e) Редактируем /etc/raddb/radiusd.conf. данная настройка нужна для того, чтобы Google Authenticator мог проверить файл $HOME/.google_authenticator для всех пользователей.
находим
user = radiusd
group = radiusd

и меняем на
user = root
group = root


f) Собственно базовый Radius установлен. Если при установке FreeRadius что-то идет не так, очень полезная возможность консольной работы с FreeRadius. Для этого стопаем службу и запускаем Radius в консольном режиме с debug
#systemctl stop radius#radiusd -Xx


4) Ставим Google Autenticator
a) К сожелению я не знаю как подружить Google Authenticator и selinux. Поэтому отключаем.
Файл /etc/selinux/config меняем:
SELINUX=enforcing

на
SELINUX=permissive

После чего
#setenforce 0

а лучше вообще перезагрузить машину

b)
#yum install y epel-release#yum install y google-authenticator


5) Модифицируем FreeRadius для 3 типов аутентификации
a) Редактируем /etc/raddb/mods-enabled/pam, добавляя строки
pam radius11812{
pam_auth = radiusd_ad
}

pam radius21812{
pam_auth = radiusd_ga
}


b) В папке /etc/pam.d копируем pam настройки для разных типов аутентификации
Для просто в AD берем системную
#ln s /etc/pam.d/password-auth-ac /etc/pam.d/radiusd_ad

Для просто GoogleAuth пишем самостоятельно в /etc/pam.d/radiusd_ga

#%PAM-1.0
#
auth required pam_google_authenticator.so nullok
auth required pam_permit.so
account required pam_nologin.so
account include password-auth
password include password-auth
session include password-auth


!!! очень важный момент. При такой конфигурации если отсутствует привязка пользователя в профиле к GoogleAuth то такой пользователь считается валидным. Если нужно без ввода цифр GoogleAuth не пускать вообще, не зависимо от привязки, то нужно в первой строке убрать nullok а вторую строку убрать вообще.

c) Копируем /etc/raddb/sites-enabled/default для двух дополнительных портов
# cp /etc/raddb/sites-enabled/default /etc/raddb/sites-enabled/radius11812# cp /etc/raddb/sites-enabled/default /etc/raddb/sites-enabled/radius21812


d) Редактируем /etc/raddb/sites-enabled/radius11812
Находим в разделе authenticate строку вида
pam

и заменяем на
Auth-Type pam {
radius11812
}


e) Аналогично /etc/raddb/sites-enabled/radius21812
Находим в разделе authenticate строку вида
pam

и заменяем на
Auth-Type pam {
Radius21812
}


6) Устанавливаем shellinabox
a)
#yum install y shellinabox#yum enable now shellinabox


b) В принципе этого достаточно. Но некоторые любят красоту ;). Тогда дополнительно ставим еще figlet, и шрифт rebel.tlf ( взять с репозитория https://github.com/xero/figlet-fonts и положить в /usr/share/figlet ).

c) Добавляем вызов логики генерации GoogleAuth токена для всех пользователей
#echo . /usr/local/etc/radius_user_profiles.sh >> /etc/skel/.bash_profile


d) Создаем /usr/local/etc/radius_user_profiles.sh ( это вариант с украшательствами )
#!/bin/bash# Set groups for vpn, etc. ##   !!! Names of groups without caps letters !!!#VPNissuer="MyCompany"GROUP_VPN="groupusevpn"# Get the aliases and functionsif [ -f ~/.bashrc ]; then        . ~/.bashrcfi# User specific environment and startup programs# Make several commands available from user shell# for group VPN that use 2FA Google authenticatorif [[ -n $(id $USER | grep $GROUP_VPN) ]]  then     clear    [[ ! -d $HOME/bin ]] && mkdir $HOME/bin    [[ ! -f $HOME/bin/id ]] && ln -s /usr/bin/id $HOME/bin/id    [[ ! -f $HOME/bin/google-auth ]] && ln -s /usr/bin/google-authenticator $HOME/bin/google-auth    [[ ! -f $HOME/bin/grep ]] && ln -s /usr/bin/grep $HOME/bin/grep    [[ ! -f $HOME/bin/figlet ]] && ln -s /usr/bin/figlet $HOME/bin/figlet    [[ ! -f $HOME/bin/rebel.tlf ]] && ln -s /usr/share/figlet/rebel.tlf $HOME/bin/rebel.tlf    [[ ! -f $HOME/bin/sleep ]] && ln -s /usr/bin/sleep $HOME/bin/sleep  # Set PATH env to <home user directory>/bin    PATH=$HOME/bin    export PATH    if [[ ! -e $HOME/.google_authenticator ]]      then        figlet -t -c -f $HOME/bin/rebel.tlf "Welcome to $VPNissuer GAuth setup portal"        sleep 1.5        echo "Please, run Google Autheticator to setup OTP and prepare to scan QR code.If you don't have, please download that from market:AppStore    - https://apps.apple.com/us/app/google-authenticator/id388497605Play Market - https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en"        sleep 1.5        google-auth -f -t -w 3 -r 3 -R 30 -d -e 1 -l "$VPNissuer" -i "$USER"        echo "Congratulations, now you can use an OTP token from application as a password to VPN."        logout    else        echo "You have already setup a Google Authenticator        "        logout    fifi

e) Устнавливаем разрешения на выполнение всем.
#chmod 755  /usr/local/etc/radius_user_profiles.sh


f) Можно файлы типа .google_authenticator вынести в отдельный каталог ( по-умолчанию это файлы $HOME/.google_authenticator). Увеличивает ли это безопасность системы? Нет, а удобство дело привычки. Для этого надо сделать несколько шагов:
  • в скрипте /usr/local/etc/radius_user_profiles.sh заменить строки
    if [[! -e $HOME/.google_authenticator ]]
    google-auth -f -t -w 3 -r 3 -R 30 -d -e 1 -l "$VPNissuer" -i "$USER"

    на
    if [[! -e /path_secrets/${USER} ]]
    google-auth -f -t -w 3 -r 3 -R 30 -d -e 1 -l "$VPNissuer" -i "$USER" --secret=/path_secrets/$USER
  • и в модулях PAM /etc/pam.d/radiusd и /etc/pam.d/radiusd_ga
    везде после pam_google_authenticator.so добавить параметр secret=/path_secrets/${USER}
    auth required pam_google_authenticator.so secret=/path_secrets/${USER} nullok
  • создать каталог
    #mkdir /path_secrets#chmod 777 /path_secrets
    

7) Теперь самое интересное. Shellinabox это по-сути графическая web оболочка для шелла. Для того чтоб не нарушить безопасность системы делаем отдельный sshd c ограничением по группе AD на нестандартном порту и направляем shelinabox на этот порт. Стандартный 22 остается для администраторов и снаружи недоступен.

a) Копируем systemd service скрипт и конфиг sshd:
#cp /usr/lib/systemd/system/sshd.service /usr/lib/systemd/system/sshd_web.service#cp /etc/ssh/sshd/sshd_config /etc/ssh/sshd_web_config


b) Редактируем /usr/lib/systemd/system/sshd_web.service заменяя строку
ExecStart=/usr/sbin/sshd -D $OPTIONS

на
ExecStart=/usr/sbin/sshd -D -f /etc/ssh/sshd_web_config $OPTIONS


c) Редактируем /etc/ssh/sshd_web_config добавляя или исправляя параметры:
port 2022
MaxAuthTries 3
MaxSessions 1
AllowGroups groupusevpn


Таким образом мы запускаем дополнительный шелл sshd на порту 2022 не открывая его на firewall т.к обращения к нему исключительно по интерфейсу local.

d) Редактируем /etc/sysconfig/shellinaboxd изменив параметр на
OPTS=" -s /:SSH:localhost:2022"


e) В папке /var/lib/shellinabox по умолчанию лежат самосгенеренные и самоподписанные сертификаты shellinabox. Лично у себя я установил дополнительно nginx в который внес реальные сертификаты ssl, вынеся shellinabox на порт 8443 ( любой нестандартный )

#yum install y nginx


Конфигурация для nginx:

server {
listen 443 ssl;
server_name shellinabox.my.domen;

add_header Strict-Transport-Security max-age=15768000; includeSubDomains always;

set $upstream localhost:8443;

proxy_intercept_errors on;
underscores_in_headers on;

location ~ ^/(.*) {
proxy_pass $upstream$request_uri;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/ privkey.pem;
ssl_protocols TLSv1.2;
ssl_dhparam /etc/ssl/ssl-dhparams.pem;
}

и в /etc/sysconfig/shellinaboxd меняем
PORT=8443


f) Перезапускаем после всех изменений.
#systemctl daemon-reload#systemctl enable now sshd_web#systemctl enable now shellinabox

Если ставили nginx то
#systemctl enable now nginx


g) Открываем порты firewalld
firewall-cmd --new-zone=radius permanentfirewall-cmd --zone=radius --add-source=10.10.10.5 --permanentfirewall-cmd --zone=radius --add-port=1812/udp --permanentfirewall-cmd --zone=radius --add-port=11812/udp --permanentfirewall-cmd --zone=radius --add-port=21812/udp --permanentfirewall-cmd --reload


8) Тестируем весь конструктор.
a) Заходим на shellinabox.my.domen
b) Логинимся пользователем VPN и получаем QR-код для GoogleAuth
c) Ставим на смартфон GoogleAuthenticator и сканим им QR-код.
d)
#radtest userVPN password_for_userVPNXXXXXX localhost 0 testing123

где XXXXXX цифры с GoogleAuthenticator. Результат должен быть Received Access-Accept
e)
#radtest userVPN password_for_userVPN localhost:11812 0 testing123

Результат должен быть Received Access-Accept
f)
#radtest userVPN XXXXXX localhost:21812 0 testing123 

где XXXXXX цифры с GoogleAuthenticator. Результат должен быть Received Access-Accept

9) Собственно VPN
a) Если все предидущие этапы прошли успешно то прописываем сервер типа Radius c IP и портом 11812/UDP как первый фактор в CISCO AnyconnectVPN и его же с портом 21812/UDP как второй фактор.





b) Деплоим конфигурацию и проверяем.

Как понятно из процесса тестирования, те системы, которые не умеют отдельно спрашивать первый и второй фактор ( или мы не хотим факторы разделять специально) мы направляем на порт Radius 1812 и используем схему пароль_ADXXXXXX добавляя цифры с Google Authenticator сразу после пароля без пробела.

Незакрытые вопросы:
  • Смена пароля при истечении времени жизни пароля через FreeRadius. Буду благодарен за советы.
  • SELINUX и GoogleAuthenticator.
  • Хотелось бы более красивого, аккуратного и, главное, более управляемого варианта генерации GoogleAuth токена, чем банальный шелл-скрипт.


PS. В статье использовались материалы http://personeltest.ru/aways/habr.com/ru/post/516362, откуда взята идея shellinabox
Источник: habr.com
К списку статей
Опубликовано: 24.02.2021 20:16:16
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Настройка linux

Информационная безопасность

Системное администрирование

Linux

Centos

Anyconnect

Freeradius

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru