Три ствари одлучују који извор акредитива да користите: да ли особа седи за конзолом, да ли тајна може да живи на диску и да ли други процес треба да одговори на упит. Ако изаберете погрешно, клијент пријављује проблем са 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 сервере које је сервер послао. То је следећи проблем и нема никакве везе са лозинком коју сте управо исправили.

Повезани чланци