Build a File Server




Build a File Server

Share files with Linux, Windows, and Macintosh machines.

There are many different file-sharing protocols, each with strengths and weaknesses and each coming from different development backgrounds. The traditional file-sharing protocol for Unix is NFS (Network File System); for Mac OS, it's AppleShare; and for Windows, it's SMB (Server Message Block). Running a mixed-environment file server used to require supporting a multitude of protocols simultaneously, but in recent years, there has been a convergence on the use of CIFS (Common Internet File System) across all platforms. CIFS is derived from SMB and is the standard file-sharing method in recent versions of Windows. It is also extremely well supported under both Linux and Mac OS as a client and as a server, thanks to the Samba project.

The server component of Samba can even run as a domain controller for a Windows network and supports several authentication backends, including LDAP and TDB. Large installations may benefit from using LDAP, but it is far more complex to set up, so this hack will cover the use of TDB, which is quite suitable for networks up to several hundred users.

Enable Quota Support

To work with quotas, first install the quota package:

$ sudo apt-get install quota
            

Open /etc/fstab (the File System TABle) in your favorite editor and find the line that refers to the partition that will hold your shares. Add the usrquota and grpquota options. If you have /home on a separate partition, you will need to add the same options to that as well. The end result should look something like:

/dev/hda2     /        ext3 defaults,usrquota,grpquota    0   1
/dev/hda3     /home    ext3 defaults,usrquota,grpquota    0   2

Then set up the user and group quota files and remount the filesystem:

$ sudo touch /quota.user /quota.group
$ sudo chmod 600 /quota.*
$ sudo mount -o remount /
            

If you have a separate /home partition, do the same for that file:

$ sudo touch /home/quota.user /home/quota.group
$ sudo chmod 600 /home/quota.*
$ sudo mount -o remount /home
            

Since there is already data on the partitions, you will need to run the Quota Check tool to scan the filesystems and record current usage per user and group, then activate quota enforcement:

$ sudo quotacheck -avugm
$ sudo quotaon -avug
            

The mechanism is now in place to enforce quotas, but no users or groups have limits set, so there is no limit yet on how much of the disk they can use.

Install Samba

On your server, install Samba itself plus some additional packages for documentation, share browsing, and printer sharing:

$ sudo apt-get install samba samba-doc libcupsys2-gnutls10 \\
                 libkrb53 winbind smbclient
            

There are quite a few things to change in the default Samba config file, so open /etc/samba/smb.conf in an editor and go through it to adjust the settings to match the following example. Most of the example can be copied verbatim, but set WORKGROUP to the name of the Windows domain (you can even leave it at WORKGROUP) and set FILESERVER to the hostname of your Linux server:

[global]
   workgroup = WORKGROUP
   netbios name = FILESERVER
   server string = %h server (Samba, Ubuntu)

   passdb backend = tdbsam
   security = user
   username map = /etc/samba/smbusers
   name resolve order = wins bcast hosts
   domain logons = yes
   preferred master = yes
   wins support = yes

   ## Use CUPS for printing
   printcap name = CUPS
   printing = CUPS

   ## Set default logon
   logon drive = H:
   #logon script = scripts/logon.bat
   logon path = \\\\fileserver\\profile\\%U

   ## User management scripts
   add user script = /usr/sbin/useradd -m %u
   delete user script = /usr/sbin/userdel -r %u
   add group script = /usr/sbin/groupadd %g
   delete group script = /usr/sbin/groupdel %g
   add user to group script = /usr/sbin/usermod -G %g %u
   add machine script = /usr/sbin/useradd -s /bin/false/ -d /var/lib/nobody %u
   idmap uid = 15000-20000
   idmap gid = 15000-20000

   ## Settings to sync Samba passwords with system passwords
   passwd program = /usr/bin/passwd %u
   passwd chat = *Enter\\snew\\sUNIX\\spassword:* %n\\n *Retype\\snew\\s 
UNIX\\spassword:* %n\\n . passwd chat debug = yes unix password sync = yes ## Set the log verbosity level log level = 3 [homes] comment = Home valid users = %S read only = no browsable = no [printers] comment = All Printers path = /var/spool/samba printable = yes guest ok = yes browsable = no [netlogon] comment = Network Logon Service path = /home/samba/netlogon admin users = Administrator valid users = %U read only = no [profile] comment = User profiles path = /home/samba/profiles valid users = %U create mode = 0600 directory mode = 0700 writable = yes browsable = no

The commented-out line that says:

   #logon script = scripts/logon.bat

defines a Windows batch script that will be executed by Windows workstations as soon as a user logs in. This can be really handy if you want to apply standard settings to all computers on your network; you may want to define server drive mappings, set up printers, or configure a proxy server. If you have a logon.bat script, uncomment that line.

Create directories to store domain logons and profiles:

$ sudo mkdir -p /home/samba/netlogon
$ sudo mkdir /home/samba/profiles
$ sudo mkdir /var/spool/samba
$ sudo chmod 777 /var/spool/samba/
$ sudo chown -R root:users /home/samba/
$ sudo chmod -R 771 /home/samba/
            

Make sure Samba has seen your new configuration:

$ sudo /etc/init.d/samba restart
            

To enable WINS (Windows Internet Name Service) host resolution, edit /etc/nsswitch.conf and look for a line similar to:

hosts: files dns mdns

Change it to:

hosts: files wins dns mdns

Since your file server is going to be the domain controller (DC) for your Windows domain, you need to specify the computers that will be part of the domain. Open /etc/hosts and add all the servers and workstations:

192.168.0.10 server1
192.168.0.101 workstation1
192.168.0.102 workstation2
...
192.168.0.107 workstation7

Windows typically has a special user named Administrator, which is akin to the root user on Linux, so add the root user to the Samba password database and set up an alias for it. This will allow you to use the Administrator username to add new computers to the Windows domain:

$ sudo smbpasswd -a root
$ sudo sh -c "echo 'root = Administrator' > /etc/samba/smbusers"
            

To make sure everything has worked up to this point, use smbclient to query Samba:

$ smbclient -L localhost -U%
            

The output will include details of several standard services, such as netlogon and ADMIN, as well as the machines that have registered in the domain:

Domain=[WORKGROUP] OS=[Unix] Server=[Samba 3.0.21b]

        Sharename       Type      Comment
        ---------   ----      -------
        netlogon        Disk      Network Logon Service
        IPC$            IPC       IPC Service (fileserver server (Samba, Ubuntu))
        ADMIN$          IPC       IPC Service (fileserver server (Samba, Ubuntu))
Domain=[WORKGROUP] OS=[Unix] Server=[Samba 3.0.21b]

        Server               Comment
        ---------            -------
        FILESERVER           fileserver server (Samba, Ubuntu)

        Workgroup  Master
        ---------            -------
        WORKGROUP            FILESERVER

Map some standard groups used in Windows domains to equivalent Linux groups:

$ sudo net groupmap modify ntgroup="Domain Admins" unixgroup=root
$ sudo net groupmap modify ntgroup="Domain Users" unixgroup=users
$ sudo net groupmap modify ntgroup="Domain Guests" unixgroup=nogroup
            

To allow users to authenticate in the domain, they need to be defined in the domain controller. This process needs to be repeated for each user, but for now just create one user to start with by first adding the Linux user and then setting a password for that user in Samba. The user also needs to be placed in the users group that was aliased to the Windows group Domain Users a moment ago:

$ sudo useradd jon -m -G users
$ sudo smbpasswd -a jon
            

That user should now be able to authenticate on workstations within your domain, but there haven't yet been any shares added.

Add Shares

Start by adding a simple share that all users can access. First, create the directory that will become the share and set appropriate permissions on it:

$ sudo mkdir -p /home/shares/public
$ sudo chown -R root:users /home/shares/public
$ sudo chmod -R ug+rwx,o+rx-w /home/shares/public
            

Each share needs to be configured in Samba. Open /etc/samba/smb.conf and add a new stanza at the end:

[public]
  comment = Public Share
  path = /home/shares/public
  valid users = @users
  force group = users 
  create mask = 0660
  directory mask = 0771
  writable = yes

Each time you modify the configuration, you need to restart Samba:

$ sudo /etc/init.d/samba restart
            

The preceding public stanza allows all users in the @users group to access the share with full write privileges. This is probably not what you want in many cases. For a share that can be accessed only by specific users, you can substitute a line such as:

  valid users = jon,kyle,bill

To manage a large number of users, you can alternatively create another separate group, set permissions on the share appropriately, and specify it in the share definition. That way, you can add and remove users from that group without having to reconfigure or restart Samba:

  valid users = @authors

You can also create read-only shares by setting the writable option to no:

 writable = no

Another typical scenario is a share that is read/write by some users but read-only for others:

  valid users = @authors,@editors
  read list = @authors
  write list = @editors

Samba has a huge range of options for specifying various access restrictions, so refer to the extensive documentation at http://samba.org/samba/docs/ for more details.

Share Printers

If you have printers that you want to make accessible to your Windows workstations through Samba, start by following the steps in "Set Up Your Printer" [Hack #9] to get your printers working locally, and then use cupsaddsmb to tell Samba to make them available. To share all printers, run:

$ sudo cupsaddsmb -a
            

If you want to share only a specific printer, you can instead refer to its CUPS identity:

$ sudo cupsaddsmb laserjet