ProtectHome супраць зерня TOTP: чаму ўваход у VPN не ўдаецца
Правільны код не дапаможа модулю PAM, які не можа адкрыць зерне. Выберыце паміж drop-in і запісваемым шляхам стану, затым праверце юніт.
Аўтэнтыфікатар паказвае свежы шасцізначны код, VPN яго адхіляе, а той самы код паспяхова правяраецца, калі вы тэстуеце з уласнай абалонкі. Гэтая розніца — уся гісторыя. Модуль PAM, які не можа адкрыць сакрэт рэгістрацыі, вяртае збой, што выглядае аднолькава з няправільным кодам, і асяроддзе службы, якое хавае хатнія каталогі, — частая прычына гэтага. Перш чым паслабляць любыя правы, вызначце, у якой з трох сітуацый вы знаходзіцеся.
Які з трох збояў гэта?
Першы — сакрэт, які модуль зусім не можа прачытаць. Другі — сакрэт, які ён можа прачытаць, але не можа абнавіць. Трэці — код, які сапраўды няправільны, звычайна праз дрыфт гадзінніка або паўторна выкарыстанае значэнне.
Адрозніце іх, прачытаўшы журнал службы і сістэмны журнал аўтэнтыфікацыі для адной няўдалай спробы, затым пацвердзіце, якую службу PAM загружае плагін і які радок модуля гэтая служба выкарыстоўвае. Агульнае паведамленне пра збой аўтэнтыфікацыі іх не адрознівае, як і паспяховы ручны тэст, бо ваша абалонка — не асяроддзе службы.
Прадстаўленне файлавай сістэмы ў юніце — звычайны віноўнік, калі збой адбываецца толькі ў службе.
systemctl show -p ProtectHome -p ProtectSystem -p ReadWritePaths [email protected]
ls -l /var/lib/vpn-otp/*/.google_authenticator 2>/dev/null | head -n 20Варыянт A: вынесці сакрэт з хатняга каталога
Калі служба хавае /home, а вы хочаце захаваць гэтую абарону, захоўвайце сакрэт там, дзе яна можа яго бачыць. Модуль прымае шлях secret= і ўліковы запіс user=, які выконвае аперацыі з файламі, што дазваляе цэнтральнаму сховішчу абслугоўваць шматлікія ідэнтычнасці.
Гэта ахайны варыянт, і менавіта ён патрабуе найбольшай увагі, бо супольнае сховішча робіць адзін каталог мяжой бяспекі для кожнага ўліковага запісу.
auth required pam_google_authenticator.so secret=/var/lib/vpn-otp/${USER}/.google_authenticator user=vpn-otpПраверце тры рэчы, перш чым давяраць гэтаму: уліковы запіс існуе, працоўны працэс модуля можа пераключыцца на яго, і файлы належаць яму з абмежавальнымі рэжымамі. Не выкарыстоўвайце ~ або шлях з хатняй зменнай разам з user= і не адключайце праверкі ўласнасці модуля, каб прымусіць шлях працаваць. Захавайце этап пароля і астатні стек цэлымі.
Варыянт B: пакінуць файл і адкрыць шлях
Калі сакрэт мусіць застацца ў хатнім каталозе карыстальніка, юніту патрэбна прадстаўленне, якое ўключае гэты адзін каталог, не адкрываючы ўсе хатнія каталогі на хосте. Drop-in можа дадаць вузка абмежаванае прывязванне пад ізаляваным хатнім каталогам.
Гэта захоўвае ўласнасць па кожным карыстальніку як мадэль, каштуючы змены юніта, якую трэба пераглядаць кожны раз, калі змяняецца пясочніца.
Дзве мяжы лёгка прапусціць. Шлях толькі для чытання, дададзены пад каталогам, які хавае пясочніца, не адкрывае яго, бо бацькоўскага каталога проста няма. І прывязванне павінна быць запісваемым, калі модуль мусіць абнаўляць стан, што ўводзіць у гульню наступны варыянт. Пішыце drop-in асобным файлам, а не рэдагуйце спакаваны юніт пад /usr/lib, каб абнаўленне пакета не скасавала яго моўчкі.
Варыянт C: пакінуць пясочніцу і выправіць запісы стану
Чытанне сакрэту — гэта толькі палова аўтэнтыфікацыі. Модуль можа перазапісваць звесткі пра зрух часу, абарону ад паўтору або лічыльнік, і файл, які праходзіць праверку чытання, усё яшчэ можа збаіць на запісе.
Гэты збой выглядае як дрэнны код пры наступнай спробе, а не пры гэтай, таму яго блытаюць з дрыфтам гадзінніка.
Дайце яму ўласны каталог для запісу і накіруйце шлях сакрэту туды, замест таго каб рабіць запісваемым увесь хатні каталог. Пацвердзіце ўладальніка каталога, свабоднае месца файлавай сістэмы і тое, ці юніт абмяжоўвае запісы ў іншых месцах. Затым праверце два паслядоўныя ўваходы, бо другі даказвае шлях запісу, а першы — толькі чытанне.
Правярайце як служба, а не як вы самі
Кожная важная праверка павінна выконвацца ўнутры пясочніцы юніта з ідэнтычнасцю юніта.
Каманда, якая паспяхова выконваецца ад root, кажа вам, што файл існуе, і больш нічога. Уваход праз сапраўдную службу кажа, ці можа модуль прачытаць сакрэт, выкарыстаць яго і запісаць назад тое, што яму патрэбна.
Нарэшце, захавайце патрабаванне цэлым. Даданне варыянту з пустым паролем, прыняцце збояў толькі для чытання або выдаленне пясочніцы — усё гэта прыбрала б сімптом шляхам змены палітыкі. Карыстальнік, які абавязаны прад'явіць код, павінен па-ранейшаму атрымліваць адмову, калі сакрэт недасяжны.