![]() |
![]() |
||||
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!
/* 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); }