CentOS 6.6; java 7: libjli.so не найден файл

Вопрос или проблема

Предыстория:

Я написал программу на Java для захвата сетевых пакетов. Код использует обёртку API вокруг libpcap и работает хорошо — до тех пор, пока я запускаю программу с правами sudo.

Сейчас я пытаюсь найти способ настроить все так, чтобы я мог запускать программу как “обычный” пользователь. В конечном итоге она будет запускаться на системе, где у меня нет привилегий sudo.

После некоторых исследований было найдено возможное решение, которое заключается в установке возможностей, предоставляющих привилегированный доступ определенным образом. Частью этого является установка возможностей CAP_NET_RAW и CAP_NET_ADMIN на ei (например, sudo setcap 'CAP_NET_RAW=ei CAP_NET_ADMIN=ei' program).

Проблема:

Итак, я сделал это для команды java на моей системе. К сожалению, это создало проблему (о чем уже спрашивали многие на различных форумах), когда при вызове java появляется следующее сообщение:

java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory

Эта библиотека действительно существует и отображается в списке библиотек для команды java.

$ sudo find / -name libjli.so -print
/opt/jdk1.7.0_79/lib/amd64/jli/libjli.so
/opt/jdk1.7.0_79/jre/lib/amd64/jli/libjli.so
/usr/java/jdk1.7.0_79/lib/amd64/jli/libjli.so
/usr/java/jdk1.7.0_79/jre/lib/amd64/jli/libjli.so
/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.35.x86_64/lib/amd64/jli/libjli.so
/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.35.x86_64/jre/lib/amd64/jli/libjli.so
$ which java
/usr/bin/java
$ ls -l /usr/bin/java
lrwxrwxrwx. 1 root root 22 Jun 22  2015 /usr/bin/java -> /etc/alternatives/java
$ ls -l /etc/alternatives/java
lrwxrwxrwx. 1 root root 25 Jun 22  2015 /etc/alternatives/java -> /opt/jdk1.7.0_79/bin/java
$ ls -l /opt/jdk1.7.0_79/bin/java
-rwxr-xr-x. 1 uucp 143 7718 Apr 10  2015 /opt/jdk1.7.0_79/bin/java
$ ldd /usr/bin/java
    linux-vdso.so.1 =>  (0x00007fff3f3fa000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003150c00000)
    libjli.so => /usr/java/jdk1.7.0_79/lib/amd64/jli/libjli.so (0x00007ff56d563000)
    libdl.so.2 => /lib64/libdl.so.2 (0x0000003151000000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003150800000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003150400000)

Кстати, я использую JDK 7, а не OpenJDK.

Так в чем же проблема? Все, кажется, на своих местах, но не может найти нужное. Имеет ли значение, что на машине установлены две версии Java? Существует ли какая-то другая странная ситуация?

Поиск показал, что с этой проблемой сталкивались многие, но я не смог найти ни причину, ни решение.

Кто-нибудь может помочь с этим?

ОБНОВЛЕНИЕ #1

После еще немного внимательного изучения оказалось, что проблема вызвана “функцией” в Java. Следующая ссылка включает другую ссылку, которая объясняет суть дела.

Проблема запуска java на Debian: “error while loading shared libraries: libjli.so” с вложенной ссылкой Почему программы с правами setuid в Java не работают.

Судя по прочитанному, кажется, что запуск java с включенными определенными возможностями не разрешен. Возможно, это изменится в будущем с улучшением безопасности Java.

Если кто-то знает об этом или, что важнее, знает о решении этой проблемы, пожалуйста, прокомментируйте.

если вы находитесь в среде chroot, вам нужно примонтировать /proc, чтобы java работала.

Если вы используете “strace”, вы увидите что-то вроде: readlink(“/proc/self/exe”, “/usr/lib/jvm/java-8-openjdk-amd6″…, 4096) Это значит, что Java сначала смотрит на “/proc/self/exe”, чтобы понять, где искать /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/../lib/amd64/jli/libjli.so. Итак, если нет /proc, он не может найти libjli.so.

С наилучшими пожеланиями!

Ответ или решение

Решение проблемы с библиотекой libjli.so в CentOS 6.6 при использовании Java 7

Фон проблемы

Вы написали Java-программу для захвата сетевых пакетов с использованием API-обертки для libpcap. Программа работает без проблем, когда вы запускаете её через sudo. Однако ваша цель – настроить программу так, чтобы она могла работать от имени обычного пользователя, поскольку в будущем она будет выполняться на системе без прав sudo.

Вы исследовали возможность настройки авторизаций сетевого уровня с помощью применения возможностей CAP_NET_RAW и CAP_NET_ADMIN к исполняемому файлу. Однако, после применения этой методики к команде java, вы сталкиваетесь с ошибкой:

java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory

Анализ проблемы

Проблема возникает из-за того, что Java не может найти библиотеку libjli.so, несмотря на то, что библиотека существует в системе. После выполнения команды ldd по пути /usr/bin/java, вы можете увидеть, что библиотека libjli.so должна находиться по пути /usr/java/jdk1.7.0_79/lib/amd64/jli/libjli.so.

Это связано с особенностью доступа к Java из-под привилегированных исполняемых файлов. При использовании setuid/setcap библиотека libjli.so может не распознаваться должным образом.

Решения и рекомендации

  1. Настройка переменных окружения: Убедитесь, что ваши переменные окружения JAVA_HOME и LD_LIBRARY_PATH правильно настроены так, чтобы они указывали на корректные пути вашей установки JDK. Например:

    export JAVA_HOME=/opt/jdk1.7.0_79
    export LD_LIBRARY_PATH=$JAVA_HOME/lib/amd64/jli
  2. Использование strace для диагностики: Используйте strace для отслеживания системных вызовов и выяснения, почему библиотека не может быть найдена. Это может дать дополнительный контекст для решения проблемы.

    strace /usr/bin/java -version
  3. Монтирование /proc: Если вы работаете в chroot окружении, проверьте, смонтирована ли файловая система /proc. Java может использовать /proc/self/exe для определения пути к исполняемым файлам, и отсутствие /proc может вызвать проблему.

    mount -t proc proc /your_chroot/proc
  4. Создание скрипта-обертки: Создайте скрипт, который устанавливает нужные переменные окружения перед запуском вашей Java программы не имея привилегий.

  5. Изучение альтернативных подходов: В будущем, возможно, стоит рассмотреть другие методы, позволяющие вашему приложению иметь нужные привилегии без использования setcap на Java.

Заключение

Ошибка с libjli.so при использовании привилегированных возможностей Java – это известная проблема, возникающая из-за специфики работы Java с библиотеками в Unix-системах. Применение предложенных методов может помочь в ее решении, позволяя вашему приложению работать без привилегий sudo, что особенно важно в средах с ограниченными правами доступа. Подготовка среды исполнения и правильное монтирование важны для корректной работы вашей Java программы на CentOS 6.6.

Оцените материал
Добавить комментарий

Капча загружается...