
صحيح ، ولإله التشفير ، سنقول نفس الشيء اليوم.
هنا سيكون الأمر حول نفق IPv4 غير مشفر ، ولكن ليس عن "مصباح دافئ" ، ولكن حول "مصباح LED" حديث. ثم تومض المآخذ الأولية ، وهناك عمل مع الحزم في مساحة المستخدم.
هناك بروتوكولات نفق N لكل ذوق ولون:
- WireGuard أنيق وعصري وشبابي
- متعدد الوظائف مثل السكاكين السويسرية و OpenVPN و SSH
- GRE القديم وليس الشر
- أبسط وأذكى وغير مشفر IPIP على الإطلاق
- تعمل بنشاط على تطوير جنيف
- آخرين كثر.
لكنني مبرمج ، لذا سأزيد N بنسبة صغيرة ، وأترك تطوير البروتوكولات الحقيقية لمطوري b.
في مشروع آخر لم يولد بعد ، والذي أشارك فيه حاليًا ، أحتاج إلى الوصول إلى مضيفين خلف NAT من الخارج. باستخدام البروتوكولات مع تشفير الكبار لهذا ، لم أترك الشعور بأن الأمر كان مثل كرة المدفع. لان يتم استخدام النفق في الغالب فقط لإحداث فجوة في NAT-e ، وعادةً ما يتم تشفير حركة المرور الداخلية أيضًا ، ومع ذلك فهي غارقة في HTTPS.
أثناء البحث عن بروتوكولات الأنفاق المختلفة ، تم جذب انتباه الكمال الداخلي الخاص بي إلى IPIP مرة بعد مرة نظرًا للحد الأدنى من النفقات العامة. لكن له عيوبًا كبيرة ونصف في مهامي:
- يتطلب عناوين IP عامة على كلا الجانبين ،
- ولا يوجد مصادقة لك.
لذلك ، عاد المثالي إلى الزاوية المظلمة من الجمجمة ، أو في أي مكان يجلس فيه.
ومرة واحدة ، أثناء قراءة المقالات حول الأنفاق المدعومة محليًا في Linux ، صادفت FOU (Foo-over-UDP) ، أي أيا كان ، ملفوفة في UDP. حتى الآن ، يتم دعم IPIP و GUE (تغليف UDP العام) فقط من أي شيء آخر.
"هذه رصاصة فضية! أنا و IPIP بسيط للعيون. " اعتقدت.
في الواقع ، لم تكن الرصاصة فضية بالكامل. يحل التغليف في UDP المشكلة الأولى - يمكنك الاتصال بالعملاء خلف NAT من الخارج باستخدام اتصال محدد مسبقًا ، ولكن هنا نصف العيب التالي في ازدهار IPIP في ضوء جديد - يمكن إخفاء أي شخص من الشبكة الخاصة خلف IP العام المرئي ومنفذ العميل (في IPIP النقي لا توجد مشكلة).
لحل هذه المشكلة التي تبلغ نصف ، ولدت الأداة المساعدة ipipou . يقوم بتنفيذ آلية ذاتية الصنع لمصادقة مضيف بعيد ، مع عدم تعطيل تشغيل FOU النشط ، والذي سيعالج الحزم في مساحة النواة بسرعة وكفاءة.
لا تحتاج البرنامج النصي الخاص بك!
حسنًا ، إذا كنت تعرف المنفذ العام وعنوان IP للعميل (على سبيل المثال ، كل ما يخصك ، أينما ذهبوا ، يحاول NAT تعيين المنافذ من 1 إلى 1) ، يمكنك إنشاء نفق IPIP-over-FOU باستخدام الأوامر التالية ، دون أي نصوص.
على الخادم:
# FOU
modprobe fou
# IPIP FOU.
# ipip .
ip link add name ipipou0 type ipip \
remote 198.51.100.2 local 203.0.113.1 \
encap fou encap-sport 10000 encap-dport 20001 \
mode ipip dev eth0
# FOU
ip fou add port 10000 ipproto 4 local 203.0.113.1 dev eth0
# IP
ip address add 172.28.0.0 peer 172.28.0.1 dev ipipou0
#
ip link set ipipou0 up
على العميل:
modprobe fou
ip link add name ipipou1 type ipip \
remote 203.0.113.1 local 192.168.0.2 \
encap fou encap-sport 10001 encap-dport 10000 encap-csum \
mode ipip dev eth0
# local, peer, peer_port, dev , .
# peer peer_port FOU-listener-.
ip fou add port 10001 ipproto 4 local 192.168.0.2 peer 203.0.113.1 peer_port 10000 dev eth0
ip address add 172.28.0.1 peer 172.28.0.0 dev ipipou1
ip link set ipipou1 up
أين
ipipou*- اسم واجهة شبكة النفق المحلية203.0.113.1- IP العام للخادم198.51.100.2- IP العام للعميل192.168.0.2- عنوان IP للعميل المخصص لواجهة eth010001- منفذ العميل المحلي لـ FOU20001- منفذ العميل العام لـ FOU10000- منفذ الخادم العمومي لـ FOUencap-csum— UDP UDP ;noencap-csum, , ( )eth0— ipip172.28.0.1— IP ()172.28.0.0— IP ()
طالما أن اتصال UDP على قيد الحياة ، فسيكون النفق في حالة عمل ، وكيف ينكسر ، كم هو محظوظ - إذا ظل IP: منفذ العميل كما هو - سيعيش ، ويتغير - فسوف ينكسر.
أسهل طريقة لتغيير الأمور هي عن طريق تفريغ وحدات النواة:
modprobe -r fou ipip
حتى إذا لم تكن المصادقة مطلوبة ، فإن عنوان IP العام ومنفذ العميل غير معروفين دائمًا وغالبًا ما يكونان غير متوقعين أو متغيرين (اعتمادًا على نوع NAT). إذا حذفته من
encap-dportجانب الخادم ، فلن يعمل النفق ، ولن يكون ذكيًا بما يكفي لأخذ منفذ الاتصال البعيد. في هذه الحالة ، يمكن أن يساعدك ipipou أيضًا ، أو WireGuard وآخرين مثله لمساعدتك.
كيف تعمل؟
يقوم العميل (الذي يكون عادةً خلف NAT) بإعداد نفق (كما في المثال أعلاه) ويرسل حزمة مصادق عليها إلى الخادم بحيث يمكنه تكوين النفق من جانبه. اعتمادًا على الإعدادات ، يمكن أن تكون هذه حزمة فارغة (فقط حتى يرى الخادم IP العام: منفذ الاتصال) ، أو مع البيانات التي يمكن للخادم من خلالها التعرف على العميل. يمكن أن تكون البيانات عبارة مرور بسيطة للنص العادي (يتبادر إلى الذهن تشابه مع مصادقة HTTP الأساسية) أو بيانات منسقة بشكل خاص موقعة بمفتاح خاص (بالقياس مع HTTP Digest Auth ، فقط أقوى ، انظر الوظيفة
client_authفي الكود).
على الخادم (بجانب IP العام) ، عندما يبدأ ipipou ، يقوم بإنشاء معالج nfqueue queue وتكوين netfilter بحيث يتم إرسال الحزم الضرورية إلى حيث يجب أن تذهب: الحزم التي تهيئ الاتصال بقائمة انتظار nfqueue ، و [تقريبًا] كل الباقي مباشرة إلى مستمع FOU.
من ليس في الموضوع ، يعد nfqueue (أو NetfilterQueue) شيئًا خاصًا
بالنسبة لبعض لغات البرمجة ، هناك ارتباطات للعمل مع nfqueue ، بالنسبة إلى bash لم يكن هناك (هيه ، ليس مفاجئًا) ، كان علي استخدام python: ipipou يستخدم NetfilterQueue .
إذا لم يكن الأداء حرجًا ، فبمساعدة هذا الشيء يمكنك بسرعة وسهولة نسبيًا طهي منطقك الخاص للعمل مع الحزم بمستوى منخفض إلى حد ما ، على سبيل المثال ، نحت بروتوكولات نقل البيانات التجريبية ، أو التصيد بالخدمات المحلية والبعيدة بسلوك غير قياسي.
تعمل المقابس الأولية جنبًا إلى جنب مع nfqueue ، على سبيل المثال ، عندما يكون النفق مهيئًا بالفعل ويستمع FOU إلى المنفذ المطلوب ، فلن يعمل بالطريقة المعتادة لإرسال حزمة من نفس المنفذ - إنه مشغول ، ولكن يمكنك أخذ وتشغيل حزمة تم إنشاؤها عشوائيًا مباشرة في الشبكة واجهة باستخدام مقبس خام ، على الرغم من أنه سيتعين عليك العبث أكثر من إنشاء مثل هذه الحزمة. هذه هي الطريقة التي يتم بها إنشاء الحزم مع المصادقة في ipipou.
نظرًا لأن ipipou يعالج فقط الحزم الأولى من الاتصال (حسنًا ، تلك التي تمكنت من التسرب إلى قائمة الانتظار قبل إنشاء الاتصال) ، فإن الأداء بالكاد يعاني.
بمجرد أن يتلقى خادم ipipou حزمة مصدق عليها ، يتم إنشاء نفق وتتم معالجة جميع الحزم اللاحقة في الاتصال بالفعل بواسطة تجاوز kernel nfqueue. إذا كان الاتصال سيئًا ، فسيتم إرسال الحزمة الأولى من التالية إلى قائمة انتظار nfqueue ، اعتمادًا على الإعدادات ، إذا لم تكن حزمة مصادقة ، ولكن من آخر منفذ IP والعميل الذي تم تذكره ، فيمكن إما تمريرها أو تجاهلها. إذا كانت الحزمة المصادق عليها تأتي من IP ومنفذ جديدين ، فسيتم إعادة تكوين النفق لاستخدامهما.
يواجه IPIP-over-FOU المعتاد مشكلة أخرى عند العمل مع NAT - لا يمكنك إنشاء أنفاق IPIP مغلفة في UDP بنفس عنوان IP ، لأن وحدتي FOU و IPIP منفصلتان تمامًا عن بعضهما البعض. أولئك. لن يتمكن زوج من العملاء خلف نفس عنوان IP العام من الاتصال بنفس الخادم في نفس الوقت بهذه الطريقة. في المستقبل ، قد يتم حلها على مستوى النواة ، لكن هذا غير مؤكد. في غضون ذلك ، يمكن حل مشاكل NAT بواسطة NAT - إذا حدث أن زوجًا من عناوين IP مشغول بالفعل بواسطة نفق آخر ، فإن ipipou سوف يقوم NAT من عام إلى عنوان IP خاص بديل ، فويلا! - يمكنك إنشاء أنفاق حتى تنفد المنافذ.
لان ليست كل الحزم في الاتصال موقعة ، فإن هذه الحماية البسيطة تكون عرضة لـ MITM ، لذلك إذا كان الشرير يتربص بين العميل والخادم ، والذي يمكنه الاستماع والتحكم في حركة المرور ، يمكنه إعادة توجيه الحزم المصادق عليها من خلال عنوان آخر وإنشاء نفق من مضيف غير موثوق به ...
إذا كان لدى أي شخص أي أفكار حول كيفية إصلاح ذلك مع الحفاظ على الجزء الأكبر من حركة المرور في جوهرها ، فلا تتردد في التحدث.
بالمناسبة ، أثبت تغليف UDP نفسه جيدًا. مقارنةً بالتغليف عبر IP ، فهو أكثر استقرارًا وأسرع غالبًا على الرغم من حمل رأس UDP الإضافي. ويرجع ذلك إلى حقيقة أن غالبية المضيفين على الإنترنت يعملون بشكل جيد مع البروتوكولات الثلاثة الأكثر شيوعًا: TCP و UDP و ICMP. يمكن للجزء المحسوس عمومًا أن يتجاهل كل شيء آخر ، أو يعمل بشكل أبطأ ، لأنه محسّن فقط لهؤلاء الثلاثة.
على سبيل المثال ، لذلك ، تم إنشاء QUICK ، على أساسه تم إنشاء HTTP / 3 عبر UDP ، وليس عبر IP.
حسنًا ، كلمات كافية ، حان الوقت لنرى كيف تعمل في "العالم الحقيقي".
معركة
تستخدم لمحاكاة العالم الحقيقي
iperf3. من حيث درجة القرب من الواقع ، يتعلق الأمر بمحاكاة العالم الحقيقي في Minecraft ، ولكن في الوقت الحالي ستفعل.
تتضمن المسابقة:
- قناة مرجعية رئيسية
- بطل هذا المقال هو ipipou
- OpenVPN مع مصادقة ولكن بدون تشفير
- OpenVPN All Inclusive
- WireGuard بدون مفتاح مشترك مسبقًا ، مع MTU = 1440 (لـ IPv4 فقط)
البيانات الفنية للمهوسين
يتم أخذ المقاييس بواسطة الأوامر التالية
على العميل:
UDP
TCP
زمن انتقال ICMP
( ):
UDP
TCP
ipipou
openvpn ( , )
openvpn (c , , UDP, )
openvpn-manage
wireguard
على العميل:
UDP
CPULOG=NAME.udp.cpu.log; sar 10 6 >"$CPULOG" & iperf3 -c SERVER_IP -4 -t 60 -f m -i 10 -B LOCAL_IP -P 2 -u -b 12M; tail -1 "$CPULOG"
# "-b 12M" , "-P", .
TCP
CPULOG=NAME.tcp.cpu.log; sar 10 6 >"$CPULOG" & iperf3 -c SERVER_IP -4 -t 60 -f m -i 10 -B LOCAL_IP -P 2; tail -1 "$CPULOG"
زمن انتقال ICMP
ping -c 10 SERVER_IP | tail -1
( ):
UDP
CPULOG=NAME.udp.cpu.log; sar 10 6 >"$CPULOG" & iperf3 -s -i 10 -f m -1; tail -1 "$CPULOG"
TCP
CPULOG=NAME.tcp.cpu.log; sar 10 6 >"$CPULOG" & iperf3 -s -i 10 -f m -1; tail -1 "$CPULOG"
ipipou
/etc/ipipou/server.conf:
server
number 0
fou-dev eth0
fou-local-port 10000
tunl-ip 172.28.0.0
auth-remote-pubkey-b64 eQYNhD/Xwl6Zaq+z3QXDzNI77x8CEKqY1n5kt9bKeEI=
auth-secret topsecret
auth-lifetime 3600
reply-on-auth-ok
verb 3
systemctl start ipipou@server
/etc/ipipou/client.conf:
client
number 0
fou-local @eth0
fou-remote SERVER_IP:10000
tunl-ip 172.28.0.1
# pubkey of auth-key-b64: eQYNhD/Xwl6Zaq+z3QXDzNI77x8CEKqY1n5kt9bKeEI=
auth-key-b64 RuBZkT23na2Q4QH1xfmZCfRgSgPt5s362UPAFbecTso=
auth-secret topsecret
keepalive 27
verb 3
systemctl start ipipou@client
openvpn ( , )
openvpn --genkey --secret ovpn.key # ovpn.key
openvpn --dev tun1 --local SERVER_IP --port 2000 --ifconfig 172.16.17.1 172.16.17.2 --cipher none --auth SHA1 --ncp-disable --secret ovpn.key
openvpn --dev tun1 --local LOCAL_IP --remote SERVER_IP --port 2000 --ifconfig 172.16.17.2 172.16.17.1 --cipher none --auth SHA1 --ncp-disable --secret ovpn.key
openvpn (c , , UDP, )
openvpn-manage
wireguard
/etc/wireguard/server.conf:
[Interface]
Address=172.31.192.1/18
ListenPort=51820
PrivateKey=aMAG31yjt85zsVC5hn5jMskuFdF8C/LFSRYnhRGSKUQ=
MTU=1440
[Peer]
PublicKey=LyhhEIjVQPVmr/sJNdSRqTjxibsfDZ15sDuhvAQ3hVM=
AllowedIPs=172.31.192.2/32
systemctl start wg-quick@server
/etc/wireguard/client.conf:
[Interface]
Address=172.31.192.2/18
PrivateKey=uCluH7q2Hip5lLRSsVHc38nGKUGpZIUwGO/7k+6Ye3I=
MTU=1440
[Peer]
PublicKey=DjJRmGvhl6DWuSf1fldxNRBvqa701c0Sc7OpRr4gPXk=
AllowedIPs=172.31.192.1/32
Endpoint=SERVER_IP:51820
systemctl start wg-quick@client
النتائج
قرص الخام القبيح
CPU , .. :
proto bandwidth[Mbps] CPU_idle_client[%] CPU_idle_server[%]
# 20 Mbps (4 core) VPS (1 core)
# pure
UDP 20.4 99.80 93.34
TCP 19.2 99.67 96.68
ICMP latency min/avg/max/mdev = 198.838/198.997/199.360/0.372 ms
# ipipou
UDP 19.8 98.45 99.47
TCP 18.8 99.56 96.75
ICMP latency min/avg/max/mdev = 199.562/208.919/220.222/7.905 ms
# openvpn0 (auth only, no encryption)
UDP 19.3 99.89 72.90
TCP 16.1 95.95 88.46
ICMP latency min/avg/max/mdev = 191.631/193.538/198.724/2.520 ms
# openvpn (full encryption, auth, etc)
UDP 19.6 99.75 72.35
TCP 17.0 94.47 87.99
ICMP latency min/avg/max/mdev = 202.168/202.377/202.900/0.451 ms
# wireguard
UDP 19.3 91.60 94.78
TCP 17.2 96.76 92.87
ICMP latency min/avg/max/mdev = 217.925/223.601/230.696/3.266 ms
## -1Gbps VPS (1 core)
# pure
UDP 729 73.40 39.93
TCP 363 96.95 90.40
ICMP latency min/avg/max/mdev = 106.867/106.994/107.126/0.066 ms
# ipipou
UDP 714 63.10 23.53
TCP 431 95.65 64.56
ICMP latency min/avg/max/mdev = 107.444/107.523/107.648/0.058 ms
# openvpn0 (auth only, no encryption)
UDP 193 17.51 1.62
TCP 12 95.45 92.80
ICMP latency min/avg/max/mdev = 107.191/107.334/107.559/0.116 ms
# wireguard
UDP 629 22.26 2.62
TCP 198 77.40 55.98
ICMP latency min/avg/max/mdev = 107.616/107.788/108.038/0.128 ms
قناة 20 ميغابت في الثانية
لـ 1 Gbps متفائل
في جميع الأحوال ipipou قريبة جدًا من حيث الأداء من القناة الأساسية ، وهذا رائع!
تصرف نفق openvpn غير المشفر بشكل غريب في كلتا الحالتين.
إذا كان أي شخص سيختبرها ، فسيكون من الممتع سماع التعليقات.
قد يكون IPv6 و NetPrickle معنا!