Effectuer en toute sécurité TCP traceroute de la demande de l'utilisateur

1

Je dois effectuer un traceroute TCP en utilisant soit le traceroute Linux, soit un autre paquet, mais j'ai du mal à trouver le moyen de faire la requête depuis PHP sans avoir besoin de privilèges sudo.

Parce que l'URL proviendra d'une requête utilisateur, je ne souhaite pas utiliser sudo.

Voici un exemple:

 $url = 'ebay.com';
 $exec = 'sudo traceroute -w 1 -q 1 -T ' . $url;
 $escaped_command = escapeshellcmd($exec);
 $result = shell_exec($escaped_command);

 echo $result;
 var_dump($result);

Ce code fonctionne, mais seulement avec sudoou sans -T. Sans sudocela, il retourne une chaîne vide. Sans -Tle traceroute ne survit pas aux pare-feu.

Si cela peut aider, je suis sur un OS Centos 7.

Remarque: je ne peux pas utiliser UDP au lieu de TCP car il est souvent bloqué par le pare-feu de destination.

turrican_34
la source
Quelques considérations lors de l' utilisation escapeshellcmd () gist.github.com/Zenexer/40d02da5e07f151adeaeeaa11af9ab36
Daisetsu
@schroeder: -Test l'abréviation de -M tcpet cette méthode est décrite comme utilisant des connexions semi-ouvertes par défaut et nécessite donc un accès root. Il n’est pas écrit explicitement dans la page de manuel, mais rien n’est écrit sur les autorisations nécessaires. Probablement avec l'option (explicitement non recommandée), tcpconnil n'aura pas besoin de root car il s'agit d'une opération simple connect.
Steffen Ullrich
Merci Steffen, donc dans ce cas, probablement avec UDP et une augmentation de la durée de vie (TTL), mais l'expéditeur doit lire le ICMP généré par les routeurs. Je pense donc que l'application source a besoin de permissions de racine pour lire le ICMP Unreach généré, Je pense
@ camp0 l'OP dit qu'il fonctionne sans sudo et sans-T
schroeder
Je pense que @SteffenUllrich a la réponse ultime, et qu’il s’agit bien plus d’une question Linux que d’une question de sécurité.
Schroeder

Réponses:

0

Vous ne pouvez pas utiliser sudo depuis PHP, car Apache ne vous laissera pas faire cela pour des raisons de sécurité. Vous devez implémenter traceroute en PHP dans votre code.

Plusieurs de ces implémentations se trouvent dans le domaine public.

Voir par exemple:

En créant un programme traceroute en PHP , le code est disponible sur github .


Une autre approche pour éviter sudo pour traceroute repose sur le fait que traceroute ne doit pas nécessairement être exécuté en tant que racine; il a juste besoin de la capacité CAP_NET_ADMIN. Pour définir cela comme capacité de fichier pour tous les utilisateurs, si votre noyau prend en charge les capacités de fichier et qu'aucun module de sécurité Linux (SELinux, AppArmor) ne la bloque:

setcap CAP_NET_ADMIN+ep /usr/sbin/traceroute

Le code PHP peut alors être très simple en utilisant popen():

$handle = popen("traceroute www.xxx.com 2>&1", "r");
while(!feof($handle)) {
    $buffer = fgets($handle);
    $buffer = "<p>".$buffer."</p>\n";
    echo $buffer;
}
pclose($handle);
harrymc
la source
J'utilise Nginx pour pouvoir exécuter sudo, mais ce n'est pas sûr. L'implémentation PHP que vous avez liée nécessite également sudo et utilise UDP, pas TCP, ce dont j'ai besoin. .
turrican_34
En tant que personne de Nginx, vous pouvez peut-être m'expliquer pourquoi sudo est nécessaire pour envoyer des messages sur des sockets.
harrymc
Selon un thread SO que j'ai trouvé, l' ouverture d'un socket brut permet de lire tout ce qui est reçu dans une interface donnée. Vous pouvez donc lire tout paquet envoyé à une application, même si cette application appartient à un autre utilisateur. Cela signifie fondamentalement que l'utilisateur doté de cette capacité est capable de lire toutes les communications de tous les utilisateurs. . stackoverflow.com/questions/4404860/…
turrican_34
Bon, alors j'ai ajouté une autre approche.
harrymc
Cela l'a fait! Merci. Bizarrement, je ne l' ai pas besoin , cap_net_adminil a travaillé avec seulement cap_net_rawcomme sudo setcap cap_net_raw+ep /usr/bin/traceroute. Si je cours getcap /usr/bin/tracerouteje reçois /usr/bin/traceroute = cap_net_raw+ep. J'ai sélinux en mode permissif pour le moment, donc une fois que je l'activer, je suppose que je vais avoir des problèmes à résoudre.
turrican_34