OpenVPN auth-user-pass: ფაილი, stdin თუ მოთხოვნა? როგორ ავირჩიოთ
აირჩიეთ კონსოლის მოთხოვნას, სერტიფიკატების ფაილს, ნაკადსა და მართვის ინტერფეისს შორის, შემდეგ გაასწორეთ შეცდომები, რომლებიც მხოლოდ არასწორ პაროლს ჰგავს.
რომელი სერტიფიკატების წყარო გამოიყენოთ, სამი რამ წყვეტს: ზის თუ არა ადამიანი კონსოლთან, შეიძლება თუ არა საიდუმლო დისკზე ცხოვრება და უნდა უპასუხოს თუ არა სხვა პროცესმა მოთხოვნას. არასწორი არჩევანისას კლიენტი stdin-ის პრობლემას იტყობინება, მაშინ როცა პაროლი სრულიად ვალიდურია, და ეს უმიზეზოდ აგზავნის უმეტესობას სერვერთან. ჯერ გზა აირჩიეთ; შეცდომის შეტყობინებებს აზრი მხოლოდ მაშინ აქვს, როცა იცით, რომელმა გზამ შექმნა ისინი.
სამი პირობა, რომელიც ამას წყვეტს
კონსოლის მოთხოვნა ერთადერთი გზაა, რომელსაც ადამიანი სჭირდება, ამიტომ ეს არის ერთადერთი, რომელიც ჩუმად ფეილდება systemd ერთეულში ან კონტეინერში. თუ ადამიანი კლიენტს უშვებს და პაროლს აკრეფს, არცერთი ფაილი არ მონაწილეობს და არაფერი მგრძნობიარე არ ხვდება დისკზე. თუ კლიენტი ჩატვირთვისას იშვება, იგივე მოთხოვნა ჩამოკიდებად იქცევა, და დროის ამოწურვა ჩვეულებრივ ზოგადი კავშირის ჩავარდნად ჩნდება და არა სერტიფიკატების შეცდომად.
სერტიფიკატების ფაილი სწორი პასუხია, როცა პროცესი ზედამხედველობის გარეშე იშვება და საიდუმლო შეიძლება გადარჩეს დისკზე კონტროლირებული ნებართვების ნაკრების ქვეშ. როცა საიდუმლოს საერთოდ არ უნდა ჩაწერა - მხოლოდ საცავის პოლიტიკა, ხანმოკლე ტოკენი - გჭირდებათ ნაკადი, რომლის გახსნაც კლიენტს შეუძლია, რაც პრაქტიკაში პროცესის ჩანაცვლებას ან ფაილის დესკრიპტორში მწერლობის დამხმარეს ნიშნავს. მართვის ინტერფეისი მეოთხე შემთხვევას ფარავს: კონტროლერი, რომელიც უკვე მართავს გვირაბის სასიცოცხლო ციკლს და socket-ის მეშვეობით პასუხის გაცემა შეუძლია.
- ადამიანი კონსოლთან, ავტომატიზაციის გარეშე: ინტერაქტიული მოთხოვნა.
- ჩატვირთვა ზედამხედველობის გარეშე, საიდუმლოს შენახვა შეიძლება: სერტიფიკატების ფაილი 0600 რეჟიმით.
- ჩატვირთვა ზედამხედველობის გარეშე, საიდუმლოს შენახვა არ შეიძლება: პროცესის ჩანაცვლება ან fd, რომელშიც საიდუმლოების აგენტი წერს.
- კლიენტს სხვა პროცესი ფლობს: მართვის ინტერფეისი.
როცა ორი პასუხი ერგება, აირჩიეთ ის, რომელიც საიდუმლოს argv-ისა და shell-ის ისტორიის გარეთ ინახავს. პროგრამის არგუმენტად გადაცემული პაროლი ნებისმიერ ლოკალურ მომხმარებელს შეუძლია წაიკითხოს პროცესების სიით, და ამ გამჟღავნების გაუქმება ძნელია.
რას აკეთებს სინამდვილეში თითოეული შემავალი გზა
--auth-user-pass თავისთავად კონსოლზე მომხმარებლის სახელსა და პაროლს ითხოვს. ფაილის სახელის მიცემისას კლიენტი პირველ სტრიქონს მომხმარებლის სახელად იღებს, მეორეს კი პაროლად; არაფერი უჭერს მხარს ბრჭყალებს, კომენტარებს ან გასაღები-მნიშვნელობის სინტაქსს. ეს არის მთელი ფორმატი, ამიტომ ვინც INI ფაილის იმედით რედაქტირებს, ის ამტვრევს. ჩაშენებული <auth-user-pass> ბლოკი იმავე ორ სტრიქონს ინახავს პროფილში, რაც თავად პროფილს საიდუმლოდ აქცევს და კერძო გასაღების იგივე დამუშავების კლასში ათავსებს.
დარჩენილი ორი გზა ნაკადი და socket-ია. 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' ტოკენი იმეორებს მოთხოვნის იდენტიფიკატორს და უნდა დაემთხვეს, თორემ პასუხი იგნორირდება და კლიენტი ელოდება.
ფასი არის მდგომარეობის მანქანა, რომელიც ახლა თქვენ გაქვთ: კავშირების რიგი, კლიენტის გადატვირთვები და ლოკალური socket, რომელზეც ჰოსტის სხვა მომხმარებლები არ უნდა მივიდნენ. რასაც ყიდულობთ, არის გაშვების დროს მიწოდებული სერტიფიკატი, დისკზე ფაილის გარეშე და ჩამოკიდებადი მოთხოვნის გარეშე. თუ თქვენს სტეკში სხვა არაფერი ლაპარაკობს ამ პროტოკოლზე, ეს გზა ამატებს მოსავლელ კომპონენტს.
სერტიფიკატების პრობლემას რომ ჰგავს, ისეთი ჩავარდნები
TLS ხელის ჩამორთმევა, რომელიც არასდროს სრულდება, ან VERIFY ERROR: depth=0, error=certificate signature failure, ნდობის პრობლემაა და ხდება მანამ, სანამ რომელიმე მომხმარებლის სახელი წაიკითხება. UDP მსმენელზე მიმართული proto tcp კლიენტი იმავე ადგილას ფეილდება: პაკეტები არასდროს აღწევს აუთენტიფიკაციის ფაზას, ამიტომ ყოველი პაროლი ასოციაციით არასწორად გამოიყურება. სერტიფიკატის შემოწმება ჩართული დატოვეთ სანამ სერტიფიკატი გაიგზავნება; ნაცნობი მოთხოვნა არაფერს ამბობს იმაზე, თუ ვინ იღებს პაროლს. შეამოწმეთ სერტიფიკატების ჯაჭვი, საერთო სახელი და ტრანსპორტი სანამ სერტიფიკატს შეეხებით.
პროფილის ამწყობ სკრიპტში shell-ის შეცდომები მეორე ცრუ კვალია. [ ! -f "$file" ]-ის შიგნით დაკარგული სივრცე წარმოქმნის command not found-ს, სკრიპტი ადრე ჩერდება, პროფილი არასდროს აღდგება და კლიენტი წინათი პროფილით იშვება. ეს შეცდომა shell-ს ეკუთვნის და არა აუთენტიფიკაციას, და პაროლის რამდენჯერმე გადაკრეფა მას არ წაშლის.
ამ ნაკადში ყოველი მოთხოვნა არ არის ეს სერტიფიკატი. კერძო გასაღების პაროლფრაზა, HTTP პროქსიში შესვლა და სერვისის პაროლი სამი განსხვავებული საიდუმლოა, რომლებიც სხვადასხვა ფაზაში ითხოვება, და გასაღების პაროლფრაზას ჩვეულებრივ კლიენტი ან აგენტი მართავს და არა auth-user-pass. თუ მოთხოვნა ჩნდება მანამ, სანამ TLS სესია დადგება, თქვენ არასწორ კითხვას პასუხობთ და ანგარიშის აღდგენა არ დაეხმარება. არასწორი მოთხოვნის გამორიცხვის შემდეგ დარჩენილი შემოწმებები ყველაზე ადრეული ფენიდან იწყება:
- წაიკითხეთ პირველი პროტოკოლის შეცდომა და არა ბოლო სერტიფიკატის სტრიქონი: TLS, შემდეგ აუთენტიფიკაცია, შემდეგ push.
- დაადასტურეთ, რომ ფაილი ორი სტრიქონია, ვაგონის დაბრუნებები არ აქვს და აბსოლუტური გზით არის მითითებული.
- დაადასტურეთ, რომ პროფილი და ბრძანების სტრიქონი დირექტივის თაობაზე არ ეწინააღმდეგებიან ერთმანეთს.
- "სერტიფიკატები მიღებულია" გამოყავით "ტრაფიკი მიემართება"-სგან - მარშრუტიზაცია და DNS შემდგომი ფენაა.
როცა კლიენტი push ფაზას მიაღწევს, შეწყვიტეთ სერტიფიკატებზე ყურება და დაიწყეთ სერვერის მიერ გაგზავნილი მარშრუტებისა და DNS სერვერების კითხვა. ეს შემდეგი პრობლემაა და არაფერი აქვს საერთო იმ პაროლთან, რომელიც ახლახან გაასწორეთ.