الروبوت Telegram الذي يراقب المجال

مرحبا لسكان هبر.

في عملية تعلم PHP ، توصلت إلى فكرة الممارسة لكتابة بعض الروبوت في PHP ، دون استخدام الأطر.

وقع الاختيار على البرنامج الذي سيحصل على معلومات حول عمر المجال (whois) ، ثم الحصول على تاريخ التسجيل من هناك وإضافة هذا المجال إلى قاعدة البيانات (mysql) ، مع ربط لاحق للمستخدم والإخطار في البرق.

شفرة المصدر في مستودع بلدي على غيتا.

كنت أرغب في استخدام بنية MVC ، والتي في رأيي لم تكن صحيحة تمامًا ، نظرًا لأن العرض لم يكن متورطًا ولم يعد بالإمكان تسمية mvc هذا ، ولكن ...

هيكل التطبيق




أدوات التحكم - رابط يربط بين منطق النموذج والتطبيق.
نماذج - ملفات "منطق الأعمال" للتطبيق (حاولت "حشر" sql بأكمله هنا).
الأساسية - تطبيق الملفات "الأساسية".
المكتبة - تستخدم المكتبات المكتبة لتحليل معلومات اسم المجال.

التوجيه


يوجد ملف التوجيه (route.php) في الدليل الأساسي .
تتم إضافة 2 عناوين في التطبيق:

/ bot - يذهب Telegramm إلى هذا العنوان (تحتاج إلى تعيين webhook على عنوان uri / bot).
/ check - في هذا العنوان ، تتوقف wget مع cron 1 يوميًا (الساعة 12) ، والمزيد في ذلك لاحقًا.

BotController


عند الانتقال إلى وحدة التحكم هذه ، نحصل على القيم من نص طلب POST ، ونقوم بفك تشفيرها كصفيف.

json_decode(file_get_contents('php://input'), JSON_OBJECT_AS_ARRAY); 

php: // input - الحصول على نص طلب POST

CheckerController


عند الانتقال إلى وحدة التحكم هذه ، يتم تشغيل برنامج نصي يقوم بفحص جميع المجالات المضافة وشهادات ssl لانتهاء الصلاحية ، مع الفاصل الزمني:

  • التاريخ الحالي
  • يومين
  • 7 ايام
  • 30 يوم

ويرسل إخطارات إذا كان تاريخ انتهاء صلاحية المجال وشهادة SSL ينتهي.

مضيفا المستخدمين


عندما يكتب المستخدم رسالة إلى webegook telegram bot ، يرسلها إلى موقعنا ، ثم نتلقى رسالة بتنسيق json ، نحتاج إلى فك تشفيرها وتحويلها إلى صفيف لمزيد من العمل.



سوف نعمل مع مجموعة الرسائل.

الحصول عليها من رسالة الصفيف ['chat'] : id ، first_name
حيث:

معرف - معرف الدردشة
الاسم الأول - اسم المستخدم

ومن صفيف الرسالة ['text'] ، نحصل على الأمر الذي أرسله المستخدم.

نجد المستخدم في جدول المستخدمين ، إذا لم يكن هناك ، قم بإنشاء

 //   $sql= "SELECT user_id FROM users WHERE chat_id=?"; $stmt = $db->prepare($sql); $stmt->execute([$chat_id]); $rows = $stmt->fetch(PDO::FETCH_ASSOC); return (int)$rows['user_id']; 

 //   $sql = 'INSERT INTO users (user_name, chat_id) VALUES (:user_name, :chat_id)'; $insert = $db->prepare($sql); $insert->execute([':user_name' => $name, ':chat_id' => $chat_id]); return true; 

مضيفا المجالات و SSL


عند إرسال الأمر / addDomain url إلى الروبوت ، نحصل على عنوان url للنطاق من الأمر ونحصل على بيانات تسجيل المجال باستخدام هذه المكتبة .

الحصول على المجال


نحصل على إجابة في شكل نص:



باستخدام التعبيرات المعتادة ، نحصل على تاريخ تسجيل النطاق منه.

 preg_match('/Registry\sExpiry\sDate:\s(.*)\\r/', $date, $matches); if (!$matches[1]){ preg_match('/paid-till:\s*(.*)\\n/', $date, $matches); } $matches[1] = $this->formatDate($matches[1]); return $matches[1]; 

الحصول على SSL


قررت الحصول على شهادة SSL باستخدام openssl لنظام التشغيل Linux .

 $getDomainSSL = shell_exec("echo | openssl s_client -servername $url -connect $url:443 2>/dev/null | openssl x509 -noout -dates"); preg_match('~notAfter=(\w+)\s(\d+)\s.+\s(\d+)~', $getDomainSSL, $matches); $date = $matches[2].$matches[1].$matches[3]; $date = date("Ymd", strtotime($date)); $date = str_replace('.','-',$date); return $date; 

وبالتالي نحصل على:

 echo | openssl s_client -servername google.com -connect google.com:443 2>/dev/null | openssl x509 -noout -dates notBefore=Jan 7 15:47:12 2020 GMT notAfter=Mar 31 15:47:12 2020 GMT 

تحليل النتيجة باستخدام التعبيرات العادية

 preg_match('~notAfter=(\w+)\s(\d+)\s.+\s(\d+)~', $getDomainSSL, $matches); 



يبقى فقط لإضافة البيانات إلى الجدول.

 $sql = 'INSERT INTO domains (domain_name, date_start, date_end, date_end_ssl) VALUES (:domain_name, :date_start, :date_end, :date_end_ssl)'; $insert = $db->prepare($sql); $insert->execute([':domain_name' => $url, ':date_end' => $exp, ':date_end_ssl' => $ssl_date]); 

نحن نربط المجال و ssl للمستخدم


تحتاج البيانات التي تم الحصول عليها ببساطة إلى تسجيلها في جدول وسيط حتى لا "تضاعف" المجالات.

 $sql = 'INSERT INTO domain_users (user_id, domain_id) VALUES (:user_id, :domain_id)'; $insert = $db->prepare($sql); $insert->execute([':user_id' => $user_id, ':domain_id' => $domain_id]); 

التحقق من تاريخ انتهاء المجال


عندما ينتقل wget إلى عنوان / check ، يتم تحديد جميع المجالات وشهادات SSL مع تاريخ انتهاء الصلاحية ، وإذا كان هناك أي ، فإنه يرسل رسالة دردشة التي يرتبط بها هذا المجال.

 $db = $this->db; $sql= " SELECT user_name, chat_id, domain_name, date_end FROM domain_users JOIN users USING (user_id) JOIN domains USING (domain_id) WHERE ( domains.date_end = CURDATE() OR domains.date_end = CURDATE() + INTERVAL 2 DAY OR domains.date_end = CURDATE() + INTERVAL 7 DAY OR domains.date_end = CURDATE() + INTERVAL 30 DAY ) "; $stmt = $db->prepare($sql); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); 

CRON


التاج في هذا المشروع ضروري لتنظيم الانتقال إلى العنوان "/ check" ، كل يوم في الساعة 12.

 crontab -e 0 12 * * * wget url/check 

وكيل تور


بضع كلمات حول إرسال رسائل إلى برقية.

لسوء الحظ ، في أراضي بلدي (روسيا) ، قاموا بحظر البرق ، بما في ذلك api.
لا بد لي من استخدام وكيل ، سقط اختياري على وكيل تور (منذ المشروع الأخير).

يحتاج فقط ليتم تثبيتها.

 sudo apt-get install tor 

ثم سيكون الوكيل متاحًا على المنفذ 9050.

 curl_setopt($myCurl, CURLOPT_PROXYTYPE, 7); curl_setopt($myCurl, CURLOPT_PROXY, "127.0.0.1:9050"); 

شكرا لكم جميعا لقراءة هذا المقال!

هذا هو مقالي الأول ، لذلك لا نحكم بدقة :)

التعليق على هذا المنصب ، وسأقبل بكل سرور أي نقد.

شفرة المصدر للمشروع في مستودع جيثب الخاص بي :)

Source: https://habr.com/ru/post/ar485392/


All Articles