Тры рэчы вызначаюць, якую крыніцу ўліковых даных выкарыстоўваць: ці сядзіць чалавек за кансоллю, ці можа сакрэт жыць на дыску і ці павінен іншы працэс адказваць на запыт. Калі выбраць няправільна, кліент паведаміць пра праблему stdin, а пароль будзе цалкам слушным, і гэта без падстаў адпраўляе большасць людзей на сервер. Спачатку выберыце шлях; паведамленні пра памылкі маюць сэнс толькі тады, калі вы ведаеце, які шлях іх спарадзіў.

Тры ўмовы, якія вызначаюць выбар

Запыт у кансолі - адзіны шлях, якому патрэбны чалавек, таму гэта адзіны шлях, які ціха ламаецца ў юніце systemd або ў кантэйнеры. Калі чалавек запускае кліент і ўводзіць пароль, файл не ўдзельнічае і нічога адчувальнага не трапляе на дыск. Калі кліент запускаецца пры загрузцы, гэты ж запыт ператвараецца ў завісанне, і тайм-аўт звычайна выглядае як агульная памылка злучэння, а не як памылка ўліковых даных.

Файл уліковых даных - правільны адказ, калі працэс запускаецца без нагляду і сакрэт можа заставацца на дыску пад кантраляваным наборам правоў. Калі сакрэт нельга запісваць зусім - палітыка толькі сховішча, кароткачасовы токен - патрэбны паток, які кліент можа адкрыць, а гэта на практыцы азначае падстаноўку працэсу або памочніка, які піша ў дэскрыптар файла. Інтэрфейс кіравання пакрывае чацвёрты выпадак: кантролер, які ўжо кіруе жыццёвым цыклам тунэля і можа адказваць на пытанні праз сокет.

  • Чалавек за кансоллю, без аўтаматызацыі: інтэрактыўны запыт.
  • Запуск без нагляду, сакрэт можна захоўваць: файл уліковых даных з рэжымам 0600.
  • Запуск без нагляду, сакрэт захоўваць нельга: падстаноўка працэсу або fd, у які піша агент сакрэтаў.
  • Кліентам валодае іншы працэс: інтэрфейс кіравання.

Калі падыходзяць два адказы, выбірайце той, што трымае сакрэт па-за argv і па-за гісторыяй shell. Пароль, перададзены як аргумент праграмы, можа прачытаць любы лакальны карыстальнік праз спіс працэсаў, і такую ўцечку цяжка адмяніць.

Што насамрэч робіць кожны шлях уводу

--auth-user-pass сам па сабе запытвае імя карыстальніка і пароль у кансолі. Калі даць імя файла, кліент бярэ першы радок як імя карыстальніка, а другі - як пароль; нічога не падтрымлівае лапкі, каментары або сінтаксіс ключ-значэнне. Гэта ўвесь фармат, таму любы, хто рэдагуе яго ў спадзеве на файл INI, яго ламае. Убудаваны блок <auth-user-pass> трымае тыя ж два радкі ўнутры профілю, што робіць сам профіль сакрэтам і ставіць яго ў той жа клас апрацоўкі, што і прыватны ключ.

Два іншыя шляхі - гэта паток і сокет. OpenVPN патрэбны толькі чытэльны дэскрыптар файла, таму ён прыме падстаноўку працэсу, запіс /dev/fd з падтрымкай канала або імя файла, якое насамрэч з'яўляецца FIFO. Інтэрфейс кіравання іншы па сваёй прыродзе: кліент пытае значэнні ў кіруючага працэсу, а не чытае іх сам. Гэтая розніца важная пры перападключэнні: файл уліковых даных, FIFO, у які памочнік сакрэтаў можа запісаць зноў, і інтэрфейс кіравання могуць падаць значэнні без чалавека; падстаноўка працэсу не можа, бо дэскрыптар спажываецца пры першым чытанні.

Файл павінен быць роўна два радкі

Два рэжымы збою ахопліваюць большасць зламаных файлаў уліковых даных. Рэдактар Windows пакідае канчаткі CRLF, вяртанне карэткі становіцца часткай пароля, і сервер адхіляе значэнне, якое на экране выглядае правільным. Пусты другі радок - пусты радок там, дзе павінен быць пароль - пакідае кліент з пустым паролем, які сервер адхіляе, нават калі значэнне на экране выглядае правільным. Зайвы новы радок пасля пароля не шкодзіць. Запісвайце файл з shell, а не з рэдактара, і праверце байты:

install -m 600 /dev/null /etc/openvpn/client.creds
printf '%s\n%s\n' "$VPN_USER" "$VPN_PASS" > /etc/openvpn/client.creds
od -c /etc/openvpn/client.creds | head -3

Шлях важны не менш за змест. Адносны шлях вылічваецца ад працоўнага каталога працэсу, а для службы гэта рэдка той каталог, дзе вы тэставалі. Выкарыстоўвайце абсалютны шлях, зрабіце файл уласнасцю ўліковага запісу, які запускае кліент, і трымайце рэжым 0600, каб група і астатнія не маглі яго чытаць. Дапаможнік OpenVPN 2.6 пералічвае дапушчальныя формы дырэктывы; праверце яго, перш чым вынаходзіць трэцюю.

Праверце файл, перш чым вінаваціць сервер. Запуск openvpn --config client.ovpn --auth-user-pass /etc/openvpn/client.creds --verb 4 друкуе, ці быў файл адкрыты і, пазней, ці былі ўліковыя даныя прыняты, што падказвае, які пласт змяняць далей.

Патокі, stdin і памылкі, якія яны спараджаюць

Перадача пароля праз канал - гэта першае, што спрабуе большасць, і шлях з найбольшай колькасцю сюрпрызаў. Падстаноўка працэсу працуе, бо кліенту патрэбны толькі чытэльны дэскрыптар: openvpn --config client.ovpn --verb 3 --auth-user-pass <(printf '%s\n%s\n' "$VPN_USER" "$VPN_PASS"). Перадача /dev/stdin працуе толькі тады, калі stdin яшчэ адкрыты і чытэльны ў момант, калі кліент запытвае, а ў канвееры, які ўжо яго спажыў, гэта не так.

ERROR: could not read Auth username from stdin мае дзве розныя прычыны. У некаторых кліентах 2.3.x паведамленне паходзіла ад дэфекту апрацоўкі stdin, які выправілі пазнейшыя выпускі 2.3, таму такі стары кліент паляпшаецца толькі абнаўленнем. У сучасным кліенце тое ж фармуляванне азначае, што кліент запытаў увод у кансолі, а stdin не быў тэрміналам - менавіта сітуацыя ў юніце systemd, задачы cron або кантэйнеры, запушчаным без -t.

auth-nocache дадае трэці цыкл, які выглядае як зламаны пароль. Ён скідае ўліковыя даныя з памяці пасля выкарыстання, таму перападключэнню, выкліканаму зменай сеткі, няма чаго прайграваць, і запыт вяртаецца. Гэта дырэктыва, якая працуе як задумана. auth-nocache змяняе тое, што кліент трымае ў памяці, а не тое, што сервер або пастаўшчык ідэнтычнасці думае пра ўліковы запіс, таму ўсё выпраўленне - гэта паўторна падаць той жа файл, перачытаны пры перазапуску, - і для кіруемага злучэння гэтая падача павінна ісці з зацверджанага сховішча сакрэтаў, а не з пароля ў скрыпце.

Інтэрфейс кіравання, калі запытам валодае іншы працэс

Кантролер, які ўжо наглядае за тунэлем, можа таксама адказваць на яго пытанні. Запусціце кліент з --management 127.0.0.1 7505, чытайце радкі стану і сачыце за >PASSWORD:Need 'Auth' username/password. Кантролер адказвае username "Auth" alice, за якім ідзе password "Auth" ..., у асобных радках каманд. Токен 'Auth' адлюстроўвае ідэнтыфікатар з запыту і павінен супадаць, інакш адказ ігнаруецца і кліент чакае.

Кошт - гэта машына станаў, якой вы цяпер валодаеце: парадак злучэнняў, перазапускі кліента і лакальны сокет, да якога іншыя карыстальнікі на хаце не павінны дабрацца. Што вы купляеце - гэта ўліковыя даныя, якія падаюцца ў час выканання, без файла на дыску і без запыту, які можа завіснуць. Калі нішто іншае ў вашым стэку ўжо не гаворыць на гэтым пратаколе, гэты шлях дадае кампанент, які трэба абслугоўваць.

Збоі, якія выглядаюць як праблемы з уліковымі данымі

Рукапаціск TLS, які ніколі не завяршаецца, або VERIFY ERROR: depth=0, error=certificate signature failure - гэта праблема даверу, і яна адбываецца раней, чым чытаецца любое імя карыстальніка. Кліент proto tcp, накіраваны на UDP-слухач, ламаецца ў тым жа месцы: пакеты ніколі не дасягаюць этапу аўтэнтыфікацыі, таму кожны пароль выглядае няправільным па асацыяцыі. Трымайце праверку сертыфіката ўключанай да адпраўкі ўліковых даных; знаёмы запыт нічога не кажа пра тое, хто атрымлівае пароль. Праверце ланцуг сертыфікатаў, агульнае імя і транспарт, перш чым кранаць уліковыя даныя.

Памылкі shell у скрыпце, які збірае профіль, - іншая ілжывая нітка. Прапушчаны прабел унутры [ ! -f "$file" ] спараджае command not found, скрыпт спыняецца рана, профіль ніколі не перабудоўваецца, і кліент запускаецца з папярэднім. Гэтая памылка належыць shell, а не аўтэнтыфікацыі, і колькі б вы ні перадрукоўвалі пароль, яна не знікне.

Не кожны запыт у гэтым потоцы - гэтыя ўліковыя даныя. Парольная фраза прыватнага ключа, уваход праз HTTP-проксі і пароль службы - гэта тры розныя сакрэты, якія запытваюцца на розных этапах, і парольную фразу ключа звычайна апрацоўвае кліент або агент, а не auth-user-pass. Калі запыт з'яўляецца да таго, як сеанс TLS усталяваны, вы адказваеце на няправільнае пытанне, і ніякі скід уліковага запісу не дапаможа. Пасля выключэння няправільнага запыту астатнія праверкі пачынаюцца з самага ранняга пласта:

  • Чытайце першую памылку пратакола, а не апошні радок уліковых даных: TLS, затым аўтэнтыфікацыя, затым push.
  • Упэўніцеся, што файл складаецца з двух радкоў, не мае вяртанняў карэткі і ўказваецца абсалютным шляхам.
  • Упэўніцеся, што профіль і камандны радок не разыходзяцца адносна дырэктывы.
  • Аддзяляйце "ўліковыя даныя прыняты" ад "трафік ідзе" - маршрутызацыя і DNS гэта пазнейшы пласт.

Калі кліент дасягае этапу push, перастаньце глядзець на ўліковыя даныя і пачніце чытаць маршруты і DNS-серверы, якія даслаў сервер. Гэта наступная праблема, і яна не мае нічога агульнага з паролем, які вы толькі што выправілі.

Падобныя артыкулы