Samba 4 AD on ZFS
Introduction
This Wiki page covers installing and configuring Samba 4 as an Active Directory server on a ZFS system. It was developed based on FreeBSD 11 (amd64) installed mid July 2017.
This install was an upgrade of an older FreeBSD system running Samba 3.6 using the 'classicupgrade' script using BIND for DNS and the Samba 4.5 port.
The example domain is 'example.org' - change to match your network.
ToDo
The following is still not done
- Work out why Samba 4.6 is broken (the upgrade script failed, I didn't investigate)
- Check samba48 port which probably doesn't need the sysvol hack
Shadow copy support (this looks like it will require some small code changes - see https://bugzilla.samba.org/show_bug.cgi?id=11658)
- Authenticating users via PAM (was deemed not useful enough for the hassle).
- DHCP updating DNS (not enough DHCP used to be bothered).
Installation
Configuration
Enable NFSv4 ACLs in your ZFS volume
Setup UFS system volume
Samba's upgrade script is not smart enough (yet) to enable zfsacl automatically so it's simpler to have a POSIX ACL enabled UFS file system as sysvol.
Copy old data
1 sudo -i
2 mkdir -p /usr/local/samba.PDC/dbdir
3 cd /usr/local/samba.PDC
4 scp root@oldserver:/usr/local/etc/smb.conf smb.PDC.conf
5 scp root@oldserver:/usr/local/etc/samba/smbpasswd dbdir
6 scp root@oldserver:/usr/local/etc/samba/secrets.tdb dbdir/
7 scp root@oldserver:/usr/local/etc/samba/schannel_store.tdb dbdir/
8 scp root@oldserver:/usr/local/etc/samba/passdb.tdb dbdir/
9 scp root@oldserver:/var/spool/samba/locks/gencache_notrans.tdb dbdir/
10 scp root@oldserver:/var/spool/samba/locks/group_mapping.tdb dbdir/
11 scp root@oldserver:/var/spool/samba/locks/account_policy.tdb dbdir/
Run upgrade script
This was done iteratively - I ran the upgrade script and removed entries from the old smbpasswd file that it objected to.
Configure BIND
Generate an RNDC key by running..
rndc-confgen -a -k rndc-key -c tmp
Note the contents of "tmp" and combine with /usr/local/etc/named.conf as below..
options { // All file and path names are relative to the chroot directory, // if any, and should be fully qualified. directory "/usr/local/etc/namedb/working"; pid-file "/var/run/named/pid"; dump-file "/var/dump/named_dump.db"; statistics-file "/var/stats/named.stats"; // These zones are already covered by the empty zones listed below. // If you remove the related empty zones below, comment these lines out. disable-empty-zone "255.255.255.255.IN-ADDR.ARPA"; disable-empty-zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA"; disable-empty-zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA"; forwarders { 8.8.8.8; 4.4.4.4; }; empty-zones-enable yes; disable-empty-zone "example.org"; disable-empty-zone "3.2.1.in-addr.arpa"; tkey-gssapi-keytab "/var/db/samba4/private/dns.keytab"; }; zone "." { type slave; file "/usr/local/etc/namedb/slave/named.root"; masters { 192.0.32.132; // lax.xfr.dns.icann.org 2620:0:2d0:202::132; // lax.xfr.dns.icann.org 192.0.47.132; // iad.xfr.dns.icann.org 2620:0:2830:202::132; // iad.xfr.dns.icann.org }; notify no; }; // IPv4 ARPA zone "arpa" { type slave; file "/usr/local/etc/namedb/slave/arpa.root"; masters { 192.0.32.132; // lax.xfr.dns.icann.org 2620:0:2d0:202::132; // lax.xfr.dns.icann.org 192.0.47.132; // iad.xfr.dns.icann.org 2620:0:2830:202::132; // iad.xfr.dns.icann.org }; notify no; }; // IPv6 ARPA zone "ip6.arpa" { type slave; file "/usr/local/etc/namedb/slave/ip6.arpa.root"; masters { 192.0.32.132; // lax.xfr.dns.icann.org 2620:0:2d0:202::132; // lax.xfr.dns.icann.org 192.0.47.132; // iad.xfr.dns.icann.org 2620:0:2830:202::132; // iad.xfr.dns.icann.org }; notify no; }; // RFCs 1912, 5735 and 6303 (and BCP 32 for localhost) zone "localhost" { type master; file "/usr/local/etc/namedb/master/localhost-forward.db"; }; zone "127.in-addr.arpa" { type master; file "/usr/local/etc/namedb/master/localhost-reverse.db"; }; key "rndc-key" { algorithm hmac-md5; secret "XXXXXX"; }; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; }; include "/var/db/samba4/private/named.conf";
Where "XXXXXX" is the key material. Also update the non-empty zones to match your domain and IP range.
Create "/usr/local/etc/namedb/rndc.conf"
key "rndc-key" { algorithm hmac-md5; secret "XXXXXX"; }; options { default-key "rndc-key"; default-server 127.0.0.1; default-port 953; };
Where "XXXXXX" is the key material.
This file should be owned root:wheel with permissions 0640.
Check "/var/db/samba4/private/named.conf" and make sure only the "dlz_bind9_11.so" line is uncommented.
Configure Samba
The following configuration will create a 'users' share and a 'public' share.
# Global parameters [global] log level = all:2 netbios name = EXAMPLEHOST realm = EXAMPLE.ORG workgroup = EXAMPLE server role = active directory domain controller server services = -dns idmap_ldb:use rfc2307 = yes [netlogon] path = /var/db/samba4/sysvol/example.org/scripts read only = No [sysvol] path = /var/db/samba4/sysvol read only = No [users] comment = User home directories path = /usr/home read only = no vfs objects = zfsacl [public] comment = Public path = /public read only = no public = yes vfs objects = zfsacl
Note that AD mode is incompatible with the home directories feature, the 'users' share above is the canonical (Windows) way to do this.
Configure Kerberos
Copy the Kerberos configuration and key tab created by the classicupgrade script
sudo cp -p /var/db/samba4/private/krb5.conf /etc/ sudo cp -p /var/db/samba4/private/secrets.keytab /etc/krb5.keytab
Modify "/etc/krb5.conf" so it looks like so
[libdefaults] default_realm = EXAMPLE.ORG dns_lookup_realm = false dns_lookup_kdc = true default_ccache_name = /tmp/krb5cc_%{uid} [domain_realm] .example.org = EXAMPLE.ORG
Configure NSS
Modify "/etc/nsswitch.conf" to comment out group, group_compat, passed and passwd_compat and replace with
group: files winbind passwd: files winbind
Configure /etc/hosts
Add an entry to "/etc/hosts" which matches the hostname to to the IP, e.g.
1.2.3.4 examplehost example host.example.org
Configure rc.conf
Add this to /etc/rc.conf to start bind & Samba at boot
samba_server_enable="YES" named_enable="YES"
Start daemons
Reboot or run the following to start BIND and Samba
sudo service samba_server start sudo service named start
Testing
You should now be able to use "getent" to query Samba, eg..
[examplehost 14:38] ~ >getent group Domain\ Users EXAMPLE\domain users:x:20 [examplehost 14:38] ~ >getent group Domain\ Admins EXAMPLE\domain admins:x:0
Permissions
In order for Windows to be able to manage permissions someone has to be given the right to change permissions. This can be done like so
sudo setfacl -m g:Domain\ Admins:cC:fd:allow /public /usr/home
Useful Commands
DNS
As Samba is now managing DNS you need to get it to add/remove records. This can be done with the Windows management tools or using samba-tool, e.g.
# Get a Kerberos ticket as an admin user kinit # List all zones samba-tool dns zonelist examplehost -k yes # List all forward records samba-tool dns query examplehost -k yes example.org @ ALL # Create reverse zone (not done by default) samba-tool dns zonecreate examplehost -k yes 1.2.3.in-addr.arpa # Add A record for testpc -> 1.2.3.10 samba-tool dns add examplehost -k yes example.org testpc A 1.2.3.10 samba-tool dns add examplehost -k yes 3.2.1.in-addr.arpa 10 CNAME testpc.example.org. # Delete above records samba-tool dns delete examplehost -k yes example.org testpc A 1.2.3.10 samba-tool dns delete examplehost -k yes 3.2.1.in-addr.arpa 10 CNAME testpc.example.org.
Set permissions
Grant group "Domain Users" all permissions on /somedir and contents
sudo find /somedir -type f -print0 | sudo xargs -0 setfacl -m g:Domain\ Users:full_set::allow sudo find /somedir -type d -print0 | sudo xargs -0 setfacl -m g:Domain\ Users:full_set:fd:allow
Or for everybody (probably not wise, since it's like chmod 777/666)
sudo find /somedir -type f -print0 | sudo xargs -0 setfacl -m @everybody:full_set::allow sudo find /somedir -type d -print0 | sudo xargs -0 setfacl -m @everybody:full_set:fd:allow
Limited privilege users
Create a "dhcpuser" who is a member of "DnsAdmins" which could be used to from a DHCP server to updated DNS
samba-tool user create dhcpduser --description="Unprivileged user for TSIG-GSSAPI DNS updates via ISC DHCP server" --random-password samba-tool user setexpiry dhcpduser --noexpiry samba-tool group addmembers DnsAdmins dhcpduser samba-tool domain exportkeytab --principal=dhcpduser@example.org dhcpduser.keytab sudo cp dhcpduser.keytab /usr/local/etc/dhcpduser.keytab
Note that I have only done limited testing here. This is based on an ArchLinux Wiki page https://wiki.archlinux.org/index.php/Samba/Active_Directory_domain_controller and the package https://aur.archlinux.org/packages/samba-dhcpd-update/
Edit user profile information
sudo ldbedit -H /var/db/samba4/private/sam.ldb 'sAMAccountName=testuser'
Time synchronisation
When a Windows PC is joined to a domain the 'Internet Time' tab will disappear and it will instead only synchronise to the DC. For this to work NTPd needs to be configured to sign messages (with Samba's help).
Edit /etc/ntp.conf and add/modify the following..
ntpsigndsocket /var/run/samba4/ntp_signd/ restrict -4 default kod notrap nomodify nopeer noquery mssntp restrict -6 default kod notrap nomodify nopeer noquery mssntp
And restart NTPd (eg sudo service ntpd restart)
Time synchronisation on a client Windows PC can be checked by running the following..
w32tm /stripchart /computer:time.windows.com /dataonly
Which will give output like so
C:\Users\darius>w32tm /stripchart /computer:time.windows.com /dataonly Tracking time.windows.com [52.163.118.68:123]. The current time is 10/01/2018 9:49:52 AM. 09:49:52, +00.0064586s 09:49:55, -00.0050746s 09:49:57, -00.0034439s 09:49:59, -00.0038588s 09:50:01, +00.1017965s 09:50:04, -00.0029371s 09:50:06, -00.0055241s 09:50:08, -00.0004811s 09:50:10, -00.0039628s ^C