UNPKG

dtp-tripwire-agent

Version:

A service for protecting your node against malicious attacks and scans.

135 lines (118 loc) 3.31 kB
import env from "./config/env.js"; import path from "node:path"; import fs from "node:fs"; import readline from "readline"; import dayjs from "dayjs"; import customParseFormat from "dayjs/plugin/customParseFormat.js"; import { MethodMap, TripwireConfigFile, UriSet } from "service.js"; dayjs.extend(customParseFormat); const blockedUriStrings = [ ".env", ".git", ".php", ".zip", ".htaccess", "wordpress", "wp-admin", "wp-config", "wp-content", "wp-includes", "wp-mail", ]; const blockedUriPrefixes = [ "/.well-known", "/cgi-bin", "/file.php", "/modules", "/wp", "/wp1", "/wp2", "/xmlrpc.php", ]; const logFile = fs.createReadStream("./data/access.log"); const rl = readline.createInterface({ input: logFile, crlfDelay: Infinity, }); const methods: MethodMap = new Map<string, UriSet>(); let recordCount = 0; let prefixMatchCount = 0; let stringMatchCount = 0; rl.on("line", (line) => { ++recordCount; const re = /([^ ]*) ([^ ]*) ([^ ]*) \[([^\]]*)\] "([^"]*)" ([^ ]*) ([^ ]*)/; const matches = line.match(re); if (!matches || !matches[4] || !matches[5]) { return; } if (matches) { // const timestamp = matches[4]; // const date = dayjs(timestamp, "DD/MMM/YYYY:HH:mm:ss ZZ").toDate(); const requestTokens = matches[5].split(" "); if (!requestTokens[0] || !requestTokens[1] || !requestTokens[2]) { // console.error(matches[1], "malformed request", matches[5]); return; } const request = { method: requestTokens[0].trim(), uri: requestTokens[1].trim(), version: requestTokens[2].trim(), }; if ( request.method[0] === "\\" || request.uri[0] === "\\" || request.version[0] === "\\" ) { // console.error(matches[1], "malformed request", matches[5]); return; } for (const text of blockedUriStrings) { if (request.uri.includes(text)) { ++stringMatchCount; return; } } for (const prefix of blockedUriPrefixes) { if (request.uri.startsWith(prefix)) { ++prefixMatchCount; return; } } const method = methods.get(request.method); if (method) { method.add(request.uri); } else { methods.set(request.method, new Set<string>([request.uri])); } // const obj = { // remoteHost: matches[1], // remoteLogName: matches[2], // authUser: matches[3], // date, // request, // status: Number(matches[6]), // bytes: Number(matches[7]) || 0, // }; // console.log(JSON.stringify(obj)); } }); rl.on("close", async () => { console.log(`${recordCount} records read`); console.log(`${prefixMatchCount} prefix matches`); console.log(`${stringMatchCount} string matches`); const configPath = path.join(env.cache.path, "tripwire"); await fs.promises.mkdir(configPath, { recursive: true }); const configuration: TripwireConfigFile = { prefixes: blockedUriPrefixes, strings: blockedUriStrings, methods: [], }; for (const [method, uris] of methods) { configuration.methods.push({ name: method, uris: Array.from(uris) }); } const configFile = path.join(configPath, "config.json"); await fs.promises.writeFile( configFile, JSON.stringify(configuration, null, 2) ); });