2008年8月20日 星期三

整合Apache2.2和Tomcat5.5

自从Apache2.2出来后,apache开始支持proxy-ajp.大家知道Apache里的proxy模块,可以实现双向代理功能,功能非常强大。其实从连接器的实现原理上来说,用proxy模块来实现是非常自然的。proxy模块的功能无非就是把相关的请求发给特定的主机再返回结果。那连接器的功能需求就是要把所有对Servlet/JSP的请求都转给后台的Tomcat。
1.安装包
jdk-1_5_0_09-linux-i586.bin
apache-tomcat-5.5.26.tar.gz
httpd-2.2.9.tar.gz

2.开始安装
a)首先安装jdk,直接拷贝到/usr/local下执行

cd /usr/local
./jdk-1_5_0_09-linux-i586.bin
ln -s /usr/local/jdk1.5.0_09 java

b)解压tomcat到/data/app/tomcat
修改/data/app/tomcat/bin/catalina.sh,在开始添加一行:
JAVA_OPTS='-Xms512m -Xmx1024m'

修改/data/app/tomcat/bin/startup.sh和shutdown.sh,添加java环境变量:
export JAVA_HOME=/usr/local/java

c)最关键的就是安装apache了

# tar zxvf httpd-2.2.9.tar.gz
# cd httpd-2.2.9
# ./configure --prefix=/data/app/apache --enable-proxy
\ --enable-proxy-ajp --enable-proxy-connect
\ --enable-proxy-http --enable-proxy-balancer
\ --enable-so --enable-deflate --enable-headers
\ --enable-include --enable-modules=most
\ -enable-mods-shared=all --enable-rewrite
# make
# make install


d)配置httpd.conf

#加载解析模块(前面我们的linux编译时把下面的模块嵌入到了apache中,所以不用再加载)
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so

#禁止使用proxy_ajp代理的目录:
ProxyPass /images/ !

#使用proxy_ajp代理;下面的配置,是把所有目录全用代理(当然,还会跟上面的禁用配置组合成完整的规则)
ProxyPass / ajp://127.0.0.1:8009/
ProxyPassReverse / ajp://127.0.0.1:8009/

ProxyRequests Off

ProxyPass /admin balancer://tomcatcluster/admin lbmethod=byrequests stickysession=JSESSIONID nofailover=Off timeout=5 maxattempts=3

ProxyPassReverse /admin balancer://tomcatcluster/admin


BalancerMember ajp://localhost:8009 route=tomcat8080
BalancerMember ajp://localhost:10009 smax=10 route=tomcat10080
BalancerMember ajp://localhost:11009 route=tomcat11080
BalancerMember ajp://localhost:12009 smax=10 route=tomcat12080


e)配置虚拟主机
修改httpd.conf
找到以下内容

# Virtual hosts
# Include conf/extra/httpd-vhosts.conf

将第二行前面的”#”去除。
编辑conf/extra/httpd-vhosts.conf


ServerAdmin 127.0.0.1
DocumentRoot “/data/app/tomcat/webapps“
ServerName 127.0.0.1
CustomLog logs/dummy-127.0.0.1-access_log common
ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/
ServerName localhost
ServerAlias 127.0.0.1


对应的修改/data/app/tomcat/conf/server.xml
另外继续配置tomcat的oracle连接池:/data/app/tomcat/conf/context.xml

至此apache和tomcat的整合就基本结束了。

阅读全文...

2008年7月28日 星期一

关于Nginx Fastcgi的安全问题

没有在Nginx的配置中找到Apache中针对每个虚拟主机设置open_basedir的设置,目前只有禁止在某些特定目录下的php解析。
引用官方配置:
Too many example configs fail to secure the "uploads" directory of the application. Remember that if someone can upload a file named xyz.php and the uploads dir is publically accessible then you have given the attacker an easy way to insert PHP onto your site...

So if your app has an upload dir "/images/" then adjust your fastcgi call along the lines of:

http {
index index.php;
root /var/www/htdocs;
# .php
location ~ .*\.php$ {
include /etc/nginx/fcgi.conf;
if ( $uri !~ "^/images/") {
fastcgi_pass 127.0.0.1:10004;
}
fastcgi_index index.php;
}
}

文件夹路径支持正则表达式。如$uri !~ "/*images*/"表示所有含有images字串的文件夹。找到更好的方法再贴出来。

阅读全文...

2008年7月23日 星期三

find的-prune用法 忽略某目录

用find查找时忽略某一目录:

# find -name 123
./a/123
./b/123
./123

# find -path ./a -prune -o -name 123 -print
./b/123
./123

# find -path './[ab]' -prune -o -name 123 -print
./123

注意:-prune参数和-depth、-type等参数冲突,使用后者则-prune失效。

阅读全文...

2008年7月17日 星期四

PHPMyAdmin中文乱码问题简单解决办法

去phpMyAdmin的根目录下,打开以下这个文件:
libraries/select_lang.lib.php
1、找到有"zh-gb2312"的那一行,把'zh-gb2312' 改成 'zh-gb2312-utf-8'
  为什么这样加?那是因为服务器会把没有"-utf-8"的语言过滤掉。
2、找到"$GLOBALS['mysql_charset_map'] = array("那一行
  把'gb2312' => 'gb2312',
  改成 'gb2312' => 'latin1',
  保存,OK,在进入phpMyAdmin管理,选择语言chinese simplified(zh-gb2312-utf-8)
切记要选择语言为chinese simplified(zh-gb2312-utf-8)!
3、编辑phpMyAdmin/libraries/下的string.lib.php
将第41行的
mb_internal_encoding($GLOBALS['charset']);
改为:mb_internal_encoding('utf-8');

重新进入PHPMyAdmin就OK了

阅读全文...

[转帖][备忘]About Bash Shell program

`command` 执行command后取输出作为字串。'`' 为tab上方的键

脚本文件头行若写成#!/bin/sh 即为使用系统默认shell (/binsh为链接文件)

如果省略#!,那么这个脚本文件将不能使用shell内建的指令,such as ‘if else esle fi"

注释:在行后添加注释时,#前需要一个空格。

';'用于在同一行中分隔多个命令

'.'等价于source命令。

':'等价于"NOP",它的返回值为0,也就是shell返回的true。
1、在一个2元命令中提供一个占位符,如: ${username=`whoami`} 如果没有":"的话,将给出一个错误,除非"username"是个命令。
2、在和 > (重定向操作符)结合使用时,把一个文件截断到0长度,没有修改它的权限.
如果文件在之前并不存在,那么就创建它.如:
1 : > data.xxx #文件"data.xxx"现在被清空了.
2
3 #与 cat /dev/null >data.xxx 的作用相同
4 #然而,这不会产生一个新的进程,因为":"是一个内建命令.
注意: 这只适用于正规文件,而不是管道,符号连接,和某些特殊文件

$? 退出状态变量.$?保存一个命令/一个函数或者脚本本身的退出状态.
$$ 进程ID变量.
() 命令组.如: (a=hello;echo $a) Warning!: ()中的命令列表,将作为一个子shell来运行.
在()中的变量,由于是在子shell中,所以对于脚本剩下的部分是不可用的.

&在后台执行命令。
下面这个比较特别
for i in 1 2 3 4 5 6 7 8 9 10 #第一个循环
do
echo -n "$i"
done& #here is the unique。

- 用于重定向标准输入输出 like this:tar cf - .

$arg <-> ${arg}

全引用: '

从命令行中传进来的参数,$0, $1, $2, $3... like: char * arg[].
$* 类似env 环境变量数组
$# 就是args

shift 左移变量 $1的值将被替换成$2...注意$0保持原状

$?读取最后执行命令的退出码。一般情况下,0为成功,非0失败。

文件测试操作
----------------
返回true如果...
-e 文件存在
-a 文件存在
这个选项的效果与-e相同.但是它已经被弃用了,并且不鼓励使用
-f file是一个regular文件(不是目录或者设备文件)
-s 文件长度不为0
-d 文件是个目录
-b 文件是个块设备(软盘,cdrom等等)
-c 文件是个字符设备(键盘,modem,声卡等等)
-p 文件是个管道
-h 文件是个符号链接
-L 文件是个符号链接
-S 文件是个socket
-t 关联到一个终端设备的文件描述符
这个选项一般都用来检测是否在一个给定脚本中的stdin[-t0]或[-t1]是一个终端
-r 文件具有读权限(对于用户运行这个test)
-w 文件具有写权限(对于用户运行这个test)
-x 文件具有执行权限(对于用户运行这个test)
-g set-group-id(sgid)标志到文件或目录上
如果一个目录具有sgid标志,那么一个被创建在这个目录里的文件,这个目录属于创建
这个目录的用户组,并不一定与创建这个文件的用户的组相同.对于workgroup的目录
共享来说,这非常有用.见<>第58页.
-u set-user-id(suid)标志到文件上
如果运行一个具有root权限的文件,那么运行进程将取得root权限,即使你是一个普通
用户.[1]这对于需要存取系统硬件的执行操作(比如pppd和cdrecord)非常有用.如果
没有suid标志的话,那么普通用户(没有root权限)将无法运行这种程序.
见<>第58页.
-rwsr-xr-t 1 root 178236 Oct 2 2000 /usr/sbin/pppd
对于设置了suid的文件,在它的权限标志中有"s".
-k 设置粘贴位,见<>第65页.
对于"sticky bit",save-text-mode标志是一个文件权限的特殊类型.如果设置了这
个标志,那么这个文件将被保存在交换区,为了达到快速存取的目的.如果设置在目录
中,它将限制写权限.对于设置了sticky bit位的文件或目录,权限标志中有"t".
drwxrwxrwt 7 root 1024 May 19 21:26 tmp/
如果一个用户并不时具有stick bit位的目录的拥有者,但是具有写权限,那么用户只
能在这个目录下删除自己所拥有的文件.这将防止用户在一个公开的目录中不慎覆盖
或者删除别人的文件,比如/tmp(当然root或者是目录的所有者可以随便删除或重命名
其中的文件).
-O 你是文件的所有者.
-G 文件的group-id和你的相同.
-N 从文件最后被阅读到现在,是否被修改.

f1 -nt f2
文件f1比f2新
f1 -ot f2
f1比f2老
f1 -ef f2
f1和f2都硬连接到同一个文件

二元比较操作符,比较变量或者比较数字.注意数字与字符串的区别.

整数比较

-eq 等于,如:if [ "$a" -eq "$b" ]
-ne 不等于,如:if [ "$a" -ne "$b" ]
-gt 大于,如:if [ "$a" -gt "$b" ]
-ge 大于等于,如:if [ "$a" -ge "$b" ]
-lt 小于,如:if [ "$a" -lt "$b" ]
-le 小于等于,如:if [ "$a" -le "$b" ]
< 小于(需要双括号),如:(("$a" < "$b"))
<= 小于等于(需要双括号),如:(("$a" <= "$b"))
> 大于(需要双括号),如:(("$a" > "$b"))
>= 大于等于(需要双括号),如:(("$a" >= "$b"))

字符串比较
= 等于,如:if [ "$a" = "$b" ]
== 等于,如:if [ "$a" == "$b" ],与=等价
注意:==的功能在[[]]和[]中的行为是不同的,如下:
1 [[ $a == z* ]] # 如果$a以"z"开头(模式匹配)那么将为true
2 [[ $a == "z*" ]] # 如果$a等于z*(字符匹配),那么结果为true
3
4 [ $a == z* ] # File globbing 和word splitting将会发生
5 [ "$a" == "z*" ] # 如果$a等于z*(字符匹配),那么结果为true
一点解释,关于File globbing是一种关于文件的速记法,比如"*.c"就是,再如~也是.
但是file globbing并不是严格的正则表达式,虽然绝大多数情况下结构比较像.
!= 不等于,如:if [ "$a" != "$b" ]
这个操作符将在[[]]结构中使用模式匹配.
< 小于,在ASCII字母顺序下.如:
if [[ "$a" < "$b" ]]
if [ "$a" \< "$b" ]
注意:在[]结构中"<"需要被转义.
> 大于,在ASCII字母顺序下.如:
if [[ "$a" > "$b" ]]
if [ "$a" \> "$b" ]
注意:在[]结构中">"需要被转义.
具体参考Example 26-11来查看这个操作符应用的例子.
-z 字符串为"null".就是长度为0.
-n 字符串不为"null"
注意:
使用-n在[]结构中测试必须要用""把变量引起来.使用一个未被""的字符串来使用! -z
或者就是未用""引用的字符串本身,放到[]结构中(见Example 7-6)虽然一般情况下可
以工作,但这是不安全的.习惯于使用""来测试字符串是一种好习惯.[1]

混合比较

-a 逻辑与
exp1 -a exp2 如果exp1和exp2都为true的话,这个表达式将返回true

-o 逻辑或
exp1 -o exp2 如果exp1和exp2中有一个为true的话,那么这个表达式就返回true

<< 左移1位(每次左移都将乘2)

<<= 左移几位,=号后边将给出左移几位
let "var <<= 2"就是左移2位(就是乘4)

>> 右移1位(每次右移都将除2)
>>= 右移几位
& 按位与
&= 按位与赋值
| 按位或
|= 按位或赋值
~ 按位非
! 按位否?(没理解和上边的~有什么区别?),感觉是应该放到下边的逻辑操作中
^ 按位异或XOR
^= 异或赋
|| 逻辑或
&& 逻辑与

阅读全文...

2008年4月18日 星期五

PHP的mhash和mcrypt支持

志愿通的网站需要添加mhash和mcrypt模块
首先在SourceForge上下载mhash和mcrypt (mcrypt要下载Libmcrypt和mcrypt两个包)
mhash下载
mcrypt下载
下载后先安装Mhash

# tar zxvf mhash-0.9.9.tar.gz
# cd mhash-0.9.9
# ./configure
# make install

按照PHP手册的配置安装Libmcrypt

# tar zxvf libmcrypt-2.5.8.tar.gz
# cd libmcrypt-2.5.8
# ./configure --disable-posix-threads
# make install

最后安装mcrypt,mcrypt与以上两个包有依赖性的,因此必须按此顺序安装
直接configure报错:configure: error: "You need at least libmhash 0.8.15 to compile this program. http://mhash.sf.net/"
由于先前安装了mhash,多半是没有找到mhash的lib文件的路径,修改LD_LIBRARY_PATH:

# cd mcrypt-2.6.4
# LD_LIBRARY_PATH=/usr/local/lib ./configure
# make
# make install

安装成功!
重新编译PHP:
./configure --with-mcrypt[=DIR] --with-mhash[=DIR]
查看phpinfo,成功添加mhash和mcrypt模块!

阅读全文...

2008年3月19日 星期三

MySQL同步故障:" Slave_SQL_Running:No"

今天检查数据库发现一台MySQL Slave未和主机同步,查看Slave状态:
mysql> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_Errno: 1062
....
Seconds_Behind_Master:NULL

原因:
1.程序可能在slave上进行了写操作
2.也可能是slave机器重起后,事务回滚造成的.

解决办法I:
1.首先停掉Slave服务:slave stop
到主服务器上查看主机状态:
记录File和Position对应的值。


mysql> show master status;
+------------------+-----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+-----------+--------------+------------------+
| mysql-bin.000020 | 135617781 | | |
+------------------+-----------+--------------+------------------+
1 row in set (0.00 sec)

3.到slave服务器上执行手动同步:

mysql> change master to
> master_host='master_ip',
> master_user='user',
> master_password='pwd',
> master_port=3307,
> master_log_file='mysql-bin.000020',
> master_log_pos=135617781;
1 row in set (0.00 sec)
mysql> slave start;
1 row in set (0.00 sec)

再次查看slave状态发现:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
Seconds_Behind_Master: 0
解决办法II:
mysql> slave stop;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> slave start;

阅读全文...

2008年3月6日 星期四

使用DBLINK创建oracle数据库链接

首先保证所有的oracle能够识别其他的host,编辑/etc/hosts做命名和IP的对应;
编辑所有的tnsname.ora,保证所有的oracle均能够通过统一的命名访问其他的oracle
数据库全局名称可以用以下命令查出:
SQL>SELECT * FROM GLOBAL_NAME;
修改可以用以下语句来修改参数值:
SQL>ALTER SYSTEM SET GLOBAL_NAME=TRUE/FALSE;
I.当数据库参数global_name=false时,就不要求数据库链接名称跟远端数据库名称一样。

oracle数据库之间进行连接通讯。
创建数据库链接的语法如下:
CREATE [PUBLIC] DATABASE LINK link
CONNECT TO username IDENTIFIED BY password
USING ‘connectstring’


这样在某一台数据库上都能够操作其他的数据库,例如
如果我们在oracle3上要查询oracle4上的一个表:
oracle3 sql> select id,name from table1@oracle4;

注意:创建数据库链接的帐号必须有CREATE DATABASE LINK或CREATE PUBLIC DATABASE LINK的系统权限,用来登录到远程数据库的帐号必须有CREATE SESSION权限。这两种权限都包含在CONNECT角色中(CREATE PUBLIC DATABASE LINK权限在DBA中)。

一个公用数据库链接对于数据库中的所有用户都是可用的,而一个私有链接仅对创建它的用户可用。由一个用户给另外一个用户授权私有数据库链接是不可能的,一个数据库链接要么是公用的,要么是私有的。

II.当数据库参数global_name=true时,那就要求数据库链接名称跟远端数据库名称一样
通过视图global_name可以获得当前参数的设置:
SQL> select * from global_name;

GLOBAL_NAME
--------------------------------------------------
WAPDB.REGRESS.RDBMS.DEV.US.ORACLE.COM

我们可以通过如下命令修改GLOBAL_NAME
SQL>conn / as sysdba
SQL>update props$ set value$ = 'oradb' where name = 'GLOBAL_DB_NAME';
SQL>commit;
SQL>shutdown immediate
SQL>startup

之后再创建dblink即不带域名。

注意:
1)dblink名必须与远程数据库的全局数据库名(global_name)相同;
2)用户名,口令为远程数据库用户名,口令;
3)主机字符串为本机tnsnames.ora中定义的串;
4)两个同名的数据库间不得建立dblink;
然后,你就可以通过dblink访问远程数据库了。

参考:
oracle数据库链接及数据合并的问题?
在oracle下如何创建database link全面总结
Global_name从何处来?

阅读全文...