Compare commits
9 Commits
ed11b2d15d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
3a31cd4540
|
|||
|
c876cbedc4
|
|||
|
3bd264f974
|
|||
|
21c3d2e194
|
|||
|
71312297be
|
|||
|
58b8cf3bdc
|
|||
|
38e5654341
|
|||
|
efbcc5a7fb
|
|||
|
20881c1ba4
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.env
|
||||
11
Dockerfile
11
Dockerfile
@@ -1,8 +1,15 @@
|
||||
FROM node:lts-alpine
|
||||
USER node
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV production
|
||||
ENV TZ Europe/Warsaw
|
||||
ENV NODE_ENV=production
|
||||
ENV TZ=Europe/Warsaw
|
||||
COPY --chown=node:node index.mjs ./
|
||||
EXPOSE 3000
|
||||
CMD ["node", "./index.mjs"]
|
||||
|
||||
HEALTHCHECK \
|
||||
--interval=10s \
|
||||
--timeout=5s \
|
||||
--start-period=3s \
|
||||
--retries=3 \
|
||||
CMD ["wget", "http://localhost:3000/health", "-O", "/dev/null", "-q"]
|
||||
|
||||
87
index.mjs
87
index.mjs
@@ -2,21 +2,31 @@ import { createServer } from 'node:http';
|
||||
import { setTimeout } from 'node:timers';
|
||||
|
||||
const msg = 'Relax, take it easy! For there is nothing that we can do.';
|
||||
const minDelay = 3000;
|
||||
const maxDelay = 5000;
|
||||
const delayDiff = maxDelay - minDelay;
|
||||
const randomDelay = () => Math.floor(Math.random() * delayDiff + minDelay);
|
||||
const minDelayMs = 3000;
|
||||
const maxDelayMs = 6000;
|
||||
const delayDiff = maxDelayMs - minDelayMs;
|
||||
const randomDelay = () => Math.floor(Math.random() * delayDiff + minDelayMs);
|
||||
const ipNextReportDateMap = new Map();
|
||||
|
||||
const server = createServer((req, res) => {
|
||||
const connOpenDate = new Date();
|
||||
const dateText = connOpenDate.toLocaleString('pl');
|
||||
const scannerIP = req.headers['x-forwarded-for'];
|
||||
const host = req.headers['x-forwarded-host'];
|
||||
const endpoint = `${req.method} ${req.url}`;
|
||||
|
||||
if (endpoint === 'GET /health') {
|
||||
res.statusCode = 200;
|
||||
return res.end('OK\n');
|
||||
}
|
||||
|
||||
const ip = req.headers['x-forwarded-for'];
|
||||
const userAgent = req.headers['user-agent'];
|
||||
const host = req.headers['x-forwarded-host'];
|
||||
|
||||
console.log(
|
||||
`${ip} (${userAgent}) targeted ${host} on ${endpoint}`
|
||||
);
|
||||
|
||||
let charIdx = 0;
|
||||
|
||||
console.log(`[${dateText}] ${scannerIP} targeted ${host} on ${endpoint}`);
|
||||
|
||||
|
||||
const hang = () => {
|
||||
if (res.closed) return;
|
||||
else if (charIdx === msg.length) res.end('\n');
|
||||
@@ -27,17 +37,64 @@ const server = createServer((req, res) => {
|
||||
|
||||
hang();
|
||||
|
||||
res.once('close', () => {
|
||||
res.once('close', async () => {
|
||||
const connCloseDate = new Date();
|
||||
const timeDiff = connCloseDate.getTime() - connOpenDate.getTime();
|
||||
const dateText = connCloseDate.toLocaleString('pl');
|
||||
const diffText = new Date(timeDiff).toISOString().substring(14, 19);
|
||||
const diffText = new Date(connCloseDate - connOpenDate)
|
||||
.toISOString()
|
||||
.substring(14, 19);
|
||||
|
||||
const nextIpReportDate = ipNextReportDateMap.get(ip) || connCloseDate;
|
||||
const hangResult =
|
||||
charIdx === msg.length ? 'received the message' : 'aborted connection';
|
||||
|
||||
console.log(`[${dateText}] ${scannerIP} ${hangResult} after ${diffText}`);
|
||||
console.log(`${ip} ${hangResult} after ${diffText}`);
|
||||
|
||||
if (connCloseDate < nextIpReportDate) return;
|
||||
|
||||
const queryParams = new URLSearchParams();
|
||||
|
||||
queryParams.append('ip', ip);
|
||||
queryParams.append('categories', '15,21');
|
||||
queryParams.append('timestamp', connOpenDate.toISOString());
|
||||
queryParams.append(
|
||||
'comment',
|
||||
`Vulnerability scanner detected!\nUser-Agent: ${userAgent}\nEndpoint: ${endpoint}`
|
||||
);
|
||||
|
||||
const abuseIpDbRes = await fetch(
|
||||
`https://api.abuseipdb.com/api/v2/report?${queryParams.toString()}`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Key': process.env.ABUSEIPDB_API_KEY,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (abuseIpDbRes.ok) {
|
||||
const reportDate = new Date();
|
||||
|
||||
console.log(`${ip} has been reported!`);
|
||||
ipNextReportDateMap.set(
|
||||
ip,
|
||||
new Date(
|
||||
reportDate.getFullYear(),
|
||||
reportDate.getMonth(),
|
||||
reportDate.getDate() + 1,
|
||||
reportDate.getHours(),
|
||||
reportDate.getMinutes(),
|
||||
reportDate.getSeconds()
|
||||
)
|
||||
);
|
||||
} else {
|
||||
console.error(
|
||||
`Failed to report ${ip}: ${abuseIpDbRes.status} ${abuseIpDbRes.statusText}`
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(3000);
|
||||
|
||||
process.on('SIGTERM', () => server.close());
|
||||
|
||||
Reference in New Issue
Block a user