Docker კონტეინერი VPN-ში მიუწვდომელია? შეადარეთ ქვექსელები
Docker გასცემს ქვექსელს, რომელსაც VPN-იც ითვისებს. შეადარეთ ორი მისამართების გეგმა და შემდეგ აირჩიეთ გამოსწორება, რომელიც გადატვირთვას გაუძლებს.
კონტეინერები პასუხობენ ოფისის LAN-ში, შემდეგ კი პასუხს წყვეტენ იმ მომენტში, როცა კომპანიის VPN უკავშირდება. კონტეინერში არაფერი შეცვლილა: არავითარი გადატვირთვა, არავითარი იმიჯის განახლება, არავითარი კონფიგურაციის ცვლილება. შეიცვალა ჰოსტის მარშრუტიზაციის ცხრილი, სადაც გვირაბის მიერ დამატებული მარშრუტი ახლა ფარავს იმ მისამართს, რომელიც Docker-მა გასცა. სანამ შეცვლით ქვექსელს ან მოითხოვთ VPN-იდან გამოკლებას, დააყენეთ ორივე მისამართების გეგმა გვერდიგვერდ, რადგან გამოსწორებები ძალიან განსხვავებულ დროს მოითხოვს.
წაიკითხეთ მარშრუტი, სანამ შეცვლით კონფიგურაციას
დაიწყეთ იმ ქსელით, რომელიც Docker-მა რეალურად ააგო. IPAM ბლოკი არის მისამართების გეგმა, ხოლო ქვექსელი — ის ხაზი, რომელსაც მნიშვნელობა აქვს:
docker network inspect project_default --format '{{json .IPAM.Config}}'
# [{"Subnet":"172.18.0.0/16","Gateway":"172.18.0.1"}]Compose ნაგულისხმევად ანაწილებს /16-ს ყოველ ახალ პროექტზე, ასე რომ ორი სერვისი შეიძლება განთავსდეს 65,536 მისამართის დიაპაზონში. სწორედ ეს სიგანე ხდის გადაფარვებს ხშირს: შემთხვევით არჩეული /16 საკმარისად დიდია, რომ გადაყლაპოს საიტი, რომელსაც გვირაბის გავლით აღწევთ, და ვერავინ ამჩნევს, სანამ გვირაბი არ ამოქმედდება.
შემდეგ შეადარეთ მარშრუტის შერჩევა ერთი კონტეინერის მისამართისთვის — ერთხელ გამორთული გვირაბით და ერთხელ ჩართული გვირაბით:
ip route get 172.18.0.7
# 172.18.0.7 dev br-3f2a9c src 172.18.0.1პასუხის ორი ფორმა სხვადასხვა ადგილამდე მიგვიყვანს. თუ გამოსავალში მითითებულია tun0, wg0 ან სხვა გვირაბის მოწყობილობა, VPN-ის პრეფიქსი სულ მცირე ისეთივე კონკრეტულია, როგორც ხიდის მარშრუტი და პაკეტი კონტეინერამდე საერთოდ არ აღწევს. თუ გამოსავალი კვლავ ხიდს ასახელებს, ჰოსტს კონტეინერამდე მისვლა შეუძლია, და თქვენი ხარვეზია ფილტრაცია, DNS ან დაბრუნების გზა, რომელიც მხოლოდ ერთი მიმართულებით ცდება.
რატომ არის /16-ის შეჯახება ადვილად დასაშვები
Docker ხიდის ქსელებს კერძო პულებიდან იღებს, და ნაგულისხმევი პული მოდის 172.16.0.0/12 ბლოკიდან /16 ნაჭრებად. კორპორატიული ქსელები ხშირად იყენებენ იმავე კერძო სივრცეს, და დისტანციური წვდომის VPN ამ პრეფიქსებს ყველა დაკავშირებულ კლიენტს უგზავნის. როცა ორივე მხარე თვლის, რომ ფლობს 172.18.0.0/16, ერთი მარშრუტიზაციის ცხრილი ორ ურთიერთგამომრიცხავ მოთხოვნას ინახავს.
გამარჯვებას წყვეტს პრეფიქსის სიგრძე და არა მარშრუტების თანმიმდევრობა. გვირაბი, რომელიც უგზავნის 10.0.0.0/8 არ სძლევს ხიდის მარშრუტს 172.18.0.0/16, რადგან /8 ნაკლებად კონკრეტულია. გვირაბი, რომელიც უგზავნის 172.18.0.0/16, ან 172.18.5.0/24 მის შიგნით, სძლევს. ამიტომ ერთი ლეპტოპი მუშაობს ოფისის ქსელში და ვერ მუშაობს სასტუმროს Wi-Fi-ზე იმავე VPN-ით: კლიენტი სხვადასხვა პრეფიქსს იღებს.
იგივე ცხრილი მართავს საპირისპირო მიმართულებასაც. კონტეინერი, რომელსაც სჭირდება შიდა ჰოსტი მისამართზე 10.8.4.20 აგზავნის პაკეტს თავისი ხიდის გეითვეიზე, და ჰოსტი შემდეგ მას გვირაბში მარშრუტიზაციას უკეთებს. ეს გზა ჩვეულებრივ მუშაობს, რადგან ჰოსტი NAT-ს ასრულებს, მაგრამ ცდება, როცა კორპორატიული მხარე მხოლოდ ლეპტოპის VPN მისამართს იღებს, ან როცა საპირისპირო გზის ფილტრაცია ასიმეტრიულ პასუხს ყრის.
შეადარეთ სამი გამოსწორება
გამოსავალი მხოლოდ სამია, და ისინი განსხვავდებიან იმით, ვინ უნდა დაამტკიცოს ისინი და რა ფუჭდება მათი გამოყენებისას.
| Repair | Who owns it | What it costs |
|---|---|---|
| Renumber the container network | You | Recreates the network, restarts services, invalidates literal addresses in configs and scripts |
| Exclude your range from the tunnel | Network team | Changes what every laptop sees, needs a change request and a client profile update |
| Reach the service through a published port | You and the client | One port only, no direct container-to-container routing across the tunnel |
გადანომრვა ერთადერთი გამოსწორებაა, რომელსაც ბილეთის გარეშე დაასრულებთ, ამიტომ უმეტესი წერილები სწორედ აქ ჩერდება. ახალგაზრდა პროექტზე ის იაფია, ხოლო ძვირი — როცა მიგრაციის ხელსაწყო ან შენახული კავშირის სტრიქონი ლიტერალურ მისამართზე მიუთითებს. დაითვალეთ ეს მითითებები YAML-ის რედაქტირებამდე და არა შემდეგ.
გვირაბიდან გამოკლება ყველაზე სუფთა პასუხია, როცა გადაფარვა იმ დიაპაზონშია, რომელსაც თქვენი კომპანია ნამდვილად ფლობს. ის ასევე ყველაზე ნელია და უსარგებლოა კონტრაქტორისთვის, რომელსაც კლიენტის პროფილის შეცვლა არ შეუძლია. გამოქვეყნებული პორტი ან პატარა საპირისპირო პროქსი კამათს თავიდან გვაშორებს: კლიენტი საუბრობს მისამართთან, რომელსაც გვირაბი უკვე სწორად მარშრუტიზაციას უკეთებს, და მხოლოდ ეს პორტი უნდა იყოს მიწვდომადი.
დააფიქსირეთ დიაპაზონი განზრახ
ერთი პროექტისთვის გამოაცხადეთ ქვექსელი compose ფაილში, რომ პროექტმა შეწყვიტოს საერთო პულიდან აღება:
networks:
default:
ipam:
config:
- subnet: 10.201.7.0/24ეს დიაპაზონი აიღეთ რეესტრიდან, რომელსაც თქვენი გუნდი ინახავს და არა მაგალითიდან, რომელიც ძებნისას იპოვეთ. შეამოწმეთ ის VPN-ის მიერ გაგზავნილ პრეფიქსებთან, სახლის LAN-ებთან, საიდანაც ადამიანები მუშაობენ, და იმავე ჰოსტის სხვა კონტეინერის ქსელებთან. შემდეგ დაგეგმეთ ხელახლა შექმნა, რადგან არსებული ქსელი ძველ ქვექსელს ინარჩუნებს: docker compose down, შემდეგ up -d. docker network rm უარს ამბობს, სანამ ბოლო წერტილები მიმაგრებულია, და ნებისმიერი ipv4_address ჩანაწერი ფაილში ახალ დიაპაზონში უნდა მოხვდეს.
ქსელებისთვის, რომლებსაც Docker თავად ქმნის, დააყენეთ დემონის პული /etc/docker/daemon.json:
{
"default-address-pools": [
{ "base": "10.201.0.0/16", "size": 24 },
{ "base": "10.202.0.0/16", "size": 24 }
]
}პული ვრცელდება ქსელებზე, რომლებიც დემონის გადატვირთვის შემდეგ შეიქმნა, და უკვე არსებული ხიდები თავის მისამართებს ინარჩუნებს. ეს მოსახერხებელია და ადვილად დასავიწყებელი, ამიტომ ძველ პროექტს ჯერ კიდევ გადაფარულად მიიჩნიეთ, სანამ ვინმე მის ქსელს ხელახლა არ შექმნის. Docker-ის ძრავის ქსელის დოკუმენტაცია აღწერს განაწილების წესებს, თუ დაგჭირდებათ პულის დაცვა მიმოხილვაზე.
Linux-ის ხიდი და Docker Desktop სხვადასხვაგვარად ცდება
Linux ჰოსტზე კონტეინერები ჰოსტის namespace-ში ხიდებზე სხედან. ყველაფერს ერთი ცხრილი წყვეტს, ამიტომ ზემოთ მოცემული შედარება მთელი ამბავია: წაიკითხეთ ხიდის მარშრუტი, წაიკითხეთ გვირაბის მარშრუტი და ნახეთ, რომელი იმარჯვებს რეალური კონტეინერის მისამართისთვის.
Docker Desktop კონტეინერებს ათავსებს VM-ის უკან, რომელსაც საკუთარი NAT აქვს. ჰოსტს კონტეინერის მისამართამდე მარშრუტი საერთოდ არ აქვს; ის სერვისს აღწევს გამოქვეყნებული პორტით, რომელიც ჩვეულებრივ მიბმულია 127.0.0.1. VPN კლიენტს შეუძლია სერვისი გააფუჭოს ყოველგვარი ქვექსელის გადაფარვის გარეშე — ან VM-ის შიდა დიაპაზონისთვის მარშრუტის დაყენებით, ან loopback ტრაფიკის დაბლოკვით, სანამ გვირაბი დაკავშირებულია. თუ ip route get ჰოსტზე არ იუწყება მარშრუტს კონტეინერის მისამართისთვის, ეს მოსალოდნელია და არა ხარვეზი.
პრაქტიკული შედეგი ის არის, სადაც პირველად იხედებით. Linux-ზე დაიწყეთ მარშრუტიზაციის ცხრილიდან. Desktop-ზე დაიწყეთ გამოქვეყნებული პორტიდან და VPN კლიენტის firewall წესებიდან, შემდეგ შეამოწმეთ, ემთხვევა თუ არა VM-ის შიდა ქვექსელი იმას, რასაც გვირაბი უგზავნის.
გადაამოწმეთ ჩართული გვირაბით
ხელახლა დაუკავშირდით VPN-ს ორჯერ, სანამ გამოსწორებულად გამოაცხადებთ, რადგან პროფილი, რომელიც დაკავშირებისას მარშრუტებს უგზავნის და გათიშვისას უკან იბრუნებს, პირველი ცდის შემდეგ სწორად შეიძლება გამოიყურებოდეს. შემდეგ გაუშვით ის შემოწმებები, რომლებსაც კლიენტი რეალურად ატარებს:
ip route getჰოსტიდან, კონტეინერის რეალური მისამართის გამოყენებით.- მოთხოვნა სხვა კონტეინერიდან, რათა დადასტურდეს, რომ თავად სერვისი ჯანსაღია.
curl -sv http://127.0.0.1:8080/კლიენტიდან ჩართული გვირაბით, შემდეგtraceroute -nკონტეინერის მისამართამდე LAN-ის მანქანიდან.sysctl net.ipv4.conf.all.rp_filterთუ მოთხოვნა ჰოსტამდე აღწევს, მაგრამ პასუხი ქრება.
დაბოლოს, ჩაწერეთ არჩეული დიაპაზონი იმავე რეესტრში, რომელიც გამოიყენეთ მის ასარჩევად, თარიღითა და იმ პროექტით, რომელიც მას ფლობს. შემდეგი გადაფარვა მოვა პროექტიდან, რომელიც არავის დაუდოკუმენტებია, და ერთადერთი დაცვა ის არის, რომ დიაპაზონი განზრახ იყო დაცული და არა შემთხვევით არჩეული.