updated code
This commit is contained in:
parent
4ae7a41554
commit
d4b9b2eb50
1 changed files with 78 additions and 9 deletions
85
src/index.ts
85
src/index.ts
|
|
@ -21,16 +21,64 @@ const NODE_ENV = process.env.NODE_ENV || 'production';
|
|||
|
||||
const objs: ApiResponse[] = []
|
||||
|
||||
// Create Fastify instance with trust proxy enabled
|
||||
// Create Fastify instance with comprehensive trust proxy
|
||||
const fastify = Fastify({
|
||||
logger: NODE_ENV === 'development',
|
||||
trustProxy: process.env.TRUST_PROXY === 'true' || true
|
||||
trustProxy: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '127.0.0.1', '::1'] // Trust k8s networks
|
||||
});
|
||||
|
||||
// Enhanced IP detection function
|
||||
function getClientIP(request: FastifyRequest): string {
|
||||
const headers = request.headers;
|
||||
|
||||
// Try multiple headers in order of preference
|
||||
const ipSources = [
|
||||
headers['cf-connecting-ip']?.toString(), // Cloudflare
|
||||
headers['true-client-ip']?.toString(), // Akamai/other CDNs
|
||||
headers['x-forwarded-for']?.toString().split(',')[0]?.trim(), // Most common
|
||||
headers['x-client-ip']?.toString(), // Apache
|
||||
headers['x-cluster-client-ip']?.toString(), // Cluster
|
||||
headers['forwarded']?.toString().match(/for=([^;,\s]+)/)?.[1], // RFC 7239
|
||||
request.ip, // Fastify default
|
||||
request.socket.remoteAddress // Socket
|
||||
];
|
||||
|
||||
// Filter out internal/private IPs and return first public IP
|
||||
for (const ip of ipSources) {
|
||||
if (ip && ip !== 'unknown' && !isPrivateIP(ip)) {
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
|
||||
// If no public IP found, return the first non-unknown IP
|
||||
return ipSources.find(ip => ip && ip !== 'unknown') || 'unknown';
|
||||
}
|
||||
|
||||
// Check if IP is private/internal
|
||||
function isPrivateIP(ip: string): boolean {
|
||||
if (!ip || ip === 'unknown') return true;
|
||||
|
||||
// Remove any port number
|
||||
const cleanIP = ip.split(':')[0];
|
||||
|
||||
// Private IP ranges
|
||||
const privateRanges = [
|
||||
/^10\./, // 10.0.0.0/8
|
||||
/^172\.(1[6-9]|2[0-9]|3[0-1])\./, // 172.16.0.0/12
|
||||
/^192\.168\./, // 192.168.0.0/16
|
||||
/^127\./, // 127.0.0.0/8 (localhost)
|
||||
/^169\.254\./, // 169.254.0.0/16 (link-local)
|
||||
/^::1$/, // IPv6 localhost
|
||||
/^fe80:/ // IPv6 link-local
|
||||
];
|
||||
|
||||
return privateRanges.some(range => range.test(cleanIP));
|
||||
}
|
||||
|
||||
// API Key authentication middleware
|
||||
fastify.addHook('preHandler', async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
// Skip auth for health check endpoint
|
||||
if (request.url === '/health') {
|
||||
// Skip auth for health check and debug endpoints
|
||||
if (request.url === '/health' || request.url === '/ip-debug') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -55,9 +103,8 @@ fastify.addHook('preHandler', async (request: FastifyRequest, reply: FastifyRepl
|
|||
|
||||
// Helper function to get full IP chain
|
||||
function getFullIPChain(request: FastifyRequest): { clientIP: string, ipChain: string[] } {
|
||||
// Fastify automatically parses X-Forwarded-For when trustProxy is enabled
|
||||
const clientIP = request.ip || 'unknown';
|
||||
const ipChain = request.ips || []; // Full chain of IPs
|
||||
const clientIP = getClientIP(request);
|
||||
const ipChain = request.ips || [];
|
||||
|
||||
return {
|
||||
clientIP,
|
||||
|
|
@ -84,6 +131,27 @@ const start = async () => {
|
|||
};
|
||||
});
|
||||
|
||||
// IP Debug endpoint (bypasses authentication) - for troubleshooting
|
||||
fastify.get('/ip-debug', async (request) => {
|
||||
return {
|
||||
detectedClientIP: getClientIP(request),
|
||||
fastifyIP: request.ip,
|
||||
fastifyIPs: request.ips,
|
||||
socketIP: request.socket.remoteAddress,
|
||||
allIPHeaders: {
|
||||
'x-forwarded-for': request.headers['x-forwarded-for'],
|
||||
'x-real-ip': request.headers['x-real-ip'],
|
||||
'cf-connecting-ip': request.headers['cf-connecting-ip'],
|
||||
'true-client-ip': request.headers['true-client-ip'],
|
||||
'x-client-ip': request.headers['x-client-ip'],
|
||||
'x-cluster-client-ip': request.headers['x-cluster-client-ip'],
|
||||
'forwarded': request.headers['forwarded']
|
||||
},
|
||||
isPrivateIP: isPrivateIP(request.headers['x-real-ip']?.toString() || ''),
|
||||
timestamp: Date.now()
|
||||
};
|
||||
});
|
||||
|
||||
// Random endpoint for testing
|
||||
fastify.get('/random', async () => {
|
||||
return objs[Math.round(objs.length * Math.random())] || { message: 'No data yet' };
|
||||
|
|
@ -103,7 +171,7 @@ const start = async () => {
|
|||
const ipInfo = getFullIPChain(request);
|
||||
const obj = {
|
||||
success: true,
|
||||
clientIP: ipInfo.clientIP, // Fastify's auto-detected client IP
|
||||
clientIP: ipInfo.clientIP, // Enhanced client IP detection
|
||||
ipChain: ipInfo.ipChain, // Full proxy chain
|
||||
foundIPs: result.ips, // IPs found by our custom parser
|
||||
totalFound: result.ips.length,
|
||||
|
|
@ -122,6 +190,7 @@ const start = async () => {
|
|||
console.log(`🚀 Proxy Detection API running on http://localhost:${PORT}`);
|
||||
console.log(`📍 Available endpoints:`);
|
||||
console.log(` GET /health - Health check (no auth required)`);
|
||||
console.log(` GET /ip-debug - IP debugging info (no auth required)`);
|
||||
console.log(` GET / - Extract all IP addresses from request headers`);
|
||||
console.log(` GET /random - Get random cached result`);
|
||||
console.log(`🔑 API Key required for protected endpoints`);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue