Skip to content

Commit f2b128d

Browse files
committed
feat: HAProxy PROXY protocol, externalTrafficPolicy, and chart env var fixes
- Add PROXY protocol support to the RadSec TLS listener (proxy_protocol = true) - Set externalTrafficPolicy: Local on the FreeRADIUS Service so HAProxy-proxied traffic preserves the real client IP - Remove the Helm ConfigMap and inline all config as env vars on the Deployment; pod restart was already required for config changes so the ConfigMap added no value - Fix pre-existing bug: chart rendered PINT_IPA_CA_NAME but PINT reads PINT_IPA_WIRELESS_CA_NAME; rename ipaCAName -> ipaWirelessCAName throughout - Add missing env vars: PINT_IPA_RADSEC_CA_NAME, PINT_IPA_ROOT_CA_NAME, PINT_IPA_CERT_PROFILE, PINT_IPA_RADSEC_CLIENT/SERVER_CERT_PROFILE, PINT_RADIUS_RADSEC_CHECK_CRL, PINT_RADIUS_RADSEC_PROXY_PROTOCOL, PINT_RADIUS_STATUS_PORT, PINT_RADIUS_STATUS_ADDR, PINT_IPA_CODE_SIGNING_CA_NAME, PINT_PROFILE_SIGNING_CERT_SECRET, PINT_IPA_CODE_SIGNING_CERT_PROFILE - Update values.schema.json to match all renamed and new values fields
1 parent c969464 commit f2b128d

16 files changed

Lines changed: 175 additions & 61 deletions

.env.dev.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ PINT_RADIUS_SERVER=127.0.0.1:32083
3737
PINT_RADIUS_STATUS_ADDR=127.0.0.1:31181
3838
#PINT_RADIUS_STATUS_PORT=18121
3939
PINT_RADIUS_RADSEC_CHECK_CRL=false
40+
#PINT_RADIUS_RADSEC_PROXY_PROTOCOL=true

README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,18 +291,15 @@ helm repo update
291291

292292
### Credentials Secret
293293

294-
PINT splits config into two Kubernetes objects:
295-
296-
- **ConfigMap**: rendered automatically by the chart from the `config:` values block. Contains all non-sensitive settings (`PINT_IPA_HOST`, `PINT_WIFI_SSID`, etc.).
297-
- **Secret**: must be created manually before deploying. Contains only the two sensitive credentials:
294+
All non-sensitive PINT configuration is rendered directly into the Deployment's `env` block from the `config:` values. Sensitive credentials must be provided in a pre-existing Secret:
298295

299296
```bash
300297
kubectl create secret generic <release-name> -n pint \
301298
--from-literal=PINT_CLIENT_SECRET=<oidc-secret> \
302299
--from-literal=PINT_IPA_PASSWORD=<ipa-password>
303300
```
304301

305-
Set `envSecret` in your values to the name of this Secret. The chart's PINT Deployment mounts both objects as environment variables.
302+
Set `envSecret` in your values to the name of this Secret. The chart mounts it via `envFrom` on the PINT Deployment.
306303

307304
---
308305

@@ -394,6 +391,7 @@ All configuration is via environment variables. Copy `.env.dev.example` to `.env
394391
| `PINT_FREERADIUS_DEPLOYMENT` | `pint-freeradius` | FreeRADIUS Deployment name |
395392
| `PINT_RADIUS_STATUS_PORT` | `18121` | FreeRADIUS status server port |
396393
| `PINT_RADIUS_RADSEC_CHECK_CRL` | `true` | Enable CRL checking in the RadSec TLS listener |
394+
| `PINT_RADIUS_RADSEC_PROXY_PROTOCOL` | `false` | Expect HAProxy PROXY protocol header on RadSec connections; set `true` when HAProxy fronts FreeRADIUS |
397395
| `PINT_IPA_SKIP_TLS_VERIFY` | `false` | Skip FreeIPA TLS verification (dev only) |
398396
| `PINT_DISABLE_OIDC` | `false` | Bypass OIDC and inject a static dev user |
399397
| `PINT_DEV_RTP` | `false` | Inject `rtp` group into dev user (requires `PINT_DISABLE_OIDC=true`) |

chart/templates/_helpers.tpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ never collide. Each can be overridden via the corresponding values key.
5454
{{- .Values.secrets.radSecCert | default (printf "%s-radsec-server-certificates" (include "pint.fullname" .)) }}
5555
{{- end }}
5656

57+
{{- define "pint.secretName.profileSigningCert" -}}
58+
{{- .Values.secrets.profileSigningCert | default (printf "%s-profile-signing-cert" (include "pint.fullname" .)) }}
59+
{{- end }}
60+
5761
{{- define "pint.envSecret" -}}
5862
{{- .Values.envSecret | default (include "pint.fullname" .) }}
5963
{{- end }}

chart/templates/configmap.yaml

Lines changed: 0 additions & 31 deletions
This file was deleted.

chart/templates/deployment.yaml

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,69 @@ spec:
2525
- containerPort: 8080
2626
name: http
2727
envFrom:
28-
- configMapRef:
29-
name: {{ include "pint.fullname" . }}
3028
- secretRef:
3129
name: {{ include "pint.envSecret" . }}
3230
env:
33-
# Non-sensitive deployment config injected by the chart so it stays
34-
# consistent with the Role resourceNames and FreeRADIUS volume mounts.
31+
- name: PINT_CLIENT_ID
32+
value: {{ .Values.config.clientID | quote }}
33+
- name: PINT_SERVER_URL
34+
value: {{ .Values.config.serverURL | quote }}
35+
- name: PINT_IPA_HOST
36+
value: {{ .Values.config.ipaHost | quote }}
37+
- name: PINT_IPA_SERVICE_ACCOUNT
38+
value: {{ .Values.config.ipaServiceAccount | quote }}
39+
- name: PINT_IPA_WIRELESS_CA_NAME
40+
value: {{ .Values.config.ipaWirelessCAName | quote }}
41+
- name: PINT_IPA_RADSEC_CA_NAME
42+
value: {{ .Values.config.ipaRadSecCAName | quote }}
43+
- name: PINT_IPA_ROOT_CA_NAME
44+
value: {{ .Values.config.ipaRootCAName | quote }}
45+
- name: PINT_WIFI_SSID
46+
value: {{ .Values.config.wifiSSID | quote }}
47+
- name: PINT_RADIUS_SERVER
48+
value: {{ .Values.config.radiusServer | quote }}
49+
{{- if .Values.config.ipaCertProfile }}
50+
- name: PINT_IPA_CERT_PROFILE
51+
value: {{ .Values.config.ipaCertProfile | quote }}
52+
{{- end }}
53+
{{- if .Values.config.ipaRadSecClientCertProfile }}
54+
- name: PINT_IPA_RADSEC_CLIENT_CERT_PROFILE
55+
value: {{ .Values.config.ipaRadSecClientCertProfile | quote }}
56+
{{- end }}
57+
{{- if .Values.config.ipaRadSecServerCertProfile }}
58+
- name: PINT_IPA_RADSEC_SERVER_CERT_PROFILE
59+
value: {{ .Values.config.ipaRadSecServerCertProfile | quote }}
60+
{{- end }}
61+
{{- if .Values.config.ipaSkipTLSVerify }}
62+
- name: PINT_IPA_SKIP_TLS_VERIFY
63+
value: "true"
64+
{{- end }}
65+
{{- if not .Values.config.radSecCheckCRL }}
66+
- name: PINT_RADIUS_RADSEC_CHECK_CRL
67+
value: "false"
68+
{{- end }}
69+
{{- if .Values.config.radSecProxyProtocol }}
70+
- name: PINT_RADIUS_RADSEC_PROXY_PROTOCOL
71+
value: "true"
72+
{{- end }}
73+
{{- if .Values.config.radSecStatusPort }}
74+
- name: PINT_RADIUS_STATUS_PORT
75+
value: {{ .Values.config.radSecStatusPort | quote }}
76+
{{- end }}
77+
{{- if .Values.config.radSecStatusAddr }}
78+
- name: PINT_RADIUS_STATUS_ADDR
79+
value: {{ .Values.config.radSecStatusAddr | quote }}
80+
{{- end }}
81+
{{- if .Values.config.codeSigningCAName }}
82+
- name: PINT_IPA_CODE_SIGNING_CA_NAME
83+
value: {{ .Values.config.codeSigningCAName | quote }}
84+
- name: PINT_PROFILE_SIGNING_CERT_SECRET
85+
value: {{ include "pint.secretName.profileSigningCert" . | quote }}
86+
{{- if .Values.config.codeSigningCertProfile }}
87+
- name: PINT_IPA_CODE_SIGNING_CERT_PROFILE
88+
value: {{ .Values.config.codeSigningCertProfile | quote }}
89+
{{- end }}
90+
{{- end }}
3591
- name: PINT_NAMESPACE
3692
valueFrom:
3793
fieldRef:

chart/templates/freeradius-service.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ metadata:
88
{{- include "pint.freeradiusLabels" . | nindent 4 }}
99
spec:
1010
type: {{ .Values.freeradius.service.type }}
11+
{{- if and (ne .Values.freeradius.service.type "ClusterIP") .Values.freeradius.service.externalTrafficPolicy }}
12+
externalTrafficPolicy: {{ .Values.freeradius.service.externalTrafficPolicy }}
13+
{{- end }}
1114
selector:
1215
{{- include "pint.freeradiusSelectorLabels" . | nindent 4 }}
1316
ports:

chart/templates/role.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ rules:
1414
resourceNames:
1515
- {{ include "pint.secretName.config" . | quote }}
1616
- {{ include "pint.secretName.radSecCert" . | quote }}
17+
{{- if .Values.config.codeSigningCAName }}
18+
- {{ include "pint.secretName.profileSigningCert" . | quote }}
19+
{{- end }}
1720
verbs: ["get", "patch", "update"]
1821
- apiGroups: ["apps"]
1922
resources: ["deployments"]

chart/values-dev.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ config:
1212
serverURL: http://localhost:8080
1313
ipaHost: localhost:8088
1414
ipaServiceAccount: pint
15-
ipaCAName: ipa
15+
ipaWirelessCAName: wireless
1616
ipaRadSecCAName: radsec
1717
ipaRootCAName: ipa
1818
ipaSkipTLSVerify: true

chart/values.schema.json

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
},
2929
"config": {
3030
"type": "object",
31-
"description": "Non-sensitive PINT application configuration, rendered into a ConfigMap.",
31+
"description": "Non-sensitive PINT application configuration, rendered as env vars on the Deployment.",
3232
"properties": {
3333
"clientID": {
3434
"type": "string",
@@ -46,10 +46,10 @@
4646
"type": "string",
4747
"description": "FreeIPA service account DN used to issue certificates."
4848
},
49-
"ipaCAName": {
49+
"ipaWirelessCAName": {
5050
"type": "string",
5151
"description": "FreeIPA CA name for WiFi client certificates.",
52-
"default": "ipa"
52+
"default": "wireless"
5353
},
5454
"ipaRadSecCAName": {
5555
"type": "string",
@@ -81,6 +81,33 @@
8181
"description": "Skip TLS verification when connecting to FreeIPA. For development only.",
8282
"default": false
8383
},
84+
"radSecCheckCRL": {
85+
"type": "boolean",
86+
"description": "Enable CRL checking in the RadSec TLS listener. Set false to disable.",
87+
"default": true
88+
},
89+
"radSecProxyProtocol": {
90+
"type": "boolean",
91+
"description": "Enable PROXY protocol on the RadSec listener. Required when HAProxy fronts FreeRADIUS.",
92+
"default": false
93+
},
94+
"radSecStatusPort": {
95+
"type": "string",
96+
"description": "Override the FreeRADIUS status server port (default: 18121)."
97+
},
98+
"radSecStatusAddr": {
99+
"type": "string",
100+
"description": "Override the status server address (host:port). Useful in dev when pod IPs are unreachable."
101+
},
102+
"codeSigningCAName": {
103+
"type": "string",
104+
"description": "FreeIPA CA name for the iOS mobileconfig code signing certificate. Leave empty to disable profile signing."
105+
},
106+
"codeSigningCertProfile": {
107+
"type": "string",
108+
"description": "Dogtag certificate profile for the mobileconfig signing cert.",
109+
"default": "pint_profile_signing"
110+
},
84111
"wifiSSID": {
85112
"type": "string",
86113
"description": "WiFi SSID embedded in generated device profiles.",
@@ -91,7 +118,7 @@
91118
"description": "RadSec server address shown to users (e.g. radius.csh.rit.edu:2083)."
92119
}
93120
},
94-
"required": ["clientID", "serverURL", "ipaHost", "ipaServiceAccount", "ipaCAName", "ipaRadSecCAName", "wifiSSID", "radiusServer"]
121+
"required": ["clientID", "serverURL", "ipaHost", "ipaServiceAccount", "ipaWirelessCAName", "ipaRadSecCAName", "wifiSSID", "radiusServer"]
95122
},
96123
"secrets": {
97124
"type": "object",
@@ -104,6 +131,10 @@
104131
"radSecCert": {
105132
"type": "string",
106133
"description": "Secret storing the FreeRADIUS TLS certificate and key. Defaults to '<fullname>-radsec-server-certificates'."
134+
},
135+
"profileSigningCert": {
136+
"type": "string",
137+
"description": "Secret storing the iOS mobileconfig signing certificate and key. Defaults to '<fullname>-profile-signing-cert'. Only created when codeSigningCAName is set."
107138
}
108139
}
109140
},
@@ -190,6 +221,12 @@
190221
"nodePort": {
191222
"type": ["integer", "null"],
192223
"description": "NodePort number. Only used when service.type is NodePort."
224+
},
225+
"externalTrafficPolicy": {
226+
"type": "string",
227+
"enum": ["Cluster", "Local"],
228+
"description": "ExternalTrafficPolicy for NodePort/LoadBalancer services. Use Local to preserve client IPs (required for HAProxy PROXY protocol).",
229+
"default": "Local"
193230
}
194231
}
195232
},
@@ -206,6 +243,10 @@
206243
"type": "string",
207244
"description": "Source CIDR allowed to query the status server.",
208245
"default": "0.0.0.0/0"
246+
},
247+
"nodePort": {
248+
"type": ["integer", "null"],
249+
"description": "NodePort for the status server port. Dev only; PINT queries pods directly in production."
209250
}
210251
}
211252
}

chart/values.yaml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,24 @@ config:
2424
# FreeIPA
2525
ipaHost: ""
2626
ipaServiceAccount: ""
27-
ipaCAName: "ipa"
27+
ipaWirelessCAName: "wireless"
2828
ipaRadSecCAName: "radsec"
2929
ipaRootCAName: "ipa"
3030
ipaCertProfile: "pint_wifi"
3131
ipaRadSecClientCertProfile: "pint_radsec_client"
3232
ipaRadSecServerCertProfile: "pint_radsec_server"
3333
ipaSkipTLSVerify: false
3434

35+
# RADIUS / RadSec
36+
radSecCheckCRL: true # set false to disable CRL checking in the RadSec TLS listener
37+
radSecProxyProtocol: false # set true when HAProxy fronts FreeRADIUS and sends PROXY protocol headers
38+
radSecStatusPort: "" # overrides the FreeRADIUS status server port (default: 18121)
39+
radSecStatusAddr: "" # overrides the status server address (host:port); useful in dev when pod IPs are unreachable
40+
41+
# iOS mobileconfig signing (optional — leave codeSigningCAName empty to disable)
42+
codeSigningCAName: ""
43+
codeSigningCertProfile: "" # default: pint_profile_signing
44+
3545
# WiFi
3646
wifiSSID: "CSH"
3747

@@ -52,8 +62,9 @@ envSecret: ""
5262
# multiple releases in the same namespace never collide. Override only when
5363
# you need to share a secret between releases.
5464
secrets:
55-
config: "" # default: <fullname>-config (clients.json, clients.conf, status-secret, status)
56-
radSecCert: "" # default: <fullname>-radsec-server-certificates (tls.crt, tls.key, ca.pem, wifi-ca.pem)
65+
config: "" # default: <fullname>-config (clients.json, clients.conf, status-secret, status)
66+
radSecCert: "" # default: <fullname>-radsec-server-certificates (tls.crt, tls.key, ca.pem, wifi-ca.pem)
67+
profileSigningCert: "" # default: <fullname>-profile-signing-cert (tls.crt, tls.key); only created when codeSigningCAName is set
5768

5869
service:
5970
type: ClusterIP
@@ -69,6 +80,7 @@ freeradius:
6980
service:
7081
type: NodePort
7182
nodePort: null
83+
externalTrafficPolicy: Local # Local preserves the client's real IP; required when using HAProxy PROXY protocol
7284
# FreeRADIUS status virtual server — used by PINT to surface per-pod auth statistics.
7385
# Managed automatically by PINT at startup.
7486
statusServer:

0 commit comments

Comments
 (0)