mm_os 3.3.1 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/LICENSE +21 -201
  2. package/README.md +498 -99
  3. package/README_EN.md +505 -0
  4. package/adapter/adapter.js +431 -0
  5. package/adapter/custom_persistence.js +660 -0
  6. package/adapter/mqtt.js +273 -0
  7. package/adapter/socket.js +113 -0
  8. package/adapter/web.js +67 -0
  9. package/adapter/websocket.js +146 -0
  10. package/com/api/com.json +5 -0
  11. package/{core/com → com}/api/config.tpl.json +8 -8
  12. package/com/api/drive.js +708 -0
  13. package/com/api/index.js +198 -0
  14. package/com/api/oauth.js +200 -0
  15. package/com/api/script.tpl.js +32 -0
  16. package/com/cmd/README.md +11 -0
  17. package/com/cmd/com.json +5 -0
  18. package/com/cmd/config.tpl.json +122 -0
  19. package/com/cmd/drive.js +1548 -0
  20. package/com/cmd/index.js +1066 -0
  21. package/com/cmd/msg.json +48 -0
  22. package/com/cmd/nlp.js +525 -0
  23. package/com/cmd/script.tpl.js +32 -0
  24. package/com/db/com.json +5 -0
  25. package/com/db/drive.js +1999 -0
  26. package/com/db/index.js +242 -0
  27. package/{core/com → com}/event/README.md +4 -4
  28. package/com/event/com.json +5 -0
  29. package/{core/com → com}/event/config.tpl.json +18 -18
  30. package/com/event/drive.js +59 -0
  31. package/com/event/index.js +409 -0
  32. package/com/event/script.tpl.js +23 -0
  33. package/com/mqtt/com.json +5 -0
  34. package/{core/com → com}/mqtt/config.tpl.json +3 -5
  35. package/com/mqtt/drive.js +676 -0
  36. package/com/mqtt/index.js +822 -0
  37. package/com/mqtt/mm_mqtt.js +425 -0
  38. package/com/mqtt/script.tpl.js +723 -0
  39. package/com/nav/com.json +5 -0
  40. package/com/nav/config.tpl.json +84 -0
  41. package/com/nav/drive.js +702 -0
  42. package/com/nav/index.js +231 -0
  43. package/{core/com → com}/nav/tpl/admin_pc/page_config.vue +280 -280
  44. package/{core/com → com}/nav/tpl/admin_pc/page_config_form.vue +194 -194
  45. package/com/nav/tpl/admin_pc/page_form.vue +180 -0
  46. package/com/nav/tpl/admin_pc/page_view.vue +124 -0
  47. package/com/nav/tpl/dev_pc/page_default.vue +247 -0
  48. package/com/nav/tpl/dev_pc/page_type.vue +313 -0
  49. package/com/nav/tpl/home_pc/page_default.vue +234 -0
  50. package/com/nav/tpl/home_pc/page_form.vue +137 -0
  51. package/com/nav/tpl/home_pc/page_list.vue +234 -0
  52. package/com/nav/tpl/home_pc/page_nav.vue +221 -0
  53. package/com/nav/tpl/home_pc/page_type.vue +234 -0
  54. package/com/nav/tpl/home_pc/page_view.vue +125 -0
  55. package/com/nav/tpl/home_phone/page_channel.vue +234 -0
  56. package/com/nav/tpl/home_phone/page_default.vue +234 -0
  57. package/com/nav/tpl/home_phone/page_form.vue +137 -0
  58. package/com/nav/tpl/home_phone/page_nav.vue +237 -0
  59. package/com/nav/tpl/home_phone/page_type.vue +234 -0
  60. package/com/nav/tpl/home_phone/page_view.vue +125 -0
  61. package/com/nav/viewmodel.js +446 -0
  62. package/com/param/com.json +5 -0
  63. package/{core/com → com}/param/config.tpl.json +7 -1
  64. package/com/param/drive.js +502 -0
  65. package/com/param/index.js +155 -0
  66. package/com/param/script.tpl.js +12 -0
  67. package/com/pendant/com.json +5 -0
  68. package/{core/com/component → com/pendant}/config.tpl.json +15 -13
  69. package/com/pendant/drive.js +204 -0
  70. package/com/pendant/index.js +441 -0
  71. package/com/pendant/pendant.html +16 -0
  72. package/com/pendant/script.tpl.js +18 -0
  73. package/com/socket/com.json +5 -0
  74. package/com/socket/config.tpl.json +12 -0
  75. package/com/socket/drive.js +651 -0
  76. package/com/socket/index.js +351 -0
  77. package/com/socket/script.tpl.js +41 -0
  78. package/com/sql/com.json +5 -0
  79. package/{core/com → com}/sql/config.tpl.json +13 -9
  80. package/com/sql/drive.js +1259 -0
  81. package/com/sql/index.js +150 -0
  82. package/com/sql/script.tpl.js +47 -0
  83. package/com/static/com.json +5 -0
  84. package/{core/com → com}/static/config.tpl.json +10 -6
  85. package/com/static/drive.js +194 -0
  86. package/com/static/index.js +226 -0
  87. package/com/static/script.tpl.js +28 -0
  88. package/com/task/com.json +5 -0
  89. package/{core/com → com}/task/config.tpl.json +4 -6
  90. package/com/task/drive.js +405 -0
  91. package/com/task/index.js +148 -0
  92. package/com/task/script.tpl.js +37 -0
  93. package/com/template/com.json +5 -0
  94. package/com/template/config.tpl.json +16 -0
  95. package/com/template/drive.js +80 -0
  96. package/com/template/index.js +141 -0
  97. package/com.js +156 -0
  98. package/common/README.md +2 -0
  99. package/common/handler/msg/handler.json +22 -0
  100. package/common/handler/msg/index.js +23 -0
  101. package/common/handler/player/handler.json +22 -0
  102. package/common/handler/player/index.js +287 -0
  103. package/common/handler/user/handler.json +22 -0
  104. package/common/handler/user/index.js +23 -0
  105. package/common/middleware/web_after/index.js +29 -0
  106. package/common/middleware/web_after/middleware.json +9 -0
  107. package/common/middleware/web_base/index.js +113 -0
  108. package/common/middleware/web_base/middleware.json +19 -0
  109. package/common/middleware/web_before/index.js +33 -0
  110. package/common/middleware/web_before/middleware.json +9 -0
  111. package/common/middleware/web_cors/index.js +87 -0
  112. package/common/middleware/web_cors/middleware.json +24 -0
  113. package/common/middleware/web_error/index.js +119 -0
  114. package/common/middleware/web_error/middleware.json +18 -0
  115. package/common/middleware/web_ip/index.js +15 -0
  116. package/common/middleware/web_ip/middleware.json +14 -0
  117. package/common/middleware/web_logger/index.js +156 -0
  118. package/common/middleware/web_logger/middleware.json +14 -0
  119. package/common/middleware/web_main/index.js +24 -0
  120. package/common/middleware/web_main/middleware.json +9 -0
  121. package/common/middleware/web_static/index.js +73 -0
  122. package/common/middleware/web_static/middleware.json +54 -0
  123. package/common/middleware/web_waf/index.js +385 -0
  124. package/common/middleware/web_waf/middleware.json +13 -0
  125. package/common/model/msg/index.js +88 -0
  126. package/common/model/msg/model.json +401 -0
  127. package/common/model/player/index.js +63 -0
  128. package/common/model/player/model.json +185 -0
  129. package/common/model/user/index.js +11 -0
  130. package/common/model/user/model.json +219 -0
  131. package/core/app/config.tpl.json +67 -0
  132. package/core/app/index.js +632 -0
  133. package/core/app/script.tpl.js +52 -0
  134. package/core/channel/index.js +899 -0
  135. package/core/channel/matcher.js +585 -0
  136. package/core/com/config.tpl.json +16 -0
  137. package/core/com/index.js +74 -0
  138. package/core/com/script.tpl.js +5 -0
  139. package/core/component/component.js +42 -0
  140. package/core/component/config.tpl.json +63 -0
  141. package/core/component/index.js +273 -0
  142. package/core/component/script.tpl.js +19 -0
  143. package/core/controller/config.tpl.json +14 -0
  144. package/core/controller/index.js +373 -0
  145. package/core/controller/script.tpl.js +27 -0
  146. package/core/factory/config.tpl.json +14 -0
  147. package/core/factory/entity.js +275 -0
  148. package/core/factory/index.js +241 -0
  149. package/core/factory/script.tpl.js +16 -0
  150. package/core/game/bat/index.js +137 -0
  151. package/core/game/bat/world.js +622 -0
  152. package/core/game/config.tpl.json +16 -0
  153. package/core/game/entity_admin.js +230 -0
  154. package/core/game/index.js +186 -0
  155. package/core/handler/config.tpl.json +22 -0
  156. package/core/handler/index.js +181 -0
  157. package/core/handler/script.tpl.js +23 -0
  158. package/core/logic/config.tpl.json +14 -0
  159. package/core/logic/index.js +59 -0
  160. package/core/logic/script.tpl.js +19 -0
  161. package/core/middleware/config.tpl.json +16 -0
  162. package/core/middleware/index.js +125 -0
  163. package/core/middleware/script.tpl.js +37 -0
  164. package/core/mod/config.tpl.json +22 -0
  165. package/core/mod/index.js +130 -0
  166. package/core/mod/script.tpl.js +34 -0
  167. package/core/model/config.tpl.json +219 -0
  168. package/core/model/index.js +272 -0
  169. package/core/model/model.js +27 -0
  170. package/core/model/script.tpl.js +20 -0
  171. package/core/notifier/config.tpl.json +14 -0
  172. package/core/notifier/index.js +77 -0
  173. package/core/notifier/script.tpl.js +20 -0
  174. package/core/plugin/config.tpl.json +24 -0
  175. package/core/plugin/index.js +232 -0
  176. package/core/plugin/script.tpl.js +51 -0
  177. package/core/pusher/config.tpl.json +14 -0
  178. package/core/pusher/index.js +161 -0
  179. package/core/pusher/script.tpl.js +20 -0
  180. package/core/room/bat/index.js +170 -0
  181. package/core/room/bat/room.js +524 -0
  182. package/core/room/config.tpl.json +20 -0
  183. package/core/room/index.js +249 -0
  184. package/core/room/room.js +61 -0
  185. package/core/scene/config.tpl.json +14 -0
  186. package/core/scene/index.js +466 -0
  187. package/core/scene/loop.js +1255 -0
  188. package/core/scene/map.js +28 -0
  189. package/core/scene/script.tpl.js +22 -0
  190. package/core/sender/config.tpl.json +14 -0
  191. package/core/sender/index.js +79 -0
  192. package/core/sender/script.tpl.js +20 -0
  193. package/core/service/config.tpl.json +14 -0
  194. package/core/service/index.js +100 -0
  195. package/core/service/script.tpl.js +25 -0
  196. package/core/store/config.tpl.json +26 -0
  197. package/core/store/index.js +1755 -0
  198. package/core/store/script.tpl.js +22 -0
  199. package/core/store/sql.js +1464 -0
  200. package/core/system/config.tpl.json +18 -0
  201. package/core/system/index.js +312 -0
  202. package/core/system/script.tpl.js +77 -0
  203. package/core/view/config.tpl.json +14 -0
  204. package/core/view/index.js +91 -0
  205. package/core/view/script.tpl.js +20 -0
  206. package/core/zone/bat/index.js +725 -0
  207. package/core/zone/config.tpl.json +54 -0
  208. package/core/zone/index.js +614 -0
  209. package/core/zone/script.tpl.js +10 -0
  210. package/core/zone/zone_bat.js +136 -0
  211. package/core//345/237/272/347/261/273/346/250/241/345/235/227/346/270/205/345/215/225.md +24 -0
  212. package/index.js +17 -333
  213. package/os.js +57 -0
  214. package/package.json +65 -55
  215. package/server.js +598 -0
  216. package/README.en.md +0 -36
  217. package/conf.json +0 -3
  218. package/core/base/mqtt/index.js +0 -1110
  219. package/core/base/mqtt/lib.js +0 -40
  220. package/core/base/web/index.js +0 -245
  221. package/core/com/api/com.json +0 -4
  222. package/core/com/api/drive.js +0 -668
  223. package/core/com/api/index.js +0 -108
  224. package/core/com/api/oauth.js +0 -158
  225. package/core/com/api/script.js +0 -32
  226. package/core/com/app/README.md +0 -3
  227. package/core/com/app/com.json +0 -4
  228. package/core/com/app/config.tpl.json +0 -16
  229. package/core/com/app/drive.js +0 -309
  230. package/core/com/app/index.js +0 -211
  231. package/core/com/app/script.js +0 -155
  232. package/core/com/cmd/com.json +0 -4
  233. package/core/com/cmd/config.tpl.json +0 -66
  234. package/core/com/cmd/drive.js +0 -513
  235. package/core/com/cmd/index.js +0 -354
  236. package/core/com/cmd/old/5w2h.js +0 -54
  237. package/core/com/cmd/old/drive.js +0 -423
  238. package/core/com/cmd/script.js +0 -11
  239. package/core/com/component/README.md +0 -3
  240. package/core/com/component/com.json +0 -4
  241. package/core/com/component/component.html +0 -16
  242. package/core/com/component/drive.js +0 -197
  243. package/core/com/component/index.js +0 -312
  244. package/core/com/component/script.js +0 -18
  245. package/core/com/db/com.json +0 -4
  246. package/core/com/db/drive.js +0 -1160
  247. package/core/com/db/index.js +0 -176
  248. package/core/com/event/com.json +0 -4
  249. package/core/com/event/drive.js +0 -133
  250. package/core/com/event/index.js +0 -345
  251. package/core/com/event/script.js +0 -26
  252. package/core/com/eventer/com.js +0 -477
  253. package/core/com/eventer/com.json +0 -4
  254. package/core/com/middleware/com.js +0 -154
  255. package/core/com/middleware/com.json +0 -4
  256. package/core/com/middleware/config.tpl.json +0 -8
  257. package/core/com/middleware/script.js +0 -9
  258. package/core/com/mqtt/com.json +0 -4
  259. package/core/com/mqtt/drive.js +0 -600
  260. package/core/com/mqtt/index.js +0 -572
  261. package/core/com/mqtt/mm_mqtt.js +0 -330
  262. package/core/com/mqtt/script.js +0 -604
  263. package/core/com/msg/com.js +0 -296
  264. package/core/com/msg/com.json +0 -4
  265. package/core/com/nav/com.json +0 -4
  266. package/core/com/nav/config.tpl.json +0 -75
  267. package/core/com/nav/drive.js +0 -549
  268. package/core/com/nav/index.js +0 -182
  269. package/core/com/nav/tpl/admin_pc/page_form.vue +0 -180
  270. package/core/com/nav/tpl/admin_pc/page_view.vue +0 -124
  271. package/core/com/nav/tpl/dev_pc/page_default.vue +0 -247
  272. package/core/com/nav/tpl/dev_pc/page_type.vue +0 -313
  273. package/core/com/nav/tpl/home_pc/page_default.vue +0 -234
  274. package/core/com/nav/tpl/home_pc/page_form.vue +0 -137
  275. package/core/com/nav/tpl/home_pc/page_list.vue +0 -234
  276. package/core/com/nav/tpl/home_pc/page_nav.vue +0 -221
  277. package/core/com/nav/tpl/home_pc/page_type.vue +0 -234
  278. package/core/com/nav/tpl/home_pc/page_view.vue +0 -125
  279. package/core/com/nav/tpl/home_phone/page_channel.vue +0 -234
  280. package/core/com/nav/tpl/home_phone/page_default.vue +0 -234
  281. package/core/com/nav/tpl/home_phone/page_form.vue +0 -137
  282. package/core/com/nav/tpl/home_phone/page_nav.vue +0 -237
  283. package/core/com/nav/tpl/home_phone/page_type.vue +0 -234
  284. package/core/com/nav/tpl/home_phone/page_view.vue +0 -125
  285. package/core/com/nav/viewmodel.js +0 -296
  286. package/core/com/param/drive.js +0 -366
  287. package/core/com/param/index.js +0 -80
  288. package/core/com/param/script.js +0 -12
  289. package/core/com/param/test.js +0 -98
  290. package/core/com/plugin/README.md +0 -3
  291. package/core/com/plugin/com.json +0 -4
  292. package/core/com/plugin/config.tpl.json +0 -26
  293. package/core/com/plugin/drive.js +0 -536
  294. package/core/com/plugin/index.js +0 -259
  295. package/core/com/plugin/script.js +0 -213
  296. package/core/com/rpc/com.json +0 -4
  297. package/core/com/rpc/drive.js +0 -160
  298. package/core/com/rpc/index.js +0 -87
  299. package/core/com/rpc/rpc.js +0 -118
  300. package/core/com/socket/com.json +0 -4
  301. package/core/com/socket/config.tpl.json +0 -14
  302. package/core/com/socket/drive.js +0 -403
  303. package/core/com/socket/index.js +0 -62
  304. package/core/com/socket/script.js +0 -42
  305. package/core/com/sql/drive.js +0 -1087
  306. package/core/com/sql/index.js +0 -83
  307. package/core/com/sql/script.js +0 -48
  308. package/core/com/static/com.json +0 -4
  309. package/core/com/static/drive.js +0 -220
  310. package/core/com/static/index.js +0 -149
  311. package/core/com/static/script.js +0 -28
  312. package/core/com/task/com.json +0 -4
  313. package/core/com/task/drive.js +0 -403
  314. package/core/com/task/index.js +0 -110
  315. package/core/com/task/script.js +0 -37
  316. package/core/com/timer/com.js +0 -217
  317. package/core/com/timer/com.json +0 -4
  318. package/core/com/tpl/com.js +0 -19
  319. package/core/com/tpl/com.json +0 -4
  320. package/lib/actions.js +0 -50
  321. package/lib/base.js +0 -361
  322. package/lib/com.js +0 -29
  323. package/lib/ref.js +0 -121
  324. package/middleware/cors/index.js +0 -119
  325. package/middleware/cors/middleware.json +0 -20
  326. package/middleware/csrf/index.js +0 -202
  327. package/middleware/csrf/middleware.json +0 -24
  328. package/middleware/ip_firewall/index.js +0 -476
  329. package/middleware/ip_firewall/middleware.json +0 -109
  330. package/middleware/mqtt_base/index.js +0 -10
  331. package/middleware/mqtt_base/middleware.json +0 -11
  332. package/middleware/security_audit/index.js +0 -543
  333. package/middleware/security_audit/middleware.json +0 -48
  334. package/middleware/waf/index.js +0 -343
  335. package/middleware/waf/middleware.json +0 -10
  336. package/middleware/waf_ddos/index.js +0 -520
  337. package/middleware/waf_ddos/middleware.json +0 -38
  338. package/middleware/waf_xss/index.js +0 -269
  339. package/middleware/waf_xss/middleware.json +0 -18
  340. package/middleware/web_after/index.js +0 -33
  341. package/middleware/web_after/middleware.json +0 -10
  342. package/middleware/web_base/index.js +0 -90
  343. package/middleware/web_base/middleware.json +0 -10
  344. package/middleware/web_before/index.js +0 -27
  345. package/middleware/web_before/middleware.json +0 -10
  346. package/middleware/web_check/index.js +0 -28
  347. package/middleware/web_check/middleware.json +0 -10
  348. package/middleware/web_main/index.js +0 -28
  349. package/middleware/web_main/middleware.json +0 -10
  350. package/middleware/web_proxy/index.js +0 -37
  351. package/middleware/web_proxy/middleware.json +0 -10
  352. package/middleware/web_render/index.js +0 -87
  353. package/middleware/web_render/middleware.json +0 -10
  354. package/middleware/web_socket/index.js +0 -34
  355. package/middleware/web_socket/middleware.json +0 -10
  356. package/middleware/web_static/index.js +0 -115
  357. package/middleware/web_static/middleware.json +0 -10
  358. /package/{core/com → com}/api/README.md +0 -0
  359. /package/{core/com → com}/db/README.md +0 -0
  360. /package/{core/com → com}/mqtt/README.md +0 -0
  361. /package/{core/com → com}/nav/README.md +0 -0
  362. /package/{core/com → com}/nav/tpl/admin_pc/page_channel.vue +0 -0
  363. /package/{core/com → com}/nav/tpl/admin_pc/page_default.vue +0 -0
  364. /package/{core/com → com}/nav/tpl/admin_pc/page_lang.vue +0 -0
  365. /package/{core/com → com}/nav/tpl/admin_pc/page_nav.vue +0 -0
  366. /package/{core/com → com}/nav/tpl/admin_pc/page_table.vue +0 -0
  367. /package/{core/com → com}/nav/tpl/admin_pc/page_type.vue +0 -0
  368. /package/{core/com → com}/nav/tpl/dev_pc/page_channel.vue +0 -0
  369. /package/{core/com → com}/nav/tpl/dev_pc/page_config.vue +0 -0
  370. /package/{core/com → com}/nav/tpl/dev_pc/page_form.vue +0 -0
  371. /package/{core/com → com}/nav/tpl/dev_pc/page_nav.vue +0 -0
  372. /package/{core/com → com}/nav/tpl/dev_pc/page_table.vue +0 -0
  373. /package/{core/com → com}/nav/tpl/home_pc/page_channel.vue +0 -0
  374. /package/{core/com → com}/nav/tpl/home_phone/page_list.vue +0 -0
  375. /package/{core/com → com}/param/README.md +0 -0
  376. /package/{core/com/cmd → com/pendant}/README.md +0 -0
  377. /package/{core/com → com}/socket/README.md +0 -0
  378. /package/{core/com → com}/sql/README.md +0 -0
  379. /package/{core/com → com}/static/README.md +0 -0
  380. /package/{core/com → com}/task/README.md +0 -0
@@ -1,520 +0,0 @@
1
- const mm_expand = require('mm_expand');
2
-
3
- /**
4
- * 综合流量控制与DDOS攻击防护中间件
5
- * 合并了原rate_limit和ddos_protection的功能,提供全面的流量防护机制
6
- */
7
- class Middleware {
8
- /**
9
- * 构造函数
10
- */
11
- constructor() {
12
- // 内存存储,用于记录请求计数和IP信息
13
- this.ipRequestCount = new Map();
14
- this.blockedIps = new Map();
15
- this.connectionCount = new Map();
16
-
17
- this.default = {
18
- // 启用综合流量保护
19
- enable: true,
20
- // 存储方式: 'memory', 'redis'
21
- storage: 'memory',
22
- // 基于IP的速率限制
23
- ip_rate_limit: {
24
- // 时间窗口(毫秒)
25
- window_ms: 60000,
26
- // 每个IP在时间窗口内的最大请求数
27
- max_requests: 500,
28
- // 是否启用
29
- enable: true
30
- },
31
- // 基于路径的速率限制
32
- path_rate_limit: {
33
- // 时间窗口(毫秒)
34
- window_ms: 60000,
35
- // 每个IP对每个路径在时间窗口内的最大请求数
36
- max_requests: 250,
37
- // 是否启用
38
- enable: true
39
- },
40
- // 连接限制
41
- connection_limit: {
42
- // 单个IP的最大并发连接数
43
- max_connections: 50,
44
- // 是否启用
45
- enable: true
46
- },
47
- // 阻止规则
48
- blocking: {
49
- // 触发阻止的阈值倍数
50
- threshold: 2,
51
- // 阻止时间(毫秒)
52
- block_time: 300000, // 5分钟
53
- // 是否自动解除阻止
54
- auto_unblock: true
55
- },
56
- // 白名单IP
57
- whitelist: [],
58
- // 忽略的路径(白名单路径)
59
- ignore_paths: ['/api/health', '/favicon.ico', '/static/'],
60
- // 是否记录攻击尝试
61
- log: true,
62
- // 是否阻止恶意请求
63
- block: true,
64
- // 响应状态码
65
- status_code: 429,
66
- // 响应消息
67
- response_message: '请求过于频繁,请稍后再试',
68
- // 是否设置X-RateLimit响应头
69
- set_rate_limit_headers: true
70
- };
71
- }
72
-
73
- /**
74
- * 初始化中间件
75
- * @param {Object} config 配置项
76
- */
77
- init(config) {
78
- config = Object.assign({}, this.default, config);
79
- this.config = config;
80
-
81
- // 启动清理过期数据的定时器(仅在内存存储模式下需要)
82
- if (config.storage === 'memory') {
83
- this.startCleanupTimer();
84
- }
85
-
86
- return function() {
87
- // 返回中间件的run方法作为实际的处理函数
88
- return function(ctx, next) {
89
- return middleware.run(ctx, next);
90
- };
91
- };
92
- }
93
-
94
- /**
95
- * 获取客户端真实IP
96
- * 在代理环境中,优先从代理头获取真实IP
97
- * @param {Object} ctx Koa上下文
98
- * @returns {String} 客户端真实IP
99
- */
100
- getClientIp(ctx) {
101
- const headers = ctx.headers;
102
- // 优先检查常用代理头获取真实IP
103
- const xForwardedFor = headers['x-forwarded-for'];
104
- if (xForwardedFor) {
105
- // X-Forwarded-For 格式通常为: client, proxy1, proxy2
106
- const ips = xForwardedFor.split(',').map(ip => ip.trim());
107
- for (let i = 0; i < ips.length; i++) {
108
- const ip = ips[i];
109
- if (ip && ip !== 'unknown' && ip !== '127.0.0.1' && ip !== '::1') {
110
- return ip;
111
- }
112
- }
113
- }
114
-
115
- // 检查其他常见的代理头
116
- return headers['x-real-ip'] ||
117
- headers['x-client-ip'] ||
118
- headers['cf-connecting-ip'] || // CloudFlare
119
- headers['fastly-client-ip'] || // Fastly
120
- headers['true-client-ip'] || // Akamai and Cloudflare
121
- ctx.ip; // 默认回退到ctx.ip
122
- }
123
-
124
- /**
125
- * 使用Redis存储请求计数(从rate_limit中间件合并的功能)
126
- * @param {String} clientKey 客户端标识符(通常是IP)
127
- * @param {String} prefix 键前缀
128
- * @param {Number} windowMs 时间窗口(秒)
129
- * @returns {Promise<Number>} 请求计数
130
- */
131
- async incrementRequestWithRedis(clientKey, prefix, windowMs) {
132
- try {
133
- // 检查Redis是否可用
134
- if ($.cache && typeof $.cache.addInt === 'function') {
135
- const key = `${prefix}:${clientKey}`;
136
-
137
- // 使用addInt方法增加计数(mm_redis包提供的方法)
138
- const count = await $.cache.addInt(key, 1);
139
-
140
- // 设置过期时间
141
- await $.cache.ttl(key, Math.ceil(windowMs / 1000));
142
-
143
- return count || 0;
144
- }
145
- } catch (error) {
146
- if (this.config.log && $.log && $.log.error) {
147
- $.log.error('Redis速率限制失败:', error);
148
- }
149
- }
150
-
151
- // Redis不可用时返回null,将使用内存存储
152
- return null;
153
- }
154
-
155
- /**
156
- * 执行中间件
157
- * @param {Object} ctx Koa上下文
158
- * @param {Function} next 下一个中间件
159
- */
160
- async run(ctx, next) {
161
- const config = this.config;
162
- // 使用改进的IP获取方法
163
- const ip = this.getClientIp(ctx);
164
- const path = ctx.path;
165
-
166
- if (!config.enable) {
167
- return await next();
168
- }
169
-
170
- // 检查是否在白名单中
171
- if (this.isWhitelisted(ip)) {
172
- return await next();
173
- }
174
-
175
- // 检查是否应该忽略该路径
176
- if (this.shouldIgnorePath(path)) {
177
- return await next();
178
- }
179
-
180
- // 检查IP是否被阻止
181
- if (this.isBlocked(ip)) {
182
- if (config.log && $.log && $.log.warn) {
183
- $.log.warn('Blocked IP Attempted Access:', {
184
- ip: ip,
185
- path: path,
186
- method: ctx.method
187
- });
188
- }
189
-
190
- ctx.status = config.status_code;
191
- ctx.body = {
192
- code: config.status_code,
193
- msg: config.response_message
194
- };
195
- return;
196
- }
197
-
198
- // 检查连接限制
199
- if (config.connection_limit.enable && !this.checkConnectionLimit(ip)) {
200
- this.blockIp(ip, 'Exceeded connection limit');
201
- ctx.status = config.status_code;
202
- ctx.body = {
203
- code: config.status_code,
204
- msg: config.response_message
205
- };
206
- return;
207
- }
208
-
209
- // 检查IP速率限制
210
- let requestCount = null;
211
-
212
- if (config.ip_rate_limit.enable) {
213
- if (config.storage === 'redis') {
214
- // 使用Redis进行速率限制
215
- requestCount = await this.incrementRequestWithRedis(
216
- ip,
217
- 'rate_limit',
218
- config.ip_rate_limit.window_ms
219
- );
220
-
221
- if (requestCount !== null) {
222
- // Redis成功执行了计数
223
- if (requestCount > config.ip_rate_limit.max_requests) {
224
- this.blockIp(ip, 'Exceeded IP rate limit');
225
-
226
- // 设置响应头
227
- if (config.set_rate_limit_headers) {
228
- ctx.set('X-RateLimit-Limit', config.ip_rate_limit.max_requests);
229
- ctx.set('X-RateLimit-Remaining', 0);
230
- }
231
-
232
- ctx.status = config.status_code;
233
- ctx.body = {
234
- code: config.status_code,
235
- msg: config.response_message
236
- };
237
- return;
238
- }
239
-
240
- // 设置响应头
241
- if (config.set_rate_limit_headers) {
242
- ctx.set('X-RateLimit-Limit', config.ip_rate_limit.max_requests);
243
- ctx.set('X-RateLimit-Remaining', Math.max(0, config.ip_rate_limit.max_requests -
244
- requestCount));
245
- }
246
- } else {
247
- // Redis不可用,使用内存存储方式
248
- if (!this.checkIpRateLimit(ip)) {
249
- this.blockIp(ip, 'Exceeded IP rate limit');
250
- ctx.status = config.status_code;
251
- ctx.body = {
252
- code: config.status_code,
253
- msg: config.response_message
254
- };
255
- return;
256
- }
257
- }
258
- } else {
259
- // 使用内存存储方式
260
- if (!this.checkIpRateLimit(ip)) {
261
- this.blockIp(ip, 'Exceeded IP rate limit');
262
- ctx.status = config.status_code;
263
- ctx.body = {
264
- code: config.status_code,
265
- msg: config.response_message
266
- };
267
- return;
268
- }
269
- }
270
- }
271
-
272
- // 检查路径速率限制(仅内存存储支持)
273
- if (config.path_rate_limit.enable && config.storage === 'memory') {
274
- if (!this.checkPathRateLimit(ip, path)) {
275
- this.blockIp(ip, `Exceeded path rate limit for ${path}`);
276
- ctx.status = config.status_code;
277
- ctx.body = {
278
- code: config.status_code,
279
- msg: config.response_message
280
- };
281
- return;
282
- }
283
- }
284
-
285
- // 增加连接计数
286
- this.incrementConnection(ip);
287
-
288
- try {
289
- await next();
290
- } finally {
291
- // 减少连接计数
292
- this.decrementConnection(ip);
293
- }
294
- }
295
-
296
- /**
297
- * 检查IP是否在白名单中
298
- * @param {String} ip IP地址
299
- * @returns {Boolean} 是否在白名单中
300
- */
301
- isWhitelisted(ip) {
302
- return this.config.whitelist.includes(ip);
303
- }
304
-
305
- /**
306
- * 检查是否应该忽略该路径
307
- * @param {String} path 路径
308
- * @returns {Boolean} 是否忽略
309
- */
310
- shouldIgnorePath(path) {
311
- return this.config.ignore_paths.some(p => path === p || path.startsWith(p));
312
- }
313
-
314
- /**
315
- * 检查IP是否被阻止
316
- * @param {String} ip IP地址
317
- * @returns {Boolean} 是否被阻止
318
- */
319
- isBlocked(ip) {
320
- const blocked = this.blockedIps.get(ip);
321
- if (!blocked) return false;
322
-
323
- // 如果启用了自动解除阻止
324
- if (this.config.blocking.auto_unblock) {
325
- if (Date.now() > blocked.unblock_time) {
326
- this.blockedIps.delete(ip);
327
- return false;
328
- }
329
- }
330
-
331
- return true;
332
- }
333
-
334
- /**
335
- * 阻止IP
336
- * @param {String} ip IP地址
337
- * @param {String} reason 阻止原因
338
- */
339
- blockIp(ip, reason) {
340
- if (!this.config.block) return;
341
-
342
- const blockTime = this.config.blocking.block_time;
343
- const unblockTime = Date.now() + blockTime;
344
-
345
- this.blockedIps.set(ip, {
346
- reason: reason,
347
- block_time: Date.now(),
348
- unblock_time: unblockTime
349
- });
350
-
351
- if (this.config.log && $.log && $.log.warn) {
352
- $.log.warn('IP Blocked:', {
353
- ip: ip,
354
- reason: reason,
355
- block_time: new Date().toISOString(),
356
- unblock_time: new Date(unblockTime).toISOString()
357
- });
358
- }
359
- }
360
-
361
- /**
362
- * 检查连接限制
363
- * @param {String} ip IP地址
364
- * @returns {Boolean} 是否通过检查
365
- */
366
- checkConnectionLimit(ip) {
367
- const count = this.connectionCount.get(ip) || 0;
368
- return count < this.config.connection_limit.max_connections;
369
- }
370
-
371
- /**
372
- * 增加连接计数
373
- * @param {String} ip IP地址
374
- */
375
- incrementConnection(ip) {
376
- const count = this.connectionCount.get(ip) || 0;
377
- this.connectionCount.set(ip, count + 1);
378
- }
379
-
380
- /**
381
- * 减少连接计数
382
- * @param {String} ip IP地址
383
- */
384
- decrementConnection(ip) {
385
- const count = this.connectionCount.get(ip);
386
- if (count && count > 0) {
387
- this.connectionCount.set(ip, count - 1);
388
- } else {
389
- this.connectionCount.delete(ip);
390
- }
391
- }
392
-
393
- /**
394
- * 检查IP速率限制(内存存储方式)
395
- * @param {String} ip IP地址
396
- * @returns {Boolean} 是否通过检查
397
- */
398
- checkIpRateLimit(ip) {
399
- const now = Date.now();
400
- const windowMs = this.config.ip_rate_limit.window_ms;
401
- const maxRequests = this.config.ip_rate_limit.max_requests;
402
-
403
- let requests = this.ipRequestCount.get(ip) || [];
404
-
405
- // 清理过期的请求记录
406
- requests = requests.filter(timestamp => now - timestamp < windowMs);
407
-
408
- // 检查是否超过限制
409
- if (requests.length >= maxRequests) {
410
- return false;
411
- }
412
-
413
- // 添加当前请求时间戳
414
- requests.push(now);
415
- this.ipRequestCount.set(ip, requests);
416
-
417
- return true;
418
- }
419
-
420
- /**
421
- * 检查路径速率限制(内存存储方式)
422
- * @param {String} ip IP地址
423
- * @param {String} path 路径
424
- * @returns {Boolean} 是否通过检查
425
- */
426
- checkPathRateLimit(ip, path) {
427
- const key = `${ip}:${path}`;
428
- const now = Date.now();
429
- const windowMs = this.config.path_rate_limit.window_ms;
430
- const maxRequests = this.config.path_rate_limit.max_requests;
431
-
432
- let requests = this.ipRequestCount.get(key) || [];
433
-
434
- // 清理过期的请求记录
435
- requests = requests.filter(timestamp => now - timestamp < windowMs);
436
-
437
- // 检查是否超过限制
438
- if (requests.length >= maxRequests) {
439
- return false;
440
- }
441
-
442
- // 添加当前请求时间戳
443
- requests.push(now);
444
- this.ipRequestCount.set(key, requests);
445
-
446
- return true;
447
- }
448
-
449
- /**
450
- * 启动清理过期数据的定时器
451
- */
452
- startCleanupTimer() {
453
- // 每30秒清理一次过期数据
454
- setInterval(() => {
455
- this.cleanupExpiredData();
456
- }, 30000);
457
- }
458
-
459
- /**
460
- * 清理过期数据
461
- */
462
- cleanupExpiredData() {
463
- const now = Date.now();
464
-
465
- // 清理过期的IP请求记录
466
- for (const [key, requests] of this.ipRequestCount.entries()) {
467
- const cleanedRequests = requests.filter(timestamp =>
468
- now - timestamp < Math.max(this.config.ip_rate_limit.window_ms, this.config.path_rate_limit
469
- .window_ms)
470
- );
471
-
472
- if (cleanedRequests.length > 0) {
473
- this.ipRequestCount.set(key, cleanedRequests);
474
- } else {
475
- this.ipRequestCount.delete(key);
476
- }
477
- }
478
-
479
- // 自动解除过期的阻止
480
- if (this.config.blocking.auto_unblock) {
481
- for (const [ip, blockInfo] of this.blockedIps.entries()) {
482
- if (now > blockInfo.unblock_time) {
483
- this.blockedIps.delete(ip);
484
- if (this.config.log && $.log && $.log.info) {
485
- $.log.info('IP Unblocked Automatically:', {
486
- ip: ip,
487
- reason: blockInfo.reason
488
- });
489
- }
490
- }
491
- }
492
- }
493
- }
494
- }
495
-
496
- // 创建中间件实例
497
- const middleware = new Middleware();
498
-
499
- // 导出符合系统期望的函数
500
- exports = module.exports = function(server, config) {
501
- // 初始化中间件
502
- const handlerFactory = middleware.init(config);
503
- const middlewareHandler = handlerFactory();
504
-
505
- // 直接使用server.use注册中间件
506
- server.use(middlewareHandler);
507
-
508
- // 记录中间件初始化信息
509
- if ($.log && $.log.info) {
510
- const cg = middleware.config;
511
- $.log.info(
512
- `综合流量控制中间件已加载: 存储方式=${cg.storage}, IP限制=${cg.ip_rate_limit.max_requests}/${cg.ip_rate_limit.window_ms/1000}秒, 连接限制=${cg.connection_limit.max_connections}`
513
- );
514
- }
515
-
516
- return server;
517
- };
518
-
519
- // 保留原始实例,以便其他方式调用
520
- exports.middleware = middleware;
@@ -1,38 +0,0 @@
1
- {
2
- "name": "waf_ddos",
3
- "title": "综合流量控制与DDOS攻击防护中间件",
4
- "type": "web_before",
5
- "state": 1,
6
- "sort": 12,
7
- "desc": "提供DDOS攻击防护和速率限制,包括IP限流、路径限流、连接控制和IP封禁功能",
8
- "config": {
9
- "enable": true,
10
- "storage": "memory",
11
- "ip_rate_limit": {
12
- "window_ms": 60000,
13
- "max_requests": 500,
14
- "enable": true
15
- },
16
- "path_rate_limit": {
17
- "window_ms": 60000,
18
- "max_requests": 250,
19
- "enable": true
20
- },
21
- "connection_limit": {
22
- "max_connections": 50,
23
- "enable": true
24
- },
25
- "blocking": {
26
- "threshold": 2,
27
- "block_time": 300000,
28
- "auto_unblock": true
29
- },
30
- "whitelist": [],
31
- "ignore_paths": ["/api/health", "/favicon.ico", "/static/"],
32
- "log": true,
33
- "block": true,
34
- "status_code": 429,
35
- "response_message": "请求过于频繁,请稍后再试",
36
- "set_rate_limit_headers": true
37
- }
38
- }