Skip to content

Instantly share code, notes, and snippets.

@jvdi
Last active August 7, 2024 09:52
Show Gist options
  • Save jvdi/913549b4e329b9382459033322bf393d to your computer and use it in GitHub Desktop.
Save jvdi/913549b4e329b9382459033322bf393d to your computer and use it in GitHub Desktop.
Set Up a dockerize Wireguard VPN Server over WebSocket Tunneling

This tutorial good for Linux or Unix system at the end need to run bash script for connect
(Also it's have some technic for use in windows - Explained at client install section.)

VPS => virtual private server as wiregurd vpn server

Requirements

  • Assuming the firewall is off (Not Secure - it's just for test so in production: config firewall)
  • VPS have docker and docker-compose (for install instrucrion : docker site full explained)
  • In VPS enable net.ipv4.ip_forward=1 at /etc/sysctl.conf (or /etc/sysctl.d/99-sysctl.conf) and reboot your system
  • Have access to root user in VPS
  • replace:

Install Wireguard at VPS by docker

version: "2.1"
services:
  wireguard:
    image: lscr.io/linuxserver/wireguard:latest
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE #optional
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Tehran
      - SERVERURL=auto #optional
      - SERVERPORT=51820 #optional
      - PEERS=peer1,peer2 #optional
      - PEERDNS=8.8.4.4,8.8.8.8 #optional
      - ALLOWEDIPS=0.0.0.0/0 #optional
    volumes:
      - ~/projects/wireguard/config:/config
      - /lib/modules:/lib/modules #optional
    ports:
      - 51820:51820/udp
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped


Save to: docker-compose.yml
and move to: /root/projects/wireguard/
and in /root/projects/wireguard/ run : docker-compose up -d

Install wstunnel by docker in VPS

docker run --network host -d -e COMMAND="/usr/local/bin/wstunnel -v --server ws://0.0.0.0:33344 --restrictTo=127.0.0.1:51820" --name wstunnel --restart unless-stopped javidi/wstunnel

Get free Cert for your domain by docker in VPS

docker run --rm -p 80:80 -p 443:443 -v ~/projects/certs:/etc/letsencrypt certbot/certbot certonly -d sub.domain.com --standalone -m your_email@mailserver.com --agree-tos

Install nginx for revese proxy by docker in VPS

server {
    server_name sub.domain.com;
    listen 443 ssl;

    # Only allow access if the host is correct
    if ( $host != "sub.domain.com" ){
        return 444; #CONNECTION CLOSED WITHOUT RESPONSE
    }

    ssl on;
    ssl_certificate /etc/nginx/certs/sub.domain.com/fullchain1.pem;
    ssl_certificate_key /etc/nginx/certs/sub.domain.com/privkey1.pem;
    
    location / {
        return 404;
    }

    location /svmvvvhDqtyd54zsP/ {
        proxy_pass http://172.17.0.1:33344; #host ip in docker network (if you not use docker nginx - use 127.0.0.1)
        proxy_http_version  1.1;
        proxy_set_header    Upgrade $http_upgrade;
        proxy_set_header    Connection "upgrade";
        proxy_set_header    Host $http_host;
        proxy_set_header    X-Real-IP $remote_addr;

        proxy_connect_timeout       10m;
        proxy_send_timeout          10m;
        proxy_read_timeout          90m;
        send_timeout                10m;
   }
}


Save to: sub.domain.com.conf
and move to: /root/projects/nginx/
and run :

# Crete a network for other service
docker network create ngx-rev
# Run nginx server for Reverse-Proxy
docker run --net ngx-rev -itd -v ~/projects/nginx:/etc/nginx/conf.d -v ~/projects/certs/archive/:/etc/nginx/certs/ -p 80:80 -p 443:443 --name ngx-rev-proxy --restart=unless-stopped nginx

So in the Client 🎆:

Install Wireguard in Client

  • Linux : sudo apt install wireguard-tools
  • Mac : brew install wireguard-tools (Like Ubuntu)
  • Windows : Download setup file of wireguard client for windows from Wireguard website

Install WebSocket Tunnel on Client (Windows > 8):

1.Enable (preup and postup and postdown) script in wireguad:
- open cmd as admin in your windows
- run:
- reg add HKLM\Software\WireGuard /v DangerousScriptExecution /t REG_DWORD /d 1 /f
2.Add Your host Custom IP (optional - if you need) - fill detail and add this text to end of hosts file of windows in c:\Windows\System32\Drivers\etc\hosts:


# Added by Wg Over WS-Tunnel
ws-server-ip_OR_cdn-server-ip yourdomain.com
# End of section

3.Create "WireGuardWS-Tunnel" folder in "C:" (root of drive C)
download needed tools:

@echo off

for /f %%g in ('powershell -Command "(Get-NetRoute -DestinationPrefix '0.0.0.0/0').NextHop"') do set DefaultGateway=%%g
for /f "tokens=2" %%i in ('nslookup %1 ^| findstr /C:"Address"') do set IPAddress=%%i

:: add_route_to_main_gway_for_tunnel
route add %IPAddress% mask 255.255.255.255 %DefaultGateway%
C:\WireGuardWS-Tunnel\nssm.exe start "WireGuardWS-Tunnel"
  • Create PostDown.bat file in C:\WireGuardWS-Tunnel:
@echo off

for /f %%g in ('powershell -Command "(Get-NetRoute -DestinationPrefix '0.0.0.0/0').NextHop"') do set DefaultGateway=%%g
for /f "tokens=2" %%i in ('nslookup %1 ^| findstr /C:"Address"') do set IPAddress=%%i

C:\WireGuardWS-Tunnel\nssm.exe stop "WireGuardWS-Tunnel"
:: del_route_to_main_gway_for_tunnel
route delete %IPAddress% mask 255.255.255.255 %DefaultGateway%

4.run cmd in "C:\WireGuardWS-Tunnel" [with this command cd C:\WireGuardWS-Tunnel`` ] directory and enter:
- .\nssm.exe install "WireGuardWS-Tunnel"
5.in new opened window - set:
- Path: C:\WireGuardWS-Tunnel\wstunnel.exe
- Start directory: C:\WireGuardWS-Tunnel

- Argument:
--quiet --udpTimeoutSec -1 --upgradePathPrefix "ENTER_YOUR_NGINX_PREFIX" --udp -L 127.0.0.1:51820:127.0.0.1:51820 wss://yourdomain.com:443
- Arg for wstunnel-v7.9.0:
client --log-lvl OFF --tls-verify-certificate --tls-sni-override yourdomain.com --http-upgrade-path-prefix "ENTER_YOUR_NGINX_PREFIX" -L udp://127.0.0.1:51820:127.0.0.1:51820?timeout_sec=0 wss://yourdomain.com:443

- In Detail tab -> Startup type: Manual and Display name: WireGuard WS-Tunnel
6.Click on: Install service
7.open wireguard client and Import your wireguard config file (get config from wireguard server)
7.In Wireguard client click on your connection and click on edit connecton:
- set(write this line in connection)

  • get ip of yor domain by ping yourdomain.com command in cmd and get default gateway by ipconfig command in cmd:
    PreUp = "C:\WireGuardWS-Tunnel\PreUp.bat YOUR_DOMAIN"
    PostDown = "C:\WireGuardWS-Tunnel\PostDown.bat YOUR_DOMAIN"
    
    • uncheck Block untunneled traffic (kill-switch) in wireguard gui
    • Clock on: Save
      7.Click on Connect

Install WebSocket Tunnel on Client (Linux):


if you not have resolvconf run:
- ubuntu : ```sudo apt install resolvconf```
wget https://github.com/erebe/wstunnel/releases/download/v5.0/wstunnel-linux-x64
# if you get a zip file - extract it with unzip command then continue
# maybe name in next versions change
sudo mv wstunnel-linux-x64 /usr/local/bin/wstunnel
sudo chmod +x /usr/local/bin/wstunnel

Get this bash script for automation run Tunneling befor wireguard and down next (wireguard down) and ...

wget https://raw.githubusercontent.com/jvdi/wireguard-over-wss/patch-1/wstunnel.sh
sudo mv wstunnel.sh /etc/wireguard/wstunnel.sh
sudo chmod +x /etc/wireguard/wstunnel.sh

Get wg Client Config from server

scp root@VPS-ip:/root/projects/wireguard/config/peer_peer1/peer_peer1.conf ~/
then sudo mv ~/peer_peer1.conf /etc/wireguard/wg0.conf and change end point ip in /etc/wireguard/wg0.conf like this:

[Interface]
Address = 10.13.13.2 # not change
PrivateKey = ... # not change
# ListenPort = 51820 # remove -- just delete this line or set this line as a comment 
DNS = 8.8.4.4,8.8.8.8 # not change

Table = off # add
PreUp = source /etc/wireguard/wstunnel.sh && pre_up %i # add
PostUp = source /etc/wireguard/wstunnel.sh && post_up %i # add
PostDown = source /etc/wireguard/wstunnel.sh && post_down %i # add

[Peer]
PublicKey = ... # not change
PresharedKey = ... # not change
Endpoint = 127.0.0.1:51820 # chnage to it
AllowedIPs = 0.0.0.0/0 # not change

Create the wstunnel configuration file for shell script

REMOTE_HOST=sub.domain.com
REMOTE_PORT=51820
UPDATE_HOSTS='/etc/hosts'
WS_PREFIX='svmvvvhDqtyd54zsP' #Set in nginx conf
# other config like change port or ... in script's doc

and save to : /etc/wireguard/wg0.wstunnel

If use CDN

add : REMOTE_IP="0.1.2.3" # set a ip of your cdn (for find ip -> ping your cdn domain) :) in the end of /etc/wireguard/wg0.wstunnel

Start WireGuard

sudo wg-quick up wg0

Stop WireGuard

sudo wg-quick down wg0
البته پیشنهاد میکنم از همون بالا با راهنمای انگلیسی پیش برید
آموزش فارسی (منبع در زیر ذکر شده - با تشکر فراوان از نویسنده اصلی - من فقط داکر چسباندم بهش و بنظر خودم بعضی جاهاشو تغییر دادم بهتر بشه)

CDN

خب اول یک دامنه یا ساب دامنه انتخاب کنید و یک A رکورد به مقدار آی پی سرور خارجی و پرت HTTPS بسازید. سی دی ان داخلی باشه، باید روی آن ابر یا SSL , Proxy یا رمزنگاری رو فعال کنید تا ترافیک هم رمز بشه و هم از سرور هاش عبور کنه تا سرعت بهتر بشه (و ترجیحا اتصال مستقیم به سرور نباشه)

SSL

خب برای اون دامنه باید اس اس ال داشته باشید با این فایل ها fullchain.pem, privkey.pem, chain.pem, dhparam.pem آموزش گرفتن اس اس ال هم که زیاده. (dhparam- Diffie–Hellman (D-H))

من قانع نشدم از dhparam استفاده کنم همون fullchain و privkey هم کفایت میکنه - با یه دستور ساده داکر در بالا تو ضیح داده شده که چطور ssl بگیرید

WireGuard Server

wget https://git.io/wireguard -O wireguard-install.sh && bash wireguard-install.sh

کافیه این اسکریپت رو روی سرور ران کنید و بوم. با wg0.confسرور کاری نداریم. ولی فایل کانفیگ که برای کلاینت میسازه رو باید تغییر بدیم مختصر - پیشنهاد من استفاده از نسخه داکر وایرگارد هست - خیلی بهتره

NGINX

کانفیگ nginx در بالا آورده شده

  • مسیر فایل های اس اس ال رو درست کنید

Client.conf

فایل کلاینت بعد از تغییر همچین چیزی میشه.

[Interface]
Address = 10.10.1.2/24
DNS = 8.8.8.8, 8.8.4.4
# اگر از نسخه داکر استفاده کنید یه listenport داره اونو حذف کنید
# <= این ۴خط هم اضافه میشه =>
Table = off
PreUp = source /etc/wireguard/wstunnel.sh && pre_up %i
PostUp = source /etc/wireguard/wstunnel.sh && post_up %i
PostDown = source /etc/wireguard/wstunnel.sh && post_down %i

PrivateKey = ....

[Peer]
PublicKey = ....
PresharedKey = ....
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = 127.0.0.1:51820          # <= این از آی پی سرور تغییر میکنه به لوکال
PersistentKeepalive = 25

Wstunnel Server

  • به آدرس زیر میرید و نسخه مربوطه هم برای سرور و کلاینت رو دانلود میکنید(در بالا یه نسخه داکر هم من ساختم براش)
    • https://github.com/erebe/wstunnel/releases/
wget https://github.com/erebe/wstunnel/releases/download/v4.1/wstunnel-x64-linux
mv wstunnel-x64-linux /usr/local/bin/wstunnel
chmod uo+x /usr/local/bin/wstunnel
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/wstunnel

Wstunnel Service in Server

  • یک فایل سرویس سیستم دی در مسیر زیر و محتویات پایین درست میکنید
    • /etc/systemd/system/wstunnel.service
[Unit]
Description=Tunnel WG UDP over websocket
After=network.target

[Service]
Type=simple
User=nobody
ExecStart=/usr/local/bin/wstunnel -q --server ws://127.0.0.1:33344 --restrictTo=127.0.0.1:51820
Restart=no

[Install]
WantedBy=multi-user.target
  • 33344: همون پورتی که برای کانفیگ nginx انتخاب کردید
  • 51820: پورت دیفالت وایرگارد.اگه تغییر دادید هرجایی این پورت بود توی تنظیمات عوضش کنید

سرویس رو با دستور زیر اجرا میکنید و وب سوکت راه میوفته sudo systemctl enable --now wstunnel.service چک کنید سرویس درست راه اندازی شده باشه sudo systemctl status wstunnel.service

Enable IP Forward

توی فایل زیر قسمت net.ipv4.ip_forward=1 رو از حالت کامنت خارج کنید و سرور رو ریستارت کنید.

  • /etc/sysctl.d/99-sysctl.conf

Client Side

wg-quick

برای وصل شدن به وایرگارد باید این نصب بشه

WireGuard Config

اول با دسترسی روت این مسیرها رو ایجاد کنید

  • /var/run/wireguard/
  • /etc/wireguard/

فایل client.conf که قبلا سرور برامون ساخته بود و ما تغییرش دادیم رو با اسم wg0.conf روی مسیر زیر میریزیم

  • /etc/wireguard/wg0.conf
  • sudo bash -c "chown root wg0.conf && chmod 640 wg0.conf"

wstunnel

برای کلاینت هم سوکت رو نصب میکنید.چک کنید نسخه ها آخری باشه.

wget https://github.com/erebe/wstunnel/releases/download/v5.0/wstunnel-linux-x64
# if you get a zip file - extract it with unzip command then continue
# maybe name in next versions change
sudo mv wstunnel-linux-x64 /usr/local/bin/wstunnel
sudo chmod +x /usr/local/bin/wstunnel

wg0.wstunnel

فایل کانفیگ وب سوکت رو توی مسیر زیر با محتویات پایین میسازیم

  • /etc/wireguard/wg0.wstunnel
REMOTE_HOST=yourdomain.com
REMOTE_PORT=51820
UPDATE_HOSTS='/etc/hosts'
WS_PREFIX='E7m5vGDqryd55MMP'
  • yourdomain.com: همونی که گذاشتید پشت سی دی ان
  • E8m4vGDqrydhgfjlP: همون مسیر رندومه توی nginx

wstunnel.sh

این اسکریپت کارهای روتینگ رو انجام میده که کل ترافیک لازم ما از وایرگارد از داخل سوکت رد بشه.

wget https://raw.githubusercontent.com/jvdi/wireguard-over-wss/patch-1/wstunnel.sh
sudo mv wstunnel.sh /etc/wireguard/wstunnel.sh
sudo chmod +x /etc/wireguard/wstunnel.sh

فقط چون سرویس ما قراره پشت سی دی ان باشه یه کانفیگ به فایل/etc/wireguard/wg0.wstunnel اضافه میکنیم

  • شما این خط رو کامنت میکنی
    • REMOTE_IP="0.1.2.3" # set a ip of your cdn (for find ip -> ping your cdn domain) :)
  • و در خط بالا آی پی سرور سی دی ان رو هارد کد کن (فقط آی پی باید آی پی سرور سی دی ان باشه با پینگ دامنه متصل به سی دی ان می توان آی پی پیدا کرد - اگر میخواهید از سی دی ان استفاده کنید)

Start WireGuard

sudo wg-quick up wg0

Stop WireGuard

sudo wg-quick down wg0

یه توضیح کوچک

اینکه این اسکریپت فقط برای آزمایش درست شده و حتی در نسخه ویندوزی هم چیزی نیست که به منظوره تجاری بشه استفاده کرد و اینکه من بگم این پروژه رو من از جاهای دیگه ای که منابعش رو در آخر همین نوشته ذکر کردم برداشتم و کامل ترش کردم و یه بخش هایی اضافه کردم و بهترش کردم و برام جالب بود که میشه اینکار رو کرد و اینکه چقدر کارایی میدهد.

اگر شما حوصله داشتید - یعنی اگر خودم حوصله داشته باشم شاید یه روز با grpc هم پیاده سازیش کردم - موفق و پیروز باشید

Notice

This project for me just for fun (We have very faster way than Wireguard about ****** 😊😁) - so it's just a test for fun
and i'm not goood in English grammar so ... (thankyou for your patient)

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment