Setup SSH keys 用于无密码访问远程服务器。
如果用户不是root,则配置远程/etc/sudoers 以通过sudo 命令执行无密码命令。例如,您可以将远程用户添加到uhttpd group(remotely):
sudo gpasswd -a user uhttpd
然后列出允许在没有密码的情况下运行的命令
%uhttpd ALL=(ALL) NOPASSWD: ALL
为了简单起见,我们允许使用 ALL 命令。您可以改为列出特定命令。见man sudoers。
编写类似以下的脚本:
#!/usr/bin/env php
<?php
namespace Tools\Uhttpd\ChangePort;
$ssh_user = 'user'; // Change this
$ssh_host = 'remote.host'; // Change this
$remote_config = '/etc/config/uhttpd';
//////////////////////////////////////////////////////
if (false === ($o = getopt('p:', ['port:']))) {
fprintf(STDERR, "Failed to parse CLI options\n");
exit(1);
}
// Using PHP7 Null coalescing operator
$port = $o['p'] ?? $o['port'] ?? 0;
$port = intval($port);
if ($port <= 0 || $port > 65535) {
fprintf(STDERR, "Invalid port\n");
exit(1);
}
$sudo = $ssh_user == 'root' ? '' : 'sudo';
$sed = <<<EOS
"s/option\s*'listen_http'\s*'[0-9]+'/option 'listen_http' '$port'/"
EOS;
// Replace port in remote config file
execute(sprintf("ssh %s -- $sudo sed -i -r %s %s",
"{$ssh_user}@{$ssh_host}", $sed,
escapeshellarg($remote_config)));
// Restart remote daemon
execute("$sudo /etc/init.d/uhttpd restart");
//////////////////////////////////////////////////////
/**
* @param string $cmd Command
* @return int Commands exit code
*/
function execute($cmd) {
echo ">> Running $cmd\n";
$desc = [
1 => ['pipe', 'w'],
2 => ['pipe', 'w'],
];
$proc = proc_open($cmd, $desc, $pipes);
if (! is_resource($proc)) {
fprintf(STDERR, "Failed to open process for cmd: $cmd\n");
exit(1);
}
if ($output = stream_get_contents($pipes[1])) {
echo $output, PHP_EOL;
}
if ($error = stream_get_contents($pipes[2])) {
fprintf(STDERR, "Error: %s\n", $error);
}
fclose($pipes[1]);
fclose($pipes[2]);
if (0 != proc_close($proc)) {
fprintf(STDERR, "Command failed(%d): %s\n", $exit_code, $cmd);
exit(1);
}
}
将其保存到chport.php 并使其可执行:
chmod +x chport.php
那么你可以这样使用它:
./chport.php --port=10000
您可能希望将脚本中使用的命令包装在 shell 脚本中,然后在 /etc/sudoers 中列出它们。