Compare commits

..

6 commits

7 changed files with 148 additions and 6 deletions

View file

@ -20,6 +20,8 @@ This repository contains documentation, guides, and reference material.
Documentation and guides related to Keycloak configuration and best practices.
- [Enforce OTP 2FA for Internal Users](./keycloak/enforce-otp-internal.md)
Step-by-step instructions for enforcing OTP-based two-factor authentication for internal users, while excluding external Microsoft Entra users.
- [Integrate MS Entra in Keycloak as IDP](./keycloak/idp-ms-entra.md)
Step-by-step instructions for integrating MS Entra as identity-provider.
- **[Microsoft Entra](./ms-entra/)**
Documentation and guides related to Microsft Entra configuration and best practices.

View file

@ -1 +1,48 @@
#ACME
# ACME DNS Challenges
## Summary
We agreed to use **ACME DNS-01 challenges** for issuing certificates for **both public-facing and internal services**. A key benefit is that DNS-01 **enables internal certificate issuance** in the first place, since the CA only needs to verify TXT records in DNS (no inbound HTTP/ALPN access to the service). To keep our primary DNS zones clean, we will create a **separate, dedicated zone** for ACME challenges and **delegate** challenge records to it via **CNAME**.
## Decisions
- Use **ACME DNS-01** as the challenge type for **both external/public and internal** certificate issuance.
- Create a **dedicated DNS zone** for ACME challenges (e.g., `_acme.example.com`).
- For each certificate FQDN, publish a **CNAME** at `_acme-challenge.<fqdn>` that points into the dedicated challenge zone.
- Store the **TXT token(s)** only in the dedicated challenge zone to avoid cluttering primary zones.
- Keep **low TTLs** (e.g., 60-120s) on both CNAME and TXT records to speed up renewals.
- Restrict write access to the challenge zone to the ACME automation only.
## Meetings
- 05.08.2025: Bert-Jan Fikse, Tobias Schaller, Tobias Wüst, Tom Jampen (inital version)
## Background
The following article explains how DNS-01 challenges can be effectively used to issue Let's Encrypt certificates for servers with internal IP addresses:
- https://lists.bfh.science/pipermail/bfh-linux-announce/2021-September/000134.html
The following manpage explains important implementation details for correctly handling DNS-01 challenges:
- https://sources.debian.org/src/open-infrastructure-service-tools/20250626-2/dehydrated/share/man/dehydrated-nsupdate.1.rst#L20
## Reference Design
**Dedicated zone:**
`_acme.digitalboard.ch`
**Dedicated zone for each managed school:**
`gymkirchenfeld._acme.digitalboard.ch`
**For a service FQDN:**
Target certificate: `app1.gymkirchenfeld.ch`, `app2.kinet.ch`
**Publish in the primary zone:**
```dns
; Delegate the challenge to the dedicated zone
_acme-challenge.app1.gymkirchenfeld.ch. IN CNAME
app1.gymkirchenfeld.ch.gymkirchenfeld._acme.digitalboard.ch.
_acme-challenge.app2.kinet.ch. IN CNAME
app2.kinet.ch.gymkirchenfeld._acme.digitalboard.ch.
_acme-challenge.app.example.com. IN CNAME
app.example.com.school-a._acme.digitalboard.ch.
```
> During validation, the CA will follow the CNAME from the primary zone to the dedicated zone and read the TXT record there.

View file

@ -1,5 +1,18 @@
# IPv6 Overview and Best Practices
## Summary
We agreed to setup dual stack by default as IPv6 is essential for modern IT infrastructures and significantly simplifies network management in the long term. By relying on **DNS names instead of raw IP addresses**, operating an **own, globally valid IPv6 stack**, using **Dual Stack during the migration phase**, and providing a **Jump Host for IPv6-only zones**, networks become more robust, scalable, and future-proof.
## Decisions
- Use **Dual Stack** (IPv4 and IPv6 addresses)
- Rely on **DNS names instead of raw IP addresses**
- **Each school is responsible for its DNS records** and must manage them for IPv4/IPv6 (including CNAME records for ACME)
- The Digitalboard provides an optional service (dynamic DNS zone for acme challenge responses) as described in the [ACME documentation](./acme.md)
- The Digitalboard might act as a RIPE customer and provide a `/32` or `/48` IPv6 network for interested schools
## Meetings
- 05.08.2025: Bert-Jan Fikse, Tobias Schaller, Tobias Wüst, Tom Jampen (inital version)
## Why IPv6?
IPv6 was introduced to address the limitations of IPv4, most notably the shortage of available addresses. It provides an almost unlimited address space, improved support for modern networking, and forms the foundation for future-proof infrastructures.
@ -10,11 +23,14 @@ IPv6 was introduced to address the limitations of IPv4, most notably the shortag
## Own IPv6 Stack
- The **RFC4193 range** (`fd00::/8`) is reserved for **local, private use**, similar to private IPv4 networks (e.g. `192.168.x.x`).
→ Disadvantages:
- In a dual stack environment (IPv4 and IPv6 with `fd00::/8` addresses) IPv4 is used by default, so IPv6 is never used!
- For production environments, it is preferable to use **public, globally routable IPv6 prefixes** obtained from an ISP or an own IPv6 allocation.
→ Advantages:
- Unique addressing without overlaps
- Direct reachability and routability on the Internet
- Sustainable, future-oriented network design
- As a direct RIPE customer an institution can get one `/29` IPv6 network (resulting in 8 `/32` IPv6 networks) for < CHF 2'000.-/year (e.g. one `/32` network for CHF 250.-/year)
## Dual Stack as a Transition Strategy
- In many environments, IPv4 cannot be replaced immediately.
@ -27,7 +43,3 @@ IPv6 was introduced to address the limitations of IPv4, most notably the shortag
- A **Jump Host** with both IPv4 and IPv6 connectivity can serve as an entry point.
- It enables access from IPv4-based networks into IPv6-only segments, acting as a controlled and secure bridge during the transition phase.
- This approach ensures operability while gradually phasing out IPv4.
## Conclusion
IPv6 is essential for modern IT infrastructures and significantly simplifies network management in the long term.
By relying on **DNS names instead of raw IP addresses**, operating an **own, globally valid IPv6 stack**, using **Dual Stack during the migration phase**, and providing a **Jump Host for IPv6-only zones**, networks become more robust, scalable, and future-proof.

81
keycloak/idp-ms-entra.md Normal file
View file

@ -0,0 +1,81 @@
# Add Microsoft Entra ID as an Identity Provider in Keycloak
> **Goal:** Connect your Microsoft Entra application (from the previous guide) to Keycloak using OpenID Connect so users can sign in with their Microsoft accounts.
---
## Prerequisites
From the [Entra guide](../ms-entra/enterprise-app-keycloak.md) you should have:
- **OpenID Connect metadata document URL**
- **Application (client) ID**
- **Client secret (Value)**
- (Optional) **Tenant ID** — useful to verify you used the correct discovery URL
You'll also need:
- Access to the **Keycloak Admin Console**
- The **realm** where you want to add the provider (e.g., `Digitalboard`)
- The **alias** you decided on (this must match the alias in the Entra Redirect URI)
---
## Step 1 — Open Identity Providers in your realm
1. In Keycloak, switch to the target realm (e.g., `Digitalboard`).
2. Navigate to **Configure → Identity providers**.
3. Click **Add provider****OpenID Connect v1.0**.
![Open “Add provider”](images/idp-ms-entra/step-01-A.png "Add provider → OpenID Connect v1.0")
*Figure 1: Adding an OIDC provider.*
![Open “Add provider”](images/idp-ms-entra/step-01-B.png "Add provider → OpenID Connect v1.0")
*Figure 1: Adding an OIDC provider.*
---
## Step 2 — Fill the basic settings
On the **Add identity provider** form:
1. **Alias**: enter your organization alias (must match the alias used in the Entra Redirect URI).
Example: `test-schule`
2. **Display name**: a friendly label users will see on the login page.
Example: `Test Schule`
3. **Use discovery endpoint**: **On**.
4. **Discovery endpoint**: paste the **OpenID Connect metadata document URL** you copied in Entra (Step 7).
Example: `https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration`
5. **Client authentication**: keep **Client secret sent as post**.
6. **Client ID**: paste the **Application (client) ID** from Entra.
7. **Client Secret**: paste the **client secret Value** from Entra.
8. **Client assertion signature algorithm**: leave **Algorithm not specified** (default).
9. Click **Add** (or **Save**).
> As soon as you set the **Alias**, Keycloak shows the **Redirect URI** at the top (read-only). It must exactly match the Redirect URI you registered in Entra.
![Fill OIDC settings](images/idp-ms-entra/step-02-A.png "OIDC identity provider form in Keycloak")
*Figure 2: Basic OIDC settings in Keycloak.*
---
## Step 3 — Set recommended options
After saving, on the provider's **Settings** tab, adjust:
- **Default Scopes**: `openid profile email`
(ensures Entra returns the claims you added in the [Entra guide](../ms-entra/enterprise-app-keycloak.md))
- **Trust email**: **On** (lets Keycloak trust verified email from Entra)
- **Sync Mode**: **Import** (default; copies basic attributes into Keycloak)
- **Disable User Info**: **Off** (keep it off so Keycloak can fetch claims from the UserInfo endpoint)
- **Backchannel logout**: **On** (optional but recommended)
Click **Save**.
---
## Step 3 — Check the provider appears on the login page
Back on **Configure → Identity providers**, you should see your new provider listed.
Open your realm's login page (or log out of the Admin Console and choose **Sign in with <Provider-Display-Name>**). You should be redirected to Microsoft, then back to Keycloak, and end up authenticated.
---
## Troubleshooting
- **`invalid_redirect_uri` (on Microsoft)**: The Redirect URI in Entra must match exactly what Keycloak shows (including realm name and **alias**).
- **`AADSTS50105`**: Access to the Enterprise App is restricted. Follow Steps 10-11 in the [Entra guide](../ms-entra/enterprise-app-keycloak.md) to assign the user/group.
- **No name/email in Keycloak user**: Check **Default Scopes** include `profile email`, verify Entra **Token configuration** (claims) and Keycloak **Mappers**.
- **Issuer/metadata errors**: Ensure the **Discovery endpoint** uses your real **tenant ID** and is reachable over HTTPS from Keycloak.

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB