意外地用scp禁用你的SSH访问
Disable Your SSH access accidentally with scp

原始链接: https://sny.sh/hypha/blog/scp

## SSH 登录失败,源于 SCP 权限问题 最近出现了一个问题:使用 `scp` 传输文件到服务器后,SSH 密钥认证停止工作。尽管密钥仍然存在于 `authorized_keys` 文件中,但登录尝试被拒绝。可以通过 WebDAV 维持文件系统访问。 根本原因在于意外更改的目录权限。`scp` 命令在传输权限过于开放(777)的目录时,会将这些权限递归地应用于服务器上的目标目录——甚至用户的家目录。这触发了 `sshd` 中的安全检查,如果家目录权限过于开放,则会拒绝密钥认证。 将家目录权限恢复为 700 解决了问题。问题源于 `scp` 将源权限镜像到目标目录的行为,OpenSSH 现在已经发现了这个缺陷,并计划在 10.3 版本中发布修复。这凸显了一种潜在的安全风险,并强调了在文件传输期间谨慎管理权限的重要性。

黑客新闻 新的 | 过去的 | 评论 | 提问 | 展示 | 工作 | 提交 登录 意外地用scp禁用你的SSH访问 (sny.sh) 11点 由 zdw 1小时前 | 隐藏 | 过去的 | 收藏 | 2评论 帮助 zahlman 31分钟前 | 下一个 [–] 我假设在`scp`命令中使用`./*`而不是`.`可以解决这个问题?回复 binaryturtle 16分钟前 | 上一个 [–] 当我用我的(稍微旧一点的)Firefox加载这个网站时,我只会得到一些随机的垃圾和胡言乱语(马尔可夫链生成的无意义内容?) 那些无意义的东西!回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系 搜索:
相关文章

原文

Here's an interesting bug I ran into recently: After transferring some files to my server via scp, I couldn't log in via SSH anymore - my key was rejected by sshd.

user@host: Permission denied (publickey).

The thing is, as luck would have it, I had previously set up a WebDAV server on the same machine - I've been using it for a number of things, for example as a makeshift synchronization solution for my KeePass database - and since it was just sshd acting up and everything else still worked fine, I could still access the entire file system via WebDAV.

My first thought was that some application had overwritten my authorized_keys file. Forgejo used to do this in the past every time it was updated, but I believe they fixed this. I certainly haven't had that issue for quite a while now. And sure enough, my key was still in there.

I tried creating a new key, putting it into authorized_keys and logging in using that, but to no avail. I tried logging in from a different machine - still nothing. I temporarily modified the sshd configuration to allow logging in via a password again, which worked flawlessly, but of course this was a workaround and not a solution. A reboot didn't help either (but I thought I might as well).

Luckily, when I say "server", what I really mean is a single-board computer sitting in my own four walls. So eventually, I gave in, took out the SD card and put it into my machine. I thought I'd run fsck for good measure, but it didn't report any issues. (And I hoped it wouldn't, the card is barely a few months old after all!)

But then I noticed something odd while cd'ing and ls'ing my way around the file system: The file system permissions of my home directory were set to rwxrwxrwx (777). I was certain that I didn't make this change - not least because ls helpfully highlighted the respective entry with a green background, something I no doubt would've noticed in the past.

If you're using SSH yourself, you may have run into a curious issue in the past: sshd telling you that the permissions of your private key file are too open. OpenSSH will refuse to use a key to connect to any server if said file is readable by any user but yourself:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'id_ed25519' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "id_ed25519": bad permissions
user@host: Permission denied (publickey).

Well, it seems like there's a similar check on the server as well. As soon as I reverted the permissions of my home directory to rwx------ (700), everything went back to normal. And sure enough, between thousands of authentication failures from bots and scrapers, there was a revealing line in the OpenSSH logs:

sshd-session: Authentication refused: bad ownership or modes for directory /home/user

Alright, problem solved. But why did the permissions of my home directory change all of a sudden?

Well, let's replicate what happened right before all of this went down: the SCP file transfer. The exact command I used at the time (save for the redacted hostname) was:

$ scp -r . host:

This transfers everything in the current local directory to my home directory on the server. Another part that's going to be of importance is that, for reasons, the directory I wanted to transfer had the permissions of rwxrwxrwx (777). Can you tell where this is going already?

First, let's create the directory, as well as some sample files to transfer:

$ mkdir local_directory
$ chmod 777 local_directory
$ cd local_directory
$ touch test_file_1 test_file_2 test_file_3

Next is the destination directory. We could also use the home directory again, but I'm not going to take any more risks:

$ ssh host mkdir remote_directory
$ ssh host chmod 700 remote_directory

The moment of truth:

$ ssh host ls -ld remote_directory | cut -d " " -f 1
drwx------

$ scp -r . host:remote_directory
test_file_1	100%	0	0.0KB/s	00:00
test_file_2	100%	0	0.0KB/s	00:00
test_file_3	100%	0	0.0KB/s	00:00

$ ssh host ls -ld remote_directory | cut -d " " -f 1
drwxrwxrwx

It seems that OpenSSH's scp modifies the permissions of the transferred files and directories to match their local counterparts. This makes sense, except it also does so if the target directory already exists!

So, in short: When I transferred the files within a directory with the permissions of rwxrwxrwx (777) to my server, scp modified the permissions of the target (and, in this case, home) directory to match. Then, when I tried to log in via SSH, sshd determined that these permissions were too broad, too open to other users, to continue in a safe manner, and rejected my key.

I reported my findings to OpenSSH's bug tracker. Within hours, a fix was pushed, and the author told me that it's going to be included in the next release, 10.3. Kudos to them for such a quick response!

Links of interest:

联系我们 contact @ memedata.com