{"id":2426,"date":"2023-08-11T10:23:31","date_gmt":"2023-08-11T01:23:31","guid":{"rendered":"https:\/\/manvscloud.com\/?p=2426"},"modified":"2023-08-11T10:23:31","modified_gmt":"2023-08-11T01:23:31","slug":"ncloud-api%eb%a5%bc-%ed%99%9c%ec%9a%a9%ed%95%9c-dos-%ea%b3%b5%ea%b2%a9-%ec%b0%a8%eb%8b%a8-%ec%8b%9c%ec%8a%a4%ed%85%9c-%ea%b5%ac%ed%98%84","status":"publish","type":"post","link":"https:\/\/manvscloud.com\/?p=2426","title":{"rendered":"[NCLOUD] API\ub97c \ud65c\uc6a9\ud55c DoS \uacf5\uaca9 \ucc28\ub2e8 \uc2dc\uc2a4\ud15c \uad6c\ud604"},"content":{"rendered":"\n<p>\uc548\ub155\ud558\uc138\uc694 MANVSCLOUD \uae40\uc218\ud604\uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<p>IT \ubcf4\uc548\uc740 \uae30\uc220\uc774 \ubc1c\uc804\ud560\uc218\ub85d \ub354\uc6b1 \uc911\uc694\ud574\uc9c0\ub294 \uc694\uc18c\uc785\ub2c8\ub2e4.<br>\ucd5c\uadfc \ud2b9\uc815 \ud574\uc678 IP \ud558\ub098\uac00 \uc6f9\uc744 \ud1b5\ud574 \ucd08\ub2f9 \uc218\uc2ed\ubc88\uc758 \uc5f0\uacb0\ub85c \uc11c\ubc84 \ub0b4 \ub514\uc2a4\ud06c \uc6a9\ub7c9\uc774 \uac00\ub4dd\ucc28\ub294 \uc0ac\ub840\ub97c \uacaa\uc5c8\uc2b5\ub2c8\ub2e4. \uc774\ub7ec\ud55c \uacf5\uaca9\uc740 \uc790\uc6d0 \uace0\uac08\uc744 \ub178\ub9b0 DoS \uacf5\uaca9 \uc720\ud615 \uc911 \ud558\ub098\uc778\ub370\uc694.<\/p>\n\n\n\n<p>SQL \uc778\uc81d\uc158, XSS, CSRF \ub4f1 \uacf5\uaca9\uc744 \ubc29\uc5b4\ud558\ub294 \ub370 \uc720\uc6a9\ud55c WAF \uc11c\ube44\uc2a4\ub85c\ub294 \ud6a8\uacfc\uc801\uc774\uc9c0 \ubabb\ud558\uc5ec \uc11c\ube44\uc2a4 \ub2e4\uc6b4\uc73c\ub85c \uc774\uc5b4\uc9c8 \uc218 \ubc16\uc5d0 \uc5c6\uc5c8\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"458\" src=\"https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2023\/08\/03004702\/image-1024x458.png\" alt=\"\" class=\"wp-image-2428\" srcset=\"https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2023\/08\/03004702\/image-1024x458.png 1024w, https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2023\/08\/03004702\/image-300x134.png 300w, https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2023\/08\/03004702\/image-768x344.png 768w, https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2023\/08\/03004702\/image.png 1066w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>\ub124\uc774\ubc84 \ud074\ub77c\uc6b0\ub4dc \ud50c\ub7ab\ud3fc\uc758 Security Monitoring \uc11c\ube44\uc2a4\uc5d0\ub294 WAF \uc0c1\ud488 \uc678\uc5d0\ub3c4 Anti-DDoS, IPS \ub4f1 \ub2e4\uc591\ud55c \uc11c\ube44\uc2a4\uac00 \uc874\uc7ac\ud558\uc9c0\ub9cc \ubcf4\uc548\uc5d0 \ud070 \ube44\uc6a9\uc744 \ud22c\uc790\ud560 \uc218 \uc5c6\ub294 \uae30\uc5c5\uc774\ub098 \uac1c\uc778 \ud14c\uc2a4\ud2b8\uc6a9\uc73c\ub85c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 \ube44\uc6a9\uc5d0 \ub300\ud55c \ubd80\ub2f4\uc774 \uc0dd\uae38 \uc218 \ubc16\uc5d0 \uc5c6\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uc774\ub7ec\ud55c \ubb38\uc81c\ub85c \uc624\ub298\uc740 \ub124\uc774\ubc84 \ud074\ub77c\uc6b0\ub4dc\uc5d0\uc11c \uc81c\uacf5\ud558\uace0 \uc788\ub294 \ub2e4\uc591\ud55c \uc11c\ube44\uc2a4\uc758 API \ub4e4\uc744 \uc774\uc6a9\ud558\uc5ec \uac04\ub2e8\ud558\uac8c \uc6f9\uc73c\ub85c\ubd80\ud130 \ub4e4\uc5b4\uc624\ub294 DoS \uacf5\uaca9 \ucc28\ub2e8 \uc2dc\uc2a4\ud15c\uc744 \ub9cc\ub4e4\uc5b4\ubcfc \uac83\uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<p>DoS \uacf5\uaca9\uc744 \uc804\ubb38\uc801\uc73c\ub85c \ucc28\ub2e8\ud558\uae30 \uc704\ud55c \uc11c\ube44\uc2a4\ubcf4\ub2e4\ub294 \uc644\ubcbd\ud560 \uc21c \uc5c6\uaca0\uc9c0\ub9cc \uac04\ub2e8\ud558\uc9c0\ub9cc \uc5b4\ub290\uc815\ub3c4 \ub9cc\uc871\uc2a4\ub7ec\uc6b8 \uc218 \uc788\ub294 \uc2dc\uc2a4\ud15c\uc744 \uad6c\ud604\ud574\ubd05\uc2dc\ub2e4. <\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading has-white-color has-vivid-green-cyan-background-color has-text-color has-background\"> Idea<\/h3>\n\n\n\n<p>\uc0dd\uac01\uc740 \uadf8\ub9ac \uc624\ub798\ud558\uc9c0 \uc54a\uc558\uace0 \uadf8\ub0e5 manvscloud.com \ud658\uacbd\uc744 \uadf8\ub300\ub85c \uc774\uc6a9\ud558\uc5ec \uc77c\ub2e8 \uc2dc\uc791\ud574\ubcf4\uae30\ub85c \ud588\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uc544\ub798 \uc774\ubbf8\uc9c0\ub294 \uc0dd\uac01\ud55c DoS \uacf5\uaca9 \ucc28\ub2e8 \uc2dc\uc2a4\ud15c\uc774 \ub3d9\uc791\ud558\ub294 \ubc29\uc2dd\uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"860\" height=\"880\" src=\"https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2023\/08\/03002536\/dos-nacl.png\" alt=\"\" class=\"wp-image-2427\" srcset=\"https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2023\/08\/03002536\/dos-nacl.png 860w, https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2023\/08\/03002536\/dos-nacl-293x300.png 293w, https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2023\/08\/03002536\/dos-nacl-768x786.png 768w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/figure>\n\n\n\n<p>\uc6f9 \uc11c\ubc84\uc5d0 \uc5f0\uacb0\ub41c ACG\uc5d0\uc11c HTTP \uc811\uc18d\uc740 Application Load Balancer\uc758 Subnet \ub300\uc5ed\uc5d0\uc11c\ub9cc \uc811\uadfc\ud560 \uc218 \uc788\ub3c4\ub85d \ub418\uc5b4\uc788\uae30\ub54c\ubb38\uc5d0 \uc9c1\uc811\uc801\uc73c\ub85c Web \uc11c\ubc84\ub85c \uc5f0\uacb0\ub418\ub294 \uac83\uc740 \ubd88\uac00\ub2a5\ud55c \uc0c1\ud0dc\uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uacb0\uad6d \uc6f9 \uc811\uadfc\uc740 Application Load Balancer\ub97c \ud1b5\ud574\uc11c\ub9cc \uac00\ub2a5\ud558\uae30\ub54c\ubb38\uc5d0 ALB\uc758 Subnet\uc5d0 \uc5f0\uacb0\ub41c NACL(Network Access Control List)\uc5d0 \uc815\ucc45\uc744 \ucd94\uac00\/\uc81c\uac70\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud588\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uc5ec\uae30\uc11c \uc911\uc694\ud55c \uc810\uc740 NACL\uc5d0\ub294 \uc815\ucc45\uc774 200\uac1c\uae4c\uc9c0\ub9cc \ucd94\uac00 \uac00\ub2a5\ud558\uae30\ub54c\ubb38\uc5d0 \uc5ec\ub7ec\uac1c\uc758 ALB \ub610\ub294 Subnet\uc774 \ud558\ub098\uc758 NACL\ub97c \ud568\uaed8 \uc4f0\ub294 \uacbd\uc6b0\uc5d0\ub294 \ubb38\uc81c\uac00 \ub420 \uc218 \uc788\uc73c\ubbc0\ub85c \ud558\ub098\uc758 ALB\ubcc4\ub85c \uac01\uac01\uc758 Subnet\uc744 \uac16\ub3c4\ub85d\ud558\uace0 \ud574\ub2f9 Subnet\uc6a9 NACL\uc774 \uc5f0\uacb0\ub418\ub3c4\ub85d \ud574\uc57c\ud569\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\ud558\ub098\uc758 IP\uac00 \ub9ac\uc18c\uc2a4 \uace0\uac08\uc744 \ubaa9\uc801 \uc6f9 \uc811\uadfc\uc744 \ud588\ub2e4\uace0 \uac00\uc815\ud558\uace0 \uc2dc\ub098\ub9ac\uc624\ub97c \uc791\uc131\ud574\ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p class=\"has-vivid-cyan-blue-color has-text-color\">1) \uc811\uc18d\uc790\uac00 Application Load Balancer\ub97c \ud1b5\ud574 \uc811\uadfc<\/p>\n\n\n\n<p class=\"has-vivid-cyan-blue-color has-text-color\">2) Application Load Balancer\uc758 \uc561\uc138\uc2a4 \ub85c\uadf8\ub97c Cloud Log Analytics\uc5d0\uc11c \uc218\uc9d1<\/p>\n\n\n\n<p class=\"has-vivid-cyan-blue-color has-text-color\">3) DoS \uacf5\uaca9 \ucc28\ub2e8 \uc2dc\uc2a4\ud15c\uc774 \uad6c\ud604\ub41c \uc11c\ubc84\uc5d0\uc11c Cloud Log Analytics\uc758 Application Load Balancer \ub85c\uadf8\ub97c \ubd84\uc11d<\/p>\n\n\n\n<p class=\"has-vivid-cyan-blue-color has-text-color\">4) \uc608\uc678 IP\ub97c \uc81c\uc678\ud55c \ub098\uba38\uc9c0 IP\uac00 x\ubd84\ub2f9 x\ud68c \uc774\uc0c1 \uc811\uadfc \uc2dc \ud574\ub2f9 IP\ub294 NACL\uc5d0 \ucc28\ub2e8 \uc815\ucc45 \ucd94\uac00<\/p>\n\n\n\n<p class=\"has-vivid-cyan-blue-color has-text-color\">5) \ucc28\ub2e8\ub41c IP\ub85c\ub294 \uc6f9 \uc811\uadfc \ubd88\uac00<\/p>\n\n\n\n<p class=\"has-vivid-cyan-blue-color has-text-color\">6) \uc815\ud574\uc9c4 \ud2b9\uc815 \uc2dc\uac04\uc774 \uc9c0\ub09c IP\ub294 NACL\uc5d0\uc11c \ucc28\ub2e8 \uc815\ucc45 \uc81c\uac70 <\/p>\n\n\n\n<p>\uc774\uc81c \uc704 \uc2dc\ub098\ub9ac\uc624\ub300\ub85c \ub3d9\uc791\ud560 \uc218 \uc788\ub3c4\ub85d DoS \uacf5\uaca9 \ucc28\ub2e8 \uc2dc\uc2a4\ud15c\uc744 \uad6c\ud604\ud574\ubcf4\ub3c4\ub85d \ud569\uc2dc\ub2e4.<br>(\ucc38\uace0\ub85c Cloud Log Analytic\ub97c \uc0ac\uc6a9\ud558\uace0 \uc2f6\uc9c0 \uc54a\ub2e4 or ALB \uc561\uc138\uc2a4 \ub85c\uadf8 \uc218\uc9d1\uc744 \ud558\uace0 \uc2f6\uc9c0 \uc54a\ub2e4\uba74 WEB \uc11c\ubc84\uc5d0\uc11c x-forwarded-for \uc124\uc815\uc744 \ud574\uc11c \ud574\ub2f9 \ud658\uacbd\uc5d0 \ub9de\uac8c \uad6c\ud604\ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading has-white-color has-vivid-cyan-blue-background-color has-text-color has-background\"> DoS Blocker<\/h3>\n\n\n\n<p>\uc774 \uc2dc\uc2a4\ud15c \uc774\ub984\uc740 DoS Blocker\ub77c\uace0 \uc815\ud588\uc2b5\ub2c8\ub2e4.<br>Python\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub9cc\ub4e4\uc5c8\uace0 \ucd1d 3\uac1c\uc758 \ud30c\uc77c\ub9cc \uc0dd\uc131\ud558\uba74 \ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<p class=\"has-vivid-red-color has-text-color\">&#8211; nacl_auto_class.py<br>&#8211; nacl_auto_block.py<br>&#8211; nacl_auto_remove.py<\/p>\n\n\n\n<p><em># VPC, Server \uc0dd\uc131\uc5d0 \ub300\ud55c \uac00\uc774\ub4dc\ub294 \uc0dd\ub7b5\ud569\ub2c8\ub2e4.<br># Python\uc740 3.7 \ubc84\uc804\uc774 \uc0ac\uc6a9\ub418\uc5c8\uc2b5\ub2c8\ub2e4.<\/em><br><em># \ud574\ub2f9 \uacfc\uc815\uc5d0\uc11c\ub294 \ud3b8\uc758\uc0c1 \ud658\uacbd \ubcc0\uc218\uc5d0 ACCESS KEY \ucd94\uac00\ud55c \uc810 \ucc38\uace0 \ubd80\ud0c1\ub4dc\ub9bd\ub2c8\ub2e4.<\/em><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">mkdir -p dos-blocker\/manvscloud-alb\nmkdir \/var\/log\/nacl\ncd dos-blocker\/manvscloud-alb<\/pre>\n\n\n\n<p>\uba3c\uc800 \uc704\uc640 \uac19\uc774 \ub514\ub809\ud1a0\ub9ac \uc0dd\uc131 \ubc0f \uc774\ub3d9\uc744 \ud574\uc8fc\uc138\uc694.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<ul>\n<li><strong>nacl_auto_class.py<\/strong><\/li>\n<\/ul>\n\n\n\n<p>\uc774 \ud30c\uc77c\uc740 \uac04\ub2e8\ud55c Class \ud30c\uc77c\uc785\ub2c8\ub2e4. <br>\ucf54\ub4dc\uc758 \uc911\ubcf5\uc744 \uc904\uc774\uace0 \ucf54\ub4dc\uac00 \uae54\ub054\ud574\uc9c8 \uc218 \uc788\ub3c4\ub85d \uc544\ub798\uc640 \uac19\uc774 \uc0dd\uc131\ud558\uc600\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import os\nimport base64\nimport hmac\nimport hashlib\nimport requests\nimport time\nimport json\n\nclass NACLAutomation:\n    def __init__(self, nacl_no, region, drop_port, drop_proto, api_server_ncloud, log_filename=None, keyword=None):\n        self.nacl_no = nacl_no\n        self.region = region\n        self.drop_port = drop_port\n        self.drop_proto = drop_proto\n        self.api_server_ncloud = api_server_ncloud\n        self.log_filename = log_filename\n        self.keyword = keyword\n\n    def get_access_headers(self, timestamp, method, uri):\n        access_key = os.environ['NCLOUD_ACCESS_KEY']\n        secret_key = os.environ['NCLOUD_SECRET_KEY']\n        secret_key = bytes(secret_key, 'UTF-8')\n        message = method + \" \" + uri + \"\\n\" + timestamp + \"\\n\" + access_key\n        message = bytes(message, 'UTF-8')\n        signingKey = base64.b64encode(hmac.new(secret_key, message, digestmod=hashlib.sha256).digest())\n        http_header = {\n            'x-ncp-apigw-signature-v2': signingKey,\n            'x-ncp-apigw-timestamp': timestamp,\n            'x-ncp-iam-access-key': access_key\n        }\n        return http_header\n\n    def make_request(self, method, uri, payload=None, api_server=None):\n        timestamp = str(int(time.time() * 1000))\n        http_header = self.get_access_headers(timestamp, method, uri)\n\n        api_server = api_server or self.api_server_ncloud\n\n        if method == \"POST\":\n            response = requests.post(api_server + uri, headers=http_header, json=payload)\n        else:\n            response = requests.get(api_server + uri, headers=http_header)\n        return response.text\n\n    def get_nacl_rules(self):\n        uri = \"\/vpc\/v2\/getNetworkAclRuleList?responseFormatType=json&amp;regionCode=\" + self.region + \"&amp;networkAclNo=\" + self.nacl_no\n        response = self.make_request(\"GET\", uri)\n        return json.loads(response)['getNetworkAclRuleListResponse']['networkAclRuleList']\n<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<ul>\n<li><strong>nacl_auto_block.py<\/strong><\/li>\n<\/ul>\n\n\n\n<p>1) exclude_ips = [&#8220;1.1.1.1\/32&#8221;] \ubd80\ubd84\uc5d0\uc11c Block \ub418\uc9c0 \uc54a\uae38 \ubc14\ub77c\ub294 IP\ub97c \ucd94\uac00\ud560 \uacbd\uc6b0 \ud574\ub2f9 IP\ub294 NACL\uc5d0 \ucc28\ub2e8 \ub4f1\ub85d\uc774 \ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p>2) payload\uc5d0\uc11c logTypes, timeZone, timestampFrom, interval, pageSize \uc218\uc815\uc774 \ud544\uc694\ud560 \uacbd\uc6b0 \uc218\uc815\ud574\uc8fc\uc138\uc694.<\/p>\n\n\n\n<p>3) block_ips = [f&#8221;{ip}\/32&#8243; for ip, count in ip_counter.items() if count &gt; 300] \ubd80\ubd84\uc5d0\uc11c 300 \ubd80\ubd84\uc740 \uc704 payload\uc5d0\uc11c \uc124\uc815\ud55c \uc2dc\uac04 \ub0b4\uc5d0 300\ud68c \uc774\uc0c1 Count \ub420 \uacbd\uc6b0 \ucc28\ub2e8\uc774 \ub418\ub3c4\ub85d \ud574\ub454 \uac83\uc785\ub2c8\ub2e4. \uc6d0\ud558\ub294 Count \uac12\uc774 \uc788\ub2e4\uba74 300 \ubd80\ubd84\uc744 \ub2e4\ub978 \uc218\uce58\ub85c \ubcc0\uacbd\ud574\uc8fc\uc2dc\uba74 \ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<p>4) \uc544\ub798 \ucf54\ub4dc\uc5d0\uc11c nacl_no=&#8221;1111&#8243;\uc758 1111 \ubd80\ubd84\uacfc log_filename=&#8221;\/var\/log\/nacl\/drop-1111.log&#8221;\uc758 1111 \ubd80\ubd84\uc740 ALB\uac00 \uc788\ub294 \uc11c\ube0c\ub137\uc758 NACL No\ub85c \ubcc0\uacbd\ud574\uc8fc\uc138\uc694.<br>(Cloud Log Analytics\uc5d0 \uac80\uc0c9 \uc2dc \uc0ac\uc6a9\ub418\ub294 keyword\ub3c4 \ub530\ub85c \uc124\uc815\ud574\uc904 \uc218 \uc788\uc5b4\uc694.)<\/p>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">if <strong>name<\/strong> == &#8220;<strong>main<\/strong>&#8220;:<br>nacl_block = NACLAutoBlock(nacl_no=&#8221;1111&#8243;,<br>region=&#8221;KR&#8221;,<br>drop_port=&#8221;1-65535&#8243;,<br>drop_proto=&#8221;TCP&#8221;,<br>api_server_ncloud=&#8221;https:\/\/ncloud.apigw.ntruss.com&#8221;,<br>api_server_cloud_log_analytics=&#8221;https:\/\/cloudloganalytics.apigw.ntruss.com&#8221;,<br>log_filename=&#8221;\/var\/log\/nacl\/drop-1111.log&#8221;,<br>keyword=&#8221;&#8221;)<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from nacl_auto_class import NACLAutomation\nimport logging\nimport datetime\nimport time\nimport json\nfrom collections import Counter\nimport re\n\n#Block \uc608\uc678 \ucc98\ub9ac(exclude_ips = [\"1.2.3.4\/32\", \"5.6.7.8\/32\"])\nexclude_ips = [\"1.1.1.1\/32\"]\n\nclass NACLAutoBlock(NACLAutomation):\n    def __init__(self, nacl_no, region, drop_port, drop_proto, api_server_ncloud, api_server_cloud_log_analytics, log_filename, keyword):\n        super().__init__(nacl_no, region, drop_port, drop_proto, api_server_ncloud, log_filename)\n        self.api_server_cloud_log_analytics = api_server_cloud_log_analytics\n        self.action_code = \"DROP\"\n\n    def write_log(self, ip):\n        logging.basicConfig(filename=self.log_filename, level=logging.INFO)\n        current_time = datetime.datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n        logging.info('[%s] %s DROP', current_time, ip)\n\n    def extract_ips_to_block(self):\n        payload = {\n            \"keyword\" : self.keyword,\n            \"logTypes\" : \"application_loadbalancer_access\",\n            \"timeZone\": \"+09:00\",\n            \"timestampFrom\": \"now-1h\",\n            \"timestampTo\": \"now\",\n            \"interval\": \"5m\",\n            \"pageNo\": 1,\n            \"pageSize\": 100\n        }\n\n        response = self.make_request(\"POST\", \"\/api\/v1\/logs\/search?responseFormatType=json\", payload, self.api_server_cloud_log_analytics)\n\n        data = json.loads(response)\n        ip_counter = Counter()\n\n        for result in data['result']['searchResult']:\n            ip = re.search(r\"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b\", result['logDetail'])\n            if ip:\n                ip_counter[ip.group()] += 1\n\n        block_ips = [f\"{ip}\/32\" for ip, count in ip_counter.items() if count > 300]\n        return block_ips\n\n    def get_min_priority(self):\n        rules = self.get_nacl_rules()\n        return min(rule['priority'] for rule in rules)\n\n    def is_ip_exist(self, ip):\n        rules = self.get_nacl_rules()\n        return any(rule['ipBlock'] == ip for rule in rules)\n\n    def add_nacl_rule(self, ip, priority):\n\n        if ip in exclude_ips:\n            return\n\n        uri = f\"\/vpc\/v2\/addNetworkAclInboundRule?responseFormatType=json&amp;regionCode={self.region}&amp;networkAclNo={self.nacl_no}&amp;networkAclRuleList.1.priority={priority}&amp;networkAclRuleList.1.protocolTypeCode={self.drop_proto}&amp;networkAclRuleList.1.ipBlock={ip}&amp;networkAclRuleList.1.portRange={self.drop_port}&amp;networkAclRuleList.1.ruleActionCode={self.action_code}\"\n        self.make_request(\"GET\", uri)\n        self.write_log(ip)\n\nif __name__ == \"__main__\":\n    nacl_block = NACLAutoBlock(nacl_no=\"1111\",\n                               region=\"KR\",\n                               drop_port=\"1-65535\",\n                               drop_proto=\"TCP\",\n                               api_server_ncloud=\"https:\/\/ncloud.apigw.ntruss.com\",\n                               api_server_cloud_log_analytics=\"https:\/\/cloudloganalytics.apigw.ntruss.com\",\n                               log_filename=\"\/var\/log\/nacl\/drop-1111.log\",\n                               keyword=\"\")\n\n    ips_to_block = nacl_block.extract_ips_to_block()\n    min_priority = nacl_block.get_min_priority()\n\n    for i, ip in enumerate(ips_to_block, start=1):\n        if not nacl_block.is_ip_exist(ip):\n            nacl_block.add_nacl_rule(ip, str(min_priority - i))\n            time.sleep(15)\n<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<ul>\n<li><strong>nacl_auto_remove.py<\/strong><\/li>\n<\/ul>\n\n\n\n<p>\ud574\ub2f9 \ucf54\ub4dc\ub294 log \ud30c\uc77c\uc744 \uac80\uc0ac\ud558\uc5ec \ud2b9\uc815 \uc2dc\uac04\uc774 \uc9c0\ub09c IP\uac00 NACL\uc5d0\uc11c \ucc28\ub2e8\ub418\uc5b4\uc788\ub2e4\uba74 \uc815\ucc45\uc744 \uc81c\uac70\ud558\ub294 \ucf54\ub4dc\uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<p>1) if (current_time &#8211; last_seen) &gt; timedelta(days=1): \ubd80\ubd84\uc5d0\uc11c days=1\uc740 \ud558\ub8e8\uc785\ub2c8\ub2e4. \ud558\ub8e8\uac00 \uc9c0\ub09c IP\ub294 \uc81c\uac70\ub418\uac8c \ub429\ub2c8\ub2e4. \uc774 \ubd80\ubd84\uc744 \ubcc0\uacbd\ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p>2) \uc544\ub798 \ucf54\ub4dc\uc5d0\uc11c nacl_no=&#8221;1111&#8243;\uc758 1111 \ubd80\ubd84\uacfc log_filename=&#8221;\/var\/log\/nacl\/drop-1111.log&#8221;\uc758 1111 \ubd80\ubd84\uc740 ALB\uac00 \uc788\ub294 \uc11c\ube0c\ub137\uc758 NACL No\ub85c \ubcc0\uacbd\ud574\uc8fc\uc138\uc694.<\/p>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">if <strong>name<\/strong> == &#8220;<strong>main<\/strong>&#8220;:<br>nacl_remove = NACLAutoRemove(nacl_no=&#8221;1111&#8243;,<br>region=&#8221;KR&#8221;,<br>drop_port=&#8221;1-65535&#8243;,<br>drop_proto=&#8221;TCP&#8221;,<br>api_server_ncloud=&#8221;https:\/\/ncloud.apigw.ntruss.com&#8221;,<br>log_filename=&#8221;\/var\/log\/nacl\/drop-1111.log&#8221;)<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from nacl_auto_class import NACLAutomation\nimport re\nfrom datetime import datetime, timedelta\n\nclass NACLAutoRemove(NACLAutomation):\n    def __init__(self, nacl_no, region, drop_port, drop_proto, api_server_ncloud, log_filename):\n        super().__init__(nacl_no, region, drop_port, drop_proto, api_server_ncloud, log_filename)\n        self.action_code = \"DROP\"\n        self.uri_remove = \"\/vpc\/v2\/removeNetworkAclInboundRule\"\n\n    def get_ip_list(self):\n        with open(self.log_filename) as f:\n            lines = f.readlines()\n        current_time = datetime.now()\n        ip_last_seen = {}\n        ip_list = []\n\n        for line in lines:\n            log_time, ip = re.search(r'INFO:root:\\[(.*?)\\] (.*?)\/32 DROP', line).groups()\n            log_time = datetime.strptime(log_time, \"%Y-%m-%d %H:%M:%S\")\n            ip_last_seen[ip] = max(log_time, ip_last_seen.get(ip, log_time))\n\n        for ip, last_seen in ip_last_seen.items():\n            if (current_time - last_seen) > timedelta(days=1):\n                ip_list.append(ip)\n\n        return ip_list\n\n\n    def get_rule_priority(self, remove_ip):\n        rules = self.get_nacl_rules()\n        for rule in rules:\n            if rule['ipBlock'] == remove_ip+\"\/32\":\n                return rule['priority']\n        return None\n\n    def remove_nacl(self, remove_ip, priority):\n        uri = self.uri_remove\n        uri = uri + \"?responseFormatType=json&amp;regionCode=\" + self.region + \"&amp;networkAclNo=\" + self.nacl_no + \"&amp;networkAclRuleList.1.priority=\" + str(priority) + \"&amp;networkAclRuleList.1.protocolTypeCode=\" + self.drop_proto + \"&amp;networkAclRuleList.1.ipBlock=\" + remove_ip + \"\/32\" + \"&amp;networkAclRuleList.1.portRange=\" + self.drop_port + \"&amp;networkAclRuleList.1.ruleActionCode=\" + self.action_code\n        self.make_request(\"GET\", uri)\n\nif __name__ == \"__main__\":\n    nacl_remove = NACLAutoRemove(nacl_no=\"1111\",\n                                 region=\"KR\",\n                                 drop_port=\"1-65535\",\n                                 drop_proto=\"TCP\",\n                                 api_server_ncloud=\"https:\/\/ncloud.apigw.ntruss.com\",\n                                 log_filename=\"\/var\/log\/nacl\/drop-1111.log\")\n\n    ip_list = nacl_remove.get_ip_list()\n    for ip in ip_list:\n        priority = nacl_remove.get_rule_priority(ip)\n        if priority:\n            nacl_remove.remove_nacl(ip, priority)\n<\/pre>\n\n\n\n<p>\ucd5c\uc885\uc801\uc73c\ub85c \uc644\uc131\ub41c \uad6c\uc131\uc740 \uc544\ub798 tree\uc640 \uac19\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[root@manvscloud-bastion-kr2 dos-blocker]# tree\n.\n\u2514\u2500\u2500 manvscloud-alb\n\u00a0\u00a0 \u251c\u2500\u2500nacl_auto_block.py\n\u00a0\u00a0 \u251c\u2500\u2500nacl_auto_class.py\n\u00a0\u00a0 \u251c\u2500\u2500nacl_auto_remove.py\n\u00a0\u00a0 \u2514\u2500\u2500__pycache__\n\u00a0\u00a0     \u2514\u2500\u2500 nacl_auto_class.cpython-37.pyc\n\n\n2 directories, 4 files<\/pre>\n\n\n\n<p>\uc644\uc131\ub418\uc5c8\ub2e4\uba74 crontab\uc744 \uc774\uc6a9\ud558\uc5ec \uc6d0\ud558\uc2dc\ub294 \uc2dc\uac04\ub300\uc5d0 \ub3d9\uc791\ud558\uac8c \ud558\uac70\ub098 \ub4f1 \ub2e4\uc591\ud55c \ubc29\ubc95\uc73c\ub85c \ucf54\ub4dc\uac00 \ub3d9\uc791\ud558\uac8c \ud558\uba74 \ub418\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p>[\ucc38\uace0] \ub4a4\ub2a6\uac8c Application Load Balancer\ubcc4\ub85c \uad6c\ubd84\ud574\uc57c\uaca0\ub2e4\uace0 \ud310\ub2e8\ud558\uc5ec Application Load Balancer\ubcc4\ub85c \ubd84\ub9ac\ud558\uc5ec \uc0ac\uc6a9\ud560 \uacbd\uc6b0 \ucf54\ub4dc\ub97c \uc870\uae08 \uc218\uc815\ud574\uc57c\ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \uc704 \ucf54\ub4dc\ub4e4\uc740 \ud604\uc7ac \uc804\uccb4 Application Load Balancer\ub97c \ub300\uc0c1\uc73c\ub85c \ubd84\uc11d\ud558\uae30\ub54c\ubb38\uc5d0 instance_no\ub85c \uad6c\ubd84\ud558\uc5ec \ubd84\uc11d\ud558\ub3c4\ub85d \ud574\uc8fc\uba74 \uc6d0\ud558\ub294 \uacb0\uacfc\ub97c \uc5bb\uc73c\uc2e4 \uc218 \uc788\uc744 \uac83\uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading has-white-color has-cyan-bluish-gray-background-color has-text-color has-background\"> Personal Comments<\/h3>\n\n\n\n<p>\uc9c0\uae08\uae4c\uc9c0 Cloud Log Analytics\uc640 NACL\uc758 API\ub97c \ud65c\uc6a9\ud558\uc5ec \uc6f9 \uc811\uadfc \ub85c\uadf8 \ubd84\uc11d\uc744 \uae30\ubc18\uc73c\ub85c DOS \uacf5\uaca9\uc774 \uc758\uc2ec\ub418\ub294 IP\ub97c \uc2e4\uc2dc\uac04\uc73c\ub85c \uc790\ub3d9 \ucc28\ub2e8\ud558\uace0 \uc77c\uc815 \uc2dc\uac04 \ud6c4\uc5d0 \ud574\ub2f9 \ucc28\ub2e8 \uaddc\uce59\uc744 \uc790\ub3d9\uc73c\ub85c \uc81c\uac70\ud558\ub294 \uc2dc\uc2a4\ud15c\uc758 \uad6c\ud604\uc5d0 \ub300\ud574 \uc0c1\uc138\ud558\uac8c \uc54c\uc544\ubcf4\uc558\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uc774 \uc2dc\uc2a4\ud15c\uc740 \uac1c\uc778 \ud14c\uc2a4\ud2b8 \ud658\uacbd\uc5d0\uc11c \uc801\uc740 \ube44\uc6a9\uc73c\ub85c \uc0ac\uc774\ubc84 \ubcf4\uc548 \uc704\ud611\uc73c\ub85c\ubd80\ud130 \ucd5c\uc18c\ud55c\uc758 \ud6a8\uacfc\ub294 \uc5bb\uc744 \uc218 \uc788\uc744 \uac83\uc73c\ub85c \ubcf4\uc785\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uae34 \uae00 \uc77d\uc5b4\uc8fc\uc154\uc11c \uac10\uc0ac\ud569\ub2c8\ub2e4.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"137\" src=\"https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2021\/08\/25143135\/ncloud-master-1.png\" alt=\"\" class=\"wp-image-1265\" srcset=\"https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2021\/08\/25143135\/ncloud-master-1.png 800w, https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2021\/08\/25143135\/ncloud-master-1-300x51.png 300w, https:\/\/cdn.manvscloud.com\/wp-content\/uploads\/2021\/08\/25143135\/ncloud-master-1-768x132.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>\uc548\ub155\ud558\uc138\uc694 MANVSCLOUD \uae40\uc218\ud604\uc785\ub2c8\ub2e4. IT \ubcf4\uc548\uc740 \uae30\uc220\uc774 \ubc1c\uc804\ud560\uc218\ub85d \ub354\uc6b1 \uc911\uc694\ud574\uc9c0\ub294 \uc694\uc18c\uc785\ub2c8\ub2e4.\ucd5c\uadfc \ud2b9\uc815 \ud574\uc678 IP \ud558\ub098\uac00 \uc6f9\uc744 \ud1b5\ud574 \ucd08\ub2f9 \uc218\uc2ed\ubc88\uc758 \uc5f0\uacb0\ub85c \uc11c\ubc84 \ub0b4 \ub514\uc2a4\ud06c \uc6a9\ub7c9\uc774 \uac00\ub4dd\ucc28\ub294 \uc0ac\ub840\ub97c \uacaa\uc5c8\uc2b5\ub2c8\ub2e4. \uc774\ub7ec\ud55c \uacf5\uaca9\uc740 \uc790\uc6d0 \uace0\uac08\uc744 \ub178\ub9b0 DoS \uacf5\uaca9 \uc720\ud615 \uc911 \ud558\ub098\uc778\ub370\uc694. SQL \uc778\uc81d\uc158, XSS, CSRF \ub4f1 \uacf5\uaca9\uc744 \ubc29\uc5b4\ud558\ub294 \ub370 \uc720\uc6a9\ud55c WAF \uc11c\ube44\uc2a4\ub85c\ub294 \ud6a8\uacfc\uc801\uc774\uc9c0 \ubabb\ud558\uc5ec \uc11c\ube44\uc2a4 \ub2e4\uc6b4\uc73c\ub85c \uc774\uc5b4\uc9c8 \uc218 \ubc16\uc5d0 \uc5c6\uc5c8\uc2b5\ub2c8\ub2e4. \ub124\uc774\ubc84 \ud074\ub77c\uc6b0\ub4dc \ud50c\ub7ab\ud3fc\uc758 Security Monitoring \uc11c\ube44\uc2a4\uc5d0\ub294 WAF \uc0c1\ud488 \uc678\uc5d0\ub3c4 Anti-DDoS, IPS \ub4f1 \ub2e4\uc591\ud55c \uc11c\ube44\uc2a4\uac00 \uc874\uc7ac\ud558\uc9c0\ub9cc \ubcf4\uc548\uc5d0 \ud070 \ube44\uc6a9\uc744 \ud22c\uc790\ud560 \uc218 \uc5c6\ub294 \uae30\uc5c5\uc774\ub098 \uac1c\uc778 \ud14c\uc2a4\ud2b8\uc6a9\uc73c\ub85c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 \ube44\uc6a9\uc5d0 \ub300\ud55c \ubd80\ub2f4\uc774 \uc0dd\uae38 \uc218 \ubc16\uc5d0 \uc5c6\uc2b5\ub2c8\ub2e4. \uc774\ub7ec\ud55c \ubb38\uc81c\ub85c \uc624\ub298\uc740 \ub124\uc774\ubc84 \ud074\ub77c\uc6b0\ub4dc\uc5d0\uc11c \uc81c\uacf5\ud558\uace0 \uc788\ub294 \ub2e4\uc591\ud55c \uc11c\ube44\uc2a4\uc758 API \ub4e4\uc744 \uc774\uc6a9\ud558\uc5ec \uac04\ub2e8\ud558\uac8c \uc6f9\uc73c\ub85c\ubd80\ud130 \ub4e4\uc5b4\uc624\ub294 DoS \uacf5\uaca9 \ucc28\ub2e8 \uc2dc\uc2a4\ud15c\uc744 \ub9cc\ub4e4\uc5b4\ubcfc \uac83\uc785\ub2c8\ub2e4. DoS \uacf5\uaca9\uc744 \uc804\ubb38\uc801\uc73c\ub85c \ucc28\ub2e8\ud558\uae30 \uc704\ud55c \uc11c\ube44\uc2a4\ubcf4\ub2e4\ub294 \uc644\ubcbd\ud560 \uc21c \uc5c6\uaca0\uc9c0\ub9cc \uac04\ub2e8\ud558\uc9c0\ub9cc \uc5b4\ub290\uc815\ub3c4 \ub9cc\uc871\uc2a4\ub7ec\uc6b8 \uc218 \uc788\ub294 \uc2dc\uc2a4\ud15c\uc744 \uad6c\ud604\ud574\ubd05\uc2dc\ub2e4. Idea \uc0dd\uac01\uc740 \uadf8\ub9ac \uc624\ub798\ud558\uc9c0 \uc54a\uc558\uace0 \uadf8\ub0e5 manvscloud.com \ud658\uacbd\uc744 \uadf8\ub300\ub85c \uc774\uc6a9\ud558\uc5ec \uc77c\ub2e8 \uc2dc\uc791\ud574\ubcf4\uae30\ub85c \ud588\uc2b5\ub2c8\ub2e4. \uc544\ub798 \uc774\ubbf8\uc9c0\ub294 \uc0dd\uac01\ud55c DoS \uacf5\uaca9 \ucc28\ub2e8 \uc2dc\uc2a4\ud15c\uc774 \ub3d9\uc791\ud558\ub294 \ubc29\uc2dd\uc785\ub2c8\ub2e4. \uc6f9 \uc11c\ubc84\uc5d0 \uc5f0\uacb0\ub41c ACG\uc5d0\uc11c HTTP \uc811\uc18d\uc740 Application Load Balancer\uc758 Subnet \ub300\uc5ed\uc5d0\uc11c\ub9cc \uc811\uadfc\ud560 \uc218 \uc788\ub3c4\ub85d \ub418\uc5b4\uc788\uae30\ub54c\ubb38\uc5d0 \uc9c1\uc811\uc801\uc73c\ub85c Web \uc11c\ubc84\ub85c \uc5f0\uacb0\ub418\ub294 \uac83\uc740 \ubd88\uac00\ub2a5\ud55c \uc0c1\ud0dc\uc785\ub2c8\ub2e4. \uacb0\uad6d \uc6f9 \uc811\uadfc\uc740 Application Load Balancer\ub97c \ud1b5\ud574\uc11c\ub9cc \uac00\ub2a5\ud558\uae30\ub54c\ubb38\uc5d0 ALB\uc758 Subnet\uc5d0 \uc5f0\uacb0\ub41c NACL(Network Access Control List)\uc5d0 \uc815\ucc45\uc744 \ucd94\uac00\/\uc81c\uac70\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud588\uc2b5\ub2c8\ub2e4. \uc5ec\uae30\uc11c \uc911\uc694\ud55c \uc810\uc740 NACL\uc5d0\ub294 \uc815\ucc45\uc774 200\uac1c\uae4c\uc9c0\ub9cc \ucd94\uac00 \uac00\ub2a5\ud558\uae30\ub54c\ubb38\uc5d0 \uc5ec\ub7ec\uac1c\uc758 ALB \ub610\ub294 Subnet\uc774 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"\ub124\uc774\ubc84 \ud074\ub77c\uc6b0\ub4dc\uc758 API\ub97c \uc774\uc6a9\ud558\uc5ec DoS \uacf5\uaca9 \ucc28\ub2e8 \uc2dc\uc2a4\ud15c\uc744 \ub9cc\ub4e4\uace0 DoS \uacf5\uaca9\uc73c\ub85c\ubd80\ud130 \ud0d0\uc9c0 \ubc0f \ucc28\ub2e8\uc744 \uc9c4\ud589\ud569\ub2c8\ub2e4.","jetpack_seo_html_title":"[NCLOUD] API\ub97c \ud65c\uc6a9\ud55c DoS \uacf5\uaca9 \ucc28\ub2e8 \uc2dc\uc2a4\ud15c \uad6c\ud604","jetpack_seo_noindex":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[249,812,899,32,900,87,91,17,90,16,220,89,202,398,221],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/manvscloud.com\/index.php?rest_route=\/wp\/v2\/posts\/2426"}],"collection":[{"href":"https:\/\/manvscloud.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/manvscloud.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/manvscloud.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/manvscloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2426"}],"version-history":[{"count":2,"href":"https:\/\/manvscloud.com\/index.php?rest_route=\/wp\/v2\/posts\/2426\/revisions"}],"predecessor-version":[{"id":2431,"href":"https:\/\/manvscloud.com\/index.php?rest_route=\/wp\/v2\/posts\/2426\/revisions\/2431"}],"wp:attachment":[{"href":"https:\/\/manvscloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/manvscloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/manvscloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}