Telnet - Python网络编程
Telnet 是一种遵循客户端-服务器模型的网络协议。它使用 TCP 作为其底层通信协议。它通常用于启动和远程命令行会话,通常在服务器上。
关于 telnet 的一些事实:
- 使用传输控制协议进行数据传输。
- 双向 8 位协议
- 该协议标准最初在 RFC15 中描述,并在 RFC854 和 RFC855 中进一步扩展。
- 它是在 1969 年开发的。
在Python中, telnetlib模块促进了 telnet 通信。 telnetlib模块提供Telnet类,该类实现 RFC 854 中描述的 telnet 协议。
Telnet 类:
Syntax: class telnetlib.Telnet(host=None, port=0[, timeout]) :
Input Parameters:
- host(optional): it takes the server name or ip-address. Example: 127.0.0.1, “localhost”
- port(optional): takes the port number if not provided uses the default port number.
- timeout(optional): an additional parameter can be passed to specify the timeout duration else the global timeout duration is used.
如果创建 Telnet 对象时不带任何参数,则可以通过调用open()方法建立连接。或者,用户可以传递主机和端口详细信息,在这种情况下,返回对象并建立连接。
WARNING: A lot of functions in the Telnet class raise EOFError. Hence, appropriate exception handling must be done.
重要功能:
- Telnet.read_until(预期,超时=无)
- Telnet.read_all()
- Telnet.open(主机,端口=0 [,超时])
- Telnet.close()
- Telnet.write(缓冲区)
- Telnet.interact()
我们已经在下面的代码中解释了函数的用法。
复杂:
开发 telnet 时,基本的 ASCII 文本占主导地位。当今的终端通常使用 Unicode 作为标准。此外,颜色编码和格式使屏幕上可见的文本与通过 telnet 传递的字节字符串大不相同。这在使用 Telnet 类的某些功能时会造成混乱。本文旨在在这方面提供帮助。
编写telnet程序的步骤:
步骤 1:启动 telnet 服务器
根据要求,您可能必须启动 telnet 服务器或可能会提供。如果您有一个 telnet 服务器已经在运行,请继续执行第 2 步,否则启动该服务器。
出于说明目的,将使用在“localhost”上运行的 telnet 服务器。
第二步:寻找魔法序列
看看下面的图片:
$ telnet localhost
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Linux 5.10.0-5mx-amd64 (mx) (2)
mx login: pvtejeswar
Password:
Last login: Sun Sep 26 05:24:30 EDT 2021 from localhost on pts/2
No mail.
pvtejeswar@mx:~ <=========================
$
您可能希望红色三角形处的文字是: “pvtejeswar@mx:~\n$” ,但请记住,有很多后台处理和格式化正在进行。红色三角形处的文字实际上是: b”\x1b[1;35mpvtejeswar\x1b[0m@\x1b[1;36mmx\x1b[0m:\x1b[1;32m~\x1b[0m\r\r\n \x1b[1;32m$\x1b[0m”。现在你可能会问:我怎么知道这个魔术字符串在我的情况下是什么样子的。以下程序将帮助您。
Python3
import telnetlib
import getpass
HOST = "localhost"
user = input("USERNAME: ")
password = getpass.getpass()
tn = telnetlib.Telnet()
tn.open(HOST)
tn.read_until(b"login: ")
tn.write(user.encode("ascii")+b"\n")
tn.read_until(b"Password: ")
tn.write(password.encode("ascii")+b"\n")
tn.write(b"exit\n")
print(tn.read_all())
tn.close()
Python3
import telnetlib
import getpass
HOST = "localhost"
user = input("USERNAME: ")
password = getpass.getpass()
# MAGIC is the formatted output information
# that we gathered in step 2.
MAGIC = b"\x1b[1;35mpvtejeswar\x1b[0m@\x1b[1;36mmx\x1b[0m:"
tn = telnetlib.Telnet()
tn.open(HOST)
tn.read_until(b"login: ")
tn.write(user.encode("ascii")+b"\n")
tn.read_until(b"Password: ")
tn.write(password.encode("ascii")+b"\n")
# reading until we reach the
# MAGIC or reading whatever is
# there and timeout after 5 sec.
tn.read_until(MAGIC, 5)
# we write the command to the terminal
tn.write(b"ls -ltr /\n")
print("="*80)
print("output for 'ls -ltr /': ")
# output needs to be decoded to human readable
print(tn.read_until(MAGIC).decode('ascii'))
print("="*80)
tn.write(b"exit\n")
# read everything there is on the console
print(tn.read_all().decode('ascii'))
tn.close()
输出:
pvtejeswar@mx:~/Desktop/telnet
$ python3 telnet_base.py
USERNAME: pvtejeswar
Password:
b’\r\nLast login: Sun Sep 26 04:56:42 EDT 2021 from localhost on pts/2\r\nNo mail.\r\n\x1b[1;35mpvtejeswar\x1b[0m@\x1b[1;36mmx\x1b[0m:\x1b[1;32m~\x1b[0m\r\r\n\x1b[1;32m$\x1b[0m exit\r\nlogout\r\n’
看一眼就知道“\r\n”和“exit”之间的输出是对应“pvtejeswar@mx:~\n$”的字符串。现在我们知道所有输入提示都会有“pvtejeswar@mx:” ,相当于b”\x1b[1;35mpvtejeswar\x1b[0m@\x1b[1;36mmx\x1b[0m:”。现在我们准备编写实际的程序。
第 3 步:编写实际代码。
有了我们从步骤 2 中收集到的知识,我们将编写代码以逐个命令与 telnet 命令交互:
Python3
import telnetlib
import getpass
HOST = "localhost"
user = input("USERNAME: ")
password = getpass.getpass()
# MAGIC is the formatted output information
# that we gathered in step 2.
MAGIC = b"\x1b[1;35mpvtejeswar\x1b[0m@\x1b[1;36mmx\x1b[0m:"
tn = telnetlib.Telnet()
tn.open(HOST)
tn.read_until(b"login: ")
tn.write(user.encode("ascii")+b"\n")
tn.read_until(b"Password: ")
tn.write(password.encode("ascii")+b"\n")
# reading until we reach the
# MAGIC or reading whatever is
# there and timeout after 5 sec.
tn.read_until(MAGIC, 5)
# we write the command to the terminal
tn.write(b"ls -ltr /\n")
print("="*80)
print("output for 'ls -ltr /': ")
# output needs to be decoded to human readable
print(tn.read_until(MAGIC).decode('ascii'))
print("="*80)
tn.write(b"exit\n")
# read everything there is on the console
print(tn.read_all().decode('ascii'))
tn.close()
输出:
pvtejeswar@mx:~/Desktop/telnet
$ python3 telnet.py
USERNAME: pvtejeswar
Password:
================================================================================
output for 'ls -ltr /':
~
$ ls -ltr /
total 64
lrwxrwxrwx 1 root root 8 Apr 7 23:50 sbin -> usr/sbin
lrwxrwxrwx 1 root root 9 Apr 7 23:50 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 7 Apr 7 23:50 lib -> usr/lib
lrwxrwxrwx 1 root root 7 Apr 7 23:50 bin -> usr/bin
drwxr-xr-x 2 root root 4096 Apr 7 23:50 media
drwxr-xr-x 3 root root 4096 Apr 7 23:56 opt
drwxr-xr-x 14 root root 4096 Apr 7 23:57 usr
drwxr-xr-x 12 root root 4096 Apr 7 23:58 var
drwx------ 2 root root 16384 Sep 24 21:34 lost+found
drwxr-xr-x 3 root root 4096 Sep 24 21:38 home
drwxr-xr-x 3 root root 4096 Sep 24 21:39 boot
drwxr-xr-x 2 root root 4096 Sep 24 21:39 mnt
dr-xr-xr-x 13 root root 0 Sep 24 21:39 sys
dr-xr-xr-x 229 root root 0 Sep 24 21:39 proc
drwx------ 7 root root 4096 Sep 25 03:24 root
drwxr-xr-x 147 root root 12288 Sep 25 03:27 etc
drwxr-xr-x 15 root root 3360 Sep 26 04:43 dev
drwxr-xr-x 32 root root 1180 Sep 26 04:43 run
drwxrwxrwt 9 root root 4096 Sep 26 05:24 tmp
pvtejeswar@mx:
================================================================================
~
$ exit
logout
结论
Telnet 是 1970 年代开发的旧协议。它不知道现代终端中最近使用的格式和字符集。因此,在使用 telnet 时,我们必须始终牢记这一点。本指南旨在帮助使用 telnet 通过命令交互获得命令,并提供telnetlib库的一般概述。