A macOS command-line tool that creates transparent system-level routing for specified CIDR blocks through an AWS EC2 instance via SSM Session Manager. Applications require zero configuration - traffic is automatically routed based on destination IP address.
Architecture: Uses TUN device + SSH tunnel over SSM + internal SOCKS5 proxy (invisible to apps). See Architecture Guide for details.
- β Zero Application Configuration - Works transparently with all applications
- β No VPN Client - Uses AWS SSM infrastructure
- β No SSH Keys - Leverages AWS IAM authentication
- β Secure & Auditable - All traffic logged via AWS CloudTrail
- β Simple UX - One command to start, applications just work
- β Multiple CIDR Blocks - Route multiple networks simultaneously
- β Auto-Reconnect - Automatic reconnection on connection failures
- β Session Management - Track and manage multiple concurrent sessions
- Access RDS databases in private subnets
- Connect to ElastiCache Redis clusters
- Reach internal APIs and services
- Access multiple AWS resources without VPN
- Development/debugging in private VPCs
- Temporary access to AWS resources
- macOS 11.0 (Big Sur) or later
- Root/sudo privileges (for network configuration)
- AWS credentials configured (
~/.aws/credentialsor environment variables)
- EC2 instance running in your VPC (bastion/jump host)
- EC2 instance with SSM Agent installed and running
- EC2 instance with IAM role:
AmazonSSMManagedInstanceCore - EC2 instance with IP forwarding enabled:
sudo sysctl -w net.ipv4.ip_forward=1 - VPC with SSM endpoints OR NAT Gateway/Internet Gateway
Your IAM user/role needs:
ssm:StartSessionssm:TerminateSessionec2:DescribeInstances
- Quick Start Guide - Get started in 5 minutes
- Architecture Guide - How transparent proxy works
- Specification - Complete feature specification
# Install mise https://mise.jdx.dev/
mise use --global github:sbkg0002/ssm-proxygit clone https://github.com/sbkg0002/ssm-proxy.git
cd ssm-proxy
make build
sudo make install# Route 10.0.0.0/8 through EC2 instance
sudo -E ssm-proxy start \
--instance-id i-1234567890abcdef0 \
--cidr 10.0.0.0/8# Database - NO PROXY CONFIGURATION NEEDED!
e.g. psql -h 10.0.1.5 -p 5432 mydbsudo -E ssm-proxy stop# Basic usage
sudo -E ssm-proxy start --instance-id i-xxx --cidr 10.0.0.0/8
# Multiple CIDR blocks
sudo -E ssm-proxy start \
--instance-id i-xxx \
--cidr 10.0.0.0/8 \
--cidr 172.16.0.0/12
# Find instance by tag
sudo -E ssm-proxy start \
--instance-tag Name=bastion-host \
--cidr 10.0.0.0/16
# Custom AWS profile and region
sudo -E ssm-proxy start \
--profile production \
--region us-west-2 \
--instance-id i-xxx \
--cidr 10.0.0.0/8
# Run as daemon (background)
sudo -E ssm-proxy start \
--instance-id i-xxx \
--cidr 10.0.0.0/8 \
--daemon# Show active sessions
ssm-proxy status
# JSON output
ssm-proxy status --json
# Watch mode (live updates)
ssm-proxy status --watch
# Detailed output with routes and stats
ssm-proxy status --show-routes --show-stats# List all running instances
ssm-proxy list-instances
# Filter by tag
ssm-proxy list-instances --tag Environment=production
# Only show SSM-ready instances
ssm-proxy list-instances --ssm-only# Stop default session
sudo -E ssm-proxy stop
# Stop specific session
sudo -E ssm-proxy stop --session-name my-session
# Stop all sessions
sudo -E ssm-proxy stop --all# Test TCP connectivity
ssm-proxy test 10.0.1.5:5432
# Test with custom timeout
ssm-proxy test --timeout 30s 10.0.2.100:8080Create ~/.ssm-proxy/config.yaml:
# AWS Configuration
aws:
profile: default
region: us-east-1
# Default Settings
defaults:
local_ip: 169.254.169.1/30
mtu: 1500
keep_alive: 30s
timeout: 30s
auto_reconnect: true
reconnect_delay: 5s
max_retries: 0 # 0 = unlimited
# Logging
logging:
level: info # debug, info, warn, error
file: ~/.ssm-proxy/logs/ssm-proxy.log
# Named Profiles for Quick Access
profiles:
prod:
instance_id: i-1234567890abcdef0
cidr:
- 10.0.0.0/8
session_name: prod-vpc
dev:
instance_tag: Environment=dev,Role=bastion
cidr:
- 172.16.0.0/12
session_name: dev-vpc# Start using named profile
sudo -E ssm-proxy start --profile-name prod
# Override profile settings
sudo -E ssm-proxy start --profile-name prod --cidr 10.0.0.0/16Your EC2 instance needs the following configuration:
# Amazon Linux 2 / Amazon Linux 2023 (pre-installed)
sudo systemctl status amazon-ssm-agent
# Ubuntu
sudo snap install amazon-ssm-agent --classic
sudo snap start amazon-ssm-agentsudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.confAttach the AWS managed policy AmazonSSMManagedInstanceCore to the instance's IAM role, or create a custom policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:UpdateInstanceInformation",
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}Ensure outbound HTTPS (443) is allowed to SSM endpoints.
Application (psql, curl, etc.)
β (no configuration needed)
macOS Routing Table (10.0.0.0/8 β utun2)
β
utun2 (virtual network interface)
β
TUN-to-SOCKS Translator (user-space TCP/IP stack)
β (internal SOCKS5 - apps don't see this!)
SSH Tunnel (-D dynamic forwarding)
β (encrypted over SSM WebSocket)
AWS SSM Session Manager
β
EC2 Instance (bastion with IP forwarding)
β
Target Resources (RDS, Redis, etc.)
Key Innovation: Applications connect normally to private IPs. The TUN device captures packets, translates them to SOCKS5 connections internally (invisible to apps), and forwards through an SSH tunnel over SSM.
π Read the detailed architecture guide to understand how this achieves true transparency.
# Solution: Run with sudo
sudo -E ssm-proxy start --instance-id i-xxx --cidr 10.0.0.0/8# Check SSM Agent status on EC2 instance
sudo systemctl status amazon-ssm-agent
# Verify IAM role has AmazonSSMManagedInstanceCore policy
# Check VPC has connectivity to SSM endpoints# Ensure running with sudo
# Check macOS security settings (System Preferences β Security)
# Restart and try again# Another session may be using same CIDR
ssm-proxy status
# Clean up stale routes
sudo -E ssm-proxy routes cleanup
# Or stop conflicting session
sudo -E ssm-proxy stop --allsudo -E ssm-proxy start --debug --instance-id i-xxx --cidr 10.0.0.0/8# View routing table
netstat -rn | grep utun
# Verify specific route
route get 10.0.1.5sudo -E ssm-proxy start --instance-id i-xxx --cidr 10.0.0.0/16
# PostgreSQL
psql -h mydb.abc.us-east-1.rds.amazonaws.com -p 5432 -U admin myapp
# MySQL
mysql -h mydb.abc.us-east-1.rds.amazonaws.com -P 3306 -u admin -psudo -E ssm-proxy start --instance-id i-xxx --cidr 10.0.0.0/8
redis-cli -h master.abc.cache.amazonaws.com -p 6379# Route entire VPC CIDR
sudo -E ssm-proxy start --instance-id i-xxx --cidr 10.0.0.0/8
# Now all services work transparently
psql -h 10.0.1.5 -p 5432 db1
redis-cli -h 10.0.2.25
curl http://10.0.3.100:8080/api
ssh ec2-user@10.0.4.50# Morning: Start proxy as daemon
sudo -E ssm-proxy start \
--instance-tag Environment=dev \
--cidr 10.10.0.0/16 \
--daemon
# Work all day with transparent access
psql -h dev-db.internal -p 5432 mydb
curl http://dev-api.internal:8080
# Evening: Stop proxy
sudo -E ssm-proxy stopContributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- AWS Systems Manager team for the excellent SSM Session Manager service
- The Go community for amazing libraries and tools
Give a βοΈ if this project helped you!
How It Works: This tool creates a TUN device for packet capture, establishes an SSH tunnel with dynamic SOCKS5 forwarding over SSM, and translates TUN packets to SOCKS5 connections in user-space. The result is truly transparent networking where applications require zero configuration. See the Architecture Guide for a deep dive.