我正在尝试通过 SSH 从 PHP 脚本在远程服务器上运行命令。这是片段:
$ssh_command = "ssh -F keys/config -o UserKnownHostsFile=keys/known_hosts -i keys/deployment_key -p $ssh_port $r
$git_fetch = "git --git-dir=$remote_path/.git --work-tree=$remote_path fetch 2>&1";
exec("$ssh_command '$git_fetch' 2>&1", $out);
如果我从命令行运行该脚本,它可以正常工作,因为它是以具有常规登录 shell 和他们自己的 .ssh 目录的用户身份运行的。当我尝试通过 Web 界面运行脚本时,它失败了,因为 SSH 无法在 Apache 用户的主目录中创建它的 .ssh 目录。
是否可以在没有 .ssh 目录的情况下使用 SSH,或者是否有另一种方法可以作为 Apache 用户运行 SSH?我不想为 Apache 用户创建 .ssh 文件夹。
最佳答案
我可以通过一个小问题/副作用来绕过这个限制。
设置选项 UserKnownHostsFile=/dev/null 和 StrictHostKeyChecking=no,您可以欺骗 SSH 使其不实际存储或要求验证主机 key 。
将 StrictHostKeyChecking 设置为 no 允许在不知道或验证其 key 的情况下连接到服务器;并将 /dev/null 用于 UserKnownHostsFile 只是读取和写入任何内容,因此不会读取或保存任何值。
需要注意的是,SSH 仍会尝试创建 .ssh 目录并失败,但失败会导致警告并且它将继续连接。警告将包含在您的输出中(除非您要禁止显示警告)。
这是一个例子。注意:对于此示例,我没有设置任何身份验证,因此它将尝试使用密码身份验证并失败,但由于您使用的是身份,因此您应该能够正常连接。
<?php
$ssh_command = "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "
."-p 2223 user@host.localdomain";
exec("$ssh_command ls 2>&1", $out);
var_dump($out);
// output when called from browser running as daemon(1)
array(5) {
[0]=>
string(44) "Could not create directory '/usr/sbin/.ssh'."
[1]=>
string(110) "Warning: Permanently added '[host.localdomain]:2223,[192.168.88.20]:2223' (RSA) to the list of known hosts."
[2]=>
string(36) "Permission denied, please try again."
[3]=>
string(36) "Permission denied, please try again."
[4]=>
string(82) "Received disconnect from 192.168.88.20: 2: Too many authentication failures for user"
}
您的输出很可能只包含关于无法创建 .ssh 目录的第一个警告,然后是关于将主机永久添加到已知主机列表中的警告 (/dev/null),然后是命令的输出;所以你必须检查第一行是否是这个警告,并将它从 $out 数组中移出。
另一个注意事项:这确实开启了中间人攻击或 DNS/IP 黑客攻击的可能性,让您尝试连接到流氓服务器。
请参阅 SSH Host Key Protection 上的这篇文章来自赛门铁克。
关于php - 是否可以在不创建 .ssh 目录的情况下执行 ssh 命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9425638/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb
如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife