最近在捣鼓逆向的同时沉迷于Github Workflow,总想利用它来整点骚东西,遂有此文。
前言
以Windows系统为例,让我们来看一下,假设不换DNS查询服务器,当要访问的一个网站被DNS污染的时候,我们是如何人工解决的。
- 第一步,找一个海外的机器,尝试DNS解析得出ip
举例,最简单的一个做法,找个工具站ping域名就行。- 打开站长工具
- 输入域名,仅勾选海外即可
- 查询即可得出结果
-
第二步,更改本机hosts
编辑C:\Windows\System32\drivers\etc\hosts
- 第三步,刷新缓存
win
+R
键打开运行- 输入
cmd
,回车 - 输入
ipconfig /flushdns
,回车
问题与思路
当我有很多域名,每个域名都这么执行第一步,其实也挺麻烦的,该如何实现python的自动化批量操作呢?
- 直接DNS查询
先安装库:pip install dnspython
然后直接上码:
import dns.resolver def get_ip(domain): ip_list = [] try: cn = dns.resolver.query(domain, 'CNAME') for i in cn.response.answer: for j in i.items: cname_domain = j.to_text() except: pass else: A = dns.resolver.query(cname_domain.rstrip('.'), 'A') for i in A.response.answer: for j in i.items: ip_list.append(j.address) try: A = dns.resolver.query(domain, 'A') for i in A.response.answer: for j in i.items: print(j) ip_list.append(j.address) except: pass if ip_list == []: return None else: return ip_list[0] if __name__ == '__main__': ip = get_ip('www.baidu.com') print(ip)
缺点是需要额外安装库,同时由于DNS查询是UDP发包,单次很容易就抛出异常。
-
直接ping
调用系统的ping命令,然后从回复获取ipimport subprocess import re import locale import platform def ping(domain): ip = [] if platform.system() == "Windows": cmd = u"ping %s -n 1" % domain else: cmd = u"ping %s -c 1" % domain p = subprocess.Popen(cmd, stdout=subprocess.PIPE) line = p.stdout.readline().decode(locale.getpreferredencoding()) while len(line) > 0: line = p.stdout.readline().decode(locale.getpreferredencoding()) if ip == []: ip = re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', line) if ip == []: return None else: return ip[0] if __name__ == '__main__': ip = ping('www.baidu.com') print(ip)
缺点是系统可能没有ping工具,而安装可能又没有权限。例如github的workflow的Ubuntu虚拟机冇这个功能,安装报错…
apt-get install iputils-ping
-
巧妙利用socket转换
直接上码#!/usr/bin/env python # coding:utf-8 import socket if __name__ == '__main__': ip = socket.gethostbyname('www.baidu.com') print(ip)
部署与实现
-
如何将workflow的运行结果呈现出来,这里有几种思路。
放到工程本身、放到issue,以及放到release。
放到工程里面,每次提交都会产生commit,影响正常的数据统计;放到release里面也感觉怪怪的;感觉issue区是个交流展示的好地方。 - 如何触发workflow的工作流,这里有几种思路。
- 周期性触发
√
- 通过PUSH/PR来人工触发event
X
(PUSH需要权限,而PR感觉麻烦,还要fork什么的 - 打开issue
√
正好结果直接回复到相应issue中
- 周期性触发
-
周期性关闭已打开的有label的issue,并新建issue打上标签
name: CreateIssue on: schedule: - cron: '1 0 1,16 * *' jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Python 3.8 uses: actions/setup-python@v1 with: python-version: 3.8 - name: Generate github hosts run: | python socket_query.py cat hosts.txt - name: Close issues of hosts label uses: actions/github-script@0.4.0 with: github-token: $ script: | let response = await github.issues.listForRepo({ owner: context.repo.owner, repo: context.repo.repo, labels: ['host'], state: 'open' }); let data = response['data']; data.forEach(function(issue){ var id = issue['number']; github.issues.update({ owner: context.repo.owner, repo: context.repo.repo, issue_number: id, state: 'closed' }); }); - name: Create issue to show hosts uses: actions/github-script@0.4.0 with: github-token: $ script: | const date = new Date(); const year = date.getFullYear().toString(); const month = (date.getMonth() + 1).toString(); const day = date.getDate().toString(); const title = year + '-' + month + '-' + day + ' github hosts'; var fs = require("fs"); fs.readFile("hosts.txt", 'utf-8', (err, data) => { github.issues.create({ owner: context.repo.owner, repo: context.repo.repo, labels: ['host'], title: title, body: data }); });
-
用户新建issue后,自动查询并回复
name: ReplyIssueCreate on: issues: types: [opened] jobs: permission: name: permission check runs-on: ubuntu-latest if: github.actor != 'github-actions[bot]' steps: - name: check permission run: | echo $ echo permission pass build: runs-on: ubuntu-latest needs: permission steps: - uses: actions/checkout@v2 - name: Set up Python 3.8 uses: actions/setup-python@v1 with: python-version: 3.8 - name: Generate github hosts run: | python socket_query.py - uses: actions/github-script@0.4.0 with: github-token: $ script: | var fs = require("fs"); fs.readFile("hosts.txt", 'utf-8', (err, data) => { github.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body: data }); });
后续
- 源码实现 :一个周期性发布Github hosts的项目,如果担心不是最新的,支持issue自动回复–> GithubHost
- 关于Github Action的其它应用,可以看看这个–> 一次GitHub Action自动化发布集成部署