Je sais qu'il y a des questions sur ce sujet, mais aucune ne semble résoudre mon problème. Voir ceci ou ceci ou ceci .
Je suis sous Linux, Fedora21 et j'essaie d'activer le script CGI par annuaire d'utilisateurs. J'ai suivi ces instructions, mais sans succès.
Je reçois l'erreur:
[cgi:error] End of script output before headers: test.cgi
test.cgi
est un fichier sh exécutable, contenant un script très simple:
#!/usr/bin/sh
echo "Content-type: text/plain"
echo ""
echo "Hello"
qui a un drapeau exécutable et fonctionne sans problèmes de Shell . J'ai aussi essayé avec Python: même résultat.
J'ai également désactivé selinux pour faire bonne mesure.
J'ai également essayé de définir le niveau debug
sur ErrorLog d'Apache, mais tout ce que j'obtiens est uniquement des autorisations "accordées" avant l'erreur ci-dessus.
J'ai également configuré le fichier /etc/httpd/conf.d/userdir.conf
avec
<Directory "/home/*/public_html">
AllowOverride All
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
Require all granted
</Directory>
<Directory /home/*/public_html/cgi-bin/>
Options ExecCGI FollowSymLinks
SetHandler cgi-script
AddHandler cgi-script .cgi .exe .pl .py .vbs
Require all granted
AllowOverride All
</Directory>
et redémarré le serveur. Sans succès. Tout me semble bien, je ne peux pas comprendre ... Qu'est-ce qui ne va pas ??
J'ai oublié d'ajouter que le problème concerne uniquement le répertoire par utilisateur: si je déplace le même script dans le répertoire /var/www/cgi-bin
, il fonctionne comme prévu.
Le shell existe:
$ ls /usr/bin/sh
/usr/bin/sh
Finalement j'ai résolu ça. Merci à @JimB, parce que dans son commentaire il a souligné SUEXEC, ce que je ne connaissais pas (ou que je n'avais tout simplement pas ignoré jusqu'à présent).
Après avoir lu un peu la documentation suEXEC , j’ai compris que le problème devait être là. Alors, j'ai jeté un coup d'œil à la configuration:
# suexec -V
-D AP_DOC_ROOT="/var/www"
-D AP_GID_MIN=1000
-D AP_HTTPD_USER="Apache"
-D AP_LOG_SYSLOG
-D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=1000
-D AP_USERDIR_SUFFIX="public_html"
et tout avait l'air Ok (bon uid/gid pour mon utilisateur, userdir_suffix va bien, etc.). J'ai donc jeté un coup d'œil aux journaux du système:
# journalctl -b | grep "suexec"
May 22 11:43:12 caladan suexec[5397]: uid: (1000/user) gid: (1000/user) cmd: test.cgi
May 22 11:43:12 caladan suexec[5397]: directory is writable by others: (/home/user/public_html/cgi-bin)
et c'est le problème: mon répertoire cgi-bin
était accessible en écriture par d'autres.
J'ai corrigé en changeant simplement les permissions en 755
.
Pour moi, cela a fonctionné lorsque j'ai changé la ligne Shebang (#!/usr/bin/sh
) en #!/usr/bin/env sh
. J'ai trouvé que toutes les lignes Shebang de Quel est le shebang Bash préféré? semblait fonctionner (cependant, notez que sh
est différent de bash
donc si vous voulez utiliser sh
, restez-y)
Donc, ce code a fonctionné pour moi:
#!/usr/bin/env sh
echo "Content-type: text/plain"
echo ""
echo "Hello"
En outre, selon le message mentionné ci-dessus, il semble que /usr/bin/env sh
semble préférable à /bin/sh
. Je n'ai aucune idée de la substance par répertoire.
Cela survient parfois lorsque vous essayez d'appeler d'autres méthodes de module Python à partir de votre cgi où vous avez peut-être laissé des instructions 'print' (peut-être pour le débogage). Alors, scannez votre code pour toute instruction 'print', cela résout parfois le problème facilement.
J'ai vu le message "Fin de la sortie du script avant les en-têtes: myscript.py" pour un script CGI Python 2.x qui s'est bien déroulé à partir de la ligne de commande.
Le problème s'est avéré que le serveur Web ne s'exécutait pas correctement, même s'il provenait de la ligne de commande. Quel que soit le message d'erreur que le système a renvoyé au serveur, les en-têtes CGI n'ont certainement pas abouti (par exemple, "Content-Type: text/html\r\n\r\n"). Par conséquent, ce message d'échec.
Pour moi, corriger cela signifiait changer le Shebang de:
#!/usr/bin/env python
Vers un système plus spécifique (mais vérifiable):
#!/usr/local/bin/python
Peut-être que vous rencontrez quelque chose de similaire.
(FreeBSD 9.x.)
Essayez d’exécuter votre script en tant qu’utilisateur Apache.
Cela pourrait être dû à un certain nombre de raisons. @JimB mentionne un problème avec le Shebang. @premganz mentionne des problèmes liés aux instructions d'impression de débogage qui se déclenchent avant que votre chaîne Content-Type ne soit écrite. Dans mon cas, c'était un échec de connexion à la base de données. Cela pourrait être un autre problème.
J'ai trouvé que le meilleur moyen de déboguer cela consiste à exécuter le script directement en tant qu'utilisateur Apache sur la ligne de commande et à voir les erreurs qu'il génère.
Comment exécuter votre script en tant qu'utilisateur Apache
En supposant que vous utilisez Apache2 et que l'utilisateur Apache est www-data, et que votre script cgi est /myapp/myreport.py, vous pouvez procéder comme suit.
Autorisez les connexions en tant qu'utilisateur www-data en modifiant son shell par défaut. Éditer/etc/passwd (temporairement)
Sudo su -
cd /etc
cp -p passwd passwd.2017-10-22
emacs passwd # edit file - use your favorite editor
Changement:
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
À:
www-data:x:33:33:www-data:/var/www:/bin/bash
Connectez-vous en tant qu'utilisateur www-data
Sudo su - www-data
Définissez n'importe quel vars d'environnement. Convertissez vos instructions Apache SetEnv en déclarations d’exportation. Dans mon cas, les paramètres de mon répertoire de configuration Apache sont configurés
SetEnv PYTHONPATH /myapp/lib
SetEnv VCONF /myapp/conf/prod.yaml
Les exécuter comme
export PYTHONPATH=/myapp/lib
export VCONF=/myapp/conf/prod.yaml
Ensuite, essayez votre script CGI
cd /myapp
./myreport.py
Vous devriez voir quelle que soit l'erreur rencontrée par Apache. RÉPARE LES.
Réinitialisez le shell par défaut de l'utilisateur www-data sur/usr/sbin/nologin
Laissez uniquement le fichier propriétaire disposer des autorisations d'écriture sur le script cgi, mais pas le groupe, c'est-à-dire -rwxr-xr-x
et non -rwxrwxr-x
.
Dans les répertoires d’utilisateurs, le groupe est souvent un groupe d’utilisateurs personnel dont seul l’utilisateur est membre, mais il semble qu'Apache s'inquiète de voir le bit g + w mais donne un message d'erreur quelque peu faux à ce sujet.
Cette erreur se produit lorsque nous utilisons une impression plus ancienne.
print 'your test'
Cela devrait être pour une version ultérieure de Python.
print ('your test')