From Newroco tech docs
Jump to: navigation, search


Samba Installation


Set a static IP

# vi /etc/network/interfaces 

should look something like this:

  2. auto enp0s3
  3. iface enp0s3 inet static
  4. address
  5. netmask
  6. network
  7. broadcast
  8. gateway
  9. dns-nameservers
  10. dns-search example.local

Note: Don't use real world TLDs like


Installing the package:

# apt-get install samba ntp winbind dnsutils

Stop samba and empty /etc/samba/smb.conf:

# service samba-ad-dc stop
# > /etc/samba/smb.conf

For a DC continue as below, for a fileserver go to #Creating a samba fileserver

For creating a domain use this command

# samba-tool domain provision --interactive --use-rfc2307

For Realm put your desired realm e.g. example.local or a TLD you control absolutely, for DNS forwarder IP address put your main (Internet facing e.g. firewall) DNS server IP address (whether you have a multiple domain bind setup or just using a DNS service on your router) and for the others you can just press enter. NB every DC should have an appropriate forwarder set

If you get an error about ldb, make sure packages samba-dsdb-modules and samba-vfs-modules are installed, if not install them:

  1. apt-get install samba-dsdb-modules samba-vfs-modules

For joining an existing domain use this command

# samba-tool domain join domain.local DC -Usamba.user --realm=domain.local --server=primary.dc.ip

Note: The user used for the join needs to be in group "Domain Admins", you can add a samba user to this group like this:

  1. samba-tool group addmembers "Domain Admins" samba.user

Now start the samba DC service:

# service samba-ad-dc start

If you end up with multiple domain controllers in your domain, edit your /etc/network/interfaces file and remove the nameserver reference, then add, on each DC, all of them to the resolvconf template:

  1. # vi /etc/resolvconf/resolv.conf.d/tail
  2. search example.local
  3. nameserver ip.addr.a.dc
  4. nameserver ip.addr.b.dc
  5. nameserver ip.addr.c.dc

Don't forget to update resolv.conf afterwards

# resolvconf -u

SSL Certificate

If you want to use LDAPS you can create a self-signed certificate

  1. openssl req -newkey rsa:2048 -keyout /var/lib/samba/private/tls/samba-key.pem -nodes -x509 -days 3650 -out /var/lib/samba/private/tls/samba-cert.pem

Change permissions for the key

  1. chmod 600 /var/lib/samba/private/tls/samba-key.pem

And add these lines in /etc/samba/smb.conf:

  1. tls enabled = yes
  2. tls keyfile = /var/lib/samba/private/tls/samba-key.pem
  3. tls certfile = /var/lib/samba/private/tls/samba-cert.pem
  4. tls cafile =

Restart samba

  1. service samba-ad-dc restart

Note well: when using a self-signed certificate most applications would not trust them by default, you have to add it as a trusted certificate.

Checking the replication

If you end up with multiple DCs it's probably a good thing to check that replication works. On a newly joined DCs test manual replication to see if it works both ways, like this:

  1. samba-tool drs replicate <new-dc> <primary-dc> dc=<domain>,dc=local
  2. samba-tool drs replicate <primary-dc> <new-dc> dc=<domain>,dc=local

Next test if automatic replication works

  1. samba-tool drs showrepl

Samba & LDAP

Authenticating LDAP user

Standard LDAP config in Samba (& elsewhere) is to require a connection to be authenticated before other access granted. This can often be disabled, but it's better practice (and as easy) to create an account for the service that needs access, and use that for connection. The base string for the authenticating user will be of the form:

  1. cn=<username>,cn=<userbasegroup>,dc=<firstpartofADdomainname>,dc=<secondpartofADdomainname>

Base DN

Will vary on setup, but simple base DN is likely to be of the form:

  1. dc=<firstpartofADdomainname>,dc=<secondpartofADdomainname>
Where AD domain name (realm) was of the form
  1. firstpart.secondpart
. If the domain name has more parts you will need those parts expressed as separate DCs.

Secure LDAP quick workaround

Not recommended in production if LDAP authing outside a firewall.

Samba 4 LDAP is secure by default which makes it hard for some simpler LDAP auth systems. If no other solution or for initial testing purposes, secured LDAP can be disabled by adding the following line to smb.conf main section:

  1. ldap server require strong auth = no

Creating a samba fileserver

To make your samba installation into a fileserver. This assumes you already have a working DC or 2 and this server will be a member server for load balancing/egg separation purposes. In this scenario you should set your DNS forwarders to be any local or routable DCs for the domain you want the fileserver to be part of. This can be done by editing resolvconf's head file:

#vi /etc/resolvconf/resolv.conf.d/head
nameserver ip.addr.dc.1
nameserver ip.addr.dc.2

Then updating resolv.conf with

# resolvconf -u

Installation and configuration

Depending on how your base machine was created you may need to add the universe repository:

apt-get install software-properties-common
add-apt-repository universe

Then install these additional packages:

# apt-get install libnss-winbind libpam-winbind acl libpam-krb5 krb5-user

And configure nsswitch to be able to use winbind:

# vi /etc/nsswitch.conf

passwd:         compat winbind
group:          compat winbind

Set up your shares

# vi /etc/samba/smb.conf

Add the following configuration to the top section

  1. [global]
  2. workgroup = workgroupname
  3. server string = yourservername
  4. security = ads
  5. realm = WORKGROUPNAME.TLD # common to be .LOCAL
  7. socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=131072 SO_SNDBUF=131072
  8. use sendfile = true
  10. idmap config * : backend = tdb
  11. idmap config * : range = 100000-299999
  12. idmap config workgroupname : backend = rid
  13. idmap config workgroupname : range = 10000-99999
  14. winbind separator = +
  15. winbind enum users = yes
  16. winbind enum groups = yes
  17. winbind use default domain = yes
  18. winbind refresh tickets = yes
  20. restrict anonymous = 2
  21. log file = /var/log/samba/log.%m
  22. max log size = 50
  25. deadtime = 45
  26. read raw = Yes
  27. write raw = Yes
  29. server signing = mandatory
  31. # Network
  32. interfaces = ens3 # change to suit, ens3 is first interface if using a [ VM built as per our approach]
  33. bind interfaces only = true
  34. log file = /var/log/samba/log.%m
  35. log level = 1
  36. max log size = 1000
  37. logging = syslog@0 file
  38. panic action = /usr/share/samba/panic-action

Example share definition allowing read/write for all domain users:

       comment = What this share is 
       writeable = yes
       write list = @"Domain Users"
       path = /path/to/data/
       force directory mode = 755
       force group = Domain Users
       force create mode = 665
       valid users = @"Domain Users"
       create mode = 665
       directory mode = 775

Example read-only share definition

       comment = What this share is 
       writeable = no
       read list = @"Domain Users"
       path = /path/to/readonlydata/
NB if your shared volume is coming from a network source like iscsi it is recommended you don't make your share and the mounted volumes directly match; rather shares should reference directories within the mounted volume i.e. if you have an iscsi mount at
  1. /mnt/myiscsi
your samba share should be at
  1. /mnt/myiscsi/myshare
or a further sub branch. This ensures that is the network source is not available, user data isn't written to (nor fills) your fileserver's / filesystem.

If a share should be accessed by 'Domain Users', give the shares folder necessary permissions for the group and set group ownership to "domain users"

  1. chown :"domain users" /path/to/folder

Restart the samba services

# systemctl restart winbind nmbd smbd

And then join the domain using a domain user that has appropriate privileges e.g. is a member of the Domain Admins group for that domain:

# net ads join -U 

NB which domain to join is determined from the configuration files.


Assuming you got no joining errors at the last step above (DNS update ones can be ignored for now), you can verify your server is seeing domain users correctly by

# getent passwd

This should return the normal contents of /etc/passwd, pause for a moment and then continue with all the domain users.

You can then test the availability of the shares you've created

# smbclient -L your.ip.add.ress -U adomain.username

This should ask for your password and if correctly entered return information of the form

  1. Domain=[EXAMPLE] OS=[Windows 6.1] Server=[Samba 4.3.11-Ubuntu]
  3. Sharename Type Comment
  4. --------- ---- -------
  5. sharename Disk What this share is
  6. IPC$ IPC IPC Service (yourservername)
  7. Domain=[EXAMPLE] OS=[Windows 6.1] Server=[Samba 4.3.11-Ubuntu]
  9. Server Comment
  10. --------- -------
  15. Workgroup Master
  16. --------- -------

NB you may get different results depending whether you are testing from a machine in the domain or not - if it works from a machine in the domain but not in one from outside, check your that the relevant share configs have


and the general section doesn't contain a

restrict anonymous

with a value higher than 0 (which is the default i.e. the line isn't needed unless you want to restrict unauthenticated browsing of share listings)

When working remotely without access to a GUI machine that can access the smb fileserver, a final test (e.g. checking users have correct permissions when they have the share mapper) can be performed by mounting the share from the command line. This requires the cifs-util package which can be installed with

apt-get install cifs-utils

and then running

mount -t cifs //server-ip/sharename /mountpoint -o 

where is an SMB user. If the mount is successful you can check that user has the permissions you expect it to have in terms of file access/creation/deletion etc..

Adding samba users

  2. #!/bin/bash
  4. if [ $# -eq 0 ] ; then
  5. printf "Username(format name.surname):"
  6. read username
  7. printf "Email:"
  8. read email
  9. printf "Fullname(format Name Surname):"
  10. read fullname
  11. samba-tool user add $username --mail-address=$email
  12. samba-tool user setexpiry $username --noexpiry
  13. pdbedit -u $username -f "$fullname"
  14. else
  15. while IFS='' read -r line || [[ -n "$line" ]]; do
  16. IFS=':' read -a userinfo <<< "$line"
  17. samba-tool user add ${userinfo[0]} ${userinfo[1]} --mail-address=${userinfo[2]}
  18. samba-tool user setexpiry ${userinfo[0]} --noexpiry
  19. pdbedit -u ${userinfo[0]} -f "${userinfo[3]}"
  20. done < "$1"
  21. fi

If the script is called with no argument, it asks the information for the user to be added, but it can be called with a file as an argument that contains a user list in the following format:

  2. Name
  3. Name
  4. Name

Adding Service accounts

Service accounts

Tips and Tricks

Get user info

If you want to get information about a samba user (displayName, mail, etc.), i found ldapsearch to show the most details

  1. ldapsearch -xLLL -H ldap://localhost:389 -D ",cn=users,dc=<domain>,dc=local" -W -b "dc=<domain>,dc=local" '(&(cn=<user-to-search-for>))'

If last part ('(&(cn=<user-to-search-for>))') is omitted it will show all users.

Setting an email for a user

When creating the user

  2. samba-tool user add <username> --mail-address=<email>

For an existing user

Package ldap-utils is required so install it if not already:

  2. apt-get install ldap-utils

Create a file entrymods.ldif:

  2. dn: cn=<username>,cn=Users,dc=<firstpartofdomain>,dc=<secondpartofdomain>
  3. changetype: modify
  4. replace: mail
  5. mail: <email>
  6. -

Set the email with ldapmodify command using a samba user that belongs to "Account Operators" group:

  2. ldapmodify -x -D "cn=<username>,cn=Users,dc=<firstpartofdomain>,dc=<secondpartofdomain>" -W -H ldaps://localhost -f entrymods.ldif

Rename username

Rename the CN (ldb-tools should be installed for ldbrename command)

  1. ldbrename -H ldap://localhost CN=<olduser>,CN=Users,DC=<domain>,DC=local CN=<newuser>,CN=Users,DC=<domain>,DC=local -U <user>

Create a file chuser.ldif:

  1. dn: cn=<newuser>,cn=Users,dc=<domain>,dc=local
  2. changetype: modify
  3. replace: sAMAccountName
  4. sAMAccountName: <newuser>
  5. -
  6. replace: userPrincipalName
  7. userPrincipalName: <newuser>@<domain>.local
  8. -

Change sAMAccountName and userPrincipalName (the user used below should belong to "Account Operators" group)

  1. ldapmodify -x -D "cn=<user>,cn=Users,dc=<domain>,dc=local" -W -H ldap://localhost -f chuser.ldif