ฉันจะเชื่อมต่อกับบริการที่ซ่อนของ Tor โดยใช้ cURL ใน PHP ได้อย่างไร


366

ฉันกำลังพยายามเชื่อมต่อกับบริการที่ซ่อนอยู่ของ Tor โดยใช้รหัส PHP ต่อไปนี้:

$url = 'http://jhiwjjlqpyawmpjx.onion/'
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PROXY, "http://127.0.0.1:9050/");
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
$output = curl_exec($ch);
$curl_error = curl_error($ch);
curl_close($ch);

print_r($output);
print_r($curl_error);

เมื่อฉันเรียกใช้ฉันได้รับข้อผิดพลาดต่อไปนี้:

ไม่สามารถแก้ไขชื่อโฮสต์

อย่างไรก็ตามเมื่อฉันเรียกใช้คำสั่งต่อไปนี้จากบรรทัดคำสั่งของฉันใน Ubuntu:

curl -v --socks5-hostname localhost:9050 http://jhiwjjlqpyawmpjx.onion

ฉันได้รับการตอบสนองตามที่คาดไว้

เอกสารcURL PHP บอกสิ่งนี้:

--socks5-hostname
Use  the  specified  SOCKS5 proxy (and let the proxy resolve the host name).

ฉันเชื่อว่าเหตุผลที่ใช้งานได้จากบรรทัดคำสั่งนั้นเป็นเพราะ Tor (พร็อกซี) กำลังแก้ไขชื่อโฮสต์. onion ที่รู้จัก เมื่อใช้งานโค้ด PHP ด้านบนการเดาของฉันคือ cURL หรือ PHP พยายามแก้ไขชื่อโฮสต์. onion และไม่รู้จัก ฉันค้นหาวิธีที่จะบอก cURL / PHP เพื่อให้พร็อกซีแก้ไขชื่อโฮสต์ แต่ฉันหาวิธีไม่พบ

มีความคล้ายกันมากแตกมากเกินคำถามคือคำขอม้วนโดยใช้พร็อกซี่ SOCKS5 ล้มเหลวเมื่อใช้ PHP แต่มันทำงานผ่านบรรทัดคำสั่ง

คำตอบ:


98

คุณต้องไปที่ตัวเลือกชุดCURLOPT_PROXYTYPEไปCURLPROXY_SOCKS5_HOSTNAMEซึ่งน่าเศร้าที่ไม่ได้กำหนดไว้ในรุ่น PHP เก่าประมาณ pre-5.6 ; หากคุณมีก่อนหน้านี้ แต่คุณสามารถใช้ค่าของมันอย่างชัดเจนซึ่งเท่ากับ7:

curl_setopt($ch, CURLOPT_PROXYTYPE, 7);

21

ฉันใช้Privoxyและ cURL เพื่อขูดหน้า Tor:

<?php
    $ch = curl_init('http://jhiwjjlqpyawmpjx.onion'); // Tormail URL
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
    curl_setopt($ch, CURLOPT_PROXY, "localhost:8118"); // Default privoxy port
    curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
    curl_exec($ch);
    curl_close($ch);
?>

หลังจากติดตั้ง Privoxy คุณจะต้องเพิ่มบรรทัดนี้ในไฟล์กำหนดค่า ( /etc/privoxy/config) สังเกตช่องว่างและ '.' จุดสิ้นสุดของบรรทัด

forward-socks4a / localhost:9050 .

จากนั้นรีสตาร์ท Privoxy

/etc/init.d/privoxy restart

มันใช้งานได้! ทดสอบทั้งใน Windows 10 และ CentOS 6 เช่นกันถ้า Tor ใช้ถุงเท้า 5 แทนถุงเท้า 4 ให้ใช้สิ่งนี้:forward-socks5 / localhost:9150 .
David Refoua

ฉันต้องใช้ TOR และ Privoxy เพื่อให้ใช้งานได้หรือไม่ ขอบคุณ
AMB


5

TL; DR: ตั้งค่าCURLOPT_PROXYTYPEให้ใช้CURLPROXY_SOCKS5_HOSTNAMEหากคุณมี PHP ที่ทันสมัยค่า7อื่น ๆ และ / หรือแก้ไขCURLOPT_PROXYค่า

เมื่อคุณอนุมานอย่างถูกต้องคุณจะไม่สามารถแก้ไข.onionโดเมนผ่านระบบ DNS ปกติได้เนื่องจากเป็นโดเมนระดับบนสุดที่สงวนไว้สำหรับ Tor โดยเฉพาะและโดเมนดังกล่าวโดยการออกแบบไม่มีที่อยู่ IP ที่จะจับคู่กับ

การใช้CURLPROXY_SOCKS5จะนำคำสั่ง cURL เพื่อส่งทราฟฟิกไปยังพร็อกซี แต่จะไม่เหมือนกันสำหรับการแก้ไขชื่อโดเมน คำขอ DNS ซึ่งถูกปล่อยออกมาก่อน cURL พยายามสร้างการเชื่อมต่อจริงกับไซต์ Onion จะยังคงถูกส่งไปยังโปรแกรมแก้ไข DNS ปกติของระบบ คำขอ DNS เหล่านี้จะล้มเหลวอย่างแน่นอนเนื่องจากตัวแก้ไข DNS ปกติของระบบจะไม่รู้ว่าจะทำอย่างไรกับที่.onionอยู่เว้นแต่จะส่งต่อข้อความค้นหาดังกล่าวไปยัง Tor โดยเฉพาะ

แทนที่จะคุณต้องใช้CURLPROXY_SOCKS5 CURLPROXY_SOCKS5_HOSTNAMEหรือคุณสามารถใช้CURLPROXY_SOCKS4Aแต่เป็นที่ต้องการ SOCKS5 มาก พร็อกซีทั้งสองประเภทแจ้ง cURL ให้ทำการค้นหา DNS และการถ่ายโอนข้อมูลจริงผ่านพร็อกซี สิ่งนี้จำเป็นสำหรับการแก้ไข.onionโดเมนใด ๆ ให้สำเร็จ

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

  • เซมิโคลอนหายไปที่ท้ายบรรทัด 1
  • ค่าที่อยู่พร็อกซีถูกตั้งค่าเป็น HTTP URL แต่ชนิดของมันคือ SOCKS; สิ่งเหล่านี้ไม่เข้ากัน สำหรับพร็อกซี SOCKS ค่าต้องเป็นชื่อ IP หรือชื่อโดเมนและหมายเลขพอร์ตโดยไม่มีแบบแผน / โปรโตคอล / คำนำหน้า

นี่คือรหัสที่ถูกต้องเต็มความคิดเห็นเพื่อแสดงการเปลี่ยนแปลง

<?php
$url = 'http://jhiwjjlqpyawmpjx.onion/'; // Note the addition of a semicolon.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PROXY, "127.0.0.1:9050"); // Note the address here is just `IP:port`, not an HTTP URL.
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME); // Note use of `CURLPROXY_SOCKS5_HOSTNAME`.
$output = curl_exec($ch);
$curl_error = curl_error($ch);
curl_close($ch);

print_r($output);
print_r($curl_error);

คุณยังสามารถละเว้นการตั้งค่าCURLOPT_PROXYTYPEทั้งหมดโดยเปลี่ยนCURLOPT_PROXYค่าเพื่อรวมsocks5h://คำนำหน้า:

// Note no trailing slash, as this is a SOCKS address, not an HTTP URL.
curl_setopt(CURLOPT_PROXY, 'socks5h://127.0.0.1:9050');
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.