Если на вашем IoT-шлюзе установлена операционная система с поддержкой SRM, каждый RPM-пакет, перед инсталляцией, нужно подписывать, даже если IMA-безопасность не используется. Из этого материала вы узнаете о том, как подписывать и устанавливать RPM-пакеты в операционных системах шлюзов с включенным и выключенным SRM.
То, о чём мы здесь расскажем, применимо к IoT-шлюзам Intel, основанным на процессорах Intel Atom, Intel Core и Intel Quark. Освоив это руководство, вы научитесь работать с RPM-пакетами. А именно, подписывать их, устанавливать, деинсталлировать. Так же мы рассмотрим сборку ОС для шлюзов и работу с ключами.
Ожидается, что читатель этого материала обладает следующими знаниями и навыками:
Здесь, под термином «шлюз» мы будем понимать «Шлюз Intel для Интернета вещей» («Intel IoT Gateway»). «Компьютер» – это Linux-система (предпочтительно – с Ubuntu 14.0.4 Base), которая используется для разработки приложений, предназначенных для шлюзов.
Так будут выделены команды, названия API, параметры, имена обычных и исполняемых файлов, пути в файловой системе.
Полужирный шрифт применяется для выделения упоминаний элементов пользовательского интерфейса, экранных кнопок и названий клавиш на клавиатуре.
А так выделены блоки текста, демонстрирующие реакцию системы на выполнение скрипта или исполнение команды, введённой с клавиатуры.
Для того, чтобы испытать на практике то, о чём пойдёт речь, у вас должен быть подготовленный к работе шлюз. На компьютере должна быть развёрнута среда разработки Wind River.
Рассмотрим, как собрать и установить на шлюзе операционную систему с включенной функцией безопасности (SRM). Когда безопасность включена, перед установкой RPM-пакетов на шлюз их нужно подписывать. Для начала модифицируем скрипт конфигурации операционной системы шлюза.
Теперь соберём операционную систему шлюза. Для этого в папке $HOME/Projects нужно выполнить такую команду:
Обратите внимание на то, что на выполнение команды, которая собирает образ операционной системы для установки на шлюз, может потребоваться несколько часов. Всё зависит от мощности компьютера, который применяется для разработки.
Скопируем собранный образ на загрузочный флэш-диск. Его ёмкость должна быть, как минимум, 4 Гб. При этом учитывайте, что при записи образа ОС все данные с диска будут удалены.
Теперь установим операционную систему на шлюз. Обратите внимание на то, что перед загрузкой шлюза с флэш-диска нужно внести соответствующие изменения в BIOS. Здесь, в разделе «Appendix: Setup BIOS Boot from USB», можно найти подробности об этом. Когда шлюз будет готов к загрузке с внешнего носителя, выполните следующие шаги:
Создадим проект, который включает в себя незащищённый RPM-пакет. Назовём его hello. Так как в этом пакете безопасность (SRM) отключена, его можно использовать для того, чтобы поэкспериментировать с подписями.
Следующие действия нужно выполнить на компьютере.
Создадим три папки, в которые нужно будет скопировать пакет hello. В одну из них поместим ключи, которые нужны для того, чтобы подписать пакет. Мы, в учебных целях, рассмотрим не только правильный способ подписывания и установки пакетов, но и неправильный.
Следующие действия нужно выполнить на компьютере.
В разделе «SRM в операционной системе шлюза» были созданы ключи, которые подходят для подписывания RPM-пакетов. В предыдущем разделе мы скопировали эти ключи и пакет hello в папку $HOME/project_nonsrm/rpmtest/goodkeys.
Сейчас создадим собственный набор ключей, которые поместим в папку badkeys. И, хотя эти ключи являются вполне нормальными, они не подходят для подписывания пакета, поэтому мы считаем их «неправильными». Цель создания этих ключей заключается в том, чтобы вы увидели, что произойдёт, если воспользоваться неподходящими ключами для подписывания пакета.
Следующие действия нужно выполнить на компьютере.
Пакеты подписывают закрытым ключом поставщика, и, когда пакет устанавливают на шлюз, вместе с ними устанавливается и ключ vendor-cert.pem. Он используется для проверки подписи. Сейчас мы, с помощью команды SST sign-rpm, подпишем пакеты, расположенные в папках с неподходящими и подходящими ключами.
Рассмотрим установку пакетов на шлюз. Напомним, что в учебных целях мы пытаемся установить следующие пакеты:
Эти действия нужно выполнять на шлюзе.
Выше мы успешно установили правильно подписанный пакет. Теперь удалим его.
Рассмотрим методы работы с сертификатами на шлюзе.
Вот, что вы узнали, изучив этот материал:
То, о чём мы здесь расскажем, применимо к IoT-шлюзам Intel, основанным на процессорах Intel Atom, Intel Core и Intel Quark. Освоив это руководство, вы научитесь работать с RPM-пакетами. А именно, подписывать их, устанавливать, деинсталлировать. Так же мы рассмотрим сборку ОС для шлюзов и работу с ключами.
Ожидается, что читатель этого материала обладает следующими знаниями и навыками:
- Исполнение команд Linux.
- Создание, правка, исполнение скриптов.
- Установка и настройка программного обеспечения для Linux
- Использование эмулятора терминала, наподобие Putty, при наличии соединения между компьютерами по последовательному интерфейсу.
Здесь, под термином «шлюз» мы будем понимать «Шлюз Intel для Интернета вещей» («Intel IoT Gateway»). «Компьютер» – это Linux-система (предпочтительно – с Ubuntu 14.0.4 Base), которая используется для разработки приложений, предназначенных для шлюзов.
Так будут выделены команды, названия API, параметры, имена обычных и исполняемых файлов, пути в файловой системе.
Полужирный шрифт применяется для выделения упоминаний элементов пользовательского интерфейса, экранных кнопок и названий клавиш на клавиатуре.
Блоки текста, выделенные таким шрифтом – это команды, которые вам нужно будет ввести с клавиатуры или добавить в файл скрипта.
А так выделены блоки текста, демонстрирующие реакцию системы на выполнение скрипта или исполнение команды, введённой с клавиатуры.
Для того, чтобы испытать на практике то, о чём пойдёт речь, у вас должен быть подготовленный к работе шлюз. На компьютере должна быть развёрнута среда разработки Wind River.
SRM в операционной системе шлюза
Рассмотрим, как собрать и установить на шлюзе операционную систему с включенной функцией безопасности (SRM). Когда безопасность включена, перед установкой RPM-пакетов на шлюз их нужно подписывать. Для начала модифицируем скрипт конфигурации операционной системы шлюза.
- При установке среды разработки на компьютер был создан скрипт config.sh, который расположен в папке $HOME/Project. Отредактируйте этот скрипт следующим образом:
Включите в него это:
--with-layer=wr-ima-appraise
--without-layer=wr-mcafee
Найдите и удалите следующее:
wr-ima-appraise из выражения --without-layer=.
wr-mcafee из выражения --with-layer=.
- Сохраните и закройте файл config.sh
- Запустите config.sh
Теперь соберём операционную систему шлюза. Для этого в папке $HOME/Projects нужно выполнить такую команду:
make fs
Обратите внимание на то, что на выполнение команды, которая собирает образ операционной системы для установки на шлюз, может потребоваться несколько часов. Всё зависит от мощности компьютера, который применяется для разработки.
Переносим образа ОС на флэш-диск
Скопируем собранный образ на загрузочный флэш-диск. Его ёмкость должна быть, как минимум, 4 Гб. При этом учитывайте, что при записи образа ОС все данные с диска будут удалены.
- Выведите список накопителей компьютера:
ls /dev/sd?
- Подключите USB-диск к компьютеру.
- Снова выполните команду из шага №1 и сравните её результаты с теми, что были получены до подключения диска. Нужно это для того, чтобы определить, как в системе отображается новый флэш-диск:
ls /dev/sd?
Вот, как выглядит выполнение вышеописанной последовательности действий.
Вывод списка устройств хранения данных, подключённых к компьютеру
На следующем шаге вам понадобится знать имя USB-диска в системе. В нашем случае это — /dev/sdb.
- Перейдите в папку $HOME/Project:
cd $HOME/Project
- Разверните образ ОС шлюза на USB-диске. Скомпилированный файл операционной системы имеет имя, соответствующее типу процессора шлюза. Используйте команду, подходящую для того шлюза, на который планируется установить ОС, при этом замените ??? на имя флэш-диска, выясненное выше. Запись образа занимает около 15 минут.
Команда для шлюзов с процессором Intel Atom:
sudo ./deploy.sh -u -f export/intel-baytrail-64-idp-idp-dist.tar.bz2 \-d /dev/??? -y; sync
Команда для шлюзов с процессором Intel Core:
sudo ./deploy.sh -u -f export/intel-haswell-64-idp-idp-dist.tar.bz2 \-d /dev/??? -y; sync
Команда для шлюзов с процессором Intel Quark:
sudo ./deploy.sh -u -f export/intel-quark-idp-idp-dist.tar.bz2 \-d /dev/??? -y -u -b cross-hill; sync
- Если будет нужно, введите пароль и нажмите ОК. Когда вы увидите сообщение DONE!, это будет означать, что загрузочный USB-диск создан.
- Отключите диск от компьютера и подключите его снова. Он, после монтирования, будет выглядеть как два раздела, один из которых доступен по адресу
/media/<username>/wr_usb_boot
- Скопируйте файл образа операционной системы шлюза на флэш-диск с помощью подходящей команды. При этом, замените username на имя пользователя, под которым работаете в Linux.
Команда для шлюзов с процессором Intel Atom:
sudo cp export/intel-baytrail-64-idp-idp-dist.tar.bz2 /media/<username>/wr_usb_boot/opt/; sync
Команда для шлюзов с процессором Intel Core:
sudo cp export/intel-haswell-64-idp-idp-dist.tar.bz2 /media/<username>/wr_usb_boot/opt/; sync
Команда для шлюзов с процессором Intel Quark:
sudo cp export/intel-quark-idp-idp-dist.tar.bz2 /media/<username>/wr_usb_boot/opt/; sync
- Отключите флэш-диск от компьютера
Устанавливаем ОС на шлюз
Теперь установим операционную систему на шлюз. Обратите внимание на то, что перед загрузкой шлюза с флэш-диска нужно внести соответствующие изменения в BIOS. Здесь, в разделе «Appendix: Setup BIOS Boot from USB», можно найти подробности об этом. Когда шлюз будет готов к загрузке с внешнего носителя, выполните следующие шаги:
- Отключите питание шлюза, подключите к нему USB-диск и включите питание. Войдите в систему с именем пользователя root и таким же паролем.
- Установите операционную систему на шлюз с помощью подходящей команды:
Команда для шлюзов с процессором Intel Atom и Intel Core:
tgt=/dev/sda /sbin/reset_media
Команда для шлюзов с процессором Intel Quark:
/sbin/reset_media
На вопрос Restore the boot media to its factory defaults ответьте yes. Установка может занять около 20 минут.
Если вы столкнётесь с сообщением об ошибке следующего содержания: ERROR: Unmount /dev/sda1 failed!, это означает, что шлюз не смог загрузиться с флэш-диска. Проверьте порядок загрузки и параметры UEFI для того, чтобы выяснить, является ли первым загрузочным устройством внешний накопитель.
- Сообщение DONE! будет означать, что установка ОС завершена. Выключите шлюз такой командой:
poweroff
- Отключите USB-накопитель от шлюза и включите питание устройства.
Если на данном этапе вы столкнётесь с сообщением об ошибке, например, с таким: Reboot and select proper boot device, проверьте настройки BIOS шлюза. А именно, нужно, чтобы на первом месте в списке загрузки был встроенный накопитель.
- Войдите в систему, использовав, в качестве имени пользователя и пароля, root.
Собираем незащищённый RPM-пакет
Создадим проект, который включает в себя незащищённый RPM-пакет. Назовём его hello. Так как в этом пакете безопасность (SRM) отключена, его можно использовать для того, чтобы поэкспериментировать с подписями.
Следующие действия нужно выполнить на компьютере.
- Создайте директорию для проекта:
mkdir -p $HOME/project_nosrm cd $HOME/project_nosrm
- Выберите команду, соответствующую шлюзу, которым пользуетесь, и, скопировав её в командную строку Linux, исполните. Это настроит среду разработки на сборку учебного пакета без SRM.
Команда для шлюзов с процессором Intel Atom:
$HOME/WindRiver/wrlinux-7/wrlinux/configure --enable-addons=wr-idp --enableboard=intel-baytrail-64 --enable-kernel=idp --enable-rootfs=idp --with-layer=wriot,wr-wks-oneagent-oma-dm-ia --with-template=feature/recovery,feature/openjdkbin,feature/realtek --without-layer=wr-srm
Команда для шлюзов с процессором Intel Core:
$HOME/WindRiver/wrlinux-7/wrlinux/configure --enable-addons=wr-idp --enableboard=intel-haswell-64 --enable-kernel=idp --enable-rootfs=idp --with-layer=wriot,wr-wks-oneagent-oma-dm-ia --with-template=feature/recovery,feature/openjdkbin,feature/realtek --without-layer=wr-srm
Команда для шлюзов с процессором Intel Quark:
$HOME/WindRiver/wrlinux-7/wrlinux/configure --enable-addons=wr-idp --enableboard=intel-quark --enable-kernel=idp --enable-rootfs=idp --with-layer=wr-iot,wrwks-oneagent-oma-dm-ia --with-template=feature/recovery,feature/openjdkbin,feature/realtek --without-layer=wr-srm
- Соберите пакет hello:
make -C build hello
Пакет будет собран и сохранён.
- Точное имя папки и файла пакета будет отличаться в зависимости от шлюза, для которого этот пакет готовился. Выясните имя и расположение пакета, сделать это можно так:
cd $HOME/project_nosrm/bitbake_build/ find . -name hello*.rpm
Запишите то, что удалось узнать. Эти сведения понадобятся нам в следующем разделе. Там мы скопируем пакет hello в три папки и разберёмся с тем, как правильно подписывать пакеты.
Копии пакета и правильный ключ
Создадим три папки, в которые нужно будет скопировать пакет hello. В одну из них поместим ключи, которые нужны для того, чтобы подписать пакет. Мы, в учебных целях, рассмотрим не только правильный способ подписывания и установки пакетов, но и неправильный.
Следующие действия нужно выполнить на компьютере.
- Создайте директории, которые будут использоваться для экспериментов с подписанным, неподписанным и неправильно подписанным пакетом. У них, соответственно, будут такие имена: goodkeys, notsigned, badkeys. А располагаться они будут в папке rpmtest.
cd $HOME/project_nosrm/ mkdir rpmtest mkdir rpmtest/notsigned mkdir rpmtest/badkeys mkdir rpmtest/goodkeys
- Скопируйте неподписанный пакет hello в каждую из папок. Вводя команды, замените [RPM directory] и [hello file] на соответствующие имена папки и файла пакета из вашего проекта:
cp $HOME/Project/bitbake_build/tmp/deploy/[RMP directory]/[hello file].rpm rpmtest/notsigned cp $HOME/Project/bitbake_build/tmp/deploy/[RMP directory]/[hello file].rpm rpmtest/badkeys cp $HOME/Project/bitbake_build/tmp/deploy/[RMP directory]/[hello file].rpm rpmtest/goodkeys
- В результате выполнения операций, описанных в разделе «SRM в операционной системе шлюза», вы, кроме прочего, создали правильные ключи (сертификаты), которые подходят для того, чтобы подписывать ими пакеты. Скопируйте эти ключи в папку goodkeys.
cp $HOME/Project/layers/wr-idp/wr-srm/files/keys/*.pem rpmtest/goodkeys
- Проверьте, действительно ли файлы с ключами были скопированы в папку. А именно, там должно быть пять необходимых для дальнейшей работы файлов: RPM-файл пакета, два ключа (сертификата) владельца (owner keys) и два ключа поставщика (vendor keys). Выполните такую команду:
ls -1 rpmtest/goodkeys
Если всё сделано так, как нужно, она должна выдать следующий список файлов:
[hello file].rpm
owner-cert.pem
owner-private.pem
vendor-cert.pem
vendor-private.pem
В итоге, на данном этапе у вас должно получиться следующее:
— Папки notsigned и badkeys содержат пакет hello, но файлов с ключами в них нет.
— Папка goodkeys содержит пакет hello и правильные файлы ключей. При этом пакет пока не подписан.
Создаём ключи
В разделе «SRM в операционной системе шлюза» были созданы ключи, которые подходят для подписывания RPM-пакетов. В предыдущем разделе мы скопировали эти ключи и пакет hello в папку $HOME/project_nonsrm/rpmtest/goodkeys.
Сейчас создадим собственный набор ключей, которые поместим в папку badkeys. И, хотя эти ключи являются вполне нормальными, они не подходят для подписывания пакета, поэтому мы считаем их «неправильными». Цель создания этих ключей заключается в том, чтобы вы увидели, что произойдёт, если воспользоваться неподходящими ключами для подписывания пакета.
Следующие действия нужно выполнить на компьютере.
- Средство для работы с ключами находится в папке проекта $HOME/Project, в котором используется SRM. В папке проекта, в котором SRM не применяется, создайте символьную ссылку на средство для работы с ключами:
cd $HOME/project_nonsrm/rpmtest ln -s $HOME/Project/SST SST
- Создайте ключ владельца и поместите его в папку $HOME/project_nonsrm/rpmtest/badkeys. Этот вполне рабочий ключ, но он не подходит для подписывания RPM-пакета.
./SST create-key --role=owner --name=badowner --output-dir=./badkeys/
- Создайте ключ поставщика и поместите его в ту же папку:
./SST create-key --role=vendor --issuer=badowner --name=badvendor --output-dir=./ badkeys
- Проверьте, содержит ли папка $HOME/project_nonsrm/rpmtest/badkeys все необходимые файлы:
ls -1 ./badkeys
Если всё сделано правильно, команда выдаст следующий список:
badowner-cert.pem
badowner-private.pem
badvendor-cert.pem
badvendor-private.pem
[hello file].rpm
Вот, что теперь у нас есть:
— Пакет hello и ключи, подходящие для его подписывания в папке goodkeys.
— Пакет hello и неподходящие ключи в папке badkeys.
— Пакет hello в папке notsigned без каких-либо ключей.
Наш пакет всё ещё не подписан, займёмся этим в следующем разделе.
Подписываем RPM-пакет
Пакеты подписывают закрытым ключом поставщика, и, когда пакет устанавливают на шлюз, вместе с ними устанавливается и ключ vendor-cert.pem. Он используется для проверки подписи. Сейчас мы, с помощью команды SST sign-rpm, подпишем пакеты, расположенные в папках с неподходящими и подходящими ключами.
- Перейдите в папку, которая содержит пакет и неподходящие ключи:
cd $HOME/project_nosrm/rpmtest/badkeys
- Подпишите пакет hello, который находится в этой папке, с помощью неподходящего ключа, заменив в команде, приведённой ниже, [hello file] на имя файла пакета:
../SST sign-rpm --mode=rpm --priv-key=badvendor-private.pem ./[hello file].rpm
- Перейдите в папку с подходящими ключами:
cd $HOME/project_nosrm/rpmtest/goodkeys
- Подпишите с их помощью пакет, находящийся в той же папке:
../SST sign-rpm --mode=rpm --priv-key=badvendor-private.pem ./[hello file].rpm
- Так как символьная ссылка на средство для работы с ключами больше не нужна, удалите её.
cd $HOME/project_nosrm/rpmtest rm SST
- Подключите к компьютеру USB-диск.
- На данном этапе имеются следующие файлы и папки:
— Пакет hello, подписанный подходящим ключом в папке goodkeys.
— Пакет hello, подписанный неподходящим ключом в папке badkeys.
— Неподписанный пакет hello в папке notsigned.
Поместите все три папки в tar-архив и скопируйте его на USB-диск. В данном примере USB-диск смонтирован как /media/rpmflash. Отредактируйте команды, приведённые ниже, в соответствии с тем, как диск отображается в вашей системе.
cd $HOME/project_nosrm tar czvf rpmtest.tar.gz rpmtest cp rpmtest.tar.gz /media/rpmflash
- Размонтируйте USB-диск, отключите его от компьютера и подключите к USB-порту шлюза.
- Скопируйте файл rpmtest.tar.gz на накопитель шлюза и распакуйте архив в той же директории, куда скопировали его. В данном примере USB-диск смонтирован как /media/sdb1, отредактируйте команду так, чтобы она соответствовала состоянию вашего шлюза:
cd root cp /media/sdb1/rpmtest.tar.gz /root tar xzvf rpmtest.tar.gz
- Проверьте MD5-сигнатуры пакетов:
cd rpmtest find . -name hello* -exec md5sum {} \;
То, что получится у вас, будет похоже на вывод, показанный ниже, но сигнатуры будут другими. Самое главное – проверьте, чтобы все они были разными.
2430f938a6f96a0eeff2459ccb7b4ee8 ./badkeys/[hello file].rpm
0f631d629b8a7aa4c8e86ee13bdb9cfb ./notsigned/[hello file].rpm
a83507c6f5b1eeec49b034a2aae44968 ./goodkeys[hello file].rpm
Устанавливаем пакеты
Рассмотрим установку пакетов на шлюз. Напомним, что в учебных целях мы пытаемся установить следующие пакеты:
- Неподписанный пакет.
- Пакет, подписанный неправильным ключом.
- Пакет, подписанный правильным ключом.
Эти действия нужно выполнять на шлюзе.
- Попытайтесь установить неподписанный пакет, заменив [hello file], на то имя, которое дано вашему файлу:
cd /root/rpmtest/notsigned rpm -ivh [hello file].rpm
В результате выполнения этой команды будет выведено сообщение об ошибке:
RPM [hello file].rpm is not signed with extend openssl signature
- Попытайтесь установить пакет, который подписан неверным ключом. Так же, как и в первом пункте, используйте в команде имя вашего .rpm-файла:
cd /root/rpmtest/badkeys rpm -ivh [hello file].rpm
На выходе снова получаем сообщение об ошибке, но уже другого содержания:
MD5 Code:e91148db3dd3a5e0bdb76ea5a8fa8e34
Can not find the right certificate for RPM [hello file].rpm
- Теперь установите правильно подписанный пакет.
cd /root/rpmtest/goodkeys rpm -ivh [hello file].rpm
В данном случае перед нами – сообщение об успешной установке.
MD5 Code:e91148db3dd3a5e0bdb76ea5a8fa8e34
Find right certificate: vendor-cert.pem
Certificate vendor-cert.pem is verified successfully
RPM package [hello file].rpm is verified successfully
Preparing… ########################################### [100%]
1:hello ########################################### [100%]
Import IMA signatures successfully Update IMA signatures successfully
- Протестируйте установленный пакет:
hello
Если программа была успешно выполнена, вот что она выведет:
Hello World
Деинсталлируем пакеты
Выше мы успешно установили правильно подписанный пакет. Теперь удалим его.
- Проверим, установлен ли пакет hello. В предыдущем разделе мы проверяли это, запуская программу, здесь поступим иначе:
rpm -qa | grep hello
Эта команда выведет имя пакета, что указывает на то, что он установлен.
- Удалим пакет:
rpm -e hello
- Проверим, действительно ли пакет удалён:
rpm -qa | grep hello hello
Как и следовало ожидать, появилось сообщение об ошибке:
-sh: hello: command not found
Сертификаты: получаем сведения, удаляем и устанавливаем
Рассмотрим методы работы с сертификатами на шлюзе.
- Выполните команду, которая выведет список сертификатов:
imtools --listcert
Она сообщит сертификате, который был скопирован в папку $HOME/project_nosrm/rpmtest/goodkeys в разделе «Копии пакета и правильный ключ».
vendor-cert.pem
- Удалите сертификат:
imtools --removecert vendor-cert.pem
На выходе будет такое сообщение:
Remove certificate vendor-cert.pem successfully
- Снова выведите список сертификатов для того, чтобы проверить, действительно ли сертификат был удалён:
imtools –listcert
Так как сертификат удалён, в результате выполнения команды ничего выведено не будет.
- Проверьте, можно ли установить сертификат из папки $HOME/project_nosrm/rpmtest/goodkeys. Если это так – установите его.
cd /root/rpmtest/goodkeys imtools --verifycert vendor-cert.pem
Эта пара команд выведет сообщения об успешной проверке и установке сертификата:
Certificate vendor-cert.pem is verified successfully
Certificate vendor-cert.pem is installed successfully
Итоги
Вот, что вы узнали, изучив этот материал:
- Как включать поддержку SRM на шлюзе.
- Как создавать проект для подготовки RPM-пакета с отключенным SRM для целей тестирования.
- Как создать подписанный, неподписанный и подписанный неправильно пакеты для того, чтобы проверить реакцию ОС шлюза на установку таких пактов.
- Как инсталлировать и деинсталлировать пакеты на шлюз.
- Как просматривать, добавлять и удалять сертификаты на шлюзе.
Поделиться с друзьями