kiến thức [Đơn giản] Hướng dẫn tạo VPN Wireguard trên Mikrotik và kết nối từ điện thoại dễ nhất

ohyourgod

Senior Member
Giả sử có 1 router chạy Mikrotik để nhà, văn phòng và khi ra ngoài cần dùng điện thoại để truy cập về LAN, lấy tài liệu, in ấn, xem camera, không cần mở port.
Router cần chạy mikrotik v7 và đã cấu hình pppoe truy cập internet bình thường.
Các giao thức VPN PPTP và L2TP hiện tại Android, IOS đã dừng hỗ trợ, IPSEC thì cấu hình rất phức tạp.
(Tham khảo hướng dẫn kết nối Wireguard từ máy tính tới mikrotik)
Giải pháp nhanh gọn là dùng VPN Wireguard, hướng dẫn này gồm từng bước tạo và kết nối wireguard từ điện thoại (tạm thời chưa dùng QR hay import file để hiểu rõ hơn các bước cấu hình, tiện cho sửa lỗi về sau:

Bước 1. Tại winbox/ wireguard, tạo 1 New Interface với tên bất kì:
1713855081280.png


Bước 2. Tạo 1 IP Address List dành riêng cho wireguard cho dễ quản lý, địa chỉ bất kì, không trùng lặp là được, interface chọn wireguard interface đã tạo ở b1
1713882255610.png


Bước 3. Tải ứng dụng wireguard trên mobile về, Bấm +, create from scratch, copy public key vào đâu đó, chưa save vội.
1713855451720.png


Bước 4, tại router, wireguard / peers, add new wireguard peer
Dán public key ở bước 3 trên điện thoại vào đây, Allowed Address là IP sẽ cấp cho peer này khi nó kết nối (cần nằm trong subnet đã tạo ở B2), Apply
1713855770268.png

Tại tab Wireguard, copy public key ở đây
1713856063410.png


Bước 5, Trở lại app wireguard mobile bấm add peer ở phía dưới để mở rộng menu, cấu hình như hình rồi Save:
1713856479560.png


Bước 6, tại IP / Firewall, chain input, protocal udp, cho phép dst port 13231 (listen port ở bước 1), action = accept, OK rồi kéo nó lên đầu danh sách trước drop
1713856586735.png


Bước 7, Bây giờ từ điện thoại đã có thể kết nối thành công bằng 4G tới router qua wireguard rồi, nếu điện thoại chưa có quyền truy cập vào file sharing, máy in, webserver... trong LAN thì cần srcnat masquerade address list (tạo ở bước 2) như sau:
1713856775681.png
1713856809800.png



Kết quả, toàn quyền truy cập mạng LAN ở nhà từ xa thông qua 4G, có thể stream video 1080 bluray chất lượng cao
1713857211637.png
 
Last edited:
Sau khi cấu hình mọi thứ chạy rồi thì các bác có thể thí nghiệm tăng giá trị MTU trên client Android/iOS lên. Nếu không chỉnh sửa gì (để trống nó hiện auto như trên hình ở trên) thì MTU chỉ có 1280 thôi. Đây là giá trị tối thiểu cho phép với IPv6 (không thể set thấp hơn được nếu dùng IPv6). Trong mã nguồn cả client Android và iOS đều thấy rõ:



Xửa xưa thì client di động cũng có giá trị mặc định là 1420 (MTU mặc định 1500 bên ngoài tunnel - 80 bytes overhead nếu dùng IPv6, IPv4 thì chỉ cần 60) như trên client desktop, nhưng sau đó thì có quá nhiều vấn đề vì các mạng di động MTU đủ các kiểu loại giá trị, đa số không đủ 1500, và Path MTU Discovery nhiều nơi không hoạt động. Thế nên từ 6 năm trước chú viết WireGuard đã phải cho giảm MTU mặc định trên ứng dụng mobile xuống 1280, cũng không xuống được thấp hơn nếu muốn dùng được IPv6 trong tunnel.


Nhưng mà không có nghĩa là chúng ta phải dùng giá trị mặc định 1280 này, nhỏ quá thì tỉ lệ overhead đâm ra cao, kém hiệu quả. Như mạng di động của em thì nối vào peer WireGuard qua IPv4 thì có thể dùng được MTU 1380, còn nối vào peer IPv6 thì chỉ được 1376 là max. Dù sao cũng cao hơn giá trị mặc định 1280 bytes.

NẾU DÙNG peer IPv6: các bác có thể thử đặt MTU, bắt đầu từ 1420, rồi mở link speedguide.net/analyzer.php (SpeedGuide - Broadband, Wireless, Network Security (https://www.speedguide.net/analyzer.php)). Nếu nó treo cứng ở trang trắng thì MTU to quá, không thành công. Lúc này giảm giá trị xuống 8 hay 4 bytes gì đó rồi thử lại. Còn nếu nó ra trang kết quả thì MTU vừa chọn hoạt động tốt.

NẾU DÙNG peer IPv4: các bác vào trang kia bằng 4G mà không bật WireGuard. Giá trị MTU nhận được là bao nhiêu thì lúc cấu hình MTU trên kết nối WireGuard các bác lấy số đó trừ đi 60 là ok. Nếu để to hơn số này thì WireGuard sẽ tự phân mảnh packet thành 2 và sẽ giảm hiệu quả!

Lúc đổi mạng di động hay ra nước ngoài roaming dùng mạng khác thì cũng nên test lại cho chắc là MTU hiện thời vẫn ok.
 
Last edited:
Nhưng mà không có nghĩa là chúng ta phải dùng giá trị mặc định 1280 này, nhỏ quá thì tỉ lệ overhead đâm ra cao, kém hiệu quả. Như mạng di động của em thì nối vào peer WireGuard qua IPv4 thì có thể dùng được MTU 1420, còn nối vào peer IPv6 thì chỉ được 1376 là max. Dù sao cũng cao hơn giá trị mặc định 1280 bytes.
Có lẽ vì lí do này mà khi stream video hoặc truyền file nặng (~20GB) bị tụt tốc độ.
Source code của wireguard thực sự gọn gàng và tường minh hơn IPSEC, cách triển khai cũng đơn giản và rất hiện đại, đáng tin cậy ngay cả khi mạng 4G chập chờn, xem ra tác giả đặt bản thân vào vai người dùng cuối, với một người dùng bình thường thì chẳng có lí do gì bắt họ đi cài chứng chỉ nọ kia, chữ ký số các kiểu... chỉ để xem mấy video pỏnhup lưu trong cái minipc cả 😂

(1492)
1713874867606.png
 
Last edited:
Có lẽ vì lí do này mà khi stream video hoặc truyền file nặng (~20GB) bị tụt tốc độ.
Source code của wireguard thực sự gọn gàng và tường minh hơn IPSEC, cách triển khai cũng đơn giản và rất hiện đại, đáng tin cậy ngay cả khi mạng 4G chập chờn, xem ra tác giả đặt bản thân vào vai người dùng cuối, với một người dùng bình thường thì chẳng có lí do gì bắt họ đi cài chứng chỉ nọ kia, chữ ký số các kiểu... chỉ để xem mấy video pỏnhup lưu trong cái minipc cả 😂

(1492)
View attachment 2457027

Oh 1492 có vẻ là giá trị của mạng bên ngoài tunnel của nhà bác rồi (PPPoE với MTU ethernet 1500). Nếu wireguard thì không được thế đâu ạ, tại overhead của nó tối thiểu 60 bytes khi dùng IPv4, gồm header IPv4, UDP, Wireguard. Tức là mạng bên ngoài tunnel MTU 1500 thì MTU của tunnel tối đã được 1440. Còn nếu bên ngoài dùng IPv6 thì còn mất tới 80 bytes cho header các kiểu (header IPv6 to hơn IPv4 20 bytes), nên các chú mới chọn 1420. Nếu bên ngoài tunnel MTU 1492 thì bên trong 1420 cũng không đạt được nếu dùng IPv6, các bác thường dùng IPv4 nên mới không bị dính vấn đề này dù dùng PPPoE.

Nên có khả năng bác test ở trên bên ngoài tunnel mất rồi ạ. Bác phải test thiết lập MTU cho Wireguard bằng cách tắt WiFi, dùng 4G, rồi chỉnh thiết lập MTU chỗ app Wireguard trên điện thoại, bật kết nối, rồi test link kia ạ. Link treo thì giảm xuống test lại ạ.
 
Oh 1492 có vẻ là giá trị của mạng bên ngoài tunnel của nhà bác rồi (PPPoE với MTU ethernet 1500). Nếu wireguard thì không được thế đâu ạ, tại overhead của nó tối thiểu 60 bytes khi dùng IPv4, gồm header IPv4, UDP, Wireguard. Tức là mạng bên ngoài tunnel MTU 1500 thì MTU của tunnel tối đã được 1440. Còn nếu bên ngoài dùng IPv6 thì còn mất tới 80 bytes cho header các kiểu (header IPv6 to hơn IPv4 20 bytes), nên các chú mới chọn 1420. Nếu bên ngoài tunnel MTU 1492 thì bên trong 1420 cũng không đạt được nếu dùng IPv6, các bác thường dùng IPv4 nên mới không bị dính vấn đề này dù dùng PPPoE.

Nên có khả năng bác test ở trên bên ngoài tunnel mất rồi ạ. Bác phải test thiết lập MTU cho Wireguard bằng cách tắt WiFi, dùng 4G, rồi chỉnh thiết lập MTU chỗ app Wireguard trên điện thoại, bật kết nối, rồi test link kia ạ. Link treo thì giảm xuống test lại ạ.
đây là test 4G với MTU 1420 và 1440, cùng 1 kết quả:
1713879941428.png


đây là test 4G với MTU 1492 và MTU 1500, đều ra kết quả:
1713879965976.png


Với e thì xanh = tốt, đỏ = không tốt, nên e chọn 1492 🤣
 
Bước 2. Tạo 1 IP Address List dành riêng cho wireguard cho dễ quản lý, địa chỉ bất kì, không trùng lặp là được, interface chọn wireguard interface đã tạo ở b1
1713855173912.png

Ở bước 2 bác có thể chọn địa chỉ ở dạng CIDR thí dụ 192.168.100.1/24 (Network tự thành 192.168.100.0). Khi đó trong bảng route sẽ có route đích là cả dải /24 thay vì chỉ /32 dùng gateway là interface WireGuard, về lý thuyết như thế bác không cần bước thêm rule masquerade bên dưới nữa ạ.

Trước giờ như thế em chỉ có vấn đề duy nhất với mấy con router nhà mạng bị em tận dụng làm access point (bằng cách gán địa chỉ LAN tĩnh rồi cắm dây vào cổng LAN của bọn nó), lý do là bọn này khi đó không có thông tin gateway gì cả, nên lúc bọn nó gửi packet trả lời, có địa chỉ đích trong dải của WireGuard thì không thuộc dải LAN của nó nên nó không biết gửi đi đâu vì không có thông tin gateway. Với bọn đó thì em add tạm route vào bảng route của bọn chúng để bọn nó biết cách dùng router MikroTik làm gateway khi gửi đến đích thuộc dải WG (em vẫn không để route 0.0.0.0/0 để ngăn bọn nó vào mạng nói chuyện với ISP gốc).

Còn các thiết bị khác trong LAN bình thường dùng DHCP hoặc gắn địa chỉ tĩnh nhưng có điền thông tin gateway là router MikroTik thì không có vấn đề gì khi trả lời các thiết bị bên ngoài dùng WireGuard cả (vì có route đầy đủ trong bảng route của router). Nên không cần rule masquerade ạ.
 
đây là test 4G với MTU 1420 và 1440, cùng 1 kết quả:
View attachment 2457191

đây là test 4G với MTU 1492 và MTU 1500, đều ra kết quả:
View attachment 2457192

Với e thì xanh = tốt, đỏ = không tốt, nên e chọn 1492 🤣

Hic có khả năng lúc này WireGuard nó tự phân mảnh thành 2 packet đấy bác ạ. Bác cứ set không quá 1420 ạ (cái interface trên router của bác cũng để có vậy).
 
Ở bước 2 bác có thể chọn địa chỉ ở dạng CIDR thí dụ 192.168.100.1/24 (Network tự thành 192.168.100.0). Khi đó trong bảng route sẽ có route đích là cả dải /24 thay vì chỉ /32 dùng gateway là interface WireGuard, về lý thuyết như thế bác không cần bước thêm rule masquerade bên dưới nữa ạ.

Trước giờ như thế em chỉ có vấn đề duy nhất với mấy con router nhà mạng bị em tận dụng làm access point (bằng cách gán địa chỉ LAN tĩnh rồi cắm dây vào cổng LAN của bọn nó), lý do là bọn này khi đó không có thông tin gateway gì cả, nên lúc bọn nó gửi packet trả lời, có địa chỉ đích trong dải của WireGuard thì không thuộc dải LAN của nó nên nó không biết gửi đi đâu vì không có thông tin gateway. Với bọn đó thì em add tạm route vào bảng route của bọn chúng để bọn nó biết cách dùng router MikroTik làm gateway khi gửi đến đích thuộc dải WG (em vẫn không để route 0.0.0.0/0 để ngăn bọn nó vào mạng nói chuyện với ISP gốc).

Còn các thiết bị khác trong LAN bình thường dùng DHCP hoặc gắn địa chỉ tĩnh nhưng có điền thông tin gateway là router MikroTik thì không có vấn đề gì khi trả lời các thiết bị bên ngoài dùng WireGuard cả (vì có route đầy đủ trong bảng route của router). Nên không cần rule masquerade ạ.
Như vậy khi dùng subnet mask /24 thì OS sẽ tạo route tới interface wireguard tự động, không cần thêm rule masquerade.
Còn dùng masquerade thì gói tin đi ra từ wireguard sẽ đổi src addr thành IP của router à bác, nôm na là lúc này các thiết bị trong LAN sẽ coi điện thoại vừa kết nối vào là 1 phần của mạng LAN, chứ không phải là từ VPN
 
Như vậy khi dùng subnet mask /24 thì OS sẽ tạo route tới interface wireguard tự động, không cần thêm rule masquerade.
Còn dùng masquerade thì gói tin đi ra từ wireguard sẽ đổi src addr thành IP của router à bác, nôm na là lúc này các thiết bị trong LAN sẽ coi điện thoại vừa kết nối vào là 1 phần của mạng LAN, chứ không phải là từ VPN

Đúng rồi bác ạ, lúc masquerade thì mọi client WireGuard lúc nối vào thiết bị trong LAN thì các thiết bị sẽ tưởng là router nối vào bọn nó (vì thế nên ngay cả với trường hợp không set gateway như em tả ở trên cũng trả lời được, vì router và thiết bị không có gateway đó cùng subnet nên nói chuyện với nhau thẳng trên Layer 2). Còn có /24, route đến /24 thì các client WireGuard kiểu như các thiết bị trong 1 VLAN khác vậy. Khi bác thiết lập nhiều VLAN thì mặc định nếu firewall không block, các thiết bị giữa các VLAN vẫn nói chuyện được với nhau bằng địa chỉ của nhau. Router làm gateway cho bọn chúng và router có trong bảng route cách để đến được các dải địa chỉ đó.

Khi bác ở bước 2 chỉ ghi địa chỉ IP không thì nó là /32, tức là trong bảng route chỉ có destination 192.168.100.1/32. Lúc ở dải LAN khác muốn trả lời 192.168.100.5 thì nhờ router, router không biết gửi đi đâu (không biết phải chuyển qua interface wireguard). Nên bác mới phải dùng rule masquerade.
 
đây là test 4G với MTU 1420 và 1440, cùng 1 kết quả:
View attachment 2457191

đây là test 4G với MTU 1492 và MTU 1500, đều ra kết quả:
View attachment 2457192

Với e thì xanh = tốt, đỏ = không tốt, nên e chọn 1492 🤣

Sorry bác nhiều, sau khi test thì em đã phải update cái bài #2 của em ở tên, thêm 2 đoạn in đậm ở dưới ạ. Xưa này em toàn dùng IPv6 với WireGuard (không phải lo khoản CGNAT với di động ở Việt Nam IPv6 hỗ trợ tốt hết cả) nên cái cách em nói ở trên em không test với IPv4. IPv4 thì WG nó không bật flag do not fragment nên packet to hơn MTU nó tự tách làm đôi, thế nên nếu bác làm như em post trước thì không được kết quả như mong đợi. Em đã update phần tìm giá trị cho IPv4 cho tối ưu ạ (tìm MTU lúc không có tunnel rồi trừ đi 60).
 
Khi bác thiết lập nhiều VLAN thì mặc định nếu firewall không block, các thiết bị giữa các VLAN vẫn nói chuyện được với nhau bằng địa chỉ của nhau. Router làm gateway cho bọn chúng và router có trong bảng route cách để đến được các dải địa chỉ đó.
Đúng vậy, mặc định tạo xong 2VLAN thì tường lửa không có auto drop hộ, nên 2 VLAN sẽ thông nhau như thường. Sau khi drop chain forward như sau thì có vẻ ổn, ngăn VLAN 20 truy cập vào 10
1713883075593.png
 
Bổ sung chút:
WG app mobile thì ko cần, nhưng WG desktop (Windows), nếu để Allowed IP 0.0.0.0/0 sẽ không vào được mạng LAN. Muốn vào mạng LAN, uncheck chỗ Block untunnelled trafic (kill-switch) hoặc đổi 0.0.0.0/0 thành AllowedIPs = 0.0.0.0/1, 128.0.0.0/1
1713944505307.png


Ngoài ra, sau một thời gian sài WG site-to-site hoặc client-to-site với IP động, mình nhận thấy Mik resolve domain thành IP tương đối chậm. VD: Khi public IP của mình thay đổi, lập tức script để cập nhật WAN IP lên Dynu với domain my_name.freeddns.org và chỉ khoảng 3-5 phút sau, google DNS (8.8.8.8) đã resolve và nhận IP mới, nhưng Mik vẫn resolve ra IP cũ (phải tầm hơn 1 giờ, có khi mất tới hơn 2 giờ Mik mới resolve ra IP mới). Vì vậy, mình có 2 script để update Endpoint trên WG server và WG client.

script trên Mik server để update public (WAN) IP lên Dynu
Code:
:global ddnsuser "dynu_user_name"
:global ddnspass "dynu_password"
:global theinterface "PPPoE"
:global ddnshost "your_name.freeddns.org"
:global ipddns [:resolve $ddnshost server="8.8.8.8"]
:global ipfresh [/ip address get [/ip address find interface=$theinterface] address]
:if ([ :typeof $ipfresh ] = nil ) do={
:log warning ("DDNS: No IP address on $theinterface .")
} else={
:for i from=( [:len $ipfresh] - 1) to=0 do={
:if ( [:pick $ipfresh $i] = "/") do={
:set ipfresh [:pick $ipfresh 0 $i];
}
}
:if ($ipddns != $ipfresh) do={
:log warning "DDNS: Update IP needed, Sending Update...!"
:global str "/nic/update?hostname=$ddnshost&myip=$ipfresh"
/tool fetch address=api.dynu.com src-path=$str mode=http user=$ddnsuser password=$ddnspass dst-path=("/Dynu.".$ddnshost)
:delay 1
:global str [/file find name="Dynu.$ddnshost"];
/file remove $str
:global ipddns $ipfresh
:log warning "DDNS: IP updated to $ipfresh!"
}
}

script để update WG Endpoint trong peer của client:
Code:
:global myDDNS "your_name.freeddns.org"
:global curIP [/interface wireguard peer get [find interface=WG_Interface] endpoint-address]
:global newIP [:resolve $myDDNS server="8.8.8.8"]
:if ($curIP != $newIP) do={
     /interface wireguard peer set [find interface=WG_Interface] endpoint-address=$newIP
}
 
Last edited:
thớt bổ ích.
zFNuZTA.png
1713960450934.png

Các bác có hứng với máy tính <-> Mikrotik thì đây là hướng dẫn mới:
 
nhà dùng cái mik fake x86 chạy OS 6 thì cần phải lên phiên bản 7 bao nhiêu để ổn định và chạy được như chủ thớt nhỉ.
 
Back
Top