client-connect სკრიპტიდან მისამართის დაბრუნება ისე გამოიყურება, თითქოს კლიენტის IP უნდა დაყენდეს. ასე არ ხდება: hook-ის ერთადერთი არხი სერვერამდე დროებითი ფაილია, რომლის გზაც სკრიპტის ბოლო არგუმენტად მოდის, და მისამართი იქ უნდა ჩაიწეროს ifconfig-push სინტაქსით. სკრიპტი, რომელიც მისამართს ბეჭდავს ან არაფრის ჩაწერის გარეშე ნულით გადის, ქმნის დაკავშირებულ კლიენტს აუზიდან მიღებული მისამართით, და სერვერის ჟურნალი სრულიად ჯანმრთელად გამოიყურება.

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

Hook ფაილს წერს და არა დაბრუნების მნიშვნელობას

დეკლარაცია ორი ხაზია: script-security 2 გამოძახების დასაშვებად, შემდეგ client-connect /etc/openvpn/server/assign-address.sh. როცა კლიენტი ავთენტიფიკაციას გადის, სერვერი ამ სკრიპტს აშვებს გენერირებული ფაილის გზის ბოლო არგუმენტად დამატებით, რაც $1 მხოლოდ მაშინაა, თუ დეკლარაცია საკუთარ დამატებით არგუმენტებს არ გადასცემს. ყველაფერი, რაც ამ კლიენტზე ვრცელდება, იმ ფაილში ჩვეულებრივ დირექტივებად, თითო ხაზზე ერთი, ზუსტად ისე იწერება, როგორც კონფიგურაციაში გამოჩნდებოდა. საკუთარი პარამეტრების დამმატებელი გარსი პოზიციას ცვლის, და კლასიკური სიმპტომია სკრიპტი, რომელიც --verbose-ის მსგავს გზაზე წერს.

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

ორი დირექტივა ყურადღებას იმსახურებს, რადგან დანარჩენ ყველაფერთან ურთიერთქმედებს. ifconfig-push მისამართს აფიქსირებს, ხოლო გაგზავნილი route კლიენტს ეუბნება, რა არის ხელმისაწვდომი გვირაბის გავლით; დააბრუნეთ პირველი და დაივიწყეთ მეორე და მიიღებთ კლიენტს მისამართით და წასასვლელი ადგილის გარეშე. ფაილში რიგითობას მნიშვნელობა არ აქვს, სისრულეს კი აქვს. Hook, რომელიც მარშრუტს უგზავნის იმ პრეფიქსისთვის, რომელსაც ვერც ერთი თანაბარი მხარე ვერ მიაღწევს, იგივე შეცდომაა მეორე მხრიდან დანახული.

შეყვანა გარემოს ცვლადებით მოდის: common_name, trusted_ip, ifconfig_pool_remote_ip და დანარჩენი. ყველა მათგანს მოეპყარით როგორც სერვერის გარედან მოსულ სტრიქონებს, არასდროს როგორც shell-ის ნაწილებს.

მისამართების დაკავშირება პოლიტიკაა და არა არითმეტიკა

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

ვინც სახელს აკონტროლებს, მისამართსაც აკონტროლებს, ამიტომ გადაწყვიტეთ, რას წარმოადგენს common_name სინამდვილეში ამ განლაგებაში. username-as-common-name-ის ჩართვისას იდენტობა არის შესვლა და არა სერტიფიკატის სუბიექტი. არასდროს გადასცეთ ეს მნიშვნელობა shell-ის შეფასებას და არასდროს მისცეთ კლიენტს ფაილის გზაზე გავლენის მოხდენის საშუალება.

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

ტოპოლოგია განსაზღვრავს, რას ნიშნავს ifconfig-push

10.77.0.0/24-ზე topology subnet-ით ifconfig-push 10.77.0.20 255.255.255.0 არის მისამართი და მისი ქსელის ნიღაბი. topology net30-ის ქვეშ მეორე არგუმენტი საერთოდ არ არის ნიღაბი, არამედ თანაბარი მხარის მისამართი, ამიტომ ქვექსელის ფორმის net30 სერვერზე კოპირება გაძლევთ კლიენტს, რომელიც უერთდება და ვერ ატარებს ტრაფიკს. შეცვალეთ ტოპოლოგია განზრახ, არასდროს იმისთვის, რომ მაგალითი თანმიმდევრულად გამოიყურებოდეს. სერვერს, რომელიც უკვე net30-ზე მუშაობს, ცოცხალი კლიენტები აქვს ძველ მისამართებზე, ამიტომ გადართვა ტექნიკური მომსახურების ფანჯრის მქონე მიგრაციაა და არა ერთი ხაზის ცვლილება.

სტატიკური მისამართები დინამიკური აუზის გარეთ და ყოველი სხვა სტატიკური მინიჭების გარეთ უნდა იყოს, მათ შორის ჩვეულებრივი client-config-dir ფაილებით გაცემული. თუ ორ მექანიზმს სხვადასხვა კლიენტისთვის ერთი და იმავე მისამართის გამომუშავება შეუძლია, ერთი მათგანი საბოლოოდ ამას გააკეთებს.

სანამ ენდობით, ოთხი შემთხვევა შეამოწმეთ

გაუშვით იგივე შემოწმებები დაკავშირებულ იდენტობაზე, დაუკავშირებელზე, ხელახალ დაკავშირებაზე და რეესტრის სიმულირებულ უკმარისობაზე. openvpn --config client.ovpn --verb 4 გამოყოფილ მისამართს push პასუხში აჩვენებს, ხოლო სერვერზე grep -A2 PUSH_REPLY /var/log/openvpn/openvpn.log ადასტურებს, რა გაიგზავნა სინამდვილეში. დაუკავშირებელი იდენტობისთვის მოსალოდნელი შედეგი უარყოფილი კავშირია და არა აუზის მისამართი.

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

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

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