Skip to content

Latest commit

 

History

History
299 lines (211 loc) · 16.7 KB

File metadata and controls

299 lines (211 loc) · 16.7 KB

十二、通过 Telnet 和 SSH 远程监控主机

在本章中,您将学习如何在配置了 Telnet 和 SSH 的服务器上执行基本配置。我们将首先使用 Telnet 模块,然后使用首选方法实现相同的配置:使用 Python 中的不同模块实现 SSH。您还将了解telnetlib、subprocess、fabric、Netmiko和paramiko模块的工作原理。在本章中,您必须具备网络的基本知识。

在本章中,我们将介绍以下主题:

  • telnetlib()模块
  • subprocess.Popen()模块
  • 使用结构模块的 SSH
  • 使用 Paramiko 库的 SSH
  • 使用 Netmiko 库的 SSH

telnetlib()模块

在本节中,我们将学习 Telnet 协议,然后通过远程服务器使用telnetlib模块执行 Telnet 操作。

Telnet 是一种允许用户与远程服务器通信的网络协议。它主要用于网络管理员远程访问和管理设备。要访问设备,请使用终端中远程服务器的 IP 地址或主机名运行 Telnet 命令。

Telnet 在默认端口号23上使用 TCP。要使用 Telnet,请确保系统上已安装 Telnet。如果没有,请运行以下命令进行安装:

$ sudo apt-get install telnetd

要使用简单终端运行 Telnet,只需输入以下命令:

$ telnet ip_address_of_your_remote_server

Python 有telnetlib模块,可以通过 Python 脚本执行 Telnet 功能。在 Telnet 远程设备或路由器之前,请确保它们已正确配置,如果未正确配置,您可以使用路由器终端中的以下命令进行基本配置:

configure terminal
enable password 'set_Your_password_to_access_router'
username 'set_username' password 'set_password_for_remote_access'
line vty 0 4 
login local 
transport input all 
interface f0/0 
ip add 'set_ip_address_to_the_router' 'put_subnet_mask'
no shut 
end 
show ip interface brief 

现在,让我们看一下远程设备的 Telnet 示例。为此,创建一个telnet_example.py脚本,并在其中写入以下内容:

import telnetlib
import getpass
import sys

HOST_IP = "your host ip address"
host_user = input("Enter your telnet username: ")
password = getpass.getpass()

t = telnetlib.Telnet(HOST_IP)
t.read_until(b"Username:")
t.write(host_user.encode("ascii") + b"\n")
if password:
 t.read_until(b"Password:") t.write(password.encode("ascii") + b"\n")

t.write(b"enable\n")
t.write(b"enter_remote_device_password\n") #password of your remote device
t.write(b"conf t\n")
t.write(b"int loop 1\n")
t.write(b"ip add 10.1.1.1 255.255.255.255\n") t.write(b"int loop 2\n") t.write(b"ip add 20.2.2.2 255.255.255.255\n") t.write(b"end\n") t.write(b"exit\n") print(t.read_all().decode("ascii") )

运行脚本,您将获得如下输出:

student@ubuntu:~$ python3 telnet_example.py Output: Enter your telnet username: student Password: 

server>enable Password: server#conf t Enter configuration commands, one per line.  End with CNTL/Z. server(config)#int loop 1 server(config-if)#ip add 10.1.1.1 255.255.255.255 server(config-if)#int loop 23 server(config-if)#ip add 20.2.2.2 255.255.255.255 server(config-if)#end server#exit

在前面的示例中,我们使用telnetlib模块访问并配置了 Cisco 路由器。在这个脚本中,首先,我们从用户那里获取用户名和密码,以初始化与远程设备的 Telnet 连接。建立连接后,我们在远程设备上进行了进一步的配置。在 Telnet 之后,我们将能够访问远程服务器或设备。但是,这种 Telnet 协议有一个非常重要的缺点,那就是所有数据,包括用户名和密码,都是通过网络以文本方式发送的,这可能会造成安全风险。正因为如此,如今 Telnet 很少使用,已经被一种非常安全的协议(称为 SSH)所取代。

SSH

SSH 是一种网络协议,用于通过远程访问管理设备或服务器。SSH 出于安全目的使用公钥加密。Telnet 和 SSH 之间的重要区别在于 SSH 使用加密,这意味着通过网络传输的所有数据都受到保护,不受未经授权的实时拦截。

访问远程服务器或设备的用户必须安装 SSH 客户端。通过在终端中运行以下命令来安装 SSH:

$ sudo apt install ssh

此外,在用户希望通信的远程服务器上,必须安装并运行 SSH 服务器。SSH 使用 TCP 协议,默认在端口号22上工作。

您可以通过终端运行ssh命令,如下所示:

$ ssh host_name@host_ip_address

现在,您将学习使用 Python 中的不同模块来实现 SSH,例如 subprocess、fabric、Netmiko 和 Paramiko。现在,我们将逐一查看这些模块。

subprocess.Popen()模块

Popen类处理流程创建和管理。通过使用此模块,开发人员可以处理不太常见的情况。子程序将在新进程中执行。要在 Unix/Linux 上执行子程序,类将使用os.execvp()函数。要在 Windows 中执行子程序,类将使用CreateProcess()函数。

现在,让我们看看subprocess.Popen()的一些有用的论点:

class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None,
 stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

让我们看看每个论点:

  • args:可以是程序参数序列,也可以是单个字符串。如果args是序列,则执行 args 中的第一项。如果 args 是字符串,则建议将 args 作为序列传递。 *** shell:shell 参数默认设置为False,指定是否使用 shell 执行程序。如果 shell 为True,则建议将 args 作为字符串传递。在 Linux 中,如果为shell=True,shell 默认为/bin/sh。如果args是字符串,则该字符串指定要通过 shell 执行的命令。* bufsize:如果bufsize为0(默认为0),则表示未缓冲;如果bufsize为1,则表示行缓冲。如果bufsize是任何其他正值,则使用给定大小的缓冲区。如果bufsize为任何其他负值,则表示完全缓冲。* executable:指定要执行的替换程序* stdin、stdout和stderr:这些参数分别定义标准输入、标准输出和标准误差* preexec_fn:设置为可调用对象,在子进程中执行子进程之前调用。*** close_fds:在 Linux 中,如果close_fds为 true,则在执行子进程之前,除0、1、2之外的所有文件描述符都将关闭。在 Windows 中,如果close_fds是true,则子进程将不会继承任何句柄*** env:如果该值不是None,则映射将为新流程定义环境变量。*** universal_newlines:如果值为True,则stdout和stderr将以换行方式作为文本文件打开。********

******现在,我们将看到一个subprocess.Popen()的示例。为此,创建一个ssh_using_sub.py脚本,并在其中写入以下内容:

import subprocess
import sys

HOST="your host username@host ip"
COMMAND= "ls"

ssh_obj = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],
 shell=False,
 stdout=subprocess.PIPE,
 stderr=subprocess.PIPE)

result = ssh_obj.stdout.readlines()
if result == []:
 err = ssh_obj.stderr.readlines()
 print(sys.stderr, "ERROR: %s" % err)
else:
 print(result)

运行脚本,您将获得如下输出:

student@ubuntu:~$ python3 ssh_using_sub.py Output : student@192.168.0.106's password: [b'Desktop\n', b'Documents\n', b'Downloads\n', b'examples.desktop\n', b'Music\n', b'Pictures\n', b'Public\n', b'sample.py\n', b'spark\n', b'spark-2.3.1-bin-hadoop2.7\n', b'spark-2.3.1-bin-hadoop2.7.tgz\n', b'ssh\n', b'Templates\n', b'test_folder\n', b'test.txt\n', b'Untitled1.ipynb\n', b'Untitled.ipynb\n', b'Videos\n', b'work\n']

在前面的示例中,首先导入子流程模块,然后定义要在其中建立 SSH 连接的主机地址。之后,我们给出了一个在远程设备上执行的简单命令。设置完所有这些之后,我们将这些信息放入subprocess.Popen()函数中。此函数执行该函数中定义的参数,以创建与远程设备的连接。建立 SSH 连接后,执行我们定义的命令并提供结果。然后我们在终端上打印 SSH 的结果,如输出所示。

使用结构模块的 SSH

Fabric 是一个 Python 库,也是一个用于 SSH 的命令行工具。它用于通过网络进行系统管理和应用程序部署。我们还可以通过 SSH 执行 shell 命令。

要使用 fabric module,首先必须使用以下命令安装它:

$ pip3 install fabric3

现在,我们来看一个例子。创建一个fabfile.py脚本,并在其中写入以下内容:

from fabric.api import * env.hosts=["host_name@host_ip"] env.password='your password'  def dir(): run('mkdir fabric') print('Directory named fabric has been created on your host network') def diskspace():
 run('df') 

运行脚本,您将获得如下输出:

student@ubuntu:~$ fab dir Output: [student@192.168.0.106] Executing task 'dir' [student@192.168.0.106] run: mkdir fabric
Done. Disconnecting from 192.168.0.106... done.

在前面的示例中,我们首先导入了fabric.api模块,然后设置主机名和密码以连接主机网络。之后,我们设置了不同的任务来通过 SSH 执行。因此,为了执行我们的程序而不是 Python3fabfile.py,我们使用了fab实用程序(fab dir,之后我们声明所需的任务应该从我们的fabfile.py执行。在我们的例子中,我们执行了dir任务,它在您的远程网络上创建了一个名为'fabric'的目录。您可以在 Python 文件中添加特定任务。它可以使用 fabric 模块的fab实用程序执行。

使用 Paramiko 库进行 SSH

Paramiko 是一个实现 SSHv2 协议的库,用于与远程设备的安全连接。Paramiko 是一个围绕 SSH 的纯 Python 接口。

在使用 Paramiko 之前,请确保已将其正确安装在系统上。如果未安装,可以通过在终端中运行以下命令进行安装:

$ sudo pip3 install paramiko

现在,我们将看到一个使用paramiko的示例。对于这个paramiko连接,我们使用的是 Cisco 设备。Paramiko 支持基于密码和基于密钥对的身份验证,以实现与服务器的安全连接。在我们的脚本中,我们使用基于密码的身份验证,这意味着我们检查密码,如果可用,则尝试使用普通用户名/密码身份验证进行身份验证。在我们对远程设备或多层路由器执行 SSH 之前,请确保它们配置正确,如果不正确,您可以在多层路由器终端中使用以下命令进行基本配置:

configure t
ip domain-name cciepython.com
crypto key generate rsa
How many bits in the modulus [512]: 1024
interface range f0/0 - 1
switchport mode access
switchport access vlan 1
no shut
int vlan 1
ip add 'set_ip_address_to_the_router' 'put_subnet_mask'
no shut
exit
enable password 'set_Your_password_to_access_router'
username 'set_username' password 'set_password_for_remote_access'
username 'username' privilege 15
line vty 0 4
login local
transport input all
end

现在,创建一个pmiko.py脚本,并在其中写入以下内容:

import paramiko
import time

ip_address = "host_ip_address"
usr = "host_username"
pwd = "host_password"

c = paramiko.SSHClient()
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
c.connect(hostname=ip_address,username=usr,password=pwd)

print("SSH connection is successfully established with ", ip_address)
rc = c.invoke_shell() for n in range (2,6):
 print("Creating VLAN " + str(n)) rc.send("vlan database\n") rc.send("vlan " + str(n) +  "\n") rc.send("exit\n") time.sleep(0.5) time.sleep(1) output = rc.recv(65535) print(output) c.close

运行脚本,您将获得如下输出:

student@ubuntu:~$ python3 pmiko.py Output: SSH connection is successfuly established with  192.168.0.70 Creating VLAN 2 Creating VLAN 3 Creating VLAN 4 Creating VLAN 5

在前面的示例中,我们首先导入了paramiko模块,然后定义了连接远程设备所需的 SSH 凭据。在提供凭证后,我们创建了一个paramiko.SSHclient()的'c'实例,该实例是用于与远程设备建立连接并执行命令或操作的主要客户端。SSHClient对象的创建允许我们使用.connect()功能建立远程连接。然后,我们设置策略paramiko连接,因为默认情况下,paramiko.SSHclient将 SSH 策略设置为拒绝策略状态。这会导致策略在没有任何验证的情况下拒绝任何 SSH 连接。在我们的脚本中,我们通过使用AutoAddPolicy()函数来忽略 SSH 连接断开的可能性,该函数在不提示的情况下自动添加服务器的主机密钥。我们可以将此策略仅用于测试目的,但出于安全目的,在生产环境中这不是一个好的选择。

建立 SSH 连接后,您可以在设备上执行任何配置或操作。在这里,我们在远程设备上创建了一些虚拟局域网。创建 VLAN 后,我们刚刚关闭了连接。

使用 Netmiko 库的 SSH

在本节中,我们将了解 Netmiko。Netmiko 库是 Paramiko 的高级版本。这是一个基于 Paramiko 的multi_vendor图书馆。Netmiko 简化了到网络设备的 SSH 连接,并在设备上执行特定操作。在对远程设备或多层路由器执行 SSH 之前,请确保它们配置正确,如果没有,您可以通过 Paramiko 部分中提到的命令执行基本配置。

现在,让我们看一个例子。创建一个nmiko.py脚本,并在其中编写以下代码:

from netmiko import ConnectHandler

remote_device={
 'device_type': 'cisco_ios',
 'ip':  'your remote_device ip address',
 'username': 'username',
 'password': 'password',
}

remote_connection = ConnectHandler(**remote_device)
#net_connect.find_prompt()

for n in range (2,6):
 print("Creating VLAN " + str(n))
 commands = ['exit','vlan database','vlan ' + str(n), 'exit']
 output = remote_connection.send_config_set(commands)
 print(output)

command = remote_connection.send_command('show vlan-switch brief')
print(command)

运行脚本,您将获得如下输出:

student@ubuntu:~$ python3 nmiko.py Output: Creating VLAN 2 config term Enter configuration commands, one per line.  End with CNTL/Z. server(config)#exit server #vlan database server (vlan)#vlan 2 VLAN 2 modified: server (vlan)#exit APPLY completed. Exiting.... server # .. .. .. .. switch# Creating VLAN 5 config term Enter configuration commands, one per line.  End with CNTL/Z. server (config)#exit server #vlan database server (vlan)#vlan 5 VLAN 5 modified: server (vlan)#exit APPLY completed. Exiting.... VLAN Name                             Status    Ports ---- -------------------------------- --------- ------------------------------- 1    default                          active    Fa0/0, Fa0/1, Fa0/2, Fa0/3, Fa0/4, Fa0/5, Fa0/6, Fa0/7, Fa0/8, Fa0/9, Fa0/10, Fa0/11, Fa0/12, Fa0/13, Fa0/14, Fa0/15 2    VLAN0002                         active 3    VLAN0003                         active 4    VLAN0004                         active 5    VLAN0005                         active 1002 fddi-default                    active 1003 token-ring-default         active 1004 fddinet-default               active 1005 trnet-default                    active

在前面的示例中,我们使用 Netmiko 库来执行 SSH,而不是 Paramiko。在这个脚本中,首先,我们从 Netmiko 库导入了ConnectHandler,我们使用它通过传入设备字典来建立到远程网络设备的 SSH 连接。在我们的例子中,那本字典是remote_device。建立连接后,我们执行配置命令,使用send_config_set()功能创建多个虚拟 LAN。

当我们使用此类型(.send_config_set()函数在远程设备上传递命令时,它会自动将我们的设备设置为配置模式。在发送配置命令之后,我们还传递了一个简单的命令来获取有关配置设备的信息。

总结

在本章中,您学习了 Telnet 和 SSH。您还学习了不同的 Python 模块,如 telnetlib、subprocess、fabric、Netmiko 和 Paramiko,我们使用这些模块执行 Telnet 和 SSH。SSH 出于安全目的使用公钥加密,并且比 Telnet 更安全

在下一章中,我们将使用各种 Python 库,您可以使用它们创建图形用户界面。

问题

  1. 什么是客户机-服务器体系结构?
  2. 如何在 Python 代码中运行特定于操作的命令?
  3. 局域网和 VLAN 之间有什么区别?
  4. 以下代码的输出是什么?
 List = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’]
 Print(list [10:])
  1. 编写一个 Python 程序来显示日历(提示:使用calendar模块)。
  2. 编写一个 Python 程序来计算文本文件中的行数。

进一步阅读