Linux学习29-SSH服务

SSH

1. 概述

  • ssh: (secure shell)
    SSH 为建立在应用层基础上的安全协议,端口号为22/tcp

  • 功能

    1. 通过使用SSH,可以把所有传输的数据进行加密,可以有效防止类似Telnet安全验证缺陷带来的中间人攻击,而且也能够防止DNS欺骗和IP欺骗。
    2. 使用SSH,还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。
    3. SSH有很多功能,它既可以代替Telnet,又可以为FTP、PoP、甚至为PPP提供一个安全的"通道"
  • 具体的软件实现:

    1. OpenSSH: ssh协议的开源实现,CentOS默认安装
    2. dropbear:另一个开源工具,需要安装
  • SSH协议版本

    1. v1: 基于CRC-32做MAC,不安全;man-in-middle
    2. v2:双方主机协议选择安全的MAC方式
      基于DH算法做密钥交换,基于RSA或DSA实现身份认证
  • 用户登录认证:

    1. 基于password
      登录到远程主机,验证帐号和口令,传输的数据都会被加密,但是不能保证正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“中间人”这种方式的攻击
    2. 基于key
      需要远程登录用户创建一对密钥,将公钥放到目标服务器上,客户向服务器发出请求,请求用你的密匙进行安全验证。服务器收到请求之后,先在该服务器上你的主目录下寻找你的公用密匙,然后把它和你发送过来的公用密匙进行比较。如果两个密匙一致,服务器就用公用密匙加密“质询”(challenge)并把它发送给客户端软件。客户端软件收到“质询”之后就可以用你的私人密匙解密再把它发送给服务器,此方法可有效避免中间人攻击。

2. Openssh软件组成

2.1. 软件概述

  • 相关包
    openssh
    openssh-clients
    openssh-server
  • 工具
    基于C/S结构:client/server
    1. 客户端(Client)
      ssh, scp, sftp,slogin
    2. 服务器端(Server)
      sshd
    3. Windows客户端
      xshell, putty, securecrt, sshsecureshellclient

2.2 ssh客户端

  • 配置文件
    /etc/ssh/ssh_config
  • 格式
    ssh [user@]host [COMMAND]
    ssh [-l user] host [COMMAND]
  • 选项
    -p port:远程服务器监听的端口,通常实际应用中,需要更改为非标准端口,示例2
    -b:指定连接的源IP,示例3
    -v:调试模式
    -C:压缩方式
    -X:支持x11转发,可以在客户端上运行服务器端的图形工具,示例4
    底层跑X协议, X 协议(基于tcp/ip协议)允许跨网络,在不同计算机显示器上显示内容。
    -t:强制伪tty分配
    应用场景,服务器A只允许B连接,C可以连接B,C想要连接A,通过B来跳转
    ssh -t remoteserver1 ssh -t remoteserver2 ssh remoteserver2

示例1:连接格式

'1. 连接目标主机以v9用户登录'
[root@hai7 ~]$ssh [email protected]   
'2. 连接目标主机执行命令后退回'
[root@hai7 ~]$ssh [email protected] 'cat /etc/centos-release' 
'3. 第二种格式,效果相同'
[root@hai7 ~]$ssh -l v9 172.20.50.201  
'4. 简写方式默认以root方式连接 '
[root@hai7 ~]$ssh 172.20.50.201 

示例2:更改默认端口,修改服务器配置文件vim /etc/ssh/sshd_config如下项

'1. 修改配置文件'
[root@hai7 ~]$vim /etc/ssh/sshd_config
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22       <==去掉注释,更改端口
Port 10086     <==修改后效果
'2. 重新读入一次,新端口生效'
[root@hai7 ~]$systemctl reload sshd
'3. 更改后再远程连接需要加上-p选项'
[root@hai7 ~]$ssh [email protected]  -p 10086 
'4. 如果服务器端口都更改为10086,可以考虑将客户端默认连接端口改为10086就不需要每次加-p选项'
[root@hai7 ~]$vim /etc/ssh/ssh_config
#   Port 22     <==去掉注释,修改为10086
#   Protocol 2

示例3:指定客户端ip去链接目标地址

[root@hai7 ~]$ssh -b 172.20.50.100  192.168.121.66

示例4:在CentOS6图形界面上使用终端连接CentOS7(172.20.121.4),打开7上的图形工具nm-connection-editor

'1. 使用ssh直接连接,显示如下,打不开'
[root@os6  ~]$ssh 172.20.121.4
[root@os7  ~]$nm-connection-editor 
(nm-connection-editor:11120): Gtk-WARNING **: cannot open display:
'2. 想要远程打开目标服务器的图形工具,需要配合选项-X,例如远程安装oracle数据库,此时CentOS6充当X协议的服务器(server),CentOS7充当X协议的客户端(client)'
[root@os6  ~]$ssh  -X 172.20.121.4

示例5:在Windows环境管理Linux系统

  1. 在Windows上运行xmanager enterprise中的xstart, 如下图所示填写对应项,点击运行,就可以连接到目标主机桌面
    Linux学习29-SSH服务_第1张图片
  2. 退出,点击左上角的system,弹出子菜单,选择log out root
    Linux学习29-SSH服务_第2张图片

示例6:服务器A只允许B连接,C可以连接B,C想要连接A,通过B来跳转,期间需要输入输入2次口令,分别为B、A的密码

ssh   ssh -t remoteserverB  ssh -t remoteserverA

3. 安全验证

3.1用户/口令

Linux学习29-SSH服务_第3张图片

  1. 客户端发起ssh请求,服务器会把自己的公钥发送给用户,用户通过服务器提供的公钥对应算法哈希值,确认连接地址是否正确。
[root@localhost  ~]$ssh 172.20.50.201
The authenticity of host '172.20.50.201 (172.20.50.201)' can't be established.
ECDSA key fingerprint is SHA256:GFmkHQ3S85LfqblqjPjOF3InnScqL9HIS+UZw3MDzro.
"通过SHA256哈希运算服务器的公钥"
ECDSA key fingerprint is MD5:21:bb:99:04:c1:bd:9f:db:60:b1:5d:7d:79:0a:d5:ed.
"通过MD5哈希运算服务器的公钥"
Are you sure you want to continue connecting (yes/no)? 
获取公钥哈希值
'CentOS7为例,服务器端找到以ssh_host_ecdsa_key.pub,拷贝副本'
[root@hai7 ssh]$cp ssh_host_ecdsa_key.pub ssh_host_ecdsa_key.pub1
'将其上下注释去掉,base64 -d还原文本,生成文件f1'
[root@hai7 /etc/ssh]$base64 -d  ssh_host_ecdsa_key.pub1>f1
'运算得到哈希值'
[root@hai7 /etc/ssh]$md5sum f1 
21bb9904c1bd9fdb60b15d7d790ad5ed  f1
  1. 用户确认无误后,输入y,验证登录密码,系统会根据服务器发来的公钥对密码进行加密
  2. 加密后的信息回传给服务器,服务器用自己的私钥解密,如果密码正确,则用户登录成

3.2 基于密钥的登录方式

Linux学习29-SSH服务_第4张图片

  • 验证原理
  1. 首先在客户端生成一对密钥(ssh-keygen)
  2. 并将客户端的公钥ssh-copy-id 拷贝到服务端
  3. 当客户端再次发送一个连接请求,包括ip、用户名
  4. 服务端得到客户端的请求后,会到authorized_keys中查找,如果有响应的IP和用户,就会随机生成一个字符串,例如:acdf
  5. 服务端将使用客户端拷贝过来的公钥进行加密,然后发送给客户端
  6. 得到服务端发来的消息后,客户端会使用私钥进行解密,然后将解密后的字符串发送给服务端
  7. 服务端接受到客户端发来的字符串后,跟之前的字符串进行对比,如果一致,就允许免密码登录
  • 实现验证
  1. 在客户端生成密钥对
    1. 格式:ssh-keygen -t rsa [-p ‘’] [-f “~/.ssh/id_rsa"]
    2. 选项:
      -t:指定算法rsa、dsa默认为rsa 生成的密钥
      -P:提供旧密码
      -p:要求改变某私钥文件的密语而不重建私钥。程序将提示输入私钥文件名、原来的密语、以及两次输入新密语
      -f:指定密钥保存路径
      -N:指定私钥密码
      -b bits:
      指定密钥长度。对于RSA密钥,最小要求768位,默认是2048位。DSA密钥必须恰好是1024位(FIPS 186-2 标准的要求)
[root@hai7 ~]$ssh-keygen  -t  rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
'将生成的密钥保存至,默认为/root/.ssh/id_rsa'
Enter passphrase (empty for no passphrase): 
'为密钥加密'
[root@hai7 ~/.ssh]$ll -a   
-rw-------   1 root root 1675 Sep 17 20:41 id_rsa
'生成的私钥'
-rw-r--r--   1 root root  393 Sep 17 20:41 id_rsa.pub
'生成的公钥'
  1. 把公钥文件传输至远程服务器对应用户的家目录下的.ssh/生成authorized_keys
    1. 格式
      ssh-copy-id [-i [identity_file]] [user@]host
    2. 选项
      -i :指定公钥路径,不加此项,则拷贝默认路径
[root@hai7 ~]$ssh-copy-id  -i /root/.ssh/id_rsa.pub  172.20.129.251
  1. 测试
[root@hai7 ~/.ssh]$ssh 172.20.129.251
Last login: Sun Sep 16 01:28:20 2018 from 172.20.129.183
  1. 重设私钥口令:
    • 格式:ssh-keygen –p
    • 可配合选项:-f、-P、-N
'1. 如果不指定路径,会交互式问答要求输入密钥路径'
[root@hai7 .ssh]$ssh-keygen -p
Enter file in which the key is (/root/.ssh/id_rsa): /data/.ssh/id_rsa
'2. 如果需要写入脚本可也可以如下写法,直接修改'
[root@hai7 .ssh]$ssh-keygen -p -f "/data/.ssh/id_rsa" -P "abc" -N "123"
'3. 加密后的私钥会多出如下行'
[root@hai7 ~/.ssh]$cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED    '<==已被加密,使用的是AES-128算法'
DEK-Info: AES-128-CBC,9FEBEF484BDEECB537DCA17308D3A843
  1. 验证代理(authentication agent)
    • 功能
      加密私钥后,每次连接认证过的主机都要输入加密口令,此时可以考虑使用验证代理
      1. 这样口令就只需要输入一次
      2. 在GNOME中,代理被自动提供给root用户
      3. 否则运行命令ssh-agent bash来激活代理
    • 添加
      钥匙通过命令添加给代理
[root@hai7 ~/.ssh]$ssh-add
Enter passphrase for  /root/.ssh/id_ras:
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)

3.4 在SecureCR或Xshell实现基于key验证

  1. 在Xshell5对话框中选择工具新建用户密钥生成向导,选择加密类型,密钥长度,下一步
    Linux学习29-SSH服务_第5张图片
  2. 生成公钥对,下一步
  3. 创建私钥密码,下一步
  4. 保存密钥至桌面.pub结尾的文件
  5. 将公钥导入至登录主机/root/.ssh/下
  6. 建立文件authorized_keys,并追加公钥到文件中
[root@hai6  ~/.ssh]$cat id_rsa_1024.pub >>authorized_keys
  1. 测试,在Xshell对话框,新建连接,填写登录主机(有公钥的主机)ip,点击用户身份验证,方法选择Public key,输入用户名,选择密钥,输入私钥密码,确定连接。

  2. 如果是SecureCRT生成的公钥,需要导入登录主机后转化为openssh兼容格式,权限必须为600,命令如下

[root@hai6  ~/.ssh]$ssh-keygen -i -f  *.pub >> .ssh/authorized_keys

4. scp命令与rsync命令

4.1 scp命令

  • 常用格式
    scp [options] [user@]host:/sourcefile /destpath
    scp [options] [目标ip]/sourcefile [user@]host:/destpath
  • 常用选项
    -C:压缩数据流
    -r :递归复制
    -p:保持原文件的属性信息
    -q:静默模式
    -P PORT:指明remote host的监听的端口
'1. 将文件拷贝到目标主机'
[root@hai7 ~]$scp  /etc/passwd/ 192.168.32.6:/data
'2. 将目标文件拷贝至本机'
[root@hai7 ~]$scp 192.168.32.6:/etc/passwd  /data/
'3. 在本机上,将目标A192.168.32.6的文件拷贝给目标B192.168.32.17'
[root@hai7 ~]$scp  192.168.32.6:/etc/passwd  192.168.32.17:/data
  • scp性能上的缺点,性能优化方法为使用rsync命令
'1. 从A主机拷贝文件f1、f2、f3至主机B'
[root@hai7 ~]$scp -p f*  172.20.50.150:/data
f1                        100%   13    28.3KB/s   00:00    
f2                        100%    7    17.3KB/s   00:00    
f3                        100%   10    23.6KB/s   00:00  
'2. 然后在A主机更改文件f2其他文件不变,再次执行'
[root@hai7 data]$echo abc>>f1
'3. 再次执行,会将所有文件再次拷贝一次'
[root@hai7 ~]$scp -p f*  172.20.50.150:/data
f1                        100%   17     5.4KB/s   00:00    
f2                        100%    7     4.8KB/s   00:00    
f3                        100%   10     7.4KB/s   00:00
'4. 使用rsync命令重复操作,reync只复制更改的文件'
[root@hai7 data]$rsync -v f*  172.20.129.251:/data
f1
sent 117 bytes  received 40 bytes  12.56 bytes/sec

4.2 rsync命令

基于ssh和rsh服务实现高效率的远程系统之间复制文件

  • 需要注意的格式
    rsync –av /etc server1:/tmp 复制目录和目录下文件
    rsync –av /etc/ server1:/tmp 只复制目录下文件

  • 选项:
    -n:模拟复制过程
    -v:显示详细过程
    -r:递归复制目录树
    -p:保留权限
    -t:保留时间戳
    -g:保留组信息
    -o:保留所有者信息
    -l:将软链接文件本身进行复制(默认)
    -L:将软链接文件指向的文件复制
    -a:存档,相当于–rlptgoD,但不保留ACL(-A)和SELinux属性(-X)

  • sftp命令
    交互式文件传输工具,用法和传统的ftp工具相似
    利用ssh服务实现安全的文件上传和下载

  • 格式
    sftp [user@]host
    [root@hai7 .ssh]# sftp 172.20.129.251

  • 获取帮助
    进入交互界面后输入?或help

[root@hai7 .ssh]$sftp 172.20.129.251
[email protected]'s password: 
Connected to 172.20.129.251.
sftp> ?     <==获取帮助
Available commands:
bye                                Quit sftp
cd path                            Change remote directory to path
  • 常用命令
    ls 、cd 、mkdir、 rmdir 、pwd、 get、put等

5. pssh工具

pssh是一个python编写可以在多台服务器上执行命令的工具,也可实现文件复制,来自epel源

5.1 pssh命令

  • 常用格式
    pssh [-H [user@]host[:port]] command …
  • 常用选项
    –version:查看版本
    -h:主机文件列表,内容格式”[user@]host[:port]”
    -H:指定访问的主机名,内容格式”[user@]host[:port]”,默认为root,端口号默认22
    -A:手动输入密码模式,默认为基于key验证
    -i:每个服务器内部处理信息输出,不加此项只会提示执行成功失败,不显示内容
    -l:登录使用的用户名
    -p:并发的线程数【可选】
    -o:输出的文件目录【可选】
    -e:错误输入文件【可选】
    -t:TIMEOUT 超时时间设置,0无限制【可选】
    -O:SSH的选项
    -P:打印出服务器返回信息
    -v:详细模式
  • 选项

示例1:密码验证-A选项,连接目标主机并执行命令hostname

1. '完整格式'
[root@hai7 ~]$pssh -H [email protected] -A -i hostname
2. '省略格式,默认用户为root'
[root@hai7 ~]$pssh -H 172.20.129.251 -A hostname
[1] 21:51:20 [SUCCESS] 172.20.129.251
'不加-i选项只会提示执行成功失败,不显示内容'
[root@hai7 ~]$pssh -H 172.20.129.251 -A -i  hostname
[1] 21:52:03 [SUCCESS] 172.20.129.251
hai6		

示例2:基于key验证,连接多台主机执行命令hostname,默认为k验证,不需要加选项

[root@localhost~]$pssh -H "172.20.129.251  172.20.50.201"  -i  hostname
[1] 21:52:03 [SUCCESS] 172.20.50.201
已经做过基于key验证的主机,登录成功
hai7
[2] 20:11:02 [FAILURE] 172.20.129.251 Exited with error code 255
172.20.129.251没有做基于key验证的主机,验证失败
Stderr: pssh error: SSH requested a password. Please create SSH keys or use
the -A option to provide a password.
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password)

示例3:-h选项,将ip放入文件中,批量执行

[root@localhost]$touch f1
[root@localhost]$echo  172.20.50.201>>f1
[root@localhost]$pssh -h f1  -i ls

示例4:通过pssh批量关闭seLinux

pssh -H [email protected] -i "sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config"

示例5:将标准错误和标准正确重定向都保存至/data目录下

[root@localhost]$pssh -H "172.20.129.251 172.20.50.201" -o /data -e /data -A -i hostname
会自动生成以ip命名的文件夹来存放
[root@localhost]$ls
172.20.129.251  172.20.50.201  f1  shanwuyu.key

5.2 PSCP.PSSH命令

pscp.pssh功能是将本地文件批量复制到远程主机

  • 格式
    pscp.pssh [-vAr] [-h hosts_file] [-H [user@]host[:port]] [-l user] [-p par] [-o outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] local remote
  • 选项
    -v 显示复制过程
    -r 递归复制目录
  • 示例
    示例1:将本地a.sh 复制到/data/目录
[root@hai7  ~]$pscp.pssh  -H  172.20.50.201  /data/a.sh  /data/

示例2:将本地多个文件批量复制到/app/目录

[root@hai7  ~]$pscp.pssh -H 192.168.1.10 /root/f1.sh /root/f2.sh /app/

示例3:将本地目录批量复制到/app/目录

[root@hai7  ~]$pscp.pssh -H 192.168.1.10 -r /root/test/ /app/

5.3 PSLURP命令

pslurp功能是将远程主机的文件批量复制到本地

  • 格式
    pslurp [-vAr] [-h hosts_file] [-H [user@]host[:port]] [-l user] [-p par][-o outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] [-L localdir] remote local(本地名)
  • 选项
    -L:指定从远程主机下载到本机的存储的目录,local是下载到本地后的名称
    -r :递归复制目录
  • 示例
    批量下载目标服务器的日志文件至/app下,并更名为user
[root@hai7  ~]$pslurp -H 192.168.1.10 -L /app/ /var/log/messages  user

6. SSH端口转发

SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据。而且,SSH 还能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程也被叫做“隧道”(tunneling),这是因为 SSH 为其他 TCP 链接提供了一个安全的通道来进行传输而得名。
例如,Telnet,SMTP,LDAP 这些 TCP 应用均能够从中得益,避免了用户名,密码以及隐私信息的明文传输。而与此同时,如果工作环境中的防火墙限制了一些网络端口的使用,但是允许 SSH 的连接,也能够通过将 TCP 端口转发来使用 SSH 进行通讯

  • SSH 端口转发能够提供两大功能:

    1. 加密 SSH Client 端至 SSH Server 端之间的通讯数据
    2. 突破防火墙的限制完成一些之前无法建立的 TCP 连接

    例如在局域网中的服务器,限制了只有局域网中的客户机才可以访问此服务器,外部客户端想要访问,就需要通过本地端口转发

6.1 SSH端口转发

  • 本地转发格式
    -L : :
    例如ssh -L 10086:172.20.50.121:23 172.20.169.50

  • 选项:
    -f 后台启用
    -N 不打开远程shell,处于等待状态
    -g 启用网关功能

  • 示例
    客户端A想要使用telnet服务连接文件服务器C,而telnet服务时明文的,不安全。
    使用SSH隧道功能,将telnet服务包在SSH中,以达到安全连接的目的。
    前提是客户机A要有与服务器B连接SSH的能力
    Linux学习29-SSH服务_第6张图片

  1. 在客户机A上操作,开通与SSH服务器的隧道
     在客户端A开一个端口10086来连接SSH服务器B,开通隧道

     	[root@haiA ~]$ssh –L  |10086:|172.20.129.50:|23 |172.20.50.121|
     	|客户端A连接SSH服务器B的端口|目标服务器C的ip|C的端口|SSH服务器ip|
    

     上例只是登录到SSH服务器B上,加上选项-N,会在当前shell中等待执行指令,终端不释放,客户机A不能执行其他操作

        [root@haiA ~]$ssh -L  10086:172.20.129.50:23  -N 172.20.50.121
    

     配合-f选项,后台执行,不影响

        [root@haiA ~]$ssh -L  10086:172.20.129.50:23  -Nf 172.20.50.121
    
  2. 当A访问本机的10086的端口时,会通过ssh服务将据被加密后转发到SSH服务器B的,B再解密信息转发到C:23

[root@haiA ~]$telnet  127.0.0.1 10086
输入口令登录
  1. 分别查看A、B、C三台主机的端口
客户端A
[root@haiA  ~]$ss -nt	
State      Recv-Q Send-Q    Local Address:Port       Peer Address:Port
ESTAB      0      0           127.0.0.1:51562                127.0.0.1:10086	
'本机服务器开随机端口10086接收数据,10086通过SSH封装数据'
ESTAB      0      0           192.168.50.100:53198         172.20.50.121:22
'将封装后的数据再开一个随机端口发送给远程服务器上'
[root@haiB  ~]$ss -nt	
State      Recv-Q Send-Q    Local Address:Port       Peer Address:Port
ESTAB      0      0           172.20.50.121:49638      172.20.129.50:23
'SSH服务器B充当客户端A与C连接'
ESTAB      0      0           172.20.50.121:22         192.168.50.100:53198
[root@haiC  ~]$ss -nt	
State      Recv-Q Send-Q    Local Address:Port       Peer Address:Port
ESTAB      0       0           172.20.129.50:23          172.20.50.121:49638
  1. 连接关系
    A:data ←→A:localhost:10086 ←→ A:localhost:53198 ←→ B:sshsrv:22 ←→ B:sshsrv:49638←→ C:telnetsrv:23

6.2 远程转发:

通常情况下,外部网络是不能直接使用ssh服务与防火墙内部的主机连接,而内部网络是可以向外通讯的,可以由内部向外搭接隧道,来达成远程转发,依然以上例图为例。
在实际工作中搭接要注意telnet服务器地址为公网地址,不然连接不了

  1. 在SSH服务B上执行如下,让A(sshsrv)侦听10086端口的访问,如有访问,就加密后通过ssh服务转发请求到B(本机ssh客户端),再由B解密后转发到telnetsrv:23
[root@haiB  ~]$ssh -R 10086:172.20.129.50:23  -fN  192.168.50.100 
                      |  1 |      2     | 3 |      |      4     |
                   |A:ssh端口|:Cip|:Ctelnet端口|   |     Aip    |
充当telnet客户端以及ssh的客户端
  1. 在客户端A上执行,访问本地ssh服务端口10086
[root@haiA ~]$telnet  127.0.0.1 10086
反向连接,客户端A充当的是SSH的服务器
  1. 连接关系
    Data ←→ sshsrv:10086←→ sshsrv:22 ←→ localhost:sshXX ←→ localhost:telnetYY ←→ telnetsrv:23

6.3 实验,跨网络访问

  • 目的
    A主机使用telnet服务连接D服务器,达成安全通信
    Linux学习29-SSH服务_第7张图片
  • 搭建实验环境
    本地转发 -L ,此实验环境为本地转发
    A(telnet client) B(SSH client) ------internet ssh----C(ssh server) D(telnet server)
    远程转发 -R
    A(telnet client) B(SSH server) ------internet ssh----C(ssh client) D(telnet server)
  • 操作流程
  1. 在D上执行以下命令拒绝AB的访问
[root@haiD  ~]$iptables -A INPUT -s 172.20.50.100 -j REJECT
[root@haiD  ~]$iptables -A INPUT -s 172.20.50.201 -j REJECT
  1. 本地在服务器B上执行
    需要加上选项-g 来充当网关
    1. 如果不加B机器上的10086端口为172.20.50.202:10086,只用本机可以连接
    2. 加上-g选项,10086端口为*:10086,所有人都可以连接,也就是说A可以连接
[root@haiB  ~]$ssh -L  10086:172.20.50.150:23   172.20.50.202   -fgN
  1. 在主机A上执行如下命令,将请求发送到B主机的10086端口,通过SSH封装,发送给C,C解SSH封装后发送给D
[root@haiB  ~]$telnet  172.20.50.201 10086
  • 如果使用远程转发
    在远程服务器C上执行
$ssh -R 10086:D:25  B  -fgN

7 动态端口转发(科学上网)

当用firefox访问internet时,本机的1080端口做为代理服务器,firefox的访问请求被转发到sshserver上,由sshserver替之访问internet

  • 格式
    ssh -D locaport root@sshserver
    在本机firefox设置代理socket proxy:127.0.0.1:1080
    curl --socks5 127.0.0.1:1080 http://www.qq.com
  • 示例
    A B C三台主机,假设B为墙外服务器,C为本地客户端,工作原理同SSH隧道,SSH客户端发送请求,通过ssh端口将信息封装,发送给SSH服务器,服务器解封装,发送给目标地址
  1. A主机充当谷歌
'启动httpd服务'
[root@haiB  ~]$service httpd start
'将google放入名/var/www/html/index.html,伪装google页面'
[root@haiB  ~]$echo www.google.com>/var/www/html/index.html
  1. C本地客户端
加入名字DNS解析,将192.168.32.6伪装为google,这里只是做实验,正常不这么配
[root@haiC  ~]$vim /etc/hosts
192.168.32.6  www.google.com
字符界面,检验搭建情况
[root@haiC  ~]$curl www.google.com
图形界面
[root@haiC  ~]$firefox  www.google.com
  1. A主机上拒绝C访问,假冒防火墙
[root@haiA  ~]$iptables -A INPUT -s  172.20.50.201  -j  REJECT
  1. C主机上执行一下命令,通过本地10086接口,连接墙外服务器B,
[root@haiA  ~]$ssh -D 10086 172.20.50.150  -fN
  1. 修改浏览器的代理地址,让代理地址指向本机的10086端口
    配置浏览器,在浏览界面选择菜单preferences→Advanced→Network→Seting→Manual proxy configuration→SOCKS Host 127.0.0.1 Port:10086
  • 将C主机作为代理服务器,让其他主机通过C来连接A
  1. 在C主机上执行以下命令,以10086端口作为ssh服务,连接B主机,加上网关功能-g选项
[root@haiC  ~]$ssh -D 10086 172.20.50.150 -fgN
  1. 在A上拒绝主机D,假设防火墙
    [root@haiA ~]$iptables -A INPUT -s 172.20.50.222 -j REJECT
  2. 主机D尝试通过代理服务连接A
字符界面
[root@haiD  ~]$curl  --socks5  172.20.50.201:10086  http://www.google.com
图形界面
配置浏览器,在浏览界面选择菜单preferences→ Advanced→ Network→ Seting→ Manual proxy configuration→ SOCKS Host  172.20.50.201  Port:10086

8. ssh服务器配置

  • SSH服务器端 配置文件
    修改服务器端配置时,建议先备份
    /etc/ssh/sshd_config

  • 常用参数

#Port 22                      
'建议修改为非常规端口'
#AddressFamily any             
'支持ipv4/ipv6,any为都支持'
#ListenAddress 0.0.0.0   <==指定那个IP地址来监听服务端口port
listenaddress  172.20.251.121   <==添加一行指定监听端口

HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
'key验证算法相关'
'连接centos6优先使用RSA key'
'连接centos7优先使用EXDSA key'
#LoginGraceTime 2m   
'登录宽限时长,也就是等待输入密码时间'
#PermitRootLogin yes
'改为no,不予许root连接登录  <==解决方法,用普通账户登录,然后su -root'
ListenAddress ip
#StrictModes yes 
'检查.ssh/文件的所有者,权限等,改为no就会跳过,不检查这些属性'
#MaxAuthTries 6
'最大尝试连接次数,为指定值的一半'
#MaxSessions 10 同一个连接最大会话
'每一个网络连接开启的会话'
AuthorizedkeysFile         .ssh/authorized_keys
'基于key验证,公钥的存放文件'
#PubkeyAuthentication yes
'支持基于key验证'
PasswordAuthentication yes
'支持用户密码验证'
GSSAPIAuthentication yes 	
'提高连接速度可改为no'
GatewayPorts no
'是否允许远程主机连接本地的转发端口'
UseDNS yes      
'提高连接速度可改为no'
#AllowAgentForwarding yes
'允许代理转发'
#AllowTcpForwarding yes
'允许Tcp转发'
#MaxStartups 10:30:100
'未认证连接超过10时, 限制30%的连接,多大为100个连接'
PermitEmptyPasswords no
'是否允许空口令登录'
#ClientAliveInterval 0
'每过多少秒,探测一次连接用户是否活动'
#ClientAliveCountMax 3
'最大探测次数,超过后断开'
Banner /path/file       <==如:/etc/ssh.txt
'登录提示语句,指定一个文件路径,在文本中写入提示语,ssh连接是会显示文本内容'

  • 限制可登录用户的办法
    在配置文件中添加如下内容
    1. 允许访问用户
      AllowUsers user1 user2 user3
    2. 拒绝访问用户
      DenyUsers
    3. 允许访问组
      AllowGroups
    4. 拒绝访问组
      DenyGroups

例如 在配置文件中加如下行,v9为另一台主机的用户

AllowUsers  v9
只允许用户v9连接
DENYUSERS v9
拒绝用户v9连接
  • ssh服务的最佳实践
    1. 建议使用非默认端口
    2. 禁止使用protocol version 1
      协议版本有漏洞
    3. 限制可登录用户
    4. 设定空闲会话超时时长
    5. 利用防火墙设置ssh访问策略
    6. 允许特定的主机访问服务器
    7. 仅监听特定的IP地址 :
    8. 基于口令认证时,使用强密码策略
      tr -dc A-Za-z0-9_ < /dev/urandom | head -c 30| xargs
      xargs为增加空格
  1. 使用基于密钥的认证
  2. 禁止使用空密码
  3. 禁止root用户直接登录
  4. 限制ssh的访问频度和并发在线数
  5. 经常分析日志
    例如日志中出现同一个ip多次提示 Failed password,可能是恶意破解口令

9. 编译安装dropbear示例

dropbear是一个较小的SSH服务器和客户端,使用时避免与SSH冲突,更改与SSH不同的端口

  • 源码编译安装:

    1. 安装开发包组:yum groupinstall “Development tools”
    2. 下载服务安装包
      dropbear-2017.75.tar.bz2
    3. 解压dropbear服务安装包
      tar xf dropbear-2017.75.tar.bz2
    4. 查看安装说明
      cat README
    5. 进入到解压目录,指定安装路径、配置文件路径,启用禁用功能
      ./configure --prefix=/app/dropbear --sysconfdir=/etc/dropbear --disable-zlib
      README里提示生成的key将放在/etc/dropbear/下,通常情况key要和配置文件放在一起,所以–sysconfdir=/etc/dropbear/
      编译过程中提示少zlib 根据官方提示,禁用掉 --disable-zlib
    6. 根据README,指定要编译的程序,也可以直接make
      make PROGRAMS=“dropbear dbclient dropbearkey dropbearconvert scp”
    7. 安装
      1. 默认安装,安装路径为/usr/local/bin
        make install
      2. 指定程序安装
        make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install
    8. tree查看生成的文件
      dbclient 相当于ssh
      dropbar 相当于sshd服务
    9. 程序不在PATH变量中,使用时要指定路径,将其添加到变量中
      1. 在/etc/profile.d/下建一个.sh后缀文件
        touch /etc/profile.d/dropber.sh
      2. 在文件dropber.sh中编辑以下内容
        PATH=/app/dropbear/bin:/app/dropbear/sbin:$PATH
      3. 生效变量
        /etc/profile.d/dropbear.sh
    10. 生成key
      1. 依 README建立文件
        mkdir /etc/dropbear
      2. 生成密钥
        dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key -s 2048

        dropbearkey -t dss -f /etc/dropbear/dropbear_dsa_host_key
    11. 执行以下命令,启动服务
      1. 前台运行
        dropbear -p :2222 -F –E
      2. 后台运行
        dropbear -p :2222
  • 客户端访问:
    简写:dbclient 172.20.50.201

  • 当做服务器使用
    命令:dropbear
    选项
    -F:不在后台执行
    -E:记录错误信息而不在日志中,将错误信息在屏幕打印
    -p:指定端口
    -r :基于key登录
    -P:运行进程的端口pid文件,默认为/var/run/dropbear.pid
    如:dropbear -FEp 2222 打开一个2222的端口作为连接服务器

  • dropbear传输文件命令scp

示例:可能出现的错误

1. 将文件/etc/fstab发送给192.168.32.6存放在其家目录下
[root@hai7-7  ~]$scp  /etc/fstab 192.168.32.6:
/usr/bin/dbclient:No such file or directory   <==报错
lost connection

错误原因,scp调用dbclient,程序执行时调用的是PATH变量,找不到/app/dropbear/bin
解决方法:
1.将文件拷贝到/usr/bin/下
2.创建软连接:ln -s /app/dropbear/bin/dbclient /usr/bin/dbclient

  • 编译的dropbear服务设置开机启动
    1. 写服务配置文件/usr/lib/systemd/system/
    2. 写入/etc/rc.local
      1. rc.local文件添加行/app/dropbear/sbin/dropbear -p 2222
      2. 为rc.local加执行权限 chmod +x /etc/rc.d/rc.local
  • 删除编译程序
    1. 将服务配置文件,或者rc.local下内容删除
    2. 杀掉进程killall dropbear
    3. 删除目录安装目录/app/dropbear
    4. 删除配置目录/etc/dropbear
    5. 删除编译包dropbear-2018.76*
    6. 删除定义的PATH变量
    7. 因为此工具包含scp命令,使用后已hash到缓存中,记忆的仍然是dropbear路径删除hash中的响应记录 hash -d scp 删一个 hash -r 全删

你可能感兴趣的:(Linux学习29-SSH服务)