สิ่งที่ต้องได้รับอนุญาตในไฟร์วอลล์เพื่อให้ไคลเอนต์ WireGuard สามารถเชื่อมต่อกันผ่าน SSH ได้


การตั้งค่า

ฉันมีไคลเอนต์สองเครื่องและเซิร์ฟเวอร์หนึ่งเครื่องในเครือข่าย WireGuard VPN ทั้งหมดนั้นใช้ Debian 11

CLIENT A -------- SERVER -------- CLIENT B
10.0.1.2         10.0.1.1         10.0.1.3

สิ่งที่สามารถทำได้

  • ฉันสามารถ SSH จากลูกค้ารายใดรายหนึ่งไปยังเซิร์ฟเวอร์
  • ฉันสามารถ SSH จากเซิร์ฟเวอร์ไปยังไคลเอนต์ใดก็ได้

ปัญหา: แต่เมื่อฉันพยายามไคลเอนต์ SSH กับไคลเอนต์ ฉันจะได้รับ "ssh: เชื่อมต่อกับโฮสต์ 10.0.1.2 พอร์ต 22: ไม่มีเส้นทางไปยังโฮสต์"


การแก้ไขปัญหา

  1. เส้นทางระหว่างเครื่องขึ้นเพราะผมปิงได้...
    • ลูกค้าไปยังเซิร์ฟเวอร์,
    • เซิร์ฟเวอร์ให้กับลูกค้า,
    • และลูกค้าให้กับลูกค้า
  2. พอร์ตสามารถเข้าถึงได้เพราะฉันสามารถ telnet...
    • จากเซิร์ฟเวอร์ไปยังไคลเอ็นต์บนพอร์ต 22
    • จากไคลเอนต์ใดไปยังเซิร์ฟเวอร์บนพอร์ต 22

ปัญหา: แต่เมื่อฉันพยายามไคลเอ็นต์ telnet ไปยังไคลเอนต์ ฉันได้รับ "telnet: ไม่สามารถเชื่อมต่อกับโฮสต์ระยะไกล: ไม่มีเส้นทางไปยังโฮสต์"


สิ่งที่ได้รับการยืนยัน

  • SSH เป็นบริการที่ระบุไว้ใน firewalld: firewall-cmd --list-servicesreturnssh
  • ip-foward ถูกตั้งค่าบนเคอร์เนล: sysctl -areturnnet.ipv4.ip_forward = 1
  • การส่งต่อถูกตั้งค่าบน iptables: iptables-savereturn-A FORWARD -i wg0 -o wg0 -j ACCEPT
  • การปิดใช้งานไฟร์วอลล์บนเซิร์ฟเวอร์ทำให้สามารถเชื่อมต่อ SSH ระหว่างไคลเอ็นต์ WireGuard สองเครื่องได้

ขอบคุณสำหรับความช่วยเหลือและตัวชี้ของคุณ

answer

แม้ว่าโดยทั่วไปแล้ว firewalld จะเป็นเครื่องมือที่ยอดเยี่ยมสำหรับการกำหนดค่าไฟร์วอลล์บนกล่อง Linux แต่สำหรับกรณีการใช้งานเฉพาะนี้ - การส่งต่อการรับส่งข้อมูลสำหรับโฮสต์อื่น ๆ - การใช้งานค่อนข้างยุ่งยาก ฉันขอแนะนำให้ปิดบนเซิร์ฟเวอร์ของคุณและเพียงแค่ใช้ iptables (หรือ nftables) โดยตรง

หากคุณต้องการใช้ firewalld จริงๆ ให้ลองทำสิ่งนี้ (ในฐานะรูท):

1. สร้างโซนที่กำหนดเองสำหรับอินเทอร์เฟซ WireGuard ของคุณที่ยอมรับการรับส่งข้อมูลทั้งหมด:
firewall-cmd --permanent --new-zone=mywg
firewall-cmd --permanent --zone=mywg --set-target=ACCEPT
firewall-cmd --reload
2. เพิ่มกฎ "รวย" ในโซนเพื่อปฏิเสธการเชื่อมต่อขาเข้าจาก WireGuard ไปยังเซิร์ฟเวอร์:
firewall-cmd --zone=mywg --add-rich-rule='rule family="ipv4" priority="30001" protocol value="tcp" reject'
firewall-cmd --zone=mywg --add-rich-rule='rule family="ipv4" priority="30002" protocol value="udp" reject'
firewall-cmd --zone=mywg --add-rich-rule='rule family="ipv6" priority="30003" protocol value="tcp" reject'
firewall-cmd --zone=mywg --add-rich-rule='rule family="ipv6" priority="30004" protocol value="udp" reject'
3. เพิ่มกฎ "โดยตรง" เพื่ออนุญาตการส่งต่อการเชื่อมต่อ IPv4 SSH ระหว่างโฮสต์ WireGuard อื่นๆ และปฏิเสธทุกอย่าง:
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i wg0 -m state --state ESTABLISHED,RELATED -j ACCEPT
firewall-cmd --direct --add-rule ipv4 filter FORWARD 1 -i wg0 -o wg0 -m state --state NEW -p tcp --dport 22 -j ACCEPT
firewall-cmd --direct --add-rule ipv4 filter FORWARD 2 -i wg0 -j REJECT
firewall-cmd --direct --add-rule ipv6 filter FORWARD 0 -i wg0 -j REJECT
4. ผูกโซนเข้ากับอินเทอร์เฟซ WireGuard ของคุณและบันทึกการเปลี่ยนแปลงของคุณ:
firewall-cmd --zone=mywg --add-interface=wg0
firewall-cmd --runtime-to-permanent

คุณสามารถเพิ่มกฎโดยตรงของ IPv4 ระหว่าง 0 ถึง 2 (เปลี่ยนหมายเลขREJECTกฎให้เป็นลำดับสุดท้าย) หากคุณต้องการอนุญาตการรับส่งข้อมูลประเภทอื่นระหว่างโฮสต์ WireGuard ของคุณ (หรือเพียงแค่แทนที่กฎ 0 และ 1 ด้วยกฎเดียว เช่น-i wg0 -o wg0 -J ACCEPTถ้าคุณต้องการอนุญาต เซิร์ฟเวอร์เพื่อส่งต่อการรับส่งข้อมูลระหว่างโฮสต์ WireGuard ของคุณ)

ดูหัวข้อ Hub and Spoke ของบทความวิธีใช้ WireGuard กับ Firewalldสำหรับคำอธิบายแบบเต็ม (โฮสต์ C คือเซิร์ฟเวอร์ของคุณในบทความนี้)