სკრიპტი, რომელიც OpenVPN-ს უშვებს და არასოდეს უკავშირდება, ჩვეულებრივ ქსელის პრობლემა არ არის: კლიენტი ზის მოთხოვნასთან ტერმინალის გარეშე, რომ მისი დახატვა შეძლოს. OpenVPN-ს აქვს ზუსტად ორი მხარდაჭერილი გზა ამ მოთხოვნაზე ადამიანის გარეშე პასუხის გასაცემად: სერტიფიკატის ფაილი auth-user-pass-ის უკან და მართვის socket, და ისინი ურთიერთშემცვლელი არ არის. ფაილი ერთი დირექტივა ღირს და ერთ მოთხოვნას პასუხობს; socket პასუხობს ყველა მოთხოვნას და ყველაფერს, რაც loopback პორტს გახსნის, აუთენტიფიკაციულ საკონტროლო არხს აძლევს. რომელი ეკუთვნის თქვენს განლაგებას, დამოკიდებულია იმაზე, რომელი მოთხოვნა ბლოკავს სინამდვილეში და რომელი საიდუმლოს დატოვება შეგიძლიათ მშვიდად.

დაასახელეთ მოთხოვნა მექანიზმის არჩევამდე

ოთხი მოთხოვნა ტერმინალზე ერთნაირად გამოიყურება. ანგარიშის წყვილი მოდის სერვერის PAM ან auth-user-pass-verify პარამეტრიდან და მას auth-user-pass პასუხობს. პირადი გასაღების პაროლფრაზა გასაღების ფაილს ეკუთვნის და იკითხება --askpass-ით ან ხელით იბეჭდება. PKCS#12 პაკეტი საკუთარ პაროლს ითხოვს. პროქსის აუთენტიფიკაცია იყენებს auth ფაილს, რომელსაც --http-proxy იღებს, და არა ანგარიშის მონაცემებს.

როცა OpenVPN მუშაობს როგორც systemd-ის, PHP-ის ან Node-ის შვილი, ტერმინალი არ არის, ამიტომ რომელიმე მათგანი ჩუმად ბლოკავს. პროცესი იქ ზის, ჟურნალი შიფრის ხაზის შემდეგ ჩერდება და ერთეული საბოლოოდ ვადას გადის; ეს სიჩუმეა მიზეზი, რატომაც ხალხი ამატებს განმეორების ციკლს ან sleep-ს იმის ნახვის ნაცვლად, თუ რომელი მოთხოვნაა მოლოდინში. მხოლოდ მართვის socket-ს შეუძლია ოთხივეს პასუხი. სერტიფიკატის ფაილი პასუხობს პირველს და სხვა არაფერს.

auth-user-pass: ერთი ფაილი, ერთი მოთხოვნა

ფაილი შეიცავს მომხმარებლის სახელს პირველ ხაზზე და პაროლს მეორეზე, და სხვა არაფერს: ბრჭყალების გარეშე, გასაღების სახელების გარეშე, კომენტარის გარეშე. დააყენეთ რეჟიმი 600 და მფლობელად აქციეთ ის ანგარიში, რომელიც openvpn-ს უშვებს, რაც სერვისისთვის ხშირად თქვენი შესვლა კი არა, ცალკე მომხმარებელია. /root-ის ქვეშ root-ის საკუთრებაში არსებული ფაილი განსხვავებაა თქვენს shell-ში მომუშავე ბრძანებასა და ჩატვირთვისას წარუმატებელ ერთეულს შორის.

ორი დეტალი აქცევს სწორ ფაილს მოთხოვნად. CRLF-ის შემნახველი რედაქტორი პაროლზე მიკრულ კარეტის დაბრუნებას ტოვებს, ამიტომ სერვერი უარყოფს პაროლს, რომელიც ფაილში სწორად გამოიყურება; შეამოწმეთ cat -A-ით ან od -c-ით და არა თვალით. ხოლო პროფილის შიგნით არგუმენტის გარეშე auth-user-pass ნიშნავს «ჰკითხე მომხმარებელს» დიზაინით, რასაც ბრძანების ხაზზე მეორე დირექტივა შეიძლება ვერ გააუქმოს, რადგან პროფილი იქ ირჩევა, სადაც დგას.

ოპციების თანმიმდევრობა მესამე ხაფანგია და ვერსიაზეა დამოკიდებული. OpenVPN 2.4-ის ზოგიერთი აშენება უგულებელყოფს --auth-user-pass-ს, როცა ის --config-ამდე მოდის, ამიტომ იგივე ორი ოპცია საპირისპირო რიგში უკავშირდება. დირექტივა ჩადეთ პროფილში ან ბრძანების ხაზზე --config-ის შემდეგ, და სხვა რამის შეცვლამდე grep-ით მოძებნეთ პროფილში ყველა შემთხვევა.

auth-nocache ამ მექანიზმს ეკუთვნის, მაგრამ არაფერს იძლევა. ის ზღუდავს, რამდენ ხანს ინახავს კლიენტი სერტიფიკატს მეხსიერებაში, რაც ეხმარება ავარიის შემდეგ და საერთოდ არ ეხმარება, როცა ფაილი აკლია. სერვერის მხრიდან სესიის ვადის გასვლის შემდეგ ხელახალი დაკავშირება ფაილს ხელახლა კითხულობს, ამიტომ ჩატვირთვისას მომუშავე სერტიფიკატი მაინც შეიძლება დღის შუაში ამოიწუროს.

მართვის socket: ყველა მოთხოვნა, მეტი ზედაპირი

გაუშვით კლიენტი მსმენელით და ცხადად განაცხადეთ, რომ მოთხოვნები მასზე შეატყობინება, OpenVPN 2.6-ის სახელმძღვანელოში დოკუმენტირებული დირექტივებით:

management 127.0.0.1 3030
management-query-passwords

bash-იდან დაიჭირეთ კავშირი თავისუფალ ფაილის აღწერილობაზე და უპასუხეთ მოთხოვნის სახელით და არა პოზიციით, რადგან ხელახალი დაკავშირება სხვა რიგში შეიძლება იკითხოს:

exec 3<>/dev/tcp/127.0.0.1/3030
while read -r -u 3 line; do
  case "$line" in
    *"Need 'Auth' username/password"*)
      echo 'username "Auth" alice' >&3
      echo 'password "Auth" secret' >&3 ;;
    *"Need 'Private Key' password"*)
      echo 'password "Private Key" secret' >&3 ;;
  esac
done

საზღვარი ტრანსპორტია. მართვის პროტოკოლი ღია ტექსტია TCP-ზე loopback-ში, ამიტომ მსმენელი არ უნდა გამოქვეყნდეს LAN ან გვირაბის მისამართზე, რომ დისტანციურმა კონტროლერმა მიაღწიოს; დისტანციური კონტროლერი ნიშნავს SSH გადაგზავნას და არა უფრო ფართო მიბმას. საზოგადოების დემონი ერთდროულად მხოლოდ ერთ მართვის კლიენტს იღებს, ამიტომ GUI ან მონიტორი ვერ გაიზიარებს socket-ს თქვენს სკრიპტთან. მეორე კავშირი უარყოფილია და არა რიგში ჩასმული, და წარუმატებლობა ყრუ გამხდარ სკრიპტს ჰგავს.

ეს socket საკონტროლო არხიც არის. მართვის პაროლის გარეშე ყველაფერს, რაც 127.0.0.1:3030-ს უკავშირდება, შეუძლია მდგომარეობის წაკითხვა, გვირაბის მოკვლა ან თავად პასუხის გაცემა მოთხოვნაზე. მართვის პაროლი და სერტიფიკატის ფაილი ერთი კლასის საიდუმლოა და ორივე ერთსა და იმავე ზრუნვას იმსახურებს.

რომელი ერგება განლაგებას

აირჩიეთ სერტიფიკატის ფაილი, როცა ერთადერთი მოთხოვნა ანგარიშის წყვილია, კლიენტი სერვისად მუშაობს სტაბილური მფლობელით და შეგიძლიათ 600 ფაილი იმ სარეზერვო ასლების გარეთ შეინახოთ, რომლებსაც არ აკონტროლებთ. აირჩიეთ მართვის socket, როცა საქმეშია გასაღების პაროლფრაზა ან PKCS#12 პაროლი, როცა გარსაცმი უკვე ზედამხედველობს პროცესს, ან როცა ხელახალი დაკავშირების გამართვისას მდგომარეობისა და მოთხოვნების ყურება გჭირდებათ.

ორი პირობა ცვლის გადაწყვეტილებას. თუ გარსაცმი /bin/sh-ია, ბინარს უშუალოდ გამომძახებელი systemd ერთეული, ან მინიმალური კონტეინერი, მხოლოდ bash-ისთვის განკუთვნილი socket-ის წებო მიუწვდომელია და ფაილი უფრო იაფი პასუხია. თუ საიდუმლო ხშირად ბრუნავს, არც ერთი ფაილი არ არის მისთვის კარგი სახლი: ჰკითხეთ გასაღებების რგოლს პატარა გარსაცმს და მიეცით ერთეულს უფლება, გამოიძახოს გარსაცმი, რაც ბრუნვას ერთ ადგილას ინახავს და პაროლს shell-ის ისტორიის გარეთ.

პროცესის ჩანაცვლება ორივეს შორის დგას და არც ერთს არ ეკუთვნის. ქვემოთ მოცემული ერთხაზიანი მუშაობს იმიტომ, რომ bash მას openvpn-ის დაწყებამდე აფართოებს და არა იმიტომ, რომ კლიენტს სინტაქსი ესმის:

openvpn --config client.ovpn --auth-user-pass <(printf "%s
%s
" "$USER" "$PASS")

ის ტყდება /bin/sh-ის ქვეშ, shell-ს გვერდის ავლით მოქმედ ერთეულში და bash-ის ან /dev/fd-ის გარეშე გამოსახულებებში. შეინახეთ ის ინტერაქტიული ტესტირებისთვის და არასოდეს როგორც ხელშეკრულება, რომელზეც სერვისია დამოკიდებული.

დაიცავით საიდუმლო, შემდეგ გადაამოწმეთ ჟურნალიდან

ორივე მექანიზმი ტოვებს საიდუმლოს, რომელიც OpenVPN-ის პროცესს შეუძლია წაიკითხოს. არასოდეს დადოთ პაროლი ბრძანების ხაზზე ან ერთეულის ფაილში, სადაც ps და systemctl მას ყველა ლოკალურ მომხმარებელს უჩვენებენ; გადასცეთ ფაილის გზა და არა მისი შიგნით არსებული მნიშვნელობა. სადაც სერტიფიკატებს შეუძლიათ ანგარიშის წყვილის ჩანაცვლება, ეს მოთხოვნის კატეგორიას შლის და არა მალავს.

სწორი გაშვება აჩვენებს მოთხოვნების მიმდევრობის დასრულებას და სესიის «Initialization Sequence Completed»-მდე მისვლას. თუ კლიენტი იმავე მოთხოვნაზე ჩერდება, შედარება ვერ მოხდა: დაბეჭდეთ ზუსტი ხაზები, რომლებიც socket-მა გაგზავნა, შეამოწმეთ ბრჭყალები და მოთხოვნის სახელი, და გაასწორეთ ნიმუში sleep-ის დამატების ნაცვლად. გვირაბი, რომელიც წარმატებას იტყობინება და არაფერს ატარებს, მარშრუტიზაციის ან push პრობლემაა და არა სერტიფიკატის.

შემდეგ გამოსცადეთ ხელახალი დაკავშირება და არა მხოლოდ პირველი გაშვება. ჩამოაგდეთ სერვერის მხრიდან სესია ან დაელოდეთ მის ვადის გასვლას; კლიენტი ისევ იკითხავს, და სწორედ იქ აჩვენებს ჩატვირთვისას სწორად მოჩვენებული ფაილი, არის თუ არა ის ჯერ კიდევ წაკითხვადი ხელახლა დაკავშირებული ანგარიშისთვის.

დაკავშირებული სტატიები