
Research
/Security News
Malicious npm Packages Target WhatsApp Developers with Remote Kill Switch
Two npm packages masquerading as WhatsApp developer libraries include a kill switch that deletes all files if the phone number isn’t whitelisted.
@push.rocks/smartproxy
Advanced tools
A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.
A unified high-performance proxy toolkit for Node.js, with SmartProxy as the central API to handle all your proxy needs:
SmartProxy has been restructured using a modern, modular architecture with a unified route-based configuration system:
/ts
├── /core # Core functionality
│ ├── /models # Data models and interfaces
│ ├── /utils # Shared utilities (IP validation, logging, etc.)
│ └── /events # Common event definitions
├── /forwarding # Forwarding system
│ ├── /handlers # Various forwarding handlers
│ │ ├── base-handler.ts # Abstract base handler
│ │ ├── http-handler.ts # HTTP-only handler
│ │ └── ... # Other handlers
│ ├── /config # Configuration models
│ └── /factory # Factory for creating handlers
├── /proxies # Different proxy implementations
│ ├── /smart-proxy # SmartProxy implementation
│ │ ├── /models # SmartProxy-specific interfaces
│ │ │ ├── route-types.ts # Route-based configuration types
│ │ │ └── interfaces.ts # SmartProxy interfaces
│ │ ├── certificate-manager.ts # SmartCertManager
│ │ ├── cert-store.ts # Certificate file storage
│ │ ├── route-helpers.ts # Helper functions for creating routes
│ │ ├── route-manager.ts # Route management system
│ │ ├── smart-proxy.ts # Main SmartProxy class
│ │ └── ... # Supporting classes
│ ├── /http-proxy # HttpProxy implementation (HTTP/HTTPS handling)
│ └── /nftables-proxy # NfTablesProxy implementation
├── /tls # TLS-specific functionality
│ ├── /sni # SNI handling components
│ └── /alerts # TLS alerts system
└── /routing # Routing functionality
└── /router # HTTP routing system
ts/proxies/smart-proxy/smart-proxy.ts
)
The central unified API for all proxy needs, featuring:
ts/proxies/http-proxy/http-proxy.ts
)
HTTP/HTTPS reverse proxy with TLS termination and WebSocket supportts/proxies/nftables-proxy/nftables-proxy.ts
)
Low-level port forwarding using nftables NAT rulests/tls/sni/sni-handler.ts
)
Utilities for SNI extraction from TLS handshakests/core/utils/validation-utils.ts
)
Domain, port, and configuration validationts/core/utils/ip-utils.ts
)
IP address validation and filtering with glob patternsIRouteConfig
, IRouteMatch
, IRouteAction
(ts/proxies/smart-proxy/models/route-types.ts
)IRoutedSmartProxyOptions
(ts/proxies/smart-proxy/models/route-types.ts
)IHttpProxyOptions
(ts/proxies/http-proxy/models/types.ts
)INfTableProxySettings
(ts/proxies/nftables-proxy/models/interfaces.ts
)Install via npm:
npm install @push.rocks/smartproxy
SmartProxy v20.0.0 provides a unified route-based configuration system with enhanced certificate management, NFTables integration for high-performance kernel-level routing, custom socket handling, and improved helper functions for common proxy setups.
⚠️ Breaking Change in v20.0.0: The route action configuration has changed from single target
to targets
array to support multiple upstream targets for load balancing and failover.
import {
SmartProxy,
createHttpRoute,
createHttpsTerminateRoute,
createHttpsPassthroughRoute,
createHttpToHttpsRedirect,
createCompleteHttpsServer,
createLoadBalancerRoute,
createApiRoute,
createWebSocketRoute,
createSocketHandlerRoute,
createNfTablesRoute,
createNfTablesTerminateRoute,
createCompleteNfTablesHttpsServer,
createPortMappingRoute,
createOffsetPortMappingRoute,
createDynamicRoute,
createSmartLoadBalancer,
createApiGatewayRoute,
addRateLimiting,
addBasicAuth,
addJwtAuth,
SocketHandlers
} from '@push.rocks/smartproxy';
// Create a new SmartProxy instance with route-based configuration
const proxy = new SmartProxy({
// Global ACME settings for all routes with certificate: 'auto'
acme: {
email: 'ssl@example.com', // Required for Let's Encrypt
useProduction: false, // Use staging by default
renewThresholdDays: 30, // Renew 30 days before expiry
port: 80, // Port for HTTP-01 challenges (use 8080 for non-privileged)
autoRenew: true, // Enable automatic renewal
renewCheckIntervalHours: 24 // Check for renewals daily
},
// Define all your routing rules in a single array
routes: [
// Basic HTTP route - forward traffic from port 80 to internal service
createHttpRoute('api.example.com', { host: 'localhost', port: 3000 }),
// HTTPS route with TLS termination and automatic certificates
createHttpsTerminateRoute('secure.example.com', { host: 'localhost', port: 8080 }, {
certificate: 'auto' // Uses global ACME settings
}),
// HTTPS passthrough for legacy systems
createHttpsPassthroughRoute('legacy.example.com', { host: '192.168.1.10', port: 443 }),
// Redirect HTTP to HTTPS for all domains and subdomains
createHttpToHttpsRedirect(['example.com', '*.example.com']),
// Complete HTTPS server (creates both HTTPS route and HTTP redirect)
...createCompleteHttpsServer('complete.example.com', { host: 'localhost', port: 3000 }, {
certificate: 'auto'
}),
// API route with CORS headers
createApiRoute('api.service.com', '/v1', { host: 'api-backend', port: 8081 }, {
useTls: true,
certificate: 'auto',
addCorsHeaders: true
}),
// WebSocket route for real-time communication
createWebSocketRoute('ws.example.com', '/socket', { host: 'socket-server', port: 8082 }, {
useTls: true,
certificate: 'auto',
pingInterval: 30000
}),
// Load balancer with multiple backend servers
createLoadBalancerRoute(
'app.example.com',
['192.168.1.10', '192.168.1.11', '192.168.1.12'],
8080,
{
tls: {
mode: 'terminate',
certificate: 'auto'
}
}
),
// Custom socket handler for specialized protocols
createSocketHandlerRoute('telnet.example.com', 23, SocketHandlers.lineProtocol((line, socket) => {
console.log('Received:', line);
socket.write(`Echo: ${line}\n`);
})),
// High-performance NFTables route (requires root/sudo)
createNfTablesRoute('fast.example.com', { host: 'backend-server', port: 8080 }, {
ports: 80,
protocol: 'tcp',
preserveSourceIP: true,
ipAllowList: ['10.0.0.*']
}),
// NFTables HTTPS termination for ultra-fast TLS handling
createNfTablesTerminateRoute('secure-fast.example.com', { host: 'backend-ssl', port: 443 }, {
ports: 443,
certificate: 'auto',
maxRate: '100mbps'
}),
// Route with security configuration
{
name: 'secure-admin',
match: {
ports: 443,
domains: 'admin.example.com'
},
action: {
type: 'forward',
targets: [{ host: 'localhost', port: 8080 }], // Note: targets is an array
tls: {
mode: 'terminate',
certificate: 'auto'
}
},
security: {
ipAllowList: ['10.0.0.*', '192.168.1.*'],
ipBlockList: ['192.168.1.100'],
maxConnections: 100
}
}
]
});
// Start the proxy
await proxy.start();
// Dynamically add new routes later
await proxy.updateRoutes([
...proxy.settings.routes,
createHttpsTerminateRoute('new-domain.com', { host: 'localhost', port: 9000 }, {
certificate: 'auto'
})
]);
// Dynamically add or remove port listeners
await proxy.addListeningPort(8081);
await proxy.removeListeningPort(8081);
console.log('Currently listening on ports:', proxy.getListeningPorts());
// Later, gracefully shut down
await proxy.stop();
SmartProxy uses a unified route configuration system based on the IRouteConfig
interface. This system follows a match/action pattern that makes routing more powerful, flexible, and declarative.
The IRouteConfig
interface is the core building block of SmartProxy's configuration system. Each route definition consists of match criteria and an action to perform on matched traffic:
interface IRouteConfig {
// What traffic to match (required)
match: IRouteMatch;
// What to do with matched traffic (required)
action: IRouteAction;
// Security configuration (optional)
security?: IRouteSecurity;
// Metadata (all optional)
name?: string; // Human-readable name for this route
description?: string; // Description of the route's purpose
priority?: number; // Controls matching order (higher = matched first)
tags?: string[]; // Arbitrary tags for categorization
enabled?: boolean; // Whether the route is active (default: true)
}
The match
property defines criteria for identifying which incoming traffic should be handled by this route:
interface IRouteMatch {
// Port(s) to match
ports: number | number[] | string; // Single port, array, or range like '8000-8999'
// Domain matching (optional - if not specified, matches all domains)
domains?: string | string[]; // Exact domains or patterns with wildcards
// Path matching (optional)
path?: string; // URL path pattern (supports wildcards)
// Client IP matching (optional)
clientIp?: string | string[]; // IP addresses or CIDR ranges
// Protocol matching (optional)
protocol?: 'tcp' | 'udp' | 'http' | 'https' | 'ws' | 'wss';
// TLS version matching (optional)
tlsVersion?: string | string[]; // e.g., ['TLSv1.2', 'TLSv1.3']
// Custom matcher function (optional)
customMatcher?: (context: IRouteContext) => boolean | Promise<boolean>;
}
Domain Matching Patterns:
example.com
*.example.com
['example.com', '*.example.com', 'example.org']
domains
fieldPath Matching Patterns:
/api/users
/api/*
/api/users/:id
/api/*/details
The action
property defines what to do with matched traffic:
interface IRouteAction {
// Action type (required)
type: 'forward' | 'redirect' | 'block' | 'socket-handler';
// For 'forward' type - array of upstream targets
targets?: IRouteTarget[];
// For 'redirect' type
redirectUrl?: string; // URL template with placeholders
redirectCode?: number; // HTTP status code (301, 302, etc.)
// For 'socket-handler' type
socketHandler?: (socket: net.Socket, context: IRouteContext) => void | Promise<void>;
// TLS configuration (optional)
tls?: IRouteTls;
// WebSocket configuration (optional)
websocket?: {
enabled: boolean;
pingInterval?: number; // Milliseconds between pings
pingTimeout?: number; // Milliseconds to wait for pong
};
// Headers manipulation (optional)
headers?: {
request?: Record<string, string>; // Headers to add to requests
response?: Record<string, string>; // Headers to add to responses
};
}
Forward Action with Multiple Targets:
{
type: 'forward',
targets: [
{ host: 'backend1.example.com', port: 8080 },
{ host: 'backend2.example.com', port: 8080 },
{ host: 'backend3.example.com', port: 8080 }
]
}
Redirect Action:
{
type: 'redirect',
redirectUrl: 'https://{domain}/{path}', // Placeholders: {domain}, {path}, {clientIp}
redirectCode: 301
}
Socket Handler Action:
{
type: 'socket-handler',
socketHandler: (socket, context) => {
// Custom logic for handling the socket
socket.write('Hello from custom handler\n');
socket.end();
}
}
{
match: {
ports: 80,
domains: 'api.example.com'
},
action: {
type: 'forward',
targets: [{ host: 'localhost', port: 3000 }]
}
}
{
match: {
ports: 443,
domains: ['secure.example.com', '*.secure.example.com']
},
action: {
type: 'forward',
targets: [
{ host: '10.0.0.10', port: 8080 },
{ host: '10.0.0.11', port: 8080 },
{ host: '10.0.0.12', port: 8080 }
],
tls: {
mode: 'terminate',
certificate: 'auto' // Automatic Let's Encrypt certificate
}
}
}
{
match: {
ports: 443,
domains: 'ws.example.com',
path: '/socket/*'
},
action: {
type: 'forward',
targets: [{ host: 'websocket-server', port: 8080 }],
tls: {
mode: 'terminate',
certificate: 'auto'
},
websocket: {
enabled: true,
pingInterval: 30000,
pingTimeout: 5000
}
}
}
{
match: {
ports: 443,
domains: 'api.example.com',
path: '/v1/*'
},
action: {
type: 'forward',
targets: [{ host: 'api-backend', port: 8080 }],
tls: {
mode: 'terminate',
certificate: 'auto'
},
headers: {
request: {
'X-API-Version': 'v1',
'X-Real-IP': '{clientIp}'
},
response: {
'Access-Control-Allow-Origin': '*',
'X-Powered-By': 'SmartProxy'
}
}
},
security: {
ipAllowList: ['10.0.0.0/8', '172.16.0.0/12'],
rateLimit: {
maxRequests: 100,
windowMs: 60000
},
authentication: {
type: 'basic',
realm: 'API Access',
users: {
'apiuser': 'hashedpassword'
}
}
}
}
SmartProxy includes high-performance kernel-level packet forwarding using Linux NFTables. This provides ultra-low latency forwarding by operating at the kernel level.
nft
command-line tool installed// Basic NFTables forwarding
createNfTablesRoute('fast.example.com', { host: 'backend', port: 8080 }, {
ports: 80,
protocol: 'tcp',
preserveSourceIP: true
})
// NFTables with TLS termination
createNfTablesTerminateRoute('secure-fast.example.com', { host: 'backend', port: 8080 }, {
ports: 443,
certificate: 'auto',
maxRate: '100mbps'
})
SmartProxy supports custom socket handlers for implementing specialized protocols or custom logic:
// Echo server
createSocketHandlerRoute('echo.example.com', 7, SocketHandlers.echo)
// HTTP redirect
createHttpToHttpsRedirect('example.com')
// Line-based protocol
createSocketHandlerRoute('telnet.example.com', 23, SocketHandlers.lineProtocol((line, socket) => {
socket.write(`You said: ${line}\n`);
}))
// HTTP server for custom logic
createSocketHandlerRoute('custom.example.com', 8080, SocketHandlers.httpServer((req, res) => {
if (req.url === '/health') {
res.status(200);
res.send('OK');
} else {
res.status(404);
res.send('Not Found');
}
res.end();
}))
// Block connections
createSocketHandlerRoute('blocked.example.com', 443, SocketHandlers.block('Access Denied'))
// TCP proxy
createSocketHandlerRoute('proxy.example.com', 8080, SocketHandlers.proxy('internal-server', 3000))
{
match: {
ports: 9999,
domains: 'custom.example.com'
},
action: {
type: 'socket-handler',
socketHandler: async (socket, context) => {
console.log(`New connection from ${context.clientIp} to ${context.domain}`);
socket.write('Welcome to the custom protocol server\n');
socket.on('data', (data) => {
// Process incoming data
const command = data.toString().trim();
if (command === 'QUIT') {
socket.end('Goodbye\n');
} else {
socket.write(`Unknown command: ${command}\n`);
}
});
socket.on('error', (err) => {
console.error('Socket error:', err);
});
}
}
}
SmartProxy allows you to dynamically add or remove listening ports without restarting:
// Add a new listening port
await proxy.addListeningPort(8443);
// Remove a listening port
await proxy.removeListeningPort(8080);
// Get all currently listening ports
const ports = proxy.getListeningPorts(); // [80, 443, 8443]
SmartProxy includes automatic certificate management with Let's Encrypt support:
{
action: {
tls: {
mode: 'terminate',
certificate: 'auto' // Automatic Let's Encrypt certificate
}
}
}
{
action: {
tls: {
mode: 'terminate',
certificate: {
key: fs.readFileSync('./certs/private.key', 'utf8'),
cert: fs.readFileSync('./certs/certificate.crt', 'utf8')
}
}
}
}
Certificates are automatically stored and managed:
./certificates/{domain}/
{
security: {
ipAllowList: ['10.0.0.0/8', '192.168.*', '::1'],
ipBlockList: ['192.168.1.100', '10.0.0.0/24']
}
}
{
security: {
maxConnections: 1000, // Total connections
maxConnectionsPerIp: 10 // Per IP address
}
}
{
security: {
rateLimit: {
maxRequests: 100, // Maximum requests
windowMs: 60000 // Time window (1 minute)
}
}
}
// Basic Authentication
{
security: {
authentication: {
type: 'basic',
realm: 'Protected Area',
users: {
'admin': 'hashedpassword'
}
}
}
}
// JWT Authentication
{
security: {
authentication: {
type: 'jwt',
secret: 'your-secret-key',
algorithms: ['HS256']
}
}
}
{
match: {
ports: 443,
customMatcher: async (context) => {
// Custom logic to determine if route should match
const hour = new Date().getHours();
return hour >= 9 && hour < 17; // Only match during business hours
}
}
}
{
action: {
headers: {
request: {
'X-Real-IP': '{clientIp}',
'X-Forwarded-For': '{clientIp}',
'X-Custom-Header': 'value'
},
response: {
'X-Powered-By': 'SmartProxy',
'Strict-Transport-Security': 'max-age=31536000'
}
}
}
}
{
action: {
type: 'forward',
targets: [
{
host: ['backend1.example.com', 'backend2.example.com'], // Round-robin
port: (context) => {
// Dynamic port based on path
return context.path.startsWith('/api/v1') ? 8081 : 8080;
}
}
]
}
}
const proxy = new SmartProxy({
acme: {
email: 'admin@example.com',
useProduction: true
},
routes: [
// HTTPS routes
...['example.com', 'app.example.com', 'api.example.com'].map(domain =>
createHttpsTerminateRoute(domain, { host: 'localhost', port: 3000 }, {
certificate: 'auto'
})
),
// HTTP to HTTPS redirects
createHttpToHttpsRedirect(['example.com', '*.example.com'])
]
});
const proxy = new SmartProxy({
routes: [
// User service
createApiRoute('api.example.com', '/users', { host: 'user-service', port: 8081 }),
// Product service
createApiRoute('api.example.com', '/products', { host: 'product-service', port: 8082 }),
// Order service with authentication
{
match: {
ports: 443,
domains: 'api.example.com',
path: '/orders/*'
},
action: {
type: 'forward',
targets: [{ host: 'order-service', port: 8083 }],
tls: {
mode: 'terminate',
certificate: 'auto'
}
},
security: {
authentication: {
type: 'jwt',
secret: process.env.JWT_SECRET
}
}
}
]
});
const proxy = new SmartProxy({
routes: [
{
match: {
ports: 443,
domains: 'ws.example.com'
},
action: {
type: 'forward',
targets: [
{ host: 'ws-server-1', port: 8080 },
{ host: 'ws-server-2', port: 8080 },
{ host: 'ws-server-3', port: 8080 }
],
tls: {
mode: 'terminate',
certificate: 'auto'
},
websocket: {
enabled: true,
pingInterval: 30000
}
}
}
]
});
Enable detailed logging:
const proxy = new SmartProxy({
debug: true,
routes: [...]
});
Test route matching:
const matchedRoute = proxy.findMatchingRoute({
port: 443,
domain: 'example.com',
path: '/api/users',
clientIp: '192.168.1.100'
});
console.log('Matched route:', matchedRoute?.name);
The main breaking change is the route action configuration:
Before (v19.x):
{
action: {
type: 'forward',
target: { host: 'localhost', port: 8080 } // Single target
}
}
After (v20.x):
{
action: {
type: 'forward',
targets: [{ host: 'localhost', port: 8080 }] // Array of targets
}
}
Helper functions have been updated to use the new format automatically.
proxy.stop()
for clean shutdownclass SmartProxy {
constructor(options: IRoutedSmartProxyOptions);
// Lifecycle methods
start(): Promise<void>;
stop(): Promise<void>;
// Route management
updateRoutes(routes: IRouteConfig[]): Promise<void>;
addRoute(route: IRouteConfig): Promise<void>;
removeRoute(routeName: string): Promise<void>;
findMatchingRoute(context: Partial<IRouteContext>): IRouteConfig | null;
// Port management
addListeningPort(port: number): Promise<void>;
removeListeningPort(port: number): Promise<void>;
getListeningPorts(): number[];
// Certificate management
getCertificateInfo(domain: string): ICertificateInfo | null;
renewCertificate(domain: string): Promise<void>;
// Status and monitoring
getStatus(): IProxyStatus;
getMetrics(): IProxyMetrics;
}
See the TypeScript definitions in:
ts/proxies/smart-proxy/models/route-types.ts
ts/proxies/smart-proxy/models/interfaces.ts
Contributions are welcome! Please follow these guidelines:
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the license file within this repository.
Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
Task Venture Capital GmbH
Registered at District court Bremen HRB 35230 HB, Germany
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
FAQs
A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.
The npm package @push.rocks/smartproxy receives a total of 18 weekly downloads. As such, @push.rocks/smartproxy popularity was classified as not popular.
We found that @push.rocks/smartproxy demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
Two npm packages masquerading as WhatsApp developer libraries include a kill switch that deletes all files if the phone number isn’t whitelisted.
Research
/Security News
Socket uncovered 11 malicious Go packages using obfuscated loaders to fetch and execute second-stage payloads via C2 domains.
Security News
TC39 advances 11 JavaScript proposals, with two moving to Stage 4, bringing better math, binary APIs, and more features one step closer to the ECMAScript spec.