Coder Social home page Coder Social logo

bertvv / ansible-role-samba Goto Github PK

View Code? Open in Web Editor NEW
186.0 8.0 119.0 163 KB

Ansible role for managing Samba as a file server on RedHat- and Debian-based linux distros.

Home Page: https://galaxy.ansible.com/bertvv/samba/

License: Other

Shell 65.15% Jinja 34.85%

ansible-role-samba's Introduction

Ansible role bertvv.samba

An Ansible role for setting up Samba as a file server.

Due to lack of time and resources, I have handed over the maintenance of this role to @vladgh. I am no longer able to follow up on Issues and PRs and to make sure that new releases are of sufficiently high quality to be actually usable.

Thanks to everyone who showed their support during the years, to all contributors and especially to @vladgh for graciously volunteering to take over maintenance.


The responsibilities of this role are to:

  • Install the necessary packages
  • Configure SELinux settings (when SELinux is active)
  • Create share directories
  • Manage Samba users and passwords
  • Manage access to shares

The following are not considered concerns of this role, and you should configure these using another role (e.g. bertvv.rh-base:

  • Managing firewall settings.
  • Creating system users. Samba users should already exist as system users.

If you like/use this role, please consider giving it a star! Thanks!

CVE-2017-7494

A remote code execution vulnerability may affect your Samba server installation. Samba versions 3.5.0 and before 4.6.4 are affected. If SELinux is enabled on your system, it is NOT vulnerable.

This role will check if the installed version of Samba is affected by the vulnerability and apply the proposed workaround: adding nt pipe support = no to the [global] section of the configuration. Remark that this disables share browsing by Windows clients.

You can explicitly disable the fix if necessary, by setting the role variable samba_mitigate_cve_2017_7494 to false.

More info: https://access.redhat.com/security/cve/cve-2017-7494

Requirements

No specific requirements

Role Variables

Variable Default Comments
samba_apple_extensions no When yes, enables support for Apple specific SMB extensions. Required for Time Machine support to work (see below)
samba_create_varwww_symlinks false When true, symlinks are created in web docroot to the shares. (var/www/ or /var/www/html depending on platform)
samba_cups_server localhost:631 Value for the global option cups server (only needed when samba_printer_type is "cups")
samba_domain_master true When true, smbd enables WAN-wide browse list collation
samba_global_include - Samba-compatible configuration file with options to be loaded to [global] section (see below)
samba_guest_account - Guest account for unknown users
samba_homes_include - Samba-compatible configuration file with options to be loaded to [homes] section (see below)
samba_interfaces [] List of network interfaces used for browsing, name registration, etc.
samba_load_homes false When true, user home directories are accessible.
samba_load_printers false When true, printers attached to the host are shared
samba_local_master true When true, nmbd will try & become local master of the subnet
samba_log - Set the log file. If left undefined, logging is done through syslog.
samba_log_size 5000 Set the maximum size of the log file.
samba_log_level 0 Set Samba log level, 0 is least verbose and 10 is a flood of debug output.
samba_map_to_guest bad user Behaviour when unregistered users access the shares.
samba_mitigate_cve_2017_7494 true CVE-2017-7494 mitigation breaks some clients, such as macOS High Sierra.
samba_netbios_name {{ ansible_hostname }} The NetBIOS name of this server.
samba_passdb_backend tdbsam Password database backend.
samba_preferred_master true When true, indicates nmbd is a preferred master browser for workgroup
samba_realm - Realm domain name
samba_printer_type cups value for the global option printing and printcap name
samba_security user Samba security setting
samba_server_max_protocol - Specify a maximum protocol version offered by the server.
samba_server_min_protocol - Specify a minimum protocol version offered by the server.
samba_server_string fileserver %m Comment string for the server.
samba_shares_root /srv/shares Directories for the shares are created under this directory.
samba_shares [] List of dicts containing share definitions. See below for details.
samba_users [] List of dicts defining users that can access shares.
samba_wins_support true When true, Samba will act as a WINS server
samba_workgroup WORKGROUP Name of the server workgroup.

Defining users

In order to allow users to access the shares, they need to get a password specifically for Samba:

samba_users:
  - name: alice
    password: ecila
  - name: bob
    password: bob
  - name: charlie
    password: eilrahc

Unfortunately, passwords have to be in plain text for now. Also, remark that this role will not change the password of an existing user.

These users should already have an account on the host! Creating system users is not a concern of this role, so you should do this separately. A possibility is my role bertvv.rh-base. An example:

rhbase_users:
  - name: alice
    comment: 'Alice'
    password: !!
    shell: /sbin/nologin
    groups:
      [...]

This user is not allowed to log in on the system (e.g. with SSH) and would only get access to the Samba shares.

Defining shares

Defining Samba shares and configuring access control can be challenging, since it involves not only getting the Samba configuration right, but also user and file permissions, and SELinux settings. This role attempts to simplify the process.

To specify a share, you should at least give it a name:

samba_shares:
  - name: readonlyshare

This will create a share with only read access for registered users. Guests will not be able to see the contents of the share.

A good way to configure write access for a share is to create a system user group, add users to that group, and make sure they have write access to the directory of the share. This role assumes groups are already set up and users are members of the groups that control write access. Let's assume you have two users jack and teach, members of the group pirates. This share definition will give both read and write access to the pirates:

samba_shares:
  - name: piratecove
    comment: 'A place for pirates to hang out'
    group: pirates
    write_list: +pirates

Guests have no access to this share, registered users can read. You can further tweak access control. Read access can be extended to guests (add public: yes) or restricted to specified users or groups (add valid_users: +pirates). Write access can be restricted to individual pirates (e.g. write_list: jack). Files added to the share will be added to the specified group and group write access will be granted by default.

This is an example of configuring multiple vfs object modules to share a glusterfs volume. VFS object options are optional. The necessary VFS object modules must be present/installed outside this role. In this case samba-glusterfs was installed on centos. See samba documentation for how to install or what the default VFS object modules are.

samba_shares:
  - name: gluster-app_deploys
    comment: 'For samba share of volume app_deploys'
    vfs_objects:
      - name: audit
        options:
          - name: facility
            value: LOCAL1
          - name: priority
            value: NOTICE
      - name: glusterfs
        options:
          - name: volume
            value: app_deploys
          - name: logfile
            value: /var/log/samba/glusterfs-app_deploys.%M.log
          - name: loglevel
            value: 7
    path: /
    read_only: no
    guest_ok: yes
    write_list: tomcat
    group: tomcat

A complete overview of share options follows below. Only name is required, the rest is optional.

Option Default Comment
browseable - Controls whether this share appears in file browser.
comment - A comment string for the share
create_mode 0664 See the Samba documentation for details.
directory_mode 0775 See the Samba documentation for details.
include_file - Samba combatible configuration file with options to be included for this share (see below).
force_create_mode 0664 See the Samba documentation for details.
force_directory_mode 0775 See the Samba documentation for details.
group users The user group files in the share will be added to.
guest_ok - Allow guest access.
name (required) - The name of the share.
owner root Set the owner of the path
path /{{samba_shares_root}}/{{name}} The path to the share directory.
public no Controls read access for guest users
setype samba_share_t The SELinux type of the share directory
valid_users - Controls read access for registered users. Use the syntax of the corresponding Samba setting.
vfs_objects - See the Samba documentation for details.
writable - Writable for guests.
write_list - Controls write access for registered users. Use the syntax of the corresponding Samba setting.

The values for valid_users and write_list should be a comma separated list of users. Names prepended with + or @ are interpreted as groups. The documentation for the Samba configuration has more details on these options.

Adding arbitrary configuration files

You can add settings that are not supported by this role out-of-the-box through custom configuration files that will be included from the main configuration file. There are three types of include files: for the global section, for the homes section, and for individual shares. Put your custom configuration files in a subdirectory templates, relative to your master playbook location. Then, specify them in the variables samba_global_include, samba_homes_include, or include_file in the samba_shares definition.

Your custom configuration files are considered to be Jinja templates, so you can use Ansible variables inside them. The configuration files will be validated to ensure they are syntactically correct.

For example, to include templates/global-include.conf, set:

samba_global_include: global-include.conf

Remark that is it not necessary to specify the templates/ directory.

Likewise, to include templates/piratecove-include.conf, specific for the piratecove share (see the example above); set:

samba_shares:
  - name: piratecove
    comment: 'A place for pirates to hang out'
    group: pirates
    write_list: +pirates
    include_file: piratecove-include.conf

The test playbook has some examples. The custom configuration files can be found in the docker-tests branch.

Dependencies

No dependencies.

Example Playbook

See the test playbook

Testing

This role is tested using Ansible Molecule. Tests are launched automatically on Travis CI after each commit and PR.

This Molecule configuration will:

  • Run Yamllint and Ansible Lint
  • Create a Docker container
  • Run a syntax check
  • Apply the role with a test playbook
  • Run acceptance tests with BATS

This process is repeated for the supported Linux distributions.

Local test environment

If you want to set up a local test environment, you can use this reproducible setup based on Vagrant+VirtualBox: https://github.com/bertvv/ansible-testenv. Steps to install the necessary tools manually:

  1. Docker, BATS and smbclient should be installed on your machine (assumed to run Linux). No Docker containers should be running when you start the test.
  2. As recommended by Molecule, create a python virtual environment
  3. Install the software tools python3 -m pip install molecule docker yamllint ansible-lint
  4. Navigate to the root of the role directory and run molecule test

Molecule automatically deletes the containers after a test. If you would like to check out the containers yourself, run molecule converge followed by molecule login --host HOSTNAME.

The Docker containers are based on images created by Jeff Geerling, specifically for Ansible testing (look for images named geerlingguy/docker-DISTRO-ansible). You can use any of his images, but only the distributions mentioned in meta/main.yml are supported.

The default config will start a Centos 7 container. Choose another distro by setting the MOLECULE_DISTRO variable with the command, e.g.:

MOLECULE_DISTRO=debian9 molecule test

or

MOLECULE_DISTRO=debian9 molecule converge

You can run the acceptance tests on both servers with molecule verify or manually with

SUT_IP=172.17.0.2 bats molecule/default/files/samba.bats

You need to initialise the variable SUT_IP, the system under test's IP address. The server, smb1, should have IP address 172.17.0.2.

Contributing

Issues, feature requests, ideas are appreciated and can be posted in the Issues section.

Pull requests are also very welcome. The best way to submit a PR is by first creating a fork of this Github project, then creating a topic branch for the suggested change and pushing that branch to your own fork. Github can then easily create a PR based on that branch. Don't forget to add yourself to the list of contributors below!

License

2-clause BSD license, see LICENSE.md

Contributors

This role could only have been realized thanks to the contributions of the people listed below. If you have an idea to improve it even further, don't hesitate to pitch in!

Issues, feature requests, ideas, suggestions, etc. can be posted in the Issues section.

Pull requests are also very welcome. Please create a topic branch for your proposed changes. If you don't, this will create conflicts in your fork after the merge. Don't hesitate to add yourself to the contributor list below in your PR!

Ben Tomasik, Bengt Giger, Bert Van Vreckem (maintainer), Birgit Croux, DarkStar1973, George Hartzell, Ian Young, Jonas Heinrich, Jonathan Underwood, Karl Goetz, morbidick, Paul Montero, Slavek Jurkowski, Sven Eeckeman, Tiemo Kieft, Tobias Wolter, Tomohiko Ozawa, Robin Ophalvens.

ansible-role-samba's People

Contributors

bertvv avatar darkstar1973 avatar goetzk avatar iangreenleaf avatar jonathanunderwood avatar kota65535 avatar morbidick avatar onny avatar robinoph avatar slavekjurkowski2 avatar sveneeckeman avatar thiagogomesverissimo avatar tomislacker avatar towo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ansible-role-samba's Issues

Using include for other configurations doesn't work

I am defining a global include with:

vars:
    # Include global options from `templates/global-include.conf`
    samba_global_include: global-include.conf

After running Ansible and SSH'ing into the machine, I see my file has made it:

❯ ls /etc/samba/global-include.conf
/etc/samba/global-include.conf

And that a configuration line has made it into /etc/samba/smb.conf:

❯ cat /etc/samba/smb.conf | grep include
  include = global-include.conf

However, this is an invalid smb.conf as shown with testparm:

❯ testparm
Load smb config files from /etc/samba/smb.conf
rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384)
Can't find include file global-include.conf
...

The fix for me was making an absolute path definition in the Jinja template:

diff --git a/templates/smb.conf.j2 b/templates/smb.conf.j2
index a57d8bd..58e8273 100755
--- a/templates/smb.conf.j2
+++ b/templates/smb.conf.j2
@@ -79,7 +79,7 @@
 {% endif %}

 {% if samba_global_include is defined %}
-  include = {{ samba_global_include }}
+  include = /etc/samba/{{ samba_global_include }}
 {% endif %}

 {% if samba_load_homes %}
@@ -91,7 +91,7 @@
 {% endif %}

 {% if samba_home_include is defined %}
-  include = {{ samba_home_include }}
+  include = /etc/samba/{{ samba_home_include }}
 {% endif %}

 {% if samba_shares|length > 0 %}
@@ -138,7 +138,7 @@
   directory mode = {{ share.directory_mode|default('0775') }}
   force directory mode = {{ share.force_directory_mode|default('0775') }}
 {% if share.include_file is defined %}
-  include = {{ share.include_file }}
+  include = /etc/samba/{{ share.include_file }}
 {% endif %}

 {% endfor %}

Is this the correct fix for this bug? Would you be amenable to a PR?

Arbitrary samba configuration options

Hi,
It would be good to see support for arbitrary configuration options added, OR, the ability to include other files.

As it stands there are lots of samba configuration options which might need a tweak which can't be used because the template overwrites them on every ansible run.

AIX Support / AIX PR / Thoughts/Concerns

Howdy

I've forked and added support for the IBM AIX Operating System, and have pulled it into my master branch here: https://github.com/d-little/ansible-role-samba

I'm still doing some testing to ensure that it works as expected, but if it does work, any thoughts or concerns with me submitting a PR to get this into the root project?

It's a different architecture, and outside the scope of the original 'RedHat- and Debian-based linux distros'; I'd just wanted a single role I can use on my Linux and AIX servers :) If there's a preference to keep AIX out of this role I can split it out and maintain it separately, probably remove the Linux support entirely and just have two separate roles per-environment.

Also NB: I'm very new to putting this together in Ansible, only a few weeks in, so I might have done thing's very wrong! Please let me know.

Thanks

How to add special smb.conf setting.

Hi,

How do I get the global setting ntlm auth = yes to be added to the smb.conf file? I need this to deal with login's from some old machines on my LAN. Note that I'm aware that ntlmv1 is broken from a security standpoint but I need it none-the-less.

I tried the templates/global-include.conf trick but the samba role isn't finding the file:

fatal: [ansible-nas]: FAILED! => {"changed": false, "msg": "Could not find or access 'global-include.conf'\nSearched in:\n\t/home/skb/.ansible/roles/bertvv.samba/templates/global-include.conf\n\t/home/skb/.ansible/roles/bertvv.samba/global-include.conf\n\t/home/skb/.ansible/roles/bertvv.samba/tasks/templates/global-include.conf\n\t/home/skb/.ansible/roles/bertvv.samba/tasks/global-include.conf\n\t/home/skb/my-ansible-nas/ansible-nas/templates/global-include.conf\n\t/home/skb/my-ansible-nas/ansible-nas/global-include.conf"}

In my case I'm including a playbook that exists in a sub-directory beneath where I define the samba_global_include: global-include.conf in a master playbook. I include the playbook ansible-nas\nas.yml after defining the above symbol.

The role does engage in a search for the file so I believe it's seeing the symbol definition but it won't look in the templates directory from the directory of the top-most playbook.

Any insights here?

-Dale

Note that samba_mitigate_cve_2017_7494 disables share browsing

samba_mitigate_cve_2017_7494, which sets nt pipe support = no prevents access to IPC$. Therefore, Windows clients cannot browse shares anymore. README should state this behaviour.

The best option might be to ignore samba_mitigate_cve_2017_7494 on patched Samba versions.

CVE-2017-7494 Mitigation is activated even if Samba version is newer then the affected one

In Ubuntu 20.04 Samba Version 4.11.6 is installed. Even though the mitigation option nt pipe support = no is added to the global part of smb.conf. This results in windows clients not able to connect to the shares.
The reason is that ubuntu has its own naming convention for the version number which is not correctly detected by the mechnism already in place. The following happen on ubuntu.

$ smbd --version
Version 4.11.6-Ubuntu

Therefore the mechnism to detect the samba version fails to remove all text except the version number. I would propose to replace the shell command in main.yml

smbd --version | sed 's/Version //'

by

smbd --version | sed 's/Version //' | sed 's/-Ubuntu//'
# or even
smbd --version | sed 's/Version //' | sed 's/-.*//'

use "map to guest = never"

Please use map to guest = never as default (which is the Samba default according to the man page).

If you use map to guest = bad user, one will be asked for credentials when browsing available samba shares from a Windows client. Windows will save those credentials, because they apparently worked (but were actually wrong). The Windows client will never be asked again for those credentials on browsing shares.

For me, it also broke somehow the authentication for a share (although the Windows GUI asked again for a password) because something seems to mess up in the authentication process then.

Wrong service names for Arch Linux

The service names for Arch Linux are incorrect in roles/samba/vars/os_Archlinux.yml

https://wiki.archlinux.org/title/Samba#Enabling_and_starting_services

TASK [bertvv.samba : Start Samba service(s)] ***********************************
failed: [test] (item=smbd) => {"ansible_loop_var": "item", "changed": false, "item": "smbd", "msg": "Could not find the requested service smbd: host"}
failed: [test] (item=nmbd) => {"ansible_loop_var": "item", "changed": false, "item": "nmbd", "msg": "Could not find the requested service nmbd: host"}

Allow for changing the user password

Hi,

If I read your code correctly, you can't change the password of an existing Samba user.

Could you please change the role so that a changed password in the Ansible configuration also changed the password of the user?

Cheers,
Thomas

adding users fails

Found your role when searching for a way to create samba users ... unfortunately it fails.
Do you assume that the underlying shell/system account already exists? Otherwise I'd have to add a task doing "useradd" before ...

Fails if filesystem is EXFAT

Hey, thanks so much for this ansible role!

I am trying to get this up and running, to share data from an EXFAT drive. However, it fails at TASK [bertvv.samba : Create share directories]. This because the EXFAT filesystem does not support chown/etc, and so chrgrp is failing.

Example error:

failed: [nas] (item={'name': 'documents', 'comment': 'Documents', 'guest_ok': True, 'public': True, 'writable': True, 'browsable': True, 'path': '/server/documents'}) => changed=false
  ansible_loop_var: item
  gid: 0
  group: root
  item:
    browsable: true
    comment: Documents
    guest_ok: true
    name: documents
    path: /server/documents
    public: true
    writable: true
  mode: '0777'
  msg: chgrp failed
  owner: root
  path: /server/documents
  size: 262144
  state: directory
  uid: 0

is it possible to skip/handle this task differently based on the filesystem?

Thanks!

Don't print passwords out to the log

I'm currently storing my samba passwords in an ansible-vault file. It was annoying to see them printed when ansible runs.

While it's not perfect, I believe that 'no_log' is the current ansible state of the art for hiding passwords.

This works for me:

@@ -100,6 +100,7 @@
     || (echo {{ item.password }}; echo {{ item.password }}) \
     | smbpasswd -s -a {{ item.name }}
   with_items: "{{ samba_users }}"
+  no_log: true
   register: create_user_output
   changed_when: "'Added user' in create_user_output.stdout"
   tags: samba

g.

This code is not idempotent

This code is not idempotent


- name: Create Samba users if they don't exist yet
  shell: >
    (pdbedit -L | grep {{ item.name }} 2>&1 > /dev/null) \
    || (echo {{ item.password }}; echo {{ item.password }}) \
    | smbpasswd -s -a {{ item.name }}
  with_items: samba_users
  when: samba_users is defined
  tags: samba

There should be some check if all users in the list exists

- name: Check if user exists
  shell: pdbedit -L | grep -c {{ samba_user }} || true
  register: shell_output
  changed_when: False

but with_items ...

Fout in ansible documentatie: samba_home(s)_include

Expected Behavior

templates/home-include.conf wordt gekopieerd naar /etc/samba/ door gebruik van de volgende variable: samba_home_include: home-include.conf

Current Behavior

De config file wordt niet gekopieerd van de host naar de virtual machine.

Possible Solution

  • Gebruik de variable samba_homes_include en verander de documentatie zodat die overeenkomt met de definitie in tasks/main.yml
  • Of verander de definitie van de module op lijn 100 in tasks/main.yml naar src: "{{ samba_homes_include }}" zodat dit overeenkomt met de documentatie

No support for "allow hosts"

There is currently no way to restrict shares by host / subnet.

Basic functionality can be accomplished by adding the following to templates/smb.conf.j2. I recommend including it after "force directory mode = {{ share.force_directory_mode|default('0775') }}".

{% if share.allow_hosts is defined %}
  allow hosts = {% for entry in share.allow_hosts %}{{ entry }}{% if not loop.last %}, {% endif %}{% endfor %}
{% endif %}

Example Configuration:

samba_shares:
  - name: /srv/shares/test
    write_list: +users
    setype: public_content_rw_t
    allow_hosts:
      - 192.168.1.0/24
      - 172.16.10.0/255.255.255.0

Keeping previous shares intact

As far as I can see in this role it doesn't keep previous shares intact.
For eg, if the role is called as a dependency to another, it'll wipe out any other shares previously defined.

It can be hard to find out if samba has been configured or shares defined therefore to keep things clean maybe the onus should be on the user to define if it should do a config reset or just add share info. A flag perhaps?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.