G3 Proxy Forward Proxy on AWS User Guide
Overview
This image runs g3proxy, the enterprise grade HTTP and HTTPS forward proxy from the open source ByteDance g3 project. g3proxy is written in Rust for high throughput and memory safety and is licensed under Apache 2.0, so there is no vendor lock in or licence ambiguity for commercial and SaaS deployments. This image packages it as a hardened systemd appliance that requires username and password authentication from the moment it starts, so it never ships as an open relay.
The g3proxy binary is installed under /usr/local/bin and runs as a dedicated unprivileged g3proxy system account under a systemd service that starts it on boot and restarts it on failure. Its configuration lives at /etc/g3proxy/default/main.yml. The proxy listens for HTTP and HTTPS (CONNECT) requests on TCP port 3128.
The proxy is secure by default. A unique proxy username and a strong password are generated on the first boot of every deployed instance, so two instances launched from the same Amazon Machine Image never share a credential. The credentials are written to /root/g3proxy-credentials.txt with mode 0600 so that only the root user can read them. Anonymous and wrong credential requests are refused with HTTP 407. By default the proxy accepts authenticated clients from loopback and private (RFC1918) ranges only, restricts destination ports to the standard web ports, and denies the cloud metadata and link local range on egress to block server side request forgery. The recommended security group opens SSH alone, so the proxy is not reachable from the internet until you deliberately add a scoped ingress rule or connect over an SSH tunnel.
Prerequisites
Before you deploy this image you need:
- An AWS account with permission to subscribe to AWS Marketplace products and launch EC2 instances.
- A key pair in your target region for SSH access.
- A security group that allows inbound TCP 22 (SSH) from your administrative address. The proxy port 3128 is not exposed by default.
Step 1: Launch the Instance from the AWS Marketplace
- Open the product page on AWS Marketplace and choose Continue to Subscribe, then Continue to Configuration.
- Select the software version and your AWS Region, then choose Continue to Launch.
- Under Choose Action select Launch through EC2, pick an instance type (a general purpose
m5.largeis a good starting point), your key pair, and a security group that allows inbound SSH (port 22). - Launch the instance and note its public IP address or DNS name.
Step 2: Launch the Instance from the AWS CLI
You can also launch the subscribed image from the command line. Replace the AMI id, key name, security group and subnet with your own:
aws ec2 run-instances \
--image-id ami-0123456789abcdef0 \
--instance-type m5.large \
--key-name my-key \
--security-group-ids sg-0123456789abcdef0 \
--subnet-id subnet-0123456789abcdef0 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=g3proxy}]'
Step 3: Connect to Your Instance
Connect over SSH as the default login user for your OS variant. Use the private key for the key pair you launched with.
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i /path/to/my-key.pem ubuntu@<public-ip>
Step 4: Retrieve Your Proxy Credentials
The per instance proxy username and password are generated on first boot and written to a root only file. Read them with sudo:
sudo cat /root/g3proxy-credentials.txt
The file contains the PROXY_USERNAME and PROXY_PASSWORD values that are unique to this instance, along with the proxy endpoint and usage examples. Keep these credentials safe; they are the only way to authenticate to the proxy.
Step 5: Confirm the Proxy Is Running
Check the service is active, confirm the version, and confirm it is listening on port 3128 as the unprivileged g3proxy user:
systemctl is-active g3proxy.service
/usr/local/bin/g3proxy --version
sudo ss -tlnp | grep 3128
You should see active, the g3proxy version, and a listener on *:3128 owned by the g3proxy process.


Step 6: Verify Authentication Is Enforced
An anonymous request through the proxy must be refused with HTTP 407 Proxy Authentication Required:
curl -s -o /dev/null -w 'anonymous -> HTTP %{http_code}\n' -x http://127.0.0.1:3128 http://example.com
This confirms the proxy is not an open relay: without valid credentials no request is forwarded.

Step 7: Send a Request Through the Proxy
Use your per instance credentials to send an HTTP and an HTTPS request through the proxy. On the instance, read the username and password from the root only credentials file into shell variables (so the secret is never typed on the command line) and pass them to curl:
U=$(sudo grep '^PROXY_USERNAME=' /root/g3proxy-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^PROXY_PASSWORD=' /root/g3proxy-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'authenticated HTTP -> HTTP %{http_code}\n' -x "http://$U:$P@127.0.0.1:3128" http://example.com
curl -s -o /dev/null -w 'authenticated HTTPS -> HTTP %{http_code}\n' -x "http://$U:$P@127.0.0.1:3128" https://example.com
Both requests return HTTP 200: the HTTP request is forwarded directly, and the HTTPS request is tunnelled with the CONNECT method to the TLS origin on port 443. From a remote client (see the next step) use the same username and password with your HTTP client's proxy setting.

Step 8: Remote Access over an SSH Tunnel
The proxy port is not exposed by the recommended security group. The simplest way to use the proxy from your workstation is an SSH tunnel that forwards a local port to port 3128 on the instance:
ssh -i /path/to/my-key.pem -L 3128:127.0.0.1:3128 ubuntu@<public-ip>
With that tunnel open, point any client at http://127.0.0.1:3128 on your workstation and authenticate with the per instance username and password. For example, set the https_proxy environment variable to http://PROXY_USERNAME:PROXY_PASSWORD@127.0.0.1:3128 and run your HTTP client.
Step 9: Allow Remote Clients Directly (Optional)
If you prefer to reach the proxy directly rather than over a tunnel, do both of the following:
- Add an inbound rule to the instance's security group allowing TCP 3128 from your own client source range only.
- Widen the proxy's ingress access list to include that range. Edit
/etc/g3proxy/default/main.ymland add your CIDR underserver->ingress_network_filter->allow, then reload the service:
sudo systemctl reload g3proxy
Keep both the security group rule and the ingress access list scoped to the smallest client range you need. The default policy accepts loopback and private ranges only, and destinations are limited to the standard web ports (80, 443 and 563), so the proxy cannot be abused to tunnel to arbitrary services.
Step 10: Review the Security Policy
The shipped configuration is secure by default. You can review it at any time:
sudo sed -n '1,80p' /etc/g3proxy/default/main.yml
Key controls in the configuration:
- Authentication required — a
user_groupis attached to the HTTP proxy server, so every request must present valid per instance credentials. - Ingress access list — authenticated clients are accepted from loopback and private (RFC1918) ranges only, with a deny by default policy.
- Destination port filter — only HTTP (80), HTTPS (443) and NNTPS (563) destinations are permitted, so the proxy cannot tunnel to SMTP, SSH or other arbitrary ports.
- Anti SSRF egress filter — the proxy denies the cloud metadata and link local range (169.254.0.0/16) and loopback on egress, so it cannot be used to reach instance metadata or local only services.
Step 11: Service Maintenance
The proxy runs under systemd. Common operations:
systemctl status g3proxy.service --no-pager
sudo systemctl restart g3proxy.service
sudo journalctl -u g3proxy.service --no-pager -n 50
After editing the configuration, validate it before reloading:
sudo /usr/local/bin/g3proxy -t -c /etc/g3proxy/default/main.yml
Support
cloudimg provides 24/7 technical support for this image by email at support@cloudimg.co.uk and via live chat. We assist with deployment and instance sizing, client access list and egress policy tuning, TLS and CONNECT configuration, credential management, and performance troubleshooting. Please include your EC2 instance id and a description of the issue for fastest routing.