Tunel konteyneriniz işləyir, docker compose exec vpn curl -s https://ifconfig.me provayderin ünvanı ilə cavab verir, amma masaüstünüzdəki brauzer hələ də internet provayderinizdən çıxır. Bu fərq gözləniləndir. VPN müştərisini işlədən konteyner şəbəkə adlar məkanı, marşrutlar və tunel interfeysi saxlayır, HTTP və ya SOCKS danışan heç nə saxlamır; ona port yayımlamaq heç vaxt olmayan dinləyici yarada bilməz.

Müştərinin harada işləməsi dizaynı müəyyən edir. Qardaş konteyner tunelin adlar məkanına keçə bilər, masaüstü tətbiqi keçə bilməz, marşrutlaşdırıcıya isə proxy sahəsi deyil, marşrutlar lazımdır. Xəritələməni səhv etsəniz, simptom eynidir: bağlantı rədd edildi və ya trafik sakitcə köhnə yolla gedir.

Quruluşu müştərinin işlədiyi yerə uyğunlaşdırın

Compose-u redaktə etməzdən əvvəl bir sual verin: müştəri VPN konteynerinin şəbəkə adlar məkanı daxilində başlada bilərmi? Artıq Linux konteyneri kimi işləyən hər şey bilər. Masaüstünüzdəki brauzer, IDE və ya CLI bilməz, çünki onun proxy ayarı protokol xidməti gözləyir, adlar məkanı deyil.

ClientArrangementWhat must already exist
Another Compose serviceShares the vpn namespace via network_mode: service:vpnA working tunnel and correct start order
Host browser, IDE or CLIProxy listener inside the namespace, published to host loopbackA configured SOCKS or HTTP proxy and its access rules
Router, VM or phoneThe container as a layer-3 gatewayForwarding, NAT and a return route

Bu üçü qarışmır. Konteynerin körpü ünvanına yönəldilmiş HTTP proxy sahəsi, orada proxy dinləmirsə heç nəyə çatmır, proxy dinləyicisi isə marşrutlaşdırıcının trafikini yönləndirmir. Əvvəlcə qərar verin, sonra uyğun bölməni izləyin.

Tunel adlar məkanını qardaş konteynerlə paylaşın

Bu, ən ucuz variantdır, çünki heç bir proxy protokolu iştirak etmir. Tətbiq vpn xidmətinin adlar məkanına qoşulur və onun interfeyslərini, marşrutlarını və port sahəsini miras alır:

services:
  vpn:
    image: your-vpn-client
    cap_add:
      - NET_ADMIN
    healthcheck:
      test: ["CMD-SHELL", "ip link show tun0 >/dev/null"]
      interval: 10s
      retries: 5
  app:
    image: your-app
    network_mode: service:vpn
    depends_on:
      vpn:
        condition: service_healthy

Adlar məkanının başqa xidmətə aid olmasından üç məhdudiyyət doğur. Tətbiq öz networks açarını almır, çünki qoşulacaq adlar məkanı yoxdur. Port yayımı vpn üzərindədir, çünki adlar məkanı orada yaşayır. Və vpn-i yenidən yaratmaq tətbiqin qoşulduğu adlar məkanını məhv edir, ona görə docker compose up -d --force-recreate vpn sizi app-ı da yenidən yaratmağa qoyur; adi yenidən başlatma həmişə kifayət etmir. Compose xidmət arayışı bu quruluşu və port yayımı məhdudiyyətini əhatə edir.

Həlledicinin özü ilə gəldiyini güman etməyin. /etc/resolv.conf hər konteynerə aid fayldır, şəbəkə adlar məkanının hissəsi deyil, ona görə tətbiq paketləri tuneldən çıxarkən yenə də hostun həlledicisini soruşa bilər. Onu konteynerin içindən oxuyun və şəxsi adlar tuneldən həll olunmalıdırsa, tətbiqdə dns: təyin edin.

docker compose exec app ip route
docker compose exec app cat /etc/resolv.conf
docker compose exec app curl -s https://ifconfig.me

Əgər marşrut siyahısında tunel interfeysi varsa və ünvan provayderinkidirsə, tətbiq tunelin içindədir. İnterfeys yoxdursa, app vpn-in tuneli olmadan əvvəl başlamışdır, ona görə vpn sağlam hesabat verdikdən sonra app-ı yenidən yaradın.

Host müştəriləri üçün adlar məkanına real proxy dinləyicisi qoyun

Masaüstü brauzeri adlar məkanına qoşula bilməz, ona görə tunel xidmət kimi açılmalıdır. vpn adlar məkanı daxilində həqiqi SOCKS və ya HTTP proxy işlədin və yalnız onun portunu yayımlayın:

services:
  vpn:
    ports:
      - "127.0.0.1:1080:1080"
  proxy:
    image: your-proxy
    network_mode: service:vpn
    command: ["--socks", "0.0.0.0:1080"]

Host tərəfindəki ünvan həmin xəritələmənin vacib yarısıdır. Soldakı 127.0.0.1:1080 dinləyicini LAN-dan kənarda saxlayır; təkbaşına "1080:1080" isə maşınınıza çata bilən hər cihaza açıq proxy yayımlayır.

Konteyner tərəfinin öz tələsi var. Yayımlanan portlar konteynerin körpüdəki ünvanına çatdırılır, loopback-ına deyil, ona görə adlar məkanı daxilində --socks 127.0.0.1:1080 ilə başladılan proxy qardaşlardan gələn bağlantıları qəbul edir və yayımlanan portdan gələn hər şeyi rədd edir. Onu 0.0.0.0 ünvanına bağlayın və təcrid üçün host tərəfindəki loopback bağlamasına güvənin. Eyni qayda proxy konfiqurasiya faylındakı dinləmə ünvanına da aiddir.

Sonra adların harada həll olunduğuna qərar verin. curl-də --socks5 host adını yerli həll edir, --socks5-hostname isə adı proxy-yə göndərir; brauzerlər eyni açarı başqa etiket altında təqdim edir. Yerli həll, səhifə tuneldən yüklənsə belə, sorğunu sızdırır.

Konteyneri yalnız geri marşrutla şlüz kimi qəbul edin

Marşrutlaşdırıcılar, VM-lər və telefonlar HTTP proxy sahəsindən istifadə etməyəcək, bəzi tətbiqlər isə proxy dəyişənlərini tamamilə nəzərə almır. Onların trafikini yönləndirmək 3-cü qat deməkdir: konteyner paketləri ötürür və tunel interfeysində ünvanları çevirir.

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

İki şeyi asanlıqla qaçırmaq olar. Müştəriyə defolt şlüzünü bu hosta yönəldən marşrut lazımdır və cavablar geri yol tapmalıdır: ya yuxarı marşrutlaşdırıcıda statik marşrutla, ya da müştərilərə baxan interfeysdə NAT ilə. Bunlardan biri olmadan tunel sorğunu çölə aparır və cavab yox olur.

Həm də ən geniş təsir radiusuna malikdir. Bütün LAN üçün şlüz rolunu oynayan host hər səhv konfiqurasiya edilmiş müştərini VPN hesabınızdan keçirir, tunelin düşməsi isə ya LAN-ı qaraldır, ya da kill switch-dən asılı olaraq provayderə qayıdır.

Çıxış yolunu yoxlayın, sonra sıra ilə geri qaytarın

Bu sıra ilə yoxlayın və ilk uğursuzluqda dayanın: adlar məkanı daxilində çıxış ünvanı, hostdan proxy vasitəsilə çıxış ünvanı, sonra şəxsi host üçün ad həlli.

docker compose exec vpn curl -s https://ifconfig.me
curl -s -x socks5h://127.0.0.1:1080 https://ifconfig.me
curl -s -x socks5h://127.0.0.1:1080 http://internal.example/health

İlk iki ünvan provayderlə uyğun gəlməlidir, üçüncüsü isə ad xətası ilə uğursuz olmaq əvəzinə proxy vasitəsilə həll olunmalıdır. Uyğun gələn birinci sətir və uğursuz ikinci sətir dinləyicinin və ya yayımlanan portun səhv olduğunu bildirir, tunelin deyil.

Geri qaytarmaq quraşdırmanın tərsidir. Proxy mühit dəyişənlərini shell profilindən və hər hansı systemd vahidindən silin, sonra stack-i aşağı salın ki, ortaq adlar məkanı sahibi ilə birlikdə yox olsun. Yayımlanan portu proxy xidmətini silməzdən əvvəl silin, əks halda host heç nəyin oxumadığı loopback dinləyicisini saxlayır.

Davam etməzdən əvvəl dörd şeyi təsdiqləyin: əhəmiyyət verdiyiniz müştəri həqiqətən tunelə çatır, portları yalnız adlar məkanının sahibi yayımlayır, şəxsi adlar nəzərdə tutduğunuz yerdə həll olunur və loopback olmayan host ünvanında heç nə dinləmir. Bunların hər biri istehsalatda səssizcə uğursuz olur və hər biri yuxarıdakı bir sətirlik yoxlamadır.

Əlaqəli məqalələr