Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save exabrial/368c279aad65cefd8c5f to your computer and use it in GitHub Desktop.
Save exabrial/368c279aad65cefd8c5f to your computer and use it in GitHub Desktop.
FreeRadius, PEAP-MSCHAP, Samba, Ubuntu 14.04, ActiveDirectory, LDAP

FreeRadius, PEAP-MSCHAP, Samba, Ubuntu 14.04, ActiveDirectory, LDAP

Why This guide

Directions

Install Sernet Samba

  • I tried using Samba 4.1.6-Ubuntu and the box would not stay "joined" to active directory
  • Run sudo apt-get update && sudo apt-get -y install apt-transport-https
  • Add Samba 4.1 from here to your local /etc/apt/sources.list https://portal.enterprisesamba.com/
  • Now run sudo apt-get update && sudo apt-get install -y sernet-samba sernet-samba-winbind sernet-samba-ad

Install all the other components

  • sudo apt-get -y install freeradius freeradius-ldap haveged

Adjust hostname if necessary

  • My server's name is freeradius, which is less than 15 characters and a valid windows server name.
  • Your server's default domain MUST be in the AD.x.x.com domain.

/etc/hosts should have the following:

127.0.1.1 freeradius.AD.x.x.com freeradius

Install configuration files for samba

/etc/samba/smb.conf should something like the following:

[global]
	workgroup=AD
	security=ads
	realm=AD.x.x.COM
	domain master=no
	local master=no
	preferred master=no
	load printers=no
	printing=bsd
	printcap name=/dev/null
	disable spoolss=yes
	idmap backend=tdb
	idmap uid=10000-99999
	idmap gid=10000-99999
	idmap config AD:backend=rid
	idmap config AD:range=10000-9999
	winbind enum users=yes
	winbind enum groups=yes
	winbind use default domain=yes 
	winbind nested groups=yes
	winbind refresh tickets=yes
	winbind offline logon=yes
	template shell=/bin/false
	client use spnego=yes
	client ntlmv2 auth=yes
	encrypt passwords=yes
	restrict anonymous=2
	log file=/var/log/samba/samba.log
	log level=2
	dcerpc endpoint servers=remote

Join domain

Run the following, substituing your AD domain

sudo kinit administrator@AD.x.x.COM
sudo net ads join -k
sudo service nmbd restart && sudo service smbd restart && sudo service winbind restart

Test! All of these MUST work before you continue!

sudo wbinfo -t
sudo wbinfo -u
sudo wbinfo -g
sudo wbinfo -i administrator
sudo wbinfo -a administrator

Generate Valid certificates

Use a CA manager like XCA (http://xca.sourceforge.net/) to manage your certificates. Distribute your CA's public cert via ActiveDirectory group policy.

Create a Certificate Authority, an intermediate cert, and finally a cert who's CN matches your wireless network name. Use the template of HTTPS server on the final certificate. It should ALL and ONLY these extensions, including the CRL (even if it doesn't exist).

X509v3 Basic Constraints critical:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, EAP over Lan
X509v3 CRL Distribution Points:

Full Name:
URI:https://crl/list

Netscape Cert Type:
SSL Server
Netscape Comment:
xca certificate

Remove stock certs certs

  • You will have to su - root to do the next few parts of the guide.
  • All certs and keys are PEM encoded ASCII

Run the following:

rm /etc/freeradius/certs/server*
rm /etc/freeradius/certs/ca*

Install your certs

Create a CA bundle by concatentaing your intermediate certificate on top of your root certifacte into a file:

<INTERMEDIATE CERT>
<ROOT CERT>
  • Store this file here /etc/freeradius/certs/ca.pem
  • Export the server's private key and save it to /etc/freeradius/certs/server.key
  • Export the server's public cert and save it to /etc/freeradius/certs/server.pem
  • Don't remove the generated /etc/freeradius/certs/dh file

Weed through the documentation on freeradius. Go ahead. I'll wait.

  • It's actually very well documented! And there are a ton of examples in Ubuntu's default installation

Done? Ok, use the configuration files here now

clients.conf
  • The subnet here is the subnet of your wireless controller and accees points, not the subnet of the wireless client stations

/etc/freeradius/clients.conf

client 192.168.1.0/24 {
	secret=RANDOM_PHRASE
	shortname=1192.168.1.0/24 Secret Subnet
}
ldap
  • Even though we use winbind and mschap, in order to to do group authorization, you need to have freeradius perform and LDAP search
  • Create a freeradius user in AD and use a RANDOM_PASSWORD that never expires and can't be changed
  • Deletegate control of your ou=Users so the freeradius user can read all attributes about Users
  • I created a ou=Networks and a group called wireless_corp in AD to keep things organized. Substitue below appropriately

/etc/freeradius/modules/ldap

ldap {
	server = "AD_SERVER.AD.x.x.com"
	identity = "CN=freeradius,CN=Users,DC=AD,DC=x,DC=x,DC=com"
	password = "RANDOM_PASSWORD"
	basedn = "cn=Users,dc=AD,dc=x,dc=x,dc=com"
	base_filter = "(&(objectcategory=person)(objectclass=user))"
	filter = "(&(sAMAccountName=%{Stripped-User-Name:-%{User-Name}})(memberOf:1.2.840.113556.1.4.1941:=CN=wireless_corp,OU=Networks,DC=AD,DC=x,DC=x,DC=com))"
	ldap_connections_number = 5
	timeout = 4
	timelimit = 3
	net_timeout = 1
	dictionary_mapping = ${confdir}/ldap.attrmap
	keepalive {
		idle = 60
		probes = 3
		interval = 3
	}
}
mschap

/etc/freeradius/mschap

mschap {
	use_mppe = yes
	require_encryption = yes
	require_strong = yes
	with_ntdomain_hack = yes 
	ntlm_auth = "/usr/bin/ntlm_auth --request-nt-key --username=%{mschap:User-Name:-None} --domain=AD.x.x.COM --challenge=%{mschap:Challenge:-00} --nt-response=%{mschap:NT-Response:-00}"
}
eap.conf

/etc/freeradius/eap.conf

eap {
	default_eap_type = peap 
	timer_expire     = 60
	ignore_unknown_eap_types = no
	cisco_accounting_username_bug = no
	max_sessions = 4096

	tls {
		certdir = ${confdir}/certs
		cadir = ${confdir}/certs
		private_key_file = ${certdir}/server.key
		certificate_file = ${certdir}/server.pem
		CA_file = ${cadir}/ca.pem
		dh_file = ${certdir}/dh
		random_file = /dev/urandom
		CA_path = ${cadir}
		cipher_list = "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:ECDH+AES128:!aNULL:!MD5"
		make_cert_command = "${certdir}/bootstrap"
		ecdh_curve = "prime256v1"
	}

	peap {
		default_eap_type = mschapv2
		copy_request_to_tunnel = no
		use_tunneled_reply = no
		virtual_server = "inner-tunnel"
	}

	mschapv2 {
	}
}

default

/etc/freeradius/sites-enabled/default

authorize {
	preprocess
	auth_log
	suffix
	eap {
		ok = return
	}
	expiration
	logintime
}

authenticate {
	Auth-Type MS-CHAP {
		mschap
	}
	eap
}

session {
	radutmp
}

post-auth {
	Post-Auth-Type REJECT {
		attr_filter.access_reject
	}
}

inner-tunnel

/etc/freeradius/sites-enabled/inner-tunnel

server inner-tunnel {
	authorize {
		mschap
		suffix
		update control {
			Proxy-To-Realm := LOCAL 
		}
		eap {
			ok = return
		}
		ldap
		expiration
		logintime
	}

	authenticate {
		Auth-Type MS-CHAP {
			mschap
		}
		eap
	}

	session {
		radutmp
	}

	post-auth {
		Post-Auth-Type REJECT {
			attr_filter.access_reject
		}
	}
}

Let freeradius access samba stuff

  • freeradius user needs to run the ntlm_auth program, so it's shared secret files have to be available to freerad
sudo service freeradius stop
sudo usermod -a -G winbindd_priv freerad
sudo chown root:winbindd_priv /var/lib/samba/winbindd_privileged/
sudo service freeradius restart

Hold onto your butts

It doesn't work

Good luck!

@schorschii
Copy link

Thanks for this guide! In order to make the LDAP group check work, I replaced ldap in the inner-tunnel config file with:
ldap { notfound=reject }
and moved it on top of
eap { ok = return }
Otherwise, users which are not in the specified group were also accepted in my case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment