Compare commits
5 Commits
c8fd93570c
...
5d32580580
Author | SHA1 | Date | |
---|---|---|---|
5d32580580 | |||
2e4aa8b5bd | |||
0f0626dc57 | |||
daa38cdeab | |||
df544d6580 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -130,3 +130,5 @@ dist
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# Routemap ignore
|
||||
routemap.txt
|
||||
|
@ -235,6 +235,17 @@ module.exports = class HTTPServer extends Component {
|
||||
});
|
||||
});
|
||||
|
||||
this.app.use((req, res, next) => {
|
||||
req.realip = req.ip;
|
||||
if (req.headers["cf-connecting-ip"])
|
||||
req.realip = req.headers["cf-connecting-ip"];
|
||||
|
||||
req.st403 = "<h1>403: Permission denied</h1><hr/><p>Permission denied.</p>";
|
||||
req.st404 = "<h1>404: Page not finded</h1><hr/><p>Please, recheck the URL address and try again.</p>";
|
||||
req.st500 = "<head><title>500: Internal Server Error</title></head><body><h1>Error:</h1><hr/><p>Error catched. Check logs</p></body>";
|
||||
next();
|
||||
});
|
||||
|
||||
this.app.use((req, res, next) => {
|
||||
const currentDomain = req.hostname;
|
||||
const isNotDomained = !this.syntax.domains[currentDomain];
|
||||
@ -246,13 +257,6 @@ module.exports = class HTTPServer extends Component {
|
||||
authPage(this, req, res, next)
|
||||
});
|
||||
|
||||
this.app.use((req, res, next) => {
|
||||
req.st403 = "<h1>403: Permission denied</h1><hr/><p>Permission denied.</p>";
|
||||
req.st404 = "<h1>404: Page not finded</h1><hr/><p>Please, recheck the URL address and try again.</p>";
|
||||
req.st500 = "<head><title>500: Internal Server Error</title></head><body><h1>Error:</h1><hr/><p>Error catched. Check logs</p></body>";
|
||||
next();
|
||||
});
|
||||
|
||||
this.app.use(cookieParser());
|
||||
|
||||
this.routelist.forEach(route => {
|
||||
|
109
modules/antiddos.js
Normal file
109
modules/antiddos.js
Normal file
@ -0,0 +1,109 @@
|
||||
const { NetHelperModule } = global.moduleApi;
|
||||
const express = require("express");
|
||||
const captcha = require("draw-captcha");
|
||||
|
||||
const HTTPServer = require("../components/_http");
|
||||
|
||||
const captchaPage = `<!DOCTYPE html><html><head><title>Captcha handling required</title><meta name="viewport" content="width=device-width, initial-scale=1"><meta charset="utf-8"></head><body>
|
||||
<center>
|
||||
<h1>Enter captcha</h1>
|
||||
<p><img src=:captchaImg:></img></p>
|
||||
<form action="/captcha-solve/:sid:/:from:" method="get">
|
||||
<p><input type="label" name="solve"> <input type="submit" id="solve-captcha"></p>
|
||||
</form>
|
||||
</center>
|
||||
</body></html>`;
|
||||
|
||||
function randint (min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||
}
|
||||
|
||||
async function getCaptchaPage (fromUrl) {
|
||||
const sidDict = "1234567890abcdef";
|
||||
let sid = "";
|
||||
for (let i = 0; i < 32; i++) {
|
||||
sid += sidDict[randint(0, 15)];
|
||||
}
|
||||
const captchaObject = new captcha.MasterCaptcha();
|
||||
getCaptchaPage.sids[sid] = await captchaObject.setupRandomCaptcha();
|
||||
return captchaPage
|
||||
.replace(new RegExp(":captchaImg:"), `/captcha/${sid}`)
|
||||
.replace(new RegExp(":from:"), Buffer.from(fromUrl).toString("hex"))
|
||||
.replace(new RegExp(":sid:"), sid);
|
||||
}
|
||||
getCaptchaPage.sids = new Object();
|
||||
|
||||
module.exports = class ExampleMdoule extends NetHelperModule {
|
||||
constructor () {
|
||||
super();
|
||||
this.router = express.Router();
|
||||
|
||||
this.lastUptime = new Date(new Date().getTime() + 3600000);
|
||||
this.queryCount = 0;
|
||||
this.ipWhiteListed = new Object();
|
||||
|
||||
this.querylimit = new this.statics.Operator("querylimit", (argv) => {
|
||||
if (argv.length !== 1) return false;
|
||||
return !Number.isNaN(+argv[0]);
|
||||
}, (argv, self, syntaxTree) => {
|
||||
if (!(syntaxTree.Type.prototype instanceof HTTPServer)) {
|
||||
throw new SyntaxError("Unsupported type of server");
|
||||
}
|
||||
let [ queriesLimit ] = argv;
|
||||
queriesLimit = +queriesLimit;
|
||||
|
||||
const router = this.router;
|
||||
|
||||
router.use(async (req, res, next) => {
|
||||
req.adsEx = req.adsEx ?? {};
|
||||
if (this.lastUptime <= new Date()) {
|
||||
this.lastUptime = new Date(this.lastUptime.getTime() + 3600000);
|
||||
this.queryCount = 1;
|
||||
this.ipWhiteListed = new Object();
|
||||
} else
|
||||
this.queryCount++;
|
||||
if (this.queryCount > queriesLimit) {
|
||||
//this.lastUptime = new Date(new Date().getTime() + 3600000);
|
||||
req.adsEx.needsCaptcha = this.ipWhiteListed[req.realip] !== true;
|
||||
}
|
||||
return next();
|
||||
});
|
||||
|
||||
router.get("/captcha/:sid", async (req, res, next) => {
|
||||
if (!req.adsEx.needsCaptcha)
|
||||
return next();
|
||||
const sid = req.params.sid;
|
||||
const content = getCaptchaPage.sids[sid];
|
||||
if (content === undefined) {
|
||||
res.set("Content-Type", "text/plain");
|
||||
return res.status(400).send("Invalid SID. Captcha was solved or not found");
|
||||
}
|
||||
res.set("Content-Type", "image/jpeg");
|
||||
res.send(content.buffer);
|
||||
});
|
||||
|
||||
router.get("/captcha-solve/:sid/:redirectTo", async (req, res) => {
|
||||
const sid = req.params.sid;
|
||||
const content = getCaptchaPage.sids[sid];
|
||||
const redirectTo = Buffer.from(req.params.redirectTo, "hex").toString("utf8");
|
||||
const isSolved = req.query.solve?.toLowerCase() === content?.code;
|
||||
this.ipWhiteListed[req.realip] = isSolved;
|
||||
req.adsEx.needsCaptcha = !isSolved;
|
||||
res.redirect(redirectTo);
|
||||
});
|
||||
|
||||
router.use(async (req, res, next) => {
|
||||
if (!req.adsEx.needsCaptcha)
|
||||
return next();
|
||||
res.send(await getCaptchaPage(req.originalUrl));
|
||||
});
|
||||
});
|
||||
|
||||
this.operators.push(this.querylimit);
|
||||
}
|
||||
|
||||
bind (type) {
|
||||
super.bind(type);
|
||||
this.serverType.routelist.push(this.router);
|
||||
}
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
const express = require("express");
|
||||
const { NetHelperModule } = global.moduleApi;
|
||||
|
||||
const HTTPReverse = require("../components/http-reverse");
|
||||
const HTTPServer = require("../components/_http");
|
||||
|
||||
module.exports = class CustomAuthPage extends NetHelperModule {
|
||||
constructor () {
|
||||
@ -11,7 +11,7 @@ module.exports = class CustomAuthPage extends NetHelperModule {
|
||||
this.cauth = new this.statics.Operator("cauth", (argv) => {
|
||||
return argv.length === 2;
|
||||
}, (argv, self, syntaxTree) => {
|
||||
if (![HTTPReverse].includes(syntaxTree.Type)) {
|
||||
if (!(syntaxTree.Type.prototype instanceof HTTPServer)) {
|
||||
throw new SyntaxError("Unsupported type of server");
|
||||
}
|
||||
const [ login, password ] = argv;
|
||||
|
91
package-lock.json
generated
91
package-lock.json
generated
@ -12,6 +12,7 @@
|
||||
"body": "^5.1.0",
|
||||
"body-parser": "^1.20.3",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"draw-captcha": "^0.0.2",
|
||||
"express": "^4.21.2",
|
||||
"mime": "^3.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
@ -51,6 +52,16 @@
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
||||
},
|
||||
"node_modules/array-parallel": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/array-parallel/-/array-parallel-0.1.3.tgz",
|
||||
"integrity": "sha512-TDPTwSWW5E4oiFiKmz6RGJ/a80Y91GuLgUYuLd49+XBS75tYo8PNgaT2K/OxuQYqkoI852MDGBorg9OcUSTQ8w=="
|
||||
},
|
||||
"node_modules/array-series": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/array-series/-/array-series-0.1.5.tgz",
|
||||
"integrity": "sha512-L0XlBwfx9QetHOsbLDrE/vh2t018w9462HM3iaFfxRiK83aJjAt/Ja3NMkOW7FICwWTlQBa3ZbL5FKhuQWkDrg=="
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@ -264,6 +275,15 @@
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz",
|
||||
"integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^4.0.1",
|
||||
"which": "^1.2.9"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
@ -289,6 +309,15 @@
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/draw-captcha": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/draw-captcha/-/draw-captcha-0.0.2.tgz",
|
||||
"integrity": "sha512-rXFp1AvzjzznpNSBnhcOo5/UaX98VQa3ZCr225OA1dNwtlE4zz1L5490xWIAFctTGEyZvJ9tcLIRFnM947FVnA==",
|
||||
"dependencies": {
|
||||
"express": "^4.21.2",
|
||||
"gm": "^1.25.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
@ -522,6 +551,33 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/gm": {
|
||||
"version": "1.25.0",
|
||||
"resolved": "https://registry.npmjs.org/gm/-/gm-1.25.0.tgz",
|
||||
"integrity": "sha512-4kKdWXTtgQ4biIo7hZA396HT062nDVVHPjQcurNZ3o/voYN+o5FUC5kOwuORbpExp3XbTJ3SU7iRipiIhQtovw==",
|
||||
"dependencies": {
|
||||
"array-parallel": "~0.1.3",
|
||||
"array-series": "~0.1.5",
|
||||
"cross-spawn": "^4.0.0",
|
||||
"debug": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/gm/node_modules/debug": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/gm/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
@ -651,6 +707,20 @@
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
|
||||
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
|
||||
"dependencies": {
|
||||
"pseudomap": "^1.0.2",
|
||||
"yallist": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
@ -884,6 +954,11 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/pseudomap": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||
"integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ=="
|
||||
},
|
||||
"node_modules/pstree.remy": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
|
||||
@ -1255,6 +1330,22 @@
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"which": "bin/which"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||
"integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
"body": "^5.1.0",
|
||||
"body-parser": "^1.20.3",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"draw-captcha": "^0.0.2",
|
||||
"express": "^4.21.2",
|
||||
"mime": "^3.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
|
@ -1,15 +1,14 @@
|
||||
127.0.0.1:9889 {
|
||||
import antiddos;
|
||||
type revHTTP;
|
||||
target https://example.org; # RRR
|
||||
|
||||
querylimit 0;
|
||||
domain localhost {
|
||||
firewall whitelist GLOBAL;
|
||||
type revHTTP;
|
||||
target https://github.com;
|
||||
};
|
||||
domain domain.loc {
|
||||
import example;
|
||||
testi;
|
||||
};
|
||||
}
|
||||
|
||||
127.0.0.1:7889 {
|
||||
|
38
routemap.txt.custom
Normal file
38
routemap.txt.custom
Normal file
@ -0,0 +1,38 @@
|
||||
127.0.0.1:9889 {
|
||||
type revHTTP;
|
||||
target https://example.org; # RRR
|
||||
domain localhost {
|
||||
firewall whitelist GLOBAL;
|
||||
type revHTTP;
|
||||
target https://github.com;
|
||||
};
|
||||
domain domain.loc {
|
||||
import example;
|
||||
testi;
|
||||
};
|
||||
}
|
||||
|
||||
127.0.0.1:7889 {
|
||||
import example, example_custom_auth;
|
||||
type revHTTP;
|
||||
target https://google.com;
|
||||
auth loopback admin qwerty;
|
||||
#cauth admin 123;
|
||||
cert public ./tests/pub.crt;
|
||||
cert private ./tests/priv.key;
|
||||
}
|
||||
|
||||
127.0.0.1:9999 {
|
||||
type redirectHTTP;
|
||||
target https://duckduckgo.com;
|
||||
domain localhost {
|
||||
type revHTTP;
|
||||
target https://google.com;
|
||||
}
|
||||
}
|
||||
|
||||
127.0.0.1:8081 {
|
||||
type simpleHTTP;
|
||||
target /;
|
||||
#showdir;
|
||||
}
|
Loading…
Reference in New Issue
Block a user