Como fazer com que o Oracle java 7 funcione com setcap cap_net_bind_service + ep

11

Estou tentando conceder ao executável java o direito de abrir portas abaixo de 1024 no Linux. Aqui está a configuração

  • /home/test/java contém o Oracle Server JRE 7.0.25
  • CentOS 6.4

Aqui está o que getcap retorna

[test@centos6 java]$ pwd
/home/test/java

[test@centos6 java]$ getcap bin/java
bin/java = cap_net_bind_service+ep

[test@centos6 java]$ getcap jre/bin/java
jre/bin/java = cap_net_bind_service+ep

Tentar executar o java dá o seguinte erro.

[test@centos6 java]$ bin/java
bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory
[test@centos6 java]$ jre/bin/java
jre/bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory

É possível executar o Java 7_u25 quando o binário recebeu privilégios elevados com o setcap; se sim, como?

JDK-6919633: O tempo de execução não suporta os recursos de arquivo POSIX (AKA Linux Capabilities) diz que

Note: when using the setcap the libraries needed by the java launcher
should be present in /usr/lib or any other "trusted" location that the
runtime loader (rtld) uses to find shared libraries.

Como faço para confiar nas bibliotecas compartilhadas?

ams
fonte

Respostas:

14

Até você fazer a pergunta, eu nunca ouvi falar desse recurso no Unix (recursos de arquivo). Encontrei este link que parece ter a solução de como fazer o ld.so confiar em suas bibliotecas compartilhadas:

trecho desse post

Quando alguém aumenta os privilégios de um executável, o runtime loader (rtld), melhor conhecido como ld.so, não se vincula às bibliotecas em caminhos não confiáveis. É assim que o ld.so (1) foi projetado. Se for necessário executar um executável, você precisará adicionar esse caminho aos caminhos confiáveis ​​do ld.so, a seguir, descreveremos como fazê-lo:

Fedora 11:
% uname -a
Linux localhost.localdomain 2.6.29.4-167.fc11.i686.PAE #1 SMP Wed May 27 17:28:22 EDT 2009 i686 i686 i386 GNU/Linux

% sudo setcap cap_net_raw+epi ./jdk1.7.0_04/bin/java

% ./jdk1.7.0_04/bin/java -version
./jdk1.7.0_04/bin/java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory

Ok, estamos na mesma página agora, para corrigir isso, crie um arquivo como este, com o caminho para libjli.so

% cat /etc/ld.so.conf.d/java.conf
/home/someuser/jdk1.7.0_04/jre/lib/i386/jli

Isso adicionará o nome do caminho ao caminho do usuário confiável que o ld.so usará para criar seu cache de tempo de execução, verificar se o ld.so o está vendo fazendo isso, precisar executá-lo como root e uma reinicialização .

% ldconfig | grep libjli
libjli.so -> libjli.so
.......

Agora teste o java:

% ./jdk1.7.0_04/bin/java -version
java version "1.7.0_04-ea"
Java(TM) SE Runtime Environment (build 1.7.0_04-ea-b18)

e aí está ...

Referências

slm
fonte
1
Essa abordagem parece ser uma mudança geral do sistema; existe uma maneira de restringir a confiança por usuário, para que o usuário foo e bar possam ter suas próprias versões diferentes de java com versões diferentes do libjli.so sem entrar em conflito.
24413
1
@ams: você está confiando em um programa para fornecer ao usuário uma capacidade que geralmente não possui. Isso é importante: você confia no código do programa para não usar mal (nem permitir que outros usem mal) esse recurso. É por isso que você precisa confiar nessas bibliotecas em todo o sistema.
Ninjalj 16/10
@ams Você pode usar o utilitário privbind para poder fazer isso por processo, não por executável.
mighq