创建一个Rsync图形界面以备份到远程服务器

4 投票
2 回答
1405 浏览
提问于 2025-04-16 22:39

我正在用Python创建一个备份图形界面(GUI),这个界面主要是让用户输入他们的用户名、密码和源目录,这样就可以把文件通过rsync传输到远程服务器上。现在我遇到的唯一问题是,如何把用户在界面上输入的密码传递给服务器,执行这个命令:

rsync -options source_path rsync_user@rsync_server:remote_path

因为我希望用户每次使用这个图形界面时都要进行身份验证,所以我不想设置自动的ssh密钥会话。我查了一下Pexpect和Paramiko,但发现expect似乎不太安全,而且我也不太确定怎么配置Paramiko,以便能够从本地计算机通过rsync传输到远程服务器。

总的来说,我在寻找一种方法,可以在执行rsync命令后,将密码传递给服务器(并信任这个主机),而不需要任何终端交互(这正是图形界面的目的)。

2 个回答

0

首先,真棒,你在做这个!应该有更多的图形界面(GUI)来使用rsync。我写了一个叫Truck的应用程序——这是一个Mac上的rsync图形界面应用,是用Python和Qt(PyQt)开发的。我解决这个问题的方法是生成一对本地密钥;把私钥保存在本地;然后把公钥添加到远程主机的authorized_keys文件里,像这样:

  PRIV_KEY_PATH = "~/.ssh/private.key"
  if os.path.exists(PRIV_KEY_PATH):
        key = paramiko.RSAKey(filename=PRIV_KEY_PATH)
    else:
        touch(PRIV_KEY_PATH)
        key = paramiko.RSAKey.generate(bits=1024, progress_func=self.keygen_progress)
        key.write_private_key_file(PRIV_KEY_PATH)

    try:
        ftp_cli.chdir(".ssh")
        ftp_cli.chdir("..")
    except IOError:
        ftp_cli.mkdir(".ssh", mode=0o700)

    key_line = "{name} {key} {comment}".format(name=key.get_name(),
                                               key=key.get_base64(),
                                               comment="hello world")
    with ftp_cli.open(".ssh/authorized_keys", mode="a+") as fh:
        fh.seek(0)
        lines = fh.readlines() 
        if not key_line in lines:
            fh.write("\n" + key_line)
        fh.close()

然后,当你调用rsync的时候,传递类似--rsh=ssh -i ~/.ssh/private.key的参数。

这样几行代码,你就配置好了无密码的SSH登录,并利用它来进行rsync。恭喜你选择了Python。

你提到希望用户在下次使用你的图形界面时再次进行身份验证,那么你需要把这看作是一个临时的密钥会话,并适当地清理authorized_keys文件。我也用Tkl和Expect做过类似的解决方案,但我不推荐那条路。Paramiko是安全的,除非你在实现上出错。(P)Expect本身并不不安全。

你也可以考虑将Paramiko设置为SSH转发服务器,但我担心这样会通过Paramiko造成rsync的性能瓶颈。我觉得我更倾向于使用机器自带的SSH实现。

0

你能用这个吗?

在远程服务器上,有些模块可能需要你输入密码才能使用。如果是这样,当你连接的时候就会出现一个输入密码的提示。你可以通过设置一个环境变量 RSYNC_PASSWORD 来提前填好你想用的密码,这样就可以避免输入密码的提示,或者你也可以使用 --password-file 这个选项。这在写脚本使用 rsync 的时候会很方便。

警告:在某些系统上,环境变量对所有用户都是可见的。在这些系统上,建议使用 --password-file

来自 rsync(1)

撰写回答