Deployment guide

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 unprivileged g3proxy system 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.txt with 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.

1

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 azureuser administrative 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.
2

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 1001
3

Connect 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>
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 virtual machine, along with the proxy endpoint and usage examples. Keep these credentials safe. They are the only way to authenticate to the proxy.

5

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 g3proxy

You should see active, the g3proxy version, a listener on *:3128, and the process owned by the g3proxy account rather than root.

6

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.com

The 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.

7

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.

8

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 under server -> 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 g3proxy

Keep 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.

9

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.yml

Key controls in the configuration:

  • Authentication required. A user_group is 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.

10

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

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

Deploy on Azure