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
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: Configure the Cloudflare One Client to use a custom root certificat
Cloudflare certificate.
---

import { Render, Tabs, TabItem, APIRequest } from "~/components";
import { Render, Tabs, TabItem, APIRequest, Details } from "~/components";

:::note
Only available on Enterprise plans.
Expand All @@ -28,40 +28,87 @@ If your users need to connect to self-signed origin servers, create an HTTP Allo

## Generate a custom root CA

Before you generate a custom root CA, make sure you have [OpenSSL](https://www.openssl.org/) installed.

1. Open a terminal.

2. Create a directory for the root CA and change into it.
2. (Optional) Create a directory for the root CA and change into it.

```sh
mkdir -p /root/customca
cd /root/customca
```

You can generate the certificate files in any directory. This step keeps things organized. If you skip it, files will be created in your current working directory.

3. Generate a private key for the root CA.

```sh
openssl genrsa -out <CUSTOM-ROOT-PRIVATE-KEY>.pem 2048
```

The `2048` value specifies the RSA key size in bits. You can use `4096` for stronger security at the cost of slightly slower TLS handshakes.

:::caution
Keep the private key secure — if it is compromised, an attacker could issue trusted certificates on your behalf.
:::

4. Generate a self-signed root certificate.

```sh
openssl req -x509 -sha256 -new -nodes -key <CUSTOM-ROOT-PRIVATE-KEY>.pem -days 365 -out <CUSTOM-ROOT-CERT>.pem
openssl req -x509 -sha256 -new -nodes \
-key <CUSTOM-ROOT-PRIVATE-KEY>.pem \
-days 365 \
-out <CUSTOM-ROOT-CERT>.pem \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
```

When preparing your certificate and private key for upload, be sure to remove any unwanted characters, such as mismatching subdomains in the certificate's common name. To review the private key, run the following command:
The `-addext` flags add the `basicConstraints` and `keyUsage` extensions required by [RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280) for CA certificates. Without them, some TLS clients may reject certificates signed by your custom CA. In particular, Python 3.13 and later enforce strict RFC 5280 compliance by default (`ssl.VERIFY_X509_STRICT`), causing HTTPS requests to fail for devices using the Cloudflare One Client when the uploaded CA does not include these extensions.

The `-days 365` value controls certificate expiry. A shorter duration reduces risk if the key is compromised, but requires more frequent rotation. Rotating a deployed BYOPKI certificate is a disruptive operation, so choose an expiry that balances security with operational overhead.

<Details header="Error: `Unknown cipher or option -addext`">
If your system runs OpenSSL versions older than 1.1.1, the `-addext` flag is not available. Use a config file instead:

```sh
openssl req -x509 -sha256 -new -nodes \
-key <CUSTOM-ROOT-PRIVATE-KEY>.pem \
-days 365 \
-out <CUSTOM-ROOT-CERT>.pem \
-config <(printf '[req]\ndistinguished_name=dn\n[dn]\n[v3_ca]\nbasicConstraints=critical,CA:TRUE\nkeyUsage=critical,keyCertSign,cRLSign') \
-extensions v3_ca
```
</Details>

5. Verify the required RFC 5280 extensions are present:

```sh
openssl x509 -in <CUSTOM-ROOT-CERT>.pem -noout -ext keyUsage,basicConstraints
```

```sh
openssl rsa -in <CUSTOM-ROOT-PRIVATE-KEY>.pem -text
```
The output should include:

To review the certificate, run the following command:
```txt
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
```

```sh
openssl x509 -in <CUSTOM-ROOT-CERT>.pem -text
```
If these fields are missing, regenerate the certificate using the command in step 4.

6. To review the private key, run the following command:

```sh
openssl rsa -in <CUSTOM-ROOT-PRIVATE-KEY>.pem -text
```

To review the certificate, run the following command:

```sh
openssl x509 -in <CUSTOM-ROOT-CERT>.pem -text
```

When preparing your certificate and private key for upload, be sure to remove any unwanted characters, such as mismatching subdomains in the certificate's common name.

## Deploy a custom root certificate

Expand Down Expand Up @@ -180,6 +227,14 @@ When you upload a private key to Zero Trust, Cloudflare encrypts the key and sto

To use a custom root certificate you generated and uploaded to Cloudflare, refer to [Activate a root certificate](/cloudflare-one/team-and-resources/devices/user-side-certificates/#activate-a-root-certificate).

## Troubleshoot HTTP errors
## Troubleshooting

### Error 526: Invalid SSL certificate

If Gateway returns an **HTTP Response Code: 526** after deploying a custom certificate, refer to the [Error 526 documentation](/cloudflare-one/traffic-policies/troubleshooting/#error-526-invalid-ssl-certificate).

### Python 3.13+ SSL errors with the Cloudflare One Client

Python 3.13 and later enable `ssl.VERIFY_X509_STRICT` by default, which requires CA certificates to comply with [RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280). If your BYOPKI certificate was generated without the `keyUsage` and `basicConstraints` extensions, Python HTTPS requests will fail when the Cloudflare One Client is active. To resolve the issue, [generate a new custom root CA](/cloudflare-one/team-and-resources/devices/user-side-certificates/custom-certificate/#generate-a-custom-root-ca) and upload it to Cloudflare.


If Gateway returns an **HTTP Response Code: 526** after deploying a custom certificate, you can [troubleshoot errors with Gateway](/cloudflare-one/traffic-policies/troubleshooting/#error-526-invalid-ssl-certificate).
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ Gateway will automatically detect changes in user name, title, and group members

Specify a value from a [custom OIDC claim](/cloudflare-one/integrations/identity-providers/generic-oidc/#custom-oidc-claims) configured on your identity provider.

:::note
This selector is only available for the [Generic OIDC](/cloudflare-one/integrations/identity-providers/generic-oidc/) identity provider integration. Named OIDC providers such as Okta and Microsoft Entra ID do not support custom OIDC claims in Gateway policies — use the [User Group Names](#user-group-names) or [User Group IDs](#user-group-ids) selectors for those providers instead.
:::

<Render file="gateway/selectors/oidc-claims" product="cloudflare-one" />

### SAML Attributes
Expand Down
Loading