@push.rocks/smartproxy
A high-performance proxy toolkit for Node.js, offering:
- HTTP/HTTPS reverse proxy with TLS termination and WebSocket support
- Automatic ACME certificate management (HTTP-01)
- Low-level port forwarding via nftables
- HTTP-to-HTTPS and custom URL redirects
- Advanced TCP/SNI-based proxying with IP filtering and rules
- Unified forwarding configuration system for all proxy types
Exports
The following classes and interfaces are provided:
- NetworkProxy (ts/networkproxy/classes.np.networkproxy.ts) HTTP/HTTPS reverse proxy with TLS termination, WebSocket support, connection pooling, and optional ACME integration.
- Port80Handler (ts/port80handler/classes.port80handler.ts) ACME HTTP-01 challenge handler and certificate manager.
- NfTablesProxy (ts/nfttablesproxy/classes.nftablesproxy.ts) Low-level port forwarding using nftables NAT rules.
- Redirect, SslRedirect (ts/redirect/classes.redirect.ts) HTTP/HTTPS redirect server and shortcut for HTTP→HTTPS.
- SmartProxy (ts/smartproxy/classes.smartproxy.ts) TCP/SNI-based proxy with dynamic routing, IP filtering, and unified certificates.
- SniHandler (ts/smartproxy/classes.pp.snihandler.ts) Static utilities to extract SNI hostnames from TLS handshakes.
- Forwarding Handlers (ts/smartproxy/forwarding/*.ts) Unified forwarding handlers for different connection types (HTTP, HTTPS passthrough, TLS termination).
- Interfaces
- IPortProxySettings, IDomainConfig (ts/smartproxy/classes.pp.interfaces.ts)
- INetworkProxyOptions (ts/networkproxy/classes.np.types.ts)
- IAcmeOptions, IDomainOptions (ts/common/types.ts)
- INfTableProxySettings (ts/nfttablesproxy/classes.nftablesproxy.ts)
- IForwardConfig, ForwardingType (ts/smartproxy/types/forwarding.types.ts)
Installation
Install via npm:
npm install @push.rocks/smartproxy
Quick Start
1. HTTP(S) Reverse Proxy (NetworkProxy)
import { NetworkProxy } from '@push.rocks/smartproxy';
const proxy = new NetworkProxy({ port: 443 });
await proxy.start();
await proxy.updateProxyConfigs([
{
hostName: 'example.com',
destinationIps: ['127.0.0.1'],
destinationPorts: [3000],
publicKey: fs.readFileSync('cert.pem', 'utf8'),
privateKey: fs.readFileSync('key.pem', 'utf8'),
}
]);
// Add default headers to all responses
await proxy.addDefaultHeaders({
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'
});
// ...
await proxy.stop();
2. HTTP→HTTPS Redirect (Redirect / SslRedirect)
import { Redirect, SslRedirect } from '@push.rocks/smartproxy';
import * as fs from 'fs';
// Custom redirect rules
const redirect = new Redirect({
httpPort: 80,
httpsPort: 443,
sslOptions: {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
},
rules: [
{
fromProtocol: 'http',
fromHost: '*',
toProtocol: 'https',
toHost: '$1',
statusCode: 301
}
]
});
await redirect.start();
// Quick HTTP→HTTPS helper on port 80
const quick = new SslRedirect(80);
await quick.start();
3. Automatic Certificates (ACME Port80Handler)
import { Port80Handler } from '@push.rocks/smartproxy';
// Configure ACME on port 80 with contact email
const acme = new Port80Handler({
port: 80,
contactEmail: 'admin@example.com',
useProduction: true,
renewThresholdDays: 30
});
acme.on('certificate-issued', evt => {
console.log(`Certificate ready for ${evt.domain}, expires ${evt.expiryDate}`);
});
await acme.start();
acme.addDomain({
domainName: 'example.com',
sslRedirect: true,
acmeMaintenance: true
});
4. Low-Level Port Forwarding (NfTablesProxy)
import { NfTablesProxy } from '@push.rocks/smartproxy';
// Forward port 80→8080 with source IP preservation
const nft = new NfTablesProxy({
fromPort: 80,
toPort: 8080,
toHost: 'localhost',
preserveSourceIP: true,
deleteOnExit: true
});
await nft.start();
// ...
await nft.stop();
5. TCP/SNI Proxy (SmartProxy)
import { SmartProxy } from '@push.rocks/smartproxy';
import { createDomainConfig, httpOnly, tlsTerminateToHttp, httpsPassthrough } from '@push.rocks/smartproxy';
const smart = new SmartProxy({
fromPort: 443,
toPort: 8443,
domainConfigs: [
// HTTPS passthrough example
createDomainConfig(['example.com', '*.example.com'],
httpsPassthrough({
target: {
host: '127.0.0.1',
port: 443
},
security: {
allowedIps: ['*']
}
})
),
// HTTPS termination example
createDomainConfig('secure.example.com',
tlsTerminateToHttp({
target: {
host: 'localhost',
port: 3000
},
acme: {
enabled: true,
production: true
}
})
)
],
sniEnabled: true
});
smart.on('certificate', evt => console.log(evt));
await smart.start();
// Update domains later
await smart.updateDomainConfigs([/* new configs */]);
6. SNI Utilities (SniHandler)
import { SniHandler } from '@push.rocks/smartproxy';
// Extract SNI from a TLS ClientHello buffer
const sni = SniHandler.extractSNI(buffer);
// Reassemble fragmented ClientHello
const complete = SniHandler.handleFragmentedClientHello(buf, connId);
API Reference
For full configuration options and type definitions, see the TypeScript interfaces in the ts/
directory:
INetworkProxyOptions
(ts/networkproxy/classes.np.types.ts)IAcmeOptions
,IDomainOptions
,IForwardConfig
(ts/common/types.ts)INfTableProxySettings
(ts/nfttablesproxy/classes.nftablesproxy.ts)IPortProxySettings
,IDomainConfig
(ts/smartproxy/classes.pp.interfaces.ts)
Architecture & Flow Diagrams
HTTPS Reverse Proxy Flow
This diagram shows how HTTPS requests are handled and proxied to backend services:
SNI-based Connection Handling
This diagram illustrates how TCP connections with SNI (Server Name Indication) are processed and forwarded:
Let's Encrypt Certificate Acquisition
This diagram shows how certificates are automatically acquired through the ACME protocol:
Features
-
HTTP/HTTPS Reverse Proxy (NetworkProxy) • TLS termination, virtual-host routing, HTTP/2 & WebSocket support, pooling & metrics
-
Automatic ACME Certificates (Port80Handler) • HTTP-01 challenge handling, certificate issuance/renewal, pluggable storage
-
Low-Level Port Forwarding (NfTablesProxy) • nftables NAT rules for ports/ranges, IPv4/IPv6, IP filtering, QoS & ipset support
-
Custom Redirects (Redirect / SslRedirect) • URL redirects with wildcard host/path, template variables & status codes
-
TCP/SNI Proxy (SmartProxy) • SNI-based routing, IP allow/block lists, port ranges, timeouts & graceful shutdown
-
SNI Utilities (SniHandler) • Robust ClientHello parsing, fragmentation & session resumption support
Certificate Hooks & Events
Listen for certificate events via EventEmitter:
- Port80Handler:
certificate-issued
,certificate-renewed
,certificate-failed
manager-started
,manager-stopped
,request-forwarded
- SmartProxy:
certificate
(domain, publicKey, privateKey, expiryDate, source, isRenewal)
Provide a certProvisionFunction(domain)
in SmartProxy settings to supply static certs or return 'http01'
.
Unified Forwarding System
The SmartProxy Unified Forwarding System provides a clean, use-case driven approach to configuring different types of traffic forwarding. It replaces disparate configuration mechanisms with a unified interface.
Forwarding Types
The system supports four primary forwarding types:
- HTTP-only (
http-only
): Forwards HTTP traffic to a backend server. - HTTPS Passthrough (
https-passthrough
): Passes through raw TLS traffic without termination (SNI forwarding). - HTTPS Termination to HTTP (
https-terminate-to-http
): Terminates TLS and forwards the decrypted traffic to an HTTP backend. - HTTPS Termination to HTTPS (
https-terminate-to-https
): Terminates TLS and creates a new TLS connection to an HTTPS backend.
Basic Configuration
Each domain is configured with a forwarding type and target:
{
domains: ['example.com'],
forwarding: {
type: 'http-only',
target: {
host: 'localhost',
port: 3000
}
}
}
Helper Functions
Helper functions are provided for common configurations:
import { createDomainConfig, httpOnly, tlsTerminateToHttp,
tlsTerminateToHttps, httpsPassthrough } from '@push.rocks/smartproxy';
// HTTP-only
await domainManager.addDomainConfig(
createDomainConfig('example.com', httpOnly({
target: { host: 'localhost', port: 3000 }
}))
);
// HTTPS termination to HTTP
await domainManager.addDomainConfig(
createDomainConfig('secure.example.com', tlsTerminateToHttp({
target: { host: 'localhost', port: 3000 },
acme: { production: true }
}))
);
// HTTPS termination to HTTPS
await domainManager.addDomainConfig(
createDomainConfig('api.example.com', tlsTerminateToHttps({
target: { host: 'internal-api', port: 8443 },
http: { redirectToHttps: true }
}))
);
// HTTPS passthrough (SNI)
await domainManager.addDomainConfig(
createDomainConfig('passthrough.example.com', httpsPassthrough({
target: { host: '10.0.0.5', port: 443 }
}))
);
Advanced Configuration
For more complex scenarios, additional options can be specified:
{
domains: ['api.example.com'],
forwarding: {
type: 'https-terminate-to-https',
target: {
host: ['10.0.0.10', '10.0.0.11'], // Round-robin load balancing
port: 8443
},
http: {
enabled: true,
redirectToHttps: true
},
https: {
// Custom certificate instead of ACME-provisioned
customCert: {
key: '-----BEGIN PRIVATE KEY-----\n...',
cert: '-----BEGIN CERTIFICATE-----\n...'
}
},
security: {
allowedIps: ['10.0.0.*', '192.168.1.*'],
blockedIps: ['1.2.3.4'],
maxConnections: 100
},
advanced: {
timeout: 30000,
headers: {
'X-Forwarded-For': '{clientIp}',
'X-Original-Host': '{sni}'
}
}
}
}
Extended Configuration Options
IForwardConfig
type
: 'http-only' | 'https-passthrough' | 'https-terminate-to-http' | 'https-terminate-to-https'target
: { host: string | string[], port: number }http?
: { enabled?: boolean, redirectToHttps?: boolean, headers?: Record<string, string> }https?
: { customCert?: { key: string, cert: string }, forwardSni?: boolean }acme?
: { enabled?: boolean, maintenance?: boolean, production?: boolean, forwardChallenges?: { host: string, port: number, useTls?: boolean } }security?
: { allowedIps?: string[], blockedIps?: string[], maxConnections?: number }advanced?
: { portRanges?: Array<{ from: number, to: number }>, networkProxyPort?: number, keepAlive?: boolean, timeout?: number, headers?: Record<string, string> }
Configuration Options
NetworkProxy (INetworkProxyOptions)
port
(number, required)backendProtocol
('http1'|'http2', default 'http1')maxConnections
(number, default 10000)keepAliveTimeout
(ms, default 120000)headersTimeout
(ms, default 60000)cors
(object)connectionPoolSize
(number, default 50)logLevel
('error'|'warn'|'info'|'debug')acme
(IAcmeOptions)useExternalPort80Handler
(boolean)portProxyIntegration
(boolean)
Port80Handler (IAcmeOptions)
enabled
(boolean, default true)port
(number, default 80)contactEmail
(string)useProduction
(boolean, default false)renewThresholdDays
(number, default 30)autoRenew
(boolean, default true)certificateStore
(string)skipConfiguredCerts
(boolean)domainForwards
(IDomainForwardConfig[])
NfTablesProxy (INfTableProxySettings)
fromPort
/toPort
(number|range|array)toHost
(string, default 'localhost')preserveSourceIP
,deleteOnExit
,protocol
,enableLogging
,ipv6Support
(booleans)allowedSourceIPs
,bannedSourceIPs
(string[])useIPSets
(boolean, default true)qos
,netProxyIntegration
(objects)
Redirect / SslRedirect
- Constructor options:
httpPort
,httpsPort
,sslOptions
,rules
(RedirectRule[])
SmartProxy (IPortProxySettings)
fromPort
,toPort
(number)domainConfigs
(IDomainConfig[]) - Using unified forwarding configurationsniEnabled
,preserveSourceIP
(booleans)defaultAllowedIPs
,defaultBlockedIPs
(string[]) - Default IP allowlists/blocklists- Timeouts:
initialDataTimeout
,socketTimeout
,inactivityTimeout
, etc. - Socket opts:
noDelay
,keepAlive
,enableKeepAliveProbes
acme
(IAcmeOptions),certProvisionFunction
(callback)useNetworkProxy
(number[]),networkProxyPort
(number)globalPortRanges
(Array<{ from: number; to: number }>)
Troubleshooting
NetworkProxy
- Verify ports, certificates and
rejectUnauthorized
for TLS errors - Configure CORS or use
addDefaultHeaders
for preflight issues - Increase
maxConnections
orconnectionPoolSize
under load
Port80Handler
- Run as root or grant CAP_NET_BIND_SERVICE for port 80
- Inspect
certificate-failed
events and switch staging/production
NfTablesProxy
- Ensure
nft
is installed and run with sufficient privileges - Use
forceCleanSlate:true
to clear conflicting rules
Redirect / SslRedirect
- Check
fromHost
/fromPath
patterns and Host headers - Validate
sslOptions
key/cert correctness
SmartProxy & SniHandler
- Increase
initialDataTimeout
/maxPendingDataSize
for large ClientHello - Enable
enableTlsDebugLogging
to trace handshake - Ensure
allowSessionTicket
and fragmentation support for resumption - Double-check forwarding configuration to ensure correct
type
for your use case - Use helper functions like
httpOnly()
,httpsPassthrough()
, etc. to create correct configurations - For IP filtering issues, check the
security.allowedIps
andsecurity.blockedIps
settings
License and Legal Information
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.
Trademarks
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.
Company Information
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.