Gp
Networking Azure

G3 Proxy on Ubuntu 24.04 on Azure User Guide

| Product: G3 Proxy on Ubuntu 24.04 LTS on Azure

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 virtual machine, so two machines launched from the same 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 Network Security Group opens SSH alone, so the proxy is not reachable from the internet until you deliberately 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. Higher throughput deployments should use Standard_D2s_v5 or larger.

Step 1: Deploy from the Azure Portal

  1. Search for G3 Proxy in the Azure Marketplace, select the cloudimg publisher, and choose Create.
  2. Select your subscription, resource group and region, and choose the recommended VM size.
  3. Provide your SSH public key for the azureuser administrative account.
  4. Configure the Network Security Group to allow inbound TCP 22 for administration from your address. Leave the proxy port 3128 closed for now; you will open it deliberately for your own clients later if you need direct access.
  5. Review and create the virtual machine, then note its public IP address.

Step 2: Deploy from the Azure CLI

You can also deploy the image from the command line. Replace the subscription id, image version, and networking with your own:

RG="proxy-prod"; LOCATION="eastus"; VM_NAME="proxy1"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/g3proxy-ubuntu-24-04/versions/latest"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az vm create \
  --resource-group "$RG" --name "$VM_NAME" \
  --image "$GALLERY_IMAGE_ID" \
  --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

Step 3: Connect to Your Virtual Machine

Connect over SSH as the azureuser administrative account, using the private key that matches the public key you supplied at deploy time:

ssh -i ~/.ssh/id_rsa azureuser@<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 virtual machine, 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
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.

The g3proxy service active under systemd, its version, and the HTTP and HTTPS forward proxy listening on TCP port 3128 as the unprivileged g3proxy user

Step 6: Verify Authentication Is Enforced 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) 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 '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, confirming 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 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.

The secure by default authentication round trip: an anonymous request and a wrong password request are both rejected with HTTP 407, while a request with the correct per VM username and password succeeds with HTTP 200 over both HTTP and HTTPS

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

Step 8: Allow Remote Clients Directly (Optional)

If you prefer to reach the proxy directly rather than over a tunnel, do both of the following:

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

Step 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 shipped g3proxy configuration: mandatory per VM user authentication, a deny by default ingress access list for loopback and RFC1918 ranges, destination ports limited to standard web ports, and an anti SSRF egress filter blocking the cloud metadata range

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, readable only by root and the g3proxy group.

The security proof: the credentials file is 0600 root root, and the g3proxy dynamic users file is 0640 root g3proxy storing a crypt hash of the per VM password rather than the plaintext

Step 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

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 machine sizing, client access list and egress policy tuning, TLS and CONNECT configuration, credential management, and performance troubleshooting. Please include your Azure virtual machine name and a description of the issue for fastest routing.