# easy_ngx_waf **Repository Path**: hzdwang/easy_ngx_waf ## Basic Information - **Project Name**: easy_ngx_waf - **Description**: 适用于 nginx 的WAF,建议 openresty 环境下使用。语义化过滤规则; IP白名单、IP黑名单、UA白名单、URL白名单、URL过滤、UA+IP蜘蛛校验、境外IP过滤、UA过滤、CC攻击检测、COOKIE过滤、GET参数、POST参数过滤、HEADER过滤; - **Primary Language**: Lua - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 7 - **Created**: 2023-05-24 - **Last Updated**: 2023-05-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # easy_ngx_waf > 应用于 `nginx` 的 `waf` (建议用 `openresty` ) 项目由来: > bt面板相信很多人都不陌生也有用过(或正在用),这无疑是一个很好的产品,为广大站长提供了极其方便的管理功能(包括有免费的WAF功能),但同时也有大家都知道的问题(懂得自然懂的)。 > > 为此我目前已经改用 [`OneinStack`](https://oneinstack.com) (^∀^)(当然也可自已搭建环境或者 [`LNMP`](https://lnmp.org/) 也是不错的选择)。 > > 针对 WAF 这块,之前基于 `loveshell/ngx_lua_waf` 改造了一个 [`cls_lua_waf`](https://gitee.com/chleniang/cls_lua_waf) 项目,此项目也是为了学习下 `lua` 及熟悉下 `openresty` ,故功能也比较简单。 > > 在研究了下 `ModSecurity` 后,就想将其规则相关的设计借鉴一下(本项目在规则设计这块进行了相当的简化),于是就有了当前这个项目。(同时当前项目中一些功能也借鉴了 bt WAF中的部分功能设计) ## 功能特点 - 防护功能:见 [检测流程](#检测流程) 中各个检测阶段; - 简单易写的规则文件(规则文件请参见 [`easy_ngx_waf_rule`](https://gitee.com/chleniang/easy_ngx_waf_rule) 项目); - IP检测全面支持IPv4、IPv6的CIDR格式; - SEO爬虫放行,避免误拦截; - 可指定域名取消WAF检测,针对同时拥有多域名的服务器更加灵活; - 支持指定 "具体域名" / "通配符域名" - 支持 "全局" / "某一检测阶段" 取消WAF检测 ## 检测流程 > IP白名单、IP黑名单、UA白名单、URL白名单、URL过滤、UA+IP蜘蛛校验、境外IP过滤、UA过滤、CC攻击检测、COOKIE过滤、GET参数、POST参数过滤、HEADER过滤 ![waf检测流程](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbwAAAOICAMAAACaGrR/AAABmFBMVEX////4zsyw4+YAAAAboeLExMS4VFDY2NhnZ2eCgoL29vakpKTs7OwUFBROTk5HR0c7OzsnJyeJiYmdnZ12dnZiYmKwsLDr6+sOgIhYWFgvLy/x8fEAbq8ICAjZ2dkGBgZ1dXWxsbHPz8+AgIANDQ3mv73Sr60PDw/vx8VwcHA/Pz+6urqOjo5kU1ILhcaMjIyQkJALCwvk5OQlJiaj0tVWR0YIfr+/np36/PwgICCXl5fZ7/qZmZnD5vdxkpTp9ftFOTladXbm8vhHXF2/2+us0OUZnt+Twt0Uk9QJdrUDdLWghYMZGxtuw+1+aWiVwMNdXV2P0fExP0Ck2vTf39/PhoNyX14XFxfy+v6At9fIyMiGrbBWuemq2963t7cuJibO4++g2d252tyEudkVltd2sdRxrtIRj9DqzcxOm8hyvcLywsA2jcAigbodfrhssrdYqK3fn5wukpnUl5UfipHDa2i+YV3z8/O+vr6rq6uQeHehoaHDw8NKo6psbGxRaGrT09M9Tk+1lpWrjo0wPj/dt7ZqiIoAN1cdFvVHAAAtkUlEQVR42uzcTarqQBAF4IZXyzhryLARmiYgmphABpJJBAeCfwjqNt62XxKvaC76zJ1VXc43CY4P3Xb1TzkiIiIiol9mspnn29U2n28mjiyZ7c94OO9njmyYri5oFT7p+AKty2rqSL30AKBMFpncZYukBHBIHemWF4BfyHcLDxS5I8WmJ8Dv5JWdB06cO/WaXVEe5Z1jiStXLlrNAZ/Je5kH5o40mgOJ/F/C9HSa9dl9To8zpz7TKxL5LMGVqxZ1TvAyhsfJkS45ykzGyEqw3tMlLXCUcY4ouNeiygFexvI4ONJjCuxkrB3ANYsiK3gZz2PlSI0LFjLeAhdHWsxQyk+UrNT12CORn0iwd6TE+fusGYP0qrTqP038Nm+eHekwAbLX4UlM19JaNkt5kgG8laTEBoXcrZ8K8KYSCXVwX9oc7wpsHKkwHxQKsb6NvBgH43DA82RIi3ywXqmauourbj8S3GT5KryE+5tabIeLzTq0ca1DdVuxdOG5ThiEt3WkwuopvOiehK/wwi3Sh4R7LFo8Rt4jwVp6fXghduFx5KmUD8NbTmIMIV1/hRfqtEsyBv7naTRYbVZNG1sMbYTtt/3lwq3Wi5GrTY2e67zQVPdhtpx0a86qL9BvcyfrPH3e77C01tNlX7k3FXdYVDp/PhHi3qZWPFUwjOd5lvEk3TDeYTGMt8cs471Nw3hj2jK+VbCMr4QM4/s8y/gy1jK+SbeM3SAsYx8Wy9gByTT2HrOMXf9MY79N29jp1ra+x/Rf9pi2648jsxieYQzPMIZnGMMzjOEZxvAMY3iGMTzDGN4/9s5up3EYiMKWLMs/MYS/gtIopKhIVbsXILiCp9j3f5ptInfThMrBmUKPmxwhQLQqX+Z4PJM2sSPVS/nKOHstX9ik6JSXxYqvijJnk+LT+plvtWSTIlRecM6LKfHi1Pp5SrxolRdT4sWr9ZR48SrnuIn3yCb5JGarmWCQErMNKhqEbq+ubx5vrq9uGZyA0RAk7y4un+rfni4v7iQDEjAahO5dVJpo3TMQAaMh6MHNR9156oGdXMBoEBIzPhOev39fY0KDkG8YP4R1CCNCQ5ArIP0Fp18jQoOQ9+iDOoQxoSHIO+8EdQhjQvsJJVzUP+aS1AnQn2+UMtXTUxuCT0cLDBPWbKuraNlU0IYrPR2M4gnBPAJaSJjAGlWb6i2aJnYC9EJklJ7Lg+adHG0/TGASXIjUEo+SHl2jhFbmkHknR9sPE5qSdC4o8wt9XnPm2TQ5YN7p0f6HCWzSdBMWqbLTOwRnHhNz+cU8ALQdINykWUkntGFJTxNnHtPqT9c8ALQmTIDSCbEg0AuUM8+mWdc8ALRIzQvrBAhRd+YxwbvmAaDFaN73OgGZNiFsN9NCO1P657vmedpjXgiaTflOcxmOFo95ARW87gYTXkkZVinRrJHmtVz6aGVcgEI7BDqaVZa5b5n0oZ3hx0bt4deNkHbHL+ec78dE6yYZjeI7KUPp8V/yIWhWicxaZW0mMulDO7ePjZqJ3xchmdntF6tVj3GbJknzDpdZSDf05cJQCldZrvNwNKusXLzVDmbSh3ZeHxs9OepQ82wqmFHqLa0f7Q5v/xVCPr0Wz8U6D0Vr1TwKWkRqrpHzRsids7bMc3Gpx3Z3ePdfm+d5fMV5ZV8QWpuKhAZywe6G9+rj/ZO15O0KujUvaQZ0Z3j79fn+0QdW/t0MReOCiEbVhh1B/HiZV6udeVW4Evf3hTlu5vFimQehtTOPhoZxvzen1Ty/eXXmNRFqR49W8yrrQtCcXY3EcDSYm/V5SLdJNE/wfQlSt7kM7Ta7Go6Gs9ICP955Xi1PzesM7989z3MndCKtTxO0MoPR4jSv520G4rTpf306mrtgQeuKsDJ1EFrE5pGGX3hmnw0aiHm/+tb9OaGBmHfoaGCiDowGYt7BeQRmvgNGAzHv5y4UAXrJ/dc5L/PcsARKkzjQQMzbFQSgAhUHGoh57iiROoEo0EDM280vMJ1AJGgo5rnKDtIJRIKGYx70TXCYaEjmYd9+CogGZh70jd9waHDmYS+5gIWGaB70YidIaJjmQS8zhIOGah72Al8gaMDmQS+tB4EGbR72opanR0M3D3o5WTH7CEQbm3nQCzkHHTnmfx/vTk1Djhxsk6XJvAChbbI0mRckrE2WRm5e4NJ0YJssjd68wKXpoDZZGr15YUvTYW2yNHrzhixNR9e6XOKXbfTzvGFL09GV/2PvjFajBqIwvGWIyWRSg14oa0iztMJiFWzXGxUfwYteWASfoNCrIq2I4LObyWZ7do/NbJI223My5weh1br8m69nZpKdOf9ZRh0e4ScsAA9a0w2oi/ObJy7dnF/Qgvf4DxCdUqg13ZD6eX11uefS5dX1TzrwSDy6d0p1bk3Xn9353nad/yQCj8iHZk4p1JpuOF1c77XR9QUBeHQ+rm4Lb6IHhXd+1Qre1fmjw6O0UYTITdLNZSt4lzeye4wevCd77fRE9m0KvHFsSxZ4jA8E+AiPTJYQksBDUpSzhJAEHpKinCWEJPCQFOUsISSBh6QoZwkhCTwkRTlLaFMCD0tRzhJCEnhIinKWEJLAQ1KUs4SQBF4neP2HuDgyqOEs6tBtdPehWOA9YKdbgJCkAcQUQMPbWsFG8+bgVQjsuixeBN7dbyF732dZj+EF06lZpYMALlt3UIwGJWk5KxtbE3j/v4XsqCj6zEkYnjYmijdizHS1v+dwFt8+bjOm/ut4Fm6dU7E1gYffQnaUv85PeuQqYHjJNAzTEMPTunrGravyw5Xn3ryErQm8TSl7fZSa90k0wfBs2WmN4G18UIErz71tEFsTeEjq7LRvlhCGZ5lV8xue88JXUGuo8lyBPcdOazTSfEhU3v79K2+1pjSblWdJRjEkZXWsPGuNuwaf8476znlBFNfpj3qVEImHzXAG8OCvW2zYXVljrsFXm3nf1WaSmiUyW3xLjA54SarWpFutNvMJc9G9z7MzXIXBrO7mtGPOc1Se4z6Pueg+YblDbYZNWh8PIY0SHrfAHiKiAm9Enyo4NF54Y/k8r1mjhjeOT9KbNXZ4I9jD0igP4LHfPdYsH+Ax37fZLE/gcd4x7ZAv8PieVXDII3hMTwk1yjN4LM/nNcs3eAxPxjbLQ3jczqQ75CM8Xt0gHPIUHqM+LI3yGB6bDkgOeQyPSe8xh/yGx6Hrn0uew6Pfb9MhgUcgsIeIeMLzuf+4wBuHBB5jCTzGYg1vLbDHSzGHp4zAYwtPvwoFHld4NrBH4HGFl6RG4HGFZ5uvCDyu8Gxgj8DjCi9JpwKPK7xJoAQeW3gTLfAYwvNdAo+xOMJ7X5yUL39SsO/m4CO8rMjnap4X2cRzcYRno9xLsW9g5Ce8LC/Z5d4XHk94ZelJ4bGFl+VSeGzhTd4UUnhs4WVP6RbegePfBJ7ddHtMddOty5rAI73dfYs13+ERPmjSwprX8Agf8WpjzWN4hA9XtrTGGR6kNY/rWHNba6zh3aY1j6qhQBdrnOHVac0jauXR0RpneHVa82ia6HS1xhteldY8kvZVj2+NXlrzjhrHwQkjcj3tYF1HDN5EGxotG+GEEb1ukqt1HbXKK+HRaJYKJ4zo9XGt13Xkhs0SHo02xXDCiGAH5eW6jiW8nTQIhxNGFHuX23UdvQULmdb8cMKInLXKnSa42iQTigEnjMhZs9KGG7xdxtHACSNy1jjC220QFJwwImeNHbwuKwG0jA7TEJDMQogsdY53cMLo4Rcpeu0mO3y3zLxNE4j/Q9aYw6tncHRhgzSpsyotCwPAkinggvhKs/wuAHZNr9/b2naHAC9Mv1Q2tLZ2kuhgegjw0OsTfTzWOXYUX5qg+l7DpdHqVmZZd1CMAfxb0Kt83mcOa9sdgsHAPiDRll4y/RIdTg8A3v0r+8uuAn+LHgM/XBr4CuCVyCDW3qQHUWL/h6l+TkPafa+JqyjeZA5r7RxabnVccZqURgIMr6s1TLv4+mc3UdsnHaK2u8Mz9iGJCqrpBVVe4w4hl05KxxYfWOsOzw7dcTStJroX6Y80dMBzWHMoUvkHs4OQ+3nXkHv3oITh1cjsF7jyHHvzHJ7mSll8yFo3h+9SZdbz3t9ieP2sgRZKqfzZ7wHhnZ2qLfr04fP2S1PnnjfOeRCQHrgqD/T5wye1RcXZMVjr7DDRs7ezsPoRbZb4DmcLBK+btWNVFHl++no+39///v3r16JyORu68vbvX3nVmruh8rRdg8MS70EqT+VHqPK6OTSBDuzXxlSr4nD6oqy9xf0q7+PHj3H8K8uS5OXLxeLba8suCgef8466znkAyETx8iLpNGkcNpMI4G2Mpj3nPIvOZW27wxdxaaXkZsfL+gZCl3+Sh5vznp/O1d+DHaw28x6rTfvE2A6Ipv4NT9IobgHPjmCgKO612rToXNbcDldWrM1wGgX1A/A0sm7iB1ptLgr19xvZ+7z6zrt+69W3emKUlXbMeajyBrzPczus4K1+r8JpYgdVuyyOH+o+72xB+AmLQx2GzSGfsLilA3jsE2izfNDyLlVpwusJC4W40Kp8aMatV9bY7B4j9eieuzVC8O56N2SuOklrpODdOY6QGe/oWaMGb7iNIoResnodhjumKW3RYm+NIrzVhEBogqJpjSi8+l0SWhpStEYW3mp8IXRTRs4aZXiDHcUZizXa8CgcgiNsjTq8xz9+StgaA3hyJp01POkGwRue9GFhDU86ILGGJ73HeMOTrn+s4Um/Td7wiHe6/VRaa2jzIvDqRs5kdRskLfD4CYKkBR47rQVJCzxuWguSFnjctB4kLfCYaSNIWuDx0kaQtMDjpY0gaYHHSxtB0gKPl5rfucAjL4H3j70z6m0aBgKwJctKLmcIIAFKq5JoIE20laDwAqg/gQfekHjgb4AEPx7HTnFqUtMWAr7kPjSN0W0K+3b2xbHvCMPyCMPyqC9MD8Py0n4kxPJSeuLJ8gjvNWB5hHf5sDzC++tYHuGdrSyP8J5ylkf4NAfLI3yOiuURPsHI8sKufoTODrO8oKsfpVP7LC/S1S8+h/n+JEWOPnodh1qzsgVTSV6mKu/crn5eQChPV01ehPJcrVlMJHmZrLygq1986BuSp/Kb0llF8PLcx4kkL9OVV+RwUdIRygO07wflJZK8TFeeALw0SfHyXOcgVeoBedlCJZK8zFSen6tOyUNw2aqSFuwnLKmsvMxSXveDjsnTZVd1P4i8pFZe5icvNsRllRZdwJXa9TQI5CW18jJhedEkJZbkoBEH4D7GQF5SKy/TkXddU4wQcGOlS0qcR0NUXjyyw0tjecPND5N5GtCbU8NLY3nXNz8cnXDzUnhpLO/a5ofjE24bDC+N5V3X/PDf8+712lzaiKzFScjI65ofpht5dwR10mx+6BlzznsqiJNm88MDqFyLNYfC3plTAb2n8tnWLZiV+twOg+7SiJP2fR4q22QQuna+aN7gSF5W7l13OlDmvT6/k7y7NOKkvMLSeiu3j6rMiOn6CSqQLYvMvle6VAJae7ra+37Wie5tEWKa8obXNrMtPirLJwd5W4W4r3QXecabeUO3MQaUUF5eorvKhJiqvMOcFMrLte7L6zdpVUVeSUP5qPxUZj15ie7nFGLC8oIftJNXlUZP9VMeSAeIbSmx/9Ro4+UlupPaMGV5fojzc57WuT6KPCWhHTWh2TSZDUNAp++m6TrJJ7QNMGDi8nxyYSNP2ad5vYRF6KYCJQQqUAJBIOoqaz/pkYm9Tt6kk5S05fUjBh9BgRJ+Rp4QRXOTtyH3qDDy7HS4abNN7PaD6lbepJOU1OX5uQo3zY35s2/lCaH2TQZY5CorM3efB5hVeZfEqDLPC/vXSScpBOTZ5OV+l5t0A6ZdRAEnKi+sPNfk3g6t7VIL5oV5+cGkkxQS8g6LyFAIYYdNkHmRbfvLY0aqAxWgW2jZruVu2kkKFXlETwmdZGbySJ7PO83c5BE8GXuaGcqjdiY9whzl0aoGEWGm8gjVYTnJjOWRqYAUYcbyiNQeizBveRSq/sWYubz0623GivCyPNthMNUkJVqEl+WlXH+c244m8O1pTMcsj3AizPII34KSlvcnLZGnsPhDXJ7E/y/vomVXlvenLZGn8sCDuLwrWyJP5FEjdXlXtUSeykN+6vKuaomc+PYaXxB46vL+dkvkFIrwHgoCTz7yxmuJHJ/DRpsjfUHg6Q+bY7VEjgsYUbwvCDwHeSO0RI4PfaMOub4g8MQTlvGIJx3jf58ih6lnmyMSj5jxIxiQ5SWQpETnTpY3SEJJSvQXguUFjJqkIIqu2q4FwWdOgZum6NJ+wzZzpbDRnnk6HopZ3lj45MLLQ+lAq83LU6XuXsuLgzxo7GtZaY/sIiIYeeH3n+Py2N/nxfK3SQp2HQLQOsgWrSrdkwfCAPnNwjrEvHD1edFIBAzkXXn7Ub1heQPU9fNlZE5ysqpKOhaZHd7Ur/KySlu7WOr2a9BEYRHIu35O/VbvoGB5v/DSFAM0+mKbiBDDwvMIRS7hF3mQF6pcSMM+R4CIPL956Tzuyt3q6ZLlhdxK2eqLbN9DFEo6VGErU4BqxSwyL6/Iwfhb9FZ+zGdG5Pltg2KYN2/eFMWX5VLrx49fvfpcm6usn2qq8tZyROoP66AIbyAPnA+VbUVWqlzbEhRldpSw4L7ZgM0tXV+IVrAK5YVFeN/KQdayrle73bPb2zt3Pr5//162rDZU5Y3FbftTeXpu5LlFZDzKNkFYNNw0ha4ynWv7T7BvY++6yAv5vDMXWX4nO2yOxMtVqy4+58nF/hB53e3ckLzspn0BwY6XQhiNNkcVf2POuyd366+EE5aRqOunv8s2QfjI61KTIXnOqnkVmsZVIynyxt40/HG2ifW9DelbhYCx7/NCEDJX+ROMr9PyfHoKqEtwT8f//D7vG/Gb9HGJr4CAlK6hWPkqN6oiy2MgHeWrRpUuTrftF898heUMUnoAG33MNLvdY+dA+akCy0vpBz38CzHPfZtnkdIQNzAUz3bT7WWQ28PC8hzJJS82gme93f0iEpqr7Nw597MKl5JG8mLF80GTy/nvycthyGV5/50UivCyPD6fN0d5fDKWOnwmnTZcDYI0XIeFNFwBiTZce4w0XPWPNlxvkzSmCC9XuqXL6f85y0selkcYlkcYlkeYSBFelpc6nTyJLI8evggvyyNHrwgvy6NGrwgvy6NGvwgvyyPGURFelkeLoyK8LI8WR0V4WR4tjorwsjxa8PIYYVgeYVgeYVgeUV7UL4UUL+sXYhCWlzLLenUrb1f1UgzC8pLm+TNpeCqGYXlJs1wZd6tTgcfy0ub5s0jgsby0Wa4igcfyEud5fTrwWF7iLO+eDjyWlzbq4Zq3u9OED5pQhY94kYUPV1KFjzWThQsKkIVLefxg7+x6mgiiMDzNZJydndFRI5jdBksqLRVpFIhZIVz0vqbxgkjiBfwNQWOMxv/t7G7LYm2HshSZE94nIV0I6UWfnpkzX2eogiI6ZEH5KqqgcBxZbrFko+aieEkl5FVQKZZa7PY0ViDySkiVKTZWOYMKzeYEUgXCBRfCGshzECzNr20qkLD8TSCXWVz9PnGkkG06aF5HozTkBZCkePvOZcrr9bNGY+R+GtkI8u7uCrb68jqDrNF914G8OklKvC6rc3lCMz2+eNsk0tMUL02es9frfeqi2bwyudCKsclgOo6sqeQJu62KP+r8f+R6O3kxJW/5146OOOeDc14ygrypyPDJE0mic1uc81RKK8t0USbbSkRtj7xaw4+t3TmRh4RlTp/kl6e0LoqNOW9MpiL3GBkXhdojr26fetLir44gz8P0JiK/PJNIaYsGM5UmsdwRHUZfrPHIq3/JfcI3Wx/lv/L4aRfyGKu27y0mLw87pfIuz3Jx+T9myPNuG2SzeR/HTfN8d/fo6IX80T7j3Ol71J7u81yiecpzBp37LG9r74CxxeXFkSiLxEm1LiKTB+K4HISTp2Qlz8/B3j6fyVartbPx8OHxh/29vSdpmrZ4zgmazWVEnuAFmm2312We5ishE+N8RodKK1kj8rysbnDeio7Q592gzxMXKYoqNKrIrMZOnvOmVWFW6Xy4wJhcbp+X8p0ViYTlRtmmsbpQFufBN9aYy4sjIZJIFmkM00mSazRLzDbPXHf371Bh6NKVjI/p9+67vKvGeeWwzqnR1pS/qkJejlyPi9BU1hRxaZY5zhOYmL6VZSAnT/AxQmulCqmHKY9iz/tjA9I/BLQA641s7B6bBeFVBcgL6YOe/YXAvs25hNTEeZripcnrvHPTY1n/Z78HebOTi4De58HU1GbOKOv3svs9PeaNmGAieE7k9dBsevuqMPrO6YlpBxZjFxEQQtY6FXnD4dC1l91PiLwFmr47Hy/+JW+yHHT+rtN9hz7vDk4J1Zfn3PV7Luryjm80ROTROp93fs5zTrv90QBb/6idjM3KyGsMT7H1j9yZ9LG8zsAN9LAkRKwaRMZLfvZd2onIo1WH5SLcOoPTLuShAtJ9AbXHSIOqf7RBvU3SiJV9VLqlyx3dJVQdy8s4sk1i8hrZoFMuyPZ7PUxME5PnloR6/QzNJk15jQbkkZY32e0OeaTkjbjr8z6d58tBWM+jJq/R6XfcQmzGh6MRmk2C8vK56V5/0IE8evJ+912+ybMhR7NJT96v/jnP3FN3gEE6LXnZ4Fe/h+kxmvLOu40Mm26JysPENORB3hwgL3ggjzB3JK8z4DkoX1WbN623jLO3rTfsf/Bg+nDeGBw0qUWztbbJN9daTTYTyAuaVxvc8ZJ5uD155YrQAEe8atJc45yveQLvNuUV21i6OJ93g9DzBB7khU1zzRN4kBc4r1rzAw/yAqf5yBt4SFgCRqxseXZMI/IC5uqzChjnhclCp4QwPRYiC53PQ+QFCE7GkiWMM+mQR7gaBOQRrsMCeYQrIEEe3dpjkBdE1T/NRfGSSsi7BJF6m8qa4oIpRF4FmUq3xipnUKHZnECqxrTgQlgDeQXkqrtrmwokLBOI3asQRwrZpoPmjSZKQ14ASYq374S8mQSUpHi/EJDn4X8nKerSAFtuM8Ed1rA4EnObYsjzsvzkorp2VFdPF/KkPYzi/Bcl3KuJXiTtSODmyvosP0mRqS4H1NWT4g5hrGAqt2eSw6idvPDIqzP8+HZ8Bnk3TFLiSI/vaK6emPM2ucXZGiWY8Mir26fu8taHQ8irf0966ap6qqJRxFHCHXbVfrbSI6/+PenfN/jOxtMm5M1mke17wpqpJ8e25ZpdIKLXlbyFtg3Oi/Lm7pFsf/5ysnr29eCtanHOd/hryJvJ1t4BYzXkGbX+urzmnild6muv71by/Bzs7fOZbK1tHu8/SR9v2UfJSvTqWSHv8WfI80bedZtNLZRgWjGti1vtZbLqYm+3RuR5Odzha+kJ+ry6fV6VsBgrqqfV2Mlz3oRzFjuX46Uds9w+77j1QSNhWTDb9A8Vorh6Ksd5SsvEySpaT2Gj/M/xErPNb5tvMVS48WS0sZOhefWkSkkmMnmraXQqmXb24iWO89h7DNJvZxlICZnyEi2ULidati23BjMs1yGgBVhvZGP32CwIrypAXkgf9OwvBPZtziWkJm5GU4xNt4tAbw8L5JUEl7wUEYzt7osSUF9V9J04q3A9wkheCvE4aHJ97jx5mTS5kHfn1DwlBHlhgPN5tMHJWNLgTDptUA2CNKjDQhpUQKLNIrXHIC9YFqj6B3kBc0W9TcgLG7GyPzdJgbzgwUVQhIE8wkAeYSCPMLw8yBDFk/NDFZAXOmN5XEMePcbyVCohjxxjeUJFMeRRYyLPWA151JjIYyKVkEeMC3lMRa8hjxaVPGMTyKNFJY8JDnm0uCSPKcijBabHCAN5hIG8P+yd327TMBSHLVlWfGxvBiFATRUajUnVxiRYd8OmPcIukSbtYq8BCC54dPynIVtJurZjzEf6fRJtWLJe7OuxjxP7mDGQx5SPs09Cik+zj2IQyCuZ6ayZy3kzm4pBIK9ojg5l4L0YBvKKZtoEd81Y4EFe2Rwdrgk8yCubabMm8CCvcI5m44EHeYUz3R8PPMgrG/X6GNPdeYKFJlzBEi+2YHElV7CsmS0oKMAWlPLgCorosAXlq7iCwnFsecKSjVZ2+85CXg+XYqnkXdpWCpGXYVWmOO1DS4Rms4NVgXAllfIO8gIMS/NbXyskLPcpZDOLhz/HaEK2GeC5HQ1ZyCsgSVnbd0LeIAUlKWu/EJD3FwUlKYr+7C8rDDnnZUAJYalriiFvhadIUtLfPR0bHY7o/r6xblIlSdppGy9IqKU8o0/SaeXfxXdSZC1h29EnZCUylFQpguILdfdBlLS5VlWUl0+bJE91v5Q0EwlVR3t0EnfdzvJ2jmz9C/K26pO621XKu2gnQrT8YfQV5WWrvbzuKkHaJPmKhOvl7dqnft6b7R9A3sab3GdrnVRf5feJ636otAnynCexKs9oikNuGXjjv2m7Im+nTe5fzefN/g3kjTAwfc9qs6Ix6LLadB7dRPm6+iNPRsKFaiLTNZlwUS9vaNrgWLB9Nubr1L19u1gsvnx5dyXl3qn/AHmDHJ9dCLGlPC+JtFmNvJPL4CnllipdGyKvrQbkRS7OzuUgx3I2Oz2dz/eur67Oz8/PTk+llM0+5K2NvG2aTU8i/FuRV50oihdWraGU2rwJsVdtHHnDfG2Cupff0Wxu3Oc5r5bmRhOWlJTcl3dQqSCJrIvOkm+RhD+qz6OmObNIWDbONvuhAo0PFfLj75VsM8pT2mmieDpFZ+oaH5FtNtc/MFTYapwXnT08SDe6PrgzSKckL0FKRKdVbXO7+4hx3i0G6f/pMZCizqTUC61Sf6l0K6XCHZYRyrm3+XBkY/bY37B+qgB5Jf2hh78QmLc5SklN3EBTjEm3D1JS8nL3czBjegOKS15SBGO6+6YU1FelvhNrFbajjOQli8dCk6159uSla3Ih79nZcZUQ5JUB1ufxBitjWYM16bxBNQjWoA4La1ABiTeoPcYaVP3jDeptska9PkelW75gLyHGQB5jII8xkMcYKcRyBrzAJvfcWMqTFvL4sZRHdQV57FjKU6QN5HGjk+e8hTxudPJi8Q7IY8YfeYL0B8jjRS/P+Qnk8aKXJ5SEPF7ckScI8niB22OMgTzGQB5jII8pH2efhBSfZh/FIJBXMtNZM5fzZjYVg0Be0RwdysB7MQzkFc20Ce6ascCDvLI5OlwTeJBXNtNmTeBBXuEczcYDD/IKZ7o/HniQVzbq9TGmu/MEC024giVebMHiSq5gWTNbUFCALSjlwRUU0WELyldxBYXj2PKEJRutVOmtriCvh0uxVPIubTyFyMuwKlOcdnIjQrPZwapAuJJKeQd5AYal+a2vFRKW+xSymcXDn2M0IdsM8NyOhizkFZCkrO07IW+QgpKUtV8IyBvgvycpzivTJsMUD6rW2CwgHC3T/8BJZbQM2LTDc26KIe+JyMlFv2UspUQ+oZ2WCe9ihhFeTd5U1LQH7ZvWBFF35FGrVfyPP4jv1loK8rDt6BNyNzJsXeWqVClkOixlxXJJuMj57HaR3m0dj43VpkrZvw0SyXbydht+7H+DvM37pH5nezepBuT1F1jKWzZX+ZBilIXLrXcxdG2IQrMib4c+9fr0xS3kbbHJfW9pQB7JHu+qutWSnD4RqRMkbZSvZeBSW6IVebtscm/ncq9+A3kjpOl7YxmEkgl716nRNhyTzSEYpJG8JFdNnKgmtXeiw+gPA/L6aYNimM/m6/TtYvHlXfXr4Obm55WUcvbyAvIGOT67GEj/jI7OhppNK5WV5BaXdbVsWwOk4ll72X6gFK5RZa5KplblZS7OzuUgx7PmdL53fXV+9rKu6xcv9mSg2Ye8TSKvt2T0gDyjyUob01Eyur6tZUQJ5WslHB20Jth02qVr6TLG3qaRN4yL6vwNms1N+7zKVyPyMs7L6G/iUpDFg3yDsjqIQwVLqb1MQZk/6jF93vvm9PgbEpYNs83+wTYNNJtZnY3pZDqjlJQp3UyvomqTS2pbk8Qa3aZBw87Zpjl8eYuhwlbjvDxI11FAN6TL8vrTnQ0rJxO/0N4pqbK8iLWp63Se8lPy3cd5Nxik/8vHQCpp7SxSisX8qqI8khm/aFX0FiLxJLayuMMySkEPYNdGNmaPDcH4qQLklfSHHv5CYN7mKCU1cQNNMSbdbgK/OSyQlykueUkRjOnum1JQX5X6TqxV2I4ykpcsHgtNtubZk5euyYW8Z2fHVUKQVwZYn8cbrIxlDdak8wbVIFiDOiysQQUk3qD2GGtQ9Y83qLfJGvX6HJVuf7N3Rqttw1AYFgjNOpY2wWAdSchc1kBoF9iy3nSlj7CLXawM9gSFXZXRbrvZs0+W7DpL7TROm1Sn/B+0TZ0ScL8c6cixzuELegkxBvIYA3mMgTzGSCGqLbQCTe65UcmTBvL4UcmjYQZ57KjkKdI55HGjlmedgTxu1PKEGmaQx4wbeYL0O8jjRSPPugHk8aKRJ5SEPF4syBMEebzA5THGQB5jII8p74sPQooPxXvRCuSlzKgYT+V0XIxEK5CXNIcT6TkQ7UBe0ozG3t24K/AgL20OJysCD/LSZjReEXiQlziHRXfgQV7ijF50Bx7kpY16dYQ7pnmCvQpcwS4htmB/HlewM5Yt2JPOFlSD4ArqsLAFFZC4gtpjbNli1T8jVdVCBfIauNTbJGdDPw1EXoRVpdvQDYUIw2YNqxrTSirlLOR5GFZ3N26okLD8TyL9EO5+nVwTsk0Pz44maHKfRJKycu6EvFYSSlJWviEg7xYJJCm0sNLOZkLFHuoi12p5KIa8BbabpOR6oUt6FOJRsQ9pNpQBquRl7kznpYvQ3tfqN4O3C/LQuXI7dEdGDB3rjH9Uigt9YVX9qH6epEdZpwSV9uzgTL8dvIny7h3Z+18hr/+c1MgThoQptURxRMJD1DzvvQXD4WIXKaEaefeeU+fy71fIW6NPere8XJv6QDm1LT2fDVWuB9Lj9tx3l3XL698n/XQ6Lb68gbwOum7fi3KiG+tUk1xQnOgaeTMnjbhB6XeNvFW3DYoOTk5O8jz/9Ws0svb1689STotBBnmtHB2finaahGVBXn1cNXMi7b/bz8Iv8WkfefsfO+VFTo8/yVaOpCyKYjyfzyfT6fPnz4u5Pzh+AXmbRF5gcdiMGJ3XvxpFKsyLxg6ysi/6no+9j70ir5uTiZTzb2cYNjea8yJNwmKdqh7Vz+/lXp73pryzXHiNMZ2xDzLnvRzPp6dIWDbMNiPNUiEkLCEUm+dJ+S+TDbSKx5TTITDvn22eFPMPWCpsvM6LLC/SvcUleR6rbTlqWq83hGr+AOu8P1ikb/ljIFLZUEaMojjE0sx52bjCcgePf21z/cjG3WO3Yf2pAuSl9I9uf0Pgvs1OUhriWoZi3HR7JykkL22vgzum1yC55CVEMG53X5eE5qowd2KvQj/SSF6ieGw06c2jJy/1kAt5j86Gu4QgLw2wP4832BnLGuxJ5w2qQbAGdVhYgwpIvEHtMdag6h9vUG+TNerVJ1S65Qt6CTFmd2d+/WMtdz+u0z2F1NjdmZ9friXv8jzdU0iN3Z35xdVa8q4u0j2F1Kjajuq82r2wRX6er+Hu/GfC77/UqORJs1150d7V5Y/V893l1c+UB4/UqOTRMNu+PHFxfv1sFdfnF0mP/KlRyVOk8yBvp4y+jFhN26lRy7PO7F7ewfwA8h5AnlDDrIe8lBrAQZ4QpN/tWN7BRE4OIO8h5Fk3WFteUk1PIS/sl92hvBh40oce5D2EPEG7lBcbfT8fFyPI43fmscX+wfg931PozZORVyKTeRGWQB5jII8pcdb5UPSYdSAvFUK+N+2V70FeMhxOpKfPSgvykqH/NQ7IS4fDSc/Ag7x06H1dH/IS4rDoF3iQlxCjF/0CD/LSQb066ne7O+SlwgYbTSAvCTbc4gV5j8+mmysh7z7w3dYMeYwLCkAe41IekMe4iA7kMS5fBXmMC8dBXnolG42s281C3v9wKJZKzobWl4i8RZiUKbYuNP3CsLkImwLhSirlLOQ1cCrNb9xQIWGpYdYUI9eEbDPCsB0NGchLIElZOXdCXisJJSkr3xCQd4ukkhRFQdWw9JGTta5qUWooDsWQtxWa5MIOsqpBc65lQIUFWaxzJEvKh1GMHGa5ro7V8nI9Cy+h3JvyJykyhprXx+WxwHaSlEV5StQY7VQpIDginVd/Flyp8J2iWRLkH4XrXTQr221HeU1kQ57YzpzULi8aIrqRl2uzLC/WYSEKZuPam4RdklfPqZAX2EKT+1Z52cAGO1GeMNQmL4SfcUPp2XO/tVmW19y8lMz/nbe8W7fvWScDN3NeDKkQblFe+FH9WaU4eBNq4H9feBeoNnn1bYNp/N95yzs6PhWBzsiLx8KRRXlN5MmSUs/szHsKcRn/zkfefrYkL3J6/EnelyPIC5F3lzwjA6pr2IyfyGUzReUAm+3nZMon9nzsZZ2RlwS85a0z5+XahO/UnbCQs+Jtpsg/MrZ0FubJmMa0zXmpwF7endlm5rIqJ+lcKsR1YClPaauJqvB0FBYNy9lmOjwBeV3rPBmgUlYQZFQ8sJDXmEpxNqQgL0AqSM2GJor/b52XFE9D3oNcAVFUC5f6o1YhYJXel1LdvH5iPBV5LZGR6MdMkJfKpwp9gbyEPs/rC+Ql9El6XyDvH3v3ksIgDEVhOEQKvsCppXQBpVvpJnToxBAyde9tJXGugrknOf8OLh9KBnnI2cOyN+IJ2j22N+LJ2be5O+KJ2TEdvYTxwq8vrUVKPnh+0ZHSIiUnPKnn84gHfDKWeMBn0okHfBsE8YDvYSEe8A1IxAO+e4x4wLf+EQ/4vk3inVq8PDEXKcRLZPIERsh38gRGyHfyBEbId/IERjj3ZmxZ+/N5gGWPVzTEw8vj/Q6TEA8uj3erypp4aAW8tmuIh1bA+1/dQTywNjxVlW/i4bS91rzitd2deDhtrzWveOpWEA+o8FqzP9ZcEQ+o6K81Ew/4tWbiAb/WTLwzvfA/vHzxHgX8h4ePNxrXH+rTH8qZUUkJHW+206CvbJjsrIQEjjcv+voWKXrYeKPVMbJC/pzYeGbSMZqMEhE2nht0jAanRISN923nDlYjhIEwjpeZl1hYxEMLS3vpgnMODHmAlFxDnkWE0ueug+y9sWB28PsdBL3+GSVCcqE+Li9PAfEQ748QD/EQD/EQrwniIR7iIR7iNekdr8S6XoPSJqhkNlkQr0GnydPwuKxKFkze8T6vO+NJJUrfiUzIgtdmB+P4fm2Pp2xyZKNFKc0V8Q53H94Gy9c4eRKFKE1KFILd5hJ5EyviHebGbPn2xNOfuZIWohrD46nTyftgv8av1niZeUp1TrIku/Eez6kbMw+vrZOXFlnLUdCgRFoC4vVwHyxd8zevxGqlJE+JVojXxThautZ4VstKpSkL4rV4gnWeLfDSIsolcEG8ntrjaSnMmmMlkqxbPMnM6nWd59vJf0z7hniOIZ5jiOcY4jmGeI4hnmOI5xjiOXbyXUK+nXx/nm8n3xnr3Ln3pHt36tMg3LNzWPbxfw4LAAAAAMD//AKq97OHhuzlIAAAAABJRU5ErkJggg==) ## 目录结构 ```shell ./easy_ngx_waf/ # 项目根目录 | .gitignore | access.lua # access_by_lua_file 对应的文件 | config.lua # easy_ngx_waf 配置文件 | init.lua # init_by_lua_file 对应的文件 | log.lua # log_by_lua_file 对应的文件 | README.md | report.lua # 当前waf概要报告;详见文件内容有说明; | +---data/ # 数据目录 | Country.mmdb # geoip数据文件 | +---lib/ # 工具库目录 | | ccutil.lua # CC检测 工具调用类 | | cc_redis.lua # CC检测 redis存储的具体实现 | | cc_shared_dict.lua # CC检测 shared_dict存储的具体实现 | | cls_redis.lua # redis封装 | | post.lua # post请求相关解析工具 | | string_util.lua # string工具类(修改自项目https://github.com/stein197/lua-string) | | util.lua # 工具类 | | | +---rule_core/ # 规则解析库 | | act.lua | | host.lua | | operator.lua | | rule.lua | | value.lua | | var.lua | | | \---packages/ # 第三方lua模块目录(文件说明详见该目录下README) | \---rules/ # 主规则目录(文件说明详见该目录下README;此目录下所有文件可通过easy_ngx_waf_rule项目覆盖更新) | | .gitignore | | demo.rule # 规则演示文件 | | README.md | | | +---simple/ # 简单规则文件目录 | | args # query参数过滤规则 | | cookie # cookie过滤规则 | | ip_black # IP黑名单 | | ip_white # IP白名单 | | post # post参数过滤规则 | | url # url过滤规则 | | url_white # url白名单 | | user_agent # user-agent过滤规则 | | user_agent_white # user-agent白名单 | | | \---spider/ # 蜘蛛数据目录(文件格式说明详见该目录下README) | | README.md | | ...... | +---rules_custom/ # 用户自定义规则目录(文件说明详见该目录下README) | | .gitignore | | README.md | | custom_demo.rule # 用户自定义规则演示文件 | | | +---simple/ # 用户自定义:简单规则文件目录 | | ...... # 文件列表同主规则目录下的简单规则文件列表相同 | | | \---spider/ # 用户自定义:蜘蛛数据目录 | myself.data # 用户自定义蜘蛛数据演示文件 | \---tpl/ # 模板目录 report.html # WAF概要报告模板文件 ``` ## 安装使用 ### 1. 安装 openresty/nginx > 安装好 `openresty` 或 `nginx` + `luajit` + `lua-nginx-module` + `lua-resty-core` (安装教程请自行度娘 或 参考 [lua-nginx-module 安装说明](https://github.com/openresty/lua-nginx-module#installation)) > > 当前文档假设已安装好 `openresty` > > - 安装目录为 `/usr/local/openresty` > - 配置文件目录为 `/usr/local/openresty/nginx/conf/` > - `nginx` 主配置文件为 `/usr/local/openresty/nginx/conf/nginx.conf` ### 2. 安装 libmaxminddb > 本库使用 `libmaxminddb` (https://github.com/maxmind/libmaxminddb) 作为IP地区查询工具 > > 请下载最新 `libmaxminddb` 库并安装 (写此文档时版本为 1.7.1) - linux安装 ```shell # linux 安装-------- $ wget https://github.com/maxmind/libmaxminddb/releases/download/1.7.1/libmaxminddb-1.7.1.tar.gz $ tar -zxvf libmaxminddb-1.7.1 $ cd libmaxminddb-1.7.1 $ ./configure $ make $ make check $ sudo make install $ sudo ldconfig # 默认安装路径 /usr/local/lib/libmaxminddb.so # 此路径需要在 ./easy_ngx_waf/config.lua 文件中使用 ``` - windows安装 ```shell # windows 下可自行编译动态库; # 当前 easy_ngx_waf 提供有编译好的 dll 方便童鞋们在开发阶段使用,路径为: # ./easy_ngx_waf/lib/packages/libmaxminddb_win/libmaxminddb.dll ``` > 补充: 定期更新 IP地址库 > > IP地址库保存路径 `./easy_ngx_waf/data/Country.mmdb` > > IP地址库项目地址 https://github.com/Loyalsoldier/geoip > > IP地址库下载地址 https://raw.githubusercontent.com/Loyalsoldier/geoip/release/Country.mmdb > > IP地址库备用下载地址 https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/Country.mmdb > > 下载 `Country.mmdb` 即可 > > ```shell > # 可自定义定时任务自动下载 > # 每周六00:00下载文件保存到 /usr/local/openresty/nginx/conf/easy_ngx_waf/data/Country.mmdb > 0 0 * * 6 wget -O /usr/local/openresty/nginx/conf/easy_ngx_waf/data/Country.mmdb https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/Country.mmdb > ``` ### 3. 安装lfs > 本库使用了 `luafilesystem` (https://github.com/lunarmodules/luafilesystem) > > 用以操作文件系统 (如扫描目录下的文件等,本库在加载 `.rule` 文件时用到) > > `lfs` 使用API请自行查找 > > 请下载安装最新版本 (实际该库应该较稳定了,很久没更了) - linux下安装使用 ```shell # linux 安装-------- # 下载源码包并命名为 luafilesystem.zip $ wget -O luafilesystem.zip https://github.com/lunarmodules/luafilesystem/archive/refs/heads/master.zip # 解压 (没有unzip命令的请先安装) $ unzip luafilesystem.zip # luafilesystem.zip包中实际是一个目录,解压后会在当前目录下多出 luafilesystem-master 目录 $ cd luafilesystem-master # 编辑 config 文件中的几个配置 $ vim config # ---------- config 文件内容 S ---------- # 原来这两行注释掉(或者直接改一个,另一行注释) # LUA_INC += -I$(PREFIX)/include # LUA_INC += -I/usr/include/lua$(LUA_VERSION) -I/usr/include/lua/$(LUA_VERSION) # 设置为实际已经安装的 openresty 下 luajit/include/luajit-2.1 (包含 lua.h 的目录) LUA_INC += -I/usr/local/openresty/luajit/include/luajit-2.1 # 保存退出 # ---------- config 文件内容 E ---------- # 编译 $ make # 等待编译完成(不报错即可),此时已经在 ./src/ 目录下生成 lfs.so 文件 # 笔者编译结束,最后一行提示如下: # gcc -O2 -Wall -fPIC -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -pedantic -I/usr/local/openresty/luajit/include/luajit-2.1 -c -o src/lfs.o src/lfs.c MACOSX_DEPLOYMENT_TARGET=10.5; export MACOSX_DEPLOYMENT_TARGET; gcc -shared -o src/lfs.so src/lfs.o # 将编译好的 .so 文件复制到相关目录中 # 方法1: 复制 ./src/lfs.so 到 openresty安装路径下的 lualib/ 目录中 # (此路径已经包含在lua_package_cpath中,不用做其他设置) $ cp ./src/lfs.so /usr/local/openresty/lualib/ # 方法2 (推荐): 复制 ./src/lfs.so 到 其他目录(假设 /web_server/tools/libs/) $ cp ./src/lfs.so /web_server/tools/libs/ # nginx.conf 文件添加: # lua_package_cpath "/web_server/tools/libs/?.so;;"; # 测试----- # 任意 lua 代码块中 require('lfs') # 重启 nginx 运行不报错即可 ``` - windows下安装使用 ```shell # windows 下可自行编译动态库; # 当前 easy_ngx_waf 提供有编译好的 dll 方便童鞋们在开发阶段使用,路径为: # ./easy_ngx_waf/lib/packages/clib_win/lfs.dll # 使用方法1: 使用时可在lua代码中添加 # package.cpath = package.cpath .. ';{easy_ngx_waf目录绝对路径}/lib/packages/clib_win/?.dll;' # 使用方法2 (推荐): 在 nginx.conf 中添加 lua_package_cpath 配置 # lua_package_cpath "{easy_ngx_waf目录绝对路径}/lib/packages/clib_win/?.dll;;"; # 测试----- # 任意 lua 代码块中 require('lfs') # 重启 nginx 运行不报错即可 ``` ### 4. 配置 1. 上传 `easy_ngx_waf` 项目到服务器 本文档假设 `easy_ngx_waf` 根目录为 `/web_server/tools/easy_ngx_waf/` 2. 设置 `./easy_ngx_waf/config.lua` 相关配置(具体配置参考 [完整配置文件](#完整配置文件) ) 3. 在 `nginx` 主配置文件的 `http 段` 添加如下几行 ```nginx # nginx.conf 文件 http 段 # ============= easy_ngx_waf配置 START ============= # easy_waf_cc_dict 此共享内存主要保存cc相关特征变量,内存大小根据访问量调整设置(此处为20MB大小) # 如果 ./easy_ngx_waf/config.lua 配置文件中使用redis作为cc_dict_type(配置为 config.cc_dict_type = 'redis' ),则 easy_waf_cc_dict 这一行可注释 lua_shared_dict easy_waf_cc_dict 20m; # 用于通用缓存,内存大小根据实际情况调整 lua_shared_dict easy_waf_cache 10m; # 设置lua库加载路径(注意最后的 ;; 不可写错了) lua_package_path "{easy_ngx_waf目录绝对路径}/?.lua;;"; # 如果是windows环境,请加下一行配置 # lua_package_cpath "{easy_ngx_waf目录绝对路径}\\lib\\packages\\clib_win\\?.dll;;"; # 如果是linux环境, lfs.so 保存在了非 openresty/lualib/ 目录,设置一下 cpath # lua_package_cpath "{动态库文件目录绝对路径}/?.so;;"; init_by_lua_file {easy_ngx_waf目录绝对路径}/init.lua; # 推荐写在 http 段作为全局使用, 写在 server 段就只针对当前 server 生效 access_by_lua_file {easy_ngx_waf目录绝对路径}/access.lua; log_by_lua_file {easy_ngx_waf目录绝对路径}/log.lua; # ============= easy_ngx_waf配置 END ============= ``` 4. (此步骤非必须) 在 `{easy_ngx_waf目录绝对路径}/rules/custom/` 自定义规则目录下可添加自定义规则 - 不建议对 `{easy_ngx_waf目录绝对路径}/rules/` 规则主目录下添加/修改规则,原因请见规则主目录下 README - 规则文件中,以 ## 开头的行是注释行(不支持行内注释),不作为规则 5. 重载/重启 `nginx` ** 任何 `lua` 文件的修改,都需要重载/重启 `nginx` ```shell # 如果使用 systemd $ systemctl reload nginx # 重载 nginx (生产环境下建议重载) $ systemctl restart nginx # 重启 nginx # 如果其他linux # 检测配置文件正确性 $ /usr/local/openresty/nginx/sbin/nginx -t -c /usr/local/openresty/nginx/conf/nginx.conf # 重载 nginx $ /usr/local/openresty/nginx/sbin/nginx -s reload -c /usr/local/openresty/nginx/conf/nginx.conf # 停止 nginx $ /usr/local/openresty/nginx/sbin/nginx -s stop # 启动 nginx $ /usr/local/openresty/nginx/sbin/nginx -s start ``` ## 完整配置文件 > 配置文件中的开关项 > > - 打开状态可用值有: `"on"` / `"yes"` / `"y"` / `"true"` / `"1"` / `true` / `1` (字符串不区分大小写) > > - 关闭状态可用值有: `"off"` / `"no"` / `"n"` / `"false"` / `"0"` / `false` / `0` (字符串不区分大小写) > > - 通过 `lib/util.check_switch_is_on(value)` 检测开关状态 > > 打开状态返回 `true` > > 关闭状态返回 `false` > > 非以上值返回 `nil` ``` lua -- ./easy_ngx_waf/config.lua 文件 local config = {} -- 总开关 config.waf_enable = "on" -- 是否记录waf拦截日志(拦截日志总开关) config.waf_log = "on" -- waf拦截日志路径(绝对路径,确保nginx用户有写权限;文件未生成前,所属目录需要有写权限) -- 文件名可自定义,只要nginx用户有写权限即可。 -- 配置示例: "{nginx_log目录}/easy_ngx_waf_nginx.log" -- 此处文件名以 _nginx.log 结尾,是因为我的环境用 logrotate 定时处理日志,已经有 *nginx.log 的规则,省点事。 config.waf_log_file = "/web_server/web/logs/easy_ngx_waf.log" -- waf基础目录(绝对路径,库中规则目录及某些文件路径依赖此路径) -- 示例: "/web_server/tools/easy_ngx_waf" -- "D:\\server\\easy_ngx_waf" config.waf_base_path = "/web_server/tools/easy_ngx_waf" -- WAF排除域名列表(host_exclude) -- 可在此设置不参与WAF检测的域名(可设置全局排除,也可针对各检测阶段排除) -- 排除域名设置注意事项 -- "abc.com" => 具体域名,只针对 "abc.com" 域名排除,"www.abc.com" 还是参与waf检测的 -- "*.abc.com" => 通配符域名,针对所有 "abc.com" 域名("abc.com" "www.abc.com" "x.y.abc.com")都排除 config.host_x = { -- "all" 全局排除域名列表 -- 包含在此列表的域名直接跳过所有WAF检测 all = { "*.easy_ngx_waf.xxx", "localhost", }, -- "ip_white" IP白名单检测阶段排除域名列表 ip_white = { "www.example.xxx", "*.example2.xxx", }, -- "ip_black" IP黑名单检测阶段排除域名列表 ip_black = { }, -- "ip_foreign" 境外IP检测阶段排除域名列表 ip_foreign = { }, -- "ua" user-agent检测阶段排除域名列表(同时也不参与ua白名单检测) ua = { }, -- "cookie" cookie检测阶段排除域名列表 cookie = { }, -- "cc" cc检测阶段排除域名列表 cc = { }, -- "args" args检测阶段(也就是get参数检测)排除域名列表 args = { }, -- "post" post检测阶段排除域名列表 post = { }, -- "header" header检测阶段排除域名列表 header = { }, } -- END config.host_x -- libmaxminddb编译安装后的库文件路径(绝对路径) -- IP归属地区检测 -- linux下需要先安装libmaxminddb(项目地址 https://github.com/maxmind/libmaxminddb) -- 默认安装路径 "/usr/local/lib/libmaxminddb.so" -- windows下已预置了动态库 config.waf_base_path.."\\lib\\packages\\libmaxminddb_win\\libmaxminddb.dll" config.libmaxminddb_path = "/usr/local/lib/libmaxminddb.so" -- IP白名单: 所有规则中, "var":"ip" "act":"allow" 的都算作IP白名单(不管是 ip_match, ip_region 运算) -- "op":"ip_match" 时, 规则 value 可以是符合CIDR规则的IP -- "op":"ip_region" 时, 规则 value 可以是所在地区的代码(如: "CN","MO"...) -- 是否开启IP白名单校验(白名单命中,后续校验都不做) config.ip_white_check = "on" -- IP白名单命中时是否记录日志(推荐关闭,可减少日志);此设置只针对简单规则有效,常规规则中有单独的日志开关; config.ip_white_log = "off" -- IP黑名单: 所有规则中, "var":"ip" "act":"deny" 的都算作IP黑名单(不管是 ip_match, ip_region 运算) -- "op":"ip_match" 时, 规则 value 可以是符合CIDR规则的IP -- "op":"ip_region" 时, 规则 value 可以是所在地区的代码(如: "US","TW"...) -- 是否开启IP黑名单校验 config.ip_black_check = "on" -- IP黑名单命中时是否记录日志(推荐关闭,可减少日志);此设置只针对简单规则有效,常规规则中有单独的日志开关; config.ip_black_log = "on" -- IP黑名单校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容) config.ip_black_deny_return = ngx.HTTP_NOT_FOUND -- 是否开启user-agent白名单校验(开启可放行UA白名单) config.user_agent_white_check = "off" -- user-agent白名单命中时是否记录日志(关闭可减少日志);此设置只针对简单规则有效,常规规则中有单独的日志开关; config.user_agent_white_log = "off" -- 是否开启user-agent校验 config.user_agent_check = "on" -- user-agent校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容) config.user_agent_deny_return = "user_agent_deny" -- 是否开启url白名单校验 config.url_white_check = "on" -- url白名单命中时是否记录日志(关闭可减少日志);此设置只针对简单规则有效,常规规则中有单独的日志开关; config.url_white_log = "off" -- 是否开启url校验 config.url_check = "on" -- url校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容) config.url_deny_return = "url_deny" -- 是否开启SEO蜘蛛校验 config.seo_spider_check = "on" -- SEO蜘蛛校验命中时是否记录日志(关闭可减少日志) config.seo_spider_log = "off" -- 是否开启 禁止境外IP访问 config.ip_foreign_check = "on" -- 禁止境外IP命中时是否记录日志(推荐关闭,可减少日志) config.ip_foreign_log = "on" -- 非境外IP地区列表(在这个列表中的地区为非境外IP),注意大小写 config.domestic_iso_code = { "CN", -- 中国CODE "HK", -- 香港CODE "MO", -- 澳门CODE "TW", -- 台湾省CODE "PRIVATE", -- 内网CODE -- 内网IP段 -- 10.0.0.0 - 10.255.255.255 -- 172.16.0.0 - 172.31.255.255 -- 192.168.0.0 - 192.168.255.255 } -- 禁止境外IP访问时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容) config.ip_foreign_deny_return = "ip_foreign_deny" -- 是否开启cookie校验 config.cookie_check = "on" -- cookie校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容) config.cookie_deny_return = "cookie_deny" -- 是否开启args参数校验 config.args_check = "on" -- args参数校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容) config.args_deny_return = "args_deny" -- 是否开启post参数校验 config.post_check = "on" -- post参数校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容) config.post_deny_return = "post_deny" -- 是否开启header校验(此检测阶段已将user-agent cookie剥离) config.header_check = "on" -- header校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容) config.header_deny_return = "header_deny" -- 是否开启CC校验 config.cc_check = "on" -- CC频率 单位:请求次数N/M秒 默认100/60:60秒请求100次即触发CC攻击 config.cc_rate = "100/60" -- CC校验不通过时,返回内容 (可填写 HTTP错误码 / "default" / 自定义内容) config.cc_deny_return = ngx.HTTP_NOT_FOUND -- CC检测命中,封锁IP时长(单位:秒,如果为0则永久封锁) config.cc_ip_lock_time = 300 -- CC防护使用的数据存储类型( "redis" / "shared_dict" ) -- 如果使用redis,需要正确配置下方redis相关配置项 -- 如果使用shared_dict,需要在 nginx.conf 的 http 段配置 lua_shared_dict easy_waf_cc_dict ?m; config.cc_dict_type = "shared_dict" -- redis主机 config.redis_host = "127.0.0.1" -- redis端口 config.redis_port = 6379 -- redis数据库编号(默认0号库,通常可选0-15) config.redis_db_index = 0 -- redis密码(没有留空字符串) config.redis_password = "" -- 防火墙拦截后,默认返回响应状态码 及 html内容(如果各个拦截响应配置项设置为"default"时) config.default_return_code = ngx.HTTP_NOT_FOUND config.default_return_html = [[MMP...]] return config ``` ## 注意事项 - 如果服务器使用了 `文件验证` 的方式自动续签 `SSL` 证书,且 `WAF` 开启了 `禁止境外IP` 功能,一些CA机构执行验证的IP会被视为 `境外IP` 被拦截,导致续签失败。 可在 `error.log` 中看到 `GET /.well-known/acme-challenge/` 此类的信息。 解决方法1:(推荐)添加 `URL白名单` ```shell # 在 rules/custom/ 目录下某个 .rule 文件中添加一条常规规则 { "name": "ACME-validate-url", "var": "request_uri", "op": "re", "value": "^(/\.well-known/acme-challenge/\.*)|(/\.well-known/\.*)", "act": "allow", "log": "off", "msg": "ACME续签文件验证" } # 或者在 rules/custom/simple/url_white 文件中添加: ^(/\.well-known/acme-challenge/\.*)|(/\.well-known/\.*) ``` 解决方法2: 添加 `IP白名单` ```shell # 比如常见的有 91.199.212.132 91.199.212.133 ``` > 执行验证的IP也不是不变的,比如 Let's Encrypt 文档中就有说明 [=点击查看文档=](https://letsencrypt.org/zh-cn/docs/integration-guide/#%E9%98%B2%E7%81%AB%E5%A2%99%E9%85%8D%E7%BD%AE) > > 引用一段原文如下: > > ​ 如果您 “http-01” ACME 验证方法,您需要允许 80 端口上的入站通信。 我们不会公布执行验证的 IP 范围,它们可能在不另行通知的情况下改变。 ## 后续功能 - 目前针对WAF的设置都是基于 `config` 文件及各个规则文件的,暂时还没有前端管理,后期时间允许或许会出; (目前 `config` 文件中配置说明及各个 `README` 中的说明其实也相当清楚了) - 目前所有配置修改、规则添加 / 修改等操作都需要重载 / 重启 `nginx` ,后期增加动态刷新功能; ## License [MulanPSL-2.0](http://license.coscl.org.cn/MulanPSL2)