Let’s face it: Though Linux is experiencing a bit of a renaissance lately, it’s still a Windows world out there. This seems to be especially true in the Enterprise. Users love their Windows. They love their Start Menu, their Task Bar, their Internet Explorer, their My Documents folder and all the problems and pain that go along with it. Don’t get me wrong, I like Windows, too. And in fact, when it comes to my own use, I’m not much different than the users I’ve supported for the last 20 years. Sure, I try to strike a balance between Linux and Windows for my daily-use machines, and I’m a huge Linux advocate. But ultimately, I find myself gravitating back to Windows for most of my daily tasks, even for email and general web browsing, and certainly for music and entertainment.
But in many Enterprises, Windows’ roots run even deeper. With Exchange Server, SharePoint, Lync (now Skype for Business), MSSQL, System Center and a myriad of other offerings, Microsoft’s server solutions just make sense for many IT shops which have hundreds, even thousands, of desktops and laptops running Windows. Perhaps most ubiquitous of all, however, is the Windows Domain Controller. Microsoft’s Active Directory seems to be the go-to product for authentication and policy management in the Enterprise. In fact, it’s routinely stated that 95% of Fortune 500 companies use Active Directory. And though the push to, “the cloud,” has some folks decrying the inflexibility of Active Directory as more and more services are moved off-premise, it seems pretty safe to say we won’t see the demise of AD any time soon.
With all this said, according to Red Hat, by 2013 over 90% of Fortune 500 companies relied on Linux in some capacity. It seems pretty clear that it’s a good bet to have both Windows and Linux skill sets in today’s technology landscape. It also shouldn’t come as much surprise that integrating non-Windows systems into a Windows Domain is big business these days. In this article we hope to demonstrate an example of just that – how to integrate a Linux server into a Windows domain as a file server for Windows clients.
Jump To:
Samba
Why Linux?
Prerequisites
Webmin
IP Address Configuration
DNS Configuration
Installing Samba Components
Samba and Kerberos Configuration
Samba Winbind Options
Joining the Windows Domain
Domain Users & Groups
Extended ACLs
Creating Samba File Shares
Accessing the Share
Configuring AD User Shells & Home Dirs
Conclusion
Enter Samba
For nearly 25 years, Samba has been providing interoperability between Linux/Unix and Windows. Samba allows Linux or Unix-like systems to become Windows domain members in a Windows domain. And though it’s beyond the scope of this article, newer versions of Samba will even allow a Linux/Unix server to act as a domain controller. In turn, Samba facilitates communication between Windows systems and a Linux/Unix server over the Server Message Block (SMB)/Common Internet File System (CIFS) protocol. In essence, your Windows machine will talk to the Samba server just as though it’s a Windows file/print server.
Why Linux?
So if we’re essentially emulating a Windows server with Linux, why not just use a Windows operating system? Well, there are a few of scenarios where this configuration may make sense:
- Application Compatibility. You may have an application that runs on Linux or Unix only, but you still need the connectivity that Samba provides. In this case, you can still run your native Linux application, but allow your Windows clients to access file shares on the server.
- Licensing. Licensing costs for Windows Server may be another factor. For some SMBs, an additional Windows license for a file/print server may be prohibitively expensive. Many flavors of Linux, on the other hand, are free.
- Hardware. Windows generally requires beefier hardware than Linux. Even an old desktop in the basement can make a fine home or lab file server.
- Software RAID. For others, Linux offers the unique ability to inexpensively provide something that many folks do not trust Windows to do – software RAID. Linux software RAID (aka MDADM) doesn’t have the strict requirements of hardware RAID controllers, and many times can be done less expensively. It also is mostly hardware agnostic. You can typically lift a Linux MDADM RAID array from one box and drop it in another, assemble the RAID array, and find the data intact. Since hardware RAID controllers are often tied to their disks via specific metadata, this is critical for the hobbyist or home lab, where you may not have an endless supply of identical controllers should one fail. We’ve even done this with name-brand SOHO NAS appliances which had kernel failures and rescued terabytes of data for a client!
Prerequisites
There are a few things you need to have working before this exercise, however. Make sure you are at least somewhat familiar with the technologies mentioned.
- Domain Controller/Active Directory. You need to have a working domain controller running Active Directory. We’ve only tested this configuration on a Windows domain controller, but a Samba 4.0 or newer domain controller emulates this functionality as well. We’ve been doing this since Windows Server 2008 through Windows Server 2012 R2, so any recent Windows Server should work just fine.
- DNS Server. You also need a properly functioning DNS server, preferably Active Directory integrated. DNS is critical to the domain join process, so make sure your DNS server(s) are working properly – more on this later.
- Linux Server. This is the member server that is to join the domain. It doesn’t need anything fancy for this exercise, but must be able to communicate with your domain controller/DNS server. It can even be a virtual machine for proof of concept, although most home/lab file servers will likely be physical machines.
- Windows Domain Member. This machine can be a desktop, laptop, or virtual machine, as long as it’s joined to the domain and can reach the three servers listed above over the network.
Webmin
Now, we like to perform most operations from the command-line in Linux, as many GUIs typically aren’t very mature in Linux or don’t offer the same functionality as the CLI. In addition, the CLI gives you an intimate view of applications and configurations you just don’t get from a GUI. On the other hand, when it makes sense to use a GUI to do something, we won’t shy away from it just to impress our friends. Webmin is a perfect example of this. Webmin offers a web-based interface for completing many Linux/Unix administration tasks. Available for most distributions, it simplifies many operations, eliminating the need to manually edit configuration files. Joining a Linux server to a Windows domain is one area we like to use Webmin, so our first task will be to install Webmin on our Linux server. We’ll use Webmin for much of this walk-through, but also show the configuration changes in the file system when possible, so you can become familiar with the underlying files that are affected.
Our Linux server in this case is Ubuntu 14.04, so you’ll see some specificity to Ubuntu, such as using aptitude for package installation. Most other distros should work much the same as what’s shown in this guide, but obviously some commands and steps will have to be altered.
The simplest way to install Webmin is to download the bits and use the Debian package manager to perform the installation. First, install any necessary dependencies for Webmin:
1 2 3 |
$ sudo apt-get install perl libnet-ssleay-perl openssl libauthen-pam-perl libpam-runtime libio-pty-perl apt-show-versions python |
Once any dependency issues are resolved, find the latest version of Webmin here and dowload it using wget. We want the debian version that is offered:
1 2 3 |
$ sudo wget http://prdownloads.sourceforge.net/webadmin/webmin_1.820_all.deb |
Finally, install Webmin using the Debian package manager:
1 2 3 |
$ sudo dpkg --install webmin_1.820_all.deb |
Once installed, you should find Webmin listening on port 10000. Keep in mind that distros which have a firewall like iptables enabled by default may need firewall rule modifications to allow access to Webmin.
1 2 3 4 5 |
$ sudo netstat -nl | grep 10000 tcp 0 0 0.0.0.0:10000 0.0.0.0:* LISTEN udp 0 0 0.0.0.0:10000 0.0.0.0:* |
From your Windows workstation, you should now be able to log into Webmin by browsing to https://servername:10000, where servername is the host name of your new Linux server. If you cannot resolve it by hostname, IP Address should work as well. Keep in mind, however, that name resolution of your Linux server will need to work at some point.
IP Address Configuration
It’s best to assign your server a static IP, so you won’t run into any stale DNS record issues. DHCP may work, at least in the short term, but future problems could arise. Although IP Address changes can be made via Webmin, this is one area that it’s usually best to be in front of a console. I also find this configuration change to be easier and quicker from the command line. Log into the server and edit the interface configuration as follows, substituting the IP and domain information for your network.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ sudo vi /etc/network/interfaces # The primary network interface iface eth0 inet static address 10.0.0.101 netmask 255.255.255.0 broadcast 10.0.0.255 network 10.0.0.0 gateway 10.0.0.1 dns-nameservers 10.0.0.11 10.0.0.12 dns-domain domain.com |
Once you’ve saved the configuration file, bounce the network adapter.
1 2 3 |
$ sudo ifdown eth0 && sudo ifup eth0 |
Now log into Webmin on your Linux server and verify the changes that were just made. From the left-hand navigation menu, expand, “Networking,” and click on, “Network Configuration.” The Network Configuration module contains all the settings related to interface configuration, routing and gateways and DNS and hostnames.
Select the Network Interfaces link. Here we should see both the active and at-boot configurations for our Ethernet adapter with the static IP Address we just assigned. You can also verify the default gateway and DNS server settings for your server here.
DNS Configuration
As mentioned before, DNS is critical for the domain-join process. Your Linux server relies on name resolution to locate the domain controller and begin authentication. We set the preferred DNS servers in the previous step, so the Linux server should be able to resolve the domain controller(s) on your network now. Test name resolution by running a simple ping test from the Linux server to the domain controller.
1 2 3 4 5 6 7 |
$ ping dc01 PING dc01.domain.com (10.0.0.11) 56(84) bytes of data. 64 bytes from dc01.domain.com (10.0.0.11): icmp_seq=1 ttl=128 time=0.399 ms 64 bytes from dc01.domain.com (10.0.0.11): icmp_seq=2 ttl=128 time=0.395 ms 64 bytes from dc01.domain.com (10.0.0.11): icmp_seq=3 ttl=128 time=0.432 ms |
Now we’ll add a hosts file entry for the loopback adapter on the Linux server. In the Networking > Network Configuration module, select the Hosts Addresses configuration. Click on the entry for 127.0.0.1 that lists the server’s hostname. Add the FQDN of the Linux server as the first entry in the list as shown.
Again, test the settings by running a simple ping test from the Linux server. You should see replies containing the FQDN.
1 2 3 4 5 6 7 |
$ ping ubuntu-test PING ubuntu-test.domain.com (127.0.1.1) 56(84) bytes of data. 64 bytes from ubuntu-test.domain.com (127.0.1.1): icmp_seq=1 ttl=64 time=0.031 ms 64 bytes from ubuntu-test.domain.com (127.0.1.1): icmp_seq=2 ttl=64 time=0.041 ms 64 bytes from ubuntu-test.domain.com (127.0.1.1): icmp_seq=3 ttl=64 time=0.038 ms |
We also need to make sure we have name resolution in the other direction. Since we set a static IP address, we will likely need to create an A-record on the DNS server for the Linux box. Once the A-record is created, ensure that you have name resolution to the Linux server from both your domain controller and your Windows client.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
C:\Windows\System32>ping ubuntu-test Pinging ubuntu-test.domain.com [10.0.0.101] with 32 bytes of data: Reply from 10.0.0.101: bytes=32 time<1ms TTL=63 Reply from 10.0.0.101: bytes=32 time<1ms TTL=63 Reply from 10.0.0.101: bytes=32 time<1ms TTL=63 Reply from 10.0.0.101: bytes=32 time<1ms TTL=63 Ping statistics for 10.0.0.101: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 0ms, Average = 0ms |
Installing Samba, Winbind & Kerberos for Authentication
Next, use aptitude to install samba and winbind. These components will allow you to communicate with the domain controller and use Windows-based accounts in a Linux or Unix environment.
1 2 3 |
$ sudo apt-get install samba winbind |
Next, install Kerberos. Kerberos was developed at the Massachusetts Institute of Technology as a means of providing mutual authentication. All versions of Windows since Windows 2000 use Kerberos as their default authentication mechanism, and thus is necessary for our Linux server to provide authentication in a Windows domain.
1 2 3 |
$ sudo apt-get install heimdal-clients libpam-heimdal |
Samba and Kerberos Configuration
Back in Webmin, refresh the modules to display the newly installed applications. You should now see Samba listed under Servers, and Kerberos5 listed under Networking. First, click on Kerberos5. Here, provide the following information based on your environment.
Realm: Your domain name – IN ALL CAPS
- Domain name: Your domain name – in all lowercase
- Default domain name: Your domain name – in all lowercase
- Use DNS to lookup KDC: Select Yes
- KDC: FQDN of your domain controller – use port 88 unless you know otherwise
- Admin server: FQDN of your domain controller – use port 88 unless you know otherwise
Next, click on the Samba Windows File Sharing under Servers and click on the Windows Networking icon. Again, provide the following information based on your environment.
Workgroup: Pre-Windows 2000 (short) domain name – in all lowercase
- WINS mode: Use Server – IP of your domain controller
- Server description: %h server (something descriptive)
- Master browser priority: 20
- Highest protocol: default
- Master browser: Yes
- Security: Active Directory
- Password server: FQDN of your domain controller
Samba Winbind Options
Finally, click on Winbind Options in the Samba module. Select the options here, and click save. Frustratingly, the options here seems to have inconsistent results in the configuration file, so we’ll need to verify them in the config. On the server, backup and then edit the smb.conf file as follows. You’ll notice a number of the other changes we’ve made have been stored here.
1 2 3 4 5 |
$ sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.orig $ sudo vi /etc/samba/smb.conf |
Locate the [global] section and edit as follows. Comment out the following two lines if present:
1 2 3 4 |
# winbind use default domain = yes # winbind trusted domains only = yes |
Now add these lines to the end of the global section if they do not exist:
1 2 3 4 5 6 7 |
winbind enum groups = yes winbind enum users = yes template shell = /bin/bash template homedir = /home/%D/%U encrypt passwords = yes |
Interestingly, you can see the options reflected in the Winbind Options in the Webmin Samba module. If you look closely in the Webmin UI, the setting, “Disallow listing of users/groups?” is clearly set to “Yes.” However, we’ve just set the winbind enumeration to “yes” in the smb.conf file. These settings appears to be contradictory, and you can have strange results if you make changes in the GUI after effecting the changes in the config. Once things are working, it’s best not to make any additional changes to the Samba Winbind options in Webmin.
Joining the Windows Domain
We’re finally ready to join the Windows domain now. Issue the following command, where the user, “username” is a domain user that has the permissions necessary to join computers to the domain. It’s always best to use an account with the least amount of privileges to perform an action, but if you are in doubt or if you encounter errors, use a Domain Admin account to rule out permissions issues. If you’ve carefully applied the settings, however, and DNS is working properly, you should achieve success here and see the new computer account in Active Directory.
1 2 3 4 5 6 7 |
$ sudo net ads join -S dc01.domain.com -U username -k createcomputer=Lab\ Computers/Linux-Unix\ Servers osName=Ubuntu osVer=14.04 [sudo] password for administrator: Enter username's password: Using short domain name -- DOMAIN Joined 'UBUNTU-TEST' to dns domain 'domain.com' |
Before we move on, let’s break this command down a bit. The net commands are useful tools for managing Samba/CIFS on your domain-joined Linux server. In this instance, the ‘net ads join’ command tells Samba that we’re working with the AD command set, hence the ‘ads’ component, while the ‘join’ directive tells Samba that we want to join an Active Directory domain. The next three options are not specific to Active Directory, but modify the ‘net’ portion of the command. The -S option specifies the target server (Domain Controller) and the -U specifies the username of the user to use for the domain join. As mentioned above, this user must have the necessary rights to create objects in AD. The -k option states that we wish to use Kerberos as the authentication mechanism.
The final options, createcomputer, osName and osVer are not required, although they do add some useful features. First, ‘createcomputer’ creates the new computer account in a specific OU within AD. This can be handy if you want to keep your Windows and Linux servers separated for policy or organization purposes. The ‘osName’ and ‘osVer’ options are pretty self-explanatory, but if you like things neatly documented, this will prepopulate the Name and Version fields for the new computer object in AD.
In additional to joining a domain, you can leave a domain, view logon server info, query domain users and groups, and even dynamically update Active Directory integrated DNS records. The full list of net ads commands can be viewed by simply typing ‘net ads.’
Domain Users & Groups
Next, we need to configure our Linux server to look to the domain controller for users and group authentication. To do this, we need to simply edit the nsswitch.conf file. For the passwd and group directives, simply add “winbind” after the compat parameter on each line. After saving the file, restart all relevant daemons.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
$ sudo vi /etc/nsswitch.conf passwd: compat winbind group: compat winbind shadow: compat hosts: files dns networks: files protocols: db files services: db files ethers: db files rpc: db files netgroup: nis $ sudo service winbind stop && sudo service nmbd stop && sudo service smbd stop winbind stop/waiting nmbd stop/waiting smbd stop/waiting $ sudo service smbd start && sudo service nmbd start && sudo service winbind start smbd start/running, process 9514 nmbd start/running, process 9530 winbind start/running, process 9543 |
We can now verify the configuration as follows. The wbinfo command let’s us know that Winbind is successfully working and we’re able to connect to the DC to enumerate users and groups.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
$ sudo wbinfo -u DOMAIN\guest DOMAIN\krbtgt DOMAIN\administrator DOMAIN\user1 DOMAIN\user2 DOMAIN\user3 DOMAIN\user4 DOMAIN\user5 $ sudo wbinfo -g DOMAIN\cert publishers DOMAIN\domain users DOMAIN\domain guests DOMAIN\ras and ias servers DOMAIN\allowed rodc password replication group DOMAIN\enterprise read-only domain controllers DOMAIN\domain controllers DOMAIN\read-only domain controllers DOMAIN\domain computers DOMAIN\denied rodc password replication group DOMAIN\domain admins DOMAIN\group policy creator owners DOMAIN\enterprise admins DOMAIN\schema admins DOMAIN\user group1 |
And now check to verify that the passwd and group databases on the Linux server are populated with the domain users and groups. The output has been abbreviated a bit, but notice that after the usual passwd file entries, we see our domain accounts beginning with the id 10000.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
$ sudo getent passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync . . . administrator:x:1000:1000:administrator,,,:/home/administrator:/bin/bash DOMAIN\guest:*:10000:10000:Guest:/home/DOMAIN/guest:/bin/bash DOMAIN\krbtgt:*:10001:10001:krbtgt:/home/DOMAIN/krbtgt:/bin/bash DOMAIN\administrator:*:10002:10001:Administrator:/home/DOMAIN/administrator:/bin/bash DOMAIN\user1:*:10003:10001:user1: Access:/home/DOMAIN/user1:/bin/bash DOMAIN\user2:*:10004:10001:user2:/home/DOMAIN/user2:/bin/bash DOMAIN\user3:*:10005:10001:user3:/home/DOMAIN/user3:/bin/bash $ sudo getent group root:x:0: daemon:x:1: bin:x:2: sys:x:3: . . . winbindd_priv:x:112: DOMAIN\cert publishers:x:10002: DOMAIN\domain users:x:10001: DOMAIN\domain guests:x:10000: DOMAIN\ras and ias servers:x:10003: DOMAIN\allowed rodc password replication group:x:10004: DOMAIN\enterprise read-only domain controllers:x:10005: DOMAIN\domain controllers:x:10006: DOMAIN\read-only domain controllers:x:10007: DOMAIN\domain computers:x:10008: DOMAIN\denied rodc password replication group:x:10009: DOMAIN\domain admins:x:10010: DOMAIN\group1:x:10011: |
Extended ACLs
One thing that’s important to keep in mind when we’re talking about Windows file shares, is that permissions, or access control lists (ACLs) are a crucial component to ensure users can see the files they should, but are restricted from those they shouldn’t. In the Windows world permissions are further divided into two components – share permissions and file system permissions. Without both properly set, users may experience issues with access.
First, let’s discuss file system permissions in our Linux-in-a-Windows-domain environment that we’ve created. Traditional Unix permissions aren’t much good to us if we want our new Linux file server to work like Windows, as we would be limited to a single user and group on each directory or file. You certainly may have a situation where you’d want both Accounting and Finance to have read-write access to a directory, but perhaps HR to only have read access to that same directory. Enter Linux Extended ACLs. We dig into the Extended ACL package in detail here, but suffice to say that Extended ACLs are the icing on the metaphorical Linux file server cake. Extended ACLs gives us more Windows NTFS-like permissions; without them much of the power of Linux domain integration is lost. To see this in action we need to install the acl package with the following command.
1 2 3 |
$ sudo apt-get install acl |
We’ll also need a directory to share out so let’s assume we have an empty 5 GB partition to work with. First, we need to create an EXT4 file system on the partition as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
$ sudo fdisk -l /dev/sdb Disk /dev/sdb: 5368 MB, 5368709120 bytes 181 heads, 40 sectors/track, 1448 cylinders, total 10485760 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disk identifier: 0xccf9a5dc Device Boot Start End Blocks Id System /dev/sdb1 2048 10485759 5241856 83 Linux $ sudo mke2fs -t ext4 /dev/sdb1 mke2fs 1.42.9 (4-Feb-2014) Discarding device blocks: done Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 327680 inodes, 1310464 blocks 65523 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=1342177280 40 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done |
Now we need to mount our partition on the server. First, create the directory to hold our shares, and a subdirectory in which we want to mount our partition.
1 2 3 |
$ sudo mkdir -p /mnt/shares/files |
Next, edit the fstab file to auto mount our new partition to ensure it persists after a reboot. I prefer to do this by using the disk UUID rather than the device letter and partition number (i.e. sda1, sda2, sdb1, etc.), as device letters may change if disks are swapped around on a SATA or SAS controller, a new controller or disk enclosure is added, or if disks are moved to a different system. Disk UUIDs are easily determined by listing the devices as shown. Locate the disk UUID for /dev/sdb1 and use the unique identifier in the fstab file. Note also that the our disk is to be mounted with the acl option. This enables us to use the extended ACLs package we just installed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$ ll /dev/disk/by-uuid/ total 0 drwxr-xr-x 2 root root 100 Nov 12 12:43 ./ drwxr-xr-x 4 root root 80 Nov 12 12:38 ../ lrwxrwxrwx 1 root root 10 Nov 12 12:38 2a25fffc-5bcc-4e60-b255-99ed78cfbb64 -> ../../sda2 lrwxrwxrwx 1 root root 10 Nov 12 12:43 a4c2d2d0-93c8-4041-b76b-cf04fa7dca0f -> ../../sdb1 lrwxrwxrwx 1 root root 10 Nov 12 12:38 a55d5515-eb94-4ac6-b96f-3c5f75ded8e4 -> ../../sda1 $ sudo vi /etc/fstab # / was on /dev/sda2 during installation UUID=2a25fffc-5bcc-4e60-b255-99ed78cfbb64 / ext4 errors=remount-ro,acl 0 1 # swap was on /dev/sda1 during installation UUID=a55d5515-eb94-4ac6-b96f-3c5f75ded8e4 none swap sw 0 0 /dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0 # Mount for Samba file share UUID=a4c2d2d0-93c8-4041-b76b-cf04fa7dca0f /mnt/shares/files ext4 acl 0 0 |
Finally, mount the partition from fstab. We can then easily verify the newly available space by taking a quick peek at the disk file systems with the df command.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ sudo mount -a $ df -Th Filesystem Type Size Used Avail Use% Mounted on udev devtmpfs 232M 4.0K 232M 1% /dev tmpfs tmpfs 49M 604K 48M 2% /run /dev/sda2 ext4 5.0G 2.1G 2.7G 44% / none tmpfs 4.0K 0 4.0K 0% /sys/fs/cgroup none tmpfs 5.0M 0 5.0M 0% /run/lock none tmpfs 242M 0 242M 0% /run/shm none tmpfs 100M 0 100M 0% /run/user /dev/sdb1 ext4 4.8G 10M 4.6G 1% /mnt/shares/files |
Now that we have a place to share our files, let’s modify the traditional Unix permission set on the shares directory, but leverage the domain groups we now have available.
1 2 3 4 5 6 7 8 9 10 11 |
$ sudo chown -R domain\\shareadmin /mnt/shares/ $ sudo chgrp -R domain\\share\ admins /mnt/shares/ $ sudo chmod -R 770 /mnt/shares/ $ ll /mnt/shares/ total 12 drwxr-xr-x 3 root root 4096 Oct 26 22:34 ./ drwxr-xr-x 22 root root 4096 Oct 20 21:16 ../ drwxrwx--- 3 DOMAIN\shareadmin DOMAIN\share admins 4096 Nov 12 12:43 files/ |
Note the double backslash when setting permissions. To make the Windows users and groups work, we must escape the backslash that typically separates the domain\user and domain\group since it’s a special character in Linux. The first command sets the owner to a domain user called shareadmin; the second command sets the group to a domain group called share admins. Finally, the last command sets the traditional POSIX rw- permissions. So, there’s not much new here, but we can start to see the additional flexibility our AD integrated server offers.
Next, let’s consider the same directory called files, but suppose we want further granularity than just the owner and group permissions. This is where the extended ACL commands become quite powerful. To first take a look at any ACLs that exist on this directory, we’ll use the getfacl command. Getfacl will not only show us the traditional UNIX permissions, but also any additional ACLs applied to the file or directory. Again, not much to see here yet, but this will start to take shape soon.
1 2 3 4 5 6 7 8 9 |
$ sudo getfacl /mnt/shares/ # file: /mnt/shares/ # owner: DOMAIN\134shareadmin # group: DOMAIN\134share\040admins user::rwx group::rwx other::--- |
The setfacl command allows us to set ACLs on file or directory, separate from the traditional UNIX permissions set above. The setfacl -m parameter specifies that we want to modify the ACL, and the u: or g: parameter indicates whether we’re modifying a user or group permission. Additionally, the -d parameter, along with the ‘chmod g+s’ command, gives us the ability to set default ACLs on the directory, so that new files and subdirectories inherit the parent ACL.
1 2 3 4 5 6 7 8 |
$ sudo chmod -R g+s /mnt/shares/ $ sudo setfacl -R -d -m u::rwx /mnt/shares/ $ sudo setfacl -R -d -m g::rwx /mnt/shares/ $ sudo setfacl -R -d -m g:domain\\domain\ admins:rwx /mnt/shares/ $ sudo setfacl -R -d -m g:domain\\share\ admins:rwx /mnt/shares/ $ sudo setfacl -R -d -m g:domain\\backup\ admins:r-x /mnt/shares/ |
So in the above example, we’re turning on inheritance, setting the default permissions for the default user and group, and we’re also assigning three separate group default permissions to this directory. The first two groups, Domain Admins and Share Admins both have read/write/execute, while the third group, Backup Admins, has read and execute only. Now taking a look at getfacl again on this directory, we can see a clear difference from our vanilla directory:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ sudo getfacl /mnt/shares/ getfacl: Removing leading '/' from absolute path names # file: mnt/shares/ # owner: DOMAIN\134shareadmin # group: DOMAIN\134share\040admins # flags: -s- user::rwx group::rwx other::r-x default:user::rwx default:group::rwx default:group:DOMAIN\134domain\040admins:rwx default:group:DOMAIN\134share\040admins:rwx default:group:DOMAIN\134backup\040admins:r-x default:mask::rwx default:other::r-x |
Finally, we want to grant explicit ACLs on the parent folder – remember the previous ACLs we assigned were only defaults. These commands look similar to the default ACLs, less the -d parameter.
1 2 3 4 5 6 7 |
$ sudo setfacl -R -m u::rwx /mnt/shares/ $ sudo setfacl -R -m g::rwx /mnt/shares/ $ sudo setfacl -R -m g:domain\\domain\ admins:rwx /mnt/shares/ $ sudo setfacl -R -m g:domain\\share\ admins:rwx /mnt/shares/ $ sudo setfacl -R -m g:domain\\backup\ admins:r-x /mnt/shares/ |
Now we have a full set of permissions, and any new subdirectories will inherit these permissions as well.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ sudo getfacl /mnt/shares/ getfacl: Removing leading '/' from absolute path names # file: mnt/shares/ # owner: DOMAIN\134shareadmin # group: DOMAIN\134share\040admins # flags: -s- user::rwx group::rwx group:DOMAIN\134domain\040admins:rwx group:DOMAIN\134share\040admins:rwx group:DOMAIN\134backup\040admins:r-x mask::rwx other::--- default:user::rwx default:group::rwx default:group:DOMAIN\134domain\040admins:rwx default:group:DOMAIN\134share\040admins:rwx default:group:DOMAIN\134backup\040admins:r-x default:mask::rwx default:other::--- |
Creating Samba File Shares
Now for the part we all came for – creating the file shares. Again, this is one of the operations that just plain easier to manage in Webmin. In the Samba module, click on the “Create a new file share,” link. Here, provide the basic share information.
Share name: Something logical but succinct, such as Music or Pictures
- Directory to share: The directory on the Linux server that contains the files we want to share out
- Available: Yes
- Browseable: Yes (No, if you want the share to be hidden)
- Comment: Not required, but can be a longer description of the share contents
Once done, click the Create button to commit the settings. You should now see the share in the Samba share list. Click on the new share name in the list and click the ‘Security and Access Control’ link. Recall before we said that file server permissions were comprised of two components – file system and share permissions. We’ve configured the file system permissions with Linux Extended ACLs, but here we’ll set the share permissions.
On the Edit Security page, provide the information for share permissions. We will use the same groups we discussed in the setfacl examples.
Writable: Yes
- Guest Access: None
- Limit to possible list? No
- Hosts to allow: All (unless you choose to restrict access by host)
- Hosts to deny: None (unless you choose to restrict access by host)
- Revalidate users? No
- Valid groups: “domain\share admins” “domain\domain admins” “domain\backup admins”
- Read only groups: “domain\backup admins”
- Read/write groups: “domain\share admins” “domain\domain admins”
Click the Save button when complete. Regarding the group information, be sure to provide this information as shown here – each entry should be enclosed in quotes, with a single slash between domain and group, and the list should be delimited by a single space.
Here’s what this new share looks like in the smb.conf file:
1 2 3 4 5 6 7 8 9 10 |
$ less /etc/samba/smb.conf [Files] write list = @"domain\share admins",@"domain\domain admins" writeable = yes comment = Files read list = @"domain\backup admins" valid users = @"domain\share admins",@"domain\domain admins",@"domain\backup admins" path = /mnt/shares/files |
Finally, restart the samba daemons to fully implement the share.
1 2 3 4 5 6 7 |
$ sudo service smbd restart && sudo service nmbd restart smbd stop/waiting smbd start/running, process 5507 nmbd stop/waiting nmbd start/running, process 5525 |
Accessing the Share
Now, from our Windows client, we should be able to access our new share. First, ensure you’re logged into Windows as a user that is in one of the groups we assigned to the share. Then, from the run line, simply type \\servername.
You should now see a familiar Windows Explorer window and you should see the new file share. You should also be able to create, copy or move files and folders to the new share. Try this by creating a folder called ‘Dir1’. If we then take a look at Dir1 with getfacl, we should see a pattern similar to our previous examples. Note that the only exception is that the owner is the user who created the file, in this case user1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
s# getfacl Dir1/ # file: Dir1/ # owner: DOMAIN\134user1 # group: DOMAIN\134share\040admins # flags: -s- user::rwx group::r-x group:DOMAIN\134domain\040admins:rwx group:DOMAIN\134share\040admins:rwx group:DOMAIN\134backup\040admins:r-x mask::rwx other::r-x default:user::rwx default:group::rwx default:group:DOMAIN\134domain\040admins:rwx default:group:DOMAIN\134share\040admins:rwx default:group:DOMAIN\134backup\040admins:r-x default:mask::rwx default:other::--- |
The beauty of this configuration is that we can now manage files and subdirectories from Windows, using the familiar right-click > Properties context menu. As a final test, look at the properties for Dir1 from your Windows client. On the security tab, click the ‘Edit’ button to change permissions. Highlight Backup Admins in the list of group or user names and check the box for Write permissions under the Allow column. Click, ‘OK’ and ‘OK’ again to close the dialogue boxes.
Now let’s look at Dir1 again with getfacl. Note that the Backup Admins group now has rwx permissions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
s# getfacl Dir1/ # file: Dir1/ # owner: DOMAIN\134user1 # group: DOMAIN\134share\040admins # flags: -s- user::rwx user:DOMAIN\134user1:rwx group::rwx group:DOMAIN\134domain\040admins:rwx group:DOMAIN\134share\040admins:rwx group:DOMAIN\134backup\040admins:rwx mask::rwx other::r-x default:user::rwx default:user:DOMAIN\134user1:rwx default:group::rwx default:group:DOMAIN\134domain\040admins:rwx default:group:DOMAIN\134share\040admins:rwx default:group:DOMAIN\134backup\040admins:rwx default:mask::rwx default:other::--- |
Configuring AD User Shells & Home Dirs
As a final exercise, you can also configure your domain-joined Linux server to leverage Samba for single sign-on, so Active Directory users may log into the Linux file server, using Kerberos authentication. First, to automatically have home directories created for domain users upon login, create the following directory. This folder will house the home folders for domain users, keeping them separate from any Unix users, and avoiding any naming collisions.
1 2 3 |
$ sudo mkdir -p /home/DOMAIN |
Add the following line to the PAM common-session file.
1 2 3 4 5 |
$ vi /etc/pam.d/common-session session required pam_mkhomedir.so umask=0022 skel=/etc/skel |
Now add the Domain Admins group to the sudoers file so that any Domain Admins will have sudo capabilities upon login. Additionally, set the group_source to dynamic in the sudo.conf file. This will allow any member of the Domain Admins group to also manage Webmin.
1 2 3 4 5 6 7 8 9 10 11 |
$ sudo visudo # Members of the admin group may gain root privileges %admin ALL=(ALL) ALL %DOMAIN\\domain\ admins ALL=(ALL) ALL $ sudo echo "Set group_source dynamic" >> /etc/sudo.conf |
Finally restart the samba, winbind, and webmin daemons to enable these settings.
1 2 3 4 5 6 7 8 9 |
# sudo service smbd restart && sudo service nmbd restart && sudo service winbind restart && sudo service webmin restart smbd stop/waiting smbd start/running, process 6528 nmbd stop/waiting nmbd start/running, process 6544 winbind stop/waiting winbind start/running, process 6562 |
Conclusion
Though not without a few quirks, a Windows domain-integrated Linux file server is a great alternative for those environments in which running a Windows file server doesn’t quite fit the bill. Linux file servers are flexible, can be relatively inexpensive, and can give you excellent performance and reliability when properly configured. This walk-through hopefully gives you the necessary information to make Linux work nearly seamlessly for you and your users in your Windows domain.