我怎样才能让只有一个常规帐户的系统由一台计算机来管理管理任务?
我只想能够从单个系统添加/删除所有计算机上的软件。批量操作 - 无需单独登录每台计算机并执行需要执行的操作。我可以通过物理方式或 SSH 执行此操作,但对于一百台左右的计算机,这并不是我想要考虑的选项。
答案1
答案2
隐藏管理员
每个系统至少需要一个管理用户,因为在 Ubuntu 中禁用了单独的 root 帐户*。不过,可以通过在 中添加以下行来隐藏此用户“管理员”,使其不被 gdm 登录所识别/etc/gdm/custom.conf
:
[greeter]
Exclude=nobody,administrator
我们可能会进一步限制非管理用户的读取权限 /home/administrator/
。
对于管理任务我们以用户身份本地登录行政人员(例如在命令行上或通过选择其他的在 GUI 中),或者通过 ssh 远程登录。
定义 ssh_config
为了向多台远程机器发出命令,我们需要定义一个本地配置文件我们在~/.ssh/ssh_config
其中列出了登录远程机器所需的详细信息,并可以为客户端定义方便的名称:
# ssh configuration
Host remote1
HostName 192.168.0.1
Port 22
User USERNAME
Host remote2
HostName 192.168.0.2
Port 22
User USERNAME
可能需要附加选项来进一步控制会话细节(例如禁用密码验证)。
在多个客户端上运行命令
我们现在编写一个脚本,连接到一个又一个的客户端来运行给定的命令:
#!/bin/bash
# run a command on multiple remotes
REMOTES=$1;shift
COMMAND=$1;shift
for remote in $REMOTES
do
echo $remote
ssh -oConnectTimeout=10 $remote $COMMAND
done
如果这个脚本被命名,remote_command.sh
我们就可以通过调用以下命令在我们的远程机器 1-X 上运行任何命令:
remote_command "remote1 remote2 ... remote<X>" "<COMMAND>" > remote_command.log
根据个人需求,我们可以从文件中读取 $REMOTES 列表,或者使用常规模式作为远程名称,以方便脚本使用。如果远程客户端没有变化,我们也可以在此脚本中编写所有名称,以便仅使用命令来调用它。
passwd root <password>
*重新启用 root 帐户(通过在 root shell 中为 root 定义有效密码)是灰心因为缺点过于明显。
答案3
它并不便宜,也不是开源的,但也许 Canonical 的景观可以帮助。
答案4
我不知道有哪款网吧软件可以做到这一点,而且我认为像 Puppet 或 Chef 这样的软件有点小题大做。您可以基于 SSH 构建一个非常简单的设置,这样就可以了。
假设您有 20 个客户端(10.0.0.101 到 10.0.0.120)和 1 个管理站(10.0.0.1)。
以下步骤均可在 1 个客户端上进行初步测试。初始设置需要在所有客户端上手动执行。
步骤 1:使其更安全(可选?)
在所有客户端上制定防火墙规则,仅接受来自 10.0.0.1 的新连接
也许您可以就此提出另一个问题。我也可以提供一些帮助,iptables
但我没有使用新的 Ubuntu 防火墙规则的经验。
第 2 步:建立连接
您需要在所有客户端上运行 SSH 服务。
- 在管理站上创建一个单独的非root帐户。
- 运行
ssh-keygen
以获取 SSH 密钥对。不要提供任何密码。 - 在客户端上创建一个单独的帐户。Takkat 提到了如何将其从 Gnome 登录窗口中排除。
将账户添加到 sudoers(例如使用
sudo visudo
)。添加此行:aptaccount1 ALL=(silktree) NOPASSWD: /usr/bin/apt-get
NOPASSWD 很重要,因为您需要运行安装而不需要为每个客户端都输入密码。
现在您可以测试了。从您的管理工作站运行:
ssh 10.0.0.101 sudo apt-get update
步骤 3:并行连接所有
现在,我的贡献就到此为止了。我使用这个脚本大约 3 年了,并且对它非常满意。它并行运行 ssh 命令到许多节点,并很好地打印输出和/或错误。
您需要在管理站上安装 rubyapt-get install ruby
并将所有客户端主机放入 /etc/managed-clients 列表中,如下所示:
n01
n02
n03
n04
并在管理站上添加/etc/hosts
:
10.0.0.101 n01
10.0.0.102 n02
10.0.0.103 n03
10.0.0.103 n04
然后将此脚本保存到/usr/local/bin/on-all-nodes-run
#!/usr/bin/ruby
CLIENTS_FILE = "/etc/managed-clients"
require "open3"
# Non-interactive, no password asking, and seasonable timeouts
SSH_OPTIONS = ["-o PreferredAuthentications=publickey,hostbased,gssapi,gssapi-with-mic",
"-o ForwardX11=no",
"-o BatchMode=yes",
"-o SetupTimeOut=5",
"-o ServerAliveInterval=5",
"-o ServerAliveCountMax=2"
].join(" ")
SSH = "/usr/bin/ssh #{SSH_OPTIONS}"
MKDIR = "/bin/mkdir"
raise "Pleae give this command at least one argument" if ARGV.size < 1
COMMAND = ARGV[0..-1].join(' ')
output_o = {}
output_e = {}
IO_CONNECTIONS_TO_REMOTE_PROCESSES = {}
def on_all_nodes(&block)
nodes = []
File.open(CLIENTS_FILE) do |f|
while line = f.gets
i = line.split(' ').first
nodes.push(i)
end
end
nodes.sort.each {|n| block.call(n)}
end
# Create processes
on_all_nodes do |node|
stdin, stdout, stderr = Open3.popen3("#{SSH} #{node} \"#{COMMAND}\"")
IO_CONNECTIONS_TO_REMOTE_PROCESSES[node] = [stdin, stdout, stderr]
end
has_remote_errors = false
# Collect results
on_all_nodes do |node|
stdin, stdout, stderr = IO_CONNECTIONS_TO_REMOTE_PROCESSES[node]
stdin.close
e_thread = Thread.new do
while line = stderr.gets
line.chomp!
STDERR.puts "#{node} ERROR: #{line}"
has_remote_errors = true
end
end
o_thread = Thread.new do
while line = stdout.gets
line.chomp!
puts "#{node} : #{line}"
end
end
# Let the threads finish
t1 = nil
t2 = nil
while [t1, t2].include? nil
if t1.nil?
t1 = e_thread.join(0.1) # Gives 1/10 of a second to STDERR
end
if t2.nil?
t2 = o_thread.join(0.1) # Give 1/10 of a second to STDOUT
end
end
end
exit(1) if has_remote_errors
该代码已经过审查,符合良好的编码风格,以下是一些屏幕截图: https://codereview.stackexchange.com/questions/1180/ruby-script-on-all-nodes-run-for-teaching 但我没有时间介绍这些建议。代码运行良好。
像这样测试:
on-all-nodes-run echo hi
n01 : hi
n02 : hi
n03 ERROR: Timeout, server not responding.
n04 : hi
步骤 4:并行安装软件
现在您应该能够像这样安装和升级软件(抱歉,我只有show
aptitude 的示例,但应该可以做同样的事情apt-get
):
on-all-nodes-run sudo aptitude show pbzip2 \| grep State
n01 : State: not installed
n02 : State: not installed
n03 ERROR: Timeout, server not responding.
n04 : State: not installed
on-all-nodes-run echo "Yes" \| sudo apt-get install pbzip2
...
on-all-nodes-run sudo aptitude show pbzip2 \| grep State
n01 : State: installed
n02 : State: installed
n03 ERROR: Timeout, server not responding.
n04 : State: installed
最后说明
如果你有超过 10-20 个客户,那么此外对于上面的脚本,你应该找到一种方法来重新配置硬盘,例如珀耳塞斯。这样,您可以节省一些时间(添加新客户端等...),并确保所有客户端的所有内容都相同。实际上,我on-all-nodes-run
每年使用 100 次。我每年使用 Perceus 对所有客户端进行几次重新映像。