Useful Commands

The commands here can save your life, please help us to maintain this page

Not Specific To Nethserver

Each time you launch 'signal-event ibay-modify IBAYNAME' you will restore the good ACL ownership.


getfacl /path/2/files/or/folders

set ACL

setfacl -P -R -m u:UID:rwX,d:u:UID:rwX /path/2/files/or/folders
setfacl -P -R -m g:UID:rwX,d:g:UID:rwX /path/2/files/or/folders

-R : recursive<br />

-P : physical, follow symlinks

Remove Specific ACL

setfacl -d u:UID:rwX,d:u:UID:rwX /path/2/files/or/folders
setfacl -d g:UID:rwX,d:g:UID:rwX /path/2/files/or/folders

Remove all ACL

setfacl -b /path/2/files/or/folders


PHPinfo will provide an overview of all PHP related settings. A quick way to get an overview or search for a setting, one could use:

explanation Command
get overviewphp -r "phpinfo();" |less
to save to a text filephp -r "phpinfo();" > phpinfo.txt
to search for specific values and save to a text filephp -r "phpinfo();" | grep mysql > phpmysql.txt
to push it directly in the vhost data contentecho '<?php phpinfo(); ?>' > /var/lib/nethserver/vhost/
in the terminalphp -i

Virtualhost parsing order

-S Show the settings as parsed from the config file (currently only shows the virtualhost settings).

httpd -S

Adding date and time to bash history

By default the bash history does not show the date and time of any activity. You can enable this by entering the following command:

 HISTTIMEFORMAT="%d/%m/%y %T "

where %d=day, %m is month, &y is year and %T is time

To see the bash history with the date and time added, enter:


the history command can be useful in combination with added comments to shell commands for more precise analysis or (automatic) reporting based on a shell script and cron.

Find a file/folder

  • find quickly with a database
locate <FileOrFolderName'>

do before :

yum install mlocate -y ; updatedb

updatedb must be launched manually each time you add new files (a cron job runs each night).

  • find by name
find / -iname 'FileOrFolderName'
  • find files by their size

it could be useful to find large file by the command line

find /home/e-smith -type f -size +200M -exec ls -lh {} \; | awk '{ print $ ":_" $5 }';


 k    for Kilobytes (units of 1024 bytes)
 M    for Megabytes (units of 1048576 bytes)
 G    for Gigabytes (units of 1073741824 bytes)

Replace a chain of characters

Replace a chain of characters chaine1 by chaine2 in all files of the current directory with '.txt'

find . -name "*.txt" -type f -exec sed -i "s/chaine1/chaine2/g" {} \;

Run a command a multiple time

you can run a command as fast the computer can do to test if it fails or not. For example here the echo 'plop' will be executed until you stop it with ctrl+c

time while echo 'plop'; do : ; done

time will save the time it will end, you can remove it if needed

you can add & at the end, it will run as a background process and you can launch it several time.

time while echo 'plop'; do : ; done &

Unix user/group properties

Explanation Command
see informations of a userid USER
change the uid of a user usermod -u <UID> USER_NAME
create a groupgroupadd -g <GID> -o GROUPE_NAME
modify the GID of a groupgroupmod -o -g <GID> GROUPE_NAME
add a principal group to a userusermod -g <GROUP_NAME_OR_GID> USER_NAME
add a secondary group to a userusermod -a -G <GROUP_NAME_OR_GID> USER_NAME
change the home directory (-m move files/folders to the new location)usermod -d /var/lib/jdownloader jdownloader
change the shell access of a userusermod --shell /bin/bash jdownloader

Read a TAI64N timestamp in human readable format

[ tai64nlocal] converts precise TAI64N timestamps to a human-readable format. tai64nlocal reads lines from stdin. If a line does not begin with @, tai64nlocal writes it to stdout without change. If a line begins with @, tai64nlocal looks for a timestamp after the @, in the format printed by tai64n, and writes the line to stdout with the timestamp converted to local time in ISO format: YYYY-MM-DD HH:MM:SS.SSSSSSSSS. <br />


 cat  /var/log/qpsmtpd/current |tai64nlocal|less


 tailf /var/log/sshd/current | tai64nlocal


Command Explanation
rpm -qa shows all rpms installed
rpm -qa --last shows all rpms installed & installation date
rpm -q asks for rpm info
rpm -qi asks for detailed rpm info
rpm -qlv <packagename> lists all files in a package
rpm -qlvp <packagename.rpm> List all files in a rpm which is not installed
rpm -qf <filename> reports what package a file belongs to
rpm -ql <packagename> for listing the files
rpm -qc <packagename> for listing the config files
rpm -qd <packagename> for listing the documentation files
rpm -qV <packagename> reports if permission and ownership are OK
rpm -qRp <packagename.rpm> Find what dependencies have a rpm
rpm -qR <packagename> Find what dependencies have a package name
rpm -q --whatrequires <packagename> find what packages have <packagename> as dependency
rpm -e --test <packagename> find what packages have <packagename> as dependancy (more verbose as above)
rpm -e --nodeps <packagename> remove packagename without removing dependencies
rpm --setugids <packagename> set right ownership to rpm
rpm --setperms <packagename> set right permissions to rpm
rpm -e --noscripts <packagename> remove packagename without executing sciptlets (%pre, %post, %preun, %postun)
rpm -Va capture any damaged/incomplete rpms - but will also show lots of configuration files, which you of course expect to be modified.
  • Restore all permissions and ownership

If you want to restore all permissions and right ownership of rpm, you can do this in a root terminal.

  for f in $(rpm -qa); do echo $f; rpm --setugids $f; done
  for f in $(rpm -qa); do echo $f; rpm --setperms $f; done
  • or specific to a rpm
# rpm --setugids  opendkim
# rpm --setperms  opendkim
# rpm -V opendkim
S.5....T.  c /etc/opendkim.conf
S.5....T.  c /etc/opendkim/KeyTable
S.5....T.  c /etc/opendkim/SigningTable
S.5....T.  c /etc/opendkim/TrustedHosts


  • reinstall all base dependencies
yum install @nethserver-iso
  • Yum helper
Command Explanation
yum install <packagename> installs packagename & any package it may need
yum remove <packagename> removes packagename
yum history package-info <packagename> Shows the installation/removal history of a package and it's Transaction ID [ see more commands]
yum history undo <Transaction ID> Removes all packages from a specific Transaction ID [ see more commands]
yum list updates list updates to any installed package
yum list available list available packages in all repos not already installed
yum list available | grep <reponame> list available packages -shows only from repo name
yum search <packagename> lists all packages in all repos matching packagename
yum clean all --enablerepo=* Is used to clean up various things which accumulate in the yum cache (includes disabled repos)
yum --enablerepo=<reponame> <command> enable a repo not normally enabled
yum autoremove remove all orphan dependencies
  • reload the database

you can force clamav to reload its database

kill -USR2 `cat /var/run/clamd@rspamd/`

or to make a long freeze

kill -STOP `cat /var/run/clamd@rspamd/`

 and to unfreeze

kill -CONT `cat /var/run/clamd@rspamd/`
  • inspect

see all settings of a container

docker inspect containerName

see some settings of a container (EG: command given)

docker inspect  -f "{{.Name}} {{.Config.Cmd}}" containerName
  • Ping the host

Testing It Out, Can the Container Reach the Docker Host?

We can test this out without needing to run a database or any service. We’ll just run an Alpine image, drop into a shell, install the ping utility and ping the Docker host.

Start the Alpine container and drop into a Shell prompt.

docker run --rm -it alpine sh

Install the ping utility.

apk update && apk add iputils

Ping your local network IP address (replace my IP address with yours).

  • ping a host from a container
docker run busybox ping -c 1
PING ( 56 data bytes
64 bytes from seq=0 ttl=61 time=19.222 ms

--- ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 19.222/19.222/19.222 ms
  • query dns from a container
docker run busybox nslookup

Non-authoritative answer:
Address: 2a00:1450:4007:805::200e

*** Can't find No answer
  • start a container and open a shell inside
docker exec -ti dockername /bin/sh
  • start a nginx container for testing networking
docker run  -dit --name nginx-test-01 -p 9001:80 --restart=unless-stopped nginx:alpine nginx-debug -g 'daemon off;'
  • delete all container
docker rm -f $(docker ps -aq)
  • fix docker dns

vim /etc/docker/daemon.json
    "dns": ["", ""]
Then restart the docker service:

sudo service docker restart


Discover the address of your DNS server You can find out what network’s DNS server from within Ubuntu as follows:

$ nmcli dev show | grep 'IP4.DNS'

Run Docker with the new DNS server To run a docker container with this DNS server, provide the –dns flag to the run command. For example, let’s run the command we used to check if DNS is working:

$ docker run --dns busybox nslookup
Address 1:
Address 1: 2a00:1450:4009:811::200e
Address 2:
And that’s what success looks like.



For a debugging purpose you can redirect queries to logs add in /etc/dnsmasq.conf

#redirect dns queries to /var/log/messages (test purpose)

restart dnsmasq

systemctl restart dnsmasq

then check /var/log/messages


Unbound runs on the port 10053

dig @ -p 10053 maps.rspamd.comf

mysql users

display all mysql users

SELECT User,Host FROM mysql.user;

delete a mysql user

SELECT User,Host FROM mysql.user;
DROP USER 'testuser'@'localhost';

Create a database

create database owncloud;
grant all privileges on owncloud.* to username@localhost identified by 'password';
flush privileges;

delete a database

drop database owncloud;

Backup a database

mysqldump database > database.sql

When you want to diff the differences between two versions of a database, you need to do a specific dump

mysqldump --skip-comments --skip-extended-insert database >  database.sql
  • Backup a database with the idea to diff the output

You might need to want to dump the database and have the need to diff the output against another database.

mysqldump --skip-comments --skip-extended-insert database >  filename


diff -Nur filename1  filename2 > diff_mysql.sql

Find open ports

  • to find opened udp and tcp ports in the firewall:
netstat -tupln
  • to find TCP ports with nmap
yum install nmap
nmap -p 1-65535
  • find a specific port with netstat
 # netstat -anp|grep 5232
 tcp        0      0*                   LISTEN      2028/python
  • find a specific port with nmap

nmap can specify if a port is closed or not

 yum install nmap
 nmap localhost -p 5232

Get MAC address without ifconfig

cat /sys/class/net/host0/address
  • remove all podman containers, if you use podman containers just for makerpms
sudo rm -rf $HOME/.local/share/containers/ 


rspamc uptime

Dump the configuration

Display all settings in rspamd, useful to understand what it occurs

 rspamadm configdump
rspamadm configdump | grep -E '(WHITE|BLACK)LIST \{'

Test manually to check an email

 rspamc email.eml
curl smtp:// -v --anyauth --mail-from --mail-rcpt --upload-file ./2019.eml
  • test the fom IP
[root@ns7loc14 ~]# host $(hostname)
[root@ns7loc14 ~]# config setprop postfix AccessBypassList

((++I)) ; curl smtp://$(hostname):25/$(hostname) -v --mail-from --mail-rcpt <<EOF
Subject: Test ${I}
Date: $(date -R)
Message-ID: <${I}.$(date +%s)@$(hostname -d)>
Mime-Version: 1.0

Test $I

Configuration settings for bayes expiry module should be 
added to the corresponding classifier section (for instance 
in the local.d/classifier-bayes.conf).
Bayes expiry module provides intelligent expiration of 
statistical tokens for the new schema of Redis statistics 

  • test from email/domain
((++I)) ; curl smtp://$(hostname):25/$(hostname) -v --mail-from --mail-rcpt <<EOF
Subject: Test ${I}
Date: $(date -R)
Message-ID: <${I}.$(date +%s)@$(hostname -d)>
Mime-Version: 1.0

Test $I

Configuration settings for bayes expiry module should be 
added to the corresponding classifier section (for instance 
in the local.d/classifier-bayes.conf).
Bayes expiry module provides intelligent expiration of 
statistical tokens for the new schema of Redis statistics 

  • test with getMail and a eicar
[root@vm5 ~]# /usr/bin/rspamc-getmail "-i" "" "--mime" "-t" "120" "-h" "localhost:11334" <<'EOF' 
Return-Path: <>
Received: from
by with LMTP id 2MyWCgn7O14ucwAAJc5BcA
for <>; Thu, 06 Feb 2020 12:39:53 +0100
Received: by (Postfix, from userid 0)
id 2A0133054108E; Thu,  6 Feb 2020 12:39:53 +0100 (CET)
To: undisclosed-recipients:;
Subject: amavisd test - simple - virus scanner test pattern
Message-Id: <>
Date: Thu,  6 Feb 2020 12:39:53 +0100 (CET)


check the content of all maps

grep -r -F .  /etc/rspamd/{white,black}list* | grep -v -F '#' | sort


- Display statistics

rspamc stat
  • Show scores and actions (no action, reject…) from a log file
rspamd_stats </var/log/maillog

Validate the settings

When you upgrade a rspamd version, useful to check if the settings are not obsoleted

rspamadm configtest

check clamav reloading

grep -E '(Cannot validate the message now|SelfCheck|Database correctly reloaded|/var/run/clamd@rspamd/clamav)' /var/log/maillog

Flush cache data in redis

redis-cli -s /var/run/redis-rspamd/rspamd FLUSHALL

Delete all the keys of the currently selected DB in redis

redis-cli -s /var/run/redis-rspamd/rspamd FLUSHDB

check bayes in redis

[root@prometheus ~]# redis-cli -s /var/run/redis-rspamd/rspamd
redis /var/run/redis-rspamd/rspamd> HGET BAYES_HAM learns 
redis /var/run/redis-rspamd/rspamd> HGET BAYES_SPAM learns

check keys/values in redis


for key in $(redis-cli -s /var/run/redis-rspamd/rspamd keys \*);
     #if [[ $key =~ 'BAYES' ]]; then
       echo "Key : '$key'" 
       redis-cli -s /var/run/redis-rspamd/rspamd type $key;
       redis-cli -s /var/run/redis-rspamd/rspamd GET $key;

redis monitor

redis-cli -s /var/run/redis-rspamd/rspamd monitor

Test rspamd by the command line

RESET bayes data

You need to delete keys in Redis to reset learned mail, so create a copy of your Redis database now:

Backup database

# It is better to stop Redis before you copy the file.
cp /var/lib/redis/rspamd/dump.rdb /root/Reset Bayes data
 redis-cli -s /var/run/redis-rspamd/rspamd --scan --pattern BAYES_* | xargs redis-cli del
 redis-cli -s /var/run/redis-rspamd/rspamd --scan --pattern RS* | xargs redis-cli del

If it complains about…

(error) ERR wrong number of arguments for 'del' command …the key pattern was not found and thus no data is available to delete.

Clear dynamic

iptables -F dynamic
shorewall save

Disable shorewall

shorewall clear

to restart

shorewall start

RedHat documentation

Check customized services


Manage a service

Procedure The following commands control the foo service:

  • Activate a service immediately:
# systemctl start foo
  • Deactivate a service immediately:
# systemctl stop foo
  • Restart a service:
# systemctl restart foo
  • Show the status of a service including, whether it is running or not:
# systemctl status foo
  • Enable a service to be started on boot:
# systemctl enable foo
  • Disable a service to not start during boot:
# systemctl disable foo
  • Prevent a service from starting dynamically or even manually unless unmasked:
# systemctl mask foo
  • Check if a service is enabled or not:
# systemctl is-enabled foo
  • Check if the service is active (started) or inactive (stopped)
# systemctl is-active foo
  • Related Information Run man systemctl for more details.

    Specific To Nethserver

Rsync Backup

The official backup module is probably the better way to do, but you can rsync the data of the NS by rsync. Only rsync the /var/lib/nethserver, might not be enough since some additional modules put a link in /etc/backup-data.d/ to save their data with the backup module.

[root@NS7DEVAllModules ~]# cat /etc/backup-data.d/*

so if you want a full backup solution, these paths must be saved also.

Therefore a solution like this should be better

rsync -avzR $(cat /etc/backup-data.d/*) root@YourIP:/your/path/to/save

the -R rsync option save the full path, it will ease your restoration

You have a full howto Page to RTFM, Like in every Linux shell you can use the TAB key when you use the command line to auto complete or propose all available answers.

dbfile : database name see them in /var/lib/nethserver/db or type 'db' then 'tab'
key    : uniq name not modifiable
prop   : property of key
val    : value of property
db dbfile keys List all keys
db dbfile print [key]Print the [key] properties
db dbfile printjson [key]Print the [key] properties in a Json format
db dbfile show [key]Display the [key] properties
db dbfile showjson [key]Display the [key] properties in a Json format
db dbfile get [key]Retrieve the values of [key] properties
db dbfile getjson [key]Retrieve the values of [key] properties in a Json format
db dbfile set [key] [type] [prop1 val1] [prop2 val2] …Create the [key] and [prop* val*] following a 'type' value(adjust the 'type')
db dbfile setdefault [key] [type] [prop1 val1] [prop2 val2] …Create the default [key] and [prop* val*] following a key 'type' (adjust the 'type')
db dbfile delete [key]Delete the [key]
db dbfile printtype [key]Print the type value of [key]
db dbfile gettype [key]Retrieve the type value of [key]
db dbfile settype [key] [type] Set a different type of [key]
db dbfile printprop [key] [prop1] [prop2] [prop3] …Print the value of [key] following [prop*]
db dbfile getprop [key] [prop]Give the value of [prop]
db dbfile setprop [key] [prop1] [val1] [prop2 val2] [prop3 val3] …Set the values of [prop*]
db dbfile delprop [key] [prop1] [prop2] [prop3] …Delete the values of [prop*]

Access to the LDAP server

the STARTTLS command is supported on port 389, and is the preferred method if the clients have it. Check the libuser's password has been correctly set. The libuser's DN should be


or, if your domain part is


The port 636 is disabled by default

you have two specific users to bind for ldap service

  • ldapservice - read-only
  • libuser - full access, read-write restricted to the localhost
  • Anonymous bind has read-only access and does not require STARTTLS.

passwords are stored under /var/lib/nethserver/secrets/

For more documentation, please read

List all entries with libuser bind

ldapsearch  -D cn=libuser,dc=directory,dc=nh -w `cat /var/lib/nethserver/secrets/libuser`

Log retention policy on nethserver

By default set to 4 weeks, if you want to increase to one year

config setprop logrotate Times 52
signal-event nethserver-base-update

You have other options like compression and rotate condition

# config show logrotate

Force log rotation

logrotate -vf /etc/logrotate.conf
  • generate the backup code (5 code, it is not possible to know if they have not been already used, reset the key or generate more code)
oathtool -w 5 $(cat /var/lib/nethserver/home/user/.2fa.secret)
  • generate a time based code (valid 30 seconds)
oathtool --totp $(cat /var/lib/nethserver/home/user/.2fa.secret)
  • reset the otp for a user
rm -f /var/lib/nethserver/home/user/.2fa.secret

have a shell inside the nsdc container

If you find something strange, you need to access the container and use the samba-tool

systemd-run -M nsdc -t /bin/bash

Control samba container

stop, start and status of the samba DC process

systemctl -M nsdc stop samba
systemctl -M nsdc start samba
systemctl -M nsdc status samba

Search following filter in SAMBA AD

search with filters

net ads search -P objectClass=Computer
net ads search -P objectClass=User
net ads search -P objectClass=Group

you can retrieve for a specific cn

net ads search -P cn=stephane

or use wildcard

net ads search -P cn=*|less

list all entries with the administrator bind

  ldapsearch -Z -x -D CN=Administrator,CN=Users,DC=neth,DC=eu -w Nethesis,1234 -b CN=Users,DC=neth,DC=eu -h
  ldapsearch -Z -x -D  CN=stephane,CN=Users,DC=ad,DC=nethservertest,DC=org -w 'azerty' -b CN=Users,DC=ad,DC=nethservertest,DC=org -h
  • the ip must be relevant to the one of your container.
  • the default password (Nethesis,1234) must be changed to the right one.

Browse SAMBA AD field without password

systemd-run -M nsdc -q -t  /usr/bin/ldbsearch -H /var/lib/samba/private/sam.ldb

Retrieve the dn without password with ldapsearch

systemd-run -M nsdc -q -t \
    /usr/bin/ldbsearch -H /var/lib/samba/private/sam.ldb "samaccountname=${userName}" dn | \
    sed -n '/^dn: / { s/\r// ; p ; q }'

reset administrator's password

If you're running a local Samba DC account provider, to enable and reset administrator's password:

systemd-run -t -M nsdc /bin/bash
samba-tool user enable administrator
samba-tool user setpassword administrator --newpassword=Nethesis,1234

join the domain

It supports -U flag, to specify an alternative user with domain join rights. For instance

realm join -U administrator  YOURDOMAIN.COM

to leave it

realm leave

Demote a Secondary Domain Controller

Please check this

A secondary DC is down, you are sure it will never come up again (e.g. hardware failure). You may want to remove it. Make sure the “broken DC” is offline.

From Nethserver root log into the NSDC chroot.

systemd-run -M nsdc -t /bin/bash

If you know the DC-name, you can check is status in your AD, please notice the name is case-sensitive.

ldbsearch -H /var/lib/samba/private/sam.ldb '(invocationId=*)' --cross-ncs objectguid | grep -A1 DC-NAME

If you do not know the name, you may check all configured AD-DCs:

ldbsearch -H /var/lib/samba/private/sam.ldb '(invocationId=*)' --cross-ncs objectguid

Now the magic … you are sure what you are doing?

samba-tool domain demote --remove-other-dead-server=DC-NAME 

Modify the SAMBA4 AD settings

You can modify the samba ldap of the samba container with a ldif file, put your file in /var/lib/machines/nsdc/var/lib/samba/private/file.ldif.

then launch

/usr/bin/systemd-run -M nsdc -q -t /usr/bin/ldbmodify -H /var/lib/samba/private/sam.ldb /var/lib/samba/private/file.ldif

this is an example of a ldif file

dn: cn=stephane,cn=Users,dc=ad,dc=plop,dc=org
changetype: modify
replace: loginShell
loginShell: /usr/libexec/openssh/sftp-server

Get MAC address of nsdc interface

cat /var/lib/machines/nsdc/sys/class/net/host0/address

Samba Member Server Troubleshooting

Please check this page In short

  • Do you have a keytab on the file server ?
klist -k
  • check if the computer is joined to the domain.
sudo net ads testjoin

This should print:

Join is OK
  • leave the domain and rejoin:
net ads leave -U Administrator

net ads join -U Administrator

You should now have a keytab, if it is still not there, try creating it manually:

net ads keytab create -U Administrator

To retrieve the ldap settings, in a shell type the following command to get the current NethServer setup:

[root@vm5 ~]# account-provider-test dump
   "startTls" : "",
   "bindUser" : "VM5$",
   "userDN" : "dc=dpnet,dc=nethesis,dc=it",
   "port" : 636,
   "isAD" : "1",
   "host" : "",
   "groupDN" : "dc=dpnet,dc=nethesis,dc=it",
   "isLdap" : "",
   "ldapURI" : "ldaps://",
   "baseDN" : "dc=dpnet,dc=nethesis,dc=it",
   "bindPassword" : "secret",
   "bindDN" : "DPNET\\VM5$"

To expand all templates and restart the relevant services (no reboot, a business server shouldn't be rebooted) you can use:

yum install @nethserver-iso

Allow a user to the server-manager

  • NS7

The builtin /usr/share/nethesis/NethServer/Authorization/base.json policy grants full access to members of administrators.

groupadd administrators
usermod -G administrators -a

Now user has full privileges from server-manager. You have two groups with delegated powers

  • administrators: Users of this group have the same permissions as the root or admin user.
  • managers: Users of this group are granted access to the Management section.

Use the server-manager with a SSH tunnel

A SSH local port forward of 980

ssh -L 9980:localhost:980 <public IP>

Then connect to


Use the Server Manager by the terminal

Of course the display is not as good as you can have in a real browser :)

elinks -eval 'set connection.ssl.cert_verify = 0' https://localhost:980/


yum install links     # if not installed yet
links2 https://localhost:980

Allow sudo power for a group

  • create a group powerusers in Users & Groups page
  • add one ore more user to the group
  • create a sudo file like this:
  echo "%powerusers ALL=(ALL) ALL" > /etc/sudoers.d/90powerusers
  chmod 440  /etc/sudoers.d/90powerusers

Sudoers files validation

Validation of the sudoers.d syntax

visudo -c

Determine what commands a user can do

See all commands that the user may do on your system

sudo -ll -U userName

Edit sudoers files

Edit and valid when you exit the sudoers file

visudo -f /etc/sudoers.d/20_nethserver_sssd