
ברצוני לחלוק את החוויה שלי בשילוב רשתות בשלוש דירות מרוחקות גיאוגרפית, שכל אחת מהן משתמשת בנתבי OpenWRT כשער, לרשת אחת משותפת. בבחירת שיטה לשילוב רשתות בין L3 עם ניתוב רשת משנה ל-L2 עם גישור, כאשר כל צמתי הרשת יהיו באותה רשת משנה, ניתנה העדפה לשיטה השנייה, שקשה יותר להגדיר אותה, אך מספקת הזדמנויות גדולות יותר, שכן תוכנן שימוש שקוף בטכנולוגיות ברשת שנוצרת Wake-on-Lan ו-DLNA.
חלק 1: רקע
הפרוטוקול שנבחר ליישום משימה זו היה בתחילה OpenVPN, כי, ראשית, זה יכול ליצור התקן הברגה שניתן להוסיף לגשר ללא בעיות, ושנית, OpenVPN הוא תומך ב-TCP, וזה היה חשוב גם כן, מכיוון שלאף אחת מהדירות לא הייתה כתובת IP ייעודית. לא יכולתי להשתמש ב-STUN מכיוון שספק האינטרנט שלי, מסיבה כלשהי, חוסם חיבורי UDP נכנסים מהרשתות שלו. TCP אפשר לי להעביר את פורט שרת ה-VPN לשרת ה-VPS השכור באמצעות SSH. בעוד שגישה זו יוצרת תקורה משמעותית, מכיוון שהנתונים מוצפנים פעמיים, לא רציתי לשלב את ה-VPS ברשת הפרטית שלי, מכיוון שהיה סיכון שצדדים שלישיים ישתלטו עליו. לכן, החזקת מכשיר כזה ברשת הביתית שלי הייתה מאוד לא רצויה, אז החלטתי לשלם תקורה משמעותית עבור אבטחה.
כדי להעביר את הפורט בנתב שבו תוכנן לפרוס את השרת, השתמשתי בתוכנת sshtunnel. לא אכנס לפרטים של התצורה שלה - זה די קל. אציין רק שמטרתה הייתה להעביר את פורט TCP 1194 מהנתב ל-VPS. לאחר מכן, הגדרתי את השרת. OpenVPN במכשיר tap0, שהיה מחובר לגשר br-lan. לאחר בדיקת החיבור לשרת החדש שנוצר מהמחשב הנייד שלי, התברר שרעיון העברת הפורטים עבד, והמחשב הנייד שלי הפך לחבר ברשת של הנתב, למרות שהוא לא היה חלק ממנה פיזית.
הדבר היחיד שנותר לעשות היה לפזר כתובות IP בדירות שונות כדי שלא יתנגשו ולהגדיר את הנתבים כ... OpenVPNלקוחות.
נבחרו כתובות ה-IP של הנתב וטווחי שרתי ה-DHCP הבאים:
- 192.168.10.1 עם טווח 192.168.10.2 - 192.168.10.80 עבור השרת
- 192.168.10.100 עם טווח 192.168.10.101 - 192.168.10.149 לראוטר בדירה מס' 2
- 192.168.10.150 עם טווח 192.168.10.151 - 192.168.10.199 לראוטר בדירה מס' 3
היה צורך גם להקצות כתובות אלו לנתבים של הלקוח. OpenVPN-server, על ידי הוספת השורה הבאה לתצורה שלו:
ifconfig-pool-persist /etc/openvpn/ipp.txt 0והוספת השורות הבאות לקובץ /etc/openvpn/ipp.txt:
flat1_id 192.168.10.100
flat2_id 192.168.10.150
כאשר flat1_id ו- flat2_id הם שמות המכשירים שצוינו בעת יצירת אישורים להתחברות אל OpenVPN
לאחר מכן, הנתבים הוגדרו OpenVPN- לקוחות, מכשירי tap0 בשניהם נוספו לגשר br-lan. בשלב זה, הכל נראה בסדר, שכן שלוש הרשתות יכלו לראות זו את זו ולתפקד כיחידה אחת. עם זאת, צץ פרט לא נעים למדי: לפעמים מכשירים היו מקבלים כתובת IP מנתב שגוי, עם כל ההשלכות הנלוות לכך. מסיבה כלשהי, הנתב באחת הדירות לא הגיב ל-DHCPDISCOVER בזמן, והמכשיר קיבל את הכתובת הלא נכונה. הבנתי שאני צריך לסנן בקשות כאלה ב-tap0 בכל נתב, אבל כפי שהתברר, iptables לא יכולים לעבוד עם מכשיר אם הוא חלק מגשר, אז הייתי צריך להשתמש ב-ebtables. לרוע המזל, הקושחה שלי לא כללה את זה, אז הייתי צריך לבנות מחדש את התמונות עבור כל מכשיר. לאחר שעשיתי זאת והוספת השורות הבאות ל-/etc/rc.local בכל נתב, הבעיה נפתרה:
ebtables -A INPUT --in-interface tap0 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A INPUT --in-interface tap0 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP
ebtables -A FORWARD --out-interface tap0 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A FORWARD --out-interface tap0 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP
תצורה זו נמשכה שלוש שנים.
חלק 2: היכרות WireGuard
לאחרונה, גוברת השיח באינטרנט על WireGuard, מתפעל מקלות התצורה שלו, מהירות העברה גבוהה, פינג נמוך ואבטחה דומה. חיפוש מידע נוסף עליו גילה שהוא אינו תומך בתמיכה בפרוטוקול גשר או בפרוטוקול TCP, מה שהוביל אותי להאמין שאין אלטרנטיבה. OpenVPN בשבילי זה עדיין לא שם. אז דחיתי את ההיכרות WireGuard.
לפני מספר ימים, חדשות התפשטו דרך משאבים הקשורים ל-IT בצורה כזו או אחרת, WireGuard ייכלל סוף סוף בליבת הגרעין Linux, החל מגרסה 5.6. כתבות חדשותיות, כרגיל, זכו לשבחים. WireGuardשוב צללתי לתוך חיפוש אחר דרכים להחליף את הישן והטוב OpenVPNהפעם נתקלתי ב . זה דיבר על יצירת מנהרת Ethernet על L3 באמצעות GRE. המאמר הזה נתן לי תקווה. לא היה ברור מה לעשות עם פרוטוקול UDP. החיפוש הוביל אותי למאמרים על שימוש ב- socat בשילוב עם מנהרת SSH להעברת יציאת UDP, עם זאת, הם ציינו שגישה זו עובדת רק במצב חיבור יחיד, כלומר, העבודה של מספר לקוחות VPN תהיה בלתי אפשרית. הגעתי לרעיון להתקין שרת VPN ב-VPS ולהגדיר GRE עבור לקוחות, אבל כפי שהתברר, GRE אינו תומך בהצפנה, מה שיוביל לכך שאם צדדים שלישיים יקבלו גישה לשרת , כל התעבורה בין הרשתות שלי תהיה בידיים שלהם, מה שלא התאים לי בכלל.
שוב, ההחלטה התקבלה לטובת הצפנה מיותרת, על ידי שימוש ב-VPN דרך VPN באמצעות הסכימה הבאה:
VPN ברמה XNUMX:
VPS זה שרת עם כתובת פנימית 192.168.30.1
מ.ס. זה לָקוּחַ VPS עם כתובת פנימית 192.168.30.2
MK2 זה לָקוּחַ VPS עם כתובת פנימית 192.168.30.3
MK3 זה לָקוּחַ VPS עם כתובת פנימית 192.168.30.4
VPN ברמה שנייה:
מ.ס. זה שרת עם כתובת חיצונית 192.168.30.2 וכתובת פנימית 192.168.31.1
MK2 זה לָקוּחַ מ.ס. עם הכתובת 192.168.30.2 ויש לו IP פנימי 192.168.31.2
MK3 זה לָקוּחַ מ.ס. עם הכתובת 192.168.30.2 ויש לו IP פנימי 192.168.31.3
* מ.ס. — שרת נתב בדירה 1, MK2 - נתב בדירה 2, MK3 - נתב בדירה 3
* תצורות המכשיר מתפרסמות בספוילר בסוף המאמר.
וכך, פינגים פועלים בין צמתי רשת 192.168.31.0/24, הגיע הזמן לעבור להגדרת מנהרת GRE. לפני כן, כדי לא לאבד גישה לנתבים, כדאי להגדיר מנהרות SSH להעברת יציאה 22 ל-VPS, כך, למשל, הנתב מדירה 10022 יהיה נגיש ביציאה 2 של ה-VPS, וה-VPS. נתב מדירה 11122 יהיה נגיש בנתב יציאה 3 מדירה XNUMX. עדיף להגדיר העברה באמצעות אותו sshtunnel, מכיוון שהוא ישחזר את המנהרה אם היא תיכשל.
המנהרה מוגדרת, אתה יכול להתחבר ל-SSH דרך היציאה המועברת:
ssh root@МОЙ_VPS -p 10022בשלב הבא עליך להשבית OpenVPN:
/etc/init.d/openvpn stopעכשיו בואו נגדיר מנהרת GRE על הנתב מדירה 2:
ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.2
ip link set grelan0 up
והוסיפו את הממשק שנוצר לגשר:
brctl addif br-lan grelan0
בואו נבצע הליך דומה בנתב השרת:
ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set grelan0 up
וגם הוסף את הממשק שנוצר לגשר:
brctl addif br-lan grelan0
החל מרגע זה, פינגים מתחילים לעבור בהצלחה לרשת החדשה ואני, בסיפוק, הולך לשתות קפה. לאחר מכן, כדי להעריך כיצד הרשת פועלת בקצה השני של הקו, אני מנסה להכניס SSH לאחד מהמחשבים בדירה 2, אך לקוח ה-ssh קופא מבלי לבקש סיסמה. אני מנסה להתחבר למחשב הזה דרך telnet ביציאה 22 ואני רואה קו שממנו אני יכול להבין שהחיבור נוצר, שרת ה-SSH מגיב, אבל משום מה זה פשוט לא מנחה אותי להיכנס ב.
$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1
אני מנסה להתחבר אליו דרך VNC ולראות מסך שחור. אני משכנע את עצמי שהבעיה היא במחשב המרוחק, כי אני יכול בקלות להתחבר לראוטר מהדירה הזו באמצעות הכתובת הפנימית. עם זאת, אני מחליט להתחבר ל-SSH של המחשב הזה דרך הראוטר ומופתע לגלות שהחיבור הצליח, והמחשב המרוחק עובד די רגיל, אבל הוא גם לא יכול להתחבר למחשב שלי.
אני מוציא את התקן grelan0 מהגשר ומפעיל אותו. OpenVPN בנתב בדירה 2, אישרתי שהרשת שוב פועלת כראוי והחיבורים לא נופלים. בחיפוש נתקלתי בפורומים שבהם אנשים התלוננו על אותן בעיות, ושם יעצו להם להעלות את ערך ה-MTU. לא מהר אמרתי את זה, זה נעשה. עם זאת, עד שה-MTU הוגדר גבוה מספיק - 7000 עבור התקני Gretap - חוויתי או ניתוקי חיבורי TCP או מהירויות העברה נמוכות. בגלל ה-MTU הגבוה עבור Gretap, ה-MTU עבור חיבורים... WireGuard הרמות הראשונה והשנייה נקבעו על 8000 ו-7500 בהתאמה.
ביצעתי הגדרה דומה על הנתב מדירה 3, כשההבדל היחיד הוא שנוסף לנתב השרת ממשק gretap שני בשם grelan1, שנוסף גם לגשר br-lan.
הכל עובד. כעת אתה יכול להכניס את מכלול gretap להפעלה. לזה:
שמתי את השורות האלה ב-/etc/rc.local בנתב בדירה 2:
ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.2
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0
הוסיף את זה ל-/etc/rc.local בנתב בדירה 3:
ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.3
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0
ובנתב השרת:
ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0
ip link add grelan1 type gretap remote 192.168.31.3 local 192.168.31.1
ip link set dev grelan1 mtu 7000
ip link set grelan1 up
brctl addif br-lan grelan1
לאחר אתחול מחדש של נתבי הלקוח, גיליתי שמסיבה כלשהי הם לא התחברו לשרת. לאחר התחברות ל-SSH שלהם (למרבה המזל, הגדרתי קודם לכן את sshtunnel לכך), גיליתי ש WireGuard מסיבה כלשהי, הוא יוצר נתיב עבור נקודת הקצה, אך הוא שגוי. לדוגמה, עבור 192.168.30.2, טבלת הנתיבים ציינה נתיב דרך ממשק pppoe-wan, כלומר דרך האינטרנט, למרות שהנתיב אליו היה אמור להיות מופנה דרך ממשק wg0. לאחר מחיקת נתיב זה, החיבור שוחזר. האם אוכל למצוא הוראות איפשהו כיצד לאלץ? WireGuard לא יכולתי להימנע מליצור את הנתיבים האלה. יתר על כן, אפילו לא הבנתי אם זו תכונה של OpenWRT או של ה- WireGuardבלי לבזבז זמן רב בפתרון הבעיה, פשוט הוספתי שורה לסקריפט לולאת הטיימר בשני הנתבים שמחקו את הנתיב הזה:
route del 192.168.30.2
תמצות
דחייה מוחלטת OpenVPN עדיין לא הצלחתי בכך, מכיוון שאני צריך מדי פעם להתחבר לרשת חדשה ממחשב נייד או טלפון, והגדרת מכשיר gretap בהם היא בדרך כלל בלתי אפשרית. עם זאת, למרות זאת, השגתי יתרון במהירות העברת נתונים בין דירות, והשימוש ב-VNC, למשל, הוא כעת ללא טרחה. הפינג ירד מעט אך הפך ליציב יותר:
בעת שימוש OpenVPN:
[r0ck3r@desktop ~]$ ping -c 20 192.168.10.110
PING 192.168.10.110 (192.168.10.110) 56(84) bytes of data.
64 bytes from 192.168.10.110: icmp_seq=1 ttl=64 time=133 ms
...
64 bytes from 192.168.10.110: icmp_seq=20 ttl=64 time=125 ms
--- 192.168.10.110 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19006ms
rtt min/avg/max/mdev = 124.722/126.152/136.907/3.065 ms
בעת שימוש WireGuard:
[r0ck3r@desktop ~]$ ping -c 20 192.168.10.110
PING 192.168.10.110 (192.168.10.110) 56(84) bytes of data.
64 bytes from 192.168.10.110: icmp_seq=1 ttl=64 time=124 ms
...
64 bytes from 192.168.10.110: icmp_seq=20 ttl=64 time=124 ms
--- 192.168.10.110 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19003ms
rtt min/avg/max/mdev = 123.954/124.423/126.708/0.675 ms
הוא מושפע יותר מהפינג הגבוה ל-VPS, שהוא בערך 61.5 אלפיות השנייה
עם זאת, המהירות עלתה משמעותית. אז, בדירה עם הנתב-שרת, יש לי מהירות חיבור לאינטרנט של 30 מגה-ביט לשנייה, ובדירות האחרות זה 5 מגה-ביט לשנייה. יתר על כן, במהלך השימוש OpenVPN לא הצלחתי להשיג מהירות העברת נתונים בין רשתות של יותר מ-3,8 מגה-ביט לשנייה לפי קריאות iperf, בעוד WireGuard "העלה" את זה לאותם 5 מגה-ביט/שנייה.
תְצוּרָה WireGuard ב-VPS[Interface]
Address = 192.168.30.1/24
ListenPort = 51820
PrivateKey = <ЗАКРЫТЫЙ_КЛЮЧ_ДЛЯ_VPS>
[עמית]
מפתח ציבורי = <VPN_1_MS_PUBLIC_KEY>
כתובות IP מותרות = 192.168.30.2/32
[עמית]
מפתח ציבורי = <VPN_2_MK2_PUBLIC_KEY>
כתובות IP מותרות = 192.168.30.3/32
[עמית]
מפתח ציבורי = <VPN_2_MK3_PUBLIC_KEY>
כתובות IP מותרות = 192.168.30.4/32
תְצוּרָה WireGuard ב-MS (נוסף ל-/etc/config/network)
#VPN первого уровня - клиент
config interface 'wg0'
option proto 'wireguard'
list addresses '192.168.30.2/24'
option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МС'
option auto '1'
option mtu '8000'
config wireguard_wg0
option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
option endpoint_port '51820'
option route_allowed_ips '1'
option persistent_keepalive '25'
list allowed_ips '192.168.30.0/24'
option endpoint_host 'IP_АДРЕС_VPS'
#VPN второго уровня - сервер
config interface 'wg1'
option proto 'wireguard'
option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
option listen_port '51821'
list addresses '192.168.31.1/24'
option auto '1'
option mtu '7500'
config wireguard_wg1
option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК2'
list allowed_ips '192.168.31.2'
config wireguard_wg1ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.3
option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК3'
list allowed_ips '192.168.31.3'
תְצוּרָה WireGuard ב-MK2 (נוסף ל-/etc/config/network)
#VPN первого уровня - клиент
config interface 'wg0'
option proto 'wireguard'
list addresses '192.168.30.3/24'
option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МК2'
option auto '1'
option mtu '8000'
config wireguard_wg0
option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
option endpoint_port '51820'
option persistent_keepalive '25'
list allowed_ips '192.168.30.0/24'
option endpoint_host 'IP_АДРЕС_VPS'
#VPN второго уровня - клиент
config interface 'wg1'
option proto 'wireguard'
option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МК2'
list addresses '192.168.31.2/24'
option auto '1'
option listen_port '51821'
option mtu '7500'
config wireguard_wg1
option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
option endpoint_host '192.168.30.2'
option endpoint_port '51821'
option persistent_keepalive '25'
list allowed_ips '192.168.31.0/24'
תְצוּרָה WireGuard ב-MK3 (נוסף ל-/etc/config/network)
#VPN первого уровня - клиент
config interface 'wg0'
option proto 'wireguard'
list addresses '192.168.30.4/24'
option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МК3'
option auto '1'
option mtu '8000'
config wireguard_wg0
option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
option endpoint_port '51820'
option persistent_keepalive '25'
list allowed_ips '192.168.30.0/24'
option endpoint_host 'IP_АДРЕС_VPS'
#VPN второго уровня - клиент
config interface 'wg1'
option proto 'wireguard'
option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МК3'
list addresses '192.168.31.3/24'
option auto '1'
option listen_port '51821'
option mtu '7500'
config wireguard_wg1
option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
option endpoint_host '192.168.30.2'
option endpoint_port '51821'
option persistent_keepalive '25'
list allowed_ips '192.168.31.0/24'
בתצורות המתוארות עבור VPN ברמה השנייה, אני מציין ללקוחות WireGuard פורט 51821. זה לא אמור להיות הכרחי, מכיוון שהלקוח ייצור חיבור מכל פורט פנוי ולא מורשה, אבל עשיתי זאת כך כדי שאוכל לדחות את כל החיבורים הנכנסים בממשקי wg0 של כל הנתבים, למעט חיבורי UDP נכנסים לפורט 51821.
אני מקווה שהמאמר יועיל למישהו.
נ.ב. כמו כן, אני רוצה לשתף את הסקריפט שלי ששולח לי הודעת PUSH לטלפון שלי באפליקציית WirePusher כאשר מכשיר חדש מופיע ברשת שלי. הנה הקישור לתסריט: .
עדכון: תְצוּרָה OpenVPN-שרתים ולקוחות
OpenVPN-שרת
client-to-client
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/vpn-server.crt
dh /etc/openvpn/server/dh.pem
key /etc/openvpn/server/vpn-server.key
dev tap
ifconfig-pool-persist /etc/openvpn/ipp.txt 0
keepalive 10 60
proto tcp4
server-bridge 192.168.10.1 255.255.255.0 192.168.10.80 192.168.10.254
status /var/log/openvpn-status.log
verb 3
comp-lzoOpenVPN-לָקוּחַ
client
tls-client
dev tap
proto tcp
remote VPS_IP 1194 # Change to your router's External IP
resolv-retry infinite
nobind
ca client/ca.crt
cert client/client.crt
key client/client.key
dh client/dh.pem
comp-lzo
persist-tun
persist-key
verb 3 השתמשתי ב- easy-rsa כדי להפיק אישורים
מקור: www.habr.com
