# Client Certificates

Client certificates allow the internal web server to verify a web connection is coming from a Pritunl Zero server. Connections that do not have a valid certificate will be blocked by the internal web server. This prevents unauthenticated connections even if the remote user has network access to the internal web server. The Pritunl Zero server manages the certificate authority for the client certificates and uses regularly renewed certificates that are valid for 30 seconds.

Client certificates offer similar functionality to JWT tokens without requiring significant changes to the internal web server. Most web servers and web frameworks have support for client certificate authentication without the need for any plugins or modifications to the internal application. Client certificates will not effect web technologies such as WebSockets or long polling connections.

![](https://github.com/pritunl/pritunl-docs/blob/master/pritunl-zero/.gitbook/assets/client_certificates0.png)

### Create Authority

Authorities in Pritunl Zero represent a public key pair with a certificate authority. Multiple authorities can be created and a different one can be used for each internal web service if required. Open the *Authorities* tab in the Pritunl Zero web console and create an authority if one does not exists. No authority options need to be configured for client certificates. The certificate expire option is unrelated to client certificates.

![](https://github.com/pritunl/pritunl-docs/blob/master/pritunl-zero/.gitbook/assets/client_certificates1.png)

### Configure Service

Open the *Services* tab and select the authority created above in the *Client Certificate Authority* option. To minimize downtime this step should be done before configuring the internal web server. Adding a client certificate to the service will not effect connections to the internal web server, the client certificate is only sent when requested by the internal server. The connection to the internal server must also use HTTPS. The internal server must allow HTTPS connections but does not require a valid certificate if the internal server is configured with an IP address in Pritunl Zero. If a hostname is used in Pritunl Zero the internal server must have a valid certificate.

![](https://github.com/pritunl/pritunl-docs/blob/master/pritunl-zero/.gitbook/assets/client_certificates2.png)

### Configure Internal Server

Open the *Authorities* tab and select the *Root Certificate* tab. This will display the root CA certificate that will be used for client certificates. This CA certificate must be copied to the internal web server and stored in the paths shown in the examples below.

![](https://github.com/pritunl/pritunl-docs/blob/master/pritunl-zero/.gitbook/assets/client_certificates1.png)

Configuring the internal server will depend on what software is used. Below is an example configuration for Nginx, Gitlab and Go.

```
ssl_client_certificate /etc/nginx/client.crt;
ssl_verify_client on;
```

```shell
sudo nano /etc/gitlab/gitlab.rb
##! Most root CA's are included by default
nginx['ssl_client_certificate'] = "/etc/gitlab/ssl/client.crt"

##! enable/disable 2-way SSL client authentication
nginx['ssl_verify_client'] = "on"

sudo gitlab-ctl reconfigure
```

```go
const clientCa = `-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
`

func main() {
	certPool := x509.NewCertPool()
	certPool.AppendCertsFromPEM([]byte(clientCa))

	tlsConfig := &tls.Config{
		ClientAuth: tls.RequireAndVerifyClientCert,
		ClientCAs:  certPool,
	}

	listener, err := tls.Listen("tcp", ":8443", tlsConfig)
	if err != nil {
		panic(err)
	}

	server := &http.Server{
		Addr:    ":8443",
		Handler: engine,
	}

	err = server.Serve(listener)
	if err != nil {
		panic(err)
	}
}
```

### Test Internal Server

Once configured connections directly to the internal web server should display a certificate error similar to the one shown below.

![](https://github.com/pritunl/pritunl-docs/blob/master/pritunl-zero/.gitbook/assets/client_certificates3.png)

Connections from the Pritunl Zero server should work without any errors.

![](https://github.com/pritunl/pritunl-docs/blob/master/pritunl-zero/.gitbook/assets/client_certificates4.png)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.pritunl.com/kb/zero/general/client-certificates.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
