{"id":15133236,"url":"https://github.com/ruisiang/pow-phalanx","last_synced_at":"2025-10-12T08:16:02.902Z","repository":{"id":37749573,"uuid":"463365676","full_name":"RuiSiang/PoW-Phalanx","owner":"RuiSiang","description":"Controller for PoW Shield (a layer7 DDoS filter) providing multi-instance utilities.","archived":false,"fork":false,"pushed_at":"2022-09-04T06:08:33.000Z","size":132,"stargazers_count":11,"open_issues_count":0,"forks_count":9,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-30T17:38:25.310Z","etag":null,"topics":["controller","cybersecurity","ddos","ddos-mitigation","ddos-protection","koa2","machine-learning","network-security","nodejs","security","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RuiSiang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-25T02:07:55.000Z","updated_at":"2025-01-16T12:44:40.000Z","dependencies_parsed_at":"2023-01-17T16:01:48.144Z","dependency_job_id":null,"html_url":"https://github.com/RuiSiang/PoW-Phalanx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RuiSiang%2FPoW-Phalanx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RuiSiang%2FPoW-Phalanx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RuiSiang%2FPoW-Phalanx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RuiSiang%2FPoW-Phalanx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RuiSiang","download_url":"https://codeload.github.com/RuiSiang/PoW-Phalanx/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237807454,"owners_count":19369595,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["controller","cybersecurity","ddos","ddos-mitigation","ddos-protection","koa2","machine-learning","network-security","nodejs","security","typescript"],"created_at":"2024-09-26T05:00:44.337Z","updated_at":"2025-10-12T08:15:57.847Z","avatar_url":"https://github.com/RuiSiang.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PoW Phalanx\n\nController for [PoW-Shield](https://github.com/RuiSiang/PoW-Shield) that calculates and assigns the optimal difficulty via request and waf trigger distributions based on machine learning model.\n\nUser interface for PoW-Phalanx can be found at [PoW-Phalanx Controller UI](https://github.com/RuiSiang/PoW-Phalanx-Controller-UI)\n\nTodos:\n\n- [x] Socket connectivity with PoW Shield\n- [x] Statistics synchronization\n- [x] Difficulty control\n- [x] Model interaction interface\n- [x] Feature synchronization\n- [x] Ban state synchronization\n- [x] Controller graphics interface\n- [ ] Security model update\n- [ ] Unit test\n\n## Prerequisites\n\nDocker ^19.0.0\nNodejs ^14.0.0\n\n## Configuration\n\n- nodejs: .env (example: .env.example)\n- docker-compose: docker-compose.yaml (example: docker-compose.example.yaml)\n- docker run: -e parameter\n\n### Environmental Variables\n\n| Variable                      | Default                 | Description                                                                                  |\n| ----------------------------- | ----------------------- | -------------------------------------------------------------------------------------------- |\n| PORT                          | 6000                    | port for phalanx instance                                                                    |\n| DATABASE_HOST                 | 127.0.0.1               | host for redis database                                                                      |\n| DATABASE_PORT                 | 6379                    | port for redis database                                                                      |\n| DATABASE_PASSWORD             |                         | password for redis database                                                                  |\n| SUBSCRIPTION_TOKEN            | test-subscription-token | token for access to subscription endpoint                                                    |\n| CONTROLLER_TOKEN              | test-controller-token   | token for access to controller endpoint                                                      |\n| MODEL_TOKEN                   | test-model-token        | token for access to model endpoint                                                           |\n| CONTROLLER_BROADCAST_INTERVAL | 20                      | interval(seconds) for phalanx to broadcast controller stats                                  |\n| STAT_FETCH_INTERVAL           | 10                      | interval(seconds) for phalanx to broadcast fetch directive to subscibed pow-shield instances |\n| STAT_KEEP_HISTORY_TIME        | 3600                    | length(seconds) for phalanx to keep history fetched from pow-shield instances                |\n| RESOURCE_MONITOR              | off                     | connect to resource monitor on backend                                                       |\n| RESOURCE_MONITOR_HOST         |                         | resource monitor host                                                                        |\n| RESOURCE_MONITOR_PORT         |                         | resource monitor port                                                                        |\n| SETTINGS_FETCH                | off                     | fetch settings dump alongside batch stats                                                    |\n| RESTFUL                       | on                      | enable restful api                                                                           |\n| RESTFUL_PORT                  | 9000                    | port for restful api                                                                         |\n\n## Usage\n\n```\n# Clone repository\ngit clone https://github.com/RuiSiang/PoW-Phalanx.git\n\n# Install dependencies\nnpm install\n\n# Configure settings\ncp -n .env.example .env\n# Edit .env\nnano .env\n\n# Transpile\nnpm run build\n\n#############################################\n# Set up redis server as database           #\n# install redis first                       #\n# sudo apt-get install redis-server         #\n#############################################\nnpm start\n```\n\n## Subscriptions\n\nDefault endpoint: `http://localhost:6000?token=token-for-type`\n\nThe following are implemented with standard socket.io protocol. Base url is designated as endpoint, and `message` as the event. Calls are standarized in the following format:\n\n```JSON\n{\n  \"method\": \"call-method\",\n  \"arguments\": [\"array-of-parameters\"],\n}\n```\n\nPassive endpoints consume a call and return data (call handled by phalanx socket server), active feeds emit a call to the client (call not handled by phalanx socket server).\n\n## Subscription Channel\n\n| Method                | Type             | Scope     | Arguments                  | Description                                                     |\n| --------------------- | ---------------- | --------- | -------------------------- | --------------------------------------------------------------- |\n| phlx_update_stats     | passive endpoint | unicast   | stats:Stat[]               | Shield pushes new data to phalanx                               |\n| phlx_update_settings  | passive endpoint | unicast   | stats:Config               | Shield pushes new settings dump to phalanx                      |\n| phlx_ban_ip           | passive endpoint | unicast   | [ip:string, seconds: uint] | Shield signals to phalanx that a new IP is banned               |\n| shld_ban_ip           | active feed      | broadcast | [ip:string, seconds: uint] | Phalanx broadcasts to shields that a new IP is banned           |\n| shld_fetch_stats      | active feed      | broadcast | N/A                        | Phalanx broadcasts to shields to signal a new data push         |\n| shld_fetch_settings   | active feed      | broadcast | N/A                        | Phalanx broadcasts to shields to signal a new settings dump     |\n| shld_set_config       | active feed      | broadcast | [key:string, value:any]    | Phalanx broadcasts to shields to set a config parameter         |\n| shld_add_whitelist    | active feed      | broadcast | [token:string]             | Phalanx broadcasts to shields to add a whitelist token          |\n| shld_remove_whitelist | active feed      | broadcast | [token:string]             | Phalanx broadcasts to shields to remove a whitelist token       |\n| shld_update_model     | active feed      | broadcast | TBD                        | Phalanx broadcasts to shields to update the edge security model |\n\n## Controller Channel\n\n| Method                   | Type             | Scope     | Arguments                           | Description                                                           |\n| ------------------------ | ---------------- | --------- | ----------------------------------- | --------------------------------------------------------------------- |\n| phlx_override_difficulty | passive endpoint | unicast   | [difficulty:uint]                   | Controller asks phalanx to override difficulty                        |\n| phlx_add_whitelist       | passive endpoint | unicast   | [token:string]                      | Controller asks phalanx to add new whitelist token                    |\n| phlx_remove_whitelist    | passive endpoint | unicast   | [token:string]                      | Controller asks phalanx to remove whitelist token                     |\n| phlx_update_model        | passive endpoint | unicast   | TBD                                 | Controller pushes edge security model to phalanx to update on shields |\n| ctrl_stats               | active feed      | broadcast | {stats:Stat[], whitelist: string[]} | Phalanx broadcasts current stats to controller                        |\n\n## Model Channel\n\n| Method                 | Type             | Scope     | Arguments         | Description                                         |\n| ---------------------- | ---------------- | --------- | ----------------- | --------------------------------------------------- |\n| phlx_set_difficulty    | passive endpoint | unicast   | [difficulty:uint] | Model asks phalanx to set new difficulty            |\n| phlx_fetch_batch_stats | passive endpoint | unicast   | [lastRow?:string] | Model requests phalanx to send batch stats          |\n| modl_batch_stats       | active feed      | unicast   | stats:Stat[]      | Phalanx sends batch stats to model                  |\n| modl_backend_stats     | active feed      | broadcast | util:ResourceUtil | Phalanx redirects resource monitor stats on backend |\n| modl_settings          | active feed      | broadcast | config:Config     | Phalanx sends settings dump to model                |\n\n## Data Formats\n\n### Stat\n\n\"stat-type\":\"client-id\":\"ISO-Timestamp\"|\"count\"\n\ni.e. `ttl_req:aTqmrN0eKqaQa1nIAAAB:2022-06-14T01:55:00.014Z|10`\n\n| stat-type      | Value                                | Unit         |\n| -------------- | ------------------------------------ | ------------ |\n| legit_req      | accumulative legit request count     | count        |\n| ttl_req        | accumulative total request count     | count        |\n| bad_nonce      | accumulative bad nonce request count | count        |\n| ttl_waf        | accumulative waf trigger count       | count        |\n| ttl_solve_time | accumulated time of solved problems  | milliseconds |\n| prob_solved    | number of problems solved            | count        |\n\n### ResourceUtil\n\ni.e.\n\n```json\n{\n  \"cpuUtil\": \"0.27\",\n  \"memUtil\": \"14.22\",\n  \"uptime\": \"350\"\n}\n```\n\n| stat-type | Value                        |\n| --------- | ---------------------------- |\n| cpuUtil   | CPU utilization (percentage) |\n| memUtil   | RAM utilization (percentage) |\n| uptime    | machine uptime (seconds)     |\n\n## Restful API for Model\n\n### GET /stats?token=model-token\n\nDescription: Get stats for model training\n\nRequest:\n\n- Params: N/A\n- Query:\n  - token: token for model connection (same as the one for socket)\n\nResponse:\n\n- instances: object of stat entry arrays organized by client id and stat type (see example)\n- settings: object of setting configurations for each client\n- backend: resource stats on the backend site\n\nExample Request\n\n```\ncurl http://pow-phalanx:9000/stats?token=test-model-token\n```\n\nExample Response\n\n```JSON\n{\n  \"instances\": {\n    \"Do4a-RmsY-0zJmFeAAAB\": {\n      \"legit_req\": [\"1\", \"13\", \"22\", \"22\", \"23\", \"24\", \"24\", \"24\", \"24\"],\n      \"ttl_req\": [\"4\", \"16\", \"25\", \"27\", \"29\", \"30\", \"30\", \"31\", \"31\"],\n      \"bad_nonce\": [\"0\", \"0\", \"0\", \"0\", \"0\", \"0\", \"0\", \"0\", \"0\"],\n      \"ttl_waf\": [\"0\", \"0\", \"0\", \"0\", \"0\", \"0\", \"0\", \"1\", \"1\"],\n      \"ttl_solve_time\": [\"2544\", \"2544\", \"2544\", \"2544\", \"4647\", \"4647\", \"4647\", \"4647\", \"4647\"],\n      \"prob_solved\": [\"1\", \"1\", \"1\", \"1\", \"2\", \"2\", \"2\", \"2\", \"2\"]\n    }\n  },\n  \"settings\": [\n    {\n      \"settings:Do4a-RmsY-0zJmFeAAAB\": \"{\\\"session_key\\\":\\\"abcdefghijklmnop\\\",\\\"pow\\\":true,\\\"nonce_validity\\\":60000,\\\"difficulty\\\":13,\\\"backend_url\\\":\\\"http://webapp:80\\\",\\\"database_host\\\":\\\"redis1\\\",\\\"database_port\\\":6379,\\\"database_password\\\":\\\"\\\",\\\"rate_limit\\\":true,\\\"rate_limit_sample_minutes\\\":60,\\\"rate_limit_session_threshold\\\":100,\\\"rate_limit_ban_ip\\\":true,\\\"rate_limit_ip_threshold\\\":500,\\\"rate_limit_ban_minutes\\\":15,\\\"waf\\\":true,\\\"waf_url_exclude_rules\\\":\\\"\\\",\\\"waf_header_exclude_rules\\\":\\\"14,33,80,96,100\\\",\\\"waf_body_exclude_rules\\\":\\\"\\\",\\\"ssl\\\":false,\\\"ssl_cert_path\\\":\\\"tests/ssl/mock-cert.pem\\\",\\\"ssl_key_path\\\":\\\"tests/ssl/mock-key.pem\\\",\\\"socket\\\":true,\\\"socket_url\\\":\\\"http://pow-phalanx:6000\\\",\\\"socket_token\\\":\\\"test-subscription-token\\\"}\"\n    }\n  ],\n  \"backend\": \"\\\"{\\\\\\\"cpuUtil\\\\\\\":\\\\\\\"0.30\\\\\\\",\\\\\\\"memUtil\\\\\\\":\\\\\\\"21.78\\\\\\\",\\\\\\\"uptime\\\\\\\":\\\\\\\"2591\\\\\\\"}\\\"\"\n}\n```\n\n### GET /set?token=model-token\u0026difficulty=difficulty\n\nDescription: Get stats for model training\n\nRequest:\n\n- Params: N/A\n- Query:\n  - token: token for model connection (same as the one for socket)\n  - difficulty: difficulty to set (integer)\n\nResponse:\n\n- 200: OK\n- 400: Invalid\n\nExample Request\n\n```\ncurl http://pow-phalanx:9000/set?token=test-model-token\u0026difficulty=13\n```\n\nExample Response\n\n`200 OK`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fruisiang%2Fpow-phalanx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fruisiang%2Fpow-phalanx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fruisiang%2Fpow-phalanx/lists"}