For more than a decade, I used NFS on my home server to share files. I did not consider using Samba for anything but to provide Windows access to shares. NFSv3 then NFSv4 suited me, allowing per host/IP write access policy. The only main drawback was very crude handling of NFS server downtime: X sessions would be half-frozen, requiring restart to be usable once again.
However, I moved recently my servers to LXC (which I’ll probably document a bit later) and NFS server on Debian, as you can guess from nfs-kernel-server package’s name, is kernel-based: not only it apparently defeats the purpose of LXC containers to actually have a server within a container tied to the kernel, but it does not seems to really work reliably. I managed to get it running, but it had to be run on both the master host and within the container. Even then, depending which started first could make the shares unavailable to hosts.
I checked a few articles over the web (https://superuser.com/questions/515080/alternative-to-nfs-or-better-configuration-instable-network-simple-to-set-up, http://serverfault.com/questions/372151/nas-performance-nfs-vs-samba-vs-glusterfs etc) and it looked that, as of today, you can expect decent performances from Samba, as much as of NFS. That could possibly be proven wrong if I was using massively NFS, writing a lot through networked file systems, opening a big number of files simultaneously, moving big files around a lot, but I have really simple requirements: no latency when browsing directories, no latency when playing 720p/1080p videos and that’s about it.
I had already a restricted write access directory per user, via Samba, but I use it only on lame systems as temporary area: on proper systems, I use SSH/scp/rsync/git to manipulate/save files.
Dropping NFS, I have now quite a simple setup, here are relevant parts of my /etc/samba/smb.conf:
[global] ## Browsing/Identification ### # What naming service and in what order should we use to resolve host names # to IP addresses name resolve order = lmhosts host wins bcast #### Networking #### # The specific set of interfaces / networks to bind to # This can be either the interface name or an IP address/netmask; # interface names are normally preferred interfaces = eth0 # Only bind to the named interfaces and/or networks; you must use the # 'interfaces' option above to use this. # It is recommended that you enable this feature if your Samba machine is # not protected by a firewall or is a firewall itself. However, this # option cannot handle dynamic or non-broadcast interfaces correctly. bind interfaces only = true #### File names #### # remove characters forbidden on Windows mangled names = no # charsets dos charset = iso8859-15 unix charset = UTF8 ####### Authentication ####### # "security = user" is always a good idea. This will require a Unix account # in this server for every user accessing the server. See # /usr/share/doc/samba-doc/htmldocs/Samba3-HOWTO/ServerType.html # in the samba-doc package for details. security = user # Private network hosts allow = 192.168.1. # You may wish to use password encryption. See the section on # 'encrypt passwords' in the smb.conf(5) manpage before enabling. encrypt passwords = true # If you are using encrypted passwords, Samba will need to know what # password database type you are using. passdb backend = tdbsam obey pam restrictions = yes guest account = nobody invalid users = root bin daemon adm sync shutdown halt mail news uucp operator www-data sshd Debian-exim debian-transmission map to guest = bad user # This boolean parameter controls whether Samba attempts to sync the Unix # password with the SMB password when the encrypted SMB password in the # passdb is changed. unix password sync = yes #======================= Share Definitions ======================= realm = ... [commun] comment = Commun path = /srv/common browseable = yes writable = yes public = yes guest ok = yes valid users = @smbusers force group = smbusers create mode = 0660 directory mode = 0770 force create mode = 0660 force directory mode = 0770 [tmpthisuser] comment = Données protégées path = /srv/users/thisuser browseable = yes writable = yes public = yes valid users = thisuser create mode = 0600 directory mode = 0700 force create mode = 0600 force directory mode = 0700 guest ok = no
I installed package libpam-smbpass and edited /etc/pam.d/samba as follow:
@include common-auth @include common-account @include common-session-noninteractive @include common-password
For this setup to work, you need every user allowed to connect:
- to be member of group smbusers – including nobody (or whatever the guest account is) ;
- to have a unix password set ;
- to be known to samba (smbpasswd -e thisuser or option -a).
If you are not interested in per user access restricted area, only nobody account will need to be taken care of.
And, obviously, files and directories ownership and modes must be set accordingly:
cd /srv/common # (0770/drwxrwx---) GID : (nnnnn/smbusers) find . -type d -print0 | xargs -0 chmod 770 -v find . -type f -print0 | xargs -0 chmod 660 -v cd /srv/users # (0700/drwx------) UID : ( nnnn/ thisuser) GID : ( nnnn/ thisuser) find . -type d -print0 | xargs -0 chmod 700 -v find . -type f -print0 | xargs -0 chmod 600 -v # main directories, in addition, need sticky bit some future directory get proper modes chmod 2770 /srv/common/* chmod 2700 /srv/users/*
To access this transparently over GNU/Linux systems, just add in /etc/fstab:
//servername/commun /mountpoint cifs guest,uid=nobody,gid=users,iocharset=utf8 0 0
This assumes that any users entitled to access files belongs to users group. If not, update accordingly.
With this setup, there is no longer any IP based specific write access set but, over years, I found out it was quite useless for my setup.
The only issue I have is with files with colon within (“:”). Due to MS Windows limitations, CIFS list these files but access is made impossible. The easier fix I found was to actually rename these files (not a problem due to the nature of the files served) through a cronjob /etc/cron.hourly/uncolon :
#!/bin/bash # a permanent cifs based fix would be welcomed find "/srv" -name '*:*' -exec rename 's/://g' {} +
but I’d be interested in better options.