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

ორი ფორმა, ერთი შეხვედრის ადგილი

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

ssh -N -R 8081:127.0.0.1:8080 -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 [email protected]

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

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

პირობა პირველი: უნდა იცოცხლოს პორტმა სესიაზე მეტხანს

უკუქცეული გადაცემა ცოცხლობს ზუსტად იმდენ ხანს, რამდენსაც მისი შემქმნელი SSH სესია. როცა კავშირი წყდება, მოსმენა ქრება და კოლეგა ნელი გზის ნაცვლად უარყოფილ კავშირს ხედავს. ბრძანების ზედამხედველობა systemd ერთეულით და გადატვირთვის პოლიტიკით ამას ასწორებს, და ExitOnForwardFailure=yes წარუმატებელ მიბმას მაშინვე ხილვადს ხდის, გადაცემის გარეშე მოქმედი სესიის დატოვების ნაცვლად.

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

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

პირობა მეორე: ვის ეკუთვნის firewall და ლოგები

უკუქცეული ფორმა მთელ პოლიტიკას ორ ადგილას ინახავს. sshd AllowTcpForwarding-ის მეშვეობით წყვეტს, საერთოდ ნებადართულია თუ არა დისტანციური გადაცემები, ხოლო GatewayPorts წყვეტს, მიებას მოსმენა loopback-ს თუ ყველა მისამართს. ნაგულისხმევი no-ით სერვერის გარეთ მყოფი კოლეგა პორტზე ვერ მივა, მიუხედავად იმისა, რომ გადაცემა წარმატებით დასრულდა, და ეს გატეხილ გვირაბად გამოიყურება, სინამდვილეში კი მიბმის მისამართია.

sudo ss -ltn '( sport = :8081 )'
sudo grep -E '^(GatewayPorts|AllowTcpForwarding)' /etc/ssh/sshd_config

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

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8081 -j DNAT --to-destination 10.88.0.6:8080
sudo iptables -t nat -A POSTROUTING -o tun0 -m conntrack --ctstate DNAT -j SNAT --to-source 10.88.0.1

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

პირობა მესამე: ერთი პორტი თუ ბევრი, და ვის ეკუთვნის სახელი

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

სახელები ამას უფრო ართულებს. უკუქცეული გადაცემა შეიძლება იყოს TCP proxy-ის უკან, რომელიც SNI-ით მარშრუტიზაციას აკეთებს, მაშინ როცა თარგმნილი პორტი, როგორც წესი, ერთი პორტია თითო სერვისზე. თუ სერვისი თავად ასრულებს TLS-ს და სჭირდება თავდაპირველი host-ის სახელი, proxy მიდგომა მას ინარჩუნებს, ხოლო DNAT მიდგომა ინარჩუნებს მხოლოდ იმ შემთხვევაში, თუ სერვისი ამ სახელს ამ პორტზე მიიღებს.

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

გადაწყვიტეთ, შემდეგ გარედან გამოსცადეთ

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

sudo iptables -t nat -L PREROUTING -n -v
sudo tcpdump -ni any 'tcp port 8081' -c 20

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

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

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