[转]SSH 原理和基本使用:ssh 安全配置 以及ssh key 认证登录

一、什么是 SSH ?

     SSH全称(Secure SHell)是一种网络协议,顾名思义就是非常安全的shell,主要用于计算机间加密传输。早期,互联网通信都是基于明文通信,一旦被截获,内容就暴露无遗。1995年,芬兰学者Tatu Ylonen设计了SSH协议,将登录信息全部加密,成为互联网安全的一个基本解决方案,迅速在全世界获得推广,目前已经成为Linux系统的标准配置。SSH的主要目的是用来取代传统的telnet 和 R 系列命令(rlogin, rsh, rexec 等)远程登录和远程执行命令的工具,实现对远程登录和远程执行命令加密,防止由于网络监听而密码泄露问题。

    需要指出的是,SSH协议是IETF(Internet Engineering Task Force)的Network Working Group所制定的一种协议。SSH 只是一种协议(规范),存在很多实现方式,既有商业实现,也有开源实现。

    ssh协议目前有SSH1和SSH2两个主流版本,SSH2协议兼容SSH1,强烈建议使用SSH2版本。目前实现SSH1和SSH2协议的主要软件有OpenSSH 和SSH Communications Security Corporation 公司的SSH Communications 软件。前者是OpenBSD组织开发的一款免费的SSH软件,后者是商业软件,因此在linux、FreeBSD、OpenBSD 、NetBSD等免费类UNIX系统种,通常都使用OpenSSH作为SSH协议的实现软件。

    因此,本文重点介绍一下OpenSSH的使用。需要注意的是OpenSSH 和 SSH Communications的登陆公钥/私钥的格式是不同的,如果想用SSH Communications产生的私钥/公钥对来登入到使用OpenSSH的linux系统需要对公钥/私钥进行格式转换。    

    OpenSSH 是一组用于安全地访问远程计算机的连接工具。 它可以作为 rlogin、 rsh rcp 以及 telnet 的直接替代品使用。 更进一步, 其他任何 TCP/IP 连接都可以通过 SSH 安全地进行隧道/转发。 OpenSSH 对所有的传输进行加密, 从而有效地阻止了窃听、 连接劫持, 以及其他网络级的攻击。

    在出现SSH之前,系统管理员需要登入远程服务器执行系统管理任务时,都是用telnet 或者 rlogin 来实现的,telnet协议采用明文密码传送,在传送过程中对数据也不加密,很容易被不怀好意的人在网络会话中窃取到传输的用户名/密码和数据。同样,在SSH工具出现之前R系列命令也很流行(由于这些命令都以字母r开头,故把这些命令合称为R系列命令R是remote的意思),比如rexec是用来执行远程服务器上的命令的,和telnet的区别是telnet需要先登陆远程服务器再实行相关的命令,而R系列命令可以把登陆和执行命令并登出系统的操作整合在一起。这样就不需要为在远程服务器上执行一个命令而特地登陆服务器了。

    SSH是一种加密协议,不仅在登陆过程中对密码进行加密传送,而且对登陆后执行的命令的数据也进行加密,这样即使别人在网络上监听并截获了你的数据包,他也看不到其中的内容。OpenSSH已经是目前大多数linux和BSD操作系统(甚至cygwin)的标准组件,因此关于如何安装OpenSSH本文就不再叙述了,如果不出意外,你的系统上必定已经安装好了OpenSSH。

SSH 服务器端:    

OpenSSH 软件包包含了以下程序:

 

sshd             -- SSH服务端程序

sftp-server  -- SFTP服务端程序(类似FTP,但提供数据加密的一种协议)

scp               -- 非交互式sftp-server的客户端,用来向服务器上传/下载文件,安全复制

sftp              -- 交互式sftp-server客户端,用法和ftp命令一样。

slogin          -- ssh的别名

ssh               -- SSH协议的客户端程序,用来登入远程系统或远程执行命令

ssh-add       --  SSH代理相关程序,用来向SSH代理添加dsa key

ssh-agent      -- ssh代理程序

ssh-keygen    -- ssh public key 生成器

SSH 客户端工具:

    ssh 客户端工具比较常用的有:

  • Windows(SecureCRT / Xshell / Putty) 

  • Linux (ssh)

 

    SSH最常用的使用方式是代替telnet进行远程登陆。不同于telnet的密码登陆,SSH还同时支持Publickey、Keybord Interactive、GSSAPI等多种登入方式,不像telnet那样只有输入系统密码一种途径。目前最常用的登陆方式还是传统的Password方式 和 Publickey方式登陆。

 

SSH提供两种方式的登录验证:

1、密码(口令)验证:以服务器中本地系统用户的登录名称,密码进行验证。

2、密钥对验证:要求提供相匹配的秘钥信息才能通过验证。通常先在客户机中创建一对密钥文件(公钥和私钥),然后将公钥文件放到服务器中的指定位置。

注意:当密码验证和私钥验证都启用时,服务器将优先使用密钥验证。

 

二、基本使用

1、用于代替 telnet, 进行远程登录。
# ssh user@host
2、如果bending用户名与远程主机用户名一致,登录时可以省略用户名。
# ssh host
3、ssh 协议默认端口 22,也就是缺省情况是连接远程主机的22号端口,使用 -p 参数可以指定端口号
# ssh -p 2222 user@host

4、ssh 远程执行命令
# ssh user@host 'ls -l /etc'
输入正确的密码后,ssh会链接远程服务器的sshd服务器程序,然后执行远程服务器上的 ls –l /etc 命令 ,并把输入结果传到本地服务器。相当于你先登陆到远程服务器,然后再实行命令ls –l /,最后再登出服务器。

三、中间人攻击

    SSH之所以能够保证安全,原因在于它采用了公钥加密。

    整个过程是这样的:

(1)远程主机收到用户的登录请求,把自己的公钥发给用户。

(2)用户使用这个公钥,将登录密码加密后,发送回来。

(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。

    这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。

    可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。

SSH协议是如何应对的呢?

如果你是第一次通过ssh登录远程主机,会出现下面的提示:

1
2
3
4
# ssh user@host
The authenticity of host 'host (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?

wKiom1b2kG3gEk01AACK7YPNUt8227.png

    这段话的意思是,无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?

    所谓"公钥指纹",是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。上例中是98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,再进行比较,就容易多了。

很自然的一个问题就是,用户怎么知道远程主机的公钥指纹应该是多少?回答是:没有好的办法,远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对。

    假定经过风险衡量以后,用户决定接受这个远程主机的公钥。

1
Are you sure you want to continue connecting (yes/no)? yes

系统会出现一句提示,表示host主机已经得到认可。

1
Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.

 

    当远程主机的公钥被接受以后,它就会被保存在用户home目录的  $HOME/.ssh/known_hosts 文件之中。下次再连接这台远程主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。

    出现“WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED 警告”无法建立ssh连接。如果远程系统重装过系统, ssh指纹已经改变,你需要把 .ssh 目录下的 know_hosts 文件中相应远程主机IP一致的指纹删除,再通过ssh登录一次回答 yes,重新认证一次方可登录。注意 .ssh 目录是以 "." 开头的隐藏目录,需要 # ls -a 参数才能看到。如果使用的windows ssh客户端工具,也有类似  Host Key Manager 管理的功能。

而且这个目录的权限必须是700,并且用户的home目录也不能给其他用户写权限,否则ssh服务器会拒绝登陆。如果发生不能登陆的问题,请察看服务器上的日志文件/var/log/secure。通常能很快找到不能登陆的原因。

    每个SSH用户都有自己的 known_hosts 文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts,  保存一些对所有用户都可信赖的远程主机的公钥。

 

四、公钥登录

 

    使用密码登录,每次都必须输入密码,感觉太浪费时间,而且非常麻烦。尤其是密码超级复杂,维护的服务器又比较多的情况下。好在SSH还提供了公钥(public key)登录,可以省去输入密码的步骤。

    所谓"公钥登录",原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。

    基于密钥的安全验证必须为用户自己创建一对密钥,并把共有的密钥放在需要访问的服务器上。当需要连接到SSH服务器上时,客户端软件就会向服务器发出请求,请求使用客户端的密钥进行安全验证。服务器收到请求之后,先在该用户的根目录下寻找共有密钥,然后把它和发送过来的公有密钥进行比较。如果两个密钥一致,服务器就用公有的密钥加密“质询”,并把它发送给客户端软件(putty,xshell等)。客户端收到质询之后,就可以用本地的私人密钥解密再把它发送给服务器,这种方式是相当安全的。

步骤:

1、在客户端生成一对密钥

2、将公钥传输至服务器端某用户的家目录下的 .ssh/authorized_keys 文件中(多个公钥需要进行追加)

3、测试登录 

 

在此之前,将自己服务器的公钥拷贝上远程服务器上,加添到~/.ssh/authorized_keys文件中。可以用ssh-keygen -t rsa 或者 ssh-keygen -t dsa命令生成公钥和私钥。这一点不难,最关键的是要留意远程服务器上的文件和目录的权限问题。

Make sure the permissions on the ~/.ssh directory and its contents are proper. When I first set up my ssh key auth, I didn't have the ~/.ssh folder properly set up, and it yelled at me.

  1. Your home directory ~ and your ~/.ssh directory on the remote machine must be writable only by you: rwx------ and rwxr-xr-x are fine, but rwxrwx--- is no good, even if you are the only user in your group (if you prefer numeric modes: 700 or 755, not 775).

  2. Your private key file (on the local machine) must be readable and writable only by you: rw-------, i.e. 600.

  3. Your ~/.ssh/authorized_keys file (on the remote machine) must be readable (at least 400), but you'll need it to be also writable (600) if you will add any more keys to it.

  4. Also, if SELinux is set to enforcing, you may need to run restorecon -R -v ~/.ssh (see e.g. Ubuntu bug 965663 and Debian bug #658675; this is patched in CentOS 6).

参考:http://unix.stackexchange.com/questions/36540/why-am-i-still-getting-a-password-prompt-with-ssh-with-public-key-authentication

 

生成私钥和公钥的方式有很多种, 下面分别介绍。

 因为puttygen生成的密钥有问题可能会出现:“Server refused our key”,最好使用XShell生成密钥或者在远程Linux VPS/服务器利用 ssh-keygen生成密钥。

===================  /var/log/secure

.ssh ,  authorized_keys 用户和组都是需要登录的用户。

 

权限很重要。搞了很久发现权限问题,key这东西对权限有很严格的限制。
登录端的 .ssh目录权限是  ssh-keygen自己生成的不要乱改
默认.ssh目录是700 , id_rsa 是600  不能多也不能少,如果有写的权限会导致 ssh认为这个文件不可靠,可能被改写。

被登录的机器 .ssh 目录是 700 ,至少不能有写的权限
.ssh 目录下的 authorized_keys 权限 600或644

====================

 

1、在Linux下通过 ssh-keygen生成密钥

    这种方法要求用户必须提供自己的公钥。如果没有现成的,可以直接用ssh-keygen生成一个:

第一步:生成密钥文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[zbj@web ~]# ssh-keygen -b 1024 -t dsa
Generating public/private dsa key pair.
#提示正在生成,如果选择4096长度,可能需要较长时间
Enter file in which to save the key (/root/.ssh/id_dsa): 
#询问把公钥和私钥放在那里,回车用默认位置即可
Enter passphrase (empty for no passphrase): 
#询问输入私钥密语,为了实现自动登陆,应该不要密语,直接回车
Enter same passphrase again: 
#再次提示输入密语,再次直接回车
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
#提示公钥和私钥已经存放在/root/.ssh/目录下
The key fingerprint is:
71:e5:cb:15:d3:8c:05:ed:05:84:85:32:ce:b1:31:ce zbj@web
#提示key的指纹
 
说明:
-b 1024 采用长度为1024字节的公钥/私钥对,最长4096字节,一般1024或2048就可以了,太长的话加密解密需要的时间也长。
-t dsa  采用dsa加密方式的公钥/私钥对,除了dsa还有rsa方式,rsa方式最短不能小于768字节长度。
 
 
1、在本地生成一对密钥文件(公钥和私钥)
# ssh-keygen
# 以上命令等价于 ssh-keygen -t rsa
# -t:指定密钥的类型,默认为SSH-2 的rsa类型;
 
[root@localhost ~]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase):          # 如果设置密码,通过密钥连接也需要输入密码
Enter same passphrase again: 
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:
35:dd:d8:49:05:be:e9:7e:89:b7:86:e2:96:17:a0:2b root@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
|              oo.|
|           . * . |
|          o o =  |
|         . o   o |
|        S . . o  |
|         .   o   |
|          . . = .|
|       E . + = +.|
|        . o.o +o.|
+-----------------+
 
[zbj@web ~]$ ls -l .ssh
total 8
-rw------- 1 zbj zbj 1675 Feb 14 14:29 id_rsa
-rw-r--r-- 1 zbj zbj  389 Feb 14 14:29 id_rsa.pub

    运行上面的命令以后,系统会出现一系列提示,可以一路回车。

特别说明,其中有一个问题是,要不要对私钥设置口令(passphrase),如果担心私钥的安全,这里可以设置一个(设置私钥口令的目的是防止私钥被盗用),但是设置之后,利用私钥连接也需要输入密码。

    运行结束以后,在 $HOME/.ssh/ 目录下,会新生成两个文件:id_rsa.pub 和 id_rsa。前者是你的公钥,后者是你的私钥。再一次强调用户自己的目录(~/.ssh)必须不能有其他人可写的权限, .ssh 目录的权限必须是 700, chmod 700 ~/.ssh 必须。否则ssh服务器会拒绝登录。

    产生的公钥/私钥文件在用户home目录的.ssh目录下,其中id_dsa.pub是公钥,把产生的公钥上传到需要登陆的服务器的对应用户目录的home目录的.ssh目录下,再一次强调用户自己的目录(home目录)必须不能有其他人可写的权限,.ssh目录的权限必须是700,即除了用户自己,其他人没有任何读写察看该目录的权限,否则ssh服务器会拒绝登陆。

    ssh服务器端默认的公钥文件是用户home目录下的.ssh目录下的authorized_keys文件,因此需要把产生的公钥以这个文件名放到服务器的~user/.ssh/目录下,这个文件中可以存放多个客户端的公钥文件,就好比一个大门上可以上很多锁,可以有不同的钥匙来尝试开锁,只要有一个锁被打开了,门就可以打开了。放到服务器上应该是这样子的:公钥必须是600权限,否则ssh服务器会拒绝用户登陆。

    sshd 服务器端默认的公钥文件是用户home目录下的.ssh目录下的 authorized_keys 文件,因此需要把产生的公钥以这个文件名放到服务器的 $HOME/.ssh/ 目录下,这个文件中可以存放多个客户端的公钥文件,就好比一个大门上可以上很多锁,可以有不同的钥匙来尝试开锁,只要有一个锁被打开了,门就可以打开了。~/.ssh/authorized_keys 必须是600权限,否则ssh服务器会拒绝用户登陆。chmod 600 ~/.ssh/authorized_keys

第二步:把生成的密钥文件上传到远程主机

这时再输入下面的命令,将生成的公钥传送到远程主机host上面对应用户home目录下的 .ssh 目录下:

1
2
3
2、将公钥上传到欲远程连接的主机上面
 
# ssh-copy-id user@host

    好了,经过以上两步之后,从此你再登录,就不需要输入密码了。此命令执行后,远程主机直接将用户的公钥保存在 ~/.ssh/authorized_keys 文件中。

 

如果还是不行,就打开远程主机的 /etc/ssh/sshd_config 这个文件,检查下面几行前面"#"注释是否取掉。

wKiom1VCEQvDzi0OAABfv8B_Mdw258.jpg

然后重新启动远程主机的sshd服务:

1
2
3
4
5
## RHEL / CentOS
# service sshd restart
 
## ubuntu
# /etc/init.d/ssh restart

 

2、通过 SecureCRT生成密钥

1、Tools - Create Public Key 【工具 - 创建公钥】

wKiom1VCHXKTHZ_iAAFR505y_2Y293.jpg

2、Select Key type:   RSA

wKioL1VCHtuhw4BKAADurSry1ko903.jpg

3、对私钥设置口令, 也可以不设置。【这一步中,通行短语可以不输入。但要求输入,登陆的时候会要求你输入通行短语。并修改Comment 相关信息,采用   个人账户名称@服务器信息 方式(可以所有的服务器都使用一个密钥对)】

wKiom1VCHXLhX3wcAAFXWp_hSrA062.jpg

4、设置密钥长度

wKioL1VCHtvjYn-UAAE8tbo_Bng308.jpg

5、关键,一定要选择 "OpenSSH Key format" , 为什么呢? 等一下再说,这和多种实现 key 格式不一致有关。

    这里选择生成的密钥使用 OpenSSH Key 格式。如果选择默认的格式,上传到服务器的时候需要执行格式转换的工作,需要通过命令行来连接的也需要通过securecrt来转换私钥为openssh格式,这里建议采用openssh key格式!

点击完成后会生成两个文件,默认是Identity和Identity.pub,其中Identity为私钥,Identity.pub为公钥。

wKiom1VCHXLwtKaUAAGT3KfXa_o410.jpg

6、上传 公钥 到远程服务器(文件传输工具: ssh-copy-id, scp, sftp,  lrzsz)

    通过 sftp, 或者 ftp(ASCII模式),lrzsz 把刚才创建生成的公钥(Identity.pub) 上传到远程服务器, $HOME/.ssh 目录下。如果此用户home目录没有 .ssh 目录,则手动创建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## 如果没有 .ssh 目录执行 mkdir .ssh 进行创建
# 在需要开启ssh连接的用户目录下建立 .ssh目录
# mkdir .ssh
# chmod 700 .ssh
# cd .ssh
# mv Identity.pub authorized_keys
# chmod 600 authorized_keys
 
## 如果有多个公钥需要保存,必须使用追加方式
# cat Identity.pub >> authorized_keys
 
# 如果密钥的格式不是OpenSSH的,需要进行转换
# ssh-keygen -i -f <公钥文件>  >> ./.ssh/authorized_keys  
# 转换为公钥为openssh能识别的公钥格式,转换后的文件名为authorized_keys,这是ssh的公钥文件) 
 
# ssh-keygen -i -f Identity.pub >> authorized_keys

7、编辑 sshd_config 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# vi /etc/sshd_config
 
Protocol 2 
ServerKeyBits 2048 
PermitRootLogin no  #禁止root登录而已,与本文无关,加上安全些 
  
#以下三行没什么要改的,把默认的#注释去掉就行了 
RSAAuthentication yes 
PubkeyAuthentication yes 
AuthorizedKeysFile    .ssh/authorized_keys 
  
PasswordAuthentication no   #初次试验的时候最好用yes,否则配置错误的话重启sshd后你就悲剧了,key 登陆成功之后,再改为 no 
PermitEmptyPasswords no 
 
# 在确定你的公钥加入到authorzed_keys后重启sshd服务
# /etc/init.d/sshd restart

8、通过SecureCRT 登录

    首先设置登录模式为PublicKey,并选择刚刚创建的公钥文件 Identity.pub。

右键要连接的服务器—会话属性, 在authentication选项中只勾选PublicKey或者将PublicKey选项提到首选,再选中它点击Properties。

 

wKiom1VCREKjDigQAAJGKP5OqqQ545.jpg

指定我们刚创建的私钥。

wKioL1VCRayTcHjOAAEvkCV72S8862.jpg

OK,Over...

如果登录不成功,请从下面几个方面查看:

  • 权限是否是600

  • 属主是否正确

  • 选择创建密钥的时候选择的是否是openssh,如果不是需要转换格式

 

3、通过 Xshell 生成密钥

使用密钥登录分为3步:
1、生成密钥(公钥与私钥);
2、放置公钥(Public Key)到服务器~/.ssh/authorized_key文件中;
3、配置ssh客户端使用密钥登录。    

Xshell是一款Windows下面功能强大的SSH客户端,能够按分类保存N多会话、支持Tab、支持多密钥管理等等,管理比较多的VPS/服务器使用XShell算是比较方便的,而且对于 home/school 是free的,推荐使用。

1、Tools

wKioL1VCJJWiUUP-AAIePdzKwKU145.jpg

wKiom1VCIyyBmE9qAAGbPzY-Jl8785.jpg

wKioL1VCJJaio5g_AAG8Yjeh8Jw513.jpg

wKiom1VCIy2Qcm9cAAFXZjPmZoY266.jpg

wKioL1VCJJaQaBFOAAJPVYDIdkw750.jpg

 

 

二、将密钥添加到远程Linux服务器

1、用winscp,sftp, lrzsz,将id_rsa.pub文件上传到/root/.ssh/下面(如果没有则创建此目录),并重命名为:authorized_keys(如果是在Linux服务器上生成的密钥直接执行:mv /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys),再执行:chmod 600 /root/.ssh/authorized_keys 修改权限。

 

2、修改/etc/ssh/sshd_config 文件,将RSAAuthentication 和 PubkeyAuthentication 后面的值都改成yes ,保存。

3、重启sshd服务,Debian/Ubuntu执行/etc/init.d/ssh restart ;CentOS执行:/etc/init.d/sshd restart

 

五、 ssh 配置文件 

sshd 默认配置文件为: /etc/ssh/sshd_config

配置文件中: 以# 空格开头的行为纯注释信息。 单以#开头的行是指令,表示默认配置

更详细信息: man  sshd_config

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
##SSH服务器监听的选项  
#修改监听的端口,可以增加入侵者探测系统是否运行了 sshd守护进程的难度。  
Port 30003   
#使用SSH V2协议  
Protocol 2  
#监听的地址为所有地址  
#ListenAdderss 0.0.0.0  
ListenAdderss 192.168.5.0/24
#禁止DNS反向解析  
UseDNS no  
# 密钥长度
ServerKeyBits 2048
   
##用户登录控制选项  
#是否允许root用户登录,如果允许用户使用root用户登录,那么黑客们可以针对root用户尝试暴力破解密码,给系统安全带来风险。  
PermitRootLogin no  
#是否允许空密码用户登录,允许使用空密码系统就像不设防的堡垒,任何安全措施都是一句空话。 
PermitEmptyPasswords no  
#登录验证时间(2分钟)  
LoginGraceTime 2m  
#最大重试次数  
MaxAuthTries 6  
#只允许user用户登录,与DenyUsers选项相反  
AllowUsers user1 user2  
# 禁止指定的 用户或组
DenyUsers apache
 
#注:Allow 和 Deny 可以组合使用,它们的处理顺序是:DenyUsers, AllowUsers, DenyGroups, AllowGroups
 
##登录验证方式  
#关闭密码验证  
PasswordAuthentication no  
 
#以下三行没什么要改的,把默认的#注释去掉就行了
RSAAuthentication yes
#启用秘钥验证  
PubkeyAuthentication yes  
#指定公钥数据库文件  
AuthorsizedKeysFile .ssh/authorized_keys

 

另外,限制登录设置主要是对hosts.allow与hosts.deny就行改动

  首先限制所有IP都无法连接,我们顺便将FTP的限制也加入其中。注意要想FTP限制起作用,需要修改配置中的tcp_wrappers=YES。

  vi /etc/hosts.deny

  sshd:ALL
  vsftpd:ALL

设定允许指定的IP地址连接:

  vi /etc/hosts.allow # xxx.xxx.xxx.表示网段
  sshd:192.168.1.
  vsftpd:192.168.1.

 

六、 最佳实践 

服务器安全第一条:启用尽可能少的服务.

服务器安全第二条:管好你的ssh.      

1)禁止root用户远程登录

 root是linux里的最高统帅了,就它官最大,可以在系统里畅通无阻.也就是因为这个原因,它是我们的重点保护对象.对于管理linux系统,一个最基本的建议就是:平时登陆和工作的时候都使用普通用户进行操作.在需要修改系统设置使用特级权限时,再切换到root用户(su  - root).这样可以最大限度的避免因为误操作造成对linux系统的破坏.另外因为root用户是每个linux系统里都内置的,恶意的黑客可能会拿它做用户名然后尝试用不同的密码登陆密码哟.所以还是自己新建一个帐号,这样用户名被猜中的机率就很低了,再禁止root用户登陆,想猜密码?先猜用户吧.

在sshd_config中修改如下就可以了:

      PermitRootLogin  no

2)禁止空密码登陆

再有就是空密码.一般来说linux系统都会内置很多帐号,而这些用户的密码我们是不知道的.谁知道哪天哪个linux的发行版,对其中的帐号设置空密码或者指定的密码呢?所以还是禁止为妙,省得夜长梦多.

在sshd_config这样修改:

      PermitEmptyPasswords  no

3)使用非默认端口,非22端口

  其实吧很多时候你的服务器被盯上,并不是有人特别跟你过不去.人家随机的用软件扫了一个ip段,而你的ip正好在里面.而人家的扫描规则就是:是否开启22端口.这个时候,如果你没有禁止root登陆,root的密码又是简单的123456或者000000,111111这些地球人都知道的密码的话,你的服务器不黑,谁的被黑?所以安全从简单的小事儿做起,你向前移动一小步,你的服务器安全就进步一大步.还等什么?先修改默认端口呗,打开sshd_config文件,修改成:

      Port 30003

  根据你的心情,port随机的选一个,除了你自己,鬼知道你当时选的哪个端口.再打开/var/log/secure,看下世界是不是一下子清静了?再也没有烦人的用不同的帐号和密码尝试登陆的日志了.这招百试不爽.

4)限制ssh监听的ip

  在服务器有多个ip的时候.设置ssh服务器只监听在指定的ip,未尝不是一个好办法.例如一组服务器中,肯定会组成内网和外网两个小的局域网.这时候只让不起眼的一两台机器的ssh服务监听到公网ip上.其它的机器ssh只监听内网ip,通过另外的一两台机器登陆进行管理,是不是很安全保守的做法呢?

在sshd_config中修改如下:

      ListenAddress 192.168.1.5

如上的写法,是ssh服务器只监听192.168.1.5这个ip.

 

5)使用的协议版本2: ssh v2

  ssh协议有两个版本.肯定v2要比v1安全高效的多了.ssh服务器默认会接受两种协议的连接.为了保证服务器的安全,咱们可以定义服务器只使用v2:

在sshd_config中修改如下:

      Protocol 2

6)禁用密码登陆,推荐使用密钥登录,并且私钥使用强密码加密

  其实经过前面几步简单的设置,个人认为ssh服务器的安全已经有了一个质的提高.但是在不使用其它复杂的手段的情况下,还有一些加固的小技巧,例如这一条:禁止使用密码登陆.什么?是不是写错了,或者弄迷糊了?ssh服务器竟然要禁止使用密码登陆?那怎么管理服务器呢?当然还是用ssh啦.ssh服务器不单支持密码认证,还支持通过key的认证方式,而且是默认的哟.关于怎样生成key的方法参见:<<使ssh不用输入密码>>

在sshd_config中修改如下:

      PasswordAuthentication no

  经过这点小的改动,你的ssh服务绝对又是一个质的提升.能够拿到你的私key,又知道服务器登陆的用户名和端口,这绝对不是一件简单的事儿吧.

7)限制连接IP,仅保证有限的机器能够远程访问

  现在再拿出最后一招杀手锏:限制ssh服务连接的ip.我们前面提到一组服务器我们只留一两台机器可以远程访问.这样这两台机器的安全又成了重中之重.怎样再保证一下这两台机器的安全呢?我们可以限制连接这两台机器的ip.例如:这两台机器只允许公司的出口ip进行访问.这样就再次提高了服务器的安全系数.想想如果有一个黑客,能够进入你们公司的办公网络,能够拿到你的私key,又能知道只有你才知道的服务器的用户名和登陆的端口,以及登陆的方式,如果有这样的牛X的黑客,还有什么好防的呢?因为防不胜防啊.扯远了,看下限制ip的做法:

      在/etc/hosts.allow输入  

      sshd:192.168.1.5:allow(其中192.168.1.5是你要允许登陆ssh的ip,或者是一个网段192.168.1.0/24)  

      在/etc/hosts.deny输入

      sshd:ALL(表示除了hosts.allow中允许的,其他的ip拒绝登陆ssh)  

      呵呵,这是传统的做法,因为开了防火墙所以笔者更喜欢直接在防火墙上做设置:)

使用 iptables 设置 ssh 服务安全访问策略。

8) 日志

记录好日志,经常做日志分析。 

用户登录成功日志: /var/log/wtmp  , 使用 # last 命令查看

用户登录失败日志: /var/log/btmp , 使用 # lastb 命令查看

查看所有用户上次登录情况: 使用  #lastlog [-u User]

 

关于ssh安全的其它做法:

  令牌: 笔者的哥们所在的游戏公司,专门为了服务器的登陆开发了一个程序.所有的服务器统一认证.密码放在数据库里,当你想登陆的时候,先访问一个网页,验证完信息以后会给你的手机发一条短信告诉你登陆的密码.而且会告诉你一分钟内有效,过时重取,哈哈,除了数据库自己,谁也不知道密码是多少,是不是很专业呢?

    动态ssh: 据说有这么一种做法,在服务器上安装另外一个程序,当然也是开源的.那个程序会打开一个你指定的端口,而默认的时候ssh服务是关闭的.当你需要登陆服务器的时候.你先telnet一下,你的ip和你指定的先前那个程序所监听的端口,那个程序就会帮你把ssh服务打开,然后你就可以进行正常的登陆操作了.是不是也很专业呢?

 

ssh 最佳实践:

1
2
3
4
5
6
7
8
9
10
11
12
13
Port 30003
ListenAddress 192.168.1.5
Protocol 2
 
#白名单
AllowUsers user1 user2
#黑名单
denyUser user3 user4
 
PasswordAuthentication no
PermitEmptyPasswords no
PermitRootLogin  no
UseDNS no

脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
 
# 配置sshd的参数
/bin/cp  /etc/ssh/sshd_config   /etc/ssh/sshd_config.bak.$(date +"%Y-%m-%d-%H-%m-%S")
 
/bin/sed -i 's/#Port 22/Port 30003/g'  /etc/ssh/sshd_config
/bin/sed -i 's/#LogLevel INFO/LogLevel VERBOSE/g'  /etc/ssh/sshd_config
/bin/sed -i "s/PasswordAuthentication yes/PasswordAuthentication no/g"  /etc/ssh/sshd_config
/bin/sed -i "s/#PermitEmptyPasswords no/PermitEmptyPasswords no/g"  /etc/ssh/sshd_config
/bin/sed -i "s/#PermitRootLogin yes/PermitRootLogin no/g"  /etc/ssh/sshd_config
/bin/sed -i "s/#UseDNS yes/UseDNS no/" /etc/ssh/sshd_config
 
/sbin/service sshd reload

 

 

http://blog.lizhigang.net/archives/249

http://blog.chinaunix.net/uid-20639775-id-3207171.html

http://www.ibm.com/developerworks/cn/aix/library/au-sshsecurity/

http://rainbird.blog.51cto.com/211214/247387/

http://www.aiezu.com/system/linux/xshell_ssh_public-key_login.html

http://www.laozuo.org/2784.html

http://zhaochj.blog.51cto.com/368705/1602279

(原文地址:http://skypegnu1.blog.51cto.com/8991766/1641064

 

posted @ 2017-05-23 14:05  HelloSUN  阅读(1099)  评论(0编辑  收藏  举报