SSD Nodes Learn Hosting plans →
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-09-01

Docker Compose मध्ये wg-easy WireGuard सेटअप

Docker Compose मध्ये wg-easy साठी ports, NET_ADMIN आणि आवश्यक sysctls योग्यरीत्या सेट करा. Version 15 मधील बदल व phone साठी QR code onboarding जाणून घ्या.

तुम्ही काय तयार करणार आहात

wg-easy हे web interface असलेले WireGuard आहे. ते एकाच Docker container मध्ये चालते. ते WireGuard interface तुमच्यासाठी व्यवस्थापित करते आणि clients तयार करण्यासाठी browser UI देते. तुम्ही तयार केलेल्या प्रत्येक client ला config file आणि QR code मिळतो. त्यामुळे phone ला VPN शी जोडण्यासाठी camera स्क्रीनकडे रोखणे पुरेसे असते.

Tunnel स्वतः नेहमीचे WireGuard असते. Kernel module packets पुढे पाठवते, त्यामुळे throughput हाताने लिहिलेल्या setup प्रमाणेच राहतो. SSH द्वारे config file संपादित न करता peers जोडणे, disable करणे आणि delete करणे हे client lifecycle व्यवस्थापनामुळे शक्य होते. मात्र त्या config वरचे थेट नियंत्रण कमी होते. याच विषयाची माहिती VPS वरील manual WireGuard setup मध्ये आहे.

तुमच्याकडे public IPv4 address असलेला KVM VPS, Compose plugin सह Docker Engine आणि root access असणे आवश्यक आहे. OpenVZ किंवा LXC सारखे host kernel share करणारे container virtualization प्रकार सहसा WireGuard module load करू शकत नाहीत. त्यामुळे container interface सुरू करण्यात अपयशी ठरते.

Version 15 मध्ये settings environment मधून काढण्यात आल्या

तुम्हाला सापडणाऱ्या बहुतेक मार्गदर्शिका wg-easy 14 साठी लिहिलेल्या आहेत. त्यामध्ये WG_HOST मध्ये server address आणि PASSWORD_HASH मध्ये admin password चा bcrypt hash, ही दोन्ही मूल्ये environment variables म्हणून सेट केली जात. Version 15 ही पुन्हा लिहिलेली आवृत्ती आहे. अधिकृत migration notes मध्ये स्पष्टपणे सांगितले आहे की v15 मध्ये v14 सारखीच environment variables वापरली जात नाहीत आणि त्यांपैकी बहुतेक settings web UI मधील admin panel मध्ये हलवण्यात आल्या आहेत.

त्यामुळे WG_HOST आणि PASSWORD_HASH यांचा आता कोणताही परिणाम होत नाही. तुम्ही जुनी compose file कॉपी केल्यास container सुरू होतो, त्या lines दुर्लक्षित करतो आणि त्यानंतर browser मध्ये admin account तयार करण्यास सांगतो. ही bug नाही. ही नवीन setup flow आहे.

July 2026 पर्यंत pin करण्यासाठी major tag 15 आहे. latest वापरण्याऐवजी major version pin करा, कारण major upgrade मुळे on-disk config format बदलतो आणि rollback व्यवस्थित होत नाही.

Compose फाइल

Stack साठी एक directory तयार करा आणि त्यात अधिकृत compose फाइल लिहा. ही upstream फाइल कोणताही बदल न करता वापरलेली आहे.

sudo mkdir -p /etc/docker/containers/wg-easy
sudo curl -o /etc/docker/containers/wg-easy/docker-compose.yml \
  https://raw.githubusercontent.com/wg-easy/wg-easy/master/docker-compose.yml

मजकूर असा दिसतो:

volumes:
  etc_wireguard:

services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy:15
    container_name: wg-easy
    networks:
      wg:
        ipv4_address: 10.42.42.42
        ipv6_address: fdcc:ad94:bacf:61a3::2a
    volumes:
      - etc_wireguard:/etc/wireguard
      - /lib/modules:/lib/modules:ro
    ports:
      - "51820:51820/udp"
      - "51821:51821/tcp"
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.ip_forward=1
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv6.conf.all.disable_ipv6=0
      - net.ipv6.conf.all.forwarding=1
      - net.ipv6.conf.default.forwarding=1

networks:
  wg:
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: 10.42.42.0/24
        - subnet: fdcc:ad94:bacf:61a3::/64

etc_wireguard हा server key आणि तुम्ही तयार केलेला प्रत्येक client ठेवणारा named volume आहे. या volume चा backup घ्या; अन्यथा rebuild केल्यावर तुमचे सर्व peers नष्ट होतील. या फाइल्स host filesystem वर पाहायच्या असल्यास, त्याऐवजी bind mount वापरा. तसे करण्यापूर्वी bind mount आणि named volume मधील फरक वाचा, कारण त्यांचे permissions वेगळ्या पद्धतीने कार्य करतात.

NET_ADMIN, SYS_MODULE आणि sysctls का आवश्यक आहेत

डीफॉल्टनुसार कंटेनरला network stack मध्ये बदल करण्याची परवानगी नसते. या प्रत्येक ओळीमुळे एक विशिष्ट अडथळा दूर होतो.

NET_ADMIN मुळे कंटेनरला wg0 interface तयार करता येतो, त्याला address देता येतो आणि routes लिहिता येतात. हे नसल्यास interface सुरू करताना कंटेनर सुरू होऊन लगेच बंद होतो, कारण ip link add wg0 type wireguard कडून Operation not permitted परत मिळते.

SYS_MODULE आणि read-only /lib/modules mount मुळे host वर WireGuard kernel module आधीपासून load केलेला नसल्यास कंटेनर तो load करू शकतो. हा module image च्या आत नसून host kernel मध्ये असतो. त्यामुळे host directory कंटेनरला दिसणे आवश्यक आहे. आधुनिक kernel मध्ये हा module सहसा built in असतो. Host वर sudo modprobe wireguard && echo ok वापरून तुम्ही याची पुष्टी करू शकता.

net.ipv4.ip_forward=1 मुळे स्वतःच्या box ला उद्देशून नसलेली packets kernel forward करतो. हे नसल्यास client connect होतो आणि handshake यशस्वी होते. त्यानंतर internet कडे जाणारी प्रत्येक packet drop होते. त्यामुळे VPN connected दिसत असतानाही ping 1.1.1.1 timeout होते.

net.ipv4.conf.all.src_valid_mark=1 हे लोकांना सर्वाधिक आश्चर्यचकित करते. WireGuard स्वतःच्या outgoing packets वर mark लावतो, जेणेकरून त्या पुन्हा tunnel मध्ये route होणार नाहीत. Strict reverse path filtering ला source address अपेक्षित route शी जुळत नसलेली packet दिसते आणि तो ती drop करतो. हा sysctl kernel ला marked packets स्वीकारण्यास सांगतो. त्यामुळे full tunnel स्वतःच्याच network traffic मध्ये अडथळा आणत नाही.

ते सुरू करा आणि admin account तयार करा

cd /etc/docker/containers/wg-easy
sudo docker compose up -d
sudo docker compose logs -f

start आणि stop ऐवजी docker compose up आणि docker compose down वापरा. वेगवेगळ्या settings अंतर्गत तयार केलेल्या container वर start चालवल्यास network ची स्थिती विसंगत होते, असा upstream चा इशारा आहे. Reboot नंतर stack पुन्हा सुरू हवा असल्यास restart: unless-stopped हे आधीच त्यासाठी पुरेसे आहे. compose services चे boot behaviour हे policy काय करते आणि काय हमी देत नाही, हे स्पष्ट करते.

Web UI TCP 51821 वर listening करते. पहिल्यांदा उघडल्यावर setup page दिसते. त्यावर admin account तयार करा आणि clients server पर्यंत पोहोचण्यासाठी वापरतील तो host address निश्चित करा. हा host address प्रत्येक client config मधील Endpoint line मध्ये येतो. त्यामुळे तो VPS चा public IP किंवा DNS name असला पाहिजे. तो चुकीचा असल्यास, तुम्ही phone ला दिलेला QR code पोहोचता न येणाऱ्या पत्त्याकडे निर्देश करतो आणि handshake कधीही पूर्ण होत नाही.

त्या port विषयी आणखी एक महत्त्वाची बाब आहे: INSECURE=true सेट न केल्यास wg-easy 15 plain HTTP नाकारते. Untrusted certificate वापरून HTTPS द्वारे त्याच्यापर्यंत पोहोचणे किंवा त्याच्या समोर reverse proxy वर TLS termination करणे, दोन्ही योग्य पर्याय आहेत. Default settings सह http:// द्वारे त्याच्यापर्यंत पोहोचणे योग्य नाही.

इंटरनेटवर UI पोर्ट प्रकाशित करू नका

compose file मध्ये 51821 प्रत्येक interface वर प्रकाशित केलेला आहे. हे अशा मशीनसाठीचे login page आहे जी तुमचा traffic route करू शकते. त्यामुळे ते सर्वांसाठी खुले ठेवू नये. Docker मध्ये port प्रकाशित केल्यावर DOCKER chain मध्ये rules लिहिले जातात. ही chain ufw च्या आधी तपासली जाते. त्यामुळे ufw deny rule मुळे हा port बंद होत नाही. हा सापळा स्वतंत्रपणे समजून घेणे महत्त्वाचे आहे. Docker ने प्रकाशित केलेले ports ufw कडे दुर्लक्ष का करतात यामध्ये त्याचे संपूर्ण स्पष्टीकरण आहे.

सोपे उपाय म्हणजे UI ला loopback वर bind करणे आणि SSH tunnel द्वारे त्याच्यापर्यंत पोहोचणे:

    ports:
      - "51820:51820/udp"
      - "127.0.0.1:51821:51821/tcp"
    environment:
      - INSECURE=true

त्यानंतर तुमच्या laptop वरून:

ssh -L 51821:127.0.0.1:51821 youruser@your.server.address

तुमच्या laptop वरील browser मध्ये http://127.0.0.1:51821 उघडा. Traffic SSH द्वारे encrypted असतो. या port ला इतर कोणाकडूनही उत्तर मिळत नाही. तसेच plain HTTP hop loopback interface च्या बाहेर जात नसल्यामुळे INSECURE=true येथे सुरक्षित आहे.

UDP 51820 उघडा आणि दोन्ही firewall तपासा

WireGuard साठी इंटरनेटवरून UDP 51820 पर्यंत पोहोचता येणे आवश्यक आहे. Docker हा पोर्ट प्रकाशित करतो. मात्र अनेक providers VPS च्या पुढे स्वतंत्र network firewall ठेवतात. Docker ला त्याची माहिती नसते. त्यामुळे दोन्ही ठिकाणी हा पोर्ट उघडा. तुम्ही host firewall साठी ufw वापरत असल्यास, nftables हाताने लिहिण्यापेक्षा VPS साठीचे मूलभूत ufw नियम वापरणे अधिक सोपे आहे.

कंटेनर प्रत्यक्षात listening करत आहे का ते तपासा:

sudo ss -ulnp | grep 51820

तुम्हाला listening UDP socket दिसला पाहिजे. त्या ओळीत काहीही दिसत नसेल, तर कंटेनरने interface सुरू केलेला नाही. sudo docker compose logs wg-easy त्याचे कारण दाखवेल.

फोनवर client तयार करा आणि त्याचे scan करा

UI मध्ये client तयार करा आणि नंतर ओळखता येईल असे त्याला नाव द्या, उदाहरणार्थ तो ज्या device साठी आहे त्याचे नाव. wg-easy पुढील उपलब्ध tunnel address वाटप करते आणि तुमच्यासाठी key pair तयार करते. प्रत्येक client row मध्ये QR code आणि डाउनलोड करता येणारी .conf file असते.

फोनवर अधिकृत WireGuard app install करा. QR code मधून tunnel add करण्याचा पर्याय निवडा आणि स्क्रीनवरील code कॅमेऱ्यासमोर धरा. तुम्ही टाइप केलेल्या नावासह tunnel दिसेल. तो सुरू करा. त्यानंतर UI मधील client row मध्ये transfer counters आणि अलीकडील handshake time दिसू लागतो. फोन tunnel वर आल्यानंतर तो तुम्ही इंटरनेटवर प्रकाशित न केलेल्या services पर्यंत पोहोचू शकतो. त्यामुळे server चे एकही port संपूर्ण इंटरनेटसाठी खुले न ठेवता फोन कुठूनही self-hosted photo server वर upload करत राहू शकतो. हीच पद्धत media साठीही वापरता येते. 90s video store प्रमाणे पुन्हा तयार केलेली Jellyfin library LAN वर जितकी private राहते, तितकीच private ठेवून hotel room मधून पाहता येते. त्याच tunnel वर alerts उलट दिशेनेही कार्य करतात. self-hosted ntfy server public internet वरील request ला कधीही उत्तर न देता backup job fail होताच त्या फोनवर message push करू शकतो.

Client enable केल्यानंतर त्यामध्ये handshake दिसत नसेल, तर तो server पर्यंत पोहोचतच नाही. याचा संबंध UDP 51820 शी असतो. हा port provider firewall कडे किंवा config मध्ये समाविष्ट केलेल्या endpoint address कडे अडलेला असू शकतो. Client मध्ये handshake दिसत असेल, पण internet कार्यरत नसेल, तर कारण forwarding किंवा DNS मध्ये असण्याची शक्यता असते.

Desktop वर .conf file download करा आणि ती पुन्हा टाइप करण्याऐवजी WireGuard client मध्ये import करा. त्या file मधील private key एकदाच तयार केली जाते आणि एकदाच दाखवली जाते. या file कडे SSH private key प्रमाणेच सुरक्षिततेने पाहा.

UI ची मर्यादा कधी ओलांडावी

तुमचे peers म्हणजे माणसे आणि phones असतील, तोपर्यंत wg-easy हे योग्य साधन आहे. Configuration files संपादित करण्यापेक्षा UI अधिक वेगवान आहे. हरवलेल्या phone ची access एका click ने revoke करता येते.

UI मध्ये ज्या गोष्टींचे मॉडेल नाही, त्या आवश्यक झाल्यावर त्याची मर्यादा जाणवते. Site-to-site routing, ज्यामध्ये peer चे AllowedIPs एकाच address ऐवजी संपूर्ण remote subnet व्यापते, ही सहसा पहिली अडचण असते. प्रत्येक peer साठी स्वतंत्र routing rules असलेले split tunnels किंवा तुमच्या provisioning tool ने तयार केलेली config ही पुढची पायरी असते. त्या टप्प्यावर हाताने केलेली setup अधिक कठीण नसते; ती फक्त वेगळी असते. साध्या WireGuard मार्गदर्शकामध्ये wg0.conf वापरून तोच tunnel तयार करण्याची पद्धत दाखवली आहे. Control plane चालवणेच थांबवायचे असल्यास, WireGuard आणि Tailscale ची तुलना managed पर्याय स्पष्ट करते. हा बदल योग्य आहे की नाही हे coordination server प्रत्यक्षात कुठे पोहोचू शकतो यावर अवलंबून असते. तुमचे network त्याच्याकडे सोपवण्यापूर्वी Tailscale चे trust model वाचणे उपयुक्त ठरेल. पुढचा प्रश्न सहसा खर्चाचा असतो. Tailscale च्या free plan मध्ये प्रत्यक्षात काय समाविष्ट आहे हे household किंवा small team साठी पुरेसे आहे आणि त्यासाठी कोणताही खर्च येत नाही. त्यापुढे billing मध्ये devices ऐवजी users मोजले जातात. तुम्ही आधीच पैसे देत असलेल्या VPS च्या billing पेक्षा हा वेगळा खर्चाचा प्रकार आहे. त्यामुळे team migrate करण्यापूर्वी free plan ची मर्यादा ओलांडल्यानंतर Tailscale ची किंमत तपासा. तुम्ही नुकताच तयार केलेला full tunnel तिथे थेट उपलब्ध आहे. VPS ला Tailscale exit node म्हणून advertise करणे server मार्फत बाहेर जाण्यासाठी तोच route देते. हा route प्रत्येक client config मध्ये लिहिण्याऐवजी admin console मध्ये approve करता येतो. Subnet साठीही समान पर्याय आहे. VPS वरून संपूर्ण private network advertise करणे ते network tailnet मधील प्रत्येक device ला उपलब्ध करून देते. त्यामुळे UI सोडण्यास भाग पाडणारे per-peer AllowedIPs editing करावे लागत नाही. Dashboard आणि automatic mesh routing हवे असतील, पण दुसऱ्या संस्थेचा coordination server नको असेल, तर VPS वर स्वतःचा NetBird server चालवणे control plane तुमच्या मालकीच्या hardware वर ठेवते. मात्र त्यासाठी DNS आणि TLS setup करावी लागते, जी wg-easy मध्ये आवश्यक नव्हती.

वरील compose syntax हा WireGuard पेक्षा अपरिचित भाग असेल, तर VPS वरील Docker Compose ची मूलभूत माहिती file format आणि दैनंदिन commands स्पष्ट करते.

FAQ

wg-easy माझे WG_HOST आणि PASSWORD_HASH का दुर्लक्षित करते?

ही variables wg-easy 14 शी संबंधित आहेत. Version 15 ही नव्याने लिहिलेली आवृत्ती आहे आणि upstream ने जवळपास सर्व configuration web UI मधील admin panel मध्ये हलवले आहे. Container यापैकी कोणतीही variable वाचत नाही. त्यामुळे ते सामान्यपणे सुरू होते आणि पहिल्यांदा उघडल्यावर admin account तयार करण्यास सांगते. Setup page वर client-facing host address सेट करा.

माझ्या kernel मध्ये WireGuard आधीपासून असल्यास SYS_MODULE आवश्यक आहे का?

नाही. SYS_MODULE आणि /lib/modules mount मुळे host वर module उपलब्ध नसल्यास container ते load करू शकतो. sudo modprobe wireguard आधीपासून यशस्वी होत असलेल्या host वर ही capability वापरली जात नाही. ती काढून टाकणे हा योग्य hardening उपाय आहे. मात्र NET_ADMIN कोणत्याही परिस्थितीत आवश्यक आहे.

Client connect होतो, पण internet उपलब्ध नाही. काय चूक आहे?

Traffic नसलेला handshake जवळपास नेहमी forwarding कडे निर्देश करतो. net.ipv4.ip_forward=1 आणि net.ipv4.conf.all.src_valid_mark=1 अजूनही compose file मध्ये आहेत का ते तपासा, कारण manually edit केलेल्या copy मध्ये ते अनेकदा गहाळ होतात. Forwarding सुरू असल्यास client ला मिळालेला DNS server तपासा. VPN मार्फत सर्व traffic पाठवणारा tunnel, पण client ला यापुढे पोहोचता न येणाऱ्या DNS server कडे निर्देश करत असल्यास, browser मध्ये connection बंद असल्यासारखेच दिसते.

माझ्या clients चा backup कसा घ्यावा?

सर्व data etc_wireguard named volume मधील wg0.json file मध्ये असतो. UI मध्ये त्याच data चा export करणारे backup button देखील आहे. कोणतेही upgrade करण्यापूर्वी ही file server च्या बाहेर सुरक्षित ठिकाणी copy करा. नवीन container च्या setup step दरम्यान upload करून restore करता येते.

मी wg-easy reverse proxy मागे चालवू शकतो का?

होय. TCP 51821 च्या पुढे proxy ठेवा, तिथे TLS termination करा आणि proxy कडून येणारा plain HTTP hop स्वीकारण्यासाठी container वर INSECURE=true सेट करा. UDP 51820 थेट published ठेवा, कारण VPN traffic UDP वापरतो आणि HTTP proxy मधून जात नाही.