Permitir que um usuário deixe escutar uma porta abaixo de 1024

56

Eu preciso permitir que um usuário (diferente do root) execute um servidor escutando na porta 80.

Existe alguma maneira de fazer isso?

    
por peoro 06.04.2011 / 13:45

6 respostas

45

setcap 'cap_net_bind_service=+ep' /path/to/program

isso funcionará para processos específicos. Mas, para permitir que um usuário em particular se conecte a portas abaixo de 1024, você terá que adicioná-lo aos sudoers.

Dê uma olhada nestes discussão para mais.

    
por 06.04.2011 / 14:13
28

(Alguns desses métodos foram mencionados em outras respostas; estou dando várias opções possíveis em ordem aproximada de preferência.)

Você pode redirecionar a porta baixa para uma porta alta e ouvir na porta alta.

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 1080

Você pode iniciar seu servidor como privilégios root e drop depois de começar a escutar na porta privilegiada. De preferência, em vez de codificá-lo, inicie seu servidor a partir de um wrapper que faça o trabalho para você. Se o seu servidor iniciar uma instância por conexão, inicie-a em inetd (ou em um programa semelhante como xinetd ). Para inetd , use uma linha como esta em /etc/inetd.conf :

http  stream  tcp  nowait  username:groupname  /path/to/server/executable  argv[0] argv[1]…

Se o seu servidor atender em uma única instância, inicie-o em um programa como authbind . Crie um arquivo vazio /etc/authbind/byport/80 e torne-o executável para o usuário que está executando o servidor; ou crie /etc/authbind/byuid/1234 , em que 1234 é o UID que está executando o servidor, contendo a linha 0.0.0.0/0:80,80 .

Se o seu executável do servidor estiver armazenado em um sistema de arquivos que suporta recursos, você pode fornecer o cap_net_bind_service capacidade . Esteja ciente de que as capacidades ainda são relativamente novas e ainda têm algumas dobras.

setcap cap_net_bind_service=ep /path/to/server/executable
    
por 07.04.2011 / 01:53
4

A resposta curta é que isso não é possível por design.

A resposta longa é que nos mundos de código aberto há muitas pessoas brincando com o design e desenvolvendo métodos alternativos. Em geral, é prática amplamente aceita que isso não seja possível. O fato de você estar tentando provavelmente significa que você tem outra falha de projeto em seu sistema e deve reconsiderar toda a sua arquitetura de sistema à luz das melhores práticas e implicações de segurança do * nix.

Dito isso, um programa para autorizar o acesso não-root a portas baixas é authbind . Ambos selinux e grsecurity também fornecer estruturas para tais autenticações bem ajustadas.

Por último, se você quiser que usuários específicos executem programas específicos como root e o que você realmente precisa é apenas permitir que um usuário reinicie o apache ou algo parecido, sudo é seu amigo!

    
por 06.04.2011 / 14:31
3

Você pode usar o netcat ou xinetd ou o encaminhamento de porta do iptables, ou usar o apache como um proxy de front-end e executar o processo em uma porta sem privilégios.

    
por 06.04.2011 / 14:13
2

Authbind , @Gilles já mencionou isso, mas eu gostaria de expandir um pouco sobre isso.

Possui controle de acesso conveniente (detalhes na página de manual): você pode filtrar o acesso por porta, endereço de interface, uid, intervalos de endereço ou porta e combinação destes.

Tem um parâmetro muito útil --depth :

--depth levels

Causes authbind to affect programs which are levels deep in the calling graph. The default is 1.

"Níveis profundos" significa que quando um script (ou programa) executa outro script, ele desce um nível. Então, se você tem --depth 5 , isso significa que nos níveis 1 (ou é 0?) Até 5 você tem permissão para ligar, enquanto que no nível 6 e em diante, você não tem. Útil quando você quer que um script tenha acesso, mas não programas que são executados com ou sem o seu conhecimento.

Para ilustrar, você poderia ter algo assim: por questões de segurança, você tem um usuário java que serve apenas para executar java e você quer dar a ele acesso à porta 80:

sudo echo > /etc/authbind/byport/80 &&
chown root:java /etc/authbind/byport/80
chmod 710 /etc/authbind/byport/80

Eu criei o ../byport/80 file , dei-o ao grupo de usuários java (cada usuário tem seu próprio grupo) e o tornei executável por grupo, o que significa que ele é executável por java user. Se você está dando acesso por porta, o arquivo tem que ser executável pelo usuário que deve ter acesso, então fizemos isso.

Isso pode ser o suficiente para o Joe comum, mas como você sabe como usar o parâmetro --depth , execute (como java user) authbind --depth [depth] my_web_app's_start_script começando em --depth 1 e trabalhando até encontrar a menor profundidade que funciona e usar isso.

Leia a página de manual para detalhes .

    
por 27.09.2013 / 15:17
1

Eu tentei o método iptables PREROUTING REDIRECT, mas descobri que ele também afeta os pacotes encaminhados. Ou seja, se a máquina também estiver encaminhando pacotes entre interfaces (por exemplo, se estiver atuando como um ponto de acesso Wi-Fi conectado a uma rede Ethernet), a regra iptables também localizará as conexões dos clientes conectados aos destinos da Internet e as redirecionará para a máquina. Não é isso que eu queria - eu só queria redirecionar as conexões direcionadas para a própria máquina.

Uma possibilidade é usar o encaminhamento de porta TCP. Por exemplo. usando socat :

socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080

No entanto, uma desvantagem desse método é que o aplicativo que está escutando na porta 8080 não sabe o endereço de origem das conexões de entrada (por exemplo, para fins de registro ou outros fins de identificação).

    
por 04.09.2015 / 05:12