วิธีการไพพ์ข้อมูลเพื่อการเชื่อมต่อ SFTP?


9

ftp สนับสนุนput "|..." "remote-file.name"คำสั่งเพื่อไพพ์ข้อมูลไปยังการเชื่อมต่อ ftp มีบางอย่างที่คล้ายกันสำหรับ sftp หรือไม่

ใน SFTP ฉันได้รับข้อผิดพลาดต่อไปนี้:

sftp 'jmw@backupsrv:/uploads'
sftp> put "| tar -cx /storage" "backup-2012-06-19--17-51.tgz"
stat | tar -cv /storage: No such file or directory

ดังกล่าวข้างต้นไคลเอนต์ sftp ไม่ชัดเจนรันคำสั่ง

ฉันต้องการใช้คำสั่ง pipe เพื่อเปลี่ยนเส้นทางสตรีมไฟล์ไปยัง sftp โดยตรง (เนื่องจากมีพื้นที่ไม่เพียงพอที่จะสร้างไฟล์สำรองข้อมูลบนดิสก์เดียวกันก่อนที่จะอัปโหลดไปยังเซิร์ฟเวอร์ sftp)


1
ฉันคิดถึงการใช้ FIFO สำหรับสิ่งนี้ แต่ SFTP และ SCP จะไม่อ่านจาก FIFO
Tom Anderson

1
ยังเป็นความคิดที่ดีนี่คือของฉัน: qxs.ch/2012/07/05/sftp-upload-tool
JMW

คำตอบ:


4

ฉันสนุกกับการหาวิธีแก้ไขปัญหานี้ ต้องการเครื่องมือ nc (netcat) บนเครื่องทั้งสองและไม่จำเป็นต้องใช้ SSH (SFTP)

ในตัวอย่างนี้ฉันจะเรียกเครื่องที่มีข้อมูลที่ต้องสำรองข้อมูล linux-a และเครื่องที่ต้องได้รับ backup linux-b

บน linux-a ให้ netcat ฟังพอร์ต (ฉันใช้ 2000) และเปลี่ยนเส้นทางไปยังไฟล์ นี่จะนั่งตรงนั้นและรอจนกว่าจะมีอะไรผ่านเข้ามาในพอร์ตนั้น

[kenny@linux-b /var/backups]$ nc -l 2000 > backup.tgz

บน linux-b เปิดอุโมงค์ ssh ไปยัง linux-a ฉันใช้พอร์ต 2000 อีกครั้ง สิ่งนี้จะเปลี่ยนเส้นทางสิ่งที่คุณส่งไปที่พอร์ต TCP 2000 บนโลคัลโฮสต์ไปยังพอร์ต TCP 2000 บน linux-a โดยที่ netcat กำลังฟัง

[kenny@linux-a /var/data]$ ssh -L 2000:localhost:2000 -CfN linux-b

ตอนนี้สร้างไฟล์เก็บถาวร tar แต่ส่งออกไปยัง stdout (โดยใช้ -) และไพพ์ไปยัง gzip สำหรับการบีบอัดบางอย่าง ตอนนี้ไปป์ที่ไปยัง netcat อื่นที่ส่งไปยัง localhost บน TCP บนพอร์ต 2000

[kenny@linux-a /var/data]$ tar cf - important-data | gzip -fc | nc localhost 2000

เราเสร็จแล้ว! บน linux-b netcat จะไม่ฟังอีกต่อไปและจะมีการสร้างไฟล์ใหม่ ส่วนที่ดีที่สุดคือไฟล์เก็บถาวร tar ไม่เคยอยู่ในฮาร์ดดิสก์ของ linux-a

[kenny@linux-b /var/backups]$ file backup.tgz 
backup.tgz: gzip compressed data, from Unix, last modified: Thu Jul  5 13:48:03 2012

ฉันรู้ว่ามันไม่ตรงกับที่คุณถามในคำถาม แต่ถ้าคุณมี netcat ให้ใช้มันเป็นทางออกสำหรับปัญหาของคุณ

แก้ไข:ฉันลืมเกี่ยวกับสิ่งหนึ่ง: ถ้าคุณทำตามคำแนะนำเหล่านี้คุณจะยังคงมีอุโมงค์ SSH ที่ลอยอยู่บน linux-a ค้นหาว่า ID กระบวนการคืออะไรและฆ่ามัน

[kenny@linux-a /var/data]$ ps -ef | grep "ssh -L"
kenny     5741     1  0 13:40 ?        00:00:00 ssh -L 2000:localhost:2000 -CfN linux-b
kenny     5940  3360  0 14:13 pts/1    00:00:00 grep --color=auto ssh -L
[kenny@linux-a /var/data]$ kill 5741

3
ฉันชอบ แต่มี 2 ปัญหา: ผู้ใช้ sftponly มักจะไม่สามารถใช้การส่งต่อพอร์ตและผู้ใช้ sftponly ไม่สามารถเข้าถึง nc บนเซิร์ฟเวอร์ sftp (โปรดจำไว้ว่าพวกเขาไม่มีการเข้าถึง ssh)
JMW

1
นั่นเป็นการวิจารณ์ที่ถูกต้องทั้งหมด
Kenny Rasschaert

นอกหัวข้อ แต่เหตุใดจึงมีภาพหน้าจอของ "The Prestige" ฝังอยู่ในโพสต์นี้
Rilindo

4

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

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

ตัวอย่างการใช้งาน:

pg_dump -d database | pigz -1 | curl -u username -T - sftp://sftpserver/folder/dbbackup.sql.gz

curlใช้.ssh/known_hostsไฟล์ของคุณสำหรับการตรวจสอบที่สำคัญ สิ่งนี้อาจล้มเหลวในกรณีที่ไคลเอ็นต์ ssh ของคุณใช้มาตรฐานการเข้ารหัสที่ใหม่กว่าซึ่งไม่สนับสนุนไลบรารีที่ใช้ใน curl

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

ssh-keyscan sftpserver >> ~/.ssh/known_hosts

หรือคุณสามารถปิดการใช้งานการตรวจสอบคีย์โดยใช้-kแฟล็ก (ฉันไม่แนะนำให้ทำ)


2

output-stream-generating-command | ssh user@remotehost 'input-stream-accepting-command' เป็นตัวเลือกหากผู้ใช้รีโมตของคุณมีเชลล์ที่ถูกต้อง


5
นี่ไม่ใช่ SFTP!
jirib

3
@JiriXichtkniha ไม่มันไม่ใช่ แต่ SFTP ถูกนำไปใช้เป็นระบบย่อยของเซิร์ฟเวอร์ SSH ของคุณเกือบทุกครั้งและนี่เป็นแอนะล็อกที่ใกล้เคียงที่สุดกับฟังก์ชั่นที่ฉันเห็นการร้องขอจากคำถาม (ข้อมูลท่อผ่าน SFTP ที่จะจัดการโดยโปรแกรม ในอีกด้านหนึ่ง) บางครั้งคำตอบคือ "คุณใช้เครื่องมือที่ผิด - ทำthisแทน" - นี่ทำให้ฉันเป็นหนึ่งในเวลานั้น
voretaq7

2
sftp คือ protol และแตกต่างจากการ piping ผ่าน ssh นั่นแหละ! ข้อเสนอแนะของคุณจะไม่ทำงานหากส่วนระยะไกลจะเป็น SFTP เท่านั้น
jirib

1
ฉันไม่ได้รับอนุญาตให้เข้าสู่ระบบในฐานะผู้ใช้ ssh
JMW

1
@JMW ในกรณีนี้เท่าที่ฉันรู้ว่าคุณกำลังเมาสวยดีที่นี่ - ฉันไม่เคยเห็นรุ่นของ sftp ที่สนับสนุนการ piping ไปยังคำสั่งในระบบระยะไกล (อาจเป็นเพราะมันอาจเอาชนะSecure bit โดยให้ใครบางคนเข้า สถานการณ์ของคุณที่ไม่มีเชลล์รันโปรแกรมอยู่แล้ว) ฉันอาจจะผิด - ฉันคุ้นเคยกับฟังก์ชั่น SFTP ส่วนใหญ่ใน OpenSSH และเซิร์ฟเวอร์ SSH ที่เป็นกรรมสิทธิ์ของ Sun ที่ใช้ส่ง ...
voretaq7

1

voretaq7ชี้ให้เห็นว่าไคลเอนต์ sftp ไม่รองรับการถ่ายโอนข้อมูลแบบpipedสำหรับผู้ใช้ที่ได้รับอนุญาตให้ใช้ sftp เท่านั้นเพื่อเชื่อมต่อกับเซิร์ฟเวอร์

โชคดีที่มี libssh2 ซึ่งรองรับ sftp ดังนั้นเราแค่ต้องการลูกค้า 2 รายที่ใช้ libssh2 ซึ่งฉันได้เรียกว่า:

  • sftp_stdin_upload (เพื่ออัพโหลดไปยังเซิร์ฟเวอร์ sftp)
  • sftp_stdout_download (เพื่อดาวน์โหลดจากเซิร์ฟเวอร์ sftp)

ซอร์สโค้ดสามารถพบได้ใน URL ต่อไปนี้: http://www.qxs.ch/2012/07/05/sftp-upload-tool/


ตั้งแต่ฉันไม่ได้มีประสบการณ์ในการเขียนโปรแกรม libssh2 ฉันมีความสุขสำหรับข้อเสนอแนะใด ๆ กับรหัสที่มา


ใช้งานไม่ได้สำหรับฉัน :-( / usr / bin / ld: libssh2-1.4.2 / src / .libs / libssh2.a (knownhost.o): การอ้างอิงที่ไม่ได้กำหนดสัญลักษณ์สัญลักษณ์ 'EVP_sha1' / usr / lib / libcrypto so.1.0.0: ข้อผิดพลาดการเพิ่มสัญลักษณ์: DSO หายไปจาก command line collect2: ข้อผิดพลาด: ld ส่งคืน 1 สถานะการออก
tobixen

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