Проблема со сценарием оболочки, вызванным из переполнения стека

TLDR;

У меня есть сценарий оболочки, который отлично работает при запуске из командной строки, но не при вызове из сценария PHP (доступ через Интернет).

В обоих случаях вызывающий пользователь www-data,

Ошибка строки такова:

openssl genrsa -des3 -out certs/$PCODE.key -passout env:PASSPHRASE 2048

Почему это происходит? Как я могу отладить это?

Полный рассказ

У меня есть следующий скрипт, который является слегка измененной версией этот смысл для создания самозаверяющих сертификатов SSL.

Когда я запускаю его из терминала как www-data он работает нормально и генерирует файлы ключей, CSR и файл сертификата SSL. Но когда я вызываю скрипт из скрипта PHP, он выдает ошибку, и файлы не создаются. Что является причиной отказа? Как я могу отладить это?

С терминала:

 me@machine$ sudo su www-data
www-data@machine$ ./gencert.sh acme
www-data will generate an SSL cert for acme.dev
Command after line 32 executed oK
Passphrase expoted as I7gOnWxWd0hOk38Zu ... FbxL3K3Rzlv
Generating RSA private key, 2048 bit long modulus
..............................................+++
.................+++
e is 65537 (0x10001)
Command after line 49 executed oK
Command after line 54 executed oK
Command after line 65 executed oK
writing RSA key
Command after line 69 executed oK
Signature ok
subject=/C=IR/ST=Alborz/.../emailAddress=noreply@acme.dev
Getting Private key
Command after line 74 executed oK

Результирующие файлы:

  • сертификаты / acme.key.org
  • сертификаты / acme.key
  • сертификаты / acme.csr
  • сертификаты / acme.crt

Из PHP:

$r = `/var/www/testbench/pm/shell/gencert.sh acme`;
echo $r;

Файлы не генерируются, и вывод таков:

www-data will generate an SSL cert for acme.dev
Command after line 32 executed oK
Passphrase expoted as 1Fd1seZoe2XF ... oSmQFJdVpdwOeTo2CK5VjLxp
Error. Return value = 1 after line 49

Строка, возвращающая 1, выглядит так:
openssl genrsa -des3 -out certs/$PCODE.key -passout env:PASSPHRASE 2048

Вот модифицированный сценарий оболочки:

#!/bin/bash

# Bash shell script for generating self-signed certs. Run this in a folder, as it
# generates a few files. Large portions of this script were taken from the
# following artcile:
#
# http://usrportage.de/archives/919-Batch-generating-SSL-certificates.html
# https://deliciousbrains.com/ssl-certificate-authority-for-local-https-development/
# Additional alterations by: Brad Landers
# Date: 2012-01-27

# Script accepts a single argument, the fqdn for the cert
PCODE="$1"if [ -z "$PCODE" ]; then
echo "Usage: $(basename $0) <PCODE>"exit 11
fi

THE_USER="$(whoami)"echo "$THE_USER will generate an SSL cert for $PCODE.dev"
fail_if_error() {
[ $1 != 0 ] && {
echo -n "Error. Return value = $1 after line $LASTLINE"unset PASSPHRASE
exit 10
}
echo "Command after line $LASTLINE executed oK"}

# Generate a passphrase
LASTLINE="${LINENO}"export PASSPHRASE=$(head -c 500 /dev/urandom | tr -dc a-z0-9A-Z | head -c 128; echo)
fail_if_error $?
echo -n "Passphrase expoted as "printenv PASSPHRASE

# Certificate details; replace items in angle brackets with your own info
subj="C=IR
ST=Alborz
O=ACME
localityName=Karaj
commonName=*.$PCODE.dev
organizationalUnitName=WebAdmin
emailAddress=noreply@$PCODE.dev
"
LASTLINE="${LINENO}"# Generate the server private key
openssl genrsa -des3 -out certs/$PCODE.key -passout env:PASSPHRASE 2048
fail_if_error $?

LASTLINE="${LINENO}"# Generate the CSR
openssl req \
-new \
-batch \
-subj "$(echo -n "$subj" | tr "\n" "/")" \
-key certs/$PCODE.key \
-out certs/$PCODE.csr \
-passin env:PASSPHRASE
fail_if_error $?

LASTLINE="${LINENO}"cp certs/$PCODE.key certs/$PCODE.key.org
fail_if_error $?

LASTLINE="${LINENO}"# Strip the password so we don't have to type it every time we restart Apache
openssl rsa -in certs/$PCODE.key.org -out certs/$PCODE.key -passin env:PASSPHRASE
fail_if_error $?

LASTLINE="${LINENO}"# Generate the cert (good for 10 years)
openssl x509 -req -days 3650 -in certs/$PCODE.csr -signkey certs/$PCODE.key -out certs/$PCODE.crt
fail_if_error $?

4

Решение

Команда, которую вы хотите выполнить, имеет относительные пути, например: certs/$PCODE.key, Когда вы выполняете команды (в данном случае через оператор backtick), пути расширяются относительно текущего рабочего каталога процесса PHP. Это редко, если вообще когда-либо, тот же путь, который использует ваша командная оболочка.

Чтобы отладить это, вы можете расширить вашу фактическую команду с помощью straceНапример: strace openssl ..., Это даст вам значительную диагностику и, ближе к концу, вы увидите что-то вроде EPERM,

Чтобы это исправить, вы можете использовать chdir в вашем PHP, чтобы установить текущий рабочий каталог, или вы можете cd в вашем сценарии, или ваш сценарий может использовать абсолютные пути. Я бы предпочел последнее.

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru