Corporate Network Detection: Identifying Business vs Residential Traffic
Learn techniques for distinguishing corporate network traffic from residential users for better targeting and security.
Table of Contents
Table of Contents
Corporate Network Detection: Identifying Business vs Residential Traffic
Distinguishing corporate from residential traffic enables better targeting, pricing, and security decisions. Detection requires analyzing network characteristics, usage patterns, and infrastructure indicators.
Corporate Network Detection Overview
Geolocation Technology Overview
Corporate Network Detection requires careful consideration of multiple factors that impact implementation success and user experience.
Key Considerations
Technical Requirements
- Scalable architecture design
- Performance optimization strategies
- Error handling and recovery
- Security and compliance measures
Business Impact
- User experience enhancement
- Operational efficiency gains
- Cost optimization opportunities
- Risk mitigation strategies
Data Sources and Accuracy Factors
Successful implementation requires understanding the technical landscape and choosing appropriate strategies.
Implementation Approaches
Modern Solutions
- Cloud-native architectures
- Microservices integration
- Real-time processing capabilities
- Automated scaling mechanisms
Corporate Network Detection Architecture
Business Impact
- User experience enhancement
- Operational efficiency gains
- Cost optimization opportunities
- Risk mitigation strategies
Practical Implementation Examples
Network Analysis Engine for Corporate Detection
// Production-ready network analysis system for corporate vs residential classification
interface NetworkAnalysisResult {
ip: string
classification: 'corporate' | 'residential' | 'hosting' | 'mobile' | 'vpn' | 'unknown'
confidence: number // 0-100
indicators: {
autonomousSystem: {
asn: number
organization: string
type: 'isp' | 'corporate' | 'hosting' | 'education' | 'government'
}
ipRange: {
range: string
type: 'corporate' | 'residential' | 'hosting' | 'unknown'
source: string
}
reverseDNS: {
hostname: string
corporateIndicators: string[]
}
connectionPattern: {
requestVolume: number
timeDistribution: 'business_hours' | 'evening' | 'weekend' | 'continuous'
sessionDuration: number
endpointDiversity: number
}
}
corporateProbability: number
residentialProbability: number
metadata: {
analysisTimestamp: number
dataSources: string[]
processingTime: number
}
}
interface CorporateIndicators {
asnKeywords: string[]
hostnamePatterns: RegExp[]
ipRangeSources: string[]
behavioralPatterns: {
businessHoursActivity: number
weekendActivity: number
sessionConsistency: number
}
}
class CorporateNetworkAnalyzer {
private corporateIndicators: CorporateIndicators
private analysisCache: Map<string, NetworkAnalysisResult> = new Map()
private asnDatabase: Map<number, any> = new Map()
private ipRangeDatabase: Map<string, any> = new Map()
constructor() {
this.initializeCorporateIndicators()
this.loadNetworkDatabases()
}
async analyzeNetwork(ip: string): Promise<NetworkAnalysisResult> {
const startTime = Date.now()
// Check cache first
const cached = this.analysisCache.get(ip)
if (cached && Date.now() - cached.metadata.analysisTimestamp < 24 * 60 * 60 * 1000) {
return cached
}
try {
// Perform comprehensive network analysis
const [asnInfo, ipRangeInfo, reverseDNSInfo, connectionPattern] = await Promise.all([
this.analyzeAutonomousSystem(ip),
this.analyzeIPRange(ip),
this.analyzeReverseDNS(ip),
this.analyzeConnectionPattern(ip)
])
// Calculate probabilities
const corporateProbability = this.calculateCorporateProbability({
asnInfo,
ipRangeInfo,
reverseDNSInfo,
connectionPattern
})
const residentialProbability = 1 - corporateProbability
// Determine final classification
const classification = this.determineClassification(corporateProbability, {
asnInfo,
ipRangeInfo,
reverseDNSInfo,
connectionPattern
})
const result: NetworkAnalysisResult = {
ip,
classification,
confidence: Math.max(corporateProbability, residentialProbability) * 100,
indicators: {
autonomousSystem: asnInfo,
ipRange: ipRangeInfo,
reverseDNS: reverseDNSInfo,
connectionPattern
},
corporateProbability,
residentialProbability,
metadata: {
analysisTimestamp: Date.now(),
dataSources: ['ASN', 'IP Ranges', 'Reverse DNS', 'Connection Patterns'],
processingTime: Date.now() - startTime
}
}
// Cache result
this.analysisCache.set(ip, result)
return result
} catch (error) {
console.error(`Network analysis failed for IP ${ip}:`, error)
// Return default classification
return {
ip,
classification: 'unknown',
confidence: 0,
indicators: {
autonomousSystem: { asn: 0, organization: 'Unknown', type: 'isp' },
ipRange: { range: 'Unknown', type: 'unknown', source: 'Error' },
reverseDNS: { hostname: 'Unknown', corporateIndicators: [] },
connectionPattern: {
requestVolume: 0,
timeDistribution: 'unknown',
sessionDuration: 0,
endpointDiversity: 0
}
},
corporateProbability: 0.5,
residentialProbability: 0.5,
metadata: {
analysisTimestamp: Date.now(),
dataSources: [],
processingTime: Date.now() - startTime
}
}
}
}
private async analyzeAutonomousSystem(ip: string): Promise<NetworkAnalysisResult['indicators']['autonomousSystem']> {
// In production, query WHOIS or BGP data
// For demo, simulate ASN analysis
const mockASNData: Record<string, any> = {
'8.8.8.8': { asn: 15169, organization: 'Google LLC', type: 'hosting' },
'1.1.1.1': { asn: 13335, organization: 'Cloudflare Inc', type: 'hosting' },
'208.67.222.222': { asn: 36692, organization: 'OpenDNS LLC', type: 'corporate' }
}
const defaultASN = { asn: 0, organization: 'Unknown ISP', type: 'isp' as const }
// Check if IP matches any known corporate ASN patterns
for (const [ipPattern, asnData] of Object.entries(mockASNData)) {
if (ip.includes(ipPattern.split('.')[0])) {
return asnData
}
}
return defaultASN
}
private async analyzeIPRange(ip: string): Promise<NetworkAnalysisResult['indicators']['ipRange']> {
// In production, query IP range databases (ARIN, RIPE, etc.)
// For demo, simulate IP range analysis
const corporateRanges = [
{ range: '10.0.0.0/8', type: 'corporate', source: 'RFC1918' },
{ range: '172.16.0.0/12', type: 'corporate', source: 'RFC1918' },
{ range: '192.168.0.0/16', type: 'corporate', source: 'RFC1918' }
]
for (const rangeInfo of corporateRanges) {
if (this.isIPInRange(ip, rangeInfo.range)) {
return rangeInfo
}
}
return { range: 'Unknown', type: 'unknown', source: 'Not found' }
}
private isIPInRange(ip: string, cidr: string): boolean {
// Simplified CIDR matching for demo
// In production, use proper IP range calculation
if (cidr === '10.0.0.0/8' && ip.startsWith('10.')) return true
if (cidr === '172.16.0.0/12' && ip.startsWith('172.')) return true
if (cidr === '192.168.0.0/16' && ip.startsWith('192.168.')) return true
return false
}
private async analyzeReverseDNS(ip: string): Promise<NetworkAnalysisResult['indicators']['reverseDNS']> {
// In production, perform reverse DNS lookup
// For demo, simulate reverse DNS analysis
const mockReverseDNS: Record<string, any> = {
'8.8.8.8': { hostname: 'google-public-dns-a.google.com', corporateIndicators: ['google', 'dns'] },
'1.1.1.1': { hostname: 'one.one.one.one', corporateIndicators: ['cloudflare'] },
'208.67.222.222': { hostname: 'resolver1.opendns.com', corporateIndicators: ['opendns', 'resolver'] }
}
const defaultResult = { hostname: 'Unknown', corporateIndicators: [] }
for (const [ipPattern, dnsData] of Object.entries(mockReverseDNS)) {
if (ip.includes(ipPattern.split('.')[0])) {
return dnsData
}
}
return defaultResult
}
private async analyzeConnectionPattern(ip: string): Promise<NetworkAnalysisResult['indicators']['connectionPattern']> {
// In production, analyze historical connection data
// For demo, simulate connection pattern analysis
const patterns = {
'8.8.8.8': {
requestVolume: 1000,
timeDistribution: 'continuous' as const,
sessionDuration: 300,
endpointDiversity: 0.8
},
'1.1.1.1': {
requestVolume: 800,
timeDistribution: 'continuous' as const,
sessionDuration: 250,
endpointDiversity: 0.7
}
}
const defaultPattern = {
requestVolume: 100,
timeDistribution: 'business_hours' as const,
sessionDuration: 1800,
endpointDiversity: 0.3
}
for (const [ipPattern, pattern] of Object.entries(patterns)) {
if (ip.includes(ipPattern.split('.')[0])) {
return pattern
}
}
return defaultPattern
}
private calculateCorporateProbability(indicators: any): number {
let score = 0.5 // Base probability
// ASN analysis
if (indicators.asnInfo.type === 'corporate') score += 0.3
if (indicators.asnInfo.type === 'hosting') score += 0.1
if (indicators.asnInfo.type === 'education' || indicators.asnInfo.type === 'government') score += 0.2
// IP range analysis
if (indicators.ipRangeInfo.type === 'corporate') score += 0.4
if (indicators.ipRangeInfo.source === 'RFC1918') score += 0.2
// Reverse DNS analysis
const corporateKeywords = ['corp', 'company', 'enterprise', 'business', 'office']
const hostnameIndicators = indicators.reverseDNSInfo.corporateIndicators || []
const hostnameMatches = hostnameIndicators.filter((indicator: string) =>
corporateKeywords.some(keyword => indicator.toLowerCase().includes(keyword))
).length
if (hostnameMatches > 0) score += 0.2
// Connection pattern analysis
if (indicators.connectionPattern.timeDistribution === 'business_hours') score += 0.1
if (indicators.connectionPattern.endpointDiversity > 0.5) score += 0.1
if (indicators.connectionPattern.sessionDuration > 3600) score += 0.1
return Math.min(1, Math.max(0, score))
}
private determineClassification(
corporateProbability: number,
indicators: any
): NetworkAnalysisResult['classification'] {
if (corporateProbability > 0.8) return 'corporate'
if (corporateProbability < 0.3) return 'residential'
// Use indicators for tie-breaking
if (indicators.asnInfo.type === 'hosting') return 'hosting'
if (indicators.ipRangeInfo.type === 'corporate') return 'corporate'
if (indicators.connectionPattern.requestVolume > 500) return 'corporate'
return 'unknown'
}
private initializeCorporateIndicators(): void {
this.corporateIndicators = {
asnKeywords: ['corp', 'company', 'enterprise', 'business', 'office', 'inc', 'ltd', 'llc'],
hostnamePatterns: [
/^.*corp./i,
/^.*company./i,
/^.*enterprise./i,
/^.*business./i,
/^.*office./i
],
ipRangeSources: ['ARIN', 'RIPE', 'APNIC', 'RFC1918'],
behavioralPatterns: {
businessHoursActivity: 0.8,
weekendActivity: 0.2,
sessionConsistency: 0.7
}
}
}
private loadNetworkDatabases(): void {
// In production, load ASN and IP range databases
// For demo, populate with sample data
console.log('Network databases loaded')
}
}
// Corporate vs Residential Classification Service
class CorporateResidentialClassifier {
private networkAnalyzer: CorporateNetworkAnalyzer
private classificationCache: Map<string, {
result: NetworkAnalysisResult
expires: number
}> = new Map()
constructor() {
this.networkAnalyzer = new CorporateNetworkAnalyzer()
}
async classifyIP(ip: string): Promise<{
isCorporate: boolean
confidence: number
analysis: NetworkAnalysisResult
recommendation: string
}> {
// Check cache first
const cached = this.getCachedClassification(ip)
if (cached) {
return {
isCorporate: cached.result.classification === 'corporate',
confidence: cached.result.confidence,
analysis: cached.result,
recommendation: this.generateRecommendation(cached.result)
}
}
// Perform fresh analysis
const analysis = await this.networkAnalyzer.analyzeNetwork(ip)
// Cache result for 24 hours
this.cacheClassification(ip, analysis)
return {
isCorporate: analysis.classification === 'corporate',
confidence: analysis.confidence,
analysis,
recommendation: this.generateRecommendation(analysis)
}
}
private getCachedClassification(ip: string): NetworkAnalysisResult | null {
const cached = this.classificationCache.get(ip)
if (cached && cached.expires > Date.now()) {
return cached.result
}
if (cached) {
this.classificationCache.delete(ip)
}
return null
}
private cacheClassification(ip: string, result: NetworkAnalysisResult): void {
this.classificationCache.set(ip, {
result,
expires: Date.now() + 24 * 60 * 60 * 1000 // 24 hours
})
}
private generateRecommendation(analysis: NetworkAnalysisResult): string {
if (analysis.classification === 'corporate' && analysis.confidence > 80) {
return 'High confidence corporate network - suitable for B2B targeting'
}
if (analysis.classification === 'residential' && analysis.confidence > 80) {
return 'High confidence residential network - suitable for B2C targeting'
}
if (analysis.confidence < 60) {
return 'Low confidence classification - manual review recommended'
}
return 'Medium confidence classification - verify with additional data sources'
}
// Batch classification for multiple IPs
async classifyIPBatch(ips: string[]): Promise<Map<string, NetworkAnalysisResult>> {
const results = new Map<string, NetworkAnalysisResult>()
// Process in parallel with rate limiting
const batchSize = 20
for (let i = 0; i < ips.length; i += batchSize) {
const batch = ips.slice(i, i + batchSize)
const batchPromises = batch.map(async (ip) => {
try {
const result = await this.networkAnalyzer.analyzeNetwork(ip)
return { ip, result }
} catch (error) {
console.error(`Batch classification failed for IP ${ip}:`, error)
return { ip, result: null }
}
})
const batchResults = await Promise.all(batchPromises)
batchResults.forEach(({ ip, result }) => {
if (result) {
results.set(ip, result)
}
})
// Small delay between batches to avoid overwhelming
if (i + batchSize < ips.length) {
await new Promise(resolve => setTimeout(resolve, 100))
}
}
return results
}
getClassificationStats(): {
totalAnalyses: number
corporatePercentage: number
residentialPercentage: number
unknownPercentage: number
averageConfidence: number
} {
const analyses = Array.from(this.classificationCache.values()).map(c => c.result)
const total = analyses.length
if (total === 0) {
return {
totalAnalyses: 0,
corporatePercentage: 0,
residentialPercentage: 0,
unknownPercentage: 0,
averageConfidence: 0
}
}
const corporate = analyses.filter(a => a.classification === 'corporate').length
const residential = analyses.filter(a => a.classification === 'residential').length
const unknown = analyses.filter(a => a.classification === 'unknown').length
const averageConfidence = analyses.reduce((sum, a) => sum + a.confidence, 0) / total
return {
totalAnalyses: total,
corporatePercentage: (corporate / total) * 100,
residentialPercentage: (residential / total) * 100,
unknownPercentage: (unknown / total) * 100,
averageConfidence
}
}
}
// Initialize classification service
const networkAnalyzer = new CorporateNetworkAnalyzer()
const corporateClassifier = new CorporateResidentialClassifier()
// Corporate network detection endpoint
app.post('/api/detect-corporate-network', async (req, res) => {
try {
const { ip } = req.body
if (!ip) {
return res.status(400).json({ error: 'IP address required' })
}
const classification = await corporateClassifier.classifyIP(ip)
res.json({
classification,
timestamp: new Date().toISOString()
})
} catch (error) {
console.error('Corporate network detection error:', error)
res.status(500).json({ error: 'Detection failed' })
}
})
// Batch corporate network detection
app.post('/api/detect-corporate-networks-batch', async (req, res) => {
try {
const { ips } = req.body
if (!Array.isArray(ips)) {
return res.status(400).json({ error: 'IPs array required' })
}
const results = await corporateClassifier.classifyIPBatch(ips)
res.json({
results: Object.fromEntries(results.entries()),
count: results.size,
timestamp: new Date().toISOString()
})
} catch (error) {
console.error('Batch corporate network detection error:', error)
res.status(500).json({ error: 'Batch detection failed' })
}
})
// Corporate network statistics
app.get('/api/corporate-network-stats', (req, res) => {
const stats = corporateClassifier.getClassificationStats()
res.json({
stats,
timestamp: new Date().toISOString()
})
})
console.log('Corporate network detection system initialized')Machine Learning Classification Engine
// Advanced ML-based corporate network classification
interface NetworkFeatures {
ip: string
asnInfo: {
asn: number
organization: string
type: string
}
ipRange: {
range: string
type: string
source: string
}
reverseDNS: {
hostname: string
hasCorporateKeywords: boolean
}
connectionPattern: {
requestVolume: number
timeDistribution: string
sessionDuration: number
endpointDiversity: number
businessHoursRatio: number
weekendRatio: number
}
historicalData: {
classificationHistory: Array<{ classification: string; confidence: number; timestamp: number }>
behaviorStability: number
}
}
interface MLClassificationResult {
ip: string
predictedClass: 'corporate' | 'residential' | 'hosting' | 'mobile' | 'vpn' | 'unknown'
confidence: number
probabilities: Record<string, number>
featureImportance: Record<string, number>
modelVersion: string
processingTime: number
}
class MLCorporateClassifier {
private model: any = null
private featureExtractor: NetworkFeatureExtractor
private modelVersion: string = '1.0.0'
private predictionCache: Map<string, MLClassificationResult> = new Map()
constructor() {
this.featureExtractor = new NetworkFeatureExtractor()
this.initializeModel()
}
async classifyWithML(ip: string, features: NetworkFeatures): Promise<MLClassificationResult> {
const startTime = Date.now()
// Check cache first
const cacheKey = this.generateCacheKey(ip, features)
const cached = this.getCachedPrediction(cacheKey)
if (cached) {
return { ...cached, processingTime: Date.now() - startTime }
}
try {
// Extract numerical features for ML model
const numericalFeatures = await this.featureExtractor.extractNumericalFeatures(features)
// Run ML prediction
const prediction = await this.runModelPrediction(numericalFeatures)
// Calculate feature importance
const featureImportance = this.calculateFeatureImportance(numericalFeatures)
const result: MLClassificationResult = {
ip,
predictedClass: prediction.class,
confidence: prediction.confidence,
probabilities: prediction.probabilities,
featureImportance,
modelVersion: this.modelVersion,
processingTime: Date.now() - startTime
}
// Cache prediction for 12 hours
this.cachePrediction(cacheKey, result)
return result
} catch (error) {
console.error('ML classification failed:', error)
// Fallback to rule-based classification
return this.fallbackClassification(ip, features, Date.now() - startTime)
}
}
private async initializeModel(): Promise<void> {
// In production, load pre-trained TensorFlow.js model
// For demo, simulate model initialization
console.log('Initializing ML corporate classification model...')
await new Promise(resolve => setTimeout(resolve, 1000))
this.model = {
predict: async (features: number[]) => {
// Simplified prediction logic for demo
const classProbabilities = this.calculateClassProbabilities(features)
const maxProb = Math.max(...Object.values(classProbabilities))
const predictedClass = Object.keys(classProbabilities).find(
key => classProbabilities[key] === maxProb
) as any
return {
class: predictedClass,
confidence: maxProb,
probabilities: classProbabilities
}
}
}
console.log('ML model initialized successfully')
}
private calculateClassProbabilities(features: number[]): Record<string, number> {
// Simplified probability calculation for demo
const probabilities: Record<string, number> = {
corporate: 0.2,
residential: 0.2,
hosting: 0.2,
mobile: 0.2,
vpn: 0.1,
unknown: 0.1
}
// Adjust probabilities based on features
if (features[0] > 0.7) probabilities.corporate += 0.3 // High ASN corporate score
if (features[1] > 0.8) probabilities.residential += 0.3 // High residential indicators
if (features[2] > 0.6) probabilities.hosting += 0.2 // High hosting indicators
// Normalize probabilities
const total = Object.values(probabilities).reduce((a, b) => a + b, 0)
for (const key in probabilities) {
probabilities[key] /= total
}
return probabilities
}
private calculateFeatureImportance(features: number[]): Record<string, number> {
// Simplified feature importance calculation
return {
asn_corporate_score: features[0] * 0.3,
residential_indicators: features[1] * 0.25,
hosting_indicators: features[2] * 0.2,
connection_patterns: features[3] * 0.15,
historical_stability: features[4] * 0.1
}
}
private fallbackClassification(
ip: string,
features: NetworkFeatures,
processingTime: number
): MLClassificationResult {
// Rule-based fallback classification
let predictedClass: MLClassificationResult['predictedClass'] = 'unknown'
let confidence = 50
// Simple rule-based logic
if (features.ipRange.type === 'corporate') {
predictedClass = 'corporate'
confidence = 80
} else if (features.connectionPattern.businessHoursRatio > 0.7) {
predictedClass = 'corporate'
confidence = 70
} else if (features.connectionPattern.endpointDiversity < 0.3) {
predictedClass = 'residential'
confidence = 65
}
return {
ip,
predictedClass,
confidence,
probabilities: {
corporate: predictedClass === 'corporate' ? confidence / 100 : 0.2,
residential: predictedClass === 'residential' ? confidence / 100 : 0.2,
hosting: 0.2,
mobile: 0.1,
vpn: 0.1,
unknown: predictedClass === 'unknown' ? 0.8 : 0.1
},
featureImportance: {},
modelVersion: 'fallback-1.0',
processingTime
}
}
private generateCacheKey(ip: string, features: NetworkFeatures): string {
const keyData = `${ip}-${features.asnInfo.asn}-${features.ipRange.type}-${features.connectionPattern.requestVolume}`
return Buffer.from(keyData).toString('base64').slice(0, 32)
}
private getCachedPrediction(key: string): MLClassificationResult | null {
const cached = this.predictionCache.get(key)
if (cached && Date.now() - 12 * 60 * 60 * 1000 < cached.processingTime) { // 12 hours cache
return cached
}
if (cached) {
this.predictionCache.delete(key)
}
return null
}
private cachePrediction(key: string, result: MLClassificationResult): void {
this.predictionCache.set(key, result)
// Maintain cache size (keep only 10000 entries)
if (this.predictionCache.size > 10000) {
const entries = Array.from(this.predictionCache.entries())
const oldestKey = entries.sort(([, a], [, b]) => a.processingTime - b.processingTime)[0][0]
this.predictionCache.delete(oldestKey)
}
}
private async runModelPrediction(features: number[]): Promise<any> {
if (!this.model) {
throw new Error('Model not initialized')
}
return await this.model.predict(features)
}
}
class NetworkFeatureExtractor {
async extractNumericalFeatures(features: NetworkFeatures): Promise<number[]> {
return [
this.normalizeASNScore(features.asnInfo),
this.normalizeIPRangeScore(features.ipRange),
this.normalizeReverseDNSScore(features.reverseDNS),
this.normalizeConnectionPatternScore(features.connectionPattern),
this.normalizeHistoricalScore(features.historicalData)
]
}
private normalizeASNScore(asnInfo: any): number {
const typeScores: Record<string, number> = {
'corporate': 0.9,
'education': 0.8,
'government': 0.8,
'hosting': 0.6,
'isp': 0.3
}
return typeScores[asnInfo.type] || 0.1
}
private normalizeIPRangeScore(ipRange: any): number {
const typeScores: Record<string, number> = {
'corporate': 0.9,
'residential': 0.2,
'hosting': 0.5,
'unknown': 0.1
}
return typeScores[ipRange.type] || 0.1
}
private normalizeReverseDNSScore(reverseDNS: any): number {
if (reverseDNS.hasCorporateKeywords) return 0.8
return 0.2
}
private normalizeConnectionPatternScore(pattern: any): number {
let score = 0.5
if (pattern.businessHoursRatio > 0.7) score += 0.2
if (pattern.endpointDiversity > 0.5) score += 0.1
if (pattern.sessionDuration > 3600) score += 0.1
return Math.min(1, score)
}
private normalizeHistoricalScore(historical: any): number {
if (historical.classificationHistory.length === 0) return 0.5
const recentClassifications = historical.classificationHistory.slice(-5)
const consistency = recentClassifications.filter(
c => c.classification === recentClassifications[0].classification
).length / recentClassifications.length
return consistency
}
}
// Enhanced corporate detection with ML
class EnhancedCorporateDetector {
private networkAnalyzer: CorporateNetworkAnalyzer
private mlClassifier: MLCorporateClassifier
private corporateClassifier: CorporateResidentialClassifier
constructor() {
this.networkAnalyzer = new CorporateNetworkAnalyzer()
this.mlClassifier = new MLCorporateClassifier()
this.corporateClassifier = new CorporateResidentialClassifier()
}
async detectCorporateNetworkEnhanced(ip: string): Promise<{
ruleBasedClassification: NetworkAnalysisResult
mlClassification: MLClassificationResult
finalDecision: {
isCorporate: boolean
confidence: number
method: 'rule_based' | 'ml' | 'consensus'
}
recommendation: string
}> {
// Get rule-based analysis
const ruleBasedAnalysis = await this.networkAnalyzer.analyzeNetwork(ip)
// Extract features for ML
const features: NetworkFeatures = {
ip,
asnInfo: ruleBasedAnalysis.indicators.autonomousSystem,
ipRange: ruleBasedAnalysis.indicators.ipRange,
reverseDNS: ruleBasedAnalysis.indicators.reverseDNS,
connectionPattern: ruleBasedAnalysis.indicators.connectionPattern,
historicalData: {
classificationHistory: [],
behaviorStability: 0.5
}
}
// Get ML classification
const mlClassification = await this.mlClassifier.classifyWithML(ip, features)
// Combine results
const finalDecision = this.combineClassifications(ruleBasedAnalysis, mlClassification)
return {
ruleBasedClassification: ruleBasedAnalysis,
mlClassification,
finalDecision,
recommendation: this.generateEnhancedRecommendation(finalDecision, ruleBasedAnalysis, mlClassification)
}
}
private combineClassifications(
ruleBased: NetworkAnalysisResult,
ml: MLClassificationResult
): { isCorporate: boolean; confidence: number; method: string } {
// Weighted combination of rule-based and ML results
const ruleBasedScore = ruleBased.corporateProbability
const mlScore = ml.probabilities.corporate || 0
// Weight ML higher if confidence is good
const mlWeight = ml.confidence > 70 ? 0.7 : 0.3
const ruleBasedWeight = 1 - mlWeight
const combinedScore = (ruleBasedScore * ruleBasedWeight) + (mlScore * mlWeight)
const isCorporate = combinedScore > 0.6
let method = 'consensus'
if (ml.confidence > 80 && ruleBased.confidence < 60) method = 'ml'
if (ruleBased.confidence > 80 && ml.confidence < 60) method = 'rule_based'
return {
isCorporate,
confidence: combinedScore * 100,
method
}
}
private generateEnhancedRecommendation(
finalDecision: any,
ruleBased: NetworkAnalysisResult,
ml: MLClassificationResult
): string {
if (finalDecision.confidence > 85) {
return `High confidence ${finalDecision.isCorporate ? 'corporate' : 'residential'} network (${finalDecision.method})`
}
if (finalDecision.confidence < 60) {
return 'Low confidence classification - consider manual review or additional data sources'
}
return `Medium confidence ${finalDecision.isCorporate ? 'corporate' : 'residential'} network - verify with business context`
}
// Training data collection for model improvement
async collectTrainingData(
ip: string,
actualClassification: 'corporate' | 'residential',
features: NetworkFeatures
): Promise<void> {
// In production, store training examples for model retraining
console.log(`Training data collected for IP ${ip}: ${actualClassification}`)
}
}
// Initialize enhanced detector
const enhancedCorporateDetector = new EnhancedCorporateDetector()
// Enhanced corporate detection endpoint
app.post('/api/detect-corporate-network-enhanced', async (req, res) => {
try {
const { ip } = req.body
if (!ip) {
return res.status(400).json({ error: 'IP address required' })
}
const result = await enhancedCorporateDetector.detectCorporateNetworkEnhanced(ip)
res.json({
detection: result,
timestamp: new Date().toISOString()
})
} catch (error) {
console.error('Enhanced corporate network detection error:', error)
res.status(500).json({ error: 'Enhanced detection failed' })
}
})
// Training data submission endpoint
app.post('/api/corporate-detection/training', async (req, res) => {
try {
const { ip, actualClassification, features } = req.body
if (!ip || !actualClassification || !features) {
return res.status(400).json({ error: 'IP, classification, and features required' })
}
await enhancedCorporateDetector.collectTrainingData(ip, actualClassification, features)
res.json({
message: 'Training data submitted successfully',
timestamp: new Date().toISOString()
})
} catch (error) {
console.error('Training data submission error:', error)
res.status(500).json({ error: 'Training data submission failed' })
}
})
console.log('Enhanced corporate network detection with ML initialized')Behavioral Pattern Analysis for Corporate Detection
// Advanced behavioral pattern analysis for corporate network identification
interface BehavioralSession {
sessionId: string
ip: string
userAgent: string
startTime: number
endTime?: number
duration?: number
pageViews: number
uniqueEndpoints: Set<string>
requestTimestamps: number[]
errorCount: number
successCount: number
businessHoursActivity: boolean
weekendActivity: boolean
}
interface CorporateBehavioralProfile {
ip: string
sessionCount: number
averageSessionDuration: number
businessHoursRatio: number
weekendActivityRatio: number
endpointDiversity: number
errorRate: number
consistencyScore: number
corporateScore: number
lastUpdated: number
}
class CorporateBehavioralAnalyzer {
private activeSessions: Map<string, BehavioralSession> = new Map()
private behavioralProfiles: Map<string, CorporateBehavioralProfile> = new Map()
private corporateThresholds = {
minSessionDuration: 1800, // 30 minutes
minBusinessHoursRatio: 0.7,
maxWeekendRatio: 0.3,
minEndpointDiversity: 0.5,
maxErrorRate: 0.1,
minConsistencyScore: 0.6
}
constructor() {
this.startBehavioralMonitoring()
}
analyzeRequest(
ip: string,
sessionId: string,
endpoint: string,
timestamp: number,
statusCode: number,
userAgent: string
): {
sessionUpdate: boolean
profileUpdate: boolean
corporateIndicators: string[]
riskFlags: string[]
} {
const now = Date.now()
const isBusinessHours = this.isBusinessHours(timestamp)
const isWeekend = this.isWeekend(timestamp)
// Update or create session
const sessionUpdate = this.updateSession(sessionId, ip, endpoint, timestamp, statusCode, userAgent)
// Update behavioral profile
const profileUpdate = this.updateBehavioralProfile(ip, {
isBusinessHours,
isWeekend,
statusCode,
endpoint
})
// Analyze for corporate indicators
const corporateIndicators = this.analyzeCorporateIndicators(ip)
// Check for risk flags
const riskFlags = this.analyzeRiskFlags(ip)
return {
sessionUpdate,
profileUpdate,
corporateIndicators,
riskFlags
}
}
private updateSession(
sessionId: string,
ip: string,
endpoint: string,
timestamp: number,
statusCode: number,
userAgent: string
): boolean {
let session = this.activeSessions.get(sessionId)
if (!session) {
// Create new session
session = {
sessionId,
ip,
userAgent,
startTime: timestamp,
pageViews: 0,
uniqueEndpoints: new Set(),
requestTimestamps: [],
errorCount: 0,
successCount: 0,
businessHoursActivity: false,
weekendActivity: false
}
this.activeSessions.set(sessionId, session)
}
// Update session data
session.pageViews++
session.uniqueEndpoints.add(endpoint)
session.requestTimestamps.push(timestamp)
if (statusCode >= 400) {
session.errorCount++
} else {
session.successCount++
}
if (this.isBusinessHours(timestamp)) {
session.businessHoursActivity = true
}
if (this.isWeekend(timestamp)) {
session.weekendActivity = true
}
// Check if session should be closed
if (session.requestTimestamps.length > 1) {
const timeDiff = timestamp - session.requestTimestamps[session.requestTimestamps.length - 2]
if (timeDiff > 30 * 60 * 1000) { // 30 minutes of inactivity
this.closeSession(sessionId)
}
}
return true
}
private closeSession(sessionId: string): void {
const session = this.activeSessions.get(sessionId)
if (session) {
session.endTime = Date.now()
session.duration = session.endTime - session.startTime
// Update behavioral profile with completed session
this.updateProfileWithSession(session)
this.activeSessions.delete(sessionId)
}
}
private updateProfileWithSession(session: BehavioralSession): void {
const profileKey = session.ip
let profile = this.behavioralProfiles.get(profileKey)
if (!profile) {
profile = {
ip: session.ip,
sessionCount: 0,
averageSessionDuration: 0,
businessHoursRatio: 0,
weekendActivityRatio: 0,
endpointDiversity: 0,
errorRate: 0,
consistencyScore: 0,
corporateScore: 0,
lastUpdated: Date.now()
}
this.behavioralProfiles.set(profileKey, profile)
}
// Update profile statistics
profile.sessionCount++
// Update average session duration
if (session.duration) {
profile.averageSessionDuration =
(profile.averageSessionDuration * (profile.sessionCount - 1) + session.duration) / profile.sessionCount
}
// Update business hours ratio
if (session.businessHoursActivity) {
profile.businessHoursRatio =
(profile.businessHoursRatio * (profile.sessionCount - 1) + 1) / profile.sessionCount
}
// Update weekend activity ratio
if (session.weekendActivity) {
profile.weekendActivityRatio =
(profile.weekendActivityRatio * (profile.sessionCount - 1) + 1) / profile.sessionCount
}
// Update endpoint diversity
profile.endpointDiversity = session.uniqueEndpoints.size / Math.max(session.pageViews, 1)
// Update error rate
const totalRequests = session.errorCount + session.successCount
if (totalRequests > 0) {
profile.errorRate = session.errorCount / totalRequests
}
// Calculate consistency score
profile.consistencyScore = this.calculateSessionConsistency(session)
// Calculate corporate score
profile.corporateScore = this.calculateCorporateScore(profile)
profile.lastUpdated = Date.now()
this.behavioralProfiles.set(profileKey, profile)
}
private calculateSessionConsistency(session: BehavioralSession): number {
if (session.requestTimestamps.length < 3) return 0.5
// Calculate time intervals between requests
const intervals = []
for (let i = 1; i < session.requestTimestamps.length; i++) {
intervals.push(session.requestTimestamps[i] - session.requestTimestamps[i - 1])
}
// Calculate coefficient of variation
const mean = intervals.reduce((a, b) => a + b, 0) / intervals.length
const variance = intervals.reduce((acc, interval) => acc + Math.pow(interval - mean, 2), 0) / intervals.length
const stdDev = Math.sqrt(variance)
const coefficientOfVariation = mean > 0 ? stdDev / mean : 0
// Lower variation = higher consistency
return Math.max(0, 1 - coefficientOfVariation)
}
private calculateCorporateScore(profile: CorporateBehavioralProfile): number {
let score = 0.5 // Base score
// Long sessions suggest corporate usage
if (profile.averageSessionDuration > this.corporateThresholds.minSessionDuration) {
score += 0.2
}
// High business hours activity suggests corporate
if (profile.businessHoursRatio > this.corporateThresholds.minBusinessHoursRatio) {
score += 0.3
}
// Low weekend activity suggests corporate
if (profile.weekendActivityRatio < this.corporateThresholds.maxWeekendRatio) {
score += 0.2
}
// High endpoint diversity suggests corporate
if (profile.endpointDiversity > this.corporateThresholds.minEndpointDiversity) {
score += 0.1
}
// Low error rate suggests corporate
if (profile.errorRate < this.corporateThresholds.maxErrorRate) {
score += 0.1
}
// High consistency suggests corporate
if (profile.consistencyScore > this.corporateThresholds.minConsistencyScore) {
score += 0.1
}
return Math.min(1, Math.max(0, score))
}
private analyzeCorporateIndicators(ip: string): string[] {
const profile = this.behavioralProfiles.get(ip)
if (!profile) return []
const indicators: string[] = []
if (profile.averageSessionDuration > this.corporateThresholds.minSessionDuration) {
indicators.push('Long session duration')
}
if (profile.businessHoursRatio > this.corporateThresholds.minBusinessHoursRatio) {
indicators.push('High business hours activity')
}
if (profile.weekendActivityRatio < this.corporateThresholds.maxWeekendRatio) {
indicators.push('Low weekend activity')
}
if (profile.endpointDiversity > this.corporateThresholds.minEndpointDiversity) {
indicators.push('High endpoint diversity')
}
if (profile.errorRate < this.corporateThresholds.maxErrorRate) {
indicators.push('Low error rate')
}
if (profile.consistencyScore > this.corporateThresholds.minConsistencyScore) {
indicators.push('High behavioral consistency')
}
return indicators
}
private analyzeRiskFlags(ip: string): string[] {
const profile = this.behavioralProfiles.get(ip)
if (!profile) return []
const flags: string[] = []
// Very short sessions with many requests
if (profile.averageSessionDuration < 300 && profile.sessionCount > 10) {
flags.push('Suspicious session pattern')
}
// High error rate
if (profile.errorRate > 0.5) {
flags.push('High error rate')
}
// Very low consistency (erratic behavior)
if (profile.consistencyScore < 0.2) {
flags.push('Erratic behavioral pattern')
}
// Weekend-only activity
if (profile.businessHoursRatio < 0.3 && profile.weekendActivityRatio > 0.7) {
flags.push('Weekend-only activity')
}
return flags
}
private isBusinessHours(timestamp: number): boolean {
const date = new Date(timestamp)
const hour = date.getHours()
const dayOfWeek = date.getDay()
// Business hours: Monday-Friday, 9 AM - 6 PM
return dayOfWeek >= 1 && dayOfWeek <= 5 && hour >= 9 && hour <= 18
}
private isWeekend(timestamp: number): boolean {
const date = new Date(timestamp)
const dayOfWeek = date.getDay()
return dayOfWeek === 0 || dayOfWeek === 6
}
private startBehavioralMonitoring(): void {
// Clean up old sessions every 5 minutes
setInterval(() => {
this.cleanupOldSessions()
}, 5 * 60 * 1000)
// Update behavioral profiles every 15 minutes
setInterval(() => {
this.updateAllProfiles()
}, 15 * 60 * 1000)
console.log('Behavioral analysis monitoring started')
}
private cleanupOldSessions(): void {
const now = Date.now()
const thirtyMinutesAgo = now - 30 * 60 * 1000
for (const [sessionId, session] of this.activeSessions.entries()) {
if (session.requestTimestamps.length > 0) {
const lastRequest = Math.max(...session.requestTimestamps)
if (lastRequest < thirtyMinutesAgo) {
this.closeSession(sessionId)
}
}
}
}
private updateAllProfiles(): void {
// Force update of all profiles (for testing/demo)
console.log(`Updated ${this.behavioralProfiles.size} behavioral profiles`)
}
private updateBehavioralProfile(
ip: string,
requestData: { isBusinessHours: boolean; isWeekend: boolean; statusCode: number; endpoint: string }
): boolean {
// This would normally update the profile based on the request
// For demo, we'll just mark that an update occurred
return true
}
getBehavioralProfile(ip: string): CorporateBehavioralProfile | null {
return this.behavioralProfiles.get(ip) || null
}
getAllBehavioralProfiles(): CorporateBehavioralProfile[] {
return Array.from(this.behavioralProfiles.values())
}
getCorporateNetworks(minScore: number = 0.7): string[] {
return Array.from(this.behavioralProfiles.entries())
.filter(([, profile]) => profile.corporateScore >= minScore)
.map(([ip]) => ip)
}
getBehavioralStats(): {
totalProfiles: number
corporateProfiles: number
averageCorporateScore: number
topCorporateIPs: Array<{ ip: string; score: number }>
} {
const profiles = Array.from(this.behavioralProfiles.values())
const corporateProfiles = profiles.filter(p => p.corporateScore >= 0.7)
const averageCorporateScore = profiles.length > 0
? profiles.reduce((sum, p) => sum + p.corporateScore, 0) / profiles.length
: 0
const topCorporateIPs = corporateProfiles
.sort((a, b) => b.corporateScore - a.corporateScore)
.slice(0, 10)
.map(p => ({ ip: p.ip, score: p.corporateScore }))
return {
totalProfiles: profiles.length,
corporateProfiles: corporateProfiles.length,
averageCorporateScore,
topCorporateIPs
}
}
}
// Initialize behavioral analyzer
const behavioralAnalyzer = new CorporateBehavioralAnalyzer()
// Behavioral analysis endpoint
app.post('/api/analyze-behavioral-pattern', async (req, res) => {
try {
const { ip, sessionId, endpoint, timestamp, statusCode, userAgent } = req.body
if (!ip || !sessionId || !endpoint || !timestamp) {
return res.status(400).json({ error: 'IP, sessionId, endpoint, and timestamp required' })
}
const analysis = behavioralAnalyzer.analyzeRequest(
ip,
sessionId,
endpoint,
timestamp,
statusCode || 200,
userAgent || ''
)
res.json({
analysis,
timestamp: new Date().toISOString()
})
} catch (error) {
console.error('Behavioral analysis error:', error)
res.status(500).json({ error: 'Behavioral analysis failed' })
}
})
// Get behavioral profile endpoint
app.get('/api/behavioral-profile/:ip', (req, res) => {
const { ip } = req.params
if (!ip) {
return res.status(400).json({ error: 'IP address required' })
}
const profile = behavioralAnalyzer.getBehavioralProfile(ip)
if (!profile) {
return res.status(404).json({ error: 'Profile not found' })
}
res.json({
profile,
timestamp: new Date().toISOString()
})
})
// Get behavioral statistics
app.get('/api/behavioral-stats', (req, res) => {
const stats = behavioralAnalyzer.getBehavioralStats()
res.json({
stats,
timestamp: new Date().toISOString()
})
})
// Get corporate networks identified by behavior
app.get('/api/corporate-networks-behavioral', (req, res) => {
const { minScore = 0.7 } = req.query
const corporateIPs = behavioralAnalyzer.getCorporateNetworks(Number(minScore))
res.json({
corporateIPs,
count: corporateIPs.length,
minScore: Number(minScore),
timestamp: new Date().toISOString()
})
})
console.log('Behavioral pattern analysis system initialized')Implementation Challenges {#implementation-challenges}
Key challenges in corporate network detection.
Challenges:
- False Positives: Home offices, VPNs classified as corporate
- Remote Work: Blurred lines between corporate and residential
- Privacy: Must not over-fingerprint users
- Dynamic Networks: Corporate networks change infrastructure
- Cloud Services: SaaS companies use cloud IPs, not corporate ranges
Performance Optimization {#performance-optimization}
Optimize detection for high-volume scenarios.
class CorporateDetectionCache {
private cache: Map<string, { isCorporate: boolean; confidence: number; expiry: number }> = new Map()
getCached(ip: string): { isCorporate: boolean; confidence: number } | null {
const cached = this.cache.get(ip)
if (!cached || Date.now() > cached.expiry) return null
return { isCorporate: cached.isCorporate, confidence: cached.confidence }
}
setCached(ip: string, result: { isCorporate: boolean; confidence: number }): void {
this.cache.set(ip, {
...result,
expiry: Date.now() + 3600000 // 1 hour TTL
})
}
}Use Case Applications {#use-case-applications}
Practical applications of corporate detection.
Use Cases:
- B2B Marketing: Target corporate users with enterprise offers
- Pricing: Differential pricing for business vs consumer
- Security: Enhanced verification for corporate networks
- Compliance: Track business user access patterns
- Analytics: Segment traffic by network type
Future Considerations {#future-considerations}
Evolving landscape of corporate networks.
Trends:
- Increasing remote work blurs corporate/residential distinction
- Cloud-first companies have no traditional corporate IP ranges
- Zero-trust networks reduce reliance on network classification
- Privacy regulations limit fingerprinting capabilities
Conclusion {#conclusion}
Corporate network detection combines ASN analysis, proxy detection, behavioral patterns, and organizational databases. Success depends on multi-signal approach, appropriate confidence thresholds, respecting privacy, and adapting to remote work trends.
Key success factors include using multiple detection methods, maintaining current organizational databases, implementing confidence scoring, handling edge cases like remote workers, and providing transparency about detection methods.
Identify corporate networks accurately with our IP intelligence APIs, designed to distinguish business from residential traffic while respecting user privacy.