Я не уверен, лучше ли это здесь или в SO, но поскольку проблема не в программировании, я подумал, что это применимо здесь (или в U & L, или в случае отказа сервера, но я думаю / надеюсь, у меня все хорошо).
Я хочу отправить команды TCP на экземпляр telegram-cli из PHP.
До сих пор я использовал: shell_exec('echo "msg user#idXXXXXX message" | nc 127.0.0.1 9007');
и это работало нормально. Но здесь задействованы переменные и пользовательский ввод, и хотя я цитирую свои переменные, я считаю, что это плохой OPSEC, поэтому вместо этого я хочу использовать сокеты PHP, но здесь начинаются проблемы.
Сервер TCP запускается под пользователем "B" на сервере. PHP работает как "www-данные". Запуск вышеуказанного shell_exec
отлично работает, как пользовательские www-data
. Вход в систему от имени пользователя A
и запуск команды непосредственно в оболочке bash также работает. Используя чистый netcat, я также могу подключиться к сокету как пользователь A
, поэтому я думаю, что проблема с разрешениями здесь не в этом. Пользователь A
является обычным пользователем без специальных разрешений.
Мой код PHP:
$fp = fsockopen("127.0.0.1", 9007, $errno, $errstr, 5);
fwrite($fp, 'msg user#idXXXX "message"');
То, что это делает, абсолютно ничего.
И вот почему я считаю, что это не подходит для StackOverflow:
Если я попытаюсь подключиться к порту 9001
(для тестирования) вместо 9007
(на котором работает tg-cli) после запуска nc -l 9001
от имени пользователя A
, он прекрасно работает, и я вижу сообщение, которое PHP должен отправить в выводе nc
,
Судя по этому, проблема должна быть где-то вне моего короткого кода PHP, но я понятия не имею, где искать. Соединение установлено, но fwrite
ничего не отправляет.
$fp = fsockopen("127.0.0.1", 9007, $errno, $errstr, 5);
if(!$fp){
echo "$errstr ($errno)"; die();
}else{
echo "test"; // THIS IS BEING PRINTED
fwrite($fp, 'msg user#idXXXXX "message"');
while(!feof($fp)){
echo fgets($fp);
}
fclose($fp);
}
Это весь рассматриваемый кодовый блок. test
печатается, fwrite
выполняется (поскольку PHP входит в цикл while), но tg-cli
ничего не получает. Затем скрипт PHP полностью застрял в цикле while (без вывода!) пока я SIGTERM
apache2.
Редактировать: вывод tg-cli в режиме отладки, когда я пытаюсь отправить сообщение:
*** 1538301112.516826 Accepting incoming connection
*** 1538301112.517262 Read from incoming connection
Edit2: для дальнейшего тестирования разрешений я запустил sudo -u www-data echo 'dialog_list' | nc 127.0.0.1 9007
- с успехом.
Edit3: я также дважды проверил с base64
что PHP fwrite
отправляет именно то, что он должен отправлять.
Edit4: я могу исключить, что проблема заключается в ответе сервера обратно в PHP, поскольку tg-cli сообщает, что он читает из TCP-соединения, но не обрабатывает его. Например, когда я использую shell_exec
или nc
на оболочке, он сообщает, что отправил запрос в центр данных Telegram после чтения из потока TCP. Это не тот случай, когда используется мой код PHP выше.
Edit5: я также пытался суффикс команды TCP с \n
, \r
или \n\r
но снова безуспешно. Может быть, мне нужно закончить команду чем-то конкретным? Ничего из этого не требуется при использовании чуть-чуть nc
или shell_exec()
.