Another way to bind a reserved port (<1024) from an unprivileged process is to spawn a privileged binary to do the binding for you.
I first saw this in:
Firewalls and Internet Security:
Repelling the Wily Hacker First Edition
William R. Cheswick and Steven M. Bellovin
Chap 4, p103. (In reference to port 20 for ftp.)
bind_port.c is the privileged executable installed suid-root. If you have a kernel > 2.6.25 you can just use setcap to give the program or a wrapper CAP_NET_BIND_SERVICE without all the privilege/chroot/capabilities fiddling in bind_port.c.
bind.c contains the bind(2) replacement intercept_bind(). intercept_bind() just calls bind(2) if no privilege is needed or the socket being bound isn't AF_INET. (AF_INET6 would follow pretty much the same logic.) If the port number requires privilege the code clears the close-on-exec flags of the socket descriptor, forks:
a) The child closes all inherited descriptors except the one we are binding
and execs the privileged wrapper passing the descriptor number, port,
and local address on the command line.
b) The parent waits for the child to complete and retrieves the exit code and restores the close-on-exec flags on the socket descriptor. (The close-on-exec flag on apache 1.3.X is set for the socket descriptor hence this rigamarole.)
The common header constants.h
To use you can either overide the weak symbol bind in libc
with the one defined in bind.c or alter any calls to bind in your
source to call intercept_bind and add libbind.o to the link line.
cc -o bind_port bind_port.c -lcap sudo install -o root -o root -m 4511 bind_port /sbin/opt cc -c -DREPLACE_BIND_SYMBOL libbind.c cp libbind.o /tmp cd $APACHE_1.3.41_SOURCE env EXTRA_LDFLAGS="/tmp/bind.o -lcap" ./configure --prefix=/tmp/apache make make install /tmp/apache/bin/apactl start
The REPLACE_BIND_SYMBOL preprocessor symbol controls this in libbind.c
Another option for unmodified binaries is to interpolate a shared library containing the modified bind routine using the LD_PRELOAD environment variable. The make target libbind.so will build libbind.so from libbind.c eg
cc -fPIC -o libbind.o -DREPLACE_BIND_SYMBOL bind.c cc -shared -o libbind.so -Wl,-soname,libbind.so libbind.o cp bind.so /tmp env LD_PRELOAD=/tmp/libbind.so /usr/sbin/apactl start
Source files are in "files"