სახლის სერვერის გამოქვეყნება VPS-ის მეშვეობით, როცა CGNAT პორტებს ბლოკავს
გზა ბრაუზერიდან სახლის მანქანამდე: დაამტკიცე, რომ ხაზი CGNAT-ის უკანაა, DNS მიმართე VPS-ზე, გააკეთე DNAT ერთ პორტზე, გაასწორე დაბრუნების გზა და შეამოწმე გარედან.
გარედან დავიწყე, როგორც მომხმარებელი გააკეთებდა: სახელი მობილური ინტერნეტის ტელეფონის ბრაუზერში აკრიფე და ვუყურე, როგორ ეკიდა კავშირი დროის ამოწურვამდე. სახელი წყდებოდა, ასე რომ DNS რიგზე იყო. სახლის როუტერის პორტების გადამისამართების გვერდიც ჩიხი იყო, რადგან მისი WAN მისამართი 100.64.31.42-ს აჩვენებდა, და ეს არ არის მისამართი, სადაც პროვაიდერი ინტერნეტიდან მიმისამართებს. ეს რიცხვი ხსნის მთელ ხარვეზს: ხაზი carrier-grade NAT-ის უკანაა, ამიტომ გვირაბის ჩემი მხარის საჯარო მისამართი პროვაიდერს ეკუთვნის. შემდგომ მოცემულია გზა, რომელიც გავიარე იმ გაჭედილი ჩანართიდან პასუხისმგებელ სერვისამდე.
დაიწყე კლიენტიდან და იმოძრავე შიგნით
სანამ რომელიმე წესს შეცვლი, დაამტკიცე, სად ჩერდება ჯაჭვი. ლეპტოპზე გავუშვი dig +short files.example.net და მივიღე VPS-ის მისამართი უკან, რამაც გამორიცხა მოძველებული DNS ჩემს მანქანაზე. შემდეგ curl -v --connect-timeout 5 files.example.net:5022 დროის ამოწურვაში გადავარდა უარყოფის ნაცვლად. ეს განსხვავება მნიშვნელოვანია: დროის ამოწურვა ჩვეულებრივ ნიშნავს, რომ პაკეტები გზაში იყრება, ხოლო უარყოფა ნიშნავს, რომ რაღაცამ უპასუხა და თქვა არა.
შიგნით შემდეგი ნაბიჯი თავად VPS იყო. ss -ltnp არაფერს არ აჩვენებდა, რაც 5022-ზე უსმენდა, რაც მოსალოდნელი იყო DNAT წესის არსებობამდე. იმავე მანქანაზე wg show (ან ip -br a show tun0 OpenVPN-ისთვის) დაადასტურა, რომ სახლის peer მუშაობს და აქვს ახალი handshake. თუ peer არ მუშაობს, არც ერთი NAT წესი არ დაეხმარება, და სახლის როუტერის VPN გვერდზე მწვანე შუქი არაფერს ნიშნავს.
დაადასტურე, რომ სახლის ხაზი ნამდვილად CGNAT-ის უკანაა
შეადარე როუტერის მიერ WAN ინტერფეისზე მოხსენებული მისამართი იმას, რასაც გარე სერვისი ხედავს. ყველაფერი 100.64.0.0/10-ში, ანუ 100.64.x.x-დან 100.127.x.x-მდე, RFC 6598-ის საერთო მისამართების დიაპაზონია და ინტერნეტიდან მიუწვდომელია. იმავე დასკვნამდე მიდიხარ, როცა როუტერი ამტკიცებს, რომ ჩვეულებრივი კერძო მისამართი აქვს, და საჯარო ძებნა რაღაც შეუსაბამოს აბრუნებს. CGNAT ხაზს შეიძლება ჰქონდეს საჯარო მისამართი, რომელიც მხოლოდ შემდეგ lease-მდე მოქმედებს, ამიტომ პორტის გადამისამართება ერთი საათი მუშაობს და შემდეგ ჩუმად კვდება.
ზოგიერთი პროვაიდერი ნამდვილად გასცემს ნამდვილ საჯარო მისამართს, მაგრამ ბლოკავს შემავალ 80 და 443 პორტებს საცხოვრებელ ანგარიშებზე. თუ შენი სერვისი მხოლოდ ვებია და WAN მისამართი ნამდვილად საჯაროა, ჰკითხე მხარდაჭერას სანამ relay აგებ. თუ არა, ქვემოთ მოცემული დიზაინი ყველა პორტს თანაბრად ეხება, და ღირს ექსპერიმენტის შეჩერება როუტერის მხარეს: პროვაიდერის ქსელში მყოფი მთარგმნელი წყვეტს კავშირს სანამ ის შენს WAN ინტერფეისამდე მივა.
მიმართე სახელი VPS-ის მისამართზე
DNS ტრაფიკს არ გადასცემს, ამიტომ სერვისის A ჩანაწერში უნდა იყოს VPS-ის საჯარო მისამართი. 192.168.1.20-ზე მიმართული A ჩანაწერი სასარგებლოდ მხოლოდ VPN-ის შიგნით მყოფი კლიენტებისთვის წყდება; ინტერნეტიდან ის იმ მისამართზე წყდება, რომელსაც ვერავინ გადაამისამართებს. VPS-ის საკუთარი ადმინისტრაციული წვდომისთვის ცალკე სახელს ვინახავ, რომ არასდროს ავურიო, რომელ ჰოსტს ეხება ჩანაწერი.
თუ HTTP-ს ემსახურება როგორც VPS, ისე სახლის მანქანა, მიეცი თითოეულს საკუთარი სახელი და VPS-მა გადაწყვიტოს, ვინ პასუხობს. მათი ერთ სახელში შერწყმა და იმედი, რომ პროქსი სწორ backend-ს აირჩევს, ზუსტად ის გზაა, რომლითაც მთელ შუადღეს არასწორ ჰოსტზე შეცდომებს ეძებ.
ერთი პორტი DNAT-ით, SSH რჩება 22-ზე
პირდაპირი ვარიანტია დანიშნულების NAT VPS-ზე. ჩართე forwarding მუშა ბირთვისთვის და წესში შეინახე სახლის სერვერის გვირაბის მისამართი, და არა მისი LAN მისამართი:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp -d 198.51.100.10 --dport 5022 -j DNAT --to-destination 10.8.0.2
დატოვე SSH თავად VPS-ზე 22-ზე და გადაამისამართე სხვა პორტი, მაგალითად 5022, სახლის მანქანაზე. თუ 22-ს გადაამისამართებ გამორთულ მანქანაზე, დაკარგავ ერთადერთ გზას, რომელსაც მისი გასწორება შეეძლო. იგივე ლოგიკა ეხება პროქსის: შეინახე VPS-ის მართვის პორტი relay წესების გარეთ.
გახადე წესები მუდმივი, როცა იმუშავებენ. Debian-ზე ან Ubuntu-ზე apt install iptables-persistent და შემდეგ netfilter-persistent save მათ /etc/iptables/rules.v4 ფაილში წერენ. firewalld-ის მქონე ჰოსტზე ეკვივალენტია მუდმივი პორტის გადამისამართება ზონაში, რომელსაც გამოყენებამდე firewall-cmd --reload სჭირდება. მხოლოდ მეხსიერებაში მცხოვრები წესები ქრება პროვაიდერის პირველ ტექნიკურ გადატვირთვაზე, ჩვეულებრივ ცუდ საათზე.
გაასწორე დაბრუნების გზა, ან აირიდე მისი საჭიროება
DNAT მხოლოდ დანიშნულებას გადაწერს. სახლის სერვერი ხედავს კავშირს თავდაპირველი კლიენტის მისამართიდან, და თუ მისი ნაგულისხმევი მარშრუტი სახლის როუტერზე მიდის, პასუხი სახლის WAN-ით გადის, სადაც პროვაიდერის მთარგმნელი ყრის მას. ეს ასიმეტრია იყო მეორე ხარვეზი, რომელსაც წავაწყდი მას შემდეგ, რაც DNAT წესი სრულიად სწორად გამოიყურებოდა.
ორი შესწორება მუშაობს. მიეცი სახლის მანქანას პოლიტიკის მარშრუტი, რომ გვირაბიდან მომავალი ტრაფიკი გვირაბით დაბრუნდეს:
ip rule add from 10.8.0.2 table 100
ip route add default dev wg0 table 100
ან მიეცი VPS-ს საშუალება გადაწეროს წყარო, რომ პასუხს ჰქონდეს მისაწვდომი მისამართი, და conntrack-მა ის გასასვლელზე უკუაქციოს:
iptables -t nat -A POSTROUTING -d 10.8.0.2 -p tcp --dport 5022 -j SNAT --to-source 10.8.0.1
SNAT ვერსია მალავს ნამდვილ კლიენტის მისამართს სახლის სერვერისგან, ამიტომ აპლიკაციის ჟურნალები peer-ად 10.8.0.1-ს აჩვენებენ. გადაეცი თავდაპირველი მისამართი აპლიკაციის დონეზე, ან დაეთანხმე კლიენტის მიხედვით ჟურნალის დაკარგვას, მაგრამ გადაწყვიტე განზრახ, ნაცვლად იმისა რომ ინციდენტის დროს აღმოაჩინო.
შეამოწმე მთელი გზა გარედან
შეამოწმე ქსელიდან, რომელიც არც VPS-ია და არც სახლი: ტელეფონი მობილური ინტერნეტით ან იაფი shell სხვაგან. nc -vz files.example.net 5022 უნდა იტყობინოს წარმატებულ კავშირზე, ხოლო openssl s_client -connect files.example.net:443 -servername files.example.net უნდა აჩვენოს სერტიფიკატი საჯარო სახელისთვის. შემდეგ შეამოწმე პროვაიდერის უსაფრთხოების ჯგუფი ან ღრუბლოვანი firewall. DNAT წესი, რომელიც არასდროს ხედავს პაკეტს, ჩვეულებრივ ბლოკირდება ერთი დონით ჰოსტის ზემოთ.
და ბოლოს, გადაწყვიტე რა მოხდება, როცა გვირაბი ვარდება. DNAT წესი აგრძელებს კავშირების მიღებას და ჩუმად აწოდებს მათ მკვდარ გვირაბს, რაც ზუსტად გაფუჭებულ სერვისს ჰგავს. ჯანმრთელობის შემოწმება VPS-ზე, რომელიც უარყოფს პორტს სანამ peer არ მუშაობს, რამდენიმე ხაზი ღირს და ერთი საათის ვარაუდს ზოგავს. ამის შემდეგ შეწყვიტე წესების რედაქტირება და დააკვირდი ერთი დღე, სანამ ენდობი.