如何用Python脚本控制TPLINK路由器
我想知道有没有什么工具可以让我连接到路由器,然后关掉它,再从一个Python脚本里重启它。
我知道如果我写:
import os
os.system("ssh -l root 192.168.2.1")
我可以通过Python连接到我的路由器。但是接下来,我不知道怎么输入路由器的密码,也不知道怎么登录进去以便重启它。
所以我在这方面研究了一下,写了下面这段代码,用来通过SSH连接到我的路由器:
import os, urllib, urllib2, re
def InterfaceControl():
#os.system("echo training")
os.system("ssh -l root 192.168.2.1")
os.system("echo yes")
os.system("echo My_ROUTER_PASSWORD")
os.system("shutdown -r")
def main():
InterfaceControl()
if __name__=="__main__":
main()
问题是,我还是无法用这段代码连接到我的路由器,而且我用来写Python脚本的编辑器IDLE还崩溃了。有没有人能帮我改进这段代码?
4 个回答
我找到了一些选项,具体取决于你使用的设备(我找不到任何关于这个API的文档,所以我猜这些都是一些人为了自己的需求而逆向工程出来的):
- menahishayan/TP-Link-Archer-C50-API 是结构最清晰的,展示了实现的cgi命令和命令的负载。以__init__.py中的主要定义为模型,我使用Wireshark抓取了使用网页界面时的API交互,这让我能很快实现我需要的命令。
- epsi95/TPLink-Python 使用起来很简单,并且展示了命令的流程。我用它来检查我发送的请求头(我漏掉了需要的referer)。不过它在我的路由器(Archer C2)上不工作,返回了HTTP状态500。
- tplink-wr-api 似乎也是一个候选项,但我在这里没有找到关于我的路由器的额外信息。
在一个Python requests.session 会话中完成所有命令是很重要的,并且确保在每次交互结束时实现路由器的“注销”功能,然后再关闭会话。如果不这样做(至少在C2上),你将无法运行进一步的命令或登录网页界面,除非等到超时或重置路由器。否则,cgi命令会返回HTTP状态403,并且你会在网页界面上看到只有一个管理员可以同时登录的消息。
我觉得你可以查看路由器的管理页面,看看它发送了哪些参数。在你的脚本中,你可以模仿这些参数。
我认为大多数路由器在使用https时会采用基本的身份验证。
补充一下:我找到了这个。
wget -qO- --user=admin --password=admin-password http://192.168.1.2/userRpm/SysRebootRpm.htm?Reboot=Reboot
来源:http://blog.taragana.com/old-code-how-to-reboot-tp-link-router-11849
我的wget手册告诉我,-q是用来安静模式的。我不知道0-是什么意思。你也可以用curl做类似的事情。注意:有些tp-link设备需要发送referer头。在curl中,例如,-H 'Referer: http://192.168.0.1'
我可以用下面的代码在python中做到同样的事情。
from urllib.request import urlopen, Request
import base64
req = Request('http://192.168.0.1/userRpm/SysRebootRpm.htm?Reboot=Reboot')
req.add_header('Authorization', ('Basic %s' % base64.b64encode('uname:pass'.encode('ascii')).decode('ascii')))
req.add_header('Referer', 'http://192.168.0.1')
urlopen(req)
这要看你的tplink设备型号和固件版本,因为不同型号的认证算法是不同的。
我写了一个Python脚本,这个脚本在我的tp link W740N上运行得很好。代码里解释了如何使用requests库在这个设备上进行认证。
#!/usr/bin/python3
# imports
from requests import get
from base64 import b64encode
from urllib.parse import quote
# constants
tplink = '192.168.0.1'
user = 'admin'
password = 'admin'
url_template = 'http://{}/userRpm/SysRebootRpm.htm?Reboot=Reboot'
if __name__ == '__main__':
auth_bytes = bytes(user+':'+password, 'utf-8')
auth_b64_bytes = b64encode(auth_bytes)
auth_b64_str = str(auth_b64_bytes, 'utf-8')
auth_str = quote('Basic {}'.format(auth_b64_str))
auth = {
'Referer': 'http://'+tplink+'/',
'Authorization': auth_str,
}
reboot_url = url_template.format(tplink)
r = get(reboot_url, headers=auth)