Am Donnerstag, 18. Oktober 2012 19:17 CEST, Theo de Raadt 
<dera...@cvs.openbsd.org> schrieb: 
 
> As you note, this has come up before, and the same reasons exist then
> as now.
> 
> The security model makes no sense: firewall, but allow NFS.

Yes, its not optimal ;)

Before with my search, I only found the one I pointed out, now I searched 
further, and I found the 
thread: 
http://old.nabble.com/mountd%3A-user-specified-port-td32147473.html#a32151940

reading up that, I see good points in the arguments from Christopher Zimmerman.

Anyways, since in my case, I only need a read-only export, I can also go with 
sharing the files via http.
Both networks that are separated with the firewall, have about the same trust 
level. 
So now someone could argue, why the hell a firewall in there at all, but that's 
a different topic ;)

So let me shut up and forget about it.

cheers,
Sebastian


> 
> > getting NFS through a firewall is not that trivial with mountd binding to a 
> > random port each time it starts.
> > The patch below allows to specify a port which mountd will use.
> > 
> > The idea and the patch is not from me. 99% is based on an old patch 
> > submitted to tech@ in 2007:
> > http://old.nabble.com/-PATCH--mountd-to-listen-to-specified-port-td11075352.html
> > The patch did not got much attention at that time, hope for a bit more now 
> > ;)
> > 
> > Only one or two minor tweaks were necessary to bring it to compile without 
> > warnings.
> > Tested and works well for me on i386/amd64.
> > 
> > comments, rants or even test reports are welcome.
> > 
> > cheers,
> > Sebastian
> > 
> > 
> > Index: include/rpc/svc.h
> > ===================================================================
> > RCS file: /cvs/src/include/rpc/svc.h,v
> > retrieving revision 1.12
> > diff -u -r1.12 svc.h
> > --- include/rpc/svc.h       1 Sep 2010 14:43:34 -0000       1.12
> > +++ include/rpc/svc.h       17 Oct 2012 10:33:06 -0000
> > @@ -305,6 +305,9 @@
> >  __BEGIN_DECLS
> >  extern SVCXPRT *svcudp_create(int);
> >  extern SVCXPRT *svcudp_bufcreate(int, unsigned int, unsigned int);
> > +extern SVCXPRT *svcudp_create2(int, int, u_short);
> > +extern SVCXPRT *svcudp_bufcreate2(int, int, u_short, unsigned int,
> > +               unsigned int);
> >  __END_DECLS
> >  
> >  
> > @@ -313,6 +316,7 @@
> >   */
> >  __BEGIN_DECLS
> >  extern SVCXPRT *svctcp_create(int, unsigned int, unsigned int);
> > +extern SVCXPRT *svctcp_create2(int, int, u_short, unsigned int, unsigned 
> > int);
> >  __END_DECLS
> >  
> >  /*
> > Index: lib/libc/rpc/rpc.3
> > ===================================================================
> > RCS file: /cvs/src/lib/libc/rpc/rpc.3,v
> > retrieving revision 1.45
> > diff -u -r1.45 rpc.3
> > --- lib/libc/rpc/rpc.3      27 Sep 2012 11:31:58 -0000      1.45
> > +++ lib/libc/rpc/rpc.3      17 Oct 2012 10:33:11 -0000
> > @@ -52,7 +52,7 @@
> >  .\"   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> >  .\"   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> >  .\"
> > -.Dd $Mdocdate: September 27 2012 $
> > +.Dd $Mdocdate: October 15 2012 $
> >  .Dt RPC 3
> >  .Os
> >  .Sh NAME
> > @@ -109,8 +109,12 @@
> >  .Nm svcfd_create ,
> >  .Nm svcraw_create ,
> >  .Nm svctcp_create ,
> > +.Nm svctcp_create2 ,
> >  .Nm svcudp_create ,
> >  .Nm svcudp_bufcreate ,
> > +.Nm svcudp_bufcreate2 ,
> > +.Nm svcudp_create ,
> > +.Nm svcudp_create2 ,
> >  .Nm xdr_accepted_reply ,
> >  .Nm xdr_authunix_parms ,
> >  .Nm xdr_callhdr ,
> > @@ -234,11 +238,19 @@
> >  .Ft SVCXPRT *
> >  .Fn svctcp_create "int sock" "u_int send_buf_size" "u_int recv_buf_size"
> >  .Ft SVCXPRT *
> > +.Fn svctcp_create2 "int sock" "int family" "u_short port" "u_int 
> > send_buf_size" "u_int recv_buf_size"
> > +.Ft SVCXPRT *
> >  .Fn svcfd_create "int fd" "u_int sendsize" "u_int recvsize"
> >  .Ft SVCXPRT *
> >  .Fn svcudp_create "int sock"
> >  .Ft SVCXPRT *
> >  .Fn svcudp_bufcreate "int sock" "u_int sendsz" "u_int recvsz"
> > +.Ft SVCXPRT *
> > +.Fn svcudp_bufcreate2 "int sock" "int family" "u_short port" "u_int 
> > sendsz" "u_int recvsz"
> > +.Ft SVCXPRT *
> > +.Fn svcudp_create "int sock"
> > +.Ft SVCXPRT *
> > +.Fn svcudp_create2 "int sock" "int family" "u_short port"
> >  .Ft bool_t
> >  .Fn xdr_accepted_reply "XDR *xdrs" "struct accepted_reply *ar"
> >  .Ft bool_t
> > @@ -1096,6 +1108,13 @@
> >  users may specify the size of buffers; values of zero
> >  choose suitable defaults.
> >  .Pp
> > +.Fn svctcp_create2
> > +supersedes
> > +.Fn svctcp_create
> > +function. It allows to specify address family and port number also. This
> > +function accepts AF_INET and AF_INET6 address families. If port is equal 
> > to 0,
> > +the function tries to bind socket to one of reserved ports.
> > +.Pp
> >  .Fn svcfd_create
> >  will create a service on top of any open descriptor.
> >  Typically, this descriptor is a connected socket for a stream protocol such
> > @@ -1131,6 +1150,13 @@
> >  except that it allows the user to specify the maximum packet size for 
> > sending
> >  and receiving UDP-based RPC
> >  messages instead of using the default size limit of 8800 bytes.
> > +.Pp
> > +.Fn svcudp_bufcreate2
> > +supersedes
> > +.Fn svcudp_bufcreate
> > +function. It allows to specify address family and port number also. This
> > +function accepts AF_INET and AF_INET6 address families. If port is equal 
> > to 0,
> > +the function tries to bind socket to one of reserved ports.
> >  .Pp
> >  .Fn xdr_accepted_reply
> >  is used for encoding RPC reply messages.
> > Index: lib/libc/rpc/svc_tcp.c
> > ===================================================================
> > RCS file: /cvs/src/lib/libc/rpc/svc_tcp.c,v
> > retrieving revision 1.30
> > diff -u -r1.30 svc_tcp.c
> > --- lib/libc/rpc/svc_tcp.c  1 Sep 2010 14:43:34 -0000       1.30
> > +++ lib/libc/rpc/svc_tcp.c  17 Oct 2012 10:33:12 -0000
> > @@ -136,7 +136,7 @@
> >  
> >     if (sock == RPC_ANYSOCK) {
> >             if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
> > -                   perror("svctcp_.c - udp socket creation problem");
> > +                   perror("svctcp_.c - tcp socket creation problem");
> >                     return (NULL);
> >             }
> >             madesock = TRUE;
> > @@ -186,6 +186,119 @@
> >             return (NULL);
> >     }
> >     return (xprt);
> > +}
> > +
> > +/*
> > + * This function creates sock (with specified adress family) if sock is -1.
> > + * Then binds it to the specified port. It's possible to create v4 and v6
> > + * sockets.
> > + */
> > +SVCXPRT *
> > +svctcp_create2(int sock, int af, u_short port, u_int sendsize, u_int 
> > recvsize)
> > +{
> > +   struct tcp_rendezvous *r;
> > +   SVCXPRT *xprt;
> > +   struct sockaddr *sa;
> > +   struct sockaddr_in sin;
> > +#ifdef INET6
> > +   struct sockaddr_in6 sin6;
> > +#endif
> > +   socklen_t salen;
> > +   bool_t madesock;
> > +   int error;
> > +
> > +#ifdef INET6
> > +   if (af != AF_INET && af != AF_INET6)
> > +           return (NULL);
> > +#else
> > +   if (af != AF_INET)
> > +           return (NULL);
> > +#endif
> > +
> > +   madesock = FALSE;
> > +
> > +   if (sock == RPC_ANYSOCK) {
> > +           sock = socket(af, SOCK_STREAM, 0);
> > +           if (sock == -1)
> > +                   return (NULL);
> > +           madesock = TRUE;
> > +   }
> > +
> > +   if (af == AF_INET) {
> > +           memset(&sin, 0, sizeof(sin));
> > +           sin.sin_family = AF_INET;
> > +           sin.sin_port = htons(port);
> > +           sin.sin_addr.s_addr = INADDR_ANY;
> > +           salen = sizeof(sin);
> > +           sa = (struct sockaddr *)&sin;
> > +   }
> > +#ifdef INET6
> > +   else {
> > +           memset(&sin6, 0, sizeof(sin6));
> > +           sin6.sin_family = AF_INET6;
> > +           sin6.sin_port = htons(port);
> > +           sin6.sin_addr.s_addr = in6addr_any;
> > +           salen = sizeof(sin6);
> > +           sa = (struct sockaddr *)&sin6;
> > +   }
> > +#endif     /* INET6 */
> > +
> > +   switch (port) {
> > +   case 0:
> > +           error = bindresvport_sa(sock, sa);
> > +           if (error == 0)
> > +                   break;
> > +           /* FALLTHOUGH */
> > +   default:
> > +           error = bind(sock, sa, salen);
> > +           break;
> > +   }
> > +
> > +   if (error != 0 || listen(sock, 2) != 0) {
> > +           if (madesock)
> > +                   close(sock);
> > +           return (NULL);
> > +   }
> > +
> > +   if (port == 0) {
> > +           if (getsockname(sock, sa, &salen) != 0) {
> > +                   if (madesock)
> > +                           close(sock);
> > +                   return (NULL);
> > +           }
> > +           if (af == AF_INET)
> > +                   port = ntohs(((struct sockaddr_in *)sa)->sin_port);
> > +#ifdef INET6
> > +           else
> > +                   port = ntohs(((struct sockaddr_in6 *)sa)->sin_port);
> > +#endif
> > +   }
> > +
> > +   r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r));
> > +   if (r != NULL) {
> > +           r->sendsize = sendsize;
> > +           r->recvsize = recvsize;
> > +
> > +           xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
> > +           if (xprt != NULL) {
> > +                   xprt->xp_p2 = NULL;
> > +                   xprt->xp_p1 = (caddr_t)r;
> > +                   xprt->xp_verf = _null_auth;
> > +                   xprt->xp_ops = &svctcp_rendezvous_op;
> > +                   xprt->xp_port = port;
> > +                   xprt->xp_sock = sock;
> > +                   if (__xprt_register(xprt) != 0)
> > +                           return (xprt);
> > +
> > +                   free(xprt);
> > +           }
> > +           free(r);
> > +   }
> > +
> > +   if (madesock)
> > +           close(sock);
> > +
> > +   return (NULL);
> >  }
> >  
> >  /*
> > Index: lib/libc/rpc/svc_udp.c
> > ===================================================================
> > RCS file: /cvs/src/lib/libc/rpc/svc_udp.c,v
> > retrieving revision 1.19
> > diff -u -r1.19 svc_udp.c
> > --- lib/libc/rpc/svc_udp.c  1 Sep 2010 14:43:34 -0000       1.19
> > +++ lib/libc/rpc/svc_udp.c  17 Oct 2012 10:33:12 -0000
> > @@ -173,6 +173,125 @@
> >     return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE));
> >  }
> >  
> > +SVCXPRT *
> > +svcudp_bufcreate2(int sock, int af, u_short port, u_int sendsz, u_int 
> > recvsz)
> > +{
> > +   SVCXPRT *xprt;
> > +   struct svcudp_data *su;
> > +   struct sockaddr *sa;
> > +   struct sockaddr_in sin;
> > +#ifdef INET6
> > +   struct sockaddr_in6 sin6;
> > +#endif
> > +   socklen_t salen;
> > +   bool_t madesock;
> > +   int error;
> > +
> > +#ifdef INET6
> > +   if (af != AF_INET && af != AF_INET6)
> > +           return (NULL);
> > +#else
> > +   if (af != AF_INET)
> > +           return (NULL);
> > +#endif
> > +
> > +   madesock = FALSE;
> > +
> > +   if (sock == RPC_ANYSOCK) {
> > +           sock = socket(af, SOCK_DGRAM, 0);
> > +           if (sock == -1)
> > +                   return (NULL);
> > +           madesock = TRUE;
> > +   }
> > +
> > +   if (af == AF_INET) {
> > +           memset(&sin, 0, sizeof(sin));
> > +           sin.sin_family = AF_INET;
> > +           sin.sin_port = htons(port);
> > +           sin.sin_addr.s_addr = INADDR_ANY;
> > +           salen = sizeof(sin);
> > +           sa = (struct sockaddr *)&sin;
> > +   }
> > +#ifdef INET6
> > +   else {
> > +           memset(&sin6, 0, sizeof(sin6));
> > +           sin6.sin_family = AF_INET6;
> > +           sin6.sin_port = htons(port);
> > +           sin6.sin_addr.s_addr = in6addr_any;
> > +           salen = sizeof(sin6);
> > +           sa = (struct sockaddr *)&sin6;
> > +   }
> > +#endif     /* INET6 */
> > +
> > +   switch (port) {
> > +   case 0:
> > +           error = bindresvport_sa(sock, sa);
> > +           if (error == 0)
> > +                   break;
> > +           /* FALLTHOUGH */
> > +   default:
> > +           error = bind(sock, sa, salen);
> > +           break;
> > +   }
> > +
> > +   if (error != 0) {
> > +           if (madesock)
> > +                   close(sock);
> > +           return (NULL);
> > +   }
> > +
> > +   if (port == 0) {
> > +           if (getsockname(sock, sa, &salen) != 0) {
> > +                   if (madesock)
> > +                           close(sock);
> > +                   return (NULL);
> > +           }
> > +           if (af == AF_INET)
> > +                   port = ntohs(((struct sockaddr_in *)sa)->sin_port);
> > +#ifdef INET6
> > +           else
> > +                   port = ntohs(((struct sockaddr_in6 *)sa)->sin_port);
> > +#endif
> > +   }
> > +
> > +   xprt = (SVCXPRT *)mem_alloc(sizeof(*xprt));
> > +   if (xprt != NULL) {
> > +           su = (struct svcudp_data *)mem_alloc(sizeof(*su));
> > +           if (su != NULL) {
> > +                   su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
> > +                   rpc_buffer(xprt) = mem_alloc(su->su_iosz);
> > +                   if (rpc_buffer(xprt) != NULL) {
> > +                           xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt),
> > +                               su->su_iosz, XDR_DECODE);
> > +                           su->su_cache = NULL;
> > +                           xprt->xp_p2 = (caddr_t)su;
> > +                           xprt->xp_verf.oa_base = su->su_verfbody;
> > +                           xprt->xp_ops = &svcudp_op;
> > +                           xprt->xp_port = port;
> > +                           xprt->xp_sock = sock;
> > +
> > +                           if (__xprt_register(xprt) != 0)
> > +                                   return (xprt);
> > +
> > +                           free(rpc_buffer(xprt));
> > +                   }
> > +                   free(su);
> > +           }
> > +           free(xprt);
> > +   }
> > +
> > +   if (madesock)
> > +           close(sock);
> > +   return (NULL);
> > +}
> > +
> > +SVCXPRT *
> > +svcudp_create2(int sock, int af, u_short port)
> > +{
> > +
> > +   return(svcudp_bufcreate2(sock, af, port, UDPMSGSIZE, UDPMSGSIZE));
> > +}
> > +
> >  /* ARGSUSED */
> >  static enum xprt_stat
> >  svcudp_stat(SVCXPRT *xprt)
> > Index: sbin/mountd/mountd.8
> > ===================================================================
> > RCS file: /cvs/src/sbin/mountd/mountd.8,v
> > retrieving revision 1.16
> > diff -u -r1.16 mountd.8
> > --- sbin/mountd/mountd.8    31 May 2007 19:19:46 -0000      1.16
> > +++ sbin/mountd/mountd.8    17 Oct 2012 10:33:30 -0000
> > @@ -30,7 +30,7 @@
> >  .\"
> >  .\"     @(#)mountd.8       8.4 (Berkeley) 4/28/95
> >  .\"
> > -.Dd $Mdocdate: May 31 2007 $
> > +.Dd $Mdocdate: October 15 2012 $
> >  .Dt MOUNTD 8
> >  .Os
> >  .Sh NAME
> > @@ -41,6 +41,7 @@
> >  .Sh SYNOPSIS
> >  .Nm mountd
> >  .Op Fl dn
> > +.Op Fl p Ar portnum
> >  .Op Ar exportsfile
> >  .Sh DESCRIPTION
> >  .Nm
> > @@ -71,6 +72,10 @@
> >  The use of
> >  .Fl n
> >  is STRONGLY discouraged, as it opens up a wide range of security problems.
> > +.It Fl p Ar portnum
> > +Specify port number
> > +.Nm
> > +will listen on. It allows to configure firewall to filter on this port.
> >  .It Ar exportsfile
> >  The
> >  .Ar exportsfile
> > Index: sbin/mountd/mountd.c
> > ===================================================================
> > RCS file: /cvs/src/sbin/mountd/mountd.c,v
> > retrieving revision 1.71
> > diff -u -r1.71 mountd.c
> > --- sbin/mountd/mountd.c    22 Mar 2010 16:35:27 -0000      1.71
> > +++ sbin/mountd/mountd.c    17 Oct 2012 10:33:31 -0000
> > @@ -51,6 +51,7 @@
> >  #include <arpa/inet.h>
> >  
> >  #include <ctype.h>
> > +#include <err.h>
> >  #include <errno.h>
> >  #include <grp.h>
> >  #include <netdb.h>
> > @@ -175,6 +176,8 @@
> >  int        xdr_mlist(XDR *, caddr_t);
> >  void       mountd_svc_run(void);
> >  
> > +SVCXPRT *  create_svctcp(u_short port, int af);
> > +
> >  struct exportlist *exphead;
> >  struct mountlist *mlhead;
> >  struct grouplist *grphead;
> > @@ -196,6 +199,7 @@
> >  #define    OP_ALLDIRS      0x40
> >  
> >  int debug = 0;
> > +u_short use_port = 0;      /* default: any */
> >  
> >  volatile sig_atomic_t gothup;
> >  volatile sig_atomic_t gotterm;
> > @@ -214,8 +218,11 @@
> >     SVCXPRT *udptransp, *tcptransp;
> >     FILE *pidfile;
> >     int c;
> > +   const char *errstr;
> > +   long long portnum;
> >  
> > -   while ((c = getopt(argc, argv, "dnr")) != -1)
> > +   portnum = 0;    /* any port */
> > +   while ((c = getopt(argc, argv, "dnrp:")) != -1)
> >             switch (c) {
> >             case 'd':
> >                     debug = 1;
> > @@ -226,8 +233,15 @@
> >             case 'r':
> >                     /* Compatibility */
> >                     break;
> > +           case 'p':
> > +                   portnum = strtonum(optarg, 0, USHRT_MAX, &errstr);
> > +                   if (errstr != NULL)
> > +                           errx(1, "Port number is invalid");
> > +                   use_port = portnum;
> > +                   break;
> >             default:
> > -                   fprintf(stderr, "usage: mountd [-dn] [exportsfile]\n");
> > +                   fprintf(stderr,
> > +                           "usage: mountd [-dn] [-p port] 
> > [exportsfile]\n");
> >                     exit(1);
> >             }
> >     argc -= optind;
> > @@ -273,8 +287,8 @@
> >     signal(SIGHUP, (void (*)(int)) new_exportlist);
> >     signal(SIGTERM, (void (*)(int)) send_umntall);
> >     signal(SIGSYS, SIG_IGN);
> > -   if ((udptransp = svcudp_create(RPC_ANYSOCK)) == NULL ||
> > -       (tcptransp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL) {
> > +   if ((udptransp = svcudp_create2(RPC_ANYSOCK, AF_INET, portnum)) == NULL 
> > ||
> > +       (tcptransp = svctcp_create2(RPC_ANYSOCK, AF_INET, portnum, 0, 0)) 
> > == NULL) {
> >             syslog(LOG_ERR, "Can't create socket");
> >             exit(1);
> >     }

Reply via email to