分类 技术 Technology 下的文章

本博自 2012 年光荣地被 GFW 认证后,长期流亡海外。辗转香港、日本、美国等地,依然在高墙之外。2014 年的时候,眼看我的域名邮箱都收不到来自墙内的邮件,再也坐不住了。后来通过一些技术方式调整了部署,邮箱恢复正常,本博也终于得见天日。

三年多的时间发生了什么?我不能告诉你。只能说我也做了很多事情,唯一值得庆幸的是,我终于离开了互联网行业。这种感觉也正如同围城效应,现在反思前后,居然还有些许不舍。再值得庆幸的是,互联网就在我们身边。你玩儿,或者不玩儿,Ta 都在这里。每时每刻、不离不弃。

最近又遇到一件事情让我重操旧业。作为重度 Google 用户,已经具备常年与 GFW 作斗争的经验。然而在各种两会各种峰会的轮番轰炸下,梯子一个一个倒下去。SSH 转 Socks5 的方式早已落伍,各种 VPN 服务也在挣扎。为了能够更愉快地玩耍,我决定自食其力。

首先要有一台墙外的服务器或者 VPS。现在阿里云、腾讯云等各种云都做得不错,价格也亲民(我用的不是上述服务商,别问为什么,谢谢)。操作系统 CentOS,开始:

检查内核环境是否包含 mppe,是否支持 pptp。CentOS 6.4 内核版本在 2.6.15 以上,都已默认集成。

cat /dev/ppp
cat /dev/net/tun

安装 ppp、防火墙与 pptpd:

yum install -y ppp iptables
wget -c http://poptop.sourceforge.net/yum/stable/packages/pptpd-1.4.0-1.el6.x86_64.rpm
rpm -Uhv pptpd-1.4.0-1.el6.x86_64.rpm
yum install pptpd

修改配置文件中的 DNS 为 8.8.8.8 和 8.8.4.4:

vi /etc/ppp/options.pptpd

配置 VPN 账户:

vi /etc/ppp/chap-secrets

配置客户端分配到内网的 IP 地址,记得在最后加一个空行。

vi /etc/pptpd.conf

修改 net.ipv4.ip_forward 为 1:

vi /etc/sysctl.conf

生效配置,启动防火墙服务:

/sbin/sysctl -p
/sbin/service iptables start

根据网卡参数配置防火墙。由于我的 VPS 有两个公网 IP,就这样:
/sbin/iptables -t nat -A POSTROUTING -o eth1 -s 192.168.0.0/24 -j SNAT --to-source xx.xx.xx.xx
/sbin/iptables -t nat -A POSTROUTING -o eth1:1 -s 192.168.0.0/24 -j SNAT --to-source x.x.x.x

保存设置,重启服务:

/etc/init.d/iptables save
/sbin/service iptables restart

最后重启 pptpd 就大功告成了:

service pptpd restart

还可以设置开机启动:

chkconfig pptpd on
chkconfig iptables on

参考文章《centos6.4安装搭建pptp vpn服务(附pptp vpn 一键安装包) | 大步's Blog》,原文作者:大步。原链接已失效。

从今天开始,妈妈再也不用担心我的学习。家中小米路由以及单位极路由完美适配。其中极路由本身有智能路由模式,小米路由需要刷开发包,开启 SSH。具体可参见《正确姿势使用智能VPN分流,无缝国内外分流科学上网》。

- 阅读剩余部分 -

首先我想说,在 FreeBSD 7.2 上真的很折腾,尤其还是 64 位的系统。其次感谢贾同学的鼎力帮助,我们两个在这个环境上至少连续耗费 30 个小时以上。最后请原谅我不写注释以及 MySQL 主从的跳票(敬请期待),请理解我没有贴报错信息——虽然有太多太多,希望本文对有一定基础、且热爱折腾的同学有所帮助。

本文参考资料:张宴《Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建胜过 Apache 十倍的 Web 服务器(第 6 版)》与袁旭东《FreeBSD 上搭建 nginx 0.7.x + PHP 5.2.x (FastCGI) + MySQL 5.1.x》。之所以要单独发文,是因为我在折腾过程中遇到了太多上述二位所没有遇到或者没有在文中叙述的问题。

由于没有搞定 sed 的原因,很遗憾暂时无法发布自动化脚本。先给个半自动的吧。

mkdir /home/work/src/

chown -R work:work /home/work/

cd /home/work/src/

fetch http://ftp.gnu.org/gnu/wget/wget-1.12.tar.gz
tar xzf wget-1.12.tar.gz
cd wget-1.12
./configure
make
make install
cd ..

rehash

wget -c "http://prdownloads.sourceforge.net/pcre/pcre/8.02/pcre-8.02.tar.gz?download"
tar xzf pcre-8.02.tar.gz
cd pcre-8.02
./configure
make
make install
cd ..

wget -c http://nginx.org/download/nginx-0.7.66.tar.gz
tar xzf nginx-0.7.66.tar.gz
cd nginx-0.7.66

vi auto/cc/gcc

# debug
CFLAGS="$CFLAGS -g"

修改为

# debug
# CFLAGS="$CFLAGS -g"

顺便期待 sed 脚本(下文半自动处同)。

./configure --user=work --group=work --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
make
make install
cd ..

wget -c http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.47.tar.gz/from/http://ftp.jaist.ac.jp/pub/mysql/
tar xzf mysql-5.1.47.tar.gz
cd mysql-5.1.47
./configure --prefix=/usr/local/mysql/ --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-big-tables --with-readline --with-ssl --with-embedded-server --enable-local-infile --with-plugins=innobase --with-mysqld-user=work --without-ndb-debug --without-debug --with-charset=utf8 --localstatedir=/database --with-collation=utf8_general_ci

若有独立数据库服务器,只需客户端的话,加“--without-server”参数即可。

make
make install

/usr/local/mysql/bin/mysql_install_db --basedir=/usr/local/mysql --datadir=/database --user=work
chown -R work:work /database
cp support-files/my-large.cnf /etc/my.cnf
cp support-files/mysql.server /etc/rc.mysqld
chmod +x /etc/rc.mysqld
cd ..

pkg_add -r -f libiconv

wget -c "http://downloads.sourceforge.net/mcrypt/libmcrypt-2.5.8.tar.gz?modtime=1171868460&big_mirror=0"
tar xzf libmcrypt-2.5.8.tar.gz 
cd libmcrypt-2.5.8
./configure --prefix=/usr
make
make install
/sbin/ldconfig
cd libltdl
./configure --enable-ltdl-install
make
make install
cd ../../

wget -c "http://downloads.sourceforge.net/mhash/mhash-0.9.9.9.tar.gz?modtime=1175740843&big_mirror=0"
tar xzf mhash-0.9.9.9.tar.gz
cd mhash-0.9.9.9
./configure --prefix=/usr
make
make install
cd ..

wget -c "http://downloads.sourceforge.net/mcrypt/mcrypt-2.6.8.tar.gz?modtime=1194463373&big_mirror=0"
tar xzf mcrypt-2.6.8.tar.gz
cd mcrypt-2.6.8

vi src/rfc2440.c

include <malloc.h>

修改为

include <stdlib.h>

./configure --prefix=/usr
make
make install
cd ..

wget -c http://xmlsoft.org/sources/libxml2-2.7.7.tar.gz
tar xzf libxml2-2.7.7.tar.gz 
cd libxml2-2.7.7
./configure
make
make install
cd ..

wget -c http://curl.haxx.se/download/curl-7.20.0.tar.gz
tar xzf curl-7.20.1.tar.gz
cd curl-7.20.1
./configure
make
make install
cd ..

wget -c "http://prdownloads.sourceforge.net/libpng/libpng-1.4.2.tar.gz?download"
tar xzf libpng-1.4.2.tar.gz
cd libpng-1.4.2
./configure
make
make install
cd ..

wget -c http://www.ijg.org/files/jpegsrc.v8a.tar.gz
tar xzf jpegsrc.v8a.tar.gz
cd jpeg-8a
./configure
make
make install
cd ..

wget -c http://ftp.gnu.org/pub/gnu/make/make-3.79.tar.gz
tar xzf make-3.79.tar.gz
cd make-3.79
./configure
make
make install
cd ..

wget -c http://ftp.twaren.net/Unix/NonGNU/freetype/freetype-2.1.10.tar.gz
tar xzf freetype-2.1.9.tar.gz
cd freetype-2.1.9
/usr/local/bin/make CFLAGS="-O3 -fPIC"
/usr/local/bin/make
/usr/local/bin/make install
cd ..

wget -c http://ftp.gnu.org/gnu/libtool/libtool-2.2.tar.gz
tar xzf libtool-2.2.tar.gz
cd libtool-2.2
./configure
make
make install
cd ..

wget -c http://www.php.net/get/php-5.2.13.tar.gz/from/this/mirror
wget -c http://php-fpm.org/downloads/php-5.2.13-fpm-0.5.13.diff.gz
tar xzf php-5.2.13.tar.gz
gzip -cd php-5.2.13-fpm-0.5.13.diff.gz | patch -d php-5.2.13 -p1
cd php-5.2.13
./configure --prefix=/usr/local/php --with-config-file-path=/etc --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-iconv-dir=/usr --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-discard-path --enable-safe-mode --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --with-curlwrappers --enable-mbregex --enable-fastcgi --enable-fpm --enable-force-cgi-redirect --enable-mbstring --with-mcrypt --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-ldap-sasl --with-xmlrpc --enable-zip --enable-soap
make
make install

cp php.ini-dist /etc/php.ini
cd ..

pkg_add -r -f autoconf262

wget -c http://pecl.php.net/get/memcache-2.2.5.tgz
tar xzf memcache-2.2.5.tgz
cd memcache-2.2.5
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
make install
cd ..

wget -c http://bart.eaccelerator.net/source/0.9.6/eaccelerator-0.9.6.tar.bz2
tar xzf eaccelerator-0.9.6.tar.bz2
cd eaccelerator-0.9.6
/usr/local/php/bin/phpize
./configure --enable-eaccelerator=shared --with-php-config=/usr/local/php/bin/php-config
make with-eaccelerator-shared-memory=yes
make install
cd ..

wget -c http://pecl.php.net/get/PDO_MYSQL-1.0.2.tgz
tar xzf PDO_MYSQL-1.0.2.tgz
cd PDO_MYSQL-1.0.2
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --with-pdo-mysql=/usr/local/mysql
make
make install

由于死活没有成功安装 ImageMagick(低版本装了 PHP 不认,高版本报 png.c 错误),因此使用 GD 代替。安装后的配置方法与调整细节,可参见上文所述两篇参考文献。期待同行交流。

谨以此文,献给 12 年的今天离开我们的所有人。

最近唯一值得欣慰的事情,就是成功地在 64 位 FreeBSD 7.2 上使用源码编译的方式部署了 Subversion 守护进程。

为了秉承好人做到底、送佛送到西的原则,我将后期启动配置及仓库的创建、导入与导出方法记录并共享如下。同样地,感谢期间公司运维同事的全力协助。

启动方式:

/path/to/subversion/bin/svnserve -d -r /path/to/repository --listen-host=you.host.name --listen-port=4444

建议端口不低于 1024,否则需要 root 来启动。有了启动方式,系统自启动就不说了,自由发挥。

创建仓库:

/path/to/subversion/bin/svnadmin create /path/to/repository

导入仓库:

/path/to/subversion/bin/svnadmin load /path/to/repository < /path/to/dumpfile

导出仓库:

/path/to/subversion/bin/svnadmin dump /path/to/repository > /path/to/dumpfile

之前我居然用 svn import 命令导入仓库,死活报错,想起来丢脸万分、后悔万分:

subversion/libsvn_client/commit.c:765: (apr_err=150002)
svn: Path 'svn://you.host.name:4444/repository' already exists

关于钩子的作用,可以让客户端在操作 SVN 的同时触发一些事务脚本,从而完成某些作业——譬如在服务端 checkout 仓库到 Web 服务器所指向的目录,实现测试服务器的实时调试。

在折腾钩子的时候,我无意间发现我们敬爱的水总在一年前就写过相关的文章,猛击这里拜读。

下集预告:《64 位 FreeBSD 7.2 上部署 Nginx + PHP 及 MySQL 主从》。当然,老规矩,我不会写使用诸如 ports 来安装的此类“没有技术含量”的文章。

其实,我要的只是一个与 Apache 无关的轻量的独立的 Subversion 守护进程,即 svnserve;这次操作系统是 64 位的 FreeBSD 7.2。不知是 64 位的原因还是 7.2 的原因,部署过程非常不顺利。前后陆陆续续地折腾了两个多星期,快把 Google 都搜烂了。期间公司运维的贾同学与杨同学给予了大力帮助,在此表示感谢。

现在我们开始。首先刻录 64 位 FreeBSD 7.2 的第一张 CD,分区,最小化安装,设置 root 密码,添加隶属 wheel 组的普通用户帐户,配置网络与 sshd……一路顺畅无比,十分痛快,不再赘述。

然后使用 ssh 客户端(推荐 PuTTy,它还支持手机塞班操作系统)连接到服务器,验明正身:

svn# uname -a
FreeBSD svn.xx.xxxx.com 7.2-RELEASE FreeBSD 7.2-RELEASE #0: Fri May  1 07:18:07 UTC 2009     [email protected]:/usr/obj/usr/src/sys/GENERIC  amd64

接着下载 wget 并安装:

svn# mkdir -p /home/work/src/
svn# cd /home/work/src/
svn# fetch http://ftp.gnu.org/gnu/wget/wget-1.12.tar.gz
svn# tar -xzf wget-1.12.tar.gz
svn# cd wget-1.12.tar.gz
svn# ./configure
svn# make
svn# make install
svn# rehash

然后下载需要的其他安装包,并解压:

svn# cd /home/work/src/
svn# wget -c http://xmlsoft.org/sources/libxml2-2.7.7.tar.gz
svn# wget -c "http://downloads.sourceforge.net/project/expat/expat/2.0.1/expat-2.0.1.tar.gz?use_mirror=cdnetworks-kr-2"
svn# wget -c http://subversion.tigris.org/downloads/subversion-1.6.11.tar.gz
svn# wget -c http://subversion.tigris.org/downloads/subversion-deps-1.6.11.tar.gz
svn# tar -xzf libxml2-2.7.7.tar.gz
svn# tar -xzf expat-2.0.1.tar.gz
svn# tar -xzf subversion-1.6.11.tar.gz
svn# tar -xzf subversion-deps-1.6.11.tar.gz

安装 libxml:

svn# cd /home/work/src/libxml2-2.7.7/
svn# ./configure
svn# make
svn# make install

安装 expat:

svn# cd /home/work/src/expat-2.0.1/
svn# ./configure
svn# make
svn# make install

然后:

ln -s /usr/local/lib/libexpat.so /usr/lib/libexpat.so

进入 subversion 目录,逐个安装依赖包的组件:

svn# cd /home/work/src/subversion-1.6.11/

svn# cd apr
svn# ./configure --prefix=/usr/local/apr LDFLAGS="-L/lib64"
svn# make
svn# make install

svn# cd ../apr-util
svn# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr/ LDFLAGS="-L/lib64"
svn# make
svn# make install

svn# cd ../zlib
svn# ./configure
svn# make
svn# make install

之前一直安装 serf,方法:

svn# cd ../serf
svn# ./configure --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util/ LDFLAGS="-L/lib64"
svn# make
svn# make install

无奈它死活就是报错:

/usr/lib/crt1.o(.text+0x8a): In function `_start':
: undefined reference to `main'
*** Error code 1

Stop in /usr/home/work/src/subversion-1.6.11/serf.

结果 Google 了好几天,看了 N 篇老外的帖子,发现如果不搭配 Apache 使用,这个组件可以不安装……

然后 neon 也可以不安装。下面的安装方式或许会报错:

svn# cd ../neon
svn# ./configure --enable-shared --enable-ssl LDFLAGS="-L/lib64"
svn# make
svn# make install

其实这个 sqlite 也可以不安装:

svn# cd ../sqlite-amalgamation
svn# ./configure --prefix=/usr/local/sqlite
svn# make
svn# make install

记得不要写到 Subversion 的编译参数里面。“--without-sqlite”也不行,会报错。

最后可以安装 Subversion 了:

svn# cd ..
svn# ./configure --prefix=/usr/local/subversion --with-apr=/usr/local/apr/bin/apr-1-config --with-apr-util=/usr/local/apr-util/bin/apu-1-config --with-ssl --with-zlib=/usr/lib --without-serf --without-berkeley-db --enable-maintainer-mode LDFLAGS="-L/lib64"
svn# make
svn# make install

如果不安装前面的 expat,会报错:

/usr/bin/ld: cannot find -lexpat
*** Error code 1

Stop in /usr/home/work/src/subversion-1.6.11.

安装到此结束,如果没有意外报错的话——恭喜你,可以自恋一下了:

svn# /usr/local/subversion/bin/svnserve --version
svnserve, version 1.6.11 (r934486)
   compiled May 12 2010, 04:25:34

Copyright (C) 2000-2009 CollabNet.
Subversion is open source software, see http://subversion.tigris.org/
This product includes software developed by CollabNet (http://www.Collab.Net/).

The following repository back-end (FS) modules are available:

* fs_fs : Module for working with a plain file (FSFS) repository.

启动方式就不多说了,手册上写得非常清楚。需要智能化脚本的,也可以 Google 到。

部署结束,感谢收看。

前段时间将博客从独立服务器迁移到了 Godaddy 的主机上,顺便从 Magike 换到了 Typecho。期间先将 Magike 迁移到 Godaddy 的主机上测试,然后将本地安装好的 Typecho 迁移到 Godaddy 的主机上测试,最后在 Godaddy 主机上全新安装 Typecho,整个过程始终被一个诡异的问题所困扰,即重写无法生效。

这个问题源于 Godaddy 主机环境使用的 Apache 版本和 Magike、Typecho 本身使用的 Rewrite 机制。经过自己反复折腾和反复骚扰 70 同学后均没有彻底解决问题,最后易先生眼看自己的博客也受到了影响,于是才亲自动手搞定。

这个问题是这样的:

首先,Godaddy 主机的 Apache 版本是 1.3.33。假设 Magike 或 Typecho 没有开启伪静态,在处理类似 https://www.xuchao.org/index.php/archives/1/ 这样的地址时,服务器会在
/index.php/archives/1/ 这个目录里找 index.php 然后来执行,并不会带上 /archives/1/
这个参数,所以点到哪都是首页。若 Magike 或 Typecho 开启了伪静态,浏览器则会接收到 404 错误。

要解决这个问题,大致有两种方案:
1、改变 Magike 和 Typecho 的 URL 传参形式,及程序获得参数的方法;
2、通过升级 Apache 版本等方式,解决服务器对 Magike 和 Typecho 的 URL 的识别。

很显然,在一个租用环境中无法做到第二点。因此只能考虑调整 Magike 和 Typecho 的 URL 解析的函数。

最后问题是这样解决的:

1、Magike

在根目录 index.php 的 include('./core/core.php'); 这行前面加上如下代码:

$baseInfo = @explode('?', $_SERVER['REQUEST_URI'], 2);
if (is_array($baseInfo))
{
        $_SERVER['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
        $_SERVER['PATH_INFO'] = $baseInfo[0];
        unset($_GET);
        if ($baseInfo[1])
        {
                $getInfo = @explode('&', $baseInfo[1]);
                foreach ($getInfo as $v)
                {
                        $getInfo2 = @explode('=', $v);
                        $_GET[$getInfo2[0]] = $getInfo2[1];
                }
        }
}

如果启用了伪静态,则需要修改 .htaccess 文件如下:

RewriteEngine On
RewriteBase /
RewriteRule index(\.)php/(.*) /index.php?/$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]

2、Typecho

在根目录 index.php 的 Typecho_Plugin::factory('index.php')->begin(); 这行前面加上上面一样的代码,若需伪静态,.htaccess 文件也一样。

值得庆幸地是,以上问题仅存在于 Magike 和 Typecho 0.6 以下(含)版本,最新的 Typecho 0.7 正式版已完全解决此问题。

问题解决,立此存照。感谢易先生的帮助与 70 同学的辛勤耕耘。

2013 年 4 月 13 日更新:关闭本篇文章评论,垃圾太多。