在Linode的Ubuntu上搭建L2TP over IPSec服务器

之前在Linode上部署的openVPN服务在我把instance迁移到东京之后就歇菜了。之后特地花了时间重新配置了一把,但是还是出现了连接没问题,仍然无法访问外网的问题(编者按,L2TP配置完之后触类旁通的基本可以肯定是路由问题,也有把握修复了,这是后话)。考虑到ipad只能支持L2TP,所以特地花了时间搞了一把,特地记录一下。
不得不说运气不错,找到一篇很赞的总结文在Linode上搭建L2TP / IPSec VPN,不仅总结了自己的问题,而且还提供了其他详细教程的链接,相当方便。


1)安装IPSec
没啥好说的,Ubuntu就是方便阿方便。

sudo apt-get install openswan

2) 配置IPSec Connection
修改/etc/ipsec.conf,注意把%YOUR.SERVER.IP.ADDRESS%替换成你的服务器地址。

version 2.0
config setup
nat_traversal=yes
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
oe=off
protostack=netkey
conn L2TP-PSK-NAT
rightsubnet=vhost:%priv
also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
authby=secret
pfs=no
auto=add
keyingtries=3
rekey=no
ikelifetime=8h
keylife=1h
type=transport
left=%YOUR.SERVER.IP.ADDRESS%
leftprotoport=17/1701
right=%any
rightprotoport=17/%any

3) 配置IPSec共享密钥
修改/etc/ipsec.secrets,注意把%YOUR.SERVER.IP.ADDRESS%替换成你的服务器地址。另外国外论坛也有提到第二种写法可以避免一些不必要的问题。

%YOUR.SERVER.IP.ADDRESS% %any: PSK “YourSharedSecret”

: PSK “YourSharedSecret”

4)修改包转发设置
执行下列命令

for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done
echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -p
ipsec verify #用来验证配置

最后重启一下ipsec服务器。

sudo /etc/init.d/ipsec restart

5)安装配置xl2tpd
再次赞叹ubuntu的方便。

sudo apt-get install xl2tpd

修改/etc/xl2tpd/xl2tpd.conf.

[global]
ipsec saref = yes
[lns default]
ip range = 10.1.2.2-10.1.2.255
local ip = 10.1.2.1
;require chap = yes
refuse chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

6)安装配置ppp

sudo apt-get install ppp

修改或者创建/etc/ppp/options.xl2tpd,注意我这里用的是Google的Public DNS。

[global]
ipsec saref = yes
[lns default]
require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
asyncmap 0
auth
crtscts
lock
hide-password
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4

添加VPN用户,修改/etc/ppp/chap-secrets

# user server password ip
xiuxiu l2tpd testpassword *

重启xl2tpd

sudo /etc/init.d/xl2tpd restart

7)设置 iptables 的数据包转发
执行下列程序。

iptables –table nat –append POSTROUTING –jump MASQUERADE



8)设置启动脚本
关于IP路由和转发的配置在服务器重启后会消失,所以需要在启动脚本中添加相关内容.修改/etc/rc.local

iptables –table nat –append POSTROUTING –jump MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done
/etc/init.d/ipsec restart



问题汇总
Ubuntu openswan errno 111, origin ICMP type 3 code 3 (not authenticated)
这是我自己遇到的问题,郁闷了半天,结果是最新的openswan for ubuntu有bug,与最新的Linux Kernel有冲突。去openswan的官网下载较老的版本openswan_2.6.32-1xelerance1_i386.deb就可以了。


ERROR: asynchronous network error report on eth0 (sport=4500) for message to your.client.ip.address port 4500, complainant your.server,ip.address: No route to host [errno 113, origin ICMP type 3 code 1 (not authenticated)]
在 ipsec.conf 中加上 leftnexthop=your.server.gateway.ip 应该可以解决。


The remote system is required to authenticate itself
pppd[4407]: but I couldn’t find any suitable secret (password) for it to use to do so.

这是由于验证过程中未使用 l2tp-secrets 中的密码(至于为何如此我不懂,另请高人解释),而是使用 pptp(L2TP/IPsec 也是要走 pptp 的)的密码,所以需要在 /etc/ppp/chap-secrets 中设置密码(具体请见上面如何搭建 PPTP VPN)。


xl2tpd[4062]: Maximum retries exceeded for tunnel 44651. Closing.
在/etc/ipsec.conf里的L2TP-PSK-noNAT中加上
dpddelay=40
dpdtimeout=130
dpdaction=clear

参考链接
Using Linux as an L2TP/IPsec VPN client
openswan_2.6.32-1xelerance1_i386.deb

如何在 Debian / Ubuntu 服务器上架设 L2TP / IPSec VPN
Linode CentOS / Debian 部署 ipsec+l2tpd 简要笔记
Guide: Openswan, XL2TP and PPP on Ubuntu Maverick for iPhone VPN Connection
联通连不通─VPN
linux l2tp vpn install


推荐链接
有兴趣的朋友可以使用我的referral链接注册使用Linode。
http://www.linode.com/?r=513a31440dd0a6c0980cc05a164b4ae2520a19d6

 

Linode一次简单的运维经历

2012年3月1日下午2点,有用户报告说安装的Wordpress坏了,用身边的Ipad尝试链接,Database Error。
用ipad的ssh客户端登录服务器作初步检查。
1)ps -ef | grep mysql
显示没有正在运行的mysql实例对象。
2)service mysql start
mysql: Job failed to Start
显示mysql运行失败
3)cat /var/run/log/mysql/error
没有数据,google之后可能是日志文件权限不够,不过查看之后发现没有问题。问题暂时搞不定。

2012年3月1日晚上8点,回到家用电脑开始登陆服务器尝试修复。
1)cat /var/log/daemon.log
Mar 1 21:09:53 xiuxiu init: mysql pre-start process (4597) terminated with status 1
死办法通过时间找到日志文件daemon.log,查看内容发现如下错误信息。google之后发现Linode论坛就有人讨论这个问题(大赞linode),是服务器硬盘不够引起的。
2)mysql> use information_schema
Database changed

mysql> select concat(round(sum(index_LENGTH)/(1024*1024),2),’MB’) as ‘Index Size’ from tables where table_schema=’bbs’;
首先想到的是数据库可能太大了,google了查看数据库大小的方法,发现所有数据库没有容量太大的问题。
3)du -h –max-depth=1 /
Google了Linux查看文件夹大小的命令,但是还是不熟悉LInux的文件结构,只好从根目录开始查看,最后定位到了/var/mail/root,最后发现是自己的一个app给系统发送了过多的mail导致。删除本地mail,系统恢复正常。

没有特别的含义,记录一下linux操作以及大致的诊断问题的方法。

参考链接

mysql查看数据库大小,索引大小

Linux下查看文件和文件夹大小的df和du命令

 

Kindle Fire初体验(注册+Root+TWRP+输入法)

为什么要买Kindle Fire?199$!这是最有力的答案了吧,也可以把你对它的一些不满丢到九霄云外去。1G CPU,1.2G内存,内置8G硬盘。一个字:赞赞赞赞赞赞赞! (作者按:最近US促销,买Kindle Fire送50$抵用券,哭死吧阿门。。。)
拿到手,注册好,连接上电脑,方便的把之前的kindle3的mobi电子书导入Kindle Fire中,偏黑白的高清电子书阅读体验可以让你把“值得”这个想法推到另外一个高度。
随便记录了一下自己折腾的一些步骤作为总结吧。


注册
Kindle Fire激活的时候需要输入你的Amazon帐号,比起WP7来说比较贴心的地方是,这个帐号是可以Degister的。注册本身没有什么问题,唯一需要国内朋友注意的是如果你没有绑定信用卡,或者绑定了billing address不是US的信用卡的话,是没有办法下载Amazon Market的应用的,哪怕是免费的应用。具体的解决办法可以参考
从Amazon Appstore购买免费App和游戏的方法(不需要真实信用卡)。不过这样的话1-click本身基本就没法用了,如果你真的需要在Amazon上购物的话,可能会需要跳过这个billing address和credit card的选项,略显麻烦。


安装应用
主要安装应用的办法有三个:

  1. 通过Amazon Market安装应用。如果按照上述方法注册了信用卡,就可以按照这个方法安装应用。Amazon Market的应用都为Kindle Fire做了定制,质量比较有保证,但是国内的必备应用例如微博,微信基本都没有。。。。。另外一个好处是每天都有一款Amazon特约的限时免费应用。
  2. 通过豌豆荚安装应用。打开”Settings”-”Device”-”Allow Installation of Application”开关就可以了。绝对是最方便的安装应用的方法。唯一的缺点是应用没有为Kindle Fire定制过,屏幕尺寸,硬件支持都比较差,可能导致兼容性不好甚至闪屏。
  3. 通过Google Android Market安装。没有深入研究,感觉豌豆荚很不错了,有兴趣的可以研究一下。



Rooting
安装Google Android Market,安装中文输入法,安装TWRP等备份应用,一切的一切都让你不得不去Rooting你的Kindle Fire。
我激活的时候顺便就更新了我的Kindle Fire,所以是最新的6.2.2的固件,按照
[教程] Kindle Fire 6.2.2 ROOT教程(附上6.2.2固件,115网盘的哦!!)中的方法进行Rooting,基本不用动脑筋。唯一的问题是链接中的RE浏览器下载链接失效了,直接用豌豆荚下载一个打开,如果询问你是否授予Superuser权限的话,那么恭喜你,高智商破解的Rooting工作你已经完成了。


TWRP
TWRP的功能类似HTC系列的三色屏,在ROM下层帮助你实现类似Bakcup,Restore,Wipe的功能。按照
[教程] ADB环境搭建 & Kindle Fire安装驱动 & TWRP安装教程 & TWRP美化 中的方法进行操作即可,同样的条件就是需要先Rooting。


输入法
注意:安装输入法是最容易让系统变砖的原因之一,提高警惕啊。

Kindle Fire默认不支持中文输入,也不支持输入法安装选择。这就根本不能用啊。
没办法Root先,然后安装[教程] 《终极篇》 第四波,傻瓜方式,支持所有语言所有版本所有输入法!!!!!中的方法进行安装。

1 没办法,还是需要你先root
2 安装任何你喜欢的输入法,是任何都可以,你想安装波斯语的输入法都可以
3 运行re管理器,到/data/app目录,找到你刚刚安装的输入法的apk文件,找不到?! 不可能,看图标就可以找到的
把它移动到/system/app目录,注意 是 移动,不是拷贝!!!!!! 不需要你修改任何权限!!!!!
4 重启
5 再次运行re管理器,到/system/app目录,运行刚才你移动过来的apk文件,它会提示你安装,安装好之后,删除它,一定要删除
6 一切都ok了,不需要重启就可以马上使用你安装的输入法了

需要注意的是

  1. /data/需要将“Remount R/O”修改成”Remount R/W”才能移动成功。
  2. 安装完毕后一定要直接打开输入法的application,修改默认输入选择。因为退出之后你不会在App列表中再看到输入法的图标。可能Kindle默认该apk是系统应用的关系吧,或者我装傻了-,-。每次修改输入法选择应该会把一部分人逼疯吧。
  3. 如果要切换输入法选项的话,长按待输入的区域两秒以上就可以了。

遗留问题
其实遗留问题更多的是对目前Kindle Fire定位设计方面的不满。

  1. 没有摄像头。
  2. 没有MIC。(可以兼容4pin的耳麦)。
  3. 不兼容Skype。
  4. 不兼容微信。
  5. 不官方支持输入法安装和选择。

总体感觉,Kindle Fire更象一个多媒体终端,要当平板电脑,还有一些距离吧。


相关链接
新手amazon注册及kindle注册教程
[分享] [Kindle Fire] 安装中文输入法(包括 Root 及中文介面安装教0程)
[交流] Kindle Fire TWRP使用说明

 

WP7初体验(HTC Mozart 注册+刷机+越狱)

题外话,不得不说同样的硬件配置WP7要比Android便宜不少,看得出M记砸钱的力度,赞美一下。

前一阵子入手了一台HTC Mozart, 800万摄像头,疝气闪光灯,1.8k,再次赞美一下。友好的店主已经帮忙刷机过了,DFT(WP7的福星团队啊,资源里面第一条)出品的基于7713的ROM,已然非常的好用了。不过作为专业人士(自封的。。),还是禁不住要重头整理一遍,自己捣鼓一下。基本参考了从初见开始 Windows Phone 7 初/中/高级 经典教程专题,非常的全面,然后根据自己的情况做了一些删减,记录如下。

安装Zune
没啥好说的,看名字难道是冲着itunes来的,界面很酷,不过除了连接WP7貌似其他功能还没有兴趣了解。唯一需要注意的是如果要连接Microsfot Marketplace,一定要把电脑的区域设置成非中国。


注册Window Live ID
援引了一段原文中的话,可以了解一下WP7中的Window Live ID和Zune通行证的一个关系,总结下来就是通过Zune来注册一个新的Window Live ID(即Zune通行证)是最方便稳妥的方法。需要注意的有三点:

  1. Window Live ID中选择的区域需要和电脑的区域保持一致。
  2. Zune注册好以后需要在Window Phone上首次登录一下再与电脑进行连接,否则无法同步安装应用。
  3. Window Phone上的Window Live ID(首个)一旦登录就无法删除,除非重置手机或者刷ROM。第二个以后的Window Live ID没有这个问题。

为什么要通过向导申请ID ,这里面的奥秘,关于Windows Live ID和Zune通行证的关系(仅作了解,可以跳过):
Windows Live ID和Zune通行证有一个转换关系,当你用之前就申请好的Windows Live ID登录ZUNE的时候,你的Windows Live ID会变成一个ZUNE通行证,Windows Live ID的个人资料都会填充到ZUNE通行证里面,而且地区信息在ZUNE通行证被锁定了(无法修改,不知道为什么要这样设定),这就造成你的Windows Live ID的地区可以更改,但是ZUNE通行证的地区已经无法更改了。如果你用中国的Windows Live ID登录一次ZUNE或手机Marketplace市场,那么由于中国区不支持的原因,这个Windows Live ID就算在WP7上废了。

我们可以理解为其实WP7需要的不是Windows Live ID,而是需要Zune通行证(因为市场只认通行证的地区,却不认LIVE ID的地区),只是你在申请Zune通行证后,这个通行证会由于微软业务的共通关系同时生成一个Windows Live ID。因此为了保险起见,我们直接申请Zune通行证。



同步音乐,电影
M记的东西在这个时候用起来就会觉得极其方便了。默认配置下,只要把电影,音乐放到电脑Music/Movies目录下,就会自动显示在Zune中,拖拉一下就可以同步到Window Phone里面去了,还有比这个更方便的么。对于喜欢保存mp3的我来说,真是超级方便啊。如果不喜欢留mp3,Window Phone Marketplace里也已经有QQ音乐和虾米音乐的客户端了,赞就一个字啊。


刷机
不得不说刷机绝对是一个手艺活。是否需要越狱刷机方式不同;不同的品牌手机(HTC,三星,LG)刷机方式不同;不同的Window Phone 版本(NODO, Mango or Later)刷机方法也不同。没接触过的同学建议一定要看下面两篇文章融会贯通一下概念。

不过作为坐拥HTC Magic的我来说现在的情况已然简化很多了(骄傲),最多也就多刷一个SPL而已。。。
HTC标准的刷机方法有三种,总体的思路就是从7008之前的版本开始越狱,然后更新一次越狱一次,保证更新到最新的Mango还是越狱的。

  1. 先刷RSPL/HSPL,然后刷非官方的民间自制Mango版本的ROM。好处是快速,简单(但要谨慎),30分钟内用上Mango+越狱。
  2. 先刷7004版本的ROM,然后通过微软官方的推送更新来一步步从7004版本更新到Mango版本,更新过程中通过各种方法保留越狱状态到Mango。好处是不用担心收不到Mango以后的官方更新,且由于使用的是官方ROM,所以纯净,稳定。缺点是非常繁琐。
  3. 直接刷mango官方ROM,然后在Mango下用开发者帐号解锁。此法非常适用于二代机。

因为我有开发者帐号,无所谓这些,直接就按照第三个方法进行了刷机,非常的方便。主要刷机步骤如下,唯一要注意的是一开始连接的时候要保证机器没有锁屏。

  1. 准备好ROM,感谢DFT的努力,我们有了自己的自定义ROM,支持IE直接安装XAP这么强大的功能。不过第一次刷机我还是很胆小的准备了官方Mango 7720 ROM。
  2. 手机关机后,按住音量下键,然后同时按住开机键,进入三色屏模式,如下图,有HSPL字样,才能刷DFT或其他第三方自制 ROM,而且有这个字样的话你就不能在直接刷官方的芒果ROM,我这里刷的是7720的官方ROM
  3. 数据线接上手机,保证手机电量50%以上。电脑端开始安装驱动。如果出现找不到驱动,那就看这里解决
  4. 打开事先下载的ROM包,DFT 自制ROM与官方ROM不同的是:官方ROM直接是一个EXE文件,点击开刷;自制 ROM是个7z压缩包,需要解压它,找到ROMUpdateUtility.exe开始刷机。
  5. 然后就搞定了!



越狱
由于我莫名其妙把自己搞成了开发者(支付掉99美金。。。),所以这部就非常容易了。Microsoft默认开发者可以越狱三部设备。安装好Window Phone SDK,保证Zune运行正常,Window Phone正确连接,之后直接运行”Windows Phone Developer Registration”,输入你的开发者帐号就可以了。 复杂的注册方法,等一年之后再说吧。。。。


安装XAP
唯一的遗憾就是没有刷DFT的自定义ROM,所以没办法通过手机IE直接访问智机市场,下载XAP。
不过系统已经越狱了,除了通过Zune或者手机Marketplace来安装官方应用之外,也可以通过Window Phone SDK的Application Deployment来安装自定义的XAP应用。


遗留问题

  • MSN应用。WP7对MSN做了深度整合,所以没有单独的MSN应用。可以让我随意切换Window Live ID。
  • Skype应用。至今没有提供Skype客户端。Mango自带的Tango也没有试用成功。
  • 联系人资源。其实这是根本问题。由于绑定的Window Live ID是为了区域问题新创建的,所以没有任何联系人信息。平时用的Window Live ID可以添加但是MSN只认第一个Window Live ID。另外就是电话号码联系人会和MSN联系人混在一起有些混乱。
  • 系统通用设置。感觉少了很多系统级别通用的设置。


相关资源
论坛- 黑暗军团- DFT 论坛- Powered by Discuz!
Windows Phone 7论坛|智机网|WP7论坛|WP7软件|WP7游戏|ROM
从初见开始 Windows Phone 7 初/中/高级 经典教程专题
HTC Mozart亚太官方Mango 7720 ROM
Download Windows Phone SDK 7.1
How to: Register Your Phone for Development

 

WP-Douban-Post发布后记

距离WP-Douban-Post发布已经有差不多两个月了。总想写点什么总结一下。

缘由

说起来初衷很简单。我的博客可以同步到twitter,新浪,就差同步到豆瓣上了。受不了每次人肉同步的繁琐,又没找到合适的现成wordpress插件,又打算学习一下Oauth+Douban API + WordPress Plugin的各种技术,袖子管一卷咱就干了起来。

过程

前后大概花了一周的业余时间,大概按照如下的步骤走了一遍,总算是客服了重重难关,完成了这个插件。
1)Wordpress Hello World Plugin (了解Wordpress插件结构)
2)Wordpress Option Page(了解添加配置选项,存取数据库,添加事件响应)
3)Douban Oauth (Douban Zend Client太复杂,只好自己用php oauth library。自己拼接header,测试MD5验证,多谢Douban API支持,这部分是最艰辛的)
4)Douban API 调用(真正开始调用API,发送自己的记录到我说)
5)WP-Douban-Post (拼装完成,达达达搭)

推广

说是推广其实是抬举了自己。自己作了好用当然是想广而告之显摆一下。第一个想到的自然就是wordpress.org插件库。如果可以在Plugins里面搜索到自己的名字,想想就威风。
提交开发者申请,编写README,提交代码。所有的步骤都有清楚的指南。Wordpress.org基于SVN的发布系统让我大开眼界,收益非浅。
1)通过README提取插件信息,例如作者信息,安装指南,Q&A,对开发人员和wordpress.org都是方便清楚。
2)建议开发者拉branch进行发布,通过README元信息指定发布的具体branch.通过这样的最佳实践直接帮助开发者分清了发布和开发的代码。清晰明了。

然后就是更新豆瓣应用信息,在豆瓣API小组发贴庆祝。然后就是每天刷屏期待了。。。这就是我做的推广-,-。大概的情形趋势图上都清清楚楚。
1)2011-01-19,推荐给了几个用豆瓣也用Wordpress的朋友,小推销了一把,迎来了下载高峰。
2)2011-01-21 to 2011-02-12,春节期间,下载量逐渐走低。。。。
3)2011-02-13 to 2011-02-20,春节结束,赢了小小的反弹。。。。
4)2011-02-21 to 2011-03-20, 大概可以看出周末基本没有下载,工作日偶尔有人。。
5)2011-03-25, 豆瓣有了应用小站,很荣幸被发布了出来,还被表扬了^@^,也迎来了之后小小的高峰。。。

没有什么特别的期待,有人用,觉得有用大概就是对我最大的夸奖了。呵呵。欢迎提意见给我。

后记

1)听说豆瓣九点可以自动收录wordpress,我那叫一个后悔啊。新手不会玩豆瓣,sigh。
2)想要php调用douban Oauth的同学,可以参考我在wordpress.org上的代码,这可是汗水和泪水啊-,-
3)wordpress.org的缺点也很明显,一定需要wordpress.com的账号才能rate和vote,这导致基本没人回来给意见。

WordPress.org 地址

http://wordpress.org/extend/plugins/wp-douban-post/stats/

Douban应用小站 地址

http://site.douban.com/widget/notes/2324209/note/141570144/

WP-Douban-Post Stats 2011-03-26

WP-Douban-Post Stats 2011-03-26

 

在Linode上安装openVPN

一些朋友需要VPN访问一些墙外资源。本着服务器放着不用是浪费的原则我决定搭一个VPN服务器帮助解决朋友的需求。
不得不说Linode的文档非常齐全,而且很傻瓜,照着作一遍基本解决了所有的问题。

openVPN安装

Ubuntu方便是没话说的。

apt-get update
apt-get upgrade --show-upgraded
apt-get install openvpn udev

这就是所有你需要的软件了。安装包里提供了密钥工具包“easy-rsa”,把它拷贝到配置文件夹下。

cp -R /usr/share/doc/openvpn/examples/easy-rsa/ /etc/openvpn

修改工具包中的文件vars,按照你的需要配置相关信息

export KEY_COUNTRY="US"
export KEY_PROVINCE="OH"
export KEY_CITY="Oxford"
export KEY_ORG="Ducklington"
export KEY_EMAIL="squire@ducklington.org"

配置你的密钥体系

首先需要初始化PKI.

cd /etc/openvpn/easy-rsa/2.0/
source . /etc/openvpn/easy-rsa/2.0/vars
. /etc/openvpn/easy-rsa/2.0/clean-all
. /etc/openvpn/easy-rsa/2.0/build-ca

接着生成服务器私钥。会有一些问题和提示,选择默认和Y就可以了。

. /etc/openvpn/easy-rsa/2.0/build-key-server server

然后是生成客户端的证书.其中client1是证书的名字,你可以按照你的需要填写。如果需要生成多个客户端证书,重复该步骤就可以了。

. /etc/openvpn/easy-rsa/2.0/build-key client1

最后生成Diffie Hellman Parameters。

. /etc/openvpn/easy-rsa/2.0/build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time

如果一切正常,会出现如上所示的信息。
密钥的配置基本就是这样,最后把生成的密钥文件和easy-rsa提供的服务器端配置文件样本拷贝到配置文件夹下。

cd /etc/openvpn/easy-rsa/2.0/keys
cp ca.crt ca.key dh1024.pem server.crt server.key /etc/openvpn

cd /usr/share/doc/openvpn/examples/sample-config-files
gunzip -d server.conf.gz
cp server.conf /etc/openvpn/
cp client.conf ~/
cd ~/

配置openVPN链接

密钥的配置保证了客户端和VPN服务器的链接。还要配置openVPN对网络包地转发规则。
修改/etc/openvpn/server.conf,添加如下语句

push "redirect-gateway def1"

修改/etc/sysctl.conf,添加如下语句

net.ipv4.ip_forward=1

为VPN会话添加下列变量。

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

为了保证每次启动这边规则都生效,可以把后面四个语句添加到/etc/rc.local中去。
除了IP包地转发规则,我们还需要处理来自客户端的dns请求,安装dnsmasq来解决这个问题。

apt-get update
apt-get install dnsmasq

修改/etc/openvpn/server.conf,添加如下语句

push "dhcp-option DNS 10.8.0.1"

OK,一切搞定,启动openVPN服务吧。

/etc/init.d/openvpn restart

客户端的使用

Mac下的openVPN客户端
http://code.google.com/p/tunnelblick/
Windows下的openVPN客户端
http://openvpn.se/download.html
将上文生成的client.conf, ca.crt, client1.key, client1.crt拷贝到你的电脑,配合客户端使用即可。

参考连接

http://library.linode.com/networking/openvpn/ubuntu-10.04-lucid

推荐连接

有兴趣的朋友可以使用我的referral链接注册使用Linode,将获得10%的优惠。
http://www.linode.com/?r=513a31440dd0a6c0980cc05a164b4ae2520a19d6

 

WordPress搬家记

Hostmonster的两年租约转眼到期了。想当年4刀每月如今已经涨到了6刀每月,感慨之际只好把东西通通往Linode这边搬。希望这次可以坚持的更长。
Hostmonster上需要搬的也就一个wordpress,其中有经历了一些问题,记录下来也算是经验。
之前已经把domain transfer搞定了,所以主要就是程式的挪动。大致的搬家过程主要分三步。

数据库搬家

不得不说mysqldump还是很方便的。对于我这种要求不高,只求没数据遗留的人来说超级方便。

mysqldump wordpress > wordpress.sql

然后在linode上直接导入数据库就好了

mysql -u xxx -p
create database wordpress character set utf8;
exit
mysql -u xxx -p -D wordpress < wordpress.sql

WordPress搬家

我的hostmonster和Linode都开通了SSH服务。所以php文件搬家直接就是一句话的事情。

scp -rf blog/* xxx@tech4k.com:/path/

配置更新

wp-configs.php包含了wordpress的所有全局配置,搬过来以后要做对应的修改。我的域名没有变,所以只需要对数据库配置修改就可以了。

define('DB_NAME', 'xxxxxx');^M
^M
/** MySQL database username */^M
define('DB_USER', 'xxxxxx');^M
^M
/** MySQL database password */^M
define('DB_PASSWORD', 'xxxxxx');^M
^M
/** MySQL hostname */^M
define('DB_HOST', 'xxxxxxxx');^M



除了这三步之外还有一些小地方的注意事项,也许不适合你的案例,但是注意一下总归没错。

用户和用户组,以及权限

scp搬过来的所有文件的用户和用户组信息都会被修改,一开始完全没有办法更新插件。之后才发现这个问题的。这里的用户必须是apache的执行用户,这样才不会有问题。

chown -R aaa:xxx *

设置上传路径

在wordpress的管理界面中,需要设置一个上传路径,这样才可以自动从wordpress.org上自动下载插件。
Settings -> Media -> Store uploads in this folder
需要注意的是该文件夹需要权限配置可写。

sitemap.xml&sitemap.xml.gz配置

我使用了XML-Sitemap这个插件,方便好用。该插件需要根目录下的sitemap.xml和sitemap.xml.gz可写。

遗留问题

timer启动

理论上有些插件需要在插件激活的时候启动一些后台Timer定时完成任务的。不是很清楚我这样的搬家方法会不会对这种插件有问题。

Permalink配置

我现在的Permalink有问题。只能通过/?p=%post_id%来访问,不能通过/archive/%post_id%这种方式访问。添加了.htaccess也确认可写之后仍然有这个问题。还需要进一步研究。

搬家总是很麻烦,皑皑,感叹一下。

 

WordPress Ajax Widget开发

本篇文章是紧接上一篇WordPress 2.8+ Widget 插件开发.
自己开发得一个小工具 WP Dict需要调用服务器端方法查询单词,但是个人觉得页面跳转的用户体验不好,所以小研究了一把ajax的实现方法而且试验成功,特此记录。

注册服务端方法


function wp_dict_request_handler() {
}
add_action('init', 'wp_dict_request_handler');

比想象的更加简单,Wordpress可以通过add_action注册自己的服务器端方法,所有页面均可调用。唯一需要注意的是方法名需要保证唯一。

注册jquery

在Widget类的构造方法中添加如下语句。

// Load jQuery
wp_enqueue_script('jquery');

获得Widget ID

在widget()方法extract方法后天添加如下语句。

function widget( $args, $instance ) {
extract( $args );
// Get the div id of the widget
$widgetid = $args['widget_id'];
。。。
}

Ajax实现

在Widget的显示内容部分($after_title,$after_widget之间)添加ajax调用代码。

echo $after_title;
?>
<script type="text/javascript">
jQuery(document).ready(function($){
$("#wp_dict_submit").click(function(){
$.ajax({
type : "GET",
url : "index.php",
data : { mywidget_request : "wp_dict_request_handler",
query : $("#wp_dict_query").val() },
success : function(response) {
// The server has finished executing PHP and has returned something,
// so display it!
$("#wp_dict_result").html(response);
}
});
});
});
</script>
<?php

/* After widget (defined by themes). */
echo $after_widget;

基本就是jQuery调用ajax的典型用法。不过这里有几点针对wordpress的说明

  • url参数其实可以是任意有效的php路径。
  • mywidget_request配置的就是之前注册的方法名。
  • mywidget_request之后的都是自定义的参数,这里我需要一个query的单词名。

最后

按照普通Widget的要求,把widget添加之后,就可以在页面看到并使用了。相当方便。

遗留问题

WP Super Cache会把页面内容转化成静态HTML,所以Ajax会破坏这个机制。参考资料中另外一篇文章,不过还没有时间学习。

参考资料

AJAX-ifying WordPress Widgets
Make Any Plugin Work with WP Super Cache

 

WordPress 2.8+ Widget 插件开发

WordPress 2.8.0之后的版本对Widget提供了一套详细的API规范。貌似和水煮鱼团队的范例有很大区别。

加载Widget


<?php

/* Add our function to the widgets_init hook. */
add_action( 'widgets_init', 'example_load_widgets' );

/* Function that registers our widget. */
function example_load_widgets() {
register_widget( 'Example_Widget' );
}

Wordpress 2.8以上的版本中,widgets_init事件会在wordpress注册默认widgets之后被触发。Example_Widget是具体实现widget的类名。

配置你的Widget


function Example_Widget() {
/* Widget settings. */
$widget_ops = array( 'classname' => 'example', 'description' => 'An example widget that displays a person\'s name and sex.' );

/* Widget control settings. */
$control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'example-widget' );

/* Create the widget. */
$this->WP_Widget( 'example-widget', 'Example Widget', $widget_ops, $control_ops );
}

这里主要配置的Widget的一些基本信息,例如标识符,描述,以及大小等信息。

显示你的Widget


function widget( $args, $instance ) {
extract( $args );

/* User-selected settings. */
$title = apply_filters('widget_title', $instance['title'] );
$name = $instance['name'];
$sex = $instance['sex'];
$show_sex = isset( $instance['show_sex'] ) ? $instance['show_sex'] : false;

/* Before widget (defined by themes). */
echo $before_widget;

/* Title of widget (before and after defined by themes). */
if ( $title )
echo $before_title . $title . $after_title;

/* Display name from widget settings. */
if ( $name )
echo '<p>Hello. My name is' . $name . '.</p>';

/* Show sex. */
if ( $show_sex )
echo '<p>I am a ' . $sex . '.</p>';

/* After widget (defined by themes). */
echo $after_widget;
}

Wordpress 2.8以上的版本中,规定了function widget( $args, $instance )这个接口。这个接口专门用来实现widget的显示内容的。其中extract( $args );是标准用法,只需要添加就可以了。除此之外Wordpress还提供了四个标准变量用来区分显示的阶段:$before_widget, $after_widget, $before_title, and $after_title。最后$instance是用来获取Widget本身实例属性的。Widget实例属性的操作会在后面提到。

Widget配置页面

在Widgets页面中添加了某个Widget之后可以配置该Widget的实例属性。

function form( $instance ) {

/* Set up some default widget settings. */
$defaults = array( 'title' => 'Example', 'name' => 'John Doe', 'sex' => 'male', 'show_sex' => true );
$instance = wp_parse_args( (array) $instance, $defaults ); ?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>">Title:</label>
<input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'name' ); ?>">Your Name:</label>
<input id="<?php echo $this->get_field_id( 'name' ); ?>" name="<?php echo $this->get_field_name( 'name' ); ?>" value="<?php echo $instance['name']; ?>" style="width:100%;" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'sex' ); ?>">Sex:</label>
<select id="<?php echo $this->get_field_id( 'sex' ); ?>" name="<?php echo $this->get_field_name( 'sex' ); ?>" class="widefat" style="width:100%;">
<option <?php if ( 'male' == $instance['format'] ) echo 'selected="selected"'; ?>>male</option>
<option <?php if ( 'female' == $instance['format'] ) echo 'selected="selected"'; ?>>female</option>

</p>
<p>
<input class="checkbox" type="checkbox" <?php checked( $instance['show_sex'], true ); ?> id="<?php echo $this->get_field_id( 'show_sex' ); ?>" name="<?php echo $this->get_field_name( 'show_sex' ); ?>" />
<label for="<?php echo $this->get_field_id( 'show_sex' ); ?>">Display sex publicly?</label>
</p>
<?php
}
?>

Wordpress提供了标准接口function form( $instance ) 用来显示该配置页面的内容。方法中主要包含两个部分。

  • 第一部分配置了所有实例属性的默认值。
  • 第二个部分是配置页面的显示内容。

更新Widget实例属性


function update( $new_instance, $old_instance ) {
$instance = $old_instance;

/* Strip tags (if needed) and update the widget settings. */
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['name'] = strip_tags( $new_instance['name'] );
$instance['sex'] = $new_instance['sex'];
$instance['show_sex'] = $new_instance['show_sex'];

return $instance;
}

Wordpress提供了标准接口function update( $new_instance, $old_instance )用来处理实例属性的更新。更新的内容直接设置在$instance中就可以了。不需要直接操作数据库。

总结

这就是所有开发正常widget所需要了解的内容了。快动手吧。

参考资料

http://codex.wordpress.org/Widgets_API
The complete guide to creating widgets in WordPress 2.8

 

WP-Dict version 1.0.0 released

=== Plugin Name ===
Contributors: windlx
Donate link: http://blog.tech4k.com/
Tags: dict, translation, wp-dict
Requires at least: 2.8
Tested up to: 3.0.4
Stable tag: 1.0.0

Widget Plugin. A widget could help to translate between English and Chinese.Take advantage of the API from dict.cn.

== Description ==

Widget Plugin. A widget could help to translate between English and Chinese.Take advantage of the API from dict.cn. Implimented by Ajax.

== Installation ==

  1. Unzip wp-douban-post to the ‘/wp-content/plugins/’ directory
  2. Activate the plugin through the ‘Plugins’ menu in WordPress
  3. Add ‘WP Dict’ in through the ‘Widgets’ menu in WordPress
  4. Any problem, please contact windlx from my blog.
  1. 解压后将文件上传到’/wp-content/plugins/’目录
  2. 在插件中激活wp-dict
  3. 在Widget中添加WP-Dict
  4. 如有问题,请通过我的博客windlx联系我

== Frequently Asked Questions ==

= What do I need before the installation? =

You don’t need anything. Dict.cn API is open to everyone.

= Why I can’t see WP Dict Widget from my ‘Widgets’? =

There is a build issue before 2011/01/23. If you used to install it, please delete the plugin and reinstall it. Everything will be fine.

== Screenshots ==

1. WP-Dict

== Changelog ==

= 1.0.0 =
Get the Translation of the words by Ajax.

== Upgrade Notice ==

= 1.0.0 =
Basic Version.

 

无觅相关文章插件,快速提升流量