https://cromwell-intl.com/open-source/samba-active-directory/freebsd-raspberry-pi.html Raspberry Pi running Active Directory, using Samba on FreeBSD. Installing FreeBSD on a Raspberry Pi [INS::INS] FreeBSD on the Raspberry Pi We're building an Active Directory server from Samba running on FreeBSD, free server software on a free operating system. We have set up the needed DNS infrastructure on an existing BIND master (or primary) DNS server. Our next step is to put together a system that we will make a slave (or secondary) DNS server, an initial step in building a Samba-based Active Directory server. We will do this with FreeBSD running on a Raspberry Pi. We must take a few extra steps in this stage because of Samba's requirements for file system security. That requirement for POSIX Access Control Lists along with this admittedly uncommon combination of operating system and hardware means that I will have to modify a file system. Jump back to the start for an overview of the project. How to install FreeBSD on a Raspberry Pi Jump to the next step if you aren't using FreeBSD I initially used a Raspberry Pi 1 Model B+ for this project. It has a Broadcom BCM2835 SoC or System on Chip, which includes a 700 MHz ARM1176JZF-S processor, 512 MB of RAM, and a VideoCore IV GPU. The CPU performance is about like a 300 MHz Pentium II of 1997-1999, so bear in mind that this is just for initial testing and experimentation. Do not try to run your enterprise on a Raspberry Pi Model B+. A Raspberry Pi 3, by comparison, has a 4-core CPU with a faster clock, for about 10 times the CPU performance. It would get the Samba suite of services running faster. We will see in a later step that there are something like 13 samba processes, 3 smbd processes, and 2 winbind processes running simultaneously. More cores would definitely help. Still, don't run the entire enterprise on one Raspberry Pi. They only cost US$ 30-35. At least get several and set up replication, load balancing, and failover. (But seriously, you probably don't want to deploy this.) [INS::INS] Both the Raspberry Pi 1 B+ and the model 3 have 4 USB 2.0 ports, a 100 Mbps Ethernet port, and HDMI video and audio output. You power it from something like a smart phone charger, ideally one that provides more current than the usual 1000 mA. I later moved the project to a 4-core Raspberry Pi 3. That provides more CPU cores for all the server processes. Raspberry Pi running FreeBSD. Raspberry Pi running FreeBSD. A single-core Raspberry Pi Model B+. You can download FreeBSD images from raspbsd.org or from freebsd.org. There is also a page about FreeBSD on the Raspberry Pi at FreeBSD.org , although that page seems to be updated much less frequently. [INS::INS] I'm doing this on Linux. If you're writing the image on a BSD system with one disk /dev/sd0*, the microSD card will appear as something like /dev/sd1i and the device inventory will not change. On either Linux or BSD, look at the kernel ring buffer with: dmesg | tail and see what just appeared after you plug in the microSD card. I downloaded the image, uncompressed it, and wrote it onto a memory card with dd. Be very careful to select the correct device! I ran df first, and if I were using LVM I would have run pvscan, all of that to inventory all the disks holding my data. Then get a listing of all device files /dev/sd*. Now plug in the USB device with the SD memory card and see what was added. As I have several disks in my system, /dev/sda through sdf, I saw that the two new devices were sdg and sdg1. This is because the card has an IBM MBR partition table defining one partition spanning the device, and a VFAT file system in that partition. Write the image onto the entire device, being careful to choose the correct target location. Change "sdX" as appropriate in the following. I used sdg but don't destroy your data by overwriting the wrong device. # dd if=FreeBSD-*-RPI-*.img of=/dev/sdX bs=10M I connected an Ethernet cable and the power supply, and waited for it to boot up. I saw it get an IP address from my DHCP server. I connected in over SSH as user raspberry with password raspberry for the image from raspbsd.org. From there I could run su to become root without a password. Here's the resulting file system. It resizes the root partition to fill the device at first boot. My "disk" is a 32 GB microSD card. $ df -hT Filesystem Type Size Used Avail Capacity Mounted on /dev/mmcsd0s2a ufs 29G 1.8G 25G 7% / devfs devfs 1.0K 1.0K 0B 100% /dev /dev/mmcsd0s1 msdosfs 17M 4.1M 13M 24% /boot/msdos /dev/md0 ufs 29M 24K 26M 0% /tmp /dev/md1 ufs 14M 56K 13M 0% /var/log /dev/md2 ufs 4.4M 8.0K 4.0M 0% /var/tmp [INS::INS] Setting up my user account I created a user account for myself with the same UID/GID as on my other systems, and copied .vimrc, .cshrc, and .ssh/ into place. I also added myself to the wheel group. Modifying /etc/rc.conf My main Linux system has one interface on the interior network, with hostname router resolving to both IPv4 and IPv6 addresses. It runs the RADVD IPv6 Router Advertisement Daemon, and forwards both IPv4 and IPv6 to and from the Internet on another interface connected to a cable modem. It advertises a fc00::/7 prefix internally as per RFC 4193. The FreeBSD /etc/rc.conf file originally contained these lines (along with several others): hostname="raspberry-pi" ifconfig_ue0="DHCP" #ntpd_enable="YES" syslogd_enable="NO" I replaced those lines with the following to customize the hostname and networking. ##ORIGINAL hostname="raspberry-pi" hostname="freebsd" ##ORIGINAL ifconfig_ue0="DHCP" ifconfig_ue0="inet 10.1.1.235/24" defaultrouter="router.example.com" ipv6_prefix_ue0="fc00:0:0:0" ipv6_defaultrouter="router.example.com" ##ORIGINAL #ntpd_enable="YES" ntpd_enable="YES" ##ORIGINAL syslogd_enable="NO" syslogd_enable="yes" I restarted networking with the /etc/netstart script and found that things have worked: $ ifconfig lo0: flags=8049 metric 0 mtu 16384 options=600003 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 inet 127.0.0.1 netmask 0xff000000 groups: lo nd6 options=21 ue0: flags=8843 metric 0 mtu 1500 options=80009 ether b8:27:eb:41:b9:ae inet 10.1.1.235 netmask 0xffffff00 broadcast 10.1.1.255 inet6 fe80::ba27:ebff:fe41:b9ae%ue0 prefixlen 64 scopeid 0x2 inet6 fc00::ba27:ebff:fe41:b9ae prefixlen 64 media: Ethernet autoselect (100baseTX ) status: active nd6 options=21 $ netstat -r Routing tables Internet: Destination Gateway Flags Netif Expire default router.example.com UGS ue0 10.1.1.0/24 link#2 U ue0 freebsd.example.com link#2 UHS lo0 localhost link#1 UH lo0 Internet6: Destination Gateway Flags Netif Expire ::/96 localhost UGRS lo0 default router.example.com UGS ue0 localhost link#1 UH lo0 ::ffff:0.0.0.0/96 localhost UGRS lo0 fc00::/64 link#2 U ue0 fc00::ba27:ebff:fe link#2 UHS lo0 fe80::/10 localhost UGRS lo0 fe80::%lo0/64 link#1 U lo0 fe80::1%lo0 link#1 UHS lo0 fe80::%ue0/64 link#2 U ue0 fe80::ba27:ebff:fe link#2 UHS lo0 ff02::/16 localhost UGRS lo0 $ traceroute www.google.com 1 router.example.com (10.1.1.100) 1.703 ms 1.499 ms 1.422 ms 2 96.120.112.89 (96.120.112.89) 17.280 ms 9.576 ms 10.053 ms 3 68.85.180.213 (68.85.180.213) 9.543 ms 9.771 ms 9.768 ms 4 68.86.184.189 (68.86.184.189) 10.917 ms 11.047 ms 11.122 ms 5 68.86.197.49 (68.86.197.49) 22.263 ms 21.605 ms 21.943 ms 6 be-33491-cr01.chicago.il.ibone.comcast.net (68.86.92.33) 23.310 ms 23.166 ms 22.689 ms 7 be-10506-cr02.350ecermak.il.ibone.comcast.net (68.86.86.229) 25.958 ms 27.498 ms 27.028 ms [... several hops deleted ...] 15 209.85.250.237 (209.85.250.237) 46.348 ms 47.041 ms 46.873 ms 16 den03s09-in-f4.1e100.net (216.58.217.4) 46.300 ms 46.433 ms 46.700 ms $ traceroute6 www.google.com 1 router.example.com 2.055 ms 1.903 ms 1.797 ms 2 2001:558:600d:16::1 10.707 ms 10.560 ms 11.185 ms 3 2001:558:302:191::1 9.734 ms 10.111 ms 9.955 ms 4 2001:558:320:9a::2 9.845 ms 9.364 ms 9.548 ms 5 2001:558:300:15c::1 18.606 ms 17.251 ms 17.699 ms 6 2001:558:300:2003::1 28.996 ms 29.607 ms 29.016 ms 7 be-33491-cr02.350ecermak.il.ibone.comcast.net 30.339 ms 30.031 ms 31.602 ms [... several hops deleted ...] 15 2001:4860:0:1::121f 49.468 ms 2001:4860::1:0:a619 56.989 ms 2001:4860:0:1::121f 49.451 ms 16 den03s09-in-x04.1e100.net 49.241 ms 57.925 ms 58.238 ms [INS::INS] Configuring Syslog I edited /etc/syslog and commented out all the lines sending output to files. Then I added one line to the end, sending all syslog output to my log collector. The result is: # egrep -v '^#|^$' /etc/syslog.conf include /etc/syslog.d include /usr/local/etc/syslog.d *.* @10.1.1.100 The syslogd daemon on FreeBSD does not include its hostname in the message. Its message is simply the timestamp, daemon[PID], and then the message. Compare that to other syslog daemons that insert the hostname after the timestamp. If there is no hostname or IP address in the message, the log collector will insert the IP address of the source. If the log collector is using Rsyslog, add a new file to get it to resolve that to a name. It can be named anything as long as it ends ".conf". # cat /etc/rsyslog.d/fqdn.conf $PreserveFQDN on # systemctl restart rsyslog Configuring the time zone Until you set the time zone with tzsetup, times and dates will be reported in UTC as no local time has been defined. You have many choices, they are defined by the files under /usr/share/zoneinfo. Do something like this: # tzsetup EST5EDT Refer to the hierarchy of files, in the Yukon you could do something like this: # tzsetup America/Yellowknife Also recall that we configured the NTP daemon to run. Kerberos requires time synchronization. [INS::INS] Mounting the root file system with POSIX ACLs Samba requires that the file system support POSIX access-control lists. I modified /etc/fstab, additions are highlighted in yellow: /dev/mmcsd0s1 /boot/msdos msdosfs rw,noatime 0 0 /dev/mmcsd0s2a / ufs rw,noatime,acls 1 1 md /tmp mfs rw,noatime,-s30m,acls 0 0 md /var/log mfs rw,noatime,-s15m,acls 0 0 md /var/tmp mfs rw,noatime,-s5m,acls 0 0 However, the mount command after the next boot showed that the root file system was mounted with the incompatible nfsv4acls option. The others all had the requested acls option. The following line went to /var/log/messages at each reboot: freebsd kernel: WARNING: /: NFSv4 ACLs flag on fs conflicts with "acls" mount option; option ignored This was mysterious, as kenv showed that the kernel environment looked right: # kenv LINES="24" autoboot_delay="10" bootfile="kernel" console="uboot" currdev="disk0s2a:" interpret="OK" kernel="kernel" kernelname="/boot/kernel/kernel" loaddev="disk0s2a:" loader_conf_files="/boot/loader.conf /boot/loader.conf.local" module_path="/boot/kernel;/boot/kernel;/boot/modules;/boot/dtb" prompt="loader>" twiddle_divisor="1" vfs.root.mountfrom="ufs:/dev/mmcsd0s2a" vfs.root.mountfrom.options="rw,noatime,acls" I tried creating a new file /boot/loader.conf.local with these contents: vfs.root.mountfrom.options="rw,nonfsv4acls,acls,noatime" That added the nonfsv4acls option to the kernel environment, but it did not have the desired effect. Other file systems could be interactively modified: # mount | grep /var/tmp /dev/md2 on /var/tmp (ufs, local, noatime, soft-updates, acls) # mount -u -o noatime,noacls,nfsv4acls /var/tmp # mount | grep /var/tmp /dev/md2 on /var/tmp (ufs, local, noatime, soft-updates, nfsv4acls) # mount -u -o noatime,acls,nonfsv4acls /var/tmp /dev/md2 on /var/tmp (ufs, local, noatime, soft-updates, acls) But for the root file system, the mount command to change the options ran with no error or warning message, and exited with a status of 0. However, the attributes did not change: # mount | grep s2a /dev/mmcsd0s2a on / (ufs, local, noatime, journaled soft-updates, nfsv4acls) # mount -u -o noatime,acls,nonfsv4acls / # echo $? 0 # mount | grep s2a /dev/mmcsd0s2a on / (ufs, local, noatime, journaled soft-updates, nfsv4acls) The problem is that the root file system in the Raspberry Pi image is set to always use the nfsv4acls option for NFSv4 ACLs. If NFSv4 ACLs are in use, POSIX ACLs cannot be enabled. As explained on the FreeBSD Access Control Lists, page, the mount-time flag can be set in a persistent manner by modifying a flag in the superblock, the file system header. If a flag is set there, it will be used. It cannot be modified without unmounting the file system, and you cannot unmount the root file system. As that page explains, for security you want to mark the file system itself, precisely for the reason that I was unable to proceed -- an intruder who gains root access cannot disable ACL protection. ACLs that are enforced within the superblock can prevent a user with otherwise unlimited power from modifying protected components of the file system. [INS::INS] I agree with the logic. This is analogous to the reason why in Linux you should not be able to disable the Security-Enhanced Linux protection while the kernel is running. You should be forced to reboot the system and disable it at boot time, requiring physical access to the console. Notice that Red Hat chooses to build their kernels to allow it to be changed during run time, decreasing security but making it easy to help their customers solve problems. The kernel build configuration variable is SECURITY_SELINUX_DISABLE, "y" means that it can be disabled while running. In the kernel build configuration interface: Security Options - NSA SELinux Support - NSA SELinux runtime disable. Building Linux kernels Samba requires POSIX ACLs for part of its database, maintained under /var/db/samba4. It uses the ACLs for the part under /var/db/samba4/ sysvol. There is no other persistent file system (/var/log, /var/tmp, and / tmp are based on RAM, the md pseudodevice. So, the root file system itself has to be modified, and tunefs is the tool for the job. On typical server hardware I could reboot and request a boot to single-user or maintenance mode. Or, I could boot from media. But neither is possible here. I plugged in an HDMI cable to the TV, plugged in a USB keyboard, and rebooted. The problem was that the early boot environment doesn't see a USB keyboard. So, I couldn't send any key to stop the automated boot and ask for a boot into single-user mode. I manually shut down the network services, using lsof -i to see what remained. Then I manually unmounted the /boot/msdos, /var/log, /var/tmp, and / tmp file systems. Then I manually terminated all the processes I could. The getty processes respawn. Finally, I forced a change from read/write to read-only: # sync # sync # sync # mount -f -u -o ro / Now I could use tunefs to disable the NFSv4 ACL enable flag in the file system, and dumpfs to verify that it worked: # dumpfs / | grep flags flags soft-updates+journal nfsv4acls # tunefs -N disable / tunefs: NFSv4 acls cleared tunefs: filesystem reloaded # tunefs -a enable / tunefs: POSIX 1.e ACLs set tunefs: filesystem reloaded # dumpfs / | head -22 magic 19540119 (UFS2) time Fri Feb 17 19:42:56 2017 superblock location 65536 id [ 5887d304 7cce2791 ] ncg 130 size 7787248 blocks 7540727 bsize 32768 shift 15 mask 0xffff8000 fsize 4096 shift 12 mask 0xfffff000 frag 8 shift 3 fsbtodb 3 minfree 8% optim time symlinklen 120 maxbsize 32768 maxbpg 4096 maxcontig 4 contigsumsize 4 nbfree 883015 ndir 5571 nifree 3844183 nffree 471 bpg 7493 fpg 59944 ipg 30080 unrefs 0 nindir 4096 inopb 128 maxfilesize 2252349704110079 sbsize 4096 cgsize 16384 csaddr 1920 cssize 4096 sblkno 24 cblkno 32 iblkno 40 dblkno 1920 cgrotor 0 fmod 0 ronly 0 clean 0 metaspace 2392 avgfpdir 64 avgfilesize 16384 flags soft-updates+journal acls fsmnt / volname swuid 0 providersize 7787248 cs[].cs_(nbfree,ndir,nifree,nffree): (1635,451,25991,4) (15,441,24276,7) (57,440,25955,109) (190,443,23526,23) (1949,30,23230,41) (2266,150,24514,113) (4308,356,26422,58) (3137,218,27997,61) # tunefs -p / tunefs: POSIX.1e ACLs: (-a) enabled tunefs: NFSv4 ACLs: (-N) disabled tunefs: MAC multilabel: (-l) disabled tunefs: soft updates: (-n) enabled tunefs: soft update journaling: (-j) enabled tunefs: gjournal: (-J) disabled tunefs: trim: (-t) disabled tunefs: maximum blocks per file in a cylinder group: (-e) 4096 tunefs: average file size: (-f) 16384 tunefs: average number of files in a directory: (-s) 64 tunefs: minimum percentage of free space: (-m) 8% tunefs: space to hold for metadata blocks: (-k) 2392 tunefs: optimization preference: (-o) time tunefs: volume label: (-L) The soft updates mechanism drastically improves file system performance. It buffers metadata updates through a memory cache. Details are available at the FreeBSD disk tuning page. [INS::INS] Adding Samba and BIND I ran out of space on /tmp while doing the initial package updating, so I umounted it for a while and let it use the root partition. At the end there wasn't anything left in /tmp so there was no need to clean up before remounting it. I later ran out of space again when doing a pkg search, so I commented out the line in /etc/fstab defining /tmp. 29 MB of space in /tmp just isn't enough! It's a RAM-based "memory device", faster but limited in size. I could make it larger, but RAM is already limited on this platform. There wasn't a package literally named "samba", or "bind", or "named". That's because those packages are available in different versions, with the version numbers in the names: # pkg search '^bind|^named|^samba' bind-tools-9.11.0P2 Command line tools from BIND: delv, dig, host, nslookup... bind9-devel-9.12.0.a.2017.01.21 BIND DNS suite with updated DNSSEC and DNS64 bind910-9.10.4P5_1 BIND DNS suite with updated DNSSEC and DNS64 bind911-9.11.0P2_1 BIND DNS suite with updated DNSSEC and DNS64 bind99-9.9.9P5_1 BIND DNS suite with updated DNSSEC and DNS64 bindgraph-0.3_1 RRDtool frontend for BIND statistics bindtest-1.56_1 Test bind() semantics of IPv6 sockets samba-nsupdate-9.8.6_1 nsupdate utility with GSS-TSIG support samba-virusfilter-0.1.3_1 On-access anti-virus filter for Samba samba36-3.6.25_3 Free SMB and CIFS client and server for Unix samba36-libsmbclient-3.6.25_2 Shared lib from the samba package samba36-nmblookup-3.6.25 NetBIOS Name lookup tool samba36-smbclient-3.6.25 Samba "ftp-like" client samba42-4.2.14 Free SMB/CIFS and AD/DC server and client for Unix samba43-4.3.13_1 Free SMB/CIFS and AD/DC server and client for Unix OK, so the package with BIND is called "bind" and not "named". Package management on BSD (and Linux and Solaris) I initially installed BIND 9.11 (bind911) and Samba 4.3 (samba43), went through everything that follows, and only then found that Samba 4.3 only supports BIND 9.10. Samba uses dynamically loadable zones (or DLZ), which can be accessed through the AD schema. We must have a compatible combination of BIND and Samba. Here's the information from Samba's page on the BIND 9 DLZ DNS back end. BIND Version Supported starting with BIND 9.11 Samba 4.5.2 BIND 9.10 Samba 4.2 BIND 9.9 Samba 4.0 BIND 9.8 Samba 4.0 Let's install the latest available version of Samba, and the latest available and compatible version of BIND: # pkg install bind910 samba43 Updating FreeBSD repository catalogue... FreeBSD repository is up-to-date. All repositories are up-to-date. The following 43 package(s) will be affected (of 0 checked): New packages to be INSTALLED: bind910: 9.10.4P6 samba43: 4.3.13_1 [... more packages deleted ...] Number of packages to be installed: 43 The process will require 404 MiB more space. 68 MiB to be downloaded. Proceed with this action? [y/N]: y Fetching bind910-9.10.4P6.txz: 100% 5 MiB 901.5kB/s 00:06 Fetching samba43-4.3.13_1.txz: 100% 21 MiB 810.3kB/s 00:27 Fetching libxml2-2.9.4.txz: 100% 740 KiB 378.9kB/s 00:02 [... more packages deleted ...] [... many installations deleted ...] The OpenLDAP client package has been successfully installed. Edit /usr/local/etc/openldap/ldap.conf to change the system-wide client defaults. Try `man ldap.conf' and visit the OpenLDAP FAQ-O-Matic at http://www.OpenLDAP.org/faq/index.cgi?file=3 for more information. [... more installations deleted ...] Message from bind910-9.10.4P6: ********************************************************************** * _ _____ _____ _____ _ _ _____ ___ ___ _ _ * * / \|_ _|_ _| ____| \ | |_ _|_ _/ _ \| \ | | * * / _ \ | | | | | _| | \| | | | | | | | | \| | * * / ___ \| | | | | |___| |\ | | | | | |_| | |\ | * * /_/ \_\_| |_| |_____|_| \_| |_| |___\___/|_| \_| * * * * BIND requires configuration of rndc, including a "secret" key. * * The easiest, and most secure way to configure rndc is to run * * 'rndc-confgen -a' to generate the proper conf file, with a new * * random key, and appropriate file permissions. * * * * The /usr/local/etc/rc.d/named script will do that for you. * * * ********************************************************************** [... more installations deleted ...] Message from samba43-4.3.13_1: =============================================================================== How to start: http://wiki.samba.org/index.php/Samba4/HOWTO * Your configuration is: /usr/local/etc/smb4.conf * All the relevant databases are under: /var/db/samba4 * All the logs are under: /var/log/samba4 * Provisioning script is: /usr/local/bin/samba-tool For additional documentation check: http://wiki.samba.org/index.php/Samba4 The key for BIND was automatically generated the first time it started. The key is stored in /usr/local/etc/namedb/rncd.key. You use it if you control BIND with the program rndc, but you will probably use the script /usr/local/etc/rc.d/named. Run it with no argument to see your choices, the parameters start, stop, restart, reload, and status cover most needs. I also added lsof and vim. The next step... The next step is to turn the new FreeBSD system into a slave DNS server. Back to the start Set up the needed DNS records Install FreeBSD on a Raspberry Pi Establish a slave DNS server Configure Samba as an Active Directory domain controller Deploying Users and Groups Overview of all changes [INS::INS] Raspberry Pi running FreeBSD. Raspberry Pi running FreeBSD with BIND and Samba software installed. Other Linux Topics --------------------------------------------------------------------- Now some lurid advertisements from Google AdSense: [INS::INS] Home Travel Linux/Unix Cybersecurity Networking Technical Radio Site Map Valid HTML 5. Validate it here. Valid CSS. Validate it here. Valid Unicode. Nginx FreeBSD Bob the Traveler Conan the Sysadmin Tweet Follow @ToiletGuru submit to reddit Viewport size: x Protocol: HTTP/1.0 Crypto: TLSv1.2 / X25519 / ECDHE-ECDSA-AES256-GCM-SHA384 (c) by Bob Cromwell Dec 2022. Created with vim and ImageMagick, hosted on FreeBSD with Nginx. As an Amazon Associate, I earn from qualifying purchases. Contact | Privacy policy | Root password