DetectGFW.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <?php
  2. namespace App\Command;
  3. use App\Models\{
  4. Node,
  5. User
  6. };
  7. use App\Services\Config;
  8. use App\Utils\Telegram;
  9. class DetectGFW extends Command
  10. {
  11. public $description = '├─=: php xcat DetectGFW - 节点被墙检测定时任务' . PHP_EOL;
  12. public function boot()
  13. {
  14. //节点被墙检测
  15. $last_time = file_get_contents(BASE_PATH . '/storage/last_detect_gfw_time');
  16. for ($count = 1; $count <= 12; $count++) {
  17. if (time() - $last_time >= $_ENV['detect_gfw_interval']) {
  18. $file_interval = fopen(BASE_PATH . '/storage/last_detect_gfw_time', 'wb');
  19. fwrite($file_interval, time());
  20. fclose($file_interval);
  21. $nodes = Node::all();
  22. $adminUser = User::where('is_admin', '=', '1')->get();
  23. foreach ($nodes as $node) {
  24. if (
  25. $node->node_ip == '' ||
  26. $node->node_ip == null ||
  27. $node->online == false
  28. ) {
  29. continue;
  30. }
  31. $api_url = $_ENV['detect_gfw_url'];
  32. $api_url = str_replace(
  33. array('{ip}', '{port}'),
  34. array($node->node_ip, $_ENV['detect_gfw_port']),
  35. $api_url
  36. );
  37. //因为考虑到有v2ray之类的节点,所以不得不使用ip作为参数
  38. $result_tcping = false;
  39. $detect_time = $_ENV['detect_gfw_count'];
  40. for ($i = 1; $i <= $detect_time; $i++) {
  41. $json_tcping = json_decode(file_get_contents($api_url), true);
  42. if (eval('return ' . $_ENV['detect_gfw_judge'] . ';')) {
  43. $result_tcping = true;
  44. break;
  45. }
  46. }
  47. if ($result_tcping == false) {
  48. //被墙了
  49. echo ($node->id . ':false' . PHP_EOL);
  50. //判断有没有发送过邮件
  51. if ($node->gfw_block == true) {
  52. continue;
  53. }
  54. foreach ($adminUser as $user) {
  55. echo 'Send gfw mail to user: ' . $user->id . '-';
  56. $user->sendMail(
  57. $_ENV['appName'] . '-系统警告',
  58. 'news/warn.tpl',
  59. [
  60. 'text' => '管理员您好,系统发现节点 ' . $node->name . ' 被墙了,请您及时处理。'
  61. ],
  62. []
  63. );
  64. $notice_text = str_replace(
  65. '%node_name%',
  66. $node->name,
  67. Config::getconfig('Telegram.string.NodeGFW')
  68. );
  69. }
  70. if (Config::getconfig('Telegram.bool.NodeGFW')) {
  71. Telegram::Send($notice_text);
  72. }
  73. $node->gfw_block = true;
  74. $node->save();
  75. } else {
  76. //没有被墙
  77. echo ($node->id . ':true' . PHP_EOL);
  78. if ($node->gfw_block == false) {
  79. continue;
  80. }
  81. foreach ($adminUser as $user) {
  82. echo 'Send gfw mail to user: ' . $user->id . '-';
  83. $user->sendMail(
  84. $_ENV['appName'] . '-系统提示',
  85. 'news/warn.tpl',
  86. [
  87. 'text' => '管理员您好,系统发现节点 ' . $node->name . ' 溜出墙了。'
  88. ],
  89. []
  90. );
  91. $notice_text = str_replace(
  92. '%node_name%',
  93. $node->name,
  94. Config::getconfig('Telegram.string.NodeGFW_recover')
  95. );
  96. }
  97. if (Config::getconfig('Telegram.bool.NodeGFW_recover')) {
  98. Telegram::Send($notice_text);
  99. }
  100. $node->gfw_block = false;
  101. $node->save();
  102. }
  103. }
  104. break;
  105. }
  106. echo ($node->id . 'interval skip' . PHP_EOL);
  107. sleep(3);
  108. }
  109. }
  110. }