พร็อกซี SSH ถุงเท้าตามคำขอผ่านหน่วยผู้ใช้ systemd พร้อมการเปิดใช้งานซ็อกเก็ตไม่รีสตาร์ทตามที่ต้องการ


14

ในการเข้าถึงเครือข่ายที่แยกผมใช้ -D พร็อกซี่

เพื่อหลีกเลี่ยงการต้องพิมพ์รายละเอียดทุกครั้งที่ฉันเพิ่มลงใน~/.ssh/config:

$ awk '/Host socks-proxy/' RS= ~/.ssh/config
Host socks-proxy
  Hostname pcit
  BatchMode yes
  RequestTTY no
  Compression yes
  DynamicForward localhost:9118

จากนั้นฉันสร้างไฟล์ข้อกำหนดหน่วยบริการ :

$ cat ~/.config/systemd/user/SocksProxy.service 
[Unit]
Description=SocksProxy Over Bridge Host

[Service]
ExecStart=/usr/bin/ssh -Nk socks-proxy

[Install]
WantedBy=default.target

ฉันปล่อยให้ daemon โหลดข้อกำหนดบริการใหม่เปิดใช้บริการใหม่เริ่มตรวจสอบสถานะและตรวจสอบว่ากำลังฟังอยู่:

$ systemctl --user daemon-reload
$ systemctl --user list-unit-files | grep SocksP
SocksProxy.service   disabled

$ systemctl --user enable SocksProxy.service
Created symlink from ~/.config/systemd/user/default.target.wants/SocksProxy.service to ~/.config/systemd/user/SocksProxy.service.

$ systemctl --user start SocksProxy.service 
$ systemctl --user status SocksProxy.service 
● SocksProxy.service - SocksProxy Over Bridge Host
   Loaded: loaded (/home/alex/.config/systemd/user/SocksProxy.service; enabled)
   Active: active (running) since Thu 2017-08-03 10:45:29 CEST; 2s ago
 Main PID: 26490 (ssh)
   CGroup: /user.slice/user-1000.slice/user@1000.service/SocksProxy.service
           └─26490 /usr/bin/ssh -Nk socks-proxy

$ netstat -tnlp | grep 118
tcp     0    0 127.0.0.1:9118        0.0.0.0:*             LISTEN     
tcp6    0    0 ::1:9118              :::*                  LISTEN

ใช้งานได้ตามที่ตั้งใจ จากนั้นฉันต้องการหลีกเลี่ยงการเริ่มบริการด้วยตนเองหรือเรียกใช้อย่างถาวรด้วยโดยใช้ สำหรับการวางไข่ตามคำขอ (อีกครั้ง) ไม่ทำงานฉันคิดว่า (เวอร์ชันของฉัน) ไม่สามารถรับไฟล์ตัวอธิบายซ็อกเก็ตได้ssh

ฉันพบเอกสาร ( 1 , 2 ) และตัวอย่างสำหรับการใช้systemd-socket-proxyd-tool เพื่อสร้าง 2 "wrapper" services "service" และ "socket":

$ cat ~/.config/systemd/user/SocksProxyHelper.socket 
[Unit]
Description=On Demand Socks proxy into Work

[Socket]
ListenStream=8118
#BindToDevice=lo
#Accept=yes

[Install]
WantedBy=sockets.target

$ cat ~/.config/systemd/user/SocksProxyHelper.service 
[Unit]
Description=On demand Work Socks tunnel
After=network.target SocksProxyHelper.socket
Requires=SocksProxyHelper.socket SocksProxy.service
After=SocksProxy.service

[Service]
#Type=simple
#Accept=false
ExecStart=/lib/systemd/systemd-socket-proxyd 127.0.0.1:9118
TimeoutStopSec=5

[Install]
WantedBy=multi-user.target

$ systemctl --user daemon-reload

นี้ดูเหมือนว่าการทำงานจนsshตายหรือได้รับฆ่า จากนั้นจะไม่เกิดใหม่อีกครั้งในการพยายามเชื่อมต่อครั้งถัดไปเมื่อต้องการ

คำถาม:

  1. สามารถ / usr / bin / ssh ไม่ยอมรับซ็อกเก็ต systemd-pass หรือไม่ หรือรุ่นที่ใหม่กว่าเท่านั้น? เหมืองแร่เป็นหนึ่งจาก up2date Debian 8.9
  2. หน่วยของรูทใช้BindTodeviceตัวเลือกได้หรือไม่
  3. เหตุใดบริการพร็อกซีของฉันจึงไม่ตอบสนองอย่างถูกต้องในการเชื่อมต่อใหม่ครั้งแรกหลังจากอุโมงค์เก่าตาย
  4. นี่เป็นวิธีที่เหมาะสมในการตั้งค่า "พร็อกซีถุงเท้า ssh ถุงเท้าตามความต้องการ" หรือไม่? ถ้าไม่คุณจะทำอย่างไร

autosshควรดูแลการเชื่อมต่อใหม่ในกรณีที่การเชื่อมต่อล้มเหลว (แม้ว่าจะไม่ใช่ระบบ)
Jakuje

@Jakuje: ขอบคุณสำหรับความคิดเห็น แต่ฉันไม่ต้องการให้การเชื่อมต่อเป็นแบบถาวร ฉันต้องการให้มันเกิดใหม่เมื่อฉันใช้มันและหลังจากนั้น (โดยเฉพาะอย่างยิ่งหลังจากการหมดเวลาที่ไม่มีข้อมูลที่ส่งใน x x นาที) สิ้นสุดลงด้วยตนเอง autosshนอกจากนี้ยังมีวิธีการแก้ปัญหาของฉันก่อนหน้าใช้
Alex Stragies

คำตอบ:


4
  • สามารถ / usr / bin / ssh ไม่ยอมรับซ็อกเก็ต systemd-pass หรือไม่

ฉันคิดว่ามันไม่น่าแปลกใจมากเมื่อพิจารณา:

  • OpenSSH เป็นโครงการ OpenBSD
  • systemd รองรับเฉพาะเคอร์เนล Linux
  • การสนับสนุน systemd จะต้องมีการเพิ่มลงใน OpenSSH อย่างชัดเจนเนื่องจากเป็นทางเลือก / การสร้างเวลาดังนั้นจึงอาจเป็นการขายยาก

  • หน่วยของรูทใช้BindTodeviceตัวเลือกได้หรือไม่

โดยทั่วไปอินสแตนซ์ของผู้ใช้ systemd นั้นค่อนข้างจะแยกได้และเช่นไม่สามารถสื่อสารกับอินสแตนซ์ pid-0 หลักได้ สิ่งที่ต้องการขึ้นอยู่กับหน่วยระบบจากไฟล์หน่วยผู้ใช้เป็นไปไม่ได้

เอกสารสำหรับการBindToDeviceกล่าวถึง:

โปรดทราบว่าการตั้งค่าพารามิเตอร์นี้อาจส่งผลให้เพิ่มการอ้างอิงเพิ่มเติมลงในหน่วย (ดูด้านบน)

เนื่องจากข้อ จำกัด ดังกล่าวข้างต้นเราสามารถบอกเป็นนัยได้ว่าตัวเลือกไม่ทำงานจากผู้ใช้ systemd อินสแตนซ์


  • เหตุใดบริการพร็อกซีของฉันจึงไม่ตอบสนองอย่างถูกต้องในการเชื่อมต่อใหม่ครั้งแรกหลังจากอุโมงค์เก่าตาย

ดังที่ฉันเข้าใจห่วงโซ่ของเหตุการณ์เป็นดังนี้:

  • SocksProxyHelper.socket เริ่มแล้ว
  • SOCKS client เชื่อมต่อกับ localhost: 8118
  • SocksProxyHelper.serviceเริ่มต้น systemd
  • ในฐานะที่พึ่งพาของSocksProxyHelper.service, systemd SocksProxy.serviceยังเริ่มต้น
  • systemd-socket-proxydยอมรับซ็อกเก็ต systemd sshและส่งต่อข้อมูลไปยัง
  • ssh ตายหรือถูกฆ่าตาย
  • ประกาศ systemd และวางSocksProxy.serviceไว้ในสถานะไม่ใช้งาน แต่ไม่ทำอะไรเลย
  • SocksProxyHelper.serviceยังคงทำงานและยอมรับการเชื่อมต่อ แต่ไม่สามารถเชื่อมต่อได้sshเนื่องจากไม่ได้ทำงานอีกต่อไป

การแก้ไขคือการเพิ่มการBindsTo=SocksProxy.service SocksProxyHelper.serviceการอ้างถึงเอกสาร (เน้นการเพิ่ม):

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

เมื่อใช้ร่วมกับAfter=ยูนิตเดียวกันพฤติกรรมของBindsTo=จะแข็งแกร่งยิ่งขึ้น ในกรณีนี้หน่วยผูกพันที่จะเคร่งครัดจะต้องมีในสภาพที่ใช้งานสำหรับหน่วยนี้ยังอยู่ในสภาพที่ใช้งาน นี้ไม่เพียง แต่หมายความว่าหน่วยที่ถูกผูกไว้กับหน่วยที่อยู่ ๆ ก็เข้าสู่สภาวะที่ไม่ใช้งานอีก แต่ยังเป็นหนึ่งที่ถูกผูกไว้กับหน่วยงานที่ได้รับข้ามไปอีกเนื่องจากมีการตรวจสอบสภาพล้มเหลว (เช่นConditionPathExists=, ConditionPathIsSymbolicLink=... - ดูด้านล่าง) จะหยุดควรมัน จะวิ่ง ดังนั้นในหลายกรณีที่ดีที่สุดคือการรวมกับBindsTo=After=


  • นี่เป็นวิธีที่เหมาะสมในการตั้งค่า "พร็อกซีถุงเท้า ssh ถุงเท้าตามความต้องการ" หรือไม่? ถ้าไม่คุณจะทำอย่างไร

อาจไม่มี "วิธีที่ถูกต้อง" วิธีนี้มีข้อดีของมัน (ทุกอย่างเป็น "ตามคำขอ") และข้อเสีย (การพึ่งพา systemd, การเชื่อมต่อครั้งแรกไม่ผ่านเพราะ ssh ยังไม่เริ่มฟัง) บางทีการใช้การสนับสนุนการเปิดใช้งานซ็อกเก็ต systemd ใน autossh อาจเป็นทางออกที่ดีกว่า


ฉันได้เพิ่มBindsTo=SocksProxy.serviceไปยังส่วนหน่วยของไฟล์~/.config/systemd/user/SocksProxyHelper.serviceหลังจากAfter=SocksProxy.serviceบรรทัด การเริ่มบริการ SocksProxy ด้วยตนเองไม่จำเป็นต้องใช้อีกต่อไปเมื่อ SSH ตาย / gets_killed มีวิธีสำหรับ systemd เพื่อ "ระงับ" การเชื่อมต่อเริ่มต้นเพื่อที่จะไม่ได้รับการรีเซ็ต TCP หรือไม่?
Alex Stragies

@Vladimir Panteleev จุดหนึ่งที่ฉันต้องการชี้แจง: การสนับสนุนสำหรับการเปิดใช้งานซ็อกเก็ต systemd สามารถดำเนินการได้อย่างง่ายดายโดยการแยกวิเคราะห์$LISTEN_FDSโดยไม่ต้องเพิ่มการพึ่งพาsd_listen_fds()ดังนั้นจึงอาจยังคงขายยาก แต่ไม่ยากเกินไป
อาเมียร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.