Programming, electronics, lifestyle

16 Jan 2022

Приветственное сообщение на Raspberry Pi (motd, profile.d)

Я в принципе уже знал как +/- работает вывод текстовой информации при логине. Однако написать это меня побудил следующий вывод. А точнее две его последние строки.

artemsmirnov@Artems-MacBook-Pro ~ % ssh [email protected]
Linux theimage-9373 5.10.17+ #1403 Mon Feb 22 11:26:13 GMT 2021 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Jan  9 17:44:07 2022 from 192.168.11.1

SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.

rfkill: cannot open /dev/rfkill: Permission denied
rfkill: cannot read /dev/rfkill: Bad file descriptor

За основу образа был взят Raspberry Pi OS версии armhf от 2021-03-25. Запуск производился на Raspberry Pi Model B Plus Rev 1.2 (на которой нет Wi-Fi чипа)

Как это все устроено

При логине, SSH сервер использует PAM модули: /etc/pam.d/login и /etc/pam.d/sshd. Которые помимо аутентификации пользователей, выводят motd сообщение, и производят логин, в котором запускается скрипт profile (Разбираемся с файлами /etc/profile и /etc/bashrc).

motdman настраивается в двух местах:

  1. /etc/motd

    
    The programs included with the Debian GNU/Linux system are free software;
    the exact distribution terms for each program are described in the
    individual files in /usr/share/doc/*/copyright.
    
    Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
    permitted by applicable law.
    
  2. /etc/update-motd.d, здесь в моём образе есть только один файл 10-uname со следующим содержанием:

    #!/bin/sh
    uname -snrvm
    

Как видно это верхушка в приветственном сообщении. Далее запускается скрипт, который инициализирует окружение пользователя (инициализирует переменные, сорсит ~/.bashrc итд), помимо этого он и выводит остальную часть сообщения которую мы видим. Его конфигурация находится в следующих местах.

  1. /etc/profile – основной файл, который всё запускает

    # /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
    # and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
    
    if [ "`id -u`" -eq 0 ]; then
    PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    else
    PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games"
    fi
    export PATH
    
    if [ "${PS1-}" ]; then
    if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
        # The file bash.bashrc already sets the default PS1.
        # PS1='\h:\w\$ '
        if [ -f /etc/bash.bashrc ]; then
        . /etc/bash.bashrc
        fi
    else
        if [ "`id -u`" -eq 0 ]; then
        PS1='# '
        else
        PS1='$ '
        fi
    fi
    fi
    
    if [ -d /etc/profile.d ]; then
    for i in /etc/profile.d/*.sh; do
        if [ -r $i ]; then
        . $i
        fi
    done
    unset i
    fi
    
  2. /etc/profile.d – директория где находятся вызываемые скрипты. В моём случае это:

    • Z97-byobu.sh
    • at-dbus-fix.sh
    • bash_completion.sh
    • gawk.csh
    • gawk.sh
    • sshpwd.sh
    • wifi-check.sh

    В частности, если посмотреть содержание последнего, то мы и обнаружим откуда берется эта ошибка при логине:

    (
        export TEXTDOMAIN=wifi-check
    
        . gettext.sh
    
        if [ ! -x /usr/sbin/rfkill ] || [ ! -c /dev/rfkill ]; then
                exit 0
        fi
    
        if ! /usr/sbin/rfkill list wifi | grep -q "Soft blocked: yes" ; then
                exit 0
        fi
    
        echo
        /usr/bin/gettext -s "Wi-Fi is currently blocked by rfkill."
        /usr/bin/gettext -s "Use raspi-config to set the country before use."
        echo
    )
    

Решение проблемы с выводом

На StackOverflow я нашел решение которое ломает wifi-check.sh скрипт:

sudo sed -i '2i\ \ \ \ \ \ \ \ exit 0' /etc/profile.d/wifi-check.sh

Мне не совсем нравится идея менять содержимое чужого файла, поэтому я попробовал отключить сам rf-модуль, добавив следующие строки в /boot/config.txt:

...
[all]
...
dtoverlay=disable-wifi
dtoverlay=disable-bt

Как сказано здесь:

Однако мне это не помогло, и я решил просто переименовать расширение файла с .sh на .sh.disabled. Тк /etc/profile выбирает файлы по маске, это исключит выполнение скрипта.