Hockeypuck reads configuration from a TOML-format configuration file, which should be supplied on the command line using the `-c` flag. This file is preprocessed as a Go template (See Templating below).
[hockeypuck] contact="DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" hostname="keys.example.com" nodename="node1.keys.example.com" enableVhosts=true
These settings are displayed on the stats page (/pks/lookup?op=stats).
contact should contain the full fingerprint of the keyserver administrator.hostname should be set to the external hostname of the server. This may differ from the system hostname, if reverse-proxied. (defaults to the system hostname)nodename may be used to identify a particular node in a load-balancing pool. (defaults to the system hostname)enableVHosts instructs Hockeypuck to report the HTTP/1.1 virtual host in the status page. (default false)[hockeypuck] logfile="/path/to/logfile" loglevel=<one of: DEBUG,INFO,WARNING,ERROR,FATAL,PANIC>
If not configured, hockeypuck will log INFO level messages and higher severity to standard error.
Hockeypuck will serve static files from / out of the webroot path, so long as
the path names do not conflict with HKP routed requests (like /pks/lookup).
[hockeypuck] webroot="/path/to/www/files"
index.html will be served by default if the path resolves to a directory and the file exists.
By default, Hockeypuck will respond to HKP operations op=index, op=vindex
and op=stats with an application/json response. The underlying
structs for these responses can be used in HTML templates of your own design
to customize the output.
Specify these templates with:
[hockeypuck] indexTemplate="/path/to/template" vindexTemplate="/path/to/template" statsTemplate="/path/to/template"
The path must be to a file containing a valid Go html/template.
indexTemplate and vindexTemplate operate on a struct containing two top-level fields,
.Query, an instance of the hkp.Lookup request parameters..Keys, a slice of jsonhkp.PrimaryKey model structs.
statsTemplate operates on an instance of sks.Stats.
See the packaged templates for an example.
[hockeypuck]
adminKeys=[
"DECAFBADDECAFBADDECAFBADDECAFBADDECAFBAD",
]
The listed fingerprints identify keys that may sign administration requests for this server. It is strongly recommended that the server contact advertised on the stats page (see above) is not one of the admin keys.
Currently, administration requests are restricted to key deletion and key replacement. See Remote Administration for details.
[hockeypuck.hkp] bind=":11371" advertisedBind="keys.example.com:80" logRequestDetails=false
bind identifies the HKP port that Hockeypuck should listen on, in host:port formatadvertisedBind is the bind value reported on the stats page. It defaults to the value of bindlogRequestDetails indicates whether Hockeypuck should log HKP requests; a public keyserver may not wish to log these for privacy reasons[hockeypuck.hkp.queries] selfSignedOnly=false keywordSearchDisabled=false
selfSignedOnly serves only self-signatures, and drops third-party signatures. (default false)keywordSearchDisabled only allows fingerprint and key ID queries - email addresses or full text searches are disabled. (default false)If this section is populated, Hockeypuck will listen on HKPS.
[hockeypuck.hkps] bind=":443" logRequestDetails=false cert="/path/to/cert" key="/path/to/key"
bind identifies the HKPS port that Hockeypuck should listen on, in host:port formatlogRequestDetails has the same meaning as for HKP above.cert and key identify the certificate and key files for use by TLS.[hockeypuck.openpgp]
maxPacketLength=8192
maxKeyLength=1048576
blacklist=[
# "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF",
]
nworkers=8
maxPacketLength indicates the maximum size of a packet that is accepted by the OpenPGP enginemaxKeyLength indicates the maximum total size of a key that is accepted by the OpenPGP engineblacklist contains a list of key fingerprints that are not accepted by this server. This may be for abuse reasons, or because the key owner has requested their deletion.nworkers is the number of worker threads (default 8)PostgreSQL >= 9.5 is required for use with Hockeypuck. Some fields are broken out into separate columns for indexing. For details, refer to the PostgreSQL storage backend, pghkp/storage.go. Hockeypuck has been tested with versions of PostgreSQL up to and including 16.
To use PostgreSQL:
[hockeypuck.openpgp.db] driver="postgres-jsonb" dsn="database=hkp host=/var/run/postgresql port=5432 sslmode=disable"
See the pq driver package documentation for details on how to construct the connection string.
The headers added to the ASCII-armored output can be optionally customised.
[hockeypuck.openpgp.headers] comment="Hockeypuck" version="2.2.0"
comment is the contents of the "Comment" field. (default empty)version is the contents of the "Version" field. (default empty)Hockeypuck supports the SKS synchronisation protocol. SKS consists of two interlinked protocols, "recon" and "recovery". Recon is initiated unidirectionally, and identifies differences between the datasets of the two servers based on hash digests of the entries. Recovery takes place bidirectionally after recon is complete, and transfers the actual differences in the datasets.
Recon is handled by the conflux package, which then initiates recovery over HKP.
[hockeypuck.conflux.recon] httpAddr=":11371" reconAddr=":11370" allowCIDRs=["127.0.0.1/8"] filters=["preProduction"] seenCacheSize=256 gossipIntervalSecs=60 maxOutstandingReconRequests=100 logname="conflux.recon"
httpAddr determines the recovery address that will be advertised in the recon protocol. (default ":11371")reconAddr determines the listen address for the recon server. (default ":11370")allowCIDRs is a list of network addresses in CIDR format that are allowed to initiate recon with this server, despite not being listed as partners.filters are labels that indicate how the dataset has been processed.filters is a list of additional labels that is appended to the hard-coded list.
They can be used to prevent sync between different server pools, e.g. a pre-production and production pool. (default empty)seenCacheSize is the size of the LRU cache used to minimise repeated requests for the same entries on remote partners.256)gossipIntervalSecs is the number of seconds to wait between recon attempts. (default 60)maxOutstandingReconRequests is the number of total recon connections to keep open. (default 100)logname is the name used when the conflux module emits logs. (default "conflux.recon")[hockeypuck.conflux.recon.partner.peer1] httpAddr="keys.example.com:11371" reconAddr="keys.example.com:11370" [hockeypuck.conflux.recon.partner.peer2] httpAddr="juju-azure-dev-y9157oo521.cloudapp.net:11371" reconAddr="juju-azure-dev-y9157oo521.cloudapp.net:11370" ...
Create a section for each partner [hockeypuck.conflux.recon.partner.NAME],
where NAME contains only characters from [A-Za-z0-9_].
Each partner section must include a httpAddr and a reconAddr entry, in host:port format.
These are usually the same host, but they might differ, especially if the HKP service is reverse-proxied.
[hockeypuck.conflux.recon.leveldb] path="/path/to/prefix/tree"
The prefix tree is used to keep track of which keys the peer has, for synchronization purposes.
path should be a writeable directory that already exists.Hockeypuck exposes a metrics endpoint for aggregation by Prometheus.
[hockeypuck.metrics] metricsAddr=":9626" metricsPath="/metrics"
metricsAddr is the address that the Hockeypuck metrics service will listen on, in host:port format. (default ":9626")metricsPath is the endpoint path at which the metrics will be served. (default "/metrics")The configuration file supports templating using the Go text/template package with Sprig extensions. The template is rendered before the configuration file is parsed, so the configuration file can contain environment variables.
For example, setting the database configuration to use environment variables:
[hockeypuck.openpgp.db]
driver="postgres-jsonb"
dsn="database=hkp host=postgres user={{ .POSTGRES_USER }} password={{ .POSTGRES_PASSWORD }} port=5432 sslmode=disable"
You can also use the osenv custom function to read environment variables by prefix:
{{ range $key, $value := osenv "HKP_" }}
{{ $key }}={{ $value }}
{{ end }}Sprig extensions are powerful, and can be used to construct quite complex configuration files. For example, given an environment variable:
GOSSIP_PEERS='{"ks1_example_com": {"httpAddr": "ks1.example.com:11371", "reconAddr": "ks1.example.com:11370"},'\
'"ks2_example_com": {"httpAddr": "ks2.example.com:11371", "reconAddr": "ks2.example.com:11370"}}'We can populate the list of recon partners by parsing it as JSON and iterating over the resulting structure:
{{- if .GOSSIP_PEERS }}
{{- range $name, $peer := fromJson .GOSSIP_PEERS }}
[hockeypuck.conflux.recon.partner.{{ $name }}]
httpAddr="{{ $peer.httpAddr }}"
reconAddr="{{ $peer.reconAddr }}"
{{- end }}
{{- end }}