[MediaTemple]合租第二年开张

时间过得真是飞快啊,不知不觉租用这个空间已经满一年了。记得当时为了凑够20个人,到处发消息,一些朋友也帮忙转贴,虽然我当时有主机用,不着急搬家,后来也是实在是等不及了,一咬牙直接租了下来,先让已经入伙的住进来,然后再继续招租。好在人很快就满了,并且陆续还有人询问有没有空缺,说明“需求”还是很旺盛的。

在这一年时间里,大部分都风平浪静,MT的服务器也没出过什么问题,除了因“不可抗力”折腾了一气儿,现在我们已经舍弃了原来的ip(累计4个),搬到了新的主机、新的ip、新的(dv)3.5。

所以,请所有合租的邻居尽快完成搬家哦,原来的主机租期是到7月19号,估计拆迁还会提前,所有的文件和数据库我都已经转换到了新服务器,大家修改域名指向就可以继续使用了。新主机还是有几个变化的:

  • ssh的chroot取消了,可以登录上来作更多的事情;
  • 两个ip,其中一个备用,万一出现事故,不会连控制面板都登录不了(用代理上plesk有问题);
  • 启用suPHP,速度比原来更快一些;
  • 新版centos和plesk更节约内存,正好分配给apache和mysql;
  • 我终于会用yum了 🙂

搬家完成后请在旧主机的plesk里作个记号,把相关domain暂停即可,就像这样:

plesk-domain-deactivate

方便我到时候统计还有谁没搬家呢。当然确认文件都转移完成后,也可以删除相应domain。

至于合租的费用,还和去年一样吧,全年¥200,晚来一个月减¥20,付款方式不变,支付宝、贝宝账号还都是用我的邮箱,打款的时候记得带上域名或者账号信息,方便我作记录。

另外,现在的人员组成情况:

  • 9位2年级同学已经确认会续租;
  • 2位还没拿定主意,不着急,想好之后给我答复;
  • 5位新来的朋友;
  • 1位一直没有答复我是否要续租,希望尽快回话哦;
  • 3个空缺,虚位以待,愿上钩者请与我mail联系,主机情况和去年一样。

友情提醒想写blog或建网站,又没有时间或耐心的朋友,还是先找个免费空间练练手吧,一年的费用虽然不多,浪费了也确实挺可惜的。

[MediaTemple]从(dv)3.0升级到3.5

从(dv)3.0升级到(dv)3.5,其实我理解最大的差别就是php5, centos5了,其它的也有一些,包括硬件上的,不管怎样,新的应该好,升级之。

升级主要依据KB里的这篇文章:(dv) HOWTO: Using the Plesk Migration Manager,英文好的直接去看,不用听我唠叨了。

升级之前

升级的准备条件:要知道旧主机的域名(废话),有旧主机的root权限(早有了),超过50%的磁盘剩余空间(这个没问题,我们用得比较省)。

升级之前,要通过support request申请新的(dv)3.5主机,为什么要通过support request而不是直接下订单购买呢?我也不知道。新主机不能和旧主机使用同样的域名,可以用个假的,比如new.fwolf.com,升级完成后可以调过来。申请的时候,我还要了2个新ip,打算把旧ip全部换掉。

可能是周末的原因,反应速度稍微慢一些,将近12个小时之后才得到消息,先是一个回复说已经添加了新的主机方案(默认一年,可以调整成按月的),然后另外一个回复说ip已经添加完毕,另外还有一封Service Activation Letter邮件,告知新主机的登录信息。

由于我们并没有使用主机上的DNS,所以DNS部分的调整略过。

备份资料

首先是备份旧主机上的资料,主要是文档和数据库。

文档就是把/var/www/vhosts打包下载即可,虽然我们并没有使用太多的空间,但打包之后还是有1.5G,下载得花点时间,早知道我就在等待新主机的时候作了。

然后就是备份数据库了,这个用脚本会方便些:

# mysql -u admin -p -e "show databases;" > mysql_backup.sh

然后用vi加工一下这个文件,删掉第一行标题Database,然后用正则替换:

:%s/^\(.*\)$/mysqldump --add-drop-table --default-character-set=utf8 --user=admin --password=your_passwd --extended-insert=false \1 > \1.sql

加上可执行属性之后,就可以运行这个脚本了,会在当前目录下生成一堆sql文件,打包下载到本地即可。这个文件终于小一点,才17M。

设置新的主机

按照MT Service Activation Letter中的登录信息,登录新的主机,完成主机设置。

plesk setup step 1

hostname、默认ip都不用动,所有ip改为shared类型,并更改管理员密码。

plesk setup step 2

这些都是联系信息,按照KB中的说明,I would like to create a default client account要选中。

完事之后,简单对比了一下新、旧主机,发现除了centos和plesk有升级之外,硬件居然还略微下降了一点点,这个是旧主机的:

mediatemple old vps

这个是新主机的:

mediatemple new vps

用unixbench算了一下,果然要差一些:

Start Benchmark Run: Sun Jul 13 02:52:13 PDT 2008
 02:52:13 up 1 day,  3:19,  3 users,  load average: 0.07, 0.12, 0.05

End Benchmark Run: Sun Jul 13 03:02:39 PDT 2008
 03:02:39 up 1 day,  3:30,  3 users,  load average: 14.05, 6.09, 2.71


                     INDEX VALUES            
TEST                                        BASELINE     RESULT      INDEX

Dhrystone 2 using register variables        376783.7 10407496.2      276.2
Double-Precision Whetstone                      83.1     1363.3      164.1
Execl Throughput                               188.3     3177.3      168.7
File Copy 1024 bufsize 2000 maxblocks         2672.0    70892.0      265.3
File Copy 256 bufsize 500 maxblocks           1077.0    17388.0      161.4
File Read 4096 bufsize 8000 maxblocks        15382.0   376396.0      244.7
Pipe-based Context Switching                 15448.6   224834.4      145.5
Pipe Throughput                             111814.6   619968.9       55.4
Process Creation                               569.3    11806.2      207.4
Shell Scripts (8 concurrent)                    44.8      270.9       60.5
System Call Overhead                        114433.5   280994.4       24.6
                                                                 =========
     FINAL SCORE                                                     131.3

原来得分是207.1的,只好阿Q一下,希望MT不同配置的硬件所带的vps数量不同,另外软件上的优化也能弥补一些差距。

开始升级

左边菜单里点Server,然后在右边页面的Services组中选择Migration Manager,然后点Start a new migration开始新的服务器转换:

plesk migration step 1

由于磁盘空间足够,可以一次转换,所以很方便,填上原主机名称和登录信息即可。不小心还发现/使用的是reserfs,并且默认安装耗费4%的空间,也就是大概600M。

确认之后,plesk自动到旧主机上查出信息:

plesk migration setp middle

plesk migration setp 2

当然要选择Migrate all clients and domains,同时还看到plesk还能从其它主机管理软件,比如从cPanel转换数据。Advanced里还有一些选项,包括旧主机的空间占用信息,一般不用动的:

plesk migration step 2-1

确认之后:

plesk migration step 3

设置新、旧主机上的ip对应关系,我们旧主机上有2个ip(虽然显示3个,有一个其实已经退掉了),新主机上打算大多数人用一个ip,管理后台用单独的一个,免得被封了之后连后台都进不去(plesk通过代理登录总有问题)。

下一步:

plesk migration setp 4

Mysql设置,没什么好设置的,直接继续,就可以喝茶等机器干活儿了,先备份信息:

plesk migration step 5

然后拷贝文件:

plesk migration step 5-1

传输速度10MB/s左右,基本上相当于100M局域网对拷了。拷贝完成后再逐个进行部署:

plesk migration step 5-2

最后,终于完成,不过发现了错误:

plesk migration error

好像是因为plesk没有装中文语言包,不是很严重的错误,到Parallels下载一个语言包,在plesk -> Server -> Interface Prefenences -> Add Locale里上传语言包。网站上显示有错误,简体中文实际上是链接向荷兰语的,繁体中文链接是指向简体中文的。上传成功后又发现无法启动,原来Maximum number of language packs只有1,难道新的主机方案只能安装一个语言包?大家只能暂时都用英文界面了。

升级回顾、检查、补漏

plesk的migration只是把所有client、domain的设置和文件都压缩、拷贝、解压部署到了新主机上,其余的东西还得自己动手:

  • root账号没有开,developer tools没有安装,这两个可以在account center里作;
  • Virtuozzo -> System Services里的服务大部分都和旧主机一样,有一点不同,手工修改了;
  • root目录下的文件都需要手工拷贝过来;
  • 用户$HOME下除系统自建目录之外的文件都没有转过来,需要手工处理,比如.bashrc, .vimrc
  • chroot环境里原来配置的可执行文件都没了,需要重新配;
  • plesk中的client模板也没转换过来,需要自己重新新建;
  • Apache配置文件/etc/httpd/conf/httpd.conf,php配置文件/etc/php.ini,mysql配置文件/etc/my.cnf,需要手工处理;
  • 原来手工更改为PHP5的用户,需要参照KB: Reverting PHP5 for (dv) 3.0 after migrating to a (dv) 3.5进行修改,删除原来添加的PHP5 fcgi处理部分,然后/usr/local/psa/admin/sbin/websrvmng -a -v即可;
  • 为了安装其他东西方便,这回我先装个yum,从这里下载,i386的;
  • denyhosts还是要装的,从这里下载;
  • ssl证书,虽然是没有公信力的,但还是自己的看着舒服;

vi里中文乱码,需要编辑/etc/sysconfig/i18n,把里面的4行原来注释了的取消注释,原来没注释的加上注释,即:

# cat /etc/sysconfig/i18n 
LANG="en_US.UTF-8"
SUPPORTED="en_US.UTF-8:en_US:en"
SYSFONT="latarcyrheb-sun16"
#LANG="C"

这个需要重启生效。这个好像只对root有效,jail的ssh用户仍然不行,取消了chroot之后就好了;

另注:我migration的时候,虽然大部分文件都过来了,但因为语言包的原因失败了,所以有些内容可能是因为这个原因没有migration过来。

后记、感想

  • 下次再升级之前,一定把自己修改过的脚本备份打包,便于修改新主机上的配置;
  • migration的范围如果能扩大到系统配置,然后系统配置不是覆盖,而是像svn那样能智能merge就好了;
  • plesk功能虽然丰富,可速度是那么得慢,慢到我可以一边等待一边写这些记录,时不时的操作一下对写作思路还有干扰。不止我一个人这么说哦:使用plesk的感想
  • 现在的web服务器选择真是太多了,我知道的除了apache还有lihttpd和nginx,鼓捣php的时候还发现同一种服务还有N种实现方式,学无止境阿。

升级之后

升级结果信息总体保存在/usr/local/psa/PMM/var/2008-07-11-20.05.45.106523,这个目录下面有个archives子目录,是升级时旧服务器上打包的所有文件,确认升级没问题后,可以删掉以节省控件。如果升级完全成功,应该会自动删除这些文件吧。

还得停掉原来的旧主机,可以在Account Center里自助进行:billing > request to close,比如:

plesk migration: close old service

注意并不是一申请就立刻关闭,而是按整月计的,比如:我的旧主机是2007年7月19号租下的,migration到新主机后,新主机将从2008年7月19号开始计算日期;同时我申请关闭旧主机的时候,也只能选择在7月19号、8月19号、9月19号等没有19日关闭,也就是凑够整月。

这个简单的问题疑惑了我很久呢,嘟噜嘟噜问了客服N回,后来自己点点这个功能试试,一切就都清楚了。如果不关闭的话,下一年的账单可又是$500哦。

参考

Update @ 2008-07-20

补充说明一下,刚才看了一下账单,旧主机的“时间”并没有“续”到新服务器上,新服务器的钱是另外单算的,但时间确实是以19号为期限。即:旧主机不动,新主机从2008-07-11到2008-07-18还要收$11,之后才是从2008-07-19到2009-07-18的年费$500。另:ip一年是$12,应该还算便宜吧。

Update @ 2008-07-22

MT还不愿自动关闭旧主机,都21号了,我怕再出什么变故,提交了一个support request询问了一下,今天才“正式”被关闭了。我在想,如果我不要求关闭,会不会一直开下去,还不收钱呢。。。?

关闭之后再访问旧主机页面,好嘛,已经被“升级”到dv 3.5了,这次手可够快的,哼哼。

Update @ 2011-07-16

今天将主机又升级到了 DV4,再用 Unix Bench 算一下,速度大增啊,赚了:

BYTE UNIX Benchmarks (Version 4.1-wht.1)
System -- Linux fwolf.com 2.6.18-028stab091.2 #1 SMP Fri Jun 3 00:02:40 MSD 2011 x86_64 x86_64 x86_64 GNU/Linux
/dev/vzfs             30000000   8393836  21606164  28% /

Start Benchmark Run: Sat Jul 16 05:26:18 EDT 2011
 05:26:18 up  2:57,  1 user,  load average: 0.16, 0.11, 0.03

End Benchmark Run: Sat Jul 16 05:36:23 EDT 2011
 05:36:23 up  3:08,  1 user,  load average: 17.75, 7.10, 3.02


                     INDEX VALUES            
TEST                                        BASELINE     RESULT      INDEX

Dhrystone 2 using register variables        376783.7 27501042.5      729.9
Double-Precision Whetstone                      83.1     1779.1      214.1
Execl Throughput                               188.3     6382.8      339.0
File Copy 1024 bufsize 2000 maxblocks         2672.0   280904.0     1051.3
File Copy 256 bufsize 500 maxblocks           1077.0    65361.0      606.9
File Read 4096 bufsize 8000 maxblocks        15382.0  2573713.0     1673.2
Pipe-based Context Switching                 15448.6   164684.0      106.6
Pipe Throughput                             111814.6  3194647.9      285.7
Process Creation                               569.3    20258.7      355.9
Shell Scripts (8 concurrent)                    44.8     2845.5      635.2
System Call Overhead                        114433.5  2355994.7      205.9
                                                                 =========
     FINAL SCORE                                                     424.3

由一个错误学到的一些php安全配置问题

错误

在MediaTemple主机从(dv)3.0升级到3.5之后,我遇到的第一个问题就是一个莫名奇妙的php错误:

[Sat Jul 12 04:51:27 2008] [error] [client 121.42.26.81] PHP Warning:  require_once(/var/www/vhosts/fwolf.com/include/fwolflib/func/config.php) [<a href='function.require-once'>function.require-once</a>]: failed to open stream: Operation not permitted in /var/www/vhosts/fwolf.com/httpdocs/info.php on line 4
[Sat Jul 12 04:51:27 2008] [error] [client 121.42.26.81] PHP Fatal error:  require_once() [<a href='function.require'>function.require</a>]: Failed opening required '/var/www/vhosts/fwolf.com/include/fwolflib/func/config.php' (include_path='.:/var/www/vhosts/fwolf.com/include') in /var/www/vhosts/fwolf.com/httpdocs/info.php on line 4

因为是migration过来的,所以require的这个文件肯定存在,并且apache用户也的确有权访问,那问题出在哪里呢?

如果换一种方式,require直接使用文件的全路径,错误信息就更清楚了:

<b>Warning</b>:  require_once() [<a href='function.require-once'>function.require-once</a>]: open_basedir restriction in effect. File(/var/www/vhosts/fwolf.com/include/fwolflib/func/config.php) is not within the allowed path(s): (/var/www/vhosts/fwolf.com/httpdocs:/tmp) in <b>/var/www/vhosts/fwolf.com/httpdocs/info.php</b> on line <b>4</b><br />
<br />
<b>Warning</b>:  require_once(/var/www/vhosts/fwolf.com/include/fwolflib/func/config.php) [<a href='function.require-once'>function.require-once</a>]: failed to open stream: Operation not permitted in <b>/var/www/vhosts/fwolf.com/httpdocs/info.php</b> on line <b>4</b><br />

<br />
<b>Fatal error</b>:  require_once() [<a href='function.require'>function.require</a>]: Failed opening required '/var/www/vhosts/fwolf.com/include/fwolflib/func/config.php' (include_path='.:/var/www/vhosts/fwolf.com/include') in <b>/var/www/vhosts/fwolf.com/httpdocs/info.php</b> on line <b>4</b><br />

原来是有个open_basedir限制,找了一下是在$HOME/conf/httpd.include里,这个文件是由plesk自动维护的:

<IfModule sapi_apache2.c>
    php_admin_flag engine on
    php_admin_flag safe_mode off
    php_admin_value open_basedir "/var/www/vhosts/fwolf.com/httpdocs:/tmp"
</IfModule>
<IfModule mod_php5.c>
    php_admin_flag engine on
    php_admin_flag safe_mode off
    php_admin_value open_basedir "/var/www/vhosts/fwolf.com/httpdocs:/tmp"
</IfModule>

看到没,只允许包含httpdocs下的文件。open_basedir影响的范围是fopen, require, include之类的函数,在一定程度上加强了安全防护。

问题

但open_basedir也有局限性,它不会影响那些执行系统命令的函数,比如exec, system,如果我想偷主机上另外一位同学的文件(内容),也不见得非要去用require包含过来或者种个hack过去,直接system('cat /path/to/file')不是更省事么?

system函数有时候还是能派上正当用场的,直接禁用不是什么好办法,现在流行chroot,就是用户的/就是自己的$HOME,压根儿就访问不到别人的文件,什么open_basedir, exec, dl都不用禁用,我觉得这才是安全和方便的最佳接合点。

以前用(dv)3.0的时候,手工配置使用fastcgi的php5就是这样,每个用户的cgi用自己的身份,在自己的chroot环境下运行。

不过plesk现在的版本8、将来的版本9都没有要直接使用fastcgi解析php的打算,在“更远的计划里”,才可怜兮兮的有这么一句:

Use PHP via FastCGI rather than Apache module

参见:Parallels Summit 2008 – Day 1,所以就只能自己动手了。

fastcgi

很走运,找到了一个2天前刚刚出炉的脚本:Script for using php-cgi instead of mod_php,专门针对plesk,禁用掉mod_php,然后用它来配置fcgi解析。

使用环境:Plesk 8.X on Centos 5.X,依赖:

  • 禁用mod_php,开启mod_fcgid
  • python-curl, PyXML
  • php开启–enable-fastcgi, –enable-force-cgi-redirect

文件需要解压到/root/bin/下,自己一个子目录,幸好我也是用这个bin目录的。

然后在Server -> Control Panel -> Event Manager里添加自定义事件,在增加、修改、删除domain的时候,自动调用这个脚本。(subdomain的删除没有包含,手工删除文件就可以了)设置好大概就是这个样子:

using php-cgi instead of mod_php, plesk event manager

还要把/etc/httpd/conf.d/php.conf删得只剩一行:

LoadModule php5_module modules/libphp5.so

并且在/etc/httpd/conf.d/fcgid.conf里加一句:

PHP_Fix_Pathinfo_Enable 1

不过,这种方法作到一半我就没有继续了,因为我想起来前几天一位朋友和我提到过的suPHP。

suPHP

个人感觉suPHP是最“正统”的解决方案,它是以文件属主用户的身份来运行,正好使用各个用户的权限实现访问限制。

没找到centos的mod_suphp包,只好下载suphp 0.6.3源码自己编译,不过之前要先修改src/apache2/mod_suphp.c,在324行替换掉两行内容:

//AP_INIT_ITERATE("suPHP_AddHandler", suphp_handle_cmd_add_handler, NULL, ACCESS_CONF, "Tells mod_suphp to handle these MIME-types"),
AP_INIT_ITERATE("suPHP_AddHandler", suphp_handle_cmd_add_handler, NULL, RSRC_CONF | ACCESS_CONF, "Tells mod_suphp to handle these MIME-types"),
//AP_INIT_ITERATE("suPHP_RemoveHandler", suphp_handle_cmd_remove_handler, NULL, ACCESS_CONF, "Tells mod_suphp not to handle these MIME-types"),
AP_INIT_ITERATE("suPHP_RemoveHandler", suphp_handle_cmd_remove_handler, NULL, RSRC_CONF | ACCESS_CONF, "Tells mod_suphp not to handle these MIME-types"),

然后就是编译安装那三板斧:

# ./configure\
--with-apxs=/usr/sbin/apxs\
--with-php=/usr/bin/php-cgi\
--with-logfile=/var/log/suphp.log\
--with-min-uid=10000\
--with-min-gid=10000\
--with-apache-user=apache\
--with-apr=/usr/bin/apr-1-config\
--with-setid-mode=owner\
--prefix=/usr\
--sysconfdir=/etc
# make
# make install

/etc/httpd/conf/httpd.conf中加入一句(这一句也可以放到后面的suphp.conf中):

LoadModule suphp_module modules/mod_suphp.so

关闭safe_mode,并且注释掉下面两句:

safe_mode = Off
#AddType application/x-httpd-php .php
#AddType application/x-httpd-php-source .phps

创建suphp的conf文件,使用源码中的conf文件模板:

# cp doc/suphp.conf-example /etc/httpd/conf.d/suphp.conf

修改之:

<Directory /var/www/vhosts>
    RemoveHandler x-httpd-php
#   php_admin_value engine off
    AddHandler x-httpd-php .php .php3 .php4 .php5
    suPHP_AddHandler x-httpd-php
    suPHP_Engine On
    suPHP_ConfigPath /etc/php.ini
</Directory>

禁用mod_php,把php.conf文件换一个扩展名就行了:

# cd /etc/httpd/conf.d
# mv php.conf php.conf.bak

创建suPHP的配置文件/etc/suphp.conf,这个文件和用于apache配置的conf是不一样的,其内容如下,可根据具体环境设定参数:

[global]
;Path to logfile
logfile=/var/log/suphp.log

;Loglevel
;loglevel=info
;info, warn, error
loglevel=warn

;User Apache is running as
;webserver_user=wwwrun
webserver_user=apache

;Path all scripts have to be in
docroot=/var/www/vhosts/

;Path to chroot() to before executing script
;chroot=/mychroot

; Security options
;allow_file_group_writeable=false
allow_file_group_writeable=true
;allow_file_others_writeable=false
allow_file_others_writeable=true
;allow_directory_group_writeable=false
allow_directory_group_writeable=true
;allow_directory_others_writeable=false
allow_directory_others_writeable=true

;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=true

;Send minor error messages to browser
;errors_to_browser=false
errors_to_browser=true

;PATH environment variable
env_path=/bin:/usr/bin

;Umask to set, specify in octal notation
;umask=0077
umask=0022

; Minimum UID
;min_uid=100
min_uid=10000

; Minimum GID
;min_gid=100
; Consider of psacln, psaserv
min_gid=200

; Use correct permissions for mod_userdir sites
;handle_userdir=true


[handlers]
;Handler for php-scripts
;x-httpd-php=php:/usr/bin/php
x-httpd-php=php:/usr/bin/php-cgi

;Handler for CGI-scripts
x-suphp-cgi=execute:!self

现在,重启apache,就可以啦!如果发现返回空页面,并且错误log中有如下内容:

Premature end of script headers:

那有可能是因为你把cli模式的php可执行文件拿过来当cgi模式的用了,注意他们的区别:

# php -v
PHP 5.2.6 (cli) (built: May  2 2008 16:06:40) 

# php-cgi -v
PHP 5.2.6 (cgi-fcgi) (built: May  2 2008 16:01:17)

把正确的cgi模式php执行文件设定到/etc/suphp.conf中即可。

chroot的疑惑

由于以前为了安全,ssh权限都是限定在chroot环境下,这样用户无法访问自己$HOME之外的内容。使用了suPHP之后,虽然php文件是以用户身份运行的,但却不是chroot的环境。也就是说,“理论上”在php文件执行的时候,可以访问其他用户的文件,这不也是个安全隐患么?

为了这个问题,我翻阅了好多资料,却发现很少人提起这个东西,suPHP安装不复杂,介绍的也不少,就是没有和chroot搭配的,倒是有人提出和fastcgi搭配使用。后来和michael沟通后才突然醒悟,suPHP的伪装身份和chroot是两种机制,之间没有什么联系,所以也就不存在什么配套使用的问题。至于不想让用户访问别人的文件,完全可以通过设定文件权限来实现嘛,不过还是要在安全方面比以前更加留心:

  • $HOME下系统自动创建的目录,一般属主都是user:psaserv或者root:root,有些对所有人都有rx权限(755),有些则是750权限,私密文件不要往755权限的目录下放。这些目录一般不宜改为750权限,因为有些文件是其他系统服务需要读取的。
  • $HOME下httpdocs, private等目录默认就是禁止所有人访问的,保持这样不要更改,并且httpdocs下的文件你就是搞成777权限,别人也访问不到。
  • 用户自建的文件、目录一般为user:psacln权限,主机上所有host用户所属组都是psacln,所以如果不想让别人访问,又没有上级目录的权限限制的话,一定调整为700权限。
  • 为了使用更方便,可以把$HOME目录的属主设为用户本身,比如chown fwolf:psaserv /var/www/vhosts/fwolf.com,不过这就需要一个个的单独开通了。
  • 如果发现其他系统文件中有泄密的,或者其他用户没有设置好权限,存在安全隐患,请及时告诉我或者相应用户,这样我们才是和谐的一家人嘛 🙂

取消chroot,还有一个好处就是用户几乎能够使用主机上的所有命令了,不像以前那样用哪个就需要把哪个设置到chroot的jail中,方便多了。

chroot的取消不是自动的,我已经给所有用户加上了可指定/bin/bash作为登录shell的权限,用户在plesk的站点设置中,把ssh用户的登录更换为/bin/bash即可,当然如果对安全没有信心,觉得chroot也够用的用户可以保留。

其他

suphp比suexec(就是原来dv3.0升php5的方法)要快一点;比suphp更快的还有suphp_mod_php;再快一些的是mpm-peruser,不过安装配置的麻烦程度也随之递增。

相比而言,suPHP速度还算可以接受(对于负载不是很大的站),配置方便,不用修改每个virtualhost的参数(就是$HOME/conf/vhost.conf),直接改apache的总conf就ok了,当然也比上面fastcgi方式下用event触发脚本来实现更加简洁。

参考

生成用于web服务器的openssl证书

启用https,就一定要有ssl证书,MT主机上有一个默认的证书,但是签署给plesk这个域名的,并且没有根证书认证,所以,自己搞个CA,给自己签个假证书用吧,至少好看些。

说实话,关于证书这些我也是一知半解,以前弄过apache的ssl,但那只是简单的处理,没有CA什么的,这次我上网搜集了不少资料,走了一个算是更“高级”一点的方式吧,不过出来的证书使用起来没有大差别。

注:所有操作在/big2/tools/ca下进行。

准备根证书

准备一些空目录和文件,作用如下:

  • certs/ 保存颁发的所有证书的副本
  • index.txt 跟踪已颁发的证书,初始为空
  • openssl.cnf openssl和根证书的配置文件
  • private/ CA证书的私钥
  • serial 最后一次颁发的证书的序列号,初始值01,也可以是00等其它值

openssl.cnf内容如下,我一气儿弄了10年的有效期:

[ ca ]
default_ca = FwolfCA

[ FwolfCA ]
dir = /big2/tools/ca
certificate = $dir/cacert.pem
database = $dir/index.txt
new_certs_dir = $dir/certs
private_key = $dir/private/cakey.pem
serial = $dir/serial

default_crl_days= 7
default_days = 3650
default_md = sha1

policy = FwolfCA_policy
x509_extensions = certificate_extensions

[ FwolfCA_policy ]
commonName = supplied
stateOrProvinceName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = supplied
organizationName= supplied
organizationalUnitName = optional

[ certificate_extensions ]
basicConstraints= CA:false

# 下面是根证书的配置信息

[ req ]
default_bits = 4096
default_keyfile = /big2/tools/ca/private/cakey.pem
default_md = sha1
prompt = no
distinguished_name = root_ca_distinguished_name
x509_extensions = root_ca_extensions

[ root_ca_distinguished_name ]
commonName = Fwolf CA
stateOrProvinceName = The Earth
# countryName只能是两位字母
countryName = CN
emailAddress = one_mail_of_fwolf@gmail.com
#organizationName = Root Certification Authority
organizationName = Fwolf CA Root
[ root_ca_extensions ]
basicConstraints = CA:true

然后生成根证书:

$ openssl req -x509 -newkey rsa:4096 -out cacert.pem -outform PEM -days 3650 -config openssl.cnf

会提示输入密码以及确认密码。生成好以后可以验证一下(说是验证,其实就是看看内容):

$ openssl x509 -in cacert.pem -text -noout

给自己颁发证书

$ openssl req -newkey rsa:4096 -keyout office.fwolf.com.key.pem -keyform PEM -out   office.fwolf.com.req.pem -outform PEM -sha1

按提示输入两次密码,然后输入几项证书信息,注意其中organizationName必须输入,并且Common Name要和域名一致,比如:

Common Name (eg, YOUR name) []:*.fwolf.com

就生成了私钥key文件和请求req文件,然后把req文件提交给CA根证书签署(盖章):

$ openssl ca -in office.fwolf.com.req.pem -config openssl.cnf

输入根证书的密码,就会在certs/目录下生成.pem证书文件,文件名以serial中的序号开头,信息会存储在index.txt中。

这样生成的证书,在apache中配置需要两条语句,分别指定证书和私钥:

SSLEngine On
SSLCertificateFile /big2/tools/ca/certs/office.fwolf.com.cert.pem
SSLCertificateKeyFile /big2/tools/ca/certs/office.fwolf.com.key.pem

其实这两个文件是可以合并为一个文件的:

$ cat office.fwolf.com.key.pem office.fwolf.com.cert.pem > office.fwolf.com.pem

然后在配置apache的时候就只需要一句了:

SSLEngine On
SSLCertificateFile /big2/tools/ca/certs/office.fwolf.com.pem

其它

去掉证书的口令

现在证书基本上就可以使用了,再返回来说一个问题,就是在启动apache的时候会提示输入私钥的口令,要想去掉这个(一般都不会喜欢这样的),就要求在生成私钥的时候不要设置口令:

$ openssl req -newkey rsa:4096 -keyout office.fwolf.com.key.pem -keyform PEM -out   office.fwolf.com.req.pem -outform PEM -sha1 -nodes

生成根证书的时候还是建议带上个口令,提高安全性。

index.txt

另外,如果要清空index.txt的话,一定要清空到字节0,里面有一个字节都会导致openssl ca错误:

wrong number of fields on line 1 (looking for field 6, got 1, '' left)

证书吊销

$ openssl ca -revoke office.fwolf.com.cert.pem
# 生成CRL列表 $ openssl ca -gencrl -out exampleca.crl # 查看CRL列表信息 $ openssl crl -in exampleca.crl -text -noout # 验证CRL列表签名信息 $ openssl crl -in exampleca.crl -noout -CAfile cacert.pem 可以看到CRL的版本号为1,这是OpenSSL默认的,除非crl_extensions被指定在配置文件ca一节中。

上传到MT主机上应用

首先在Server > Certificates >Add New Certificate,填上Add New Certificate(自己起),然后选下面的Private key私钥文件和Certificate证书文件上传,就存到服务器上了。

然后返回证书列表,选中新上传证书前面的复选框,点上面的链接Make default for Web sites设置为网站默认证书,也可以通过Secure control panel将其设置为控制面板所使用的证书。

还没完,证书还得加到ip上才能生效,Server > IP Addresses >中修改ip地址属性,在SSL Certificate中选择刚才上传的证书,保存,就立刻生效了。

基于ssl/https协议的特性,一个ip上只能使用一个证书,所以合租用户是无法自己上传或者选择其它证书的,不过我现在使用的证书是签给“*”的,也就是所有域名都可以使用,“好看”一点。让我不理解的是,如果在访问一个域名时同意了这个证书,在访问另外一个域名的时候还得再同意一遍,也就是证书和域名是要配套使用的,和我原先的想法不太一致。

参考资料

HTTP–>HTTPS

我无法愤怒,因为不知道该生谁的气。

几天前,网站突然无法访问了,没有响应(不是reset),一开始还以为事网络的问题,后来发现不是,用其他国外主机作跳板可以正常访问,也就是说,在出国的网络出口被DROP了。

我和我们合租的邻居们不会有什么过激的言论,也没有什么PORN的内容,咋就这样了呢。没有客服,原因也没法找了,只能先恢复访问,向MT提交了support request,很快(33分钟后)就得到了的IP,应用在主机上,谁知才2天,又完蛋了。

现在要了第3个IP(这次的响应速度更快,12分钟),同时准备把所有http访问重定向到https访问,算是有些强制吧,弄了个脚本定时执行。没办法,没有别的招数,如果再被封,我也回天无术了。

使用https方式访问网站,速度上没有太大的影响(会有一点点的,服务端加密和客户端解密要耗时),关键事客户端会弹出一个非信任证书的提示,接受或者同意或者永久同意即可,FF3会出一个提示页,上面也有按钮可以添加证书为永久信任证书。如果我们每个域名都单独购买证书的话也不是不可以,不过费用不菲。

http到https的导向其实很容易,用rewrite:

RewriteCond %{HTTPS} !on [NC]
RewriteRule (.*) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

为了使用方便,专门搞了个小脚本,在每个网站的根下添加.htaccess文件,在所有子目录现有的.htaccess文件中添加/更新这段内容。

和wordpress配合使用的时候,遇到了一些麻烦,浪费了我2天2夜的时间,也许还浪费了1个IP,如果早弄好也许第2个IP就不会出事了。这个问题就是,rewrite后重定向到https又会被重定向回http,把rewriterule仔细得看过来看过去也没找到错误,后来发现问题在wordpress上,只要在设置中把2个网站地址更改为https开头就行了。原先的转向死循环就是因为rewriterule把http转向到了https,然后wordpress发现访问地址和网站地址不一样,又给转向回了http。

如果无法进入wordpress的管理界面,也可以直接更改数据库,表wp_options中,option_name为siteurl和home这两项,option_id分别是1和46。

再次赞 (MT)的服务,鄙视国内的网络侦探。

参考

好像其他人也有类似遭遇

Update @ 2008-06-26

取消了强制https,原因一来感觉https消耗的资源和影响的速度比预想中的要多,二来强制也只是相对的,有点知识的就能够绕开,三来没有证书(即使购买了证书也不可能所有域名合用),麻烦多多,FF里有吓人的警告,IE下要狂点确认,很多工具也不支持https,四来取消了强制并不代表https不可用,革命靠自觉,感觉有危险的时候用户自己就知道用https了。

[MediaTemple]虚拟主机内存优化的一点心得

今天下午好像有人对服务器ddos,或者大量灌spam(我不敢说每个人都安装了anti spam插件,即使安装了,“应对”spammer也要消耗服务器资源),http服务器耗尽服务器资源后挂掉,一会儿被watchdog重启,过不了多一会儿再次挂掉。。。以前也尝试过优化apache,不过今天似乎终于摸到了一点儿窍门。

我们合租的MediaTemple服务器cpu负载不高,内存相对紧张:

top - 23:39:45 up 16 days,  7:24,  2 users,  load average: 0.58, 0.50, 0.47
Tasks:  46 total,   1 running,  45 sleeping,   0 stopped,   0 zombie
Cpu(s):  9.9% us,  2.5% sy,  0.0% ni, 87.6% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:    689496k total,   550892k used,   138604k free,        0k buffers

所以优化主要针对如何节约内存。主机内存实际是256M,可能是多核的缘故,总显示接近700M内存,不过对应的各个进程占用的内存也相应增加了。MediaTemple的KB中有一篇(dv) HOWTO: Performance tuning (Optimization),先按照这个来优化一下,主要分为三个部分。

优化Apache(httpd)

缩短超时时限:

#Timeout 120
Timeout 30

调整prefork参数,我调整的结果是:

<IfModule prefork.c>
#1/1/3
StartServers       1
MinSpareServers    1
MaxSpareServers    3
# 50 ?
ServerLimit       20
MaxClients        20
MaxRequestsPerChild  2000
</IfModule>

StartServers是开始的httpd进程数,Min和Max SpareServers是最少和最多空闲进程数,ServerLimit和MaxClients是总进程数限制,这两个参数一般来说是相同的,httpd所消耗的总内存数就和这个相关(实际进程数还会多两个,应该是负责管理子进程的“父进程”),内存不够可以把这两个数值进一步缩小,但这也同时对应着httpd同时处理的并发数。MaxRequestsPerChild是每个进程在处理多少个任务后自杀,根据需要和相关设置还会再启动新的子进程,这种机制有利于释放一些内存碎片。

MaxClients不够会在log产生错误信息,可以用下面的命令查询:

grep -i maxclient /var/log/httpd/error_log

可以根据情况再调整MaxClients的值,但如果内存就是短缺,又能有什么办法呢?

优化Mysql

设置缓存,在my.cnf的[mysqld]段中增加:

# Cache
query-cache-type = 1
query-cache-size = 16M

虽然会多占用一些内存,但能加快处理的速度,尽快把等待队列“消化”掉,还是有利于加速的。在mysql中可以查询cache使用情况:

mysql> show status like 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 12       |
| Qcache_free_memory      | 13028408 |
| Qcache_hits             | 35117    |
| Qcache_inserts          | 751      |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 56       |
| Qcache_queries_in_cache | 377      |
| Qcache_total_blocks     | 872      |
+-------------------------+----------+
8 rows in set (0.00 sec)
...... some times late ......
mysql> show status like 'Qcache%';
+-------------------------+---------+
| Variable_name           | Value   |
+-------------------------+---------+
| Qcache_free_blocks      | 88      |
| Qcache_free_memory      | 8837920 |
| Qcache_hits             | 164437  |
| Qcache_inserts          | 3572    |
| Qcache_lowmem_prunes    | 0       |
| Qcache_not_cached       | 432     |
| Qcache_queries_in_cache | 1177    |
| Qcache_total_blocks     | 2579    |
+-------------------------+---------+
8 rows in set (0.00 sec)

调整query-cache-size的值让Qcache_lowmem_prunes保持在0最好,设置太大了也是浪费内存。

关闭不需要的服务

比如named,域名解析使用域名注册商提供的就足够了,关闭spamassassin,邮件服务仅限于对外发送邮件,不接收:

chmod 644 /etc/init.d/psa-spamassassin

watchdog暂时不建议关闭,人不在的时候它会自动重启服务,还是有一点用处的。

其它优化设置

从其它地方还看到可以开启KeepAlive:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15

这样每个连接可以发送100次请求,超时时间为15秒。如果KeepAliveTimeout减少一些,MaxKeepAliveRequests还可以设置得更大一点。

还可以启用apache的压缩输出功能:

<ifmodule mod_deflate.c>
#   DeflateCompressionLevel 2
    AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php application/x-javascript text/css
</ifmodule>

简单观察一下,开启deflate之后,服务器cpu idle值大概会减少15~20%,国外主机数据传输本身就慢,希望这些花销值得。

top - 01:39:03 up 16 days,  9:23,  3 users,  load average: 2.16, 2.09, 1.97
Tasks:  48 total,   1 running,  47 sleeping,   0 stopped,   0 zombie
Cpu(s): 24.1% us,  8.4% sy,  0.0% ni, 67.6% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:    689496k total,   431452k used,   258044k free,        0k buffers
Swap:        0k total,        0k used,        0k free,        0k cached

结果

现在看一下结果,ps -U apache u能看到一共有20个apache进程在运行,占用内存总量为:

root@fwolf:~# ps -U apache u|awk '{S+=$6} END {print S}'
385396

随着服务运行,内存使用量还会增加(所以MaxRequestsPerChild别设太大,定期重启一些进程)。再看看那个疑似对我ddos的家伙:

root@fwolf:~# netstat -nap|grep :80|wc -l
513
root@fwolf:~# netstat -nap|grep TIME_WAIT|wc -l
9
root@fwolf:~# netstat -nap|grep 124.115|wc -l
464
root@fwolf:~# netstat -nap|grep 124.115.0|wc -l
376
root@fwolf:~# netstat -nap|grep 124.115.4|wc -l
93

此时服务器访问稍慢,有时会超时,但起以前动不动内存不足,httpd挂掉要好一些了。查了一下,这个IP地址属于“陕西省西安市 电信”,地址总换,但基本都在上面两个网段之内。

再后来,访问量降下来之后,系统就恢复正常了,优化应该还是对服务器速度有一些作用的。

root@fwolf:~# netstat -nap|grep :80|wc -l; netstat -nap|grep TIME_WAIT|wc -l
69
47

最后贴两张后台流量图表,异常大概开始于18号下午16点,导致18号流量剧增。服务器时间是西8区,所以小时图表中的0点就是16点。按天的那个图表不知为什么出不来,不过注意18号的流量只是前9个小时的就是了。

Free Image Hosting at www.ImageShack.us

Free Image Hosting at www.ImageShack.us

另外,合租的兄弟们,现在新的dv主机默认是PHP 5.2了,咱们啥时候升级呢?

参考

Update @ 2008-01-19

看来我的担心是多余的,mod_deflate启用之后并没有耗费太多系统资源,访问量恢复正常之后,cpu load也恢复了正常:

top - 16:15:45 up 17 days, 0 min,  1 user,  load average: 0.04, 0.05, 0.07
Tasks:  51 total,   1 running,  50 sleeping,   0 stopped,   0 zombie
Cpu(s):  1.8% us,  0.7% sy,  0.0% ni, 95.9% id,  1.7% wa,  0.0% hi,  0.0% si
Mem:    689496k total,   510200k used,   179296k free,        0k buffers
Swap:        0k total,        0k used,        0k free,        0k cached

好像启用了KeepAlive后httpd进程轮换得特别快,不像以前半天不重生一个。现在可以清楚的看到18号全天的流量图标了,再补两张图:

Free Image Hosting at www.ImageShack.us

Free Image Hosting at www.ImageShack.us

按每小时400M流量计算,每秒流量为110K,不知道算是个什么样的水平。

Update @ 2008-01-19

关闭named服务后,jail环境的ssh用户使用wget下载文件会遇到Name or service not known错误,把/etc/resolv.conf也配置到chroot中就可以了。有趣的是,如果named服务启动着就不存在这个问题。

顺便还把denyhosts装上了,daemon模式运行,占内存不多,攻击者还不少呢,值得。参考:使用DenyHosts阻止SSH暴力破解