diff --git a/components/_component.js b/components/_component.js new file mode 100644 index 0000000..768794b --- /dev/null +++ b/components/_component.js @@ -0,0 +1,3 @@ +module.exports = class Component { + constructor () {} +}; diff --git a/components/http-reverse.js b/components/http-reverse.js new file mode 100644 index 0000000..b2fd0fe --- /dev/null +++ b/components/http-reverse.js @@ -0,0 +1,5 @@ +const Component = require("./_component"); + +module.exports = class HTTPReverse extends Component { + constructor () { super(); } +}; diff --git a/components/index.js b/components/index.js new file mode 100644 index 0000000..515bb0e --- /dev/null +++ b/components/index.js @@ -0,0 +1,3 @@ +module.exports = { + "revHTTP": require("./http-reverse"), +}; diff --git a/firewall/GLOBAL.txt b/firewall/GLOBAL.txt new file mode 100644 index 0000000..0ad0080 --- /dev/null +++ b/firewall/GLOBAL.txt @@ -0,0 +1 @@ +deny 172.202.246.146; diff --git a/routemap-parser.js b/routemap-parser.js new file mode 100644 index 0000000..abdc78d --- /dev/null +++ b/routemap-parser.js @@ -0,0 +1,71 @@ +const fs = require("fs"); +const path = require("path"); +const components = require("./components"); + +// General regexps +// const FIND_ADDRESS_INSTR_REGEX = /([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]{1,5}\s{0,}\{[\s\n\r0-9a-z;:\/\."',]{0,}\}/gmi; +const DOMAINER_REGEX = /domain\s{1,}[a-z0-9\.]{1,}\s{1,}\{[\s\n\r0-9a-z;:\/\."',]{0,}\}/gmi; +const ADDRESS_WITH_PORT_REGEX = /([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]{1,5}/gmi +const FIND_ADDRESS_INSTR_REGEX = /([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]{1,5}\s{0,}\{([\s\n\r0-9a-z;:\/\."',]|domain\s{1,}[a-z0-9\.]{1,}\s{1,}\{[\s\n\r0-9a-z;:\/\."',]{0,}\}){0,}\}/gmi; +const COMMENT_REGEX = /#.{0,}(\n|\r|$)/gmi; + +// Instruction regexps +function readInstructions (instructions, fullCode) { + const syntaxTree = { domains: {}, firewall: false }; + + for (let instruction of instructions) { + if (!instruction) + break; + const instructionParts = instruction.split(/\s{1,}/); + const mainOperator = instructionParts[0]; + switch (mainOperator) { + case "type": + if (instructionParts.length !== 2) + throw new SyntaxError("Invalid syntax of operator `type`: type "); + const SelectedComponent = components[instructionParts[1]]; + if (SelectedComponent === undefined) + throw new SyntaxError(`Unknown component: ${instructionParts[1]}. Valid components: ${Object.keys(components).join(", ")}`); + syntaxTree.Type = SelectedComponent; + break; + case "target": + if (instructionParts.length !== 2) + throw new SyntaxError("Invalid syntax of operator `target`: target "); + syntaxTree.target = instructionParts[1]; + break; + case "#instuction:domain": + break; + default: + throw new SyntaxError(`Unknown routemap's operator: ${mainOperator}`); + } + } + + return syntaxTree; +} + +function logger (...p) { + //return; + console.debug("[DEBUG.routemap]:", ...p); +} + +module.exports.parse = function () { + const syntaxTree = new Object(); + const routemapContent = fs.readFileSync(path.join(__dirname, "./routemap.txt"), { encoding: "utf-8" }) + .replace(COMMENT_REGEX, "\n"); + const findedAdrInstructions = routemapContent.match(FIND_ADDRESS_INSTR_REGEX); + logger("findedAdrInstructions:", findedAdrInstructions); + if (findedAdrInstructions === null) + throw new SyntaxError("routemap.txt is empty"); + for (let itemAdrInst of findedAdrInstructions) { + itemAdrInst = itemAdrInst.replace(/[\n\r]{1,}/g, ""); + const content = itemAdrInst + .replace(ADDRESS_WITH_PORT_REGEX, "") + .replace(DOMAINER_REGEX, "#instuction:domain") + .trim() + .slice(1, -1) + .split(/\s{0,};\s{0,}/g).map(x => x.trim()); + logger("itemAdrInst:", itemAdrInst, "with content:", content); + const localSyntaxTree = readInstructions(content, itemAdrInst); + syntaxTree[itemAdrInst.match(ADDRESS_WITH_PORT_REGEX)[0]] = localSyntaxTree; + } + logger("Full syntax tree:", syntaxTree); +} diff --git a/routemap.txt b/routemap.txt new file mode 100644 index 0000000..cc60ed0 --- /dev/null +++ b/routemap.txt @@ -0,0 +1,11 @@ +127.0.0.1:9889 { + type revHTTP; + target https://example.org; # RRR + domain localhost { + firewall whitelist GLOBAL; + type revHTTP; + target https://github.org; + }; +} + +127.0.0.1:7889 {} diff --git a/server.js b/server.js index f7fde93..acabd03 100644 --- a/server.js +++ b/server.js @@ -8,6 +8,8 @@ const path = require('path'); const fetch = require('node-fetch'); global.config = require("./config.json"); +const rtmap = require("./routemap-parser"); + const app = express(); const address = global.config.net.address ?? "127.0.0.1"; @@ -15,7 +17,7 @@ const reverseTo = global.config.target ?? "https://example.org"; function logger (...p) { return; - console.log("[LOGGER]:", ...p); + console.log("[DEBUG.main]:", ...p); } app.use('/*', async (req, res, next) => { // Myself body parser :) @@ -58,6 +60,8 @@ app.use("*", async (req, res) => { }); }); +rtmap.parse(); + app.listen(global.config.net.port, address, (err) => { if (err) { throw err;