mind04 / mod-ruid2 Goto Github PK
View Code? Open in Web Editor NEWmod_ruid2 is a suexec module for apache which takes advantage of POSIX.1e capabilities to increase performance.
License: Apache License 2.0
mod_ruid2 is a suexec module for apache which takes advantage of POSIX.1e capabilities to increase performance.
License: Apache License 2.0
ABOUT mod_ruid2 is a suexec module for apache 2.0, 2.2 and 2.4, based on mod_ruid and mod_suid2 -it runs only on Linux because only the Linux kernel has implemented the required process capabilities. -it has better performance than mod_suid2 because it doesn`t need to kill httpd children after one request. it makes use of kernel capabilites and after receiving a new request suids again. -there are some security issues, for instance if attacker successfully exploits the httpd process, he can set effective capabilities and setuid to root. i recommend to use some security patch in kernel (grsec), or something.. -there are two main operation modes: stat and config 1. config is default, you must define uid and gid. If no [ug]id is defined the default user and group are used. 2. stat httpd setuid and setgid to uid and gid of requested filename(script)/directory this is good if you use mod_vhost_alias for virtual hosting INSTALL 1. download and install latest libcap from here 2. run /apachedir/bin/apxs -a -i -l cap -c mod_ruid2.c 3. configure httpd.conf 4. restart apache CONFIGURE OPTIONS: RMode config|stat (default is config) RUidGid user|#uid group|#gid - when RMode is config, set to this uid and gid RMinUidGid user|#uid group|#gid - when uid/gid is < than min uid/gid set to default uid/gid RDefaultUidGid user|#uid group|#gid RGroups group1 group2 - additional groups set via setgroups @none - clear all previous defined groups. RDocumentChrRoot - Set chroot directory and the document root inside EXAMPLE: LoadModule ruid2_module modules/mod_ruid2.so User apache Group apache RMode stat RGroups apachetmp RDocumentChRoot /home /example.com/public_html NameVirtualHost 192.168.0.1 <VirtualHost example.com> ServerAdmin [email protected] RDocumentChRoot /home /example.com/public_html ServerName example.com ServerAlias www.example.com RMode config # unnecessary since config is the default RUidGid user1 group1 RGroups apachetmp <Directory /home/example.com/public_html/dir> RMode stat </Directory> <Directory /home/example.com/public_html/dir/test> RMode config RUidGid user2 group2 RGroups groups1 </Directory> <Directory /home/example.com/public_html/dir/test/123> RUidGid user3 group3 </Directory> <Location /yustadir> RMode config RUidGid user4 user4 RGroups groups4 </Location> </VirtualHost> <VirtualHost example.net> ServerAdmin [email protected] DocumentRoot /home/example.net/public_html ServerName example.net ServerAlias www.example.net </VirtualHost>
Hello, I'm using mod_ruid2 for a long time and this is the first time that I'm having issue. I'm installing a new server to replace an old one. I installed mod_ruid2 using yum
mod_ruid2-0.9.8-2.el6.x86_64
After the installation I've configured on the following way one of the virtual host
<Directory /var/www/vhosts/MYDOMAIN.COM/httpdocs>
RMode config
RUidGid mydomain psacln
RGroups psacln
But when I'm trying to test my website i'm getting the following error at /var/log/httpd/error_log
[Tue Jul 07 12:48:44 2015] [error] mod_ruid2 www.MYDOMAIN.COM GET / HTTP/1.0 ruid_setup>ruid_set_perm:setgid(48) failed. getgid=48 getuid=48
My server doesn't have SELinux configured, in fact it's disabled.
I checked the source code and found the lines where it's giving error
Line 523, where is checking if setgid(gid) is 0
if (setgid(gid) != 0)
{
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "%s %s %s %s>%s:setgid(%d) failed. getgid=%d getuid=%d", MODULE_NAME, ap_get_server_name(r), r->the_request, from_func, __func__, dconf->ruid_gid, getgid(), getuid());
retval = HTTP_FORBIDDEN;
} else {
if (setuid(uid) != 0)
{
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "%s %s %s %s>%s:setuid(%d) failed. getuid=%d", MODULE_NAME, ap_get_server_name(r), r->the_request, from_func, __func__, dconf->ruid_uid, getuid());
retval = HTTP_FORBIDDEN;
}
}
My question is, is there any chance that Kernel 3.x are blocking some action at this module? I couldn't find the same issue at internet.
UPDATE: I've been able to install a kernel 2.6.X and it's working without problem but now I'm beeing crazy trying to understand/find why it's not working with kernel 3.10.X
If you enable Pipelined connections within say, FF, Chrome, etc, you will see something like this from within ruid2, which causes failures to display content:
[Sun Mar 06 12:40:21.255723 2016] [:error] [pid 31114] mod_ruid2 test.server.com GET /images/whatever.gif HTTP/1.1 chdir to /home/virtfs/blahblah failed (No such file or directory)
To reproduce this, simply enable HTTP Pipelined connections within a browser - iOS Safari has Pipelining enabled by default for images, but desktop Firefox/Chrome/Safari apparently all have it disabled by default.
A workaround is to disable KeepAlives within Apache when RUID2 is enabled.
When opening a website with DocumentRoot chmod 700, the first request for .htaccess file is made with the permissions of apache:
[Mon Jun 26 11:10:46 2017] [crit] [client xxx.xxx.xxx.xx] (13)Permission denied: /var/www/site_a/html/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable
and apache brings a 403 Forbidden. Which makes the whole construct unusable!
After upgrading from Debian 8.1 to Debian 9.5 and updating Apache to version 2.4.34 Apache crashes on the first page request. When I change 1 config line (comment the line where the module is loaded) it works again.
Linux kernel: 4.9.0-8-amd64 #1 SMP Debian 4.9.110-3+deb9u4 (2018-08-21) x86_64 GNU/Linux
Hi there, I'm running mod_ruid 0.9.7 on Apache 2.2 with ModSecurity 2.7.3 and the GotRoot/Atomicorp delayed ruleset, all on cPanel 11.38. I am unable to get ModSecurity to successfully log it's activities since mod_ruid is causing audit directories and logs to be created with the username of the running process, and more importantly with permissions for that user only, overriding a specific setting in the ModSecurity conf to create audit folders and logs to be created world-writable.
I have documented my setup here: https://www.atomicorp.com/forum/viewtopic.php?f=15&t=6932&sid=23c91691756075ec7fc5cfe86a6630d1
Is there any way that mod_ruid can be configured or patched such that it can work with ModSecurity?
Regards, Ben
Hello
i have installed mod_ruid2 on CentOS 6.4 ( x86_64 ) mod_php.
after configuring the virtual host with:
RMode config
RUidGid root root
OR
RMode stat
and chmod root.root test.php
a php script contain:
always return this:
uid=4294967295 gid=4294967295 groups=48(apache)
it was expected to return uid=0 gid=0 !
Hi all
In my setup the apache user belogns to several groups more than 8 which is the edfault RUID_MAXGROUPS value.
So I get errors "getgroups() failed on child init, ignoring supplementary group IDs" and the process groups are not reset correctly. I could recompile with a higher RUID_MAXGROUPS value, but I prefered to try a simple patch which seems to work. Maybe it (or something like that) could be included?
Thank you
--- mod_ruid2.c.orig 2013-03-19 21:42:00.000000000 +0100
+++ mod_ruid2.c 2014-01-24 17:40:05.181533124 +0100
@@ -107,7 +107,7 @@
static int coredump, root_handle;
static const char *old_root;
-static gid_t startup_groups[RUID_MAXGROUPS];
+static gid_t *startup_groups;
static int startup_groupsnr;
@@ -353,9 +353,15 @@
cap_value_t capval[4];
/* detect default supplementary group IDs */
- if ((startup_groupsnr = getgroups(RUID_MAXGROUPS, startup_groups)) == -1) {
+ if ((startup_groupsnr = getgroups(0, NULL)) == -1) {
startup_groupsnr = 0;
- ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "%s ERROR getgroups() failed on child init, ignoring supplementary group IDs", MODULE_NAME);
+ ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "%s ERROR getgroups(0, NULL) failed on child init, ignoring supplementary group IDs", MODULE_NAME);
+ } else {
+ startup_groups = apr_pcalloc(p, startup_groupsnr * sizeof(gid_t));
+ if (getgroups(startup_groupsnr, startup_groups) == -1) {
+ startup_groupsnr = 0;
+ ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "%s ERROR getgroups() failed on child init, ignoring supplementary group IDs", MODULE_NAME);
+ }
}
/* setup chroot jailbreak */
When Apache 2.4 tries to kill a instance that is running under a userid set by ruid2, it cannot kill process, giving the error Error Cannot kill process XXXX: Operation not permitted!
This happens for example on a PHP script handling Server Event Notifications that is in a loop.
Then other apache clients become affected giving emty responses.
The function RDocumentChRoot requires 2 parameters: one for the virtual directory "root" and the other is the actual real directory.
My suggestion: How about using something like this - if the line only includes 1 parameter, then ruid2 will treat it as root, so for example:
RDocumentChRoot /home/mysite/public_html
That way, the / will redirect to /home/mysite/public_html/ and if the user will put 2 parameters, it will behave as it is today.
What do you think?
I would like to propose the following patch because when I started using mod_ruid2, I had problems because after the first uid change, I was not able to return to the default user uid/gid, which in RedHat is 48. Only after some investigation I discovered it was due to minuid being 100. In my opinion, if we start as a certiain User and Group (in httpd.conf), then we should always be able to revert back to them
--- mod_ruid2-0.9.8/mod_ruid2.c.orig 2014-02-11 23:14:59.625901994 +0100
+++ mod_ruid2-0.9.8/mod_ruid2.c 2014-02-11 23:16:20.857630500 +0100
@@ -312,7 +312,7 @@
static const command_rec ruid_cmds[] = {
AP_INIT_TAKE1 ("RMode", set_mode, NULL, RSRC_CONF | ACCESS_CONF, "Set mode to config or stat (default: config)"),
- AP_INIT_TAKE2 ("RUidGid", set_uidgid, NULL, RSRC_CONF | ACCESS_CONF, "Minimal uid or gid file/dir, else set[ug]id to default (User,Group)"),
+ AP_INIT_TAKE2 ("RUidGid", set_uidgid, NULL, RSRC_CONF | ACCESS_CONF, "When mode is config set[ug]id to these uid or gid, else set[ug]id to default (User,Group)"),
AP_INIT_RAW_ARGS ("RGroups", set_groups, NULL, RSRC_CONF | ACCESS_CONF, "Set additional groups"),
AP_INIT_TAKE2 ("RDefaultUidGid", set_defuidgid, NULL, RSRC_CONF, "If uid or gid is < than RMinUidGid set[ug]id to this uid gid"),
AP_INIT_TAKE2 ("RMinUidGid", set_minuidgid, NULL, RSRC_CONF, "Minimal uid or gid file/dir, else set[ug]id to default (RDefaultUidGid)"),
@@ -518,12 +518,17 @@
}
/* if uid of filename is less than conf->min_uid then set to conf->default_uid */
+ /* but only when RMode is stat. If RMode is config, then we explicitly asked for a certain user/group, so use them. */
+ /* There's also the case where RMode is config, but no explicit RUidGid was provided. In this case we rely on original */
+ /* httpd.conf User/Group, and the concept remains */
+ if (dconf->ruid_mode != RUID_MODE_CONF) {
if (uid < conf->min_uid) {
uid=conf->default_uid;
}
if (gid < conf->min_gid) {
gid=conf->default_gid;
}
+ }
/* set supplementary groups */
/* IMHO, only in CONF mode the supplementary groups should be set to the original process supplementary groups (when the admin does not explicitly ask for some set of supplementary goups).
@@ -537,7 +542,7 @@
} else if (dconf->groupsnr > 0) {
groups = apr_pcalloc(r->pool, dconf->groupsnr * sizeof(gid_t));
for (groupsnr = 0; groupsnr < dconf->groupsnr; groupsnr++) {
- if (dconf->groups[groupsnr] >= conf->min_gid) {
+ if (dconf->groups[groupsnr] >= conf->min_gid || dconf->ruid_mode == RUID_MODE_CONF) { /* IMHO, if the admin asks for some gid, we should use it. This may be questionable if the config may be done by someone elve via .htaccess. But even in this case, IMHO we should always be able to revert back to what the admin configured in httpd.conf (for example, in RedHat/CentOS, group httpd is 48, which is < 100. But it's normal to be able to go back to 48, even to make httpd able to track the presence of .htaccess on the next request. */
groups[groupsnr] = dconf->groups[groupsnr];
} else {
groups[groupsnr] = conf->default_gid;
The readme states: "mod_ruid2 runs only on linux because afaik only linux has implemented posix 1003.1e capabilities"
Posix 1003.1e is a withdrawn standard from 1997, which wanted to define the Posix API of access control lists. Many ?NIX-like OSes implemented ACLs using this abandoned standard as a basis. Linux, BSD, and Solaris, support POSIX.1e ACLs, based on this early POSIX draft. Many of them, for example AIX, FreeBSD, Mac OS X, beginning with version 10.4 ("Tiger"), and Solaris with ZFS filesystem, support NFSv4 ACLs, which extends Posix 1003.1e, and is part of the NFSv4 standard. If anything Linux lags in this area. There are two experimental implementations of NFSv4 ACLs for Linux: NFSv4 ACLs support for Ext3 filesystem and recent Richacls, which brings NFSv4 ACLs support for Ext4 filesystem. With NFSv4 you would have a real standard to work to, instead of an abandoned draft, and NFSv4 is where Linux is headed. Then, if there are problems, they are not your problem, it's them not adhering to the standard, which translates into a bug they need to fix.
For FreeBSD, Posix 1003.1e is documented in the man pages, FreeBSD Handbook posix1e(3), acl(3), and the various references to the SEE ALSO sections. So Posix 1003.1e DOES exist in FreeBSD and other ?NIX operating systems. While you may find slight differences from the Linux implementation, I assume, this is nothing that could not be ironed out with a 100 lines of glue code. In fact, you might want to change it to be compatible with NFSv4 ACLs, where the rest are and Linux is headed, and make the glue for where Linux currently is for backward compatibility.
Are there any known problems with using mod_ruid2 in RStat mode with files on NFS?
After making an exact replica of a web site from local storage to NFS, it seems that mod_ruid2 RStat mode is not behaving the same way.
I can make the site work on NFS if I use RConfig mode, but in that case I'm just specifying the same UID and GID as that which owns the files, so I'd expect RStat mode to figure this out just as it does on local storage.
Hi
We're using this module, with success, for quite some time in production.
Today I'm looking into a way to collect some statistics on CPU usage per user. I was wondering if it would be possible to integrate CGroup support. I'm not a very experienced c-programmer, so I would be very happy if you could provide me some feedback on the idea before I start experimenting with the code.
Thank you for your feedback!
Jeroen
mod_ruid2.c:51:28: fatal error: sys/capability.h: No such file or directory
i tried to change it to linux/capability.h but some declarations are missing or not available:
'CAP_EFFECTIVE'
'CAP_SET'
'CAP_CLEAR'
i tried to grep them in /usr/include without finding them.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.