Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ghostunnel.man: ghostunnel

# Man page for docs
docs/MANPAGE.md: ghostunnel
./ghostunnel --help-man | pandoc --from man --to markdown > $@
./ghostunnel --help-custom-man | pandoc --wrap=preserve --from man --to markdown > $@

# Test binary with coverage instrumentation
ghostunnel.test: $(SOURCE_FILES)
Expand Down
27 changes: 20 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@ example, both the listen and target flags can also accept paths to UNIX domain
sockets as their argument.

To set allowed clients, you must specify at least one of `--allow-all`,
`--allow-cn`, `--allow-ou`, `--allow-dns` or `--allow-uri`. All checks are made
against the certificate of the client. Multiple flags are treated as a logical
disjunction (OR), meaning clients can connect as long as any of the flags
matches (see [ACCESS-FLAGS](docs/ACCESS-FLAGS.md) for more information). In
this example, we assume that the CN of the client cert we want to accept
connections from is `client`.
`--allow-cn`, `--allow-ou`, `--allow-dns`, `--allow-uri` or `--alow-policy`. All
checks are made against the certificate of the client. Multiple flags are
treated as a logical disjunction (OR), meaning clients can connect as long as
any of the flags matches. See [ACCESS-FLAGS](docs/ACCESS-FLAGS.md) for more
information. In this example, we assume that the CN of the client cert we want
to accept connections from is `client`.

Start a backend server:

Expand Down Expand Up @@ -182,6 +182,11 @@ Ghostunnel and forward the connections to the insecure backend.
This is an example for how to launch Ghostunnel in client mode, listening on
`localhost:8080` and proxying requests to a TLS server on `localhost:8443`.

By default, Ghostunnel in client mode verifies targets based on the hostname.
Various access control flags exist to perform additional verification on top of
the regular hostname verification. See [ACCESS-FLAGS](docs/ACCESS-FLAGS.md) for
more information.

Start a backend TLS server:

openssl s_server \
Expand Down Expand Up @@ -355,4 +360,12 @@ this option.

### Landlock Support

Ghostunnel can use [Landlock](https://landlock.io) to limit process privileges on Linux. Landlock is enabled by default (in best-effort mode) on v1.9.0 or later. On Ghostunnel v1.8.x, Landlock can enabled using the `--use-landlock` flag. When enabled, Ghostunnel will limit its access to files and sockets based on the flags passed at startup. Note that Landlock does not work with PKCS#11 modules and is disabled if PKCS#11 is used (as PKCS#11 modules are opaque to us we can't craft workable Landlock rules for them).
Ghostunnel can use [Landlock](https://landlock.io) to limit process privileges
on Linux. Landlock is enabled by default (in best-effort mode) on v1.9.0 or
later. On Ghostunnel v1.8.x, Landlock can enabled using the `--use-landlock`
flag. On Ghostunnel v1.9.x and later, Landlock can be disabled using
`--disable-landlock` if necessary (not recommended). When enabled, Ghostunnel
will limit its access to files and sockets based on the flags passed at
startup. Note that Landlock does not work with PKCS#11 modules and is disabled
if PKCS#11 is used (as PKCS#11 modules are opaque to us we can't craft workable
Landlock rules for them).
168 changes: 137 additions & 31 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (
var manPageTemplate = `{{define "FormatFlags"}}\
{{range .Flags}}\
{{if not .Hidden}}\
.TP
\fB{{if .Short}}-{{.Short|Char}}, {{end}}--{{.Name}}{{if not .IsBoolFlag}}={{.FormatPlaceHolder}}{{end}}\\fR
\fB{{if .Short}}-{{.Short|Char}}, {{end}}--{{.Name}}{{if not .IsBoolFlag}}={{.FormatPlaceHolder}}{{end}}\fR
{{.Help}}
.PP
{{end}}\
{{end}}\
{{end}}\
Expand All @@ -28,24 +28,25 @@ var manPageTemplate = `{{define "FormatFlags"}}\
{{end}}\
{{define "FormatCommands"}}\
{{range .FlattenedCommands}}\
{{if not .Hidden}}\
{{if not .Hidden}}
.SS
\fB{{.FullCommand}}{{template "FormatCommand" .}}\\fR
\fB{{.FullCommand}}{{template "FormatCommand" .}}\fR
.PP
{{.Help}}
{{template "FormatFlags" .}}\
{{end}}\
{{end}}\
{{end}}\
{{define "FormatUsage"}}\
{{template "FormatCommand" .}}{{if .Commands}} <command> [<args> ...]{{end}}\\fR
{{end}}\
{{template "FormatCommand" .}}{{if .Commands}} <command> [<args> ...]{{end}}\fR
{{end}}
.TH {{.App.Name}} 1 {{.App.Version}} "{{.App.Author}}"
.SH "NAME"
{{.App.Name}}
.SH "SYNOPSIS"
\fB{{.App.Name}}{{template "FormatUsage" .App}}\fR
.TP
\fB{{.App.Name}}{{template "FormatUsage" .App}}

.SH "DESCRIPTION"
{{.App.Help}}

Expand All @@ -57,68 +58,173 @@ a TCP domain/port or a UNIX domain socket. Ghostunnel in client mode accepts
a TLS-secured service.

For a more in-depth explanation, please see the README.md file (and docs
folder) that shipped with ghostunnel or view the latest docs on
folder) that shipped with Ghostunnel or view the latest docs on
github.com/ghostunnel/ghostunnel.
.SH "CERTIFICATES & PRIVATE KEYS"
Ghostunnel accepts certificates in multiple different file formats.
Ghostunnel supports multiple methods for loading certificates and private keys.

File-based formats:
.RS
The \fB--keystore\fR flag can take a PKCS#12 keystore or a combined PEM file
with the certificate chain and private key as input (format is auto-detected).
The \fB--cert\fR and \fB--key\fR flags can be used to load a certificate chain
and key from separate PEM files (instead of a combined one).
.RE

SPIFFE Workload API:
.RS
Ghostunnel can retrieve certificates and root CAs from the SPIFFE Workload API
using the \fB--use-workload-api\fR flag. This enables automatic certificate
rotation and is useful in service mesh deployments. The Workload API socket
location can be specified via the \fBSPIFFE_ENDPOINT_SOCKET\fR environment
variable or the \fB--use-workload-api-addr\fR flag.
.RE

ACME (Automatic Certificate Management):
.RS
In server mode, Ghostunnel can automatically obtain and renew public TLS
certificates using the ACME protocol (e.g., Let's Encrypt). Use
\fB--auto-acme-cert\fR with \fB--auto-acme-email\fR and
\fB--auto-acme-agree-to-tos\fR. This requires Ghostunnel to be accessible on
a public interface (tcp/443) with valid DNS records. The ACME CA URL can be
specified with \fB--auto-acme-ca\fR (defaults to Let's Encrypt).
.RE

PKCS#11 (Hardware Security Modules):
.RS
Private keys can be stored in PKCS#11-compatible hardware security modules
(HSMs). Use \fB--cert\fR to specify the certificate chain file, and
\fB--pkcs11-module\fR, \fB--pkcs11-token-label\fR, and \fB--pkcs11-pin\fR to
configure the HSM. PKCS#11 options can also be set via environment variables
(\fBPKCS11_MODULE\fR, \fBPKCS11_TOKEN_LABEL\fR, \fBPKCS11_PIN\fR).
.RE

Keychain (macOS/Windows):
.RS
On macOS and Windows, Ghostunnel can load certificates from the system keychain
using \fB--keychain-identity\fR (by subject CN/serial) or \fB--keychain-issuer\fR
(by issuer CN). On macOS, \fB--keychain-require-token\fR can be used to
require certificates from physical tokens (e.g., Touch ID MacBooks).
.RE

Ghostunnel also supports loading identities from the macOS keychain and having
private keys backed by PKCS#11 modules, see the documentation on GitHub for
examples.

In server mode, Ghostunnel supports automatically obtaining and renewing a
public TLS certificate using the ACME protocol. This requires either Ghostunnel
to listen on tcp/443 on a public interface, or somehow a public tcp/443
interface needs to be forwarded to Ghostunnel's server listening port
(e.g. - systemd socket, iptables, etc.). The URL to the ACME CA can be specified
using the \fB--auto-acme-ca=\fR flag. If not specified, Ghostunnel defaults
to using Let's Encrypt.
.SH "EXAMPLE: SERVER MODE"
Start a ghostunnel in server mode to proxy connections from localhost:8443
to localhost:8080, while only allowing connections from client certificates
with CN=client:

.nf
ghostunnel server \\
--listen localhost:8443 \\
--target localhost:8080 \\
--keystore server-keystore.p12 \\
--cacert cacert.pem \\
--allow-cn client
.fi

To set allowed clients, you must specify at least one of \fB--allow-all\fR,
\fB--allow-cn\fR, \fB--allow-ou\fR, \fB--allow-dns\fR or \fB--allow-uri\fR. All
checks are made against the certificate of the client. Multiple flags are
treated as a logical disjunction (OR), meaning clients can connect as long as
any of the flags match. To disable requiring client certificates, use
\fB--disable-authentication\fR.
\fB--allow-cn\fR, \fB--allow-ou\fR, \fB--allow-dns\fR, \fB--allow-uri\fR, or
\fB--allow-policy\fR. All checks are made against the certificate of the client.
Multiple flags are treated as a logical disjunction (OR), meaning clients can
connect as long as any of the flags match. To disable requiring client
certificates, use \fB--disable-authentication\fR.

.SH "EXAMPLE: CLIENT MODE"
Start a ghostunnel in client mode to proxy connections from localhost:8080
to localhost:8443, doing only hostname verification to validate the server
certificate:

.nf
ghostunnel client \\
--listen localhost:8080 \\
--target localhost:8443 \\
--cert client-cert.pem \\
--key client-key.pem \\
--cacert cacert.pem
.fi

Use \fB--override-server-name\fR to overrides the server name used for hostname
verification. Various access control flags exist to perform additional
verification (on top of the regular hostname verification) of server
certificates, such as \fB--verify-cn\fR, \fB--verify-ou\fR, \fB--verify-dns\fR
and \fB--verify-uri\fR. Multiple flags are treated as a logical disjunction
(OR), meaning clients will connect to the server as long as any of the flags
match, assuming that hostname verification was also successful. To disable
sending client certificates, use \fB--disable-authentication\fR.
certificates, such as \fB--verify-cn\fR, \fB--verify-ou\fR, \fB--verify-dns\fR,
\fB--verify-uri\fR, or \fB--verify-policy\fR. Multiple flags are treated as a
logical disjunction (OR), meaning clients will connect to the server as long as
any of the flags match, assuming that hostname verification was also successful.
To disable sending client certificates, use \fB--disable-authentication\fR.

.SH "EXAMPLE: UNIX SOCKETS"
Ghostunnel supports UNIX domain sockets for both listening and forwarding:

.nf
# Server mode with UNIX socket
ghostunnel server \\
--listen unix:/var/run/ghostunnel.sock \\
--target unix:/var/run/backend.sock \\
--keystore server-keystore.p12 \\
--cacert cacert.pem \\
--allow-cn client

# Client mode with UNIX socket listener
ghostunnel client \\
--listen unix:/var/run/client.sock \\
--target localhost:8443 \\
--keystore client-keystore.p12 \\
--cacert cacert.pem
.fi

UNIX sockets provide secure local communication without network exposure.

.SH "EXAMPLE: STATUS AND METRICS"
Enable status and metrics endpoints for monitoring and health checks:

.nf
ghostunnel server \\
--listen localhost:8443 \\
--target localhost:8080 \\
--keystore server-keystore.p12 \\
--cacert cacert.pem \\
--allow-cn client \\
--status localhost:6060
.fi

Access status and metrics:
.nf
# Status information (JSON)
curl --cacert cacert.pem https://localhost:6060/_status

# Metrics (Prometheus format)
curl --cacert cacert.pem https://localhost:6060/_metrics/prometheus

# Metrics (JSON format)
curl --cacert cacert.pem https://localhost:6060/_metrics/json
.fi

The status port can also use HTTP by prefixing with "http://" (e.g.,
\fB--status http://localhost:6060\fR). Profiling endpoints can be enabled
with \fB--enable-pprof\fR.

.SH "EXAMPLE: MULTIPLE ACCESS CONTROL FLAGS"
Multiple access control flags can be combined using OR logic:

.nf
ghostunnel server \\
--listen localhost:8443 \\
--target localhost:8080 \\
--keystore server-keystore.p12 \\
--cacert cacert.pem \\
--allow-cn client1 \\
--allow-cn client2 \\
--allow-ou developers \\
--allow-uri spiffe://example.com/*
.fi

Clients matching any of the specified criteria (CN=client1 or CN=client2 or
OU=developers or URI matching spiffe://example.com/*) will be allowed to
connect. The same OR logic applies to client mode verification flags
(\fB--verify-cn\fR, \fB--verify-ou\fR, \fB--verify-dns\fR, \fB--verify-uri\fR).

.SH "OPTIONS"
{{template "FormatFlags" .App}}\
{{if .App.Commands}}\
{{if .App.Commands}}
.SH "COMMANDS"
{{template "FormatCommands" .App}}\
{{end}}\
Expand Down
Loading
Loading