Samba: Difference between revisions

From Newroco Tech Docs
Jump to navigationJump to search
 
(56 intermediate revisions by 4 users not shown)
Line 4: Line 4:


==Samba Installation==
==Samba Installation==
Installing the package:


===Prerequisites===
# apt-get install samba ntp winbind dnsutils krb5-user smbclient acl
Set a static IP


# vi /etc/network/interfaces
For a DC continue as below, for a fileserver go to [[#Creating a samba fileserver]]


should look something like this:
Stop and disabled smbd and nmbd services as they are not needed on a DC and can even create problems if left running
<pre>systemctl stop smbd
systemctl disable smbd
systemctl stop nmbd
systemctl disable nmbd
systemctl stop winbind
systemctl disable winbind</pre>


<pre>
Stop samba and move/delete /etc/samba/smb.conf:
auto enp0s3
 
iface enp0s3 inet static
# systemctl stop samba-ad-dc
        address 192.168.1.121
# mv /etc/samba/smb.conf /etc/samba/smb.conf.default
        netmask 255.255.255.0
        network 192.168.1.0
        broadcast 192.168.1.255
        gateway 192.168.1.1
        dns-nameservers 192.168.1.1
        dns-search example.local
</pre>


'''Note''': Don't use real world TLDs like example.com
If you have multiple domain controllers in your domain, add on each DC all of them to the resolvconf template:
====Ubuntu 18.04 and newer====
Since Ubuntu 18.04 systemd has a service called '''systemd-resolved''' that listens on port 53 (DNS) which makes samba unable to listen at that port. Could be checked with netstat:
<pre># netstat -tulnp | grep 53
tcp        0      0 0.0.0.0:49152          0.0.0.0:*              LISTEN      453/samba         
tcp        0      0 0.0.0.0:49153          0.0.0.0:*              LISTEN      453/samba         
tcp        0      0 0.0.0.0:49154          0.0.0.0:*              LISTEN      453/samba         
tcp        0      0 0.0.0.0:135            0.0.0.0:*              LISTEN      453/samba         
tcp        0      0 127.0.0.53:53          0.0.0.0:*              LISTEN      280/systemd-resolve
tcp6      0      0 :::49152                :::*                    LISTEN      453/samba         
tcp6      0      0 :::49153                :::*                    LISTEN      453/samba         
tcp6      0      0 :::49154                :::*                    LISTEN      453/samba         
tcp6      0      0 :::135                  :::*                    LISTEN      453/samba         
tcp6      0      0 :::53                  :::*                    LISTEN      467/samba         
udp    29184      0 127.0.0.53:53          0.0.0.0:*                          280/systemd-resolve
udp6      0      0 :::53                  :::*                                467/samba</pre>


===Installation===
Delete the /etc/resolv.conf symlink
Installing the package:
<pre>rm /etc/resolv.conf</pre>


# apt-get install samba ntp winbind dnsutils
Create a new /etc/resolv.conf so the servers still knows where to resolve domains
<pre>#vi /etc/resolv.conf


search domain.local
nameserver dc1.ip.add.ress
nameserver dc2.ip.add.ress</pre>


Stop samba and empty /etc/samba/smb.conf:
Now you can stop and disable systemd-resolve:
<pre>systemctl stop systemd-resolved
systemctl disable systemd-resolved</pre>


# service samba-ad-dc stop
====Ubuntu 16.04 or older====
# > /etc/samba/smb.conf
<pre># vi /etc/resolvconf/resolv.conf.d/tail
search example.local
nameserver ip.addr.a.dc
nameserver ip.addr.b.dc
nameserver ip.addr.c.dc</pre>


For a DC continue as below, for a fileserver go to [[#Creating a samba fileserver]]
Don't forget to update resolv.conf afterwards
# resolvconf -u


'''For creating a domain use this command'''
===For creating a domain use this command===
  # samba-tool domain provision --interactive --use-rfc2307
  # samba-tool domain provision --interactive --use-rfc2307


Line 47: Line 72:
<pre>apt-get install samba-dsdb-modules samba-vfs-modules</pre>
<pre>apt-get install samba-dsdb-modules samba-vfs-modules</pre>


'''For joining an existing domain use this command'''
===For joining an existing domain use this command===
  # samba-tool domain join domain.local DC -Usamba.user --realm=domain.local --server=primary.dc.ip
  # samba-tool domain join domain.local DC -Usamba.user --realm=domain.local --server=primary.dc.ip


Line 54: Line 79:


Now start the samba DC service:
Now start the samba DC service:
  # service samba-ad-dc start
  # systemctl start samba-ad-dc
 
If start failes with '''Failed to start samba-ad-dc.service: Unit samba-ad-dc.service is masked''' run this command and then start samba-ad-dc again
<pre>systemctl unmask samba-ad-dc
systemctl start samba-ad-dc</pre>
 
Enable the service to auto start at boot
<pre>systemctl enable samba-ad-dc</pre>
 
Add DNS forwarder to /etc/samba/smb.conf in the [global] section
<pre>dns forwarder = <ga.te.way.ip></pre>
 
Restart samba-ad-dc service
<pre>systemctl restart samba-ad-dc</pre>
 
===For joining an existing domain when the second DC is ruining on a VM with private IP behind a public IP===
 
For joining an existing domain when the second DC is ruining on a private IP behind a public IP (NAT) replication issues can occur. 
If the replication is working only in one way (from the second DC to the main DC) the DNS records from the main DC  has to be updated.
 
1. First check on which IP the second DC is answering. If the ping returns the private IP of the DC then a DNS update is needed.
 
2. List the DNS informations of the second DC
 
<pre>
sudo samba-tool dns serverinfo newroco-dc2 -U username
</pre>
 
The output should look like this:
<pre>
dwVersion                  : 0xece0205
  fBootMethod                : DNS_BOOT_METHOD_DIRECTORY
  fAdminConfigured            : FALSE
  fAllowUpdate                : TRUE
  fDsAvailable                : TRUE
  pszServerName              : NEWROCO-DC2.newroco.local
  pszDsContainer              : CN=MicrosoftDNS,DC=DomainDnsZones,DC=newroco,DC=local
  aipServerAddrs              : '''['172.16.12.13']'''
  aipListenAddrs              : '''['172.16.12.13']'''
......
</pre>


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:
3. Update the DNS record for the second DC and set as the default IP the public IP of the host:  


<pre># vi /etc/resolvconf/resolv.conf.d/tail
<pre>
search example.local
samba-tool dns update petitsuix newroco.local newroco-dc2 A 172.16.12.13 144.76.221.153 -U username
nameserver ip.addr.a.dc
</pre>
nameserver ip.addr.b.dc
 
nameserver ip.addr.c.dc</pre>
4. Check the if the update changed the private IP with the public one.


Don't forget to update resolv.conf afterwards
5. Run again the replication command from both ways and both servers.
# resolvconf -u


===SSL Certificate===
===SSL Certificate===
Line 74: Line 138:
<pre>chmod 600 /var/lib/samba/private/tls/samba-key.pem</pre>
<pre>chmod 600 /var/lib/samba/private/tls/samba-key.pem</pre>


And add these lines in /etc/samba/smb.conf:
And add these lines in /etc/samba/smb.conf on [global] section:
<pre>tls enabled = yes
<pre>tls enabled = yes
tls keyfile = /var/lib/samba/private/tls/samba-key.pem
tls keyfile = /var/lib/samba/private/tls/samba-key.pem
Line 81: Line 145:


Restart samba
Restart samba
<pre>service samba-ad-dc restart</pre>
<pre>systemctl restart samba-ad-dc</pre>


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.
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.
===Kerberos tickets (needed for RSAT tools and probably other)===
Package krb5-user was already installed at the beggining, now lets edit '''/etc/krb5.conf'''. Delete the whole content of the file and put this instead:
<pre>[libdefaults]
        default_realm = MYDOMAIN.LOCAL
        dns_lookup_realm = false
        dns_lookup_kdc = true</pre>
Package was also installed at the beginning, but it's service needs to be stopped and disabled
<pre>systemctl stop winbind
systemctl disable winbind
systemctl restart samba-ad-dc</pre>
Now you can test a login with smbclient
<pre>smbclient -L localhost -U user.name</pre>


===Checking the replication===
===Checking the replication===
Line 92: Line 171:
Next test if automatic replication works
Next test if automatic replication works
<pre>samba-tool drs showrepl</pre>
<pre>samba-tool drs showrepl</pre>
===SysVol Replication===
If you need to setup SysVol Replication for Group Policies (GPO) follow the tutorial bellow from the official documentation
'''NOTE''': on the PDC start the rsync service with
<pre>systemctl start rsync
systemctl enable rsync</pre>
https://wiki.samba.org/index.php/Rsync_based_SysVol_replication_workaround


==Samba & LDAP==
==Samba & LDAP==
Line 114: Line 203:


==Creating a samba fileserver==
==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:
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.  
 
''NB if you have a multi-site setup, your DCs resolv.conf should have the site-local DCs. This allows site-specific DNS entries to function correctly.''
 
====Ubuntu 16.04 or older====
This can be done by editing resolvconf's head file:


  #vi /etc/resolvconf/resolv.conf.d/head
  #vi /etc/resolvconf/resolv.conf.d/head
Line 124: Line 218:


  # resolvconf -u
  # resolvconf -u
====Ubuntu 18.04 or newer====
Since Ubuntu 18.04 the way you add DNS servers changed. Delete the symlink at /etc/resolv.conf
<pre>rm /etc/resolv.conf</pre>
And manually create the file
<pre>#vi /etc/resolv.conf
search domain.local
nameserver dc1.ip.addr.ess
nameserver dc2.ip.addr.ess</pre>


===Installation and configuration===
===Installation and configuration===
Line 135: Line 240:
  # apt-get install libnss-winbind libpam-winbind acl libpam-krb5 krb5-user
  # apt-get install libnss-winbind libpam-winbind acl libpam-krb5 krb5-user


And configure nsswitch to be able to use winbind:
And configure nsswitch to be able to use winbind ('''Note''': newer ubuntu versions might have other options for passwd and group, don't delete them, just add winbind):


  # vi /etc/nsswitch.conf
  # vi /etc/nsswitch.conf
Line 146: Line 251:
  # vi /etc/samba/smb.conf
  # vi /etc/samba/smb.conf


Add the following configuration to the top section
Replace current file content with next one:


<pre>[global]
<pre>[global]
Line 194: Line 299:
         write list = @"Domain Users"
         write list = @"Domain Users"
         path = /path/to/data/
         path = /path/to/data/
         force directory mode = 755
         force directory mode = 775
         force group = Domain Users
         force group = Domain Users
         force create mode = 665
         force create mode = 665
Line 210: Line 315:
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 <pre>/mnt/myiscsi</pre> your samba share should be at <pre>/mnt/myiscsi/myshare</pre> 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.
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 <pre>/mnt/myiscsi</pre> your samba share should be at <pre>/mnt/myiscsi/myshare</pre> 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"
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". '''Note''': after joining the AD domain.
<pre>chown :"domain users" /path/to/folder</pre>
<pre>chown :"domain users" /path/to/folder</pre>
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 user.name


Restart the samba services
Restart the samba services
  # systemctl restart winbind nmbd smbd
  # 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 user.name


NB which domain to join is determined from the configuration files.
NB which domain to join is determined from the configuration files.
===Recycle Bin===
If you want to add a recycle bin functionality to a share add these lines to share configuration
<pre>vfs objects = recycle
recycle:repository = .recycle
recycle:directory_mode = 775
recycle:keeptree = yes
recycle:versions = yes
recycle:exclude = *.swp,*.swpx,*~
recycle:touch_mtime = yes</pre>
More details about samba recycle bin configuration can be found here: [https://www.samba.org/samba/docs/man/manpages/vfs_recycle.8.html Samba Recycle Bin]
If you also want files to automatically be deleted after 7 days add a daily cronjob like this:
<pre>#vi /etc/cron.daily/samba-recycle-bin
#!/bin/bash
find /path/to/share/.recycle/* -mtime +7 -exec rm {} \;</pre>
And make it executable:
<pre>chmod +x /etc/cron.daily/clean-samba-recycle</pre>


===Testing===
===Testing===
Line 225: Line 352:
  # getent passwd
  # getent passwd


This should return the normal contents of /etc/passwd, pause for a moment and then continue with all the domain users.
This should return the normal contents of /etc/passwd, pause for a moment and then continue with all the domain users. If it doesn't show any domain users try restarting the service.


You can then test the availability of the shares you've created
You can then test the availability of the shares you've created
Line 275: Line 402:
     printf "Fullname(format Name Surname):"
     printf "Fullname(format Name Surname):"
     read fullname
     read fullname
     samba-tool user add $username --mail-address=$email
     if samba-tool user list | grep -x -q $username; then
    samba-tool user setexpiry $username --noexpiry
        echo "********************************************"
    pdbedit -u $username -f "$fullname"
        echo "User $username already exists"
        echo "********************************************"
    else
        samba-tool user create $username --mail-address=$email
        samba-tool user setexpiry $username --noexpiry
        pdbedit -u $username -f "$fullname"
    fi
else
else
    echo > users-pass.txt
     while IFS='' read -r line || [[ -n "$line" ]]; do
     while IFS='' read -r line || [[ -n "$line" ]]; do
         IFS=':' read -a userinfo <<< "$line"
         IFS=':' read -a userinfo <<< "$line"
         samba-tool user add ${userinfo[0]} ${userinfo[1]} --mail-address=${userinfo[2]}
         if samba-tool user list | grep -x -q ${userinfo[0]}; then
        samba-tool user setexpiry ${userinfo[0]} --noexpiry
            echo "********************************************"
        pdbedit -u ${userinfo[0]} -f "${userinfo[3]}"
            echo "User ${userinfo[0]} already exists"
            echo "********************************************"
            echo "${userinfo[0]}" >> existing-users
        else
            pass=`shuf -i 10000-99999 -n 1`
            samba-tool user create ${userinfo[0]} "ChangeMe"$pass --mail-address=${userinfo[1]}
            samba-tool user setexpiry ${userinfo[0]} --noexpiry
            pdbedit -u ${userinfo[0]} -f "${userinfo[2]}"
            echo "${userinfo[0]} - ${userinfo[1]} - ChangeMe$pass" >> users-pass.txt
        fi
     done < "$1"
     done < "$1"
fi
fi
Line 290: Line 433:
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:
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:
<pre>
<pre>
username1:Password1:mail1@example.com:Full Name
username1:mail1@example.com:Full Name
username2:Password2:mail2@example.com:Full Name
username2:mail2@example.com:Full Name
username3:Password3:mail3@example.com:Full Name
username3:mail3@example.com:Full Name
</pre>
</pre>
The passwords are generated automatically and written into the users-pass.txt file


==Adding Service accounts==
==Adding Service accounts==
Line 302: Line 446:
===Get user info===
===Get user info===
If you want to get information about a samba user (displayName, mail, etc.), i found ldapsearch to show the most details
If you want to get information about a samba user (displayName, mail, etc.), i found ldapsearch to show the most details
<pre>ldapsearch -xLLL -H ldap://localhost:389 -D "cn=user.name,cn=users,dc=<domain>,dc=local" -W -b "dc=<domain>,dc=local" '(&(cn=<user-to-search-for>))'</pre>
<pre>ldapsearch -xLLL -H ldaps://localhost -D "cn=user.name,cn=users,dc=<domain>,dc=local" -W -b "dc=<domain>,dc=local" '(&(sAMAccountName=<user-to-search-for>))'</pre>
If last part ('(&(cn=<user-to-search-for>))') is omitted it will show all users.
If last part ('(&(sAMAccountName=<user-to-search-for>))') is omitted it will show all users.


===Setting an email for a user===
===Setting an email for a user===
Line 309: Line 453:
====When creating the user====
====When creating the user====
<pre>
<pre>
samba-tool user add <username> --mail-address=<email>
samba-tool user create <username> --mail-address=<email>
</pre>
</pre>


Line 348: Line 492:
Change sAMAccountName and userPrincipalName (the user used below should belong to "Account Operators" group)
Change sAMAccountName and userPrincipalName (the user used below should belong to "Account Operators" group)
<pre>ldapmodify -x -D "cn=<user>,cn=Users,dc=<domain>,dc=local" -W -H ldap://localhost -f chuser.ldif</pre>
<pre>ldapmodify -x -D "cn=<user>,cn=Users,dc=<domain>,dc=local" -W -H ldap://localhost -f chuser.ldif</pre>
===Reload a samba fileserver config===
This should in theory reload a samba fileserver config without breaking users connections
<pre>smbcontrol all reload-config</pre>
===Change password complexity/length===
<pre>samba-tool domain passwordsettings set --complexity=off
samba-tool domain passwordsettings set --min-pwd-length=12</pre>
===Monitor LDAP ports===
If you are about to migrate the AD to new DCs and want to make sure you don't have applications still authenticating against the old DCs you can monitor the LDAP port (or any) with '''tcpdump'''
<pre>tcpdump -n not host za.bb.ix.ip and port 636</pre>
This also works nice with '''screen'''
===Get username/groupname from UID===
<pre># wbinfo --uid-info 3000008
NEWROCO\emilian.mitocariu:*:3000008:100::/home/NEWROCO/emilian.mitocariu:/bin/false</pre>
===Get UID from username===
<pre># wbinfo --user-info emilian.mitocariu
NEWROCO\emilian.mitocariu:*:3000008:100::/home/NEWROCO/emilian.mitocariu:/bin/false</pre>
==Troubleshooting==
===Randome samba service failure===
A DC could fail with service ''samba-ad-dc'' still running but some samba related ports (389. 636, 135, 445) are closed. Can be checked with following command. If no output, port is closed.
<pre>netstat -tulnp | grep <port></pre>
If this happens and restarting the service doesn't do anything, then stop the service
<pre>service samba-ad-dc stop</pre>
Look for samba processes that are still running
<pre># ps aux | grep samba
root    23176  2.4 59.1 1063172 600936 ?      S    Oct19  35:47 /usr/sbin/samba -D
root    28407  0.0  0.0  11284  1012 pts/1    S+  06:28  0:00 grep --color=auto samba</pre>
And kill them using the PID (second column). Note: second row is just the grep command, no need to kill that one.
<pre>kill -9 23176</pre>
Start the service
<pre>service samba-ad-dc start</pre>
Check if everything works.
===kerberos_kinit_password <fileserver-name>$@OXARCH.LOCAL failed: Looping detected inside krb5_get_in_tkt===
If this error is found in the logs you need to leave the domain, rejoin and possibly restart smbd/winbind services.

Latest revision as of 10:28, 8 August 2023


Notes

Samba Installation

Installing the package:

# apt-get install samba ntp winbind dnsutils krb5-user smbclient acl

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

Stop and disabled smbd and nmbd services as they are not needed on a DC and can even create problems if left running

systemctl stop smbd
systemctl disable smbd
systemctl stop nmbd
systemctl disable nmbd
systemctl stop winbind
systemctl disable winbind

Stop samba and move/delete /etc/samba/smb.conf:

# systemctl stop samba-ad-dc
# mv /etc/samba/smb.conf /etc/samba/smb.conf.default

If you have multiple domain controllers in your domain, add on each DC all of them to the resolvconf template:

Ubuntu 18.04 and newer

Since Ubuntu 18.04 systemd has a service called systemd-resolved that listens on port 53 (DNS) which makes samba unable to listen at that port. Could be checked with netstat:

# netstat -tulnp | grep 53
tcp        0      0 0.0.0.0:49152           0.0.0.0:*               LISTEN      453/samba           
tcp        0      0 0.0.0.0:49153           0.0.0.0:*               LISTEN      453/samba           
tcp        0      0 0.0.0.0:49154           0.0.0.0:*               LISTEN      453/samba           
tcp        0      0 0.0.0.0:135             0.0.0.0:*               LISTEN      453/samba           
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      280/systemd-resolve 
tcp6       0      0 :::49152                :::*                    LISTEN      453/samba           
tcp6       0      0 :::49153                :::*                    LISTEN      453/samba           
tcp6       0      0 :::49154                :::*                    LISTEN      453/samba           
tcp6       0      0 :::135                  :::*                    LISTEN      453/samba           
tcp6       0      0 :::53                   :::*                    LISTEN      467/samba           
udp    29184      0 127.0.0.53:53           0.0.0.0:*                           280/systemd-resolve 
udp6       0      0 :::53                   :::*                                467/samba

Delete the /etc/resolv.conf symlink

rm /etc/resolv.conf

Create a new /etc/resolv.conf so the servers still knows where to resolve domains

#vi /etc/resolv.conf

search domain.local
nameserver dc1.ip.add.ress
nameserver dc2.ip.add.ress

Now you can stop and disable systemd-resolve:

systemctl stop systemd-resolved
systemctl disable systemd-resolved

Ubuntu 16.04 or older

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

Don't forget to update resolv.conf afterwards

# resolvconf -u

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:

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:

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

Now start the samba DC service:

# systemctl start samba-ad-dc

If start failes with Failed to start samba-ad-dc.service: Unit samba-ad-dc.service is masked run this command and then start samba-ad-dc again

systemctl unmask samba-ad-dc
systemctl start samba-ad-dc

Enable the service to auto start at boot

systemctl enable samba-ad-dc

Add DNS forwarder to /etc/samba/smb.conf in the [global] section

dns forwarder = <ga.te.way.ip>

Restart samba-ad-dc service

systemctl restart samba-ad-dc

For joining an existing domain when the second DC is ruining on a VM with private IP behind a public IP

For joining an existing domain when the second DC is ruining on a private IP behind a public IP (NAT) replication issues can occur. If the replication is working only in one way (from the second DC to the main DC) the DNS records from the main DC has to be updated.

1. First check on which IP the second DC is answering. If the ping returns the private IP of the DC then a DNS update is needed.

2. List the DNS informations of the second DC

sudo samba-tool dns serverinfo newroco-dc2 -U username

The output should look like this:

dwVersion                   : 0xece0205
  fBootMethod                 : DNS_BOOT_METHOD_DIRECTORY
  fAdminConfigured            : FALSE
  fAllowUpdate                : TRUE
  fDsAvailable                : TRUE
  pszServerName               : NEWROCO-DC2.newroco.local
  pszDsContainer              : CN=MicrosoftDNS,DC=DomainDnsZones,DC=newroco,DC=local
  aipServerAddrs              : '''['172.16.12.13']'''
  aipListenAddrs              : '''['172.16.12.13']'''
 ......

3. Update the DNS record for the second DC and set as the default IP the public IP of the host:

samba-tool dns update petitsuix newroco.local newroco-dc2 A 172.16.12.13 144.76.221.153 -U username 

4. Check the if the update changed the private IP with the public one.

5. Run again the replication command from both ways and both servers.

SSL Certificate

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

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

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

And add these lines in /etc/samba/smb.conf on [global] section:

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

Restart samba

systemctl restart samba-ad-dc

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.

Kerberos tickets (needed for RSAT tools and probably other)

Package krb5-user was already installed at the beggining, now lets edit /etc/krb5.conf. Delete the whole content of the file and put this instead:

[libdefaults]
        default_realm = MYDOMAIN.LOCAL
        dns_lookup_realm = false
        dns_lookup_kdc = true

Package was also installed at the beginning, but it's service needs to be stopped and disabled

systemctl stop winbind
systemctl disable winbind
systemctl restart samba-ad-dc

Now you can test a login with smbclient

smbclient -L localhost -U user.name

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:

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

Next test if automatic replication works

samba-tool drs showrepl

SysVol Replication

If you need to setup SysVol Replication for Group Policies (GPO) follow the tutorial bellow from the official documentation

NOTE: on the PDC start the rsync service with

systemctl start rsync
systemctl enable rsync

https://wiki.samba.org/index.php/Rsync_based_SysVol_replication_workaround

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:

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:

dc=<firstpartofADdomainname>,dc=<secondpartofADdomainname>

Where AD domain name (realm) was of the form

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:

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.

NB if you have a multi-site setup, your DCs resolv.conf should have the site-local DCs. This allows site-specific DNS entries to function correctly.

Ubuntu 16.04 or older

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

Ubuntu 18.04 or newer

Since Ubuntu 18.04 the way you add DNS servers changed. Delete the symlink at /etc/resolv.conf

rm /etc/resolv.conf

And manually create the file

#vi /etc/resolv.conf

search domain.local
nameserver dc1.ip.addr.ess
nameserver dc2.ip.addr.ess

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 (Note: newer ubuntu versions might have other options for passwd and group, don't delete them, just add winbind):

# vi /etc/nsswitch.conf

passwd:         compat winbind
group:          compat winbind

Set up your shares

# vi /etc/samba/smb.conf

Replace current file content with next one:

[global]
       workgroup = workgroupname
       server string = yourservername
       security = ads
       realm = WORKGROUPNAME.TLD # common to be .LOCAL
       
        socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=131072 SO_SNDBUF=131072
    use sendfile = true
 
    idmap config * : backend = tdb
    idmap config * : range = 100000-299999
    idmap config workgroupname : backend = rid
    idmap config workgroupname : range = 10000-99999
    winbind separator = +
    winbind enum users = yes
    winbind enum groups = yes
    winbind use default domain = yes
    winbind refresh tickets = yes

    restrict anonymous = 2
    log file = /var/log/samba/log.%m
    max log size = 50


    deadtime = 45
    read raw = Yes
    write raw = Yes

    server signing = mandatory

# Network
       interfaces = ens3 # change to suit, ens3 is first interface if using a [http://docswiki.newro.co/index.php/Creation_of_a_new_VM VM built as per our approach]
       bind interfaces only = true
       log file = /var/log/samba/log.%m
       log level = 1
       max log size = 1000
       logging = syslog@0 file
       panic action = /usr/share/samba/panic-action

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

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

Example read-only share definition

[sharename]
       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

/mnt/myiscsi

your samba share should be at

/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". Note: after joining the AD domain.

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

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 user.name

Restart the samba services

# systemctl restart winbind nmbd smbd

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

Recycle Bin

If you want to add a recycle bin functionality to a share add these lines to share configuration

vfs objects = recycle
recycle:repository = .recycle
recycle:directory_mode = 775
recycle:keeptree = yes
recycle:versions = yes
recycle:exclude = *.swp,*.swpx,*~
recycle:touch_mtime = yes

More details about samba recycle bin configuration can be found here: Samba Recycle Bin

If you also want files to automatically be deleted after 7 days add a daily cronjob like this:

#vi /etc/cron.daily/samba-recycle-bin

#!/bin/bash
find /path/to/share/.recycle/* -mtime +7 -exec rm {} \;

And make it executable:

chmod +x /etc/cron.daily/clean-samba-recycle

Testing

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. If it doesn't show any domain users try restarting the service.

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

Domain=[EXAMPLE] OS=[Windows 6.1] Server=[Samba 4.3.11-Ubuntu]

        Sharename       Type      Comment
        ---------       ----      -------
        sharename      Disk       What this share is
        IPC$            IPC       IPC Service (yourservername)
Domain=[EXAMPLE] OS=[Windows 6.1] Server=[Samba 4.3.11-Ubuntu]

        Server               Comment
        ---------            -------
        YOURSERVERNAME           
        ANOTHERSERVER               
        ADOMAINMEMBERPC

        Workgroup            Master
        ---------            -------
        EXAMPLE               ANOTHERSERVER

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

browseable=yes

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 user=user.name 

where user.name 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

#!/bin/bash

if [ $# -eq 0 ] ; then
    printf "Username(format name.surname):"
    read username
    printf "Email:"
    read email
    printf "Fullname(format Name Surname):"
    read fullname
    if samba-tool user list | grep -x -q $username; then
        echo "********************************************"
        echo "User $username already exists"
        echo "********************************************"
    else
        samba-tool user create $username --mail-address=$email
        samba-tool user setexpiry $username --noexpiry
        pdbedit -u $username -f "$fullname"
    fi
else
    echo > users-pass.txt
    while IFS='' read -r line || [[ -n "$line" ]]; do
        IFS=':' read -a userinfo <<< "$line"
        if samba-tool user list | grep -x -q ${userinfo[0]}; then
            echo "********************************************"
            echo "User ${userinfo[0]} already exists"
            echo "********************************************"
            echo "${userinfo[0]}" >> existing-users
        else
            pass=`shuf -i 10000-99999 -n 1`
            samba-tool user create ${userinfo[0]} "ChangeMe"$pass --mail-address=${userinfo[1]}
            samba-tool user setexpiry ${userinfo[0]} --noexpiry
            pdbedit -u ${userinfo[0]} -f "${userinfo[2]}"
            echo "${userinfo[0]} - ${userinfo[1]} - ChangeMe$pass" >> users-pass.txt
        fi
    done < "$1"
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:

username1:mail1@example.com:Full Name
username2:mail2@example.com:Full Name
username3:mail3@example.com:Full Name

The passwords are generated automatically and written into the users-pass.txt file

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

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

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

Setting an email for a user

When creating the user

samba-tool user create <username> --mail-address=<email>

For an existing user

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

apt-get install ldap-utils

Create a file entrymods.ldif:

dn: cn=<username>,cn=Users,dc=<firstpartofdomain>,dc=<secondpartofdomain>
changetype: modify
replace: mail
mail: <email>
-

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

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)

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:

dn: cn=<newuser>,cn=Users,dc=<domain>,dc=local
changetype: modify
replace: sAMAccountName
sAMAccountName: <newuser>
-
replace: userPrincipalName
userPrincipalName: <newuser>@<domain>.local
-

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

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

Reload a samba fileserver config

This should in theory reload a samba fileserver config without breaking users connections

smbcontrol all reload-config

Change password complexity/length

samba-tool domain passwordsettings set --complexity=off
samba-tool domain passwordsettings set --min-pwd-length=12

Monitor LDAP ports

If you are about to migrate the AD to new DCs and want to make sure you don't have applications still authenticating against the old DCs you can monitor the LDAP port (or any) with tcpdump

tcpdump -n not host za.bb.ix.ip and port 636

This also works nice with screen

Get username/groupname from UID

# wbinfo --uid-info 3000008
NEWROCO\emilian.mitocariu:*:3000008:100::/home/NEWROCO/emilian.mitocariu:/bin/false

Get UID from username

# wbinfo --user-info emilian.mitocariu
NEWROCO\emilian.mitocariu:*:3000008:100::/home/NEWROCO/emilian.mitocariu:/bin/false

Troubleshooting

Randome samba service failure

A DC could fail with service samba-ad-dc still running but some samba related ports (389. 636, 135, 445) are closed. Can be checked with following command. If no output, port is closed.

netstat -tulnp | grep <port>

If this happens and restarting the service doesn't do anything, then stop the service

service samba-ad-dc stop

Look for samba processes that are still running

# ps aux | grep samba
root     23176  2.4 59.1 1063172 600936 ?      S    Oct19  35:47 /usr/sbin/samba -D
root     28407  0.0  0.0  11284  1012 pts/1    S+   06:28   0:00 grep --color=auto samba

And kill them using the PID (second column). Note: second row is just the grep command, no need to kill that one.

kill -9 23176

Start the service

service samba-ad-dc start

Check if everything works.

kerberos_kinit_password <fileserver-name>$@OXARCH.LOCAL failed: Looping detected inside krb5_get_in_tkt

If this error is found in the logs you need to leave the domain, rejoin and possibly restart smbd/winbind services.