Deployment guide

chproxy for ClickHouse 1.30.0

Overview

This guide covers launching and verifying chproxy for ClickHouse 1.30.0 on Ubuntu 24.04 from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud Hardened Adminer & Database Admin and Backup Tools AMIs listing on AWS Marketplace, which you select as the software version when you subscribe and launch. The listing's guide hub describes the other tools in the listing.

chproxy is an HTTP proxy and load balancer for ClickHouse. Clients send ordinary ClickHouse HTTP requests to chproxy. It authenticates them as proxy users, applies per-user limits (concurrent queries, queue length and execution time), and checks the client's source network. It then forwards each query to a ClickHouse cluster as a mapped ClickHouse user.

chproxy is a common front door for BI tools, dashboards and applications that share one ClickHouse deployment.

The image ships chproxy 1.30.0, which SecureAnyCloud compiled from the unmodified upstream source with Go 1.27.3 and patched golang.org/x modules. The upstream release binary was built with an older Go and carries Go security advisories that govulncheck reports as reachable. The rebuilt binary has none.

A local ClickHouse 26.8 LTS server from ClickHouse's official repository is installed as the default backend, so the image answers real queries from its first boot. You can point chproxy at your own ClickHouse nodes instead (Step 8).

What you get:

  • chproxy 1.30.0 (chproxy.service) serving HTTPS only on port 8443 with a certificate generated on your instance's first boot
  • ClickHouse 26.8.31.2 (clickhouse-server.service) on 127.0.0.1:8123 (HTTP) and 127.0.0.1:9000 (native protocol) only
  • A proxy user with a random name and password that are unique to your instance
  • Two ClickHouse users: default (the administrator, for local administration) and chproxy (the user chproxy connects as, with data rights only)
  • chproxy-selftest, an end-to-end check you can run at any time
  • Default user ubuntu, x86_64 architecture and a 20 GiB gp3 root volume
  • 24/7 SecureAnyCloud support

Security posture

  • No default credential. The image contains no usable password. First boot generates the proxy user's name and password, the ClickHouse default and chproxy passwords, and the TLS key and certificate, and writes them to /root/chproxy-credentials.txt (readable by root only). ClickHouse and chproxy refuse to start until first boot has done this. The ClickHouse default user never has an empty password.
  • HTTPS only. chproxy listens for HTTPS on 8443 with TLS 1.2 or later. There is no plain-HTTP listener, and the proxy user is configured to refuse plain HTTP anyway.
  • Per-instance certificate. First boot creates this instance's own private key and self-signed certificate for its public DNS name and addresses. No key ships in the image.
  • ClickHouse on localhost only. ClickHouse binds 127.0.0.1. Its MySQL and PostgreSQL wire-protocol ports and its replication port are switched off. The only ports reachable from other machines are 22 (SSH) and 8443 (chproxy).
  • Source-network control on the real client address. chproxy accepts HTTPS only from loopback, the RFC 1918 private ranges and 100.64.0.0/10. The client address is the TCP connection's own address. chproxy is not configured to trust X-Forwarded-For or similar headers, so a client cannot claim to be somewhere else.
  • Least privilege upstream. chproxy connects to ClickHouse as the chproxy user, which can read and write data and manage tables but cannot manage users and cannot use the url(), s3(), remote() or file() table functions. A proxy user therefore cannot make ClickHouse fetch an arbitrary URL.
  • No metadata access for any service. ClickHouse, chproxy and the first-boot service cannot reach the instance metadata service (169.254.169.254 and fd00:ec2::254), so even the ClickHouse administrator's url() cannot read instance credentials. Amazon Time Sync still works.
  • IMDSv2 required. The AMI is registered with ImdsSupport v2.0, so instances launched from it refuse token-less (IMDSv1) metadata requests.
  • No secrets in logs or on command lines. Passwords are never passed on a command line, so they do not appear in /var/log/auth.log or the journal. Ready-made root-only client files let you query without typing a password.
  • Hardened service. chproxy runs as an unprivileged system user in a strict systemd sandbox (read-only system, no capabilities, restricted address families).
  • Per-instance identity. SSH host keys and the machine ID are generated fresh on every instance.

Prerequisites

  • An AWS account and permission to launch EC2 instances and create security groups
  • An EC2 key pair in the Region you launch in
  • A VPC subnet, with a public IP on the instance if you connect over the internet

Recommended instance type: m5.large. chproxy itself needs very little CPU or memory. Size the instance for the local ClickHouse workload, or keep it small if chproxy only fronts your own ClickHouse cluster.

Connecting to your instance

The version chproxy for ClickHouse 1.30.0 on Ubuntu 24.04 runs Ubuntu 24.04 LTS. Connect over SSH as the user ubuntu.

1

Launch the instance

Option A: AWS Marketplace console

  • Open the SecureAnyCloud Hardened Adminer & Database Admin and Backup Tools AMIs listing on AWS Marketplace. Choose View purchase options, then Subscribe. One subscription covers every version in the listing.
  • When the subscription is active, choose Launch your software.
  • Choose One-click launch from AWS Marketplace, or Launch from EC2 Console for the full launch wizard. In Version, choose chproxy for ClickHouse 1.30.0 on Ubuntu 24.04. Then choose your Region.
  • Pick an instance type and your key pair. m5.large is recommended, and the software charge is $0.04 per vCPU per hour.
  • Set the security group. The listing's default group allows SSH (22) and chproxy (8443). Restrict SSH to your administration address and 8443 to the VPC or VPN ranges your ClickHouse clients use. chproxy also refuses public client addresses until you allow them (Step 7).
  • Choose your VPC and subnet and leave the metadata defaults, because the image already requires IMDSv2. Then choose Launch.

Option B: AWS CLI

Run these commands on your own workstation. Replace the AMI ID with the one shown for your Region on the Marketplace launch page. Replace the VPC, subnet, key pair and CIDRs with your own.

SG=$(aws ec2 create-security-group --group-name chproxy \
  --description "chproxy for ClickHouse" --vpc-id vpc-0123456789abcdef0 \
  --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 8443 --cidr <your-vpc-cidr>
aws ec2 run-instances \
  --image-id ami-0123456789abcdef0 \
  --instance-type m5.large \
  --key-name my-key-pair \
  --security-group-ids "$SG" \
  --subnet-id subnet-0123456789abcdef0 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=chproxy}]'

You do not need --metadata-options, because the AMI already requires IMDSv2.

2

Connect and read your credentials

Connect as ubuntu with the key pair you chose.

ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>

First boot finishes within a minute of launch. Show the connection details with the command below. It leaves out the three password lines. Read those with sudo cat /root/chproxy-credentials.txt and keep them in your secrets manager.

sudo grep -vE '^(CHPROXY_PASSWORD|CLICKHOUSE_ADMIN_PASSWORD|CLICKHOUSE_UPSTREAM_PASSWORD)=' /root/chproxy-credentials.txt
# chproxy for ClickHouse on Ubuntu 24.04 — Per-instance Credentials
# Generated: Tue Oct 20 06:50:04 UTC 2026
#
# Every value below was generated on THIS instance at first boot. None was baked into the image and
# no two sac instances share any of them. Keep this file secret.
#
# chproxy client (HTTPS on port 8443, HTTP basic auth or user/password query parameters): CHPROXY_USERNAME=ch_7a99c9d7 CHPROXY_URL=https://ec2-54-210-167-124.compute-1.amazonaws.com:8443/
#
# ClickHouse administrator (listens on 127.0.0.1 only; for local administration on this instance): CLICKHOUSE_ADMIN_USER=default
#
# ClickHouse user chproxy connects as (data rights only; loopback only): CLICKHOUSE_UPSTREAM_USER=chproxy ...

Your proxy user name and host name will differ. First boot also writes two root-only client files, so you never type a password. /etc/sac/chproxy-client.curl holds the proxy user, for curl -K. /etc/sac/clickhouse-admin.xml holds the ClickHouse administrator, for clickhouse-client --config-file.

3

Confirm chproxy and ClickHouse are running

chproxy -version clickhouse-server --version systemctl is-active clickhouse-server.service chproxy.service
sudo ss -Hltn
chproxy ver. 1.30.0, rev. 3aea406897580f4dd50096ebab63d0a611e25f14, built at 2025-09-10T08:27:22Z ClickHouse server version 26.8.31.2 (official build). active active LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* LISTEN 0 4096 0.0.0.0:8443 0.0.0.0:* LISTEN 0 4096 127.0.0.1:9000 0.0.0.0:* LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* LISTEN 0 4096 127.0.0.54:53 0.0.0.0:* LISTEN 0 4096 127.0.0.1:8123 0.0.0.0:* LISTEN 0 4096 [::]:22 [::]:*

chproxy listens on 8443 on every interface. ClickHouse listens on 127.0.0.1 only. Port 53 on 127.0.0.53/127.0.0.54 is the operating system's local DNS stub.

4

Run a query through chproxy

Send a query over HTTPS as the proxy user. The client file supplies the user name and password. --cacert pins this instance's own certificate.

sudo curl -sS -K /etc/sac/chproxy-client.curl --cacert /etc/chproxy/tls/chproxy.crt \
  --data-binary 'SELECT version(), currentUser() FORMAT PrettyCompactMonoBlock' https://127.0.0.1:8443/
┌─version()─┬─currentUser()─┐ 1. │ 26.8.31.2 │ chproxy │ └───────────┴───────────────┘

The query ran on ClickHouse as the chproxy user, which is the ClickHouse identity your proxy user is mapped to. Any ClickHouse SQL works the same way.

sudo curl -sS -K /etc/sac/chproxy-client.curl --cacert /etc/chproxy/tls/chproxy.crt \
  --data-binary 'SELECT number, number * number AS square FROM numbers(5) FORMAT PrettyCompactMonoBlock' https://127.0.0.1:8443/
┌─number─┬─square─┐ 1. │ 0 │ 0 │ 2. │ 1 │ 1 │ 3. │ 2 │ 4 │ 4. │ 3 │ 9 │ 5. │ 4 │ 16 │ └────────┴────────┘

Drivers that use the ClickHouse HTTP interface connect to chproxy with host <your-host>, port 8443, HTTPS on, and the proxy user name and password. Examples are clickhouse-connect, the JDBC driver, Grafana's ClickHouse data source and most BI tools.

5

Confirm requests without valid credentials are refused

A request with no credentials, or with a wrong password, gets HTTP 401 from chproxy. It never reaches ClickHouse.

curl -q -sS --cacert /etc/chproxy/tls/chproxy.crt -w '\nHTTP %{http_code}\n' \
  --data-binary 'SELECT 1' https://127.0.0.1:8443/
curl -q -sS --cacert /etc/chproxy/tls/chproxy.crt -w '\nHTTP %{http_code}\n' \
  -u "$(sudo sed -n 's/^CHPROXY_USERNAME=//p' /root/chproxy-credentials.txt):not-the-password" \
  --data-binary 'SELECT 1' https://127.0.0.1:8443/
"127.0.0.1:50116": invalid username or password for user "default"; query: "SELECT 1" HTTP 401 "127.0.0.1:50118": invalid username or password for user "ch_7a99c9d7"; query: "SELECT 1" HTTP 401

The proxied user also cannot make ClickHouse fetch a URL.

sudo curl -sS -K /etc/sac/chproxy-client.curl --cacert /etc/chproxy/tls/chproxy.crt -w '\nHTTP %{http_code}\n' \
  --data-binary "SELECT * FROM url('http://169.254.169.254/latest/meta-data/', 'RawBLOB')" https://127.0.0.1:8443/
Code: 497. DB::Exception: chproxy: Not enough privileges. To execute this query, it's necessary to have the grant READ ON URL. (ACCESS_DENIED) (version 26.8.31.2 (official build)) HTTP 403
6

Check the certificate

openssl x509 -in /etc/chproxy/tls/chproxy.crt -noout -subject -ext subjectAltName -enddate
subject=CN = ec2-54-210-167-124.compute-1.amazonaws.com, O = sac X509v3 Subject Alternative Name: DNS:ec2-54-210-167-124.compute-1.amazonaws.com, IP Address:54.210.167.124, DNS:ip-172-31-87-187.ec2.internal, IP Address:172.31.87.187, IP Address:127.0.0.1, DNS:localhost notAfter=Jan 22 06:50:04 2029 GMT

The certificate covers this instance's public and private DNS names and addresses. Clients verify it by pinning the certificate file. Copy /etc/chproxy/tls/chproxy.crt, which is public, to each client and pass it as the CA certificate. Use curl --cacert, ca_cert in clickhouse-connect, or a trust store for JDBC.

To serve chproxy under your own DNS name, point the name at the instance and regenerate the certificate for it. The command saves the name in /etc/sac/chproxy-hostname and restarts chproxy with the new certificate.

sudo chproxy-set-hostname clickhouse-proxy.example.com

For production, replace /etc/chproxy/tls/chproxy.crt and chproxy.key with a certificate from your own CA. Keep the key owned by root:chproxy with mode 0640. Then run sudo systemctl restart chproxy.

7

Connect from other machines

The listing's security group opens 8443. chproxy accepts clients from loopback, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 and 100.64.0.0/10, which covers clients inside your VPC. Copy the certificate to another instance in the VPC as chproxy.crt, then run this command there.

curl -sS --cacert chproxy.crt -u '<proxy-user>:<proxy-password>' \
  --data-binary 'SELECT 1' https://<private-ip>:8443/

A client outside those ranges gets https connections are not allowed from <address> (HTTP 403), even if it sends an X-Forwarded-For header. To admit another range, such as your office's public range, add it to allowed_networks under server.https in /etc/chproxy/config.yml. Then restart chproxy.

sudo nano /etc/chproxy/config.yml
sudo systemctl restart chproxy

Limit the security group rule for 8443 to the same ranges.

8

Configure users and clusters

/etc/chproxy/config.yml (readable by root and the chproxy group only) holds the proxy users and the clusters they are routed to. The image's configuration has one proxy user, routed to the local ClickHouse as the chproxy user.

sudo grep -vE '^ *password:' /etc/chproxy/config.yml | grep -vE '^#'
log_debug: false hack_me_please: false server: https: listen_addr: ":8443" cert_file: "/etc/chproxy/tls/chproxy.crt" key_file: "/etc/chproxy/tls/chproxy.key" allowed_networks: ["127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "100.64.0.0/10"] metrics: allowed_networks: ["127.0.0.0/8"] users: - name: "ch_7a99c9d7" to_cluster: "local" to_user: "chproxy" deny_http: true max_concurrent_queries: 20 max_execution_time: 2m max_queue_size: 50 max_queue_time: 30s clusters: - name: "local" scheme: "http" nodes: ["127.0.0.1:8123"] users: - name: "chproxy" max_concurrent_queries: 20 max_execution_time: 2m

Typical changes are listed below. See the chproxy configuration reference for details.

  • Add proxy users for each application or team, each with its own password, limits and to_user.
  • Front your own ClickHouse cluster. Add a cluster whose nodes (or replicas) are your ClickHouse servers and whose users are ClickHouse accounts on them. Route proxy users to it with to_cluster. chproxy balances queries across the nodes and stops sending to unhealthy ones.
  • Enable response caching with a caches section and a cache setting on the user.

Keep hack_me_please: false so chproxy's own security checks stay on. Apply the change with sudo systemctl restart chproxy, then check systemctl status chproxy.

9

Administer the local ClickHouse

ClickHouse listens on 127.0.0.1 only. Use the root-only administrator client file on the instance.

sudo clickhouse-client --config-file /etc/sac/clickhouse-admin.xml \
  -q "SELECT name, auth_type FROM system.users ORDER BY name FORMAT PrettyCompactMonoBlock"
┌─name────┬─auth_type───────────┐ 1. │ chproxy │ ['sha256_password'] │ 2. │ default │ ['sha256_password'] │ └─────────┴─────────────────────┘

Both users are defined in /etc/clickhouse-server/users.d/sac-users.xml with SHA-256 password hashes and may connect from loopback only.

/etc/apt/preferences.d/clickhouse-pin pins ClickHouse to 26.8.31.2, so an operating-system upgrade never changes the database version under you. To move to a newer 26.8 LTS release, edit the version in that file. Then run sudo apt-get update && sudo apt-get install clickhouse-server clickhouse-client clickhouse-common-static.

10

Verify the appliance end to end

chproxy-selftest checks the services, the ClickHouse and chproxy credentials (including that wrong ones are refused), the certificate, the exact listening ports and the metadata block.

sudo chproxy-selftest
ok clickhouse-server and chproxy active; first boot complete ok ClickHouse: per-VM passwords accepted; no-password and wrong-password logins refused (authentication error) ok chproxy HTTPS: anonymous and wrong-password refused (401); per-VM user proxied to ClickHouse 26.8.31.2 as 'chproxy' ok url() table function is not granted to the proxied user (ClickHouse access denied) ok certificate verifies for the configured name ec2-54-210-167-124.compute-1.amazonaws.com; plain HTTP is not served ok per-VM certificate for ec2-54-210-167-124.compute-1.amazonaws.com (key 0640 root:chproxy); credentials file 0600 root ok off-box listeners exactly 22 and 8443; ClickHouse 8123/9000 on 127.0.0.1 only ok instance metadata refused inside the clickhouse-server and chproxy cgroups (loopback reachable; 200 from this shell) SELFTEST OK - per-VM credentials, HTTPS only, exact ports, metadata blocked.

The metadata block is a systemd setting on each service. You can inspect it with this command.

systemctl show -p IPAddressDeny chproxy.service clickhouse-server.service chproxy-firstboot.service
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32 IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32 IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32

Build provenance and licences

chproxy is MIT licensed and ClickHouse is Apache-2.0. The chproxy licence and a build record are in /usr/share/doc/chproxy/. The record covers the source archive and its checksum, the Go toolchain, the dependency changes, the binary's checksum and the govulncheck result.

cat /usr/share/doc/chproxy/BUILD-PROVENANCE.txt

Support

SecureAnyCloud provides 24/7 support for this image by email at sales@secureanycloud.com. Include your instance ID, the Region and the output of sudo chproxy-selftest in your message.

Deploy on AWS

Launch chproxy for ClickHouse 1.30.0 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS