继续诡异的问题。今天在一台Ubuntu 8.10 Server版本上用这样的configure条件:
[code=’sh’]
‘./configure’ \
‘–with-mysql=/usr/local/mysql’ \
‘–with-apxs2=/usr/local/apache/bin/apxs’ \
‘–enable-mbstring’ \
‘–with-mcrypt’ \
‘–with-gd’ \
‘–with-jpeg-dir=/usr/local/’ \
‘–with-png-dir=/usr/lib’ \
‘–enable-exif’
[/code]
第一个问题:
[code=’sh’]
configure: error: libjpeg.(a|so) not found.
[/code]
我以为是libjpeg没装,下好libjpeg-6b.tar.gz,这样装了:
[code=’sh’]
tar -zxvf libjpeg-6b.tar.gz
cd libjpeg-6b
./configure
make
sudo make install
[/code]
但是还是提示上面的错误。很迷惑,后来发现是/usr/lib下没有libjpeg的文件,正确的libjpeg安装应该这样子:
[code=’sh’]
tar -zxvf libjpeg-6b.tar.gz
cd libjpeg-6b
./configure
make
# 这一步很重要!
sudo make install-lib
sudo make install
[/code]
PHP的configure成功结束了,但是make编译PHP 5.2.8时出错:
[code=’sh’]
/home/nocoo/soft/php-5.2.8/main/output.c:421:
undefined reference to `php_ob_gzhandler_check’
collect2: ld returned 1 exit status
make: *** [sapi/cgi/php] Error 1
[/code]
大惑不解,然后我搜我搜我搜搜搜,终于发现,只需要加入’–with-zlib’就可以让PHP用zlib,从而消除了这个配置错误。
最终正确的configure命令如下:
[code=’sh’]
‘./configure’ \
‘–with-mysql=/usr/local/mysql’ \
‘–with-apxs2=/usr/local/apache/bin/apxs’ \
‘–enable-mbstring’ \
‘–with-mcrypt’ \
‘–with-zlib’ \
‘–with-gd’ \
‘–with-jpeg-dir=/usr/local/’ \
‘–with-png-dir=/usr/lib’ \
‘–enable-exif’
[/code]

为了达成这样一个PHP configure,当中我装过的lib列表如下:

  • libxml2-sources-2.7.2.tar.gz
  • zlib-1.2.3.tar.gz
  • libmcrypt-2.5.8.tar.gz
  • libpng-1.2.34.tar.gz
  • libjpeg-6b.tar.gz
  • gd-2.0.35.tar.gz

因为简单执行:
[code=’sh’]
tar -zxvf {target}.tar.gz
cd {target}
./configure
make
sudo make install
[/code]
就成功了,所以这里没什么好说的,你要是缺,也装上即可。

本人曾经号称Linux+Apache+MySQL+PHP环境的搭建是闭着眼睛也能做的事情。历史上也的确曾经无数次闭着眼睛半小时就能搞定从下载到编译到最终配置成生产环境的服务器整个过程。然而昨天遇到的一切,却实实在在让我睁开眼睛集中精力总计用了8个小时才部署起一套Linux+Apache+MySQL+PHP+Ruby on Rails。
回忆总是痛苦的,不过为了大家不再痛苦重蹈覆辙,我还是愿意重走长征路,分析一下我犯过的错误吧。

1. Are we ready for x64?

我们实验室的德国学弟向来使用Linux。当年他到我们这里来的时候,作为网管的我需要给他安装一套英文版操作系统。我手上有Windows Server Computing Cluster Edition,正好是英文版,而且是正版,可惜是64位系统。在我询问他的过程中,他问我觉得64位版本的Windows怎么样。我回答”Only more troubles.”,他笑,告诉我看来Windows并没有准备好,还是Linux的64位支持比较好吧。其实我还是持某种怀疑态度。
我觉得,作为生产环境的网络管理员,使用64位版本操作系统总是要三思的事情。因为有太多太多兼容性问题需要考虑。在这方面,好像其实Windows做的反而更好一些,因为.NET编译的exe程序拿到64位版本Windows上不需要重新编译直接就可以原生64位地运行。64位Windows中还包含一个32位虚拟机,可以近乎完美地模拟32位环境,提供向下支持。
Linux就不是这么幸运了。很多库都没有考虑过这些问题,这也是导致这次部署麻烦多多的根源。

2. 64位Fedora 9和32位Fedora 10

今天用的机器是一台IBM x3200服务器。本来上面装好Fedora 9的64位版本。因为很久没登陆上去,我并不知道这是一台跑着64位版本的系统。
于是上来安装Apache,似乎一切顺利。下载最新版MySQL,版本5.1的二进制版本并安装,也没有遇到什么问题。
然后安装PHP,配置make使用以下命令:
[code=’c#’]
‘./configure’
‘–with-mysql=/usr/local/mysql’
‘–with-apxs2=/usr/local/apache/bin/apxs’
‘–with-zlib’
‘–with-bz2’
‘–with-gd’
‘–with-png-dir=/usr/lib’
‘–with-zip-dir=/usr/lib’
‘–enable-track-vars’
‘–enable-exif’
‘–enable-mbstring’
[/code]
然后出现错误:
[code=’c#’]
checking for MSSQL support via FreeTDS… no
checking for MySQL support… yes
checking for specified location of the MySQL UNIX socket…
no
checking for MySQL UNIX socket location… no
checking for mysql_close in -lmysqlclient… no
checking for mysql_error in -lmysqlclient… no
configure: error: mysql configure failed. Please check
config.log for more information.
[/code]

3. 错怪MySQL 5.1

接下来我犯下了第一个错误:让新闻影响了经验。我受到影响的新闻是:MySQL创始人力劝用户暂缓部署MySQL 5.1,鉴于我不下10次地用这个配置命令装过LAMP环境,我第一个矛头指向了MySQL 5.1。
然后我在Google中发现,这个问题被当作Bug在MySQL的项目管理和PHP的项目管理系统中多次出现:

我看到几种所谓解决方案:

  • 主张将“–with-mysql=/user/local/mysql”改成“–with-mysql-dir=/user/local/mysql”
  • 主张将Makefile里面的-L/usr/lib/mysql改为-L/usr/lib64/mysql

我犯的第二个错误是过于自信,其实现在看起来有很多地方提升我,这个问题是由64位的Linux导致的,但是盲目的我当时选择了视而不见。

4. Ruby on Rails

为了避免将来更多的麻烦,我选择了最复杂的方式:换64位Fedora到32位Fedora 10。接下来的过程很顺利。
全部安装好之后我决定把原来实验室的Redmine也搬进来,于是需要集成Passenger到Apache中。
使用yum和gem安装Ruby on Rails的过程只需要用愉悦来形容,很顺利。
在gem装好Passenger之后,执行:
[code=’c#’]
passenger-install-apache2-module
[/code]
的时候出现一个小细节,Passenger安装脚本发现Apache在/etc/sbin/httpd下,其实我安装在/usr/local/apache下。这时候需要用几个环境变量来纠正一下。
[code=’c#’]
export APU_CONFIG=/usr/local/apache/bin/apu-1-config
export APR_CONFIG=/usr/local/apache/bin/apr-1-config
[/code]

DATE和TIME是MySQL表里面字段类型的两种,分别用来保存日期和时间。
也许在开发机器上不太注意吧,对这两种类型的处理的时候,尤其是插入数据的时候,不注意真的还是会出问题的。比如这次,想自己探索写一个DDNS(Dynamic DNS),插入数据的时间的时候,发觉好像有点问题啊。服务器在美国,自然是美国时间,我总不至于去手动处理时区问题…?
[code=’php’]
mysql_query(“SET time_zone = ‘+8:00′”);
[/code]
在执行MySQL查询之前,执行设置时区,之后的操作就都是东八区北京时间了。
[code=’php’]
mysql_query (“INSERT INTO `db`.`table` (`date` ,`time`) VALUES (NOW(), NOW());”);
[/code]
对DATE和TIME的数据插入时,都可以直接用MySQL函数NOW()。注意,NOW()两边不要加引号。

本文致力于描述如何在Windows Server 2008下安装配置用于开发或产品的MySQL及PHP环境。

环境说明:

  • 操作系统:Windows Server 2008 Standard Edition,英文版(由Microsoft DreamSpark支持)
  • 相关软件:Internet Information Services 7.0
  • MySQL:MySQL 5.0.67, Windows Essentials (x86)。(最新版下载地址
  • PHP:PHP 5.2.6 zip package。(最新版下载地址

1. 安装MySQL

这似乎是一个波澜不惊的过程,任何人都能做好。
[singlepic=18162]
安装欢迎界面。
[singlepic=18163]
这一步选Custom自定义安装比较好,指定安装位置,建议安装在D盘,避开系统盘C盘。由于UAC的问题,在Vista和2008下,C盘的文件搞得很特殊,一些原来好好的程序,由于权限问题的存在,会出现莫名奇妙的故障。
Continue reading

防止你的网站被注入式攻击的第一步是理解什么是注入式攻击。一个注入式攻击是网站的某个访客在你的网站输入表单中输入了某种内容,试图改变你的MySQL查询本意。例如,某些人可能会在登陆窗口使用这种方法绕开登陆。如果你的查询用户名和密码的形式类似这样子:
[code=’sql’]
SELECT * FROM users WHERE username = {username} AND
password = {password }
[/code]
那么用户可以使用任意的用户名,使用这个密码:
[code=’sql’]’ OR ”=”[/code]
从而使得你的验证用户名密码的MySQL查询变成:
[code=’sql’]
SELECT * FROM users WHERE username = ‘anyuser’ AND
password = ” OR ”=”
[/code]
由于空串总是等于空串,所以查询条件永真。因此可以看到,MySQL注入的风险还是很大的,因为攻击者可以看到那些本来应该通过登陆才能访问的数据。防止你的网站受到注入式攻击是非常重要的。幸运的是,PHP可以帮助我们防止注入式攻击。
MySQL将会返回表中的所有行,根据你的程序逻辑,可能会导致全部用户都登陆了,因为他们都被匹配到了。现在,大部分情况下,人们会打开magic_quotes_gpc选项(也是PHP的默认情况),这样的配置将会自动添加反斜线,转义全部'(单引号),”(双引号),\(反斜线)和空字符。但事情并不是这么简单就能解决,因为并不是所有的会导致风险的字符都被转义了。PHP有一个函数可以转义全部可能带来多余SQL子句的MySQL字符。这个函数就是mysql_real_escape_string()
使用这个函数的时候要小心,因为你可能已经打开了magic_quotes_gpc选项,这时候使用mysql_real_escape_string()会导致第二次转义。下面这个函数避免了这个问题,首先判断
magic_quotes_gpc选项是否打开,然后再决定是否执行mysql_real_escape_string()
[code=’php’]

[/code]
需要注意的是,quote_smart()函数会自动给字符串加引号,因此你不需要自己加。
另外需要注意,因为不同的MySQL版本对于过滤的要求不一样,mysql_real_escape_string()需要一个MySQL连接才能工作,因此必须第二个参数传入一个MySQL连接。在本机安装MySQL的情况,可以省略,但是如果本机没有装MySQL,或者远程连接到MySQL,则这个参数必不可少,否则mysql_real_escape_string()将返回一个空字符串。
如果你有任何疑问,可以在下面评论,我们一起讨论。

12月份原来在炎黄的服务器空间就要过期了, 想了想是不是继续续费的问题, 最终决定还是搬到同济网服务器吧. 毕竟是一个经常关心的服务器, 几乎每天都来维护, 放在自己手里毕竟还是放心一点. 无奈同济网服务器上的MySQL字符集还是老的3.25版本的latin1字符集, MySQL的版本也过低, wordpress装不上. 更新字符集的问题老早就提出来了, 只是这个过程实在太复杂, 一直没实施. 其实这其中的每个细节我都仔细想过, 只是没有操作出来而已. 不过即便如此, 今天在真正操作的时候心里也是没底的.

起了个大早, 6点半就开始在Linux主机上工作, 一直做到下午, 一共转了近1000万行SQL数据, 把字符集成功转换成了gbk. 功在当代利在千秋的事情. 从此我们的服务器用上了最新版本的MySQL, Apache和PHP.

如何做的呢? 说下大概过程吧. MySQL的文档里讲推荐逐步升级, 3.x要先升级到4.0, 然后4.1, 然后5.0. 我觉得没必要, 另外4.0这样的老版本根本找不到下载了, 这个文档写的太XX了. 首先在MySQL 3.x里用mysqldump把数据导成SQL文件, 按照数据库导出, 大型数据库要注意对导出后的文件进行分割, 用如下命令:

split -l 100000 filename

进行按行分割, 我们的BBS分成了8个100万行的文件. 这样操作的原因是一旦出错, 修改的时候打开起来方便, 不至于每次打开一个3GB的大文件. 然后升级MySQL到5.0, 建数据库, 整理选成gbk_chinese_ci, 然后在每个将要导入的文件开头加上:

set names 'gbk';

然后用如下命令导入:

mysql -uroot -ppassword --default-character-set=gbk -f target_db < source.sql

这样的话, 就会在phpMyAdmin里面正确看到我们的母语. 别告诉我你不行. 我行你就行, 不然对不起孔子, 也对不起王选.

MySQL是一个优秀的小型数据库,应用很广。但是新版本出来之后,困扰PHPMyAdmin用户的问题也出现了:

shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client

官方的说法是

MySQL 4.1 and up uses an authentication protocol based on a password hashing algorithm that is incompatible with that used by older clients. …..

如果你升级mysql到4.1以上版本后遇到以上问题,请先确定你的mysql client 是4.1或者更高版本.(WINDOWS下有问题你就直接跳到下面看解决方法了,因为MYSQL 在WINDOWS是client和server一起装上了的)
请使用以下两种方法之一
其一:
[code=’sql’]mysql> SET PASSWORD FOR
-> ’some_user’@’some_host’ = OLD_PASSWORD(’newpwd’);[/code]
其二:
[code=’sql’]mysql> UPDATE mysql.user SET Password = OLD_PASSWORD(’newpwd’)
-> WHERE Host = ’some_host’ AND User = ’some_user’;
mysql>; FLUSH PRIVILEGES;[/code]
上面用户名密码的部分请按自己实际情况修改….
这样做后,连接就会正常了@!
但是在我的应用中,只有第二种方法管用…