注意
不保证能使用,修复原理很简单:反复重启容器加网络
工具
import osimport sysimport recontainersNames = ["ctfd_ctfd_1", "ctfd_cache_1", "ctfd_db_1", "ctfd_frpc_1", "frp-docker-for-ctfd-whale_frps_1"]containersIDs = {"ctfd_ctfd_1": "","ctfd_cache_1": "","ctfd_db_1": "","ctfd_frpc_1": "","frp-docker-for-ctfd-whale_frps_1": ""}# 存放的值为running或exited或restarting,代表容器目前状态containersStatus = {"ctfd_ctfd_1": "","ctfd_cache_1": "","ctfd_db_1": "","ctfd_frpc_1": "","frp-docker-for-ctfd-whale_frps_1": ""}# 存放的值为info或error,代表容器目前网络正常与否networkStatus = {"ctfd_ctfd_1": "","ctfd_frpc_1": "","frp-docker-for-ctfd-whale_frps_1": ""}IPcontainers = {"172.1.0.2": "ctfd_ctfd_1","172.1.0.3": "ctfd_frpc_1","172.1.0.4": "frp-docker-for-ctfd-whale_frps_1"}containersIP = {"ctfd_ctfd_1": "172.1.0.2","ctfd_frpc_1": "172.1.0.3","frp-docker-for-ctfd-whale_frps_1": "172.1.0.4"}ctfdPort = "8000"def addContainerNetwork():global networkStatusglobal containersIPif getNetworkStatus():returnfor name in networkStatus:if networkStatus[name] != "info":cmd = "sudo docker network connect --ip {} ctfd_frp {}".format(containersIP[name], name)os.popen(cmd).read().strip()getNetworkStatus()def restartContainer():global containersNamesglobal containersStatusif getContainersStatus():returnfor name in containersNames:if containersStatus[name] != "running":cmd1 = "sudo docker stop {}".format(name)cmd2 = "sudo docker start {}".format(name)os.popen(cmd1).read().strip()os.popen(cmd2).read().strip()getContainersStatus()def fixNetwork():fixTimes = 0while check_is_fixed() or fixTimes < 10:print("[Info] 第{}次修复进行中......".format(fixTimes + 1))restartContainer()addContainerNetwork()restartContainer()fixTimes += 1if check_is_fixed():print("[Info] 修复成功!")return Trueelse:print("[Error] 修复失败!")return Falsedef getCTFdPort():global ctfdPortcmd = "sudo docker port ctfd_ctfd_1"result = os.popen(cmd).read().strip()res = re.findall("\d+", result)ctfdPort = res[-1]return ctfdPortdef check_is_fixed():global containersStatusglobal containersNamesprint("[Info] 正在检查CTFd状态......")isNormal = Truefor name in containersNames:if containersStatus[name] != "running":isNormal = Falseprint("[Warning] 容器" + name + "目前状态异常:" + containersStatus[name])cmd = "sudo curl --max-time 3 http://127.0.0.1:{}".format(ctfdPort)result = os.popen(cmd).read().strip()if "timed out" in result or "Connection reset by peer" in result:print("[Warning] 靶场目前仍然无法访问")isNormal = Falseif "CTFd" in result:print("[Info] 靶场目前可以正常访问")sys.exit(0)if isNormal:print("[Info] CTFd目前状态似乎正常")return isNormaldef getContainersStatus():# print("[Info] 正在获取容器状态......")global containersStatusfor name in containersNames:cmdExited = "sudo docker ps -aq --filter name={} --filter status=exited".format(name)cmdRunning = "sudo docker ps -aq --filter name={} --filter status=running".format(name)cmdRestarting = "sudo docker ps -aq --filter name={} --filter status=restarting".format(name)resExited = os.popen(cmdExited).read().strip()resRunning = os.popen(cmdRunning).read().strip()resRestarting = os.popen(cmdRestarting).read().strip()if len(resExited) != 0:containersStatus[name] = "exited"if len(resRunning) != 0:containersStatus[name] = "running"if len(resRestarting) != 0:containersStatus[name] = "restarting"# print("[Info] 成功获取容器状态")for name in containersStatus:if containersStatus[name] != "running":return Falsereturn Truedef getNetworkStatus():# print("[Info] 正在获取容器网络的信息......")for i in range(2, 5):cmd = "sudo docker network inspect ctfd_frp | grep 172.1.0{}".format(str(i))result = os.popen(cmd).read().strip()if "172.1.0.{}".format(str(i)) not in result:networkStatus[IPcontainers["172.1.0.{}".format(str(i))]] = "error"else:networkStatus[IPcontainers["172.1.0.{}".format(str(i))]] = "info"for name in networkStatus:if networkStatus[name] != "info":return Falsereturn True# print("[Info] 成功获取容器网络信息")def getContainersID():# print("[Info] 正在获取容器的ID......")global containersNamesfor name in containersNames:cmd = "sudo docker ps -aq --filter name={}".format(name)result = os.popen(cmd).read().strip()if result.isspace():return FalsecontainersIDs[name] = result# print("[Info] 成功获取容器的ID")return Truedef check_is_same_mode():global containersNamesfor name in containersNames:cmd = "sudo docker ps -a | grep {}".format(name)result = os.popen(cmd).read()if name not in result:return Falsereturn Truedef check_is_install_apt():result = os.popen("curl").read().strip()if "not found" in result:return Falsereturn Truedef check_is_root():user = os.geteuid()if user != 0:return Falsereturn Trueif __name__ == "__main__":if check_is_root() is not True:print("[Error] 请用root用户执行该脚本")sys.exit(1)if check_is_install_apt() is not True:print("[Error] 请手动安装curl工具")sys.exit(1)if check_is_same_mode() is not True:print("[Error] 此脚本不适用于当前所在环境")sys.exit(1)if getContainersID() is not True:print("[Error] 无法正确获取容器ID")sys.exit(1)getCTFdPort()getContainersStatus()getNetworkStatus()fixNetwork()
