I would recommend writing a very short application to open port 23, switch UIDs, then exec your real server. That means your only root security risks are in the listener program; once the other program has started, there's no way to get back root status. Plus, it's easy to give a thorough security audit to a 56-line program.

Speaking of 56-line programs,

here's a short little program that takes a port number and a program to exec on the command line, with optional UID and GID, and opens the socket on STDIN, binds it to the requested port, switches UID/GID, then execs the new program.
#!/usr/bin/perl -w use strict; use Socket; sub usage { die "Usage: $0 [-u uid] [-g gid] port prog-to-exec [args ...]\n"; } # Parse Options use vars qw(%opt); while (@ARGV && $ARGV[0] =~ /^-([ugh])$/) { shift; $opt{$1}=shift; } $opt{h} && usage(); $opt{u} = 2 # daemon unless $opt{u}; $opt{g} = 2 # daemon unless $opt{g}; # Get port and verify it my $port = shift; $port && $port =~ /^\d+$/ or usage(); # Make sure there's something to exec @ARGV >= 1 or usage(); # We're going to give the client app the socket on STDIN, so close the # old one... close(STDIN); # Create the socket and bind it to the port socket(STDIN,PF_INET,SOCK_STREAM,getprotobyname('tcp')) or die "Socket error: $!"; setsockopt(STDIN,SOL_SOCKET, SO_REUSEADDR, pack("l",1)) or die "setsockopt error: $!"; bind(STDIN,sockaddr_in($port,INADDR_ANY)) or die "bind error: $!"; # Switch to our new user and group $( = $) = $opt{g}; $< = $> = $opt{u}; if ($( != $opt{g} or $) != $opt{g}) { die "setgid failed\n"}; if ($> != $opt{u} or $< != $opt{u}) { die "setuid failed\n"}; # And get on with the show! exec(@ARGV) or die "exec error: $!\n";
You can use it by writing your client to expect a socket on STDIN, then just start listening on it. Here's a simplified variation of the server in the camel book:
#!/usr/bin/perl -Tw use Socket; use strict; listen(STDIN,SOMAXCONN) or die "listen error: $!\n"; for(;my $paddr=accept(CLIENT,STDIN); close(CLIENT)) { print CLIENT "The time is now ",scalar localtime,"\n"; }
So, for example, to start this up I run, as root:
# ~/tmp/listener -u 500 -g 500 23 ~/tmp/server
The other thing I would strongly recommend is that you write your server with perl's taint-checking (-T) switch. It's no substitute for a secure mindset, but it catches many types of silly errors and many more subtle errors. It makes sure any data coming from the user is sanitized before it's used for anything dangerous.

In reply to Re: Change UID of executing POE TCP server by sgifford
in thread Change UID of executing POE TCP server by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.