feat(configuration): mtls clients (#4221)
This implements mTLS support for LDAP, Redis, and SMTP. Specified via the tls.certificate_chain and tls.private_key options. Closes #4044pull/4222/head
parent
6e835bd8f8
commit
9532823a99
|
@ -315,6 +315,82 @@ authentication_backend:
|
|||
## Minimum TLS version for either Secure LDAP or LDAP StartTLS.
|
||||
minimum_version: TLS1.2
|
||||
|
||||
## Maximum TLS version for either Secure LDAP or LDAP StartTLS.
|
||||
maximum_version: TLS1.3
|
||||
|
||||
## The certificate chain used with the private_key if the server requests TLS Client Authentication
|
||||
## i.e. Mutual TLS.
|
||||
# certificate_chain: |
|
||||
# -----BEGIN CERTIFICATE-----
|
||||
# MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
|
||||
# EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
|
||||
# MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
# ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
|
||||
# /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
|
||||
# LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
|
||||
# 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
|
||||
# kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
|
||||
# Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
|
||||
# AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
|
||||
# AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
|
||||
# /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
|
||||
# lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
|
||||
# wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
|
||||
# OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
|
||||
# ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
|
||||
# -----END CERTIFICATE-----
|
||||
# -----BEGIN CERTIFICATE-----
|
||||
# MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
|
||||
# EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
|
||||
# MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
# ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
|
||||
# zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
|
||||
# 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
|
||||
# kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
|
||||
# ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
|
||||
# Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
|
||||
# AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
|
||||
# Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
|
||||
# kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
|
||||
# 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
|
||||
# HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
|
||||
# D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
|
||||
# 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
|
||||
# qocikt3WAdU^invalid DO NOT USE=
|
||||
# -----END CERTIFICATE-----
|
||||
|
||||
## The private key used with the certificate_chain if the server requests TLS Client Authentication
|
||||
## i.e. Mutual TLS.
|
||||
# private_key: |
|
||||
# -----BEGIN RSA PRIVATE KEY-----
|
||||
# MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
|
||||
# T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
|
||||
# KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
|
||||
# +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
|
||||
# LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
|
||||
# txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
|
||||
# aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
|
||||
# Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
|
||||
# ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
|
||||
# LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
|
||||
# jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
|
||||
# BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
|
||||
# Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
|
||||
# R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
|
||||
# tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
|
||||
# ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
|
||||
# lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
|
||||
# 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
|
||||
# fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
|
||||
# 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
|
||||
# jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
|
||||
# rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
|
||||
# n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
|
||||
# yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
|
||||
# 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
|
||||
# DO NOT USE==
|
||||
# -----END RSA PRIVATE KEY-----
|
||||
|
||||
## The distinguished name of the container searched for objects in the directory information tree.
|
||||
## See also: additional_users_dn, additional_groups_dn.
|
||||
base_dn: dc=example,dc=com
|
||||
|
|
|
@ -28,6 +28,74 @@ authentication_backend:
|
|||
server_name: ldap.example.com
|
||||
skip_verify: false
|
||||
minimum_version: TLS1.2
|
||||
maximum_version: TLS1.3
|
||||
certificate_chain: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
|
||||
EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
|
||||
MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
|
||||
/Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
|
||||
LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
|
||||
91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
|
||||
kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
|
||||
Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
|
||||
AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
|
||||
AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
|
||||
/ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
|
||||
lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
|
||||
wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
|
||||
OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
|
||||
ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
|
||||
EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
|
||||
MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
|
||||
zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
|
||||
5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
|
||||
kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
|
||||
ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
|
||||
Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
|
||||
AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
|
||||
Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
|
||||
kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
|
||||
71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
|
||||
HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
|
||||
D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
|
||||
2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
|
||||
qocikt3WAdU^invalid DO NOT USE=
|
||||
-----END CERTIFICATE-----
|
||||
private_key: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
|
||||
T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
|
||||
KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
|
||||
+5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
|
||||
LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
|
||||
txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
|
||||
aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
|
||||
Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
|
||||
ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
|
||||
LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
|
||||
jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
|
||||
BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
|
||||
Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
|
||||
R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
|
||||
tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
|
||||
ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
|
||||
lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
|
||||
6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
|
||||
fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
|
||||
9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
|
||||
jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
|
||||
rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
|
||||
n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
|
||||
yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
|
||||
27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
|
||||
DO NOT USE==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
base_dn: DC=example,DC=com
|
||||
additional_users_dn: ou=users
|
||||
users_filter: (&({username_attribute}={input})(objectClass=person))
|
||||
|
|
|
@ -37,6 +37,74 @@ notifier:
|
|||
server_name: smtp.example.com
|
||||
skip_verify: false
|
||||
minimum_version: TLS1.2
|
||||
maximum_version: TLS1.3
|
||||
certificate_chain: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
|
||||
EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
|
||||
MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
|
||||
/Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
|
||||
LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
|
||||
91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
|
||||
kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
|
||||
Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
|
||||
AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
|
||||
AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
|
||||
/ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
|
||||
lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
|
||||
wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
|
||||
OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
|
||||
ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
|
||||
EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
|
||||
MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
|
||||
zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
|
||||
5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
|
||||
kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
|
||||
ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
|
||||
Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
|
||||
AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
|
||||
Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
|
||||
kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
|
||||
71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
|
||||
HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
|
||||
D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
|
||||
2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
|
||||
qocikt3WAdU^invalid DO NOT USE=
|
||||
-----END CERTIFICATE-----
|
||||
private_key: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
|
||||
T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
|
||||
KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
|
||||
+5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
|
||||
LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
|
||||
txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
|
||||
aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
|
||||
Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
|
||||
ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
|
||||
LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
|
||||
jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
|
||||
BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
|
||||
Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
|
||||
R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
|
||||
tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
|
||||
ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
|
||||
lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
|
||||
6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
|
||||
fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
|
||||
9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
|
||||
jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
|
||||
rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
|
||||
n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
|
||||
yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
|
||||
27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
|
||||
DO NOT USE==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
```
|
||||
|
||||
## Options
|
||||
|
|
|
@ -129,10 +129,39 @@ instead you should tweak the `server_name` option, and the global option
|
|||
|
||||
{{< confkey type="string" default="TLS1.2" required="no" >}}
|
||||
|
||||
The key `minimum_version` controls the minimum TLS version Authelia will use when opening TLS connections.
|
||||
The possible values are `TLS1.3`, `TLS1.2`, `TLS1.1`, `TLS1.0`. Anything other than `TLS1.3` or `TLS1.2`
|
||||
Controls the minimum TLS version Authelia will use when performing TLS handshakes.
|
||||
The possible values are `TLS1.3`, `TLS1.2`, `TLS1.1`, `TLS1.0`, `SSL3.0`. Anything other than `TLS1.3` or `TLS1.2`
|
||||
are very old and deprecated. You should avoid using these and upgrade your backend service instead of decreasing
|
||||
this value.
|
||||
this value. At the time of this writing `SSL3.0` will always produce errors.
|
||||
|
||||
### maximum_version
|
||||
|
||||
{{< confkey type="string" default="TLS1.3" required="no" >}}
|
||||
|
||||
Controls the maximum TLS version Authelia will use when performing TLS handshakes.
|
||||
The possible values are `TLS1.3`, `TLS1.2`, `TLS1.1`, `TLS1.0`, `SSL3.0`. Anything other than `TLS1.3` or `TLS1.2`
|
||||
are very old and deprecated. You should avoid using these and upgrade your backend service instead of decreasing
|
||||
this value. At the time of this writing `SSL3.0` will always produce errors.
|
||||
|
||||
### certificate_chain
|
||||
|
||||
{{< confkey type="string" required="no" >}}
|
||||
|
||||
The certificate chain/bundle to be used with the [private_key](#private_key) to perform mutual TLS authentication with
|
||||
the server.
|
||||
|
||||
The value must be one or more certificates encoded in the DER base64 ([RFC4648]) encoded PEM format.
|
||||
|
||||
### private_key
|
||||
|
||||
{{< confkey type="string" required="yes" >}}
|
||||
|
||||
*__Important Note:__ This can also be defined using a [secret](../methods/secrets.md) which is __strongly recommended__
|
||||
especially for containerized deployments.*
|
||||
|
||||
The private key to be used with the [certificate_chain](#certificate_chain) for mutual TLS authentication.
|
||||
|
||||
The value must be one private key encoded in the DER base64 ([RFC4648]) encoded PEM format.
|
||||
|
||||
## Server Buffers
|
||||
|
||||
|
|
|
@ -34,6 +34,74 @@ session:
|
|||
server_name: myredis.example.com
|
||||
skip_verify: false
|
||||
minimum_version: TLS1.2
|
||||
maximum_version: TLS1.3
|
||||
certificate_chain: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
|
||||
EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
|
||||
MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
|
||||
/Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
|
||||
LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
|
||||
91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
|
||||
kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
|
||||
Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
|
||||
AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
|
||||
AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
|
||||
/ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
|
||||
lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
|
||||
wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
|
||||
OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
|
||||
ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
|
||||
EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
|
||||
MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
|
||||
zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
|
||||
5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
|
||||
kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
|
||||
ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
|
||||
Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
|
||||
AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
|
||||
Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
|
||||
kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
|
||||
71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
|
||||
HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
|
||||
D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
|
||||
2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
|
||||
qocikt3WAdU^invalid DO NOT USE=
|
||||
-----END CERTIFICATE-----
|
||||
private_key: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
|
||||
T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
|
||||
KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
|
||||
+5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
|
||||
LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
|
||||
txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
|
||||
aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
|
||||
Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
|
||||
ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
|
||||
LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
|
||||
jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
|
||||
BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
|
||||
Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
|
||||
R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
|
||||
tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
|
||||
ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
|
||||
lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
|
||||
6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
|
||||
fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
|
||||
9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
|
||||
jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
|
||||
rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
|
||||
n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
|
||||
yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
|
||||
27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
|
||||
DO NOT USE==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
high_availability:
|
||||
sentinel_name: mysentinel
|
||||
# If `sentinel_username` is supplied, Authelia will connect using ACL-based
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -53,7 +53,7 @@ func newLDAPUserProvider(config schema.LDAPAuthenticationBackend, disableResetPa
|
|||
config.TLS = schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom.TLS
|
||||
}
|
||||
|
||||
tlsConfig := utils.NewTLSConfig(config.TLS, tls.VersionTLS12, certPool)
|
||||
tlsConfig := utils.NewTLSConfig(config.TLS, certPool)
|
||||
|
||||
var dialOpts = []ldap.DialOpt{
|
||||
ldap.DialWithDialer(&net.Dialer{Timeout: config.Timeout}),
|
||||
|
|
|
@ -315,6 +315,82 @@ authentication_backend:
|
|||
## Minimum TLS version for either Secure LDAP or LDAP StartTLS.
|
||||
minimum_version: TLS1.2
|
||||
|
||||
## Maximum TLS version for either Secure LDAP or LDAP StartTLS.
|
||||
maximum_version: TLS1.3
|
||||
|
||||
## The certificate chain used with the private_key if the server requests TLS Client Authentication
|
||||
## i.e. Mutual TLS.
|
||||
# certificate_chain: |
|
||||
# -----BEGIN CERTIFICATE-----
|
||||
# MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
|
||||
# EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
|
||||
# MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
# ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
|
||||
# /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
|
||||
# LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
|
||||
# 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
|
||||
# kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
|
||||
# Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
|
||||
# AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
|
||||
# AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
|
||||
# /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
|
||||
# lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
|
||||
# wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
|
||||
# OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
|
||||
# ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
|
||||
# -----END CERTIFICATE-----
|
||||
# -----BEGIN CERTIFICATE-----
|
||||
# MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
|
||||
# EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
|
||||
# MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
# ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
|
||||
# zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
|
||||
# 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
|
||||
# kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
|
||||
# ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
|
||||
# Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
|
||||
# AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
|
||||
# Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
|
||||
# kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
|
||||
# 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
|
||||
# HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
|
||||
# D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
|
||||
# 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
|
||||
# qocikt3WAdU^invalid DO NOT USE=
|
||||
# -----END CERTIFICATE-----
|
||||
|
||||
## The private key used with the certificate_chain if the server requests TLS Client Authentication
|
||||
## i.e. Mutual TLS.
|
||||
# private_key: |
|
||||
# -----BEGIN RSA PRIVATE KEY-----
|
||||
# MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
|
||||
# T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
|
||||
# KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
|
||||
# +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
|
||||
# LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
|
||||
# txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
|
||||
# aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
|
||||
# Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
|
||||
# ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
|
||||
# LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
|
||||
# jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
|
||||
# BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
|
||||
# Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
|
||||
# R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
|
||||
# tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
|
||||
# ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
|
||||
# lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
|
||||
# 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
|
||||
# fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
|
||||
# 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
|
||||
# jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
|
||||
# rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
|
||||
# n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
|
||||
# yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
|
||||
# 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
|
||||
# DO NOT USE==
|
||||
# -----END RSA PRIVATE KEY-----
|
||||
|
||||
## The distinguished name of the container searched for objects in the directory information tree.
|
||||
## See also: additional_users_dn, additional_groups_dn.
|
||||
base_dn: dc=example,dc=com
|
||||
|
|
|
@ -346,6 +346,76 @@ func StringToX509CertificateChainHookFunc() mapstructure.DecodeHookFuncType {
|
|||
}
|
||||
}
|
||||
|
||||
// StringToTLSVersionHookFunc decodes strings to schema.TLSVersion's.
|
||||
func StringToTLSVersionHookFunc() mapstructure.DecodeHookFuncType {
|
||||
return func(f reflect.Type, t reflect.Type, data interface{}) (value interface{}, err error) {
|
||||
var ptr bool
|
||||
|
||||
if f.Kind() != reflect.String {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
prefixType := ""
|
||||
|
||||
if t.Kind() == reflect.Ptr {
|
||||
ptr = true
|
||||
prefixType = "*"
|
||||
}
|
||||
|
||||
expectedType := reflect.TypeOf(schema.TLSVersion{})
|
||||
|
||||
if ptr && t.Elem() != expectedType {
|
||||
return data, nil
|
||||
} else if !ptr && t != expectedType {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
dataStr := data.(string)
|
||||
|
||||
var result *schema.TLSVersion
|
||||
|
||||
if result, err = schema.NewTLSVersion(dataStr); err != nil {
|
||||
return nil, fmt.Errorf(errFmtDecodeHookCouldNotParse, dataStr, prefixType, expectedType, err)
|
||||
}
|
||||
|
||||
if ptr {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
return *result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// StringToCryptoPrivateKeyHookFunc decodes strings to schema.CryptographicPrivateKey's.
|
||||
func StringToCryptoPrivateKeyHookFunc() mapstructure.DecodeHookFuncType {
|
||||
return func(f reflect.Type, t reflect.Type, data interface{}) (value interface{}, err error) {
|
||||
if f.Kind() != reflect.String {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
field, _ := reflect.TypeOf(schema.TLSConfig{}).FieldByName("PrivateKey")
|
||||
expectedType := field.Type
|
||||
|
||||
if t != expectedType {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
dataStr := data.(string)
|
||||
|
||||
var i any
|
||||
|
||||
if i, err = utils.ParseX509FromPEM([]byte(dataStr)); err != nil {
|
||||
return nil, fmt.Errorf(errFmtDecodeHookCouldNotParseBasic, "", expectedType, err)
|
||||
}
|
||||
|
||||
if result, ok := i.(schema.CryptographicPrivateKey); !ok {
|
||||
return nil, fmt.Errorf(errFmtDecodeHookCouldNotParseBasic, "", expectedType, fmt.Errorf("the data is for a %T not a %s", i, expectedType))
|
||||
} else {
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StringToPrivateKeyHookFunc decodes strings to rsa.PrivateKey's.
|
||||
func StringToPrivateKeyHookFunc() mapstructure.DecodeHookFuncType {
|
||||
return func(f reflect.Type, t reflect.Type, data interface{}) (value interface{}, err error) {
|
||||
|
|
|
@ -64,6 +64,8 @@ func unmarshal(ko *koanf.Koanf, val *schema.StructValidator, path string, o any)
|
|||
StringToX509CertificateHookFunc(),
|
||||
StringToX509CertificateChainHookFunc(),
|
||||
StringToPrivateKeyHookFunc(),
|
||||
StringToCryptoPrivateKeyHookFunc(),
|
||||
StringToTLSVersionHookFunc(),
|
||||
StringToPasswordDigestHookFunc(true),
|
||||
ToTimeDurationHookFunc(),
|
||||
),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
@ -180,7 +181,7 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationCustom = LDAPAuth
|
|||
GroupNameAttribute: "cn",
|
||||
Timeout: time.Second * 5,
|
||||
TLS: &TLSConfig{
|
||||
MinimumVersion: "TLS1.2",
|
||||
MinimumVersion: TLSVersion{tls.VersionTLS12},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -194,6 +195,6 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory =
|
|||
GroupNameAttribute: "cn",
|
||||
Timeout: time.Second * 5,
|
||||
TLS: &TLSConfig{
|
||||
MinimumVersion: "TLS1.2",
|
||||
MinimumVersion: TLSVersion{tls.VersionTLS12},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
@ -9,20 +10,51 @@ const (
|
|||
argon2 = "argon2"
|
||||
argon2id = "argon2id"
|
||||
sha512 = "sha512"
|
||||
sha256 = "sha256"
|
||||
)
|
||||
|
||||
// ProfileRefreshDisabled represents a value for refresh_interval that disables the check entirely.
|
||||
const (
|
||||
// TLSVersion13 is the textual representation of TLS 1.3.
|
||||
TLSVersion13 = "TLS1.3"
|
||||
|
||||
// TLSVersion12 is the textual representation of TLS 1.2.
|
||||
TLSVersion12 = "TLS1.2"
|
||||
|
||||
// TLSVersion11 is the textual representation of TLS 1.1.
|
||||
TLSVersion11 = "TLS1.1"
|
||||
|
||||
// TLSVersion10 is the textual representation of TLS 1.0.
|
||||
TLSVersion10 = "TLS1.0"
|
||||
|
||||
// SSLVersion30 is the textual representation of SSL 3.0.
|
||||
SSLVersion30 = "SSL3.0"
|
||||
|
||||
// Version13 is the textual representation of version 1.3.
|
||||
Version13 = "1.3"
|
||||
|
||||
// Version12 is the textual representation of version 1.2.
|
||||
Version12 = "1.2"
|
||||
|
||||
// Version11 is the textual representation of version 1.1.
|
||||
Version11 = "1.1"
|
||||
|
||||
// Version10 is the textual representation of version 1.0.
|
||||
Version10 = "1.0"
|
||||
)
|
||||
|
||||
// ErrTLSVersionNotSupported returned when an unknown TLS version supplied.
|
||||
var ErrTLSVersionNotSupported = errors.New("supplied tls version isn't supported")
|
||||
|
||||
// ProfileRefreshDisabled represents a Value for refresh_interval that disables the check entirely.
|
||||
const ProfileRefreshDisabled = "disable"
|
||||
|
||||
const (
|
||||
// ProfileRefreshAlways represents a value for refresh_interval that's the same as 0ms.
|
||||
// ProfileRefreshAlways represents a Value for refresh_interval that's the same as 0ms.
|
||||
ProfileRefreshAlways = "always"
|
||||
|
||||
// RefreshIntervalDefault represents the default value of refresh_interval.
|
||||
// RefreshIntervalDefault represents the default Value of refresh_interval.
|
||||
RefreshIntervalDefault = "5m"
|
||||
|
||||
// RefreshIntervalAlways represents the duration value refresh interval should have if set to always.
|
||||
// RefreshIntervalAlways represents the duration Value refresh interval should have if set to always.
|
||||
RefreshIntervalAlways = 0 * time.Millisecond
|
||||
)
|
||||
|
||||
|
|
|
@ -84,8 +84,11 @@ var Keys = []string{
|
|||
"authentication_backend.ldap.timeout",
|
||||
"authentication_backend.ldap.start_tls",
|
||||
"authentication_backend.ldap.tls.minimum_version",
|
||||
"authentication_backend.ldap.tls.maximum_version",
|
||||
"authentication_backend.ldap.tls.skip_verify",
|
||||
"authentication_backend.ldap.tls.server_name",
|
||||
"authentication_backend.ldap.tls.private_key",
|
||||
"authentication_backend.ldap.tls.certificate_chain",
|
||||
"authentication_backend.ldap.base_dn",
|
||||
"authentication_backend.ldap.additional_users_dn",
|
||||
"authentication_backend.ldap.users_filter",
|
||||
|
@ -115,8 +118,11 @@ var Keys = []string{
|
|||
"session.redis.maximum_active_connections",
|
||||
"session.redis.minimum_idle_connections",
|
||||
"session.redis.tls.minimum_version",
|
||||
"session.redis.tls.maximum_version",
|
||||
"session.redis.tls.skip_verify",
|
||||
"session.redis.tls.server_name",
|
||||
"session.redis.tls.private_key",
|
||||
"session.redis.tls.certificate_chain",
|
||||
"session.redis.high_availability.sentinel_name",
|
||||
"session.redis.high_availability.sentinel_username",
|
||||
"session.redis.high_availability.sentinel_password",
|
||||
|
@ -195,8 +201,11 @@ var Keys = []string{
|
|||
"notifier.smtp.disable_html_emails",
|
||||
"notifier.smtp.disable_starttls",
|
||||
"notifier.smtp.tls.minimum_version",
|
||||
"notifier.smtp.tls.maximum_version",
|
||||
"notifier.smtp.tls.skip_verify",
|
||||
"notifier.smtp.tls.server_name",
|
||||
"notifier.smtp.tls.private_key",
|
||||
"notifier.smtp.tls.certificate_chain",
|
||||
"notifier.template_path",
|
||||
"server.host",
|
||||
"server.port",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/mail"
|
||||
"time"
|
||||
)
|
||||
|
@ -42,6 +43,6 @@ var DefaultSMTPNotifierConfiguration = SMTPNotifierConfiguration{
|
|||
Identifier: "localhost",
|
||||
StartupCheckAddress: mail.Address{Name: "Authelia Test", Address: "test@authelia.com"},
|
||||
TLS: &TLSConfig{
|
||||
MinimumVersion: "TLS1.2",
|
||||
MinimumVersion: TLSVersion{tls.VersionTLS12},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -54,3 +55,10 @@ var DefaultSessionConfiguration = SessionConfiguration{
|
|||
RememberMeDuration: time.Hour * 24 * 30,
|
||||
SameSite: "lax",
|
||||
}
|
||||
|
||||
// DefaultRedisConfiguration is the default redis configuration.
|
||||
var DefaultRedisConfiguration = RedisSessionConfiguration{
|
||||
TLS: &TLSConfig{
|
||||
MinimumVersion: TLSVersion{Value: tls.VersionTLS12},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -6,9 +6,20 @@ import (
|
|||
|
||||
// TLSConfig is a representation of the TLS configuration.
|
||||
type TLSConfig struct {
|
||||
MinimumVersion string `koanf:"minimum_version"`
|
||||
MinimumVersion TLSVersion `koanf:"minimum_version"`
|
||||
MaximumVersion TLSVersion `koanf:"maximum_version"`
|
||||
|
||||
SkipVerify bool `koanf:"skip_verify"`
|
||||
ServerName string `koanf:"server_name"`
|
||||
|
||||
PrivateKey CryptographicPrivateKey `koanf:"private_key"`
|
||||
CertificateChain X509CertificateChain `koanf:"certificate_chain"`
|
||||
}
|
||||
|
||||
// TLSCertificateConfig is a representation of the TLS Certificate configuration.
|
||||
type TLSCertificateConfig struct {
|
||||
Key CryptographicPrivateKey `koanf:"key"`
|
||||
CertificateChain X509CertificateChain `koanf:"certificate_chain"`
|
||||
}
|
||||
|
||||
// ServerTimeouts represents server timeout configurations.
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
|
@ -174,6 +175,71 @@ func NewX509CertificateChain(in string) (chain *X509CertificateChain, err error)
|
|||
return chain, nil
|
||||
}
|
||||
|
||||
// NewTLSVersion returns a new TLSVersion given a string.
|
||||
func NewTLSVersion(input string) (version *TLSVersion, err error) {
|
||||
switch strings.ReplaceAll(strings.ToUpper(input), " ", "") {
|
||||
case TLSVersion13, Version13:
|
||||
return &TLSVersion{tls.VersionTLS13}, nil
|
||||
case TLSVersion12, Version12:
|
||||
return &TLSVersion{tls.VersionTLS12}, nil
|
||||
case TLSVersion11, Version11:
|
||||
return &TLSVersion{tls.VersionTLS11}, nil
|
||||
case TLSVersion10, Version10:
|
||||
return &TLSVersion{tls.VersionTLS10}, nil
|
||||
case SSLVersion30:
|
||||
return &TLSVersion{tls.VersionSSL30}, nil //nolint:staticcheck
|
||||
}
|
||||
|
||||
return nil, ErrTLSVersionNotSupported
|
||||
}
|
||||
|
||||
// TLSVersion is a struct which handles tls.Config versions.
|
||||
type TLSVersion struct {
|
||||
Value uint16
|
||||
}
|
||||
|
||||
// MaxVersion returns the value of this as a MaxVersion value.
|
||||
func (v *TLSVersion) MaxVersion() uint16 {
|
||||
if v.Value == 0 {
|
||||
return tls.VersionTLS13
|
||||
}
|
||||
|
||||
return v.Value
|
||||
}
|
||||
|
||||
// MinVersion returns the value of this as a MinVersion value.
|
||||
func (v *TLSVersion) MinVersion() uint16 {
|
||||
if v.Value == 0 {
|
||||
return tls.VersionTLS12
|
||||
}
|
||||
|
||||
return v.Value
|
||||
}
|
||||
|
||||
// String provides the Stringer.
|
||||
func (v *TLSVersion) String() string {
|
||||
switch v.Value {
|
||||
case tls.VersionTLS10:
|
||||
return TLSVersion10
|
||||
case tls.VersionTLS11:
|
||||
return TLSVersion11
|
||||
case tls.VersionTLS12:
|
||||
return TLSVersion12
|
||||
case tls.VersionTLS13:
|
||||
return TLSVersion13
|
||||
case tls.VersionSSL30: //nolint:staticcheck
|
||||
return SSLVersion30
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// CryptographicPrivateKey represents the actual crypto.PrivateKey interface.
|
||||
type CryptographicPrivateKey interface {
|
||||
Public() crypto.PublicKey
|
||||
Equal(x crypto.PrivateKey) bool
|
||||
}
|
||||
|
||||
// X509CertificateChain is a helper struct that holds a list of *x509.Certificate's.
|
||||
type X509CertificateChain struct {
|
||||
certs []*x509.Certificate
|
||||
|
@ -259,10 +325,32 @@ func (c *X509CertificateChain) EqualKey(other any) (equal bool) {
|
|||
}
|
||||
|
||||
// Certificates for this X509CertificateChain.
|
||||
func (c *X509CertificateChain) Certificates() []*x509.Certificate {
|
||||
func (c *X509CertificateChain) Certificates() (certificates []*x509.Certificate) {
|
||||
return c.certs
|
||||
}
|
||||
|
||||
// CertificatesRaw for this X509CertificateChain.
|
||||
func (c *X509CertificateChain) CertificatesRaw() (certificates [][]byte) {
|
||||
if !c.HasCertificates() {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, cert := range c.certs {
|
||||
certificates = append(certificates, cert.Raw)
|
||||
}
|
||||
|
||||
return certificates
|
||||
}
|
||||
|
||||
// Leaf returns the first certificate if available for use with tls.Certificate.
|
||||
func (c *X509CertificateChain) Leaf() (leaf *x509.Certificate) {
|
||||
if !c.HasCertificates() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return c.certs[0]
|
||||
}
|
||||
|
||||
// Validate the X509CertificateChain ensuring the certificates were provided in the correct order
|
||||
// (with nth being signed by the nth+1), and that all of the certificates are valid based on the current time.
|
||||
func (c *X509CertificateChain) Validate() (err error) {
|
||||
|
|
|
@ -18,6 +18,35 @@ duo_api:
|
|||
authentication_backend:
|
||||
ldap:
|
||||
url: ldap://127.0.0.1
|
||||
tls:
|
||||
private_key: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA6z1LOg1ZCqb0lytXWZ+MRBpMHEXOoTOLYgfZXt1IYyE3Z758
|
||||
cyalk0NYQhY5cZDsXPYWPvAHiPMUxutWkoxFwby56S+AbIMa3/Is+ILrHRJs8Exn
|
||||
ZkpyrYFxPX12app2kErdmAkHSx0Z5/kuXiz96PHs8S8/ZbyZolLHzdfLtSzjvRm5
|
||||
Zue5iFzsf19NJz5CIBfv8g5lRwtE8wNJoRSpn1xq7fqfuA0weDNFPzjlNWRLy6aa
|
||||
rK7qJexRkmkCs4sLgyl+9NODYJpvmN8E1yhyC27E0joI6rBFVW7Ihv+cSPCdDzGp
|
||||
EWe81x3AeqAa3mjVqkiq4u4Z2i8JDgBaPboqJwIDAQABAoIBAAFdLZ58jVOefDSU
|
||||
L8F5R1rtvBs93GDa56f926jNJ6pLewLC+/2+757W+SAI+PRLntM7Kg3bXm/Q2QH+
|
||||
Q1Y+MflZmspbWCdI61L5GIGoYKyeers59i+FpvySj5GHtLQRiTZ0+Kv1AXHSDWBm
|
||||
9XneUOqU3IbZe0ifu1RRno72/VtjkGXbW8Mkkw+ohyGbIeTx/0/JQ6sSNZTT3Vk7
|
||||
8i4IXptq3HSF0/vqZuah8rShoeNq72pD1YLM9YPdL5by1QkDLnqATDiCpLBTCaNV
|
||||
I8sqYEun+HYbQzBj8ZACG2JVZpEEidONWQHw5BPWO95DSZYrVnEkuCqeH+u5vYt7
|
||||
CHuJ3AECgYEA+W3v5z+j91w1VPHS0VB3SCDMouycAMIUnJPAbt+0LPP0scUFsBGE
|
||||
hPAKddC54pmMZRQ2KIwBKiyWfCrJ8Xz8Yogn7fJgmwTHidJBr2WQpIEkNGlK3Dzi
|
||||
jXL2sh0yC7sHvn0DqiQ79l/e7yRbSnv2wrTJEczOOH2haD7/tBRyCYECgYEA8W+q
|
||||
E9YyGvEltnPFaOxofNZ8LHVcZSsQI5b6fc0iE7fjxFqeXPXEwGSOTwqQLQRiHn9b
|
||||
CfPmIG4Vhyq0otVmlPvUnfBZ2OK+tl5X2/mQFO3ROMdvpi0KYa994uqfJdSTaqLn
|
||||
jjoKFB906UFHnDQDLZUNiV1WwnkTglgLc+xrd6cCgYEAqqthyv6NyBTM3Tm2gcio
|
||||
Ra9Dtntl51LlXZnvwy3IkDXBCd6BHM9vuLKyxZiziGx+Vy90O1xI872cnot8sINQ
|
||||
Am+dur/tAEVN72zxyv0Y8qb2yfH96iKy9gxi5s75TnOEQgAygLnYWaWR2lorKRUX
|
||||
bHTdXBOiS58S0UzCFEslGIECgYBqkO4SKWYeTDhoKvuEj2yjRYyzlu28XeCWxOo1
|
||||
otiauX0YSyNBRt2cSgYiTzhKFng0m+QUJYp63/wymB/5C5Zmxi0XtWIDADpLhqLj
|
||||
HmmBQ2Mo26alQ5YkffBju0mZyhVzaQop1eZi8WuKFV1FThPlB7hc3E0SM5zv2Grd
|
||||
tQnOWwKBgQC40yZY0PcjuILhy+sIc0Wvh7LUA7taSdTye149kRvbvsCDN7Jh75lM
|
||||
USjhLXY0Nld2zBm9r8wMb81mXH29uvD+tDqqsICvyuKlA/tyzXR+QTr7dCVKVwu0
|
||||
1YjCJ36UpTsLre2f8nOSLtNmRfDPtbOE2mkOoO9dD9UU0XZwnvn9xw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
base_dn: dc=example,dc=com
|
||||
username_attribute: uid
|
||||
additional_users_dn: ou=users
|
||||
|
|
|
@ -201,6 +201,22 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidSubject() {
|
|||
suite.Assert().EqualError(suite.validator.Errors()[1], fmt.Sprintf(errAccessControlRuleBypassPolicyInvalidWithSubjects, ruleDescriptor(1, suite.config.AccessControl.Rules[0])))
|
||||
}
|
||||
|
||||
func (suite *AccessControl) TestShouldRaiseErrorBypassWithSubjectDomainRegexGroup() {
|
||||
suite.config.AccessControl.Rules = []schema.ACLRule{
|
||||
{
|
||||
DomainsRegex: MustCompileRegexps([]string{`^(?P<User>\w+)\.example\.com$`}),
|
||||
Policy: "bypass",
|
||||
},
|
||||
}
|
||||
|
||||
ValidateRules(suite.config, suite.validator)
|
||||
|
||||
suite.Require().Len(suite.validator.Warnings(), 0)
|
||||
suite.Require().Len(suite.validator.Errors(), 1)
|
||||
|
||||
suite.Assert().EqualError(suite.validator.Errors()[0], "access control: rule #1: 'policy' option 'bypass' is not supported when 'domain_regex' option contains the user or group named matches. For more information see: https://www.authelia.com/c/acl-match-concept-2")
|
||||
}
|
||||
|
||||
func (suite *AccessControl) TestShouldSetQueryDefaults() {
|
||||
domains := []string{"public.example.com"}
|
||||
suite.config.AccessControl.Rules = []schema.ACLRule{
|
||||
|
@ -359,3 +375,13 @@ func TestShouldReturnCorrectResultsForValidNetworkGroups(t *testing.T) {
|
|||
assert.True(t, validNetwork)
|
||||
assert.False(t, invalidNetwork)
|
||||
}
|
||||
|
||||
func MustCompileRegexps(exps []string) (regexps []regexp.Regexp) {
|
||||
regexps = make([]regexp.Regexp, len(exps))
|
||||
|
||||
for i, exp := range exps {
|
||||
regexps[i] = *regexp.MustCompile(exp)
|
||||
}
|
||||
|
||||
return regexps
|
||||
}
|
||||
|
|
|
@ -321,19 +321,35 @@ func validateLDAPAuthenticationBackend(config *schema.AuthenticationBackend, val
|
|||
validator.Push(fmt.Errorf(errFmtLDAPAuthBackendImplementation, config.LDAP.Implementation, strings.Join([]string{schema.LDAPImplementationCustom, schema.LDAPImplementationActiveDirectory}, "', '")))
|
||||
}
|
||||
|
||||
configDefaultTLS := &schema.TLSConfig{}
|
||||
|
||||
if implementation != nil {
|
||||
setDefaultImplementationLDAPAuthenticationBackendProfileMisc(config.LDAP, implementation)
|
||||
if config.LDAP.Timeout == 0 {
|
||||
config.LDAP.Timeout = implementation.Timeout
|
||||
}
|
||||
|
||||
configDefaultTLS = &schema.TLSConfig{
|
||||
MinimumVersion: implementation.TLS.MinimumVersion,
|
||||
MaximumVersion: implementation.TLS.MaximumVersion,
|
||||
}
|
||||
|
||||
setDefaultImplementationLDAPAuthenticationBackendProfileAttributes(config.LDAP, implementation)
|
||||
}
|
||||
|
||||
if config.LDAP.TLS != nil {
|
||||
if _, err := utils.TLSStringToTLSConfigVersion(config.LDAP.TLS.MinimumVersion); err != nil {
|
||||
validator.Push(fmt.Errorf(errFmtLDAPAuthBackendTLSMinVersion, config.LDAP.TLS.MinimumVersion, err))
|
||||
}
|
||||
if config.LDAP.URL == "" {
|
||||
validator.Push(fmt.Errorf(errFmtLDAPAuthBackendMissingOption, "url"))
|
||||
} else {
|
||||
configDefaultTLS.ServerName = validateLDAPAuthenticationBackendURL(config.LDAP, validator)
|
||||
}
|
||||
|
||||
if config.LDAP.TLS == nil {
|
||||
config.LDAP.TLS = &schema.TLSConfig{}
|
||||
}
|
||||
|
||||
if err := ValidateTLSConfig(config.LDAP.TLS, configDefaultTLS); err != nil {
|
||||
validator.Push(fmt.Errorf(errFmtLDAPAuthBackendTLSConfigInvalid, err))
|
||||
}
|
||||
|
||||
if strings.Contains(config.LDAP.UsersFilter, "{0}") {
|
||||
validator.Push(fmt.Errorf(errFmtLDAPAuthBackendFilterReplacedPlaceholders, "users_filter", "{0}", "{input}"))
|
||||
}
|
||||
|
@ -346,31 +362,9 @@ func validateLDAPAuthenticationBackend(config *schema.AuthenticationBackend, val
|
|||
validator.Push(fmt.Errorf(errFmtLDAPAuthBackendFilterReplacedPlaceholders, "groups_filter", "{1}", "{username}"))
|
||||
}
|
||||
|
||||
if config.LDAP.URL == "" {
|
||||
validator.Push(fmt.Errorf(errFmtLDAPAuthBackendMissingOption, "url"))
|
||||
} else {
|
||||
validateLDAPAuthenticationBackendURL(config.LDAP, validator)
|
||||
}
|
||||
|
||||
validateLDAPRequiredParameters(config, validator)
|
||||
}
|
||||
|
||||
func setDefaultImplementationLDAPAuthenticationBackendProfileMisc(config *schema.LDAPAuthenticationBackend, implementation *schema.LDAPAuthenticationBackend) {
|
||||
if config.Timeout == 0 {
|
||||
config.Timeout = implementation.Timeout
|
||||
}
|
||||
|
||||
if implementation.TLS == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if config.TLS == nil {
|
||||
config.TLS = implementation.TLS
|
||||
} else if config.TLS.MinimumVersion == "" {
|
||||
config.TLS.MinimumVersion = implementation.TLS.MinimumVersion
|
||||
}
|
||||
}
|
||||
|
||||
func ldapImplementationShouldSetStr(config, implementation string) bool {
|
||||
return config == "" && implementation != ""
|
||||
}
|
||||
|
@ -401,7 +395,7 @@ func setDefaultImplementationLDAPAuthenticationBackendProfileAttributes(config *
|
|||
}
|
||||
}
|
||||
|
||||
func validateLDAPAuthenticationBackendURL(config *schema.LDAPAuthenticationBackend, validator *schema.StructValidator) {
|
||||
func validateLDAPAuthenticationBackendURL(config *schema.LDAPAuthenticationBackend, validator *schema.StructValidator) (hostname string) {
|
||||
var (
|
||||
parsedURL *url.URL
|
||||
err error
|
||||
|
@ -420,9 +414,8 @@ func validateLDAPAuthenticationBackendURL(config *schema.LDAPAuthenticationBacke
|
|||
}
|
||||
|
||||
config.URL = parsedURL.String()
|
||||
if config.TLS.ServerName == "" {
|
||||
config.TLS.ServerName = parsedURL.Hostname()
|
||||
}
|
||||
|
||||
return parsedURL.Hostname()
|
||||
}
|
||||
|
||||
func validateLDAPRequiredParameters(config *schema.AuthenticationBackend, validator *schema.StructValidator) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package validator
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -625,6 +626,42 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenPasswordNot
|
|||
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: option 'password' is required")
|
||||
}
|
||||
|
||||
func (suite *LDAPAuthenticationBackendSuite) TestShouldNotRaiseErrorWhenPasswordNotProvidedWithPermitUnauthenticatedBind() {
|
||||
suite.config.LDAP.Password = ""
|
||||
suite.config.LDAP.PermitUnauthenticatedBind = true
|
||||
|
||||
ValidateAuthenticationBackend(&suite.config, suite.validator)
|
||||
|
||||
suite.Assert().Len(suite.validator.Warnings(), 0)
|
||||
suite.Require().Len(suite.validator.Errors(), 1)
|
||||
|
||||
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: option 'permit_unauthenticated_bind' can't be enabled when password reset is enabled")
|
||||
}
|
||||
|
||||
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenPasswordProvidedWithPermitUnauthenticatedBind() {
|
||||
suite.config.LDAP.Password = "test"
|
||||
suite.config.LDAP.PermitUnauthenticatedBind = true
|
||||
suite.config.PasswordReset.Disable = true
|
||||
|
||||
ValidateAuthenticationBackend(&suite.config, suite.validator)
|
||||
|
||||
suite.Assert().Len(suite.validator.Warnings(), 0)
|
||||
suite.Require().Len(suite.validator.Errors(), 1)
|
||||
|
||||
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: option 'permit_unauthenticated_bind' can't be enabled when a password is specified")
|
||||
}
|
||||
|
||||
func (suite *LDAPAuthenticationBackendSuite) TestShouldNotRaiseErrorWhenPermitUnauthenticatedBindConfiguredCorrectly() {
|
||||
suite.config.LDAP.Password = ""
|
||||
suite.config.LDAP.PermitUnauthenticatedBind = true
|
||||
suite.config.PasswordReset.Disable = true
|
||||
|
||||
ValidateAuthenticationBackend(&suite.config, suite.validator)
|
||||
|
||||
suite.Assert().Len(suite.validator.Warnings(), 0)
|
||||
suite.Require().Len(suite.validator.Errors(), 0)
|
||||
}
|
||||
|
||||
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenBaseDNNotProvided() {
|
||||
suite.config.LDAP.BaseDN = ""
|
||||
|
||||
|
@ -783,19 +820,19 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldHelpDetectNoInputPlacehol
|
|||
}
|
||||
|
||||
func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultTLSMinimumVersion() {
|
||||
suite.config.LDAP.TLS = &schema.TLSConfig{MinimumVersion: ""}
|
||||
suite.config.LDAP.TLS = &schema.TLSConfig{MinimumVersion: schema.TLSVersion{}}
|
||||
|
||||
ValidateAuthenticationBackend(&suite.config, suite.validator)
|
||||
|
||||
suite.Assert().Len(suite.validator.Warnings(), 0)
|
||||
suite.Assert().Len(suite.validator.Errors(), 0)
|
||||
|
||||
suite.Assert().Equal(schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom.TLS.MinimumVersion, suite.config.LDAP.TLS.MinimumVersion)
|
||||
suite.Assert().Equal(schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom.TLS.MinimumVersion.Value, suite.config.LDAP.TLS.MinimumVersion.MinVersion())
|
||||
}
|
||||
|
||||
func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowInvalidTLSValue() {
|
||||
func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowSSL30() {
|
||||
suite.config.LDAP.TLS = &schema.TLSConfig{
|
||||
MinimumVersion: "SSL2.0",
|
||||
MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck
|
||||
}
|
||||
|
||||
ValidateAuthenticationBackend(&suite.config, suite.validator)
|
||||
|
@ -803,7 +840,21 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowInvalidTLSValue()
|
|||
suite.Assert().Len(suite.validator.Warnings(), 0)
|
||||
suite.Require().Len(suite.validator.Errors(), 1)
|
||||
|
||||
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: tls: option 'minimum_tls_version' is invalid: SSL2.0: supplied tls version isn't supported")
|
||||
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: tls: option 'minimum_version' is invalid: minimum version is TLS1.0 but SSL3.0 was configured")
|
||||
}
|
||||
|
||||
func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowTLSVerMinGreaterThanVerMax() {
|
||||
suite.config.LDAP.TLS = &schema.TLSConfig{
|
||||
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13},
|
||||
MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS12},
|
||||
}
|
||||
|
||||
ValidateAuthenticationBackend(&suite.config, suite.validator)
|
||||
|
||||
suite.Assert().Len(suite.validator.Warnings(), 0)
|
||||
suite.Require().Len(suite.validator.Errors(), 1)
|
||||
|
||||
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: tls: option combination of 'minimum_version' and 'maximum_version' is invalid: minimum version TLS1.3 is greater than the maximum version TLS1.2")
|
||||
}
|
||||
|
||||
func TestLdapAuthenticationBackend(t *testing.T) {
|
||||
|
|
|
@ -25,7 +25,7 @@ func newDefaultConfig() schema.Configuration {
|
|||
DefaultPolicy: "two_factor",
|
||||
}
|
||||
config.Session = schema.SessionConfiguration{
|
||||
Domain: "example.com",
|
||||
Domain: examplecom,
|
||||
Name: "authelia_session",
|
||||
Secret: "secret",
|
||||
}
|
||||
|
|
|
@ -58,7 +58,11 @@ const (
|
|||
errFmtNotifierTemplatePathUnknownError = "notifier: option 'template_path' refers to location '%s' which couldn't be opened: %w"
|
||||
errFmtNotifierFileSystemFileNameNotConfigured = "notifier: filesystem: option 'filename' is required"
|
||||
errFmtNotifierSMTPNotConfigured = "notifier: smtp: option '%s' is required"
|
||||
errFmtNotifierStartTlsDisabled = "Notifier SMTP connection has opportunistic STARTTLS explicitly disabled which means all emails will be sent insecurely over plain text and this setting is only necessary for non-compliant SMTP servers which advertise they support STARTTLS when they actually don't support STARTTLS"
|
||||
errFmtNotifierSMTPTLSConfigInvalid = "notifier: smtp: tls: %w"
|
||||
errFmtNotifierStartTlsDisabled = "notifier: smtp: option 'disable_starttls' is enabled: " +
|
||||
"opportunistic STARTTLS is explicitly disabled which means all emails will be sent insecurely over plaintext " +
|
||||
"and this setting is only necessary for non-compliant SMTP servers which advertise they support STARTTLS " +
|
||||
"when they actually don't support STARTTLS"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -92,8 +96,7 @@ const (
|
|||
errFmtLDAPAuthBackendUnauthenticatedBindWithResetEnabled = "authentication_backend: ldap: option 'permit_unauthenticated_bind' can't be enabled when password reset is enabled"
|
||||
|
||||
errFmtLDAPAuthBackendMissingOption = "authentication_backend: ldap: option '%s' is required"
|
||||
errFmtLDAPAuthBackendTLSMinVersion = "authentication_backend: ldap: tls: option " +
|
||||
"'minimum_tls_version' is invalid: %s: %w"
|
||||
errFmtLDAPAuthBackendTLSConfigInvalid = "authentication_backend: ldap: tls: %w"
|
||||
errFmtLDAPAuthBackendImplementation = "authentication_backend: ldap: option 'implementation' " +
|
||||
errSuffixMustBeOneOf
|
||||
errFmtLDAPAuthBackendFilterReplacedPlaceholders = "authentication_backend: ldap: option " +
|
||||
|
@ -247,6 +250,7 @@ const (
|
|||
errFmtSessionRedisPortRange = "session: redis: option 'port' must be between 1 and 65535 but is configured as '%d'"
|
||||
errFmtSessionRedisHostRequired = "session: redis: option 'host' is required"
|
||||
errFmtSessionRedisHostOrNodesRequired = "session: redis: option 'host' or the 'high_availability' option 'nodes' is required"
|
||||
errFmtSessionRedisTLSConfigInvalid = "session: redis: tls: %w"
|
||||
|
||||
errFmtSessionRedisSentinelMissingName = "session: redis: high_availability: option 'sentinel_name' is required"
|
||||
errFmtSessionRedisSentinelNodeHostMissing = "session: redis: high_availability: option 'nodes': option 'host' is required for each node but one or more nodes are missing this"
|
||||
|
|
|
@ -10,3 +10,7 @@ const (
|
|||
testLDAPUser = "user"
|
||||
testEncryptionKey = "a_not_so_secure_encryption_key"
|
||||
)
|
||||
|
||||
const (
|
||||
examplecom = "example.com"
|
||||
)
|
||||
|
|
|
@ -257,7 +257,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) {
|
|||
RedirectURIs: []string{
|
||||
"https://google.com",
|
||||
},
|
||||
SectorIdentifier: mustParseURL("example.com"),
|
||||
SectorIdentifier: mustParseURL(examplecom),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -289,12 +289,12 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) {
|
|||
},
|
||||
},
|
||||
Errors: []string{
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifier, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", "example.com", "scheme", "https"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifier, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", "example.com", "path", "/path"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifier, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", "example.com", "query", "query=abc"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifier, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", "example.com", "fragment", "fragment"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifier, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", "example.com", "username", "user"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifierWithoutValue, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", "example.com", "password"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifier, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", examplecom, "scheme", "https"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifier, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", examplecom, "path", "/path"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifier, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", examplecom, "query", "query=abc"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifier, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", examplecom, "fragment", "fragment"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifier, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", examplecom, "username", "user"),
|
||||
fmt.Sprintf(errFmtOIDCClientInvalidSectorIdentifierWithoutValue, "client-invalid-sector", "https://user:pass@example.com/path?query=abc#fragment", examplecom, "password"),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -83,11 +83,17 @@ func validateSMTPNotifier(config *schema.SMTPNotifierConfiguration, validator *s
|
|||
}
|
||||
|
||||
if config.TLS == nil {
|
||||
config.TLS = schema.DefaultSMTPNotifierConfiguration.TLS
|
||||
config.TLS = &schema.TLSConfig{}
|
||||
}
|
||||
|
||||
if config.TLS.ServerName == "" {
|
||||
config.TLS.ServerName = config.Host
|
||||
configDefaultTLS := &schema.TLSConfig{
|
||||
ServerName: config.Host,
|
||||
MinimumVersion: schema.DefaultSMTPNotifierConfiguration.TLS.MinimumVersion,
|
||||
MaximumVersion: schema.DefaultSMTPNotifierConfiguration.TLS.MaximumVersion,
|
||||
}
|
||||
|
||||
if err := ValidateTLSConfig(config.TLS, configDefaultTLS); err != nil {
|
||||
validator.Push(fmt.Errorf(errFmtNotifierSMTPTLSConfigInvalid, err))
|
||||
}
|
||||
|
||||
if config.DisableStartTLS {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package validator
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/mail"
|
||||
"testing"
|
||||
|
@ -22,7 +23,7 @@ func (suite *NotifierSuite) SetupTest() {
|
|||
Username: "john",
|
||||
Password: "password",
|
||||
Sender: mail.Address{Name: "Authelia", Address: "authelia@example.com"},
|
||||
Host: "example.com",
|
||||
Host: examplecom,
|
||||
Port: 25,
|
||||
}
|
||||
suite.config.FileSystem = nil
|
||||
|
@ -77,8 +78,8 @@ func (suite *NotifierSuite) TestSMTPShouldSetTLSDefaults() {
|
|||
suite.Assert().Len(suite.validator.Warnings(), 0)
|
||||
suite.Assert().Len(suite.validator.Errors(), 0)
|
||||
|
||||
suite.Assert().Equal("example.com", suite.config.SMTP.TLS.ServerName)
|
||||
suite.Assert().Equal("TLS1.2", suite.config.SMTP.TLS.MinimumVersion)
|
||||
suite.Assert().Equal(examplecom, suite.config.SMTP.TLS.ServerName)
|
||||
suite.Assert().Equal(uint16(tls.VersionTLS12), suite.config.SMTP.TLS.MinimumVersion.Value)
|
||||
suite.Assert().False(suite.config.SMTP.TLS.SkipVerify)
|
||||
}
|
||||
|
||||
|
@ -96,7 +97,7 @@ func (suite *NotifierSuite) TestSMTPShouldDefaultStartupCheckAddress() {
|
|||
func (suite *NotifierSuite) TestSMTPShouldDefaultTLSServerNameToHost() {
|
||||
suite.config.SMTP.Host = "google.com"
|
||||
suite.config.SMTP.TLS = &schema.TLSConfig{
|
||||
MinimumVersion: "TLS1.1",
|
||||
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS11},
|
||||
}
|
||||
|
||||
ValidateNotifier(&suite.config, suite.validator)
|
||||
|
@ -105,10 +106,51 @@ func (suite *NotifierSuite) TestSMTPShouldDefaultTLSServerNameToHost() {
|
|||
suite.Assert().Len(suite.validator.Errors(), 0)
|
||||
|
||||
suite.Assert().Equal("google.com", suite.config.SMTP.TLS.ServerName)
|
||||
suite.Assert().Equal("TLS1.1", suite.config.SMTP.TLS.MinimumVersion)
|
||||
suite.Assert().Equal(uint16(tls.VersionTLS11), suite.config.SMTP.TLS.MinimumVersion.MinVersion())
|
||||
suite.Assert().False(suite.config.SMTP.TLS.SkipVerify)
|
||||
}
|
||||
|
||||
func (suite *NotifierSuite) TestSMTPShouldErrorOnSSL30() {
|
||||
suite.config.SMTP.Host = examplecom
|
||||
suite.config.SMTP.TLS = &schema.TLSConfig{
|
||||
MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck
|
||||
}
|
||||
|
||||
ValidateNotifier(&suite.config, suite.validator)
|
||||
|
||||
suite.Assert().Len(suite.validator.Warnings(), 0)
|
||||
suite.Require().Len(suite.validator.Errors(), 1)
|
||||
|
||||
suite.Assert().EqualError(suite.validator.Errors()[0], "notifier: smtp: tls: option 'minimum_version' is invalid: minimum version is TLS1.0 but SSL3.0 was configured")
|
||||
}
|
||||
|
||||
func (suite *NotifierSuite) TestSMTPShouldErrorOnTLSMinVerGreaterThanMaxVer() {
|
||||
suite.config.SMTP.Host = examplecom
|
||||
suite.config.SMTP.TLS = &schema.TLSConfig{
|
||||
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13},
|
||||
MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS10},
|
||||
}
|
||||
|
||||
ValidateNotifier(&suite.config, suite.validator)
|
||||
|
||||
suite.Assert().Len(suite.validator.Warnings(), 0)
|
||||
suite.Require().Len(suite.validator.Errors(), 1)
|
||||
|
||||
suite.Assert().EqualError(suite.validator.Errors()[0], "notifier: smtp: tls: option combination of 'minimum_version' and 'maximum_version' is invalid: minimum version TLS1.3 is greater than the maximum version TLS1.0")
|
||||
}
|
||||
|
||||
func (suite *NotifierSuite) TestSMTPShouldWarnOnDisabledSTARTTLS() {
|
||||
suite.config.SMTP.Host = examplecom
|
||||
suite.config.SMTP.DisableStartTLS = true
|
||||
|
||||
ValidateNotifier(&suite.config, suite.validator)
|
||||
|
||||
suite.Require().Len(suite.validator.Warnings(), 1)
|
||||
suite.Assert().Len(suite.validator.Errors(), 0)
|
||||
|
||||
suite.Assert().EqualError(suite.validator.Warnings()[0], "notifier: smtp: option 'disable_starttls' is enabled: opportunistic STARTTLS is explicitly disabled which means all emails will be sent insecurely over plaintext and this setting is only necessary for non-compliant SMTP servers which advertise they support STARTTLS when they actually don't support STARTTLS")
|
||||
}
|
||||
|
||||
func (suite *NotifierSuite) TestSMTPShouldEnsureHostAndPortAreProvided() {
|
||||
suite.config.FileSystem = nil
|
||||
ValidateNotifier(&suite.config, suite.validator)
|
||||
|
|
|
@ -58,6 +58,18 @@ func validateRedisCommon(config *schema.SessionConfiguration, validator *schema.
|
|||
if config.Secret == "" {
|
||||
validator.Push(fmt.Errorf(errFmtSessionSecretRequired, "redis"))
|
||||
}
|
||||
|
||||
if config.Redis.TLS != nil {
|
||||
configDefaultTLS := &schema.TLSConfig{
|
||||
ServerName: config.Redis.Host,
|
||||
MinimumVersion: schema.DefaultRedisConfiguration.TLS.MinimumVersion,
|
||||
MaximumVersion: schema.DefaultRedisConfiguration.TLS.MaximumVersion,
|
||||
}
|
||||
|
||||
if err := ValidateTLSConfig(config.Redis.TLS, configDefaultTLS); err != nil {
|
||||
validator.Push(fmt.Errorf(errFmtSessionRedisTLSConfigInvalid, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func validateRedis(config *schema.SessionConfiguration, validator *schema.StructValidator) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package validator
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
|
@ -13,7 +14,7 @@ import (
|
|||
func newDefaultSessionConfig() schema.SessionConfiguration {
|
||||
config := schema.SessionConfiguration{}
|
||||
config.Secret = testJWTSecret
|
||||
config.Domain = "example.com"
|
||||
config.Domain = examplecom
|
||||
|
||||
return config
|
||||
}
|
||||
|
@ -354,6 +355,67 @@ func TestShouldRaiseErrorsWhenRedisHostNotSet(t *testing.T) {
|
|||
assert.EqualError(t, errors[0], errFmtSessionRedisHostRequired)
|
||||
}
|
||||
|
||||
func TestShouldSetDefaultRedisTLSOptions(t *testing.T) {
|
||||
validator := schema.NewStructValidator()
|
||||
config := newDefaultSessionConfig()
|
||||
|
||||
config.Redis = &schema.RedisSessionConfiguration{
|
||||
Host: "redis.local",
|
||||
Port: 6379,
|
||||
TLS: &schema.TLSConfig{},
|
||||
}
|
||||
|
||||
ValidateSession(&config, validator)
|
||||
|
||||
assert.Len(t, validator.Warnings(), 0)
|
||||
assert.Len(t, validator.Errors(), 0)
|
||||
|
||||
assert.Equal(t, uint16(tls.VersionTLS12), config.Redis.TLS.MinimumVersion.Value)
|
||||
assert.Equal(t, uint16(0), config.Redis.TLS.MaximumVersion.Value)
|
||||
assert.Equal(t, "redis.local", config.Redis.TLS.ServerName)
|
||||
}
|
||||
|
||||
func TestShouldRaiseErrorOnBadRedisTLSOptionsSSL30(t *testing.T) {
|
||||
validator := schema.NewStructValidator()
|
||||
config := newDefaultSessionConfig()
|
||||
|
||||
config.Redis = &schema.RedisSessionConfiguration{
|
||||
Host: "redis.local",
|
||||
Port: 6379,
|
||||
TLS: &schema.TLSConfig{
|
||||
MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck
|
||||
},
|
||||
}
|
||||
|
||||
ValidateSession(&config, validator)
|
||||
|
||||
assert.Len(t, validator.Warnings(), 0)
|
||||
require.Len(t, validator.Errors(), 1)
|
||||
|
||||
assert.EqualError(t, validator.Errors()[0], "session: redis: tls: option 'minimum_version' is invalid: minimum version is TLS1.0 but SSL3.0 was configured")
|
||||
}
|
||||
|
||||
func TestShouldRaiseErrorOnBadRedisTLSOptionsMinVerGreaterThanMax(t *testing.T) {
|
||||
validator := schema.NewStructValidator()
|
||||
config := newDefaultSessionConfig()
|
||||
|
||||
config.Redis = &schema.RedisSessionConfiguration{
|
||||
Host: "redis.local",
|
||||
Port: 6379,
|
||||
TLS: &schema.TLSConfig{
|
||||
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13},
|
||||
MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS10},
|
||||
},
|
||||
}
|
||||
|
||||
ValidateSession(&config, validator)
|
||||
|
||||
assert.Len(t, validator.Warnings(), 0)
|
||||
require.Len(t, validator.Errors(), 1)
|
||||
|
||||
assert.EqualError(t, validator.Errors()[0], "session: redis: tls: option combination of 'minimum_version' and 'maximum_version' is invalid: minimum version TLS1.3 is greater than the maximum version TLS1.0")
|
||||
}
|
||||
|
||||
func TestShouldRaiseErrorWhenDomainNotSet(t *testing.T) {
|
||||
validator := schema.NewStructValidator()
|
||||
config := newDefaultSessionConfig()
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package validator
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||
)
|
||||
|
||||
// ValidateTLSConfig sets the default values and validates a schema.TLSConfig.
|
||||
func ValidateTLSConfig(config *schema.TLSConfig, configDefault *schema.TLSConfig) (err error) {
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if config.ServerName == "" {
|
||||
config.ServerName = configDefault.ServerName
|
||||
}
|
||||
|
||||
if config.MinimumVersion.Value == 0 {
|
||||
config.MinimumVersion.Value = configDefault.MinimumVersion.Value
|
||||
}
|
||||
|
||||
if config.MaximumVersion.Value == 0 {
|
||||
config.MaximumVersion.Value = configDefault.MaximumVersion.Value
|
||||
}
|
||||
|
||||
if config.MinimumVersion.MinVersion() < tls.VersionTLS10 {
|
||||
return errors.New("option 'minimum_version' is invalid: minimum version is TLS1.0 but SSL3.0 was configured")
|
||||
}
|
||||
|
||||
if config.MinimumVersion.MinVersion() > config.MaximumVersion.MaxVersion() {
|
||||
return fmt.Errorf("option combination of 'minimum_version' and 'maximum_version' is invalid: minimum version %s is greater than the maximum version %s", config.MinimumVersion.String(), config.MaximumVersion.String())
|
||||
}
|
||||
|
||||
if (config.CertificateChain.HasCertificates() || config.PrivateKey != nil) && !config.CertificateChain.EqualKey(config.PrivateKey) {
|
||||
return errors.New("option 'certificates' is invalid: provided certificate is not the public key for the private key provided")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -27,7 +27,7 @@ import (
|
|||
func NewSMTPNotifier(config *schema.SMTPNotifierConfiguration, certPool *x509.CertPool, templateProvider *templates.Provider) *SMTPNotifier {
|
||||
notifier := &SMTPNotifier{
|
||||
config: config,
|
||||
tlsConfig: utils.NewTLSConfig(config.TLS, tls.VersionTLS12, certPool),
|
||||
tlsConfig: utils.NewTLSConfig(config.TLS, certPool),
|
||||
log: logging.Logger(),
|
||||
templates: templateProvider,
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ func TestShouldConfigureSMTPNotifierWithTLS11(t *testing.T) {
|
|||
Port: 25,
|
||||
TLS: &schema.TLSConfig{
|
||||
ServerName: "smtp.example.com",
|
||||
MinimumVersion: "TLS1.1",
|
||||
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS11},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ func NewProviderConfig(config schema.SessionConfiguration, certPool *x509.CertPo
|
|||
var tlsConfig *tls.Config
|
||||
|
||||
if config.Redis.TLS != nil {
|
||||
tlsConfig = utils.NewTLSConfig(config.Redis.TLS, tls.VersionTLS12, certPool)
|
||||
tlsConfig = utils.NewTLSConfig(config.Redis.TLS, certPool)
|
||||
}
|
||||
|
||||
if config.Redis.HighAvailability != nil && config.Redis.HighAvailability.SentinelName != "" {
|
||||
|
|
|
@ -42,7 +42,7 @@ func TestShouldCreateRedisSessionProviderTLS(t *testing.T) {
|
|||
Password: "pass",
|
||||
TLS: &schema.TLSConfig{
|
||||
ServerName: "redis.fqdn.example.com",
|
||||
MinimumVersion: "TLS1.3",
|
||||
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13},
|
||||
},
|
||||
}
|
||||
providerConfig := NewProviderConfig(configuration, nil)
|
||||
|
|
|
@ -235,17 +235,26 @@ func IsX509PrivateKey(i any) bool {
|
|||
}
|
||||
|
||||
// NewTLSConfig generates a tls.Config from a schema.TLSConfig and a x509.CertPool.
|
||||
func NewTLSConfig(config *schema.TLSConfig, defaultMinVersion uint16, certPool *x509.CertPool) (tlsConfig *tls.Config) {
|
||||
minVersion, err := TLSStringToTLSConfigVersion(config.MinimumVersion)
|
||||
if err != nil {
|
||||
minVersion = defaultMinVersion
|
||||
func NewTLSConfig(config *schema.TLSConfig, certPool *x509.CertPool) (tlsConfig *tls.Config) {
|
||||
var certificates []tls.Certificate
|
||||
|
||||
if config.CertificateChain.HasCertificates() && config.PrivateKey != nil {
|
||||
certificates = []tls.Certificate{
|
||||
{
|
||||
Certificate: config.CertificateChain.CertificatesRaw(),
|
||||
Leaf: config.CertificateChain.Leaf(),
|
||||
PrivateKey: config.PrivateKey,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return &tls.Config{
|
||||
ServerName: config.ServerName,
|
||||
InsecureSkipVerify: config.SkipVerify, //nolint:gosec // Informed choice by user. Off by default.
|
||||
MinVersion: minVersion,
|
||||
MinVersion: config.MinimumVersion.MinVersion(),
|
||||
MaxVersion: config.MinimumVersion.MaxVersion(),
|
||||
RootCAs: certPool,
|
||||
Certificates: certificates,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,22 +299,6 @@ func NewX509CertPool(directory string) (certPool *x509.CertPool, warnings []erro
|
|||
return certPool, warnings, errors
|
||||
}
|
||||
|
||||
// TLSStringToTLSConfigVersion returns a go crypto/tls version for a tls.Config based on string input.
|
||||
func TLSStringToTLSConfigVersion(input string) (version uint16, err error) {
|
||||
switch strings.ToUpper(input) {
|
||||
case "TLS1.3", TLS13:
|
||||
return tls.VersionTLS13, nil
|
||||
case "TLS1.2", TLS12:
|
||||
return tls.VersionTLS12, nil
|
||||
case "TLS1.1", TLS11:
|
||||
return tls.VersionTLS11, nil
|
||||
case "TLS1.0", TLS10:
|
||||
return tls.VersionTLS10, nil
|
||||
}
|
||||
|
||||
return 0, ErrTLSVersionNotSupported
|
||||
}
|
||||
|
||||
// WriteCertificateBytesToPEM writes a certificate/csr to a file in the PEM format.
|
||||
func WriteCertificateBytesToPEM(cert []byte, path string, csr bool) (err error) {
|
||||
out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
@ -14,75 +13,8 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||
)
|
||||
|
||||
func TestShouldSetupDefaultTLSMinVersionOnErr(t *testing.T) {
|
||||
schemaTLSConfig := &schema.TLSConfig{
|
||||
MinimumVersion: "NotAVersion",
|
||||
ServerName: "golang.org",
|
||||
SkipVerify: true,
|
||||
}
|
||||
|
||||
tlsConfig := NewTLSConfig(schemaTLSConfig, tls.VersionTLS12, nil)
|
||||
|
||||
assert.Equal(t, uint16(tls.VersionTLS12), tlsConfig.MinVersion)
|
||||
assert.Equal(t, "golang.org", tlsConfig.ServerName)
|
||||
assert.True(t, tlsConfig.InsecureSkipVerify)
|
||||
}
|
||||
|
||||
func TestShouldReturnCorrectTLSVersions(t *testing.T) {
|
||||
tls13 := uint16(tls.VersionTLS13)
|
||||
tls12 := uint16(tls.VersionTLS12)
|
||||
tls11 := uint16(tls.VersionTLS11)
|
||||
tls10 := uint16(tls.VersionTLS10)
|
||||
|
||||
version, err := TLSStringToTLSConfigVersion(TLS13)
|
||||
assert.Equal(t, tls13, version)
|
||||
assert.NoError(t, err)
|
||||
|
||||
version, err = TLSStringToTLSConfigVersion("TLS" + TLS13)
|
||||
assert.Equal(t, tls13, version)
|
||||
assert.NoError(t, err)
|
||||
|
||||
version, err = TLSStringToTLSConfigVersion(TLS12)
|
||||
assert.Equal(t, tls12, version)
|
||||
assert.NoError(t, err)
|
||||
|
||||
version, err = TLSStringToTLSConfigVersion("TLS" + TLS12)
|
||||
assert.Equal(t, tls12, version)
|
||||
assert.NoError(t, err)
|
||||
|
||||
version, err = TLSStringToTLSConfigVersion(TLS11)
|
||||
assert.Equal(t, tls11, version)
|
||||
assert.NoError(t, err)
|
||||
|
||||
version, err = TLSStringToTLSConfigVersion("TLS" + TLS11)
|
||||
assert.Equal(t, tls11, version)
|
||||
assert.NoError(t, err)
|
||||
|
||||
version, err = TLSStringToTLSConfigVersion(TLS10)
|
||||
assert.Equal(t, tls10, version)
|
||||
assert.NoError(t, err)
|
||||
|
||||
version, err = TLSStringToTLSConfigVersion("TLS" + TLS10)
|
||||
assert.Equal(t, tls10, version)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestShouldReturnZeroAndErrorOnInvalidTLSVersions(t *testing.T) {
|
||||
version, err := TLSStringToTLSConfigVersion("TLS1.4")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, uint16(0), version)
|
||||
assert.EqualError(t, err, "supplied tls version isn't supported")
|
||||
|
||||
version, err = TLSStringToTLSConfigVersion("SSL3.0")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, uint16(0), version)
|
||||
assert.EqualError(t, err, "supplied tls version isn't supported")
|
||||
}
|
||||
|
||||
func TestShouldReturnErrWhenX509DirectoryNotExist(t *testing.T) {
|
||||
pool, warnings, errors := NewX509CertPool("/tmp/asdfzyxabc123/not/a/real/dir")
|
||||
assert.NotNil(t, pool)
|
||||
|
|
Loading…
Reference in New Issue