Linux - Security This forum is for all security related questions.
Questions, tips, system compromises, firewalls, etc. are all included here. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
09-08-2006, 03:46 PM
|
#1
|
Member
Registered: Jun 2002
Posts: 302
Rep:
|
How to Open Privileged Ports?
Hi,
I was just wondering how applications such as Apache, Bind, etc. open privileged ports and then drop privilieges. I know that Apache has a root process that's always running, but bind opens port 53 and then drops privileges. Does the application start up as root and then change it's uid/gid through some system call? Thanks for your help.
|
|
|
09-08-2006, 03:59 PM
|
#2
|
LQ Guru
Registered: May 2005
Location: Atlanta Georgia USA
Distribution: Redhat (RHEL), CentOS, Fedora, CoreOS, Debian, FreeBSD, HP-UX, Solaris, SCO
Posts: 7,831
|
apache has a something in httpd.conf wherein the original httpd runs as root but the user of the httpd that users attach to from browsers is different. (You REALLY want to do that - otherwise browsers get root access to your server.) I forget the setting off the top of my head.
named (BIND/DNS) typically is started with the -u option to specify what user to run. From the man page of named:
Quote:
-u user
setuid() to user after completing privileged operations, such
as creating sockets that listen on privileged ports.
|
The above tells you it runs as the user you specified but only AFTER it has opened port 53 or other privileged ports.
|
|
|
09-08-2006, 05:18 PM
|
#3
|
LQ Guru
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870
|
Quote:
Originally Posted by jlightner
apache has a something in httpd.conf wherein the original httpd runs as root but the user of the httpd that users attach to from browsers is different. (You REALLY want to do that - otherwise browsers get root access to your server.) I forget the setting off the top of my head.
named (BIND/DNS) typically is started with the -u option to specify what user to run. From the man page of named:
The above tells you it runs as the user you specified but only AFTER it has opened port 53 or other privileged ports.
|
i'm pretty sure the OP already knows all this... i think what he's asking is exactly how the change is done - at system level... sounds like he might be trying to implement this behavior in a program he's written or something like that...
|
|
|
09-09-2006, 01:32 AM
|
#4
|
Member
Registered: Jun 2002
Posts: 302
Original Poster
Rep:
|
Thanks for your replies. What I'm looking for is the actual mechanism. Is there a system call that changes the process's ownership? Kind of like chown but for processes instead of files or is more of an su?
|
|
|
09-09-2006, 02:07 AM
|
#5
|
LQ Guru
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870
|
sounds like your best bet (while you wait for a reply from someone who knows about the inner workings of this stuff) might be to take a look at some source code... i'd suggest dnsmasq, as it's a rather small program... it binds to port 53/UDP as root and then changes to a non-root user... the code is available here:
http://www.thekelleys.org.uk/dnsmasq...sq-2.33.tar.gz
i took a look at the dnsmasq.c file, and i think this is the part that takes care of the binding and dropping of root privilages (keep in mind i know nothing about programming):
Code:
else
{
FILE *pidfile;
struct passwd *ent_pw = daemon->username ? getpwnam(daemon->username) : NULL;
fd_set test_set;
int maxfd, i;
int nullfd = open("/dev/null", O_RDWR);
#ifdef HAVE_LINUX_NETWORK
cap_user_header_t hdr = NULL;
cap_user_data_t data = NULL;
/* On linux, we keep CAP_NETADMIN (for ARP-injection) and
CAP_NET_RAW (for icmp) if we're doing dhcp */
if (ent_pw && ent_pw->pw_uid != 0)
{
hdr = safe_malloc(sizeof(*hdr));
data = safe_malloc(sizeof(*data));
hdr->version = _LINUX_CAPABILITY_VERSION;
hdr->pid = 0; /* this process */
data->effective = data->permitted = data->inheritable =
(1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) |
(1 << CAP_SETGID) | (1 << CAP_SETUID);
/* Tell kernel to not clear capabilities when dropping root */
if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1) == -1)
{
bad_capabilities = errno;
ent_pw = NULL;
}
}
#endif
FD_ZERO(&test_set);
maxfd = set_dns_listeners(daemon, &test_set, -1);
#ifdef HAVE_DBUS
maxfd = set_dbus_listeners(daemon, maxfd, &test_set, &test_set, &test_set);
#endif
/* The following code "daemonizes" the process.
See Stevens section 12.4 */
#ifndef NO_FORK
if (!(daemon->options & OPT_NO_FORK))
{
if (fork() != 0 )
_exit(0);
setsid();
if (fork() != 0)
_exit(0);
}
#endif
chdir("/");
umask(022); /* make pidfile 0644 */
/* write pidfile _after_ forking ! */
if (daemon->runfile && (pidfile = fopen(daemon->runfile, "w")))
{
fprintf(pidfile, "%d\n", (int) getpid());
fclose(pidfile);
}
umask(0);
for (i=0; i<64; i++)
{
if (i == piperead || i == pipewrite)
continue;
#ifdef HAVE_LINUX_NETWORK
if (i == daemon->netlinkfd)
continue;
#endif
if (daemon->dhcp &&
((daemon->lease_stream && i == fileno(daemon->lease_stream)) ||
#ifndef HAVE_LINUX_NETWORK
i == daemon->dhcp_raw_fd ||
i == daemon->dhcp_icmp_fd ||
#endif
i == daemon->dhcpfd))
continue;
if (i <= maxfd && FD_ISSET(i, &test_set))
continue;
/* open stdout etc to /dev/null */
if (i == STDOUT_FILENO || i == STDERR_FILENO || i == STDIN_FILENO)
dup2(nullfd, i);
else
close(i);
}
if (daemon->groupname || ent_pw)
{
gid_t dummy;
struct group *gp;
/* change group for /etc/ppp/resolv.conf otherwise get the group for "nobody" */
if ((daemon->groupname && (gp = getgrnam(daemon->groupname))) ||
(ent_pw && (gp = getgrgid(ent_pw->pw_gid))))
{
/* remove all supplimentary groups */
setgroups(0, &dummy);
setgid(gp->gr_gid);
}
}
if (ent_pw && ent_pw->pw_uid != 0)
{
/* finally drop root */
setuid(ent_pw->pw_uid);
#ifdef HAVE_LINUX_NETWORK
data->effective = data->permitted =
(1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
data->inheritable = 0;
/* lose the setuid and setgid capbilities */
capset(hdr, data);
#endif
}
openlog("dnsmasq", LOG_PID, daemon->log_fac);
}
|
|
|
09-09-2006, 02:58 PM
|
#6
|
Member
Registered: May 2004
Posts: 552
Rep:
|
If you have a program that's setuid root, your process can "drop privilages" and become owned by the user that invoked the program by doing this.
Code:
setgid(getgid());
setuid(getuid());
Notice setting gid first is necessary because after you change uid you can no longer change gid (you lost privilages to do so).
On the other hand if the program is started by root, such is the case when its started from an init.d script, then instead of specifying getgid() and getuid(), preplace these with the user id of the user you want the program to run as (from cmdline -u <userid> option normally).
|
|
|
09-10-2006, 09:37 AM
|
#7
|
Member
Registered: Jun 2002
Posts: 302
Original Poster
Rep:
|
Thanks a lot
|
|
|
All times are GMT -5. The time now is 08:30 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|