【发布时间】:2018-03-25 16:59:24
【问题描述】:
TLDR;
我有一个 shell 脚本,从命令行运行时可以正常工作,但如果从 PHP 脚本(通过 Web 访问)中调用则不能。
在这两种情况下,调用用户都是www-data。
失败的线路是这样的:
openssl genrsa -des3 -out certs/$PCODE.key -passout env:PASSPHRASE 2048
为什么会这样?如何调试?
全文
我有以下脚本,它是 this gist 的略微修改版本,用于生成自签名 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
结果文件:
- certs/acme.key.org
- certs/acme.key
- certs/acme.csr
- certs/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
这是修改后的 shell 脚本:
#!/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 $?
【问题讨论】:
-
我敢打赌 PHP 正在从一个特权当前工作目录运行,因为失败的命令包含一个相对路径:
certs/$PCODE.key。如果你把它设为绝对路径会发生什么?或者,或者,在 PHP 中执行chdir('/tmp/')? -
您的 "From PHP" 代码包含标记
`应该是引号。仅此一项就应该给你一个错误php.net/manual/en/function.error-reporting.php “我该如何调试它?”. -
@Fred-ii- 请看,php.net/manual/en/language.operators.execution.php 反引号用于执行我相信 OP 正在尝试执行的 shell 命令。
-
@mega6382 我的立场是正确的。
-
@bishop 尖点!我刚刚将所有路径转换为绝对路径,并进一步得到一个命令 (
Command after line 49 executed oK Error. Return value = 1 after line 54)。很快就会更新我的问题。
标签: php shell command-line sh