rpcbind - Como redefinir a porta aleatória

Publicado por Perfil removido em 03/04/2013

[ Hits: 10.879 ]

 


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

Checando se sua webcam está funcionando no Famelix 2.0

Instalando o Firefox de forma diferente no Linux

Instalando o BrOffice.org no Vector Linux 6.0

Instalando o jogo Space Invaders no menu do GRUB

Mouse USB para de funcionar com pacote "laptop-mode-tools"

Leitura recomendada

Permissões persistentes em portas seriais

Ubuntu-eee: Bug na inicialização

Recuperando o GRUB no Ubuntu Linux

Resolvendo os problemas com o pacote install-info

Instalando repositório RPMforge no CentOS 6.2

  

Comentários

Nenhum comentário foi encontrado.



Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts