Убрать защиту ветки main. Сделать её не Default Branch и не Protected Branch
Потом
#Checkout the branch locally.
git checkout branch
#Rename it locally
git checkout -b branch_old
#delete remote branch
git push --delete origin branch
#push the locally renamed branch to remote.
git push --set-upstream origin branch_old
X-Window — основа графического интерфейса в Unix. Рендеринг происходит на стороне клиента. Программа, занимающаяся рендерингом, называется X-server.
X2GO — комбинация X-Window, ssh и сжатия данных
Протокол Remote Desktop основан на пересылке битмапов отрендеренных на сервере. На сервере запускается X-server, состоящий из xRDP и xorgxrdp. На клиенте используются remmina или rdesktop.
VNC — еще один протокол, основанный на пересылке битмапов. Сервер Xvnc (X-server на входе и VNC сервер на выходе). Клиент TigerVNC.
Изначально X-Window это клиент серверная архитектура и сетевой протокол передачи графических примитивов и событий ввода
X-Server рисует примитивы и принимает ввод от устройств. Может быть реализован на уровне драйверов видеокарт (XOrg), на OpenGL, на DIRECTX, в буфере в памяти (Xvfb), в окне другого X-Server'а (Xnest)
Расширения протокола обеспечивают эффективность на локальном ПК. Composite (рендеринг за пределами окна), XRender (аппаратное ускорение), GLX (OpenGL)
X-Server обеспечивает корневое окно и иерархию вложенных окон, но не дает интерактивных средств для управления окнами
Window manager создает, разворачивает, сворачивает и перемещает окна. Рисует в окнах рамочки.
Клиент получает окно, скорее всего вложенное в окно Window manager
Session Manager обеспечивает запуск комплекса программ для формирования рабочего стола
Клиенты используют библиотеку (классическая XLib, с 2001 года XCB X protocol C-language Binding)
Внешний вид приложения определяется библиотекой виджетов. Athena Widgets, Motiff, GTK, Qt, wxWidgets
На одном компьютере может быть запущено несколько X-серверов.
Доступ клиентов к серверу идет через сокет. Может использоваться Unix-сокет или Inet-сокет
Номер сервера кодируется в имени Unix-сокета (/tmp/.X11-unix/X0) или в номере порта для TCP/IP (6000 + номер сервера)
Для клиента адрес сервера определяется переменной DISPLAY в формате [хост]:сервер[.экран]
Локальный сервер может быть запущен без доступа по TCP
/usr/bin/X11/X -nolisten tcp
Ограничение доступа по IP.
xhost +192.168.1.12
MIT-Magick-Cookie основан на знании сервером и клиентом разделяемого секрета У клиента секреты хранятся в файле ~/.Xauthority
mcookie
— генерация 128 разрядного числа, xauth
— добавление его (на X-Server ?) в файл ~/.Xauthority
xauth add :0 . `mcookie`
ssh
c опцией -X
копирует пробрасывает порт локального сервера на удаленную машину и одновременно добавляет куки в .Xauthority
При запуске графических программ через sudo
надо предпринять дополнительные усилия. Команда sudo может чистить переменные окружения (в том числе DISPLAY), кроме того, у пользователя, от имени которого выполняется команда, свой ~/.Xauthority, в который надо скопировать значение куки.
Mobaxterm - комплекс из XOrg, утилит GNU, ssh и запускалки для Windows. Один самораспаковывающийся файл. Имеет свой оконный менеджер.
Xming - сервер, который запускается через xlаunch
в нескольких режимах:
+ полноэкранное корневое окно,
+ корневое окно в окне Windows,
+ свой оконный менеджер и каждое приложение в своем окне Windows
X2GO — кроссплатформенное сочетание X-сервера, ssh и сжатия данных
При старте компьютера через systemd
— graphical.target
Скриптом startx
.
startx
:mcookie
создает MIT-cokie и регистрирует ее;xinit
, передавая ему команды для запуска клиента и сервераxinit
получает две группы параметров: команда на старт сервера и команда на старт клиента.
Если первый параметр группы начинается с '/' или '.', то выполняется он; иначе проверяются переменные окружения XINITRC и XSERVERRC и, если они установлены, то соответствующие файлы указываются в качестве команд для запуска; иначе выполняется команда по умолчанию. Затем xinit
делает два fork() и стартует сервер и клиент.
xinit $clientargs -- $serverargs $authdisplay &
Файлы для запуска клиента и сервера по умолчанию
В startx
userclientrc="$HOME/.xinitrc"
userserverrc="$HOME/.xserverrc
sysclientrc=/etc/X11/xinit/xinitrc
sysserverrc=/etc/X11/xinit/xserverrc
В xinit
default_server = "X";
default_display = ":0";
default_client = "xterm -geometry +1+1 -n login";
В качестве клиента в xinit может передаваться команда графического логина (xdm) или команда менеджера окон или команда менеджера сессий
Менеджер сессий позволяет сохранять расположение и содержимое окон на рабочем столе. Для восстановления содержимого окон нужна поддержка со стороны приложений.
Для общения менеджера сессий с приложениями используется X Session Management Protocol (XSMP). Адрес менеджера сессий хранится в переменной SESSION_MANAGER
Как правило команда менеджера сессий имеет название типа name-session. Например: gnome-session, kde-session, mate-session.
Классические: twm
(в поставке XOrg), fvwm
, xfvm4
, icewm
Тайловые: xmonad
, ion
Сочетающие функции WM с функциями ускорения: compiz
(OpenGL)
date #Текущая дата
date -d '2010-12-11 12:00' # дата, указанная в строке
date --date='2010-12-11 12:00' #альтернативный вариант опции -d
Примеры дат:
Можно подсмотреть различные форматы дат командой strings $(which date)
Форматы
date +%Y-%m-%d # год-месяц-день
date +%H:%M:%S # часы:минуты:секунды
date +%s # Секунды с 1970-01-01
date +%A # Название дня недели в текущей локали
Стандартные форматы
date -I # ISO-8601 YYY-mm-dd Длинная форма опции — --iso-8601
date -Ihours # ISO-8601 с указанием точности представления даты. Можно указывать date (по умолчанию), hours, minutes, seconds, ns
date -R # Оно же --rfc-email — формат принятый в заголовках электронной почты
Проблема начала недели
В Европе и в России первый день недели понедельник, в США — воскресенье, поэтому для дня недели используются два разных формата
%u – номер дня недели начиная с понедельника (1..7). Воскресенье = 7.
%w – номер дня недели начиная с воскресенья (0..6). Воскресенье = 0.
При описании запуска заданий по расписанию в файле crontab
для воскресенья можно использовать и 0 и 7.
Вычисления с датами с помощью date
date -date='now + 3 days'
date -date='now + 5 hours'
Вычисления в секундах во внешней программе
START=$(date --date='2020-01-01 0:00' +%s)
END=$((START+3600*24*45)) # + 45 дней
date --date="@$END"
Функции перевода времени в секунды и назад в mysql
select UNIX_TIMESTAMP(date) as stamp;
select FROM_UNIXTIME(stamp) as date;
Squid
Nginx
tinyproxy
В графическом интерфейсе Chrome нельзя выбрать протокол https для подключения к прокси серверу. Параметр https proxy — это http прокси для подключения к https серверам. Если надо подключаться к прокси серверу с SSL шифрованием (например, для безопасной авторизации), то можно воспользоваться одним из перечисленных ниже способов.
Содержимое файла Proxy autho config (PAC)
function FindProxyForURL(url, host) { return "HTTPS secure-proxy.example.com:443"; }
URL файла задаётся либо в настройках прокси в графическом интерфейсе либо опцией командной строки --proxy-pac-url=...
chrome --proxy-server=https://secure-proxy.example.com:443
stunnel -f -d 443 -r localhost:8080 -p cert.pem
chrome --proxy-server=http://localhost:8080
На основе руководства
Большинство дистрибутивов Linux поддерживают репозитории совместимого программного обеспечения и ту или иную систему управления процессом установки программ из репозитория - менеджер пакетов. Чаще всего менеджер пакетов делится на две составляющие. Низкоуровневая часть менеджера, управляет локальной базой установленных пакетов. Высокоуровневая часть менеджера умеет вычислять зависимости пакетов между собой, находить необходимые пакеты в репозиториях и скачивать их для локальной установки через низкоуровневую компоненту.
Название дистрибутива: cat /etc/os-release
или lsb_release -a
Существует несколько популярных менеджеров пакетов, которые используются большинством дистрибутивов.
Debian и его производные (в частности Ubuntu) используют связку dpkg, apt, aptitude и пакеты в формате DEB. RedHat (CentOS, SciLinux и т.д.) используют rpm, yum и пакеты в формате RPM. ArchLinux использует менеджер pacman.
Программа Alien позволяет конвертировать пакеты RPM в DEB и обратно.
К сожалению, даже использование единой системы управления пакетами не всегда обеспечивает автоматическую переносимость пакетов из дистрибутива в дистрибутив. Разные дистрибутивы могут строить различные схемы зависимостей и установка пакета от "чужого" дистрибутива может привести к конфликтам в версиях используемых библиотек.
При установке kleopatra в Antix Linux выдается ошибка
$sudo apt install kleopatra
...
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:
The following packages have unmet dependencies:
kleopatra : Depends: libkf5kcmutils5 (>= 5.2.0+git20141003) but it is not going to be installed
Depends: libkf5notifications5 (>= 5.12.0) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.
последовательные попытки ручной установки пакетов по цепочке приводят к
$sudo apt install libpulse-mainloop-glib0
....
The following packages have unmet dependencies:
libpulse-mainloop-glib0 : Depends: libpulse0 (= 10.0-1+deb9u1) but 10.0-1.0nosystemd1 is to be installed
опции -f, -m, --ignore-missing не помогают
Ручная установка
apt-get download libpulse-mainloop-glib0
sudo dpkg -i --force-all libpulse-mainloop-glib0_10.0-1+deb9u1_i386.deb
sudo vim /var/lib/dpkg/status
# Находим зависимости для libpulse-mainloop-glib0
# и удаляем libpulse0
sudo apt-get install kleopatra
Утилита управления пакетами dpkg
используется в дистрибутиве Debian, а так же в Ubuntu и многих других. Файлы пакетов имеют расширение .deb
dpkg -i mc-3.14.deb
- установка пакета
dpkg -r mc
- удаление пакета с сохранением файлов конфигурации
dpkg --purge mc
-полное удаление пакета
dpkg -V mc
- проверка целостности установленного пакета
dpkg-query -L mc
- список файлов в пакете
dpkg-query -S /etc/mc.ini
- поиск пакета, которому принадлежит файл или каталог
dpkg-deb --contents mc-3.14.deb
- просмотр содержимого
dpkg-deb -x mc-3.14.deb /tmp
- извлечение файлов из архива
Для установки, удаления и обновления программ в дистрибутивах RHEL, Fedora, Mandriva, AltLinux и некоторых других используется менеджер пакетов rpm. Менеджер пакетов rpm позволяет устанавливать, удалять, верифицировать пакеты соответствующего формата, но не имеет средств для автоматического разрешения зависимостей и поиска в репозиториях. Для автоматизации установки пакетов можно воспользоваться программой yum (Yellowdog Update Manager), которая автоматически разрешает зависимости между пакетами и подгружает необходимые файлы. При необходимости собрать пакет с программой из исходных текстов можно воспользоваться rpmbuild. Для этого необходимо подготовить пакет в формате .src.rpm, включающий исходные тексты программы и .spec файл, описывающий процесс сборки.
Пакеты именуются по следующей схеме: имя-версия-сборка
. Распространяются пакеты в виде файлов, в название которых добавляется .архитектура.rpm
. Например, squid-2.5.STABLE8–1.FC3.1.i386.rpm
расшифровывается так: программа squid
, версия 2.5.STABLE8
, сборка 1.FC3.1
, архитектура i386
(неоптимизированное приложение под i386 совместимые процессоры). Номер сборки может включать название дистрибутива (FC3 в данном случае, а может и не включать). Архитектура noarch
означает скрипты, независимые от архитектуры процессора. Файлы .src.rpm
содержат исходные тексты программ и устанавливаются особым образом.
Каждый пакет содержит файлы программ, библиотек, конфигурации, документации и пр., упакованные архиватором cpio
. Также пакет содержит дополнительные секции:
и т.д.
Кроме того, каждый пакет принадлежит к некоторой группе Интернет, Разработка Программ, Развлечения и т.п. Просмотреть секции rpm файла можно в mc.
В дальнейших описаниях <пакет> означает имя пакета без i386.rpm
(если установлена одна версия программы, то номер версии и сборки тоже можно опустить), а <файл> означает имя файла .rpm. В качестве файла можно указывать его URL, например, http://download.fedora.redhat.com/pub/fedora/linux/core/updates/3/i386/yum-2.2.0-0.fc3.noarch.rpm
Вспомогательные опции: -v
– подробный вывод сообщений, -h
– показ индикатора прогресса установки.
rpm -ivh <файл>...
– установить пакет(ы)
rpm -Uvh <файл>...
– обновить пакет(ы), если не установлены – установить
rpm -Fvh <файл>...
– обновить уже установленный(е) пакет(ы)
rpm -e <пакет>...
– удалить пакет(ы)
Вспомогательные опции: -a
– все установленные пакеты, -p
– информация о файле rpm (в примерах будут приведены не везде).
rpm -q <пакет>...
– проверка на наличие установленного пакета и его версии
rpm -qa
- список всех пакетов
rpm -qi <пакет>...
– DESCRIPTION пакета
rpm -qip <файл>...
– DESCRIPTION файла
rpm -qR <пакет>...
– REQUIERS пакета
rpm -ql <пакет>...
– список файлов пакета
rpm -qf <файл_в_файловой_системе>...
– определение принадлежности произвольного файла к одному из установленных пакетов
Файлы, размещенные в rpm пакете, сопровождаются вычисленной контрольной суммой и, как правило, подписаны цифровой подписью сборщика пакета. После установки пакета контрольные суммы и подписи сохраняются в базе установленных пакетов. Эти вспомогательные данные позволяют выполнить несколько проверок, например, можно проверить, что пакет создан доверенным издателем и что файлы пакета не были подменены после установки.
Первая проверка очень важна при скачивании пакетов из интернета, а вторая при подозрении на взлом компьютера.
Публичные ключи для проверки подписи автоматически устанавливаются при установке из дистрибутива, а также полуавтоматически добавляются при установке rpm пакетов для подключения репозиториев yum
. Файлы с ключами в CentOS устанавливаются в каталог /etc/pki/rpm-gpg/
. Можно добавить ключ вручную, указав путь к локальному файлу или его url. Файл с ключем должен иметь текстовый формат 'ASCII armored'
rpm --import PUBKEY-file
После инсталляции к ключам применимы те же команды, что и к установленным пакетам
rpm -qa gpg-pubkey*
– список всех ключей
rpm -qi gpg-pubkey-db42a60e
– информация (в том числе имя хозяина) о конкретном ключе
rpm -e gpg-pubkey-db42a60e
– удаление ключа
Проверка файла пакета на целостность
rpm --checksig <файл>
Проверка установленного пакета на целостность
rpm --verify <пакет>
После выполнения этой команды будет выдан список изменившихся файлов с указанием, что именно в них поменялось. Информация о типе изменений состоит из строки аббревиатур, включающих:
Программа rpm2cpio
извлекает файлы из RPM пакета в формате архива cpio
.
Для распаковки файлов вместе со структурой каталогов используется команда cpio
с опциями -i
– распаковать и -d
– создать каталоги:
rpm2cpio <файл.rpm> | cpio -i -d
Если необходимо сохранить установленный пакет в файл, то можно воспользоваться программой rpmrebuild
:
rpmrebuild <package>
Eсли пакет уже установлен и его надо переустановить или необходимо понизить версию пакета, то можно к командам инсталяции или обновления добавить опцию --force
.
Если установка или удаление пакета формально нарушает зависимости, но известно, что все будет хорошо, то используется опция --nodeps
.
Менеджер пакетов Apt
(Advanced Package Tool) надстроен над утилитой dpkg
и предназначен для кэширования списков пакетов из локальных и сетевых репозиториев, вычисления зависимостей между пакетами и автоматизированных скачивания и установки пакетов.
Функциональность менеджера пакетов распределена между несколькими командами (apt-get
, apt-cache
и др.).
apt-cache search Midnight
- поиск пакета по регулярному выражению в названии или кратком описании
apt-cache show pkg
- основные сведения о пакете
apt-get update
- обновление кэша
apt-get upgrade
- обновление установленных пакетов до последней версии
apt-get install pkg
- установка пакета
apt-get remove pkg
- удаление пакета
apt-cdrom add
- добавить репозиторий на смонтированном CD
yum search <строка>
– поиск текстовой строки в названиях пакетов и комментариях
yum install <пакет>...
– установка пакетов и всего для них необходимого
yum install <файл.rpm>
– установка из локального файла
yum upgrade <пакет>...
– обновление пакетов до самой последней версии
yum downgrade <пакет-версия>...
– откат обновления до определённой версии
yum remove <пакет>...
– удаление пакета. Если этот пакет необходим другим, то будут удалены все
yum list z\*
– список пакетов на букву z. Пакеты разбиты на установленные и доступные.
yum info <пакет>
– просмотр информации о пакете
yum repolist
– список всех репозиториев
yum clean
– очистка кэша
Описания репозиториев находятся в каталоге /etc/yum.repos.d/
в файлах с расширением .repo
.
Формат файла
#в одном файле могут быть описаны несколько репозиториев, каждый размещается в своей секции
[epel]
# человекочитаемое имя. $basearch - архитектура процессора, $releasever - версия дистрибутива
name=Extra Packages for Enterprise Linux $releasever - $basearch
#местоположение репозитория; если репозиторий локальный, то url может иметь вид
#baseurl=file:///var/repos/myrepo
baseurl=http://download.fedoraproject.org/pub/epel/$releasever/$basearch
#если у проекта есть несколько зеркал, то baseurl может быть заменен на путь к списку зеркал в формате xml
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
#репозиторий можно отключить, поставив enabled=0
enabled=1
#надо ли проверять цифровую подпись пакетов и путь к файлу ключа
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
#если мы предпочитаем получать определённые пакеты из другого репозитория,
# то можем выборочно отключить их в этом
exclude=nagios*
<dir>
Проверить, что установлен пакет createrepo, и установить, если необходимо
rpm -q createrepo
sudo yum install createrepo
Создать XML данные репозитория
createrepo <dir>
Классическая модель доступа основана на том, что root может всё, а обычный пользователь может получить доступ к файлам, на которые установлены соответствующие права, а также отправить сигнал своим процессам. Повышение прав доступа обеспечивается специальными флагами в правах доступа (suid и sgid) на двоичные исполняемые файлы (не скрипты).
Современная модель доступа делит полномочия root на отдельные группы — capabilities. root имеет полный набор capabilities, но может отказаться от части из них. В дополнительные аттрибуты исполняемого файла вместо suid/sgid можно вписать получение тех или иных capabilities.
Классические права доступа в Unix состоят из трёх разделов: User, Group, Other (ugo), в каждом из которых определяются три права на доступ к файлу: Read, Write, eXecute (rwx). При этом, в атрибутах файла прописан ровно один владелец (User) и одна группа (Group).
Для того, чтобы можно было назначать права на объекты в файловой системе (ФС) с точностью до пользователя были введены списки доступа (Access Lists, ACL). ACL позволяют связать с объектом ФС сколько угодно пользователей и групп, и назначить каждому свой набор прав rwx
. Классические группы прав ugo
считаются тремя элементами списка ACL, которые присутствуют в ACL всегда.
Просмотр ACL:
$ chmod 0644 /tmp/user1-tmp
$ getfacl /tmp/user1-tmp
getfacl: Removing leading '/' from absolute path names
# file: tmp/user1-tmp
# owner: user1
# group: users
user::rw-
group::r--
mask::rwx
other::r--
Установка ACL
setfacl
имеет две опции -m
(modify) — добавить или изменить ACL и '-x' — удалить ACL.
$ setfacl -m user2:rwx /tmp/user1-tmp
$ getfacl /tmp/user1-tmp
getfacl: Removing leading '/' from absolute path names
# file: user1-tmp
# owner: user1
# group: user1
user::rwx
user:user2:rwx
group::rwx
mask::rwx
other::---
В исходных текстах ядра список capabilities определён в файле capabilities.h.
Количество capabilities в современных версиях ядра около 40. Точное количество можно узнать через интерфейс /proc
cat /proc/sys/kernel/cap_last_cap
Список текущих capabilities shell можно получить командой
capsh --print
cat /proc/<pid>/status | grep Cap
Эта команда выведет пять строк со значениями в виде набора двоичных флагов:
Пример вывода для команды ping
(pid 1234):
$ cat /proc/1234/status | grep Cap
CapInh: 0000000000000000
CapPrm: 0000000000003000
CapEff: 0000000000000000
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
Для декодирования двоичных флагов можно выполнить команду capsh --decode=<bits>
:
$ capsh --decode=0000000000003000
0x0000000000003000=cap_net_admin,cap_net_raw
также можно воспользоваться командой getpcaps <pid>
$ getpcaps 1234
Capabilities for `1234': = cap_net_admin,cap_net_raw+p
$ getcap /usr/bin/ping
/usr/bin/ping = cap_net_admin,cap_net_raw+p
$ setcap cap_net_admin,cap_net_raw+p /usr/bin/ping
Формат задания capabilities в getcap/setcap имя1,имя2...<op><set> где
Подробнее этот формат описан в man 3 cap_from_text
capsh
.Без ограничений
$ capsh -- -c "/usr/bin/ping -c 1 localhost"
PING localhost.localdomain (127.0.0.1) 56(84) bytes of data.
...
С отобранными capabilities
$ sudo capsh --drop=cap_net_raw -- -c "/usr/bin/ping -c 1 localhost"
ping: socket: Operation not permitted
Вызов capget для процесса с ping = 1234 (вывод strace)
$ strace -e capget getpcaps 1234
capget({version=_LINUX_CAPABILITY_VERSION_3, pid=1234}, {effective=0, permitted=1<<CAP_NET_ADMIN|1<<CAP_NET_RAW, inheritable=0}) = 0
Установка capabilities делается вызовом capset().
Какие бы права не были выставлены на файл, root будет иметь к нему доступ на чтение, запись и исполнение благодаря capability CAP_DAC_OVERRIDE
. То же справедливо для любого процесса, который получил эту capability. Например, для /bin/passwd достаточно было бы иметь CAP_DAC_OVERRIDE
для записи в /etc/passwd и /etc/shadow.
Есть тонкость, связанная с флагом на исполнение. Если флаг на исполнение не выставлен ни в одной из позиций (user, group, other), то root выполнить файл не может, а вот права типа --- --- --x
уже достаточны для выполнения файла.
Другие capabilities, связанные с правами доступа:
r-x
на все каталогиCAP_DAC_OVERRIDE
будет недостаточно.Программа sudo предназначена для выполнения администрирования обычными пользователями
Способ запуска
sudo программа опции
Пользователь не должен знать пароль root'a, но, в зависимости от настроек, ему может быть предложено ввести свой пароль для авторизации. Беспарольный доступ обычно используют для повышения полномочий в скриптах, например для управления через Web. Для обычных администраторов пароль желательно оставлять, чтобы злоумышленник не воспользовался их правами, когда они на 5 минут отойдут от терминала.
Конфигурационный файл /etc/sudoers рекомендуется изменять редактором /usr/sbin/visudo. Visudo запускается с правами root, создает копию /etc/sudoers, затем, используя переменную среды EDITOR, запускает любимый редактор пользователя (или vi по умолчанию), а после редактирования проверяет результат на синтаксическую правильность и, в случае успешной проверки, сохраняет.
Формат файла sudoers:
пользователь на_компьютере=(под чьим именем) список команд
поле на_компьютере нужно для того, чтобы один файл sudoers можно было простым копированием размножать на различные машины
Пример файла /etc/sudoers, который разрешает пользователю user выполнять любые действия, подтверждая свои полномочия паролем, а пользователю apache позволяет выключить компьютер не вводя пароль.
user ALL=(ALL) ALL
apache ALL=(ALL) NOPASWD:/sbin/poweroff
Загрузка операционной системы, это многоступенчатый процесс. В различных дистрибутивах Linux процесс загрузки может несколько изменяться, но общая схема примерно одинакова и состоит из следующих стадий:
В момент запуска процессор передаёт управление по определённому физическому адресу в ПЗУ. В этот момент начинается выполнение кода BIOS/UEFI. Производится инициализация оборудования и выбирается загрузочный носитель. В случае BIOS происходит считывание в ОЗУ начального загрузчика и передача управления на него. Начальный загрузчик обычно занимает один сектор на диске (MBR) и ограничен размером 384 байт ( 512 байт – сектор диска, минус 128 байт – таблица разделов). В зависимости от типа загрузочного устройства загрузочный сектор может считываться из разных мест:
При форматировании диска в MBR вместо загрузчика иногда пишется программа, которая пишет на экране информационный текст "No bootable device -- insert boot disk and prress any key"
1.1 Начальный загрузчик считывает в память основной загрузчик (GRUB, LiLo, NTLDR) и передаёт управление ему. Поскольку начальный загрузчик очень мал, то, как правило, в его код жестко прописывают сектора, из которых надо прочитать код основного загрузчика. На HDD это может быть пространство между MBR и первым разделом на диске (нулевая дорожка) или зарезервированное место внутри ФС (зарезервированный Inode в ext2fs). На дискете и при использовании образа диска при загрузке с CD или по сети – основной загрузчик может располагаться сразу вслед за первичным загрузчиком и занимать весь объём образа.
При загрузке через UEFI загрузчик или непосредственно ядро Linux считывается целиком из файла на системном разделе EFI с файловой системой FAT32.
Загрузка ядра (vmlinuz) и вспомогательного образа диска (initrd, initramfs). Загрузчик GRUB представляет из себя мини ОС, поддерживающую все основные файловые системы. GRUB ищет конфигурационный файл, в котором прописаны пути к образу ядра и образу вспомогательного диска. При необходимости образ ядра распаковывается в ОЗУ, формируется область памяти, содержащая параметры, передаваемые из загрузчика в ядро, в том числе адрес образа вспомогательного диска.
Ядро загружаемое через GRUB должно соответствовать соглашениям multiboot или multiboot2 . В соответствии с соглашением, образ ядра включает структуру (например в секции данных), которая начинается с магического числа и содержит информацию о желаемом положении ядра в памяти и точке на которую надо передать управление. Перед передачей управления в ядро в регистр EAX помещается ещё одно магическое число, а в регистр EBX - адрес таблицы с параметрами, подготовленными загрузчиком.
Вспомогательный диск необходим современным Linux системам из-за модульности ядра и содержит драйверы (ATA, NFS, RAID и т.п.), необходимые для получения доступа к основной файловой системе. Внутри образа находится файловая система в формате архива cpio.
На этом этапе создаётся процесс с pid=1
, в котором происходит выполнение скрипта init
, находящегося в корневом каталоге вспомогательного диска. Параметры, передаваемые ядру, фактически передаются в init
, как аргументы командной строки.
Скрипт содержит команды загрузки необходимых драйверов в виде модулей ядра, создание временных файлов устройств в каталоге /dev
для доступа к этим модулям, сканирование дисковых разделов для обнаружения и инициализации RAIDов и логических томов. После инициализации логических дисков, делается попытка смонтировать корневую файловую систему, заданную параметром root=
. В случае бездисковой сетевой загрузки корневой каталог подключается по NFS.
На экран выдаются сообщения о загрузке драйверов и о поиске виртуальных томов подсистемы LVM. Этап завершается перемонтированием корневого каталога на основную файловую систему и загрузку в процесс с pid=1
основной программы /sbin/init
(или её аналога).
В классическом UNIX'е и старых версиях Linux (примерно до 2012 года) программа init
считывает конфигурационный файл /etc/inittab
, инициализирует текстовые консоли и, как правило, запускает необходимые службы с помощью набора скриптов, расположенных в каталогах /etc/init.d
и /etc/rc*.d
. В современных дистрибутивах Linux в файле /sbin/init
находится более современная программа запуска служб. Наиболее популярной из подобных программ является systemd
, который позволяют существенно сократить время этого этапа загрузки.
На экран на этом этапе выдаются строки, сообщающие о запуске служб, и информация об успешности данного процесса ([OK] или [ERR]).
Для загрузки через EFI к ядру Linux добавляется заголовок исполняемого файла в формате PE/COFF, что позволяет использовать EFI для загрузки. Часть ядра, связанная с этим заголовком и кодом, на который передаётся управление называется EFI Stub — заглушка для EFI. Исходный код заглушки для архитектуры x86 находится в файлах arch/x86/boot/header.S и arch/x86/boot/compressed/eboot.c.
В x86 используется bzImage, в arm — zImage в arm64 — неупакованное ядро.
Для загрузки ядра файл bzImage, расположенный в arch/x86/boot/bzImage, необходимо скопировать в системный раздел EFI (ESP) на диске и переименовать с расширением .efi. Без расширения загрузчик EFI откажется его выполнить. Запуск bzImage.efi из файловых систем Linux загрузчиком EFI не поддерживается. Для архитектур arm и arm64 ядро также нужно скопировать в системный раздел, но можно не переименовывать.
Аргументы ядра в командной строке EFI указываются после bzImage.efi, например:
fs0:\Linux> bzImage.efi console=ttyS0 root=/dev/sda4 initrd=\Kernels\initrd-large.img
Параметр initrd= обрабатывается в заглушке, остальные передаются в ядро. Путь к initrd записывается как абсолютный путь от корня ESP. В качестве разделителя каталогов используется обратный слеш.
Для записи строки загрузки Linux в меню EFI можно воспользоваться efibootmgr:
efibootmgr --create \
--disk /dev/sda1 \
--label 'Linux 5.9.1 i915' \ # Строка в меню загрузки
--loader '\EFI\Boot\5.9.1.efi' \ # Образ для загрузки
'initrd=\EFI\gentoo\initramfs.img' \
'root=/dev/sda1 pcie_aspm=off'
GRUB (GRand Unified Boot Loader) – Великий унифицированный загрузчик. Разработан в рамках проекта GNU как образцовая реализация мультизагрузчика, способного загружать различные ОС с различных разделов одного диска или различные версии одной ОС в рамках одного раздела.
В настоящий момент под названием GRUB известны две существенно отличающиеся версии программы. Версия 0.97 – "старый" или "legacy" GRUB – используется в RHEL до версии 6 включительно. В этой статье речь именно о нём. GRUB версии > 1.0 – это почти полностью переписанный вариант программы, используемый в Ubuntu, Fedora и многих других дистрибутивах.
Поскольку в MBR есть только 384 байт для размещения загрузчика – GRUB поделен на две части stage1 и stage2. Размер stage1 равен одному сектору на диске – 512 байт. При этом реально используется только 384, а остальное зарезервировано. Stage2 – довольно крупная программа, содержащая драйверы нескольких ФС, интерпретатор командной строки и несколько вспомогательных функций. Её размер составляет примерно 124 КБ. При инсталляции GRUB компонент stage2 должен быть размещён в последовательных секторах на диске, а адрес первого сектора и количество секторов должны быть прописаны в секторе, содержащем stage1. Если носитель не позволяет разместить stage2 в фиксированных секторах, то применяется промежуточный загрузчик stage1.5, поддерживающий одну конкретную ФС и занимающий менее 16 КБ.
Список ФС, поддерживаемых stage2/1.5 (ls /boot/grub/*1_5
)
Иногда хочется сделать в initrd
что-то нестандартное, что не предусмотрено стандартным скриптом (mkinitrd
, mkinitramfs
, dracut
и т.п.). В этом случае можно распаковать существующий образ, поправить его руками и снова запаковать. Формат файла - архив cpio
сжатый gzip
. Единственная тонкость - для cpio
надо указывать опцию, задающую внутренний формат архива -H newc
mkdir initrd; cd initrd
gunzip -c /boot/initramfs-2.6.32.158.img | cpio -i --make-directories
#внесение правок
find . | cpio -o -H newc | gzip > /boot/myinitrd.img
initramfs, как файл, мало отличается от initrd. При создании явно указывается максимальная степень сжатия.
#Упаковка (фрагмент из dracut CentOS 6)
find . |cpio -R root:root -H newc -o --quiet| $gzip -9 > "$outfile"
В CentOS7 структура файла изменилась. В начало приклеен ещё один маленький несжатый архив cpio
"early_initramfs" он же "microcode blob" (необязательный). Программа skipcpio ищет в полученном файле признак конца архива (строку "TRAILER!!!") и выдает хвост. Для сжатия можно использовать различные программы (gzip
,bzip2
, xz
). По умолчанию используется gzip
.
#Распаковка:
/usr/lib/dracut/skipcpio /boot/initramfs-3.10.0-957.el7.x86_64.img | zcat | cpio -i --make-directories
#Упаковка
find . |cpio -c -o |xz -z -9 -C crc32 -F xz > /boot/myinitrd.img
Иногда возникает ситуация, при которой загрузка Linux невозможна из за неправильно собранного образа диска initrd. Возникает ситуация курицы и яйца: чтобы исправить initrd необходимо загрузить Linux, чтобы загрузить Linux нужен исправленный initrd.
В CentOS и аналогичных системах последовательность действий такова:
Загрузиться с установочного диска в режим восстановления - Rescue mode. Для этого в момент загрузки на приглашение boot:
необходимо ввести linux rescue
Если всё пойдёт нормально, то корневой каталог основной системы будет смонтирован в /mnt/sysimage
, загрузочный каталог в /mnt/sysimage/boot
. Кроме того текущие каталоги /proc
, /sys
и /dev
будут смонтированы в соответствующие подкаталоги /mnt/sysimage
. Если это не случится, то придётся проделать эти операции вручную.
Когда все каталоги смонтированы, можно сменить корневой каталог
#если выяснится, что вы что-то забыли смонтировать, то можно выйти по ^D
chroot /mnt/sysimage
и пересобрать initrd
В CentOS 6
#копируем старый файл
cp -p /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak
#создаём новый
dracut -f
#если версия ядра в основной системе отличается от версии на установочном диске, указываем её явно
dracut -f /boot/initramfs-2.6.32-358.el6.x86_64.img 2.6.32-358.el6.x86_64
В CentOS 5
#копируем старый файл
cp -p /boot/initrd-$(uname -r).img /boot/initrd-$(uname -r).img.bak
#создаём новый
mkinitrd -f -v /boot/initrd-$(uname -r).img $(uname -r)
#если версия ядра в основной системе отличается от версии на установочном диске, указываем её явно
mkinitrd -f -v /boot/initrd-2.6.18-371.el5.img 2.6.18-371.el5
Перезагрузка
cd /
sync
telinit 6
Полный пример с драйвером i2o_block (SCSI адаптер Adaptec 2010S), который не загружается автоматически. Пример выполняется в CentOS 5, поскольку в стандартном ядре CentOS 6 поддержка этого драйвера отключена.
После загрузки с CD в Rescue mode выдаётся сообщение, что Linux разделы не найдены и их надо монтировать самостоятельно.
#Загружаем драйвер
insmod i2o_block
#Проверяем, что всё сработало
lsmod
....
dmesg
...
#Создаём файлы устройств на основе информации в dmesg
mkdir /dev/i2o
mknod /dev/i2o/hda b 80 0
mknod /dev/i2o/hda1 b 80 1
mknod /dev/i2o/hda2 b 80 2
#Активируем VolumeGroup
lvm vgchange -a y
#Монтируем тома
mkdir /mnt/sysimage
mount /dev/mapper/VolGroup00-LogVol00 /mnt/sysimage
mount /dev/i2o/hda1 /mnt/sysimage/boot
#Монтируем спецкаталоги
mount --bind /proc /mnt/sysimage/proc
mount --bind /dev /mnt/sysimage/dev
mount --bind /sys /mnt/sysimage/sys
Далее по инструкции, только при создании образа диска надо указать программе mkinitrd
дополнительную опцию --preload=i2o_block
и отключить сервисы readahead
, поскольку они приводят к зависанию драйвера i2o_block
:
chkconfig early-readahead off
chkconfig later-readahead off
Можно посмотреть видео https://youtu.be/QlLwJhKrMGA.
В прошлый раз мы говорили о том, что происходит при загрузке Linux: вначале стартует загрузчик, он загружает ядро и развертывает временный диск в оперативной памяти, ядро запускает процесс init, init находит настоящий корневой диск, производит такой хитрый переворот - вместо временного виртуального диска на это же самое место в корневой каталог монтируется реальный диск, с этого реального дисков процесс init загружает в себя другой init, который есть на этом реальном диске. После всех этих операций UNIX переходит в состояние обычной работы.
В этой лекции я расскажу, что делает классическая программа init в сочетании со скриптами rc.d в стиле System V (Систем пять). System V - это классическая версия UNIX на которой построены коммерческие UNIX.
Судя по названию, rc.d это некий каталог. Есть такая традиция UNIX - если вся конфигурация чего-либо умещается в один файл, и он называет config, то при разбиении его на отдельные файлы, которые подключаются к основному, создают каталог с аналогичным именем и добавляют к имени .d – config.d. Буква d означает, что это директория и там лежат вспомогательные части конфигурационного файла. У формата конфигурационных файлов программы init есть две традиции: вариант System V, в котором каждая деталь конфигурации держится в отдельном файле в каталоге rc.d, и традиция BSD систем, в которой есть один файл /etc/rc, содержащий много скриптов и переменных, которые отвечают за поведение системы.
В любом случае, при старте системы у нас создается процесс с PID=1, в котором запущена программа, которая называется init. Как вы видели в прошлый раз, если программу init убить, то ядро впадает в панику и прекращает всяческую работу.
Классический System V init читает файл /etc/inittab и выполняет ряд предписаний, которые прописаны в этом файле. Inittab этот текстовый файл каждая строка которого, это, по сути дела, одна команда или какое-то правило поведения. Inittab выглядит так:
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l3:3:wait:/etc/rc.d/rc 3
1:2345:respawn:/sbin/mingetty tty1
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
Вначале строки стоит метка. В чем большой смысл этой метки я не очень понимаю. Можно считать, что это простой текст и все. Вторым пунктом стоит либо так называемый уровень загрузки, либо пустое значение. Уровень загрузки — это либо одно число от 0 до 6, либо список чисел через запятую. Дальше идет некое действие. Действия бывают следующие: wait, respawn, sysinit, ctrlaltdel. Есть и другие действия, но это самые используемые. Наконец, в конце строки написана некая команда с именем исполняемого файла и аргументов, которые этой команде надо передать.
Действие sysinit выполняется однократно при старте системы.
Действие ctrlaltdel это на самом деле не совсем действие – это обработчик сочетания клавиш control alt del. Само нажатие перехватывается ядром системы, и информация об этом пересылается в процесс init, который должен выполнить определенную команду. Например, может быть выполнена команда shutdown, которая выполнит выключение компьютера. В принципе сюда можно прописать любую другую программу, например, echo, которая после нажатия control alt del будет выдавать на все терминалы системы какое-нибудь сообщение. камина консолью так
Действие wait означает, что необходимо запустить команду, дождаться пока она закончится и только после этого продолжить обработку следующих строк. Не знаю, могут ли запускаться такие действия в параллель. Скорее всего, нет.
Действие respawn означает, что надо запустить программу и не дожидаясь ее завершения, перейти в дальнейшем действиям. Если эта программа в последующем завершится, то необходимо ее рестартовать.
Итак, есть однократное выполнение с ожиданием результатов и многократное выполнение в асинхронном режиме – запустились, дождались пока закончить, запустили слова.
Уровни загрузки — это некая условность, которая позволяет управлять загружаемыми службами. Ближайший аналог в windows – это загрузка в безопасном режиме, когда грузится только ограниченное число драйверов и стартует минимальное количество служб, загрузка с отладкой, когда каждое действие дополнительно протоколируются и обычная полноценная загрузка.
В Linux по традиции выделяется 6 вариантов загрузки. Это деление довольно условно.
0 и 6 это выключение. 0 - полное выключение электричество, а 6 - режим перезагрузки.
4 в Linux вообще пропущен
Остаются четыре уровня загрузки:
1 - однопользовательский режим. Если передать загрузчику ключевое слово single, то мы окажемся в однопользовательском режиме, где запущен только один процесса и это шелл администратора системы. Этот режим используется для восстановления системы.
3 - нормальный многопользовательский текстовый режим, когда запущены все службы, работает сеть, работают все драйверы.
2 - тоже текстовый режим, но без подключения сетевых дисков. Дело в том, что традиционные сетевая файловая система nfs, которая используется в UNIX, чрезвычайно устойчива к повреждениям сети. Если мы выключили файловый сервер или обрезали сетевой кабель, то сетевая файловая система nfs будет предпринимать многочисленные попытки восстановиться и эти попытки настолько длительны, что я ни разу не смог дождаться времени, когда же наконец появится сообщение об ошибке. Возможно это произойдёт через час, а может и через 6 часов. Всё это время драйвер nfs будет держать компьютер, не давая ничего сделать. Поэтому, если у нас упала сеть или файловый сервер в настройках написано, что при старте необходимо подмонтировать внешние диски, то попытка загрузится в полноценный режим приведёт к тому, что у вас все зависнет. Для этого случая и предусмотрен второй вариант загрузки - все как в третьем, только сетевые диски не подключаются. Сам сетевой адаптер работает, IP адрес назначается, интернет доступен.
5 - то же самое что и 3, но с запуском x window - графического интерфейса.
Можно считать, что между уровнями есть некоторая последовательность переходов:
режим 2 включает себя 1 + многопользовательский режим. 3 включает 2 + монтирование сетевых файловых систем. Наконец, 5 включает в себя 3 + запуск графической подсистемы. Будет ли это реализовано последовательно или нет - это проблема дистрибутива. Вообще говоря, администраторы могут самостоятельно настроить файл inittab так, чтобы эти режимы запускались последовательно, а можно сделать так чтобы все было абсолютно независимо - переключаясь в очередной режим, убираем все что было сделано на предыдущем шаге, и настраиваем все с нуля.
Рассмотрим строки реального файла. Они очень просты.
l3:3:wait:/etc/rc.d/rc 3
Запускается какая-то программа, которая должна выполнить все необходимые действия, которые ожидаются на третьем уровне. Наверно, на третьем уровне нужно настроить сетевые интерфейсы, запустить драйвер терминалов, стартовать какие-то службы. Только после того, как всё этого завершится мы сможем работать в системе. Поскольку надо дождаться завершения запуска, мы выбираем действие wait.
Программа запуска называется rc и запускается с номером уровня в качестве параметра. Сама программа init достаточно простая. Она умеет построчно читать свой файл с простым синтаксисом и стартовать новые процессы, запуская какие-то вспомогательные программы. Вся логика уровней загрузки спрятана в скрипте rc. Запустив rc с параметром 3 мы перейдем на третий уровень, с параметром 5 - на пятый.
Программа rc тоже очень простая. Это скрипт который выполняет все файлы в каталогах, соответствующих уровню загрузки, например, /etc/rc3.d/. В этих каталогах находятся исполняемые файлы, которые принимают один параметр - либо start, либо stop. Если файл запущен с параметром start, то он стартует службу, если с параметром stop, то останавливает её. Например, network start будет настраивать сетевые интерфейсы, а network stop будет переводить интерфейсы в выключенное состояние. Кроме сетевых интерфейсов есть скрипты подключения/отключение сетевых файловых систем, запуска/остановки сервисов и т.д.
Имена файлов в каталогах построенным по определенным правилам. Они начинаются либо с буквы K либо с буквы S, за которыми идет число и имя службы.
Скрипт rc просматриваем содержимого каталога rc3 и выбирает оттуда все файлы которые начинаются с буквы K (kill). Файлы упорядочиваются в порядке возрастания номера и выполняются с параметром stop. Потом те же действия выполняются с файлами на букву S (start), которые запускаются с параметром start. Вот в общем и вся процедура перехода на определенный уровень.
Можно предположить, что в каталоге /etc/rc0.d/ лежат только файлы, начинающиеся на букву K, поскольку при выключении надо все остановить, а в каталоге /etc/rc1.d/ будет один файл на буку S для запуска консоли администратора.
Для простоты программирования есть отдельный каталог /etc/init.d/, в котором лежат те же самые файлы только без буквы цифр в начале имени. На самом деле, файлы в каталогах уровней это просто символические ссылки на основные файлы. Так /etc/rc3.d/S10apache это ссылка на файл /etc/init.d/apache. Буквы и цифры в названии ссылок нужны для того, чтобы скрипт rc вызвал их в нужном порядке и с нужными аргументами.
В системах, которые построены по такому принципу, чтобы стартовать или остановить какую-либо службу в каталоге /etc/init.d/ надо найти файл который, который ей соответствует, и запустить его с параметром start или stop. Чем не нравится запускать службы именно таким способом - явно вызывая скрипты. Дело в том, что в командной строке linux замечательно работает автодополнение. С его помощью очень быстро можно ввести путь до файла запуска.
Чтобы спрятать от пользователя конкретную реализацию поверх системы скриптов и символических ссылок написаны две вспомогательные программы.
Программа chkconfig позволяет манипулировать символическими ссылками на соответствующие скрипты. Чтобы посмотреть, что стартует, а что останавливаться на каждом из уровней можно воспользоваться командой ls и выдать список скриптов в соответствующем каталоге, но проще воспользоваться командой chkconfig –list. Программа chkconfig пробегает по всем каталогам rc и выдает список того что стартует, а что останавливается на каждом уровне. Если мы хотим, чтобы при старте системы у нас что-то автоматически стартовала определенная службу мы выполняем chkconfig <имя службы> on и скрипт создает ссылку для запуска в нужном каталоге и с правильным именем. Запуск chkconfig <имя службы> off приводит к удалению ссылки для запуска и созданию ссылки для остановки. Таким образом программа chkconfig позволяет управлять списком служб, которые стартуют в момент старта системы.
Ещё одна программа - service используется для ручного запуска и остановки служб. Service это обертка, которая позволяет не обращаться напрямую к скрипту, а указать имя службы и сказать хотим мы ее стартовать или остановить. В bash, который я использую, нет автодополнения для команды service, поэтому мне проще набрать путь к скриптам.
В стартовых скриптах аргументы start и stop должны обрабатываться обязательно. Кроме того, можно придумать какие-то свои аргументы, которые будут делать что-то полезное.
В большинстве скриптов реализована опция status, которая показывает запущена служба или нет. Когда мы выполняем start, то скрипт после успешного запуска службы получает ее идентификатор PID и записывать его в определенный файл. По команде stop файл удаляется. Обычно такие файлы создаются в каталоге /var/run/. Команда status проверяет есть ли такой файл. Его нет, то сообщает, что служба не запущена. Если файл есть, то она извлекает из него идентификатор процесса и проверяет текущий список процессов. Если этот идентификатор присутствует все запущено, если программа по каким-то причинам поломалась, то статус выдаёт, что была сделана попытка запустить эту службу - файл существует, но сама служба не запущена.
Опция restart последовательно выполняет внутри скрипта две команды – сначала stop, а потом старт. Это совершенно необязательная команда - просто удобная. Наконец, есть службы, которые позволяет на ходу перечитать какие-то конфигурационные файлы. Для них добавляют команду reload, задачей которой является отправка службе сигнала о том, что конфигурация изменилась. Отдельный случай, команды save и load для сохранения конфигурации брандмауэра.
Если администратор системы вместо остановки или старта отдельных службы хочет всю систему перевести на определенный уровень, то этого можно достичь одним из двух способов. Можно вызвать прямо программу /sbin/init. Если ее вызвать с определенным числом в качестве параметра, то она выполнит все инструкцию из файла inittab, для которых прописывал соответствующий уровень. Если запустить, например, /sbin/init 1, то init найдет в своем конфигурационном файле все строчки, в которых есть уровень 1 и выполнит их. В некоторых системах команда shutdown реализована как /sbin/init 0, поскольку нулевой уровень соответствует остановке системы. В последнее время для перехода между уровнями появилась специальная программа под названием telinit, которая является ссылкой на init. Её задача – переслать процессу init сигнал о том, что администратор желает перейти на определенный уровень. telinit q сообщает init о том, что надо перечитать файл inittab. В старых системах это достигалось посылкой сигнала SIGHUP процессу с PID=1 (kill –HUP 1).
Ещё несколько строк в inittab, это запуск терминалов
1:2345:respawn:/sbin/mingetty tty1
Для того, чтобы обеспечить диалоговую доступ к системе, вы inittabе может присутствовать некоторое количество строчек такого рода. 2345 это уровни, на которых надо запускать команду, respawn означает, что программу надо перезапускать в случае завершения. Программа getty – это программа управления терминалом. Традиционно терминал в UNIX называется телетайпом, поскольку первыми терминалами были электрические пишущие машинка. Соответственно, tty это сокращение от телетайпа. Mingetty – программа, которая умеет работать с виртуальными терминалами на персональном компьютере. Она умеет настраивать драйвер терминала, а в качестве параметров получает имя устройства терминала, который надо настроить. В каталоге /dev/ есть файл устройства tty1, который соответствует первому виртуальному терминалу. Если бы у нас был модем и мы хотели бы инициализировать его момент загрузки, то могли бы вызвать getty с параметром ttyS0, который соответствует порту COM1. При инициализации модема можно было бы задать дополнительные параметры: скорость соединения 19200 бод, 7 или 8 бит в байте, четность, количество стоп-битов.
S0:2345:respawn:/sbin/getty ttyS0 19200 8 n 1
В прошлый раз я рисовал цепочку, в которой процесс вызовом fork делаются свою копию, дочерняя копия вызовом exec загружает в свою память другую программу, а после завершения сообщает об этом родительскому процессу.
Текстовые пользовательские сеансы устроены на таких цепочках: сначала init делает свою копию и запускает в ней программу mingetty. Mingetty инициализирует терминал и клавиатуру, а потом запускает в том же процессе программу login. Login выводит на экран приглашения на ввод имени и пароля и, если все прошло успешно то назначает себе привилегии пользователя и в том же процессе, затирая самого себя, запускает интерпретатор пользователя, например, bash. Когда пользователь набирает команду exit, то интерпретатор завершает жизненный путь этого процесса. Когда процесс завершается, init получает об этом сигнал. Init смотрит, что полагается делать, видит действие respawn, снова запускает программу mingetty, которая заново инициализирует терминал и все повторяется. Таким образом каждый сеанс находится внутри одного процесса. Как только мы вышли из сеанса наш процесс закончился и тотчас же запустилась программа, которая почистит за нами терминал и восстановит все настройки по умолчанию.
В файле inittab есть есть ещё одно специальное ключевое слово initdefault - уровень по умолчанию. Если через ядро init получил параметр single, то мы загрузимся на уровень 1. Если через загрузчик ничего не передали, то используется значение по умолчанию. Если после установки графической оболочки оказалось, что наш компьютер слабоват для графики, то можно установит уровень по умолчанию на 3, и после следующей перезагрузки мы попадаем на третий уровень - то есть в текстовый режим. Установили систему без графического режима, потом доустановили все пакеты для x window, поменяли уровень по умолчанию на 5 и после следующей перезагрузки попали сразу в графический режим.
В этой системе скриптов иногда хочется сделать что-то свое, например, при старте удалить все файлы в каталоге /tmp/. Для этого есть отдельный файл под названием /etc/rc.local, который запускается после всех остальных. Это просто скрипт без параметров, в который можно прописать всё, что угодно. Например, на одном из моих роутеров в момент старта системы в этом файле прописываются таблицы маршрутизации. Мне было лень искать где находятся соответствующие стандартные скрипты из дистрибутива и проще оказалось прописать команды в rc.local.
В различных версиях ядра Linux используются разные механизмы фильтрации сетевых пакетов.
Самый ранний с исторической точки зрения механизм ipfw, управляемый командой ipfwadm, использовался в ядрах 1.2 - 2.2.
В версии 2.2.10 появился механизим ipchains, который позволил создавать "подпрограммы" из правил, но ещё не умел отслеживать состояние соединений.
С версии 2.4 появился механизм с поддержкой состояний — netfilter, который управляется программой iptables.
С версии 3.13 добавлен механизм nftables, заменяющий iptables, ip6tables, arptables и ebtables. nftables управляется утилитой nft.
В настоящий момент основным механизмом предлагается сделать bpfilter, на основе виртуальной машины eBPF.
Надо различать механизмы сетевой фильтрации в ядре и прикладные программы, которые этими механизмами управляют.
iptables — явное создание, удаление, печать правил netfilter
UFW — генерация правил на основе существующих шаблонов в Ubuntu
ufw
— питоновский скрипт в Ubuntu для управление брандмауэром netfilter/iptables. Конфигурационные файлы находятся в каталоге /etc/ufw/
.
Перед включением брандмауэра удалённо по сети необходимо убедиться, что правила разрешают удалённый доступ по SSH. Для этого надо посмотреть правила в файле /etc/ufw/user.rules или выполнить добавление фиктивного правила с опцией --dry-run:
ufw --dry-run allow 1
У UFW есть пара недостатков:
Проверка состояния UFW:
ufw status verbose
Включение UFW
ufw enable
Отключение UFW
ufw disable
Установка правил по умолчанию
ufw default deny incoming
ufw default allow outgoing
Добавление разрешающих правил
ufw allow ssh
ufw allow 8080
ufw allow 80/tcp
Добавление запрещающих правил
ufw deny http
ufw deny from 123.45.67.89
Добавление правил в начало
ufw prepend allow http
Добавление правил в список по номеру
ufw status numbered
...
ufw insert 4 allow http
Добавление диапазонов портов
sudo ufw allow 7100:7150
Добавление разрешений по IP
ufw allow from 123.45.67.89
ufw allow from 123.45.67.0/24
ufw allow from 123.45.67.0/24 to any port 22
Удаление правил
ufw delete allow http
Удаление правил по номеру
ufw status numbered
...
ufw delete 2
Удаление всех правил
ufw reset
Если хочется изменить правила в цепочке FORWARD, то в начало правила надо добавить слово route
ufw route allow from 123.45.67.0/24
ufw route delete allow from 123.45.67.0/24
Включение/выключение сохранения логов в syslog (файлы /var/log/ufw*)
ufw logging <op>
Где <op>
Пакеты приложений могут добавлять списки необходимых им портов в файлы в каталоге /etc/ufw/applications.d. В последующем при задании правил вместо номера порта можно указывать app <NAME>
Список приложений:
ufw app list
Информация о конфигурации приложения
ufw app info <NAME>
Разрешить доступ к приложению. Имя приложения указывается вместо имени порта.
ufw allow <NAME>
ufw allow from 192.168.0.0/16 to any app <NAME>
firewalld позволяет описывать брандмауэр в терминах зон, сервисов и т.д. Конфигурация firewalld компилируется в правила iptables или nftables.
Список стандартных сервисов
firewall-cmd --get-services
Добавление разрешения на сервис или порт
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-port=4444/tcp
Удаление разрешения
firewall-cmd --permanent --remove-service=ssh
Список установленных разрешений
firewall-cmd --permanent --list-all
После всех установок необходимо их применить
firewall-cmd --reload
Подсистема netfilter/iptables в ядре отслеживает состояние соединений проходящих через NAT на маршрутизаторе.
Просмотреть текущие соединения можно командой
conntrack -L
Местоположение таблицы соединений в каталоге /proc может меняться в зависимости от версии ядра.
#new
cat /proc/net/nf_conntrack
#old
cat /proc/net/ip_conntrack
TCP Wrappers – изначально набор вспомогательных программ 'запускалок' (tcpd, miscd и вспомогательные программы), для контроля за IP адресами клиентов, стартующих сетевые сервисы через inetd. Основная функция, управляющая проверкой правил, hosts_access(request)
была в последующем выделена в отдельную библиотеку libwrap
. В настоящее время эту библиотеку используют самые разнообразные сервисы, такие как xinetd, sshd, rsyncs и т.п. Полный список программ, использующих TCP Wrappers, можно получить, выполнив следующую команду:
strings -f /usr/sbin/* /usr/local/sbin/* | grep hosts_access
Функция hosts_access
использует два конфигурационных файла /etc/hosts.allow
и /etc/hosts.deny
(в FreeBSD только /etc/hosts.allow
), которые могут иметь классический или расширенный синтаксис.
В классическом варианте вначале проверяются все правила из hosts.allow
. Если хоть одно правило применимо к паре сервис-клиент, то соединение устанавливается. Затем проверяются все правила из hosts.deny
. При нахождении соответствия соединение отклоняется. Если правила нет, то соединение устанавливается. Чтобы явно разрешить доступ только по правилам из hosts.allow
, необходимо добавить в hosts.deny
правило ALL:ALL
.
Классический синтаксис описан в man странице HOSTS_ACCESS(5). Файлы состоят из строк вида
daemon_list : client_list [ : shell_command ]
где
Файлы /etc/hosts.allow
и /etc/hosts.deny
эквивалентны по своему назначению. Каждое правило может содержать результат – allow или deny. Если в правиле результат не прописан явно, то он вычисляется по правилу классического варианта. Можно считать, что все правила находятся hosts.allow
, а hosts.deny
остается пустым. Выполняется первое найденное правило.
Синтаксис правил описан в man странице HOSTS_OPTIONS(5). Файлы состоят из строк вида
daemon_list : client_list : option [: option ...]
daemon_list, client_list полностью совместимы с классическим синтаксисом, а опции позволяют понизить привилегии, запустить дополнительную программу параллельно с сервисом или вместо него, и, наконец, принять решение allow или deny. Опции выполняются слева направо. Опция allow
/deny
должна стоять последней, поскольку после неё произойдёт запуск сервиса или прекращение работы.
Для запуска дополнительных программ используются две опции: spawn shell_command
– запуск программы в параллельном процессе одновременно с сетевым сервисом, и twist shell_command
– запуск программы в текущем процессе вместо сервиса. Командам в качестве параметров можно передать некоторую информацию о соединении. spawn не влияет на запуск основного сервиса, поэтому за ней должна следовать опция allow или deny. twist затирает текущий процесс и, соответственно, дальнейшие проверки опций. Однако, через параметры в twist можно передать имя исполняемого файла сервиса, чтобы выполнить его после дополнительных проверок.
Кроме опций запуска программ, существуют опции смены владельца, установки маски создаваемых файлов, понижение приоритета и т.п.
В конце списка правил можно добавить правило по умолчанию ALL:ALL:deny
, иначе подразумевается наличие ALL:ALL:allow
.
Список состоит из полей, разделённых пробелами и/или запятыми. Список может состоять из основной части и исключений, следующих за ключевым словом EXCEPT. Возможна группировка списков и исключений с помощью круглых скобок. В списке могут присутствовать IP адреса, имена хостов, ключевые слова и шаблоны.
Ключевые слова (часть опущена):
Шаблоны (часть опущена):
#классический стиль
sshd : .example.com
vsftpd : 192.168.
ALL : 192.168.1.0/255.255.255
# Разрешаем подключение из домена .example.com
# кроме station15.example.com
sshd : station15.example.com : deny
sshd : .example.com : allow
#Дополнительно запрещаем всем кроме домена *.hacker.org
sshd : ALL EXCEPT *.hacker.org:twist /bin/echo "Reject - bad host name %h"
# Фактически разрешаем *.hacker.org (остальные уже заблокированы)
# с логированием соединений в файл /tmp/sshd.connections
sshd : ALL:spawn /bin/echo "%d at %I connected from %i" > /tmp/sshd.connections: allow
# Запрещаем остальные соединения
ALL:ALL:deny
Для того, чтобы администратору не пришлось вникать в подробности работы с openssl
, вместе с OpenVPN поставляется набор скриптов для генерации ключей — EasyRSA.
Для работы OpenVPN с авторизацией по ключам требуется не менее семи файлов.
Серверная константа для Diffie-Hellman — dh1024.pem. Создается командой build-dh
.
Ключ и самоподписанный сертификат удостоверяющего центра (CA) — ca.key, ca.crt. Создаются командой build-ca
.
Ключ сервера и сертификат ключа сервера, подписанный ca.key, — server.key, server.crt. Создаются командой build-key-server
.
Ключи и сертификаты для клиентов. Сертификаты подписаны ca.key. Создаются командой build-key
или build-key-pass
.
В процессе работы скриптов создаются файлы запросов на сертификат с расширением .csr. Они не нужны и их можно спокойно стереть.
Конфигурация ключей на сервере:
dh /etc/openvpn/dh1024.pem
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
Конфигурация ключей на клиенте:
ca ca.crt
cert client.crt
key client.key
Сертификат удостоверяющего центра ca.crt обычно один и тот же, что на сервере, что на клиенте. Он используется для верификации целостности собственного ключа (проверка, что ключ соответствует сертификату и что сертификат подписан CA) и для проверки сертификата партнера.
Если заменить (испортить) ca.crt то при попытке соединения выдается ошибка VERIFY ERROR: depth=0, error=unable to get local issuer certificate
С настройками по умолчанию EasyRSA генерирует сертификаты на десять лет. Через десять лет после выпуска сертификата CA срок его действия закончится на сервере и у всех клиентов. Кроме того, поскольку сертификат сервера обычно генерируют сразу вслед за созданием CA, в то же время закончится и срок действия сертификата сервера. При попытке подключиться клиентам выдается ошибка VERIFY ERROR: depth=0, error=certificate has expired: CN=server, serial=123
Для решения проблемы надо средствами openssl перевыпустить сертификат CA. Новый сертификат CA надо будет установить на сервере и у всех клиентов.
Генерация самоподписанного сертификата CA с использованием атрибутов из старого сертификата:
mv ca.crt old-ca.crt
openssl x509 -in old-ca.crt -days 3650 -out ca.crt -signkey ca.key
При завершении их срока действия сертификат сервера можно попробовать либо перевыпустить средствами openssl сертификат для имеющегося серверного ключа, либо сгенерировать новые ключ и сертификат средствами EasyRSA. При генерации нового ключа могут быть проблемы, поскольку удостоверяющий центр EasyRSA ведет учет выпущенных ключей и по умолчанию отказываться генерировать новый ключ, пока не отозван старый. Те же проблемы возникнут при завершения срока действия сертификатов клиентов. Чтобы остаться в рамках использования только EasyRSA можно поступить следующим способом:
После истечения срока сертификата CA можно создать новый CA. В этом случае необходимо перевыпустить новый сертификат для старого CA, как описано выше, после чего средствами EasyRSA создать новый CA и в дальнейшем использовать составной сертификат ca.crt, который будет содержать сертификаты старого и нового CA. В этом случае по мере устаревания сертификатов клиентов и серверов им просто выпускаются новые ключи в новом CA. Старые ключи в таком сценарии отзывать не надо, поскольку новый CA про них ничего не знает, а по истечению срока действия сертификата они автоматически станут недействительными.
Обновление сертификата средствами openssl:
openssl x509 -x509toreq -in server.crt -signkey ca.key -out server.csr
openssl x509 -in server.csr -out server.crt -signkey ca.key -req -days 3650
$ nmcli con add type vlan ifname VLAN10 dev enp1s0 id 10
Connection 'vlan-VLAN10' (37750b4a-8ef5-40e6-be9b-4fb21a4b6d17) successfully added.
Для запуска сетевой службы в стиле inetd, но через systemd необходимо создать два файла:
В файле сокета ListenStream - указывает на протокол TCP (для UDP используется параметр ListenDatagram=). В качестве значения ListenStream может быть указан номер порта или пара IP:Port. Параметр Accept=yes указывает на то, что для каждого подключения надо стартовать отдельный экземпляр программы. Чтобы проинформировать приложение о свойствах соединения, ему передаются переменные окружения REMOTE_ADDR и REMOTE_PORT.
/etc/systemd/system/baz.socket:
[Unit]
Description=Baz Socket
[Socket]
ListenStream=127.0.0.1:9999
Accept=yes
[Install]
WantedBy=sockets.target
Имя файла сервиса должно заканчиваться на @, чтобы указать, что одновременно может быть запущено много экземпляров данной программы. В данной конфигурации стандартный ввод программы будет назначен на /dev/null, стандартный вывод будет перенаправлен в сокет, сообщения об ошибках будут сохранены в логах journald. Программа может быть написана на чем угодно. Переменным окружения VAR1 и VAR2 будут назначены значения "word1 word2" и 'word3" соответственно, текущий каталог будет изменен на /tmp, вместо %i будет подставлено имя экземпляра программы, которое также будет видно в списке запущенных сервисов между @ и .service.
/etc/systemd/system/baz@.service:
[Unit]
Description=Baz Service
Requires=baz.socket
[Service]
Type=simple
Environment="VAR1=word1 word2" VAR2=word3
ExecStart=/usr/local/baz %i
WorkingDirectory=/tmp
StandardInput=socket
StandardOutput=socket
StandardError=journal
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target
/usr/local/bin/baz:
#!/bin/bash
pwd
echo ${VAR1}
echo ${VAR2}
echo $1
Добавляем в файл /etc/sysctl.conf (или куда-нибудь в /etc/sysctl.d/50-noipv6.conf) строки
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
Обновляем текущую конфигурацию ядра sysctl -p
.
Применяем настройки к сетевым интерфейсам systemctl restart network
Проверяем адреса на сетевых интерфейсах ip addr
В конфигурации исправляем директиву Listen 80
на
Listen 0.0.0.0:80
Добавляем в squid.conf
dns_v4_first on
В main.cf
inet_protocols = ipv4
Для того, чтобы сам BIND не использовал IPv6 при запуске надо указать опцию -4
.
В CentOS это делается строчкой в файле /etc/sysconfig/named
OPTIONS="-4"
Дополнительно можно добавить в named.conf опцию
listen-on-v6 port 53 { none; };
Для того, чтобы BIND не выдавал записи AAAA (адреса IPv6) клиентам, подключенным по IPv4 необходимо добавить в файл named.conf опцию
filter-aaaa-on-v4 yes;
Для доступа к сетевым картам в Linux используются так называемые интерфейсы. Интерфейсы это не файлы устройств и их нет в каталоге /dev. Интерфейсы создаются динамически и не всегда связаны с сетевыми картами. Например интерфейс ppp0 - это интерфейс VPNа, организованного по протоколу PPTP, а интерфейс lo это виртуальная сетевая карта с адресом localhost (127.0.0.1). В Linux имена интерфейсов традиционно состоят из мнемонического типа интерфейса и его порядкового номера. Карты ethernet доступны через интерфейсы eth0, eth1 и т.д. В системах, использующих systemd способ именования другой - интерфейсы имеют имена вида enp2s0 (en -Ethernet, p - PCI, 2 - номер на шине) Список всех интерфейсов можно посмотреть командой ifconfig -a
или ip link
.
При наличии нескольких сетевых карт возникает вопрос о порядке их нумерации. В CentOS 6 эта задача возложена на подсистему обнаружения и конфигурации устройств - udev. В системах с systemd правила именования встроены в udev, но могот быть переопределены, как написано ниже.
Конфигурационный файл переименования интерфейсов обновляется автоматически при первом обнаружении очередной сетевой карты и находится в файле /etc/udev/rules.d/70-persistent-net.rules. Файл состоит из строк такого содержания:
# PCI device 0x1af4:0x1000 (virtio-pci)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="52:54:00:29:24:1e", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
Видно, что нумерация опирается на аппаратный (MAC) адрес карты. Если в компьютере заменить карту, то интерфейс eth0 станет недоступным, а новая карта получит имя eth1. Если есть желание вручную назначить имена картам, то можно отредактировать этот файл, выставив желаемые соответствия между MAC адресами именами интерфейсов (возможно потребуется перезагрузка).
Классическая утилита конфигурации сетевых интерфейсов ifcfg
#просмотр списка активных интерфейсов
ifcfg
#просмотр конфигурации конкретного интерфейса
ifcfg eth0
#просмотр списка доступных интерфейсов
ifcfg -a
#настройка ip адреса и активация интерфейса
ifconfig eth0 192.168.0.1 netmask 255.255.255.0 up
#деактивация интерфейса
ifconfig eth0 down
Настройка таблицы маршрутизации route
#добавление шлюза по умолчанию
route add default gw 192.168.0.1
#добавление маршрута в локальную сеть
route add -net 192.56.76.0 netmask 255.255.255.0 dev eth0
#добавление маршрута в удаленную сеть
route add -net 192.57.66.0 netmask 255.255.255.0 gw 192.168.0.2
#удаление маршрута
route del -net 192.57.66.0 netmask 255.255.255.0 gw 192.168.0.2
#просмотр таблицы маршрутизации
route
#или
netstat -r
В современных дистрибутивах линукса на смену ifconfig
и route
приходит универсальная утилита ip
#просмотр списка доступных интерфейсов
ip link
#просмотр статистики по интерфейсам
ip -s link
#просмотр ip адресов
ip addr
#просмотр таблицы маршрутизации
ip route
Адреса серверов DNS и имя локального домена вписываются в файл /etc/resolv.conf
search example.com
nameserver 8.8.8.8
Для просмотра доступных сетевых интерфейсов используется команда ip link
ArchLinux использует для настройки сети systemd/netctl
. Для конфигурации используются файлы профилей, которые хранятся в /etc/netctl/
. В данном каталоге есть подкаталог examples/
из которого можно копировать файлы с образцами профилей в /etc/netctl/
. Например:
cp /etc/netctl/examples/ethernet-static /etc/netctl/enp1s0-work
Содержимое enp1s0-work
после редактирования
Interface=enp1s0
Connection=ethernet
IP=static
Address=('10.1.10.2/24')
Gateway='10.1.10.1'
DNS=('10.1.10.1')
Базовые команды netctl
#активация профиля
netctl start enp1s0-work
#включение автоматической активации с текущими настройками профиля при старте системы
netctl enable enp1s0-work
#обновление конфигурации автостарта после изменения настроек профиля
netctl reenable enp1s0-work
В Ubuntu 20 система скриптов ifup
/ifdown
заменена программой netplan
, со своими конфигурационными файлами на языке YAML — /etc/netplan/имяфайла.yaml
См. также примеры на readthedocs.io.
Здесь только секция ethernets, но могут быть секции для vlan, bonding и т.д. Массивы имеют две альтернативные формы записи — в квадратных скобках и построчно, где каждая строка начинается с "- ". link-local: [] — запрет IPV6
network:
version: 2
renderer: networkd
ethernets:
enp3s0f0:
link-local: []
addresses:
- 192.168.56.110/24
routes:
- to: 172.16.0.0/24
via: 192.168.56.100
gateway4: 192.168.56.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
Пример с DHCP
network:
version: 2
renderer: networkd
ethernets:
enp3s0:
dhcp4: true
Несколько IP на одном интерфейсе
network:
version: 2
renderer: networkd
ethernets:
enp3s0:
addresses:
- 10.100.1.37/24
- 10.100.1.38/24:
label: "enp3s0:0"
- 10.100.1.39/24:
label: "enp3s0:some-label"
netplan generate
— генерация из файлов YAML конфигураций для бэкендов NetworkManager или systemd-networkd в каталогах /run/каталог_бэкенда/. Здесь же проходит валидация синтаксиса.
netplan apply
— применение конфигурации
Просмотр доступных интерфейсов - ifcfg -a
Файл конфигурации интерфейсов - /etc/network/interfaces
. auto
- говорит о том, что интерфейс надо конфигурировать при старте системы.
iface eth0 inet static
address 192.168.0.1
netmask 255.255.255.0
gateway 192.168.0.254
auto eth0
iface eth1 inet dhcp
auto eth1
После смены настроек в /etc/network/interfaces
, необходимо отключить и снова включить интерфейс.
ifdown eth0
ifup eth0
Файл /etc/sysconfig/network используется стартовыми скриптами и содержит ключевые параметры - нужна ли сеть, нужно ли конфигурировать IP v6, имя компьютера. Сюда можно вписать шлюз по умолчанию, но CentOS 6 ориентируется на динамическое подкючение к сетям через WiFi и вписывает его в конфигурацию подходящего интерфейса.
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=wwww.example.com
GATEWAY=10.10.10.1
Файлы в каталоге /etc/sysconfig/network-scripts с именами вида ifcfg-eth0
Интерфейс, получающий адрес по DHCP
# динамическая конфигурация интерфейса
ONBOOT="yes"
DEVICE="eth0"
BOOTPROTO="dhcp"
Ручная конфигурация
# статическая конфигурация интерфейса
ONBOOT="yes"
DEVICE="eth1"
BOOTPROTO="static"
IPADDR=145.14.137.221
PREFIX=24
# конфигурация шлюза и DNS
GATEWAY=192.168.1.1
DEFROUTE=yes
DNS1=192.168.1.14
# NM - NetworkManager - графическая оболочка + автоматизация настроек
NM_CONTROLLED="no"
Дополнительный IP адрес на интерфейсе eth1
ONBOOT=no
DEVICE=eth1:0
BOOTPROTO=static
IPADDR=172.16.12.6
NETMASK=255.255.0.0
# следующие два параметра можно не писать
# они вычисляются из IP и маски
BROADCAST=172.16.255.255
NETWORK=172.16.0.0
Инициализация VLAN на eth1
DEVICE=eth1.72
VLAN=yes
VLAN_TRUNK_IF=eth1
BOOTPROTO=static
IPADDR=10.10.0.1
NETMASK=255.255.255.192
ONBOOT=yes
Файл /etc/resolv.conf
# мой домен, для подстановки в короткие имена
search example.com
# сервер DNS
nameserver 8.8.8.8
Ручная настройка имен хостов файл /etc/hosts
127.0.0.1 localhost.localdomain localhost ANY
::1 localhost6.localdomain6 localhost6
194.87.0.50 www.ru
Файл /etc/sysconfig/system-config-firewall правила для настройки программой system-config-firewall
Файл /etc/sysconfig/iptables текущие правила, сохраненные на случай перезагрузки.
После ручного изменения правил их можно сохранить командой service iptables save
Для написания сетевой службы в Linux не обязательно уметь программировать сокеты. Сокет, с точки зрения прикладной программы, выглядит как обычный файловый дескриптор, из которого можно читать и в который можно писать любыми стандартными функциями ввода/вывода. Поэтому появляется возможность перенаправить стандартный ввод/вывод любой программы в заранее подготовленный сокет. Для такого перенаправления служит программа xinetd
.
Конфигурация xinetd
, как правило, разделяется на две части: значения по умолчанию – /etc/xinetd.conf
и настройки для отдельных служб, по одному файлу в каталоге /etc/xinetd.d/
на службу.
Чтобы запустить свою сетевую службу, необходимо создать ещё один файл в /etc/xinetd.d/
. Имя файла особого значения не имеет, но обычно выбирается по имени службы. Предположим, что служба называется mynetd
, запускается от имени пользователя user1
и выполняет команду sleep 10
. Служба должна ожидать TCP соединение на порту 8888
.
Конфигурационный файл /etc/xinetd.d/mynetd
будет выглядеть так:
service mynetd
{
disable = no
# Если не написать UNLISTED, то xinetd будет искать имя службы и номер порта
# в файле /etc/services
type = UNLISTED
# stream = TCP, datagram = UDP
socket_type = stream
port = 8888
# Можно считать, что для протокола TCP wait всегда равен 'no',
# а для протокола UDP – всегда 'yes'
wait = no
user = user1
# При считывании конфигурации файл службы должен существовать и заданный пользователь
# должен иметь право на его выполнение
server = /bin/sleep
server_args = 10
}
Параметр wait
интерпретируется следующим образом: если socket_type = datagram
и wait = yes
, то при появлении на порту данных стартует новый процесс со входом/выходом, перенаправленным в сокет. Пока этот процесс не завершится, xinetd
не контролирует наличие новых данных на порту, оставляя их запущенной программе. Если поставить wait = no
, то на каждую дейтаграмму будет запускаться новый процесс, разделяющий со своими предшественниками общий сокет. В такой ситуации невозможно предсказать, какой копии программы достанутся входные данные из сокета. В принципе, такой подход возможен, если обработка дейтаграммы идёт долго, а писать многопоточный сервис лень. Для TCP ситуация обратная, wait = yes
имеет смысл только для многопоточных программ, иначе первый процесс захватит сокет и не отдаст его, пока программа не завершится.
Ограничение трафика на маршрутизаторе делается в два этапа:
1. Классификация пакетов с помощью netfilter или фильтров iproute2
2. Создание нескольких очередей пакетов с помощью iproute2
Пакеты распределяются в зависимости от класса на несколько очередей в которых ждут своей очереди на отправку. Каждая очередь имеет ограничения на полосу пропускания, приоритет и еще некоторые параметры. При переполнения очереди пакеты соответствующего класса начинают отбрасываться.
Очереди организованы в древовидную иерархию. Каждая очередь может быть разбита на более мелкие. Корневые очереди, связанные непосредственно с «хэндлером» интерфейса имеют абсолютные ограничения по пропускной способности. Дочерние очереди могут «заимствовать» друг у друга неиспользуемую полосу пропускания.
Классификация пакетов с iptables
Первый этап выполняется с помощью программы /sbin/iptables.
Маркируем пакеты в зависимости от каких либо параметров, например по размеру, номеру порта, ip адресу. Для специфических случаев можно дописывать свои модули для netfilter. Например модуль IP2P http://www.ipp2p.org позволяет выбирать пакеты p2p сетей.
Приписываем класс пакета в соответствии с проставленными меткам
Вообще говоря, можно было бы классифицировать пакеты сразу. Например выделим входящий HTTP трафик в отдельный класс
iptables -t mangle -A POSTROUTING -o eth0 -s 0/0 --source-port 80 -j CLASSIFY --set-class 1:10
Маркировка позволяет проверять только несколько первых пакетов в соединении. Для того, чтобы не исследовать каждый пакет используется модуль CONNMARK который позволяет маркировать все пакеты принадлежащие соединению.
Пример классификации P2P трафика. Классы для различных интерфейсов определяются независимо, что позволило использовать класс 1:20 для входящего и для исходящего трафика.
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -p tcp -m mark ! --mark 0 -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp -m ipp2p --ipp2p -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p tcp -m mark --mark 1 -j CONNMARK --save-mark
iptables -t mangle -A POSTROUTING -o eth0 -m mark --mark 1 -j CLASSIFY --set-class 1:20
iptables -t mangle -A POSTROUTING -o eth1 -m mark --mark 1 -j CLASSIFY --set-class 1:20
Создание очередей пакетов
Этап второй выполняется с помощью /sbin/tc.
Создаем связанную с интерфейсом очередь исходящих пакетов, указываем класс по умолчанию. Создаем корневой класс, назначаем лимит. Создаем дочерние классы, указываем лимиты для них (Обязательно должен быть создан класс используемый по умолчанию).
Теперь каждый пакет попадает в свою очередь. Если очередь переполняется, пакеты отбрасываются не доходя до аппаратного уровня.
Пример: Общая пропускная способность канала 10 Мбит/с. Внешний интерфейс eth0, внутренний eth1. Ограничиваем исходящий трафик P2P сетей из предыдущего примера полосой 32 Кбит/с, входящий 256 Кбит/с.
/sbin/tc qdisc add dev eth0 root handle 1: htb default 10
/sbin/tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit
/sbin/tc class add dev eth0 parent 1:1 classid 1:10 htb rate 10mbit
/sbin/tc class add dev eth0 parent 1:1 classid 1:20 htb rate 32kbit
/sbin/tc qdisc add dev eth1 root handle 1: htb default 10
/sbin/tc class add dev eth1 parent 1: classid 1:1 htb rate 10mbit
/sbin/tc class add dev eth1 parent 1:1 classid 1:10 htb rate 10mbit
/sbin/tc class add dev eth1 parent 1:1 classid 1:20 htb rate 256kbit
Пример стартового скрипта /etc/init.d/shaper (написан не мною и не связан с примером iptables)
#!/bin/sh
# init script written by shane at knowplace dot org
# this script only creates the qdiscs and classes required for shaping, it
# does NOT create the necessary filters
INTERFACE='eth0'
rc_done=" done"
rc_failed=" failed"
return=$rc_done
TC='/sbin/tc'
tc_reset ()
{
# Reset everything to a known state (cleared)
$TC qdisc del dev $INTERFACE root 2> /dev/null > /dev/null
}
tc_status ()
{
echo "[qdisc - $INTERFACE]"
$TC -s qdisc show dev $INTERFACE
echo "------------------------"
echo
echo "[class - $INTERFACE]"
$TC -s class show dev $INTERFACE
}
tc_showfilter ()
{
echo "[filter - $INTERFACE]"
$TC -s filter show dev $INTERFACE
}
case "$1" in
start)
echo -n "Starting traffic shaping"
tc_reset
U320="$TC filter add dev $INTERFACE protocol ip parent 1:0 prio 0 u32"
#
# dev eth0 - creating qdiscs & classes
#
$TC qdisc add dev $INTERFACE root handle 1: htb default 60
$TC class add dev $INTERFACE parent 1: classid 1:1 htb rate 116kbit
$TC class add dev $INTERFACE parent 1:1 classid 1:10 htb rate 32kbit ceil 116kbit prio 0
$TC class add dev $INTERFACE parent 1:1 classid 1:20 htb rate 22kbit ceil 116kbit prio 1
$TC class add dev $INTERFACE parent 1:1 classid 1:30 htb rate 22kbit ceil 116kbit prio 2
$TC class add dev $INTERFACE parent 1:1 classid 1:40 htb rate 20kbit ceil 116kbit prio 3
$TC class add dev $INTERFACE parent 1:1 classid 1:50 htb rate 18kbit ceil 116kbit prio 4
$TC class add dev $INTERFACE parent 1:1 classid 1:60 htb rate 2kbit ceil 116kbit prio 5
$TC qdisc add dev $INTERFACE parent 1:10 handle 10: sfq perturb 10
$TC qdisc add dev $INTERFACE parent 1:20 handle 20: sfq perturb 10
$TC qdisc add dev $INTERFACE parent 1:30 handle 30: sfq perturb 10
$TC qdisc add dev $INTERFACE parent 1:40 handle 40: sfq perturb 10
$TC qdisc add dev $INTERFACE parent 1:50 handle 50: sfq perturb 10
$TC qdisc add dev $INTERFACE parent 1:60 handle 60: sfq perturb 10
tc_status
;;
stop)
echo -n "Stopping traffic shaper"
tc_reset || return=$rc_failed
echo -e "$return"
;;
restart|reload)
$0 stop && $0 start || return=$rc_failed
;;
stats|status)
tc_status
;;
filter)
tc_showfilter
;;
*)
echo "Usage: $0 {start|stop|restart|stats|filter}"
exit 1
esac
test "$return" = "$rc_done" || exit 1
##################################
Примечания.
В параметрах iptables цель CLASSIFY в iptables может использоваться только в таблице mangle и только в цепочке POSTROUTING.
В параметрах tc встречаются сокращения:
qdisc – Classful Queuing Disciplines – базовый объект связанный с сетевым интерфейсом и обеспечивающий управление очередями
htb – Hierarchical Token Bucket – имя собственное одного из планировщиков очередей пакетов в ядре Linux
Имена классов имеют вид M:N. M: эквивалентно M:0 и используется для создания общего корня очередей (хэндлера) связанного напрямую с интерфейсом.
В современных системах логи ведутся через сервис journald.
Просмотр последних сообщений в логах
journalctl -e
то же, но с подробной информацией о событиях
journalctl -ex
При наличии каталога /var/log/journal - файлы журнала создаются в нем и сохраняются при перезагрузке. В противном случае журнал хранится в каталоге /run/log/journal/, который отображается в ОЗУ и теряется при перезагрузке.
Для совместимости с существующими системами journald пересылает все сообщения в классический syslogd. Этот поведение можно отключить в конфигурации /etc/systemd/journald.conf установив параметр
ForwardToSyslog=no
Полезные опции:
Приоритет: emerg=0, alert=1, crit=2, err=3, warning=4, notice=5, info=6, debug=7
Типы сообщений: kern=0, user=1, mail=2, daemon=3, auth=4, syslog=5, lpr=6, news=7, uucp=8, cron=9, authpriv=10, ftp=11
Набор скриптов Logwatch предназначен для выделения из логов наиболее значимой информации.
Структура пакета практически не зависит от используемой операционной системы и ориентирована на популярные сервисы, такие как веб-сервер apache, почтовый сервер sendmail, антивирус clamav и т.п. Благодаря этому всегда можно обновить версию Logwatch, взяв tar-архив прямо с сайта проекта http://www.logwatch.org. Тонкие отличия для системных модулей, таких как pam_unix, учтены в самих скриптах.
Основные скрипты располагаются в каталоге /usr/share/logwatch При необходимости тонких настроек или внесения изменений в скрипты, необходимо скопировать соответствующие файлы в каталог /etc/logwatch с сохранением вложенной структуры каталогов.
При загрузке logwatch вначале просматривает /etc/logwatch, а затем /usr/share/logwatch. При этом скрипты с совпадающими именами берутся только из /etc/logwatch, а переменные конфигурации, описанные в /etc/logwatch либо перекрывают описанные /usr/share/logwatch, либо, в случаях когда формируется список значений, добавляются к описанным в /usr/share/logwatch.
Если у вас выдаются избыточные безвредные сообщения, нераспознанные модулями Logwatch, то в /etc/logwatch/conf/ignore.conf можно прописать набор регулярных выражений, которые будут отфильтровывать лишние строки. При настройке этого фильтра следует соблюдать осторожность, чтобы не заблокировать оповещение о важных событиях в системе.
Запись логов ведётся специальным приложением syslogd или его современной версией rsyslogd. Для отправки сообщений демону используется сетевой протокол, который может использовать либо TCP/IP, либо Unix сокет /dev/log. Программист на Си может воспользоваться для записи в лог стандартной функцией syslog(3), а разработчик скриптов или обычный пользователь – утилитой logger.
Особенностью протокола syslog является доверие к клиенту, что приводит к возможности генерировать записи любого содержания в любом логе от имени любой службы (в том числе от имени ядра ОС).
Сообщение, передаваемое в syslogd, содержит класс сообщения, состоящий из категории и важности, идентификатор (имя программы) и произвольный текст. syslogd на основе класса сообщения выбирает файл для записи и сохраняет в этот файл время получения сообщения, идентификатор и текст.
По категориям: authpriv, cron, daemon, ftp, kern, lpr, mail, news, syslog, user, uucp, local0...local7
authpriv – данные могут содержать приватную информацию, например пароли при логировании процесса аутенификации. Такие данные должны сохраняться в файле, недоступном на чтение для обычных пользователей.
cron, ftp, lpr, mail, news, uucp – различные службы (в том числе устаревшие), которые генерируют большой поток сообщений. В CentOS отдельно настроены mail и cron
daemon – любая служба
user – обычный пользователь
syslog – сообщения самого syslogd
local0...local7 – отданы на усмотрение местного администратора. В CentOS local7 используется для записи сообщений во время загрузки
По важности: emerg, alert, crit, err, warning, notice, info, debug
emerg – критическая ошибка, затрагивающая всю систему (отказ диска, отключение электропитания и т.п.)
alert, crit – проблемы различной степени тяжести. Используются редко
err, warning, notice, info – диапазон, обычно используемый приложениями
debug – отладочные сообщения. Обычно нигде не сохраняются
В зависимости от используемого демона конфигурация может находиться в /etc/syslog.conf или /etc/rsyslog.conf. rsyslog.conf имеет более развитый синтаксис, однако правила, описывающие сортировку сообщений по категориям, имеют одинаковый формат. Эти правила состоят из строк вида:
фильтр действие
фильтр – описывает класс сообщений, для которых будет выполняться действие, и состоит из шаблонов, разделённых точкой с запятой. Каждый шаблон состоит из полей категории и важности, разделённых точкой. Фильтр выбирает те сообщения, категория и важность которых соответствуют всем шаблонам фильтра. Т.е. условия-шаблоны объединяются логическим оператором И.
Примеры фильтров:
mail.info – категория mail, важность info и выше
*.=debug – любая категория, важность – только debug
*.* – все сообщения
*.*;authpriv.none – все, кроме категории authpriv
действие – имя файла, FIFO, программы или IP адрес удаленного компьютера.
Формат записи действий:
/var/log/messages – файл
/dev/console – консоль (root'а?)
/dev/ttyS0 – последовательный порт
|/tmp/debug-log – FIFO. Удобно для отладки
@192.168.1.0 – IP адрес
* – сообщение всем залогированным пользователям
Пример из реального файла syslog.conf
# Всё (кроме mail и cron) важности info и выше
# Прячем сведения об аутенификации пользователей!
*.info;mail.none;authpriv.none;cron.none /var/log/messages
# authpriv в отдельный файл с ограниченным доступом
authpriv.* /var/log/secure
# Все сообщения почты в отдельный файл
mail.* /var/log/maillog
# то же с сообщениями от crond
cron.* /var/log/cron
# Сообщения уровня emerg рассылаются всем
*.emerg *
logger -t идентификатор -p категория.важность текст
По умолчанию logger подставляет в качестве идентификатора имя пользователя, а в качестве класса сообщения user.notice, однако любой, даже непривилегированный, пользователь может изменить эти значения с помощью соответствующих опций.
Для запуска задач по расписанию в Unix традиционно используется демон crond. Эта программа при старте читает пользовательские файлы расписаний из каталога /var/spool/cron/ и общесистемное расписание, хранящееся в файле /etc/crontab и файлах, расположенных в каталоге /etc/cron.d/. Общесистемное расписание отличается от пользовательского тем, что каждая его запись содержит поле с идентификатором пользователя, от имени которого выполняется задание.
После того, как расписания загружены в оперативную память, crond ежеминутно проверяет наличие записи в расписании, соответствующей текущему времени, и, если такая найдена, запускает указанную команду от имени указанного пользователя. Вывод команды (stdout и stderr) перехватывается и отправляется по почте, указанной в расписании. По умолчанию почта при выполнении пользовательского расписания отправляется локальному пользователю, а при выполнении общесистемного расписания – root'у.
Если crond обнаруживает изменение времени mtime у файла /etc/crontab или у одного из каталогов с расписаниями, то он автоматически заново считывает все файлы расписаний.
Формат общесистемного расписания
# Установка переменных окружения
name = value
#строка расписания
mm hh DD MM DW user cmd [arg...]
Формат пользовательского расписания
# отличается отсутствием поля user
mm hh DD MM DW cmd [arg...]
mm hh DD MM DW – время выполнения в формате: минута час деньмесяца месяц деньнедели. Любое поле может быть записано следующим образом:
Месяц и день_недели задаются номером или первыми тремя буквами названия.
Переменные окружения, которые влияют на выполнение команды:
crontab file – скопировать личное расписание из файла
crontab -e – запуск редактора vi для правки расписания
crontab -l – просмотреть расписание
crontab -r – удалить расписание
# некоторые любят интерпретатор zsh
SHELL=/bin/zsh
# Отсылаем почту на внешний адрес
MAILTO= test@example.com
#
# каждый день в ноль часов пять минут
# перехватываем вывод, чтобы не приходили письма
5 0 * * * $HOME/bin/daily.job >> /dev/null 2>&1
# В 14:15 первого числа каждого месяца
15 14 1 * * $HOME/bin/monthly
# раз в пять минут проверяем почту
*/5 * * * * $HOME/bin/check_mail
Для однократного запуска команды в указанное время используется демон atd, задания для которого формируются командой at. Команда вводится со стандартного ввода или читается из файла. Время задаётся в различных форматах, например 16:00 31.12.2014 или "now +3 hours" (minutes, hours, days)
echo touch /tmp/test | at 14:35 – создать файл сегодня в 14:35, а если уже поздно, то завтра в указанное время
at -f file now + 14days – прочитать команду из файла и выполнить через две недели
atq – показать все назначенные задания
atrm id – удалить задание с номером id
Сервис anacron изначально придуман для персональных компьютеров, которые могут быть выключены в тот момент, когда crond должен был запустить очередную команду. Если anacron обнаруживает, что ежедневная, еженедельная или ежемесячная команда не была выполнена, то он осуществляет её запуск. Конфигурация anacron хранится в /etc/anacrontab в формате:
period delay job-identifier command
где
period – периодичность выполнения команды в днях
delay – если за указанный период команда не выполнялась, то делается задержка delay минут и запускается команда
job-identifier – произвольная текстовая строка для записи в лог-файлы
command – выполняемая команда
Типичный файл /etc/anacrontab (run-parts – выполнить все файлы в каталоге):
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly
В результате переноса долгопериодных действий в anacron, в CentOS 6 существенно изменилось содержание /etc/crontab
/etc/crontab:
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
/etc/crontab в CentOS 6 пуст
/etc/cron.d/0hourly:
01 * * * * root run-parts /etc/cron.hourly
/etc/cron.hourly/0anacron вызывает anacron, который и выполняет запуск ежедневных, еженедельных и ежемесячных задач.
Традиционный Unix хранил информацию о пользователях и их паролях в простой текстовой базе данных в файле /etc/passwd
. База состоит из строк, соответствующих пользователям, каждая из которых состоит из полей, разделённых двоеточием
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
Поля слева на право: имя для входа; пароль (хэш пароля, символ-ссылка на базу паролей, символ отсутствия пароля и т.п.); числовой идентификатор пользователя UID; числовой идентификатор основной группы пользователя GID; текстовое описание пользователя в произвольной форме (называется поле GECOS, поскольку изначально хранило параметры для связи с ОС GECOS); домашний каталог пользователя (стартовый при входе в систему); программа интерпретатор команд пользователя (запускается при входе в систему).
Со временем стало понятно, что хранение хэша пароля в файле доступном для чтения всем пользователям - это неудачное решение, но на формат файла passwd
и его доступность ориентировалось уже столько программ, что изменить его было нельзя не потеряв обратной совместимости. В результате, пароли были вынесены в отдельную базу, формат которой сильно отличается в разных Unix-подобных системах. В Solaris и Linux пароли хранятся в файле /etc/shadow
. В FreeBSD в /etc/master.passwd
. В OSF1 в специализированной базе данных.
В настоящее время файл passwd
обеспечивает отображение имён пользователей в числовые идентификаторы и базовую настройку программного окружения пользователя, а база паролей вне зависимости от формата - аутенификацию пользователей. Существуют ситуации, когда важно только отображение имён (запуск локальных служб, не требующий паролей; вход по ключу в протоколе SSH) или только парольная аутенификация (почтовые серверы, хранящие почту по именам в общей БД). В некоторых случаях наоборот данных из файла passwd
и пароля оказывается недостаточно. Чаще всего это процедура авторизации, например, для ограничения доступа к определённым ресурсам в определённые часы.
После того, как Unix-компьютеры начали объединяться в сети, у администраторов появилась дополнительная проблема по синхронизации паролей и числовых идентификаторов в пределах локальной сети. Общие пароли нужны для того, чтобы пользователь мог работать на любом из свободных компьютеров, а единые числовые идентификаторы нужны для удалённого доступа к файловым системах (т.к. права доступа определяются не именем пользователя, а его UIDом). Для решения проблемы были предложены протоколы репликации базы пользователей локальной сети с администраторского компьютера (Network Information Service - NIS и NIS++), а также протоколы удалённой аутенификации пользователей на основе криптографии (Kerberos).
В настоящее время существует множество решений, не использующих классические файлы: хранение учётных данных в СУБД общего назначения; доступ к учетным данным по протоколу LDAP; аутенификация с помощью смарт-карт,одноразовых паролей и биометрических средств.
В середине 1990-х для унификации всех этих средств и протоколов программисты фирмы Sun предложили вынести ключевые функций в расширяемые модульные библиотеки. Библиотека доступа к данным из файла passwd
(а так же к файлам групп /etc/group
, хостов /etc/hosts
и некоторым другим) называется Name Service Switch (переключатель служб имён NSS), а библиотека выполняющая аутенификацию и авторизацию пользователей, а также смену паролей - Pluggable Authentication Modules (подключаемые модули аутенификации PAM). Каждая библиотека может наращиваться за счёт динамически подгружаемых модулей. Данные библиотеки доступны в Solaris, Linux, FreeBSD и некоторых других Unix-подобных ОС.
В Linux список модулей NSS можно просмотреть командой:
ls /lib/libnss.so
список модулей PAM:
ls /lib*/security
Обычно в Linux присутствуют модули NSS поставляемые в составе библиотеки glibc
: files
, compat
, nis
, nisplus
, hesiod
, dns
. Модули PAM по умолчанию включают ряд локальных проверок: проверка пароля в файлах passwd
или shadow
, проверка на принадлежность к определённой группе, проверка времени суток и т.п.
Для взаимодействия с сетевыми службами, такими как сервер Active Directory, возможно, придётся доустановить дополнительные модули NSS и PAM.
В 1991г в США Филом Циммерманом были опубликованы исходные текстов программы PGP (Pretty Good Privacy – замечательная приватность). Эта программа выводила на гражданский рынок самые современные на тот момент алгоритмы шифрования с ассиметричными ключами RSA, ВSA и ElGamal (расширение Diffi-Helman). На тот момент в США действовали довольно жёсткие законы в отношении экспорта криптографических программ и Фил в течении трёх лет подвергался судебному преследованию, но был оправдан, поскольку удалось убедить судей, что исходные тексты программы, это литературное произведение, попадающее под первую поправку к конституции США.
Права на программу PGP несколько раз переходили от одной компании к другой. С начала 2000-х и по настоящее время программой владеет компания Symantec, которая закрыла доступ к исходным кодам программы.
В 1997 году на основе реализации PGP v.5 была разработана группа стандартов OpenPGP. Стандарты описывает требования к алгоритмам шифрования, форматы хранения данных, взаимодействие с почтовыми программами и т.п.
В 1999 в рамках проекта GNU и при финансировании правительства Германии была разработана свободно распространяемая программа шифрования совместимая с OpenPGP – GnuPG версии 1, а в 2006 году - GnuPG версии 2.
В 2014 году вышла версия GnuPG 2.1.0, которая значительно отличается от предшественников (включая версии 2.0.x) по формату файлов. Миграция с 2.0.x на 2.1.x происходит автоматически, обратное преобразование потребует ручного выполнения экспорта-импорта ключей. Кроме того, начиная с версии 2.1.0 прекращена поддержка исторического формата ключей PGP-2. Тем не менее, GnuPG всех версий совместима с классической программой PGP версии 5 и старше.
В 2017 вышла версия GnuPG 2.2.0, которая не сильно отличается о 2.1.x. До этой версии команда gpg
означала GnuPG 1.x, а для новых версий GnuPG использовалась команда gpg2
. Начиная с версии 2.2 во всех новых дистрибутивах команда gpg
означает GnuPG 2.2 и старше.
Реализации GnuPG существуют для всех популярных ОС. Реализация GnuPG для Linux включена во все дистрибутивы, реализация GnuPG для Windows - Gpg4win, для Android OpenKeychain.
Документацию и последние версии GnuPG можно получить на http://www.gnupg.org. На русском языке подробную информацию можно получить на сайте http://www.pgpru.com.
Для интеграции PGP в почтовые программы можно воспользоваться следующими продуктами: Linux, Windows, OS X - плагин для почтового клиента Thunderbird - Enigmail; Android - K9 mail + OpenKeychain; Серверное web-приложение Roundcubemail (ver.>1.2); Gmail и т.п. - расширение для браузеров Mailvelop.
Если не вдаваться в подробности (которые очень важны, если криптография используется по назначению, а не в качестве игрушки), то процесс работы с GnuPG делится на следующие этапы:
На данной странице описаны базовые команды GnuPG 2.x.
Обобщённый формат вызова GnuPG:
gpg --опция ... --команда [имя ключа]
Команды указывают желаемое действие, а опции - параметры для выполнения этого действия. Опции указываются до команд. Некоторые команды переводя gpg в интерактивный режим.
В качестве имени ключа может использоваться цифровой отпечаток (fingerprint), идентификатор ключа (key ID) или e-mail владельца. В дальнейшем имя ключа будет заменяться на mykey .
gpg --gen-key
В GnuPG версии 2.1.x* и старше --gen-key предлагает ввести только имя, e-mail и пароль для секретного ключа, подставляя остальные параметры по умолчанию. Для полного диалога в этих версиях необходимо использовать команду --full-gen-key, возможно с опцией --expert, которая добавляет расширенный выбор алгоритмов шифрования.
В результате выполнения команды --gen-key генерируется два ключа: мастер-ключ, он же ключ подписи, и ключ шифрования. Оба ключа используют алгоритм шифрования rsa2048 и имеют срок жизни два года. Кроме того автоматически формируется сертификат отзыва.
В процессе создания ключа у для него будет создан длинный шестнадцатеричный цифровой отпечаток (fingerprint) который может использоваться для выбора ключа при последующих операциях.
Немного о вводимых параметрах:
Идентификатор владельца ключа (UID) в OpenPGP имеет формат "Полное имя (комментарий) <адрес e-mail>". Идентификатор связывает ключ с определенным человеком. Поскольку OpenPGP в значительной мере ориентирован на использование совместно электронной почтой, то основным идентификатором является e-mail, а полное имя, это лишь вспомогательный элемент.
Пароль для шифрования секретного ключа должен быть достаточно сложным для взлома. Утеря секретного ключа сводит на нет всю систему шифровальной защиты и потому ключ хранится на диске в зашифрованном виде. В идеальном случае ключ должен храниться на съемном носителе (флешке) в физически защищенном месте. Если злоумышленник получит доступ к файлу секретного ключа, то пароль к нему будет последней линией обороны.
Если ключ сертификат отзыва мастер-ключа (revoсation certificate) не был создан во время генерации, то его следует создать, используя команду --gen-revoke. Если секретный ключ будет похищен или утерян, то этот сертификат может быть разослан для уведомления о том, что открытый ключ нельзя больше использовать.
gpg --output revoke.asc --gen-revoke mykey
Сертификат отзыва сохраняется в текстовой кодировке.
К одному ключу можно добавить несколько пользовательских идентификаторов (UID), например, личный и рабочий адреса электронной почты. Операция выполняется в диалоговом режиме.
gpg --edit-key mykey
В диалоговом режиме ввести команду adduid
gpg> adduid
Real Name: My work email
E-mail: my@example.com
После создания нового идентификатора следует отметить степень доверия к нему и назначить, какой UID будет основным. Команда uid
gpg> uid <number>
gpg> trust
(5 = ultimate trust)
gpg> uid <number>
gpg> primary
gpg> save
Удаление идентификатора
gpg> uid <number>
gpg> deluid
Отзыв идентификатора
gpg> uid <number>
gpg> revuid
Перед тем как послать кому-либо открытый ключ необходимо экспортировать его командой --export:
gpg --armor --output alice.gpg --export my@example.com
Опция --armor указывает, что ключ будет сохранён в формате ASCII.
После обмена ключами открытый ключ партнера может быть добавлен к связке открытых ключей при помощи команды --import:
gpg --import blake.asc
gpg --list-keys
/home/alice/.gnupg/pubring.gpg
pub 1024R/B115BDB6 2002–05–01 Alice (test key) <alice@wonderland.uk>
pub 1024R/01A1FE63 2002–05–01 Blake (dumb) <blake@anywhere.ru>
sub 1024R/526C7F7F 2002–05–01 [expires: 2003–05–01]
Для того, чтобы проверить достоверность ключа используется цифровой отпечаток (fingerprint) ключа. После проверки ключ заверяется подписью, для подтверждения того, что он достоверен. Ожидаемый отпечаток ключа передается через надёжный канал связи, например зачитывается владельцем по телефону.
Отпечаток ключа можно просмотреть командой --fingerprint.
gpg --fingerprint alice@wonderland.uk
pub 1024R/B115BDB6 2002–05–01 Alice (test key) <alice@wonderland.uk>
Key fingerprint = DE49 CDEF 12A3 8B7B 272B A572 C73A 9987 B115 BDB6
Или
gpg --fingerprint
/home/test/.gnupg/pubring.gpg
pub 1024R/B115BDB6 2002–05–01 Alice (test key) <alice@wonderland.uk>
Key fingerprint = DE49 CDEF 12A3 8B7B 272B A572 C73A 9987 B115 BDB6
pub 1024R/01A1FE63 2002–05–01 Blake (dumb) <blake@anywhere.ru>
Key fingerprint = 80B8 1955 7D68 FE4F D882 DAD1 D85C 124A 01A1 FE63
sub 1024R/526C7F7F 2002–05–01 [expires: 2003–05–01]
Для подписи ключа необходимо перейти в режим редактирования ключа при помощи команды --edit-key:
gpg --edit-key blake@anywhere.ru
В диалоговом режиме ввести команду sign:
gpg> sign
Подтвердить желание подписать ключ и ввести пароль секретного ключа
Указать, с какой степенью достоверности проверен ключ
gpg> trust
Укажите, насколько Вы доверяете данному пользователю в вопросах проверки
достоверности ключей других пользователей (проверяет паспорт,
сверяет отпечатки ключей из разных источников и т.п.)
1 = Не знаю или не буду отвечать
2 = НЕ доверяю
3 = Доверяю ограниченно
4 = Полностью доверяю
5 = Абсолютно доверяю
Выход из режима редактирования и сохранение изменений
gpg> quit
Для шифрования документа используется команда --encrypt. Для шифрования необходимо иметь открытые ключи предполагаемых получателей. Программа ожидает в качестве параметра имя шифруемого документа или, в случае его отсутствия, шифрует стандартный ввод. Зашифрованный результат помещается в стандартный вывод, если не указана опция --output. Для повышения защиты перед шифрованием документ дополнительно сжимается.
gpg --output message.gpg --encrypt --recipient blake@anywhere.ru message.txt
Опция --recipient может повторяться несколько раз для каждого из предполагаемых получателей и имеет в качестве аргумента идентификатор открытого ключа, которым должен быть зашифрован документ.
При шифровании документа создаётся одноразовый случайный ключ для симметричного шифрования документа, а в зашифрованный документ добавляются несколько копий этого одноразового ключа, каждая из которых зашифрована публичным ключом одного из получателей.
Для расшифровки сообщения используется команда --decrypt. Зашифрованный документ может быть расшифрован только тем, чей секретный ключ соответствует одному из указанных открытых ключей. В частности, отправитель не можете расшифровать зашифрованный им документ, если он не включил свой открытый ключ в список получателей.
gpg --output message.txt --decrypt message.gpg
Для доступа к секретному ключу необходимо ввести пароль
You need a passphrase to unlock the secret key for
user: «Blake (dumb) <blake@anywhere.ru>"
1024-bit RSA key, ID 526C7F7F, created 2002–05–01 (main key ID 01A1FE63)
Enter passphrase:
Документы можно шифровать и без открытого ключа. Вместо этого используется симметричный алгоритм для шифрования документа. Ключ, используемый при шифровании, образуется из ключевой фразы. Для большей безопасности эта ключевая фраза не должна совпадать с той, которая используется для защиты секретного ключа. Симметричный шифр применим, когда есть возможность обменяться ключевой фразой. Для использования симметричного шифра применяется команда --symmetric.
gpg --output message.gpg --symmetric message.txt
Enter passphrase:
Цифровая подпись удостоверяет создателя и дату создания документа. Если документ будет каким-либо образом изменен, то проверка цифровой подписи будет неудачной. При подписи документа используется закрытый ключ подписывающего, а проверяется подпись с использованием его открытого ключа.
Для подписи документов используется команда --sign.
gpg --output file.sig --sign file.bin
You need a passphrase to unlock the secret key for
user: «Alice (test key) <alice@wonderland.uk>"
1024-bit RSA key, ID B115BDB6, created 2002–05–01
Enter passphrase:
Перед подписью документ сжимается. Подписанный документ выводится в двоичном формате.
У подписанный документ можно либо просто проверить подпись, либо проверить подпись и восстановить исходный документ. Для проверки подписи используется команда --verify. Для проверки подписи и извлечения документа используется команда --decrypt.
gpg --output file.bin --decrypt file.sig
gpg: Signature made Sat May 4 19:04:21 2002 MSD using RSA key ID B115BDB6
gpg: Good signature from «Alice (test key) <alice@wonderland.uk>"
Обычно цифровые подписи применяются для отправки электронной почты. При этом нежелательно сжимать подписываемые документы. Команда --clearsign добавляет к документу цифровую подпись в формате ASCII, не изменяя при этом сам документ.
gpg --output doc.asc --clearsign doc.txt
Можно получить подпись, хранящуюся отдельно от документа
gpg --output doc.sig --detach-sign doc.txt
Для проверки подписи необходимы и подпись, и сам документ. Для проверки используется команда --verify.
gpg --verify doc.sig doc.txt
gpg: Signature made Sat May 4 19:34:08 2002 MSD using RSA key ID B115BDB6
gpg: Good signature from «Alice (test key) <alice@wonderland.uk>"
В криптографии существует несколько моделей доверительных отношений:
В модели непосредственного доверия мы самостоятельно проверяем ключи партнёра не полагаясь ни на кого больше. Такая модель доверия используется в SSH, где публичные ключи сервера и клиента представляет из себя набор параметров шифрования и не содержит никакой удостоверяющей информации. Проверка ключа производится самостоятельно путём сличения его цифрового отпечатка с имеющимся в наличии (закэшированном в предыдущем сеансе или размещённого в специальном файле).
В модели иерархического доверия существуют некие изначально доверенные корневые сертификаты, принадлежащие уважаемому центру аутентификации (Central authority, CA). Данный центр подписывает сертификаты доверенных удостоверяющих центров, которые, в свою очередь, подписывают сертификаты серверов и пользователей. Каждый сертификат хранит цепочку подписей, ведущую к корневым сертификатам и позволяет, таким образом, отследить на персональную ответственность за выдачу сертификата. Корневые сертификаты распространяются некоторым надёжным способом, например, как часть дистрибутива ОС или браузера. Эта модель используется в SSL.
Модель сети доверия объединяет обе предыдущие модели. В сети доверия каждый самостоятельно проверяет достоверность чужих сертификатов, но, после проверки, может выступить в качестве удостоверяющего центра для других участников сети. В отличие от централизованной модели здесь никогда не может быть стопроцентной уверенности в подлинности сертификата, но наличие многих участников, независимо подтверждающих достоверность какого-либо сертификата, оказывается вполне достаточным для большинства практических задач.
Для того, чтобы избежать MitM атаки (Man in the middle - расшифровка сообщений в канале передачи) необходимо, удостовериться в том, что публичный ключ партнёра не был подменён. Для достижения этой цели в сертификате ключа OpenPGP хранятся подписи от других участников сети доверия, подтверждающие достоверность хозяина ключа. Хочу обратить внимание, что подписывается не сам ключ, а идентификатор пользователя, привязанный к данному ключу. Так, вы можете быть уверены, что человек действительно использует один из e-mailов, привязанных к ключу, и ничего не знать про другие его e-mailы.
Уровень достоверности того, что сертификат ключа действительно выпущен своим хозяином, высчитывается по количеству подписей и уровня доверия к этим подписям. Получив от нового партнёра по переписке публичный ключ, подписанный людьми, чьи ключи помечены как доверенные, мы повышаем свою уверенность в достоверности полученного ключа.
В оригинальном PGP существовало три степени доверия к подписывающим ключ и три уровня достоверности сертификата.
Уровни доверия:
Уровни достоверности:
В версии GnuPG 2.x появился уровень "Абсолютное доверие" для своих собственных сертификатов.
Чтобы сертификат считался подлинным требуется собственноручная подпись сертификата, или хотя бы одна подпись от полностью доверенного владельца ключа, или две подписи от частично доверенных владельцев ключей.
На самом нижнем уровне этой сети находится личный ключ и личная связка сертификатов. Личный ключ считается абсолютно достоверным а его хозяин (я) абсолютно доверенным. Добавляя чей-либо публичный ключ в связку можно подписать сертификат ключа своим личным ключом, что даст ему статус подлинного сертификата. При этом уровень доверия к владельцу можно установить по своему желанию.
Возможно, что вам не известен уровень доверия к ключам, использованным для подписи ключа партнёра. Тогда вам придётся искать цепочку ключей от известных доверенных ключей к проверяемому. Кроме того, существует некоторая вероятность, что подписавшие ключ люди сговорились (принадлежат к одной тайной организации) и совместно выпустили фальшивый ключ. Поэтому, чем больше людей в мире участвует в подписании ключей, тем проще найти подтверждающую цепочку и тем меньше вероятность сговора. Процедура взаимного подписания ключей при личных контактах, или подписания при абсолютной уверенности в достоверности ключей (например путём сличения цифровых отпечатков по телефону) и создаёт сеть доверия пользователей OpenPGP.
Пример локальной сети доверия можно посмотреть на странице ключей команды разработчиков Arch Linux.
Редактирование уровня доверия к хозяину ключа:
$> gpg --edit-key DA3CE9CE6DF2C45843AB2392D5560606D3C9EE9B
...
gpg> trust
sec rsa2048/D5560606D3C9EE9B
создан: 2020-04-17 годен до: 2022-04-17 назначение: SC
доверие: абсолютное достоверность: абсолютное
ssb rsa2048/C6FF5CA708A972CD
создан: 2020-04-17 годен до: 2022-04-17 назначение: E
[ абсолютно ] (1). Jon Dow <user@example.com>
Укажите, насколько Вы доверяете данному пользователю в вопросах проверки
достоверности ключей других пользователей (проверяет паспорт,
сверяет отпечатки ключей из разных источников и т.п.)
1 = Не знаю или не буду отвечать
2 = НЕ доверяю
3 = Доверяю ограниченно
4 = Полностью доверяю
5 = Абсолютно доверяю
Выдержка из GnuPG FAQ Ru
gpg --edit-key [ID его сертификата] sign
gpg --armor --output signed_cert.asc --export [ID его сертификата]
Следуя этой процедуре, вы сначала убеждаетесь, что говорите с нужным человеком. Сравнивая отпечаток сертификата с тем, который вам сообщили, вы убеждаетесь, что получили нужный сертификат. Еще одна проверка делается, чтобы убедиться, что данный вам адрес перечислен в сертификате. Как только это сделано, вы получаете уверенность, что связали сертификат с реальным человеком. Что и подтверждаете всему миру, подписав сертификат и вернув свежеподписанный сертификат владельцу.
Термин "сертификат" в OpenPGP чаще всего используется в словосочетании "сертификат отзыва", а для структуры данных, связанной с ключом используется просто слово "ключ". На этой странице термин "сертификат" используется, для того, чтобы отличать ключи, как параметры алгоритма шифрования, от ключей, как структур данных.
Структура данных сертификата ключа в OpenPGP позволяет хранить в нём различные дополнительные поля. Подключи - это ключи, которые хранятся в сертификате другого ключа, который называют первичным или мастер-ключом.
Подключи помечаются флагами, которые определяют функциональное назначение подключа. Флаги имеют внутреннее числовое представление, а в информационных утилитах GnuPG помечаются буквами.
0x01 “C” Key Certification
0x02 “S” Sign Data
0x04 “E” Encrypt Communications
0x08 “E” Encrypt Storage
0x20 “A” Authentication
Мастер-ключ автоматически помечается флагами ключа подписи и ключа выпуска сертификатов (CS), поскольку он используется для подписывания подключей и для создания сертификатов отзыва. Отличие ключа шифрования от ключа подписи в том, что ключ подписи действует в будущем. Если его украдут, то злоумышленники смогут в будущем подписывать документы от вашего имени. Поэтому ключ подписи должен иметь ограниченный срок действия и (в случае компрометации) должен быть отозван до окончания срока, чтобы предупредить его использование злоумышленниками. Ключ шифрования действует в прошлом. Его компрометация ведёт к тому, что злоумышленники смогут расшифровать переписку, которая велась с его использованием и никакие отзывы здесь не помогут.
В GnuPG версии 2.1 и старше команда --gen-key создаёт мастер-ключ с функцией подписи и дополнительный подключ с функцией шифрования.
При создании нового подключа задаётся вопрос о его назначении:
$> gpg --edit-key jd@example.com
...
gpg> addkey
Выберите тип ключа:
(3) DSA (только для подписи)
(4) RSA (только для подписи)
(5) Elgamal (только для шифрования)
(6) RSA (только для шифрования)
(14) Existing key from card
Ваш выбор?
Для создания ключа аутентификации необходимо запускать gpg с опцией --expert
Как и во всех системах с асимметричным шифрованием, каждый ключ в OpenPGP представлен парой из публичного и приватного ключа. Публичный используется для шифрования и проверки подписи, а приватный - для подписи и дешифровки.
Для идентификации ключей используется два типа идентификации:
Идентификатор пользователя имеет формат: "Полное имя <адрес e-mail>". Этот идентификатор связывает ключ с определенным человеком. Очевидно, что человек, создающий много ключей, скорее всего, будет использовать для них одинаковые UIDы. К одному ключу можно привязать несколько идентификаторов пользователя, например UIDы для различных почтовых ящиков. Поиск ключа можно вести по полному тексту UID, по e-mail, по полному имени или по его подстроке.
Отпечаток ключа - это хэш SHA-1 длиной 160 бит, вычисляемый на основе открытого ключа и метки времени создания ключа. Для ввода/вывода отпечатка в интерфейсе пользователя используется шестнадцатеричная запись. Длина отпечатка - 40 шестнадцатеричных цифр, которые для удобства разбивают на 10 групп по 4 цифры.
$> gpg --fingerprint -k
...
-----------------------
pub rsa2048 2020-04-17 [SC] [ годен до: 2022-04-17]
DA3C E9CE 6DF2 C458 43AB 2392 D556 0606 D3C9 EE9B
uid [ абсолютно ] John Dow <jd@example.com>
sub rsa2048 2020-04-17 [E] [ годен до: 2022-04-17]
В некоторых ситуациях (при использовании агента) используется ещё один идентификатор ключа - keygrip, который вычисляется как хэш публичного ключа без добавления времени создания.
$> gpg --with-keygrip -k
...
pub rsa2048 2020-04-17 [SC] [ годен до: 2022-04-17]
DA3CE9CE6DF2C45843AB2392D5560606D3C9EE9B
Keygrip = 5D3F2A0BA1DCC59210761397A5CEC5E3393FB111
uid [ абсолютно ] John Dow <jd@example.com>
sub rsa2048 2020-04-17 [E] [ годен до: 2022-04-17]
Keygrip = 0AF602B0376E373F4158E230D0E5E3E9F32F4619
Для экономии времени на ввод идентификатора (или его диктовку по телефону) могут использоваться младшие байты цифрового отпечатка. 16 последних шестнадцатеричных цифр отпечатка называются длинным идентификатором (long ID), а последние 8 символов - коротким идентификатором (short ID). Использование длинного и короткого идентификатора считается плохой практикой, поскольку для них легко сгенерировать коллизии - т.е. различные ключи с совпадающими укороченными ID (но с несовпадающими отпечатками).
В некоторых случаях в начале идентификатора нужно добавлять символы 0x, чтобы подчеркнуть, что это число в шестнадцатеричном виде.
Для того, чтобы не пересчитывать символы руками, команда просмотра публичных ключей --list-keys (-k) позволяет указать опцию --keyid-format, которая может принимать значения 0xLONG, LONG, 0xSHORT, SHORT.
$> gpg --keyid-format 0xSHORT --list-keys
/home/user/.gpg/pubring.kbx
-----------------------
pub rsa2048/0xD3C9EE9B 2020-04-17 [SC] [ годен до: 2022-04-17]
DA3CE9CE6DF2C45843AB2392D5560606D3C9EE9B
uid [ абсолютно ] John Dow <jd@example.com>
sub rsa2048/0x08A972CD 2020-04-17 [E] [ годен до: 2022-04-17]
Личный мастер-ключ должен храниться в очень безопасном месте, желательно на внешнем носителе в физически защищенном месте. Однако использовать такой ключ крайне неудобно: каждый раз, когда вам нужно что-то подписать придётся извлекать ключ из хранилища и использовать его на компьютере с надёжной антивирусной защитой, чтобы избежать перехвата расшифрованного ключа в процессе подписи.
Альтернативой является создание подключей для текущей работы. С помощью мастер-ключа подключам можно назначать небольшой срок жизни, чтобы уменьшить ущерб при их похищении. Так же с помощью мастер-ключа можно отзывать скомпрометированные ключи.
Мастер-ключ извлекается из хранилища и используется в следующих случаях:
Можно использовать различные стратегии устаревания:
Ошибка в GnuPG 2.x: Can’t connect to the agent: Invalid value passed to IPC возникает при выполнении команды:
gpg –-homedir . –-gen-key
Причина: Вся работа с секретными ключами идёт в GnuPG 2.x идёт через gpg-agent, который запускается в фоне при первой необходимости. В данном случае gpg-agent уже запущен и создал сокет в стандартном каталоге * ~/.gpg*
Исправление:
pkill -KILL gpg-agent
gpg-agent --homedir="$(pwd)" --daemon
gpg –-homedir --homedir="$(pwd)" –-gen-key
В 1988 году Международный союз электросвязи (International Telecommunication Union - ITU) опубликовал рекомендации по методам аутенификации в протоколе доступа к службе каталогов (Direcrotry access protocol - DAP). Все рекомендации союза по компьютерным сетям (реализация модели ISO/OSI) маркировались буквой "X" и номером. Серия посвященная службе каталогов получила номера с X.500 и далее. Система аутенификации на основе публичных ключей и сертификатов получила название X.509. В дальнейшем, часть рекомендаций X.500 была реализована в протоколе LDAP, а фреймворк предложенный в X.509 была использована в вебе для реализации протокола SSL и связанной с ним иерархией отношений доверия (RFC 5280).
В частности, X.509 ввёл понятия:
Для реализации стандарта X.509 и связанных с ним стандартов (алгоритмы шифрования, форматы хранения даннных и т.п.) была разработана библиотека OpenSSL, которая поставляется с утилитой командной строки openssl
, и позволяет выполнять все основные криптографические операции. Библиотека Openssl реализована для всех основных ОС, в том числе Linux, Windows, Mac OS, Android и т.д.
Для корректной работы многих сервисов в современном интернете требуется наличие сертификатов. В качестве примера можно привести HTTPS, SMTP поверх TLS, OpenVPN. В зависимости от сферы применения к сертификатам предъявляются разные требования:
Веб сервер с поддержкой SSL (HTTPS). Необходим серверный сертификат подписанный официальным удостоверяющим центром, сертификат которого есть в поставке популярных браузеров.
Почтовый сервер с поддержкой SSL (SMTP поверх TLS, POP3S, IMAPS). Для SMTP обычно достаточно самоподписанного серверного сертификата. Для POP3S, IMAPS желательно иметь официальный сертификат, поскольку почтовые клиенты (например Thunderbird) выдают предупреждения о неизвестных или некорректных сертификатах.
С OpenVPN поставляется собственный удостоверяющий центр, который позволяет создавать сертификаты сервера и клиента. Сертификат этого центра генерируется локально и добавляется в файл конфигурации клиента и сервера.
Проект LetsEncrypt направлен на массовое внедрение HTTPS в интернете. Он предоставляет бесплатный удостоверяющий центр и наборы скриптов (для разных ОС разные), которые автоматически генерируют пару ключей, создают запрос на выпуск сертификата, отправляют его в удостоверяющий центр LetsEncrypt, а затем автоматически добавляют полученный сертификат в настройки популярных веб-серверов (Apache,Nginx, IIS).
Для почтового сервера достаточно прописать путь к файлу сертификата LetsEncrypt и использовать его совместно с веб-сервером.
Вместе с OpenVPN поставляется набор скриптов easyrsa
(есть под Linux и Windows), которые вызывают openssl для выполнения основных манипуляций с сертификатами. В набор скриптов входят:
Версии с добавлением -pass потребуют ввода пароля для шифрования приватного ключа.
В файле openssl.cnf
хранятся различные параметры openssl. Многие из них ссылаются переменные окружения, поэтому реальные настройки находятся в файле vars.sh
(vars.bat
).
vars.sh (фрагмент)
export KEY_SIZE=1024
export CA_EXPIRE=3650
export KEY_EXPIRE=3650
# Атрибуты сертификата
# могут быть изменены в диалоговом режиме
# при создании сертификата
export KEY_COUNTRY="RU"
export KEY_PROVINCE="EKB"
export KEY_CITY="Ekaterinburg"
export KEY_ORG="IMM"
export KEY_EMAIL=""
Внутри скриптов EasyRSA находятся вызовы openssl. Следует помнить, что часть параметров, такие как тип и размер ключа, ключ CA и т.п. находятся в файлt openssl.cnf.
Создание ключа CA без сертификата
#запрос на сертификат сроком на 10 лет
openssl req -days 3650 -nodes -new -x509 -keyout ca.key -out ca.csr -config openssl.cnf
Создание пары ключ-сертификат клиента
#запрос на сертификат сроком на 10 лет
openssl req -days 3650 -nodes -new -keyout client.key -out client.csr -config openssl.cnf
#подпись сертификата ключом CA
openssl ca -days 3650 -out client.crt -in client.csr -config openssl.cnf
то же для сервера
#запрос на сертификат сроком на 10 лет
openssl req -days 3650 -nodes -new -keyout srv.key -out srv.csr -config openssl.cnf
#подпись сертификата ключом CA
openssl ca -days 3650 -extensions server -in srv.csr -out srv.crt -config openssl.cnf
Экспорт в формат PKCS#12
#запрос на сертификат сроком на 10 лет
openssl req -days 3650 -nodes -new -keyout client.key -out client.csr -config openssl.cnf
#подпись сертификата ключом CA
openssl ca -days 3650 -in client.csr -out client.crt -config openssl.cnf
# конвертация пары ключ/сертификат в файл pkcs#12.
openssl pkcs12 -export -inkeyclient.key -in client.crt -certfile ca.crt -out client.p12
Стандарт X.509 предполагает, что все структуры данных, связанные с сертификатами описываются в формате ASN.1. ASN.1 - это архитектурно-независимое представление данных, пригодное для хранения произвольных иерархических структур. На практике, структура ASN.1 кодируется в двоичное представление DER (Distinguished Encoding Rules), описанное в X.690.
Все объектов в ASN.1 имеют уникальные идентификаторы OID (Object Identifier), для которых определены базовые типы данных (числа, строки, коллекции и т.п). OID - это последовательность положительных целых чисел, однозначно идентифицирующая объект. В текстовой записи OID выглядит как десятичные числа, разделяемые точкой - 1.2.345.6.79. Структура OID описывает дерево, корень которого расположен в начале записи. При записи в человекочитаемой форме корневой OID заменяют на некую мнемоническую строку, которую продолжают числовой последовательностью. Например корневой OID ветки, описывающей объекты алгоритма RSA, выглядит так: 1.2.840.113549.1. На специализированном сайте можно выяснить, что это: {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)}. Российский сегмент OID {iso(1) member-body(2) ru(643)} по соглашению с Росстандартом обслуживает ОАО "Инфотекс Интернет Траст". Объекты, связанные с российской криптографией, находятся в ветке 1.2.643.100 и описаны в Приказе ФСБ РФ от 27 декабря 2011 г. N 795 "Об утверждении Требований к форме квалифицированного сертификата ключа проверки электронной подписи".
Для обеспечения уникальности, те или иные OIDы регистрируются некими официальными организациями при координации ISO и ITU. К таким регистрирующим организациям относится IANA, которая выделяет OIDы, необходимые для протоколов сети Интернет (например, LDAP и SNMP). Частная организация может получить стартовый OID, и строить от него поддерево для внутреннего использования. В России регистрацией частных OID занимается ОАО "Инфотекс Интернет Траст".
Просмотр ASN.1 структуры ключа:
openssl asn1parse -in x509-key.pem
Кроме того, серия документов Public-Key Cryptography Standards (PKCS), созданная корпорацией RSA, описывает различные типы сертификатов X.509. Документы имеют порядковую нумерацию, записанную через #.
Основной формат хранения сертификатов X.509 - DER, однако для удобства пересылки по электронной почте его часто дополнительно кодируют в формат PEM (Privacy Enhanced Mail RFC 1421). PEM сам по себе довольно большой стандарт, но из взято только кодирование по алгоритму Base64 и обрамление полученного текста границами:
-----BEGIN label -----
-----END label -----
Для секретных ключей RSA (PKCS#1) используется традиционная форма label, похоже, не описанная в стандартах - RSA PRIVATE KEY.
RFC 7468 описывает форматы label для разных типов ключей и сертификатов
За пределами границ BEGIN и END в файл с сертификатом может быть добавлена человекочитаемая версия данных.
Вывод в человекочитаемом формате. noout - отключение вывода в формате PEM:
openssl x509 -in certificate.cer -noout -text
Конвертация PEM -> DER и наоборот:
openssl x509 -inform pem -in certificate.pem -outform der -out certificate.cer
openssl x509 -inform der -in certificate.cer -outform pem -out certificate.pem
Создание файла PFX:
openssl pkcs12 -export -out certificate.pfx -inkey private.key -in certificate.crt -certfile CA.crt
Извлечение приватного ключа RSA из PKCS#8:
openssl pkcs8 -nocrypt -in pkcs8.pem -out pkcs1.pem
CA Bundle - связка CA - это не особый формат, а просто набор открытых ключей (сертификатов) доверенных центров сертификации в формате PEM, склеенных в один текстовый файл. Формат придуман фирмой Netscape. В Linux CentOS 7 файл /etc/pki/tls/certs/ca-bundle.crt
ставится с пакетом ca-certificates-2018.2.22-70
. Создать CA Bundle из отдельных файлов можно стандартными средствами ОС:
cat *.pem > ca_bundle.crt
Статья про кроссплатформенное средство просмотра сертификатов
Краткая сводка полезных команд (исключая работу с сертификатами)
Генерация случайных данных/паролей
#сгенерировать 12 байт/16 символов в base64
openssl rand -base64 12
Хэш пароля. Первый вариант - классический DES из passwd, второй - MD5 из shadow. Если salt опустить, то будет сгенерирована случайная строка.
openssl passwd -salt 8E MySecret
openssl passwd -1 -salt sXiKzkus MySecret
Криптографический дайджест файла. В Linux можно использовать эквивалентные команды md5sum, sha1sum.
openssl dgst -md5 filename
openssl dgst -sha1 filename
(Де)Кодирование в BASE64
openssl enc -base64 < file.txt
openssl enc -base64 -in file.txt
openssl enc -base64 -in file.txt -out file.txt.enc
#Декодирование
openssl enc -base64 -d < file.txt.enc
Шифрование симметричными шифрами. Пароль можно вводить интерактивно, читать из файла или указывать в командной строке
#список алгоритмов
openssl list-cipher-commands
#шифрование
openssl enc -des -in file.txt -out file.enc
openssl enc -des -in file.txt -out file.enc -pass pass:mySillyPassword
openssl enc -des -in file.txt -out file.enc -pass file:/path/to/secret/password.txt
#шифрование + кодирование в base64
openssl enc -des -a -in file.txt -out file.asc
#дешифрование
openssl enc -d -des -a -in file.asc -out file.txt
SSL/TLS клиент. На STDERR выводится информация о сертификате. После подключения можно вручную вводить команды соответствующего протокола. TLS доступен только для определённых протоколов.
openssl s_client -connect remote.host:443
openssl s_client -connect remote.host:25 -starttls smtp
Сохранение сертификата в файл penssl s_client -connect remote.host:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p'
Веб сервер с корнем в текущем каталоге. По умолчанию слушает порт 4433.
openssl s_server -accept 443 -cert mycert.pem -WWW
И SSH и OpenPGP используют(могут использовать) алгоритм RSA для аутенификации/шифрования. Соответственно, пары открытый/секретный ключ могут использоваться совместно в двух программах, поскольку это просто числа, соответствующие некой формуле. Основное отличие между ключами в OpenPGP и SSH - это инфраструктура и формат хранения.
Не совсем понятно, зачем это надо, поскольку публичные ключи SSH (обычно) распространяются без какой либо верификации, а сами ключи (обычно) не содержат никакой информации о владельце. Соответственно, цифровая подпись, сделанная ключом SSH, не может считаться хоть сколько-нибудь значимой, поскольку невозможно удостовериться в принадлежности открытого ключа автору подписи.
Для конвертации потребуются скрипты от monkeysphere. Процедура импорта описана ЗДЕСЬ.
В gpg-agent встроена поддержка протокола ssh-agent. Соответственно, можно сгенерировать ключи средствами GPG и поместить их в gpg-agent, затем импортировать публичный ключ стандартным образом через ssh-add -L
.
Процедура генерации ключа описана ЗДЕСЬ Примерно то же самое + использование ybkey- ССЫЛКА.
GPG4Win совместим с pagent. ИНСТРУКЦИИ.
Некоторые шифры, используемые в TLS/SSL, со временем признаются ненадёжными и отключаются в стандартной конфигурации OpenSSL. В результате возникают проблемы при взаимодействии со старыми серверами/клиентами. В частности OpenLDAP-клиент в CentOS 8 и старше не может получить доступ по SSL к серверам АД Windows 2012 R2 и младше.
Чтобы включить поддержку старых алгоритмов шифрования в OpenSSL (а также в GnuTLS, OpenSSH, BIND, Jav JDK и т.д.) надо выполнить команду
update-crypto-policies --set LEGACY
update-crypto-policies
— это python-скрипт, который редактирует конфигурационные файлы следующих программ и библиотек:
update-crypto-policies
доступен в CentOS и в Ubuntu.
Генерация ключей SSH и сохранение их в пару файлов (mykey,mykey.pub)
ssh-keygen -t rsa -b 4096 -f mykey
Приватные ключи по умолчанию сохраняются в формате PEM PKCS#1. Ключи, созданные в "новом" формате OpenSSH (опция -o
) не совместимы с другими криптографическими системами.
Формат PEM можно отличить по строкам
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
в файле приватного ключа. В новом формате они заменены на строки
-----BEGIN OPENSSH PRIVATE KEY-----
-----END OPENSSH PRIVATE KEY-----
Публичный ключ так же нужно сконвертировать в формат PEM PKCS#8 (Можно это будет сделать на лету в момент шифрования):
ssh-keygen -f mykey.pub -e -m pkcs8 > mykey.pkcs8.pub
#или
openssl rsa -in mykey -pubout -outform PKCS8 > mykey.pkcs8.pub
Обмениваемся публичными ключами с партнёрами. Чтобы это подчеркнуть, при шифровании я буду использовать чужой публичный ключ anotherkey.pub
.
Генерируем одноразовый сеансовый ключ (32 байта):
openssl rand -base64 32 -out key.bin
Шифруем передаваемые данные симметричным ключом:
openssl enc -aes-256-cbc -salt -in bigdata.dat -out bigdata.dat.enc -pass file:./key.bin
Шифруем сеансовый ключ публичным ключом в формате PKCS#8:
openssl rsautl -encrypt -pubin -inkey anotherkey.pkcs8.pub -in key.bin -out key.bin.enc
# возможна конвертация на лету
openssl rsautl -encrypt -pubin -inkey <(ssh-keygen -e -m PKCS8 -f anotherkey.pub) -in key.bin -out key.bin.enc
Удаляем одноразовый ключ:
rm key.bin
По открытому каналу пересылаем bigdata.dat.enc
и key.bin.enc
.
Расшифровываем секретным ключом сеансовый ключ. В реальной жизни вместо специально сгенерированного ключа mykey
надо будет использовать стандартный ключ ~/.ssh/id_rsa
:
openssl rsautl -decrypt -inkey mykey -in key.bin.enc -out key.bin
Расшифровываем данные:
openssl enc -d -aes-256-cbc -in bigdata.dat.enc -out bigdata.dat -pass file:./key.bin
Для передачи файлов в несколько байт или килобайт можно сразу зашифровать их асимметричным алгоритмом.
# Encrypt openssl rsautl -encrypt -inkey <(ssh-keygen -e -m PKCS8 -f ~/.ssh/id_rsa.pub) -pubin -in small.dat -out small.dat.enc # Decrypt openssl rsautl -decrypt -inkey ~/.ssh/id_rsa -in small.dat.enc -out small.dat
В повседневной деятельности пользователя можно выделить два вида деятельности - запуск программ (возможно с перенаправлением ввода вывода) и операции с файлами. На настоящий момент самым популярным протоколом запуска программ является протокол ssh, а для передачи файлов используются построенные на его основе команды scp и sftp.
Протокол ssh использует шифрование трафика, что обеспечивает защиту от перехвата паролей и передаваемых данных.
В состав комплекса входят клиентские программы ssh
- аналог telnet
и rsh
, scp
- аналог rcp
и sftp
- программа внешне похожая на ftp
по защищенному каналу. Несмотря на похожесть этих программ на своих предшественников, они используют другие протоколы, разработанные заново для исправления архитектурных ошибок, выявленных в их предшественниках.
Cервер OpenSSH в большинстве дистрибутивов устанавливается по умолчанию. Необходимо только подогнать настройки под свои нужды.
Конфигурационные файлы хранятся в каталоге /etc/ssh
Пользователи могут изменить личные настройки в файле $HOME/.ssh/config или задать их в командной строке.
В сети постоянно работают хакерские программы пытающиеся подобрать пароли к ssh грубой силой. В первую очередь проверяется пользователь root. По этому, первый шаг в укреплении безопасности – запрет root'у подключаться по ssh. Все администраторские действия лучше всего проводить с использованием программы Sudo. Кроме того, проверяются стандартные имена служб и типичные имена пользователей, например andrew, alex, mary и т.п. Лучший способ избавиться от проблем с подбором пароля – перейти на аутенификацию с публичным ключом. После генерации пары секретный ключ, публичный ключ, публичный ключ добавляется в список доверенных в файле пользователя ~/.ssh/authorized_keys. Права на файл authorized_keys желательно выставить в rw-------.
Серверные настройки – sshd_config
#Запрет на вход с именем root
PermitRootLogin no
#Разрешение на вход только по ключам
RSAAuthentication yes
PubkeyAuthentication yes
PasswordAuthentication no
Для безопасного удаленного доступа к локальным сетевым службам и запуска программ с графическим интерфейсом добавляем
AllowTcpForwarding yes
X11Forwarding yes
Внимание: для работы X11Forwarding в CentOS необходимо установить пакет xorg-x11-xauth
"telnet" - протокол удалённого терминала предназначенный для удалённого подключения к ОС имеющих текстовый интерфейс.
"ftp" - по сути дела сеанс telnet
в рамках которого на сервере запускается специализированная диалоговая программа для работы с файлами. Для передачи содержимого каталогов и файлов устанавливается дополнительное соединение, по которому и передаётся содержимое файла.
Для того, чтобы проверить достоверность ключа сервера пользователь может связаться с администратором сервера по доверенному каналу и запросить хэш ключа.
Команда вычисления хэша:ssh-keygen -l -f имя_файла
Можно передавать как имя файла секретного ключа, так и имя файла публичного ключа. В любом случае будет выдан хэш от публичного ключа. Например: ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key
. Если в файле много ключей (например в ~/.ssh/authorized_keys
), то ssh-keygen
посчитает все хэши.
В зависимости от версии OpenSSH хэш может считаться по алгоритму MD5 и выдаваться в восьмеричной записи (старые версии), либо считаться по алгоритму SHA256 и выдаваться в кодировке BASE64 (новые версии). Для того, чтобы новая версия ssh-keygen
выдала хэш в старом формате необходимо добавить опцию -E md5
. Дополнительная опция -v
генерирует представление хэша в ASCII-арт.
Примеры:
#Старая версия
ssh-keygen -l -f ~/.ssh/id_rsa
2048 19:c3:6f:d8:48:88:5d:97:44:56:3e:75:5e:e0:f5:fa /home/user/.ssh/id_rsa.pub (RSA)
#Новая версия
ssh-keygen -l -f ~/.ssh/id_rsa
3072 SHA256:6jpGLR7o7uutwXjYzIJE/6eQK9rMbwmjSU+BPEMBlnk user@example.com (RSA)
ssh-keygen -l -E md5 -v-f ~/.ssh/id_rsa
3072 MD5:00:a6:22:39:bb:20:77:de:03:2a:fd:ad:79:f0:53:7f user@example.com (RSA)
+---[RSA 3072]----+
| o |
| . o . |
|= . . |
|.+ . |
|+ . o S |
|o+ +.o . |
|o o .oo. . |
| . . o+. . E |
| +o.. . |
+------[MD5]------+
Протокол SSH позволяет прокладывать TCP туннели внутри защищенного соединения. Фактически это означает, что клиент и сервер SSH создают по дополнительному сокету. Один из них принимает входящие соединения, а второй соединяется с кем-то в своей сети или в интернете. Данные из одного сокета пробрасываются в другой. В зависимости от распределения ролей сокетов туннели делятся на локальные (local) и удалённые (remote) . Первые принимают входящие соединения на локальном порту и пробрасывают их на удаленный сервер, вторые принимают соединения на удаленном сервере и пробрасывают их в локальную сеть.
++++++++ ++++++++
|Клиент| SSH |Сервер| Кто то в сети
Я --->|порт |-----| |----> сервера или в интернете
|5678 | | | с портом 80
++++++++ ++++++++
++++++++ ++++++++
Мой комп |Клиент| SSH |Сервер| Кто то из сети
порт <---| |-----|порт |<--- сервера или из интернета
3389 | | |5678 | подключается ко мне
++++++++ ++++++++
В Unix проброс локального порта 5678 на remoteserv.com:80 через ssh_host.com выглядит так:
ssh -L localhost:5678:remoteserv.com:80 ssh_host.com
После создания канала можно подключаться браузером на http://loclahost:5678. localhost: в опции -L можно опустить. Это значение по умолчанию. Если надо подключиться на порт 80 самого ssh_host.com то можно задать опцию так:
ssh -L 5678:localhost:80 ssh_host.com
Проброс удаленного порта сервера для доступа на свой компьютер удаленным рабочим столом:
ssh -R *:5678:localhost:3389 ssh_host.com
* означает, что на сервере будут задействованы все доступные сетевые интерфейсы. Если этот параметр не указать, то порт 5678 откроется на сервере ssh_host.com только по адресу 127.0.0.1
В командах выше кроме проброса портов на удалённой машине запускается shell и устанавливается терминальное соединение. Если терминал не нужен, то можно запустить ssh
с опцией -N. В этом случае никакая команда на удаленном сервере не запустится, и, что интересно, команды w
, last
и т.п. не будут показывать ваш вход на сервер. Впрочем, информация об авторизации в системе останется в логах категории authpriv.
Опция -A находит на локальной машине порт ssh-agent
пробрасывает его на удаленную машину на случайный порт или Unix-сокет и устанавливает в сеансе ssh переменную SSH_AUTH_SOCK для дальнейшей авторизации через агента.
Опция -X находит на локальной машине порт XWindow и пробрасывает его на первый свободный порт начиная от порта 6000 (базовый порт XWindow). Переменная DISPLAY в сеансе ssh устанавливается в :<номер порта - 6000>. Так, если номер порта на сервере 6007 то DISPLAY=":7".
Опция -D addr:port превращает ваш компьютер в SOCKS прокси с выходом в интернет на стороне сервера. Как и раньше, если вы укажете только порт, то вместо адреса подставится 127.0.0.1 и ваш прокси будет доступен только на локальном компьютере. Если вместо адреса подставить *, то вашим SOCKS прокси смогут воспользоваться все компьютеры, имеющие к вам доступ по сети.
Настройка туннелей в putty
находится в настройках соединения в пункте Connection -> SSH -> Tunnels. Локальный/удаленный туннель может выбираться автоматически на основе введённых данных. В нашем примере локальному туннелю соответствуют поля: Source port - 5678; Destination - remoteserv.com:80
Не забудьте после ввода данных нажать кнопку "Add".
Если вам не нужен терминал, зато нужно формировать туннель из .bat файла - воспользуйтесь программой plink
. Её параметры совпадают с параметрами ssh
.
Классическая модель доступа к драйверам
В файловой системе Unix существуют специальные объекты - файлы устройств. Как правило, они создаются в каталоге /dev, но могут сбыть созданы и в любом другом каталоге. Каждый специальный файл - это точка доступа к драйверу устройства. Если драйвер предоставляет операции чтения/записи, то файл устройства может быть открыт как обычный файл cat /dev/modem > /dev/null. Для выполнения других операций с устройством (например выдвижение лотка CDROM) требуется отправка команд драйверу через системный вызов ioctl(). Файлам устройств права доступа назначаются так же , как и обычным файлам.
ВНИМАНИЕ: сетевые карты не отображаются в файлы устройств в /dev. Все сетевые интерфейсы живут в своём пространстве имён.
Команда создания специального файла:
mknod <name> <type> <major> <minor>
Имя устройства не имеет значения для функционирования ОС и выбирается по некоторым мнемоническим правилам. Например, SCSI диск может иметь следующие имена:
Функциональность файла устройства определяется парой чисел major/minor, которые должны соответствовать номерам в некой таблице регистрации драйверов в ядре ОС. Назначение minor, обычно, определяется логикой работы драйвера. Для согласованного назначения номера major драйверам и специальным файлам существует несколько способов :
Традиционно свойства процессов и некоторые параметры ядра отображаются в Linux в каталог /proc через драйвер псевдофайловой системы procfs. Начиная с ядра 2.6 параметры ядра, связанные с драйверами устройств и файловых системам, были вынесены в каталог /sys и псевдофайловую систему sysfs.
/proc
Через файл /proc/cpuinfo можно получить информацию о физических процессорах, физических ядрах и гипертрединговых логических ядрах.
$ cat /proc/cpuinfo
...
model name : Intel(R) Xeon(R) CPU E5520 @ 2.27GHz
....
cpu MHz : 1733.000
...
Через файл /proc/net/dev можно получить список сетевых интерфейсов и статистику по ним
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
eth0: 1767479002126 7440045654 0 209199 176227535 ...
lo: 809098010894 313483867 0 0 0 0 ...
/sys
Каталог содержит информацию об инициализированных устройствах, сгруппированную по разным критериям: типам устройств, шинам, диагностическим протоколам доступа и т.п. Одни и те же устройства могут быть показаны в разных каталогах через символические ссылки.
Заряд батареи
cat /sys/class/power_supply/BAT0/charge_full
cat /sys/class/power_supply/BAT0/charge_full_design
cat /sys/class/power_supply/BAT0/charge_now
Альтернативный путь к тем же данным
/proc/acpi/battery/BAT0/*
Утилиты acpi, acpitool отсутствуют в большинстве современных дистрибутивов.
БД MySql поставляется в CentOS в виде rpm пакетов с серверной и клиентской частью, а также вспомогательных пакетов, таких как интерфейс с perl. Начиная с CentOS 7 mysql заменен на mariadb.
yum install mariadb
yum install mariadb-server
yum install mariadb-client
После установки надо установить пароль администратора
systemctl start mariadb
mysqladmin password < secret_file
Если вы забыли пароль администратора, то надо остановить My SQL и временно запустить со сброшенным контролем доступа
systemctl stop mariadb
/usr/libexec/mysqld --skip-grant-tables &
#...Меняем пароль, рестартуем обычным образом
mysql -u root mysql
>update user set Password=password('newpassword') WHERE User='root';
>flush privileges;
>exit
killall -TERM mysqld
Создание новой БД и установка прав доступа для локального пользователя user1
mysqladmin -u root -p create mydb
echo 'GRANT ALL ON mydb.* to user1@localhost IDENTIFIED BY "mypassword";' | mysql -u root -p
Сохранение (требует ввода пароля)
#вариант 1
mysqldump -u user1 -p mydb > mydb.sql
#альтернативный вариант, для автоматического удаления существующих таблиц при восстановлении
mysqldump -u user1 -p --add-drop-table mydb > mydb.sql
Восстановление
#Уничтожаем старые таблицы если сохраняли по 1му варианту
mysqldump -uuser1 -pmypassword --add-drop-table --no-data mydb | grep ^DROP | mysql -uuser1 -pmypassword mydb
#Восстанавливаем из копии
mysql -u user1 -p mydb < mydb.sql
Настройки кодировки
[mysqld]
;Для клиентов которые не указывают кодировку при установке соединения
init-connect="SET NAMES UTF8"
;Кодировка на сервере по умолчанию
character_set_server=UTF8
"I18N" означает Internationalisation т.е. начинается на “I” кончается на “N”, а в середине еще 18 букв.
По умолчанию в CentOS есть файлы локализации для русского языка в кодировке “UTF8”, если нам нужна другая кодировка надо создать нужные файлы из заготовок
localedef -f CP1251 -i /usr/share/i18n/locales/ru_RU /usr/lib/locale/ru_RU.CP1251
-f CP1251 ссылка на файл соответствия кодировки и UNICODE (по умолчанию файл ищется в /usr/share/i18n/charmaps/ и сжат gzip'ом)
-i /usr/share/i18n/locales/ru_RU каталог в котором лежат описания национальных констант
/usr/lib/locale/ru_RU.CP1251 каталог в который надо положить результат (библиотека libc ищет файлы кодировок именно здесь)
осталось объявить переменную LANG
export LANG=ru_RU.CP1251
Правильные программы должны корректно сортировать русские буквы, выдавать дату в русском формате и т.д.
Наша задача – перейти с sendmail и почтовых ящиков в формате mailbox на связку postfix+cyrus-imapd, с хранением паролей пользователей в базе MySQL и организацией виртуальных почтовых доменов.
Для удобства доступа и администрирования будем использовать web-cyradm для администрирования почтовых ящиков и squirrelmail в качестве веб-интерфейса для почты.
Cyrus IMAPD – сервер, обеспечивающий доступ к почте по протоколам IMAP и POP3.
Почта не привязана к локальным пользователям системы. Почтовые ящики хранятся в своем формате в отдельном каталоге, пароли могут проверяться различными способами, которые доступны через библиотеку SASL. Можно хранить пароли в базе My SQL, в sasldb или проверять через любые PAM модули. В состав Cyrus IMAPD входят программа для локальной доставки почты.
Внимание Необходимо сменить владельца /etc/imapd.conf на cyrus и отобрать у «прочих» права на чтение
chown cyrus /etc/imapd.conf
chmod o-r /etc/imapd.conf
/etc/imapd.conf
================
configdirectory: /var/lib/imap
#Где хранятся почтовые ящики
partition-default: /var/spool/imap
#Список администраторов, которые могут управлять почтовыми ящиками.
admins: cyradm
allowplaintext: 1
sievedir: /var/lib/imap/sieve
sendmail: /usr/sbin/sendmail
#Не трогаем 8ой бит.
munge8bit: 0
#Все ящики в нижнем регистре. При подключении клиентов регистр преобразуется.
username_tolower: 1
#Дает возможность использовать имена с точками. Если стоит "0", то точка используется как разделитель в системе почтовых каталогов.
unixhierarchysep: 1
#Для повышения производительности каталог с почтовыми ящиками разбивается на подкаталоги по алфавиту
# /var/spool/imap/a/, /var/spool/imap/b/ и т.д.
hashimapspool: true
#Проверка пойдет через PAM
sasl_pwcheck_method: saslauthd
# PLAIN - способ получения пароля от клиента, только PLAIN подойдет для проверки в файлах (базе) с паролями.
sasl_mech_list: PLAIN
#Список виртуальных доменов, для которые мы держим почтовые ящики
loginrealms: mydomain1.my mydomain2.my
#Сертификаты для шифрованного соединения
tls_cert_file: /usr/share/ssl/certs/cyrus-imapd.pem
tls_key_file: /usr/share/ssl/certs/cyrus-imapd.pem
tls_ca_file: /usr/share/ssl/certs/ca-bundle.crt
# Если мы хотим проверять пароли в БД с помощью встроенных модулей sasl, можно добавить
sasl_pwcheck_method: auxprop saslauthd
sasl_auxprop_plugin: sql
sasl_sql_engine: mysql
sasl_sql_user: mailadmin
sasl_sql_passwd: mailpasswd
sasl_sql_hostnames: localhost
sasl_sql_database: maildb
sasl_sql_statement: select password from accountuser where username = '%u' and domain_name = '%r'
(см. Аутенификация SASL)
/etc/cyrus.conf
Все по умолчанию
Программа cyradm
cyradm – скрипт на Perl для управления почтовыми ящиками по протоколу IMAP. Запуск
cyradm -u cyradmin localhost
cyradm можно использовать в диалоговом режиме, либо перенаправлять ему вывод какого либо скрипта
Создание почтового ящика и установка квоты 100МБ
cm user/newuser
sq user/newuser 100000
Удаление ящика
sam user/newuser cyradm c
dm user/newuser
Восстановление индексных файлов в порушенном ящике
sudo -u cyrus /usr/lib/cyrus-imapd/reconstruct user/john.dou
Переход на Postfix с sendmail в CentOS осуществляется почти автоматически.
Устанавливаем postfix
yum install postfix
Правим конфигурационные файлы в каталоге /etc/postfix, удаляем Sendmail, cтроим hash для файла aliases, стартуем Postfix и добавляем его в список загружаемых при старте демонов
vi /etc/postfix/main.cf
rpm -e sendmail
newaliases
/sbin/service postfix start
/sbin/chkconfig postfix on
Замечательные русские инструкции по настройке Postfix можно найти здесь: http://sergeysl.pnz.ru/freebsd/mailsystem.php
Данная страница посвящена решению некоторых специфических задач конфигурации.
Альтернативные программы
В CentOS используется специальный механизм выбора версии программы, имеющей несколько реализаций. К таким программам относятся почтовые серверы, принт серверы, различные варианты java. В каталоге /etc/alternatives/ сделаны символические линки на реально установленные программы например, /etc/alternatives/mta изначально является символическим линком на /usr/lib/sendmail.sendmail. При удалении Sendmail происходит замена и /etc/alternatives/mta становится символическим линком на /usr/lib/sendmail.postfix. Файл /usr/sbin/sendmail является в свою очередь линком на /etc/alternatives/mta. Т.к. Postfix обрабатывает те же опции при запуске, что и Sendmail, подмену никто не заметит. Аналогичная ситуайия с mailq, newaliases, rmail.
Борьба со спамом и вирусами
Желательно установить Greylisting, clamav, spamassasin и/или mimedefang
yum install postgrey clamav clamd spamassassin mimedefang
Чтобы установка прошла атоматически, надо подключить к списку репозиториев yum'а Dag RPM Repository ( http://dag.wieers.com/rpm/ )
Возможны некоторые проблемы с зависимостями mimedefang с sendmail. (Похоже там явно прописана зависимость от rpm-пакета sendmail).
Подключение этих программ к Postfix будет описано ниже, при описании конфигурационных файлов.
Mimdefang подключится если у нас Postfix версии 2.4
Правим права доступа
В файле /etc/sysconfig/mimedefang (Проверить)
MX_USER=postfix
chown -R postfix.postfix /var/spool/MIMEDefang
MIMEDefang ожидает что сокет clamd расположен в /var/spool/MIMEDefang/clamd.sock, причем это прошито в коде /usr/bin/mimedefang.pl. Clamd по умолчанию помещает свой сокет в /tmp/clamd.socket. Попробуем сделать линк (Проверить)
ln -s /tmp/clamd.socket /var/spool/MIMEDefang/clamd.sock
По умолчанию MIMEDefang запускает Spamassassin с конфигурационным файлом /etc/mail/sa-mimedefang.cf, а пакет spamassassin устанавливает свой конфиг в /etc/mail/spamassassin/local.cf. Чтобы не было путаницы удаляем /etc/mail/sa-mimedefang.cf, MIMEDefang переключится на /etc/mail/spamassassin/local.cf автоматически.
Для postgrey прописываем белые листы:
Пользователи которым нельзя задерживать доставку почты ни под каким видом
Файл /etc/postfix/postgrey_whitelist_recipients
abuse@
quickaccess@
Локальные сети
Файл /etc/postfix/postgrey_whitelist_clients.local
192.168.100
К сожалению маска сети не предусмотрена. Если ваша подсеть больше или меньше стандартного класса, то придется перечислять все подсети или IP адреса (может получиться до 128 строк на подсеть)
Теперь надо включить postgrey, clamd, spamassassin и mimedefang в автозапуск.
/sbin/chkconfig clamd on
/sbin/chkconfig spamassassin on
/sbin/chkconfig mimedefang on
Файл /etc/postfix/main.cf
Основной конфигурационный файл Postfix'а описывающий «политические» параметры (контроль доступа, виртуальные домены и т.п.).
Полный список параметров и их значения по умолчанию можно посмотреть в main.cf.default
Ограничения на пересылку почты
Перед первым запуском правим имя хоста. Скорее всего оно определится из hostname, но лучше подстраховаться.
myhostname = mail.my.net
myorigin = $mydomain
myorigin подменяет почтовый домен для почты отправляемой с локальной машины. Нынче многие почтовые серверы проверяют наличие MX записи для адреса отправителя. В приведенном примере MX запись для my.net скорее всего существует, а для mail.my.net не существует. Почта с локальной системы, например диагностические сообщения, без установки myorigin будет блокироваться.
Ограничения на пересылку почты определяютя так
mydestination = $myhostname, localhost.$mydomain, localhost
mynetworks = 168.100.189.0/24, 127.0.0.0/8
smtpd_recipient_restrictions =
permit_mynetworks,
reject_unauth_destination,
check_policy_service unix:postgrey/socket
Результат ограничений – разрешаем пересылку почты из локальных сетей. Из остального мира после аутенификации и прохождения greylisting'а, либо для наших пользователей из списка почтовых доменов mydestination и прохождения greylisting'а. (есть еще список виртуальных пользователей, но оних ниже).
(Неприятный вопрос, будеть ли greylisting пропускать аутенифицированных пользователей?)
Пример других ограничений http://www.opennet.ru/tips/info/813.shtml
Подключение mimedefang для Postfix версии >= 2.4. Postfix 2.3.3 параметр воспринял, но Mimedefang выдал ошибки протокола при попытке отправить письмо.
smtpd_milters = unix:/var/spool/MIMEDefang/mimedefang.sock
milter_default_action = tempfail
В этом варианте spamassassin и антивирус запустятся через MIMEDefang.
Доставка почты
Почта предназначенная для локальных пользователей может доставляться
в классический файл формата mailbox
mail_spool_directory = /var/mail
или в каталог Maildir
home_mailbox = Maildir/
или с помощью внешней программы (если надо проверять на вирусы только входящую почту, то здесь можно вставить антивирусный фильтр)
mailbox_command = /usr/bin/procmail
или по протоколу lmtp если Postfix используется в связке с Cyrus IMAPD
mailbox_transport = lmtp:unix:/var/lib/imap/socket/lmtp
Можно описать собственный транспорт в файле /etc/postfix/master.cf
Файл /etc/postfix/master.cf
Конфигурационный файл, описывающий «технические» параметры (запускаемые почтовые службы и их настройки).
Подключение spamassassin и антивируса для Postfix версии < 2.4.
Проверяем только SMTP
#smtp inet n - n - - smtpd
smtp inet n - n - - smtpd -o content_filter=avfilter:dummy
...
avfilter unix - n n - - pipe
flags=R user=clamav argv=/usr/local/sbin/avfilter.sh -f ${sender} -- ${recipient}
Файл /usr/local/sbin/avfilter.sh может быть таким
#!/bin/sh
INSPECT_DIR=/tmp #Каталог куда будут сохраняться письма для сканирования
SENDMAIL="/usr/sbin/sendmail -i"
VIRUSADMIN="root@my.net" # адрес для уведомлениий
EX_TEMPFAIL=75
EX_UNAVAILABLE=69
# строка для запуска spamassassin
FILTER_SPAMC="/usr/bin/spamc"
#FILTER_SPAMC="/usr/bin/spamc -u spamfilter -U /var/run/spamd.sock"
# строка для запуска clamav
FILTER_CLAMAV="/usr/bin/clamdscan -v --no-summary --stdout"
trap "rm -f $INSPECT_DIR/in.$$ $INSPECT_DIR/vr.$$ $INSPECT_DIR/vr1.$$" 0 1 2 3 15
# Проверка на спам
cat | $FILTER_SPAMC > $INSPECT_DIR/in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
# Проверка на вирусы
$FILTER_CLAMAV ${INSPECT_DIR}/in.$$>$INSPECT_DIR/vr.$$
# Результат проверки
AV_RESULT=$?
case "$AV_RESULT" in
0)
# Проверено. Мин нет :)
$SENDMAIL "$@" <${INSPECT_DIR}/in.$$
exit 0
;;
1)
# Обнаружен вирус. Посылаем уведомление админу
echo "Subject: VIRUS FOUND" >> $INSPECT_DIR/vr1.$$
echo >> $INSPECT_DIR/vr1.$$
echo "************************************************" >> $INSPECT_DIR/vr1.$$
echo "* MAIL *" >> $INSPECT_DIR/vr1.$$
echo "************************************************" >> $INSPECT_DIR/vr1.$$
echo >> $INSPECT_DIR/vr1.$$
# Включаем в отчет реальные адреса релеев
grep Received $INSPECT_DIR/in.$$ >> $INSPECT_DIR/vr1.$$
echo "Mail from: $2 (may be forget)" >> $INSPECT_DIR/vr1.$$
echo "To: $4" >> $INSPECT_DIR/vr1.$$
grep Subject $INSPECT_DIR/in.$$ >> $INSPECT_DIR/vr1.$$
echo >> $INSPECT_DIR/vr1.$$
echo "************************************************" >> $INSPECT_DIR/vr1.$$
echo "* Virus(es) *" >> $INSPECT_DIR/vr1.$$
echo "************************************************" >> $INSPECT_DIR/vr1.$$
# Включаем в отчет список вирусов
cat $INSPECT_DIR/vr.$$ >> $INSPECT_DIR/vr1.$$
$SENDMAIL -f $VIRUSADMIN -r $VIRUSADMIN -F "Antivirus" $VIRUSADMIN < $INSPECT_DIR/vr1.$$
exit 0
;;
*)
# Произошла ошибка в работе антивируса. Сообщим об ошибке админу
echo "Subject: ANTIVIRUS FAILED" >> $INSPECT_DIR/vr1.$$
echo >> $INSPECT_DIR/vr1.$$
echo "************************************************" >> $INSPECT_DIR/vr1.$$
echo "* Antivirus Failed with next problem *" >> $INSPECT_DIR/vr1.$$
echo "************************************************" >> $INSPECT_DIR/vr1.$$
case "$AV_RESULT" in
40)
echo "* Unknown option passed. *" >> $INSPECT_DIR/vr1.$$
;;
50)
echo "* Database initialization error. *" >> $INSPECT_DIR/vr1.$$
;;
52)
echo "* Not supported file type. *" >> $INSPECT_DIR/vr1.$$
;;
53)
echo "* Can't open directory. *" >> $INSPECT_DIR/vr1.$$
;;
54)
echo "* Can't open file. (ofm) *" >> $INSPECT_DIR/vr1.$$
;;
55)
echo "* Error reading file. (ofm) *" >> $INSPECT_DIR/vr1.$$
;;
56)
echo "* Can't stat input file / directory. *" >> $INSPECT_DIR/vr1.$$
;;
57)
echo "* Can't get absolute path name of current *" >> $INSPECT_DIR/vr1.$$
echo "* working directory. *" >> $INSPECT_DIR/vr1.$$
;;
58)
echo "* I/O error, please check your filesystem. *" >> $INSPECT_DIR/vr1.$$
;;
59)
echo "* Can't get information about current user *" >> $INSPECT_DIR/vr1.$$
echo "* from /etc/passwd. *" >> $INSPECT_DIR/vr1.$$
;;
60)
echo "* Can't get information about user *" >> $INSPECT_DIR/vr1.$$
echo "* clamav (default name) from /etc/passwd. *" >> $INSPECT_DIR/vr1.$$
;;
61)
echo "* Can't fork. *" >> $INSPECT_DIR/vr1.$$
;;
63)
echo "* Can't create temporary files/directories *" >> $INSPECT_DIR/vr1.$$
echo "* (check permissions). *" >> $INSPECT_DIR/vr1.$$
;;
64)
echo "* Can't write to temporary directory (please *" >> $INSPECT_DIR/vr1.$$
echo "* specify another one). *" >> $INSPECT_DIR/vr1.$$
;;
70)
echo "* Can't allocate and clear memory (calloc). *" >> $INSPECT_DIR/vr1.$$
;;
71)
echo "* Can't allocate memory (malloc). *" >> $INSPECT_DIR/vr1.$$
;;
*)
echo "Unknown error $AV_RESULT" >> $INSPECT_DIR/vr1.$$
;;
esac
echo "************************************************" >> $INSPECT_DIR/vr1.$$
$SENDMAIL -f $VIRADMIN -r $VIRADMIN -F "Antivirus" "$VIRADMIN" < $INSPECT_DIR/vr1.$$
exit $EX_TEMPFAIL
;;
esac
exit 0
Виртуальные домены
В Postfix используются несколько способов задания имен локальных почтовых ящиков.
1. Имена пользователей зарегистрированных в системе. Т.е. в файле /etc/passwd
2. Имена перечисленные в файле /etc/aliases
3. Почтовые ящики перечисленные в файле /etc/postfix/virtual
4.Имена, определяемые локальной программой доставки
В зависимости от подсистемы обслуживающей почтовые ящики, имена из virtual могут отображаться, а могут и не отображаться на имена пользователей из файла passwd.
Основное идеологическое отличие между /etc/aliases и /etc/postfix/virtual в том, что aliases предназначены для локальных имен (например postmaster->root->adminuser или root->root@remote.com), а файл virtual предназначен для отображения имен пользователей различных почтовых доменов, обслуживаемых данным сервером, в имена локальных или удаленных почтовых ящиков (например user@virtual.net ->user_virtual_net).
Другими словами aliases нужны для корректной доставки почты на компьютере не являющемся выделенным почтовым сервером, а virtual это средство для развертывания почтовой системы массового обслуживания.
Если используются оба файла, то вначале для определения маршрута доставки почты используется virtual, а затем, если почта должна быть доставлена в локальный почтовый ящик, aliases.
Squirrelmail - веб интерфейс к IMAP серверу/
После инсталляции размещается в /usr/share/squirrelmail, в /etc/httpd/conf.d создается конфигурация для виртуального каталога /webmail, в /etc/squirrelmail/ помещаются файлы config.php и config_local.php
Файл config.php редактируется скриптом /usr/share/squirrelmail/config/conf.pl Настройки сводятся к выбору языка и типа IMAP сервера.
Внимание! Для cyrus-imapd надо в /etc/squirrelmail/config_local.php прописать $default_folder_prefix= 'INBOX/';
Для включения ssl желательно дописать в /etc/httpd/conf.d/squirrelmail.conf
<Directory /usr/share/squirrelmail>
SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "mail.mydomain.my"
ErrorDocument 403 https://mail.mydomain.my/webmail
</Directory>
Дистрибутив CentOS 7
Сначала чистим почтовый архив, потом регенерируем веб-архив, стирая старый
mutt -f /var/lib/mailman/archives/private/mylist.mbox/mylist.mbox
/usr/lib/mailman/bin/arch --wipe mylist
Программа управления списками рассылки mailman написана на Python 2 и имеет хорошо задокументированное API.
Для тех, кто не хочет программировать на python, существует несколько готовых скриптов для управления списками рассылки. В CentOS 7 они находятся в каталоге /usr/lib/mailman/bin/.
Создание списка newlist [listname [listadmin-addr [admin-password]]]
Если часть параметров пропущена, то она будет запрошена в интерактивном режиме.
Добавление участников рассылки add_members -r infile listname
Где файл infile состоит из строк вида:
jdoe@example.com
<jdoe@example.com>
John Doe <jdoe@example.com>
"John D. Doe" <jdoe@example.com>
jdoe@example.com (John Doe)
Просмотр списка участников list_members listname
. С полными именами (не дружит с Unicode) list_members -f listname
Смена административного пароля на списки рассылки change_pw
. Опция -a позволяет установить один пароль на все списки, -l list1 -l list2... позволяет перечислить списки. Пароль генерируется автоматически, но его можно задать явно опцией -p pass.
Удаление списка рассылки (БЕЗ ЗАПРОСА ПОДТВЕРЖДЕНИЯ) rmlist -a listname
. Опция -a указывает, что надо удалить архив сообщений.
Сохранение в файл основных параметров списка (без информации об участниках) config_list -o listname.conf listname
. Формат вывода - программа на python, которая может быть подана на вход config_list -i listname.conf listname
Просмотр всех параметров списка dumpdb /var/lib/mailman/lists/<listname>/config.pck
Изменение параметров списка (В том числе массовое добавление полных имён участников рассылки) config_list -i infile listname
. В файле infile должна находиться программа на python, в которой присваиваются значения переменным, имена которых совпадают с именами атрибутов списка рассылки. Имена переменных не совпадающих с атрибутами игнорируются. Можно присваивать значения непосредственно атрибутам объекта списка рассылки mlist, но при этом можно нарушить внутреннюю непротиворечивость конфигурации.
Отключение ежемесячного напоминания о паролях
echo send_reminders=0 > remunders0.conf
config_list -i remunders0.conf sample_list
Для добавления участникам полных имен надо найти в выдаче dumpdb /var/lib/mailman/lists/sample_list/config.pck
подходящие атрибуты:
'members': { 'student1@example.com': 0,
'student2@example.com': 0},
...
'usernames': { 'student1@example.com': u'\u041f\u0435\u0440\u0432\u044b\u0439 \u0441\u0442\u0443\u0434\u0435\u043d\u0442',
'student2@example.com': u''},
Видно, что полные имена хранятся в формате unicode. Так, полное имя student1@example.com - "Первый студент". Можно написать присваивание какому-либо элементу массива usernames и сохранить его в файле infile:
mlist.usernames['student2@example.com'] = u'Second Student'
Команда config_list -i infile sample_list
изменит полное имя для участника student2@example.com
SASL – Simple Authentication and Security Layer, это метод аутенификации пользователя для встраивания в сетевые протоколы основанные на соединении. Ниже описана конфигурация одной из реализаций механизма - cysrus-sasl версии 2.
В cysrus-sasl существует два основных способа аутенификации: auxprop - через библиотеку, слинкованную с приложением и saslauthd - по особому протоколу через сервер аутенификации saslauthd.
auxprop позволяет проводить аутенификацию в базе данных SQL (mysql, sqlite), файле BeklyDB или в LDAP. Список вариантов проверки saslauthd можно узнать командой
# saslauthd -v
saslauthd 2.1.26
authentication mechanisms: getpwent kerberos5 pam rimap shadow ldap httpform
Один экземпляр saslauthd может использовать только один механизм аутенификации.
Не стоит использовать auxprop совместно с БД, поскольку существующая реализация требует хранить пароли БД открытым текстом. Более гибким способом является связка saslauthd
+ pam
+ pam_mysql
.
Поддержка SASL включена, в частности, postfix
и в cyrus-imapd
. Опции SASL для cyrus-imapd прописываются в файл /etc/imapd.conf
, для postfix в CentOS 7 - в файле /etc/sasl2/smtpd.conf
(/usr/[local/]lib[64]/sasl2/smtpd.conf
в других дистрибутивах).
Файл конфигурации cyrus-imapd /etc/imapd.conf
#Для отладки взаимодействия с SQL сервером (печать sql-запросов)
sasl_log_level: 5
#Для логирования необходимо вставить в конфигурацию `rsyslogd` строку
#*.=debug /var/log/debug
#Механизм запроса пароля. В данном случае в виде открытого текста.
sasl_mech_list: PLAIN
#Механизм доступа к SASL
sasl_pwcheck_method: auxprop
#Плагин, используемый через auxprop
#Сами плагины лежат в /usr/[local/]lib[64]/sasl2/
sasl_auxprop_plugin: sql
#Опции для sql плагина
# mysql - тип сервера (еще есть sqlite)
sasl_sql_engine: mysql
# Доступ к базе
sasl_sql_user: mailadmin
sasl_sql_passwd: mailpassword
sasl_sql_hostnames: localhost
sasl_sql_database: mail
# Запрос должен извлечь пароль в виде текста для пользователя %u@%r (%r - realm)
# По умолчанию вместо %r подставляется имя хоста, на котором запущен cyrus-imapd
sasl_sql_statement: select password from accountuser where username = '%u' and domain_name = '%r'
Файл конфигурации postfix - /etc/postfix/main.cf
# Сервер, который будет делать проверку
smtpd_sasl_path = smtpd
smtpd_sasl_auth_enable = yes
Файл /etc/sysconfig/saslauthd
содержит опции для запуска saslauthd, в том числе, используемый механизм проверки.
MECH=pam
Файл настроек sasl для демона smtpd /etc/sasl2/smtpd.conf
pwcheck_method: saslauthd
mech_list: PLAIN
Файл настроек PAM для службы smtp /etc/pam.d/smtp
Приложения передают в saslauthd имя сервиса. postfix передаёт строку smtp.
#%PAM-1.0
auth required pam_mysql.so config_file=/etc/security/pam_mysql.conf [where=smtpauth=1]
account required pam_mysql.so config_file=/etc/security/pam_mysql.conf [where=smtpauth=1]
В дальнейшем считаем, что в БД создана база mail, доступ к ней разрешен пользователю mailadmin с паролем mailpassword. В администраторы cyrus-imapd внесен пользователь cyradmin.
Web-cyradm предпологает следующую структуру данных для хранения паролей:
CREATE TABLE accountuser (
username varchar(255) binary NOT NULL default '',
password varchar(30) binary NOT NULL default '',
prefix varchar(50) NOT NULL default '',
domain_name varchar(255) NOT NULL default '',
UNIQUE KEY username (username)
) TYPE=MyISAM;
Перенос почтовых ящиков
Скрипт для создания пустых почтовых ящиков на основе информации в /etc/passwd
#!/usr/bin/perl -w
#
# Written by Wil Cooley <wcooley@nakedape.cc>, 25 April 2002.
#
# This script is copyright (C) 2002 by Wil Cooley and
# licensed under the GNU GPL <http://www.gnu.org//licenses/gpl.txt>
#
# Usage: migrate-pw-to-cyrus2.pl
#
# Purpose: Creates empty Cyrus mailboxes.
#
# Input: None.
#
# Notes: Set the default quota below. I used a default
# of 100MB more as a failsafe than a restriction.
#
# $Id: migrate-pw-to-cyrus2.pl,v 1.1 2002/04/26 00:56:09 wcooley Exp $
###
my $adminuser = "cyradmin" ;
my $server = "localhost" ;
my $quota = 100*1024 ; # 100MB
my $user_uid_start = 500 ;
my $err = 0 ;
my ($user,$p,$uid) ;
use Cyrus::IMAP::Admin;
$imapcon = Cyrus::IMAP::Admin->new($server) || die "Unable to connect to $server";
unless ($imapcon) {
die "Error creating IMAP connection object\n" ;
}
$imapcon->authenticate(-user => $adminuser, -mechanism => "LOGIN") ;
if ($imapcon->error) {
die $imapcon->error ;
}
print "\n" ;
setpwent() ;
while (($user,$p,$uid) = getpwent) {
if ($uid >= $user_uid_start) {
unless ($imapcon->list("user.$user")) {
$imapcon->create("user.$user") ;
if ($imapcon->error) {
print "ERROR: ", $imapcon->error, "\n" ;
next;
} ;
$imapcon->setquota("user.$user", "STORAGE", $quota) ;
if ($imapcon->error) {
print "ERROR: ", $imapcon->error, "\n";
next;
} ;
print "Created mailbox user.$user [$uid]\n" ;
}
}
}
endpwent() ;
Перенос содержимого почтовых ящиков с помощью formail и cyrus deliver
# Script to import mbox-format mailboxes to Cyrus folders
# Requires formail (from procmail)
#
# Note: As this runs cyrdeliver directly, you'll need to be
# a member of the mail group for it to work.
#
# Use this script at your own risk! I'm not responsible if
# it trashes your mail system :)
#
# By Michael-John Turner <mj@debian.org>
#
USER=$1
MAILBOX=$2
CYRUSFOLDER=$3
#CYRDELIVER=/usr/sbin/cyrdeliver
CYRDELIVER=/usr/lib/cyrus-imapd/deliver
FORMAIL=/usr/bin/formail
if ! [ -x "$FORMAIL" ]; then
echo ""
echo "formail (from procmail) is required to run this script"
echo ""
exit 1
fi
if [ "$USER" = "" ]; then
echo ""
echo "syntax: $0 user [mbox] [cyrus folder]"
echo ""
echo "If no mbox is specified, the user and mbox name are taken to be the same"
echo "If no cyrus folder is specified, the INBOX is used"
echo ""
exit 2
fi
if [ "$MAILBOX" == "" ]; then
MAILBOX=$USER
fi
if [ "$CYRUSFOLDER" == "" ]; then
echo "Adding mailbox '$MAILBOX' to Cyrus INBOX of user '$USER'..."
$FORMAIL -I "From " -s $CYRDELIVER $USER < $MAILBOX
else
echo "Adding mailbox '$MAILBOX' to Cyrus folder '$CYRUSFOLDER' of user '$USER'..."
$FORMAIL -I "From " -s $CYRDELIVER -m $CYRUSFOLDER $USER < $MAILBOX
fi
Перенос паролей
При миграции возникает желание убрать записи почтовых пользователей из /etc/passwd и перейти на хранение паролей в MySQL, LDAP или где нибудь еще. Прямого пути нет!
В качестве обходного пути можно попытаться использовать PAM-modules Сергея Позднякова http://puszcza.gnu.org.ua/software/pam-modules/
Устанавливаем pam_fshadow из указанного пакета. Копируем записи почтовых пользователей из файла /etc/shadow (/etc/master.passwd во FreeBSD) в новое место, например в /etc/mail/shadow. Пишем настройки PAM для сервисов pop, imap и, возможно, sieve.
auth sufficient pam_fshadow.so sysconfdir=/etc/mail nopass
account sufficient pam_fshadow.so sysconfdir=/etc/mail nopass
Дополнительно настраиваем SASL для проверки в MySQL. Вариант с pam_mysql менее интересен, т.к. не поддерживает виртуальные домены.
auth sufficient pam_fshadow.so sysconfdir=/etc/mail nopass
auth sufficient pam_mysql.so config_file=/etc/pam_mysql.conf
auth sufficient pam_fshadow.so sysconfdir=/etc/mail nopass
account sufficient pam_mysql.so config_file=/etc/pam_mysql.conf
Пример /etc/pam_mysql.conf
users.host=localhost;
users.database=maildb;
users.db_user=mailadmin;
users.db_passwd=mailpassword;
users.table=accountuser;
users.user_column=username;
users.password_column=password;
users.password_crypt=plain;
users.disconnect_every_operation=true;
verbose=0;
log.enabled=1;
log.table=logins;
log.message_column=message;
log.pid_column=pid;
log.user_column=username;
log.host_column=machineip;
log.time_column=logintime;
В соответствие с RFC2060 национальные символы в именах почтовых ящиков на сервере должны кодироваться в модифицированную кодировку UTF7. Отличия от оригинальной UTF7 связаны с особым значением символа '+' в некоторых почтовых системах и символа '/' в роли разделителя имён каталогов в Unix.
Алгоритм кодирования имён папок: Текст -> UTF7; & -> &-; / -> ,; + -> &
Декодирование:
echo '.&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-' \
| sed 's/&\([^-]\)/+\1/g;s/&-/&/g;s/,/\//g' \
| iconv -f UTF7 -t UTF8
.Отправленные
Автоматическая отправка почты
echo test | mail -s test user@example.com
Отправка вложенного файла
uuencode filename ./filename | mail -s "test with file" user@example.com
Дополнительные опции при отправке
-s - Subject:
-c - Cc:
-b - BCc:
-r - From:
Открыть IMAP/mailbox/Maildir
mutt -f imaps://mail.example.com/
mutt -f file.mbox
или
MAIL='/home/user/Maildir' mutt -f file.mbox
Удалить письма с определенных доменов (From:
)
Shift D ~f@example.com
Удалить письма со словом SPAM
в поле Subject:
Shift D ~sSPAM
Удалить все письма (два варианта)
Shift D ~s.*
Shift D ~A
Восстановить удаленное письмо с номером 1234 1234<CR>u
Cmd | Description |
---|---|
j,k | next, previous message |
1234 | go to mail number 1234 |
= | first message |
* | last message |
d | delete |
D~pattern | delete by pattern |
u | undelete |
U~pattern | undelete by pattern |
m | new message |
f | forward |
r | reply |
s | save message to file |
v | view attachment |
$ | delete all marked messages |
x | discard changes and quit |
q | quit |
Cmd | Description |
---|---|
j,k | next, previous message |
d | delete |
u | undelete |
m | new message |
f | forward |
r | reply |
s | save message to file |
i | return to main menu |
Cmd | Description |
---|---|
t | To: |
s | Subject: |
c | CC: |
b | BCC: |
a | attach file |
q | abort sending message |
y | send |
Шаблон | Описание |
---|---|
~A | все (all) |
~N | новые (new) |
~O | старые(old) |
~R | прочитанные (read) |
~U | непрочитанные (unread) |
~bEXPR | поиск в теле (body) письма |
~sEXPR | поиск в поле Subject |
~fEXPR | поиск в поле From: |
~tEXPR | поиск в поле To: |
~d [MIN]-[MAX] | дата отправки Date между MIN и MAX. Дата в формате DD/MM/YY[YY] или выражение вида >, <, = число дней (d), недель (w), месяцев (m), лет (y). Например 01/01/2019 или >3m |
После правок конфигурационного файла, желательно проверить его синтаксис.
Просто проверка конфигурации
named-checkconf /etc/named.conf
Проверка конфигурации в chroot
named-checkconf -t /var/named/chroot /etc/named.conf
Проверка одной зоны
named-checkzone subdomain.example.com example.zone
Дамп кэша/зон в файл (имя файла определяется параметром options {dump-file ...;}
) в named.conf
rndc dumpdb -cache
rndc dumpdb -zones
тест + печать конфигурации в stdout
testparm
postconf
apachectl configtest
squid -k parse
nginx -t -c /etc/nginx/nginx.conf
тест + печать конфигурации в stdout
nginx -T
Сервер
sshd -t
Сервер: тест + печать конфигурации в stdout
sshd -T
Печать конфигурации клиента, которая будет применена при подключению к определённому серверу
ssh -G {host_or_ip_here}
ssh -F {~/path/to/ssh_config} -G {host_or_ip_here}
CentOS 7 rsyslogd v8.24.0
rsyslogd -N1
Ubuntu 20 rsyslogd v 8.2112.0. Можно либо использовать опцию -N1
, либо опцию -o <file>
для проверки синтаксиса и печати конфигурации одним файлом. Если вместо имени файла указать "-", то содержимое выведется в stdout
rsyslogd -o file.conf
В разных дистрибутивах пакет содержащий apache может называться httpd (CentOS), apache (Arch Linux), apache2 (Debian/Ubuntu). Кроме основного пакета может потребоваться установка дополнительных модулей, например mod_ssl.
Для установки apache используется один выделенный каталог с подкаталогами (ссылками на подкаталоги) с конфигурацией, модулями и логами. В CentOS базовый каталог /etc/httpd/. Дальнейшие ссылки на файлы даются именно для CentOS.
Основной конфигурационный файл /etc/httpd/conf/httpd.conf. В каталоге /etc/httpd/conf.d/ могут храниться дополнительные конфигурационные файлы. Они имеют ту же структуру что и httpd.conf и включаются в основной файл директивой Include.
Внимание В некоторых дистрибутивах Include /etc/httpd/conf.d/
стоит в первой половине httpd.conf до объявления виртуального сервера. По этому, если вы хотите хранить в отдельных файлах конфигурацию виртуальных серверов, то создайте новый каталог, например /etc/httpd/virtual, а в конец httpd.conf вставьте Include /etc/httpd/virtual/*.conf
Структура httpd.conf проста
#Комментарий
ГлобальныйПараметр значение
<Секция значение>
ЛокальныйПараметр значение
</Секция>
Все, что не попало внутрь секций, влияет на глобальные настройки сервера, секции определяют специфические настройки каталогов, виртуальных серверов и модулей apache.
В CentOS устанавливаем rpm пакеты
yum install php-common php-cli php
Если посмотреть список установленных файлов, то видно, что php устанавливает модуль для Apache /usr/lib/httpd/modules/libphp7.so
, а php-cli — интерпретатор /usr/bin/php
Модуль для Apache требует внесения изменений в конфигурацию apache. В CentOS это делается при инсталляции пакета путем добавления файла /etc/httpd/conf.d/php.conf. Примерное содержимое файла
<FilesMatch \.(php|phar)$>
SetHandler application/x-httpd-php
</FilesMatch>
DirectoryIndex index.php
Интерпретатор php позволяет подключать дополнительные модули, которые расширяют набор доступных в языке функций. Модули могут быть статически скомпилированы в интерпретатор либо подключаться динамически. Из популярных можно упомянуть php-mysql для связи с БД My SQL, php-gd – библиотека обработки изображений, php-mbstring – работа с Unicode.
В CentOS модули можно доустанавливать в соответствии с потребностями
yum install php-mysql
В соответствии с идеологией CentOS конфигурация php для модуля сохраняется в каталоге /etc/php.d/ и содержит строку подключения модуля:
extension=mysql.so
После установки модуля, веб сервер надо перегрузить.
Общий для всех конфигурационный файл находится в /etc/php.ini
В инструкции по php перечислены параметры, которые можно (PHP_INI_ALL, PHP_INI_PERDIR) и которые нельзя (PHP_INI_SYSTEM) изменить на уровне каталога.
Начиная с версии PHP 5.3.0 в каталоге можно помещать локальный файл настроек .user.ini
Также установки «под себя» можно сделать в файле .htaccess строками подобными следующим
php_value upload_max_filesize 32M
php_value post_max_size 64M
Или в тексте самой программы
<?php
ini_set('memory_limit', '128M');
ini_set('max_input_time', '300');
ini_set('max_execution_time', '300'); // 5 minuites
?>
Простейшая, но очень полезная программа на php. Выдает всю информацию о конфигурации apache и php
<?php
print phpinfo();
?>
<?php
$host='localhost'; $user="user1"; $pass='123';
//Знак @ нужен, чтобы погасить выдачу возможных ошибок подключения на веб страницу
$connection = @mysql_connect($host, $user, $pass, TRUE, 2);
//Установка кодировки для обмена данными в mysql версии > 4.1.0
mysql_query('SET NAMES "utf8"', $connection);
$query ="SELECT * FROM table";
$result = mysql_query($query);
if( $result )
{
while( $array=mysql_fetch_array($result, MYSQL_ASSOC) );
print_r($array);
}
?>
Секции определяют права доступа к каталогам, файлам, виртуальным серверам и модулям apache Секции могут быть вложены друг в друга файл в каталог, каталог в виртуальный сервер, модуль в виртуальный сервер (это не проверено)
В списке виртуальных серверов может присутствовать <VirtualHost *:80>
который будет использоваться если к apache пришел запрос с отсутствующим (по ip) или несконфигурированным именем сервера.
<VirtualHost dummy-host.example.com:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /www/docs/dummy-host.example.com
ServerName dummy-host.example.com
ErrorLog logs/dummy-host.example.com-error_log
CustomLog logs/dummy-host.example.com-access_log common
</VirtualHost>
Допустимые опции каталога Indexes Includes, FollowSymLinks, SymLinksifOwnerMatch, ExecCGI, MultiViews, а также All или None.
<Directory "/var/www/html">
#
#Разрешаем просмотр каталогов в которых нет файла index.html
#Разрешаем использование символических ссылок
Options Indexes FollowSymLinks
#Запрещаем задание прав на доступ в .htaccess
AllowOverride None
#Разрешаем доступ всем
Order allow,deny
Allow from all
</Directory>
#Запрещаем доступ к файлам .htaccess, .htpasswd и т.п.
<Files ~ "^\.ht">
Order allow,deny
Deny from all
</Files>
Включаем прокси, но ограничиваем доступ к нему доменом **example.com**
<IfModule mod_proxy.c>
ProxyRequests On
<Proxy *>
Order deny,allow
Deny from all
Allow from .example.com
</Proxy>
</IfModule>
В файлах .htaccess можно переопределить права доступа к каталогу (и его подкаталогам), если в httpd.conf для него указано AllowOverride All
(All это по максимуму, возможно, что разрешено будет переопределять только часть настроек). По сути дела .htaccess это секция <Directory ...>...</Directory>
вынесенная в отдельный файл и лишенная обрамляющих конструкций. Если права меняются в httpd.conf, то серверу надо послать сигнал обновления конфигурации. Изменения в .htaccess вступают в действие мгновенно.
Если вы используете Apache совместно с PHP, то в .htaccess можно вынести некоторые параметры PHP необходимые для работы скриптов в данном конкретном каталоге. Например:
php_value include_path '.:/var/www/phplib:'
php_value default_charset 'windows-1251'
В директивах определяющих доступ к каталогу правила Deny и Allow можно писать в любом порядке. Реальный порядок их применения определяется директивой Order. При запоминании порядка важно уяснить, что эти правила не описывают группы адресов как в некоторых других программах (например в Squid), а последовательно применяются к каждому конкретному адресу
**Order Deny,Allow** - по умолчанию всем разрешено, т.е. если нет запрещающего правила **Deny**, то клиент допускается.
Если какое то правило Deny запрещает доступ, то дополнительно проводится проверка в правилах Allow, и при наличии подходящего правила клиенту все таки разрешается доступ. Т.е. мы пишем глобальное правило Deny, а потом формулируем для него исключения в Allow
**Order Allow,Deny** - по умолчанию всем запрещено.
Если какое то правило Allow разрешает доступ, то дополнительно проводится проверка в правилах Deny и при наличии соответствующего запрета клиента отфутболивают. Т.е. мы пишем глобальное правило Allow, а потом формулируем для него исключения в Deny
Примеры
#Никому нельзя (например в каталоге с библиотеками PHP)
Order Deny,Allow
Deny from all
#Только с apache.org
Order Deny,Allow
Deny from all
Allow from apache.org
#Только с apache.org кроме foo.apache.org
Order Allow,Deny
Allow from apache.org
Deny from foo.apache.org
<RequireAny>
Require all denied
Require ip 192.168.1.14
Require ip 10.0.12.4
<RequireAny>
<RequireAll>
Require all granted
Require no ip 192.168.1.14
Require no ip 10.0.12.4
<RequireAll>
Показ списка файлов в каталоге
DirectoryIndex disabled
Options Indexes
IndexOptions NameWidth=*
Файлы конфигурации
/etc/samba/smb.conf – основная конфигурация
/etc/samba/smbusers – отображение имен сетевых пользователей на учетные записи UNIX
/etc/samba/lmhosts – отображение имен файловых серверов на ip адреса
/etc/samba/smbpasswd – файл с паролями, как правило вручную не меняется, имя можно поменять в smb.conf
Утилиты
smbpasswd – смена пароля пользователя, добавление учетной записи пользователя или компьютера в файл smbpasswd
testparm – проверка корректности smb.conf
testprns – проверка конфигурации сетевых принтеров
smbstatus – информация о подключенных клиентах
smbclient – утилита командной строки для подключения к серверу
nmblookup – просмотр зарегистрированнных имен NETBIOS
Файл /etc/samba/smb.conf состоит из секций имена которых выделяются квадратными скобками.
Секция [global] определяет общие настройки, [homes] доступ к домашним каталогам, остальные определяют прочие сетевые ресурсы раздаваемые этим сервером
[global]
#имя рабочей группы или домена
workgroup = IMM
#Сетевое имя компьютера, по умолчанию совпадает с hostname
netbios name = SERVER1
# Сохранять ли регистр букв
preserve case = yes
# А для "досовских" имен
short preserve case = no
# Если преобразуем ДОСовские имена, то как
default case = lower
case sensitive = no
[homes]
comment = Home Directories
browseable = no
writable = yes
[sampleshare]
path = /share
comment = Тестовый сетевой ресурс
guest ok = yes
browseable = yes
writable = no
write list = @admin
force create mode = 0664
force directory mode = 0775
Поддержка русских букв в именах файлов
Для того, чтобы русские имена файлов записанных на сервер через Samba нормально выводились в Дinux необходимо добавить в глобальную секцию smb.conf
dos charset=866
unix charset= UTF8
Группы пользователей
В Samba 3.0 появилась возможность произвольного отображения Unix'овских групп пользователей в любые группы домена. Для этого используется команда net.
Просмотр соответствий
net groupmap list
Создание собственной группы
groupadd mygroup
net groupmap add ntgroup="My group" unixgroup=mygroup type=d
Установка соответствий
net groupmap modify ntgroup="Users" unixgroup=public
Пример из книги John H. Terpstra “Samba-3 by Example”. Вторая часть примера мне кажется сомнительной. Из /etc/group понадерганы служебные группы, добавлены нестандартные public и ntadmin. Принцип сопоставления в половине случаев непонятен.
# Map Windows Domain Groups to UNIX groups
net groupmap modify ntgroup="Domain Admins" unixgroup=root
net groupmap modify ntgroup="Domain Users" unixgroup=users
net groupmap modify ntgroup="Domain Guests" unixgroup=nobody
В связи с эпидемией коранвируса отменяются очные занятия 23, 30 марта и 6 апреля
Здесь будет выкладываться информация на материалы для самостоятельного изучения и ссылки на записи лекций в youtube.
Напоминаю, что у нас есть тестовая учетная запись s0222 на сервере umt.imm.uran.ru Пароль к учётке сброшен в случайное значение, так что доступ только по ключу. Кто не был на занятии 18 марта - могут прислать публичный ключ мне на почту.
Практические занятия по использованию scp и sftp. Отчетность - правильные команды для каждого из заданий в виде письма на мой e-mail.
Под windows используются утилиты:
Под Linux
Указание - scp работает как cp, но если в имени файла есть двоеточие, то всё что левее - это user@server, а правее имя файла на сервере. Если не указан абсолютный путь к файлу на сервере, то путь считается от домашнего каталога. Для копирования каталога надо будет указать опцию
Оценить права доступа к файлам, полученном при копировании по scp и sftp. В частности, проверить сохраняются ли права при копировании из Unix в Unix. Попробовать создать файлы с русскими именами.
Практически опробовать ssh-туннели.
Литература: моя методичка, более развёрнутое описание на хабре.
Задания:
Запустить графическую задачу на сервере umt.imm.uran.ru (например firefox или matlab). В Linux использовать штатные средства, в Windows putty + X-server Xming (https://sourceforge.net/projects/xming/) Прислать скриншот.
Организовать туннель с localhost:8080 на 2ip.ru:443 без терминального сеанса. Зайти на 2ip.ru через туннель браузером. Задокументировать на скриншоте URL в браузере, строку с IP в окне и отдельно время включения туннеля. Проблема в том, что по IP адресу находится виртуальный сервер. Поэтому вам:
а) придётся вписать в файл hosts строчку
127.0.0.1 2ip.ru
б) в браузере заходить по адресу https://2ip.ru:8080.
в) если ваша версия windows позволяет подключение удаленным рабочим столом, то можно попробовать пробросить свой порт 3389 на большой порт на сервере и попробовать подключиться через интернет, но это на свой страх и риск.
Прочитать историю создания программы GnuPG
Установить себе версию GnuPG 2.2 или 2.1 - почему, описано в истории.
Прочитать описание структуры ключей и описание базовых команд. Сгенерировать мастер-ключ, подключ ключ шифрования и подключ подписи со сроком действия до июня 2020 года.
Прочитать про сеть доверия. Оценить для себя, нужен ли настоящий доверенный ключ подписи в будущем или мы пока играем в шифрование на учебных примерах.
Если идея иметь свой ключ понравилась, то запаролить мастер-ключ сложным паролем, сделать его резервную копию (пока нет в методичке), и опубликовать публичный ключ на сервере ключей (тоже нет в методичке). Потом мы подпишем ключи друг другу.
Если мы делаем учебный пример, то просто переслать мне публичные ключи , ссобщив их ID и e-mail через telegram. Я в свою очередь пришлю свой ключ для последующих обменов зашифрованными файлами.
Все непонятности перспрашивать у меня в телеграм или по e-mail, чтобы я правил методичку.
Создать текстовый файл с просьбой сообщить данные учебной почтовой записи в домене uran.ru. Подписать его и прислать мне. Получить от меня зашифрованный и подписанный файл с именем и паролем для входа на сервер. Можно сделать это в командной строке или воспользоваться оболочкой (Kleopatra).
Далее воспользоваться одной из доступных почтовых программ на выбор (список см. здесь) импортировать свой подключ и для подписи и мои публичные ключи в соответствующую программу и прислать подписанное и зашифрованное письмо.
Предполагаемый список тем
Начальная загрузка компьютера. Загрузчик GRUB
Начальная загрузка ОС. Суперпроцесс init и его реализация systemd
Пользователи и пароли. Система PAM для гибкой настройки ограничений доступа
Настройка SUDO для административных работ
ssh как универсальный способ удаленного доступа
Шифорвание и подпись в PGP/GPG
Шифорвание и подпись X.509 (OpenSSL + ГОСТ)
Запуск задач по расписанию. Исторический crond и таймеры в systemd
Брандмауэр Iptables. Работа netfilter в ядре и написание правил
Брандмауэр Firewalld
Cвои программы в роли сетевых сервисов. Сокеты в systemd
Ведение логов. Исторический syslog и современный journal
Контейнеры в Linux ограничение ресурсов и изоляция процессов