Skip to content

txn2/portpxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

portPxy

An HTTP reverse proxy that routes requests to backend ports specified in the URL path.

Overview

portPxy extracts a port number from the first segment of the request path and proxies the request to that port on a backend host. For example, a request to /8081/api/endpoint is forwarded to backend:8081/api/endpoint.

This solves the problem of dynamically exposing multiple backend ports through a single proxy endpoint, particularly useful in Kubernetes environments where applications create HTTP listeners on various ports at runtime.

Use Case

Applications like Apache NiFi allow users to configure HTTP listeners on arbitrary ports at runtime (e.g., ListenHTTP processors, webhook receivers). In Kubernetes, these dynamic ports cannot be easily exposed through standard Service or Ingress configurations without constant reconfiguration.

portPxy provides a single ingress endpoint that routes to backend ports based on the URL path:

  • External request: https://app.example.com/8081/webhook
  • Ingress routes to portPxy on port 8080
  • portPxy proxies to backend:8081/webhook

How It Works

  1. Extract port from the first path segment (e.g., /8081/path → port 8081)
  2. Validate port is within the allowed range
  3. Proxy request to BACKEND_PROTO://BACKEND_HOST:8081/path
  4. Return backend response to client

The proxy records Prometheus metrics and structured logs for each request.

Configuration

All settings are configured via environment variables or command-line flags:

Variable Flag Default Description
IP -ip 127.0.0.1 Server bind address
PORT -port 8080 Proxy server port
METRICS_PORT -metricsPort 2112 Prometheus metrics port
DEBUG -debug false Enable debug logging
BACKEND_HOST -backendHost httpbin.org Target backend hostname
BACKEND_PROTO -backendProto https Backend protocol (http/https)
ALLOW_PORT_BEGIN -allowRangeBegin 443 Start of allowed port range
ALLOW_PORT_END -allowRangeEnd 443 End of allowed port range

Usage

Binary

# Build
go build -o portpxy ./cmd/portpxy.go

# Run with defaults (proxies to httpbin.org:443)
./portpxy

# Run with custom backend
./portpxy -ip=0.0.0.0 -backendHost=localhost -backendProto=http -allowRangeBegin=8080 -allowRangeEnd=8090

# Or use environment variables
IP=0.0.0.0 BACKEND_HOST=localhost BACKEND_PROTO=http ALLOW_PORT_BEGIN=8080 ALLOW_PORT_END=8090 ./portpxy

Docker

# Run with Docker
docker run --rm -p 8080:8080 -e IP=0.0.0.0 txn2/portpxy:latest

# Custom configuration
docker run --rm -p 8080:8080 \
  -e IP=0.0.0.0 \
  -e BACKEND_HOST=localhost \
  -e BACKEND_PROTO=http \
  -e ALLOW_PORT_BEGIN=8080 \
  -e ALLOW_PORT_END=8090 \
  txn2/portpxy:latest

Kubernetes Sidecar

Deploy as a sidecar container alongside your application:

apiVersion: v1
kind: Pod
metadata:
  name: app-with-proxy
spec:
  containers:
  - name: app
    image: your-app:latest
    # Application creates listeners on ports 8080-8090

  - name: portpxy
    image: txn2/portpxy:latest
    ports:
    - containerPort: 8080
      name: proxy
    - containerPort: 2112
      name: metrics
    env:
    - name: IP
      value: "0.0.0.0"
    - name: BACKEND_HOST
      value: "localhost"
    - name: BACKEND_PROTO
      value: "http"
    - name: ALLOW_PORT_BEGIN
      value: "8080"
    - name: ALLOW_PORT_END
      value: "8090"

Testing

# Start the proxy with local backend
IP=0.0.0.0 BACKEND_HOST=localhost BACKEND_PROTO=http ALLOW_PORT_BEGIN=8080 ALLOW_PORT_END=8090 ./portpxy

# In another terminal, start a test server on port 8081
python3 -m http.server 8081

# Test proxying
curl http://localhost:8080/8081/

# Test port validation (should return error)
curl http://localhost:8080/9999/

# Check metrics
curl http://localhost:2112/metrics

Metrics

Prometheus metrics are exposed on the metrics port (default 2112):

  • portpxy_total_requests: Total number of requests processed
  • portpxy_response_time: Request latency distribution

Security

The ALLOW_PORT_BEGIN and ALLOW_PORT_END settings restrict which ports can be proxied. This prevents unauthorized access to arbitrary ports on the backend host. Configure these values to match your application's port range.

Development

Build

go build -o portpxy ./cmd/portpxy.go

Test Release

goreleaser --skip-publish --rm-dist --skip-validate

Release

GITHUB_TOKEN=$GITHUB_TOKEN goreleaser --rm-dist

License

MIT

About

HTTP proxy to a port specified on the request path

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors