像往常一样,日常备份一下服务器上的备份文件:

1
rsync -auv -e "ssh -i /home/deploy/.ssh/mi" --progress /home/deploy/common/ android@xm.onns.xyz:/home/android/

突然间我服务器炸了,ssh什么的都连不上了:

1
android@xm.onns.xyz: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

之前从没遇到过这样的问题,正因为从来没遇到过,所以我服务器上只有一个账户,这个账户没法登录,我整个服务器就连接不上了,物理机也连接不上😭。

后面重新安装了ssh之后总算可以登录了,上去排查问题。

首先第一个想到的可能是,我的rsync目的路径是我用户的根目录,会不会发生了覆盖写操作,把我的根目录下的.ssh/目录删除了,导致ssh找不到authorized_keys文件。

这个问题首先去看了下rsync的参数,我没有带--delete所以肯定不会有删除的问题,而且后面登录上去之后也确实根目录下的所有文件都在,此问题排除。

到目前为止,根据我现有的知识,没有办法确定问题发生的原因,所以我打算重新配置一下ssh密钥,然后再次复现一下之前的操作。

到这里就出现了问题,ssh密钥不论我怎么配置,android用户都无法通过密钥登录。

查看了一下/etc/ssh/sshd_config,发现相关的配置都没问题:

1
2
3
4
5
PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys

PubkeyAuthentication设置了yes,允许密钥登录,验证文件也没问题,是.ssh/authorized_keys

没办法解决,所以我又创建了一个新的用户,然后同样的生成密钥,测试登录,发现新用户没有任何问题,可以使用密钥登录

再次回到android用户的登录测试,把本地的私钥权限调成777

1
2
3
4
5
6
7
8
$ ssh android@192.168.1.116 -i mi
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for 'mi' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "mi": bad permissions

按理来说没问题的,这已经在走密钥验证流程了,所以说,大概率还是android的服务器那边配置出了什么问题。

找了一些ssh密钥登录的配置教程,在配置authorized_keys的时候,教程里把.ssh目录的权限设置为700,把authorized_keys文件的权限设置为600,这是我之前从来不知道的,原来服务器端这边的公钥也需要相关的权限。

受此启发,同时我又去查了一下rsync的相关文档,其中一个教程有如下说明:

3.源目录如果不带后缀“/”表示在目标目录下创建该目录并把源目录下文件一并同步过去,带“/”表示只是把源目录下的文件全部同步过去。

所以我的/home/android/的权限极有可能是被修改了,导致ssh的文件夹信任路径没有办法走完。

重新修改了一下/home/android/目录的权限,修改成700,发现android用户的ssh已经可以正常地用密钥登录了。

再次复现一下问题:

1
2
3
4
5
6
$ rsync -auv -e "ssh -i /home/deploy/.ssh/mi" --progress /home/deploy/common/ android@xm.onns.xyz:/home/android/
sending incremental file list
./

sent 84 bytes received 19 bytes 41.20 bytes/sec
total size is 2,183,563 speedup is 21,199.64

回到服务器查看一下:

1
2
3
4
$ ls -l
total 8
drwxrwxr-x. 6 android android 4096 Sep 15 18:37 android
drwx------. 5 onns aid_system 4096 Sep 15 18:37 onns

果然是这个问题。

至此,花了几个小时时间,终于把问题解决了,因为同步的是数据库的备份文件,所以我当时以为服务器被黑了,赶紧把服务器从互联网上断网了,所幸,是小问题。

#总结

也算是,多了解了一些关于ssh的使用相关问题吧,如果未来没有相关的系统学习,那今天所做的,往好了说,就是在提前为以后填坑啦!

  • ssh本地的私钥权限必须保证为600,相关路径的权限为700,这个路径是从/开始算的所有路径,任意中间一点权限过高都不行。
  • ssh服务器公钥权限必须保证为600,相关路径的权限为700,这个路径是从/开始算的所有路径,任意中间一点权限过高都不行。
  • rsync或者说Linux下的文件拷贝复制,结尾带/或者不带/影响真的很大,这个要根据每个指令自己的相关实现,以rsync为例,源文件夹路径如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /
    ├── home
    | ├── deploy
    | | ├── common
    | | | ├── daily_backup.db
    | | | ├── ...
    | | ├── ...
    | ├── ...
    ├── ...
    daily_backup.db及其相关文件是我们要备份的文件,如果我们使用如下命令:
    1
    rsync -auv -e "ssh -i /home/deploy/.ssh/mi" --progress /home/deploy/common/ android@xm.onns.xyz:/home/android/
    在目标文件生成的文件会如下:
    1
    2
    3
    4
    5
    6
    7
    /
    ├── home
    | ├── android
    | | ├── daily_backup.db
    | | ├── ...
    | ├── ...
    ├── ...
    会直接把所有文件放到根目录,所以不可避免的会修改根目录的相关权限。但假如换成如下命令:
    1
    rsync -auv -e "ssh -i /home/deploy/.ssh/mi" --progress /home/deploy/common android@xm.onns.xyz:/home/android/
    在目标文件生成的文件会如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /
    ├── home
    | ├── android
    | | ├── common
    | | | ├── daily_backup.db
    | | | ├── ...
    | | ├── ...
    | ├── ...
    ├── ...
    一个/真的差别好大!

#相关链接