ორი DNS სახელი, ერთი OpenVPN პორტი: რა ირჩევს სინამდვილეში
ერთ მისამართზე მიმთითებელი ორი ჰოსტის სახელი მაინც ერთ მსმენელამდე აღწევს. backend-ის არჩევა მხოლოდ კლიენტის მიერ გაგზავნილ ველს შეუძლია, ხოლო ჩვეულებრივი OpenVPN ასეთს არ აგზავნის.
ორი A ჩანაწერი, ერთი მისამართი, ერთი დემონი: რომელი სახელიც არ უნდა აკრიფოს მომხმარებელმა, მოსული პაკეტი იდენტურია და 1194 პორტზე მიბმულ პროცესს ორივეს გასარჩევად არაფერი აქვს. ეს არ არის გასწორების მომლოდინე მცდარი კონფიგურაცია; ეს არის იმის ზღვარი, რისი გამოხატვაც სახელის ძიებას შეუძლია. ყველაფერი, რაც ორ OpenVPN ინსტანსს შორის ირჩევს, უნდა იყოს მნიშვნელობა, რომელსაც კლიენტი კავშირში დებს და რომელსაც წინა მხარე უკან წაიკითხავს, ხოლო სტანდარტული OpenVPN კლიენტი ასეთ მნიშვნელობას ღიად არ დებს. შემდეგი გვიჩვენებს, სად გტოვებთ ეს და რომელი განლაგებები ყოფს ტრაფიკს ნამდვილად.
დაიწყეთ იმით, რასაც გადამწყვეტი აბრუნებს
კლიენტი ითხოვს vpn-a.example-ს და იღებს მისამართს; ეს მისამართი პლუს პორტი არის ყველაფერი, რასაც აკავშირებს. სახელი იხარჯება ლოკალურად, ძიების დროს, და ის არასოდეს ხდება ველი ხაზზე, ამიტომ მეორე მხარის მსმენელი ვერ ხედავს, რომელი იარლიყი გამოიყენეს. მიმართეთ vpn-a.example და vpn-b.example ერთ ჰოსტს და ორივე ძიება ერთსა და იმავე დანიშნულებას მოგცემთ, ამიტომ დემონი ორივე კავშირს ერთ ინსტანსში შთანთქავს განსხვავების რეგისტრაციის გარეშე. მისამართზე დაფუძნებული პროფილები ზუსტად ისე იქცევიან, როგორც სახელზე დაფუძნებული, იმავე მიზეზით.
ეს ასევე ხურავს მაცდუნებელ გვერდის ავლით გადაწყვეტილებათა ოჯახს: დამატებითი ფსევდონიმები, ერთ სოკეტზე თითოეული სახელისთვის სერტიფიკატის არჩევა, ან კითხვისეულ სახელზე მიბმული ფაირვოლის წესი. არცერთ მათგანს არ შეუძლია იმ ინფორმაციაზე მოქმედება, რომელიც უკვე გადაგდებული იყო, სანამ პირველი პაკეტი დატოვებდა კლიენტს. თუ ორი სერვერი ცალკე უნდა დარჩეს, გაყოფა თავად კავშირთან ერთად უნდა მოძრაობდეს, ესე იგი მისამართი, პორტი ან დატვირთვის ველი, რომელსაც პროტოკოლი განსაზღვრავს.
ერთადერთი დასათვლელი სელექტორი პაკეტის შიგნით მიემგზავრება
HTTP ამას Host სათაურით წყვეტს, ხოლო TLS ClientHello-ში სერვერის სახელის გაფართოებით, და ასე ემსახურება ერთი მისამართი ბევრ საიტს ერთი მსმენელის უკან. ორივე მუშაობს, რადგან ხაზის პროტოკოლი კონკრეტულ სერვისზე მოთხოვნას ატარებს. OpenVPN-ის შესახებ მთავარი ფაქტი ის არის, რომ არცერთი ეს ველი არ არის იმ ფენაზე, რომელსაც შუამავალი ყუთი ამოწმებს.
სტანდარტულ განლაგებაში საკონტროლო არხის დამცავი TLS ხელის ჩამორთმევა ხდება მას შემდეგ, რაც გარე სესია დამყარებულია, და მის შიგნით გადაიტანება, ამიტომ ის მსმენელი, რომელსაც ეს სესია არ დაუსრულებია, გაუმჭვირვალე ნაკადს ხედავს. მაინც შეუძლია თქვას, რომ ეს OpenVPN-ია, რადგან საწყის ბაიტებში ოპკოდი და ჩარჩოვნება ცნობადია, მაგრამ სერვერის სახელი, თუ არსებობს, დაშიფრულ ნაწილში ზის. დიზაინი, რომელიც გარე პაკეტიდან ვირტუალური ჰოსტის წაკითხვას ელის, კითხულობს ველს, რომელსაც პროტოკოლი იქ არასოდეს წერს. ეს გამომდინარეობს იქიდან, თუ როგორ არის გვირაბი აგებული, და არა იმ ხარვეზიდან, რომელსაც უფრო ჭკვიანური შაბლონის დამთხვევა დახურავდა.
სად ჩერდება პროტოკოლის გამყოფი
იმ ტიპის მულტიპლექსორი, რომელსაც sslh პროექტი აღწერს, ერთ პორტზე უსმენს, ამოწმებს საწყის ბაიტებს და კავშირს გადასცემს იმ backend-ს, რომელიც ამოცნობილ პროტოკოლზე საუბრობს. ეს ნამდვილი ღირებულებაა, როცა ერთ პორტმა SSH, HTTPS და OpenVPN ერთად უნდა მოემსახუროს.
sslh თითოეული პროტოკოლისთვის ცალკე ზონდს ინახავს და მის TLS ზონდს შეუძლია ნამდვილი ClientHello-დან სერვერის სახელი ან ALPN მნიშვნელობა ამოიღოს. თავისი OpenVPN-ის ამოცნობა სხვა კლასიფიკაციაა, ვიდრე TLS გაფართოების წაკითხვა, და ორივე არ ერწყმის, რადგან კლიენტი, რომელიც არასოდეს აგზავნის ClientHello-ს მსმენ სოკეტზე, ზონდს საკითხავის გარეშე ტოვებს. ამიტომ OpenVPN-თან შესაბამისი წესი პასუხობს „ეს OpenVPN კლიენტია“ და შემდეგ არ მიდის. ამ წესის უკან მდგარი ორი OpenVPN backend განურჩეველია, წინა მხარეს არჩევანის საფუძველი არ აქვს და ყოველი სესია ერთსა და იმავე ადგილას ეშვება. მულტიპლექსირება ერთ პორტს სხვადასხვა სერვისებს შორის იზიარებს; ის ერთი სერვისის შიგნით ვირტუალურ ჰოსტინგს არ აკეთებს.
განლაგებები, რომლებიც ორ სერვერს ნამდვილად ყოფს
ყველაზე იაფი პატიოსანი გაყოფა მეორე საჯარო მისამართია, ერთი თითოეული ინსტანსისთვის, და არსებული პროფილები უკვე ატარებენ საჭიროს, რადგან სხვადასხვა მისამართზე მიუთითებენ. შემდეგია განსხვავებული პორტი იმავე მისამართზე, რაც არაფერი ღირს თითოეულ პროფილში ერთი რიცხვის გარდა. TCP და UDP ცალკე პორტის ცხრილებს ინახავენ, ამიტომ 1194/tcp და 1194/udp უკავშირო სოკეტებია და თითოეულიდან ერთი შეიძლება ერთ ჰოსტზე თანაარსებობდეს; ეს ტრანსპორტის გაყოფაა და არა სახელით მარშრუტიზაცია, და ხშირად მასთან ურევენ. ორივე ვარიანტი ფაირვოლის განხილვას გადის, რადგან წესი ემთხვევა იმას, რაც პაკეტში ნამდვილად არის.
თუ თქვენთვის საჭირო საზღვარი ორ იმპლემენტაციას შორის კი არა, მომხმარებელთა ჯგუფებს შორის გადის, მას ერთი ინსტანსი განსხვავებული კლიენტური კონფიგურაციებით, საკუთარი სერტიფიკატების მართვითა და მკაფიო წვდომის პოლიტიკით დაფარავს. ეს ყიდულობს პოლიტიკას სერვერის შიგნით და არა იზოლაციას სერვერებს შორის, და ეს ორი სხვადასხვა მოთხოვნაა. იზოლაციას, რომელმაც კომპრომეტაციის ქვეშ უნდა გაძლოს, მაინც სჭირდება მისამართი ან ფაირვოლის კიდე.
OpenVPN-ის წინ დაყენებულ TLS დამამთავრებელს შეუძლია ნამდვილი სერვერის სახელი გაუმჟღავნოს უნარიან წინა მხარეს, მაგრამ მხოლოდ მაშინ, როცა კლიენტის მხარეც კონფიგურირებულია იმ დამატებითი ფენისთვის. არსებული პროფილები ამ ქცევას იმით არ იძენენ, რომ იმავე მისამართზე მიუთითებენ.
დაამტკიცეთ სელექტორი სანამ ააგებთ
დაასახელეთ ველი, რომელიც backend-ს ამოიცნობს, შემდეგ დაადასტურეთ, რომ კლიენტი მას ნამდვილად აგზავნის; თუ პასუხი მისამართია, გეგმა ძლებს, ხოლო თუ ეს არის სერვერის სახელი იმ ხელის ჩამორთმევის შიგნით, რომელიც მსმენელს არასოდეს აღწევს, ვერც ერთი DNS სამუშაო ვერ იხსნის. სამი ბრძანება სწრაფად წყვეტს მსმენ მხარეს.
ss -lntup | grep -E ':443|:1194'
openssl s_client -connect vpn-a.example:443 -servername vpn-a.example </dev/null | head -n 20
journalctl -u openvpn-server@server-a -n 20 --no-pager
openssl-ის სტრიქონი სერტიფიკატს მხოლოდ იქ იძლევა, სადაც რაღაც ამ მისამართზე TLS-ს ამთავრებს; თავისი OpenVPN მსმენელის წინააღმდეგ ის იჭედება ან ვარდება, და ეს თავისთავად არის პასუხი იმაზე, თუ რას ამჟღავნებს გარე ფენა. journal-ის სტრიქონი, წაკითხული თითოეულ backend-ზე, გვიჩვენებს, რომელმა ინსტანსმა მიიღო სესია. წინა მხარის ჟურნალები იწერენ, რაც კლასიფიცირდა და არასოდეს იმას, რაც იგულისხმებოდა, ამიტომ backend რჩება ერთადერთ ხელისუფლებად იმაში, თუ სად დაეშვა მომხმარებელი.
დაასრულეთ ორი პროფილით, რომლებიც სხვადასხვა სერვერამდე მისასვლელად არის განკუთვნილი, დაუკავშირეთ ისინი სათითაოდ და ჩაწერეთ backend-ის ჟურნალი თითოეულისთვის. თუ ორივე სესია ერთსა და იმავე journal-ში გამოჩნდა, სელექტორი აკლია და არა არასწორად არის კონფიგურირებული, ხოლო გასწორება არის მისამართი ან პორტი, რომელსაც კლიენტი დამიზნავს. მარშრუტიზაციის წესის რედაქტირება არ დაეხმარება, რადგან წესს არასოდეს მიუციათ არაფერი, რაზეც იმარშრუტებდა. როცა გაყოფა რეალური გახდება, ჩაწერეთ ის პროფილების გვერდით, რომ შემდეგმა ადამიანმა მეორე ფსევდონიმი არ დაამატოს და არ მოელოდოს, რომ ის შეასრულებს საქმეს.