Git Product home page Git Product logo

gokeyless's Introduction

Go Keyless

Go Test GoDoc codecov

Go Keyless is an implementation Cloudflare's Keyless SSL Protocol in Go. It is provided as an upgrade to the previous C implementation.

Installing

Package Installation

Instructions for installing Go Keyless from .deb and .rpm packages can be found at https://pkg.cloudflare.com. Packages and binaries are also available from Github Releases, with the caveat that there's no auto update mechanism built in.

Key Management

The Keyless SSL server is a TLS server and therefore requires cryptographic keys. All requests are mutually authenticated, so both the client and the server need a TLS 1.2 compatible key pair. The client must present a client certificate that can be verified against the CA that the keyless server is configured to use. This process can be automated using a cloudflare Origin CA API Key - see the documentation for examples.

Supported Key stores

Directory

A directory containing private keys with a .key extension in either PEM or DER format

private_key_stores:
    - dir: etc/private-keys/

Full instructions: https://developers.cloudflare.com/ssl/keyless-ssl/configuration/public-dns/#populate-keys

PKCS #11 Compatable HSM

Private keys can also be stored on a Hardware Security Module. Keyless can access such a key using a PKCS #11 URI in the configuration file. Here are some examples of URIs for keys stored on various HSM providers:

private_key_stores:
    - uri: pkcs11:token=SoftHSM2%20RSA%20Token;id=%03?module-path=/usr/lib64/libsofthsm2.so&pin-value=1234
    - uri: pkcs11:token=accelerator;object=thaleskey?module-path=/opt/nfast/toolkits/pkcs11/libcknfast.so
    - uri: pkcs11:token=YubiKey%20PIV;id=%00?module-path=/usr/lib64/libykcs11.so&pin-value=123456&max-sessions=1
    - uri: pkcs11:token=SoftHSM2%20RSA%20Token;id=%03?module-path=/usr/lib64/libsofthsm2.so&pin-value=1234
    - uri: pkcs11:token=elab2parN;id=%04?module-path=/usr/lib/libCryptoki2_64.so&pin-value=crypto1

Note you must provide exactly one of the token, serial, or slot-id attributes to identify the token.

Full instructions: https://developers.cloudflare.com/ssl/keyless-ssl/hardware-security-modules#communicating-using-pkcs11

Azure Key Vault or Managed HSM

note: support added in v1.6.4

Private keys can also be stored in Azure's key management offerings.

private_key_stores:
    - uri: https://keyless-hsm-1.managedhsm.azure.net/keys/keyless-a/256400ae07e74327b5d233c15aea837
    - uri: https://keyless-vault-1.vault.azure.net/keys/keyless-b/d791e7f42b3a4f3ea8acc65014ea6a95

If gokeyless is running in a VM with Managed Services enabled, auth works out of the box. Otherwise, credentials can also be specified with an env var containing the path to a file. (env vars are defined here) The required roles are /keys/read/action and /keys/sign/action

Full instructions: https://developers.cloudflare.com/ssl/keyless-ssl/hardware-security-modules/azure-managed-hsm

Google Cloud KMS or Cloud HSM

note: support added in v1.6.4

Private keys can also be stored in Google Cloud's key management offerings

private_key_stores:
    - uri: projects/abc/locations/us-west1/keyRings/xyz/cryptoKeys/example-key/cryptoKeyVersions/3

Application Default Credentials are supported, the required IAM role is roles/cloudkms.signerVerifier

Full instructions: https://developers.cloudflare.com/ssl/keyless-ssl/hardware-security-modules/google-cloud-hsm

Running

The keyserver for Keyless SSL consists of a single binary file, gokeyless. When you run the binary, it will first check for a gokeyless.yaml file in the current working directory, falling back to the system wide file located at /etc/keyless/gokeyless.yaml (the default configuration file will be placed there if you install via one of the .deb or .rpm packages).

You should add your Cloudflare account details to the configuration file, and optionally customize the location of the private key directory. Most users should not need to modify the remaining defaults.

Each option can optionally be overridden via environment variables or command-line arguments. Run gokeyless -h to see the full list of available options.

Running using Docker Image

A docker image is published that contains a built binary file and startup instruction for the gokeyless process. An example of the usage of this docker file is in docker-compose.example.yaml

This examples shows how you may provide the same configuration options through environment variables and provide a mount with a directory for private keys instead of through a gokeyless.yaml file.

Testing

Unit tests and benchmarks have been implemented for various parts of Go Keyless via go test. Most of the tests run out of the box, but some setup is necessary to run the HSM-related tests:

  1. Follow https://wiki.opendnssec.org/display/SoftHSMDOCS/SoftHSM+Documentation+v2 to install SoftHSM2. On MacOS, the easiest is brew isntall softhsm
  2. Copy the test tokens to the location of your SoftHSM2 token directory (commonly /var/lib/softhsm/tokens, but may vary):
cp -r tests/testdata/tokens/* /opt/homebrew/var/lib/softhsm/tokens/
  1. The tests currently assume the SoftHSM2 library will be installed at /usr/lib/softhsm/libsofthsm2.so. If your system differs, SOFTHSM_MODULE_DIR env var can override that.

e.g. on MacOS with softhsm from brew: SOFTHSM_MODULE_DIR=/opt/homebrew/opt/softhsm/lib/softhsm/libsofthsm2.so make test

Note that if you need to run the tests without first configuring SoftHSM2 for some reason, you can use the test-nohsm target.

License

See the LICENSE file for details. Note: the license for this project is not 'open source' as described in the Open Source Definition.

gokeyless's People

Contributors

bjorand avatar bren2010 avatar bvwells avatar cbroglie avatar cjpatton avatar dependabot[bot] avatar dvrkps avatar elithrar avatar filosottile avatar ghedo avatar gliptak avatar grittygrease avatar jbampton avatar jkroll-cf avatar joshlf avatar jyn514 avatar kisom avatar lekensteyn avatar lgarofalo avatar lziest avatar mattbostock avatar mitalirawat avatar nickysemenza avatar sadpencil avatar tmthrgd avatar wbl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gokeyless's Issues

Panic with SoftHSM2 on CentOS 8

> cat /etc/centos-release 
CentOS Stream release 8
execve("/usr/local/bin/gokeyless", ["gokeyless", "-c", "/root/test.yaml"], 0x7fffcfea69c0 /* 29 vars */) = 0
brk(NULL)                               = 0x32f2000
brk(0x32f31c0)                          = 0x32f31c0
arch_prctl(ARCH_SET_FS, 0x32f2880)      = 0
uname({sysname="Linux", nodename="REDACTED", ...}) = 0
set_tid_address(0x32f2b50)              = 143463
set_robust_list(0x32f2b60, 24)          = 0
rt_sigaction(SIGRTMIN, {sa_handler=0xb419e0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0xb41a80, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
readlink("/proc/self/exe", "/usr/local/bin/gokeyless", 4096) = 24
brk(0x33141c0)                          = 0x33141c0
brk(0x3315000)                          = 0x3315000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
sched_getaffinity(0, 8192, [0])         = 8
openat(AT_FDCWD, "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", O_RDONLY) = 3
read(3, "2097152\n", 20)                = 8
close(3)                                = 0
mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f180223a000
mmap(NULL, 131072, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f180221a000
mmap(NULL, 1048576, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f180211a000
mmap(NULL, 8388608, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f180191a000
mmap(NULL, 67108864, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17fd91a000
mmap(NULL, 536870912, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17dd91a000
mmap(0xc000000000, 67108864, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc000000000
mmap(NULL, 33554432, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17db91a000
mmap(NULL, 2165776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17db709000
mmap(0xc000000000, 4194304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xc000000000
mmap(0x7f180221a000, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f180221a000
mmap(0x7f180219a000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f180219a000
mmap(0x7f1801d20000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f1801d20000
mmap(0x7f17ff94a000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f17ff94a000
mmap(0x7f17eda9a000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f17eda9a000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17db609000
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17db5f9000
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17db5e9000
rt_sigprocmask(SIG_SETMASK, NULL, [], 8) = 0
sigaltstack(NULL, {ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}) = 0
sigaltstack({ss_sp=0xc000002000, ss_flags=0, ss_size=32768}, NULL) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
gettid()                                = 143463
rt_sigaction(SIGHUP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGHUP, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGINT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGQUIT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGQUIT, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGILL, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGILL, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGTRAP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTRAP, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGABRT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGABRT, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGBUS, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGBUS, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGFPE, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGFPE, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGUSR1, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGUSR1, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGSEGV, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGSEGV, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGUSR2, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGUSR2, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGPIPE, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGALRM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGALRM, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGTERM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTERM, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGSTKFLT, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGSTKFLT, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGCHLD, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGURG, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGURG, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGXCPU, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGXCPU, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGXFSZ, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGXFSZ, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGVTALRM, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGVTALRM, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGPROF, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGPROF, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGWINCH, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGWINCH, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGIO, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGIO, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGPWR, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGPWR, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGSYS, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGSYS, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRTMIN, NULL, {sa_handler=0xb419e0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0xb40fb0}, 8) = 0
rt_sigaction(SIGRTMIN, NULL, {sa_handler=0xb419e0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0xb40fb0}, 8) = 0
rt_sigaction(SIGRTMIN, {sa_handler=0xb419e0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, NULL, {sa_handler=0xb41a80, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, 8) = 0
rt_sigaction(SIGRT_1, NULL, {sa_handler=0xb41a80, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0xb41a80, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_2, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_3, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_3, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_4, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_4, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_5, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_5, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_6, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_6, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_7, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_7, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_8, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_8, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_9, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_9, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_10, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_10, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_11, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_11, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_12, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_12, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_13, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_13, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_14, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_14, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_15, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_15, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_16, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_16, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_17, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_17, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_18, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_18, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_19, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_19, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_20, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_20, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_21, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_21, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_22, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_22, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_23, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_23, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_24, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_24, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_25, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_25, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_26, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_26, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_27, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_27, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_28, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_28, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_29, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_29, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_30, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_30, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_31, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_31, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigaction(SIGRT_32, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGRT_32, {sa_handler=0x468f80, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0xb40fb0}, NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f17dade8000
mprotect(0x7f17dade9000, 8388608, PROT_READ|PROT_WRITE) = 0
clone(child_stack=0x7f17db5e7e70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tid=[143464], tls=0x7f17db5e8700, child_tidptr=0x7f17db5e89d0) = 143464
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f17da5e7000
mprotect(0x7f17da5e8000, 8388608, PROT_READ|PROT_WRITE) = 0
clone(child_stack=0x7f17dade6e70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tid=[143465], tls=0x7f17dade7700, child_tidptr=0x7f17dade79d0) = 143465
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
futex(0x16b2650, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x16b2650, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f17d9de6000
mprotect(0x7f17d9de7000, 8388608, PROT_READ|PROT_WRITE) = 0
clone(child_stack=0x7f17da5e5e70, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tid=[143466], tls=0x7f17da5e6700, child_tidptr=0x7f17da5e69d0) = 143466
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
fcntl(0, F_GETFL)                       = 0x2 (flags O_RDWR)
mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17d9da6000
fcntl(1, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(2, F_GETFL)                       = 0x2 (flags O_RDWR)
readlinkat(AT_FDCWD, "/proc/self/exe", "/usr/local/bin/gokeyless", 128) = 24
openat(AT_FDCWD, "/usr/local/bin/gokeyless", O_RDONLY|O_CLOEXEC) = 3
epoll_create1(EPOLL_CLOEXEC)            = 4
pipe2([5, 6], O_NONBLOCK|O_CLOEXEC)     = 0
epoll_ctl(4, EPOLL_CTL_ADD, 5, {events=EPOLLIN, data={u32=24020784, u64=24020784}}) = 0
epoll_ctl(4, EPOLL_CTL_ADD, 3, {events=EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, data={u32=3655006040, u64=139740415981400}}) = -1 EPERM (Operation not permitted)
fstat(3, {st_mode=S_IFREG|0755, st_size=17493528, ...}) = 0
pread64(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\2\0>\0\1\0\0\0p\v@\0\0\0\0\0"..., 64, 0) = 64
pread64(3, "\211|$XH\211D$(H\211\\$HH\213\227`\1\0\0H\213\267X\1\0\0L\213\207h"..., 64, 2186691) = 64
pread64(3, "\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314\314L\215d$\370M"..., 64, 4373382) = 64
pread64(3, "L\211\300\353\276L\211\300\353\233M\205\300\351u\377\377\377\17\37D\0\0\350;4\237\377H\213\204$"..., 64, 6560073) = 64
pread64(3, "\0\0\0\0(:{\10\2\10\10\27\0\0\0\0\0\0\0\0 )\353\0\0\0\0\0\32\177\1\0"..., 64, 8746764) = 64
pread64(3, "\0\35\0\0\0>\0\0\0\262\237\7\0.\0\0\0\4\0\0\0\36\0\0\0\231\0\0\0\367\237\7"..., 64, 10933455) = 64
pread64(3, "\6\v\0050\10\n\7k\n$\t\1\f\1\2\f\ri\0\2\16\240\1\274\1\237\1\1\240\1\241\2"..., 64, 13120146) = 64
pread64(3, "\3\0\0\0\0\0\6\0\261\6\0\17\261\6\0\0\0\0\08\201\337\0\0\0\0\0\260\207\337\0\0"..., 64, 15306837) = 64
close(3)                                = 0
getpid()                                = 143463
newfstatat(AT_FDCWD, "/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}, 0) = 0
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x16b2650, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x16b2650, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x16b2650, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x16b2650, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x16b2650, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17d9d66000
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0xc000054950, FUTEX_WAKE_PRIVATE, 1) = 1
openat(AT_FDCWD, "/root/test.yaml", O_RDONLY|O_CLOEXEC) = 3
epoll_ctl(4, EPOLL_CTL_ADD, 3, {events=EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, data={u32=3655006040, u64=139740415981400}}) = -1 EPERM (Operation not permitted)
fstat(3, {st_mode=S_IFREG|0644, st_size=1320, ...}) = 0
read(3, "# Set the log level (0 = DEBUG, "..., 1832) = 1320
read(3, "", 512)                        = 0
futex(0x16b2650, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0x16e9c88, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x16b2650, FUTEX_WAIT_PRIVATE, 0, NULL2023/05/11 04:54:19 [INFO] loading /etc/keyless/keys/REDACTED.key...
2023/05/11 04:54:19 [DEBUG] add signer with SKI: REDACTED(https://crt.sh/?ski=REDACTED)
2023/05/11 04:54:19 [INFO] loading pkcs11:token=test;id=%a0%00?module-path=/usr/lib64/libsofthsm2.so&pin-value=1335&max-sessions=1...
) = 0
madvise(0xc000400000, 2097152, MADV_NOHUGEPAGE) = 0
madvise(0xc0004d6000, 8192, MADV_DONTNEED) = 0
write(6, "\0", 1)                       = 1
epoll_pwait(4, fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0xc8 pc=0x7f17cbc825d2]

runtime stack:
runtime.throw({0xdd4917, 0x1e8})
        /usr/lib/go-1.17/src/runtime/panic.go:1198 +0x71
runtime.sigpanic()
        /usr/lib/go-1.17/src/runtime/signal_unix.go:719 +0x396

goroutine 1 [syscall]:
runtime.cgocall(0xb3a9d0, 0xc00063fa60)
        /usr/lib/go-1.17/src/runtime/cgocall.go:156 +0x5c fp=0xc00063fa38 sp=0xc00063fa00 pc=0x4040fc
github.com/miekg/pkcs11._Cfunc_Initialize(0x7f17c4000b50)
        _cgo_gotypes.go:1204 +0x49 fp=0xc00063fa60 sp=0xc00063fa38 pc=0xac2129
github.com/miekg/pkcs11.(*Ctx).Initialize.func1(0xc0003a0301)
        /go/tmp/vendor/github.com/miekg/pkcs11/pkcs11.go:805 +0x3a fp=0xc00063fa98 sp=0xc00063fa60 pc=0xac533a
github.com/miekg/pkcs11.(*Ctx).Initialize(0xc0000729ce)
        /go/tmp/vendor/github.com/miekg/pkcs11/pkcs11.go:805 +0x19 fp=0xc00063fab0 sp=0xc00063fa98 pc=0xac52b9
github.com/ThalesIgnite/crypto11.Configure(0xc000388720)
        /go/tmp/vendor/github.com/ThalesIgnite/crypto11/crypto11.go:301 +0x397 fp=0xc00063fbb8 sp=0xc00063fab0 pc=0xadc257
github.com/cloudflare/gokeyless/internal/rfc7512.LoadPKCS11Signer(0xc0000aa480)
        /go/tmp/internal/rfc7512/rfc7512.go:206 +0x113 fp=0xc00063fc00 sp=0xc00063fbb8 pc=0xae98b3
github.com/cloudflare/gokeyless/server.DefaultLoadURI({0xc0000729a0, 0x65})
        /go/tmp/server/pkcs11.go:23 +0x77 fp=0xc00063fc48 sp=0xc00063fc00 pc=0xb28477
github.com/cloudflare/gokeyless/server.loadPKCS11URI(...)
        /go/tmp/server/pkcs11.go:31
github.com/cloudflare/gokeyless/server.(*DefaultKeystore).AddFromURI(0xc00037ea08, {0xc0000729a0, 0x65})
        /go/tmp/server/keystore.go:104 +0xb8 fp=0xc00063fcb0 sp=0xc00063fc48 pc=0xb270b8
main.initKeyStore()
        /go/tmp/cmd/gokeyless/gokeyless.go:330 +0xed fp=0xc00063fd38 sp=0xc00063fcb0 pc=0xb35cad
main.main()
        /go/tmp/cmd/gokeyless/gokeyless.go:289 +0x8eb fp=0xc00063ff80 sp=0xc00063fd38 pc=0xb3564b
runtime.main()
        /usr/lib/go-1.17/src/runtime/proc.go:255 +0x227 fp=0xc00063ffe0 sp=0xc00063ff80 pc=0x438de7
runtime.goexit()
        /usr/lib/go-1.17/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc00063ffe8 sp=0xc00063ffe0 pc=0x467401

goroutine 9 [select]:
go.opencensus.io/stats/view.(*worker).start(0xc0000d8b80)
        /go/tmp/vendor/go.opencensus.io/stats/view/worker.go:276 +0xb9
created by go.opencensus.io/stats/view.init.0
        /go/tmp/vendor/go.opencensus.io/stats/view/worker.go:34 +0x92
 <unfinished ...>)       = ?
+++ exited with 2 +++

Configure gokeyless during package installation

Currently, when installing via the Debian package (the pkg directory), the gokeyless service is started without having been configured. The gokeyless program itself notices this, and prompts for a configuration, but of course it's run as a service, so there's nothing attached to stdin.

Instead, we should explicitly use an interactive installation process in which the user is prompted to either configure during the installation process or else the service won't be started, pending them running the configuration manually.

Open question: Is this also an issue with RPM? Probably.

Support reading pin from file or environment variable

In the initial release I intentionally left pin-source untouched:

case "pin-source":
pk11uri.PinSource = value

I propose the following format:

  • Read from a file: pin-source=file:/secrets/mypin
  • Read from environment variable: pin-source=env:MYPIN

Alternatively I can have pin-source directly read from a file and add a pin-env attribute for environment variables. Any thoughts?

Also, in the event that both pin-source (or pin-env) and pin-value are defined, which should take priority?

Remote interface could have an additional method: PingAll()

PingAll() basically dials all ip addresses for a given remote at one time to determine if there is at least one usable established connection. This would be useful for proxying requests through a extremely unreliable network to a upstream keyserver cluster.

Seperate Out Debug Logging

Add more fine-grained logging, with levels for silent mode, normal usage, verbose, and debugging.

Maybe just import github.com/clouflare/cfssl/log

initialization process panics on ubuntu cgo call

2023/05/10 17:13:22 [INFO] received CSR
2023/05/10 17:13:22 [INFO] generating key: ecdsa-384
2023/05/10 17:13:22 [INFO] encoded CSR
2023/05/10 17:13:22 [INFO] key is generated and saved to server-key.pem
2023/05/10 17:13:22 [INFO] csr is generated and saved to server.csr
2023/05/10 17:13:22 [INFO] contacting Cloudflare API for CSR signing
2023/05/10 17:13:22 [INFO] making API call: https://api.cloudflare.com/client/v4/certificates/
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x233b0 pc=0x233b0]

runtime stack:
runtime.throw({0xdd4917, 0x1})
	/usr/lib/go-1.17/src/runtime/panic.go:1198 +0x71
runtime.sigpanic()
	/usr/lib/go-1.17/src/runtime/signal_unix.go:719 +0x396

goroutine 21 [syscall]:
runtime.cgocall(0xb37f80, 0xc00004f590)
	/usr/lib/go-1.17/src/runtime/cgocall.go:156 +0x5c fp=0xc00004f568 sp=0xc00004f530 pc=0x4040fc
net._C2func_getaddrinfo(0xc000038390, 0x0, 0xc00038dbc0, 0xc0000101c8)
	_cgo_gotypes.go:91 +0x56 fp=0xc00004f590 sp=0xc00004f568 pc=0x5b96f6
net.cgoLookupIPCNAME.func1({0xc000038390, 0x0, 0x0}, 0xc000038120, 0xc00004f650)
	/usr/lib/go-1.17/src/net/cgo_unix.go:163 +0x9f fp=0xc00004f5e8 sp=0xc00004f590 pc=0x5bb43f
net.cgoLookupIPCNAME({0xdae0aa, 0x3}, {0xc000038120, 0x5})
	/usr/lib/go-1.17/src/net/cgo_unix.go:163 +0x16d fp=0xc00004f738 sp=0xc00004f5e8 pc=0x5bac8d
net.cgoIPLookup(0x16b0a70, {0xdae0aa, 0xc000038138}, {0xc000038120, 0xc0001c7290})
	/usr/lib/go-1.17/src/net/cgo_unix.go:220 +0x3b fp=0xc00004f7a8 sp=0xc00004f738 pc=0x5bb4fb
net.cgoLookupIP·dwrap·25()
	/usr/lib/go-1.17/src/net/cgo_unix.go:230 +0x36 fp=0xc00004f7e0 sp=0xc00004f7a8 pc=0x5bb976
runtime.goexit()
	/usr/lib/go-1.17/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc00004f7e8 sp=0xc00004f7e0 pc=0x467401
created by net.cgoLookupIP
	/usr/lib/go-1.17/src/net/cgo_unix.go:230 +0x125

goroutine 1 [select]:
net/http.(*Transport).getConn(0x163b4c0, 0xc0002be300, {{}, 0x0, {0xdda70b, 0x5}, {0xc000038120, 0x16}, 0x0})
	/usr/lib/go-1.17/src/net/http/transport.go:1372 +0x5d2
net/http.(*Transport).roundTrip(0x163b4c0, 0xc0000e2200)
	/usr/lib/go-1.17/src/net/http/transport.go:581 +0x774
net/http.(*Transport).RoundTrip(0x30, 0xebf0a0)
	/usr/lib/go-1.17/src/net/http/roundtrip.go:18 +0x19
net/http.send(0xc0000e2200, {0xebf0a0, 0x163b4c0}, {0xd922e0, 0xc000042a01, 0x0})
	/usr/lib/go-1.17/src/net/http/client.go:252 +0x5d8
net/http.(*Client).send(0xc00038cf00, 0xc0000e2200, {0x16b1ae0, 0xc000042a10, 0x0})
	/usr/lib/go-1.17/src/net/http/client.go:176 +0x9b
net/http.(*Client).do(0xc00038cf00, 0xc0000e2200)
	/usr/lib/go-1.17/src/net/http/client.go:725 +0x908
net/http.(*Client).Do(...)
	/usr/lib/go-1.17/src/net/http/client.go:593
main.initAPICall({0xc0000b2160, 0xae}, {0xc00019de90, 0xc00063fce8}, {0xc000041e00, 0x1}, {0xc000018000, 0x3})
	/go/tmp/cmd/gokeyless/initialize.go:62 +0x225
main.initializeServerCertAndKey()
	/go/tmp/cmd/gokeyless/initialize.go:135 +0x346
main.main()
	/go/tmp/cmd/gokeyless/gokeyless.go:237 +0x393

goroutine 9 [select]:
go.opencensus.io/stats/view.(*worker).start(0xc0000e0b80)
	/go/tmp/vendor/go.opencensus.io/stats/view/worker.go:276 +0xb9
created by go.opencensus.io/stats/view.init.0
	/go/tmp/vendor/go.opencensus.io/stats/view/worker.go:34 +0x92

goroutine 19 [select]:
net.(*Resolver).lookupIPAddr(0x16b0a60, {0xed47f8, 0xc00038e8a0}, {0xdae0aa, 0xc00007e0f0}, {0xc000038120, 0x12})
	/usr/lib/go-1.17/src/net/lookup.go:302 +0x5c7
net.(*Resolver).internetAddrList(0xed47f8, {0xed47f8, 0xc00038e8a0}, {0xdae0aa, 0x3}, {0xc000038120, 0x16})
	/usr/lib/go-1.17/src/net/ipsock.go:288 +0x67a
net.(*Resolver).resolveAddrList(0x16e87d0, {0xed47f8, 0xc00038e8a0}, {0xdae694, 0x4}, {0xdae0aa, 0x0}, {0xc000038120, 0x16}, {0x0, ...})
	/usr/lib/go-1.17/src/net/dial.go:221 +0x41b
net.(*Dialer).DialContext(0xc000074240, {0xed47c0, 0xc0000360c8}, {0xdae0aa, 0x7f26a891e438}, {0xc000038120, 0x118})
	/usr/lib/go-1.17/src/net/dial.go:406 +0x448
net/http.(*Transport).dial(0x0, {0xed47c0, 0xc0000360c8}, {0xdae0aa, 0x0}, {0xc000038120, 0x0})
	/usr/lib/go-1.17/src/net/http/transport.go:1166 +0xda
net/http.(*Transport).dialConn(0x163b4c0, {0xed47c0, 0xc0000360c8}, {{}, 0x0, {0xdda70b, 0x5}, {0xc000038120, 0x16}, 0x0})
	/usr/lib/go-1.17/src/net/http/transport.go:1604 +0x845
net/http.(*Transport).dialConnFor(0x0, 0xc0001c7290)
	/usr/lib/go-1.17/src/net/http/transport.go:1446 +0xb0
created by net/http.(*Transport).queueForDial
	/usr/lib/go-1.17/src/net/http/transport.go:1415 +0x3d7

goroutine 20 [select]:
net.cgoLookupIP({0xed4788, 0xc0002be480}, {0xdae0aa, 0x12}, {0xc000038120, 0x0})
	/usr/lib/go-1.17/src/net/cgo_unix.go:231 +0x1b7
net.(*Resolver).lookupIP(0x16b0a60, {0xed4788, 0xc0002be480}, {0xdae0aa, 0x3}, {0xc000038120, 0x12})
	/usr/lib/go-1.17/src/net/lookup_unix.go:97 +0x128
net.glob..func1({0xed4788, 0xc0002be480}, 0x0, {0xdae0aa, 0x0}, {0xc000038120, 0x6afa10})
	/usr/lib/go-1.17/src/net/hook.go:23 +0x3d
net.(*Resolver).lookupIPAddr.func1()
	/usr/lib/go-1.17/src/net/lookup.go:296 +0x9f
internal/singleflight.(*Group).doCall(0x16b0a70, 0xc00007e410, {0xc000038138, 0x16}, 0xc0001c7290)
	/usr/lib/go-1.17/src/internal/singleflight/singleflight.go:95 +0x3b
created by internal/singleflight.(*Group).DoChan
	/usr/lib/go-1.17/src/internal/singleflight/singleflight.go:88 +0x2f1

Support for AWS KMS

Hi,

Having support for AWS KMS as a key storage would be very beneficial for AWS users. As the only option for AWS HSM currently is the very costly AWS CloudHSM. This would be similar to the work setting up support for google KMS done in an earlier PR.

#286

I'm happy to write up the patch if the work would likely be accepted.

Thanks.

reduce the frequency of health check associated with a idle client.Conn

Currently we have a goroutine probing the server healthiness, firing ping request every second. The health check frequency should be in line with the actual usage of the connection. If the connection is only used once per 20 second, then 1 health check once per 10 second makes sense rather than 1 check per 1 second. Also, by adjusting the health check frequency, we don't keep one idle connection active by health checks, so our cache-based connection pool will make sane choice on which idle connection to be closed.

I propose to augment client.Conn with a count of actual gokeyless operations done since last health check. And health check goroutine will double the sleep if the count is 0, and half the sleep if the count is 2 and above.

Don't measure key load time as part of execution time metric

Currently, the metric for execution time that we expose includes the time to load a key, but this could add significant latency, and that's not what we're trying to measure. Instead, we should only measure starting after the key has been loaded.

Consider removing ECDSA precomputation

I've been doing some benchmarking related to ECDSA precomputation, and while I found a benefit before, I am no longer able to demonstrate any difference in latency between a setup that precomputes ECDSA random values and one that doesn't. Given the (low, but non-zero) complexity of the infrastructure for computing and distributing these values, and the security risks of having our own custom ECDSA implementation (which is basically just cannibalized from the standard library, but could still theoretically have bugs, and won't get updates from the standard library unless we're proactive), I think that we should consider removing the precomputation feature entirely.

Race condition in `listenResponse`

One of the Travis tests found a data race in listenResponse.

WARNING: DATA RACE
Write by goroutine 23:
  runtime.mapdelete()
      /home/travis/.gimme/versions/go1.6.linux.amd64/src/runtime/hashmap.go:545 +0x0
  github.com/cloudflare/gokeyless.(*Conn).listenResponse.func1()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/conn.go:130 +0xf4
  github.com/cloudflare/gokeyless.(*Conn).listenResponse()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/conn.go:138 +0x258
  github.com/cloudflare/gokeyless.(*Conn).DoOperation()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/conn.go:149 +0xc5
  github.com/cloudflare/gokeyless/client.(*PrivateKey).execute()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/client/keys.go:91 +0x403
  github.com/cloudflare/gokeyless/client.(*PrivateKey).Decrypt()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/client/keys.go:130 +0x234
  github.com/cloudflare/gokeyless/tests.TestRSADecrypt()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/tests/client_test.go:116 +0x52d
  testing.tRunner()
      /home/travis/.gimme/versions/go1.6.linux.amd64/src/testing/testing.go:473 +0xdc
Previous read by goroutine 24:
  runtime.mapaccess1_fast32()
      /home/travis/.gimme/versions/go1.6.linux.amd64/src/runtime/hashmap_fast.go:13 +0x0
  github.com/cloudflare/gokeyless.(*Conn).listenResponse()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/conn.go:138 +0x1f5
  github.com/cloudflare/gokeyless.(*Conn).DoOperation()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/conn.go:149 +0xc5
  github.com/cloudflare/gokeyless.(*Conn).Ping()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/conn.go:162 +0xfe
  github.com/cloudflare/gokeyless/client.(*group).Dial.func1()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/client/remote.go:202 +0xd0
Goroutine 23 (running) created at:
  testing.RunTests()
      /home/travis/.gimme/versions/go1.6.linux.amd64/src/testing/testing.go:582 +0xae2
  testing.(*M).Run()
      /home/travis/.gimme/versions/go1.6.linux.amd64/src/testing/testing.go:515 +0x11d
  main.main()
      github.com/cloudflare/gokeyless/tests/_test/_testmain.go:64 +0x210
Goroutine 24 (running) created at:
  github.com/cloudflare/gokeyless/client.(*group).Dial()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/client/remote.go:222 +0x695
  github.com/cloudflare/gokeyless/client.(*Client).Dial()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/client/client.go:132 +0x2f5
  github.com/cloudflare/gokeyless/client.(*PrivateKey).execute()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/client/keys.go:78 +0xbc
  github.com/cloudflare/gokeyless/client.(*PrivateKey).Decrypt()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/client/keys.go:130 +0x234
  github.com/cloudflare/gokeyless/tests.TestRSADecrypt()
      /home/travis/gopath/src/github.com/cloudflare/gokeyless/tests/client_test.go:116 +0x52d
  testing.tRunner()
      /home/travis/.gimme/versions/go1.6.linux.amd64/src/testing/testing.go:473 +0xdc
==================

Don't start service during package installation

Currently, at least with the .deb artifact (I haven't tested with .rpm), when we install gokeyless as a package, the service is automatically started. However, gokeyless needs manual configuration, so the service just fails and is left in a bad state.

We should instead make it so that the service is not started during installation. Currently, this is not an option in fpm, the tool we use to generate packages. Thus, this issue is blocked on jordansissel/fpm#1363.

Worker pool model may not work well with lazy loading certificates

With @Bren2010 's recent refactor to a worker pool model (one that I intend to keep in my own performance refactor), I am concerned that lazy-loading of certificates in the worker goroutines may be a performance bottleneck.

The model is something like this (what is presented here is true both of @Bren2010 's refactor and of my own work):

  • Each connection has its own goroutine that is solely responsible for reading packets off of the connection.
  • Once a packet is read, it is sent over a single global channel to a pool of workers.
  • The pool has a fixed number of worker goroutines.
  • Worker goroutines loop pulling jobs off the channel and doing the associated work. @Bren2010 's design and my own differ in what happens next - whether the worker goroutine writes the result directly to the network connection or sends it over another channel for further processing - but in either case, the worker goroutines represent a latency bottleneck - if any one of them (or multiple of them) stalls for too long on a single job, the average latency of the system could be affected.

Here's where the problem arises: in both of our designs, a key identifier (SNI, SKI, or IP) is sent along with the job definition, and it is the worker goroutine's job to locate the key associated with that identifier. For in-memory keys, this is not a big deal. However, we also support having the key store be an in-memory cache that is backed by some slower storage medium such as disk. In that case, looking up a key which is not in cache can result in disk IO or some other slow operation.

My concern is this: In such a scenario, if a key is requested that is not currently in cache, it could result in a worker goroutine taking tens of milliseconds or more on a job when the normal runtime is in the tens of microseconds.

Solutions

I see a couple of possible solutions to this. They all involve making it somebody else's responsibility (besides the worker goroutine) to load the key into memory:

  • The goroutine reading packets off the network connection is responsible for loading keys. This makes it so that a slow key load won't affect the latency of other connections in the system, but it will still adversely affect this connection.
  • The goroutine reading packets off the network connection spawns a new goroutine. That new goroutine loads the key and then sends the job to the worker pool. This addresses the problem of the previous approach, but means that every job must spawn a new goroutine even if the key is already in memory.
  • A hybrid approach: The reading goroutine first checks to see if the key is in the memory cache. If it is, the reading goroutine sends it along with the job directly. If not, it spawns a new goroutine to load the key as in the previous model.

document the usage of AKI whitelist

currently, we have AKI field of a gokeyless operation.
https://github.com/cloudflare/gokeyless/blob/master/protocol.go#L285
which is used to whitelist gokeyless operation in keyserver.
https://github.com/cloudflare/gokeyless/blob/master/server/server.go#L134

We need to write the design of this feature, because it seems it is not being used and could cause confusion and major bugs.
The default keyserver would not populate AKI whitelist. see https://github.com/cloudflare/gokeyless/blob/master/server/server.go#L401
because op == nil, AKI whitelist is skipped.
https://github.com/cloudflare/gokeyless/blob/master/server/server.go#L72

No sign of new release?

Hi there,

There have been 20+ merges since the last release.

Is it time we had a release of this product? Is it normal to leave it go that long without releasing changes?

codahale/hdrhistogram repo url has been transferred under the github HdrHstogram umbrella

Problem

The codahale/hdrhistogram repo has been transferred under the github HdrHstogram umbrella with the help from the original author in Sept 2020 (new repo url https://github.com/HdrHistogram/hdrhistogram-go). The main reasons are to group all implementations under the same roof and to provide more active contribution from the community as the original repository was archived several years ago.

The dependency URL should be modified to point to the new repository URL. The tag "v0.9.0" was applied at the point of transfer and will reflect the exact code that was frozen in the original repository.

If you are using Go modules, you can update to the exact point of transfer using the @v0.9.0 tag in your go get command.

go mod edit -replace github.com/codahale/hdrhistogram=github.com/HdrHistogram/[email protected]

Performance Improvements

From the point of transfer, up until now (mon 16 aug 2021), we've released 3 versions that aim support the standard HdrHistogram serialization/exposition formats, and deeply improve READ performance.
We recommend to update to the latest version.

gokeyless client blacklist mechanism can be simplified by request hop TTL

The motivation behind the remote server blacklist is that it is possible that a gokeyless server uses itself as a remote keyserver, causing a request looped forever.

However, the blacklist doesn't work if two servers can point each other as remote keyserver for the same key. And we can't catch that by blacklisting fully qualified server address. In fact, the two servers can even live on the same host with different ports.

Using request hop TTL can solve the infinite loop problem gracefully,

Kubernetes Support

Hi

Does someone already deploy the gokeyless in a Kubernetes cluster? If yes, is there any different approach to take or even slight configurations to have in mind?

I've been trying to deploy it in an AKS Cluster, but I'm facing some weird issues related to the PID creation as well as getting errors like cannot parse 'port' as int: strconv.ParseInt: parsing "tcp://X.X.X.X:2407": invalid syntax

Sorry if this is not the correct place for this kind of question.

Thanks in advance

Group Dial's latency measurement is problematic

With mutex lock, a remote Group can either do dial and return connection, or do health and latency measurement. Since latency measurement would possibly take very long to finish, it practically prevent the remote group to carry out dial immediately.

We should make Dial to return as fast as possible, while measurement check can be carried out with low priority.

client.Remote interface doesn't need AddRemote() method

It appears the AddRemote() method was only used when a keyserver hostname linked by a SKI is being looked up several times by client. It is actually problematic because, in case dns record updates, old IPs associated with the server hostname would never be purged, instead all new IPs are added to a list. We should always use the IP addresses from new lookup.

Also, there is 'servers' hashmap used to cache remote lookup results, we should rename it and make it more clear that lookup is cached by a structure.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.