g3proxy
Overview
g3proxy is an enterprise-grade HTTP and HTTPS forward proxy from the open-source ByteDance g3 project. It 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 license ambiguity for commercial and SaaS deployments.
This image packages g3proxy as a hardened systemd appliance. It requires username and password authentication from the moment it starts, so it never ships as an open relay.
What you get:
- The g3proxy binary under
/usr/local/bin, running as a dedicated unprivilegedg3proxysystem account under a systemd service that starts it on boot and restarts it on failure - Configuration at
/etc/g3proxy/default/main.yml - An HTTP and HTTPS (CONNECT) listener on TCP port 3128
- A unique proxy username and a strong password, generated on the first boot of every deployed virtual machine, so two machines launched from the same image never share a credential
- Credentials written to
/root/g3proxy-credentials.txtwith mode 0600, so only the root user can read them - HTTP 407 refusals for anonymous requests and requests with wrong credentials
- A default policy that 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 Network Security Group opens SSH alone. The proxy is not reachable from the internet until you add a scoped inbound rule or connect over an SSH tunnel.
Prerequisites
Before you deploy this image, you need:
- An active Azure subscription with permission to subscribe to Marketplace images and create virtual machines.
- An SSH public key for administrative access.
- A virtual network and subnet in your target region, and a Network Security Group that allows inbound TCP 22 (SSH) from your administrative address. The proxy port 3128 is not exposed by default.
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for a small proxy. For higher-throughput deployments, use Standard_D2s_v5 or larger.
Deploy from the Azure portal
- Search for G3 Proxy in the Azure Marketplace, select the SecureAnyCloud publisher and choose Create.
- Select your subscription, resource group and region, and choose the recommended VM size.
- Provide your SSH public key for the
azureuseradministrative account. - Configure the Network Security Group to allow inbound TCP 22 for administration from your address. Leave proxy port 3128 closed for now. You can open it later for your own clients if you need direct access.
- Review and create the virtual machine, then note its public IP address.
Deploy from the Azure CLI
Deploy the image from the command line. Replace the subscription ID, image version and networking values with your own:
RG="proxy-prod"; LOCATION="eastus"; VM_NAME="proxy1" IMAGE_URN="sac1647283583153:g3proxy-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:g3proxy-ubuntu-24-04:default:latest
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$IMAGE_URN" \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values "$SSH_KEY" \
--public-ip-sku Standard
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1001Connect to your virtual machine
Connect over SSH as the azureuser administrative account. Use the private key that matches the public key you supplied at deploy time:
ssh -i ~/.ssh/id_rsa azureuser@<public-ip>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.txtThe file contains the PROXY_USERNAME and PROXY_PASSWORD values that are unique to this virtual machine, along with the proxy endpoint and usage examples. Keep these credentials safe. They are the only way to authenticate to the proxy.
Confirm the proxy is running
Check that the service is active, confirm the version, and confirm that 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 ps -o user=,comm= -C g3proxyYou should see active, the g3proxy version, a listener on *:3128, and the process owned by the g3proxy account rather than root.
Verify authentication and send a request
The proxy is not an open relay. An anonymous request and a wrong-credential request are both refused with HTTP 407, while your per-instance credentials succeed over both HTTP and HTTPS.
On the virtual machine, read the username and password from the root-only credentials file into shell variables, so the secret is never typed on the command line. 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 'anonymous -> HTTP %{http_code}\n' -x http://127.0.0.1:3128 http://example.com
curl -s -o /dev/null -w 'wrong password -> HTTP %{http_code}\n' -x "http://$U:wrongpassword@127.0.0.1:3128" http://example.com
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.comThe anonymous and wrong-password requests return HTTP 407, which confirms that no request is forwarded without valid credentials.
The two authenticated requests return HTTP 200. The HTTP request is forwarded directly, and the HTTPS request is tunneled 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.
Remote access over an SSH tunnel
The proxy port is not exposed by the recommended Network 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 virtual machine:
ssh -i ~/.ssh/id_rsa -L 3128:127.0.0.1:3128 azureuser@<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.
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 virtual machine's Network Security Group allowing TCP 3128 from your own client source range only:
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 3128 --priority 1002 \
--source-address-prefixes <your-mgmt-cidr>- Widen the proxy's ingress access list to include that range. Edit
/etc/g3proxy/default/main.yml, add your CIDR underserver->ingress_network_filter->allow, validate the configuration, and reload the service:
sudo /usr/local/bin/g3proxy -t -c /etc/g3proxy/default/main.yml
sudo systemctl reload g3proxyKeep both the Network 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.
Review the security policy
The shipped configuration is secure by default. You can review its security sections at any time:
sudo sed -n '21,72p' /etc/g3proxy/default/main.ymlKey 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.
The credentials are also stored safely. The plaintext file is root-only (mode 0600), and the proxy's own dynamic users file stores a crypt hash of the per-instance password rather than the plaintext. That file is readable only by root and the g3proxy group.
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 50After editing the configuration, validate it before reloading:
sudo /usr/local/bin/g3proxy -t -c /etc/g3proxy/default/main.ymlSupport
SecureAnyCloud provides 24/7 technical support for this image by email at sales@secureanycloud.com and via live chat. We can help with deployment and machine sizing, client access list and egress policy tuning, TLS and CONNECT configuration, credential management, and performance troubleshooting.
Include your Azure virtual machine name and a description of the issue so that we can route your request quickly.
Deploy on Azure
Launch G3 Proxy on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
g3proxy is an enterprise-grade HTTP and HTTPS forward proxy from the open-source ByteDance g3 project. It 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 license ambiguity for commercial and SaaS deployments.
This image packages g3proxy as a hardened systemd appliance. It requires username and password authentication from the moment it starts, so it never ships as an open relay.
What you get:
- The g3proxy binary under
/usr/local/bin, running as a dedicated unprivilegedg3proxysystem account under a systemd service that starts it on boot and restarts it on failure - Configuration at
/etc/g3proxy/default/main.yml - An HTTP and HTTPS (CONNECT) listener on TCP port 3128
- A unique proxy username and a strong password, generated on the first boot of every deployed instance, so two instances launched from the same Amazon Machine Image never share a credential
- Credentials written to
/root/g3proxy-credentials.txtwith mode 0600, so only the root user can read them - HTTP 407 refusals for anonymous requests and requests with wrong credentials
- A default policy that 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. The proxy is not reachable from the internet until you 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.
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.
Launch the instance from the AWS CLI
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}]'Connect to your instance
Connect over SSH with the private key for the key pair you launched with. The login user depends on the OS variant. For Ubuntu 24.04, the login user is ubuntu.
ssh -i /path/to/my-key.pem ubuntu@<public-ip>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.txtThe 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.
Confirm the proxy is running
Check that the service is active, confirm the version, and confirm that 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 3128You should see active, the g3proxy version, and a listener on *:3128 owned by the g3proxy process.
Verify that 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.comThis confirms that the proxy is not an open relay. Without valid credentials, no request is forwarded.
Send a Request Through the Proxy
Use your per-instance credentials to send an HTTP request 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. 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.comBoth requests return HTTP 200. The HTTP request is forwarded directly, and the HTTPS request is tunneled 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.
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.
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 g3proxyKeep 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.
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.ymlKey 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.
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 50After editing the configuration, validate it before reloading:
sudo /usr/local/bin/g3proxy -t -c /etc/g3proxy/default/main.ymlSupport
SecureAnyCloud provides 24/7 technical support for this image by email at sales@secureanycloud.com and via live chat. We can help with deployment and instance sizing, client access list and egress policy tuning, TLS and CONNECT configuration, credential management, and performance troubleshooting.
Include your EC2 instance ID and a description of the issue so that we can route your request quickly.
Deploy on AWS
Launch G3 Proxy on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com