2009年4月29日星期三

telnet发送邮件command

Step1: telnet mail.bdwater.com 25
说明:telnet是远程连接工具,windows自带;mail.bdwater.com是邮件服务器,这里是SMTP服务器;25是SMTP所使用的端口号。
如果该请求(命令)成功接受,远程smtp服务器就会响应如下信息:
220 bdwater.com ESMTP MDaemon 7.1.2; Tue, 10 Aug 2004 16:59:55 +0800

Step2: helo xia.bdgs.com
说明:helo是客户为了标识发信人的命令;xia.bdgs.com是客户主机的域名。
如果该请求(命令)成功接受,远程smtp服务器就会响应如下信息:
250 bdwater.com Hello xia.bdgs.com, pleased to meet you

Step3: mail from: test1@bdwater.com
说明:mail from:写发件人地址的命令。
如果该请求成功接受,远程smtp服务器就会响应如下信息:
250 , sender ok.

Step3: rcpt to: test@.bdwater.com
说明:rcpt to:写收件人地址的命令。
如果该请求成功接受,远程smtp服务器就会响应如下信息:
250 , Local recipient ok.

Step4: data
说明:data写信息内容的命令。
如果该请求成功接受,远程smtp服务器就会响应如下信息:
354 Enter mail, end with .

Step5: from:test1
to:test2
date:10/10/2004
subject:This is a test mail

Dear test2, this is a test mail.
.
说明:from:是发信人的标志;to:是收信人的标志;date:发信日期;subject:信的主题;然后留一行空格,写信的内容;结束时先按回车,输入”.”,再按回车,就ok了。
如果该请求成功接受,远程smtp服务器就会响应如下信息:
.250 Ok, message saved

2009年4月27日星期一

Linux环境下查看Tomcat版本

1、查看linux的版本号cat /proc/version - Linux的版本号 相当于 uname -r——查看linux的版本号
2、如果使用 rpm 安装的tomcat:输入命令:rpm -q tomcat
3、如果不是使用 rpm 安装的tomcat:[isomap@isomap-beta bin]$ ./catalina.sh version
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/java/jdk1.5.0_11
Server version: Apache Tomcat/5.5.23
Server built: Mar 5 2007 08:25:04
Server number: 5.5.23.0
OS Name: Linux
OS Version: 2.6.18-8.el5xen
Architecture: i386
JVM Version: 1.5.0_11-b03
JVM Vendor: Sun Microsystems Inc.

2009年4月24日星期五

APACHE-PHP-MYSQL-ZEND

先声明,我绝对是个Linux的菜鸟,以下的这些文字个人的安装笔记,是参考了网上许多高手的成功经验组合而成的,说实话我自己的东西不多 :)我想把这些经验写下来,既可以对其他跟我一样摸索的兄弟一个经验,也可以防止以后自己都忘记了,嘿嘿。

所以如果某个大虾看到我借用了你的资源,请你不要生气。也欢迎大家进行指点。

1、下载centos 4.4
我是下载的DVD版本,大家也可以下载服务器CD安装版本,其实都差不多。大家可以到这儿下载,速度很快的。
http://ftp.iasi.roedu.net/mirrors/centos.org/4.4/isos/i386/

下载后当然就刻录成光盘。我建议你刻录DVD啦,如果是菜鸟,也可以在图形界面进行学习,不会这么抓不住头脑。

2、(1)安装CentOS4.4
作为服务器,不安装不需要的组件,所以在选择组件的时候,除了选择FTP SERVER外取消所有组件的选择。也不要选web服务器。因为我们后面要手动编译安装。


系统约定RPM包和源码包存放位置

RPM包和源码包存放位置 /usr/local/src
源码包编译安装位置(prefix) /usr/local/xxx
脚本以及维护程序存放位置 /usr/local/sbin
MySQL 数据库位置 /var/lib/mysql
Apache 网站根目录 /home/www
Apache 虚拟主机日志根目录 /data/logs/www
yum RPM包信息文件 /etc/yum.list

(2)更新系统,此处我们使用up2date,先修改up2date镜像。
vi /etc/sysconfig/rhn/sources

我把源修改成这样了:

yum centos4-Base http://mirror.be10.com/centos/4/os/$ARCH/
yum centos4-Updates http://mirror.be10.com/centos/4/updates/$ARCH/
yum centos4-extras http://mirror.be10.com/centos/4/extras/$ARCH/
yum centos4-contrib http://mirror.be10.com/centos/4/contrib/$ARCH/
yum centos4-addons http://mirror.be10.com/centos/4/addons/$ARCH/
yum centos4-centosplus http://mirror.be10.com/centos/4/centosplus/$ARCH/

然后执行:
# up2date -l //列出更新
# up2date -uf //更新包括版本的所有程序。如果不包括内核,则用up2date -u


3、系统环境部署及调整

(1). 检查系统是否正常
# more /var/log/messages //检查有无系统内核级错误信息
# demesg //检查硬件设备是否有错误信息
# ifconfig //检查网卡设置是否正确
# ping www.163.com // 检查网络是否正常

(2). 关闭不需要的服务
# export LANG='en_US' //设置语言
# setup //选择启动的服务
进入system service 选项。
以space 键选定所需服务。
以下仅列出需要启动的服务,未列出的服务一律关闭:
crond
irqbalance 仅当服务器CPU为S.M.P架构或支持双核心、HT技术时,才需开启,否则关闭。
microcode_ctl
network
vsftpd
sshd
syslog

(3)、修改/etc/yum.repos.d/CentOS-Base.repo,将镜象站点地址改为在中国的镜象站点地址。不然我们通过yum安装软件速度会极慢。修改如下:

# CentOS-Base.repo
#
# This file uses a new mirrorlist system developed by Lance Davis for CentOS.
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#

[base]
name=CentOS-$releasever - Base
baseurl=http://mirror.vmmatrix.net/CentOS/$releasever/os/$basearch/
http://mirror.be10.com/centos/$releasever/os/$basearch/
http://centos.hostlink.com.hk/$releasever/os/$basearch/
http://ftp.hostrino.com/pub/centos/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos4

#released updates
[update]
name=CentOS-$releasever - Updates
baseurl=http://mirror.vmmatrix.net/CentOS/$releasever/os/$basearch/
http://mirror.be10.com/centos/$releasever/os/$basearch/
http://centos.hostlink.com.hk/$releasever/os/$basearch/
http://ftp.hostrino.com/pub/centos/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos4

#packages used/produced in the build but not released
[addons]
name=CentOS-$releasever - Addons
baseurl=http://mirror.vmmatrix.net/CentOS/$releasever/os/$basearch/
http://mirror.be10.com/centos/$releasever/os/$basearch/
http://centos.hostlink.com.hk/$releasever/os/$basearch/
http://ftp.hostrino.com/pub/centos/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos4

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=http://mirror.vmmatrix.net/CentOS/$releasever/os/$basearch/
http://mirror.be10.com/centos/$releasever/os/$basearch/
http://centos.hostlink.com.hk/$releasever/os/$basearch/
http://ftp.hostrino.com/pub/centos/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos4

#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos4

#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib
baseurl=http://mirror.centos.org/centos/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos4

保存。

然后导入key升级相应yum数据

# rpm --import /usr/share/doc/centos-release-4/RPM-GPG-KEY-centos4
# yum list tee /etc/yum.list //读取yum list 数据,将其输出到 /etc/yum.list。


(4)、定时校正服务器时间
# yum install ntp
# crontab -e
0 23 * * * root /usr/sbin/ntpdate 210.72.145.44 > /dev/null 2>&1

以上命令设置好后存盘。您的机器将在每天的23:00根据中国国家授时中心的NTP服务器时间自动校准时间。

(5). 对TCP/IP网络参数进行调整,加强抗SYN Flood能力
# echo 'net.ipv4.tcp_syncookies = 1' >> /etc/sysctl.conf //将net.ipv4.tcp_syncookies = 1写入sysctl.conf 文件
# sysctl -p //查看

(6)、FTP服务器的配置
vi /etc/vsftpd/vsftpd.conf
把anonymous_enable=YES注释掉不允许匿名登录。
把chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
前的注释去掉。
把ftpd_banner=*前的注释去掉。后面改成你的欢迎信息(这样设置可以避免显示ftp服务器的版本信息)
然后保存,service vsftpd start就可以了。

这时应当添加用户,因为root默认不能通过FTP方式登录。

# adduser username
# passwd userpassword

这样对于我们上传一些文件到系统中很方便。


4. 重新启动系统
# init 6


5. 使用 yum 程序安装所需开发包(以下为标准的 RPM 包名称)
# yum install gcc gcc-c++ gcc-g77 flex bison autoconf automake bzip2-devel zlib-devel ncurses-devel libjpeg-devel libpng-devel libtiff-devel freetype-devel pam-devel

#这里我们将编译GD所必须的一些小软件比如libpng,libtiff,freetype,libjpeg等先用RPM的方式一并安装好,避免手动编译浪费时间,同时也能避免很多错误,这几个小软件的编译很麻烦。这几个小软件编译错误了,GD当然安装不了,php5的编译当然也没戏了。所以我们抓大放小,对这些小牛鬼蛇神采取快速简洁的方式进行安装。并且对服务器的性能也不能产生什么影响。

6. 源码编译安装所需包 (Source)
(1) GD2
# cd /usr/local/src
# wget http://www.boutell.com/gd/http/gd-2.0.33.tar.gz
# tar xzvf gd-2.0.33.tar.gz
# cd gd-2.0.33
# ./configure --prefix=/usr/local/gd2 --mandir=/usr/share/man //./configure 配置。
# make //make 是用来编译的,它从 Makefile 中读取指令,然后编译。
# make install //make install 是用来安装的,它也从 Makefile 中读取指令,安装到指定的位置。

(2) Apache 日志截断程序
# cd /usr/local/src
# wget http://cronolog.org/download/cronolog-1.6.2.tar.gz
# tar xzvf cronolog-1.6.2.tar.gz
# cd cronolog-1.6.2
# ./configure --prefix=/usr/local/cronolog
# make
# make install

(3) libxml 库程序
# cd /usr/local/src
# wget http://ftp.gnome.org/pub/gnome/sources/libxml2/2.6/libxml2-2.6.26.tar.gz
# tar zxvf libxml2-2.6.26.tar.gz
# cd libxml2-2.6.26
# ./configure --prefix=/usr/local/libxml2
# make
# make install

7、编译mysql 5.0.33

cd /usr/local/src
# wget http://mysql.oss.eznetsols.org/Downloads/MySQL-5.0/mysql-5.0.33.tar.gz
# tar xzvf mysql-5.0.33.tar.gz
# cd mysql-5.0.33

修改mysql 客户端最大连接数, 默认的只有100,远远达不到我们的要求。

# vi sql/mysqld.cc

搜索找到下面一行:
{"max_connections", OPT_MAX_CONNECTIONS,
"The number of simultaneous clients allowed.", (gptr*) &max_connections,
(gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1,
0},

将其中的100改为1500, 当然小点也可以,根据你的需要来,不建议改的太大。

{"max_connections", OPT_MAX_CONNECTIONS,
"The number of simultaneous clients allowed.", (gptr*) &max_connections,
(gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 1500, 1, 16384, 0, 1,
0},

保存。

# CHOST="i686-pc-linux-gnu" CFLAGS="-O3 -msse2 -mmmx -mfpmath=sse -mcpu=pentium4 -march=pentium4 -pipe -fomit-frame-pointer" CXXFLAGS="-O3 -msse2 -mmmx -mfpmath=sse -funroll-loops -mcpu=pentium4 -march=pentium4 -pipe -fomit-frame-pointer" ./configure --prefix=/usr/local/mysql --localstatedir=/var/lib/mysql --with-comment=Source --with-server-suffix=-Community-Server --with-mysqld-user=mysql --without-debug --with-big-tables --with-charset=latin1 --with-collation=latin1_swedish_ci --with-extra-charsets=all --with-pthread --enable-static --enable-thread-safe-client --with-client-ldflags=-all-static --with-mysqld-ldflags=-all-static --enable-assembler --without-innodb --without-ndb-debug --without-isam


配置成功会提示:

MySQL has a Web site at http://www.mysql.com/ which carries details on the
latest release, upcoming features, and other information to make your
work or play with MySQL more productive. There you can also find
information about mailing lists for MySQL discussion.

Remember to check the platform specific part of the reference manual for
hints about installing MySQL on your platform. Also have a look at the
files in the Docs directory.

Thank you for choosing MySQL!

// 注意 ,CHOST="i686-pc-linux-gnu" CFLAGS="-O3 -msse2 -mmmx -mfpmath=sse -mcpu=pentium4 -march=pentium4 -pipe -fomit-frame-pointer" CXXFLAGS="-O3 -msse2 -mmmx -mfpmath=sse -funroll-loops -mcpu=pentium4 -march=pentium4 -pipe -fomit-frame-pointer" 这个环境参数只针对intel P4 芯片,如果你的CPU是AMD的,注意不能使用。请查看相应的编译优化参数。否则程序会无法编译,即使编译成功也无法运行,嘿嘿。

# make
编译的时间可能会比较长,毕竟优化的比较厉害。

# make install

编译安装完成后执行后续操作:
# useradd mysql //添加 mysql 用户
# cd /usr/local/mysql
# bin/mysql_install_db --user=mysql
# chown -R root:mysql . //设置权限,注意后面有一个 "."
# chown -R mysql /var/lib/mysql //设置 mysql 目录权限
# chgrp -R mysql . //注意后面有一个 "."
# cp share/mysql/my-medium.cnf /etc/my.cnf
# cp share/mysql/mysql.server /etc/rc.d/init.d/mysqld //开机自动启动 mysql。
# chmod 755 /etc/rc.d/init.d/mysqld
# chkconfig --add mysqld
# /etc/rc.d/init.d/mysqld start //启动 MySQL
# bin/mysqladmin -u root password "password_for_root"
# service mysqld stop //关闭 MySQL

8. 编译安装 Apache
# cd /usr/local/src
# wget http://www.ip97.com/apache.org/httpd/httpd-2.2.4.tar.gz
# tar zxvf httpd-2.2.4.tar.gz
# cd httpd-2.2.4

依次安装apr和apr-util

# cd srclib/apr
# ./configure --prefix=/usr/local/apr --enable-threads --enable-other-child USE=ipv6
# make && make install

# cd ../apr-util
# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr/ --with-mysql=/usr/local/mysql
# make && make install

cd /usr/local/src/httpd-2.2.4
# CHOST="i686-pc-linux-gnu" CFLAGS="-O3 -msse2 -mmmx -mfpmath=sse -funroll-loops -mcpu=pentium4 -march=pentium4 -pipe -fomit-frame-pointer" ./configure --prefix=/usr/local/apache2 --enable-mods-shared=all --enable-deflate=shared --with-mysql=/usr/local/mysql --enable-cache --enable-file-cache --enable-mem-cache --enable-disk-cache --enable-static-support --enable-static-htpasswd --enable-static-htdigest --enable-static-rotatelogs --enable-static-logresolve --enable-static-htdbm --enable-static-ab --enable-static-checkgid --disable-cgid --disable-cgi --with-mpm=worker --with-apr=/usr/local/apr/ --with-apr-util=/usr/local/apr-util/ --enable-ssl --with-ssl=/usr/include/openssl

# make
# make install
# echo '/usr/local/apache2/bin/apachectl start ' >> /etc/rc.local //将 apachectl 的调用加入到你的系统启动文件中。

注解:
./configure //配置源代码树
--prefix=/usr/local/apache2 //体系无关文件的顶级安装目录PREFIX ,也就Apache的安装目录。
--enable-module=so //打开 so 模块,so 模块是用来提 DSO 支持的 apache 核心模块
--enable-mods-shared=all //编译全部的模板,对于不需要我们可以在httpd.conf去掉。
--enable-cache //支持缓存
--enable-file-cache //支持文件缓存
--enable-mem-cache //支持记忆缓存
--enable-disk-cache //支持磁盘缓存
--enable-static-support //支持静态连接(默认为动态连接)
--enable-static-htpasswd //使用静态连接编译 htpasswd - 管理用于基本认证的用户文件
--enable-static-htdigest //使用静态连接编译 htdigest - 管理用于摘要认证的用户文件
--enable-static-rotatelogs //使用静态连接编译 rotatelogs - 滚动 Apache 日志的管道日志程序
--enable-static-logresolve //使用静态连接编译 logresolve - 解析 Apache 日志中的IP地址为主机名
--enable-static-htdbm //使用静态连接编译 htdbm - 操作 DBM 密码数据库
--enable-static-ab //使用静态连接编译 ab - Apache HTTP 服务器性能测试工具
--enable-static-checkgid //使用静态连接编译 checkgid
--disable-cgid //禁止用一个外部 CGI 守护进程执行CGI脚本
--disable-cgi //禁止编译 CGI 版本的 PHP
--with-mpm=worker // 让apache以worker方式运行
--enable-ssl // 编译 ssl模块。

将apache设置成开机自启动:

在/etc/rc.d/rc.local文件中加入一行
/usr/local/apache2/bin/apachectl start
这样每次重新启动系统以后,apache也会随系统一起启动.

或者
# cp /usr/local/apache2/bin/apachectl /etc/rc.d/init.d/httpd
然后 vi /etc/rc.d/init.d/httpd 添加(#!/bin/sh下面)
# chkconfig: 2345 10 90
# description: Activates/Deactivates Apache Web Server
最后,运行chkconfig把Apache添加到系统的启动服务组里面:
# chkconfig --add httpd
# chkconfig httpd on


9、编译php 5.2.1并打上Suhosin Patch。
Suhosin是php增强型安全补丁,可以编译到静态内核中,也可以编译成php动态扩展。我个人强烈你建议安装成静态内核。Suhosin已经进入freebsd和gentoo的ports。下面的以下先说静态安装步骤。当然你也可以在安装php后将它编译成php的动态扩展。

# cd /usr/local/src
# wget http://cn.php.net/get/php-5.2.1.tar.gz/from/this/mirror
wget http://www.hardened-php.net/suhosin/_media/suhosin-patch-5.2.1-0.9.6.2.patch.gz
# tar zxvf php-5.2.1.tar.gz
# gunzip suhosin-patch-5.2.1-0.9.6.2.patch.gz
# cd php-5.2.1
patch -p 1 -i ../suhosin-patch-5.2.1-0.9.6.2.patch

#./buildconf --force

# CHOST="i686-pc-linux-gnu" CFLAGS="-O3 -msse2 -mmmx -mfpmath=sse -mcpu=pentium4 -march=pentium4 -pipe -fomit-frame-pointer" CXXFLAGS="-O3 -msse2 -mmmx -mfpmath=sse -funroll-loops -mcpu=pentium4 -march=pentium4 -pipe -fomit-frame-pointer" ./configure --prefix=/usr/local/php --with-apxs2=/usr/local/apache2/bin/apxs --with-zlib-dir --with-bz2 --with-tiff-dir --with-libxml-dir=/usr/local/libxml2 --with-gd=/usr/local/gd2 --with-freetype-dir --with-jpeg-dir --with-png-dir --with-ttf --enable-mbstring --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-config-file-path=/etc --with-iconv --disable-ipv6 --enable-static --enable-maintainer-zts --enable-memory-limit --enable-zend-multibyte --enable-inline-optimization --enable-zend-multibyte --enable-sockets --enable-soap --enable-suhosin --with-openssl

# make

# make install

# cp php.ini-recommended /etc/php.ini


在这里也顺便说一下将suhosin安装成为php的动态扩展的方法。毕竟网上根本不见它的中文安装教程。

虽然我个人不推荐这种方式。

wget http://www.hardened-php.net/suhosin/_media/suhosin-0.9.16.tgz
tar zxvf suhosin-0.9.16.tgz
cd suhosin-0.9.16
./configure --with-php-config=/usr/local/php/bin/php-config
make
make install

会提示编译的模块存在的目录,记住它。
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/

然后在php.ini中增加一行下列语句。
extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/suhosin.so

10 、整合apache 与php
# vi /usr/local/apache2/conf/httpd.conf
在最后一行加上:
AddType application/x-httpd-php .php

查找:(设置 WEB 默认文件)
DirectoryIndex index.html
替换为:
DirectoryIndex index.php index.html index.htm //在 WEB 目录不到默认文件,httpd 就会执行 /var/www/error/noindex.html

找到这一段:
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride none

更改为AllowOverride all
允许apache rewrite

# 监听443端口,支持https连接
取消注释 httpd.conf 中的 Include conf/extra/httpd-ssl.conf

保存httpd.conf,退出。

# /usr/local/apache2/bin/apachectl restart //重启 Apache

11. 查看确认 L.A.M.P 环境信息
vi /usr/local/apache2/htdocs/phpinfo.php
增加下面一行,并保存。

# chmod 755 /usr/local/apache2/htdocs/phpinfo.php

用浏览器打开 http://127.0.0.1/phpinfo.php


# echo ' ' > /usr/local/apache2/htdocs/testdb.php
# chmod 755 /usr/local/apache2/htdocs/testdb.php
# service mysqld start
用浏览器打开 http://127.0.0.1/testdb.php
检查 phpinfo 中的各项信息是否正确。

12、设置SSL并创建自己的CA

# cd /usr/share/ssl/misc

# ./CA -newca

屏幕上出现如下的提示:CA certificate filename (or enter to create)

这是要求输入要创建的CA的证书文件名, 可以直接回车或输入证书文件名。

Making CA certificate ...
Generating a 1024 bit RSA private key
.........++++++
................................++++++
writing new private key to './demoCA/private/./cakey.pem'
Enter PEM pass phrase:

Verifying password - Enter PEM pass phrase:-

此时要求输入和验证CA的私钥口令、国家代码(中国是CN)、省份、城市或地区、组织或企业名称、部门名称、CA的名称或服务器的主机名称、管理员电子邮件地址。

至此,在当前目录下生成了demoCA的目录,CA的证书就在该目录下,文件名为cacert.pem

生成服务器的证书请求

# ./CA -newreq

屏幕上出现如下的提示:

Generating a 1024 bit RSA private key
.....................................................++++++
.....++++++
writing new private key to 'newreq.pem'
Enter PEM pass phrase:
Verifying password - Enter PEM pass phrase:

此时要求输入和验证服务器的私钥口令、国家代码(中国是CN)、省份、城市或地区、组织或企业名称、部门名称、CA的名称或服务器的主机名称、管理员电子邮件地址。

Please enter the following 'extra' attributes

to be sent with your certificaterequest

A challenge password []:

An optional company name []:

.Request (and private key) is in newreq.pem

这是要求输入服务器的相关信息。

此时,在当前目录下生成了一个名为newreq.pem的文件,包含了要生成服务器数字证书的请求。

签署证书

# ./CA -sign

屏幕上出现如下的提示:

Using configuration from /usr/share/ssl/openssl.cnf

Enter PEM pass phrase:

此时一样需要输入CA的私钥口令、国家代码(中国是CN)、省份、城市或地区、组织或企业名称、部门名称、CA的名称或服务器的主机名称、管理员电子邮件地址。

Certificate is to be certified until Nov 19 13:46:19 2002 GMT (365 days)

Sign the certificate? [y/n]:y

这时显示证书请求文件中的各项信息,并询问是否要签署证书,回答y,进行签署。

1 out of 1 certificate requests certified, commit? [y/n]y

回答y,会显示已经签署的证书的信息,并在当前目录下生成服务器的证书文件newcert.pem。

# mkdir /usr/local/apache2/conf/ssl.crt/
# mkdir /usr/local/apache2/conf/ssl.key/
# cp newcert.pem /usr/local/apache2/conf/ssl.crt/server.pem
# cp newreq.pem /usr/local/apache2/conf/ssl.key/server.pem


更改服务器的证书文件的相关配置
# vi /usr/local/apache2/conf/extra/httpd-ssl.conf

查找并修改

# Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate. If
# the certificate is encrypted, then you will be prompted for a
# pass phrase. Note that a kill -HUP will prompt again. Keep
# in mind that if you have both an RSA and a DSA certificate you
# can configure both in parallel (to also allow the use of DSA
# ciphers, etc.)
SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.pem
#SSLCertificateFile /usr/local/apache2/conf/server-dsa.crt

# Server Private Key:
# If the key is not combined with the certificate, use this
# directive to point at the key file. Keep in mind that if
# you've both a RSA and a DSA private key you can configure
# both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/server.pem
#SSLCertificateKeyFile /usr/local/apache2/conf/server-dsa.key


示例文件

在SSL的根目录中生成一个index.html,它是如下所示:

<html>

这是SSL示例!

</html>

测试

假如Web服务器的DNS名称是www.cnprint.org.

在浏览器的URL地址栏里输入 http://www.cnprint.org/,浏览器便会显示APACHE安装时确省的Test Page.

在浏览器的URL地址栏里输入 https://www.cnprint.org/,注意:是 https 而不是http !

浏览器会提示站点已经采用了SSL进行数据的加密传输.由于我们的CA证书不是浏览器缺省的信任的根证书,所以,浏览器会说无法确认服务器的证书可信。暂时不管,一直NEXT,最后,浏览器会显示:这是SSL示例!

可以把CA的证书放在非SSL的站点上,让浏览器下载并安装CA证书,并将其设置成可信任的根证书,便可解决上面的问题.8 解除HTTPD起动时的口令输入。

由于安全的原因,Web服务器的私钥是口令加密了的,每次重新起动HTTPD或Linux时,都会要求输入Web服务器的私钥的口令。

如果要解除HTTPD起动时的口令输入,可以这样:

# cd /usr/local/apache2/conf/ssl.key/
# cp server.pem server.pem.org
# openssl rsa -in server.pem.org -out server.pem
# chmod 400 server.pem

另外在网上看到一个方法,我没有试。有兴趣的可以试下。

创建SSL密码自动应答文件,否则每次Apache启动的时候,都会要求你输入SSL的密码.
创建 /usr/local/apache2/conf/ssl.key/sendsslpwd ,内容如下.
#!/bin/bash
SSLpasswd="YOUR PASSPHRASE"
echo $SSLpasswd
chmod 755 /usr/local/apache2/conf/ssl.key/sendsslpwd


此时,Web服务器的私钥已经没有口令加密,一定要确保server.pem文件除root外,任何用户均无权读取它。


13、安装 Zend Optimizer
# cd /usr/local/src
# wget http://downloads.zend.com/optimizer/3.2.2/ZendOptimizer-3.2.2-linux-glibc21-i386.tar.gz
# tar xzvf ZendOptimizer-3.2.2-linux-glibc21-i386.tar.gz
# ./ZendOptimizer-3.2.2-linux-glibc21-i386/install.sh
按照它的提示一步步进行就行了。

14、安装eaccelerator // eaccelerator是php的加速软件,使用后php的执行效率会有较大幅度的提升。目前eaccelerator 0.9.5已经和ZendOptimizer-3.2.2能够很好兼容啦。不过我个人觉得,ZendOptimizer-3.2.2没有加速的功能,只是起到了运行zend加密文件的作用而已。闲话不多说了,大家有兴趣的,可以去google下。

# cd /usr/local/src
# wget http://bart.eaccelerator.net/source/0.9.5/eaccelerator-0.9.5.tar.bz2
# tar -jxvf eaccelerator-0.9.5.tar.bz2
# cd eaccelerator-0.9.5

export PHP_PREFIX="/usr/local/php"
$PHP_PREFIX/bin/phpize //指定一下php的目录

# ./configure --enable-eaccelerator=shared --with-php-config=$PHP_PREFIX/bin/php-config // 设置

# make & make install

编译安装后我们会看到屏幕提示的eaccelerator.so所在的目录,比如我得到的是/usr/local/php/lib/php/extensions/no-debug-zts-20060613/eaccelerator.so,记住这个路径,待会要用到。

修改php.ini(安装完zend之后,php.ini存放于/usr/local/Zend/etc)
在文件最后,zend之前,注意,这部分内容务必放在zend之前,不然可能会出现不可预期的服务器问题。添加下列信息:

[eaccelerator]
extension="/usr/local/php/lib/php/extensions/no-debug-zts-20060613/eaccelerator.so"
eaccelerator.shm_size="32"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"

解释:
zend_extension 是安装完程序自动指示给我们的
eaccelerator.shm_size="32" 缓存大小单位MB
eaccelerator.cache_dir="/tmp/eaccelerator" 缓存路径

# mkdir /tmp/eaccelerator // 建立目录
# chmod 0777 /tmp/eaccelerator // 修改目录属性

最后重新启动apachectl

重启apache,phpinfo显示:
This program makes use of the Zend Scripting Language Engine:
Zend Engine v2.2.0, Copyright (c) 1998-2006 Zend Technologies
with eAccelerator v0.9.5, Copyright (c) 2004-2006 eAccelerator, by eAccelerator
with Zend Extension Manager v1.0.11, Copyright (c) 2003-2006, by Zend Technologies
with Zend Optimizer v3.2.2, Copyright (c) 1998-2006, by Zend Technologies

也会有eAccelerator的具体信息。

15、安装phpmyadmin,管理mysql数据库

# cd /usr/local/apache2/htdocs/
# wget http://jaist.dl.sourceforge.net/sourceforge/phpmyadmin/phpMyAdmin-2.10.0-beta1-all-languages.tar.bz2

# tar jxvf phpMyAdmin-2.10.0-beta1-all-languages.tar.bz2
# mv phpMyAdmin-2.10.0-beta1-all-languages phpmyadmin

# cd phpmyadmin/libraries

修改配置文件
# vi config.default.php

找到这几行进行修改:
$cfg['Servers'][$i]['auth_type'] = 'http'; // Authentication method (valid choices: config, http, HTTP, signon or cookie)
$cfg['Servers'][$i]['user'] = 'root'; // MySQL user
$cfg['Servers'][$i]['password'] = 'PASSWORD'; // MySQL password (only needed

经过这几个步骤,我们一个比较安全的LAMP服务器就环境基本建立成功啦。感觉上也不是很难,是吧?
当然对于打造基于动态IP的网站,以上的信息还不够,还有建立ADSL拨号,NAT,动态域名更新,防火墙,安装论坛程序等一系列的工作,我会慢慢地写出自己的心得与大家分享。毕竟这对我来说,也是个学习的过程。

2009年4月17日星期五

Java类的写法

本文向大家介绍如何创建Java类和创建Java类的基本语法,通过一个例子来向大家介绍类的主要概念。

Public class Stack {

** Vector items;

publicd Stack() {
items = new Vector(10);
}

public Object push(Object item) {
items.addElement(item);
returen item;
}

public synchronized Object pop() {
int len = items.size();
Object obj = null;
if(len == 0) throw new EmptStackException();

obj = items.elementAt(len - 1);
items.removeElementAt(len - 1);
return obj;
}

public boolean isEmpty() {
if(items.size() == 0)
return true;
else
return false;
}
}

上面的例子定义了一个类叫作Stack,在这个类中定义了一个实例变量items,定义了一个构造器,定义了三个方法,关于实例变量,构造器和方法我们会再后面一个一个的给大家进行讲解。

类的定义

一个类在使用前必须要进行定义,当然Java本身提供了许多类,你可以直接拿过来使用,就象C语言中预定义的许多变量一样,不用你自己定义了。类声明的语法主要包括两个部分,一个是类的声明,就是上面例子中的第一行语句,用来声明类的名称等信息;下面用一对大括号括起来的部分称为类体,用来定义类的实例对象,构造器和方法等。

类的声明

下面我们给出类声明的语法,

public class is publicly accessible

abstract class cannot be instantiated

final class cannot be subclassed

class NameOfClass Name of the Class

extends Super Superclass of the class

implements Interfaces Interfaces implemented by the class {
ClassBody
}

上面的语法中,大括号前面的内容就是类声明的基本语法,其中Class NameOfClass是类声明中最主要的部分,它定义了类的名称,是必不可少的,Class是Java的关键字,NameOfClass是类的真实名称。public,abstract,final可看成是一组,在使用的时候只能使用其中一个,他们必须放在类的名称前面,如果使用public说明定义的这个类可以被在同一个封装中的其他类所使用和访问,如果使用abstract说明定义的这个类是一个抽象类,不能用此类来创建类的实例,也就是对象,如果使用final说明定义的类是一个终极类,不能在用这个类来定义子类了。extends Super和implements Interfaces可以看成一组,在使用的时候只能使用其中的一个,如果使用extends Super说明现在定义的类是一个超类的子类,如果使用implements Interfaces说明该类使用了Interfaces接口,这两个组成部分体现了类的继承特性。

类定义中的类体部分主要包含三个成分:实例变量构造器方法,这三个成分称为类的成员。其中实例变量用来保存类的状态,构造器用来对类的实例进行初始化,方法将用来赋予类强大的能力,来完成一些工作。

下面我们就组成类体的三个成分分别进行说明:

构造器:

构造器的作用就是对类的实例进行初始化。构造器的名字必须和类名称相同。比如例子中展示的类Stack的构造器也叫Stack。Java允许类可以有多个构造器,但所有的构造器名称都要相同,要和类名称相同,但每个构造器的参数数量和类型是不同。编译器会根据参数的数目和类型来准确的判断应该使用哪个构造器来对类的实例进行初始化。一般的情况下,构造器主要就是对类的实例变量进行初始化。编译器会根据你调用构造器时所使用的参数的个数和类型来选择准确的构造器。

当你编写一个类的时候,你也可以不给类定义构造器,此时Java的运行环境会自动使用默认的构造器来对类实例进行初始化。

实例变量:

在上面的例子中我们使用了一个实例变量:

** Vector items;

实例变量用来描述类的状态。注意:为了声明实例变量我们应该将上面这条语句方法类体中,但不能放在类的方法声明中。在方法中声明的变量是方法的本地变量,和我们现在提到的实例变量是不一样的。

accessLevel Indicates the access level for this member

static Declares a class member

final Indicates that it is constant

transinet This variable is transient

volatile This variable is volatile

type name The type and name of the variable

上面就是声明一个实例变量的语法成分,其中type name是声明一个实例变量必须要有的,type用来说明实例变量的数据类型,也就说明该变量可以用来存放的值的类型,name是实例变量的名称,变量名可以由任何合法的字符组成,首字符应该是一个字母。在一个类中,实例变量应该是唯一的,不能存在两个名称相同的实例变量,但你可以在该类的子类中重新定义一个实例变量和你的超类的实例变量名称相同,这时,子类的实例变量会覆盖掉超类的实例变量,另外实例变量的名称可以和类中的某个方法的名称相同。

除了type name之外,下面我们对其他的成分进行一下说明:

accessLevel

你可以使用这个修改符来控制其他类对该实例变量的访问方式,不同的访问方式包括:public,protected,package,和**。

static

声明一个类变量,这个变量在不声明类实例的情况下就可以使用,使用的方式是:对象名.变量名

final

使用这个修改符实际上上是定义了常量,他的值是不能被改变的。所以你不能在程序中去修改他的值,如果你试图这样做的话,结果将是在编译的时候发生错误。

transient

这种控制方式实际上不是Java语言主要的控制方式,主要是在serialization对象中使用。

volatile

这个修改符用来通知编译器不要在编译的时候对实例变量进行优化,这是一个Java的高级特性,一般很少用到他。

方法:

向你所知道的那样,对象有一个能力就是去执行一些方法,其他类的对象可以通过调用该类的方法来让该类执行一定的操作,下面我们就来看看如何在你的程序中给类填加方法。

public Object push(Objec item) {
items.addElement(item);
return item;
}

上面的例子定义了一个方法,通过这个例子我们可以分析一下,一个方法的定义应该包括两大部分,一个就是方法声明,一个是方法体。

方法声明用来定义类的各种性质,例如访问级别,返回类型,名称和参数等等。

accessLevel Access level for this method

static This is a class method

abstract This method is not implemented

final Method cannot be overridden

native Method implemented in another language

synchronized Method requires a monitor to run

returnType methodname The return type and method name

(paramlist) The list of arguments

throws exceptions The exceptions thrown by this method

上面就是声明一个方法的语法成分,一样其中rutuenType mehtodname是在声明一个方法的时候必须要有的,其中methodname是方法的名称。returntype是方法的返回值类型。

声明一个方法的语法中其他的成分说明如下:

accessLevel:

和声明一个实例变量时是一样的,用来控制其他类访问该方法的方式,其中包括public,protected,package,和**。

static:

用来声明一个类方法,该方法可以在不声明对象实例的情况下直接使用,使用的语法是:对象名.方法名

abstract:

用来声明一个抽象方法,该方法不能通过对象实例来直接使用,因为该方法一定是一个抽象类中的方法。

final:

声明一个终极类方法,就是说在该类的子类中不能用同名的方法来覆盖本方法。

native:

如果你有一些使用其他编程语言编写的函数,想在Java程序中使用他们,你可以使用native关键字来声明类中的某个方法不是用java编写的,这样你就可以将以往的工作成果包含到你的Java程序中。

synchronized:

当多个方法可能同时对同一个数据进行操作时,就需要对这些方法进行同步,确保每个方法的操作不会影响到其他的方法,这时你就可以使用该方法来完成。

(paramlist)

这是方法的参数,用来给方法传递信息。

[throws exceptions]

当你的程序在执行过程中可能会出现一些问题或错误的时候,你应该进行违例处理,这就是本成分的功能,具体的违例处理我们还会在其他的文章中进行说明。

在方法体中,你可以编写任何条数的语句。另外我们还要说明三个概念:

this:

在类的方法中,你可以使用this来表示对本类自身的调用,比如你在方法中需要使用到该类的某个实例变量,你可以通过this.变量名来使用。

super:

如果你的类是一个超类的子类,你可以通过在该类的方法中使用super来调用超类的方法和实例变量等。

本地变量:

你可以在方法体中声明任意数量的本地变量。这些变量是本地变量,他们的作用域只限于本方法内,当方法结束的时候,该变量的生命期就结束了。

好,最后我们再对**,public,protected,package说明一下:

在类中,声明方法和实例变量的时候都可以通过上面的四个修改符来控制他们可能被其他类访问的方式,其中:

**:

将限制方法和实例变量只能被本方法中的其他方法所访问。

protected:

则允许类的方法和实例变量可以被该类,子类和在一个Package中的其他方法所访问

public:

允许任何类来访问。

package:

则限制只有该类和在一个Package中的其他类来访问。

ok,我们通过上面的讲解,基本说明了定义一个类的基本语法成分,大家如果对这一部分的内容理解之后,我想你就可以自己利用前面提到的Java基本语法和类的基本语法来编写自己的类了!

2009年4月14日星期二

利用PAM限制SSH login的user account

實作起來非常簡單,兩個設定即可,請參考如下:

需求:只允許root與u1可以ssh login至本機

1. 建立user list:
# vi /etc/ssh/ssh_users
root
u1

2. 修改/etc/pam.d/sshd:
#%PAM-1.0
#auth include system-auth
auth required pam_listfile.so item=user sense=allow file=/etc/ssh/ssh_users onerr=fail
account required pam_nologin.so
account include system-auth
password include system-auth
session optional pam_keyinit.so force revoke
session include system-auth
session required pam_loginuid.so

立即生效~
* sense=allow 代表名列於/etc/ssh/ssh_users的user才可ssh login, 反過來說當sense=deny時代表ssh_users中的account不可ssh login。
*onerr=fail 代表當/etc/ssh/ssh_users無法開啟或是檔案不存在時,當作失敗,反之onerr=succeed代表不管能不能讀取到檔案都成功。

2009年4月8日星期三

不重新编译php,增加动态模块(以mbstring模块为例)

1 进入php源代码目录中的mbstring所在目录
cd /usr/local/src/php-5.2.4/ext/mbstring/

2 执行php安装后目录中的bin/phpize文件
/usr/local/php/bin/phpize

3 进入php源代码目录
cd /usr/local/src/php-5.2.4/

4 执行上述目录中的configure文件
./configure --prefix=/usr/local/src/php-5.2.4/ext/mbstring --with-php-config=/usr/local/php/bin/php-config

5 make; make install
将mbstring.so安装到/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/中

6 编辑php.ini,加入一行
extension=mbstring.so

7 重新启动httpd
service httpd restart
(如果是php-cgi模式的,请先杀掉所有的php-cgi进程,再重启httpd)

尝试过上述方法,感觉费力不讨好。因为不很清楚的原因,始终没有能编译成mbstring.so。最后还是在pbone上找了个关于CentOS的php-mbstring的rpm包才安装成功。不管怎么说,rpm包还是要比上述方法要好。

2009年4月7日星期二

经典:Linux+Apache+Mysql+PHP典型配置

Linux+Apache+Mysql+PHP典型配置

调试环境:Redhat9.0 Apache1.3.29 Mysql3.23.58 PHP4.3.4

Linux系统的安装我就不讲了,这是基本功,其实这篇文章在类似Redhat的其他linux也应该通用,大家只要掌握我提供的方法就行。记得安装Redhat9。0的时候不要安装系统默认的apache,mysql和php以及相关的软件。已经安装的请用rpm -e * 删除已经安装的包。

1.安装Mysql3.23.58

其实老实说直接安装Mysql官方网站提供的rpm包也是一个比较可行的办法,他的官方网站的rpm包的提供基本跟tar包发行是同步的,这点我比较喜欢,至少安装rpm包的在后面的调试中不会出现mysql库文件找不到的情况。但这里还是有必要讲一下自定义安装的步骤,毕竟网友自定义安装的还说挺多的。

软件获取:http://www.mysql.com/downloads/index.html

安装步骤:

tar zxvf mysql-3.23.58.tar.gz
cd mysql-3.23.58

./configure --prefix=/usr/local/mysql --sysconfdir=/etc --localstatedir=/var/lib/mysql

make

make install

#prefix=/usr/local/mysql mysql安装的目标目录

#sysconfdir=/etc my.ini配置文件的路径

#localstatedir=/var/lib/mysql 数据库存放的路径

安装完以后要初始化数据库,当然你是升级的话不用做这步;

/usr/local/mysql/bin/mysql_install_db


如果系统没有mysql这个用户的话,最好做以下这步:

useradd -M -o -r -d /var/lib/mysql -s /bin/bash -c "MySQL Server" -u 27 mysql

然后我启动mysql

/usr/local/mysql/bin/safe_mysqld &

ok,先看看mysql能否正常工作

mysql -uroot mysql

一般情况下都是不能正常链接数据库,错误提示一般为:

ERROR 2002: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

其实网上大家问的最多的都是整个问题,说什么链接不到mysqld.sock,其实大家不妨看看mysql的错误日志就明白怎么回事,我这里的错误日志是在

/var/lib/mysql/*.err 你会发现mysql只所以不能启动,是因为/var/lib/mysql的权限不允许mysql服务访问,英文mysql默认是调用mysql用户来启动服务的,好了,既然知道是什么原因找到不能启动,那就简单了。我们只要

chown -R mysql:mysql /var/lib/mysql 就行,如果还是启动不了,再慢慢调试权限,反正一般启动不了都是权限的问题。

如果大家还是不能启动不了的话,那就用我的比较繁琐的权限的设置,反正我每次都是这么做的,一般不会有问题,见下:

chown -R root /usr/local/mysql
chgrp -R mysql /usr/local/mysql
chown -R root /usr/local/mysql/bin
chgrp -R mysql /usr/local/mysql/bin
chgrp -R mysql /var/lib/mysql
chmod 777 /var/lib/mysql
chown -R root /var/lib/mysql/mysql
chgrp -R mysql /var/lib/mysql/mysql
chmod 777 /var/lib/mysql/mysql
chown -R root /var/lib/mysql/mysql/*
chgrp -R mysql /var/lib/mysql/mysql/*
chmod 777 /var/lib/mysql/mysql/*
chmod 777 /usr/local/mysql/lib/mysql/libmysqlclient.a

做完上面的步骤,然后把你编译目录的一个脚本COPY过去

cp support-files/mysql.server /etc/rc.d/init.d/mysqld

chkconfig --add mysqld

用ntsysv设置使mysql每次启动都能自动运行。

好了,至此mysql安装完毕,你可以这样起动你的mysql服务

/etc/rc.d/init.d/mysqld start

下面这步比较关键,

ln -s /usr/local/mysql/lib/mysql /usr/lib/mysql
ln -s /usr/local/mysql/include/mysql /usr/include/mysql

大家可以不做这步,大可以在编译其他软件的时候自定义myslq的库文件路径,但我还是喜欢把库文件链接到默认的位置,这样你在编译类似PHP,Vpopmail等软件时可以不用指定mysql的库文件地址。

2.安装Apache1.3.29。我没有选择安装Apache2.0是我对他还是不放心,因为网上最新公布的apache的漏洞基本上是针对2.0,当然大家可以自己选择安装相应的版本。我这里讲的都是采用DSO动态编译的方法编译Apache.

至于有关apache的编译方法,可以参考我以前的文章《apache的静态/动态编译在apache+php+mysql的应用》 http://www.5ilinux.com/apache01.html

软件获取:http://httpd.apache.org/

tar zvxf apache_1.3.29.tar.gz
cd apache_1.3.29
修改src/include/httpd.h 增大最大线程数

#define HARD_SERVER_LIMIT 256

改成

#define HARD_SERVER_LIMIT 2560

保存退出编译apache


./configure --prefix=/usr/local/apache --enable-module=so --enable-module=rewrite --enable-shared=max --htdocsdir=/var/www &&
make &&
make install

#这里我们通过enable-module参数告诉设置脚本,我们需要启动so和rewrite模块,so模块是用来提DSO支持的apache核心模块,而rewrite模块则是用意实现地址重写的模块,由于rewrite模块需要DBM支持,如果在初次安装时没有编译进apache,以后需要用到时需要重新编译整个apache才可以实现。为此除非你可以确定以后不会用到rewrite模块,否则还是建议你在第一次编译的时候把rewrite模块编译好。

enable-shared=max 这个参数的作用时编译apache时,把除了so以外的所有apache的标准模块都编译成DSO模块。而不是编译进apache核心内。

好了安装apache很简单的哦,启动apache看看

/usr/local/apache/bin/apachectl start

然后用ie看http://你的服务器地址。应该能看到熟悉的apache羽毛标志。

3.安装PHP4.3.4

软件获取:http://www.php.net/downloads.php

tar zvxf php-4.3.4.tar.gz
cd php-4.3.4

./configure \
--prefix=/usr/local/php \
--with-mysql=/usr/local/mysql \
--enable-force-cgi-redirect \
--with-freetype-dir=/usr \
--with-png-dir=/usr \
--with-gd --enable-gd-native-ttf \
--with-ttf \
--with-gdbm \
--with-gettext \
--with-iconv \
--with-jpeg-dir=/usr \
--with-png \
--with-zlib \
--with-xml \
--enable-calendar \
--with-apxs=/usr/local/apache/bin/apxs

make

make install

#我这里由于服务器需要用到GD库,所以加了一些支持GD的编译参数 ,GD直接用了redhat自带的GD库,大家没有安装的话可以从安装盘安装,注意除了安装GD以外,还要安装libjpeg,libpng等库文件。另外--with-mysql=/usr/local/mysql指向你安装mysql的路径。--with-apxs指向apache的apxs文件的路径。

vi /usr/local/apache/conf/httpd.conf

查找

在此范围添加

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

然CPOPY PHP的配置文件

cp ../php4.3.4/php.ini.dist /usr/local/php/lib/php.ini

修改php.ini文件
register_globals = On


ok!重新启动一下apache服务器
/usr/local/apache/bin/apachectl restart

然后写个php测试页info.php:内容如下

<? php
phpinfo();
?>
正常的话,应该能看到php的信息了,恭喜你的Apche+Mysql+PHP安装成功。

好了写了这么多,希望对大家有所帮助!!!

MySql更改用户密码

有好几种方法:

1. 命令行更改:
mysqladmin password 新密码
例如, dos(或者liunx)下mysql的bin目录下,mysqladmin password 123456

2. 用MYSQL的grant语句,例如
GRANT ALL ON *.* TO 'root'@'localhost' IDENTIFIED BY '123456' WITH GRANT OPTION

3. SET PASSWORD FOR '用户名'@'主机' = PASSWORD('密码')
例如设置root密码为123456,SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');

4. UPDATE user SET Password=PASSWORD('新密码') WHERE User='用户名' AND Host = '主机';

例如,UPDATE user SET Password=PASSWORD('123456') WHERE User='root' AND Host = 'localhost';flush priviliges;

转:快速cache优化

前几个月曾经做个一次 比较Java中几种数据cache方式 的试验,最近看到 Openfire 中有一个非常小巧的本地 Cache实现, 在相同环境测试比流行的ehcache快大约5倍。简单介绍如下。

实现方法
* 用 HashMap 来存储和用来做 CacheKey 查找。
* 用一个LinkedList来存储访问顺序列表
* 用一个LinkedList来存储添加时间顺序列表,即过期时间。
* HashMap 中 Key 为 CacheKey, Value 包装成一个CacheObject
* CacheObject 包含:
1) object size
2) 指向 Access List 节点的指针
3) 指向 Age List 节点的指针

其中两个List的作用
1) AccessList
当添加新元素且 List 满时,删除列表最后的元素,即最长时间没有访问的元素。

2) AgeList
当调用 get cache 时候,判断 List 末尾有无过期元素,如有向前一直删除到最后一个没有过期的元素为止。

Performance 性能评测
写了个简单的测试,2线程写 Cache, 4 线程同时读Cache,每个Cache 100字节,平均速度大致为

写cache: 168,924 条/秒
读cache: 605,212 次/秒

结果在相同环境测试比流行的ehcache快大约5倍。

SQL注入攻击

观察近来的一些安全事件及其后果,安全专家们已经得到一个结论,这些威胁主要是通过SQL注入造成的。虽然前面有许多文章讨论了SQL注入,但今天所讨论的内容也许可帮助你检查自己的服务器,并采取相应防范措施。

SQL注入攻击的种类

知彼知己,方可取胜。首先要清楚SQL注入攻击有哪些种类。

1.没有正确过滤转义字符

在用户的输入没有为转义字符过滤时,就会发生这种形式的注入式攻击,它会被传递给一个SQL语句。这样就会导致应用程序的终端用户对数据库上的语句实施操纵。比方说,下面的这行代码就会演示这种漏洞:

statement := "SELECT * FROM users WHERE name = '" + userName + "'; "

这种代码的设计目的是将一个特定的用户从其用户表中取出,但是,如果用户名被一个恶意的用户用一种特定的方式伪造,这个语句所执行的操作可能就不仅仅是代码的作者所期望的那样了。例如,将用户名变量(即username)设置为:

a' or 't'='t,此时原始语句发生了变化:

SELECT * FROM users WHERE name = 'a' OR 't'='t';

如果这种代码被用于一个认证过程,那么这个例子就能够强迫选择一个合法的用户名,因为赋值't'='t永远是正确的。

在一些SQL服务器上,如在SQL Server中,任何一个SQL命令都可以通过这种方法被注入,包括执行多个语句。下面语句中的username的值将会导致删除“users”表,又可以从“data”表中选择所有的数据(实际上就是透露了每一个用户的信息)。

a'; DROP TABLE users; SELECT * FROM data WHERE name LIKE '%

这就将最终的SQL语句变成下面这个样子:

SELECT * FROM users WHERE name = 'a'; DROP TABLE users; SELECT * FROM DATA WHERE name LIKE '%';

其它的SQL执行不会将执行同样查询中的多个命令作为一项安全措施。这会防止攻击者注入完全独立的查询,不过却不会阻止攻击者修改查询。

2.Incorrect type handling

如果一个用户提供的字段并非一个强类型,或者没有实施类型强制,就会发生这种形式的攻击。当在一个SQL语句中使用一个数字字段时,如果程序员没有检查用户输入的合法性(是否为数字型)就会发生这种攻击。例如:

statement := "SELECT * FROM data WHERE id = " + a_variable + "; "

从这个语句可以看出,作者希望a_variable是一个与“id”字段有关的数字。不过,如果终端用户选择一个字符串,就绕过了对转义字符的需要。例如,将a_variable设置为:1; DROP TABLE users,它会将“users”表从数据库中删除,SQL语句变成:SELECT * FROM DATA WHERE id = 1; DROP TABLE users;

3.数据库服务器中的漏洞

有时,数据库服务器软件中也存在着漏洞,如MYSQL服务器中mysql_real_escape_string()函数漏洞。这种漏洞允许一个攻击者根据错误的统一字符编码执行一次成功的SQL注入式攻击。

4.盲目SQL注入式攻击

当一个Web应用程序易于遭受攻击而其结果对攻击者却不见时,就会发生所谓的盲目SQL注入式攻击。有漏洞的网页可能并不会显示数据,而是根据注入到合法语句中的逻辑语句的结果显示不同的内容。这种攻击相当耗时,因为必须为每一个获得的字节而精心构造一个新的语句。但是一旦漏洞的位置和目标信息的位置被确立以后,一种称为Absinthe的工具就可以使这种攻击自动化。

5.条件响应

注意,有一种SQL注入迫使数据库在一个普通的应用程序屏幕上计算一个逻辑语句的值:

SELECT booktitle FROM booklist WHERE bookId = 'OOk14cd' AND 1=1

这会导致一个标准的面面,而语句

SELECT booktitle FROM booklist WHERE bookId = 'OOk14cd' AND 1=2在页面易于受到SQL注入式攻击时,它有可能给出一个不同的结果。如此这般的一次注入将会证明盲目的SQL注入是可能的,它会使攻击者根据另外一个表中的某字段内容设计可以评判真伪的语句。

6.条件性差错

如果WHERE语句为真,这种类型的盲目SQL注入会迫使数据库评判一个引起错误的语句,从而导致一个SQL错误。例如:

SELECT 1/0 FROM users WHERE username='Ralph'。显然,如果用户Ralph存在的话,被零除将导致错误。

7.时间延误

时间延误是一种盲目的SQL注入,根据所注入的逻辑,它可以导致SQL引擎执行一个长队列或者是一个时间延误语句。攻击者可以衡量页面加载的时间,从而决定所注入的语句是否为真。

以上仅是对SQL攻击的粗略分类。但从技术上讲,如今的SQL注入攻击者们在如何找出有漏洞的网站方面更加聪明,也更加全面了。出现了一些新型的SQL攻击手段。黑客们可以使用各种工具来加速漏洞的利用过程。我们不妨看看the Asprox Trojan这种木马,它主要通过一个发布邮件的僵尸网络来传播,其整个工作过程可以这样描述:首先,通过受到控制的主机发送的垃圾邮件将此木马安装到电脑上,然后,受到此木马感染的电脑会下载一段二进制代码,在其启动时,它会使用搜索引擎搜索用微软的ASP技术建立表单的、有漏洞的网站。搜索的结果就成为SQL注入攻击的靶子清单。接着,这个木马会向这些站点发动SQL注入式攻击,使有些网站受到控制、破坏。访问这些受到控制和破坏的网站的用户将会受到欺骗,从另外一个站点下载一段恶意的JavaScript代码。最后,这段代码将用户指引到第三个站点,这里有更多的恶意软件,如窃取口令的木马。

以前,我们经常警告或建议Web应用程序的程序员们对其代码进行测试并打补丁,虽然SQL注入漏洞被发现和利用的机率并不太高。但近来攻击者们越来越多地发现并恶意地利用这些漏洞。因此,在部署其软件之前,开发人员应当更加主动地测试其代码,并在新的漏洞出现后立即对代码打补丁。

防御和检查SQL注入的手段

1.使用参数化的过滤性语句

要防御SQL注入,用户的输入就绝对不能直接被嵌入到SQL语句中。恰恰相反,用户的输入必须进行过滤,或者使用参数化的语句。参数化的语句使用参数而不是将用户输入嵌入到语句中。在多数情况中,SQL语句就得以修正。然后,用户输入就被限于一个参数。下面是一个使用Java和JDBC API例子:

PreparedStatement prep = conn.prepareStatement("SELECT * FROM USERS WHERE PASSWORD=?");

prep.setString(1, pwd);

总体上讲,有两种方法可以保证应用程序不易受到SQL注入的攻击,一是使用代码复查,二是强迫使用参数化语句的。强迫使用参数化的语句意味着嵌入用户输入的SQL语句在运行时将被拒绝。不过,目前支持这种特性的并不多。如H2 数据库引擎就支持。

2.还要避免使用解释程序,因为这正是黑客们借以执行非法命令的手段。

3.防范SQL注入,还要避免出现一些详细的错误消息,因为黑客们可以利用这些消息。要使用一种标准的输入确认机制来验证所有的输入数据的长度、类型、语句、企业规则等。

4.使用专业的漏洞扫描工具。但防御SQL注入攻击也是不够的。攻击者们目前正在自动搜索攻击目标并实施攻击。其技术甚至可以轻易地被应用于其它的Web架构中的漏洞。企业应当投资于一些专业的漏洞扫描工具,如大名鼎鼎的Acunetix的Web漏洞扫描程序等。一个完善的漏洞扫描程序不同于网络扫描程序,它专门查找网站上的SQL注入式漏洞。最新的漏洞扫描程序可以查找最新发现的漏洞。

5.最后一点,企业要在Web应用程序开发过程的所有阶段实施代码的安全检查。首先,要在部署Web应用之前实施安全测试,这种措施的意义比以前更大、更深远。企业还应当在部署之后用漏洞扫描工具和站点监视工具对网站进行测试。

Web安全拉警报已经响起,安全形式异常严峻,企业绝对不应当草率从事。安全重于泰山!

2009年4月6日星期一

关于火狐FireFox的争论

近日,《PCWorld》杂志周五刊登分析文章称,在与Chrome浏览器的竞争中,火狐浏览器正逐渐失去计算机专家的青睐。尽管Mozilla基金会仍致力于一些宏大的目标,但火狐浏览器已经宣告死亡。

Google近日推出了Linux版的Chrome。即使是在戴尔Mini 9这种性能不强的上网本中,Chrome仍然能够带来快速的互联网浏览体验,尤其是在登录Gmail和Google文档等大量使用JavaScript的网站时。

火狐在这一方面的表现曾经很好。但是与Chrome相比,火狐显得非常慢,甚至已经不在同一个级别。这就像一个老年人与一个20岁的年轻人赛跑。Chrome目前已经可以替代火狐。

Mozilla有着一些伟大的目标,他们的工作也值得尊敬。许多互联网专家对Mozilla也有着很高的忠诚度,因为Mozilla在开源软件领域比任何其他公司都做出了更多努力。然而,Mozilla已经忘记了如何制作一款优秀的浏览器。而火狐已不再是互联网专家最青睐的选择,很多人对火狐都存在着各种不满。

火狐目前最大的优势在于,它是一款开源软件。这意味着该浏览器是由技术驱动的,而用户的意见在其中并不会发挥决定性作用。即使有上百万的用户不满,Mozilla仍能够继续推动火狐的开发。

不过需要看到,Mozilla的收入来自终端用户。当用户使用火狐内建的搜索工具栏进行搜索时,Mozilla都会获得一部分收入。Mozilla目前主要依靠与Google之间的搜索合作在生存,如果用户放弃火狐,那么Mozilla将遭遇资金危机。

火狐项目目前就像是一辆无法停止的载重卡车。这辆卡车已经获得了足够的动力,并且将一直朝着此前选定的方向行驶。现在做出改变已经太晚。Chrome已经取胜,而火狐已经宣告死亡。Mozilla唯一的选择是仔细评估浏览器市场的发展,并扭转错误的发展方向,但是这几乎是不可能的。两到三年之后,将会有很多用户转向Chrome,而他们将不可能再回头使用火狐。

SCJP

SCJP  sun certificated java programmer (SCJP)
  一种Java认证考试
  对于Java程序设计员,Sun推出两项认证:Sun Certificated Java Programmer (SCJP)和Sun Certificated Java Developer(SCJD)。
  SCJP 可以说各种Java认证的基础,相对于SCJD来说,SCJP跟侧重于测验您的Java程序设计概念及能力,内容偏重于Java语法及JDK的内容。其对应的最主要的学习课程是SL-275。SCJP 的学习/考试过程是相对相对比较明确的,首先学员参加SL-275的培训课程(标准费用大致在2600人民币,包括考试券、教材费),也可以单独购买考试券(Certification Voucher,费用现在是1250元),然后在Prometric考试中心参加考试。通过后获得Sun颁发的SCJP认证证书。



课程概述
  掌握如何使用标准Java Development kit V1.5 (JDK)开发应用程序和applets。您将学会Java语言的语法;如何使用Java来创建图形用户接口(GUI),事件处理机制,例外处理,通过开发各种Java程序来获得实际的编程经验;您也将学到文件输入/输出(I/O);多线程和网络的知识。
  课程目标
  使用Java编程语言创建Java应用程序和applets;
  定义和描述垃圾搜集,安全性和Java虚拟机(JVM);
  描述和使用Java语言面向对象的特点;
  开发图形用户接口(GUI),利用Java支持的多种布局管理;
  描述和使用Java的事件处理模式;
  使用Java语言的鼠标输入,文本,窗口和菜单窗口部件;
  使用Java的例外处理来控制程序执行和定义用户自己的例外事件;
  使用Java语言的先进的面向对象特点,包括方法重载,方法覆盖,
  抽象类,接口,final,static和访问控制;
  实现文件的输入/输出(I/O);
  使用Java语言内在的线程模式来控制多线程;
  使用Java的Sockets机制进行网络通信。
  预备知识
  能够创建和编译简单的程序(如C语言);能够使用Notepad文件编辑器;使用WWW(World wide web )浏览器,如:Netscape,IE。
  课程考试组织 学员培训后可以随时报名参加方联公司授权考试中心的SCJP认证考试。
  认证证书获得方法 通过考试后在4—6周时间内即可获得Sun SCJP认证证书。一次不过重考免费。
  考试方式
  全英文试题,以电脑作答,在授权的Prometric考试中心参加考试
  考试编号:310-035
  先决条件:无
  考试题型:复选、填空和拖拽匹配
  题量:59
  及格标准:61%
  时限:120分钟
  费用:1500元
  要求具备的能力
  使用Java编程语言创建Java应用程序和applets。
  定义和描述垃圾搜集,安全性和Java虚拟机(JVM)。
  描述和使用Java语言面向对象的特点。
  开发图形用户界面(GUI)。利用Java支持的多种布局管理。
  描述和使用Java的事件处理模式。
  使用Java语言的鼠标输入、文本、窗口和菜单窗口部件。
  使用Java的例外处理来控制程序执行和定义用户自己的例外事件。
  使用Java语言先进的面向对象特点, 包括方法重载、方法覆盖、抽象类、接口、final、static和访问控制。
  实现文件的输入/输出 (I/O)。
  使用Java语言内在的线程模式来控制多线程。
  使用Java 的Sockets机制进行网络通信。

2009年4月4日星期六

JAVA中对数字证书的操作

未经实践,仅供研究参考存档用,使用者自行承担风险。

一:需要包含的包
import java.security.*;
import java.io.*;
import java.util.*;
import java.security.*;
import java.security.cert.*;
import sun.security.x509.*
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

二:从文件中读取证书

用keytool将.keystore中的证书写入文件中,然后从该文件中读取证书信息
CertificateFactory cf=CertificateFactory.getInstance("X.509");
FileInputStream in=new FileInputStream("out.csr");
Certificate c=cf.generateCertificate(in);
String s=c.toString();

三:从密钥库中直接读取证书

String pass="123456";
FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,pass.toCharArray());
java.security.cert.Certificate c=ks.getCertificate(alias);//alias为条目的别名

四:JAVA程序中显示证书指定信息

System.out.println("输出证书信息:\n"+c.toString());
System.out.println("版本号:"+t.getVersion());
System.out.println("序列号:"+t.getSerialNumber().toString(16));
System.out.println("主体名:"+t.getSubjectDN());
System.out.println("签发者:"+t.getIssuerDN());
System.out.println("有效期:"+t.getNotBefore());
System.out.println("签名算法:"+t.getSigAlgName());
byte [] sig=t.getSignature();//签名值
PublicKey pk=t.getPublicKey();
byte [] pkenc=pk.getEncoded();
System.out.println("公钥");
for(int i=0;i<pkenc.length;i++)System.out.print(pkenc[i]+",");

五:JAVA程序列出密钥库所有条目

String pass="123456";
FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,pass.toCharArray());
Enumeration e=ks.aliases();
while(e.hasMoreElements())
java.security.cert.Certificate c=ks.getCertificate((String)e.nextElement());

六:JAVA程序修改密钥库口令

String oldpass="123456";
String newpass="654321";
FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,oldpass.toCharArray());
in.close();
FileOutputStream output=new FileOutputStream(".keystore");
ks.store(output,newpass.toCharArray());
output.close();

七:JAVA程序修改密钥库条目的口令及添加条目

FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,storepass.toCharArray());
Certificate [] cchain=ks.getCertificate(alias);获取别名对应条目的证书链
PrivateKey pk=(PrivateKey)ks.getKey(alias,oldkeypass.toCharArray());获取别名对应条目的私钥
ks.setKeyEntry(alias,pk,newkeypass.toCharArray(),cchain);向密钥库中添加条目
第一个参数指定所添加条目的别名,假如使用已存在别名将覆盖已存在条目,使用新别名将增加一个新条目,第二个参数为条目的私钥,第三个为设置的新口令,第四个为该私钥的公钥的证书链
FileOutputStream output=new FileOutputStream("another");
ks.store(output,storepass.toCharArray())将keystore对象内容写入新文件

八:JAVA程序检验别名和删除条目

FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,storepass.toCharArray());
ks.containsAlias("sage");检验条目是否在密钥库中,存在返回true
ks.deleteEntry("sage");删除别名对应的条目
FileOutputStream output=new FileOutputStream(".keystore");
ks.store(output,storepass.toCharArray())将keystore对象内容写入文件,条目删除成功

九:JAVA程序签发数字证书

(1)从密钥库中读取CA的证书

FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,storepass.toCharArray());
java.security.cert.Certificate c1=ks.getCertificate("caroot");

(2)从密钥库中读取CA的私钥

PrivateKey caprk=(PrivateKey)ks.getKey(alias,cakeypass.toCharArray());
(3)从CA的证书中提取签发者的信息
byte[] encod1=c1.getEncoded(); 提取CA证书的编码
X509CertImpl cimp1=new X509CertImpl(encod1); 用该编码创建X509CertImpl类型对象
X509CertInfo cinfo1=(X509CertInfo)cimp1.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); 获取X509CertInfo对象
X500Name issuer=(X500Name)cinfo1.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME); 获取X509Name类型的签发者信息

(4)获取待签发的证书

CertificateFactory cf=CertificateFactory.getInstance("X.509");
FileInputStream in2=new FileInputStream("user.csr");
java.security.cert.Certificate c2=cf.generateCertificate(in);

(5)从待签发的证书中提取证书信息

byte [] encod2=c2.getEncoded();
X509CertImpl cimp2=new X509CertImpl(encod2); 用该编码创建X509CertImpl类型对象
X509CertInfo cinfo2=(X509CertInfo)cimp2.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); 获取X509CertInfo对象

(6)设置新证书有效期

Date begindate=new Date(); 获取当前时间
Date enddate=new Date(begindate.getTime()+3000*24*60*60*1000L); 有效期为3000天
CertificateValidity cv=new CertificateValidity(begindate,enddate); 创建对象
cinfo2.set(X509CertInfo.VALIDITY,cv); 设置有效期

(7)设置新证书序列号

int sn=(int)(begindate.getTime()/1000); 以当前时间为序列号
CertificateSerialNumber csn=new CertificateSerialNumber(sn);
cinfo2.set(X509CertInfo.SERIAL_NUMBER,csn);

(8)设置新证书签发者

cinfo2.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME,issuer);应用第三步的结果

(9)设置新证书签名算法信息

AlgorithmId algorithm=new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
cinfo2.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM,algorithm);

(10)创建证书并使用CA的私钥对其签名

X509CertImpl newcert=new X509CertImpl(cinfo2);
newcert.sign(caprk,"MD5WithRSA"); 使用CA私钥对其签名

(11)将新证书写入密钥库

ks.setCertificateEntry("lf_signed",newcert);
FileOutputStream out=new FileOutputStream("newstore");
ks.store(out,"newpass".toCharArray()); 这里是写入了新的密钥库,也可以使用第七条来增加条目

十:数字证书的检验

(1)验证证书的有效期

(a)获取X509Certificate类型对象

CertificateFactory cf=CertificateFactory.getInstance("X.509");
FileInputStream in1=new FileInputStream("aa.crt");
java.security.cert.Certificate c1=cf.generateCertificate(in1);
X509Certificate t=(X509Certificate)c1;
in2.close();

(b)获取日期

Date TimeNow=new Date();

(c)检验有效性

try{
t.checkValidity(TimeNow);
System.out.println("OK");
}catch(CertificateExpiredException e){ //过期
System.out.println("Expired");
System.out.println(e.getMessage());
}catch((CertificateNotYetValidException e){ //尚未生效
System.out.println("Too early");
System.out.println(e.getMessage());}

(2)验证证书签名的有效性

(a)获取CA证书

CertificateFactory cf=CertificateFactory.getInstance("X.509");
FileInputStream in2=new FileInputStream("caroot.crt");
java.security.cert.Certificate cac=cf.generateCertificate(in2);
in2.close();

(c)获取CA的公钥

PublicKey pbk=cac.getPublicKey();

(b)获取待检验的证书(上步已经获取了,就是C1)

(c)检验证书

boolean pass=false;
try{
c1.verify(pbk);
pass=true;
}catch(Exception e){
pass=false;
System.out.println(e);
}

2009年4月3日星期五

香港旅游贴士

  “动感之都”香港(Hongkong)是一个年轻的城市,是一个充满奇迹和神话的城市,是一个令人无比激动的城市。世界级的建筑、快节奏的生活、时尚摩登香港是一个生活的天堂,集各式各样的欢乐于一地。在香港,既可以观赏到美丽的自然风光,又可以获得商业文明带来的种种享受;既可以浸淫在摩登社会的物质享乐中,同样也可以重温旧时代的朴真生活方式。

  香港也是一个有着传奇故事的城市。从一个默默无闻的小渔村到繁华的都市,从殖民地到世界上第一个实施“一国两制”的地方,香港经历了历史的风云变幻,香港更成熟了,更包容了。
  

  最近几年去香港旅游的大陆公民越来越多,前几年还先后开放了北京、上海、杭州等城市的公民香港自由行,大家已经不满足走马观花式的参加旅行团旅游香港,对香港的吃、住、行、游、购、娱方面的情况需要有更多的、更实际的、更真实的了解和参考。因为我在香港工作生活了5年,身边的朋友去玩之前多向我咨询一些当地的情况。因此我将我在港期间的经历、感受分为吃在香港、住在香港、行在香港、游在香港等几个栏目记录下来,希望对将要去香港旅游的朋友有所帮助。


  香港自由行自助游攻略(一)----行在香港

  之所以要把“行”方在首位,应为介绍中除了香港本地的交通以外,还包括进出香港的各种交通方式,这对于自助旅行的朋友甚为重要。

  一、香港的外部交通

  1.航空:

香港机场早期是启德机场,在1998年迁为赤喇角机场。因为本人在航空公司工作,回西安休假多次出入香港机场,所以在此对香港机场做一下详细地介绍(香港新机场太大了,机场里面都的交通都要靠地铁,如果不了解很容易迷路,呵呵 )

  香港机场主要分为抵港区和离港区


  抵港区有两个出口(A出口和B出口),所以如果有朋友接你的话最好约好在哪个出口见面。

  位于客运大楼内的香港机场购物中心面积约3万平方米,属全球最大型客运大楼之一, 内有140多家商店和餐厅,大至国际名牌店,小至传统中式茶座。估计许多旅客会提前到达机场以进行离港前“疯狂购物”。

  香港机场的大楼是东西走向的,左右对称,这个当年被无数人关注的庞大建筑的设计的确有着很贴心的地方,厅堂、走廊简单明确,进了离港大厅,非左即右,只要看好了地图,想好了什么是自己的扫荡目标,就可以直奔主题,决不走冤枉路。


  在离港大厅东大堂是国际知名品牌的聚集区,什么Alfred Dunhill、Burberry、Gucci……想找什么品牌都没问题,这里大约集合了近百种服饰、化妆品、珠宝首饰的商家店铺。

  从机场到市区可以坐:

  公交(很多公交线路,基本都有直达,非常方便)

  机场快线(由地铁公司经营,提供往返机场的高速客运服务。从机场往第一站(青衣站)约12分钟,往第二站(九龙站)约20分钟,终点站是中环(香港站),全程仅需23分钟。机场快线的服务时间为每天上午五时五十分至凌晨一时十五分,每10分钟一班。成人单程票价为港币60元(机场至青衣站)、90元(机场至九龙站)和100元(机场至香港站)。机场快线亦为旅客提供免费穿梭巴士服务,由香港站和九龙站开出,共有9条专线,接送乘客往返39家酒店旅馆、中国客运码头和红磡火车站等地)。

  出租车(出租车站位于机场大楼外左侧,从机场至中区每程约需港币335元,至尖沙咀则约需港币270元。)

  好了,机场大致介绍到这里,其实刚刚说迷路有点夸张,机场虽大,服务设施都很到位,各种指示牌也很明确,只要按照指示牌走,应该都没有问题。

  2. 铁路,轮船等

  出入香港除了飞机外,从深圳可以坐火车,快艇,汽车出入香港,从珠海可以坐船。

  坐汽车:在深圳皇岗口岸,汽车很多,由不同的巴士公司运营,票价大概40港币左右。(好处就是人少,过关较快)

  铁路:从罗湖坐火车到市区大概需要45分钟,班次很多,不到10分钟就有一趟车。普通价格为35港币。如果想舒服的话可以坐头等座位(通常为中间的一节车厢),价格78港币。这里告诉大家,坐头等座位千万在上车前要买头等票或刷八达通卡,不要以为用普通票一样可以享受头等座位(上车时没人检查),在火车出发后,会有列车员来验票,我的一个内地朋友就碰到这样的尴尬事,后来被罚款500港币,呵呵。

  快艇:在蛇口和珠海都可以坐船出入香港,但票价很贵大概170港币左右,且班次很少一天也不过10班左右。好处就是人非常少,过关轻松。

   二、香港的内部交通

  在香港旅游出行,最好购买一张八达通卡,八达通卡是一种现金储值卡,一般分为成人、小童、学生、及长者四种。现时大多数的公共交通公具、便利店等都接受便用。

八达通卡可于地下铁路客务中心、九广铁路售票处、机场快线客务中心有售。购买时须缴付按金50元,另可按自己的需要而增值。若不再使用八达通卡,可于各出售处退回余额及按金。

若你通过(空路)到港,你可在抵港后于机场快线客务中心选购「机场快线游客八达通卡 - 3天香港乘车证」。这种八达通分300元及220元两款,300元的一款包括两程单程机场快线及3天无限次乘坐地铁(机场快线除外)及20元金额可用于其它交通工具;220元的一款跟300元的差不多,只是少了一程单程机场快线。

此外,为方便旅客畅游香港,地铁公司特设「旅客地铁1天乘车证」。此证只需50元,持证人便可在1天内自由乘坐地铁。乘车证可于地下铁路客务中心及机场快线客务中心购买。八达通很方便可以用做巴士车资,地铁车资,还可以在很多便利店购买小物品之用。

市内巴士

  香港的巴士行走香港各区。九龙巴士、新世界第一巴士及城巴经营巴士路线包括香港岛、九龙及新界。新大屿山巴士行走大屿山、城巴及龙运巴士行走北大屿山及机场。无论双层或是单层巴士,车身前方皆以中、英文标出终点站,车资便宜。乘客需自备零钱或使用「八达通」储值卡。

  港币$1.2 - $45不等;车资按目的地计算;
  长者(65岁或以上)及儿童(12岁或以下)半价(金额不足一角亦作一角计算);
  不设找赎;
  可使用「八达通」卡缴付车资。
  巴士查询服务热线 27454466

有轨电车

  香港还有一种有轨电车,很便宜到哪都2元,但是人多,车上没有空调,行使很慢。电车自1904年开始在香港岛北部行驶的电车,是港岛独有的交通工具。电车行走香港岛东面的筲箕湾至香港岛西面的坚尼地城,另有一支线行走跑马地。电车另一特色是于车尾入口上车,然后于车头出口支付车资及下车。电车是您到香港体验生活、欣赏美丽街景时最方便的交通工具。


  成人车资港币$2;
  长者(65岁或以上)及儿童(12岁或以下)港币$1;
  不设找续;
  可使用「八达通」卡缴付车资。

香港小巴

  小巴是只乘载16人的公共小型巴士,车头玻璃上注明车资和目的地。
  「非专线」红黄色小巴行驶香港各区,既没有固定的车站、班次和收费,行驶路线亦可能随当时交通情况或载客量而改动。这种小巴不能于禁区停车,故乘客在某些区域不可上下车。在一般情况下,乘客在下车时付钱,司机备有零钱找赎。
  「专线」绿黄色小巴按固定路线、车站、班次和收费提供服务。乘客可于指定地点上车或下车;上车时付钱,不设找赎;可使用「八达通」卡缴付车资。

地铁

  地下铁路贯穿港九各区,共有5条路线。分别是港岛线、荃湾线、观塘线、东涌线及将军澳线。地下铁路服务时间约由早上6时至凌晨1时。

  九广东铁是一条贯穿九龙及新界南北的铁路系统,服务地区由红磡至罗湖边境。九广东铁在九龙塘站与地下铁路相连,乘客可于九龙塘站转乘地下铁路。

渡轮

港内航线分别行走中环至尖沙咀、尖沙咀至湾仔、红磡至北角及北角至九龙城等。若要前往离岛,可从中环港外线码头乘客前往大屿山梅窝、长洲、坪洲及南丫岛等航线。乘坐渡海轮畅游维多利亚亦是游客到港的一个重要项目。您可乘搭中环至尖沙咀或尖沙咀至湾仔航线,在渡海轮上饱览维港两岸的景色。

  香港自由行自助游攻略(二)----吃在香港

  香港是人们津津乐道的美食天堂,世界各地的美味佳肴在此汇集。西餐、中餐味正宗;日菜、韩菜、泰菜、意大利菜极为普遍;另外在香港还能尝到并不多见的地中海菜、尼泊尔菜、北越菜、西班牙菜、阿根廷菜、葡国菜、俄国菜、澳洲菜、印度菜、古巴菜、美国菜等,但伊斯兰风味菜较为少见。中餐以粤菜为主,兼收国内各大菜系的代表作。海鲜非常流行。

  到了香港,当然驻要尝尝粤菜和海鲜。海鲜在香港非常便宜,而且很新鲜。一般在酒楼吃海鲜的话,价格相差非常大,有的酒楼比较大众化,比如北角的明珠海鲜酒家,我在香港时去过很多次,价格便宜,4、5个人吃下来也就1千多元港币,可以吃到龙虾、鲍鱼、基围虾、石斑鱼,还有其他一些菜。一条大青斑(约3斤)才100多。有的酒楼就非常贵,比如跑马地的竹园餐厅,同样的菜,大概要反倍还多。

  如果要在海边吃海鲜,最出名的地方要算鲤鱼门,还有西贡(和越南城市同名),南丫岛等,太贵了!!!建议不要去。推荐一个叫做布袋奥(名字可能错了,发音应该是这样),环境很有意思,是从岸边伸出的一个平台,感觉像漂在海上,海鲜非常新鲜,白灼虾居然都能吃出甜味,而且是脆的,呵呵想起来又馋了。不过去这里比较麻烦,没有公交车,需要自己开车去。

  在香港,中午可以去酒楼试试广东早茶和午茶。茶点种类非常丰富,光是粥就有10几种,价格也不算贵,点心味道也不错,花样众多。

  这里特别推荐香港的大排挡。在庙街(可以坐地铁到佐顿)有成片的夜市大排挡。椒盐濑尿虾、椒盐中虾,卤水拼盘都是我最喜欢吃的,这里的菜味道相对酒楼的比较重,有些潮州风味,比较适合我们北方人。

  铜锣湾的渣甸坊、利舞台广场、时代广场、百德新街等地方集中了地道香港风味的茶餐厅、排挡,还有些小吃店、寿司店、咖啡厅,逛街累了,吃吃小点,喝喝下午茶,很是惬意。特别是到香港的人比较喜欢去的许留山甜品店以及沾仔记面食店,很实惠。

  九龙半岛的红磡是主题餐厅的集中地,经营香港传统美食地蔡澜美食坊、意大利美食赛车吧等都是很有名气的,不过这里的消费可不低。

  无论是弥敦道、广东道、漆咸道等大道,还是亚士厘道、山林道、加连威老道等小街,中、西、港式菜馆多不胜数。在金巴利道的美丽华商场可找到水准一流的粤菜馆和川菜馆。诺是佛台及诺是佛阶(尖沙咀站B1出口)虽隐蔽于闹市一隅,却是追赶新派餐饮之地。

  不过在香港最好不要吃川菜,原因嘛,太贵了。铜锣湾曾经有一家很正宗的川菜,我们3个人点了4个菜3碗米饭,5罐啤酒居然花了800多。连在我们内地很多城市都过气的谭鱼头火锅,在香港湾仔刚刚开业的时候,如果晚上要去吃,居然座位都订到1个星期以后了,而且价格不菲。

  另外可以在香港尝尝其他国家的美食,如印度菜、泰国菜这些在国内比较少的东西。

  如果不为了刻意品尝香港美食,建议可以吃麦当劳或肯德基这些快餐,价格和国内一样。除此意外,茶餐厅的盒饭、面也能果腹,但味道我们北方人可能吃不习惯,尤其是面,做得的确不能恭维。因为在香港的人工、地租成本很高,所以普通吃饭也比较贵,一盒盒饭可以卖到30几块。

  香港自由行自助游攻略(三)----购在香港


  香港是举世闻名的购物天堂,这里既有各种大型的购物中心,也有玲珑、精致的小小服装精品店。如果对香港熟悉、时间充裕,或有熟人、朋友带路,可到中环、旺角一带主题各不相同但品质优异的小店扫货。但对于不常来香港且时间有限的内地游客来说,选择商品种类齐全的大型购物中心或购物广场,可能是更省时、省力的明智选择。

  对于一般游客我所理解的购物主要集中在服装、首饰、电器、化妆品、手机这几个方面。咱们一个个来看看吧。

  服装:

  很多人都以为香港圣诞节期间打折比较多,其实对于服装来说,每年7-8月份,夏季服装,1月份冬季服装的打折甩卖是折扣最多最值得掏宝的时候。腿脚勤快多去几间大的购物商场的话,或许能有很多意外收获。拿我的一次经历来说,在铜锣湾的崇光sogo,看到一件AIX的棉服,原价3800多,因为换季和号码不全,打折到1600,非常喜欢这个款式,但只有大号和小号,不合身,没办法,但心里一直惦记(呵呵,有点像女人),隔了几天,去尖沙嘴海港城的AIX,也没有中号,不死心,紧跟着杀回港岛,在金钟的太古广场,哈哈,还有最后两件中号,OK,搞定。

  香港比较出名也是比较大的购物商场主要有:

  铜锣湾的SOGO

  铜锣湾的时代广场,从sogo步行5分钟

  太古城,坐地铁很方便,站名既是

  吉之岛,太古城附近,和sogo一样都是日本人开的

  金钟的金钟廊,感觉像是建在过街天桥上的商场,所以称为廊

金钟的太古广场,据说明星去得最多的地方,本人五年期间在此从未见过。

尖沙嘴的海港城,据说有1000多家品牌店铺,确实很大,喜欢购物的朋友在那里转一整天都可以。

  除了大型的购物商场以外,尖沙嘴和湾仔地区还有很多街上有一些如同国内外贸服装的店铺,很多名牌服装在香港都有加工厂,所以会流出一些类似水货名牌服装,在这里也可以掏到物超所值的名牌服装。如:Burberry一件T恤,专卖店:600-2000,在这种店里,200以内搞定,不是假货而且和专卖店里的一样,可能都出自同一家工厂。缺点:样式少,时有时无,游客不可能隔三差五去看看,因此要靠运气。

  首饰:

  在香港购买首饰是比较值的,最合算的要算白金首饰和钻石首饰。在香港购买首饰推荐去六福珠宝、周大福、周生生、谢瑞麟这些珠宝店。至少买得放心吧。香港的白金首饰和钻石首饰的价格基本上是内地的60% 到40% ,如果有熟人带着去,会讲价的话甚至可以到30%。记住:这些珠宝店都是可以还价的。顺便提一下,名牌手表也是如此,如:劳力士、浪琴、雷达。

  化妆品:

  不用说,呵呵,这是女士们最关注的。在香港购买化妆品实在是太值了。口红、唇彩、香水、面膜等等价格只是内地的一半还低。在大型商场购买优点是货品全,缺点,价格稍高。推荐“莎莎”“卓越”这两家化妆品专卖。价格便宜,品牌很多:CD、SK-II、资生堂等等应有尽有,价格至少是内地的一半以下。

  暂时写到这,因为离开香港三年了,边写边回忆,想起来时再添加编辑吧,希望对大家有用。

2009年4月2日星期四

List和ArrayList的区别

List和ArrayList的区别
1.
List是接口,List特性就是有序,会确保以一定的顺序保存元素.
ArrayList是它的实现类,是一个用数组实现的List.
Map是接口,Map特性就是根据一个对象查找对象.
HashMap是它的实现类,HashMap用hash表实现的Map,就是利用对象的hashcode(hashcode()是Object的方法)进行快速散列查找.(关于散列查找,可以参看<<数据结构>>)
2.
一般情况下,如果没有必要,推荐代码只同List,Map接口打交道.
比如:List list = new ArrayList();
这样做的原因是list就相当于是一个泛型的实现,如果想改变list的类型,只需要:
List list = new LinkedList();//LinkedList也是List的实现类,也是ArrayList的兄弟类
这样,就不需要修改其它代码,这就是接口编程的优雅之处.
另外的例子就是,在类的方法中,如下声明:
private void doMyAction(List list){}
这样这个方法能处理所有实现了List接口的类,一定程度上实现了泛型函数.
3.
如果开发的时候觉得ArrayList,HashMap的性能不能满足你的需要,可以通过实现List,Map(或者Collection)来定制你的自定义类.