= 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 == {{{#!highlight hs cd /usr/ports/net/samba45 sudo make install # Select BIND911 during the samba45 config phase # Select GSSAPI_HEIMDAL during the bind911 config phase }}} == Configuration == === Enable NFSv4 ACLs in your ZFS volume === {{{#!highlight sh sudo zfs set aclmode=passthrough zroot sudo zfs set aclinherit=passthrough zroot }}} === 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. {{{#!highlight sh sudo zfs create -V 2G zroot/samba4sysvol sudo newfs /dev/zvol/zroot/samba4sysvol # Add to /etc/fstab sudo sh -c 'cat >>/etc/fstab' <<EOF /dev/zvol/zroot/samba4sysvol /var/db/samba4/sysvol ufs rw,acls 0 2 EOF sudo mkdir -p /var/db/samba4/sysvol sudo mount /var/db/samba4/sysvol }}} === Copy old data === {{{#!highlight sh sudo -i mkdir -p /usr/local/samba.PDC/dbdir cd /usr/local/samba.PDC scp root@oldserver:/usr/local/etc/smb.conf smb.PDC.conf scp root@oldserver:/usr/local/etc/samba/smbpasswd dbdir scp root@oldserver:/usr/local/etc/samba/secrets.tdb dbdir/ scp root@oldserver:/usr/local/etc/samba/schannel_store.tdb dbdir/ scp root@oldserver:/usr/local/etc/samba/passdb.tdb dbdir/ scp root@oldserver:/var/spool/samba/locks/gencache_notrans.tdb dbdir/ scp root@oldserver:/var/spool/samba/locks/group_mapping.tdb dbdir/ 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. {{{#!highlight sh vi dbdir/smbpasswd # Remove all cruft (old entries, conflicts, etc that the upgrade script complains about) sudo samba-tool domain classicupgrade --dbdir=/usr/local/samba.PDC/dbdir/ --realm=example.org --dns-backend=BIND9_DLZ /usr/local/samba.PDC/smb.PDC.conf }}} === 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 {{{#!highligh sh 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 }}} ---- CategoryHowTo CategoryZfs