ssh服务认证类型介绍
从SSH客户端来看,SSH服务主要提供两种级别的安全验证,具体级别如下:
基于口令的安全验证:
基于口令的安全验证的方式就是大家一直在用的,只要知道服务器的SSH连接账号和口令,应用服务器的IP及开放的端口,默认为22,就可以通过SSH客户端登录到这台远程主机。此时,联机过程中所有传输的数据都是加密的。
基于口令的我们可以通过expect,pssh,sshpass实现批量管理。
期中集群:一键搭建及优化50台服务器集群
基于密钥的安全验证:
基于密钥的安全验证方式是指,需要依靠密钥,也就是必须事先建立一堆密钥对,然后把公用密钥(Public key)放到ssh的客户端或对应的客户端服务器上。
此时,如果要想连接到这个带有公用密钥的SSH服务器,客户端SSH软件或者客户端服务器就会向SSH服务器发出请求,请求用联机的用户密钥进行安全验证。SSH服务器收到请求后,会先在该SSH服务器上连接的用户的家目录下寻找放上去的对应用户的公用密钥,然后把它和连接的SSH客户端发送过来的公用密钥进行比较。如果两个密钥一致,SSH服务器就用公用密钥加密“质询”(challenge)并把它发送给SSH客户端。
SSH客户端收到“质询”之后,就可以用自己的私钥解密,再把它发送给SSH服务器。使用这种方式,需要知道联机用户的密钥文件,与第一种基于口令验证的方式相比,第二种
SSH批量管理分发项目
1)为所有用户创建用户及密码
useradd oldgirl
echo "123456"|passwd --stdin oldgirl
id oldgirl
su - oldgirl
2)管理服务器上生成密钥
法一:
ssh-keygen -t dsa (不断回车)
Generating public/private dsa key pair.
Enter file in which to save the key (/home/oldgirl/.ssh/id_dsa): Created directory ‘/home/oldgirl/.ssh‘.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/oldgirl/.ssh/id_dsa. (私钥)
Your public key has been saved in /home/oldgirl/.ssh/id_dsa.pub. (公钥)
The key fingerprint is:
e0:eb:3c:a3:5d:95:b6:9d:b3:87:28:39:7f:23:96:56 oldgirl@m01
The key‘s randomart image is:
+--[ DSA 1024]----+
| |
| |
| . |
| . . . |
| . S + |
| . o oE. |
| . ...++. |
| +o.+ * +o. |
| ..+o *.o.o |
+-----------------+
法二:
ssh-keygen -t dsa -P ‘‘ -f ~/.ssh/id_dsa >/dev/null 2>&1
ll .ssh/
总用量 12
-rw------- 1 oldgirl oldgirl 601 1月 26 18:55 authorized_keys
-rw------- 1 oldgirl oldgirl 668 1月 26 19:11 id_dsa
-rw-r--r-- 1 oldgirl oldgirl 603 1月 26 19:11 id_dsa.pub
查看创建好的公钥和私钥
[[email protected] ~]$ ll .ssh/
总用量 8
-rw------- 1 oldgirl oldgirl 668 1月 26 18:03 id_dsa (钥匙 私钥)
-rw-r--r-- 1 oldgirl oldgirl 601 1月 26 18:03 id_dsa.pub (锁 公钥)
3)m01分发公钥
ssh默认22端口
[[email protected] ~]$ ssh-copy-id -i .ssh/id_dsa.pub [email protected]172.16.1.41
[email protected]172.16.1.41‘s password:
Now try logging into the machine, with "ssh ‘[email protected]‘", and check in:
.ssh/authorized_keys
(到41上就改名了,因为配置文件里
[[email protected] ~]# grep authorized_keys /etc/ssh/sshd_config
#AuthorizedKeysFile .ssh/authorized_keys
ssh配置文件里默认就是这个名字)
to make sure we haven‘t added extra keys that you weren‘t expecting.
更改过的ssh端口
ssh-copy-id -i .ssh/id_dsa.pub "-p 52113 [email protected]"
4)校验结果:查看各服务器上的IP
ssh -p52113 [email protected]172.16.1.31 /sbin/ifconfig eth0
ssh -p52113 [email protected]172.16.1.8 /sbin/ifconfig eth0
ssh -p52113 [email protected]172.16.1.41 /sbin/ifconfig eth0
成功标志!连接所有的机器,不提示密码了。
5)最简单的批量管理之查看IP
vim view_ip.sh
ssh -p52113 [email protected]172.16.1.31 /sbin/ifconfig eth0
ssh -p52113 [email protected]172.16.1.8 /sbin/ifconfig eth0
ssh -p52113 [email protected]172.16.1.41 /sbin/ifconfig eth0
企业里实现ssh方案:3种
http://study.oldboyedu.com/classModule/video/179199/182281/630896/0/0
1)直接root ssh key. 条件:允许root ssh登录
2)sudo提权实现没有权限用户拷贝。 每台机器上配置sudoers echo "oldgirl ALL= NOPASSWD: /usr/bin/rsync" >>/etc/sudoers visudo -c
scp -P52113 hosts [email protected]:~
远程sudo:-t参数
ssh -p52113 -t [email protected] sudo rsync ~/hosts /etc/hosts
3)利用suid实现没有权限用户拷贝。(做思维扩展了解) 172.16.1.31:上做一个suid的授权 chmod u+s which rsync
m01服务器上 scp -P52113 hosts [email protected]:~ ssh -p52113 [email protected] rsync ~/hosts /etc/hosts (进行覆盖)
4)批量分发覆盖/etc/hosts文件。 vim fenfa_file.sh
scp -P52113 hosts [email protected]172.16.1.31:~
ssh -p52113 -t [email protected]172.16.1.31 sudo rsync ~/hosts /etc/hosts
scp -P52113 hosts [email protected]172.16.1.41:~
ssh -p52113 -t [email protected]172.16.1.41 sudo rsync ~/hosts /etc/hosts
scp -P52113 hosts [email protected]172.16.1.8:~
ssh -p52113 -t [email protected]172.16.1.8 sudo rsync ~/hosts /etc/hosts
然后查看客户端是否已经修改。已修改表示成功。
5)ssh隧道模式
rsync -avz hosts -e ‘ssh -p 52113‘ oldgirl@172.16.1.41:~
6)自动化脚本
vim scripts/fenfa_file1.sh
#!/bin/sh
. /etc/init.d/functions
for n in 8 31 41
do
scp -P52113 ~/hosts [email protected]172.16.1.${n}:~ >/dev/null 2>&1 && ssh -p52113 -t [email protected]172.16.1.${n} sudo rsync ~/hosts /etc/hosts >/dev/null 2>&1
if [ $? -eq 0 ];then
action "fenfa hosts 172.16.1.$n" /bin/true
else
aciton "fenfa hosts 172.16.1.$n" /bin/false
fi
done
结果:
[[email protected] ~]$ sh scripts/fenfa_file1.sh
fenfa hosts 172.16.1.8 [确定]
fenfa hosts 172.16.1.31 [确定]
fenfa hosts 172.16.1.41 [确定]
优化(在命令行即可填写源文件目录 及到目的地目录)
[[email protected] ~]$ cat scripts/fenfa_file2.sh
#!/bin/sh
if [ $# -ne 2 ];then
echo "USACE:/bin/sh $0 ARG1 ARG2"
exit 1
fi
. /etc/init.d/functions
for n in 8 31 41
do
scp -P52113 ~/$1 [email protected]172.16.1.${n}:~ >/dev/null 2>&1 && ssh -p52113 -t [email protected]172.16.1.${n} sudo rsync ~/$1 $2 >/dev/null 2>&1
if [ $? -eq 0 ];then
action "fenfa hosts 172.16.1.$n" /bin/true
else
action "fenfa hosts 172.16.1.$n" /bin/false
fi
done
[[email protected] ~]$ sh scripts/fenfa_file2.sh mo1.txt /opt
fenfa hosts 172.16.1.8 [确定]
fenfa hosts 172.16.1.31 [确定]
fenfa hosts 172.16.1.41 [确定]
做一个可以加参数既可以管理所有服务器
[[email protected] ~]$ cat scripts/view_ip.sh
#!/bin/sh
if [ $# -ne 1 ];then
echo "USAGE:/bin/sh $0 ARG1"
exit 1
fi
for n in 8 31 41
do
echo ===========172.16.1.$n===========
ssh -p52113 [email protected]172.16.1.$n "$1"
done
[[email protected] ~]$ sh scripts/view_ip.sh
USAGE:/bin/sh scripts/view_ip.sh ARG1
[[email protected] ~]$ sh scripts/view_ip.sh "/sbin/ifconfig eth0"
===========172.16.1.8===========
eth0 Link encap:Ethernet HWaddr 00:0C:29:0A:9A:09
inet addr:10.0.0.8 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe0a:9a09/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:5454 errors:0 dropped:0 overruns:0 frame:0
TX packets:2994 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:5269705 (5.0 MiB) TX bytes:259828 (253.7 KiB)
===========172.16.1.31===========
eth0 Link encap:Ethernet HWaddr 00:0C:29:9A:3B:9B
inet addr:10.0.0.31 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe9a:3b9b/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1550 errors:0 dropped:0 overruns:0 frame:0
TX packets:998 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:147840 (144.3 KiB) TX bytes:150446 (146.9 KiB)
===========172.16.1.41===========
eth0 Link encap:Ethernet HWaddr 00:0C:29:C3:10:CC
inet addr:10.0.0.41 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fec3:10cc/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1146 errors:0 dropped:0 overruns:0 frame:0
TX packets:736 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:120748 (117.9 KiB) TX bytes:84306 (82.3 KiB)
[[email protected] ~]$ sh scripts/view_ip.sh "cat /etc/redhat-release"
===========172.16.1.8===========
CentOS release 6.8 (Final)
===========172.16.1.31===========
CentOS release 6.8 (Final)
===========172.16.1.41===========
CentOS release 6.8 (Final)
SSH批量分发与管理方案小结:
1)利用root做ssh key验证。
优点:简单,易用
缺点:安全性差,同时无法禁止root远程连接这个功能。
企业应用:80%的中小企业。
2)利用普通用户如oldgirl来做
思路是先把分发的文件拷贝到服务器用户家目录,然后sudo提权拷贝分发的文件到远程服务器的对应权限目录。
优点:安全,无需停止root远程连接这个功能。
缺点:配置比较复杂。
3)拓展:同方案2,知识不用sudo,而是设置suid对固定命令提权。
优点:相对安全。
缺点:复杂,安全性差,任何人都可以处理带有suid权限的命令。
建议:
1)追求简单,选1.
2)追求安全,选2.
有能力可以玩:puppet,saltstack.
suid:普通用户运行程序,没权限时也可以suid,然后运行,必须是编译好的程序命令。
重要安全思想:
不管用什么方法,我们一定要管理好中心分发服务器,因为他的权限很大,很重要,
1)一定要取消中心分发服务器的外网IP。
2)开启防火墙禁止SSH对外用户登录,并仅给某一台后端无外网机器访问,然后这台后端的服务器依然没有外网IP,并且仅能通过VPN连接,这样中心分发服务器就相对安全了。
企业自动化管理方案:
1)最简单最常用ssh key,功能最强大的,一般中小型企业会用,50-100台以下。
2)sina cfengine/puppet 较早的批量管理工具,复杂,笨重。
3)门户级别比较流行的,puppet批量管理工具,复杂,笨重。
4)saltstack批量管理工具,特点:简单,功能强大(配置复杂),赶集网,小米,一些CDN 公司。
5)http+cron
批量管理路线:sshkey--->cfengine--->puppet--->saltstack/ansible
非交互式生成密钥及实现批量管理(非交互式工具:expect,SSHpass,pssh)
管理机安装expect
yum install expect -y
rpm -qa expect
expect 也有可以生成随机数字的命令
mkpasswd -l(指定长度)
[[email protected]m01 ~]# mkpasswd -l 15
iwib/yyCMlg5hm2
1)为所有用户创建用户及密码
useradd oldgirl888
echo "123456"|passwd --stdin oldgirl888
id oldgirl888
su - oldgirl888
2)管理服务器上生成密钥
ssh-keygen -t dsa -P ‘‘ -f ~/.ssh/id_dsa >/dev/null 2>&1
3)分发公钥
ssh-copy-id -i .ssh/id_dsa.pub "-p 52113 [email protected]"
[[email protected] ~]$ expect fenfa_sshke.exp
usage: expect fenfa_sshkey.exp file host
创建exxpect脚本
vi fenfa_sshke.exp
#!/usr/bin/expect
if { $argc != 2 } {
send_user "usage: expect fenfa_sshkey.exp file host\n"
exit
}
#define var
set file [lindex $argv 0]
set host [lindex $argv 1]
set password "123456"
#spawn scp /etc/hosts [email protected]:/etc/hosts
#spawn scp -P52113 $file [email protected]$host:$dir
spawn ssh-copy-id -i $file "-p 52113 [email protected]$host"
expect {
"yes/no" {send "yes\r";exp_continue}
"*password" {send "$password\r"}
}
expect eof
exit -onexit {
send_user "Oldboy say good bye to you!\n"
}
#script usage
#expect oldboy-6.exp file host dir
#example
#expect fenfa_sshkey.exp file host dir
#expect oldboy-6.exp /etc/hosts 10.0.0.41:~
测试expect脚本免输入创建密钥对
[[email protected] ~]$ expect fenfa_sshke.exp .ssh/id_dsa.pub 172.16.1.31
spawn ssh-copy-id -i .ssh/id_dsa.pub -p 52113 [email protected]172.16.1.31
The authenticity of host ‘[172.16.1.31]:52113 ([172.16.1.31]:52113)‘ can‘t be established.
RSA key fingerprint is 87:9c:42:c6:7a:78:72:d4:57:55:21:38:74:e0:8e:b6.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘[172.16.1.31]:52113‘ (RSA) to the list of known hosts.
[email protected]172.16.1.31‘s password:
Now try logging into the machine, with "ssh ‘-p 52113 [email protected]‘", and check in:
.ssh/authorized_keys
to make sure we haven‘t added extra keys that you weren‘t expecting.
Oldboy say good bye to you!
客户端已收到)[[email protected] ~]$ ls .ssh
authorized_keys
测试查询一下ip)[[email protected] ~]$ ssh -p52113 [email protected] /sbin/ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:0C:29:9A:3B:9B
inet addr:10.0.0.31 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe9a:3b9b/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1824 errors:0 dropped:0 overruns:0 frame:0
TX packets:1213 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:176048 (171.9 KiB) TX bytes:169774 (165.7 KiB)
批量自动分发公钥到服务器上脚本
[[email protected] scripts]$ vim fenfa_sshke.sh
#!/bin/sh
. /etc/init.d/functions
for ip in 8 31 41
do
expect fenfa_sshke.exp ~/.ssh/id_dsa.pub 172.16.1.$ip >/dev/null 2>&1
if [ $? -eq 0 ];then
action "$ip" /bin/true
else
action "$ip" /bin/false
fi
done
执行自动分发公钥的脚本测试
[[email protected] scripts]$ sh fenfa_sshke.sh
8 [确定]
31 [失败] 因为前面测试已传送
41 [确定]
一键给多台服务器安装http服务:
useradd gongli888
echo "123456"|passwd --stdin gongli888
id gongli888
#配置suduers
#每台机器上配置sudoers
echo "gongli888 ALL= NOPASSWD: ALL" >>/etc/sudoers
visudo -c
su - gongli888
创建自动连接到其他服务器上的时候填写yes和密码的exxpect脚本
创建了两个模块,可以快速指定源文件和目标ip.可以通过 expect ~/scripts/fenfa_sshke.exp ~/.ssh/id_dsa.pub 172.16.1.$ 来将创建好的密钥发给172.16.1.$
vim fenfa_sshke.exp
#!/usr/bin/expect
if { $argc != 2 } {
send_user "usage: expect fenfa_sshkey.exp file host\n"
exit
}
#define var
set file [lindex $argv 0]
set host [lindex $argv 1]
set password "123456"
#spawn scp /etc/hosts [email protected]:/etc/hosts
#spawn scp -P52113 $file [email protected]$host:$dir
spawn ssh-copy-id -i $file "-p 52113 [email protected]$host"
expect {
"yes/no" {send "yes\r";exp_continue}
"*password" {send "$password\r"}
}
expect eof
exit -onexit {
send_user "Oldboy say good bye to you!\n"
}
#script usage
#expect oldboy-6.exp file host dir
#example
#expect fenfa_sshkey.exp file host dir
#expect oldboy-6.exp /etc/hosts 10.0.0.41:~
创建密钥对,并实现可以远程安装等操作
vim auto_deploy.sh
#!/bin/sh
. /etc/init.d/functions
#1)product key pai
ssh-keygen -t dsa -P ‘‘ -f ~/.ssh/id_dsa >/dev/null 2>&1
if [ $? -eq 0 ];then
action "create dsa $ip" /bin/true
else
action "create dsa $ip" /bin/false
exit 1
fi
#2)dis pub key
for ip in 8 31 41
do
expect ~/scripts/fenfa_sshke.exp ~/.ssh/id_dsa.pub 172.16.1.$ip >/dev/null 2>&1
if [ $? -eq 0 ];then
action "$ip" /bin/true
else
action "$ip" /bin/false
fi
done
#3)dis fenfa scripts
for n in 8 31 41
do
scp -P 52113 -rp ~/scripts [email protected]172.16.1.$n:~
done
#4)install service
for m in 8 31 41
do
ssh -t -p 52113 [email protected]172.16.1.$m sudo /bin/bash ~/scripts/install.sh
done