SSH สามารถถ่ายโอนข้อมูลผ่านเทคโนโลยีการเข้ารหัสแพ็กเก็ตออนไลน์ การใช้ SSH ข้อมูลทั้งหมดที่ส่งสามารถเข้ารหัสได้ แม้ว่าจะมีใครบางคนดักข้อมูล แต่ก็ไม่สามารถรับข้อมูลที่เป็นประโยชน์ได้ ในเวลาเดียวกัน ข้อมูลจะถูกบีบอัด ซึ่งจะช่วยเร่งความเร็วในการส่งข้อมูลได้อย่างมาก กล่าวโดยย่อคือ การใช้ SSH ช่วยให้มั่นใจได้ว่าการส่งข้อมูลมีความปลอดภัยและมีประสิทธิภาพ
อย่างไรก็ตาม ไม่ใช่ทุกคนที่รู้ว่า PHP สามารถเชื่อมต่อกับ SSH และรันคำสั่งระยะไกลได้ แต่มันก็มีประโยชน์มาก เนื่องจากเราสามารถใช้ประโยชน์จาก PHP ได้หลายวิธี จึงมีตัวเลือกการตั้งค่ามากมายเพื่อควบคุมพฤติกรรมของมัน ชุดพารามิเตอร์เสริมจำนวนมากช่วยให้คุณใช้ PHP เพื่อวัตถุประสงค์ที่แตกต่างกันได้มากมาย แต่ก็หมายความว่าการรวมกันของพารามิเตอร์เหล่านี้และการกำหนดค่าฝั่งเซิร์ฟเวอร์อาจทำให้เกิดปัญหาด้านความปลอดภัยบางประการได้ ผู้เขียนใช้ SSH ในแอปพลิเคชัน PHP CLI ฉันใช้มันจาก cronjobs แต่ในตอนแรกอาจกล่าวได้ว่าค่อนข้างยาก คู่มือการใช้ฟังก์ชัน Shell2 อย่างปลอดภัยนั้นใช้งานไม่ได้จริงนัก ผู้เขียนได้ทำการทดลองหลายครั้งก่อนที่จะเขียนบทความเล็กๆ นี้ขึ้นมา ฉันหวังว่าหลังจากอ่านแล้ว จะช่วยให้คุณประหยัดเวลาในการกำหนดค่า PHP ได้
ในบทความนี้ ฉันต้องสมมติว่า
ระบบปฏิบัติการที่คุณใช้งานอยู่คือ Debian/Ubuntu หากคุณไม่ได้ใช้ Debian/Ubuntu คุณอาจต้องแทนที่เนื้อหาที่เกี่ยวข้องของบทความนี้ด้วยตัวจัดการแพ็คเกจที่ Linux ของคุณมอบให้
คุณกำลังใช้งาน PHP5 หากคุณไม่ได้ใช้ PHP5 คุณสามารถใช้ PHP4 แทนได้
คุณมีความเข้าใจพื้นฐานเกี่ยวกับ PHP และการดูแลระบบเซิร์ฟเวอร์
คุณได้ติดตั้ง PHP ไว้แล้ว
ข้อกำหนดเบื้องต้น
แพ็คเกจการติดตั้ง
ก่อนอื่น มาติดตั้งแพ็คเกจต่อไปนี้:
sudo aptitude update
sudo aptitude install php5-dev php5-cli php-pear buid-essential
openssl-dev zlib1g-dev
การติดตั้งเสร็จสมบูรณ์และไปที่ขั้นตอนถัดไป
คอมไพล์ libssh2
หลังจากดาวน์โหลด Libssh2 จากเว็บไซต์ Sourceforge เราจำเป็นต้องคอมไพล์มัน แต่ไม่ต้องกังวล คุณเพียงแค่ต้องทำดังนี้:
cd /usr/src
wget
// เข้าสู่ระบบที่ server1.example.com บนพอร์ต 22
ถ้า ( !($con = ssh2_connect("server1.example.com", 22))){
echo "fail: ไม่สามารถสร้างการเชื่อมต่อn";
} else {
// พยายามตรวจสอบความถูกต้องด้วยชื่อผู้ใช้ root, รหัสผ่านลับ
if(! ssh2_auth_password ($con, "root", "secretpassword")) {
echo "fail: ไม่สามารถตรวจสอบสิทธิ์n";
} else {
// เอาล่ะ เราเข้ามาแล้ว
! ;
// ดำเนินการคำสั่ง
if(!($stream = ssh2_exec($con, "ls -al" )) ){
echo "fail: ไม่สามารถดำเนินการคำสั่งn";
} else{
// รวบรวมข้อมูลที่ส่งคืนจากคำสั่ง
stream_set_blocking ( $stream, true );
$data = "";
while( $buf = fread($
stream,4096) ){
$data .= $buf;
}
fclose($stream)
;
วิธีที่สอง: Shell
ในทำนองเดียวกัน คุณยังสามารถเขียนฟังก์ชันหรือคลาสสำหรับโค้ดต่อไปนี้ได้ อย่างไรก็ตาม บทความนี้ให้เฉพาะแนวคิดพื้นฐานเท่านั้น:
if (!function_exists("ssh2_connect")) die("function ssh2_connect does not existing")
// เข้าสู่ระบบที่ server1.example.com บนพอร์ต 22
if(!($con = ssh2_connect ("server1.example.com", 22))){
echo "fail: ไม่สามารถสร้างการเชื่อมต่อn";
} else {
// พยายามตรวจสอบความถูกต้องด้วยชื่อผู้ใช้ root, รหัสผ่าน Secretpassword
if(!ssh2_auth_password($con, "root ", "secretpassword")) {
echo "fail: ไม่สามารถตรวจสอบสิทธิ์n";
}
else {
// เอาล่ะ เราเข้ามาแล้ว
!
เชลล์
if (!($shell = ssh2_shell($con, 'vt102', null, 80, 40, SSH2_TERM_UNIT_CHARS))){
echo "ล้มเหลว: ไม่สามารถสร้างเชลล์n"
} else{
stream_set_blocking( $shell, true ) ;
/ / ส่งคำสั่ง
fwrite($shell,"ls -aln");
sleep(1);
// & รวบรวมข้อมูลที่ส่งคืน
$data = ""
; ){
$data .= $buf;
}
fclose($shell);
}
}
}
เคล็ดลับ:
บางครั้งเซิร์ฟเวอร์ไม่ว่างหรือเกิดข้อผิดพลาดในการเชื่อมต่อ และไม่มีข้อมูลในบัฟเฟอร์ และสคริปต์ PHP จะหยุดส่งออก คำสั่ง (แม้ว่าคำสั่งจะไม่สมบูรณ์ก็ตาม!) เพื่อรวบรวมข้อมูล คุณสามารถทำสิ่งต่อไปนี้:
ssh2_exec($con, 'ls -al; echo "__COMMAND_FINISHED__"' );
ตอนนี้ ในลูปของคุณที่ตรวจสอบบัฟเฟอร์อยู่ตลอดเวลา เพียงแค่ดูที่ COMMAND_FINISHED เพราะแล้วคุณจะรู้ว่าคุณมีข้อมูลทั้งหมด เพื่อหลีกเลี่ยงการวนซ้ำแบบไม่มีที่สิ้นสุด (การวนซ้ำแบบไม่มีที่สิ้นสุด) คุณสามารถใช้การจำกัดเวลา 10 วินาที:
$time_start = time();
$data = "";
while( true ){
$data .= fread($stream, 4096) ;
if( strpos($data,"__COMMAND_FINISHED__") !== false){
echo "ตกลง: คำสั่งเสร็จสิ้นn"
;
}
if( (เวลา()-$time_start) > 10 ){
echo "fail: timeout ถึง 10 วินาทีแล้วn";
break;
}
}
ในตัวอย่างข้างต้น คุณควรตั้งค่า stream_set_blocking เป็น false
ส่งไฟล์ผ่าน SSH
ssh2_scp_send($con, "/tmp/source.dat", "/tmp/dest.dat", 0644);
หากทำงานไม่ถูก
ต้อง โปรดตรวจสอบประเด็นต่อไปนี้:
ทำตามบทความนี้เพื่อตรวจสอบทุกขั้นตอน ของการดำเนินการของคุณ
ที่ฝั่งเซิร์ฟเวอร์ต้องเปิดใช้งาน "PasswordAuthentication ใช่" ใน sshd_config ค่าเริ่มต้นบนเซิร์ฟเวอร์ส่วนใหญ่คือใช่ แต่ในบางกรณีคุณอาจต้องเพิ่มบรรทัดต่อไปนี้ลงในไฟล์เพื่อเปิดใช้งานคุณสมบัตินี้ในตัวคุณเอง:
/etc/ssh/sshd_config:
# เปลี่ยนเป็นใช่เพื่อเปิดใช้งานรหัสผ่านข้อความที่ชัดเจนแบบช่องสัญญาณ
PasswordAuthentication ใช่
หากคุณทำการเปลี่ยนแปลง คุณต้องรีสตาร์ท SSH:
/etc/init.d/ssh รีสตาร์ท