A lightweight reverse proxy with IP whitelisting for accessing private services in AWS and GCP VPCs.
HTTP reverse proxy and raw TCP proxy that forward traffic from whitelisted IPs to private backend services. Perfect for accessing databases, caches, APIs, or staging environments in private subnets without VPNs or complex networking.
Your IP → Proxify (Public) → Private Service (VPC)
Supports HTTP(S) backends and raw TCP backends (e.g. Redis / ElastiCache, including TLS upstream for ElastiCache Serverless).
Access private RDS/Cloud SQL - Connect to databases in private subnets from your local machine
Expose internal APIs - Give partners/services access to specific internal endpoints
Dev/staging access - Let developers reach staging environments without opening security groups to the world
Cross-region/cloud bridge - Connect services across VPCs or cloud providers
- Go 1.23 or later
- Access to a VPC network (AWS VPC or GCP VPC)
- A virtual machine with network access to your target service
- Clone and build:
git clone <repository-url>
cd proxify
go build -o proxify server.go- Configure environment variables:
cp .env.example .env
# Edit .env with your settings- Set your target and whitelist:
# .env file
TARGET=http://your-private-service:8080
WHITELIST=203.0.113.0/24,198.51.100.45- Run the proxy:
./proxifyThe proxy will start on port 8888 and forward requests to your target.
| Variable | Required | Description | Example |
|---|---|---|---|
TARGET |
One of | HTTP backend URL (enables HTTP proxy on :8888) |
http://10.0.1.50:3000 |
REDIS_TARGET |
One of | TCP backend host:port (enables TCP proxy) |
sticky-xxx.serverless.euw2.cache.amazonaws.com:6379 |
REDIS_TLS |
No | Set to true to dial upstream over TLS (required for ElastiCache Serverless) |
true |
REDIS_LISTEN |
No | Listen address for the TCP proxy (default :6379) |
:6380 |
WHITELIST |
No | Comma-separated list of allowed IPs/CIDRs | 192.168.1.0/24,10.0.0.5 |
At least one of TARGET or REDIS_TARGET must be set. Both can run simultaneously.
REDIS_TARGET=sticky-tyyqxu.serverless.euw2.cache.amazonaws.com:6379
REDIS_TLS=true
WHITELIST=203.0.113.0/24Then connect from a whitelisted machine:
redis-cli -h <proxify-host> -p 6379 --user <iam-user> --pass <token>The client still needs valid ElastiCache credentials — proxify forwards bytes only, it does not authenticate on your behalf.
Deployment note: AWS App Runner only exposes a single HTTP port, so the TCP listener will not be reachable there. For Redis/TCP proxying, deploy on EC2, Compute Engine, or behind an NLB.
The whitelist supports both individual IPs and CIDR notation:
# Individual IPs
WHITELIST=203.0.113.45,198.51.100.67
# CIDR ranges
WHITELIST=10.0.0.0/8,172.16.0.0/12
# Mixed
WHITELIST=203.0.113.0/24,198.51.100.45,192.168.1.100If WHITELIST is not set, all IPs are allowed (not recommended for production).
The easiest way to deploy on AWS - fork this repo and deploy directly to App Runner.
-
Fork this repository to your GitHub account
-
Create VPC Connector:
- Go to App Runner → VPC connectors → Create VPC connector
- Select your VPC and private subnets where your target service lives
- Select a security group that allows outbound access to your target
-
Create App Runner Service:
- Go to App Runner → Services → Create service
- Source: Source code repository → GitHub
- Connect to GitHub and select your forked repo
- Branch:
main - Build settings:
- Runtime: Go
- Build command:
go build -o proxify server.go - Start command:
./proxify - Port:
8888
- Add environment variables:
TARGET:http://10.0.1.50:3000(your private service)WHITELIST:203.0.113.0/24(your allowed IPs)
- Networking: Select your VPC connector
- Create service
-
App Runner provides an HTTPS URL like
https://xyz.region.awsapprunner.com
Benefits: No server management, automatic scaling, built-in HTTPS, pay only for usage
- Create a Compute Engine instance with external IP
- Configure firewall rules:
- Allow ingress on port 8888 from whitelisted IPs
- Allow egress to target service
- Deploy Proxify
# Example: Access Cloud SQL via private IP
TARGET=http://10.128.0.50:3306
WHITELIST=198.51.100.0/24FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o proxify server.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/proxify .
EXPOSE 8888
CMD ["./proxify"]docker build -t proxify .
docker run -p 8888:8888 \
-e TARGET=http://10.0.1.50:8080 \
-e WHITELIST=203.0.113.0/24 \
proxify- Always use a whitelist in production - Running without a whitelist exposes your backend to the internet
- Use HTTPS for sensitive data - Consider placing Proxify behind a TLS-terminating load balancer
- Keep the whitelist minimal - Only add IPs that absolutely need access
- Monitor logs - Track access patterns and unauthorized attempts
- Network security - Ensure your target service's security groups only allow traffic from the Proxify instance
Proxify logs all requests in the format:
2024/10/17 12:34:56 GET /api/users
2024/10/17 12:34:57 POST /api/orders
Forbidden requests (non-whitelisted IPs) return HTTP 403 but are not logged by default.
- AWS VPN / GCP Cloud VPN: Better for multiple users needing access to many resources
- Bastion Host: Better for SSH/RDP access to instances
- AWS PrivateLink / VPC Peering: Better for high-volume, production-grade service-to-service communication
- Proxify: Best for simple, low-volume HTTP access with IP-based access control