繁体   English   中英

尝试从PHP脚本“ git pull”,遇到SSH权限问题

[英]Trying to 'git pull' from PHP script, running into SSH permissions problems

我对此代码感到困惑,该代码在本地但不能在远程工作。

<?php shell_exec('/usr/bin/git pull ssh://my.git.server/git/test-theme /home/dsgit1/wp-content/themes/test-theme' 2>&1); ?>

(它最终将成为WordPress插件的一部分,但是由于我目前不使用任何特定于WordPress的东西,所以这无关紧要。)

上面的代码似乎可以与http://和https://仓库一起使用,但是我的仓库目前只能通过SSH使用。

我创建了SSH密钥对,因此不需要密码。

当我使用php-cgi从Web服务器运行脚本时,作为运行Web内容的用户,它可以工作。 (我向“ exec whoami”添加了一个电话,以确认我以正确的用户身份运行。)

putenv("PATH=/usr/bin:/bin");
print "Running as user: ";
passthru('whoami');
// then the above shell_exec()

当我在本地运行git pull代码时,所有工作都按预期进行:

-bash-4.1$ /usr/bin/php-cgi /home/dsgit1/wp-content/plugins/test/pull.php
X-Powered-By: PHP/5.3.3
Content-type: text/html

Running as user: dsgit1
Cloning into '/home/dsgit1/wp-content/themes/test-theme'...
Checking connectivity... done

...,如您所料,存储库被拉入本地文件夹。

我们为每个站点使用mod_suphp和一个单独的本地用户,这就是为什么您看到“ dsgit1”而不是“ httpd”或“ apache”的原因。 该代码旨在以该特定本地用户身份运行。

当我远程运行脚本时(通过在浏览器中输入其URL或将其提供给wget),我得到了以下信息:

Running as user: dsgit1
Cloning into '/home/dsgit1/wp-content/themes/test-theme'...
ssh: connect to host my.git.server port 22: Permission denied
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

出于某种原因,当代码“远程”运行时,看起来环境还不足以读取〜/ .ssh / id_rsa中的SSH私钥。 该代码以同一本地用户身份运行,因此它应该具有SSH密钥的读取权限,但不能或不会使用它们。

在本地和远程运行代码的方式上显然存在一些差异,但是我不知道该怎么办。 有什么建议吗?

编辑:/etc/suphp.conf,根据评论者的要求:

[global]
logfile=/var/log/httpd/suphp_log
loglevel=warn
webserver_user=apache
docroot=/
env_path=/bin:/usr/bin
umask=0022
min_uid=500
min_gid=500

; Security options
allow_file_group_writeable=true
allow_file_others_writeable=false
allow_directory_group_writeable=true
allow_directory_others_writeable=false

;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=true

;Send minor error messages to browser
errors_to_browser=false
check_parent_owner=false

[handlers]
;Handler for php-scripts
; x-httpd-php=php:/usr/bin/php
x-httpd-php="php:/usr/bin/php-cgi"

;Handler for CGI-scripts
x-suphp-cgi=execute:!self

第二编辑:这是将命令更改为$output = shell_exec('ssh -v gitreader@my.git.server pwd 2>&1');之后,从CLI手动运行的$output = shell_exec('ssh -v gitreader@my.git.server pwd 2>&1');

-bash-4.1$ /usr/bin/php-cgi ./wp-content/plugins/autogit/a4.php
X-Powered-By: PHP/5.3.3
Content-type: text/html

Running as user: dsgit1
<pre>OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010
debug1: Reading configuration data /home/dsgit1/.ssh/config
debug1: Applying options for my.git.server
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to my.git.server [172.20.60.96] port 22.
debug1: Connection established.
debug1: identity file /home/dsgit1/.ssh/id_rsa type 1
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3
debug1: match: OpenSSH_5.3 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.3
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'my.git.server' is known and matches the RSA host key.
debug1: Found key in /home/dsgit1/.ssh/known_hosts:3
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password,keyboard-interactive
debug1: Next authentication method: publickey
debug1: Offering public key: /home/dsgit1/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 277
debug1: read PEM private key done: type RSA
debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending command: pwd
debug1: channel 0: forcing write
/home/gitreader
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 1 clearing O_NONBLOCK
Transferred: sent 2288, received 2360 bytes, in 0.2 seconds
Bytes per second: sent 12073.1, received 12453.0
debug1: Exit status 0
</pre>

它登录,运行一个命令并显示其输出,然后退出。 主机已经在known_hosts中,因此不需要输入。

这是从curl调用的同一件事的输出:

以用户身份运行:dsgit1

OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to my.git.server [172.20.60.96] port 22.
debug1: connect to address 172.20.60.96 port 22: Permission denied
ssh: connect to host my.git.server port 22: Permission denied

当涉及到mod_suphp时,我遇到了这种挣扎。 我不喜欢那个apt,我的脚本总是调用以检查是否禁用或卸载了mod_suphp(每次都会解决该问题)。

我认为我已经解决了根本问题,但这不是很漂亮。

我将命令更改为简单的ssh命令,并将〜/ .ssh中相关文件的权限显式更改为660:

shell_exec('ssh -v -F /home/dsgit1/.ssh/config gitreader@my.git.server pwd 2>&1')

我仍然收到“权限被拒绝”错误。

我在audit.log中发现SELinux错误,并发现SELinux上下文使得PHP进程无法读取SSH文件。 (〜/ .ssh中的文件均为ssh_home_t类型。)

暂时禁用SELinux,并显式添加-F来指定要使用的配置文件,可以解决SSH的问题。 这应该可以使用GIT_SSH环境变量和包装器脚本扩展到Git,但是需要让SELinux处于许可模式。

使用此行创建自定义SELinux策略应该可以永久解决此问题,同时允许我将SELinux保持启用状态:

allow httpd_t ssh_home_t:file read;

我和我的同事将讨论这方面可能还有很多其他安全隐患(并且可能最终决定比通过SSH自动访问Git更重要)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM