一、什么是 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
)?
|
这段话的意思是,无法确认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.
-
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).
-
Your private key file (on the local machine) must be readable and writable only by you: rw-------, i.e. 600.
-
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.
-
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 这个文件,检查下面几行前面"#"注释是否取掉。
然后重新启动远程主机的sshd服务:
1
2
3
4
5
|
## RHEL / CentOS
# service sshd restart
## ubuntu
# /etc/init.d/ssh restart
|
2、通过 SecureCRT生成密钥
1、Tools - Create Public Key 【工具 - 创建公钥】
2、Select Key type: RSA
3、对私钥设置口令, 也可以不设置。【这一步中,通行短语可以不输入。但要求输入,登陆的时候会要求你输入通行短语。并修改Comment 相关信息,采用 个人账户名称@服务器信息 方式(可以所有的服务器都使用一个密钥对)】
4、设置密钥长度
5、关键,一定要选择 "OpenSSH Key format" , 为什么呢? 等一下再说,这和多种实现 key 格式不一致有关。
这里选择生成的密钥使用 OpenSSH Key 格式。如果选择默认的格式,上传到服务器的时候需要执行格式转换的工作,需要通过命令行来连接的也需要通过securecrt来转换私钥为openssh格式,这里建议采用openssh key格式!
点击完成后会生成两个文件,默认是Identity和Identity.pub,其中Identity为私钥,Identity.pub为公钥。
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。
指定我们刚创建的私钥。
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
二、将密钥添加到远程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)