Developer Tools AWS

Athens Go Module Proxy on AWS User Guide

| Product: Athens Go Module Proxy on AWS

Overview

This image runs Athens, the open source, enterprise ready implementation of the Go module proxy, the GOPROXY protocol built into the Go toolchain. Point your developers and CI pipelines at an Athens server and every go build, go test and go mod download fetches modules through it. Athens downloads each module version once, stores it in its own on disk cache, and serves every later request from that cache. The result is faster builds, far less duplicated download traffic, and reproducible builds that keep working even when an upstream module is deleted, retagged, or its version control host is unreachable.

Athens speaks the Go module download HTTP protocol and is driven entirely by the standard go command, so there is no web console to manage. This image delivers it fully installed and hardened: Athens itself binds to the loopback interface only, and nginx is the single network facing surface, terminating TLS on port 443 and fronting the entire proxy with HTTP basic authentication so it is never an open relay. The official Go toolchain and git are installed on the image because Athens shells out to the go command to fetch modules from the upstream Go mirror or directly from a module's version control host on a cache miss.

The module cache lives on a dedicated, independently resizable EBS data volume mounted at /var/lib/athens, separate from the operating system disk, so the cache has room to grow. Athens 0.18.1 was installed from the official upstream release and verified against its published SHA256 checksum at build time.

Secure by default: per instance credentials

Nothing secret is baked into this image. On the first boot of every instance, the athens-firstboot service:

  • resolves the instance public IP through the EC2 Instance Metadata Service (IMDSv2),
  • generates a unique self signed TLS certificate whose subject alternative names cover the instance public IP, its hostname and 127.0.0.1,
  • generates a unique HTTP basic authentication username and password for the proxy and writes the nginx htpasswd, and
  • writes the credentials, the HTTPS proxy URL and a ready to paste GOPROXY example to /root/athens-aws-credentials.txt (mode 0600, root only).

Every instance therefore gets its own certificate and its own password. Unauthenticated requests are rejected with 401, and the module protocol is reachable only over TLS with the per instance credentials.

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances
  • IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access to the instance
  • A VPC and subnet in the target Region, with a security group allowing inbound port 22 (SSH) from your management network and inbound port 443 (HTTPS) from the workstations and CI agents that will use the proxy
  • The AWS CLI (version 2) installed locally if you plan to deploy from the command line

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Athens Go Module Proxy. Select the cloudimg listing, choose Select, then Continue on the subscription summary.

Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that opens port 22 from your management network and port 443 from your developer and CI networks. Leave the root volume at the default size or larger; the module cache lives on a separate data volume that is provisioned automatically.

Select Launch instance. First boot initialisation takes a few seconds after the instance state becomes Running and the status checks pass.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg Athens Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens port 22 and port 443.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=athens-go-proxy}]'

When the instance reaches the Running state and its status checks pass, note its public IP address or DNS name from the EC2 console or with aws ec2 describe-instances.

Step 3: Connect to Your Instance

Connect over SSH using your key pair and the login user for your operating system variant.

OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i /path/to/your-key.pem ubuntu@<public-ip>

Step 4: Retrieve the per instance proxy credentials

The unique username and password generated on first boot are in a root only file. Read them with sudo:

sudo cat /root/athens-aws-credentials.txt

The file contains:

  • ATHENS_PROXY_USER and ATHENS_PROXY_PASSWORD — the HTTP basic auth username and password for this instance
  • ATHENS_PROXY_URL — the HTTPS proxy URL, https://<instance-public-ip>/
  • a ready to paste GOPROXY example

Keep this file secret; it is the credential for your private module proxy.

Step 5: Confirm the proxy is running

Athens runs as a systemd service bound to 127.0.0.1:3000 only, with nginx terminating TLS on port 443 as the single network facing surface. Confirm both services are active and that Athens is listening on loopback only:

systemctl is-active athens.service nginx.service
sudo ss -ltnp | grep -E ':3000|:443'
/opt/athens/athens -version

Athens and nginx both active, with Athens bound to 127.0.0.1:3000 (loopback only) and nginx listening on port 443, and the Athens 0.18.1 version banner

Athens is listening on 127.0.0.1:3000 and never on a public interface; nginx owns port 443. This is what keeps the proxy from being an open module relay.

Step 6: Verify the authentication boundary

nginx fronts the entire proxy with HTTP basic authentication, so an unauthenticated request is rejected while an authenticated request serves the module protocol. An unauthenticated /healthz probe is available for load balancers. Substitute the username and password from your credentials file:

# no credentials -> 401 Unauthorized (the proxy is never open)
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/rsc.io/quote/@v/list

# with the per instance credentials -> 200 and the list of module versions
curl -sk -u "$ATHENS_PROXY_USER:$ATHENS_PROXY_PASSWORD" https://127.0.0.1/rsc.io/quote/@v/list

# unauthenticated load-balancer liveness probe -> 200
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/healthz

An unauthenticated proxy request returning 401 Unauthorized, the same request with the per instance basic auth credentials returning the list of rsc.io/quote module versions, and the unauthenticated healthz probe returning 200

Step 7: Point the go command at your proxy

On each workstation and CI agent, trust this instance's self signed certificate and set GOPROXY to the authenticated HTTPS URL. First copy the certificate off the instance (it is served at /etc/nginx/tls/athens.crt), then:

# trust this instance's certificate (or add it to your system trust store)
export SSL_CERT_FILE=/path/to/athens.crt

# point the go toolchain at your private Athens proxy
export GOPROXY="https://<user>:<password>@<public-ip>/"
export GOSUMDB=off

# every module now flows through Athens and is cached on the instance
go mod download rsc.io/quote@v1.5.2

The first time a module version is requested, Athens fetches it from the upstream Go mirror (falling back to the module's version control host), stores it in its on disk cache on the data volume, and serves it. Every later request for that version is served straight from the cache. You can confirm the module landed in the cache and that the cache is on the dedicated data volume:

ls -la /var/lib/athens/storage/rsc.io/quote/v1.5.2/
df -h /var/lib/athens

go mod download fetching rsc.io/quote@v1.5.2 through Athens over TLS, the cached go.mod, source.zip and info files listed under /var/lib/athens/storage, and df confirming the module cache is on the dedicated data volume mounted at /var/lib/athens

To roll the proxy out across a team, set the same GOPROXY and SSL_CERT_FILE on every developer machine and CI runner. For production use, replace the self signed certificate with one signed by your own certificate authority or a public CA for your domain, and place the instance behind a load balancer if you need horizontal scale.

Configuration and data layout

Path Purpose
/opt/athens/athens The Athens binary
/etc/athens/config.toml Athens configuration (loopback bind, disk storage, upstream mirror)
/var/lib/athens/storage The on disk module cache, on the dedicated data volume
/etc/nginx/sites-available/cloudimg-athens The nginx reverse proxy and TLS configuration
/etc/nginx/tls/athens.crt and athens.key The per instance self signed certificate and key
/etc/nginx/athens.htpasswd The per instance basic auth password file
/root/athens-aws-credentials.txt The generated per instance credentials (mode 0600)

To change the upstream module source, worker counts or storage settings, edit /etc/athens/config.toml and run sudo systemctl restart athens.service. To change the proxy password, update /etc/nginx/athens.htpasswd with htpasswd and run sudo systemctl reload nginx.

Support

This Athens image is supported 24/7 by cloudimg. For deployment help, GOPROXY rollout across teams and CI, upstream and fallback proxy configuration, nginx TLS with your own domain and certificate, module cache sizing, Athens version upgrades, or any other question, contact support@cloudimg.co.uk. Critical issues receive a one hour average response time.

Athens is a trademark of its respective owner. This is a repackaged open source software product with additional charges for cloudimg support services.