让SSH远程登录Vultr VPS更安全

前言

一般情况下,在Windows系统下远程登录Vultr的VPS,最简单的做法就是在Putty里填上Vultr所提供VPS的IP地址以及其对应的密码进行SSH登录。

如果是新手小白,那当然也会怎么简单怎么来,自然而然也没有对VPS进行更深入的配置,就连登录所用的用户名也是默认的root,同样SSH端口也是默认的22。其实,这种一切按照常规默认的做法有利有弊,我感觉唯一的好处就是不用花很多精力进行配置,相比之下坏处可能就多点,最坏就是让别人很容易入侵你的VPS,或许你会说,网上教程是多如牛毛,找一些教程跟着做就是了。话虽如此,但教程是否适用于当前自己所处的情况,那就真的不得而知了,对于新手小白是无法甄别教程的好坏,只能一个一个去试,甚至是多种做法结合起来,才能解决问题,加上怕麻烦的心里,所以最终干脆就是所有配置默认就好了。

其实,基本所有高手/有经验的人也是由小白/菜鸟慢慢成长起来的,所以,对于一些讲求技术和规范的流程或场景,小白更不应该怕,直面它,稳扎稳打一步一步解决,自己才会有进步,或许自己的步伐会比别人慢很多,但没关系,总比原地踏步甚至回避问题而永远不学习新东西永远不进步要来得好。我同样也是小白,也曾经那样原地踏步一段时间了,后来尝试求变,发现其实并不难,只要自己不怕敢去尝试,其实自己也能做到。

系统环境

这篇教程的所有结果是在以下环境实现的:

  1. Windows 10
  2. CentOS 7

Windows 10是现在大家最常用的系统,虽然也有挺多人用Windows 7的,不过我觉得应该也同样能适用;
我的VPS是CentOS 7,有些命令或许就不能用在其他Linux系统上了,而我也只是懂一点Linux的皮毛,关于这个我也说不清楚,说错勿怪,但不用担心,本文里的命令在CentOS 7执行是毫无问题的。

改变SSH登录端口

修改SSH配置的端口配置

  1. nano /etc/ssh/sshd_config打开SSH配置文件
  2. 找到Port这行配置,可以看到它默认的配置是22,并且这一行默认是被注释的,把注释标记#去掉
  3. 在刚去掉注释Port这一行的下面多增加一行Port配置,这样就指定自定义端口,比如就指定为7878

    1
    Port 7878

    配置输入完成后Ctrl+X,按Y再按回车,这样就是保存修改并退出

  4. systemctl restart sshd重启SSH服务

这里是为了避免因配置不正确而造成不能登录的麻烦,所以,先把默认的22端口留着,就算新端口配置不成,那也可以继续用默认端口登录。

修改防火墙的端口配置

光在SSH配置文件增加一个端口还不能让我们使用那个端口进行SSH登录,你必须让防火墙允许这个端口能进行通信,那才能让端口真正能被使用。

新增端口

  1. firewall-cmd --zone=public --add-port=7878/tcp --permanent告诉防火墙端口7878
  2. firewall-cmd --reload重新加载防火墙配置

现在,尝试使用新端口进行SSH登录,如果成功了,那就再把22默认端口那行配置删掉或注释掉,仅留下自己所配置的自定义端口即可,如果想增加多个端口,重复以上步骤即可。

查看/删除端口

  • firewall-cmd --list-ports查看被防火墙允许进行通信的端口,执行该命令就会列出所有被防火墙允许进行通信的端口。
  • firewall-cmd --zone=public --remove-port=7878/tcp --permanent删除指定的端口,比如删除刚才配置的端口7878,删除后就无法通过端口7878进行SSH登录。

最后提醒一点,凡是修改防火墙配置后,都要记得执行firewall-cmd --reload重新加载防火墙的配置,这样配置才会生效。

改变SSH登录用户

正如通过默认端口22进行SSH登录可以是可以的,那同样通过默认用户root进行SSH登录也不是不可以,但也正如之前所说,这明显是不安全的。因为VPS的IP地址或许很容易就会暴露于外部(至于是具体是通过什么方式暴露的那我就不懂了),如果这时别人试出了SSH端口同时也试出了默认用户名root可以对你的VPS进行SSH登录,那就有机会进行暴力破解进而入侵了。

我们之前所做的工作首先就是把默认端口22改成自定义的,让VPS更安全,同样,使用默认用户名root也是不可取的,为了增加安全性,用户名必须也要进行自定义。

自定义最高权限用户

Linux系统默认自带拥有最高权限用户,其名正是root,而默认可进行SSH登录的用户是它;登录密码是Vultr提供的,但它绝对不方便记忆,所以我们要把用户名和密码都一并改了,其他维持不变。

  1. 首先通过用户名root以及Vultr提供的密码进行SSH登录
  2. nano /etc/passwd打开这个文件,passwd是存放所有用户账号信息的文件
  3. 第一行就是与用户root相关的信息了,把用户名改成其他

    1
    root:x:0:0:root:/root:/bin/bash

    配置的通用格式:username:password:user_id:group_id:comment:home_directory:login_command

    usernamepassowrduser_idgroup_idcommenthome_diractorylogin_command
    用户名密码用户唯一标识用户组唯一标识用户描述用户目录登录所执行的命令

    可以很清楚看到,这里所有用户相关信息的密码都是一个x,只起一个占位符的作用,密码其实存储在了另一个文件/etc/shadow里,但里头的密码肯定是经过加密后才存储的,不会是明文

    我们只要把第一个root改成我们所想要的名字便可,比如改成root_DotA

    1
    root_DotA:x:0:0:root:/root:/bin/bash
  1. passwd root_DotA修改用户root_DotA的密码,执行该命令后,它会让你输入密码两次,两次输入一样即可
  2. nano /etc/sudoers打开这个配置文件
  3. 找到如下这一行配置,这样做是告诉系统让新的用户名也有sudo权限

    1
    root    ALL=(ALL)    ALL

    然后就在这一行配置后再起一行,然后加上我们的配置

    1
    root_DotA    ALL=(ALL)    ALL

现在,最高权限用户就不再叫root了,而叫root_DotA了,同时与它相关的登录密码也不再是Vultr所提供的。

添加普通新用户

修改最高权限用户这个工作必须做,其实之后还可以添加普通新用户。比如,这里演示的是增加一个名为DotA的新用户。

  1. 先用最高权限的用户登录上去
  2. 执行adduser DotA这个命令简单且易懂,就是增加一个用户名为DotA的用户
  3. 执行passwd DotA指定密码
  4. 给普通用户添加sudo权限,就像前面所讲的那样,也是打开/etc/sudoers,并给用户DotA增加一行

    1
    DotA    ALL=(ALL)    ALL

    如果不做这一步,对于普通用户来说很多命令都执行不了,因为普通用户的权限很低。

完成上述所有步骤后,既添加新用户DotA并赋予sudo权限就大功告成了。

如果没有特殊情况,一般来说普通用户的用户目录就是/home/user_name,比如对于上面增加的DotA用户来说,它的用户目录就是/home/DotA

更多与用户相关的SSH配置

之前的步骤都准确无误地做完,那就可以通过新增加的用户进行SSH登录;更重要的是,已更新用户名和密码后的最高权限用户不能再用默认用户名root以及Vultr提供的密码进行SSH登录。

如果你添加了很多用户,而只允许个别用户进行SSH登录,那就要进行额外的SSH配置:

  1. nano /etc/ssh/sshd_config打开SSH配置文件
  2. Ctrl+W查找AllowUsers这个配置,这个配置是用于指定允许进行SSH登录的用户,可以指定多个用户名,之间用空格分隔
  3. 如果找到了,就在后头加上新添的用户名,如果看到其中指定了root,那就视情况把它去掉; 如果没找到,那就随便找个地方另起一行,把配置加上
  4. systemctl restart sshd重启SSH服务

值得注意的一个细节:

有些教程会让你把SSH配置文件里的PermitRootLogin指定为no,这样配置的意思就是不允许拥有最高权限的用户SSH登录,而不是不允许用户名为root的用户SSH登录
如果在AllowUsers指定了最高权限的用户,并且,同时把PermitRootLogin指定为no,这样拥有最高权限的用户也是不能进行SSH登录的。

公钥验证登录

之前进行的SSH登录都是输入用户名以及对应的密码进行登录的,如果你觉得每次输入密码都很麻烦,那其实是有解决办法的,那就是改用公钥验证进行SSH登录。

所谓公钥验证登录,简单来讲就是生成由公钥和私钥组成的密钥对,服务器持有公钥,自己持有私钥,只要两者的关系在验证后能匹配得上,那就可以进行SSH登录。

如果你想要每个用户都可以进行公钥验证SSH登录,那必须给每个用户都指定公钥才行,给每个用户指定的公钥可以是同一个,也可以大家都不同,这个根据自己的需求来做。

生成密钥对

要实现公钥验证SSH登录,那在这之前必须生成公钥私钥密钥对,密钥对生成所要做的工作很简单,不同的系统有不同的做法,更详细的教程可以看参考资料处的教程。

Windows

在Windows系统内要生成密钥对,最常见简单的做法就是用PuTTYgen生成,PuTTYgen是Putty的配套工具,只要你安装过Putty,它也自然安装上了。

  1. 打开PuTTYgen,点击Gennerate,根据提示,你要在进度条下方空白的区域不断移动你的鼠标指针,直到进度条走完为止

    生成密钥对的过程进度条走完,即代表密钥生成了,这里我想的是密钥对可能就是根据鼠标指针的轨迹所生成的

  2. 看到Key这里,下面的内容就是公钥,是一个字符串

    公钥

  3. 随便找个地方,创建一个名为authorized_keys的文件,用这个文件将刚才所生成的公钥保存起来

    公钥整个字符串只能是单独一行,千万不要给它换行,否则公钥不起作用。

  4. Key passphraseConfirm passphrase这两处输入密码,不输入也可以,但为了安全性,那肯定是指定密码啊

    输入密码

  5. 点击Save private key按钮将私钥保存于指定文件中,PuTTYgen默认的保存格式是.ppk

    私钥文件很重要,以后进行SSH登录都要用到它的,所以千万不能把它丢失,否则就不能进行SSH登录了。

    和公钥文件一样,其实私钥文件也是文本文件,如果你想查看私钥实际的文本是什么,把这个文件改成.txt后缀再看即可,当然,真正使用的时候还是要改回来。

Linux

在Linux生成密钥对当然是用命令啦,不过命令很简单,而且也就是简单几步。

  1. 输入ssh-keygen -t rsa生成公钥/私钥组成的密钥对
    然后它会提示让你输入保存私钥的绝对文件路径

    1
    Enter file in which to save the key (/root/.ssh/id_rsa):
  2. 输入保存私钥的绝对文件路径,不输入直接回车即指定当前用户的/home_directory/.ssh/id_rsa作为保存私钥的绝对文件路径

  3. 输入完路径后,它会接着让你输入两次密码

    1
    2
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:

    这里的处理方式跟上一个小节的第四步一样,这里就不再赘述

    完成这个步骤后,最终就可以看到以下信息:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Your identification has been saved in /root/.ssh/id_rsa.
    Your public key has been saved in /root/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:6GeViKd4y9wRJBVvhgoy5AckZsx4HoMYPQk0sp8P06s your_user_name@server_info
    The key's randomart image is:
    +---[RSA 2048]----+
    |@@+. o. |
    |BBO. . o |
    |.o++o . o + |
    | ..* . * + . |
    | = . + S o |
    | + + o o |
    | + + + |
    | . + = . |
    | E + . |
    +----[SHA256]-----+

    最重要的当然是前两行信息,可以看到私钥文件就是在默认的文件中,而公钥文件id_rsa.pub默认也和私钥放一个地方,这两个文件是最重要的

  4. 将公钥文件id_rsa.pub重命名为authorized_keys,执行命令mv /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys即可

部署公钥与获取私钥

现在,密钥对是准备好了,如果之前是在Windows生成的密钥对,那现在就差把公钥部署到VPS上,而如果之前是在VPS的Linux系统上生成密钥,那就得将其私钥下载到Windows本地。

部署公钥

一般默认情况下都把公钥放在/home_directory/.ssh/内,即用户目录内的.ssh文件夹内,所以,这里遵循Linux默认的做法,那就把公钥放到/root/.ssh/

部署有两种做法可供选择:

  • /root.ssh/内新建一个名为authorized_keys的文件,并把之前生成的公钥内容复制粘贴到这个文件中
  • 在Windows命令行执行pscp -P ssh_port 本地公钥文件的绝对路径 user_name@host:/root/.ssh/把之前生成好的公钥文件authorized_keys上传到/root/.ssh/

获取私钥

之前的步骤是把私钥保存到/root/.ssh/id_rsa文件中,最重要的就是把这个私钥文件下载到本地。

同样的,获取也是两种做法可供选择:

  • 打开私钥文件nano /root/.ssh/id_rsa,将里面的内容复制粘贴到Windows本地一个空文本文件中
  • 在Windows命令行执行pscp -P ssh_port user_name@host:/root/.ssh/id_rsa 保存该私钥的Windows目录的绝对路径把之前生成好的私钥文件下载到Windows本地目录

通过以上两种方式把私钥下载到Windows本地后,然后通过Putty的Load private key加载它,接着Save private key,以.ppk格式保存即可。

pscp工具

简单来说,pscp是一个Putty附带的工具,它通过SSH连接两台电脑并进行文件传输。

官方文档是这样描述的:

PSCP, the PuTTY Secure Copy client, is a tool for transferring files securely between computers using an SSH connection.

没有特殊要求的话,像下面这样使用即可,命令通用格式如下:

1
2
3
4
5
下载
pscp -P ssh_port [user_name@]host:source target

上传
pscp -P ssh_port source [source...] [user_name@]host:target

其中-P这个参数即指定SSH端口,如果要查询命令的其他参数解析,直接执行pscp即可,这里不再对其余参数逐个解析。

SSH设置

做完了之前的步骤,仍然还不能通过公钥验证进行SSH登录的。既然进行的是SSH登录,那对SSH进行配置肯定是必不可少的。

  1. nano /etc/ssh/sshd_config打开SSH配置文件
  2. PubkeyAuthentication指定为yes,即开启公钥验证
  3. Ctrl+W查找RSAAuthentication,将其指定为yes,如果找不到就自己加上这个键值对
  4. 找到AuthorizedKeysFile,指定公钥文件的绝对路径,要配置多个路径就用空格分隔,而它默认就指定了一个路径/root/.ssh/authorized_keys

    看到这个配置,或许你现在知道为何之前要把公钥文件命名为authorized_keys了吧?正是默认做法而已。

    根据这一点反推那就搞清楚一件事了:公钥文件并不一定要放在用户目录,也不一定要命名为authorized_keys,最重要的就是AuthorizedKeysFile配置

    5.保存SSH配置文件并重启SSH服务

现在,那就来试试通过新的方式进行SSH登录!跟以往所做的一样,在Putty填上ip地址和SSH端口,但还要多一个步骤,即指定带上一个私钥:
指定私钥

然后就可以登录了,在登录的时候,当输入用户名后,如果之前所做的工作都正确的,并且私钥通过了服务器上的公钥验证:那么就会显示以下信息:

1
2
Authenticating with public key "rsa-key-comment"
Passphrase for key "rsa-key-comment":

此处就是代表着公钥验证流程正常执行,现在只要输入生成私钥时所指定的密码即可完成登录;如果在生成私钥时没有指定密码,那此处就不会要求输入密码。

注意:这里要求输入的密码不是用户密码,而是生成私钥时所指定的密码!!

如果可以登录了,那就可以做最后的配置了,OK,这真的是最后的配置了!

  1. nano /etc/ssh/sshd_config打开SSH配置文件
  2. Ctrl+W查找PasswordAuthentication,讲其指定为no,即禁止SSH登录的用户密码验证,就是说只能通过公钥验证进行SSH登录
  3. 重启SSH服务

现在再去试试登录,你会发现,如果不带上私钥进行登录,那是不允许你登录的,会直接弹出这个错误消息:

不能再使用用户密码登录

现在一切工作都做完了!完。

参考资料