Skip to content

Instantly share code, notes, and snippets.

@un4ckn0wl3z
Created September 17, 2025 07:42
Show Gist options
  • Save un4ckn0wl3z/d6c4e85244038b581bedddaabd1891fd to your computer and use it in GitHub Desktop.
Save un4ckn0wl3z/d6c4e85244038b581bedddaabd1891fd to your computer and use it in GitHub Desktop.
iplogger.js
// ip-logger.js
// Simple IP logger using Express
// Run: node ip-logger.js
// Requires: npm install express
const express = require('express');
const fs = require('fs');
const path = require('path');
const PORT = process.env.PORT || 3000;
const LOG_FILE = path.join(__dirname, 'visitors.csv');
const app = express();
// If you're behind a proxy (nginx, cloudflare, etc), enable this so req.ip uses X-Forwarded-For
app.set('trust proxy', true);
// Ensure log file has header
if (!fs.existsSync(LOG_FILE)) {
fs.writeFileSync(LOG_FILE, 'timestamp,ip,xff,user_agent,method,path,referer\n', { encoding: 'utf8' });
}
function getClientIp(req) {
// Express's req.ip returns the remote address or the left-most entry in X-Forwarded-For when trust proxy is true
return req.ip || req.connection.remoteAddress || '';
}
function appendLog(req) {
const ts = new Date().toISOString();
const ip = getClientIp(req).replace(/,/g, ''); // avoid commas breaking CSV
const xff = (req.headers['x-forwarded-for'] || '').replace(/,/g, ';');
const ua = (req.headers['user-agent'] || '').replace(/,/g, ' ');
const method = req.method;
const p = req.originalUrl || req.url;
const referer = (req.headers.referer || req.headers.referrer || '').replace(/,/g, '');
const line = `${ts},${ip},${xff},${ua},${method},${p},${referer}\n`;
fs.appendFile(LOG_FILE, line, (err) => {
if (err) console.error('Failed to append log:', err);
});
console.log(`${ts} - ${ip} - ${p} - ${ua}`);
}
// Simple middleware to log every request
app.use((req, res, next) => {
appendLog(req);
next();
});
// A friendly page
app.get('/', (req, res) => {
res.type('html').send(`
<h2>IP Logger Demo</h2>
<p>Your visit has been logged (if this server is public-facing).</p>
<p>To log visits from other pages/emails, embed this image as a beacon:</p>
<pre>&lt;img src="${req.protocol}://${req.get('host')}/beacon.png" alt="" /&gt;</pre>
`);
});
// 1x1 transparent PNG (base64) used as a beacon
const pixel = Buffer.from(
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=',
'base64'
);
app.get('/beacon.png', (req, res) => {
// We already logged via middleware, return a tiny image
res.set({
'Content-Type': 'image/png',
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0',
});
res.send(pixel);
});
// Optional: endpoint to download logs (protect in real use!)
app.get('/download-logs', (req, res) => {
// WARNING: do not expose this in production without auth
res.download(LOG_FILE, 'visitors.csv');
});
app.listen(PORT, () => {
console.log(`IP logger running on http://localhost:${PORT} (trust proxy: ${app.get('trust proxy')})`);
console.log(`Logs append to: ${LOG_FILE}`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment