我开发了一个基于 Beancount 的账本托管服务 HostedBeans,欢迎大家来了解纯文本复式记账并试用我的服务。
归档 2013 年 5 月

RP主机如何进行权限控制

折腾虚拟主机一年多了, 除去编写面板,研究的更多的就是权限控制了. 在此我分享一下我在Linux虚拟主机权限控制方面的经验.

阅读本文需要一定的Linux服务器维护基础.

《应用密码学》的前言中讲到:

如果我把一封信锁在保险柜中, 把保险柜藏在纽约的某个地方, 然后告诉你去读这封信, 这并不是安全, 而是隐藏.

相反,如果我把一封信锁在保险柜中, 然后把保险柜及其设计规范和许多同样的保险柜给你, 以便你和世界上最好的开保险柜的专家能够研究锁的装置.

而你还是无法打开保险柜去读这封信, 这才是安全.

我不是说我的安全措施无懈可击, 我只是认为隐藏起来也于事无补, 不如分享出来, 在此我也提示RP主机的用户, 请不要在服务器上做尝试突破限制的操作, 根据协议你可能被封停帐号, 你可以自行架设环境来测试, 或与我交流. 啊, 题外话说了这么多.

我很懒, 我在尽可能地借助Linux本身的功能来进行权限控制, 而且这也是RP主机的宗旨——提供完整的Linux环境.

文件

文件方面, Linux本身已经提供了一套文件权限系统, 我只需要提示用户应当将文件权限设置为770即可: chmod -R 770 ~

为了防止疏忽,我们还可以在.bashrc中加入umask 007这样创建出来的文件默认就是660(注1), 不过这对PHP等脚本生成的文件并不起作用, 因为他们没有通过bash环境.

注1: Linux不允许一个文件创建时就有执行权限, 所以默认是660, 对于目录则是770.

我没有使用单独的FTP软件, 比如有名的vsftp, 因为我觉得配置起来很麻烦, 容易产生新漏洞. sshd自带的SFTP功能完全可以满足文件管理的需求, 这是自带的功能, 方便.

我还使用了quota-tools来限制用户的磁盘占用, 因为磁盘这东西, 占了多少就是多少, 总不能随便删人的文件啊, 所以一定要限制死.

Web

Web部分可谓是重中之重, 因为按照Linux的规则, 端口是被一个进程独占的, 但是大家都需要用80端口来开设Web服务, 这就需要以root运行一个Web服务器, 然后根据用户的在面板中的配置, 分发, 执行Web请求. 其实, 只需要一个反向代理来分发请求就够了, 但是为了降低建站的门槛, 毕竟相当大一部分用户购买RP主机就是为了建站, 所以还要提供公共的常见脚本(PHP)运行环境.

Apache负责运行各种网页脚本, 如PHP, Python, CGI等等. 为了保证自由度, 我没有对PHP加任何的限制, 我希望借助Linux本身的进程安全模型——让脚本以对应的Linux用户来运行.

于是我找到了 mpm_itk_module, 这种工作模式, 可以为每个Virtual Host指定实际运行的用户. 当收到请求时, Apache的工作进程会setuid为相应用户, 然后再执行相应的脚本完成请求.

借助于Linux本身的功能, PHP进程可以按照权限访问文件, 创建新进程(以实际的用户), 而不会干扰到其他用户.

但和标准的 mpm_perfork_module 相比, 因为要频繁地setuid, 创建和销毁进程, 性能相差了几十上百倍之多. 但为了权限控制的灵活性, 只能牺牲性能了. 在新版本中, 我正在把性能低下的Apache边缘化.

目前, 事实上是Nginx在监听80端口, 负责处理静态文件请求, 并把其他请求反向代理到Apache. 为了提供静态文件, Nginx需要能偶访问所有用户的文件.

我选择了以www-data用户来运行Nginx, 同时将www-data加入到每个用户的组当中, 所以需要用户将文件设置为770, 给予同组的Nginx权限.

新版本的Web

新版本中将使用PHP-FPM代替Apache处理PHP脚本, PHP-FPM的功能很强大, 可以建立不同的进程池, 在新版本中, 每个用户都会有一个单独的进程池.

每个进程池表现为一个UNIX socket文件, 用户也可以编译自己的PHP和PHP-FPM来代替默认的PHP-FPM.

新版本中使用了 uWSGI 代替Aapche的 mod_wsgi 来处理Python脚本, 用户需要自行运行uWSGI守护进程, 监听一个UNIX socket, 并配置Nginx的反向代理即可.

事实上这种方式适用于所有的fcgi服务器.

MySQL

MySQL再简单不过了, 装一个phpmyadmin, 默认的安全策略已经相当完善, 每个用户对以自己的用户名为前缀的数据库具有全部权限, 可以随意建立数据库.

流量统计

说实话直到目前我还没找到较可行的方案, 我希望依然以Linux中的用户为单位进行统计. 目前我正在调研iptables的相关功能.

目前还有两个部分的用户相关进程没有以实际用户运行: PPTP, Nginx的worker.

不知不觉写了这么多, 不过好像没啥实际的啊.

精子生于 1995 年,英文 ID jysperm.

订阅推送

通过 Telegram Channel 订阅我的博客日志、产品和项目的动态:

王子亭的博客 @ Telegram


通过邮件订阅订阅我的博客日志、产品和项目的动态(历史邮件):

该博客使用基于  Hexo  的  simpleblock  主题。博客内容使用  CC BY-NC-ND  授权发布。最后生成于 2024-04-08.