当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 13 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 关于apache的运行用户
帖子发表于 : 2015-02-09 20:46 

注册: 2007-06-02 20:00
帖子: 294
送出感谢: 5
接收感谢: 2
一般来说为了安全着想,运行apache的用户不是root,而已类似于www-data之类的低权限nologin用户。但是只有root才能监听80端口。
很久以前自己编译的时候是让apache监听8080,然后用iptables把80的包转到8080间接实现。
今天研究了以下ubunt下的apache监听80端口的方式,搞不懂。
引用:
root@wgjak47-M410:/home/wgjak47# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
apache2 2018 root 3u IPv6 16511 0t0 TCP *:http (LISTEN)
apache2 10489 www-data 3u IPv6 16511 0t0 TCP *:http (LISTEN)
apache2 10490 www-data 3u IPv6 16511 0t0 TCP *:http (LISTEN)


为啥会有三个进程?既有root用户的也有www-data的。

无责任YY:会不会是通过root用户运行的进程监听80端口,然后通过socket转发给www-data的?

求大神指教。 :em01


页首
 用户资料  
 
2 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-09 20:51 

注册: 2009-08-04 16:33
帖子: 16882
送出感谢: 21
接收感谢: 1825
引用:
但是只有root才能监听80端口

請提供這句話的參考資料網址


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-09 23:29 

注册: 2011-02-14 17:46
帖子: 907
送出感谢: 3
接收感谢: 124
apache的做法是setuid


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-10 9:27 

注册: 2009-08-04 16:33
帖子: 16882
送出感谢: 21
接收感谢: 1825
引用:
为啥会有三个进程?

參閱
http://unix.stackexchange.com/questions ... ld-var-www
What user should apache and PHP be running as? What permissions should /var/www files have?


页首
 用户资料  
 
5 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-13 16:47 

注册: 2007-06-02 20:00
帖子: 294
送出感谢: 5
接收感谢: 2
poloshiao 写道:
引用:
但是只有root才能监听80端口

請提供這句話的參考資料網址

可能表述不当。在linux下不是只有以root权限运行的程序才能监听1024以下的端口吗。。


页首
 用户资料  
 
6 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-13 18:01 
头像

注册: 2010-04-10 16:14
帖子: 2903
系统: Arch Linux
送出感谢: 8
接收感谢: 69
代码:
ps auxfw | grep apache

root 用户那个是父进程,底下两个 apache 是子进程


_________________
dz,U,EIS. cies.
dz-cies@github
小香猪杀手@cc98.org


页首
 用户资料  
 
7 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-13 18:07 

注册: 2007-06-02 20:00
帖子: 294
送出感谢: 5
接收感谢: 2
引用:
It looks like perhaps the first process is as root, maybe from the /etc/init.d/apache script when the system started, and the other ones as www-data spawned from the first. Is that correct?

这个并没有解决我的问题。。。
我的问题是,
引用:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
apache2 2018 root 3u IPv6 16511 0t0 TCP *:http (LISTEN)
apache2 10489 www-data 3u IPv6 16511 0t0 TCP *:http (LISTEN)
apache2 10490 www-data 3u IPv6 16511 0t0 TCP *:http (LISTEN)

这三个进程是如何协作的?


页首
 用户资料  
 
8 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-13 20:32 

注册: 2009-08-04 16:33
帖子: 16882
送出感谢: 21
接收感谢: 1825
引用:
在linux下不是只有以root权限运行的程序才能监听1024以下的端口吗。。

不完全正確的描述
詳細參閱
http://unix.stackexchange.com/a/16568
Why are the first 1024 ports restricted to the root user only?
On the wide, wild world of the Internet, this doesn't matter.


页首
 用户资料  
 
9 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-13 21:12 

注册: 2011-02-14 17:46
帖子: 907
送出感谢: 3
接收感谢: 124
wgj 写道:
poloshiao 写道:
引用:
但是只有root才能监听80端口

請提供這句話的參考資料網址

可能表述不当。在linux下不是只有以root权限运行的程序才能监听1024以下的端口吗。。


监听1024以下端口需要特权 -> yes
只有root用户发起的进程才可以监听1024以下端口 -> no

通常解释这个问题时候举的例子是passwd,用户修改自己密码,那就要更新/etc/shadow中的信息,但是一般用户没有这个权限
解决方法是在修改密码时暂时变动程序的uid,有个system call叫setuid可以做到这件事情

同样,apache的做法也是setuid
你看到的三个进程,apache是fork server模型,2个非root权限的进程是实际处理clinet时候的进程
可能这时候有client请求需要处理,也可能是pre-fork出来备用的


页首
 用户资料  
 
10 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-13 21:18 

注册: 2011-02-14 17:46
帖子: 907
送出感谢: 3
接收感谢: 124
poloshiao 写道:
引用:
在linux下不是只有以root权限运行的程序才能监听1024以下的端口吗。。

不完全正確的描述
詳細參閱
http://unix.stackexchange.com/a/16568
Why are the first 1024 ports restricted to the root user only?
On the wide, wild world of the Internet, this doesn't matter.

您跑题了
楼主的问题是为什么一个非root用户的进程可以监听<1024的端口
使用这些端口确实需要特权的,简单例子
代码:
nc -l 999

会提示权限不足


页首
 用户资料  
 
11 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-13 21:43 

注册: 2009-08-04 16:33
帖子: 16882
送出感谢: 21
接收感谢: 1825
引用:
引用:
但是只有root才能监听80端口

請提供這句話的參考資料網址

引用:
引用:
在linux下不是只有以root权限运行的程序才能监听1024以下的端口吗。。

不完全正確的描述
詳細參閱
http://unix.stackexchange.com/a/16568
Why are the first 1024 ports restricted to the root user only?
On the wide, wild world of the Internet, this doesn't matter.

引用:
您跑题了
楼主的问题是为什么一个非root用户的进程可以监听<1024的端口

1. 我是針對
不是只有以root权限运行的程序才能监听1024以下的端口吗
而提供上面的文章連結

2. 還沒有針對
为什么一个非root用户的进程可以监听<1024的端口
來回覆

3. 造成誤會 特此說抱歉


页首
 用户资料  
 
12 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-13 22:32 

注册: 2011-02-14 17:46
帖子: 907
送出感谢: 3
接收感谢: 124
代码:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <error.h>
#include <string.h>
#include <arpa/inet.h>

int main(int argc, char** argv)
{
   int socketfd;
   uid_t ruid;
   struct sockaddr_in servaddr;

   if(argc != 2)
      exit(1);

   if((socketfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
      perror("socket"), exit(1);
   
   memset(&servaddr, 0, sizeof servaddr);
   servaddr.sin_family = AF_INET;
   servaddr.sin_port = htons(atoi(argv[1]));
   inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);

   ruid = getuid();
   if((seteuid(0)) < 0)
      perror("seteuid"), exit(1);
   if((bind(socketfd, (struct sockaddr *)&servaddr, sizeof servaddr)) < 0)
      perror("bind"), exit(1);
   if((seteuid(ruid)) < 0)
      perror("seteuid"), exit(1);
   if((listen(socketfd, 1)) < 0)
      perror("listen"), exit(1);
   
   while(1){
      int connectd_fd;
      int n;
      char buf[4096];
      if((connectd_fd = accept(socketfd, (struct sockaddr *)NULL, NULL))
         < 0)
         perror("connect"), exit(1);
      while((n = recv(connectd_fd, buf, 4096, 0)) > 0){
         buf[n] = '\0';
         puts(buf);
      }
      if(n == 0)
         fprintf(stderr, "%s", "Connection Closed.\n");
      else
         perror("recv"), exit(1);
   }   
   return 0;
}

示例代码,写得比较随意,楼主可以自行研究
1. 端口数大于1024时一切正常
2. 端口数小于1024时,把seteuid的东西注释掉,bind就会报告权限不足
3. 把还原euid的代码注释掉,进程owner就会变成root
4. euid还原后,还是可以正常使用特权端口的
5. 如果不做chown和chmod,seteuid会报告权限不足
编译
代码:
cc foo.c -Wall
sudo chown root:root a.out
sudo chmod +s a.out


apache的做法,以root权限载入一个进程,然后fork出一个,再setuid降低权限等级,于是就安全了,楼主可以自己试着写写看


页首
 用户资料  
 
13 楼 
 文章标题 : Re: 关于apache的运行用户
帖子发表于 : 2015-02-15 21:06 

注册: 2007-06-02 20:00
帖子: 294
送出感谢: 5
接收感谢: 2
rosynirvana 写道:
代码:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <error.h>
#include <string.h>
#include <arpa/inet.h>

int main(int argc, char** argv)
{
   int socketfd;
   uid_t ruid;
   struct sockaddr_in servaddr;

   if(argc != 2)
      exit(1);

   if((socketfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
      perror("socket"), exit(1);
   
   memset(&servaddr, 0, sizeof servaddr);
   servaddr.sin_family = AF_INET;
   servaddr.sin_port = htons(atoi(argv[1]));
   inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);

   ruid = getuid();
   if((seteuid(0)) < 0)
      perror("seteuid"), exit(1);
   if((bind(socketfd, (struct sockaddr *)&servaddr, sizeof servaddr)) < 0)
      perror("bind"), exit(1);
   if((seteuid(ruid)) < 0)
      perror("seteuid"), exit(1);
   if((listen(socketfd, 1)) < 0)
      perror("listen"), exit(1);
   
   while(1){
      int connectd_fd;
      int n;
      char buf[4096];
      if((connectd_fd = accept(socketfd, (struct sockaddr *)NULL, NULL))
         < 0)
         perror("connect"), exit(1);
      while((n = recv(connectd_fd, buf, 4096, 0)) > 0){
         buf[n] = '\0';
         puts(buf);
      }
      if(n == 0)
         fprintf(stderr, "%s", "Connection Closed.\n");
      else
         perror("recv"), exit(1);
   }   
   return 0;
}

示例代码,写得比较随意,楼主可以自行研究
1. 端口数大于1024时一切正常
2. 端口数小于1024时,把seteuid的东西注释掉,bind就会报告权限不足
3. 把还原euid的代码注释掉,进程owner就会变成root
4. euid还原后,还是可以正常使用特权端口的
5. 如果不做chown和chmod,seteuid会报告权限不足
编译
代码:
cc foo.c -Wall
sudo chown root:root a.out
sudo chmod +s a.out


apache的做法,以root权限载入一个进程,然后fork出一个,再setuid降低权限等级,于是就安全了,楼主可以自己试着写写看


感谢。 :em11


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 13 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:Exabot [Bot] 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译