อุปกรณ์ของคุณอยู่หลัง NAT ของผู้ให้บริการ สามารถเปิดการเชื่อมต่อขาออกได้ และรันเซิร์ฟเวอร์ SSH ที่ไม่มีใครเข้าถึงได้ คำขอที่เข้ามามักถูกเขียนว่า "ให้ VPN กับมันหน่อย" ซึ่งเป็นคำตอบหนึ่งในหลายคำตอบ ก่อนจะรับคำขอนั้น ให้ตัดสินว่าคุณต้องการพอร์ต TCP สำหรับผู้ดูแลระบบเพียงพอร์ตเดียว หรือ เส้นทางที่กำหนดเส้นทางไปยังทั้งซับเน็ตเพราะสิ่งเหล่านั้นเป็นโปรเจกต์ที่ต่างกันและมีความเสี่ยงเปิดเผยต่างกัน

อุโมงค์ย้อนกลับตอบโจทย์แบบแคบได้ดี อุปกรณ์ต่อเข้าฮับของคุณ ขอให้ฮับรับฟังบนพอร์ต loopback แล้วส่งพอร์ตนั้นกลับไปยังบริการ SSH ของตัวเอง จากนั้นผู้ดูแลระบบเข้าถึงตัวรับฟังผ่านฮับ ไม่ใช่ผ่านอินเทอร์เน็ตสาธารณะ

สามเงื่อนไขที่ชี้ขาดการเลือก

จดสิ่งเหล่านี้ไว้ก่อนการกำหนดค่าใด ๆ มันคือเส้นแบ่งระหว่างทางเข้าจัดการแบบจำกัดกับส่วนขยายเครือข่าย และการปนกันคือหนทางที่อุโมงค์ห้าบรรทัดกลายเป็นเครือข่ายแบนราบที่ไม่มีเจ้าของ

ConditionReverse tunnel fitsSomething else is needed
How many services must be reachable?One, or a small fixed set on loopbackAnything that needs many ports or dynamic discovery
Who connects, and how are they authenticated?Named administrators with their own hub accountsThird parties, or anything needing per-flow audit you do not control
Does the device's own LAN need to be reachable?NoYes, so a routed VPN or a managed platform is the honest answer

แถวที่สามคือแถวที่คนถกเถียงกัน อุโมงค์ไปยังพอร์ต SSH ของอุปกรณ์ไม่ได้นำเพื่อนบ้านของมันเข้าสู่เครือข่ายของคุณ และไม่ควรทำให้ดูเหมือนทำเช่นนั้นผ่านห่วงโซ่การส่งต่อเพิ่มเติม หากความต้องการคือ LAN จริง ๆ ก็บอกอย่างนั้นแล้วออกแบบ LAN แทน

ฝั่งฮับ: บัญชีรีเลย์แบบจำกัด

ให้แต่ละอุปกรณ์มีบัญชีรีเลย์ของตัวเองพร้อมการพิสูจน์ตัวตนด้วยกุญแจสาธารณะและไม่มีเซสชันแบบโต้ตอบ Match บล็อกที่จำกัดเฉพาะบัญชีนั้นทำให้สิทธิ์มีขนาดเล็ก และกุญแจส่วนตัวยังอยู่บนอุปกรณ์ที่มันควรอยู่

Match User relay-dev-7
    AuthenticationMethods publickey
    PubkeyAuthentication yes
    AllowTcpForwarding remote
    PermitListen 127.0.0.1:21022
    GatewayPorts no
    MaxSessions 0
    PermitTTY no
    X11Forwarding no
    AllowAgentForwarding no

MaxSessions 0 คือบรรทัดที่น่าสนใจ มันปฏิเสธเซสชันเชลล์และระบบย่อย แต่ยังอนุญาตการส่งต่อที่อุปกรณ์ต้องการ ดังนั้นกุญแจที่ถูกขโมยจึงเปลี่ยนเป็นการเข้าสู่ระบบแบบโต้ตอบไม่ได้ PermitListen ตรึงที่อยู่และพอร์ตของตัวรับฟังฝั่งฮับ และ GatewayPorts no เก็บมันไว้บน loopback แทนที่จะเปิดสู่เครือข่ายที่ฮับตั้งอยู่

ทดสอบการกำหนดค่าที่มีผลจริงก่อนโหลดใหม่ และเปิดเซสชันที่สองค้างไว้ระหว่างทำ Match บล็อกที่บังเอิญมีผลกับทุกคน หรือการพิมพ์ผิดในชื่อออปชัน คือวิธีคลาสสิกในการล็อกตัวเองออกจากเครื่องที่คุณกำลังเสริมความปลอดภัย ทิ้งการกำหนดค่าที่กำลังทำงานและอ่านออปชันกลับมา แทนที่จะเชื่อไฟล์ที่เพิ่งเขียน โปรดสังเกตว่าการรองรับออปชันต่างกันระหว่างบิลด์ ดังนั้นบรรทัดที่เซิร์ฟเวอร์ใหม่ยอมรับอาจถูกเซิร์ฟเวอร์เก่าเพิกเฉยได้เลย

ฝั่งอุปกรณ์: การส่งต่อที่ล้มเหลวอย่างเสียงดัง

อุปกรณ์เปิดการเชื่อมต่อและขอตัวรับฟัง ที่อยู่ทั้งสองในอาร์กิวเมนต์ -R มีความหมายต่างกัน และการอ่านจากซ้ายไปขวาคือวิธีที่เร็วที่สุดในการจำว่าตัวไหนเป็นตัวไหน

ssh -NT \
    -o ExitOnForwardFailure=yes \
    -o ServerAliveInterval=30 \
    -o ServerAliveCountMax=3 \
    -R 127.0.0.1:21022:127.0.0.1:22 \
    [email protected]

คู่ซ้ายคือที่ที่ฮับควรรับฟัง คู่ขวาคือสิ่งที่อุปกรณ์เชื่อมต่อเมื่อมีคำขอเข้ามา ซึ่งแก้ไขจากฝั่งของอุปกรณ์เอง การสลับทั้งสองทำให้เกิดอุโมงค์ที่ขึ้นมาอย่างสะอาดแต่ส่งต่อไปยังที่ผิด ซึ่งแย่กว่าการล้มเหลว

ExitOnForwardFailure=yes ทำให้คำสั่งออกเมื่อไม่สามารถสร้างตัวรับฟังที่ขอได้ ลูปการรีสตาร์ตจึงบอกความจริงกับคุณแทนที่จะทิ้งเซสชันที่ทำงานครึ่งเดียว มันไม่บอกอะไรเลยว่าบริการ SSH ภายในจะยังดีอยู่หรือไม่ในภายหลัง จึงควรจับคู่กับตัวจัดการโปรเซสและการทดสอบการเชื่อมต่อจริงเป็นครั้งคราว

อย่าแทนที่ที่อยู่รับฟัง loopback ด้วยไวลด์การ์ดเพื่อเลี่ยงการกระโดดเพิ่ม ที่เปลี่ยนเพียงอย่างเดียวนั้นคือความต่างระหว่างเส้นทางจัดการกับพอร์ตที่เข้าถึงได้จากสาธารณะ และมักเกิดขึ้นระหว่างการดีบักแล้วก็คงอยู่ หากเพื่อนร่วมงานเข้าถึงพอร์ตผ่านฮับไม่ได้ ให้แก้การกำหนดค่าการกระโดดแทนการขยายการผูก ระบบความปลอดภัยทั้งหมดของดีไซน์นี้คือ loopback

การเข้าถึงของผู้ดูแลระบบผ่านฮับ

ผู้ดูแลระบบที่มีบัญชีธรรมดาบนฮับสามารถกระโดดผ่านฮับไปยังพอร์ตที่ส่งต่อได้ บัญชีรีเลย์ไม่ได้ถูกใช้สำหรับสิ่งนี้ และนั่นคือประเด็นของการแยกทั้งสองออกจากกัน

ssh -J [email protected] -o HostKeyAlias=device-7 \
    -p 21022 [email protected]

ตรวจสอบกุญแจโฮสต์ของอุปกรณ์ภายใต้นามแฝงที่คุณเลือก เพราะกุญแจนั้นระบุตัวอุปกรณ์ที่ปลายห่วงโซ่ และอุโมงค์เป็นเพียงการขนส่ง การเข้าสู่ระบบจากปลายถึงปลายยังพิสูจน์ตัวตนทั้งสองฝั่ง อุโมงค์ที่สิ้นสุดบนฮับร่วมไม่ได้ทำให้มันเป็นเส้นทางที่เชื่อถือได้ด้วยตัวเอง

เป็นเจ้าของวงจรชีวิต

รันคำสั่งของอุปกรณ์ภายใต้ตัวจัดการโปรเซสด้วยอินสแตนซ์ที่ใช้งานอยู่เพียงหนึ่งเดียวและนโยบายรีสตาร์ตที่คุณเลือกอย่างตั้งใจ ออปชัน keepalive ตรวจจับคู่ที่ตายแล้ว แต่ไม่ได้ฟื้นโปรเซสที่จบไปแล้ว

จากนั้นเขียนขั้นตอนการปลดระวาง อุปกรณ์แต่ละเครื่องมีตัวรับฟังของตัวเองและกุญแจของตัวเอง การปลดระวางจึงหมายถึงการเพิกถอนบัญชีนั้นและลบกุญแจนั้น ไม่ใช่การหมุนเวียนความลับที่ทั้งกองเรือใช้ร่วมกัน

สุดท้าย จำไว้ว่า loopback ให้อะไรคุณ มันจำกัดการเปิดเผยต่อเครือข่ายและไม่ได้ทำอะไรกับผู้ใช้ภายในคนอื่นบนฮับร่วม ดังนั้นนโยบายการเข้าถึงของฮับเองยังต้องถูกต้อง เอกสารอ้างอิง sshd_config อธิบายทุกออปชันที่ใช้ข้างต้น และคุ้มค่าที่จะอ่านส่วนการส่งต่อให้ครบก่อนขยายอันใดอันหนึ่ง

บทความที่เกี่ยวข้อง