debian – NAS/SAN open source avec support ZFS
Ces dernières années, le secteur qui a connu d’importantes évolutions est celui du stockage de données. Le volume, la vitesse, les techniques de stockage et pour surtout les prix. HDD, RAID, cloud, NAS, SAN, iSCSI, … sont le vocabulaire couramment utilisé par nos revendeurs. Dans ce tutoriel, nous nous intéresserons ici à la mise en place d’un NAS (Network-Attached Storage) open source « made in home » a base de distribution Debian 10 et du système de fichier ZFS. Je détaillerai ici la construction du pool de stockage, l’installation du service Samba couplé à des snapshots et pour terminer un pseudo PRA via l’export zrepl du stockage vers un serveur tiers.
Prérequis matériels
Pour ce tutoriel j’utilise une machine type KVM sur un cluster Proxmox. Voici un exemple de configuration :
ZFS depuis Debian Buster 10
À partir de votre Debian 10 fraîchement installée, vérifier et ajouter le dépôt backports
vi /etc/apt/sources.list
...
###############################################
## buster
deb http://deb.debian.org/debian/ buster main contrib non-free
deb-src http://deb.debian.org/debian/ buster main contrib non-free
## buster security
deb http://deb.debian.org/debian-security/ buster/updates main contrib non-free
deb-src http://deb.debian.org/debian-security/ buster/updates main contrib non-free
## buster update
deb http://deb.debian.org/debian/ buster-updates main contrib non-free
deb-src http://deb.debian.org/debian/ buster-updates main contrib non-free
## buster backports
deb http://deb.debian.org/debian buster-backports main contrib non-free
deb-src http://deb.debian.org/debian buster-backports main contrib non-free
...
Mettre à jour votre système et installer les paquets nécessaires à la prise en charge de ZFS pour debian
apt update
apt install linux-headers-`uname -r` -y
apt install -t buster-backports dkms spl-dkms -y
apt install -t buster-backports zfs-dkms zfsutils-linux -y
Déterminer la taille maximale de l’ARC (Adaptive Replacement Cache) ZFS. Par défaut, c’est 75 % de mémoire sur les systèmes dotés de moins de 4 Go de mémoire. Vous pouvez vous aider de cette calculatrice : http://www.matisse.net/bitcalc/
Éditer ensuite le fichier /etc/modprobe.d/zfs.conf
# vi /etc/modprobe.d/zfs.conf
Quelques exemples en fonction de votre mémoire disponible
#96Go
options zfs zfs_arc_max=103079215104
#80Go
options zfs zfs_arc_max=85899345920
#50Go
options zfs zfs_arc_max=53687091200
#40Go
options zfs zfs_arc_max=42949672960
#30Go
options zfs zfs_arc_max=32212254720
#24Go
options zfs zfs_arc_max=25769803776
#16Go
options zfs zfs_arc_max=17179869184
Après le reboot de votre debian, vérifier la prise en compte des xxGo en visualisant la consommation de l’ARC
# arc_summary -p 1
...
Target size (adaptive): 100.0 % XX.0 GiB
...
Afin de construite le pool ZFS et éviter d’utiliser le nom des disques sous le format sdx car en cas de panne d’un, la numérotation va changer au redémarrage. Nous allons privilégier l’utilisation des numéros séries. Pour cela, visualiser les disques par ID :
ls -lh /dev/disk/by-id/
scsi-0QEMU_QEMU_HARDDISK_drive-scsi0
scsi-0QEMU_QEMU_HARDDISK_drive-scsi1
scsi-0QEMU_QEMU_HARDDISK_drive-scsi2
Création du pool tank en mode raidz équivalent au raid1 ()
zpool create tank -o ashift=12 raidz scsi-0QEMU_QEMU_HARDDISK_drive-scsi0 scsi-0QEMU_QEMU_HARDDISK_drive-scsi1 scsi-0QEMU_QEMU_HARDDISK_drive-scsi2
Création du volume home et timemachine sur le pool tank
zfs create -o casesensitivity=mixed -o xattr=sa -o dnodesize=auto tank/home
zfs create -o xattr=sa -o dnodesize=auto tank/timemachine
Lister le résultat des commandes précédentes
zfs list
NAME USED AVAIL REFER MOUNTPOINT
tank 155K 965G 30.6K /tank
tank/home 30.6K 965G 30.6K /tank/home
tank/timemachine 30.6K 965G 30.6K /tank/timemachine
Changer le point de montage des volumes home et timemachine
zfs set mountpoint=/home tank/home
zfs set mountpoint=/timemachine tank/timemachine
zfs mount -a
Lancer un scrub
zpool scrub tank
Arrêter un scrub
zpool scrub -s tank
Dans le cadre de l’utilisation du NFS, CIFS et éventullement de l’iSCSI il est recommandé de changer les propriétés du pool tank comme indiqué (Docs Oracle Propriétés ZFS)
Activer les acls posix (getfacl, setfacl) :
zfs set acltype=posixacl tank
Stocker les attributs étendus dans les inodes afin d’obtenir plus d’IO :
zfs set dnodesize=auto tank
zfs set xattr=sa tank
Désactiver la déduplication
zfs set dedup=off tank
Activer la compression
zfs set compression=lz4 tank
Pour de la performance
zfs set atime=off tank
zfs set sync=disabled tank
Au cours d’une opération chmod, les ACE autres que owner@, group@ ou everyone@ ne sont modifiés d’aucune manière. Les ACE owner@, group@ ou everyone@ sont désactivés afin de définir le mode de fichier comme demandé par l’opération chmod.
zfs set aclinherit=passthrough tank
Visualiser les propriétés modifiées sur le pool tank
zfs get acltype tank
zfs get casesensitivity tank
zfs get dnodesize tank
zfs get xattr tank
zfs get dedup tank
zfs get compression tank
zfs get atime tank
zfs get sync tank
zfs get aclinherit tank
Réinitialiser les propriétés modifiées sur le pool tank à la valeur d’origine
# zfs inherit -Sr xattr tank/home
# zfs inherit -Sr dnodesize tank/home
Visualiser toutes les valeurs locales modifiées pour un tank
# zfs get -s local all
Acquitter une erreur disque sur votre pool tank
zpool clear tank scsi-0QEMU_QEMU_HARDDISK_drive-scsi0
zpool status
Remplacement automatique disques défectueux dans le pool tank si un disque de spare est présent
zpool set autoreplace=on tank
Activer les notifications mail pour ZFS
# apt install zfs-zed
# vi /etc/zfs/zed.d/zed.rc
Activer immédiatement SWAP on ZFS
sysctl -w vm.swappiness=10
Activer SWAP on ZFS de manière persistante
vi /etc/sysctl.conf
# JEROME ZFS
# vm.swappiness = 0 The kernel will swap only to avoid an out of memory condition
# vm.swappiness = 1 Minimum amount of swapping without disabling it entirely
# vm.swappiness = 10 This value is sometimes recommended to improve performance when sufficient memory exists in a system
# vm.swappiness = 60 The default value
# vm.swappiness = 100|The kernel will swap aggressively
# https://pve.proxmox.com/wiki/ZFS_on_Linux
vm.swappiness = 10
Rebooter le serveur pour prendre en compte tous les paramètres ZFS
reboot
Smartmontools
Gérer l’état du smart de vos disques
apt install smartmontools
smartctl -A /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0
smartctl -t short /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0
smartctl -t long /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0
smartctl -l selftest /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0
Paquets deb requis pour construire votre NAS
# apt install vim logwatch apticron screen git lshw unzip tree lwatch dirmngr multiarch-support net-tools python-setuptools ncdu iptraf iptraf-ng iotop iftop htop locate sudo nmap dnsutils ncdu lnav rsync ufw nfs-common ifenslave-2.6
Vérifier la nom présence de fichier en rc
# dpkg --list |grep "^rc"
# dpkg --list |grep "^rc" | cut -d " " -f 3
Tuning de la VM
Pydf
Remplacer l’afficher df par pydf (https://github.com/k4rtik/pydf-pypi)
# wget http://kassiopeia.juls.savba.sk/~garabik/software/pydf/pydf_12_all.deb
# dpkg -i pydf_12_all.deb
DF : ancien affichage
# df
Filesystem Size Used Avail Use% Mounted on
udev 7.9G 0 7.9G 0% /dev
tmpfs 1.6G 11M 1.6G 1% /run
/dev/vda2 33G 2.7G 29G 9% /
tmpfs 7.9G 0 7.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 7.9G 0 7.9G 0% /sys/fs/cgroup
/dev/vda1 511M 5.2M 506M 2% /boot/efi
tank 3.6G 128K 3.6G 1% /tank
tank/home 3.6G 128K 3.6G 1% /tank/home
# alias df='pydf'
DF : nouvel affichage
# df
Filesystem Size Used Avail Use% Mounted on
/dev/vda2 33G 2728M 28G 8.1 [###................................] /
/dev/vda1 511M 5240k 506M 1.0 [...................................] /boot/efi
tank 3622M 128k 3622M 0.0 [...................................] /tank
tank/home 3622M 128k 3622M 0.0 [...................................] /tank/home
Zfstui
Ajouter une interface zfs en CLI pour la gestion de votre ZFS (https://github.com/volkerp/zfstui)
# apt install python3-setuptools
# cd /opt
# git clone https://github.com/volkerp/zfstui.git
# cd /opt/zfstui
# python3 setup.py install
# zfstui
Postfix
# apt install postfix -y
# apt remove --purge exim4-base exim4-config exim4-daemon-light libevent-2.1-6 libgnutls-dane0 libunbound8
echo -e 'mondomaine.fr' > /etc/mailname && more /etc/mailname
# vi /etc/postfix/main.cf
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = localhost.localdomain, localhost
relayhost = smtp.mondomaine.fr
mynetworks = 127.0.0.0/8
inet_interfaces = loopback-only
recipient_delimiter = +
myorigin = /etc/mailname
mailbox_size_limit = 0
inet_protocols = ipv4
compatibility_level = 2
Relancer le service Postfix
# /etc/init.d/postfix restart
Logrotate
Paramétrage du logrotate avec sortie mail et détail des logs a High
cp /etc/logrotate.conf /etc/logrotate.conf.ori
sed -i 's/rotate 4/rotate 52/g' /etc/logrotate.conf
sed -i 's/#compress/compress/g' /etc/logrotate.conf
Vim
ajout copier/coller avec la souris dans vim
echo -e 'set mouse-=a\nsyntax on' > /root/.vimrc
Logwatch
sed -i 's/Output = stdout/Output = mail/g' /usr/share/logwatch/default.conf/logwatch.conf
sed -i 's/Detail = Low/Detail = High/g' /usr/share/logwatch/default.conf/logwatch.conf
logwatch
Rsyslog
Si vous souhaitez centraliser et envoyer vos logs avec un format compatible pour Grafana
# vi /etc/rsyslog.d/grafana.conf
$template MyFormat,"%HOSTNAME% %$YEAR%-%$MONTH%-%$DAY% %timegenerated:::date-hour%:%timegenerated:::date-minute%:%timegenerated:::date-second% %HOSTNAME% %syslogseverity-text% %syslogtag:R,ERE,1,FIELD:([a-zA-Z\/]+)(\[[0-9]{1,5}\])*:--end%%msg%\n"
*.* @192.168.0.100:514;MyFormat
Xymon
Si vous utilisez un serveur xymon vous devez installer le client :
# apt install xymon-client hobbit-plugins
192.168.0.100
Le fichier apt_no_repo_accept permet de faire des exceptions sur des paquets précis
# touch /etc/xymon/apt_no_repo_accept && more /etc/default/xymon-client
Unattended-Upgrade
Mise à jour automatique de votre système
apt install unattended-upgrades
dpkg-reconfigure unattended-upgrades
unattended-upgrade -d
Motd
Si vous souhaitez avoir un motd sympathique (https://fr.wikipedia.org/wiki/FIGlet)
rm /etc/update-motd.d/10-uname
cp /etc/motd /etc/motd.ori
0>/etc/motd
apt install figlet python-apt -y
cd /usr/share/figlet/
wget https://raw.githubusercontent.com/xero/figlet-fonts/master/ANSI%20Shadow.flf
mv ANSI\ Shadow.flf ANSI-Shadow.flf
cd /etc/update-motd.d
Apticron
Si vous souhaitez être notifié pour vos updates systèmes
cp /usr/lib/apticron/apticron.conf /etc/apticron/
sed -i 's/"root"/"root@mondomaine.fr"/g' /etc/apticron/apticron.conf
sed -i 's/# CUSTOM_FROM=""/CUSTOM_FROM="root@mondomaine.fr"/g' /etc/apticron/apticron.conf
CLI Fuzzy Finder
Si vous souhaitez avoir un prompt de recherche sympathique (https://github.com/junegunn/fzf)
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
source ~/.bashrc
exec bash
CLI Powerline-Shell
Si vous souhaitez avoir un prompt design (https://github.com/b-ryan/powerline-shell)
git clone https://github.com/b-ryan/powerline-shell /opt/powerline-shell
cd /opt/powerline-shell
python setup.py install
NTP
Synchroniser l’horloge de votre serveur avec systemd
vi /etc/systemd/timesyncd.conf
[Time]
NTP=ntp.mondomaine.fr
FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
timedatectl set-ntp true
timedatectl status
Local time: Fri 2017-07-07 21:36:11 CEST
Universal time: Fri 2017-07-07 19:36:11 UTC
RTC time: Fri 2017-07-07 19:36:11
Time zone: Europe/Paris (CEST, +0200)
Network time on: yes
NTP synchronized: yes
RTC in local TZ: no
Relancer le service de temps de systemd et vérifier l’état
service systemd-timesyncd restart
service systemd-timesyncd status
Désactivation d’IPv6 au niveau des modules et du noyau
Créer le fichier suivant pour les modules
echo 'blacklist ipv6' >> /etc/modprobe.d/blacklist.conf
Il suffit d’ajouter au fichier /etc/sysctl.conf les instructions suivantes :
vi /etc/sysctl.conf
...
# désactivation de ipv6 pour toutes les interfaces
net.ipv6.conf.all.disable_ipv6 = 1
# désactivation de l’auto configuration pour toutes les interfaces
net.ipv6.conf.all.autoconf = 0
# désactivation de ipv6 pour les nouvelles interfaces (ex:si ajout de carte réseau)
net.ipv6.conf.default.disable_ipv6 = 1
# désactivation de l’auto configuration pour les nouvelles interfaces
net.ipv6.conf.default.autoconf = 0
...
Samba
Cette partie est la plus complexe, elle vous propose l’installation du service de fichiers Samba avec la configuration des quotas, de timemachine et une pseudo protection contre les ransomwares (a revoir)
Pour fonctionner avec notre domaine, Samba a besoin de Winbind
export DEBIAN_FRONTEND=noninteractive
apt-get install winbind krb5-user libnss-winbind smbclient libpam-winbind
unset DEBIAN_FRONTEND
0>/etc/krb5.conf
vi /etc/krb5.conf
Exemple de fichier krb5.conf
[libdefaults]
default_realm = MONDOMAINE.FR
ticket_lifetime = 1d
renew_lifetime = 7d
dns_lookup_realm = false
dns_lookup_kdc = true
[realms]
MONDOMAINE.FR = {
kdc = 192.168.0.1
kdc = 192.168.0.2
admin_server = 192.168.0.1 192.168.0.2 }
Installer Samba
apt install -y samba samba-common samba-vfs-modules python-samba
Exemple de fichier smb.conf
cp /etc/samba/smb.conf /etc/samba/smb.conf.ori
0>/etc/samba/smb.conf
vi /etc/samba/smb.conf
#======================= Global Settings =======================
[global]
workgroup = MONDOMAINE
server string = %h server
dns proxy = no
#### Networking ####
interfaces = 127.0.0.0/8 eno1
bind interfaces only = yes
#hosts allow = 192.168.0.0/24
#### Debugging/Accounting ####
log level = 0
log file = /var/log/samba/log.%m
max log size = 1000
panic action = /usr/share/samba/panic-action %d
####### Authentication #######
security = ADS
realm = MONDOMAINE.FR
idmap config *:backend = tdb
idmap config *:range = 700001-800000
idmap config MONDOMAINE:backend = rid
idmap config MONDOMAINE:range = 10000-700000
winbind use default domain = yes
template homedir = /home/%U
map acl inherit = Yes
#store dos attributes = Yes
#template shell = /bin/bash
############ Misc ############
socket options = TCP_NODELAY IPTOS_LOWDELAY
guest account = nobody
load printers = no
disable spoolss = yes
printing = bsd
printcap name = /dev/null
use sendfile = yes
aio read size = 16384
aio write size = 16384
time server = no
wins support = no
multicast dns register = no
########### Shadow ###########
shadow: snapdir = .zfs/snapshot
shadow: sort = desc
shadow: format = -%Y-%m-%d-%H%M%S
shadow: snapprefix = ^zfs-auto-snap
shadow: delimiter = -20
get quota command = /home/quotazfs.sh %U
vfs objects = shadow_copy2 catia fruit streams_xattr acl_xattr
fruit:model = Xserve
fruit:resource = xattr
fruit:encoding = native
fruit:copyfile = yes
########### Security ###########
include = /etc/samba/ransomwares.conf
veto files = /.DS_Store/._.DS_Store/Thumbs.db/
delete veto files = yes
client min protocol = SMB2
client max protocol = SMB3
min protocol = SMB2
max protocol = SMB3
#======================= Share Definitions =======================
[homes]
comment = Home directories
browseable = yes
writable = yes
create mask = 0600
force create mode = 0600
directory mask = 0700
force directory mode = 0700
valid users = %S
[TimeMachine]
path = /timemachine/%U
fruit:time machine = yes
fruit:time machine max size = 961G
browseable = no
writable = yes
vfs objects = catia fruit streams_xattr
valid users = @mongroupe
Joindre votre serveur NAS au domaine
net ads join -U Administrateur
Enter Administrateur's password:
Using short domain name -- MONDOMAINE
Joined 'NAS' to dns domain 'mondomaine.fr'
Ajouter winbind à l’authentification linux
vi /etc/nsswitch.conf
passwd: compat winbind
group: compat winbind
shadow: compat winbind
gshadow: files
hosts: files dns
networks: files
protocols: db files
services: db files
ethers: db files
rpc: db files
netgroup: nis
sudoers: files
Après reboot vérifiez la bonne intégration dans votre domaine
wbinfo --ping-dc
checking the NETLOGON for domain[MONDOMAINE] dc connection to "dc2.mondomaine.fr" succeeded
Lister les utilisateurs
wbinfo -u
Lister les groupes
wbinfo -g
Vérifier les informations de l’utilisateur
wbinfo -i colombet
colombet:*:12345:10513::/home/colombet:/bin/bash
Création automatique du dossier utilisateur
apt-get install oddjob-mkhomedir smbclient samba
pam-auth-update --force
Activer uniquement le service smbd
systemctl enable smbd.service
systemctl status smbd.service
Vérifier les ports en écoutent
netstat -tupln
tcp 0 0 127.0.0.1:445 0.0.0.0:* LISTEN 2219/smbd
tcp 0 0 192.168.xx.xx:445 0.0.0.0:* LISTEN 2219/smbd
tcp 0 0 127.0.0.1:139 0.0.0.0:* LISTEN 2219/smbd
tcp 0 0 192.168.xx.xx:139 0.0.0.0:* LISTEN 2219/smbd
smbclient -N -L localhost
Anonymous login successful
Sharename Type Comment
--------- ---- -------
homes Disk Home directories
IPC$ IPC IPC Service (my server)
SMB1 disabled -- no workgroup available
Tester votre fichier samba.conf
samba-tool testparm --suppress-prompt
Il est maintenant possible d’utiliser les acls posix
mkdir /home/colombet
chmod 700 /home/colombet
chown "colombet:domain users" /home/colombet
Gérer les ACLs depuis Windows
cf : https://www.vionblog.com/manage-samba-permissions-from-windows/
cf : https://wiki.samba.org/index.php/Setting_up_a_Share_Using_Windows_ACLs
net rpc rights grant "MONDOMAINE\Domain Admins" SeDiskOperatorPrivilege -U "MONDOMAINE\Administrateur"
net rpc rights revoke "MONDOMAINE\Domain Admins" SeDiskOperatorPrivilege -U "MONDOMAINE\Administrateur"
net rpc rights list privileges SeDiskOperatorPrivilege -U "MONDOMAINE\Administrateur"
Lire les acls
getfacl /home/colombet/
getfacl: Removing leading '/' from absolute path names
# file: home/colombet/
# owner: colombet
# group: domain\040users
user::rwx
user:colombet:rwx
group::---
group:domain\040users:---
group:colombet:rwx
mask::rwx
other::---
default:user::rwx
default:user:colombet:rwx
default:group::---
default:group:domain\040users:---
default:mask::rwx
default:other::---
Reset des ACLs en récursif d’un répertoire
setfacl -Rbn /home/colombet/
Quotas
Afin de définir des quotas, il faut dans un premier temps déléguer des permissions aux utilisateurs du domaine ou à tout le monde d’accéder aux variables userquota,userused.
zfs allow "Domain Users" userquota,userused tank/home
ou
zfs allow everyone userquota,userused tank/home
Supprimer les délégations de permission
zfs unallow everyone tank/home
zfs unallow "Domain Users" tank/home
zfs unallow colombet tank/home
Mettre un quota sur l’utilisateur colombet
zfs set userquota@"MONDOMAINE\colombet"=1G tank/home
zfs set userquota@colombet=1G tank/home
Afficher un quota
zfs get -H "userquota@MONDOMAINE\colombet" tank/home | /usr/bin/awk '{ print $3 };'
zfs get -H "userquota@colombet" tank/home
Supprimer un quota
zfs set userquota@colombet=none tank/home
Maintenant que le système de fichier est prêt, il faut indiquer à Samba comment interpréter les quotas ZFS. Pour cela, ajouter la directive get quota command dans la partie globale du fichier /etc/samba/smb.conf
get quota command = /opt/scripts/samba_quotazfs.sh %U
Créer le script bash samba_quotazfs.sh
vi /opt/scripts/samba_quotazfs.sh
#!/bin/sh
# Jerome Colombet
# 01-10-2020
username=$1
if [ ! -z "$username" ]; then
smbpath=${PWD}
dataset=`/bin/df -l ${smbpath} | /usr/bin/tail -n 1 | /usr/bin/awk '{ print $1 };'`
infoused=`/sbin/zfs get -Hp userused@$username $dataset`
infoquota=`/sbin/zfs get -Hp userquota@$username $dataset`
usedbytes=`echo ${infoused}| /usr/bin/awk '{ printf "%.f", $3/1024 };';`
quotabytes=`echo ${infoquota}| /usr/bin/awk '{ if ( $3 == "none" ) { print "0"} else { printf "%.f", $3/1024 } };'`
echo 2 $usedbytes $quotabytes $quotabytes $usedbytes $quotabytes $quotabytes
#dans le cas d'une utilisation de crontab
#info=`/sbin/zfs userspace -Hpo name,used,quota $dataset | /usr/bin/grep -i ${username}`
#info=`/bin/more /tmp/quotazfs-home | /usr/bin/grep -i ${username}`
#usedbytes=`echo ${info}| /usr/bin/awk '{ printf "%.f", $2/1024 };';`
fi
exit
Si utilisation du script précédent via crontab
# Quota ZFS home
*/5 * * * * /sbin/zfs userspace -Hpo name,used,quota tank/home > /tmp/quotazfs-home
Pour info ; *Flags Quotas *
1 - quota flags (0 = no quotas, 1 = quotas enabled, 2 = quotas enabled and enforced)
2 - number of currently used blocks
3 - the softlimit number of blocks
4 - the hardlimit number of blocks
5 - currently used number of inodes
6 - the softlimit number of inodes
7 - the hardlimit number of inodes
8 - (optional) - the number of bytes in a block(default is 1024)
Avahi
Afin d’utiliser TimeMachine avec Samba, il est recommandé d’utiliser Avahi afin que le serveur soit détecté par le parc MacOS
apt install avahi-daemon
Créer la configuration pour le service Samba
vi /etc/avahi/services/samba.service
Exemple de fichier samba.service
%h
_smb._tcp
445
_adisk._tcp
sys=waMa=0,adVF=0x100
dk0=adVN=TimeMachine,adVF=0x82
_device-info._tcp
0
model=RackMac
Clamav
Installer clamav
apt-get purge -y clamav-unofficial-sigs
apt-get update && apt-get install -y clamav-base clamav-freshclam clamav clamav-daemon
Lancer les commandes suivantes depuis votre terminal en root
mkdir -p /usr/local/sbin/
wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/clamav-unofficial-sigs.sh -O /usr/local/sbin/clamav-unofficial-sigs.sh && chmod 755 /usr/local/sbin/clamav-unofficial-sigs.sh
mkdir -p /etc/clamav-unofficial-sigs/
wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/config/master.conf -O /etc/clamav-unofficial-sigs/master.conf
wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/config/user.conf -O /etc/clamav-unofficial-sigs/user.conf
wget "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/config/os/os.debian.conf" -O /etc/clamav-unofficial-sigs/os.conf
Exécuter le script suivant afin de s’assurer qu’il n’y a pas d’erreurs, corriger les dépendances manquantes le script doit s’exécuter une fois en tant que super-utilisateur pour définir toutes les autorisations et créer les répertoires pertinents
/usr/local/sbin/clamav-unofficial-sigs.sh --force
################################################################################
eXtremeSHOK.com ClamAV Unofficial Signature Updater
Version: v7.2.5 (2021-03-20)
Required Configuration Version: v96
Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com
################################################################################
Loading config: /etc/clamav-unofficial-sigs/master.conf
Loading config: /etc/clamav-unofficial-sigs/os.conf
Loading config: /etc/clamav-unofficial-sigs/user.conf
+++++++++++++++++++++++
NOTICE: forcing updates
+++++++++++++++++++++++
===================
Preparing Databases
===================
Sanesecurity public GPG key successfully downloaded
Sanesecurity public GPG key successfully imported to custom keyring
==================================================
Sanesecurity Database & GPG Signature File Updates
==================================================
Checking for Sanesecurity updates...
Sanesecurity mirror site used: 62.93.225.23
Installer la rotation des logs et le man
/usr/local/sbin/clamav-unofficial-sigs.sh --install-logrotate
/usr/local/sbin/clamav-unofficial-sigs.sh --install-man
Installer les services pour clamav-unofficial-sigs via systemd
mkdir -p /etc/systemd/system/
wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/systemd/clamav-unofficial-sigs.service -O /etc/systemd/system/clamav-unofficial-sigs.service
wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/systemd/clamav-unofficial-sigs.timer -O /etc/systemd/system/clamav-unofficial-sigs.timer
systemctl enable clamav-unofficial-sigs.service
systemctl enable clamav-unofficial-sigs.timer
systemctl start clamav-unofficial-sigs.timer
Testez le scan sur le dossier /home avec et sans résumé
clamdscan --multiscan --allmatch --remove --no-summary --fdpass /home
clamdscan --multiscan --allmatch --remove --fdpass /home
Créer le fichier de log
touch /var/log/clamav/manual_clamscan.log
Activer le scan automatique via un crontab
# Tous les jours à 20h30 passage antivirus dossier home
30 20 * * * /usr/bin/clamdscan --multiscan --allmatch --remove --fdpass /home >> /var/log/clamav/manual_clamscan.log
Veto Ransomware
Crée un fichier avec le paramètre “veto files = ” tous les fichiers de rançon connus, afin d’essayer de protéger votre home.
apt install jq
mkdir /opt/scripts
wget https://raw.githubusercontent.com/mauriciomagalhaes/Ransomware-veto-samba/master/ransomware-veto-smb.sh -O /opt/scripts/samba_veto_ransomware.sh
Éditer le fichier /opt/scripts/samba_veto_ransomware.sh afin de le traduire et l’adapter à Samba Debian 10
#!/bin/bash
SMBCONF="/etc/samba"
SMBCONTROL=$(which smbcontrol)
JQ=$(which jq)
while true; do
if curl --output /dev/null --silent --head --fail https://fsrm.experiant.ca/api/v1/combined; then
curl --silent -o $SMBCONF/ransomwares.json https://fsrm.experiant.ca/api/v1/combined && break
fi
done
TOTALREG=$(jq -r .api.file_group_count $SMBCONF/ransomwares.json)
DATA=$(jq -r .lastUpdated $SMBCONF/ransomwares.json)
echo "Total des ransomware connus : $TOTALREG"
echo "Dernière mise à jour : $DATA"
$JQ -r .filters[] $SMBCONF/ransomwares.json > $SMBCONF/ransomwares.conf
sed -i 's/^/\//g' $SMBCONF/ransomwares.conf
sed -i ':a;N;s/\n//g;ta' $SMBCONF/ransomwares.conf
sed -i 's/^/veto files = /g' $SMBCONF/ransomwares.conf
$SMBCONTROL smbd reload-config
Rendre exécutable le script samba_veto_ransomware.sh
chmod 755 /opt/scripts/samba_veto_ransomware.sh
Programmer une mise à jour toutes les 6 heures via crontab
crontab -l
# Mise à jour toutes les 6 heures des ransomware connus
0 */6 * * * /opt/scripts/samba_veto_ransomware.sh
Créer un include dans la section [Global] du fichier smb.conf ou dans les partages.
[Global]
...
include = /etc/samba/ransomwares.conf
...
ZnapZend – ZFS Snapshot vers un serveur distant
Télécharger et installer le dernier paquet depuis https://github.com/Gregy/znapzend-debian/releases
wget https://github.com/Gregy/znapzend-debian/releases/download/0.20.0/znapzend_0.20.0-1_amd64.deb
dpkg -i znapzend_0.20.0-1_amd64.deb
apt install mbuffer
Création d’un plan de snapshot sans synchro distante sur 5 jours toutes les heures
# znapzendzetup create --mbuffer=/usr/bin/mbuffer --mbuffersize=1G --tsformat=zfs-auto-snap-%Y-%m-%d-%H%M%S SRC '5d=>60min,1w=>1d' tank/home
*** backup plan: tank/home ***
enabled = on
mbuffer = /usr/bin/mbuffer
mbuffer_size = 1G
post_znap_cmd = off
pre_znap_cmd = off
recursive = off
src = tank/home
src_plan = 5days=>60minutes,1week=>1day
tsformat = zfs-auto-snap-%Y-%m-%d-%H%M%S
zend_delay = 0
Création de snapshot avec synchro zrepl ssh sur 5 jours toutes les heures
# znapzendzetup create --mbuffer=/usr/bin/mbuffer --mbuffersize=1G --tsformat=zfs-auto-snap-%Y-%m-%d-%H%M%S SRC '5d=>60min,1w=>1d' tank/home DST '5d=>60min,1w=>1d' root@backup:tank/home
*** backup plan: tank/home ***
dst_0 = root@backup:tank/home
dst_0_plan = 5days=>60minutes,1week=>1day
enabled = on
mbuffer = /usr/bin/mbuffer
mbuffer_size = 1G
post_znap_cmd = off
pre_znap_cmd = off
recursive = off
src = tank/home
src_plan = 5days=>60minutes,1week=>1day
tsformat = zfs-auto-snap-%Y-%m-%d-%H%M%S
zend_delay = 0
L’exemple de PLANS de snapshot précédent peut prendre les options suivantes
En local :
toutes les heures pendant 5 jours : 5d=>1h
tous les jours pendant 1 semaine : 1w=>1d
À distance :
toutes les 6 heures pendant 2 jours : 2d=>6h
tous les jours pendant 1 semaine : 1w=>1d
garder une semaine : 1m=>1w
garder un mois : 1m=>1w
garder une semaine pendant 3 mois : 3m=>1w
Activer et relancer le service znapzend.service
systemctl restart znapzend.service
systemctl enable znapzend.service
watch -n 1 systemctl status znapzend.service
dernier snapshot vue depuis l’hôte ayant le plan de sauvegarde:
# znapzendztatz -r tank/home
USED LAST SNAPSHOT DATASET
0B No Snapshots Yet tank/home
0B No Snapshots Yet root@backup:tank/home
Le programme de backup est sauvegardé dans les propriétés du dataset ZFS :
# zfs get all tank/home | grep org.znapzend
tank/home org.znapzend:mbuffer_size 1G local
tank/home org.znapzend:dst_0 root@backup:tank/home local
tank/home org.znapzend:zend_delay 0 local
tank/home org.znapzend:tsformat zfs-auto-snap-%Y-%m-%d-%H%M%S local
tank/home org.znapzend:enabled on local
tank/home org.znapzend:mbuffer /usr/bin/mbuffer local
tank/home org.znapzend:dst_0_plan 5days=>1hours local
tank/home org.znapzend:recursive on local
tank/home org.znapzend:post_znap_cmd off local
tank/home org.znapzend:src_plan 5days=>1hours local
tank/home org.znapzend:pre_znap_cmd off local
Lister les plans de sauvegardes
# znapzendzetup list
*** backup plan: tank/home ***
dst_0 = root@backup:tank/home
dst_0_plan = 5days=>1hours
enabled = on
mbuffer = /usr/bin/mbuffer
mbuffer_size = 1G
post_znap_cmd = off
pre_znap_cmd = off
recursive = off
src = tank/home
src_plan = 5days=>1hours
tsformat = %Y-%m-%d-%H%M%S
zend_delay = 0
Supprimer un plan de sauvegardes et reprise en compte par le service znapzend
znapzendzetup delete tank/home
pkill -HUP znapzend
Éditer un plan de sauvegardes et reprise en compte par le service znapzend
znapzendzetup edit tank/home
pkill -HUP znapzend
Zfs-Prune-Snapshots
J’ai trouvé pour vous un petit script pour gérer facilement vos snapshots. Il permet de supprimer des snapshots d’un ou plusieurs pools avec vos critères. Pour plus de détails : https://github.com/bahamas10/zfs-prune-snapshots.
wget https://raw.githubusercontent.com/bahamas10/zfs-prune-snapshots/master/zfs-prune-snapshots -O /opt/scripts/zfs-prune-snapshots
chmod 755 /opt/scripts/zfs-prune-snapshots
Simuler une purge des snapshots au-delà de 15 jours
zfs-prune-snapshots -n 15d tank
Purger des snapshots au-delà de 15 jours
zfs-prune-snapshots 15d tank
Ce script vient à remplacer la commande d’origine, ici pour supprimer tous les snapshot de l’hôte
~~# zfs list -H -o name -t snapshot | xargs -n1 zfs destroy~~
iSCSI
Ajouter à votre NAS la fonctionnalité SAN afin de l’interfacer votre cluster Proxmox c’est possible. Cette partie est basée sur cette documentation : https://deepdoc.at/dokuwiki/doku.php?id=virtualisierung:proxmox_kvm_und_lxc:proxmox_debian_als_zfs-over-iscsi_server_verwenden
Sur votre cluster Proxmox, les noeuds doivent accéder dynamiquement à l’ensemble des données ZFS de votre NAS. Pour cela, ils doivent être autorisés pour les ACLs dans targetcli. J’utilise les clés SSH à cette fin.
SUR VOTRE PROXMOX
Sur un de vos noeuds proxmox, générer un couple de clés ssh et les copier vers votre NAS
cd /etc/pve/priv/zfs
ssh-keygen -f /etc/pve/priv/zfs/192.168.0.100_id_rsa
ssh-copy-id -i /etc/pve/priv/zfs/192.168.0.100_id_rsa.pub root@192.168.0.100
Number of key(s) added: 1
Vérifier la connexion ssh depuis les noeuds Proxmox vers votre NAS via le couple de clé précédent
# ssh -i /etc/pve/priv/zfs/192.168.0.100_id_rsa root@192.168.0.100
root@backup:~# logout
Connection to 192.168.0.100 closed.
Récupérer tous les noms initiateurs de vos noeuds
cat /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.1993-08.org.debian:01:1ae0ad6ebb5f
SUR VOTRE NAS
Depuis votre NAS, créer un pool iscsi
zfs create tank/iscsi
Vérifier et à adapter selon vos propriétés
zfs list
NAME USED AVAIL REFER MOUNTPOINT
tank 1.05M 3.54G 128K /tank
tank/home 128K 3.54G 128K /tank/home
tank/iscsi 128K 3.54G 128K /tank/iscsi
La configuration passe par la commande targetcli. Avec ls, nous pouvons voir l’arborescence, help affiche l’aide et avec saveconfig on enregistre les modifications.
# targetcli
targetcli shell version 2.1.fb48
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.
/> ls
o- / .......................................................................................... [...]
o- backstores ............................................................................... [...]
| o- block ................................................................... [Storage Objects: 0]
| o- fileio .................................................................. [Storage Objects: 0]
| o- pscsi ................................................................... [Storage Objects: 0]
| o- ramdisk ................................................................. [Storage Objects: 0]
o- iscsi ............................................................................. [Targets: 0]
o- loopback .......................................................................... [Targets: 0]
o- vhost ............................................................................. [Targets: 0]
o- xen-pvscsi ........................................................................ [Targets: 0]
/
Nous allons créer un target entrant dans le dossier iscsi et en exécutant create
/> cd iscsi
/iscsi> create
Created target iqn.2003-01.org.linux-iscsi.nas.x8664:sn.2c0c3e76710e.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.
Nous pouvons vérifier le nom de la target unique iqn.2003-01.org.linux-iscsi.nas.x8664:sn.2c0c3e76710e
/iscsi> ls
o- iscsi ............................................................................ [Targets: 1]
o- iqn.2003-01.org.linux-iscsi.nas.x8664:sn.2c0c3e76710e.............................. [TPGs: 1]
o- tpg1 ............................................................... [no-gen-acls, no-auth]
o- acls .......................................................................... [ACLs: 0]
o- luns .......................................................................... [LUNs: 0]
o- portals .................................................................... [Portals: 1]
o- 0.0.0.0:3260 ..................................................................... [OK]
Ajouter des ACLs avec les initiateurs de vos noeuds proxmox
/iscsi>cd iqn.2003-01.org.linux-iscsi.nas.x8664:sn.2c0c3e76710e/
/iscsi/iqn.20....2c0c3e76710e> cd tpg1
/iscsi/iqn.20...3e76710e/tpg1> cd acls
/iscsi/iqn.20...10e/tpg1/acls> create iqn.1993-08.org.debian:01:1ae0ad6ebb5f
Ne pas oublier de sauvegarder vos paramètres
/> saveconfig
Configuration saved to /etc/rtslib-fb-target/saveconfig.json
/> exit
Global pref auto_save_on_exit=true
Last 10 configs saved in /etc/rtslib-fb-target/backup.
Configuration saved to /etc/rtslib-fb-target/saveconfig.json
SUR VOTRE PROXMOX
Depuis l’interface, ajouter un storage ZFS over iSCSI
Ou en éditant le fichier via le CLI pour ajouter le stockage
more /etc/pve/storage.cfg
zfs: iscsi-zfs
disable
blocksize 4k
iscsiprovider LIO
pool tank/iscsi
portal 192.168.0.100
target iqn.2003-01.org.linux-iscsi.nas.x8664:sn.2c0c3e76710e
content images
lio_tpg tpg1
nodes finn
nowritecache 1
sparse 1
Pour supprimer une target
/> cd iscsi/
/iscsi> delete iqn.2003-01.org.linux-iscsi.nas.x8664:sn.2c0c3e76710e
Deleted Target iqn.2003-01.org.linux-iscsi.nas.x8664:sn.2c0c3e76710e.
DEBUG
Voici un petit panel des erreurs rencontrées :
Erreur 1 :
Dec 5 20:27:20 nas systemd[3272]: gpgconf: error running '/usr/lib/gnupg/scdaemon': probably not installed
Solution, installer les paquets manquants
# apt remove gpg-agent gnupg-l10n gnupg-utils pinentry-curses gpgconf gnupg dirmngr gpg gpgconf gpgsm libgpgme11 python-gpg samba-dsdb-modules libassuan0 libksba8 libnpth0 --purge
# apt install scdaemon gpg-agent gpgconf pinentry-curses dirmngr gpg gpgconf gpgsm libgpgme11 python-gpg samba-dsdb-modules
Erreur 2 :
[2020/12/09 14:12:52.633413, 0] ../source3/param/loadparm.c:3362(process_usershare_file)
process_usershare_file: stat of /var/lib/samba/usershares/systemresources failed. Permission denied
[2020/12/09 14:12:52.635011, 0] ../source3/param/loadparm.c:3362(process_usershare_file)
process_usershare_file: stat of /var/lib/samba/usershares/systemresources failed. No such file or directory
Solution, ajouter dans la partie [global] la directive usershare path à vide
usershare path =
Erreur 3 :
[2020/12/05 09:49:39.675193, 0] ../source3/nmbd/nmbd_namequery.c:109(query_name_response)
query_name_response: Multiple (2) responses received for a query on subnet 10.0.210.161 for name MONDOMAINE.
Ajouter dans la partie [global] du fichier /etc/samba/smb.conf
local master = no
domain master = no
preferred master = no
disable netbios = yes
Et désactiver le service nmbd
systemctl stop nmbd.service
systemctl disable nmbd.service
Erreur 4 :
Dec 2 09:30:02 nas clamd[8464]: Wed Dec 2 09:30:02 2020 -> Reading databases from /var/lib/clamav
Dec 2 09:30:14 nas smbd[1245]: [2020/12/02 09:30:14.291538, 0] ../source3/smbd/dosmode.c:302(get_ea_dos_attribute)
Dec 2 09:30:14 nas smbd[1245]: get_ea_dos_attribute: Rejecting root override, invalid stat [mon-equipe]
Dec 2 09:30:18 nas smbd[1245]: [2020/12/02 09:30:18.161030, 0] ../source3/smbd/dosmode.c:302(get_ea_dos_attribute)
Supprimer dans la partie [global] les vfs objects pour TimeMachine
vfs objects = shadow_copy2 acl_xattr
#vfs objects = shadow_copy2 catia fruit streams_xattr acl_xattr
Erreur 5 :
Dec 10 08:58:21 nas smbd[37182]: [2020/12/10 08:58:21.876529, 0] ../source3/smbd/uid.c:453(change_to_user_internal)
Dec 10 08:58:21 nas smbd[37182]: change_to_user_internal: chdir_current_service() failed!
Forcer un utilisateur pour un montage :
force user = nobody
Références
Zfs
ZnapZend – ZFS Snapshot vers un serveur distant
- https://github.com/oetiker/znapzend
- https://www.colabug.com/2018/0630/3396460/
- http://www.lmgc.univ-montp2.fr/perso/norbert-deleutre/2017/09/08/zfs-terminologie-et-commandes-de-bases/
Timemachine
- https://www.antoneliasson.se/journal/time-machine-compatible-samba-on-debian-buster/
- https://www.samba.org/samba/docs/current/man-html/vfs_fruit.8.html
- https://github.com/sp00ls/SambaConfigs/blob/master/smb.conf
Veto Ransomware
CLAMAV