注意

不保证能使用,修复原理很简单:反复重启容器加网络

工具

  1. import os
  2. import sys
  3. import re
  4. containersNames = [
  5. "ctfd_ctfd_1", "ctfd_cache_1", "ctfd_db_1", "ctfd_frpc_1", "frp-docker-for-ctfd-whale_frps_1"
  6. ]
  7. containersIDs = {
  8. "ctfd_ctfd_1": "",
  9. "ctfd_cache_1": "",
  10. "ctfd_db_1": "",
  11. "ctfd_frpc_1": "",
  12. "frp-docker-for-ctfd-whale_frps_1": ""
  13. }
  14. # 存放的值为running或exited或restarting,代表容器目前状态
  15. containersStatus = {
  16. "ctfd_ctfd_1": "",
  17. "ctfd_cache_1": "",
  18. "ctfd_db_1": "",
  19. "ctfd_frpc_1": "",
  20. "frp-docker-for-ctfd-whale_frps_1": ""
  21. }
  22. # 存放的值为info或error,代表容器目前网络正常与否
  23. networkStatus = {
  24. "ctfd_ctfd_1": "",
  25. "ctfd_frpc_1": "",
  26. "frp-docker-for-ctfd-whale_frps_1": ""
  27. }
  28. IPcontainers = {
  29. "172.1.0.2": "ctfd_ctfd_1",
  30. "172.1.0.3": "ctfd_frpc_1",
  31. "172.1.0.4": "frp-docker-for-ctfd-whale_frps_1"
  32. }
  33. containersIP = {
  34. "ctfd_ctfd_1": "172.1.0.2",
  35. "ctfd_frpc_1": "172.1.0.3",
  36. "frp-docker-for-ctfd-whale_frps_1": "172.1.0.4"
  37. }
  38. ctfdPort = "8000"
  39. def addContainerNetwork():
  40. global networkStatus
  41. global containersIP
  42. if getNetworkStatus():
  43. return
  44. for name in networkStatus:
  45. if networkStatus[name] != "info":
  46. cmd = "sudo docker network connect --ip {} ctfd_frp {}".format(containersIP[name], name)
  47. os.popen(cmd).read().strip()
  48. getNetworkStatus()
  49. def restartContainer():
  50. global containersNames
  51. global containersStatus
  52. if getContainersStatus():
  53. return
  54. for name in containersNames:
  55. if containersStatus[name] != "running":
  56. cmd1 = "sudo docker stop {}".format(name)
  57. cmd2 = "sudo docker start {}".format(name)
  58. os.popen(cmd1).read().strip()
  59. os.popen(cmd2).read().strip()
  60. getContainersStatus()
  61. def fixNetwork():
  62. fixTimes = 0
  63. while check_is_fixed() or fixTimes < 10:
  64. print("[Info] 第{}次修复进行中......".format(fixTimes + 1))
  65. restartContainer()
  66. addContainerNetwork()
  67. restartContainer()
  68. fixTimes += 1
  69. if check_is_fixed():
  70. print("[Info] 修复成功!")
  71. return True
  72. else:
  73. print("[Error] 修复失败!")
  74. return False
  75. def getCTFdPort():
  76. global ctfdPort
  77. cmd = "sudo docker port ctfd_ctfd_1"
  78. result = os.popen(cmd).read().strip()
  79. res = re.findall("\d+", result)
  80. ctfdPort = res[-1]
  81. return ctfdPort
  82. def check_is_fixed():
  83. global containersStatus
  84. global containersNames
  85. print("[Info] 正在检查CTFd状态......")
  86. isNormal = True
  87. for name in containersNames:
  88. if containersStatus[name] != "running":
  89. isNormal = False
  90. print("[Warning] 容器" + name + "目前状态异常:" + containersStatus[name])
  91. cmd = "sudo curl --max-time 3 http://127.0.0.1:{}".format(ctfdPort)
  92. result = os.popen(cmd).read().strip()
  93. if "timed out" in result or "Connection reset by peer" in result:
  94. print("[Warning] 靶场目前仍然无法访问")
  95. isNormal = False
  96. if "CTFd" in result:
  97. print("[Info] 靶场目前可以正常访问")
  98. sys.exit(0)
  99. if isNormal:
  100. print("[Info] CTFd目前状态似乎正常")
  101. return isNormal
  102. def getContainersStatus():
  103. # print("[Info] 正在获取容器状态......")
  104. global containersStatus
  105. for name in containersNames:
  106. cmdExited = "sudo docker ps -aq --filter name={} --filter status=exited".format(name)
  107. cmdRunning = "sudo docker ps -aq --filter name={} --filter status=running".format(name)
  108. cmdRestarting = "sudo docker ps -aq --filter name={} --filter status=restarting".format(name)
  109. resExited = os.popen(cmdExited).read().strip()
  110. resRunning = os.popen(cmdRunning).read().strip()
  111. resRestarting = os.popen(cmdRestarting).read().strip()
  112. if len(resExited) != 0:
  113. containersStatus[name] = "exited"
  114. if len(resRunning) != 0:
  115. containersStatus[name] = "running"
  116. if len(resRestarting) != 0:
  117. containersStatus[name] = "restarting"
  118. # print("[Info] 成功获取容器状态")
  119. for name in containersStatus:
  120. if containersStatus[name] != "running":
  121. return False
  122. return True
  123. def getNetworkStatus():
  124. # print("[Info] 正在获取容器网络的信息......")
  125. for i in range(2, 5):
  126. cmd = "sudo docker network inspect ctfd_frp | grep 172.1.0{}".format(str(i))
  127. result = os.popen(cmd).read().strip()
  128. if "172.1.0.{}".format(str(i)) not in result:
  129. networkStatus[IPcontainers["172.1.0.{}".format(str(i))]] = "error"
  130. else:
  131. networkStatus[IPcontainers["172.1.0.{}".format(str(i))]] = "info"
  132. for name in networkStatus:
  133. if networkStatus[name] != "info":
  134. return False
  135. return True
  136. # print("[Info] 成功获取容器网络信息")
  137. def getContainersID():
  138. # print("[Info] 正在获取容器的ID......")
  139. global containersNames
  140. for name in containersNames:
  141. cmd = "sudo docker ps -aq --filter name={}".format(name)
  142. result = os.popen(cmd).read().strip()
  143. if result.isspace():
  144. return False
  145. containersIDs[name] = result
  146. # print("[Info] 成功获取容器的ID")
  147. return True
  148. def check_is_same_mode():
  149. global containersNames
  150. for name in containersNames:
  151. cmd = "sudo docker ps -a | grep {}".format(name)
  152. result = os.popen(cmd).read()
  153. if name not in result:
  154. return False
  155. return True
  156. def check_is_install_apt():
  157. result = os.popen("curl").read().strip()
  158. if "not found" in result:
  159. return False
  160. return True
  161. def check_is_root():
  162. user = os.geteuid()
  163. if user != 0:
  164. return False
  165. return True
  166. if __name__ == "__main__":
  167. if check_is_root() is not True:
  168. print("[Error] 请用root用户执行该脚本")
  169. sys.exit(1)
  170. if check_is_install_apt() is not True:
  171. print("[Error] 请手动安装curl工具")
  172. sys.exit(1)
  173. if check_is_same_mode() is not True:
  174. print("[Error] 此脚本不适用于当前所在环境")
  175. sys.exit(1)
  176. if getContainersID() is not True:
  177. print("[Error] 无法正确获取容器ID")
  178. sys.exit(1)
  179. getCTFdPort()
  180. getContainersStatus()
  181. getNetworkStatus()
  182. fixNetwork()

Check-CTFd-Docker-Network.py