xray 设置钉钉告警

xray 扫描

xray目录为/tools/scanner/xray

1. 安装 supervisord

1
apt install supervisor

2. 设置 python 告警脚本

1
from flask import Flask, request
2
import requests
3
import json
4
import time
5
6
app = Flask(__name__)
7
8
token="XXXXXXXXXXXXXXXXXXXXXXXXXX"
9
10
headers = {'Content-Type': 'application/json;charset=utf-8'}
11
12
webhook="https://oapi.dingtalk.com/robot/send?access_token=%s"%(token)
13
14
def dingding_markdown_msg(webhook, message):
15
    time_local = time.localtime(message['create_time']/1000)
16
    stime = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
17
    data_module = '''**主机:** {name} 出现漏洞   
18
    **漏洞 url:** {url}   
19
    **漏洞 port:** {port}     
20
    **漏洞 plugin:** {plugin}      
21
    **漏洞 vuln_class:** {vuln_class}   
22
    **出现时间:** {datatime}    
23
    '''.format(name=message['detail']['host'], plugin=message['plugin'], url=message['target']['url'],
24
               port=message['detail']['port'],request1=message['detail']['request1'],
25
               request2=message['detail']['request2'],vuln_class=message['vuln_class'],datatime=stime)
26
27
    json_text = {
28
        "msgtype": "markdown",
29
        "at": {
30
            "atMobiles": [
31
            ],
32
            "isAtAll": False
33
        },
34
        "markdown": {
35
            "title":"xray 告警:%s 出现漏洞"%message['detail']['host'],
36
            "text": data_module
37
        }
38
    }
39
    try:
40
        info = requests.post(webhook, json.dumps(json_text), headers=headers).content
41
42
    except Exception as e:
43
        print(str(e))
44
45
46
@app.route('/webhook', methods=['POST'])
47
def xray_webhook():
48
    try:
49
        data = request.json
50
        dingding_markdown_msg(webhook,data)
51
    except Exception as e:
52
        print(str(e))
53
    return 'ok'
54
55
56
if __name__ == '__main__':
57
    app.run(port=7071)

3. 设置 xray 自启动脚本 /tools/scanner/xray/xray.sh

1
#!/bin/bash
2
3
cd /tools/scanner/xray/
4
[ -e "output/index.html" ] && mv output/index.html output/index-"`date +%Y%m%d%H%M%S`".html
5
./xray webscan --listen 127.0.0.1:7777 --html-output  output/index.html --webhook-output http://127.0.0.1:7071/webhook

4. Supervisor conf

1
[program:xray]
2
command=/tools/scanner/xray/xray.sh
3
user=nobody
4
autostart = true
5
autorestart=true
6
redirect_stderr=true
7
directory=/tools/scanner/xray/
8
stdout_logfile=/tools/scanner/xray/log/xray.log
9
stdout_logfile_maxbytes=20MB
10
[program:xraygaojing]
11
command=/usr/bin/python3 /tools/scanner/xray/xray_dingding.py
12
user=nobody
13
autostart = true
14
autorestart=true
15
redirect_stderr=true
16
directory=/tools/scanner/xray/
17
stdout_logfile=/tools/scanner/xray/log/xray_gaojing.log
18
stdout_logfile_maxbytes=20MB

配置 xray dnslog http 告警

1. 告警脚本

1
#!-*- coding:utf-8 -*-
2
import time
3
import json
4
import requests
5
import traceback
6
7
host="http://127.0.0.1:88"
8
token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
9
10
webhook = "https://oapi.dingtalk.com/robot/send?access_token=%s" % (token)
11
12
xray_header = {
13
    "x-token": "5a3103e6-163d-11ea-86f9-acde48001122"
14
}
15
headers = {'Content-Type': 'application/json;charset=utf-8'}
16
run_data = {"http": {"first": True, "lastid": 0}, "dns": {"first": True, "lastid": 0}}
17
18
19
def dingding_markdown_msg(webhook, message):
20
    time_local = time.localtime(message['time_stamp'] / 1000)
21
    stime = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
22
    data_module = '''**消息类型:** {event_type} 出现消息      
23
    **消息 id:** {id}    
24
    **消息 group_id:** {group_id}    
25
    **消息 remote_addr:** {remote_addr}            
26
    **消息 request:** {request}     
27
    **出现时间:** {datatime}       
28
    '''.format(id=message['id'], group_id=message['group_id'], remote_addr=message['remote_addr'],
29
               request=message['request'], event_type=message['event_type'], datatime=stime)
30
31
    json_text = {
32
        "msgtype": "markdown",
33
        "at": {
34
            "atMobiles": [
35
            ],
36
            "isAtAll": False
37
        },
38
        "markdown": {
39
            "title": u"xray 告警:%s 出现消息" % message['event_type'],
40
            "text": data_module
41
        }
42
    }
43
    try:
44
        info = requests.post(webhook, json.dumps(json_text), headers=headers).content
45
46
    except Exception as e:
47
        print(traceback.format_exc())
48
49
50
session = requests.session()
51
52
def send_msg():
53
    httprc = session.get("%s/_/api/event/list?lastID=&count=10&eventType=http&action=Next"%(host), headers=xray_header)
54
    httpdata = httprc.json()['data']['events'][0]
55
    if run_data['http']['first']:
56
        run_data['http']['first']=False
57
        run_data['http']['lastid'] = httpdata['id']
58
        print("第一次记录 http id:%s 不发送告警"%(httpdata['id']))
59
    else:
60
        if httpdata['id'] > run_data['http']['lastid']:
61
            run_data['http']['lastid'] = httpdata['id']
62
            dingding_markdown_msg(webhook,httpdata)
63
            print("发送 http message %s"%(httpdata['id']))
64
65
    dnsrc = session.get("%s//_/api/event/list?lastID=&count=10&eventType=dns&action=Next"%(host), headers=xray_header)
66
    dnsdata = dnsrc.json()['data']['events'][0]
67
    if run_data['dns']['first']:
68
        run_data['dns']['first'] = False
69
        run_data['dns']['lastid'] = dnsdata['id']
70
        print("第一次记录 dns id:%s 不发送告警" % (dnsdata['id']))
71
    else:
72
        if dnsdata['id'] > run_data['dns']['lastid']:
73
            run_data['dns']['lastid'] = dnsdata['id']
74
            dingding_markdown_msg(webhook, dnsdata)
75
            print("发送 dns message %s" % (dnsdata['id']))
76
77
if __name__ == '__main__':
78
    while True:
79
        try:
80
            send_msg()
81
        except Exception as e:
82
            print(traceback.format_exc())
83
        print("wait 5s")
84
        time.sleep(5)

2. Xray 配置文件

1
reverse:
2
  db_file_path: "/tools/scanner/xray/xray.db"
3
  token: "xxxxxxxxx"
4
  http:
5
    enabled: true
6
    listen_ip: 0.0.0.0
7
    listen_port: 88
8
  dns:
9
    enabled: true
10
    listen_ip: 0.0.0.0
11
    domain: "xxx.cc"
12
    is_domain_name_server: true
13
    # 静态解析规则
14
    resolve:
15
    - type: A
16
      record: mxx
17
      value: x5.xx.xx.1x0
18
    - type: A
19
      record: ns1
20
      value: x5.xx.xxx.1x0
21
      ttl: 60
22
    - type: A
23
      record: ns2
24
      ttl: 60
25
      value: x5.xx.xx.1x0
26
  client:
27
    http_base_url: "http://mxx.xx.cc:88"
28
    dns_server_ip: ""
29
    remote_server: false

3. 配置 supervisor

1
[program:xray]
2
command=/tools/scanner/xray/xray reverse
3
user=nobody
4
autostart = true
5
autorestart=true
6
redirect_stderr=true
7
directory=/tools/scanner/xray/
8
stdout_logfile=/tools/scanner/xray/log/xray.log
9
stdout_logfile_maxbytes=20MB
10
11
[program:xray_rec]
12
command=/usr/bin/python /tools/scanner/xray/xray_rev_ding.py
13
user=nobody
14
autostart = true
15
autorestart=true
16
redirect_stderr=true
17
directory=/tools/scanner/xray/
18
stdout_logfile=/tools/scanner/xray/log/xray_rev.log
19
stdout_logfile_maxbytes=20MB

4. 配置 nginx https 访问

1
server {
2
    listen 80;
3
     server_name mxx.xxx.cc;
4
    rewrite ^(.*) https://$host$1 permanent;
5
}
6
7
server {
8
  listen 443 ssl;
9
  server_name mxx.xxx.cc;
10
  ssl_certificate /tools/scanner/xray/mxx.xxx.cc.pem;
11
  ssl_certificate_key /tools/scanner/xray/mxx.xxx.cc.key;
12
  ssl_session_timeout 5m;
13
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
14
  ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
15
  ssl_prefer_server_ciphers on;
16
  location / {
17
18
   proxy_pass  http://127.0.0.1:88;
19
20
        #Proxy Settings
21
        proxy_set_header   Host             $host;
22
        proxy_set_header   X-Real-IP        $remote_addr;
23
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
24
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
25
        proxy_max_temp_file_size 0;
26
        proxy_connect_timeout      90;
27
        proxy_send_timeout         90;
28
        proxy_read_timeout         90;
29
        proxy_buffer_size          4k;
30
        proxy_buffers              4 32k;
31
        proxy_busy_buffers_size    64k;
32
        proxy_temp_file_write_size 64k;
33
34
    }
35
}

低权限使用1024以下端口

1
setcap cap_net_bind_service=+eip xray

设置开机自启动

1
systemctl enable supervisor
2
systemctl start supervisor