您的位置:首页 > 编程语言 > Python开发

《Python 黑帽子》学习笔记 - SSH 远程登录 - Day 11

2018-04-01 03:09 681 查看
学习 SSH 知识,碰到阮一峰大牛这段话,说得多好,去吧,找寻自己的路。

人的真正职责只有一个:找到自我。然后在心中坚守一生,全心全意,永不停息。

所有其它的路都是不完整的,是人的逃避方式,是对社会角色的懦弱伪装,是随波逐流,是对内心的恐惧。”

SSH (SECURE SHELL)

SSH 是一个种网络协议,用于计算机之间的加密登录、数据通信、执行命令、文件传输等。

SSH 存在多种实现,既有商业实现,也有开源实现,SSH 常用在 Linux 系统上,在 Windows 上也可以实现,本书就用 Python 在 Windows 上实现了 SSH 客户端和服务端。

前面学习 netcat 时,关于端口转发,代理等知识点,和 SSH 很相似 ,只不过 SSH 是加密的通信。如果修改 netcat 源码,通过加密算法对通信协议或数据进行加密处理,也能起到安全通信的作用。

简要介绍如下 SSH,摘自官网。快速入门建议参考阮一峰的博客,想更深入学习要仔细看看官网文档。

SSH (Secure Shell) is a software package that enables secure system administration and file transfers over insecure networks. It is used in nearly every data center, in every larger enterprise.

The SSH protocol uses encryption to secure the connection between a client and a server. All user authentication, commands, output, and file transfers are encrypted to protect against attacks in the network.

SSH 环境准备

在看到原书关于 SSH 客户端和服务端,以及 SSH 隧道的实现时,有很多知识盲点,我想在本地搭建 SSH 服务器,并熟悉远程登录、远程操作、端口转发等功能,打牢基础,也为后面的代码实现准备环境。

SSH 服务端

Kali 基于 debian 系统,默认是安装好了 SSH 服务,但是没有启动。如果是最小化方式安装的 debian, 通过

apt-get install ssh


进行安装。

查看 SSH 版本

root@kali:~# ssh -V
OpenSSH_7.6p1 Debian-2, OpenSSL 1.0.2n  7 Dec 2017


是 OpenSSH 实现的 SSH,还有 OpenSSL 的信息。这里解释下 OpenSSL, OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序。比如很多程序安装依赖 openssl 头文件。openssl 命令也是一个很实用且有很多参数的工具。比如申请 SSL 证书,或者计算 hash 值。例如:

root@kali:~# echo "aaaaaa" > a.txt
root@kali:~# cat a.txt
aaaaaa
root@kali:~# openssl md5 a.txt
MD5(a.txt)= b1ffb6b5d22cd9f210fbc8b7fdaf0e19
root@kali:~# echo -n 123456 |openssl md5
(stdin)= e10adc3949ba59abbe56e057f20f883e


查看 SSH 服务状态:

root@kali:~# /etc/init.d/ssh status
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; disabled; vendor preset: disabled)
Active: inactive (dead)
root@kali:~# service ssh status
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; disabled; vendor preset: disabled)
Active: inactive (dead)


启动、停止、重启 SSH 服务:

root@kali:~# /etc/init.d/ssh start
[ ok ] Starting ssh (via systemctl): ssh.service.

root@kali:~# /etc/init.d/ssh stop
[ ok ] Stopping ssh (via systemctl): ssh.service.

root@kali:~# /etc/init.d/ssh restart
[ ok ] Restarting ssh (via systemctl): ssh.service.

root@kali:~# service ssh status
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2018-03-31 12:21:08 EDT; 11s ago
Process: 6763 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 6764 (sshd)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/ssh.service
└─6764 /usr/sbin/sshd -D

Mar 31 12:21:08 kali systemd[1]: Starting OpenBSD Secure Shell server...
Mar 31 12:21:08 kali sshd[6764]: Server listening on 0.0.0.0 port 22.
Mar 31 12:21:08 kali sshd[6764]: Server listening on :: port 22.
Mar 31 12:21:08 kali systemd[1]: Started OpenBSD Secure Shell server.


配置 SSH 服务参数,允许远程 root 用户口令登录和公钥登录

修改 sshd_config 文件,重启 SSH 服务。

PasswordAuthentication = yes # 运行口令登录

PermitRootLogin yes # 允许 root 用户登录

AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 # 服务端存储用户公钥的文件。公钥就是一串字符串,所有用户的公钥都在该文件里

PubkeyAuthentication yes # 允许公钥登录

root@kali:~# vim /etc/ssh/sshd_config


备注下用 vim 的操作:

进入命令模式:
Esc


查找:
/PasswordAuthentication
(可用 * 为通配符,n 为查找下一个,N 为查找上一个)

进入编辑模式:
i
,
a
,
A
,
o
,
O


保存退出:
/wq


查看 SSH 服务进程、端口:

root@kali:~# ps -ef | grep ssh
root      1762  1691  0 Mar29 ?        00:00:01 /usr/bin/ssh-agent /usr/bin/im-launch gnome-session
root      6838     1  0 12:49 ?        00:00:00 /usr/sbin/sshd -D
root      6866  3649  0 12:54 pts/2    00:00:00 grep ssh

root@kali:~# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      6838/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      6838/sshd


远程登录 SSH

使用 OpenSSH 客户端远程登录:

D:\myProjects\Black-Hat-Python
λ ssh -V
OpenSSH_7.1p2, OpenSSL 1.0.2j  26 Sep 2016

D:\myProjects\Black-Hat-Python
λ ssh -p 22 root@192.168.1.7
The authenticity of host '192.168.1.7 (192.168.1.7)' can't be established.
ECDSA key fingerprint is SHA256:nmPjfXEAhKmr5H2PxBkV0YKufpm2spi8eJvQttOICBk.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.7' (ECDSA) to the list of known hosts.
root@192.168.1.7's password:

The programs included with the Kali GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@kali:~#


解释下,这里是使用用户口令进行远程登录。第一次远程登录时,无法确认 SSH 服务端主机的真实性,只知道它的公钥指纹,问你是否还想继续连接?选择 yes。即认可服务端,然后输入密码就可以登录了。

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

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

SSH 还提供了公钥登录的方式,就是用户将自己的公钥储存在远程 SSH 服务端上。登录的时候,服务端会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。服务端用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。

如果用户没有公钥,可以用
ssh-keygen
生成,执行完后,会在
$HOME/.ssh/
(Windows:
`C:\Users\USERNAME\.ssh\
) 目录下,新生成两个文件:id_rsa.pub 和 id_rsa。前者是你的公钥,后者是你的私钥。

我这里已经生成过了,备份后,再生成一次,覆盖之前的。

D:\myProjects\Black-Hat-Python
λ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/Administrator/.ssh/id_rsa):
/c/Users/Administrator/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/Administrator/.ssh/id_rsa.
Your public key has been saved in /c/Users/Administrator/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:6Mzo/7f7uMxmwlCUxwI+LFXgs0KdOrTDR3bOyz23L/o Administrator@XIAONA-PC
The key's randomart image is:
+---[RSA 2048]----+
|      ++.o       |
|     * .+ o      |
|    + @..o       |
|   + * O.        |
|    B +.S        |
|     X.. o       |
|    . +oo o .    |
|   .    oo++..   |
|    .....=OBEo.  |
+----[SHA256]-----+


之后,用命令
ssh-copy-id user@host
(Linux) 将公钥传送到 SSH 服务端上面。

我的 Win7 没有这个命令,参考网络上的教程,用以下方法,都没成功。找不到原因。

ssh user@host 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~\.ssh\id_rsa.pub


D:\myProjects\Black-Hat-Python
λ ssh root@192.168.1.7 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~\.ssh\id_rsa.pub
root@192.168.1.7's password:
系统找不到指定的路径。

D:\myProjects\Black-Hat-Python
λ ssh root@192.168.1.7 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < C:\Users\Administrator\.ssh\id_rsa.pub
root@192.168.1.7's password:
系统找不到指定的路径。

C:\\Users\\Administrator\\.ssh\\id_rsa.pub
C:/Users/Administrator/.ssh/id_rsa.pub


解释下上述命令,即在服务端执行新建 .ssh 文件夹,并把本地的 ~/.ssh/id_rsa.pub (也就是公钥)追加到服务端的 .ssh/authorized_keys 中。

我最后是直接将公钥内容拷贝到服务端(Kali系统)
.ssh/authorized_keys
文件(服务端保存用户公钥的文件)里面,注意文件编码要符合服务端,可以在服务端新建该文件,再粘贴内容。

不用输入口令,可以直接登录了。

D:\myProjects\Black-Hat-Python
λ ssh root@192.168.1.7

The programs included with the Kali GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Mar 31 14:02:11 2018 from 192.168.1.3
root@kali:~#


另外,如果要用公钥连接多个服务端,比如你既要用公钥登录虚拟机的 SSH 服务端,又要用公钥连接 GitHub,即在本地会存在多个公钥私钥对,连接不同的服务器时,SSH 是如何选择对应的私钥进行解密?解决的方式是,在
~/.ssh/
新建一个 config 配置文件,在该文件里指定不同服务端对应的私钥。这样就可以同时连接多个服务端了。

比如,我的 config 文件如下:

Host 192.168.1.9
User root
Hostname 192.168.1.9
Port 22
ServerAliveInterval 120
IdentityFile ~/.ssh/VM-ubuntu-16.04.2-server/id_rsa

host gitee.com
HostName gitee.com
IdentityFile ~/.ssh/id_rsa_gitee.com
User git


第一个为虚拟机 SSH 服务端。第二个为码云。

用 xshell 客户端登录

xshell 是一个功能强大的 SSH 客户端。设置好连接地址,选择公钥登录方式,导入私钥和登录用户后,就可以直接登录了。



参考

SSH原理与运用(一):远程登录 - 阮一峰

SSH原理与运用(二):远程操作与端口转发 - 阮一峰

数字签名是什么? - 阮一峰
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息