rpcbind - Como redefinir a porta aleatória

Publicado por Perfil removido em 03/04/2013

[ Hits: 11.312 ]

 


rpcbind - Como redefinir a porta aleatória



O serviço rpcbind substituiu o Portmap no Debian 7.

O utilitário NFS rpcbind escuta, por padrão, na porta TCP/111 e também abre uma porta UDP aleatória em todos os IPs (por exemplo, 0.0.0.0:730).

Normalmente, essa porta é acima de 1024, a menos que a opção "-s" seja utilizada. Alguns administradores não gostam de portas abertas aleatoriamente.

O programador Daniel Ryde, escreveu um código que permite especificar qual a porta UDP será utilizada no lugar da aleatória. O código foi modificado por Neale Rudd.

Eu testei no Debian 7 RC1 64 bits e adicionei notas de comentários que facilitam a compilação, instalação e uso. O desenvolvedor testou no Ubuntu 11.

* Atenção: utilize essa biblioteca por sua conta e risco. O desenvolvedor não dá qualquer suporte, e se encontrar erros, envie diretamente para:
Não tenho conhecimento de C para saber se esse código afeta a segurança do servidor de algum modo!

1. Como root, crie o arquivo "setrpcrandomport.c" no diretório /root.

2. Verifique suas ferramentas de compilação (GCC, Make, bison, Autoconf, etc), se precisar, instale ou atualize.

3. Compile como root:

# gcc -nostartfiles -fpic -shared setrpcrandomport.c -o setrpcrandomport.so -ldl -D_GNU_SOURCE

4. Stripe o arquivo:

# strip setrpcrandomport.so

5. Copie a biblioteca compilada para /lib:

# cp setrpcrandomport.so /lib

6. Atualize seu cache de bibliotecas manualmente:

# ldconfig

7. Crie o arquivo /etc/default/rpcbind com o conteúdo abaixo (de acordo com suas necessidades):

export LD_PRELOAD=/lib/setrpcrandomport.so
export RPC_RAND_PORT=12500
OPTIONS="-w -l -h 127.0.0.1"


8. Modifique o arquivo /etc/services incluindo a seguinte linha no lugar certo:

rpcbind-mod    12500/udp   # Porta Aleatória modificada para fixa


9. Inicie o serviço:

# service rpcbind start

Ou, rode diretamente para depuração:

# LD_PRELOAD=/lib/setrpcrandomport.so RPC_RAND_PORT=5800 rpcbind -w

10. Confira se a porta desejada está em uso e faça os ajustes necessários no seu firewall:

# netstat -au
Conexões Internet Ativas (servidores e estabelecidas)
Proto Recv-Q Send-Q Endereço Local          Endereço Remoto         Estado
udp        0      0 localhost.locald:sunrpc *:*
udp        0      0 *:rpcbind-mod           *:*

# netstat -aun
Conexões Internet Ativas (servidores e estabelecidas)
Proto Recv-Q Send-Q Endereço Local          Endereço Remoto         Estado
udp        0      0 127.0.0.1:111           0.0.0.0:*
udp        0      0 0.0.0.0:12500           0.0.0.0:*

Segue código fonte para compilação:

/*
   Copyright (C) 2013 Neale Rudd
   Based (almost completely) on bind.c (c) Daniel Ryde 2000

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   Lesser General Public License for more details.
*/

/*
   LD_PRELOAD library to make rpcbind set it's random port to a known value.

   This program was adapted from code made by Daniel Ryde:
   email: [email protected]
   web:   http://www.ryde.net/

   Modified by Neale Rudd for use with rpcbind and tcp6:
   web:   http://wiki.metawerx.net/
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <dlfcn.h>
#include <errno.h>


int (*real_bind)(int, const struct sockaddr *, socklen_t);

char *bind_port_env;
int bind_port_ns = -1;

void _init (void)
{
      const char *err;

      real_bind = dlsym (RTLD_NEXT, "bind");
      if ((err = dlerror ()) != NULL) {
         fprintf (stderr, "dlsym (bind): %s\n", err);
      }

      if (bind_port_env = getenv ("RPC_RAND_PORT")) {
         bind_port_ns = htons ( (int) strtol(bind_port_env, (char **)NULL, 10) );
      }
}

int bind (int fd, const struct sockaddr *sk, socklen_t sl)
{
      static struct sockaddr_in *lsk_in;

      lsk_in = (struct sockaddr_in *)sk;
      //printf("bind attempt: %d\n", ntohs(lsk_in->sin_port));

      if ((lsk_in->sin_family == AF_INET || lsk_in->sin_family == AF_INET6 )
         && (ntohs(lsk_in->sin_port) != 111)
         && (bind_port_env)) {
         //printf("binding to non 111: %d, will force to specified port\n", ntohs(lsk_in->sin_port));
         lsk_in->sin_port = bind_port_ns;
      }

      //printf("binding: %d\n", ntohs(lsk_in->sin_port));
      return real_bind (fd, sk, sl);
}


O código é "GNU Lesser 2.1", portanto, software livre.
Kyetoy.

Referências
Outras dicas deste autor

Fazendo VMware Workstation funcionar no Kernel 2.6.35

ActionCube - Um jogo leve e atraente

Joomla - Permissões na instalação no host

Use o Tor sem instalar nada em qualquer distribuição!

Descobrindo daemons (servidores) rodando em background

Leitura recomendada

Mudando gerenciador gráfico padrão no Conectiva e/ou Slackware

SARG: (html11) - Errinho chato

Configurando o modem Onda MSA190UP pelo NetworkManager

Ver interfaces USB em sistema guest WindowsXP no Virtualbox em OpenSUSE 11.0

Google Talk no Linux: diga adeus ao MSN/Hotmail

  

Comentários

Nenhum comentário foi encontrado.



Contribuir com comentário