IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Impossible d'éxecuter lsof dans un script via php


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 9
    Par défaut Impossible d'éxecuter lsof dans un script via php
    Salut à tous !

    J'ai beau essayer d'avoir de l'aide sur d'autres forums, ça n'avance pas trop alors tous mes espoirs sont portés sur vous !

    Pour faire court, j'ai des serveurs de jeux sur un dédié sous Debian 7, lorsqu'ils se lancent ils écrivent leur PID dans un fichier server.pid. Des fois ces serveurs freezent ou leur PID change (auto reload je pense) du coup quand je veux les stopper via l'API du jeu en PHP ça ne marche pas.

    J'ai voulu créer un script, exécuté par PHP, pour les redémarrer peu importe s'ils fonctionnent normalement, s'ils freezent ou si leur PID change.

    Problème : Pour trouver leur nouveau PID, j'utilise la commande lsof avec le port du serveur, mais depuis PHP celle ci n'est pas exécutée. Alors que via shell ça fonctionne très bien.

    - Quand je rajoute sudo dans le exec de PHP j'ai cette erreur : sudo: no tty present and no askpass program specified
    - Quand je rajoute dans etc/sudoers ces lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    www-data ALL=(ALL) NOPASSWD: SERVRES
    Cmnd_Alias SERVRES = /***/***/***/server.sh
    ça ne change rien. Même quand je fais www-data ALL=(ALL) NOPASSWD: ALL, il s'en bas les c*******.

    Le script (oui c'est sans doute pas très bien codé c'est mon premier script) ::

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    #!/bin/bash
     
    #Author : Simon B. alias Themiller
     
    #============= INFOS =============
     
    PORT_NUMBER="$2"
    NAME="$1"
    LOGS=/home/www/sites/clients/client1/web3/web/servers/$NAME/output.txt
    PIDFILE=/home/www/sites/clients/client1/web3/web/servers/$NAME/server.pid
    SDEDI=/home/www/sites/clients/client1/web3/web/servers/$NAME/server
     
    #============= FUNCTIONS =============
     
    function test_port() {
     
    	if  /usr/bin/lsof -Pi :${PORT_NUMBER} -sTCP:LISTEN -t >/dev/null ; then
        	PID="$(/usr/bin/lsof -Pi :${PORT_NUMBER} -sTCP:LISTEN -t)"
        	return 0
    	else
    	    return 1
    	fi
     
    }
     
    function my_date {
      date "+%d/%m/%y %H:%M:%S"
    }
     
    #============= SCRIPT =============
     
    # DEMARRAGE DU SERVEUR
     
    case "$3" in
      start)
     
    	if test_port; then
     
    		echo "[$(my_date)] Server already online." >> ${LOGS}
    		echo "Error : Server already online."
     
    	else
    		echo "[$(my_date)] Starting Server: "$NAME >> ${LOGS}
    		echo "Starting your server."
    		$SDEDI start
            echo "[$(my_date)] Server started: "$NAME >> ${LOGS}
            echo "Server started succefully !"
    	fi
     
    	;;
     
    # ARRET DU SERVEUR	
     
      stop)
     
    		echo "Stopping Server..."
    		echo "[$(my_date)] Stopping Server..." >> ${LOGS}
     
            # ON KILL VIA LE FICHIER PID
     
    		echo "Killing daemon with PID..."
    		echo "[$(my_date)] Killing daemon with PID..." >> ${LOGS}
            kill `cat $PIDFILE`
            rm $PIDFILE
     
      		if test_port; then
     
    			kill -9 ${PID}
    			sleep 2
     
    			if test_port; then
     
    			    echo "[$(my_date)] ERROR !!!"
     
    			else
    				echo "Server stopped !"
    				echo "[$(my_date)] Process killed to stop server." >> ${LOGS}
    			fi
     
    		else
    			echo "Server stopped !"
    			echo "[$(my_date)] Server stopped." >> ${LOGS}
    		fi
     
    	;;
     
    # REDEMARRAGE
     
      restart)
     
      	if test_port; then
     
      		echo "Restarting Server..."
    		echo "[$(my_date)] Restarting Server..." >> ${LOGS}
     
    		# ON KILL VIA LE FICHIER PID
     
            echo "Killing daemon with PID..."
            echo "[$(my_date)] Killing daemon with PID..." >> ${LOGS}
            kill `cat $PIDFILE`
            rm $PIDFILE
     
      		if test_port; then
     
    			kill -9 ${PID}
    			sleep 2
     
    			if test_port; then
     
    			    echo "[$(my_date)] ERROR !!!" >> ${LOGS}
     
    			else
    				echo "[$(my_date)] Process killed !" >> ${LOGS}
    			    sleep 5
    			    $SDEDI start
    			    sleep 5
    			    echo "Server restarted !"
    			    echo "[$(my_date)] Server restarted." >> ${LOGS}
    			fi
     
    		else
    			echo "[$(my_date)] Server stopped and going to restart..." >> ${LOGS}
    			sleep 5
    			$SDEDI start
    			sleep 5
    			echo "Server restarted !"
    			echo "[$(my_date)] Server restarted." >> ${LOGS}
    		fi
     
    	else
    	    $SDEDI start
            sleep 5
    	    echo "Server restarted !"
    	    echo "[$(my_date)] Server restarted." >> ${LOGS}
    	fi
     
    	;;
     
    # STATUS
     
      status)
     
      		if test_port; then
      			echo "Server is running ! PID : ${PID}"
    		else 
    			echo "[$(my_date)] Server is not running"
    		fi
     
    	;;
      *)
    	echo "Usage: "$3" {start|stop|restart|status}"
    	exit 1
    esac
    exit 0
    L'exec PHP :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    [...]
     
    $dossier = $row->folder;
    $port = $row->tm_port;
    $serv_path_dir = 'PATH_TO_FILE/server.sh';
    $command = $serv_path_dir.' '.$dossier.' '.$port.' restart';
    exec($command, $output);
     
    [...]
    Merci d'avance pour tous ceux qui pourront m'aider car là je sèche !

  2. #2
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    désolé si je ne réponds pas à ta question mais juste pour préciser : c'est une très mauvaise idée et un risque de sécurité majeur

    ne faites pas ça chez vous (et encore moins au boulot ^^)

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 9
    Par défaut
    Salut, je suis d'accord pour ça : www-data ALL=(ALL) NOPASSWD: ALL, mais je ne l'ai laissé que 20 secondes. Pour le reste si tu as une meilleure solution plus sécurisée je suis partant

  4. #4
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    Citation Envoyé par Themiller Voir le message
    si tu as une meilleure solution plus sécurisée je suis partant
    administrer la machine via ssh et jamais par le web ce serait un bon début

    sinon tant qu'à faire des trucs sales, le principe est de minimiser et contrôler le plus possible les entrées utilisateur (un clic souris sur un lien start/stop c'est une entrée utilisateur), le principe est alors de faire un script qui prend 1 paramètre, qui correspond par exemple aux noms des jeux "riri", "fifi" et "loulou", en début de script on effectue une vérification et si on reconnait un des trois noms alors on lance un lsof qui va bien, à la fin on autorise ce script et uniquement ce script dans les sudoers, et on demande à php d'exécuter monscript.sh loulou. on veillera également dans le script à n'utiliser que des chemins absolus pour invoquer des commandes

    ça c'est dans l'idée où tu as la main sur le serveur bien évidemment, si tu n'as qu'un compte ftp ou autre pour uploader ton site web et pas d'accès ssh c'est probablement que les admins ont tout bonnement bloqué l'exécution de commandes externes à travers php, et ce pour des raisons de sécurité bien entendu (cf. php.ini:disable_functions)

  5. #5
    Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 9
    Par défaut
    Ce que tu viens de dire c'est ce que je compte faire et que j'ai expliqué dans mon premier message. Tout comme j'ai dit que j'étais sur un dédié sous Debian, que j'administre bien entendu.
    En gros ma question c'est : Pourquoi malgré la modif dans le fichier sudoers, lsof ne s’exécute pas dans mon script ?

  6. #6
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    Citation Envoyé par Themiller Voir le message
    Ce que tu viens de dire c'est ce que je compte faire et que j'ai expliqué dans mon premier message.
    oui, et que j'ai qualifié de "truc sale", dans ton premier message tu précises que tu veux start/stop/restart tes services à travers l'API du jeu (sic), l'API elle est faite pour les utilisateurs du jeu, ou le modérateur ou autre, un processus qui tombe c'est une problématique d'administration, donc la bonne façon de faire ce n'est pas d'utiliser l'API du jeu c'est de se connecter en SSH, faire un ps et killer le processus pour l'arreter

    et si on veut automatiser, l'idée ce serait de créer une sonde pour monitorer les processus et/ou se débrouiller pour que les jeux ne se relancent pas tout seuls sans créer de pidfile, et on met ladite sonde en cron (exec toutes les minutes) ou dans un script avec une boucle infinie (+ sleep pour ne pas non plus plomber les perfs)

    En gros ma question c'est : Pourquoi malgré la modif dans le fichier sudoers, lsof ne s’exécute pas dans mon script ?
    ton script a des arguments, il faut le préciser à sudoers, un truc comme ça devrait fonctionner, à vérifier néanmoins (non testé) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    www-data ALL=(root) NOPASSWD: /path/to/myscript.sh /[[:alnum:]/]* [[:digit:]]* start|stop|restart
    Edit: question piège, tu as bien utilisé la commande visudo pour modifier le fichier sudoers ?

Discussions similaires

  1. [MySQL] Afficher une IMAGE dans une BDD via PHP
    Par lothar59 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 07/01/2011, 15h17
  2. [Système] Exécuter un script via PHP
    Par steeve93800 dans le forum Langage
    Réponses: 2
    Dernier message: 03/03/2008, 22h20
  3. [Configuration] limite de temps pour l'éxécution de scripts via php-cli
    Par icer dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 28/05/2007, 11h33
  4. [Cookies] PB cookie dans un script AJAX/PHP
    Par cassy dans le forum Langage
    Réponses: 1
    Dernier message: 04/09/2006, 11h35
  5. Réponses: 16
    Dernier message: 22/03/2006, 11h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo