GCE da OpenVPN: routelarni push qilishdan oldin alias IP qo‘shing
Push qilingan route VMni next hop qilmaydi. Alias IP diapazonini qo‘shing, uni server pooliga moslang va mijozlarni sinashdan oldin VPCda qaytish routeni yarating.
Mijoz Compute Engine VMdagi OpenVPN serveriga ulanadi, holat oynasi ulangan deydi, ammo VPC ichidagi hostga ping hali ham hech qayerga yetmaydi. Instinkt yana bitta push satrini qo‘shishni aytadi va bu uni hech qachon tuzatmaydi. Compute Engine paketlar qayerga ketishini o‘z route jadvali va VM interfeysi haqiqatan ushlab turgan manzillar asosida hal qiladi, shuning uchun VM egalik qilmaydigan tunnel pool — hech kim yetkazmaydigan pool.
Konfiguratsiya fayli o‘rniga yiqilayotgan paketni kuzatib boring, yetishmayotgan bo‘laklar tartib bilan ko‘rinadi.
O‘layotgan paketdan boshlang
SYN mijozdan chiqadi, tunnelga kiradi va VPC ichidagi manzil uchun inkapsulyatsiyalangan paket sifatida VMga yetadi. OpenVPN uni dekapsulyatsiya qiladi va eth0 orqali o‘tkazishga urinadi, u yerda fabric hamma narsadan oldin bitta savol beradi: bu instans manzilga ega mi. Boshqa birovning subnetidan kesilgan tunnel pool bu savoldan o‘tmaydi va paket har qanday route yoki firewall qoidasi ko‘rilishidan oldin tashlanadi.
Demak, mijozdan VPCga yo‘nalishning ikkita alohida talabi bor va ularning hech biri push ko‘rsatmasi emas. VMga tunnel poolni qoplaydigan alias diapazoni kerak va aynan shu uni bu manzillarning qonuniy egasi qiladi. VPCga har bir himoyalangan prefix uchun VMni next hop deb ko‘rsatadigan route kerak. Bittasi yetishmasa, paket boshqa joyda o‘ladi, mijoz esa o‘sha sukunatni ko‘radi.
Nosozlikni shu tartibda o‘qing, chunki mijoz tomondan ikkala shart bir xil ko‘rinadi. Hech narsa javob bermasa ham ulangan deb xabar beradigan tunnel — topologiya muammosining belgisi, yomon shifrning emas.
Instans tunnel poolga ega mi
VMga o‘z subneti ichida ikkilamchi diapazon bering, so‘ng OpenVPN manzillarni aynan shu diapazondan tarqatsin. Asosiy manzili 10.156.0.10/20 bo‘lgan instansda /28 alias poolni boshqa instanslar allaqachon ushlab turgan manzillardan ajratadi:
gcloud compute instances network-interfaces update openvpn-vm \
--zone=europe-west1-b \
--aliases=eth0:10.156.1.0/28Keyin server ko‘rsatmasi o‘sha blokni tavsiflashi kerak. Uning birinchi manzili tunnel gatewayiga aylanadi, qolgan manzillar mijozlarga beriladi. Bu yerda ikkita raqam bitta blokni tavsiflaydi, tarmoq va netmask, va bu OpenVPN hali ham kutayotgan pool sintaksisi.
server 10.156.1.0 255.255.255.240Manzil haqiqatan interfeysga tushganini, faqat OpenVPN konfiguratsiyasida qolmaganini tasdiqlang. Fabric NIC xabar berganini uzatadi, daemon ishonganini emas. Bitta buyruq buni hal qiladi:
ip -4 addr show dev eth0eth0ga hech qachon yetmaydigan ikkilamchi manzil yoki boshqa subnet bilan ustma-ust tushadigan pool keyinchalik ishga tushish xatosi sifatida emas, uzilishli yo‘qotish sifatida ko‘rinadi. Daemon ishga tushadi, mijozlar ulanadi va faqat ba’zi manzillar noto‘g‘ri ishlaydi. Alias diapazonini kichik tuting, shunda pool route jadvalida oson taniladi. Uni hech qachon boshqa instans ishlatayotgan subnetdan kesib olmang.
Qaytuvchi trafikka next hop bering
VPCdagi hostdan javob tunnel pooldagi mijoz manziliga yuboriladi, u VPC biladigan hech bir subnetga tegishli emas. Bu pool uchun route bo‘lmasa, javob mos kelmaydigan birinchi hopda to‘xtaydi va so‘rov narigi tomonda muvaffaqiyatli bo‘lgan bo‘lishi mumkin.
gcloud compute routes create openvpn-return \
--network=prod-vpc \
--destination-range=192.168.127.0/24 \
--next-hop-instance=openvpn-vm \
--next-hop-instance-zone=europe-west1-b \
--priority=800Xuddi shu route VPC ichida emas, mijoz orqasida turgan har qanday prefix uchun kerak. O‘sha prefixlarga o‘sha mijozning ccd faylida iroute yozuvi ham kerak. Bu yozuv server tomonidagi hisob: serverga qaysi mijoz prefixga ega ekanini aytadi va mijozning o‘ziga hech narsa o‘rnatmaydi.
Push ro‘yxatini suhbatning mijoz tomoni uchun qoldiring, chunki u faqat ulanayotgan mashinaga routelar qo‘shadi. VPC subneti uchun push satri va poolga qaytuvchi VPC route — bir yo‘lning ikki yarmi, va har qanday yarim yolg‘iz o‘zi so‘rovlarni tashigan, ammo javoblarni tashimagan tunnel yaratadi.
Firewalllar, forwarding va oradagi hoplar
VPC firewalli dekapsulyatsiya qilingan paketni baholaydi, shuning uchun ingress qoidasi tunnel poolni va shu yo‘l bilan VMga yetadigan har qanday sayt prefixini ruxsat berishi kerak. Default-deny pozitsiyasi bu yerda jimgina muvaffaqiyatsiz bo‘ladi: paket dekapsulyatsiyadan keyin tashlanadi va OpenVPN jurnali sog‘lom sessiyani ko‘rsatadi.
O‘tkazadigan, lekin tugatmaydigan har qanday Linux hostda net.ipv4.ip_forward yoqilganini tekshiring. Egalik qoidasi u yerda ham amal qiladi: o‘zi ega bo‘lmagan subnet uchun o‘tkazadigan mashina paketni VM kabi tashlaydi. Tunnelni ayblashdan oldin qiymatni o‘qing.
Aynan bitta prefix muvaffaqiyatsiz bo‘lganda
Qismiy nosozlik o‘qish uchun eng yengil holat, chunki yo‘ldagi qolgan hamma narsa allaqachon isbotlangan. Route ro‘yxatidan boshlang va prefixni qoplashi kerak bo‘lgan yozuvning manzil diapazoni va next hopini o‘qing, so‘ng instans tavsifini o‘qib, uning alias diapazonini server tarqatadigan pool bilan solishtiring.
gcloud compute routes list --filter=destination-range~10.164.0.0
gcloud compute instances describe openvpn-vm --format=get(networkInterfaces[0].aliasIpRanges)Yetishmayotgan route prefix uchun next hop yo‘qligi sifatida ko‘rinadi, yetishmayotgan alias esa interfeysda tashlangan paket sifatida; mijoz tomondan ikkisi o‘xshash ko‘rinadi va o‘sha ikki chiqishda butunlay boshqacha. Ikkisi ham bo‘lsa, qolgan gumondor — prefixga da’vo qilayotgan mijozning ccd iroutei.
To‘rt qiymatni tunnel yoniga yozib qo‘ying: alias diapazoni, server pooli, push qilingan prefixlar, VPC routelari. Eskirgan alias pooldagi har bir manzilni buzadi, eskirgan route bir yo‘nalishni buzadi, yetishmayotgan push prefixni mijozdan yashiradi va noto‘g‘ri iroute prefixni noto‘g‘ri peerga yuboradi. Subnet qo‘shadigan keyingi odamga to‘rttasi ham bir joyda kerak va bu eslatma kechqurundan arzon.