非常惭愧的还没有抽出时间去学一学git,权且先在这里记录一下当下的比较主流的subversion(svn)的架设记录,网上已经有很多了,在这里只是整理记录一下而已。
svn目前作为服务总体上有两种常见形式svn自身协议的方式或者走http协议,svn自身协议自不待言搭建简单方便一条命令搞定:

sudo svnserve -d --listen-port 1234 --listen-host scm.myhost.com --pid-file /var/run/svnserved.pid -r /scm/svn/repos/myproject

各参数大致意义:
-d 指定后台daemon服务方式运行
listen-port 监听端口 1234
listen-host 监听域名 scm.myhost.com
pid-file 指定运行时进程PID号记录文件路径 /var/run/svnserved.pid
-r 指定项目svn库所在路径。/scm/svn/repos/myproject
一旦架设完成后面就可以用svn checkout检出源码了:

svn co svn://scm.myhost.com:1234/myproject

svn库创建命令

svnadmin create /scm/svn/repos/myproject

建立好基本库后一般都需要构建一下基本的源码管理layout布局:

mkdir -p /tmp/layout/{trunk,branches,tags}
cd /tmp/layout
svn import . file:////scm/svn/repos/myproject -m 'init project layout'

然后我们以后checkout主线代码就可以:

svn co svn://scm.myhost.com:1234/myproject/trunk

svn的http协议方式目前还依赖于apache容器,不过你愿意的话也可以前端用varnish/nginx把请求转发到apache容器上也可以达到对外统一服务的目的。
基本的安装就不细细叙述了,这里只写一下vhost下的配置方法。
首先需要创建几个共用文件:
/scm/svn/conf/accessfile
用来设定所有项目的各个账户权限,具体请参考svn的配置文件文档,这里仅给个例子:

[groups]
administrator = axiong
[/]
@administrator = rw
* =

/scm/svn/conf/passwdfile
用来指定所有项目的用户和对应密码,当然这部分也可以在mysql里搞定,感觉小型项目没有什么必要,还是文本方便,可以用apache-util里的htpasswd生成。
指定完了后就是vhost的配置了:

<VirtualHost *:80>
        ServerName scm.myhost.com
        <Directory />
                Options Includes FollowSymLinks
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
    <Location /svn>
        DAV svn
        SVNParentPath /scm/svn/repos
        AuthType Basic
        AuthName "Subversion System"
        AuthUserFile /scm/svn/conf/passwdfile
        AuthzSVNAccessFile /scm/svn/conf/accessfile
        Satisfy Any
        Require valid-user
    </Location>
</VirtualHost>

这样就架设好了http://scm.myhost.com/svn/myproject的svn库,
以后还可以在/scm/svn/repos下建立更多的svn库使用统一管理的账户和密码。
注意/scm/svn/repos下的每一个项目都需要有apache所在组或用户的写入权限,否则代码会提交出错。

更新一下:修改了一下location地址方便和trac配合。

, , , ,

11

"读书笔记"

说起来我已经很久没有看纸质书籍了,最后一次看的书籍也只是《php和Mysql的web开发》这样的书籍。

我的大部分生活都是泡在网络上,说泡有点不太准确,基本上看看行业新闻之外我都在关注互联网的商务和技术方面的文章。为什么不看纸质书籍?因为我觉得传统的出版行业和新闻行业从信息传播的角度来说已经远远落后于互联网,无论于传播的速度和信息内容的更新而言都是。

一本书成型,一篇新闻定稿要经过层层工序或者层层审批,日新月异已经无法形容现在信息更新的频度了,而twitter类的短信息平台又进一步将信息的传播和更新提高到了一个闻所未闻的高度,雅虎的没落、微软的夕阳,google的崛起,facebook的热闹,twitter的火爆,无一不在预示着这个行业的明天一定是以个人为中心(facebook)的高速信息传播(twitter/friendfeed)和信息检索(google)的人群信息服务行业。在这个行业中到处是金矿就看你如何去挖了。

我不太爱看励志类的文章/书籍,对自己的能力和信心不够确信时他们才能帮助你催化你,否则就是。。难听的话我就不说了。

管理类文章都貌似不错,但别人喂给你的经验,永远没法跟自己实践中吸取的经验教训相提并论。

最后如果您想问我在网上都读了些什么,请看我的delicious书签:http://delicious.com/nickfan

虽然很不情愿被读书笔记,但是还是感谢有个机会表述我对传统纸媒体的看法和对互联网的想法。

关于thrift,可能一般情况下用到的人不多,不过在类似于facebook这样的大型系统中,需要一个统一的数据接口去连接内部的各个子系统,这个时候中间件就必不可少了,thrift主要用于rpc类的中间件,当然自己定义理论上也可以用来做异步消息处理的底层,异步消息这方面成熟的开源产品还是很多的,比如rabbitmq之类的,大公司也大多数有参考或在使用自己开发的对应产品。
在rpc中间件本身层面来说,个人之前比较熟悉的是zeroc的ICE中间件,不过随着时间的推移,facebook的thrift越来越惹人喜欢,更原始的接口(ice这方面虽然号称轻量级的中间件,不过thrift似乎更轻量,基本上和java中的mina属于一个量级的作品,同时也得承认ice帮程序员做了更多的通用工作,更易于使用),社区支持(当时ice的官方论坛注册是需要你有企业/教育系统信息并通过管理员确认的),语言支持更多(thrift直接支持erlang),开源(thrift是Apache 2.0 的License,而ice有GPL和商业两种License,但是这种两手做法个人反倒更看好前者thrift的发展)。
废话说完了,开始做thrift配置。
总体来说thrift的安装流程比较简单:
目前的release0.2.0版貌似在mail list里讨论的时候还有一些小bug,我还是上官方svn checkout 的主线代码:

svn co http://svn.apache.org/repos/asf/incubator/thrift/trunk thrift

然后开始编译,编译前最好看一下README,如果编译流程有变动以README为准。
编译基本上就是整体编译一遍,然后根据你需要的语言库(c++/java/ruby/python/php/perl/erlang/c#等)进入lib下分别编译你需要的语言中用的lib库,然后加入到你需要的语言客户端去用即可。

编译前检测一下,可能需要手动安装boost开发库bison(yacc解析器) flex(lex词汇生成器)等相关工具:

sudo apt-get install libboost-dev automake libtool flex bison pkg-config g++

java的话建议加上ant,ivy,libslf4j-java和libcommons-lang-java,其中slf4j基本上封装了很多种logger,比如常用的log4j等,安装的时候也可以带上log4j:

sudo apt-get install ant ivy libslf4j-java libcommons-lang-java liblog4j1.2-java

在你的/etc/environment中的CLASSPATH中添加一下这些jar包的调用:

CLASSPATH=/usr/share/java/ant.jar:/usr/share/java/commons-lang.jar:/usr/share/java/ivy.jar:/usr/share/java/log4j-1.2.jar:/usr/share/java/slf4j-api.jar:/usr/share/java/slf4j-log4j12.jar

开始thrift的编译安装,我libevent是手工编译安装在/usr/local下的需要指定一下:

cd thrift
./bootstrap.sh
./configure --with-libevent=/usr/local
make
sudo make install

然后我们来分别编译几个语言的支持。
先来php的thrift协议扩展,thrift的TSocketPool类用到了apc扩展中的方法apc_fetch(), apc_store(),注意如果没有的话需要先安装一下,开始安装:

cd lib/php/src/ext/thrift_protocol
phpize
./configure --enable-thrift_protocol
make
sudo make install
cd ../../../../../

安装完了后修改你的php.ini文件:

sudo vi /usr/local/php/etc/php.ini

加入扩展的设定:

[thrift_protocol]
extension=thrift_protocol.so

如果你运行了php-fpm,重启一下php-fpm的进程管理:

sudo /etc/init.d/php-fpm restart

纯粹cli应用的话可以直接检测一下扩展有否载入:

php -m |grep thrift

至此php部分的安装成功。

python的部分,安装比较简单,和通常的安装包差不多:

cd lib/py
python setup.py build
sudo python setup.py install
cd ../../

java的部分如果你前面编译没有问题的话,此时libthrift.jar应该已经被安装到/usr/local/lib下了,可以简单的做个软链接:

sudo ln -s /usr/local/lib/libthrift.jar /usr/share/java/libthrift.jar

另一种方法是到lib/java下去编译了拷贝过去:

cd lib/java
ant
sudo cp libthrift.jar /usr/share/java/

最后在环境变量中添加引用即可:

CLASSPATH=/usr/share/java/libthrift.jar

记得source一下应用新的环境变量。
至此几个比较常用的语言的thrift配置就搞定了,下一步就是根据具体的应用去做对应的开发了。

, , , ,

网上文章很多wordpress配合nginx的文章,阿熊收集整理了一下,做了一个我的本地配置版本,支持WP Super Cache插件,修正pathinfo在nginx下的问题,当然不用说,也支持nginx下的url做rewrite功能。
第一步,按照nginx官方的新增的文档中的写法,处理www.axiong.me主机类的请求:

    server {
        listen 8081;
        server_name www.axiong.me;
        rewrite ^ http://axiong.me$request_uri? permanent;
    }

注意我的前端监听的端口是8081,直接用nginx做前端的朋友,改成80即可。
然后就是主体的配置了:

    server {
        listen       8081;
        server_name axiong.me m.axiong.me;
access_log /var/log/nginx/axiong.me_access.log  access;
error_log /var/log/nginx/axiong.me_error.log;
index  index.html index.htm index.php;
root   /var/www/axiong;

                autoindex off;
                gzip_static on;

                set $wp_super_cache_file '';
                set $wp_super_cache_uri $request_uri;

                if ( $request_method = POST )
                {
                        set $wp_super_cache_uri '';
                }

                if ( $query_string )
                {
                        set $wp_super_cache_uri '';
                }

                if ( $http_cookie ~* "comment_author_|wordpress|wp-postpass_" )
                {
                        set $wp_super_cache_uri '';
                }

                if ( $wp_super_cache_uri ~ ^(.+)$ )
                {
                        set $wp_super_cache_file /wp-content/cache/wp_super_cache/$http_host/$1index.html;
                }
                if ( -f $document_root$wp_super_cache_file )
                {
                        rewrite ^(.*)$ $wp_super_cache_file break;
                }
    if (!-e $request_filename){
       rewrite ^(.*)$ /index.php$1 last;
    }
    location ~ \.php($|/) {
        fastcgi_pass   127.0.0.1:9001;
        #fastcgi_index  index.php;
        include fastcgi.conf;
        #fastcgi_param  PATH_INFO $fastcgi_script_name;
        set $path_info "";
        set $real_script_name $fastcgi_script_name;
        if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
            set $real_script_name $1;
            set $path_info $2;
        }
        fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
        fastcgi_param SCRIPT_NAME $real_script_name;
        fastcgi_param PATH_INFO $path_info;
    }
}

其中最后一段:

    if (!-e $request_filename){
       rewrite ^(.*)$ /index.php$1 last;
    }
    location ~ \.php($|/) {
        fastcgi_pass   127.0.0.1:9001;
        #fastcgi_index  index.php;
        include fastcgi.conf;
        #fastcgi_param  PATH_INFO $fastcgi_script_name;
        set $path_info "";
        set $real_script_name $fastcgi_script_name;
        if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
            set $real_script_name $1;
            set $path_info $2;
        }
        fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
        fastcgi_param SCRIPT_NAME $real_script_name;
        fastcgi_param PATH_INFO $path_info;
    }

所有单一入口的php框架类库,都可以这样配置,在一些必须pathinfo配合的框架(如kohana,ci等)也可以使用最后这段来修正pathinfo信息。

, , , , , ,

关于安全其实能讲的有很多,这里只是简单的记录一下我的iptables设定,
我开有22(ssh)服务,1194(openvpn,tcp)服务,80(http)web服务,443(https)web服务,
我在实体机器上的设定:

#!/bin/sh

iptables -P FORWARD ACCEPT

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -i lo -j ACCEPT

iptables -A INPUT -i tap+ -j ACCEPT

iptables -A INPUT -i tun+ -j ACCEPT

iptables -A FORWARD -i tap+ -j ACCEPT

iptables -A FORWARD -i tun+ -j ACCEPT

iptables -A INPUT -p tcp -i eth0 --dport 22 -j ACCEPT

iptables -A INPUT -p tcp -i eth0 --dport 443 -j ACCEPT

iptables -A INPUT -p tcp -i eth0 --dport 1194 -j ACCEPT

iptables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT

iptables -A INPUT -j DROP

iptables-save > /etc/iptables.rules

我在vps上的设定:

#!/bin/sh

iptables -P FORWARD ACCEPT

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j SNAT --to 64.233.189.104

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -i lo -j ACCEPT

iptables -A INPUT -i tap+ -j ACCEPT

iptables -A INPUT -i tun+ -j ACCEPT

iptables -A FORWARD -i tap+ -j ACCEPT

iptables -A FORWARD -i tun+ -j ACCEPT

iptables -A INPUT -p tcp -i venet0 --dport 22 -j ACCEPT

iptables -A INPUT -p tcp -i venet0 --dport 443 -j ACCEPT

iptables -A INPUT -p tcp -i venet0 --dport 1194 -j ACCEPT

iptables -A INPUT -p tcp -i venet0 --dport 80 -j ACCEPT

iptables -A INPUT -j DROP

iptables-save > /etc/iptables.rules

iptables在通常的设置中我们都是使用允许个别规则并阻止其他所有规则的策略,所以

iptables -A INPUT -j DROP

要放到所有规则的最后,更多iptables的设置教学可以参考中文wiki:
http://wiki.ubuntu.org.cn/index.php?title=IptablesHowTo&variant=zh-cn
在重启前启用iptables,可以清理一下之前的规则:

sudo iptables -F
sudo iptables -t nat -F

然后执行我们上面的脚本:

sudo ./iptables_init.sh

这样iptables就建立好了,想让系统每次启动和联网后都生效,修改/etc/network/interfaces网络适配器配置文件:

sudo vi /etc/network/interfaces

在你对应网络适配器配置段的最后添加上对我们脚本最后保存的iptables配置的调用:

pre-up iptables-restore < /etc/iptables.rules
post-down iptables-save > /etc/iptables.rules

至此配置完毕,在重启前确定你的所有的配置的正确性,在此之前不要关闭你当前连接着的ssh终端!
最后重启服务或者重启网络做最后确定:

sudo /etc/init.d/networking restart

基本搞定,如果你经常受到骚扰可以去装个Fail2ban这样的filter或者更高级的防火墙设定,fail2ban具体参考这篇:http://freshventure.wordpress.com/2009/12/29/为openvpn添加fail2ban的filter/,防火墙参考中文wiki中的即可:http://wiki.ubuntu.org.cn/index.php?title=系统安全&variant=zh-cn

, , , ,

以下内容为个人配置笔记,仅供参考,请勿用于生产环境

其实本人对vpn服务的搭建比较陌生,主要参考的还是这篇文章http://freshventure.wordpress.com/2009/12/22/在ubuntu上搭建openvpn服务器,并配合mac和windows的客户端/(需要翻墙)

在这里重新撰写一篇算是备份外加自己的整理,在最后还有一篇关于搭建ssh反向代理服务的简单说明。

首先安装openvpn:

sudo apt-get install openvpn

然后拷贝ca证书,server证书和client证书的生成脚本到我们自己的配置路径下,还有样例的服务器配置文件也解压一份,捣鼓一番:

cd /etc/openvpn/
sudo cp -af /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/easy-rsa
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn
gzip -d server.conf.gz

进入/etc/openvpn/easy-rsa开始生成根证书、服务器证书、和客户端证书,注意这一步最好以root身份执行,证书生成完了后把ca证书也就是根证书和你个人的客户端证书和私钥拿出来即可:
切换到root身份:

cd /etc/openvpn/easy-rsa/
sudo -sH

清理环境构建配置目录:

source ./vars
./clean-all

构建CA根证书,回答该回答的问题,国家代号和省一级的代号都是两个字符,中国是CN,当然你设个不存在的地方也没人来找你,不建议设置密码:

./build-ca

构建服务器证书,回答该回答的问题,不建议设置密码:

./build-key-server server

构建个人证书也就是客户端证书,建议设置密码

./build-key client1

命令中的client1为你个人证书的名字可以随便,比如nick,axiong,chunge,lurenjia等等。
然后构建Diffie Hellman参数,这部可能要花几分钟时间生成随机数,你如果对安全比较在意可以在vars里设置为2048位的,这些主要是非对称加密算法里用来保证安全用的。

./build-dh

在这些证书都生成完成后建议退出root身份。
在证书啥的都搞定了后可以开始搞服务器配置了:

sudo vi /etc/openvpn/server.conf

服务器的配置没啥好多说的,偶这里就灰常没牙齿的拷贝一下freshventure的注释版,改改并加上收集来的资讯,适应我的配置了:

# 写入你vps的公网ip地址
local 64.233.189.104

# openvpn监听的端口,你也可以改为别的
port 1194 

# tcp or udp, never use both in the same config

# tcp不会丢包,udp则不太靠谱
proto tcp

#routed VPN

#否则需要配置bridge模式,很麻烦
#除非在服务器侧有很多其他windows主机要共享,否则
dev tun

# Certificates,这些都是刚才生成的文件
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/server.crt
key /etc/openvpn/easy-rsa/keys/server.key  # This file should be kept secret
dh /etc/openvpn/easy-rsa/keys/dh1024.pem

# Server settings,一般就用默认设置比较好,避免和本地局域网地址重复
# 这里默认是设置在10.8.0.0这个网段作为你的vpn私域网络地址段
server 10.8.0.0 255.255.255.0 # Default VPN ip range.

#这句很关键,让客户端所有路由都转从VPN的默认网关
#def1也不能少,否则有时候客户端的默认网关不会变
push "redirect-gateway def1 bypass-dhcp"

# OpenDNS settings,也很关键。
#因为为客户端连DNS查询都通过VPN发出。
#当然如果你愿意也可以使用google的DNS服务 8.8.8.8 和 8.8.4.4
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

# 允许两个客户端之间可见,如果注释掉则客户端只能连接服务器,之间看不到
client-to-client

# 允许一个证书多处同时登录,不建议使用,注意此处阿熊是注释掉的
;duplicate-cn

# 启用压缩,对时延影响不大
# 注意客户端配置的时候注意与服务器保持一致
comp-lzo

# Reduce the OpenVPN daemon's privileges
user nobody
group nogroup
keepalive 10 120

#以下几个对连接建立影响不大

ifconfig-pool-persist ipp.txt

#日志也可以改到/var/log/openvpn/下

status openvpn-status.log

# 这里可以打开本地设置的日志
# 如果你等会儿服务无法开启,可以在这里的日志中检查故障原因
;log-append  openvpn.log

# Set the appropriate level of log
# file verbosity.
#
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 3

在启动你的openvpn服务之前我们还需要搞定几件事情:
1打开你的服务器的ipv4协议的网络封包转发功能:

sudo vi /etc/sysctl.conf

找到并将其中net.ipv4.ipforward=1的注释去掉:

net.ipv4.ipforward=1

想要服务器重启前立刻生效这个设定,执行命令:

sudo sysctl -w net.ipv4.ip_forward=1

启动服务前记得你的iptables上为这个网段打开路由nat转发。
注意vps(openvz)等技术里的设定和实体服务器或者vmware之类的虚拟技术的设置方法不太相同,
比如实体服务器有一块网卡eth0,设置方法基本上符合freshventure原文中的描述:

#假设服务器只有一块网卡eth0,所以无论是接收VPN请求,和向外二次转发,都用eth0这个interface

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE #VPN向Internet转发的关键

iptables -A INPUT -i tun+ -j ACCEPT #必须可以接收tun0转来的VPN内部数据包
iptables -A INPUT -i tap+ -j ACCEPT #这条主要是为了Window客户端OpenVPN GUI登录所设置的,因为其只有tap接口
iptables -A FORWARD -i tap+ -j ACCEPT #允许VPN转发
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 1194 -j ACCEPT #允许客户端递交VPN登录请求

但是在vps(openvz)的服务器上貌似MASQUERADE已经不管用了,
去掉这条:

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE #VPN向Internet转发的关键

加上阿熊的这条:

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j SNAT --to 64.233.189.104

其中64.233.189.104是你vps的公网ip地址。
另外记得将末尾那条规则的eth0换成你vps的venet0或者其他什么名字,主要看你的主机商在/etc/network/interfaces中的设置。

iptables -A INPUT -p tcp -i eth0 --dport 1194 -j ACCEPT #允许客户端递交VPN登录请求

最后服务启动:

sudo /etc/init.d/openvpn start

看到'server'启动成功的话就算是大功基本告成。

openvpn的客户端的话各个系统不一,可以在这里openvpn.net/gui.html找到你系统的解决方案。

ubuntu的用户只需要:

sudo apt-get install network-manager-openvpn

即可,当然注意你的发行版,我的是9.10没有问题,旧版的network-manager-openvpn可能会有些bug。可以参考这篇文章中的设置http://hi.baidu.com/hy0kl/blog/item/b55a97af351c8ec77dd92a5d.html

windows的用户选择貌似只有 openvpn GUI,可以编写这样一个client.ovpn文件:

client
dev tun
proto tcp
#hand-window 15
#remote-random
remote 64.233.189.104 1194
resolv-retry infinite
nobind

# Try to preserve some state across restarts.
persist-key
persist-tun

ca ca.crt
cert client1.crt
key client1.key
# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
comp-lzo
# Set log file verbosity.
verb 3

所有的openvpn客户端都需要ca.crt,client1.crt,client1.key这3个文件,刚生成的时候都保存在/etc/openvpn/easy-rsa/keys路径下,需要root身份进入。

有新的客户端证书需要生成了只需要进入/etc/openvpn/easy-rsa再次 ./build-key client2等等即可。如果你有多台服务器也可以再build一份server配置。客户端配置文件可以选择多个server,看看上面的.ovpn文件你懂的。

ssh反向代理:
如果仅仅是需要做浏览器反向代理的话:
linux下可以一条命令:

sudo /usr/bin/ssh -qTfnN -p 22 -D 7070 client@64.233.189.104

其中:
7070为你本地监听的端口,
client为你服务器上的账户名,
64.233.189.104为你服务器的ip,
当然后面两项你也可以使用证书代替。
执行后输入你服务器上账户的ssh密码即可。

windows用户可以去下个putty的组件plink.exe
做个批处理命令:

plink.exe -C -D 127.0.0.1:7070 -N -pw 123456 client@64.233.189.104

其中:
7070为你本地监听的端口,
123456为你服务器上账户所对应的ssh密码,
client为你服务器上的账户名,
64.233.189.104为你服务器的ip,

这样就建立了一个127.0.0.1:7070的本地socks代理,在你的浏览器里设置一下即可。

当然如果您仅仅是为了浏览,其实用不着vps随便买个带ssh的国外虚拟主机即可,比vps便宜,淘宝上现在也有很多直接卖ssh帐号的也可以用这个方法登录构建,而且更便宜。

如果你只想给你朋友开通仅ssh反向代理功能的账户可以这么做:
在你的vps/主机上执行:

sudo useradd -M -N -g nogroup -d /nonexistent -s /usr/sbin/nologin client1

其中client1为你朋友的账户名

sudo passwd client1

为这个账户设置个密码。
ok,搞定了,然后你朋友就可以以这个代理去访问墙外的世界了。

PS:
发发怨气,本来好好的国内网络,高速又高效,现在好了,被这群人渣整的乌烟瘴气,被逼着用脚投票,搬出来,多费我这么多银子耗在争取信息自由上,这样也好,那就不妨多分享一些信息传播的技术资料,让更多的不明真相变得明白。

当年的ultravpn是免费的不过尽管这一伟大的产品为了中国的客户群做了很多努力(https://www.ultravpn.fr/forum/index.php?topic=195.0 这条是置顶的帖子,我对管理员肃然起敬)但依然挡不住网特们的勤劳河蟹,我诅咒这些龟孙子都小鸡鸡长脸上&祖祖辈辈。

有了你自己的国外vpn记得为你国内明真相和不明真相的信得过的朋友也开通个客户端证书或者ssh代理账户吧,流量可以大家分担,但不要做被人欺辱还要说他教你的那些好话的S13。

, , , , , ,

以下内容为个人配置笔记,仅供参考,请勿用于生产环境

varnish基本上是一个不错的squid替代品,个人研究和使用不多,在小型应用中出场的机率不大,不过在这里还是简单介绍一下在ubuntu下的安装配置。

sudo apt-get install varnish

软件就安装完了,配置的话需要配合你的应用服务,比如我的设置方式:让nginx监听在8081端口,而ip默认的80端口让给varnish来做第一道处理。
修改/etc/default/varnish配置文件:

sudo vi /etc/default/varnish

将DAEMON_OPTS里的-a :6081改为-a :80
最后内容例如:

DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"

然后编辑你的varnish配置文件:/etc/varnish/default.vcl,

sudo vi /etc/varnish/default.vcl

在我的应用中后端是本机的nginx监听8081端口则修改/添加:

backend default {
.host = "127.0.0.1";
.port = "8081";
}

我的这段backend名称为default,在后面的请求处理环节需要把指定域名的请求转发给我的backend:

sub vcl_recv {
    if (req.request != "GET" &&
      req.request != "HEAD" &&
      req.request != "PUT" &&
      req.request != "POST" &&
      req.request != "TRACE" &&
      req.request != "OPTIONS" &&
      req.request != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }
    if (req.request != "GET" && req.request != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }
    if (req.http.Authorization || req.http.Cookie) {
        /* Not cacheable by default */
        return (pass);
    }
    if (req.http.host ~ "^([0-9a-z]+.)?zr4u.com$") {
        set req.backend = default;
    }elseif(req.http.host ~ "^([0-9a-z]+.)?mdat.me$"){
        set req.backend = default;
    }elseif(req.http.host ~ "^([0-9a-z]+.)?thirdparty.com$"){
        set req.backend = default;
    }else{
        return (pass);
    }
    return (lookup);
}

也有在fetch段处理的配置方式不过我的fetch段主要用来处理通用情况:

sub vcl_fetch {
    if (!obj.cacheable) {
        return (pass);
    }
    if (req.request == "GET" && req.url ~ "\.(txt|js)$") {
        set obj.ttl = 3600s;
    }else{
        if (obj.http.Set-Cookie) {
            return (pass);
        }
    }
    set obj.prefetch =  -30s;
    return (deliver);
}

更多的配置方法请参考官方的wiki:http://varnish-cache.org/wiki/VCL

, , ,

以下内容为个人配置笔记,仅供参考,请勿用于生产环境

基本上现代的web应用都离不开danga团队的这款神器级的作品了,编译安装很简单,安装前记得memcached依赖于libevent库,可以参考之前php环境搭建那一节中对libevent的描述设置。
然后开始memcached的编译安装:

wget http://memcached.googlecode.com/files/memcached-1.4.5.tar.gz
tar zxf memcached-1.4.5.tar.gz
cd memcached-1.4.5/
./configure --with-libevent=/usr/local
make
sudo make install

做一些常用命令的软链接,将一些启动脚本配置到系统路径:

sudo ln -s /usr/local/bin/memcached /usr/bin/
sudo mkdir -p /usr/share/memcached/scripts
sudo cp -af scripts/* /usr/share/memcached/scripts/
sudo chmod +x /usr/share/memcached/scripts/start-memcached
sudo cp /usr/share/memcached/scripts/memcached-init /etc/init.d/memcached
sudo chmod a+x /etc/init.d/memcached
sudo update-rc.d memcached defaults

系统默认会去读取/etc/memcached.conf配置文件,这里有一份默认的配置文件样例:

# memcached default config file
# 2003 - Jay Bonci <jaybonci@debian.org>
# This configuration file is read by the start-memcached script provided as
# part of the Debian GNU/Linux distribution. 

# Run memcached as a daemon. This command is implied, and is not needed for the
# daemon to run. See the README.Debian that comes with this package for more
# information.
-d

# Log memcached's output to /var/log/memcached
logfile /var/log/memcached.log

# Be verbose
# -v

# Be even more verbose (print client commands as well)
# -vv

# Start with a cap of 64 megs of memory. It's reasonable, and the daemon default
# Note that the daemon will grow to this size, but does not start out holding this much
# memory
-m 64

# Default connection port is 11211
-p 11211 

# Run the daemon as root. The start-memcached will default to running as root if no
# -u command is present in this config file
-u nobody

# Specify which IP address to listen on. The default is to listen on all IP addresses
# This parameter is one of the only security measures that memcached has, so make sure
# it's listening on a firewalled interface.
-l 127.0.0.1

# Limit the number of simultaneous incoming connections. The daemon default is 1024
# -c 1024

# Lock down all paged memory. Consult with the README and homepage before you do this
# -k

# Return error when memory is exhausted (rather than removing items)
# -M

# Maximize core file limit
# -r

可以根据你服务器的情况做各个细节的调整。
保存设置完毕即可启动服务:

sudo /etc/init.d/memcached start

可以用telnet测试:

telnet 127.0.0.1 11211

输入stats可以查看当前的memcached运行情况。输入quit退出连接。
至此memcached的服务端安装完毕,在各个应用中运用memcached还需要安装客户端,个人推荐http://libmemcached.org/libMemcached.html(原http://tangent.org/552/libmemcached.html)的这个版本,有不少基于这个版本的其他语言扩展,支持binary协议,支持Consistent Hashing算法等等。
下载编译安装:

wget http://launchpad.net/libmemcached/1.0/0.39/+download/libmemcached-0.39.tar.gz
tar zxf libmemcached-0.39.tar.gz
cd libmemcached-0.39/
./configure --with-memcached=/usr/local/bin/memcached
make
sudo make install

安装好它之后许多基于它的第三方warpper类代码就都能工作了。
例如http://pecl.php.net/package/memcached等等。

, , ,

以下内容为个人配置笔记,仅供参考,请勿用于生产环境

nginx实在是个非常出色的程序,能承担的角色也是千差万别,负载均衡,静态页面缓存,请求代理,在我这里的应用里,使用的还是它的传统方式,替代apache处理静态请求,并将动态请求转发给后端fast-cgi处理进程(php/python/java)处理。在nignx的前端使用varnish做静态缓存和请求转发。
注意:以下的安装扩展只是在我实验的测试机上做测试使用的,并不适用于通用的生产环境。

安装前准备,先准备好pcre和zlib这两个依赖。

wget http://downloads.sourceforge.net/project/pcre/pcre/8.02/pcre-8.02.tar.bz2?use_mirror=ncu
tar jxf pcre-8.02.tar.bz2
wget http://www.zlib.net/zlib-1.2.4.tar.gz
tar zxf zlib-1.2.4.tar.gz

预备一下安装后所需要用到的路径:

sudo mkdir -p /var/log/nginx
sudo mkdir -p /var/lib/nginx/tmp/client_body
sudo mkdir -p /var/lib/nginx/tmp/proxy
sudo mkdir -p /var/lib/nginx/tmp/fastcgi

安装的时候如果需要geoip的扩展支持的话去maxmind下载一下最新的免费数据库,安装一下libgeoip-dev开发库(http://wiki.nginx.org/NginxHttpGeoIPModule):

#Get the free database of geo_city
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
#Get the free database of geo_coundty
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
sudo apt-get install libgeoip-dev
#In other systems, you can download the source and compile it youself.
wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP.tar.gz

http://nginx.org/en/download.html下载nginx的开发版:

wget http://nginx.org/download/nginx-0.8.35.tar.gz
tar zxf nginx-0.8.35.tar.gz

nginx扩展可以一起编译,在这里我选择了nginx_upload_module,nginx-upload-progress-module,nginx-upstream-fair,nginx_upstream_hash和nginx_http_push_module,其他有些扩展貌似无法和0.8.33版兼容。
nginx扩展可以在这里下载:http://wiki.nginx.org/Nginx3rdPartyModules
注意Nginx upload module(http://www.grid.net.ru/nginx/upload.en.html)目前貌似被封了,国内需要翻墙下载再scp上去,vps在国外可以直接wget。

wget http://www.grid.net.ru/nginx/download/nginx_upload_module-2.0.11.tar.gz

Nginx upload progress module下载,使用git clone:

git clone git://github.com/masterzen/nginx-upload-progress-module.git

Nginx upstream fair下载,使用git clone:

git clone git://github.com/gnosek/nginx-upstream-fair.git

Nginx upstream hash下载:

wget http://wiki.nginx.org/images/7/78/Nginx_upstream_hash-0.3.tar.gz

Nginx http push module下载:

wget http://pushmodule.slact.net/downloads/nginx_http_push_module-0.692.tar.gz

把各个扩展模块解压后开始编译安装,安装前Nginx upstream hash模块需要给代码打个补丁:

cd nginx-0.8.35/
patch -p0 < ../nginx_upstream_hash-0.3/nginx.patch

不过这一步骤在0.8.35上会失败,原因是这个版本的src/http/ngx_http_upstream.h文件该打补丁的代码位置变了,现在打开src/http/ngx_http_upstream.h文件定位到106行左右:

ngx_array_t *servers; /* ngx_http_upstream_server_t */

在此行后面添加nginx.patch里所需要加入的3行代码,结果变为:

ngx_array_t *servers; /* ngx_http_upstream_server_t */
ngx_array_t *values;
ngx_array_t *lengths;
ngx_uint_t retries;

保存即相当于补丁打完。
开始编译安装:

./configure --prefix=/usr/local/nginx --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --user=www-data --group=www-data --with-pcre=../pcre-8.02 --with-zlib=../zlib-1.2.4 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_flv_module --with-http_gzip_static_module --with-http_stub_status_module --without-select_module --without-poll_module --add-module=../nginx_upload_module-2.0.11 --add-module=../nginx-upload-progress-module --add-module=../nginx-upstream-fair --add-module=../nginx_upstream_hash-0.3 --add-module=../nginx_http_push_module-0.692
make
sudo make install

建个软链接:

sudo ln -s /usr/local/nginx/sbin/nginx /usr/sbin/

这里我从ubuntu自带的安装代码里扒了个启动脚本出来放在/etc/init.d/nginx下:

#! /bin/sh

### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/nginx
NAME=nginx
DESC=nginx

test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
	. /etc/default/nginx
fi

set -e

. /lib/lsb/init-functions

case "$1" in
  start)
	echo -n "Starting $DESC: "
	start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
		--exec $DAEMON -- $DAEMON_OPTS || true
	echo "$NAME."
	;;
  stop)
	echo -n "Stopping $DESC: "
	start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
		--exec $DAEMON || true
	echo "$NAME."
	;;
  restart|force-reload)
	echo -n "Restarting $DESC: "
	start-stop-daemon --stop --quiet --pidfile \
		/var/run/$NAME.pid --exec $DAEMON || true
	sleep 1
	start-stop-daemon --start --quiet --pidfile \
		/var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
	echo "$NAME."
	;;
  reload)
      echo -n "Reloading $DESC configuration: "
      start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/$NAME.pid \
          --exec $DAEMON || true
      echo "$NAME."
      ;;
  status)
      status_of_proc -p /var/run/$NAME.pid "$DAEMON" nginx && exit 0 || exit $?
      ;;
  *)
	N=/etc/init.d/$NAME
	echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2
	exit 1
	;;
esac

exit 0

把上面这段保存为nginx脚本放到/etc/init.d/下,并作成服务启动:

sudo cp nginx /etc/init.d/nginx
sudo chmod a+x /etc/init.d/nginx
sudo update-rc.d nginx defaults
sudo /etc/init.d/nginx start

至此nginx基本安装完毕。可以查看系统的80端口访问起始页,您应该可以看到Welcome to nginx!的字样,说明基本安装编译成功。

, , ,

以下内容为个人配置笔记,仅供参考,请勿用于生产环境

同mysql一样php的环境也有不少定制需求,故也是采用源码安装方式。
在安装php环境前做一些周边的准备工作:

安装libevent库:
在目前的网络开发环境而言libevent几乎是现如今的新兴网络服务所必不可少的底层组件了,在此下载编译安装一下:

wget http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz
tar zxf libevent-1.4.13-stable.tar.gz
cd libevent-1.4.13-stable/
./configure
make
sudo make install

如果不想编译安装也可以直接安装源里的版本:

sudo apt-get install libevent-dev

安装apache
尽管在如今的场合里apache的使用频率已经不太高了,但有些特定的应用还是必须用到它,故在此先编译安装一下apache:

wget http://www.apache.org/dist/httpd/httpd-2.2.15.tar.bz2
tar jxf httpd-2.2.15.tar.bz2
cd httpd-2.2.15/
./configure --prefix=/usr/local/apache2 --enable-deflate --enable-expires --enable-headers --enable-proxy --enable-proxy-http --enable-http --enable-rewrite --enable-so --enable-mods-shared=most --with-mpm=worker --with-port=8088
make
sudo make install
sudo ln -s /usr/local/apache2/bin/ab /usr/bin/
sudo ln -s /usr/local/apache2/bin/apachectl /usr/bin/
sudo ln -s /usr/local/apache2/bin/apxs /usr/bin/
sudo ln -s /usr/local/apache2/bin/htpasswd /usr/bin/
sudo ln -s /usr/local/apache2/bin/httpd /usr/bin/

安装autoconf
这个步骤比较汗,以前在ubuntu上编译php环境总是过不去,google良久,发觉解决之道:
sudo apt-get install autoconf2.13
貌似是默认的autoconf有bug还是啥的。

开始安装php环境
1.下载源码
http://www.php.net/downloads.php#v5去下载目前的稳定版本

wget http://cn2.php.net/get/php-5.3.1.tar.bz2/from/us.php.net/mirror
tar jxf php-5.3.1.tar.bz2

去下载php-fpm也就是php的fast-cgi进程管理器:

wget http://launchpad.net/php-fpm/master/0.6/+download/php-fpm-0.6~5.3.1.tar.gz
tar zxf php-fpm-0.6~5.3.1.tar.gz

据说下一个版本或者php5.3.3及以后的版本已经直接整合进去了不需要另外下载打补丁安装了,当然你也有另一种选择就是使用spawn-fcgi来管理php的fast-cgi进程,sudo apt-get install spawn-fcgi即可下载这个源于lighttpd的fast-cgi通用管理器(后面python的部分才会用到它)。
安装php-fpm的方式有两种:整合式的,和分离式的,这里还需要编译一下modphp故按第二种方式安装:

export PHP_VER=5.3.1

先编译php的常规版本:

cd "php-$PHP_VER"
mkdir php-build && cd php-build
../configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-config-file-scan-dir=/usr/local/php/etc/conf.d --disable-debug --disable-rpath --enable-sockets --enable-zip --enable-ftp --with-pear --with-gd --with-freetype-dir --with-jpeg-dir --with-png-dir --enable-gd-native-ttf --with-iconv-dir=/usr --enable-mbstring --enable-mbregex --with-zlib --with-libxml-dir=/usr --enable-xml --with-mcrypt --with-mhash --enable-bcmath --with-gmp --enable-sysvsem --enable-inline-optimization --with-openssl --with-curl --with-curlwrappers --enable-shmop --with-sqlite --enable-sqlite-utf8 --with-pdo-sqlite --with-pdo-mysql=mysqlnd --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-mysql-sock=/var/run/mysqld/mysqld.sock --with-apxs2=/usr/local/apache2/bin/apxs
make
sudo make install
cd ../..

再编译上php-fpm:
不过我配置的时候,貌似php-fpm的configure脚本设置项失效了,--with-libevent指定的路径并没有能应用到它的配置查找路径中去,无奈只有做两个软链接了:

sudo ln -s /usr/local/lib/libevent.a /usr/lib/
sudo ln -s /usr/local/lib/libevent.so /usr/lib/

开始编译php-fpm:

cd "php-fpm-0.6-$PHP_VER"
mkdir fpm-build && cd fpm-build
../configure --srcdir=../ --with-php-src="../../php-$PHP_VER" --with-php-build="../../php-$PHP_VER/php-build" --with-libevent=/usr/local --with-fpm-log=/var/log/php-fpm/php-fpm.log --with-fpm-pid=/var/run/php-fpm.pid --with-fpm-conf=/usr/local/php/etc/php-fpm.conf --with-fpm-bin=/usr/local/php/bin/php-fpm --with-fpm-port=9001 --with-fpm-user=www-data --with-fpm-group=www-data
make clean
make
sudo make install
cd ../..

安装最后做一些设定工作,将常用命令链接到系统路径:

sudo mkdir -p /usr/local/php/etc/conf.d
sudo mkdir -p /var/log/php-fpm
sudo ln -s /usr/local/php/bin/php /usr/bin/
sudo ln -s /usr/local/php/bin/phpize /usr/bin/
sudo ln -s /usr/local/php/bin/pear /usr/bin/
sudo ln -s /usr/local/php/bin/pecl /usr/bin/
sudo ln -s /usr/local/php/bin/php-config /usr/bin/

将启动脚本作为系统服务:
修改执行权限,安装为系统服务:

sudo chmod a+x /etc/init.d/php-fpm
sudo update-rc.d php-fpm defaults

配置默认php.ini配置文件:

cd "php-$PHP_VER"
sudo cp php.ini-production /usr/local/php/etc/php.ini

根据你应用的需要做一些必要的调整。
修改一下默认时区:

date.timezone = "Asia/Shanghai"

更新pear库,安装一些基本的组件:

sudo pear channel-update pear.php.net
sudo pear install HTTP
sudo pear install HTTP_Client
sudo pear install --alldeps PhpDocumentor

安装apc扩展:

sudo pecl install http://pecl.php.net/get/APC

编辑php.ini文件在include_path加入pear库的路径,

include_path = ".:/usr/local/php/lib/php"

在扩展路径extension_dir添加刚刚apc编译时最后显示的扩展所在路径:

extension_dir = "/usr/local/php/lib/php/extensions/no-debug-zts-20090626"

在文件最后添加apc扩展的调用段:

[apc]
extension=apc.so
apc.enabled=1
apc.rfc1867=on
apc.shm_segments=1
apc.shm_size=128
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1

至此基本环境配置完毕,后面根据各个应用再添加扩展配置继续折腾。
运行php -v查看基本配置正常与否,php -m 可以查看当前cli模式下载入的扩展。

, , , , ,

Switch to our mobile site