我在本地计算机上有一个脚本,旨在夜间将文件复制到远程服务器。我目前通过 scp 使用无密码密钥来完成此操作,因为这是脚本工作的唯一方法。
该脚本正在客户端的计算机上运行。除了我之外,有几个人可以访问这台机器。远程机器是属于我的云实例。尽管预计不会发生任何事情,但还是保持安全为好。所以我只希望脚本能够自动且安全地工作,这样任何有权访问本地计算机的人都无法访问我的云计算机
我不想永远这样下去,因为它非常不安全。但是,我无法找到任何安全的解决方案来完成任务。我一直在研究 Rclone,但它似乎让机器处于同样的不受保护状态。
最安全地解决问题的最佳选择是什么?我一直在考虑在远程创建特定用户,并仅限制对其复制文件的文件夹的访问,但这使得该文件夹无论如何都可以使用密钥自由访问。
答案1
基本上,您需要尽可能地将服务器与客户端隔离。由于服务器(根据您的描述)仅充当接收器,因此您可能正在寻找一种使访问成为只写的方法,并且最好进行一些输入检查(至少您想施加大小限制以防止可能的 DoS) 。
如果您想使用 SSH,您可以使用该ForceCommand
选项并将其设置为过滤器脚本,该脚本会将输入通过管道传输到服务器上的适当文件中。您可能还对command="command"
可以在AuthorizedKeysFile
.有关更多详细信息,请参阅sshd(8)
和sshd_config(5)
手册页。
一种替代方案是一个简单的 REST API,它只允许上传 - 如果您选择 HTTP,您基本上需要提供一个请求方式仅处理程序:(POST
或PUT
,取决于您的具体设置)。使用证书进行身份验证(如果可能的话,最好具有较短的有效期并绑定到特定的源系统)。
答案2
你的答案是使用sftp
.这与您当前正在做的事情没有太大变化,因为它也是通过连接完成的ssh
。
sftp 是一个文件传输程序,类似于 ftp(1),它通过加密的 ssh(1) 传输执行所有操作。它还可能使用ssh的许多功能,例如公钥认证和压缩
首先,您应该为您的客户创建一个独立的用户。它应该有一个 root 拥有的主目录、其公钥.ssh/authorized_keys
以及一个用于写入访问的自拥有目录。
$ sudo mkdir -p /home/tmpuser/.ssh
$ sudo mkdir -p /home/tmpuser/uploads
$ sudo cp ~/.ssh/id_rsa.pub /home/tmpuser/.ssh/authorized_keys
$ sudo adduser --home /home/tmpuser --disabled-password tmpuser
$ sudo chown tmpuser /home/tmpuser/uploads
可以使用相同的无密码 SSH 令牌。我想您担心您的客户会与其他人分享他们的私钥。该“其他人”只能看到属于您客户的用户的内容,而不能看到属于任何其他用户的内容,也不能看到属于您计算机的其余部分的内容。这是他们的风险,而不是你的。您可以通过监控uploads/
新文件并将其移出 chroot 来缓解此问题,或者在处理后删除文件。显然永远不要“信任”传入的文件(例如永远不要执行它们)。
接下来,在 中/etc/ssh/sshd_config
,设置internal-sftp
并强制该用户执行此操作:
#Subsystem sftp /usr/lib/openssh/sftp-server <-- comment this line out
Subsystem stfp internal-sftp
# At the bottom of the file add this:
Match User tmpuser
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no
ChrootDirectory %h
现在sshd
使用重置sudo systemctl restart sshd
,然后尝试一下:
# Confirm normal ssh is impossible
$ ssh tmpuser@localhost
This service allows sftp connections only.
Connection to localhost closed.
# Confirm scp is impossible
$ scp testfile tmpuser@localhost:
This service allows sftp connections only.
# Check that you can "put" a file in uploads/
$ echo "put testfile uploads/" | sftp -b - tmpuser@localhost
sftp> put testfile uploads/
# Check that you can connect via sftp and can only use sftp commands
$ sftp tmpuser@localhost
Connected to localhost.
# Check that a basic command works
sftp> ls
uploads
# Check that we are indeed in a chroot
sftp> pwd
Remote working directory: /
# Check that our testfile was actually uploaded
sftp> ls uploads
uploads/testfile
# Try to get out of the chroot
sftp> cd ..
sftp> ls
uploads
# Try to run a non-sftp command
sftp> ps
Invalid command.