Hallo Alex,
sorry für die späte Antwort. Kann ich gerne machen, allerdings ohne Garantie, dass das sinnvoll ist, was ich da gebaut habe. Ich hoffe es sind alle relevanten Dateien dabei, sonst gerne nochmal nachfragen. Wir arbeiten mit FreeRadius 3.0.26-1.
Die Config ist zudem bei uns ursprünglich für Logodidact gebaut worden, dann für die paedML angepasst worden und läuft jetzt mit LMN - es gibt also den ein oder anderen Teil, der nicht mehr nötig wäre, aber einfach nicht rausgeworfen wurde (NetworkAccess zum Beispiel oder UserPassword).
Viele Grüße
Sebastian
# sites-enabled/inner-tunnel
server inner-tunnel {
listen {
ipaddr = 127.0.0.1
port = 18120
type = auth
}
authorize {
filter_username
chap
mschap
suffix
update control {
&Proxy-To-Realm := domain.schule
}
eap {
ok = return
}
files
expiration
logintime
pap
}
authenticate {
ntlm_auth
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
eap
}
session {
radutmp
}
post-auth {
update outer.session-state {
&User-Name = &User-Name
}
if (1) {
update reply {
User-Name !* ANY
Message-Authenticator !* ANY
EAP-Message !* ANY
Proxy-State !* ANY
MS-MPPE-Encryption-Types !* ANY
MS-MPPE-Encryption-Policy !* ANY
MS-MPPE-Send-Key !* ANY
MS-MPPE-Recv-Key !* ANY
}
update {
&outer.session-state: += &reply:
}
}
Post-Auth-Type REJECT {
attr_filter.access_reject
update outer.session-state {
&Module-Failure-Message := &request:Module-Failure-Message
}
}
}
pre-proxy {
}
post-proxy {
eap
}
} # inner-tunnel server block
# sites-enabled/server
client domain_8021x {
ipaddr = 0.0.0.0/0
secret = dontlookatme
virtual_server = schule_8021x
}
server domain_8021x {
authorize {
filter_username
preprocess
chap
mschap
digest
suffix
eap {
ok = return
}
ldap
if (&LDAP-Group[*] == "CN=role-student,OU=Groups,OU=GLOBAL,DC=lmn,DC=domain,DC=schule") {
if (&LDAP-Group[*] == "CN=staff,OU=staff,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
}
elsif (&LDAP-Group[*] == "CN=airtame,OU=Airtame,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
}
elsif (&LDAP-Group[*] == "CN=technik,OU=Technik,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
}
elsif (&LDAP-Group[*] == "CN=ipad,OU=Ipad,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
}
else {
update control {
Login-Time = 'Wk0700-1900'
}
}
}
expiration
logintime
pap
}
authenticate {
ntlm_auth
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
digest
eap
}
preacct {
preprocess
acct_unique
suffix
}
accounting {
unix
radutmp
sradutmp
exec
attr_filter.accounting_response
}
post-auth {
update {
User-Name := &session-state:User-Name
}
get_user_role
if (&session-state:User-Name == "cisco-wlan-ap") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 5
Tunnel-Type:= VLAN
Egress-VLANID += "%{expr: 0x31000000 + 10}"
Egress-VLANID += "%{expr: 0x31000000 + 11}"
Egress-VLANID += "%{expr: 0x31000000 + 12}"
Egress-VLANID += "%{expr: 0x31000000 + 24}"
Egress-VLANID += "%{expr: 0x31000000 + 31}"
Egress-VLANID += "%{expr: 0x31000000 + 33}"
}
}
else {
if (UserRole == "staff") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 13
Tunnel-Type:= VLAN
}
}
elsif (&reply:UserRole == "staff") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 13
Tunnel-Type:= VLAN
}
}
elsif (UserRole == "airtame") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 10
Tunnel-Type:= VLAN
}
}
elsif (&reply:UserRole == "airtame") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 10
Tunnel-Type:= VLAN
}
}
elsif (UserRole == "technik") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 33
Tunnel-Type:= VLAN
}
}
elsif (&reply:UserRole == "technik") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 33
Tunnel-Type:= VLAN
}
}
elsif (UserRole == "ipad") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 13
Tunnel-Type:= VLAN
}
}
elsif (&reply:UserRole == "ipad") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 13
Tunnel-Type:= VLAN
}
}
elsif (&reply:UserRole == "student") {
if (&reply:UserSophomorixRole == "staff") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 13
Tunnel-Type:= VLAN
}
}
elsif (&reply:UserSophomorixRole == "airtame") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 10
Tunnel-Type:= VLAN
}
}
elsif (&reply:UserSophomorixRole == "technik") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 33
Tunnel-Type:= VLAN
}
}
elsif (&reply:UserSophomorixRole == "ipad") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 13
Tunnel-Type:= VLAN
}
}
else {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 12
Tunnel-Type:= VLAN
}
}
}
elsif (&reply:UserRole == "teacher" || UserRole == "teacher") {
update reply {
Tunnel-Medium-Type := IEEE-802
Tunnel-Private-Group-ID:= 10
Tunnel-Type:= VLAN
}
}
}
update reply {
&UserRole !* ANY
}
if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) {
update reply {
&User-Name !* ANY
}
}
update {
&reply: += &session-state:
}
exec
remove_reply_message_if_eap
Post-Auth-Type REJECT {
attr_filter.access_reject
eap
remove_reply_message_if_eap
}
Post-Auth-Type Challenge {
}
}
post-proxy {
eap
}
session {
radutmp
}
}
#mods-enabled/eap
eap {
default_eap_type = peap
timer_expire = 60
ignore_unknown_eap_types = no
cisco_accounting_username_bug = no
max_sessions = ${max_requests}
md5 {
}
gtc {
auth_type = PAP
}
tls-config tls-eap-peap {
private_key_file = ${certdir}/privkey.pem
certificate_file = ${certdir}/fullchain.pem
dh_file = ${certdir}/dh
ca_path = ${certdir}
cipher_list = "DEFAULT@SECLEVEL=1"
cipher_server_preference = no
tls_min_version = "1.0"
tls_max_version = "1.2"
ecdh_curve = "prime256v1"
cache {
enable = no
lifetime = 12 # hours
store {
Tunnel-Private-Group-Id
}
}
verify {
}
ocsp {
enable = no
override_cert_url = yes
url = "http://127.0.0.1/ocsp/"
}
}
tls-config tls-eap-tls {
private_key_password = "dontlookat me"
private_key_file = ${certdir}/server_local.pem
certificate_file = ${certdir}/server_local.pem
ca_file = ${cadir}/ca.pem
dh_file = ${certdir}/dh
ca_path = ${cadir}
cipher_list = "ALL:!EXPORT:!eNULL:!SSLv2"
cipher_server_preference = no
tls_min_version = "1.0"
tls_max_version = "1.2"
ecdh_curve = "prime256v1"
cache {
enable = no
lifetime = 12 # hours
store {
Tunnel-Private-Group-Id
}
}
verify {
}
ocsp {
enable = no
override_cert_url = yes
url = "http://127.0.0.1/ocsp/"
}
}
tls {
tls = tls-eap-tls
virtual_server = check-eap-tls
}
ttls {
tls = tls-eap-tls
default_eap_type = md5
copy_request_to_tunnel = yes
use_tunneled_reply = no
virtual_server = "inner-tunnel"
}
peap {
tls = tls-eap-peap
default_eap_type = mschapv2
copy_request_to_tunnel = yes
use_tunneled_reply = no
virtual_server = "inner-tunnel"
}
mschapv2 {
send_error = yes
identity = "RADIUS Meine Schule"
}
fast {
tls = tls-eap-peap
cipher_list = "ALL:!EXPORT:!eNULL:!SSLv2@SECLEVEL=0"
pac_lifetime = 604800
authority_identity = "domain.schule"
pac_opaque_key = "deadbeef1234567890c0ffee123456789"
virtual_server = inner-tunnel
}
}
# mods-enabled/ldap
ldap {
server = "ldaps://10.0.0.1:636/"
identity = "CN=radius-binduser,OU=Management,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule"
password = "dontlookatme"
base_dn = "DC=lmn,DC=domain,DC=schule"
sasl {
}
x
update {
control:Password-With-Header += 'userPassword'
reply:Reply-Message := 'radiusReplyMessage'
reply:Tunnel-Type := 'radiusTunnelType'
reply:Tunnel-Medium-Type := 'radiusTunnelMediumType'
reply:Tunnel-Private-Group-ID := 'radiusTunnelPrivategroupId'
reply:UserRole := 'sophomorixRole'
reply:UserSophomorixRole := 'sophomorixAdminClass'
control: += 'radiusControlAttribute'
request: += 'radiusRequestAttribute'
reply: += 'radiusReplyAttribute'
}
user_dn = "LDAP-UserDn"
user {
base_dn = "${..base_dn}"
filter = "(&(objectclass=person)(cn=%{%{Stripped-User-Name}:-%{mschap:User-Name}}))"
sasl {
}
}
group {
base_dn = "${..base_dn}"
filter = '(objectClass=group)'
membership_filter = "(member=%{control:${..user_dn}})"
membership_attribute = 'memberOf'
}
profile {
}
client {
base_dn = "${..base_dn}"
filter = '(objectClass=radiusClient)'
template {
}
attribute {
ipaddr = 'radiusClientIdentifier'
secret = 'radiusClientSecret'
}
}
accounting {
reference = "%{tolower:type.%{Acct-Status-Type}}"
type {
start {
update {
description := "Online at %S"
}
}
interim-update {
update {
description := "Last seen at %S"
}
}
stop {
update {
description := "Offline at %S"
}
}
}
}
post-auth {
update {
description := "Authenticated at %S"
}
}
options {
chase_referrals = yes
rebind = yes
res_timeout = 10
srv_timelimit = 3
net_timeout = 1
idle = 60
probes = 3
interval = 3
ldap_debug = 0x0028
}
tls {
}
pool {
start = ${thread[pool].start_servers}
min = ${thread[pool].min_spare_servers}
max = ${thread[pool].max_servers}
spare = ${thread[pool].max_spare_servers}
uses = 0
retry_delay = 30
lifetime = 0
idle_timeout = 60
}
}
# mods-enabled/ntlm_auth
exec ntlm_auth {
wait = yes
program = "/usr/bin/ntlm_auth --allow-mschapv2 --request-nt-key --domain=lmn --require-membership-of=lmn\wifi --username=%{mschap:User-Name} --password=%{User-Password}"
}
# mods-available/mschap
mschap {
use_mppe = yes
with_ntdomain_hack = yes
ntlm_auth = "/usr/bin/ntlm_auth --allow-mschapv2 --request-nt-key --domain=lmn --require-membership-of=lmn\wifi --username=%{%{Stripped-User-Name}:-%{%{User-Name}:-None}} --challenge=%{%{mschap:Challenge}:-00} --nt-response=%{%{mschap:NT-Response}:-00}"
pool {
start = ${thread[pool].start_servers}
min = ${thread[pool].min_spare_servers}
max = ${thread[pool].max_servers}
spare = ${thread[pool].max_spare_servers}
uses = 0
retry_delay = 30
lifetime = 86400
cleanup_interval = 300
idle_timeout = 600
}
passchange {
}
}
# policy.d/group_check
get_user_role {
if (&LDAP-Group[*] == "CN=teachers,OU=Teachers,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
update reply {
UserRole := "teacher"
}
}
elsif (&LDAP-Group[*] == "CN=staff,OU=staff,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
update reply {
UserRole := "staff"
}
}
elsif (&LDAP-Group[*] == "CN=airtame,OU=Airtame,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
update reply {
UserRole := "airtame"
}
}
elsif (&LDAP-Group[*] == "CN=technik,OU=Technik,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
update reply {
UserRole := "technik"
}
}
elsif (&LDAP-Group[*] == "CN=ipad,OU=Ipad,OU=Students,OU=default-school,OU=SCHOOLS,DC=lmn,DC=domain,DC=schule") {
update reply {
UserRole := "ipad"
}
}
elsif (&LDAP-Group[*] == "CN=role-student,OU=Groups,OU=GLOBAL,DC=lmn,DC=domain,DC=schule") {
update reply {
UserRole := "student"
}
}
}
# dictionary
ATTRIBUTE UserRole 3003 string
ATTRIBUTE UserSophomorixRole 3004 string
ATTRIBUTE NetworkAccess 3005 integer