2022-07-29 01:52:34 +02:00
2019-08-20 17:50:17 +02:00
2025-05-03 13:19:23 +00:00
2025-05-01 15:39:20 +00:00

@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

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.
  • Interfaces
    • IPortProxySettings, IDomainConfig (ts/smartproxy/classes.pp.interfaces.ts)
    • INetworkProxyOptions (ts/networkproxy/classes.np.types.ts)
    • IAcmeOptions, IDomainOptions, IForwardConfig (ts/common/types.ts)
    • INfTableProxySettings (ts/nfttablesproxy/classes.nftablesproxy.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';

const smart = new SmartProxy({
  fromPort: 443,
  toPort: 8443,
  domainConfigs: [
    {
      domains: ['example.com', '*.example.com'],
      allowedIPs: ['*'],
      targetIPs: ['127.0.0.1'],
    }
  ],
  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

flowchart TB
    Client([Client])
    
    subgraph "SmartProxy Components"
        direction TB
        HTTP80["HTTP Port 80<br>Redirect / SslRedirect"]
        HTTPS443["HTTPS Port 443<br>NetworkProxy"]
        SmartProxy["SmartProxy<br>(TCP/SNI Proxy)"]
        NfTables[NfTablesProxy]
        Router[ProxyRouter]
        ACME["Port80Handler<br>(ACME HTTP-01)"]
        Certs[(SSL Certificates)]
    end
    
    subgraph "Backend Services"
        Service1[Service 1]
        Service2[Service 2]
        Service3[Service 3]
    end
    
    Client -->|HTTP Request| HTTP80
    HTTP80 -->|Redirect| Client
    Client -->|HTTPS Request| HTTPS443
    Client -->|TLS/TCP| SmartProxy
    
    HTTPS443 -->|Route Request| Router
    Router -->|Proxy Request| Service1
    Router -->|Proxy Request| Service2
    
    SmartProxy -->|Direct TCP| Service2
    SmartProxy -->|Direct TCP| Service3
    
    NfTables -.->|Low-level forwarding| SmartProxy
    
    HTTP80 -.->|Challenge Response| ACME
    ACME -.->|Generate/Manage| Certs
    Certs -.->|Provide TLS Certs| HTTPS443
    
    classDef component fill:#f9f,stroke:#333,stroke-width:2px;
    classDef backend fill:#bbf,stroke:#333,stroke-width:1px;
    classDef client fill:#dfd,stroke:#333,stroke-width:2px;
    
    class Client client;
    class HTTP80,HTTPS443,SmartProxy,NfTables,Router,ACME component;
    class Service1,Service2,Service3 backend;

HTTPS Reverse Proxy Flow

This diagram shows how HTTPS requests are handled and proxied to backend services:

sequenceDiagram
    participant Client
    participant NetworkProxy
    participant ProxyRouter
    participant Backend
    
    Client->>NetworkProxy: HTTPS Request
    
    Note over NetworkProxy: TLS Termination
    
    NetworkProxy->>ProxyRouter: Route Request
    ProxyRouter->>ProxyRouter: Match hostname to config
    
    alt Authentication Required
        NetworkProxy->>Client: Request Authentication
        Client->>NetworkProxy: Send Credentials
        NetworkProxy->>NetworkProxy: Validate Credentials
    end
    
    NetworkProxy->>Backend: Forward Request
    Backend->>NetworkProxy: Response
    
    Note over NetworkProxy: Add Default Headers
    
    NetworkProxy->>Client: Forward Response
    
    alt WebSocket Request
        Client->>NetworkProxy: Upgrade to WebSocket
        NetworkProxy->>Backend: Upgrade to WebSocket
        loop WebSocket Active
            Client->>NetworkProxy: WebSocket Message
            NetworkProxy->>Backend: Forward Message
            Backend->>NetworkProxy: WebSocket Message
            NetworkProxy->>Client: Forward Message
            NetworkProxy-->>NetworkProxy: Heartbeat Check
        end
    end

SNI-based Connection Handling

This diagram illustrates how TCP connections with SNI (Server Name Indication) are processed and forwarded:

sequenceDiagram
    participant Client
    participant SmartProxy
    participant Backend
    
    Client->>SmartProxy: TLS Connection
    
    alt SNI Enabled
        SmartProxy->>Client: Accept Connection
        Client->>SmartProxy: TLS ClientHello with SNI
        SmartProxy->>SmartProxy: Extract SNI Hostname
        SmartProxy->>SmartProxy: Match Domain Config
        SmartProxy->>SmartProxy: Validate Client IP
        
        alt IP Allowed
            SmartProxy->>Backend: Forward Connection
            Note over SmartProxy,Backend: Bidirectional Data Flow
        else IP Rejected
            SmartProxy->>Client: Close Connection
        end
    else Port-based Routing
        SmartProxy->>SmartProxy: Match Port Range
        SmartProxy->>SmartProxy: Find Domain Config
        SmartProxy->>SmartProxy: Validate Client IP
        
        alt IP Allowed
            SmartProxy->>Backend: Forward Connection
            Note over SmartProxy,Backend: Bidirectional Data Flow
        else IP Rejected
            SmartProxy->>Client: Close Connection
        end
    end
    
    loop Connection Active
        SmartProxy-->>SmartProxy: Monitor Activity
        SmartProxy-->>SmartProxy: Check Max Lifetime
        alt Inactivity or Max Lifetime Exceeded
            SmartProxy->>Client: Close Connection
            SmartProxy->>Backend: Close Connection
        end
    end

Let's Encrypt Certificate Acquisition

This diagram shows how certificates are automatically acquired through the ACME protocol:

sequenceDiagram
    participant Client
    participant Port80Handler
    participant ACME as Let's Encrypt ACME
    participant NetworkProxy
    
    Client->>Port80Handler: HTTP Request for domain
    
    alt Certificate Exists
        Port80Handler->>Client: Redirect to HTTPS
    else No Certificate
        Port80Handler->>Port80Handler: Mark domain as obtaining cert
        Port80Handler->>ACME: Create account & new order
        ACME->>Port80Handler: Challenge information
        
        Port80Handler->>Port80Handler: Store challenge token & key authorization
        
        ACME->>Port80Handler: HTTP-01 Challenge Request
        Port80Handler->>ACME: Challenge Response
        
        ACME->>ACME: Validate domain ownership
        ACME->>Port80Handler: Challenge validated
        
        Port80Handler->>Port80Handler: Generate CSR
        Port80Handler->>ACME: Submit CSR
        ACME->>Port80Handler: Issue Certificate
        
        Port80Handler->>Port80Handler: Store certificate & private key
        Port80Handler->>Port80Handler: Mark certificate as obtained
        
        Note over Port80Handler,NetworkProxy: Certificate available for use
        
        Client->>Port80Handler: Another HTTP Request
        Port80Handler->>Client: Redirect to HTTPS
        Client->>NetworkProxy: HTTPS Request
        Note over NetworkProxy: Uses new certificate
    end

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 certProvider(domain) in SmartProxy settings to supply static certs or return 'http01'.

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[])
  • sniEnabled, defaultAllowedIPs, preserveSourceIP (booleans)
  • Timeouts: initialDataTimeout, socketTimeout, inactivityTimeout, etc.
  • Socket opts: noDelay, keepAlive, enableKeepAliveProbes
  • acme (IAcmeOptions), certProvider (callback)
  • useNetworkProxy (number[]), networkProxyPort (number)

Troubleshooting

NetworkProxy

  • Verify ports, certificates and rejectUnauthorized for TLS errors
  • Configure CORS or use addDefaultHeaders for preflight issues
  • Increase maxConnections or connectionPoolSize 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

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.

Description
a proxy for handling high workloads of proxying
Readme 6.5 MiB
Languages
TypeScript 100%