chproxy
Overview
This image runs chproxy, the open source HTTP proxy and load balancer for ClickHouse, in front of a bundled local ClickHouse server. chproxy is a single Go binary, licensed under the MIT licence. It terminates client HTTP requests, enforces its own user-based access control and per-user limits, spreads queries across ClickHouse nodes, and can cache responses. ClickHouse itself is licensed under Apache 2.0.
Together they give you a working, authenticated ClickHouse HTTP endpoint on one virtual machine, with no vendor lock-in or licence ambiguity for commercial deployments.
What you get:
- Service layout. The chproxy binary is installed at
/usr/local/bin/chproxy. It runs as a dedicated unprivilegedchproxysystem account under a systemd service that starts it on boot and restarts it on failure. Its configuration lives at/etc/chproxy/config.yml. - Network ports. chproxy listens for client HTTP requests on TCP port 9090. The bundled ClickHouse server listens on the loopback interface only (127.0.0.1 ports 8123 HTTP and 9000 native). It is never exposed directly, and every request reaches it through chproxy.
- No shared credential. On the first boot of every deployed virtual machine, a unique chproxy client password and a unique ClickHouse default user password are generated. Two machines launched from the same image never share a credential. The credentials are written to
/root/chproxy-credentials.txtwith mode 0600, so that only the root user can read them. - Authentication enforced. A request to chproxy with no credentials, or with the wrong password, is refused with HTTP 401. Only the per-instance client credentials are accepted. The ClickHouse default user rejects its upstream empty-password default.
- Closed by default. 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, make sure you have:
- 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 9090 is not exposed by default.
Recommended virtual machine size: Standard_D2s_v5 (2 vCPU, 8 GB RAM) for a small single-node deployment. ClickHouse is memory-hungry, so choose a larger memory-optimised size for production analytics workloads.
Deploy from the Azure Portal
- Search for chproxy in the Azure Marketplace, select the SecureAnyCloud publisher, and choose Create.
- Select your subscription, resource group and region. 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 the proxy port 9090 closed for now. If you need direct access later, you can open it for your own clients (Step 9).
- Review and create the virtual machine, then note its public IP address.
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="chproxy-prod"; LOCATION="eastus"; VM_NAME="chproxy1" IMAGE_URN="sac1647283583153:chproxy-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:chproxy-ubuntu-24-04:default:latest
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$IMAGE_URN" \
--size Standard_D2s_v5 \
--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, using the private key that matches the public key you supplied at deploy time:
ssh -i ~/.ssh/id_rsa azureuser@<public-ip>Retrieve your credentials
The per-instance credentials are generated on first boot and written to a root-only file. Read them with sudo:
sudo cat /root/chproxy-credentials.txtThe file contains the CHPROXY_USERNAME and CHPROXY_PASSWORD values that clients use to authenticate to chproxy. It also holds the CLICKHOUSE_PASSWORD for the bundled ClickHouse default user, the proxy endpoint and a usage example. All credentials are unique to this virtual machine. Keep them safe.
Confirm the services are running
Check that both services are active and confirm the chproxy version. Then confirm that chproxy listens on port 9090 as the unprivileged chproxy user, while ClickHouse listens on loopback only:
systemctl is-active chproxy.service clickhouse-server.service /usr/local/bin/chproxy -version sudo ss -tlnp | grep -E ':9090|:8123' ps -o user=,comm= -C chproxyYou should see:
activefor both services.- The chproxy version.
- A listener on
*:9090(chproxy) and a127.0.0.1:8123listener (ClickHouse, loopback only). - The
chproxyprocess owned by the chproxy account rather than root.
Verify that authentication is enforced and run a query
chproxy is not an open endpoint. A request with no credentials and a request with the wrong password are both refused with HTTP 401, while your per-instance credentials succeed and the query is proxied to the bundled ClickHouse.
On the virtual machine, read the username and password from the root-only credentials file into shell variables, so that the secret is never typed on the command line. Then pass them to curl:
U=$(sudo grep '^CHPROXY_USERNAME=' /root/chproxy-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^CHPROXY_PASSWORD=' /root/chproxy-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'no credentials -> HTTP %{http_code}\n' 'http://127.0.0.1:9090/?query=SELECT+1'
curl -s -o /dev/null -w 'wrong password -> HTTP %{http_code}\n' "http://$U:wrongpassword@127.0.0.1:9090/?query=SELECT+1" echo -n 'authenticated -> ';
curl -s "http://$U:$P@127.0.0.1:9090/?query=SELECT+version()"The first two requests return HTTP 401, confirming that no query is forwarded without valid credentials. The authenticated request returns the ClickHouse version string, which shows that chproxy proxied the query to the bundled ClickHouse and that ClickHouse answered.
Run ClickHouse queries through the proxy
Everything that ClickHouse's HTTP interface supports works through chproxy. Create a table, insert rows and read them back, all through the authenticated proxy endpoint:
U=$(sudo grep '^CHPROXY_USERNAME=' /root/chproxy-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^CHPROXY_PASSWORD=' /root/chproxy-credentials.txt | cut -d= -f2-) CH="http://$U:$P@127.0.0.1:9090/" curl -s "$CH" --data-binary 'CREATE TABLE IF NOT EXISTS demo (id UInt32, name String) ENGINE = MergeTree ORDER BY id' curl -s "$CH" --data-binary "INSERT INTO demo VALUES (1,'alpha'),(2,'beta'),(3,'gamma')" curl -s "$CH?query=SELECT%20count()%20FROM%20demo" curl -s "$CH" --data-binary 'SELECT id, name FROM demo ORDER BY id FORMAT TabSeparated' curl -s "$CH" --data-binary 'DROP TABLE demo'The count returns 3 and the select returns the three rows. This confirms end-to-end reads and writes against ClickHouse through chproxy.
Connect remotely over an SSH tunnel
The recommended Network Security Group does not expose the proxy port. The simplest way to reach chproxy from your workstation is an SSH tunnel that forwards a local port to port 9090 on the virtual machine:
ssh -i ~/.ssh/id_rsa -L 9090:127.0.0.1:9090 azureuser@<public-ip>With the tunnel open, point any ClickHouse HTTP client or curl at http://127.0.0.1:9090 on your workstation. Authenticate with the per-instance chproxy username and password, for example curl "http://CHPROXY_USERNAME:CHPROXY_PASSWORD@127.0.0.1:9090/?query=SELECT+1".
Allow remote clients directly (optional)
If you prefer to reach chproxy directly instead of over a tunnel, do both of the following:
- Add an inbound rule to the virtual machine's Network Security Group that allows TCP 9090 from your own client source range only:
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 9090 --priority 1002 \
--source-address-prefixes <your-mgmt-cidr>- Widen chproxy's allowed client networks to include that range. Edit
/etc/chproxy/config.ymland add your CIDR underserver->http->allowed_networks. Then reload the service:
sudo systemctl reload chproxyKeep both the Network Security Group rule and the allowed_networks list scoped to the smallest client range you need. The default policy accepts loopback and private (RFC1918) ranges only.
Review the security policy
The shipped configuration is secure by default. You can review it at any time:
sudo sed -n '1,40p' /etc/chproxy/config.ymlKey controls in the configuration:
- Authentication required. Clients must authenticate as the proxy user defined in the config. There is no
defaultproxy user, so an unauthenticated request maps to a nonexistent user and is rejected with HTTP 401. - Allowed networks. chproxy accepts client connections from loopback and private (RFC1918) ranges only.
- ClickHouse on loopback. The bundled ClickHouse server listens on 127.0.0.1 only, so it is reachable exclusively through chproxy. Its default user has a per-instance password and rejects the upstream empty-password default.
The credentials are stored safely. The plaintext file is root-only (mode 0600), and the ClickHouse default user password is stored as a SHA256 hash in /etc/clickhouse-server/users.xml rather than in plaintext.
Maintain the services
Both services run under systemd. These are the common operations:
systemctl status chproxy.service --no-pager sudo systemctl restart chproxy.service
sudo journalctl -u chproxy.service --no-pager -n 50
sudo systemctl status clickhouse-server.service --no-pagerAfter editing the chproxy configuration, reload the service to apply it:
sudo systemctl reload chproxy.serviceSupport
SecureAnyCloud provides 24/7 technical support for this image by email at sales@secureanycloud.com and via live chat. We assist with deployment and machine sizing, chproxy user and cluster configuration, ClickHouse tuning, client access list changes, response caching, credential management and performance troubleshooting.
For the fastest routing, include your Azure virtual machine name and a description of the issue.
Deploy on Azure
Launch chproxy for ClickHouse 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