{"id":13490005,"url":"https://github.com/ghostunnel/ghostunnel","last_synced_at":"2026-04-29T05:01:03.608Z","repository":{"id":37831084,"uuid":"43837870","full_name":"ghostunnel/ghostunnel","owner":"ghostunnel","description":"A simple SSL/TLS proxy with mutual authentication for securing non-TLS services.","archived":false,"fork":false,"pushed_at":"2025-05-10T22:57:58.000Z","size":26547,"stargazers_count":2037,"open_issues_count":4,"forks_count":280,"subscribers_count":50,"default_branch":"master","last_synced_at":"2025-05-13T00:09:48.143Z","etag":null,"topics":["crypto","go","hsm","keychain","pkcs11","proxy","security","ssl","stunnel","tls","tunnel"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ghostunnel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-10-07T18:53:38.000Z","updated_at":"2025-05-10T22:58:01.000Z","dependencies_parsed_at":"2024-03-14T01:32:32.750Z","dependency_job_id":"88cf9793-1fde-40cd-b519-5f7effabb835","html_url":"https://github.com/ghostunnel/ghostunnel","commit_stats":{"total_commits":727,"total_committers":54,"mean_commits":"13.462962962962964","dds":0.5213204951856947,"last_synced_commit":"220bf1cadc6816fd02703a0e6a5d72893a7cdf7b"},"previous_names":["square/ghostunnel"],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostunnel%2Fghostunnel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostunnel%2Fghostunnel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostunnel%2Fghostunnel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostunnel%2Fghostunnel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ghostunnel","download_url":"https://codeload.github.com/ghostunnel/ghostunnel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253843215,"owners_count":21972873,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crypto","go","hsm","keychain","pkcs11","proxy","security","ssl","stunnel","tls","tunnel"],"created_at":"2024-07-31T19:00:39.236Z","updated_at":"2026-04-29T05:01:03.601Z","avatar_url":"https://github.com/ghostunnel.png","language":"Go","funding_links":[],"categories":["Go","SPIFFE-aware Software","Go (531)","Repositories","security"],"sub_categories":[],"readme":"Ghostunnel\n==========\n\n[![license](https://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/ghostunnel/ghostunnel/master/LICENSE) [![release](https://img.shields.io/github/release/ghostunnel/ghostunnel.svg?style=flat)](https://github.com/ghostunnel/ghostunnel/releases) [![docker](https://img.shields.io/badge/docker-hub-blue.svg?style=flat)](https://hub.docker.com/r/ghostunnel/ghostunnel) [![test](https://img.shields.io/github/checks-status/ghostunnel/ghostunnel/master)](https://github.com/ghostunnel/ghostunnel/actions) [![coverage](https://img.shields.io/codecov/c/github/ghostunnel/ghostunnel/master)](https://app.codecov.io/gh/ghostunnel/ghostunnel/) [![website](https://img.shields.io/badge/website-ghostunnel.dev-blue.svg?style=flat)](https://ghostunnel.dev)\n\n👻\n\nGhostunnel is a simple TLS proxy with mutual authentication support for\nsecuring non-TLS backend applications.\n\nGhostunnel supports two modes, client mode and server mode. Ghostunnel in\nserver mode runs in front of a backend server and accepts TLS-secured\nconnections, which are then proxied to the (insecure) backend. A backend can be\na TCP domain/port or a UNIX domain socket. Ghostunnel in client mode accepts\n(insecure) connections through a TCP or UNIX domain socket and proxies them to\na TLS-secured service.\n\n**Supported platforms**: Ghostunnel is developed primarily for Linux and macOS,\nalthough it should run on any UNIX system that exposes `SO_REUSEPORT`,\nincluding FreeBSD, OpenBSD and NetBSD. Ghostunnel also supports running on\nWindows, though without signal-based certificate reload (use `--timed-reload`\ninstead), syslog output, Landlock sandboxing, and socket activation. See the\n[releases](releases/) directory for a full changelog.\n\nKey Features\n============\n\n**[Authentication \u0026 Authorization](#access-control-flags)**: Enforces mutual\nTLS authentication by requiring valid client certificates. Supports\nfine-grained access control checks on certificate fields (CN, OU, DNS/URI\nSAN), and declarative authorization policies via [Open Policy\nAgent](https://www.openpolicyagent.org) (OPA).\n\n**[Certificate Hotswapping](#certificate-hotswapping)**: Reload certificates\nwithout restarting via SIGHUP/SIGUSR1 or timed reload intervals, enabling use\nof short-lived certificates.\n\n**[Flexible Certificate Sources](#certificates)**: Load certificates and keys\nfrom PEM/PKCS#12 files, ACME (Let's Encrypt), hardware security modules\n(PKCS#11), macOS Keychain, Windows Certificate Store, or the SPIFFE Workload\nAPI.\n\n**[Secure by Default](#landlock-support)**: Listeners and targets are\nrestricted to localhost and UNIX sockets unless explicitly overridden with\n`--unsafe-listen` or `--unsafe-target`, preventing accidental exposure. On\nLinux, Landlock sandboxing is enabled by default to limit process privileges.\n\n**[Metrics \u0026 Profiling](#metrics--profiling)**: Built-in status port with JSON\nand Prometheus metrics endpoints, plus optional pprof profiling.\n\nGhostunnel also supports UNIX domain sockets, PROXY protocol v2,\nsystemd/launchd socket activation, and more.\n\nGetting Started\n===============\n\nTo get started and play around with Ghostunnel you will need X.509 client\nand server certificates. If you already maintain a PKI, you can use your\nexisting certificates. Otherwise, you can use tools like\n[mkcert](https://github.com/FiloSottile/mkcert) or\n[cloudflare/cfssl](https://github.com/cloudflare/cfssl) to build one.\n\nFor quick testing and development, you can also generate throwaway test\ncertificates using the built-in generator:\n\n    # Generate test certificates and keys\n    go tool mage test:keys\n\nThis will create a `test-keys` directory with all the necessary certificates and keys\nfor testing. **Note: These are test certificates only and should NOT be used in production.**\n\n### Install\n\nGhostunnel is available through [GitHub releases][rel] and through [Docker Hub][hub].\n\nPlease note that the official release binaries are best effort, and are usually\nbuilt directly via Github Actions on the latest available images. If you need\ncompatibility for specific OS versions we recommend building yourself.\n\nGhostunnel uses the [mage][mage] build system, a make/rake-like build tool using\nGo. Mage is available as a Go tool dependency (no separate install needed). You\ncan build Ghostunnel with the commands shown below.\n\n    # Compile binary\n    go tool mage go:build\n\n    # Build containers\n    go tool mage docker:build\n\nYou can also run `go tool mage -l` to view all build targets and add `-v` to\nmage commands to get more verbose output.\n\n[rel]: https://github.com/ghostunnel/ghostunnel/releases\n[hub]: https://hub.docker.com/r/ghostunnel/ghostunnel\n[mage]: https://magefile.org\n\n### Develop\n\nGhostunnel has an extensive suite of integration tests. Our integration test\nsuite requires Python 3.\n\nTo run tests:\n\n    # Option 1: run unit \u0026 integration tests locally\n    go tool mage test:all\n\n    # Option 2: run unit \u0026 integration tests in a Docker container\n    # This also runs PKCS#11 integration tests using SoftHSM in the container\n    go tool mage test:docker\n\n    # Open coverage information in browser\n    go tool cover -html coverage/all.profile\n\nFor more information on how to contribute, please see the [CONTRIBUTING](CONTRIBUTING.md) file.\n\nUsage\n=====\n\nTo see available commands and flags, run `ghostunnel --help`. You can get more\ninformation about a command by adding `--help` to the command, like `ghostunnel\nserver --help` or `ghostunnel client --help`. There's also a [man page](docs/reference/manpage-linux.md).\n\nBy default, Ghostunnel runs in the foreground and logs to stdout. You can set\n`--syslog` to log to syslog instead of stdout. If you want to run Ghostunnel\nin the background, we recommend using a service manager.\n\n### Certificates\n\nGhostunnel accepts certificates in multiple different file formats.\n\nThe `--keystore` flag can take a PKCS#12 keystore or a combined PEM file with the\ncertificate chain and private key as input (format is auto-detected). The `--cert` /\n`--key` flags can be used to load a certificate chain and key from separate PEM files\n(instead of a combined one).\n\nGhostunnel also supports loading identities from the macOS keychain or the\nSPIFFE Workload API and having private keys backed by PKCS#11 modules, see the\n\"Advanced Features\" section below for more information.\n\n### Server mode\n\nThis is an example for how to launch Ghostunnel in server mode, listening for\nincoming TLS connections on `localhost:8443` and forwarding them to\n`localhost:8080`. Note that while we use TCP sockets on `localhost` in this\nexample, both the listen and target flags can also accept paths to UNIX domain\nsockets as their argument.\n\nTo set allowed clients, you must specify at least one of `--allow-all`,\n`--allow-cn`, `--allow-ou`, `--allow-dns`, `--allow-uri` or `--allow-policy`. All\nchecks are made against the certificate of the client. Multiple flags are\ntreated as a logical disjunction (OR), meaning clients can connect as long as\nany of the flags matches. See [ACCESS-FLAGS](docs/security/access-flags.md) for more\ninformation. In this example, we assume that the CN of the client cert we want\nto accept connections from is `client`.\n\n**Note:** Before running the examples below, make sure you have generated the test\ncertificates by running `go tool mage test:keys` (see the [Getting Started](#getting-started)\nsection above).\n\nStart a backend server:\n\n    nc -l localhost 8080\n\nStart a Ghostunnel in server mode to proxy connections:\n\n    ghostunnel server \\\n        --listen localhost:8443 \\\n        --target localhost:8080 \\\n        --keystore test-keys/server-keystore.p12 \\\n        --cacert test-keys/cacert.pem \\\n        --allow-cn client\n\nVerify that clients can connect with their client certificate:\n\n    openssl s_client \\\n        -connect localhost:8443 \\\n        -cert test-keys/client-combined.pem \\\n        -key test-keys/client-combined.pem \\\n        -CAfile test-keys/cacert.pem\n\nNow we have a TLS proxy running for our backend service. We terminate TLS in\nGhostunnel and forward the connections to the insecure backend.\n\n### Client mode\n\nThis is an example for how to launch Ghostunnel in client mode, listening on\n`localhost:8080` and proxying requests to a TLS server on `localhost:8443`.\n\nBy default, Ghostunnel in client mode verifies targets based on the hostname.\nVarious access control flags exist to perform additional verification on top of\nthe regular hostname verification. See [ACCESS-FLAGS](docs/security/access-flags.md) for\nmore information.\n\nStart a backend TLS server:\n\n    openssl s_server \\\n        -accept 8443 \\\n        -cert test-keys/server-combined.pem \\\n        -key test-keys/server-combined.pem \\\n        -CAfile test-keys/cacert.pem\n\nStart a Ghostunnel with a client certificate to forward connections:\n\n    ghostunnel client \\\n        --listen localhost:8080 \\\n        --target localhost:8443 \\\n        --keystore test-keys/client-combined.pem \\\n        --cacert test-keys/cacert.pem\n\nVerify that we can connect to `8080`:\n\n    nc -v localhost 8080\n\nNow we have a TLS proxy running for our client. We take the insecure local\nconnection, wrap them in TLS, and forward them to the secure backend.\n\n### Full tunnel (client plus server)\n\nWe can combine the above two examples to get a full tunnel. Note that you can\nstart the tunnels in either order.\n\nStart netcat on port `8001`:\n\n    nc -l localhost 8001\n\nStart the Ghostunnel server:\n\n    ghostunnel server \\\n        --listen localhost:8002 \\\n        --target localhost:8001 \\\n        --keystore test-keys/server-combined.pem \\\n        --cacert test-keys/cacert.pem \\\n        --allow-cn client\n\nStart the Ghostunnel client:\n\n    ghostunnel client \\\n        --listen localhost:8003 \\\n        --target localhost:8002 \\\n        --keystore test-keys/client-keystore.p12 \\\n        --cacert test-keys/cacert.pem\n\nVerify that we can connect to `8003`:\n\n    nc -v localhost 8003\n\nNow we have a full tunnel running. We take insecure client connections,\nforward them to the server side of the tunnel via TLS, and finally terminate\nand proxy the connection to the insecure backend.\n\nDocker Images\n=============\n\nDocker images are published to [Docker Hub][hub] on each release. Three\nvariants are available:\n\n| Image | Tag |\n|-------|-----|\n| Alpine | `ghostunnel/ghostunnel:latest`, `ghostunnel/ghostunnel:v1.x.x` |\n| Debian | `ghostunnel/ghostunnel:latest-debian`, `ghostunnel/ghostunnel:v1.x.x-debian` |\n| Distroless | `ghostunnel/ghostunnel:latest-distroless`, `ghostunnel/ghostunnel:v1.x.x-distroless` |\n\nThe `latest` tags always point to the most recent release.\n\nAdvanced Features\n=================\n\n### Access Control Flags\n\nGhostunnel supports different types of access control flags in both client and\nserver modes to enforce authorization checks. Ghostunnel can check various\nattributes of peer certificates directly, including a SPIFFE ID from a peer\nusing a [SPIFFE][spiffe] [X.509 SVIDs][svid]. In addition to this, Ghostunnel\nalso supports implementing authorization checks via [Open Policy Agent](https://www.openpolicyagent.org/)\n(OPA) policies for maximum flexibility. Policies can be reloaded at runtime\nmuch like certificates.\n\nSee [ACCESS-FLAGS](docs/security/access-flags.md) for details.\n\n[spiffe]: https://spiffe.io/\n[svid]: https://github.com/spiffe/spiffe/blob/main/standards/X509-SVID.md\n\n### Logging Options\n\nYou can silence specific types of log messages using the `--quiet=...` flag,\nsuch as `--quiet=conns` or `--quiet=handshake-errs`. You can pass this flag\nrepeatedly if you want to silence multiple different kinds of log messages.\n\nSupported values are:\n* `all`: silences **all** log messages\n* `conns`: silences log messages about new and closed connections.\n* `conn-errs`: silences log messages about connection errors encountered (post handshake).\n* `handshake-errs`: silences log messages about failed handshakes.\n\nIn particular we recommend setting `--quiet=handshake-errs` if you are\nrunning TCP health checks in Kubernetes on the listening port, and you\nwant to avoid seeing error messages from aborted connections on each health\ncheck.\n\n### Certificate Hotswapping\n\nTo trigger a reload, simply send `SIGHUP` (or `SIGUSR1`) to the process or set a time-based\nreloading interval with the `--timed-reload` flag. This will cause Ghostunnel\nto reload the certificate and private key from the files on disk. Once\nsuccessful, the reloaded certificate will be used for new connections going\nforward.\n\nAdditionally, Ghostunnel uses `SO_REUSEPORT` to bind the listening socket on\nplatforms where it is supported (Linux, Apple macOS, FreeBSD, NetBSD and\nOpenBSD). This means a new Ghostunnel can be started on the same host/port\nbefore the old one is terminated, to minimize dropped connections (or avoid\nthem entirely depending on how the OS implements the `SO_REUSEPORT` feature).\n\nNote that if you are using an HSM/PKCS#11 module, only the certificate will\nbe reloaded. It is assumed that the private key in the HSM remains the same.\nThis means the updated/reissued certificate must match the private key that\nwas loaded from the HSM previously, everything else works the same.\n\n### ACME Support\n\nGhostunnel in server mode supports the ACME protocol for automatically\nobtaining and renewing a public certificate, assuming it's exposed publicly\non tcp/443 and there are valid public DNS FQDN records that resolve to the\nlistening interface IP.\n\nSee [ACME](docs/certificates/acme.md) for details.\n\n### Metrics \u0026 Profiling\n\nGhostunnel has a notion of \"status port\", a TCP port (or UNIX socket) that can\nbe used to expose status and metrics information over HTTPS. The status port\nfeature can be controlled via the `--status` flag. Profiling endpoints on the\nstatus port can be enabled with `--enable-pprof`.\n\nSee [METRICS](docs/networking/metrics.md) for details.\n\n### HSM/PKCS#11 support\n\nGhostunnel has support for loading private keys from PKCS#11 modules, which\nshould work with any hardware security module that exposes a PKCS#11 interface,\nincluding YubiKeys (via the YKCS11 module).\n\nSee [HSM-PKCS11](docs/certificates/hsm-pkcs11.md) for details, including a step-by-step\nguide for using Ghostunnel with a YubiKey.\n\n### Windows/macOS Keychain Support\n\nGhostunnel supports loading certificates from the Windows and macOS keychains.\nThis is useful if you have identities stored in your local keychain that you\nwant to use with Ghostunnel, e.g. if you want your private key(s) to be backed\nby the Secure Enclave on newer Touch ID MacBooks.\n\nSee [KEYCHAIN](docs/certificates/keychain.md) for details.\n\n### SPIFFE Workload API\n\nGhostunnel has support for maintaining up-to-date, frequently rotated\nidentities and trusted CA certificates from the SPIFFE Workload API.\n\nSee [SPIFFE-WORKLOAD-API](docs/certificates/spiffe-workload-api.md) for details.\n\n### Socket Activation\n\nGhostunnel supports socket activation via both systemd (on Linux) and launchd\n(on macOS). Socket activation is supported for the `--listen` and `--status`\nflags, and can be used by passing an address of the form `systemd:\u003cname\u003e` or\n`launchd:\u003cname\u003e`, where `\u003cname\u003e` should be the name of the socket as defined in\nyour systemd/launchd configuration.\n\nSee [SOCKET-ACTIVATION](docs/networking/socket-activation.md) for examples.\n\n### PROXY Protocol Support\n\nGhostunnel in server mode supports signalling of transport connection information\nto the backend using the [PROXY protocol](https://www.haproxy.org/download/3.1/doc/proxy-protocol.txt)\n(v2), just pass the `--proxy-protocol` flag on startup. Use `--proxy-protocol-mode`\nto also include TLS metadata and/or client certificate details. Note that the\nbackend must support the PROXY protocol and must be configured to use it when\nsetting this option.\n\nSee [PROXY-PROTOCOL](docs/networking/proxy-protocol.md) for details on modes and TLV extensions.\n\n### Landlock Support\n\nGhostunnel can use [Landlock](https://landlock.io) to limit process privileges\non Linux. Landlock is enabled by default in best-effort mode and can be\ndisabled using `--disable-landlock` if necessary (not recommended). When\nenabled, Ghostunnel will limit its access to files and sockets based on the\nflags passed at startup. Note that Landlock does not work with PKCS#11 modules\nand is disabled if PKCS#11 is used (as PKCS#11 modules are opaque to us we\ncan't craft workable Landlock rules for them).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghostunnel%2Fghostunnel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fghostunnel%2Fghostunnel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghostunnel%2Fghostunnel/lists"}