我有一个 shell 脚本来设置环境并在网络服务器上安装一个相对复杂的 Web 应用程序,它逐渐从一个快速的糟糕的 hack 演变为一个更大的、稍微不那么糟糕的 hack。
以前,我的脚本有一个内置的“引导”功能,可以让我轻松地将其从我的开发计算机复制到远程服务器以供使用,要求 root 登录创建一个文件夹来放置脚本,然后复制脚本。
随着这个项目的发展,现在事实证明,我们需要依赖的其他软件需要“sudo”环境(而不是 root 登录)来用于其自己的设置脚本,因此我想切换我的设置脚本从期望 root 到使用 sudo (特别是我们可能希望与其他人共享此脚本,并使其能够在 root 不可用的服务器(例如 Ubuntu)上工作)。
目前,我的引导函数执行以下操作:
bootstrap()
{
INSTALL_DIR=/local/bin
SCRIPT=`basename $0`
echo "Copying script '${SCRIPT}' onto server: '${RHOST}' into '${INSTALL_DIR}'"
echo "(You need to login (as root) 2 times.)"
ssh root@$RHOST "umask 027; mkdir -p $INSTALL_DIR"
scp -p "$SCRIPT" root@$RHOST:/$INSTALL_DIR
echo "Done. Now login to the server and run the script as root."
exit
}
我不知道如何将其转换为使用 sudo? scp 希望我以能够写入文件所在文件夹的用户身份登录,如果没有 root 帐户,我将无法执行此操作?
或者也许我把这件事搞得太复杂了?如果远程服务器上的普通用户本质上是一步删除 root 的,也许,我可以将其 scp 到用户自己的文件空间中的某个位置,而不是尝试创建一个“整洁”的地方来存储这些管理脚本,并且然后,用户可以使用 sudo 从那里运行脚本的安装部分。 (我想可能出现的唯一问题可能是如果不同的管理员需要运行脚本并且无法访问其他用户的文件..)
答案1
除了 SSH 之外,还有多种方法可以解决此问题。除此之外,您对 root 帐户和“sudo”环境有点模糊。我假设你的意思是 root 帐户不允许 shell 访问(这是 Ubuntu 上的默认设置),并且你必须向用户授予 sudo 访问权限才能授予管理员权限。 root 帐户本身仍然存在(uid/gid 0)。
坚持使用 SSH 和 sudo
以 SSH、sudo 和安全复制文件为例。您可以将文件复制到公共位置,然后使用 sudo 将其复制或移动到受限位置。这确实有一些安全隐患,因为该文件至少暂时位于公共位置。还有许多方法可以减轻此问题的安全因素。
将文件安全地复制到远程服务器上的临时位置。
scp -p xfer_file jschaeffer@aiur:/tmp
现在使用 SSH 连接到服务器并将其复制或移动到永久位置。
ssh -t jschaeffer@aiur: sudo cp /tmp/xfer_file /perm
这里的关键要点是 -t 到 ssh。从手册页。
-t Force pseudo-tty allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.
根本不提示输入密码
除此之外,您可以将 sudo 规则定义为不需要密码,并且不会提示用户。
允许非 root 用户对 root 进行无密码身份验证
此方法的替代方法是使用公钥。您可以通过使用公钥授予用户对另一个帐户的访问权限。这也有其自身的安全隐患。您授予用户对某个盒子的完全 root 访问权限(下面有一些花絮)。
jschaeffer@defiler:~# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/jschaeffer/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /jschaeffer/.ssh/id_rsa.
Your public key has been saved in /jschaeffer/.ssh/id_rsa.pub.
然后将公钥复制到远程服务器(确保复制公钥而不是私钥)。因为整个讨论围绕将文件复制到不允许直接 root 访问的服务器,所以我不会显示与 root 帐户连接的 ssh-copy-id 或 scp 命令。无论如何,您必须找到一种方法将密钥传输到 ~root/.ssh/authorized_keys。可以使用上述策略或复制到闪存驱动器或其他方法(rsync、ftp 等)
root 帐户必须允许在服务器上进行无密码身份验证。确保 /etc/ssh/sshd_config 中的设置正确
# Authentication:
LoginGraceTime 120
PermitRootLogin without-password
StrictModes yes
然后直接将文件复制到root帐户即可。
scp -p xfer_file root@aiur:/perm_location
您可以通过将选项附加到authorized_keys 文件来限制用户在 ssh 时实际可以执行的操作
其他选项
当然还有很多其他的选择,我会列出但不会详细介绍:
- 使用 Kerberos。 Kerberos 是围绕不安全网络中的安全性设计的完整协议。这当然需要整个环境、维护、硬件等,可能不是您想要的。 SSH 与 Kerbero 集成,或者您可以使用 Kerberos 的一种不安全传输替代品。
- 将文件复制到服务器上的临时位置,并在远程服务器上以 root 身份运行一个 cron 作业,拾取该目录中的文件并将它们传输到永久位置
- rsync 文件
- 将文件放在两个服务器都可以访问的公共位置(即 ftp、sftp、http)。
- 重新启用 root 帐户。
答案2
对于 rsync,人们使用了一种模式来实现它。大多数 Linux 安装默认包含 rsync。
rsync -e "ssh -t" --rsync-path="sudo rsync" ...
--https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Automated_Backup#Backup_with_rsync_and_sudo
答案3
与其将数据推送到您无法轻松写入的地方,不如提取数据怎么样?或者将数据推送到其他可以写入的地方,然后在远程系统上将数据放置到位? --可能当应用程序被弹回以获取新文件时?
另请注意,某些建议会削弱生产系统的安全性。