Additional security software for NAS

    The series of articles is titled "Building a Secure NAS" . Therefore, this article will be considered an increase in the level of security. Also, those tools that I did not use will be described, but it is possible to apply.

    Who and how?

    Who is going to attack the system and how will it do it?

    This is usually the first question to be answered before talking about security.
    At least, in the case of NAS, there is already an implicit answer. But in order to fully answer this question, build a threat model and a model of the offender.

    Companies include the threat modeling phase in their development cycles.
    Microsoft has SDL for this , people have other models .

    They involve the use of certain techniques, such as STRIDE or DREAD (STRIDE is still more general and well supported instrumentally).

    In STRIDE, for example, a model is built from data streams and is usually large, heavy, and poorly understood. However, the tool provides a list of potential threats, which facilitates their consideration.

    The threat model is proprietary information because it makes it easier for an attacker to analyze the system and search for weak points. If he gets a model, he will not have to build it on his own, because analysts have already taken care of everything.

    It was a moment of advertising.

    So build a model of serious companies. And if this is interesting, I can somehow describe in a separate article.

    Here I will describe what is in English called "hardening" and will deal with the security flaws that were made in the process of building the system.

    Basically, maintaining security at this level is accomplished by closing known system vulnerabilities, monitoring it, and periodically checking it.

    Related Literature

    What to read:

    Snapshots and docker

    Previously, zfs-autosnapshot was installed. He repeatedly helped me, because I could restore corrupted configurations (for Nextcloud, for example) from snapshots.
    However, over time, the system began to slow down, and a few thousand snapshots spawned.

    It turned out that when creating the parent file system for containers, I forgot to set the flag com.sun:auto-snapshot=false.

    In the original article, this problem has already been fixed, here I will show how to get rid of unnecessary snapshots.

    More on how to fix the error.

    Сначала надо выключить zfs-auto-snapshot на родительской файловой системе докера:

    zfs set com.sun:auto-snapshot=false tank0/docker/lib

    Теперь удалите неиспользуемые контейнеры и образы:

    docker container prune
    docker image prune

    Произведите удаление снэпшотов:

    zfs list -t snapshot -o name -S creation | grep -e ".*docker/lib.*@zfs-auto-snap" | tail -n +1500 | xargs -n 1 zfs destroy -vr

    И выключите их на всех файловых системах образов:

    zfs list -t filesystem -o name -S creation | grep -e "tank0/docker/lib" | xargs -n 1 zfs set com.sun:auto-snapshot=false

    Подробнее возможно почитать здесь.


    Last time, only one LDAP user was created with an administrative role.

    But most services do not need to change anything in the user database. Therefore, it would be nice to add a user only for reading. In order not to create roles manually, it is possible to use a container initialization script.

    First, add to the docker-compose.ymlsettings to enable the user to read only:


    Full file under the spoiler.

    version: "2"
          name: docker0
        image: "osixia/openldap"
        hostname: "open-ldap"
        restart: always
          - "LDAP_DOMAIN=nas.nas"
          - "LDAP_READONLY_USER=true"
          - "LDAP_READONLY_USER_USERNAME=readonly"
          - "LDAP_TLS=true"
          - "LDAP_TLS_ENFORCE=false"
          - "LDAP_TLS_CRT_FILENAME=ldap_server.crt"
          - "LDAP_TLS_KEY_FILENAME=ldap_server.key"
          - "LDAP_TLS_CA_CRT_FILENAME=ldap_server.crt"
          - ./certs:/container/service/slapd/assets/certs
          - ./ldap_data/var/lib:/var/lib/ldap
          - ./ldap_data/etc/ldap/slapd.d:/etc/ldap/slapd.d
          - ldap
        image: "osixia/phpldapadmin:0.7.1"
        hostname: "nas.nas"
        restart: always
          - ldap
          - docker0
          - 443
          - open-ldap:open-ldap-server
          - ./certs:/container/service/phpldapadmin/assets/apache2/certs
          - VIRTUAL_HOST=ldap.*
          - VIRTUAL_PORT=443
          - VIRTUAL_PROTO=https
          - "PHPLDAPADMIN_LDAP_HOSTS=open-ldap-server"
          #- "PHPLDAPADMIN_HTTPS=false"
          - "PHPLDAPADMIN_HTTPS_CRT_FILENAME=certs/ldap_server.crt"
          - "PHPLDAPADMIN_HTTPS_KEY_FILENAME=private/ldap_server.key"
          - "PHPLDAPADMIN_HTTPS_CA_CRT_FILENAME=certs/ldap_server.crt"
        image: openfrontier/ldap-ssp:https
          - /etc/ssl/certs/ssl-cert-snakeoil.pem:/etc/ssl/certs/ssl-cert-snakeoil.pem
          - /etc/ssl/private/ssl-cert-snakeoil.key:/etc/ssl/private/ssl-cert-snakeoil.key
        restart: always
          - ldap
          - docker0
          - 80
          - open-ldap:open-ldap-server
          - VIRTUAL_HOST=ssp.*
          - VIRTUAL_PORT=80
          - VIRTUAL_PROTO=http
          - "LDAP_URL=ldap://open-ldap-server:389"
          - "LDAP_BINDDN=cn=admin,dc=nas,dc=nas"
          - "LDAP_BASE=ou=users,dc=nas,dc=nas"
          - "MAIL_FROM=admin@nas.nas"
          - "PWD_MIN_LENGTH=8"
          - "PWD_MIN_LOWER=3"
          - "PWD_MIN_DIGIT=2"
          - "SMTP_HOST="
          - "SMTP_USER="
          - "SMTP_PASS="

    Then, you need to make a dump and delete:

    $ cd /tank0/docker/services/ldap
    $ tar czf ~/ldap_backup.tgz .
    $ ldapsearch -Wx -D "cn=admin,dc=nas,dc=nas" -b "dc=nas,dc=nas" -H ldap:// -LLL > ldap_dump.ldif
    $ docker-compose down
    $ rm -rf ldap_data
    $ docker-compose up -d

    So that the server, when recovering from dump, does not swear at duplicate elements, delete the following lines in the file:

    dn: dc=nas,dc=nas 
    objectClass: top 
    objectClass: dcObject 
    objectClass: organization 
    o: NAS 
    dc: nas 
    dn: cn=admin,dc=nas,dc=nas 
    objectClass: simpleSecurityObject 
    objectClass: organizationalRole 
    cn: admin 
    description: LDAP administrator 
    userPassword:: PASSWORD_BASE64

    And restore users and groups:

    $ ldapadd -Wx -D "cn=admin,dc=nas,dc=nas" -H ldap:// -f ldap_dump.ldif

    In the database there will be such a beast:

    dn: cn=readonly,dc=nas,dc=nas
    cn: readonly
    objectClass: simpleSecurityObject
    objectClass: organizationalRole
    userPassword:: PASSWORD_BASE64
    description: LDAP read only user

    Roles in the LDAP server configuration for it will be created by the container.
    Perform checks after recovery and delete the backup:

    $ rm ~/ldap_backup.tgz

    Adding groups to LDAP

    Convenient is the division of LDAP users into groups similar to POSIX groups in Linux.
    For example, it is possible to create groups whose users will have access to repositories, access to the cloud, or access to the library.

    Groups are easily added to phpLDAPAdmin, and I will not focus on this.

    I note only the following:

    • The group is created from the "Default" template. This is not a POSIX group, but a group of names.
    • Accordingly, the group has an attribute objectClassthat includes the value groupOfUniqueNames.

    Adding a group to phpLDAPAdmin


    In Docker, almost everything is done for you.
    By default, it uses the system call restriction that is enabled in the OMV core:

    # grep SECCOMP /boot/config-4.16.0-0.bpo.2-amd64 

    Here it is possible to read a little more about the basic Docker security rules.
    Also, if AppArmor is enabled, Docker can integrate with it and forward its profiles to the container .


    Eliminate OS detection

    The network is located behind the router, but it is possible to do a curious exercise by changing some parameters of the network stack so that the OS cannot be identified by the answers.
    There is little real benefit from this, because the attacker will study the banners of the services and anyway understand what kind of OS you are using.

    Nmap shows which OS is running on the device.
    # nmap -O localhost
    Starting Nmap 7.40 ( ) at 2018-08-26 14:39 MSK
    Nmap scan report for localhost (
    Host is up (0.000015s latency).
    Other addresses for localhost (not scanned): ::1
    Not shown: 992 closed ports
    53/tcp   open  domain
    80/tcp   open  http
    443/tcp  open  https
    5432/tcp open  postgresql
    Device type: general purpose
    Running: Linux 3.X|4.X
    OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
    OS details: Linux 3.8 - 4.6
    Network Distance: 0 hops
    OS detection performed. Please report any incorrect results at .
    Nmap done: 1 IP address (1 host up) scanned in 4.07 seconds

    Loading settings from sysctl.conf:

    # sysctl -p /etc/sysctl.conf 
    net.ipv4.conf.all.accept_redirects = 0
    net.ipv6.conf.all.accept_redirects = 0
    net.ipv4.conf.all.send_redirects = 0
    net.ipv4.conf.all.accept_source_route = 0
    net.ipv6.conf.all.accept_source_route = 0
    net.ipv4.tcp_rfc1337 = 1
    net.ipv4.ip_default_ttl = 128
    net.ipv4.icmp_ratelimit = 900
    net.ipv4.tcp_synack_retries = 7
    net.ipv4.tcp_syn_retries = 7
    net.ipv4.tcp_window_scaling = 1
    net.ipv4.tcp_timestamps = 1

    And so...

    Nmap cannot determine the OS.
    # nmap -O localhost
    Starting Nmap 7.40 ( ) at 2018-08-26 14:40 MSK
    Nmap scan report for localhost (
    Host is up (0.000026s latency).
    Other addresses for localhost (not scanned): ::1
    Not shown: 992 closed ports
    53/tcp   open  domain
    80/tcp   open  http
    443/tcp  open  https
    5432/tcp open  postgresql
    No exact OS matches for host (If you know what OS is running on it, see ).
    TCP/IP fingerprint:
    Network Distance: 0 hops
    OS detection performed. Please report any incorrect results at .
    Nmap done: 1 IP address (1 host up) scanned in 19.52 seconds

    These settings are required to register in /etc/sysctl.conf, then with each reboot they will be read automatically.

    Full /etc/sysctl.conf
    # Additional settings - these settings can improve the network
    # security of the host and prevent against some network attacks
    # including spoofing attacks and man in the middle attacks through
    # redirection. Some network environments, however, require that these
    # settings are disabled so review and enable them as needed.
    # Do not accept ICMP redirects (prevent MITM attacks)
    net.ipv4.conf.default.accept_redirects = 0
    net.ipv6.conf.default.accept_redirects = 0
    net.ipv4.conf.all.accept_redirects = 0
    net.ipv6.conf.all.accept_redirects = 0
    # _or_
    # Accept ICMP redirects only for gateways listed in our default
    # gateway list (enabled by default)
    # net.ipv4.conf.all.secure_redirects = 1
    # Do not send ICMP redirects (we are not a router)
    net.ipv4.conf.all.send_redirects = 0
    # Do not accept IP source route packets (we are not a router)
    net.ipv4.conf.all.accept_source_route = 0
    net.ipv6.conf.all.accept_source_route = 0
    ## protect against tcp time-wait assassination hazards
    ## drop RST packets for sockets in the time-wait state
    ## (not widely supported outside of linux, but conforms to RFC)
    net.ipv4.tcp_rfc1337 = 1
    # Log Martian Packets
    #net.ipv4.conf.all.log_martians = 1
    # Magic system request Key
    # 0=disable, 1=enable all
    # Debian kernels have this set to 0 (disable the key)
    # See
    # for what other values do
    # Protected links
    # Protects against creating or following links under certain conditions
    # Debian kernels have both set to 1 (restricted) 
    # See
    vm.overcommit_memory = 1
    vm.swappiness = 10
    # Anti-fingerprinting.
    # Def: 64.
    net.ipv4.ip_default_ttl = 128
    # Скорость генерации ICMP пакетов (по умолчанию 1000)
    net.ipv4.icmp_ratelimit = 900
    # Количество повторных отсылок пакетов, на которые не получен ответ.
    # Def: 5.
    net.ipv4.tcp_synack_retries = 7
    # Def: 5.
    net.ipv4.tcp_syn_retries = 7
    # Изменять параметры TCP window и timespamp в соответствии с 1323.
    net.ipv4.tcp_window_scaling = 1
    net.ipv4.tcp_timestamps = 1
    # Redis requirement.
    net.core.somaxconn = 511

    Protection against defining versions of services is more useful, for which an attacker can also use Nmap:

    # nmap -sV -sR --allports --version-trace

    The result is not very good for the system.
    Not shown: 991 closed ports
    22/tcp   open  ssh         OpenSSH 7.4p1 Debian 10+deb9u3 (protocol 2.0)
    25/tcp   open  smtp        Postfix smtpd
    80/tcp   open  http        nginx 1.13.12
    111/tcp  open  rpcbind     2-4 (RPC #100000)
    139/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
    443/tcp  open  ssl/http    nginx 1.13.12
    445/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
    3493/tcp open  nut         Network UPS Tools upsd
    8000/tcp open  http        Icecast streaming media server 2.4.2
    Service Info: Hosts:  nas.localdomain, NAS; OS: Linux; CPE: cpe:/o:linux:linux_kernel
    Final times for host: srtt: 22 rttvar: 1  to: 100000

    But not everything is smooth with disguise:

    • For each service an individual approach is needed here.
    • It is not always possible to remove the version.

    For example, for SSH it is possible to add an option DebianBanner noto /etc/ssh/sshd_confg.

    As a result:

    22/tcp   open  ssh         OpenSSH 7.4p1 (protocol 2.0)

    Better, alas, will not work: the version is used by SSH to determine which features are supported, and it is possible to change it only by patching the server .


    Not the most well-known protection technique that allows a remote user who knows the secret to connect to a closed port.
    The work resembles a code lock : everyone knows that service daemons are running on the server, but "they are not there" until the code is dialed.
    For example, in order to connect to an SSH server, a user needs to knock on UDP ports 7000, TCP 7007, and UDP 7777.
    After that, with his IP firewall will be allowed on the private TCP port 22.

    Read more about how this works, it is possible to read here . And in the Debian manual .

    I do not recommend using, because fail2ban is usually sufficient.


    I configure the firewall via OpenMediaVault Web GUI, which I recommend to you.

    Open the necessary ports, such as 443 and 22, the rest - to taste. Also, it is advisable to enable logging of dropped packets.


    If SSH hangs on port 22, which is open on the Internet, you will receive many interesting messages ...
    # grep "invalid user" /var/log/auth.log|head
    Aug 26 00:07:57 nas sshd[29786]: input_userauth_request: invalid user test [preauth]
    Aug 26 00:07:59 nas sshd[29786]: Failed password for invalid user test from port 51268 ssh2
    Aug 26 00:11:01 nas sshd[5641]: input_userauth_request: invalid user 0 [preauth]
    Aug 26 00:11:01 nas sshd[5641]: Failed none for invalid user 0 from port 49025 ssh2
    Aug 26 00:11:04 nas sshd[5644]: input_userauth_request: invalid user 0101 [preauth]
    Aug 26 00:11:06 nas sshd[5644]: Failed password for invalid user 0101 from port 59867 ssh2
    Aug 26 00:32:55 nas sshd[20367]: input_userauth_request: invalid user ftp [preauth]
    Aug 26 00:32:56 nas sshd[20367]: Failed password for invalid user ftp from port 47981 ssh2
    Aug 26 00:32:57 nas sshd[20495]: input_userauth_request: invalid user guest [preauth]
    Aug 26 00:32:59 nas sshd[20495]: Failed password for invalid user guest from port 34202 ssh2

    At the risk of appearing banal, I will remind you what is required:

    • Strictly prohibit logging in as root.
    • Restrict access to specified users only.
    • Change port to non-standard.
    • It is advisable to disable password authentication, leaving only the key.

    Read more is possible, for example here .

    All this is easily done from the OpenMediaVault interface via the menu "Services -> SSH".
    Except for the fact that I did not change the port to a non-standard one, leaving 22 in the local network and simply replacing the port in the NAT router.

    I compiled such an interesting list of enumerated accounts until I changed the SSHD port to a different one from 22.
    # grep "invalid user" /var/log/auth.log|sed 's/.*invalid user \([^ ]*\) .*/\1/'|sort|uniq

    Once this is done, unauthorized entry attempts will be made much less frequently.

    To further improve the situation, it is possible to block attackers from certain IPs after several attempts at entry.

    What can be used for:

    • Fail2ban . A popular utility that works not only for SSH, but also for many other applications.
    • Denyhosts . Looks like fail2ban.
    • Sshguard , if you wish, you can try to use it, but I was not interested in them in detail.

    I am using fail2ban. It will monitor the logs for various unwanted actions by certain IPs, and ban them in case of exceeding the number of positives:

    2018-08-29 21:17:25,351 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:17:25,473 fail2ban.actions        [8650]: NOTICE  [sshd] Ban
    2018-08-29 21:17:27,359 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:28:13,128 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:28:13,132 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:28:15,137 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:28:20,145 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:28:25,153 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:28:25,421 fail2ban.actions        [8650]: NOTICE  [sshd] Ban
    2018-08-29 21:30:05,272 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:30:05,274 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:30:13,285 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:30:13,286 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:30:15,289 fail2ban.filter         [8650]: INFO    [sshd] Found
    2018-08-29 21:30:15,803 fail2ban.actions        [8650]: NOTICE  [sshd] Ban

    The ban is made by adding a firewall rule. After a specified time, the rule is deleted, and the user can again try to log in.

    Initially, only SSH is included, but it is possible to enable monitoring of the logs of the Web server and other services, at least the same OMV .
    And also, take out logs from containers and set fail2ban on them too.

    I recommend adding services to taste.
    You can read more about the configuration, for example, here or on your own Wiki .



    A small utility that should be installed for convenience. Highlight the logs and show them in a beautiful form.
    It is possible to use any such utility , as long as errors and problem areas of the logs are highlighted so that their visual analysis is facilitated.


    It is worthwhile to install and configure logcheck just so that when identifying problems with the configuration reported in the logs, you immediately see it in the mail.
    It helps to see well what is going wrong, although it requires adjustment.


    # apt-get install logcheck

    Immediately after installation, it will send reports.

    Sample report.
    System Events
    Oct  2 02:02:15 nas kernel: [793847.981226] [DROPPED] IN=br-ce OUT= PHYSIN=veth6c2a68e MAC=ff:ff:ff:ff:ff:ff: SRC= DST= LEN=29 TOS=0x00 PREC=0x00 TTL=64 ID=40170 DF PROTO=UDP SPT=35623 DPT=35622 LEN=9
    Oct  2 02:02:20 nas hddtemp[13791]: /dev/sdh: Micron_1100 N              #020Ђ: 32 C
    Oct  2 02:02:37 nas kernel: [793869.247128] [DROPPED] IN=br-7ba OUT= MAC= SRC= DST= LEN=239 TOS=0x00 PREC=0x00 TTL=128 ID=23017 DF PROTO=UDP SPT=138 DPT=138 LEN=219
    Oct  2 02:02:37 nas kernel: [793869.247174] [DROPPED] IN=br-7ba OUT= MAC= SRC= DST= LEN=232 TOS=0x00 PREC=0x00 TTL=128 ID=23018 DF PROTO=UDP SPT=138 DPT=138 LEN=212
    Oct  2 02:02:37 nas kernel: [793869.247195] [DROPPED] IN=br-673 OUT= MAC= SRC= DST= LEN=239 TOS=0x00 PREC=0x00 TTL=128 ID=8959 DF PROTO=UDP SPT=138 DPT=138 LEN=219
    Oct  2 02:02:37 nas kernel: [793869.247203] [DROPPED] IN=br-673 OUT= MAC= SRC= DST= LEN=232 TOS=0x00 PREC=0x00 TTL=128 ID=8960 DF PROTO=UDP SPT=138 DPT=138 LEN=212
    Oct  2 02:02:50 nas hddtemp[13791]: /dev/sdh: Micron_1100 N              #020Ђ: 32 C

    It is seen that there is a lot of superfluous, and further configuration will be reduced to its filtering.

    First you need to turn off the hddtemp, which does not work correctly due to non-ASCII characters in the SSD name.
    After correcting the hddtemp file, the messages stopped coming:

    ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ hddtemp\[[0-9]+\]: /dev/([hs]d[a-z]|sg[0-9]):.*[0-9]+.*[CF]
    ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ hddtemp\[[0-9]+\]: /dev/([hs]d[a-z]|sg[0-9]):.*drive is sleeping

    Then, it is possible to see what logcheck is talking about blocking broadcast traffic with firewall:

    [793869.247128] [DROPPED] IN=br-7ba OUT= MAC= SRC= DST= LEN=239 TOS=0x00 PREC=0x00 TTL=128 ID=23017 DF PROTO=UDP SPT=138 DPT=138 LEN=219

    Therefore, it is necessary to allow broadcast traffic from the router and containers:

    • Port 35622 from container with urbackup.
    • Port 5678 from the router is the discovery of RouterOS neighbors. It is possible to disable it on the router.
    • Port 5353 to address is mDNS .

    Logcheck check:

    sudo -u logcheck logcheck -t -d

    Finally, problems are visible:

    Oct 21 21:58:18 nas systemd[1]: Removed slice User Slice of user.
    Oct 21 21:58:31 nas systemd[1]: smbd.service: Unit cannot be reloaded because it is inactive.
    Oct 21 21:58:31 nas root: /etc/dhcp/dhclient-enter-hooks.d/samba returned non-zero exit status 1

    It turns out that SAMBA does not start. Indeed, the analysis showed that I had disguised it through the systemctl, and OMV was trying to launch it.

    Logcheck will still be spammed with various messages.
    For example, zfs-auto-snapshot has passed:

    Oct 21 22:00:57 nas zfs-auto-snap: @zfs-auto-snap_frequent-2018-10-21-1900, 16 created, 16 destroyed, 0 warnings.

    To ignore:

    ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ zfs-auto-snap: \@zfs-auto-snap_[[:alnum:]-]+, [0-9]+ created, [0-9]+ destroyed, 0 warnings.$

    rrdcached also ignore:

    ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[0-9]+\]: flushing old values$
    ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[0-9]+\]: rotating journals$
    ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[0-9]+\]: started new journal [./[:alnum:]]+$
    ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[0-9]+\]: removing old journal [./[:alnum:]]+$

    Also, it is advisable to remove zed, if it has not yet been removed:

    ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ (/usr/bin/)?zed: .*$
    ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ (/usr/bin/)?zed\[[0-9]+\]: .*$

    Well, and so on. Many people think that logcheck is quite a useless utility.
    This is true if you use it as something that you have set and forgotten.

    However, if you understand that logcheck is just a customizable log filter, without heuristics, magic, and adaptive algorithms, the question of its usefulness does not arise. Iteratively, examining what he sends and, either by inserting it into the ignore list or by correcting it, it is gradually possible to achieve informative reports.

    Using an automated tool for analysis is much better than running logs through the same regular expressions with your hands, and often better than using a complete data analysis system like Splunk.

    About logcheck and configuration may be read on Wiki Gentoo and here .

    Node-level IDS

    Here I refer to my own article “A Brief Analysis of Solutions in the Field of IDS and Development of a Neural Network Anomaly Detector in Data Networks” , in which there are several examples.

    You can read a more complete review and comparison of similar IDS on the Wiki .


    A complex and large script for static analysis of known gaps from RedHat.
    There is its port in Debian , which I recommend downloading and running at least once.

    STIG-4 work example
    # cd 
    root@nas:~# git clone
    Cloning into 'STIG-4-Debian'...
    remote: Enumerating objects: 572, done.
    remote: Total 572 (delta 0), reused 0 (delta 0), pack-reused 572
    Receiving objects: 100% (572/572), 634.37 KiB | 0 bytes/s, done.
    Resolving deltas: 100% (316/316), done.
    root@nas:~# cd STIG-4-Debian/
    root@nas:~/STIG-4-Debian# bash -H
    Script Run: Mon Nov 12 23:58:34 MSK 2018
    Start checking process...
    [ FAIL ] The cryptographic hash of system files and commands must match vendor values.
    Pass Count:  54
    Failed Count:  137

    The process of working with this script is something like this:

    • Run the script.
    • Search the web for every line from [ FAIL ].
    • As a rule, a link to the STIG online database will be found.
    • Correct, following the instructions in the database, making a discount on the fact that this is Debian.
    • Run the script again.


    Too much has been written about RkHunter . Used long ago, widely, still evolving. Available in the Debian repository.


    A modular shell script that performs system auditing and intrusion detection.
    In some ways similar to STIG-4.
    It can use third-party utilities for analyzing logs, for detecting violation of checksums.

    Consists of a large number of different modules.

    For example, there is a module that detects services that use deleted files, which happens when the libraries used by the service were changed during the system update, but the service was not restarted for some reason.

    There are modules for searching service users that are no longer used, system checks for the absence of security patches, umask checks, etc.

    Read more in man .

    Already 10 years does not develop (yes, I'm not the only one who throws software).


    Typical HIDS that can:

    • Check the integrity of the entire system using cryptographic hashes.
    • Search for various executable files with the installed SUID, which should not be installed.
    • Detect hidden processes.
    • Sign logs and databases.

    Plus, it has centralized monitoring with a web-based interface and centralized logging to the server.
    Usually, it is used to check whether the system binary files have changed between updates.
    When updating the operating system, the signature database is rebuilt.

    Naturally, ideally, the database should be stored on another machine and periodically perform offline checks. Of course, the base is signed, but when the machine is running, if the attacker takes control, no one bothers to change the result of issuing such systems.

    Once upon a time I used this HIDS: it is not very convenient and requires effort.
    The problem here is not Samhain, but in the very class of similar systems.


    Almost the same as Samhain, but Tripwire is already Serious business.
    Supported by a large enough company, has a corporate version.


    Utility from the author RkHunter .

    Partially proprietary, but has a free version.
    On the home page there is a small comparison of it with several other systems.
    It is similar to Tiger and performs approximately the same work, but unlike him, it is supported by the author.
    Use or not, decide for yourself. In one of the tutorials referenced at the beginning of the article, Lynix is ​​used along with Tripwire.


    The name speaks for itself. Utility to find rootkits.
    In short:

    • It searches for system binaries modified by rootkits.
    • Checks for no network interfaces in promiscuous mode.
    • Checks if the records were deleted from latslog, wtmp and utmp.
    • Searches for kernel-level Trojans signatures, both in memory and in the file system.

    It has a rather impressive list of rootkits detected.


    A system for determining elevation of process privileges for Linux.

    Do not confuse with the ninja-build build system.

    Runs like a daemon and monitors the processes. If the process starts with zero UID / GID, Ninja writes information about it to the log, and if it is launched from an unauthorized user, it can kill it (the process will have to be dealt with by the user later).
    Some executable files may be included in the white list (for example, su).
    Authorized users are members of a given group.

    There are Ubuntu repositories that easily connect to Debian.

    Security scanners

    I will not dwell on this topic in detail. The topic is too extensive. Scanners are required in order to check the security of the system, acting with the same tools as the attacker.
    In the case of basic checks, Nmap and W3af are enough for Web services.

    Systems of alternative security models

    Linux has an selective (also discretionary) access model .
    But access models are known about ten. Of these, besides discretionary, role and mandate are also common .

    The following systems mainly partially implement the latter, sometimes with role buds.

    You can read more about all three in the IBM Secure Linux article series .

    In the NAS, I have not used any of them yet, but I plan to enable AppArmor.
    It cannot be said that these systems greatly increase security, but they narrow the surface of attack.
    Of course, they won't save from exiting the browser's sandbox through a bug in the system call, with the ability to write to the kernel address space, but can help from malicious actions in user space.

    Access Control Lists

    The first version of the mandatory control system, dependent on the capabilities of the file system.
    Of course, ZFS supports full access control lists.

    List of rights in the ACL for ZFS.
    • Разрешение на добавление нового файла в каталог.
    • Разрешение на создание подкаталога в каталоге.
    • Разрешение на удаление файла.
    • Разрешение на удаление файла или каталога внутри каталога.
    • Разрешение на выполнение файла или поиска в содержимом каталога.
    • Разрешение на перечисление содержимого каталога.
    • Разрешение на чтение списка ACL (команда ls).
    • Разрешение для чтения базовых атрибутов файла (отличных от списков ACL, атрибутов на уровне команды "stat").
    • Разрешение для чтения содержимого файла.
    • Разрешение для чтения расширенных атрибутов файла или поиска в каталоге расширенных атрибутов файла.
    • Разрешение для создания расширенных атрибутов или записи в каталог расширенных атрибутов.
    • Разрешение для изменения или замены содержимого файла.
    • Разрешение для изменения данных о времени, связанных с файлом или каталогом, на произвольное значение.
    • Разрешение для создания или изменения списков ACL с помощью команды chmod.
    • Разрешение для изменения владельца или группы владельца файла. Или возможность выполнения для данного файла команд chown или chgrp .
    • Разрешение для владения файлом или изменения группы владельца файла на группу, в состав которой входит пользователь. Для изменения владельца или группы владельца файла на произвольного пользователя или группу необходимо право PRIV_FILE_CHOWN.
    • Наследование файлами каталога только списками ACL из родительского каталога.
    • Наследование списков ACL в подкаталогах только из родительского каталога.
    • Наследование списков ACL из родительского каталога, но только по отношению к новым файлам или подкаталогам, а не непосредственно к каталогу. Для определения наследуемого списков ACL необходимо установить флаг file_inherit, флаг dir_inherit или оба флага.
    • Наследование списков ACL из родительского каталога содержимым первого уровня каталога, но не второго или последующих уровней.

    Configuring ACLs is quite a chore and they are more likely used for fine access control than for protection. But this mechanism of the mandatory access control model fully implements.

    Unlike EXT systems, in ZFS ACL control is implemented not through separate utilities setfacl/getfacl, but through standard chmodand ls.


    Mandatory access control system based on file paths.

    Processes that are identified based on the paths to their executable files transferred to the system call execare controlled by the system, when they use system calls open, execand the like.
    These calls are passed the paths to the files with which the process wants to work.
    AppArmor checks if the process is allowed to access these paths.
    If not, the system call will return an error.
    Also can set process capabilites.

    Processes are described by text-based profile files, which are combined into a database. There is a learning mode for quickly creating a profile when the process is being analyzed, and all the paths that he used are recorded in the profile.

    An example of a simple profile for the ping utility.
    #include <tunables/global>
    profile ping /{usr/,}bin/ping flags=(complain) {
      #include <abstractions/base>
      #include <abstractions/consoles>
      #include <abstractions/nameservice>
      capability net_raw,
      capability setuid,
      network inet raw,
      network inet6 raw,
      /{,usr/}bin/ping mixr,
      /etc/modules.conf r,
      # Site-specific additions and overrides. See local/README for details.
      #include <local/>

    It can be seen that the profile does not have to describe everything, because has the ability to connect abstractions. Also, it is worth noting that the user can easily supplement the profile in a separate configuration file ( local/, without touching the settings that come with the package.

    Regular option for many deb-based systems.
    And it integrates with firejail , which allows for increased isolation.

    I use it on working systems, occasionally I supplement the base, correct the rules and send them patches.

    For use in Debian, there is a manual .


    SELinux architecture

    Mandatory access control system.
    A gift from the NSA , about working with which in Debian is described in the official manual .

    The central notion of SELinux is the type enforcement model.

    All users, files, processes, network resources, and so on have SELinux tags. One of the components of the label is "type".

    For example, a browser may be launched, labeled firefox_t.
    SELinux simply provides the ability to map application labels to resource labels to which they have access.


    allow firefox_t user_home_t : file { read write };

    This simply allows the browser running how firefox_tto read and write to files in your home directory, labeled as user_home_t.


    allow user_t user_home_t:file { create read write unlink };

    The rule allows the type user_tto create, read, write and delete files with a type user_home_t. The type user_tmost likely has a user.

    Labels, roles and types constitute the security context.

    An important difference from the sandboxes similar to the AppArmor sandbox systems is that the security context is preserved when the file is transferred between different file systems.

    A little more about the basic primitives of SELinux, see under the spoiler.
    • Пользователь в SELinux не эквивалентен пользователю в Linux. При смене пользователя через su или sudo, пользователь SELinux не меняется. Обычно несколько Linux пользователей являются одним SELinux пользователем, но возможно и отображение 1:1, как это сделано для root.
    • Роль, одну или более, могут иметь пользователи. Например "непривилегированный пользователь", "Web-администратор", "Администратор БД". Объекты также могут иметь роль, и обычно это роль object_r.
      Что конкретно ограничивает и позволяет роль, определяется политикой.
    • Тип или домен является основным средством для определения доступа. Тип — это способ классифицировать приложение, либо ресурс.
    • Контекст или метку имеет каждый процесс в системе. Это атрибут, используемый для того, чтобы определить разрешён ли доступ процесса к объекту. Например, процесс может иметь контекст user_u:user_r:user_t, а файл в каталоге пользователя имеет контекст user_u:object_r:user_home_t. Контекст состоит из четырёх полей:


    Первое поле — SELinux user. Второе и третье — роль и тип, соответственно. Четвёртое — необязательное поле MLS диапазона.

    Например, файлы в вашем домашнем каталоге, вероятно помечены, как user_home_t.user_home_t — это тип, и политика будет считать все файлы с данным типом, относящимися к вашему домашнему каталогу.

    • Объектные классы или категории объектов, такие как dir для каталогов или file для файлов используются внутри политики, чтобы более точно определить, какие виды доступа разрешены. Каждый объектный класс содержит набор разрешений, определяющий варианты доступа к объекту. Например, file содержит разрешения на создание (create), чтение (read), запись (write) и удаление (unlink), а класс unix_stream_socket object (сокет UNIX) имеет разрешения на создание (create), установление соединения (connect), и посылку данных (sendto).

    As it becomes clear from the above, setting up such a system is very dreary and requires scrupulousness.
    But there is an extensive policy base. Therefore, most typical actions (for example, allowing Samba to fumble home directories) are performed by several simple commands.

    Also, as in AppArmor, there is a permissive mode in which applications are allowed to access resources, but all calls are logged.
    This then allows you to create a profile for the application.
    The difference is that this mode is enabled for the entire system, whereas in AppArmor it is possible to selectively switch it for specific applications.

    The small introductory description on SELinux is on Habré.
    And a little more detailed .
    For enlightenment, read the course from IBM .


    Difficult and somehow did not take root on Debian. The last time I checked it, he broke the system.
    In general, this system (not a patch to the core for a long time), is the legacy of Gentoo . Everything is simple there: hardening is done by several teams .

    However, as the installation of the OS .

    There is a guide for Debian on how to use the GrSecurity and PaX symbiosis.


    Tomoyo in Debian is described in a small tutorial .

    Mandatory access control system based on file names. Looks like AppArmor, but less common. It has been developing since 2003.
    The same principle, there is also a training mode, similar tools.
    Configuration files are less structured, compared to AppArmor, well, the base profiles are smaller.

    Little things

    The old memory used to remove the excess from earlier /etc/securettyso that root can only log in from certain terminals (usually local), but now there is no much sense in this.

    Now similar security mechanisms are implemented through PAM, and their configuration can be found in /etc/security.

    Instead of such complex packages as Samhain and Tripwire, it is often a rather small debsums utility that checks the checksums of the installed binaries.


    The article was quite voluminous. And although much is not told, to delay its output is no longer a desire.

    As always, configuration and stuff are available in my Github repository , which is gradually being added.

    Also popular now: