Restructured Documentation
Automatic Documentation Deployment / Sync Docs to https://kb.bunny-lab.io (push) Successful in 8s
Automatic Documentation Deployment / Sync Docs to https://kb.bunny-lab.io (push) Successful in 8s
This commit is contained in:
@@ -0,0 +1,564 @@
|
||||
---
|
||||
tags:
|
||||
- Active Directory
|
||||
- Certificate Services
|
||||
- Authentication
|
||||
---
|
||||
|
||||
## Purpose
|
||||
This document outlines the Microsoft-recommended best practices for deploying a secure, internal-use-only, two-tier Public Key Infrastructure (PKI) using Windows Server 2022 or newer. The PKI supports securing S/MIME email, 802.1X Wi-Fi with NPS, and LDAP over SSL (LDAPS).
|
||||
|
||||
!!! abstract "CA Deployment Breakdown"
|
||||
The environment will consist of at least 2 virtual machines. For the purposes of this document they will be named `LAB-CA-01` and `LAB-CA-02`. This stands for "*Lab Certificate Authority [01|02]*". In a two-tier hierarchy, an offline (*you intentionally keep this VM offline*) Root CA signs a single "*Subordinate*" Enterprise CA certificate. The Subordinate CA is domain-joined and handles all certificate requests. Clients trust the PKI via Group Policy and Active Directory integration.
|
||||
|
||||
In this case, `LAB-CA-01` is the Root CA, while `LAB-CA-02` is the Intermediary/Subordinate CA. You can add more than one subordinate CA if you desire more redundancy in your environment. Making them operate together is generally automatic and does not require manual intervention.
|
||||
|
||||
!!! warning "Critical PKI Revocation Requirement"
|
||||
CRL Distribution Points (CDP) and Authority Information Access (AIA) are required for this deployment, even if the immediate use case is only LDAPS. Certificate chain validation and revocation checking still occur for CA certificates and issued certificates. If CDP/AIA is missing, invalid, or unreachable, the Subordinate CA service may fail to start with revocation-related errors such as `0x80092013 (CRYPT_E_REVOCATION_OFFLINE)`.
|
||||
|
||||
!!! note "Certificate Authority Server Provisioning Assumptions"
|
||||
- OS = Windows Server 2022/2025 bare-metal or as a VM
|
||||
- You should give it at least 4GB of RAM.
|
||||
- [Change the edition of Windows Server from "**Evaluation**" to "**Standard**" via DISM](<../../../workflows/Windows and Linux/Windows/Change Windows Edition.md>)
|
||||
- Ensure the server is fully updated
|
||||
- [Ensure the server is activated](<../../../workflows/Windows and Linux/Windows/Change Windows Edition.md#force-activation-edition-switcher>)
|
||||
- Ensure the timezone is correctly configured
|
||||
- Ensure the hostname is correctly configured
|
||||
|
||||
!!! note "Domain Environment Assumptions"
|
||||
It is assumed that you already have existing infrastructure hosting an Active Directory Domain with at least one domain controller. This document does not outline how to set up a domain controller, you will need to figure that out on your own.
|
||||
|
||||
!!! note "PKI HTTP Distribution Assumptions"
|
||||
This document uses a dedicated HTTP name for PKI publication:
|
||||
|
||||
- `pki.bunny-lab.io`
|
||||
|
||||
This DNS name should resolve to the server hosting the PKI publication directory. In this deployment, the HTTP distribution point is hosted on `LAB-CA-02`.
|
||||
|
||||
This indirection is intentional. Certificate CDP/AIA URLs are embedded into issued certificates, so they should point to a stable DNS name rather than directly coupling clients to a CA hostname.
|
||||
|
||||
## Offline (Non-Domain-Joined) Root CA `LAB-CA-01`
|
||||
### Role Deployment
|
||||
This is the initial deployment of the root certificate authority, the settings here should be double and triple checked before proceeding through each step.
|
||||
|
||||
- Provision a **non-domain-joined** Windows Server
|
||||
- This is critical that this device is not domain-joined for security purposes
|
||||
- Navigate to "**Server Manager > Manage > Add Roles and Features**"
|
||||
- Check "**Active Directory Certificate Services**"
|
||||
- When prompted to confirm, click the "**Add Features**" button
|
||||
- Ensure the "**Include management tools (if applicable)**" checkbox is checked.
|
||||
- Click "**Next**" > "**Next**" > "**Next**"
|
||||
- You will be told that the name of the server cannot be changed after this point, and it will be associated with `WORKGROUP` > This is fine and you can proceed.
|
||||
- Check the boxes for the following role services:
|
||||
- `Certification Authority`
|
||||
- `Certification Authority Web Enrollment`
|
||||
- When prompted to confirm multiple times, click the "**Add Features**" button
|
||||
- Ensure the "**Include management tools (if applicable)**" checkbox is checked.
|
||||
- The Root CA still requires properly configured CDP and AIA publication settings. These are configured after the CA role is installed and before the Subordinate CA certificate is issued.
|
||||
- Click "**Next**" > "**Next**" > "**Next**" > "**Install**"
|
||||
- Restart the Server
|
||||
|
||||
### Role Configuration
|
||||
We have a few things we need to configure within the CA to make it ready to handle certificate requests.
|
||||
|
||||
- Navigate to "**Server Manager > (Alert Flag) > Post-deployment Configuration: Active Directory Certificate Services**"
|
||||
- You will be prompted for an admin user, in this example, you will use the pre-populated `LAB-CA-01\Administrator`
|
||||
- Check the boxes for `Certification Authority` and `Certification Authority Web Enrollment` then click "**Next**"
|
||||
- Check the "**Standalone CA**" radio box then click "**Next**"
|
||||
- Check the "**Root CA** radio box then click "**Next**"
|
||||
- Check the "**Create a new private key**" radio box then click "**Next**"
|
||||
- Click the dropdown menu for "**Select a crypotographic provider**" and ensure that "**RSA#Microsoft Software Key Storage Provider**" is selected
|
||||
- *Microsoft Software Key Storage Provider (KSP) is the latest, most flexible provider designed to work with the Cryptography Next Generation (CNG) APIs. It offers better support for modern algorithms and improved security management (such as support for key attestation, better hardware integration, and improved key protection mechanisms).*
|
||||
- Set the key length to `4096`
|
||||
- Set the hash algorithm to `SHA256`
|
||||
- Click "**Next**"
|
||||
- **Common Name for this CA**: `BunnyLab-RootCA`
|
||||
- **Distinguished name suffix**: `O=Bunny Lab,C=US`
|
||||
- **Preview of distinguished name**: `CN=BunnyLab-RootCA,O=Bunny Lab,C=US`
|
||||
- Click "**Next**"
|
||||
- Specify the validity period: `10 Years` then click "**Next**" > "**Next**" > "**Configure**"
|
||||
|
||||
You will see a finalization screen confirming everything we have configured, it should look something like what is seen below:
|
||||
|
||||
| **Field** | **Value** |
|
||||
| :--- | :--- |
|
||||
| CA Type | Standalone Root |
|
||||
| Cryptographic provider | RSA#Microsoft Software Key Storage Provider |
|
||||
| Hash Algorithm | SHA256 |
|
||||
| Key Length | 4096 |
|
||||
| Allow Administrator Interaction | Disabled |
|
||||
| Certificate Validity Period | `<10 Years from Today>` |
|
||||
| Distinguished Name | CN=BunnyLab-RootCA,O=Bunny Lab,C=US |
|
||||
| Certificate Database Location | C:\Windows\system32\CertLog |
|
||||
| Certificate Database Log Location | C:\Windows\system32\CertLog |
|
||||
|
||||
!!! success "Active Directory Certificate Services"
|
||||
If everything went well, you will see that the "**Certificate Authority**" and "**Certification Authority Web Enrollment**" both have a status of "**Configuration succeeded**". At this point, you can click the "**Close**" button to conclude the Root CA configuration.
|
||||
|
||||
### Configure Root CA CDP and AIA Publication URLs
|
||||
Before the Root CA issues the Subordinate CA certificate, configure CDP and AIA publication URLs. These settings control what revocation and CA certificate locations are embedded into certificates issued by the Root CA.
|
||||
|
||||
!!! warning "PowerShell Syntax"
|
||||
The following commands are written for PowerShell. Use single percent signs such as `%3%8%9.crl`.
|
||||
|
||||
If using `cmd.exe`, percent escaping may differ. Do not paste caret-based (`^`) line continuations into PowerShell.
|
||||
|
||||
On `LAB-CA-01`, run:
|
||||
|
||||
```powershell
|
||||
certutil -setreg CA\CRLPublicationURLs "65:C:\Windows\System32\CertSrv\CertEnroll\%3%8%9.crl\n78:http://pki.bunny-lab.io/pki/%3%8%9.crl"
|
||||
```
|
||||
|
||||
```powershell
|
||||
certutil -setreg CA\CACertPublicationURLs "1:C:\Windows\System32\CertSrv\CertEnroll\%1_%3%4.crt\n2:http://pki.bunny-lab.io/pki/%1_%3%4.crt"
|
||||
```
|
||||
|
||||
Validate the registry values:
|
||||
|
||||
```powershell
|
||||
certutil -getreg CA\CRLPublicationURLs
|
||||
certutil -getreg CA\CACertPublicationURLs
|
||||
```
|
||||
|
||||
The CDP value should contain:
|
||||
|
||||
```text
|
||||
C:\Windows\System32\CertSrv\CertEnroll\%3%8%9.crl
|
||||
http://pki.bunny-lab.io/pki/%3%8%9.crl
|
||||
```
|
||||
|
||||
The AIA value should contain:
|
||||
|
||||
```text
|
||||
C:\Windows\System32\CertSrv\CertEnroll\%1_%3%4.crt
|
||||
http://pki.bunny-lab.io/pki/%1_%3%4.crt
|
||||
```
|
||||
|
||||
Restart Certificate Services:
|
||||
|
||||
```powershell
|
||||
net stop certsvc
|
||||
net start certsvc
|
||||
```
|
||||
|
||||
Generate the initial Root CA CRL:
|
||||
|
||||
```powershell
|
||||
certutil -crl
|
||||
```
|
||||
|
||||
Confirm that the CRL is created with the expected name in:
|
||||
|
||||
```text
|
||||
C:\Windows\System32\CertSrv\CertEnroll\
|
||||
```
|
||||
|
||||
Expected Root CA files include:
|
||||
|
||||
```text
|
||||
BunnyLab-RootCA.crl
|
||||
LAB-CA-01_BunnyLab-RootCA.crt
|
||||
```
|
||||
|
||||
!!! warning "Do Not Proceed Until CRL Generation Works"
|
||||
If `certutil -crl` fails, or if it generates a literal filename such as `%3%8%9.crl`, stop and correct the CDP/AIA registry values before issuing the Subordinate CA certificate.
|
||||
|
||||
## PKI HTTP Distribution Point on `LAB-CA-02`
|
||||
Before issuing and installing the Subordinate CA certificate, configure an HTTP distribution point that can host Root CA and Subordinate CA CRLs and CA certificates.
|
||||
|
||||
Although this HTTP endpoint is hosted on `LAB-CA-02` in this guide, clients should access it through the stable DNS name:
|
||||
|
||||
```text
|
||||
pki.bunny-lab.io
|
||||
```
|
||||
|
||||
### Install IIS
|
||||
On `LAB-CA-02`, install IIS:
|
||||
|
||||
```powershell
|
||||
Install-WindowsFeature Web-Server -IncludeManagementTools
|
||||
```
|
||||
|
||||
### Create the PKI Publication Directory
|
||||
On `LAB-CA-02`, create the HTTP publication directory:
|
||||
|
||||
```powershell
|
||||
mkdir C:\inetpub\wwwroot\pki
|
||||
```
|
||||
|
||||
### Configure DNS
|
||||
Create a DNS record:
|
||||
|
||||
```text
|
||||
pki.bunny-lab.io -> LAB-CA-02.bunny-lab.io
|
||||
```
|
||||
|
||||
or point `pki.bunny-lab.io` directly to the IP address of `LAB-CA-02`.
|
||||
|
||||
### Validate HTTP Access
|
||||
Create a temporary test file:
|
||||
|
||||
```powershell
|
||||
"test" | Out-File C:\inetpub\wwwroot\pki\test.txt -Encoding ascii
|
||||
```
|
||||
|
||||
From another system, validate access:
|
||||
|
||||
```powershell
|
||||
Invoke-WebRequest http://pki.bunny-lab.io/pki/test.txt
|
||||
```
|
||||
|
||||
Or browse to:
|
||||
|
||||
```text
|
||||
http://pki.bunny-lab.io/pki/test.txt
|
||||
```
|
||||
|
||||
Once validated, remove the test file:
|
||||
|
||||
```powershell
|
||||
Remove-Item C:\inetpub\wwwroot\pki\test.txt
|
||||
```
|
||||
|
||||
### Publish Root CA Files to the HTTP Distribution Point
|
||||
Copy the Root CA files from `LAB-CA-01`:
|
||||
|
||||
```text
|
||||
C:\Windows\System32\CertSrv\CertEnroll\
|
||||
```
|
||||
|
||||
to the IIS directory on `LAB-CA-02`:
|
||||
|
||||
```text
|
||||
C:\inetpub\wwwroot\pki\
|
||||
```
|
||||
|
||||
Required Root CA files:
|
||||
|
||||
```text
|
||||
BunnyLab-RootCA.crl
|
||||
LAB-CA-01_BunnyLab-RootCA.crt
|
||||
```
|
||||
|
||||
Validate that these files are reachable:
|
||||
|
||||
```powershell
|
||||
Invoke-WebRequest http://pki.bunny-lab.io/pki/BunnyLab-RootCA.crl
|
||||
Invoke-WebRequest http://pki.bunny-lab.io/pki/LAB-CA-01_BunnyLab-RootCA.crt
|
||||
```
|
||||
|
||||
!!! note "Root CA Offline Model"
|
||||
After the Root CA files are published to the HTTP distribution point, `LAB-CA-01` can be taken offline again until the next CRL publication, CA renewal, or Subordinate CA certificate operation is required.
|
||||
|
||||
## Online (Domain-Joined) Subordinate/Intermediary CA `LAB-CA-02`
|
||||
### Role Deployment
|
||||
Now that we have set up the root certificate authority, we can focus on setting up the subordinate CA.
|
||||
|
||||
!!! warning "Enterprise Admin Requirement"
|
||||
When you are setting up the role, you **absolutely** have to use an "*Enterprise*" Admin account. This could be a service account like `svcCertAdmin` or something similar.
|
||||
|
||||
- Navigate to "**Server Manager > (Alert Flag) > Post-deployment Configuration: Active Directory Certificate Services**"
|
||||
- Under credentials, enter the username for an Enterprise Admin. (e.g. `BUNNY-LAB\nicole.rappe`)
|
||||
- Click "**Next**"
|
||||
- Check the following roles (*we will add the rest after setting up the core CA functionality*)
|
||||
- `Certification Authority`
|
||||
- `Certification Authority Web Enrollment`
|
||||
- Check the "**Enterprise CA**" radio box then click "**Next**"
|
||||
- Check the "**Subordinate CA**" radio box then click "**Next**"
|
||||
- Check the "**Create a new private key**" radio box then click "**Next**"
|
||||
- Click the dropdown menu for "**Select a crypotographic provider**" and ensure that "**RSA#Microsoft Software Key Storage Provider**" is selected
|
||||
- *Microsoft Software Key Storage Provider (KSP) is the latest, most flexible provider designed to work with the Cryptography Next Generation (CNG) APIs. It offers better support for modern algorithms and improved security management (such as support for key attestation, better hardware integration, and improved key protection mechanisms).*
|
||||
- Set the key length to `4096`
|
||||
- Set the hash algorithm to `SHA256`
|
||||
- Click "**Next**"
|
||||
- **Common Name for this CA**: `BunnyLab-SubordinateCA-01`
|
||||
- **Distinguished name suffix**: `DC=bunny-lab,DC=io`
|
||||
- This will be auto-filled based on the domain that the CA is joined to
|
||||
- **Preview of distinguished name**: `CN=BunnyLab-SubordinateCA-01,DC=bunny-lab,DC=io`
|
||||
- Click "**Next**"
|
||||
- Select the "**Save a certificate request to file on the target machine**" radio button
|
||||
- This will auto-populate the destination to something like "`C:\LAB-CA-02.bunny-lab.io_bunny-lab-LAB-CA-02-CA.req`"
|
||||
- Click "**Next**" > "**Next**" > "**Configure**"
|
||||
|
||||
You will see a finalization screen confirming everything we have configured, it should look something like what is seen below:
|
||||
|
||||
| **Field** | **Value** |
|
||||
| :--- | :--- |
|
||||
| CA Type | Enterprise Subordinate |
|
||||
| Cryptographic provider | RSA#Microsoft Software Key Storage Provider |
|
||||
| Hash Algorithm | SHA256 |
|
||||
| Key Length | 4096 |
|
||||
| Allow Administrator Interaction | Disabled |
|
||||
| Certificate Validity Period | Determined by the parent CA |
|
||||
| Distinguished Name | CN=BunnyLab-SubordinateCA-01,DC=bunny-lab,DC=io |
|
||||
| Offline Request File Location | `C:\LAB-CA-02.bunny-lab.io_bunny-lab-LAB-CA-02-CA.req` |
|
||||
| Certificate Database Location | C:\Windows\system32\CertLog |
|
||||
| Certificate Database Log Location | C:\Windows\system32\CertLog |
|
||||
|
||||
!!! quote "Pending Certificate Signing Request"
|
||||
You will see a screen telling you that the **Certification Authority Web Enrollment** was successful but it will give a warning about the **Certification Authority**. The Active Directory Certificate Services installation is incomplete. To complete the installation, use the request file <file-name> to obtain a certificate from the parent CA [*The RootCA*]. Then, use the Certification Authority snap-in to install the certificate. To complete this procedure, right-click the node with the name of the CA, and then click "Install CA Certificate".
|
||||
|
||||
### Role Configuration
|
||||
At this point, we will need to focus on getting the certificate signing request generated on `LAB-CA-02` to `LAB-CA-01` (the rootCA), this can be via temporary network access or via a USB flashdrive.
|
||||
|
||||
!!! danger
|
||||
If using a USB flashdrive is not viable, don't leave the RootCA server on the network any longer than what is absolutely necessary.
|
||||
|
||||
!!! warning "Prerequisite Check"
|
||||
Before the Root CA signs the Subordinate CA request, confirm the following:
|
||||
|
||||
- The Root CA CDP/AIA registry values are configured.
|
||||
- `certutil -crl` succeeds on `LAB-CA-01`.
|
||||
- `BunnyLab-RootCA.crl` is published to `http://pki.bunny-lab.io/pki/BunnyLab-RootCA.crl`.
|
||||
- `LAB-CA-01_BunnyLab-RootCA.crt` is published to `http://pki.bunny-lab.io/pki/LAB-CA-01_BunnyLab-RootCA.crt`.
|
||||
|
||||
- Once the certificate signing request file `C:\LAB-CA-02.bunny-lab.io_bunny-lab-LAB-CA-02-CA.req` is on `LAB-CA-01` (RootCA) we can proceed to get it signed.
|
||||
- Navigate to "**Server Manager > Tools > Certification Authority**"
|
||||
- Right-click the CA node in the treeview on the left-hand sidebar (e.g. `BunnyLab-RootCA`)
|
||||
- Click on "**All Tasks" > "Submit new request...**"
|
||||
- Browse to and select the subordinate CA’s .req file (e.g. `LAB-CA-02.bunny-lab.io_bunny-lab-LAB-CA-02-CA.req`)
|
||||
- Click on "**BunnyLab-RootCA > Pending Requests**
|
||||
- Right-click the request we just imported, and select "**All Tasks > Issue**"
|
||||
- Click on ""**BunnyLab-RootCA > Issued Certificates**"
|
||||
- Locate the new subordinate CA certificate, and double-click it.
|
||||
- Click the "**Details**" tab
|
||||
- Click the "**Copy to File**" button
|
||||
- Click "**Next**"
|
||||
- Choose `DER encoded binary X.509 (.CER)` and save as `LAB-CA-02-SubCA.cer`.
|
||||
- Export the Root CA certificate:
|
||||
- Right-click the `BunnyLab-RootCA` node > Properties > View Certificate > Details > Copy to File...
|
||||
- Save as `RootCA.cer`
|
||||
- Copy both `LAB-CA-02-SubCA.cer` (the signed subordinate CA cert) and `RootCA.cer` (the root CA cert) to the subordinate CA (`LAB-CA-02`), using a secure method (e.g. USB drive).
|
||||
- On `LAB-CA-02` (Subordinate CA), Navigate to "**Server Manager > Tools > Certification Authority**"
|
||||
- Right-click the CA node in the treeview on the left-hand sidebar (e.g. `BunnyLab-SubordinateCA-01`)
|
||||
- Click on "**All Tasks" > "Install CA Certificate**"
|
||||
- Browse to and select `LAB-CA-02-SubCA.cer` (*you may need to change the cert file extension filter to `X.509 Certificate`*)
|
||||
- When prompted for the CA chain or root certificate, browse for and select the `RootCA.cer` you transferred earlier along with the `LAB-CA-02-SubCA.cer`
|
||||
- Launch `certlm.msc` to open the `[Certificates - Local Computer]` management window
|
||||
- Right-Click "**Trusted Root Certification Authorities**" > All Tasks > Import
|
||||
- Click "**Next**"
|
||||
- Browse to the `RootCA.cer` file exported from `LAB-CA-01`
|
||||
- Place all certificates in the following store: "Trusted Root Certification Authorities"
|
||||
- Click "**Next**" and finish importing the Root CA certificate
|
||||
- Do **not** rely on manually importing the Root CA CRL into a certificate store as the revocation strategy. Revocation should be validated through the HTTP CDP URL embedded in the issued certificates.
|
||||
- Verify Root CA CRL retrieval from `LAB-CA-02`:
|
||||
|
||||
```powershell
|
||||
Invoke-WebRequest http://pki.bunny-lab.io/pki/BunnyLab-RootCA.crl
|
||||
```
|
||||
|
||||
- Verify the Subordinate CA certificate chain and revocation status:
|
||||
|
||||
```powershell
|
||||
certutil -verify -urlfetch LAB-CA-02-SubCA.cer
|
||||
```
|
||||
|
||||
- Right-click the CA node in the treeview on the left-hand sidebar (e.g. `BunnyLab-SubordinateCA-01`)
|
||||
- Click on "**All Tasks" > "Start Service**"
|
||||
- Verify that the CA status is now green (running).
|
||||
|
||||
### Configure Subordinate CA CDP and AIA Publication URLs
|
||||
After the Subordinate CA service is running, configure CDP/AIA publication for certificates issued by the Subordinate CA.
|
||||
|
||||
Run the following on `LAB-CA-02`:
|
||||
|
||||
```powershell
|
||||
certutil -setreg CA\CRLPublicationURLs "65:C:\Windows\System32\CertSrv\CertEnroll\%3%8%9.crl\n6:http://pki.bunny-lab.io/pki/%3%8%9.crl"
|
||||
```
|
||||
|
||||
```powershell
|
||||
certutil -setreg CA\CACertPublicationURLs "1:C:\Windows\System32\CertSrv\CertEnroll\%1_%3%4.crt\n2:http://pki.bunny-lab.io/pki/%1_%3%4.crt"
|
||||
```
|
||||
|
||||
Validate the registry values:
|
||||
|
||||
```powershell
|
||||
certutil -getreg CA\CRLPublicationURLs
|
||||
certutil -getreg CA\CACertPublicationURLs
|
||||
```
|
||||
|
||||
Restart Certificate Services on `LAB-CA-02`:
|
||||
|
||||
```powershell
|
||||
net stop certsvc
|
||||
net start certsvc
|
||||
```
|
||||
|
||||
Generate the Subordinate CA CRL:
|
||||
|
||||
```powershell
|
||||
certutil -crl
|
||||
```
|
||||
|
||||
Copy the Subordinate CA CRL and certificate from:
|
||||
|
||||
```text
|
||||
C:\Windows\System32\CertSrv\CertEnroll\
|
||||
```
|
||||
|
||||
to:
|
||||
|
||||
```text
|
||||
C:\inetpub\wwwroot\pki\
|
||||
```
|
||||
|
||||
Validate HTTP access to the Subordinate CA CRL and certificate after copying them to IIS.
|
||||
|
||||
!!! note "Subordinate CA Publication"
|
||||
The Root CA signs the Subordinate CA certificate. The Subordinate CA signs domain/server/client certificates. Therefore, clients need access to both Root CA revocation data and Subordinate CA revocation data.
|
||||
|
||||
## Reissuing the Subordinate CA Certificate After CDP/AIA Corrections
|
||||
If the Root CA CDP/AIA settings were configured or corrected after the original Subordinate CA certificate was issued, the Subordinate CA certificate must be reissued.
|
||||
|
||||
This is required because CDP/AIA values are embedded into issued certificates at issuance time. Changing the Root CA registry values later does not retroactively fix already-issued Subordinate CA certificates.
|
||||
|
||||
### Generate a New Subordinate CA Renewal Request
|
||||
On `LAB-CA-02`, run:
|
||||
|
||||
```powershell
|
||||
certutil -renewCert ReuseKeys
|
||||
```
|
||||
|
||||
If prompted to submit the request to an online parent CA, click **Cancel**. This is expected for an offline Root CA workflow. A new `.req` file will be generated locally.
|
||||
|
||||
### Submit the Renewal Request to the Root CA
|
||||
Copy the generated `.req` file to `LAB-CA-01`.
|
||||
|
||||
On `LAB-CA-01`:
|
||||
|
||||
- Open "**Server Manager > Tools > Certification Authority**"
|
||||
- Right-click the Root CA node (e.g. `BunnyLab-RootCA`)
|
||||
- Click "**All Tasks > Submit new request...**"
|
||||
- Select the new `.req` file
|
||||
- Go to "**Pending Requests**"
|
||||
- Right-click the pending request and select "**All Tasks > Issue**"
|
||||
- Go to "**Issued Certificates**"
|
||||
- Open the newly issued Subordinate CA certificate
|
||||
- Click the "**Details**" tab
|
||||
- Click "**Copy to File**"
|
||||
- Export as `DER encoded binary X.509 (.CER)`
|
||||
- Save as `LAB-CA-02-SubCA.cer`
|
||||
|
||||
### Install the Renewed Subordinate CA Certificate
|
||||
Copy `LAB-CA-02-SubCA.cer` back to `LAB-CA-02`.
|
||||
|
||||
On `LAB-CA-02`:
|
||||
|
||||
- Open "**Server Manager > Tools > Certification Authority**"
|
||||
- Right-click the Subordinate CA node
|
||||
- Click "**All Tasks > Install CA Certificate**"
|
||||
- Select the renewed `LAB-CA-02-SubCA.cer`
|
||||
- Start the Certificate Services service
|
||||
|
||||
Validate:
|
||||
|
||||
```powershell
|
||||
certutil -verify -urlfetch LAB-CA-02-SubCA.cer
|
||||
```
|
||||
|
||||
The validation should not return:
|
||||
|
||||
```text
|
||||
CRYPT_E_REVOCATION_OFFLINE
|
||||
```
|
||||
|
||||
## Create Auto-Enrollment Group Policy
|
||||
The Certificate Auto-Enrollment Group Policy enables domain-joined devices (*computers, including domain controllers*) to automatically request, renew, and install certificates from the Enterprise CA (in this case, the Subordinate CA `LAB-CA-02`).
|
||||
|
||||
### Create GPO
|
||||
- Open the Group Policy Management editor on one of your domain controllers, then "Create a GPO in this domain, and link it here" wherever it will be able to target the domain controllers, this may be at the root, or in a specific OU that holds domain controllers. (e.g. `bunny-lab.io\Domain Controllers` )
|
||||
- Name the new GPO something like "**Certificate Auto-Enrollment**"
|
||||
- Edit the GPO
|
||||
- Navigate to "**Computer Configuration > Policies > Windows Settings > Security Settings > Public Key Policies**"
|
||||
- Find and open "**Certificate Services Client - Auto-Enrollment.**"
|
||||
- Set the Configuration Model to "**Enabled**"
|
||||
- Check both checkboxes for "**Renew expired certificates, update pending certificates, and remove revoked certificates**" and "**Update certificates that use certificate templates**"
|
||||
- Click "**OK**"
|
||||
- Navigate to "**Computer Configuration > Policies > Windows Settings > Security Settings > Public Key Policies > Trusted Root Certification Authorities**"
|
||||
- Right-click the "**Trusted Root Certification Authorities**" folder and select "**Import...**" > Proceed to browse for the `RootCA.cer` that you previously generated. (*copy it to the domain controller if needed from one of the Certificate Authorities*)
|
||||
- Proceed to import the certificate, clicking-through all of the prompts and confirmations until it finishes the import.
|
||||
- Navigate to "**Computer Configuration > Policies > Windows Settings > Security Settings > Public Key Policies > Intermediate Certification Authorities**"
|
||||
- Right-click the "**Intermediate Certification Authorities**" folder and select "**Import...**" > Proceed to browse for the `LAB-CA-02-SubCA.cer` that you previously generated. (*copy it to the domain controller if needed from one of the Certificate Authorities*)
|
||||
- Proceed to import the certificate, clicking-through all of the prompts and confirmations until it finishes the import.
|
||||
- Run a `gpupdate /force` on your domain controller(s) and give it a few minutes to pull down their new domain controller certificates
|
||||
|
||||
!!! note "Reissuing Certificates After PKI Corrections"
|
||||
If any machine certificates, domain controller certificates, terminal server certificates, NPS certificates, or other service certificates were issued before CDP/AIA was configured correctly, reissue them. Old certificates may continue to work in some paths, but revocation checking and chain validation may be inconsistent.
|
||||
|
||||
For auto-enrolled certificates, use:
|
||||
|
||||
```powershell
|
||||
gpupdate /force
|
||||
certutil -pulse
|
||||
```
|
||||
|
||||
On affected systems, remove old certificates from `Certificates - Local Computer > Personal > Certificates` if duplicate or stale certificates remain after renewal.
|
||||
|
||||
### Validate Auto-Enrollment Functionality
|
||||
At this point, you need to check that there is a certificate installed within "**Certificates - Local Computer > Personal > Certificates**" for "Domain Controller Server Authentication"
|
||||
|
||||
- Load the Certificate - Local Machine (`certlm.msc`) and navigate to "**Personal > Certificates**" > You should see something similar to the following:
|
||||
|
||||
| **Issued To** | **Issued By** | **Expiration Date** | **Intended Purposes** | **Certificate Template** |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| LAB-DC-01.bunny-lab.io | BunnyLab-SubordinateCA-01 | 7/15/2026 | Directory Service Email Replication | Directory Email Replication |
|
||||
| LAB-DC-01.bunny-lab.io | BunnyLab-SubordinateCA-01 | 7/15/2026 | Client Authentication, Server Authentication, Smart Card Logon | Domain Controller Authentication |
|
||||
| LAB-DC-01.bunny-lab.io | BunnyLab-SubordinateCA-01 | 7/15/2026 | Client Authentication, Server Authentication, Smart Card Logon, KDC Authentication | Kerberos Authentication |
|
||||
|
||||
### Validate LDAPS Connectivity
|
||||
Lastly, we want to ensure that LDAPS is functioning. By default, once these certs are enrolled on the domain controller(s), LDAPS *should* just work out of the box. To verify this, you can run this command on any device on the same network as the domain controllers. If it comes back successful like in the following example output, then you are golden:
|
||||
|
||||
```powershell
|
||||
PS C:\Users\nicole.rappe> Test-NetConnection LAB-DC-01.bunny-lab.io -Port 636
|
||||
ComputerName : LAB-DC-01.bunny-lab.io
|
||||
RemoteAddress : 192.168.3.25
|
||||
RemotePort : 636
|
||||
InterfaceAlias : Ethernet
|
||||
SourceAddress : 192.168.3.254
|
||||
TcpTestSucceeded : True
|
||||
|
||||
PS C:\Users\nicole.rappe> Test-NetConnection LAB-DC-02.bunny-lab.io -Port 636
|
||||
ComputerName : LAB-DC-02.bunny-lab.io
|
||||
RemoteAddress : 192.168.3.26
|
||||
RemotePort : 636
|
||||
InterfaceAlias : Ethernet
|
||||
SourceAddress : 192.168.3.254
|
||||
TcpTestSucceeded : True
|
||||
```
|
||||
|
||||
!!! success "Successful LDAPS Connectivity"
|
||||
LDAPS should now be functional on your domain controller(s).
|
||||
|
||||
### Validate Certificate Revocation and Chain Building
|
||||
After auto-enrollment and LDAPS validation, export one representative certificate from a domain controller or server and validate it:
|
||||
|
||||
```powershell
|
||||
certutil -verify -urlfetch <issued-certificate>.cer
|
||||
```
|
||||
|
||||
The output should show successful chain validation and should not contain:
|
||||
|
||||
```text
|
||||
CRYPT_E_REVOCATION_OFFLINE
|
||||
```
|
||||
|
||||
Also validate direct access to the Root CA CRL and Subordinate CA CRL:
|
||||
|
||||
```powershell
|
||||
Invoke-WebRequest http://pki.bunny-lab.io/pki/BunnyLab-RootCA.crl
|
||||
```
|
||||
|
||||
Run an equivalent check for the Subordinate CA CRL after confirming the exact generated filename in:
|
||||
|
||||
```text
|
||||
C:\Windows\System32\CertSrv\CertEnroll\
|
||||
```
|
||||
|
||||
## Maintain Certificate Revocation Lists
|
||||
After deployment, use [Publish and Maintain Certificate Revocation Lists](<../../../workflows/Identity and Certificates/Certificates/Publish and Maintain Certificate Revocation Lists.md>) for recurring publication and monitoring.
|
||||
|
||||
## Connect LDAPS Clients
|
||||
Use [Export Certificates for LDAPS Clients](<../../../workflows/Identity and Certificates/Certificates/Export Certificates for LDAPS Clients.md>) when an application needs the certificate chain.
|
||||
|
||||
## Related Documentation
|
||||
- [Related Identity and Certificates Documentation](<../../../reference/Identity and Certificates/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
tags:
|
||||
- Authelia
|
||||
- Authentication
|
||||
- Docker
|
||||
---
|
||||
|
||||
## Purpose
|
||||
Authelia is an open-source authentication and authorization server and portal fulfilling the identity and access management (IAM) role of information security in providing multi-factor authentication and single sign-on (SSO) for your applications via a web portal. It acts as a companion for common reverse proxies.
|
||||
|
||||
```yaml title="docker-compose.yml"
|
||||
services:
|
||||
authelia:
|
||||
image: authelia/authelia
|
||||
container_name: authelia
|
||||
volumes:
|
||||
- /mnt/authelia/config:/config
|
||||
networks:
|
||||
docker_network:
|
||||
ipv4_address: 192.168.5.159
|
||||
expose:
|
||||
- 9091
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
disable: true
|
||||
environment:
|
||||
- TZ=America/Denver
|
||||
|
||||
redis:
|
||||
image: redis:alpine
|
||||
container_name: redis
|
||||
volumes:
|
||||
- /mnt/authelia/redis:/data
|
||||
networks:
|
||||
docker_network:
|
||||
ipv4_address: 192.168.5.158
|
||||
expose:
|
||||
- 6379
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- TZ=America/Denver
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: docker_network
|
||||
docker_network:
|
||||
external: true
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
- [Docker Network Prerequisite](<../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
|
||||
- [Related Identity and Certificates Documentation](<../../reference/Identity and Certificates/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
@@ -0,0 +1,182 @@
|
||||
---
|
||||
tags:
|
||||
- Authentik
|
||||
- Authentication
|
||||
- Docker
|
||||
---
|
||||
|
||||
## Purpose
|
||||
Authentik is an open-source Identity Provider, focused on flexibility and versatility. With authentik, site administrators, application developers, and security engineers have a dependable and secure solution for authentication in almost any type of environment. There are robust recovery actions available for the users and applications, including user profile and password management. You can quickly edit, deactivate, or even impersonate a user profile, and set a new password for new users or reset an existing password.
|
||||
|
||||
!!! bug
|
||||
The docker-compose version of the deployment appears bugged and has known issues, deployment via Kubernetes is required to stability and support.
|
||||
|
||||
This document is based on the [Official Docker-Compose Documentation](https://goauthentik.io/docs/installation/docker-compose). It is meant for testing / small-scale production deployments.
|
||||
|
||||
## Docker Configuration
|
||||
```yaml title="docker-compose.yml"
|
||||
---
|
||||
version: "3.4"
|
||||
|
||||
services:
|
||||
postgresql:
|
||||
image: docker.io/library/postgres:12-alpine
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
||||
start_period: 20s
|
||||
interval: 30s
|
||||
retries: 5
|
||||
timeout: 5s
|
||||
volumes:
|
||||
- /srv/containers/authentik/db:/var/lib/postgresql/data
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${PG_PASS:?database password required}
|
||||
POSTGRES_USER: ${PG_USER:-authentik}
|
||||
POSTGRES_DB: ${PG_DB:-authentik}
|
||||
env_file:
|
||||
- stack.env
|
||||
networks:
|
||||
docker_network:
|
||||
ipv4_address: 192.168.5.2
|
||||
|
||||
redis:
|
||||
image: docker.io/library/redis:alpine
|
||||
command: --save 60 1 --loglevel warning
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
|
||||
start_period: 20s
|
||||
interval: 30s
|
||||
retries: 5
|
||||
timeout: 3s
|
||||
volumes:
|
||||
- /srv/containers/authentik/redis:/data
|
||||
networks:
|
||||
docker_network:
|
||||
ipv4_address: 192.168.5.3
|
||||
|
||||
server:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.7}
|
||||
restart: unless-stopped
|
||||
command: server
|
||||
environment:
|
||||
AUTHENTIK_REDIS__HOST: redis
|
||||
AUTHENTIK_POSTGRESQL__HOST: postgresql
|
||||
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
|
||||
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
||||
volumes:
|
||||
- /srv/containers/authentik/media:/media
|
||||
- /srv/containers/authentik/custom-templates:/templates
|
||||
env_file:
|
||||
- stack.env
|
||||
ports:
|
||||
- "${COMPOSE_PORT_HTTP:-9000}:9000"
|
||||
- "${COMPOSE_PORT_HTTPS:-9443}:9443"
|
||||
depends_on:
|
||||
- postgresql
|
||||
- redis
|
||||
networks:
|
||||
docker_network:
|
||||
ipv4_address: 192.168.5.4
|
||||
|
||||
worker:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.7}
|
||||
restart: unless-stopped
|
||||
command: worker
|
||||
environment:
|
||||
AUTHENTIK_REDIS__HOST: redis
|
||||
AUTHENTIK_POSTGRESQL__HOST: postgresql
|
||||
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
|
||||
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
||||
# `user: root` and the docker socket volume are optional.
|
||||
# See more for the docker socket integration here:
|
||||
# https://goauthentik.io/docs/outposts/integrations/docker
|
||||
# Removing `user: root` also prevents the worker from fixing the permissions
|
||||
# on the mounted folders, so when removing this make sure the folders have the correct UID/GID
|
||||
# (1000:1000 by default)
|
||||
user: root
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /srv/containers/authentik/media:/media
|
||||
- /srv/containers/authentik/certs:/certs
|
||||
- /srv/containers/authentik/custom-templates:/templates
|
||||
env_file:
|
||||
- stack.env
|
||||
depends_on:
|
||||
- postgresql
|
||||
- redis
|
||||
networks:
|
||||
docker_network:
|
||||
ipv4_address: 192.168.5.5
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: docker_network
|
||||
docker_network:
|
||||
external: true
|
||||
```
|
||||
|
||||
```yaml title=".env"
|
||||
PG_PASS=<See Below>
|
||||
AUTHENTIK_SECRET_KEY=<See Below>
|
||||
AUTHENTIK_BOOTSTRAP_PASSWORD=<SecurePassword>
|
||||
AUTHENTIK_BOOTSTRAP_TOKEN=<SecureOneTimePassword>
|
||||
AUTHENTIK_BOOTSTRAP_EMAIL=nicole.rappe@bunny-lab.io
|
||||
|
||||
## SMTP Host Emails are sent to
|
||||
#AUTHENTIK_EMAIL__HOST=localhost
|
||||
#AUTHENTIK_EMAIL__PORT=25
|
||||
## Optionally authenticate (don't add quotation marks to your password)
|
||||
#AUTHENTIK_EMAIL__USERNAME=
|
||||
#AUTHENTIK_EMAIL__PASSWORD=
|
||||
## Use StartTLS
|
||||
#AUTHENTIK_EMAIL__USE_TLS=false
|
||||
## Use SSL
|
||||
#AUTHENTIK_EMAIL__USE_SSL=false
|
||||
#AUTHENTIK_EMAIL__TIMEOUT=10
|
||||
## Email address authentik will send from, should have a correct @domain
|
||||
#AUTHENTIK_EMAIL__FROM=authentik@localhost
|
||||
```
|
||||
|
||||
!!! note "Generating Passwords"
|
||||
Navigate to the online [PWGen Password Generator](https://pwgen.io/en/) to generate the passwords for `PG_PASS` (40 characters) and `AUTHENTIK_SECRET_KEY` (50 characters).
|
||||
|
||||
Because of a PostgreSQL limitation, only passwords up to 99 characters are supported
|
||||
See https://www.postgresql.org/message-id/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
|
||||
|
||||
!!! warning "Password Symbols"
|
||||
You may encounter the Authentik WebUI throwing `Forbidden` errors, and this is likely caused by you using a password with "problematic" characters for the `PG_PASS` environment variable. Try to avoid using `,` or `;` or `:` in the password you generate.
|
||||
|
||||
## WebUI Initial Setup
|
||||
To start the initial setup, navigate to https://192.168.5.4:9443/if/flow/initial-setup/
|
||||
|
||||
## Traefik Reverse Proxy Configuration
|
||||
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
|
||||
|
||||
```yaml
|
||||
http:
|
||||
routers:
|
||||
PLACEHOLDER:
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls:
|
||||
certResolver: myresolver
|
||||
service: PLACEHOLDER
|
||||
rule: Host(`PLACEHOLDER.bunny-lab.io`)
|
||||
|
||||
services:
|
||||
PLACEHOLDER:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://PLACEHOLDER:80
|
||||
passHostHeader: true
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
- [Docker Network Prerequisite](<../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
|
||||
- [Related Identity and Certificates Documentation](<../../reference/Identity and Certificates/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
- [Traefik Deployment](<../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
|
||||
@@ -0,0 +1,246 @@
|
||||
---
|
||||
tags:
|
||||
- Keycloak
|
||||
- Authentication
|
||||
- Docker
|
||||
---
|
||||
|
||||
## Purpose
|
||||
Keycloak is an open source identity and access management system for modern applications and services.
|
||||
|
||||
- [Original Reference Compose File](https://github.com/JamesTurland/JimsGarage/blob/main/Keycloak/docker-compose.yaml)
|
||||
- [Original Reference Deployment Video](https://www.youtube.com/watch?v=6ye4lP9EA2Y)
|
||||
- [Theme Customization Documentation](https://www.baeldung.com/spring-keycloak-custom-themes)
|
||||
|
||||
## Keycloak Authentication Sequence
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant Traefik as Traefik Reverse Proxy
|
||||
participant Keycloak
|
||||
participant Services
|
||||
|
||||
User->>Traefik: Access service URL
|
||||
Traefik->>Keycloak: Redirect to Keycloak for authentication
|
||||
User->>Keycloak: Provide credentials for authentication
|
||||
Keycloak->>User: Return authorization token/cookie
|
||||
User->>Traefik: Send request with authorization token/cookie
|
||||
Traefik->>Keycloak: Validate token/cookie
|
||||
Keycloak->>Traefik: Token/cookie is valid
|
||||
Traefik->>Services: Forward request to services
|
||||
Services->>Traefik: Response back to Traefik
|
||||
Traefik->>User: Return service response
|
||||
```
|
||||
|
||||
## Docker Configuration
|
||||
=== "docker-compose.yml"
|
||||
|
||||
```yaml
|
||||
version: '3.7'
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16.2
|
||||
volumes:
|
||||
- /srv/containers/keycloak/db:/var/lib/postgresql/data
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U keycloak"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
keycloak_internal_network: # Network for internal communication
|
||||
ipv4_address: 172.16.238.3 # Static IP for PostgreSQL in internal network
|
||||
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:23.0.6
|
||||
command: start
|
||||
volumes:
|
||||
- /srv/containers/keycloak/themes:/opt/keycloak/themes
|
||||
- /srv/containers/keycloak/base-theme:/opt/keycloak/themes/base
|
||||
environment:
|
||||
TZ: America/Denver # (1)
|
||||
KC_PROXY_ADDRESS_FORWARDING: true # (2)
|
||||
KC_HOSTNAME_STRICT: false
|
||||
KC_HOSTNAME: auth.bunny-lab.io # (3)
|
||||
KC_PROXY: edge # (4)
|
||||
KC_HTTP_ENABLED: true
|
||||
KC_DB: postgres
|
||||
KC_DB_USERNAME: ${POSTGRES_USER}
|
||||
KC_DB_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
KC_DB_URL_HOST: postgres
|
||||
KC_DB_URL_PORT: 5432
|
||||
KC_DB_URL_DATABASE: ${POSTGRES_DB}
|
||||
KC_TRANSACTION_RECOVERY: true
|
||||
KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN}
|
||||
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
|
||||
KC_HEALTH_ENABLED: true
|
||||
DB_POOL_MAX_SIZE: 20 # (5)
|
||||
DB_POOL_MIN_SIZE: 5 # (6)
|
||||
DB_POOL_ACQUISITION_TIMEOUT: 30 # (7)
|
||||
DB_POOL_IDLE_TIMEOUT: 300 # (8)
|
||||
JDBC_PARAMS: "connectTimeout=30"
|
||||
KC_HOSTNAME_DEBUG: false # (9)
|
||||
ports:
|
||||
- 8080:8080
|
||||
restart: always
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/auth"] # Health check for Keycloak
|
||||
interval: 30s # Health check interval
|
||||
timeout: 10s # Health check timeout
|
||||
retries: 3 # Health check retries
|
||||
networks:
|
||||
docker_network:
|
||||
ipv4_address: 192.168.5.2
|
||||
keycloak_internal_network: # Network for internal communication
|
||||
ipv4_address: 172.16.238.2 # Static IP for Keycloak in internal network
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: docker_network
|
||||
docker_network:
|
||||
external: true
|
||||
keycloak_internal_network: # Internal network for private communication
|
||||
driver: bridge # Network driver
|
||||
ipam: # IP address management
|
||||
config:
|
||||
- subnet: 172.16.238.0/24 # Subnet for internal network
|
||||
|
||||
```
|
||||
|
||||
1. This sets the timezone of the Keycloak server to your timezone. This is not really necessary according to the official documentation, however I just like to add it to all of my containers as a baseline environment variable to add
|
||||
2. This assumes you are running Keycloak behind a reverse proxy, in my particular case, Traefik
|
||||
3. Set this to the FQDN that you are expecting to reach the Keycloak server at behind your reverse proxy
|
||||
4. This assumes you are running Keycloak behind a reverse proxy, in my particular case, Traefik
|
||||
5. Maximum connections in the database pool
|
||||
6. Minimum idle connections in the database pool
|
||||
7. Timeout for acquiring a connection from the database pool
|
||||
8. Timeout for closing idle connections to the database
|
||||
9. If this is enabled, Navigate to https://auth.bunny-lab.io/realms/master/hostname-debug to troubleshoot issues with the deployment if you experience any issues logging into the web portal or admin UI
|
||||
|
||||
=== ".env"
|
||||
|
||||
```yaml
|
||||
POSTGRES_DB=keycloak
|
||||
POSTGRES_USER=keycloak
|
||||
POSTGRES_PASSWORD=SomethingSecure # (1)
|
||||
KEYCLOAK_ADMIN=admin
|
||||
KEYCLOAK_ADMIN_PASSWORD=SomethingSuperSecureToLoginAsAdmin # (2)
|
||||
```
|
||||
|
||||
1. This is used internally by Keycloak to interact with the PostgreSQL database server
|
||||
2. This is used to log into the web admin portal at https://auth.bunny-lab.io
|
||||
|
||||
## Traefik Reverse Proxy Configuration
|
||||
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
|
||||
|
||||
```yaml
|
||||
http:
|
||||
routers:
|
||||
auth:
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
service: auth
|
||||
rule: Host(`auth.bunny-lab.io`)
|
||||
middlewares:
|
||||
- auth-headers
|
||||
|
||||
services:
|
||||
auth:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://192.168.5.2:8080
|
||||
passHostHeader: true
|
||||
|
||||
middlewares:
|
||||
auth-headers:
|
||||
headers:
|
||||
sslRedirect: true
|
||||
stsSeconds: 31536000
|
||||
stsIncludeSubdomains: true
|
||||
stsPreload: true
|
||||
forceSTSHeader: true
|
||||
customRequestHeaders:
|
||||
X-Forwarded-Proto: https
|
||||
X-Forwarded-Port: "443"
|
||||
```
|
||||
|
||||
## Traefik Keycloak Middleware
|
||||
At this point, we need to add the official Keycloak plugin to Traefik's main configuration. In this example, it will be assumed you need to configure this in Portainer/Docker Compose, and not via a static yml/toml file. Assume you follow the [Docker Compose based Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>).
|
||||
|
||||
## Install Keycloak Plugin
|
||||
If you do not already have the following added to the end of your `command:` section of the docker-compose.yml file in Portainer, go ahead and add it:
|
||||
|
||||
```yaml
|
||||
# Keycloak plugin configuration
|
||||
- "--experimental.plugins.keycloakopenid.moduleName=github.com/Gwojda/keycloakopenid"
|
||||
- "--experimental.plugins.keycloakopenid.version=v0.1.34"
|
||||
```
|
||||
|
||||
## Add Middleware to Traefik Dynamic Configuration
|
||||
You will want to ensure the following exists in the dynamically-loaded config file folder, you can name the file whatever you want, but it will be a one-all middleware for any services you want to have communicating as a specific OAuth2 `Client ID`. For example, you might want to have some services exist in a particular realm of Keycloak, or to have different client rules apply to certain services. If this is the case, you can create multiple middlewares in this single yaml file, each handling a different service / realm. It can get pretty complicated if you want to handle a multi-tenant environment, such as one seen in an enterprise environment.
|
||||
|
||||
```yaml title="keycloak-middleware.yml"
|
||||
http:
|
||||
middlewares:
|
||||
auth-bunny-lab-io:
|
||||
plugin:
|
||||
keycloakopenid:
|
||||
KeycloakURL: "https://auth.bunny-lab.io" # <- Also supports complete URL, e.g. https://my-keycloak-url.com/auth
|
||||
ClientID: "traefik-reverse-proxy"
|
||||
ClientSecret: "https://auth.bunny-lab.io > Clients > traefik-reverse-proxy > Credentials > Client Secret"
|
||||
KeycloakRealm: "master"
|
||||
Scope: "openid profile email"
|
||||
TokenCookieName: "AUTH_TOKEN"
|
||||
UseAuthHeader: "false"
|
||||
# IgnorePathPrefixes: "/api,/favicon.ico [comma deliminated] (optional)"
|
||||
```
|
||||
|
||||
## Configure Valid Redirect URLs
|
||||
At this point, within Keycloak, you need to configure domains that you are allowed to visit after authenticating. You can do this with wildcards, but generally you navigate to "**https://auth.bunny-lab.io > Clients > traefik-reverse-proxy > Valid redirect URIs**" A simple example is adding `https://tools.bunny-lab.io/*` to the list of valid redirect URLs. If the site is not in this list, even if it has the middleware configured in Traefik, it will fail to authenticate and not let the user proceed to the website being protected behind Keycloak.
|
||||
|
||||
## Adding Middleware to Dynamic Traefik Service Config Files
|
||||
At this point, you are in the final stretch, you just need to add the middleware to the Traefik dynamic config files to ensure that it routes the traffic to Keycloak when someone attempts to access that service. Put the following middleware section under the `routers:` section of the config file.
|
||||
|
||||
```yaml
|
||||
middlewares:
|
||||
- auth-bunny-lab-io # Referencing the Keycloak Server
|
||||
```
|
||||
|
||||
A full example config file would look like the following:
|
||||
|
||||
```yaml
|
||||
http:
|
||||
routers:
|
||||
example:
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
service: example
|
||||
rule: Host(`example.bunny-lab.io`)
|
||||
middlewares:
|
||||
- auth-bunny-lab-io # Referencing the Keycloak Server Traefik Middleware
|
||||
|
||||
services:
|
||||
example:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://192.168.5.16:80
|
||||
passHostHeader: true
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
- [Docker Network Prerequisite](<../../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
|
||||
- [Related Identity and Certificates Documentation](<../../../reference/Identity and Certificates/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
- [Traefik Deployment](<../../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
tags:
|
||||
- Password Pusher
|
||||
- Security
|
||||
- Docker
|
||||
---
|
||||
|
||||
## Purpose
|
||||
An application to securely communicate passwords over the web. Passwords automatically expire after a certain number of views and/or time has passed. Track who, what and when.
|
||||
|
||||
## Docker Configuration
|
||||
```yaml title="docker-compose.yml"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
passwordpusher:
|
||||
image: docker.io/pglombardo/pwpush:release
|
||||
expose:
|
||||
- 5100
|
||||
restart: always
|
||||
environment:
|
||||
# Read Documention on how to generate a master key, then put it below
|
||||
- PWPUSH_MASTER_KEY=${PWPUSH_MASTER_KEY}
|
||||
networks:
|
||||
docker_network:
|
||||
ipv4_address: 192.168.5.170
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.passwordpusher.rule=Host(`temp.bunny-lab.io`)"
|
||||
- "traefik.http.routers.passwordpusher.entrypoints=websecure"
|
||||
- "traefik.http.routers.passwordpusher.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.passwordpusher.loadbalancer.server.port=5100"
|
||||
networks:
|
||||
docker_network:
|
||||
external: true
|
||||
```
|
||||
|
||||
```yaml title=".env"
|
||||
PWPUSH_MASTER_KEY=<PASSWORD>
|
||||
PWP__BRAND__TITLE="Bunny Lab"
|
||||
PWP__BRAND__SHOW_FOOTER_MENU=false
|
||||
PWP__BRAND__LIGHT_LOGO="https://cloud.bunny-lab.io/apps/theming/image/logo?v=22"
|
||||
PWP__BRAND__DARK_LOGO="https://cloud.bunny-lab.io/apps/theming/image/logo?v=22"
|
||||
PWP__BRAND__TAGLINE="Secure Temporary Information Exchange"
|
||||
PWP__MAIL__RAISE_DELIVERY_ERRORS=true
|
||||
PWP__MAIL__SMTP_ADDRESS=mail.bunny-lab.io
|
||||
PWP__MAIL__SMTP_PORT=587
|
||||
PWP__MAIL__SMTP_USER_NAME=noreply@bunny-lab.io
|
||||
PWP__MAIL__SMTP_PASSWORD=<SMTP_CREDENTIALS>
|
||||
PWP__MAIL__SMTP_AUTHENTICATION=plain
|
||||
PWP__MAIL__SMTP_STARTTLS=true
|
||||
PWP__MAIL__SMTP_OPEN_TIMEOUT=10
|
||||
PWP__MAIL__SMTP_READ_TIMEOUT=10
|
||||
PWP__HOST_DOMAIN=bunny-lab.io
|
||||
PWP__HOST_PROTOCOL=https
|
||||
PWP__MAIL__MAILER_SENDER='"noreply" <noreply@bunny-lab.io>'
|
||||
PWP__SHOW_VERSION=false
|
||||
PWP__ENABLE_FILE_PUSHES=true
|
||||
PWP__FILES__EXPIRE_AFTER_DAYS_DEFAULT=2
|
||||
PWP__FILES__EXPIRE_AFTER_DAYS_MAX=7
|
||||
PWP__FILES__EXPIRE_AFTER_VIEWS_DEFAULT=5
|
||||
PWP__FILES__EXPIRE_AFTER_VIEWS_MAX=10
|
||||
PWP__FILES__RETRIEVAL_STEP_DEFAULT=true
|
||||
PWP__ENABLE_URL_PUSHES=true
|
||||
PWP__LOG_LEVEL=info
|
||||
```
|
||||
|
||||
!!! note "PWPUSH_MASTER_KEY"
|
||||
Generate a master key by visiting the [official online key generator](https://pwpush.com/en/pages/generate_key).
|
||||
|
||||
## Traefik Reverse Proxy Configuration
|
||||
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
|
||||
|
||||
```yaml
|
||||
http:
|
||||
routers:
|
||||
password-pusher:
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
service: password-pusher
|
||||
rule: Host(`temp.bunny-lab.io`)
|
||||
|
||||
services:
|
||||
password-pusher:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://192.168.5.170:5100
|
||||
passHostHeader: true
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
- [Docker Network Prerequisite](<../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
|
||||
- [Related Identity and Certificates Documentation](<../../reference/Identity and Certificates/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
- [Traefik Deployment](<../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
|
||||
@@ -0,0 +1,150 @@
|
||||
---
|
||||
tags:
|
||||
- PrivacyIDEA
|
||||
- Authentication
|
||||
---
|
||||
|
||||
## Purpose
|
||||
privacyIDEA is a modular authentication system. Using privacyIDEA you can enhance your existing applications like local login, VPN, remote access, SSH connections, access to web sites or web portals with a second factor during authentication.
|
||||
|
||||
!!! info "Assumptions"
|
||||
It is assumed you have a provisioned virtual machine / physical machine, running Ubuntu Server 22.04 to deploy a privacyIDEA server.
|
||||
|
||||
## AWX Deployment
|
||||
### Add Server to Inventory and Pull Inventory/Playbook Updates from Gitea
|
||||
You need to target the new server using a template in AWX (preferrably).
|
||||
|
||||
- We will assume the FQDN of the server is `auth.bunny-lab.io` or just `auth`
|
||||
- Be sure to add the host into the [AWX Homelab Inventory File](https://git.bunny-lab.io/GitOps/awx.bunny-lab.io/src/branch/main/inventories/homelab.ini)
|
||||
- Update / Sync the "**Bunny-Lab**" project in AWX ([Resources > Projects > Bunny-Lab > Sync](https://awx.bunny-lab.io/#/projects/8/details))
|
||||
- Update / Sync the git.bunny-lab.io Inventory Source ([Resources > Inventories > Homelab > Sources > git.bunny-lab.io > Sync](https://awx.bunny-lab.io/#/inventories/inventory/2/sources/9/details))
|
||||
|
||||
### Create a Template
|
||||
Next, you want to make a template to automate the deployment of privacyIDEA on any servers that are members of the `[privacyideaServers]` inventory host group. This is useful for development / testing, as well as rapid re-deployment / scaling.
|
||||
|
||||
- Navigate to **Resources > Templates > Add**
|
||||
|
||||
| **Field** | **Value** |
|
||||
| :--- | :--- |
|
||||
| Template Name | `Deploy PrivacyIDEA Server` |
|
||||
| Description | `Ubuntu Server 22.04 Required` |
|
||||
| Project | `Bunny-Lab` *(Click the Magnifying Lens)* |
|
||||
| Inventory | `Homelab` |
|
||||
| Playbook | `playbooks/Linux/Deployments/privacyIDEA.yml` |
|
||||
| Execution Environment | `AWX EE (latest)` *(Click the Magnifying Lens)* |
|
||||
| Credentials | `SSH: (LINUX) nicole` |
|
||||
|
||||
**Options**:
|
||||
|
||||
- [X] Privilege Escalation: Checked
|
||||
- [X] Enable Fact Storage: Checked
|
||||
|
||||
### Launch the Template
|
||||
Now we need to launch the template. Assuming all of the above was completed, we can now deploy the playbook/template against the Ubuntu Server via SSH.
|
||||
|
||||
- Launch the Template (Rocket Button)
|
||||
- As the template runs, you will see deployment progress output on the screen
|
||||
|
||||
!!! success
|
||||
You will know if everything was successful if you see something that looks like the following:
|
||||
|
||||
```sh
|
||||
ok: [auth]
|
||||
TASK [Install wget and software-properties-common] *****************************
|
||||
ok: [auth]
|
||||
TASK [Download PrivacyIDEA signing key] ****************************************
|
||||
changed: [auth]
|
||||
TASK [Add signing key for Ubuntu 22.04LTS] *************************************
|
||||
changed: [auth]
|
||||
TASK [Add PrivacyIDEA repository] **********************************************
|
||||
changed: [auth]
|
||||
TASK [Update apt cache] ********************************************************
|
||||
changed: [auth]
|
||||
TASK [Install PrivacyIDEA with Apache2] ****************************************
|
||||
changed: [auth]
|
||||
PLAY RECAP *********************************************************************auth : ok=7 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
||||
```
|
||||
|
||||
## Admin Access to WebUI
|
||||
### Create a privacyIDEA Administrator Account
|
||||
You will need to use the CLI in the server in order to create the first administrative account. Run the following command and provide a password for the administrator account.
|
||||
|
||||
```sh
|
||||
sudo pi-manage admin add nicole.rappe -e nicole.rappe@bunny-lab.io
|
||||
```
|
||||
|
||||
### Log into the WebUI
|
||||
Assuming you created an `A` record in the DNS server pointing to the IP address of the privacyIDEA server, Navigate to https://auth.bunny-lab.io and sign in with your newly-created username and password. (e.g. `nicole.rappe`)
|
||||
|
||||
## Connect to Active Directory/LDAP
|
||||
### Create a LDAP User ID Resolver
|
||||
This is what will connect privacyIDEA to an LDAP backend to pull-down users for authentication in Active Directory. Begin by navigating to "**Config > Users > New LDAP Resolver**"
|
||||
|
||||
| **Field** | **Value** |
|
||||
| :--- | :--- |
|
||||
| Resolver Name | `BunnyLab-LDAP` |
|
||||
| Server URI | `ldap://bunny-dc-01.bunny-lab.io, ldap://bunny-db-02.bunny.lab.io` |
|
||||
| Pooling Strategy | `ROUND_ROBIN` |
|
||||
| StartTLS | `<Unchecked>` |
|
||||
| Base DN | `CN=Users,DC=bunny-lab,DC=io` |
|
||||
| Scope | `SUBTREE` |
|
||||
| Bind Type | `Simple` |
|
||||
| Bind DN | `CN=Nicole Rappe,CN=Users,DC=bunny-lab,DC=io`
|
||||
| Bind Password | `<Domain Admin Password for "nicole.rappe">` |
|
||||
|
||||
- Click the "**Preset Active Directory**" button.
|
||||
- Click the "**Test LDAP Resolver**" button.
|
||||
|
||||
### Associate User ID Resolver with a Realm
|
||||
Now we need to create what is called a "**Realm**". Users need to be in realms to have tokens assigned. A user, who is not member of a realm can not have a token assigned and can not authenticate. You can combine several different User ID Resolvers (see UserIdResolvers) into a realm. Navigate to "**Config > Realms**"
|
||||
|
||||
| **Field** | **Value** |
|
||||
| :--- | :--- |
|
||||
| Realm Name | `Bunny-Lab` |
|
||||
| Resolver(s) | `BunnyLab-LDAP` |
|
||||
|
||||
## Configure Push Notifications
|
||||
### Create Policies
|
||||
You will need to create several policies, you can make them all individual, or merge the ones with identical scopes together to keep things more organized. To begin, navigate to "**Config > Policies > Create New Policy**"
|
||||
|
||||
- **Scope**: `Enrollment` > "**push_firebase_configuration**" = `poll only`
|
||||
- **Scope**: `Enrollment` > "**push_registration_url**" = `https://auth.bunny-lab.io/ttype/push`
|
||||
- **Scope**: `Enrollment` > "**push_ssl_verify**" = `0`
|
||||
- **Scope**: `Authentication` > "**push_allow_polling**" = `allow`
|
||||
|
||||
## Enrolling the First Token
|
||||
!!! bug "Push Notifications Broken"
|
||||
Currently, the push notification system (e.g. Cisco DUO") is not behaving as-expected. For now, you can use other authentication methods for the tokens, such as HOTP (on-demand MFA codes) or TOTP (conventional time-based MFA codes).
|
||||
|
||||
### TOTP Token
|
||||
Navigate to "**Tokens > Enroll Token**"
|
||||
|
||||
| **Field** | **Value** |
|
||||
| :--- | :--- |
|
||||
| Token Type | `TOTP` |
|
||||
| Realm | `Bunny-Lab` |
|
||||
| Username | `[256da6f8-9ddb-4ec5-9409-1a95fea27615] nicole.rappe (Nicole Rappe)` |
|
||||
|
||||
Use any MFA authenticator app like Bitwarden or Google Authenticator to add the code and store the secret key somewhere safe.
|
||||
|
||||
## Install Credential Provider
|
||||
### Install Credential Provider Subscription File
|
||||
In order to use the Credential Provider, you have to upload a subscription file. The free-tier allows up to 50 devices using the Credential Provider, but you can alter the source code of privacyIDEA to ignore subscriptions and just unlock everything (custom python code planned).
|
||||
|
||||
When you want to leverage MFA in an environment using the server, you need to have a domain-joined computer running the Credential Provider, which can be found on the [Official Credential Provider Github Page](https://github.com/privacyidea/privacyidea-credential-provider/releases).
|
||||
|
||||
- Download the MSI
|
||||
- Run the installer on the computer
|
||||
- Click "**Next**"
|
||||
- Check the "**Agree**" checkbox, then click "**Next**"
|
||||
- Hostname: `auth.bunny-lab.io`
|
||||
- Path: `/path/to/pi`
|
||||
- [x] Ignore Unknown CA Errors when Using SSL
|
||||
- [x] Ignore Invalid Common Name Errors when Using SSL
|
||||
- Click "**Next**" > "**Next**" > "**Next**"
|
||||
- Click "**Install**" then "**Finish**"
|
||||
|
||||
You can now log out and verify that the credential provider is displayed as an option, and can log in using your domain username, domain password, and TOTP that you configured in the privacyIDEA WebUI.
|
||||
|
||||
## Related Documentation
|
||||
- [Related Identity and Certificates Documentation](<../../reference/Identity and Certificates/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
tags:
|
||||
- Vaultwarden
|
||||
- Security
|
||||
- Docker
|
||||
---
|
||||
|
||||
## Purpose
|
||||
Unofficial Bitwarden compatible server written in Rust, formerly known as bitwarden_rs.
|
||||
|
||||
```yaml title="docker-compose.yml"
|
||||
---
|
||||
version: "2.1"
|
||||
services:
|
||||
vaultwarden:
|
||||
image: vaultwarden/server:latest
|
||||
container_name: vaultwarden
|
||||
environment:
|
||||
- TZ=America/Denver
|
||||
- INVITATIONS_ALLOWED=false
|
||||
- SIGNUPS_ALLOWED=false
|
||||
- WEBSOCKET_ENABLED=false
|
||||
- ADMIN_TOKEN=REDACTED #PUT A REALLY REALLY REALLY SECURE PASSWORD HERE
|
||||
volumes:
|
||||
- /srv/containers/vaultwarden:/data
|
||||
ports:
|
||||
- 80:80
|
||||
restart: always
|
||||
networks:
|
||||
docker_network:
|
||||
ipv4_address: 192.168.5.15
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.bunny-vaultwarden.rule=Host(`vault.bunny-lab.io`)"
|
||||
- "traefik.http.routers.bunny-vaultwarden.entrypoints=websecure"
|
||||
- "traefik.http.routers.bunny-vaultwarden.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.bunny-vaultwarden.loadbalancer.server.port=80"
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: docker_network
|
||||
docker_network:
|
||||
external: true
|
||||
```
|
||||
|
||||
!!! warning "ADMIN_TOKEN"
|
||||
It is **CRITICAL** that you never share the `ADMIN_TOKEN` with anyone. It allows you to log into the instance at https://vault.example.com/admin to add users, delete users, make changes system wide, etc.
|
||||
|
||||
```yaml title=".env"
|
||||
Not Applicable
|
||||
```
|
||||
|
||||
## Traefik Reverse Proxy Configuration
|
||||
If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below.
|
||||
|
||||
```yaml
|
||||
http:
|
||||
routers:
|
||||
bunny-vaultwarden:
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
service: vaultwarden
|
||||
rule: Host(`vault.bunny-lab.io`)
|
||||
|
||||
services:
|
||||
vaultwarden:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://192.168.5.15:80
|
||||
passHostHeader: true
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
- [Docker Network Prerequisite](<../Containers/Docker/Create the Docker Network.md>) — The configuration references the external `docker_network`; prepare it on the intended Docker host.
|
||||
- [Related Identity and Certificates Documentation](<../../reference/Identity and Certificates/index.md>) — Find the connected deployments, procedures, and references for this subject.
|
||||
- [Traefik Deployment](<../Networking and Access/Reverse Proxies/Traefik.md>) — Prepare the reverse proxy before applying this page's routing configuration.
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
tags:
|
||||
- Identity and Certificates
|
||||
- Deployments
|
||||
- Documentation
|
||||
---
|
||||
|
||||
# Identity and Certificates
|
||||
## Purpose
|
||||
Find deployments for identity and certificates. Follow the subject guide to choose the relevant environment and connect this material to the other document types.
|
||||
|
||||
## Includes
|
||||
- Active Directory
|
||||
- Authelia
|
||||
- Authentik
|
||||
- Keycloak
|
||||
- Password Pusher
|
||||
- Privacyidea
|
||||
- Vaultwarden
|
||||
|
||||
## Follow the Subject
|
||||
[Identity and Certificates](<../../reference/Identity and Certificates/index.md>) explains the relationships and offers starting points for the documented tasks.
|
||||
Reference in New Issue
Block a user