An Unofficial HOWTO build a FreeBSD 5.x
Fileserver using Samba/Active Directory Services
by Michael Brown
mikal at mikro-net dot com
http://oslabs.mikro-net.com/
version 0.93 - 02/14/2004
this is a work in progress
Updates by Graham Dunn - March 30, 2005
First of all:
Links:
Introduction:
This document is meant as a guide to build a fileserver that runs
on FreeBSD 5.3-RELEASE which operates seamlessly in a Microsoft
Active Directory Environment, whether it be Windows 2000 or 2003.
Windows domain members (clients) can browse shares on this server
as if it were a windows server. Permissions can be granted on a
domain user/group basis through Samba's winbind mapping AD
sccounts to FreeBSD 5.3's built in POSIX ACLs (using UFS2). All
of this is possible from Samba's abilty to use Kerberos/SASL and
LDAP to authenticate as if it were a native Windows machine. We
will let the OS take care of the depencies for the samba3
package. Other services beside SMB/CIFS can be extended via PAM
(ssh,ftp,printing,etc) through single-sign on through AD, but
that would be beyond the scope of this document (although not at
all difficult- see http://www.bzerk.nl/documents/ntdomauth/
for an ftp example using pam_winbind). For more in-depth research
into Samba and its functionality, please see http://us1.samba.org/samba/docs,
an Official Samba Documentation link page. Much of the
information in this document is in fact indebted to the links on
this page.
For information on mapping principals from alternative kerberos
realms to AD principals (i.e. with MIT or Heimdal KDC's) see
http://www.microsoft.com/windows2000/techinfo/planning/security/kerbsteps.asp.
Caveat:
This document assumes an intermediate level of familiarity with
basic networking principles, FreeBSD and unix-like systems in
general. It also assumes you have a functional Windows 2000 or
2003 Active Directory Domain Controller in your network and you
have an account with the administrative right to add machine
accounts to the domain. You will need this account information to
authenticate to Active Directory. We will not be using Samba's
name-services daemon (nmbd) in this scenario, as we are striving
to push all naming contexts through DNS.
I have added some comments to the config files, please read
them. These comments are to explain some of the why/how of
features within that particular file. I hope it may help in some
way. You will replace the following information in the config
files (as described in the howto) with that which is applicable
to your realm/domain:
fbsdad is our FreeBSD box's hostname
example.com is your AD domain FQDN/kerberos realm, which
would make our box fbsdad.example.com
dc.example.com is the FQDN of your AD Domain
Controller
192.168.129.50(/24) is the IP address of
dc.example.com
admin is your account login
cn=admin,cn=users,dc=example,dc=com is the ldap dn for
your admin AD account
pa55w0rd is the AD password for the admin
account
*EOF* indicates the end of that particular config file
This was done with FreeBSD 5.3-RELEASE and works against Win2k
'Native Mode'/2k3 'Windows Server 2003 Functional Level'.
This is also assuming standard FreeBSD 5.3 install, with samba as
a package.
IFS2 ACLS
FreeBSD-POSIX ACLs now exist (since FreeBSD 5.1-RELEASE) for
UFS2 enabling fine grained permission sets. To activate the ACLs
you must edit /etc/fstab to mount the filesystems correctly. You
must add the option 'acls' to the filesystems you wish to
activate. Example:
cat /etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/ad0s1b none swap sw 0 0
/dev/ad0s1a / ufs rw,acls 1 1
/dev/ad0s1h /exp ufs rw,acls 2 2
/dev/ad0s1g /home ufs rw,acls 2 2
/dev/ad0s1f /tmp ufs rw,acls 2 2
/dev/ad0s1d /usr ufs rw,acls 2 2
/dev/ad0s1e /var ufs rw,acls 2 2
/dev/acd0 /cdrom cd9660 ro,noauto 0 0
*EOF*
Active Directory's (IMHO) most secure form eschews NetBIOS and
places all name service requests within DNS. To begin, edit your
/etc/resolv.conf file so that you use your AD domain controller
as a nameserver, preferably the primary nameserver; also add the
domain name as at least one of the search domains:
cat /etc/resolv.conf
search example.com
domain example.com
#add other search domains here
#This is the AD dc
nameserver 192.0.34.43
#Add any other dns servers here
We're going to be using the ports system to get all of the
required install packages.
Kerberos
FreeBSD comes with Heimdal 0.6.1 (kerberos) installed under
/usr, which we will be using here.
Create /etc/krb5.conf:
cat /etc/krb5.conf
#/etc/krb5.conf
#where you want your logs
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
#Your AD domain FQDN (must be uppercase)
[libdefaults]
default_realm = EXAMPLE.COM
# AD domain, DC FQDNs
[realms]
EXAMPLE.COM = {
kdc
default_domain = example.com
admin_server = dc.example.com
}
#Translating all possibles to EXAMPLE.COM
[domain_realm]
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM
.EXAMPLE.COM = EXAMPLE.COM
#This is used if you have alternative KDC's in you realm (not
windows)
#that you are mapping trust accounts to in the windows domain
#see
http://www.microsoft.com/windows2000/techinfo/planning/security/kerbsteps.asp
#[kdc]
#profile = /home/krb5kdc/kdc.conf
#self-explanatory
[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}
*EOF*
Since we are using Kerberos auth, at this point you must
insure that your box's system clock is within 600 seconds (5
minutes) of your domain controller's clock.
So we need a ntp daemon to synchronize our system clock against
the DC's time service. Please make sure your windomain ntp
services checks against a valid time server! We will obtain
this from ports:
cd /usr/ports/net/ntp
make install clean
Create necessary config files (/etc/ntp.conf,
/etc/ntp.drift):
cat /etc/ntp.conf
# /etc/ntp.conf
# This is your AD DC - we will synchronize against it's time
service
server dc.example.com prefer
driftfile /etc/ntp.drift
*EOF*
touch /etc/ntp.drift
Launch the daemon:
/usr/local/bin/ntpd -c /etc/ntp.conf
You can automate this to run at system start, of
course.
The ntp package includes a client tool, ntpdc. We will use this
to check our connection; type 'ntpdc' and at the prompt type
'peers' (Type 'help' at the prompt to see available commands -
man ntpdc for more info):
ntpdc
ntpdc>peers
remote local st poll reach delay offset disp
=======================================================================
*dc.example.com 192.168.12.18 3 1024 37 0.00049 -0.021527 0.46245
ntpdc>
You should see something similar to the above.
A quick and dirty alternative workaround is to get the DC's clock
time manually and set the box to it:
Stop the ntpd deamon (if running), and type ntpdate
dc.example.com
Test Krb5 install against active directory KDC:
/usr/local/bin/kinit Administrator
password for Administrator@EXAMPLE.COM:
p455w0rd *Enter your domain admin password*
List current kerberos tickets with '/usr/local/bin/klist'
command:
/usr/local/bin/klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: admin@EXAMPLE.COM
Valid starting Expires Service principal
02/06/04 21:54:40 02/07/04 07:54:40
krbtgt/EXAMPLE.COM@EXAMPLE.COM
renew until 02/07/04 21:54:40
This means you have a valid ticket granting ticket (tgt)
from MS AD! Half of the hard part is over. :)
nss_ldap
Install nss_ldap from ports
cd /usr/ports/net/nss_ldap
make install
Symlink the library to needed locations:
ln -s /usr/local/lib/nss_ldap.so.1 /usr/lib/
ln -s /usr/local/lib/nss_ldap.so.1 /usr/lib/nss_ldap.so.2
Enterprise Root CA
This example assumes you have the Enterprise Root CA
certificate from MS Certificate Services (this needs to be
installed somewhere in the domain so DC's can be connected to via
LDAP over SSL). For a guide on how to obtain this certificate
click *here*.
create ldap.conf:
Configure OpenLDAP
cat /usr/local/etc/openldap/ldap.conf
# Active Directory server. Define multiple servers by
delimiting
# them with spaces.
host dc.example.com
# Search base
base dc=example,dc=com
# LDAP version 3
ldap_version 3
#URI for AD server
#Switch these if not using LDAP/SSL or do not have the MS Cert
Svcs installed
#in the domain
#URI ldap://dc.example.com
URI ldaps://dc.example.com
# Bind DN (this might not be needed at all for anon LDAP
connections(win2k)).
# This should be the DN of the AD account you have
# that can create machine accounts
binddn cn=ldapadmin,cn=users,dc=example,dc=com
bindpw p455w0rd
# Use port 636 for SSL
#port 636 (not really needed when ssl=on it is port 636 by
default)
# Search scope
scope sub
# User ID attr for AD
pam_login_attribute sAMAccountName
#MD5 passwd hash
pam_password md5
# Break of the connection after one hour idle time
idle_timelimit 3600
# This is mapping made possible by nss_ldap
# Bases for the searches. These should be the OU's
# you create the user accounts in.
# Here we reference the standard default AD user container
# Please change to the container your users reside in
nss_base_passwd cn=Users,dc=example,dc=com?one
nss_base_group cn=Users,dc=example,dc=com?one
# The msSFU mappings reference Microsoft's Services for Unix
# Which you may uncomment if you have this installed on your
DC
# *Schema mappings for Active Directory*
nss_map_objectclass posixAccount User
nss_map_objectclass shadowAccount User
nss_map_attribute uid sAMAccountName
#nss_map_attribute userPassword msSFUPassword
#nss_map_attribute homeDirectory msSFUHomeDirectory
nss_map_attribute uniqueMember member
nss_map_attribute cn sAMAccountName
#nss_map_attribute homeDirectory msSFUHomeDirectory
nss_map_objectclass posixGroup Group
pam_login_attribute sAMAccountName
pam_filter objectclass=User
pam_password ad
# SSL is enabled - Comment this line if no MS Enterprise Root CA
Cert
ssl on
# OpenLDAP SSL options
# Require and verify server certificate (yes/no)
# Default is "no" Uncomment this is you have a client cert (you
won't MS LDAP
# over SSL does not auth client cert, just a valid AD
password)
#tls_checkpeer yes
# CA certificates for server certificate verification
# At least one of these are required if tls_checkpeer is
"yes"
# This again refers to the MS Root CA Cert - comment it if
none
TLS_CACERT /etc/ca/ldapca.pem
# SSL cipher suite
# See man ciphers for syntax
# comment this if no cert
tls_ciphers TLSv1
# Disable SASL security layers. This is needed for AD.
sasl_secprops maxssf=0
# Override the default Kerberos ticket cache location.
krb5_ccname FILE:/tmp/krb5cc_0
*EOF*
Test out your openldap installation with ldapsearch:
/usr/bin/ldapsearch -Y GSSAPI
SASL/GSSAPI authentication started
SASL username: admin@EXAMPLE.COM
SASL SSF: 0
# extended LDIF
#
# LDAPv3
# base <> with scope sub
# filter: (objectclass=*)
# requesting: ALL
#
etc,etc.....
It should print out lines upon lines of AD info for you, as you
are
authenticating to the AD tree through SASL from the former ticket
you were
granted from the dc. Now check your ticket list:
/usr/local/bin/klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: admin@EXAMPLE.COM
Valid starting Expires Service principal
02/06/04 21:54:40 02/07/04 07:54:40
krbtgt/EXAMPLE.COM@EXAMPLE.COM
renew until 02/07/04 21:54:40
02/06/04 21:57:28 02/07/04 07:54:40
ldap/dc.example.com@EXAMPLE.COM
renew until 02/07/04 21:54:40
Good. You will see these tickets if an ldapsearch command
was issued without
the '-x' param.
Installing Samba
We are almost ready to install samba, we just need to prepare the
environment.
Edit /etc/pam.d/login
cat /etc/pam.d/login
#
# $FreeBSD: src/etc/pam.d/login,v 1.16 2003/06/14 12:35:05 des
Exp $
#
# PAM configuration for the "login" service
#
# auth
auth required pam_nologin.so no_warn
auth sufficient pam_self.so no_warn
auth include system
auth sufficient /usr/lib/pam_winbind.so
# account
account requisite pam_securetty.so
account include system
account sufficient /usr/lib/pam_winbind.so
# session
session include system
# password
password include system
*EOF*
Create /etc/nsswitch.conf
cat /etc/nsswitch.conf
passwd: files winbind
group: files winbind
*EOF*
Install samba from package pkg_add -r samba3
Create smb.conf - this is a hardened example that assumes you
have the Root CA certificate from MS Cert Services (this needs to
be installed somewhere in the domain so DC's can be connected to
via LDAP over SSL).
cat /usr/samba/lib/smb.conf
# Global parameters
[global]
workgroup = WORKGROUP
realm = EXAMPLE.COM
server string = Samba File Server %v
security = ADS
client schannel = Yes
server schannel = Yes
passdb backend = ldapsam:ldap://dc.example.com
socket options = TCP_NODELAY
dns proxy = No
ldap admin dn = cn=Administrator,cn=users,DC=example,DC=com
ldap suffix = DC=example,DC=com
idmap backend = idmap_rid:WORKGROUP=10000-20000
allow trusted domains = no
idmap uid = 10000-20000
idmap gid = 10000-20000
winbind separator = .
winbind enum users = No
winbind enum groups = No
winbind use default domain = Yes
force create mode = 0664
force directory mode = 0775
dos filemode = Yes
*EOF*
Create secrets.tdb for ldap connect to AD (specify admin
password)
/usr/local/bin/smbpasswd -w p455w0rd
You should still have a valid ticket from the domain
controller, so join the server to the domain:
/usr/local/bin/net ads join
Using short domain name -- EXAMPLE
Joined 'FBSDAD' to realm 'EXAMPLE.COM'
This shows a successful join.
Test it:
/usr/local/bin/net ads testjoin
Join is OK.
Check your ticket list; it should look similar to
this:
/usr/local/bin/klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: admin@EXAMPLE.COM
Valid starting Expires Service principal
02/07/04 21:33:03 02/08/04 07:33:01
krbtgt/EXAMPLE.COM@EXAMPLE.COM
renew until 02/08/04 21:33:03
02/07/04 21:33:02 02/08/04 07:33:01
ldap/dc.example.com@EXAMPLE.COM
renew until 02/08/04 21:54:40
02/07/04 21:33:09 02/08/04 07:33:01 dc$@EXAMPLE.COM
renew until 02/08/04 21:33:03
02/07/04 21:33:09 02/08/04 07:35:09
kadmin/changepw@EXAMPLE.COM
renew until 02/08/04 21:35:09
This reflects all the AD kerberos tickets that have beem
gained thus far.
Start the server /usr/local/etc/rc.d/samba start
Now check to see if winbind is grabbing the Windows
domain accounts:
/usr/local/bin/wbinfo -u
administrator
admin
mary
etc.....
/usr/local/bin/wbinfo -g
Domain Users
Domain Admins
Enterprise Admins
etc......
Check /var/log/samba.log (or wherever you are logging samba) for
errors.
The finish line is within reach, but first we must explore
FreeBSD's ACL interface.
There are two main commands for our needs: setfacl and
getfacl. For greater detail man getfacl or man
setfacl. Now that we have the Samba daemons running, we can
connect to the DC and extract account information that will be
added to this box's current databases.
Use the 'pw' command, which will, if winbind is working properly,
populate the db. We're using
idmap_rid, which just uses the windows SID to set the uid and
gid. This keeps your userid consistent across machines.
pw usershow 1001
EXAMPLE\administrator:*:1001:1001::0:0:administrator:/home/EXAMPLE/administrator:/usr/local/bin/bash
pw usershow 1002
EXAMPLE\admin
:*:1002:1001::0:0:admin:/home/EXAMPLE/admin:/usr/local/bin/bash
pw groupshow EXAMPLE\\Domain\ Admins
EXAMPLE\Domain
Admins:*:1002:EXAMPLE\administrator,EXAMPLE\admin,EXAMPLE\mary
etc....
Our shared directory /home/share, needs to be accessible by your
domain account:
setfacl -m u:1002:rwx /home/share
Check acls on that directory:
getfacl /home/share
#file:/home/share
#owner:0
#group:0
user::rwx
user:EXAMPLE\admin:rwx
group::r-x
mask::rwx
other::r-x
Ok.... So far so good. Let's connect with Samba's smbclient
(again, using our kerberos ticket, thus the '-k' option) to a
share on the AD domain controller, let's assume the share UNC
path is '\\dc.example.com\usershare':
/usr/samba/bin/smbclient -k
//dc.example.com/usershare
OS=[Windows Server 2003 3790] Server=[Windows Server 2003
5.2]
smb: \>
Let's connect to ourselves (our Samba share), but while
authenticating to the DC (via our kerberos tgt):
smbclient -k //fbsdad/share
OS=[Unix] Server=[Samba 3.0.x]
smb: \>
Now for the final test - in your network, there is certainly a
winstation!(2000/XP)
Navigate to it and login as your admin account.
Open an explorer window and connect to your freebsd box using the
UNC name: \\fbsdad
Right click on the share folder and select 'properties'.
Select the 'security' tab.
*click on images to enlarge*
Is EXAMPLE\admin listed? GOOD! Your AD acls are being properly
mapped to your local POSIX acls. Note that you cannot change ACLs
via windows unless you are the file's owner or root.
Troubleshooting
Check the time on your workstations if they're having problems
connecting to the share. They need to be within 5 minutes of the
server, or their Kerberos ticket will be rejected.
Copyright (c) 2004 Michael Brown