The steps we’ve looked at so far around setting up a home server are, in a sense, just a warmup. The ultimate step that brings the server to life is to set up Samba, the Linux software suite for serving files to Windows clients.
Choosing a Security Mode
Samba offers several security modes. The default is basic user-level security. Under this mode, you allow certain Linux users to connect to a Samba instance by creating passwords for them with smbpasswd
.
I had no reason to deviate from this default, and I like that it associates actions taken within a share with a specific Linux user (rather than a general “share user”).
Selecting Share Directories
While I wanted to associate actions, and files themselves, with Linux users, I didn’t want to enforce security within the circle of Samba-enabled Linux users. Rather, any Samba user was to have access to any Samba-accessible file, whether it was her own, someone else’s, or a public file.
This desire led me away from setting up sharing within the /home
hierarchy and toward new top-level directories–two, to be exact.
User-Originated Data vs. Other Stuff
Why two top-level directories? Well, user data on a PC is typically a mix of user-originated files and files sourced from elsewhere, digital music being a prime example. Traditional Windows directory structures combine the two on a single volume, which is unfortunate: it’s easiest to do backups at the volume level, but they’re much less important for stuff we could simply re-download than for items we create.
To promote better backup practices, then, I created one top-level directory (creatively, /data1
) for data that is user-originated and should be frequently backed up, and another (/data2
) for sourced-elsewhere files that could be backed up less often.
Since /home
data is definitely worth backing up frequently, I took the step of moving it into /data1
as linux-home
(and implementing a /home
> /data1/linux-home
symlink). I didn’t want to provide Samba access to that data, so a /data1/all-os
directory became the top-level /data1
share, with a /data2/all-os
counterpart on /data2
.
Putting Linux Permissions to Work
With a security mode chosen and share directories in place, the next step was to negotiate with the Linux permissions system and put it to work for me. I had the concept of the “core users” of the server being the only ones having Samba access, so I created a core-users
Linux group and made it the primary group for that subset of users. I also made it the group of /data1/all-os
and /data2/all-os
.
Making Future Files and Directories Group-Writeable
A user’s “umask” sets the permissions on files and directories he creates. Users’ umask on my system, 0022
, gives read privileges to a file’s group and read-execute privileges to a directory’s group. So far, so good: those permissions enable a file or directory created on the Samba share by one user to be viewed by other users. However, that umask denies write privileges to groups, which isn’t so hot in this context: it would prevent users from changing each others’ files.
Luckily, Samba offers force create mode
(for files) and force directory mode
, which override the permissions set based on umask. By setting those options to 0774
and 0775
, respectively, files and directories created through Samba would be group-writeable.
Getting SELinux Types Right
There’s one final, critical piece to the puzzle. Originally, I didn’t realize this step was needed, and leaving it out had brought this project to its knees–as in, my Samba share just did not work! …And I was dumbfounded as to why.
The critical step was to get the types right in my SELinux contexts.
By default, new top-level directories, like /data1
and /data2
, as well as directories created under them, are given type etc_runtime_t
. In a typical SELinux configuration, Samba cannot access the etc_runtime_t type.
To get things working, I had to set up file specifications to apply the samba_share_t
type to /data1/all-os
, to /data2/all-os
, and to any files and directories that would get created under them. The syntax, which was taken from the samba_selinux
man page (snapshot available on Dan Walsh’s blog), was as follows:
semanage fcontext -a -t samba_share_t "/data1/all-os(/.*)?"
semanage fcontext -a -t samba_share_t "/data2/all-os(/.*)?"
restorecon -R -v /data1/all-os
restorecon -R -v /data2/all-os
Samba shares have samba_share_t type
It’s Alive!
Once this range of steps was addressed, our Samba server came to life!
From Windows: Mapping drive letter to Samba share, copying up a file, reading it back
The end product works so seamlessly with Windows clients, one could easily forget there’s a Linux machine at the other end of the connection.
Appendix: Relevant Sections of smb.conf, as Written Out by SWAT
[global]
workgroup = MYGROUP
server string = Samba Server Version %v
log file = /var/log/samba/log.%m
max log size = 50
force create mode = 0774
force directory mode = 0775
cups options = raw
[data1]
comment = Frequently backed-up data
path = /data1/all-os
read only = No
[data2]
comment = Infrequently backed-up data
path = /data2/all-os
read only = No