使用PHP的SSH连接
我目前正在进行一个项目,用PHP对系统进行更改(例如更改Nginx/restarting services的配置文件) PHP脚本正在本地主机上运行。在我看来,最好的(阅读:最安全的)方法是使用SSH建立连接。我正在考虑下列选择之一: 选项1:在php会话中存储用户名/密码并提示输入sudo 使用带有用户名/密码的phpseclib,将这些值保存在php会话中,并为每个命令提示sudo 选项2:使用root登录 在登录脚本中使用根用户名和密码的phpseclib。在这种情况下,您不必向用户询问sudo。(并非真正安全的解决方案)使用PHP的SSH连接,php,linux,ssh,Php,Linux,Ssh,我目前正在进行一个项目,用PHP对系统进行更改(例如更改Nginx/restarting services的配置文件) PHP脚本正在本地主机上运行。在我看来,最好的(阅读:最安全的)方法是使用SSH建立连接。我正在考虑下列选择之一: 选项1:在php会话中存储用户名/密码并提示输入sudo 使用带有用户名/密码的phpseclib,将这些值保存在php会话中,并为每个命令提示sudo 选项2:使用root登录 在登录脚本中使用根用户名和密码的phpseclib。在这种情况下,您不必向用户询问s
选项3:使用从文件读取的公钥进行身份验证
使用带有公钥的PHP SSHlib进行身份验证,并将公钥放在www根目录之外
<?php
$connection = ssh2_connect('shell.example.com', 22, array('hostkey' => 'ssh-rsa'));
if (ssh2_auth_pubkey_file($connection, 'username', '/home/username/.ssh/id_rsa.pub', '/home/username/.ssh/id_rsa', 'secret')) {
echo "Public Key Authentication Successful\n";
} else {
die('Public Key Authentication Failed');
}
?>
选项4:?如果您在同一台主机上运行,我建议您直接编写配置文件并(重新)启动服务,或者编写包装器脚本 第一个选项显然需要非常高的特权级别,我不建议这样做。然而,它将是最容易实现的。您使用ssh的其他命名选项没有多大帮助,因为可能的攻击者仍然可以轻松获得根权限
第二种选择更安全,包括编写具有高级访问权限的程序,该程序只获取指定的输入文件,例如从目录中获取。php脚本只是用户的前端,将编写所述输入文件,因此只需要非常低的权限。这样,您就可以将高权限和低权限分开,从而降低风险,因为保护程序更容易,可能的攻击者只能通过文本文件间接地使用该程序。此选项需要更多的工作,但更安全。您可以扩展选项3并在不使用任何库的情况下使用SSH密钥
$command = sprintf('ssh -i%s -o "StrictHostKeyChecking no" %s@%s "%s"',
$path, $this->getUsername(), $this->getAddress(), $cmd );
return shell_exec( $command );
我在我的项目中经常使用它。你可以看看我创造的
上面的问题是,您无法做出实时决策(连接到服务器时)。如果您需要实时,请尝试调用PHP扩展
我同意你的看法。SSH接缝被认为是最安全的选项。我建议您通过3个简单的步骤来实现这一点: 首先。 创建另一个用户(例如
runner
),并使您的敏感数据(如用户/通行证、私钥等)仅可供该用户访问。换句话说,拒绝php代码访问这些数据
秒。
之后,创建一个简单的阻塞fifo管道,并向php用户授予写访问权
最后一个。
最后编写一个简单的守护进程,从fifo读取行,并通过ssh命令执行。使用runner
user运行此守护程序
要执行命令,只需将命令写入文件(fifo管道)。如果需要,可以将输出重定向到其他管道或一些简单文件中
要使fifo使用此简单命令:
mkfifo "FIFONAME"
runner守护进程将是一个简单的bash脚本,如下所示:
#!/bin/bash
while [ 1 ]
do
cmd=$(cat FIFONAME | ( read cmd ; echo $cmd ) )
# Validate the command
ssh 192.168.0.1 "$cmd"
done
./wrapper reloadnginx
在此之后,您可以信任您的代码,如果您的php代码完全被黑客攻击,您的上游服务器仍然是安全的。在这种情况下,攻击者根本无法访问您的敏感数据。他可以向您的运行程序守护进程发送命令,但是如果您正确验证了命令,就不用担心了
:-)老兄,那完全错了
您不想更改任何要创建新文件的配置文件,然后将其包含在默认配置文件中
例如,对于apache,您有*.conf文件和include指令。更改默认配置文件是完全疯狂的。我就是这样做的
您不需要ssh或类似的东西
相信我,如果你愿意,它会更好更安全。方法1
我可能会用这个。写一点,确保它执行的所有命令都是预定义的,并且不能由php脚本控制。
因此,创建包装器并从ARGV获取命令。所以一个电话可能是这样的:
#!/bin/bash
while [ 1 ]
do
cmd=$(cat FIFONAME | ( read cmd ; echo $cmd ) )
# Validate the command
ssh 192.168.0.1 "$cmd"
done
./wrapper reloadnginx
包装器然后执行/etc/init.d/nginx reload
确保将chown
包装到root和chmod+s
。然后,它将生成根目录下的命令,但由于您预定义了所有命令,因此php脚本无法作为根目录执行任何其他操作
方法2
使用sudo并为某些命令设置它。通过这种方式,您可以实现相同的效果,并且只有某些应用程序可以生成为root。但是,您无法控制参数,因此请确保这些二进制文件中没有权限提升
你真的不想给PHP脚本完全的根访问权限。你可以使用setcap
来允许Nginx绑定到端口80/443,而不必以根用户身份运行。Nginx只需作为root运行即可绑定端口80/443(任何小于1024的端口)<代码>设置上限
详见
不过也有一些漏洞。您必须chown
将日志文件发送给正确的用户(chown-R nginx:nginx/var/log/nginx
),并将pid文件配置为/var/run/
(pid/path/to/nginx.pid
)之外的其他位置
lawl0r为setuid/sudo提供了一个很好的答案
作为最后一次恢复,如果配置发生更改,可以使用cron作业定期重新加载配置
无论哪种方式,当SSH在同一个系统上时,您都不需要它。您到底在问什么?你想拥有最安全、最通用的选择吗?php脚本是否在同一台主机上运行,需要在该主机上编写更改或远程执行?我正在寻找最安全的选项。当前正在同一主机上运行。@nkamm在某些情况下,脚本的根权限是可行的,并且是合适的。将军