/
c3mc-base-bastion-addauth-qizhi
executable file
·115 lines (90 loc) · 3.63 KB
/
c3mc-base-bastion-addauth-qizhi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env /data/Software/mydan/python3/bin/python3
# -*- coding: utf-8 -*-
import subprocess
import json
import requests
import socket
import sys
from urllib.parse import urljoin, urlparse
sys.path.append("/data/Software/mydan/Connector/lib/pp")
from c3mc_utils import get_instance_info_list, generate_password
def test_connection(ip, port):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(3)
sock.connect((ip, port))
return True
except socket.error as e:
return False
finally:
sock.close()
def extract_ip_port(url_str):
if not url_str.startswith("http://") and not url_str.startswith("https://"):
url_str = f"http://{url_str}"
url = urlparse(url_str)
if not url.hostname or not url.port:
raise ValueError("Invalid URL format")
return url.hostname, url.port
def main(add_type, username, email, ip, sudo_hours, is_audit):
"""添加服务器权限
Args:
add_type (int): 权限处理类型。1: 添加普通权限; 2: 删除权限; 3: 添加sudo权限; 4: 删除sudo权限(保留账户)
username (str): 用户账户名
email (str): 用户邮箱
ip (str): 目标IP
sudo_hours (int): sudo权限小时数, 申请普通权限时该参数传0
"""
proxy_addr_list = subprocess.getoutput("c3mc-sys-ctl sys.bl.sync.qizhi.proxy_addr_list").strip().split(",")
app_name = subprocess.getoutput("c3mc-sys-ctl sys.bl.sync.app_name").strip()
app_key = subprocess.getoutput("c3mc-sys-ctl sys.bl.sync.app_key").strip()
instance_info_list = get_instance_info_list([ip])
request_data = {
"command": "qizhi-bastion",
"arguments": json.dumps(
{
"add_type": add_type,
"username": username,
"email": email,
"ip": ip,
"instance_id": instance_info_list[0]["instanceId"],
"sudo_hours": sudo_hours,
"password": generate_password(15, False),
"is_audit": is_audit,
}
),
}
headers = {
'Content-Type': 'application/json'
}
if app_name != "":
headers["app_name"] = app_name
if app_key != "":
headers["app_key"] = app_key
ok = False
for proxy_addr in proxy_addr_list:
print("使用代理地址........................................")
ip, port = extract_ip_port(proxy_addr)
connection_ok = test_connection(ip, port)
print(f"测试代理服务连通性 {proxy_addr}, 结果 {'成功' if connection_ok else '失败'}")
api_addr = urljoin(proxy_addr.strip(), "/run")
res = requests.request(
"POST", api_addr, headers=headers, data=json.dumps(request_data))
print(f"请求代理地址 {proxy_addr}")
print(f"请求代理时, 调用的参数为: {json.dumps(request_data)}")
# 下面解析中使用的诸如 info、output、data等字段是在 Connector/pp/bl/proxy/main.go 中定义的
try:
# 命令调用成功时的响应
print(f"响应: {json.loads(res.text)['data']}")
except Exception as e:
# 命令调用失败时的响应
print(f"响应: {json.loads(json.loads(res.text)['info'])['output']}")
print("\n\n")
data = json.loads(res.text)
# 通过一个代理执行成功后直接退出
if data["stat"] == 1:
ok = True
break
if not ok:
exit(1)
if __name__ == '__main__':
main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])