managing samba shares with salt
2014-04-28
Since I attended SaltConf, I had all sorts of motivation to help out with the [https://github.com/saltstack-formulas](Salt Stack Formulas on Github), which I did.
I’ve found out that my brain, and work environment, does not always lend itself to that. For certain states (or a combination of states) to work, but also be decoupled from each other, I can’t always easily create a one-off git repo that is self contained.
We manage a few (5) sizable Samba servers (>20TB). Like it or not, we are a heavy Windows environment, and our order and image processing relies heavily upon said OS, and more importantly, UNC file path.
Aside from the names, the configuration is nearly identical across all shares (at the top level at least) so its fairly simple to templates this out.
What this state will do, is on a targeted system, it will loop through the pillar dictionary for ‘shares’, and create a file called: etc/smb.conf.d/share-name.conf
In our main smb.conf, we have a simple Include directive:
include={{ "{{ pillar.etc_prefix "}}}}/smb.conf.local
That file, smb.conf.local, is generated with simple cmd.run:
create-smb-conf-local:
cmd:
- run
- names:
- cat {{ "pillar.etc_prefix "}}}}/smb.conf.d/* > {{ "{{ pillar.etc_prefix "}}}}/smb.conf.local
When a “share” is added, the create-smb-conf-local is called to re-generate the included smb.conf.local file.
You can see the fill Samba state in my previous post, /2013/12/active-directory-authentication-with-salt/#samba-state.
Pillar Data
A pillar for shares should look like this:
shares:
- Public
- Private
- Department
Salt State
I call this ‘shares’, and I have an open JIRA issue for myself to merge this into the samba state but we’ll keep is as simple as it is:
shares/
├── init.sls
└── share.conf.jinja
Its nice and flat, nothing scary here
Shares Init
include:
- samba
{{ "{% for share in pillar.shares " }}%}
{{ "{{ pillar.etc_prefix " }}}}/smb.conf.d/{{" {{ share "}}}}:
file.managed:
- source: salt://shares/share.conf.jinja
- template: jinja
- context:
share: {{ share }}
- use:
cmd: create-smb-conf-local
{{ "{% endfor " }}%}
Shares Jinja Template
[{{ "{{ share "}}}}]
path = /data/{{ "{{ share "}}}}
admin users = @"domain admins"
map acl inherit = yes
inherit acls = yes
browseable = yes
public = yes
writable = yes
inherit permissions = yes
posix locking = yes
nt acl support = yes
create mask = 0775
directory mask = 0775
strict locking = no
store dos attributes = yes
csc policy = disable
inherit acls = Yes
map archive = No
map readonly = no
vfs objects = zfsacl full_audit
nfs4:mode = special
nfs4:acedup = merge
nfs4:chown = yes
## ACL inheritance is done by ZFS
inherit acls = no
## Avoid chmod(2) that breaks ACL
inherit permissions = no
force create mode = 00000
force security mode = 00000
force directory mode = 00000
force directory security mode = 00000
store dos attributes = yes
## ZFS ACL implements "write_acl" and "write_owner" permissions that
## is compatible with Windows (NT) ACL better than "dos filemode = yes"
dos filemode = no
full_audit:prefix = %u|%I|%m|%S
full_audit:success = mkdir rename unlink rmdir
full_audit:failure = none
full_audit:facility = local7
full_audit:priority = NOTICE
Final Results
So what does that look like?
share files:
smb.conf.d
|-- 000.globals
|-- Public
|-- Private
|-- Department
`-- keepme
[Private]
path = /data/Private
admin users = @"domain admins"
map acl inherit = yes
inherit acls = yes
browseable = yes
public = yes
writable = yes
inherit permissions = yes
posix locking = yes
nt acl support = yes
create mask = 0775
directory mask = 0775
strict locking = no
store dos attributes = yes
csc policy = disable
inherit acls = No
#inherit owner = Yes
map archive = No
map readonly = no
vfs objects = zfsacl full_audit
nfs4:mode = special
nfs4:acedup = merge
nfs4:chown = yes
## ACL inheritance is done by ZFS
inherit acls = no
## Avoid chmod(2) that breaks ACL
inherit permissions = no
force create mode = 00000
force security mode = 00000
force directory mode = 00000
force directory security mode = 00000
store dos attributes = yes
## ZFS ACL implements "write_acl" and "write_owner" permissions that
## is compatible with Windows (NT) ACL better than "dos filemode = yes"
dos filemode = no
full_audit:prefix = %u|%I|%m|%S
full_audit:success = mkdir rename unlink rmdir
full_audit:failure = none
full_audit:facility = local7
full_audit:priority = NOTICE
ZFS is not a requirement, but you may noticed I load the zfsacl module, so in is in this use-case. I don’t manage any non-ZFS CIFS servers at this point so it works for me.
Along with ACL’s, we enable some amount of logging. This is super handy if you also have a tool like Splunk, and you can easily watch the life of an Order in real time.