Metawerx Java Hosting Small Logo

setrpcrandomport - LD_PRELOAD wrapper for rpcbind to force a specific port number for the rpc random port

The NFS rpcbind utility (formerly portmap) listens on port 111 by default, and also opens an additional random port listening on all IP addresses (eg: 0.0.0.0:34910).

The random port is typically above 1024, although on some installations unless the -s parameter is used, it may appear in the protected ports range (under 1024).

If you are like me and don't like unknowns, this small wrapper based on Daniel Ryde's bind.c code allows you to specify the port which rpcbind will open for it's "random port".

The tool is published under the GNU Lesser General Public License version 2.1, and full source code is included below.

No support is provided, this is just being made available to others who may find it helpful to improve system predictability.

A special thanks to Daniel Ryde for his extremely useful bind.c code, as well as getting me motivated to write some C again!

Compatibility

  • Designed for Ubuntu 11+, should work with earlier versions, any Linux, BSD, Solaris, Android and most other *nix variants, although the pre-configuration script location for your rpcbind may vary

Source Code and Instructions

/*
   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.

   The value is specified by the environment variable RPC_RAND_PORT.

   Compile and install on Linux with:

       gcc -nostartfiles -fpic -shared setrpcrandomport.c -o setrpcrandomport.so -ldl -D_GNU_SOURCE
       strip setrpcrandomport.so
       cp setrpcrandomport.so /lib

   Usage (Ubuntu - most likely works with other dists):

     Create a file called /etc/default/rpcbind as follows ...

       export LD_PRELOAD=/lib/setrpcrandomport.so
       export RPC_RAND_PORT=5800

     ... then restart rpcbind (will be done automatically on a reboot):

       service portmap restart

     ... or run diretly:

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

   This program was adapted from code made by Daniel Ryde:
   email: daniel@ryde.net
   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);
}

--Neale Rudd

navigation
metawerx specific
search
Share
tools
help

referring pages
...nobody

Share