<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>dipplum.com &#187; 开源软件</title>
	<atom:link href="http://dipplum.com/category/computer/opensource/feed/" rel="self" type="application/rss+xml" />
	<link>http://dipplum.com</link>
	<description>Be  the change you wanna see in the world</description>
	<lastBuildDate>Sat, 12 Nov 2011 07:38:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>自动连接ssh -D的launchd配置</title>
		<link>http://dipplum.com/2010/09/12/launchd-plist-for-ssh-d/</link>
		<comments>http://dipplum.com/2010/09/12/launchd-plist-for-ssh-d/#comments</comments>
		<pubDate>Sat, 11 Sep 2010 18:05:41 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[autossh]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[upstart]]></category>

		<guid isPermaLink="false">http://dipplum.com/?p=889</guid>
		<description><![CDATA[背景 与Ubuntu的upstart类似，Mac OS上提供了launchd作为后台服务的管理程序。ssh -D命令可以为用户提供sock5代理，但是每次访问网络之前，都要打开Terminal手动运行ssh命令是一件很烦的事情。加上网络条件不好，ssh频繁退出，就更烦了。Linux下有autossh+upstart/init可以选择，Mac OS下就需要借助launchd了 配置Mac到远程ssh服务器的自动登录 为了将ssh -D变成launchd管理的后台服务，配置ssh自动登录是必须的。Mac下过程与Linux不太一样，首先打开Terminal，生成用户ssh证书： sudo su ssh-keygen cat /var/root/.ssh/id_rsa.pub 然后把公钥上传到ssh服务器。注意：Mac OS下root的HOME被设置在了/var/root下。 ssh EXAMPLE.COM mkdir .ssh scp id_rsa.pub EXAMPLE.com:.ssh/authorized_keys &#160; # 测试公钥认证是否成功 ssh -o BatchMode=yes EXAMPLE.COM 生成launchd格式的plist文件 将下述ssh-d.plist文件放在/Library/LaunchDaemon/目录下： &#60;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&#62; &#60;!DOCTYPE plist PUBLIC &#34;-//Apple Computer//DTD PLIST 1.0//EN&#34; &#34;http://www.apple.com/DTDs/PropertyList-1.0.dtd&#34;&#62; &#60;plist version=&#34;1.0&#34;&#62; &#60;dict&#62; &#60;key&#62;Label&#60;/key&#62; &#60;string&#62;localdomain.localhost.ssh-d&#60;/string&#62; &#60;key&#62;ProgramArguments&#60;/key&#62; &#60;array&#62; &#60;string&#62;/usr/bin/ssh&#60;/string&#62; &#60;string&#62;-o&#60;/string&#62; &#60;string&#62;BatchMode=yes&#60;/string&#62; &#60;string&#62;-o&#60;/string&#62; &#60;string&#62;CheckHostIP=no&#60;/string&#62; &#60;string&#62;-o&#60;/string&#62; [...]]]></description>
			<content:encoded><![CDATA[<h4>背景</h4>
<p>与Ubuntu的upstart类似，Mac OS上提供了launchd作为后台服务的管理程序。ssh -D命令可以为用户提供sock5代理，但是每次访问网络之前，都要打开Terminal手动运行ssh命令是一件很烦的事情。加上网络条件不好，ssh频繁退出，就更烦了。Linux下有autossh+upstart/init可以选择，Mac OS下就需要借助launchd了</p>
<h4>配置Mac到远程ssh服务器的自动登录</h4>
<p>为了将ssh -D变成launchd管理的后台服务，配置ssh自动登录是必须的。Mac下过程与Linux不太一样，首先打开Terminal，生成用户ssh证书：<span id="more-889"></span></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">su</span>
<span style="color: #c20cb9; font-weight: bold;">ssh-keygen</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>root<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa.pub</pre></div></div>

<p>然后把公钥上传到ssh服务器。注意：Mac OS下root的HOME被设置在了/var/root下。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ssh</span> EXAMPLE.COM <span style="color: #c20cb9; font-weight: bold;">mkdir</span> .ssh
<span style="color: #c20cb9; font-weight: bold;">scp</span> id_rsa.pub EXAMPLE.com:.ssh<span style="color: #000000; font-weight: bold;">/</span>authorized_keys
&nbsp;
<span style="color: #666666; font-style: italic;"># 测试公钥认证是否成功</span>
<span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #660033;">-o</span> <span style="color: #007800;">BatchMode</span>=<span style="color: #c20cb9; font-weight: bold;">yes</span> EXAMPLE.COM</pre></div></div>

<h4>生成launchd格式的plist文件</h4>
<p>将下述ssh-d.plist文件放在/Library/LaunchDaemon/目录下：</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #00bbdd;">&lt;!DOCTYPE plist PUBLIC &quot;-//Apple Computer//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plist</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Label<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>localdomain.localhost.ssh-d<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ProgramArguments<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/usr/bin/ssh<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>-o<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>BatchMode=yes<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>-o<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>CheckHostIP=no<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>-o<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>StrictHostKeyChecking=no<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>-D<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1080<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>-i<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/var/root/.ssh/id_rsa<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>-vvvNnT<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>root@EXAMPLE.com<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>KeepAlive<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;true</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>RunAtLoad<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;true</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>StandardOutPath<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/var/log/ssh-d-out.log<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>StandardErrorPath<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/var/log/ssh-d-err.log<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plist<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>然后运行下面的命令后台启动ssh -D：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">launchctl load <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>LaunchDaemon<span style="color: #000000; font-weight: bold;">/</span>ssh-d.plist</pre></div></div>

<p>如果出错需要调试，ssh进程的标准输出和标准错误输出保存在/var/log目录下的ssh-d-out.log和ssh-d-err.log文件中。如果一切正常，则配置完毕，以后Mac启动后，ssh -D进程会自动启动，ssh退出后，launchd也会自动生成一个新的进程。</p>
<h4>与autossh集成</h4>
<p>如果通过fink和MacPorts或者其他方法安装了autossh，可以修改上述脚本中的ssh程序的路径为autossh的路径。并将autossh的参数按格式加入plist文件，这样，也能享受到autossh提供的隧道假死后自动重启功能。</p>
<h4>延伸阅读</h4>
<ul>
<li><a href="http://aa.cs.uit.no/blog/20050528-email">POP and SMTP over ssh with launchd</a></li>
<li><a href="http://www.devdaily.com/mac-os-x/launchd-examples-launchd-plist-file-examples-mac">launchd plist example files</a></li>
<li><a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man5/launchd.plist.5.html">launchd.plist(5) Mac OS X Manual Page</a></li>
<li><a href="http://autoproxy2pac.appspot.com">autoproxy2pac</a> (与ssh -D配合使用)</li>
</ul</p>
]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2010/09/12/launchd-plist-for-ssh-d/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>autossh在Ubuntu上的配置</title>
		<link>http://dipplum.com/2010/09/11/autossh-ubuntu-upstart-script/</link>
		<comments>http://dipplum.com/2010/09/11/autossh-ubuntu-upstart-script/#comments</comments>
		<pubDate>Sat, 11 Sep 2010 15:05:11 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[upstart]]></category>

		<guid isPermaLink="false">http://dipplum.com/?p=886</guid>
		<description><![CDATA[背景 ssh除了可以提供远程登录服务之外，还可以建立主机之间的网络隧道，尤其是可以提供SOCKS代理（传说中的ssh -D）。但用ssh命令建立的隧道可能会受网络的影响而中断，不能为用户提供持续的服务。autossh正好是解决上述问题的工具：为用户提供可靠的ssh隧道服务。 在使用autossh之前，我的做法是：首先，做一个shell脚本检查相应的ssh进程是否存在，如不存在，则重新启动ssh隧道；然后，将上述脚本加入系统crontab，定时执行，例如1分钟1次。但是，用shell脚本检查有一个缺点：有时候，ssh进程虽然并没有退出，但ssh隧道已经不能正常转发报文了，shell脚本难以发现这类情况。为了避免ssh进程存在、隧道假死的问题，可以采用定时重启ssh进程并重新建立ssh隧道的方法。但重启间隔不好设置：间隔过短，导致ssh隧道用户频频掉线，影响用户使用；间隔过长，一旦隧道假死，在重启ssh服务之前会有较长的服务中断间隔。 autossh对ssh隧道的监控则更加有效。首先，在开始执行时，autossh首先创建ssh子进程，建立隧道。同时autossh作为父进程，随时监控ssh进程是否退出，一旦退出则立即启动新的ssh隧道。autossh这种做法比crontab定时检查在失效恢复速度上更具有优势。其次，autossh还会定期检查ssh隧道是否能够正确传输数据，如发现隧道假死，也会强制重启ssh，建立新的ssh隧道。 Ubuntu上的autossh autossh在Ubuntu上的安装很简单，运行下面的命令即可: apt-get install autossh 然而，Ubuntu下的autossh并没有包含相关的后台服务脚本。用户如果希望开机自动运行autossh需要自己写daemon脚本。Ubuntu下写daemon脚本有两个选择，一种是写传统的/etc/init.d下的脚本，令一种就是Ubuntu特有的upstart脚本。 upstart是Ubuntu设计用来替换传统的SysV init的软件。upstart的daemon脚本除了更加简洁之外，还支持服务的自动唤醒（respawn）。这样autossh本身如果出错退出了，也会立即被upstart唤醒。避免autossh出错退出导致ssh隧道无法访问。 我写的autossh的upstart脚本文件如下（文件名是/etc/init/autossh.conf）： # autossh &#160; description &#34;autossh daemon&#34; &#160; start on runlevel [2345] stop on runlevel [!2345] &#160; respawn respawn limit 5 60 # respawn max 5 times in 60 seconds &#160; script export AUTOSSH_PIDFILE=/var/run/autossh.pid export AUTOSSH_PORT=10007:7 export AUTOSSH_POLL=60 export AUTOSSH_FIRST_POLL=30 autossh -4 [...]]]></description>
			<content:encoded><![CDATA[<h4>背景</h4>
<p><a href="http://www.openssh.com/">ssh</a>除了可以提供远程登录服务之外，还可以建立主机之间的网络隧道，尤其是可以提供SOCKS代理（传说中的ssh -D）。但用ssh命令建立的隧道可能会受网络的影响而中断，不能为用户提供持续的服务。<a href="http://www.harding.motd.ca/autossh/">autossh</a>正好是解决上述问题的工具：为用户提供可靠的ssh隧道服务。</p>
<p>在使用autossh之前，我的做法是：首先，做一个shell脚本检查相应的ssh进程是否存在，如不存在，则重新启动ssh隧道；然后，将上述脚本加入系统crontab，定时执行，例如1分钟1次。但是，用shell脚本检查有一个缺点：有时候，ssh进程虽然并没有退出，但ssh隧道已经不能正常转发报文了，shell脚本难以发现这类情况。为了避免ssh进程存在、隧道假死的问题，可以采用定时重启ssh进程并重新建立ssh隧道的方法。但重启间隔不好设置：间隔过短，导致ssh隧道用户频频掉线，影响用户使用；间隔过长，一旦隧道假死，在重启ssh服务之前会有较长的服务中断间隔。</p>
<p>autossh对ssh隧道的监控则更加有效。首先，在开始执行时，autossh首先创建ssh子进程，建立隧道。同时autossh作为父进程，随时监控ssh进程是否退出，一旦退出则立即启动新的ssh隧道。autossh这种做法比crontab定时检查在失效恢复速度上更具有优势。其次，autossh还会定期检查ssh隧道是否能够正确传输数据，如发现隧道假死，也会强制重启ssh，建立新的ssh隧道。<span id="more-886"></span></p>
<h4>Ubuntu上的autossh</h4>
<p>autossh在Ubuntu上的安装很简单，运行下面的命令即可:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> autossh</pre></div></div>

<p>然而，Ubuntu下的autossh并没有包含相关的后台服务脚本。用户如果希望开机自动运行autossh需要自己写daemon脚本。Ubuntu下写daemon脚本有两个选择，一种是写传统的/etc/init.d下的脚本，令一种就是Ubuntu特有的upstart脚本。</p>
<p><a href="http://upstart.ubuntu.com/">upstart</a>是Ubuntu设计用来替换传统的<a href="http://en.wikipedia.org/wiki/Init">SysV init</a>的软件。upstart的daemon脚本除了更加简洁之外，还支持服务的自动唤醒（respawn）。这样autossh本身如果出错退出了，也会立即被upstart唤醒。避免autossh出错退出导致ssh隧道无法访问。</p>
<p>我写的autossh的upstart脚本文件如下（文件名是/etc/init/autossh.conf）：</p>

<div class="wp_syntax"><div class="code"><pre class="upstart" style="font-family:monospace;"># autossh
&nbsp;
description	&quot;autossh daemon&quot;
&nbsp;
start on runlevel [2345]
stop on runlevel [!2345]
&nbsp;
respawn
respawn limit 5 60 # respawn max 5 times in 60 seconds
&nbsp;
script
    export AUTOSSH_PIDFILE=/var/run/autossh.pid
    export AUTOSSH_PORT=10007:7
    export AUTOSSH_POLL=60
    export AUTOSSH_FIRST_POLL=30
    autossh -4 -N example.com -D 1080 -o BatchMode=yes -o StrictHostKeyChecking=no
end script</pre></div></div>

<p>这样重启之后，autossh就会自动启动。手动启动、停止、重启autossh服务可以通过运行start、stop、restart等命令完成。</p>
<h4>其他</h4>
<p>1. ssh自动登录</p>
<p>autossh在后台执行ssh命令建立隧道时，需要设置好配置好本机的ssh证书，以及服务器上的authorized_keys文件，以实现ssh的自动登录。否则autossh将无法登录远程主机并建立隧道。相关说明参见<a href="http://www.google.com.hk/search?q=ssh+authorized_keys">网络上的教程</a>。</p>
<p>2. echo服务</p>
<p>上述autossh脚本中的AUTOSSH_PORT参数，是autossh用于判断ssh隧道健康状况专用的隧道链接，参数意义是：建立本地端口10007到远程服务器端口7的隧道，其他参数说明初次启动ssh时，在30秒后判断隧道链接情况，之后每60秒检查一次。</p>
<p>其中，远程服务器端口7，运行的是标准的<a href="http://en.wikipedia.org/wiki/Echo_Protocol">TCP Echo服务</a>。在Ubuntu上echo服务可以通过openbsd-inetd来实现，首先在远程服务器（<strong>注意</strong>：不是autossh所在的ssh客户端机器）上安装软件：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> openbsd-inetd</pre></div></div>

<p>安装之后，inetd默认没有把echo服务激活，需要手动在/etc/inetd.conf配置文件中增加下面一行：</p>

<div class="wp_syntax"><div class="code"><pre class="inetd" style="font-family:monospace;">echo		stream	tcp	nowait	root	internal</pre></div></div>

<p>重启inetd后，远程服务器的echo服务就正式上线了，可以供autossh判断网络隧道连通情况了。</p>
]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2010/09/11/autossh-ubuntu-upstart-script/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>用fail2ban监控nginx日志</title>
		<link>http://dipplum.com/2010/09/09/fail2ban-nginx-log/</link>
		<comments>http://dipplum.com/2010/09/09/fail2ban-nginx-log/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 08:20:26 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[fail2ban]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://dipplum.com/2010/09/09/fail2ban-nginx-log/</guid>
		<description><![CDATA[背景 fail2ban是一款日志扫描软件, 尝试从日志中发现恶意的攻击行为, 尤其是用户名密码的失败尝试, 并可以通过iptables防火墙封禁恶意用户的IP, 以防止进一步的攻击. 最近在nginx服务器的日志中发现了很多可疑的请求, 看起来像是试图从Web服务器上发现漏洞页面: 221.204.246.105 - - [08/Sep/2010:06:45:13 +0000] &#34;GET /dbzhedit/ewebeditor.asp HTTP/1.1&#34; 404 5748 &#34;-&#34; &#34;Mozilla/4.0&#34; 221.204.246.105 - - [08/Sep/2010:06:45:14 +0000] &#34;GET /edit/ewebeditor.asp HTTP/1.1&#34; 404 5744 &#34;-&#34; &#34;Mozilla/4.0&#34; 221.204.246.105 - - [08/Sep/2010:06:45:15 +0000] &#34;GET /ugvbadmin/edit/ewebeditor.asp HTTP/1.1&#34; 404 5754 &#34;-&#34; &#34;Mozilla/4.0&#34; 222.189.228.42 - - [08/Sep/2010:18:10:50 +0000] &#34;GET /piqmUserReg.asp HTTP/1.1&#34; 404 5790 &#34;-&#34; [...]]]></description>
			<content:encoded><![CDATA[<h4>背景</h4>
<p><a href="http://www.fail2ban.org/">fail2ban</a>是一款日志扫描软件, 尝试从日志中发现恶意的攻击行为, 尤其是用户名密码的失败尝试, 并可以通过iptables防火墙封禁恶意用户的IP, 以防止进一步的攻击.</p>
<p>最近在nginx服务器的日志中发现了很多可疑的请求, 看起来像是试图从Web服务器上发现漏洞页面:</p>

<div class="wp_syntax"><div class="code"><pre class="syslog" style="font-family:monospace;">221.204.246.105 - - [08/Sep/2010:06:45:13 +0000] &quot;GET /dbzhedit/ewebeditor.asp HTTP/1.1&quot; 404 5748 &quot;-&quot; &quot;Mozilla/4.0&quot;
221.204.246.105 - - [08/Sep/2010:06:45:14 +0000] &quot;GET /edit/ewebeditor.asp HTTP/1.1&quot; 404 5744 &quot;-&quot; &quot;Mozilla/4.0&quot;
221.204.246.105 - - [08/Sep/2010:06:45:15 +0000] &quot;GET /ugvbadmin/edit/ewebeditor.asp HTTP/1.1&quot; 404 5754 &quot;-&quot; &quot;Mozilla/4.0&quot;
222.189.228.42 - - [08/Sep/2010:18:10:50 +0000] &quot;GET /piqmUserReg.asp HTTP/1.1&quot; 404 5790 &quot;-&quot; &quot;Mozilla/4.0&quot;
222.189.228.42 - - [08/Sep/2010:18:10:51 +0000] &quot;GET /UserReg.asp HTTP/1.1&quot; 404 5786 &quot;-&quot; &quot;Mozilla/4.0&quot;
222.189.228.42 - - [08/Sep/2010:18:10:52 +0000] &quot;GET /ioifupfile_flash.asp HTTP/1.1&quot; 404 5795 &quot;-&quot; &quot;Mozilla/4.0&quot;
222.189.228.42 - - [08/Sep/2010:18:10:53 +0000] &quot;GET /upfile_flash.asp HTTP/1.1&quot; 404 5791 &quot;-&quot; &quot;Mozilla/4.0&quot;
222.189.228.42 - - [08/Sep/2010:18:10:53 +0000] &quot;GET /admin/zhmuupfile_flash.asp HTTP/1.1&quot; 404 5801 &quot;-&quot; &quot;Mozilla/4.0&quot;
222.189.228.42 - - [08/Sep/2010:18:10:54 +0000] &quot;GET /admin/upfile_flash.asp HTTP/1.1&quot; 404 5797 &quot;-&quot; &quot;Mozilla/4.0&quot;
222.189.228.42 - - [08/Sep/2010:18:10:54 +0000] &quot;GET /admins/xvmbupfile_flash.asp HTTP/1.1&quot; 404 5802 &quot;-&quot; &quot;Mozilla/4.0&quot;</pre></div></div>

<h4>安装fail2ban</h4>
<p>我觉得可以用fail2ban扫描日志中上述攻击, 并且封禁恶意用户. 首先安装fail2ban, 在Ubuntu/Debian下用apt-get一次搞定:<span id="more-876"></span></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> fail2ban</pre></div></div>

<h4>配置fail2ban的nginx过滤规则</h4>
<p>从攻击行为特征来看, 这是短时间连续导致服务器发送HTTP 404文件未找到错误码, 下面是用于发现上述攻击的fail2ban filter规则, 在/etc/fail2ban/filter.d/目录下建立nginx.conf文件保存下面的内容:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>Definition<span style="">&#93;</span></span>
&nbsp;
<span style="color: #000099;">failregex</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> &amp;lt</span><span style="color: #666666; font-style: italic;">;HOST&amp;gt; -.*- .*HTTP/1.* 404 .*$</span>
<span style="color: #000099;">ignoreregex</span> <span style="color: #000066; font-weight:bold;">=</span></pre></div></div>

<h4>测试fail2ban过滤规则</h4>
<p>在正式激活改过滤规则之前, 可以首先用fail2ban-regex测试规则的有效性:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx.conf</span>
Running tests
=============
&nbsp;
Use regex <span style="color: #c20cb9; font-weight: bold;">file</span> : <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>fail2ban<span style="color: #000000; font-weight: bold;">/</span>filter.d<span style="color: #000000; font-weight: bold;">/</span>nginx.conf
Use log <span style="color: #c20cb9; font-weight: bold;">file</span>   : <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>nginx<span style="color: #000000; font-weight: bold;">/</span>access.log
&nbsp;
Results
=======
&nbsp;
Failregex
<span style="color: #000000; font-weight: bold;">|</span>- Regular expressions:
<span style="color: #000000; font-weight: bold;">|</span>  <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>lt;HOST<span style="color: #000000; font-weight: bold;">&amp;</span>gt; -.<span style="color: #000000; font-weight: bold;">*</span>-.<span style="color: #000000; font-weight: bold;">*</span>HTTP<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1</span>.<span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000;">404</span> .<span style="color: #000000; font-weight: bold;">*</span>$
<span style="color: #000000; font-weight: bold;">|</span>
<span style="color: #000000; font-weight: bold;">`</span>- Number of matches:
   <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000;">1304</span> match<span style="color: #7a0874; font-weight: bold;">&#40;</span>es<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
Ignoreregex
<span style="color: #000000; font-weight: bold;">|</span>- Regular expressions:
<span style="color: #000000; font-weight: bold;">|</span>
<span style="color: #000000; font-weight: bold;">`</span>- Number of matches:
&nbsp;
Summary
=======
&nbsp;
Addresses found:
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
    222.189.228.42 <span style="color: #7a0874; font-weight: bold;">&#40;</span>Wed Sep 08 <span style="color: #000000;">18</span>:<span style="color: #000000;">10</span>:<span style="color: #000000;">50</span> <span style="color: #000000;">2010</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
    222.189.228.42 <span style="color: #7a0874; font-weight: bold;">&#40;</span>Wed Sep 08 <span style="color: #000000;">18</span>:<span style="color: #000000;">10</span>:<span style="color: #000000;">51</span> <span style="color: #000000;">2010</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
    222.189.228.42 <span style="color: #7a0874; font-weight: bold;">&#40;</span>Wed Sep 08 <span style="color: #000000;">18</span>:<span style="color: #000000;">10</span>:<span style="color: #000000;">52</span> <span style="color: #000000;">2010</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
    222.189.228.42 <span style="color: #7a0874; font-weight: bold;">&#40;</span>Wed Sep 08 <span style="color: #000000;">18</span>:<span style="color: #000000;">10</span>:<span style="color: #000000;">52</span> <span style="color: #000000;">2010</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
    ...
&nbsp;
Date template hits:
...
XXXX hit<span style="color: #7a0874; font-weight: bold;">&#40;</span>s<span style="color: #7a0874; font-weight: bold;">&#41;</span>: Day<span style="color: #000000; font-weight: bold;">/</span>MONTH<span style="color: #000000; font-weight: bold;">/</span>Year:Hour:Minute:Second
...
&nbsp;
Success, the total number of match is YYYY
&nbsp;
However, look at the above section <span style="color: #ff0000;">'Running tests'</span> <span style="color: #c20cb9; font-weight: bold;">which</span> could contain important
information.</pre></div></div>

<h4>激活fail2ban过滤规则</h4>
<p>从测试结果可以看出, 恶意攻击节点的IP地址和攻击时间都能够正确发现, 因此可以进一步修改fail2ban的配置文件激活上述规则. 下面是我的/etc/fail2ban/jail.local配置文件内容:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>DEFAULT<span style="">&#93;</span></span>
<span style="color: #000099;">ignoreip</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 127.0.0.1</span>
<span style="color: #000099;">bantime</span>  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 3600</span>
<span style="color: #000099;">maxretry</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 6</span>
<span style="color: #000099;">destemail</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> root</span>
<span style="color: #000099;">action</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> %<span style="">&#40;</span>action_mwl<span style="">&#41;</span>s</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>nginx<span style="">&#93;</span></span>
<span style="color: #000099;">enabled</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> true</span>
<span style="color: #000099;">port</span>	<span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> http,https</span>
<span style="color: #000099;">filter</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> nginx</span>
<span style="color: #000099;">logpath</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;">  /var/log/nginx/access.log</span></pre></div></div>

<p>上述配置设置fail2ban用nginx过滤规则监控nginx的access.log文件, 如果发现恶意攻击, 除了在iptables防火墙中封禁该客户端IP之外, 还将发送邮件包含该IP地址的whois信息给root. 用下面的命令激活上述配置:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">fail2ban-client reload</pre></div></div>

<p>从/var/log/fail2ban.log日志文件中可以看到上述nginx规则激活的信息:</p>

<div class="wp_syntax"><div class="code"><pre class="syslog" style="font-family:monospace;">2010-09-09 08:00:54,810 fail2ban.server : INFO   Changed logging target to /var/log/fail2ban.log for Fail2ban v0.8.4
2010-09-09 08:00:54,810 fail2ban.jail   : INFO   Creating new jail 'nginx'
2010-09-09 08:00:54,811 fail2ban.jail   : INFO   Jail 'nginx' uses poller
2010-09-09 08:00:54,812 fail2ban.filter : INFO   Added logfile = /var/log/nginx/access.log
2010-09-09 08:00:54,813 fail2ban.filter : INFO   Set maxRetry = 50
2010-09-09 08:00:54,815 fail2ban.filter : INFO   Set findtime = 600
2010-09-09 08:00:54,815 fail2ban.actions: INFO   Set banTime = 3600
...
2010-09-09 08:00:54,970 fail2ban.jail   : INFO   Jail 'nginx' started</pre></div></div>

<h4>测试fail2ban的效果</h4>
<p>可以用下面的命令模拟攻击者连续访问不存在的URL, 看看fail2ban的效果:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">while</span> <span style="color: #c20cb9; font-weight: bold;">true</span> ; <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #c20cb9; font-weight: bold;">wget</span> http:<span style="color: #000000; font-weight: bold;">//</span>127.0.0.10<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">404</span> ; <span style="color: #000000; font-weight: bold;">done</span>
<span style="color: #666666; font-style: italic;"># type Ctrl-C when you stuck at &quot;Connecting to 127.0.0.10:80... &quot;</span></pre></div></div>

<p>看fail2ban的日志是否记录了上述攻击:</p>

<div class="wp_syntax"><div class="code"><pre class="syslog" style="font-family:monospace;">#   grep Ban /var/log/fail2ban.log
2010-09-09 08:06:09,338 fail2ban.actions: WARNING [nginx-fnf] Ban 127.0.0.10</pre></div></div>

<p>用iptables命令看fail2ban添加的IP封禁规则:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># iptables -L</span>
Chain INPUT <span style="color: #7a0874; font-weight: bold;">&#40;</span>policy ACCEPT<span style="color: #7a0874; font-weight: bold;">&#41;</span>
target     prot opt <span style="color: #7a0874; font-weight: bold;">source</span>               destination
fail2ban-nginx  tcp  <span style="color: #660033;">--</span>  anywhere             anywhere            multiport dports www,https
&nbsp;
Chain FORWARD <span style="color: #7a0874; font-weight: bold;">&#40;</span>policy ACCEPT<span style="color: #7a0874; font-weight: bold;">&#41;</span>
target     prot opt <span style="color: #7a0874; font-weight: bold;">source</span>               destination
&nbsp;
Chain OUTPUT <span style="color: #7a0874; font-weight: bold;">&#40;</span>policy ACCEPT<span style="color: #7a0874; font-weight: bold;">&#41;</span>
target     prot opt <span style="color: #7a0874; font-weight: bold;">source</span>               destination
&nbsp;
Chain fail2ban-nginx <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span> references<span style="color: #7a0874; font-weight: bold;">&#41;</span>
target     prot opt <span style="color: #7a0874; font-weight: bold;">source</span>               destination
DROP       all  <span style="color: #660033;">--</span>  127.0.0.10           anywhere
RETURN     all  <span style="color: #660033;">--</span>  anywhere             anywhere</pre></div></div>

<p>fail2ban发来的邮件看起来像是这样的:</p>

<div class="wp_syntax"><div class="code"><pre class="email" style="font-family:monospace;">Hi,
&nbsp;
The IP 222.169.224.226 has just been banned by Fail2Ban after
7 attempts against ssh.
&nbsp;
Here are more information about 222.169.224.226:
&nbsp;
% [whois.apnic.net node-3]
% Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html
&nbsp;
inetnum:        222.168.0.0 - 222.169.255.255
netname:        CHINANET-JL
descr:          CHINANET Jilin province network
descr:          Jilin Telecom Corporation
...
&nbsp;
Lines containing IP:222.169.224.226 in /var/log/auth.log
&nbsp;
Sep  9 02:30:14 localhost sshd[24401]: Did not receive identification string from 222.169.224.226
Sep  9 02:34:59 localhost sshd[24511]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.169.224.226  user=root
Sep  9 02:35:01 localhost sshd[24511]: Failed password for root from 222.169.224.226 port 36724 ssh2
Sep  9 02:35:03 localhost sshd[24515]: Invalid user fluffy from 222.169.224.226
Sep  9 02:35:03 localhost sshd[24515]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.169.224.226
Sep  9 02:35:05 localhost sshd[24515]: Failed password for invalid user fluffy from 222.169.224.226 port 36927 ssh2
Sep  9 02:35:06 localhost sshd[24519]: Invalid user admin from 222.169.224.226
Sep  9 02:35:06 localhost sshd[24519]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.169.224.226
Sep  9 02:35:09 localhost sshd[24519]: Failed password for invalid user admin from 222.169.224.226 port 37140 ssh2
Sep  9 02:35:10 localhost sshd[24521]: Invalid user test from 222.169.224.226
Sep  9 02:35:10 localhost sshd[24521]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.169.224.226
Sep  9 02:35:12 localhost sshd[24521]: Failed password for invalid user test from 222.169.224.226 port 37391 ssh2</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2010/09/09/fail2ban-nginx-log/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>删除Mac OS X上的MySQL</title>
		<link>http://dipplum.com/2010/09/07/uninstall-mysql-macosx/</link>
		<comments>http://dipplum.com/2010/09/07/uninstall-mysql-macosx/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 06:58:07 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://dipplum.com/2010/09/07/uninstall-mysql-macosx/</guid>
		<description><![CDATA[MySQL提供的Mac OS X上的安装包不能卸载，需要手动删除。到网上搜到前辈总结的过程，稍微改了改，应该可以直接运行。 #!/bin/sh &#160; sudo killall /usr/local/mysql/bin/mysqld &#91; -e /usr/local/mysql &#93; &#38;&#38; sudo rm /usr/local/mysql sudo rm -rf /usr/local/mysql* sudo rm -rf /Library/StartupItems/MySQLCOM sudo rm -rf /Library/PreferencePanes/My* sudo rm -rf /Library/Receipts/mysql* sudo rm -rf /Library/Receipts/MySQL* sudo sed -i -e '/MYSQLCOM=-YES-/ d' /etc/hostconfig echo done !]]></description>
			<content:encoded><![CDATA[<p>MySQL提供的Mac OS X上的安装包不能卸载，需要手动删除。到网上搜到<a href="http://steveno.wordpress.com/2009/03/26/uninstall-mysql-on-mac-os-x/">前辈总结的过程</a>，稍微改了改，应该可以直接运行。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">killall</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>mysql<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysqld
<span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-e</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>mysql <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>mysql
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>mysql<span style="color: #000000; font-weight: bold;">*</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>StartupItems<span style="color: #000000; font-weight: bold;">/</span>MySQLCOM
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>PreferencePanes<span style="color: #000000; font-weight: bold;">/</span>My<span style="color: #000000; font-weight: bold;">*</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Receipts<span style="color: #000000; font-weight: bold;">/</span>mysql<span style="color: #000000; font-weight: bold;">*</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Receipts<span style="color: #000000; font-weight: bold;">/</span>MySQL<span style="color: #000000; font-weight: bold;">*</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-i</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'/MYSQLCOM=-YES-/ d'</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>hostconfig
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #000000; font-weight: bold;">done</span> <span style="color: #000000; font-weight: bold;">!</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2010/09/07/uninstall-mysql-macosx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在Ubuntu上安装L2TP/IPsec VPN服务器</title>
		<link>http://dipplum.com/2010/08/30/ubuntu-install-l2tp-server/</link>
		<comments>http://dipplum.com/2010/08/30/ubuntu-install-l2tp-server/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 12:52:37 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[ipsec]]></category>
		<category><![CDATA[l2tp]]></category>
		<category><![CDATA[openswan]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://dipplum.com/2010/08/30/ubuntu-install-l2tp-server/</guid>
		<description><![CDATA[最近用VPN翻墙比较流行, 我也赶了一下潮流: 买了一个Linode的VPS, 安装了最新的Ubuntu Lucid (10.04), 并在上面配置了L2TP服务器. 以下虽然是在10.04上的配置过程, 但应该对其他版本的Ubuntu同样适用. 2010-09-01: Ubuntu ppa没有karmic上的openswan包, 只能自己编译了, 或是下载我预编译的版本, 参照后面说明. 1. 安装OpenSWAN L2TP(Layer 2 Tunneling Protocol)顾名思义, 是2层隧道协议. 这个协议的认证方式不是非常安全, 因此实际使用中, 往往将L2TP和IPsec结合, 客户端和服务器之间, 首先通过IPsec生成安全信道, 之后再进行L2TP协议的交互. 因此, 安装L2TP服务器, 首先需要安装IPsec软件. 目前在Linux下, 有FreeSWAN, OpenSWAN, StrongSWAN三款IPsec协议的实现. 这里我用的是OpenSWAN. 目前Ubuntu Lucid中官方自带的OpenSWAN版本是2.6.23. 可惜的是, 这个版本的OpenSWAN有bug, 无法和L2TP服务器配合使用, 必须至少升级到2.6.24以后. 因此需要安装Ubuntu提供的非官方OpenSWAN升级版. Ubuntu Karmic 9.10 安装过程 ppa中没有Ubuntu Karmic的openswan, 安装过程有不一样. 首先下载我预编译的openswan的deb包, 然后安装: sudo dpkg -i [...]]]></description>
			<content:encoded><![CDATA[<p>最近用VPN翻墙比较流行, 我也赶了一下潮流: 买了一个<a href="http://www.linode.com/?r=44cf208b8ccc0279cecdc4b9f4cdbfdc6f497a9f">Linode的VPS</a>, 安装了最新的Ubuntu Lucid (10.04), 并在上面配置了L2TP服务器.</p>
<p>以下虽然是在10.04上的配置过程, 但应该对其他版本的Ubuntu同样适用.</p>
<p><strong>2010-09-01</strong>: Ubuntu ppa没有karmic上的openswan包, 只能自己编译了, 或是下载我预编译的版本, 参照后面说明.</p>
<h4>1. 安装OpenSWAN</h4>
<p>L2TP(<a href="http://en.wikipedia.org/wiki/Layer_2_Tunneling_Protocol">Layer 2 Tunneling Protocol</a>)顾名思义, 是2层隧道协议. 这个协议的认证方式不是非常安全, 因此实际使用中, 往往将L2TP和IPsec结合, 客户端和服务器之间, 首先通过IPsec生成安全信道, 之后再进行L2TP协议的交互.</p>
<p>因此, 安装L2TP服务器, 首先需要安装IPsec软件. 目前在Linux下, 有FreeSWAN, OpenSWAN, StrongSWAN三款IPsec协议的实现. 这里我用的是<a href="http://www.openswan.org/">OpenSWAN</a>.</p>
<p>目前Ubuntu Lucid中官方自带的OpenSWAN版本是<a href="http://packages.ubuntu.com/lucid/openswan">2.6.23</a>. 可惜的是, 这个版本的OpenSWAN有bug, 无法和L2TP服务器配合使用, 必须<a href="http://lists.openswan.org/pipermail/announce/2010-January/000036.html">至少升级到2.6.24以后</a>. 因此需要安装Ubuntu提供的非官方OpenSWAN升级版.   <span id="more-841"></span>  </p>
<h5>Ubuntu Karmic 9.10 安装过程</h5>
<p>ppa中没有Ubuntu Karmic的openswan, 安装过程有不一样. 首先下载我预编译的openswan的deb包, 然后安装: Note: There is a file embedded within this post, please visit this post to download the file.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">dpkg</span> <span style="color: #660033;">-i</span> openswan<span style="color: #000000; font-weight: bold;">*</span>i386.deb
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">-f</span></pre></div></div>

<p>安装完成后请直接跳过到步骤2: 配置OpenSWAN.</p>
<h5>1.1. 首先添加非官方的OpenSWAN apt源:</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> python-software-properties
<span style="color: #c20cb9; font-weight: bold;">sudo</span> add-apt-repository ppa:openswan<span style="color: #000000; font-weight: bold;">/</span>ppa
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> update</pre></div></div>

<h5>1.2. 然后检查OpenSWAN的版本, 至少应该是2.6.24</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># apt-cache policy openswan</span>
openswan:
  Installed: <span style="color: #7a0874; font-weight: bold;">&#40;</span>none<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  Candidate: <span style="color: #000000;">1</span>:2.6.28-1xelerance3
  Version table:
     <span style="color: #000000;">1</span>:2.6.28-1xelerance3 <span style="color: #000000;">0</span>
        <span style="color: #000000;">500</span> http:<span style="color: #000000; font-weight: bold;">//</span>ppa.launchpad.net<span style="color: #000000; font-weight: bold;">/</span>openswan<span style="color: #000000; font-weight: bold;">/</span>ppa<span style="color: #000000; font-weight: bold;">/</span>ubuntu<span style="color: #000000; font-weight: bold;">/</span> lucid<span style="color: #000000; font-weight: bold;">/</span>main Packages</pre></div></div>

<h5>1.3. 安装</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> openswan</pre></div></div>

<p>安装过程中如问到: Use an X.509 certificate for this host, 回答NO.</p>
<h4>2. 配置OpenSWAN</h4>
<h5>2.0. 设置命令行变量</h5>
<p>在后面的配置过程中, 有一些配置参数可能需要修改. 本文假设L2TP服务器的IP地址是192.168.1.1, VPN网络前缀是10.1.1.0/24, 用户名为user, 密码为1234. 在完成下面的配置之前, 应该首先把这些参数修改成正确的参数. 后面的命令将使用bash的变量替换规则吧配置文件中出现的参数名替换出下面设置的值:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">SERVER</span>=192.168.1.1
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">NET</span>=10.1.1
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">USER1</span>=user
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">PASS1</span>=<span style="color: #000000;">1234</span></pre></div></div>

<h5>2.1. 配置sysctl参数</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>sysctl.conf <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>sysctl.conf.bak
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;cat &gt; /etc/sysctl.conf &lt;&lt;EOF
net.ipv4.ip_forward=1
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
EOF
&quot;</span></pre></div></div>

<p>上述参数重启后生效, 如果想不重启即时生效, 需要继续完成步骤2:</p>
<h5>2.2. 加载sysctl参数</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> sysctl <span style="color: #660033;">-p</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">'for each in /proc/sys/net/ipv4/conf/*
do
    echo 0 &gt; $each/accept_redirects
    echo 0 &gt; $each/send_redirects
done
'</span></pre></div></div>

<h5>2.3. 生成iptables配置</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.local <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.local.bak
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;cat &gt; /etc/rc.local &lt;&lt;EOF
#!/bin/sh -e
iptables -t nat -A POSTROUTING -s <span style="color: #007800;">$NET</span>.0/24 -o eth0 -j MASQUERADE
exit 0
EOF
&quot;</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span> +x <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.local</pre></div></div>

<p>类似的, 上述参数重启后生效. 如果想不重启即时生效, 需要继续完成步骤4:</p>
<p><strong>注意:</strong> /etc/rc.local文件中引用了$NET参数的值, 检查一下文件输出是否符合预期.</p>
<h5>2.4. 加载iptables配置</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.local</pre></div></div>

<h5>2.5. 配置ipsec.secrets</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ipsec.secrets <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ipsec.secrets.bak
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;cat &gt; /etc/ipsec.secrets &lt;&lt;EOF
<span style="color: #007800;">$SERVER</span> %any: PSK <span style="color: #000099; font-weight: bold;">\&quot;</span><span style="color: #007800;">$PASS1</span><span style="color: #000099; font-weight: bold;">\&quot;</span>
EOF
&quot;</span></pre></div></div>

<p><strong>注意:</strong> /etc/ipsec.secrets文件中引用了$SERVER, $PASS1参数的值, 检查一下文件输出是否符合预期.</p>
<h5>2.6. 配置ipsec.conf</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ipsec.conf <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ipsec.conf.bak
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;cat &gt; /etc/ipsec.conf &lt;&lt;EOF
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
&nbsp;
conn L2TP-PSK-NAT
    rightsubnet=vhost:%priv
    also=L2TP-PSK-noNAT
&nbsp;
conn L2TP-PSK-noNAT
    authby=secret
    pfs=no
    auto=add
    keyingtries=3
    rekey=no
    ikelifetime=8h
    keylife=1h
    type=transport
    left=<span style="color: #007800;">$SERVER</span>
    leftprotoport=17/1701
    right=%any
    rightprotoport=17/%any
EOF
&quot;</span></pre></div></div>

<p><strong>注意:</strong> /etc/ipsec.conf文件中引用了$SERVER参数的值, 检查一下文件输出是否符合预期.</p>
<h5>2.7. 激活ipsec服务</h5>
<p>运行下面的命令, 让ipsec服务可以开机自动启动: </p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> update-rc.d ipsec defaults</pre></div></div>

<h4>3. 安装xl2tpd</h4>
<p>L2TP服务器软件, 选择与OpenSWAN同样是xelerance公司支持的xl2tpd软件. 该软件可以直接用Ubuntu自带的版本, 安装过程相对简单:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> xl2tpd</pre></div></div>

<h4>4. 配置xl2tpd</h4>
<h5>4.0. 设置命令行变量</h5>
<p>配置xl2tpd的过程中同样需要替换配置文件中的部分参数, 参数和OpenSWAN命令行变量一样.</p>
<h5>4.1. 配置xl2tpd.conf</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>xl2tpd<span style="color: #000000; font-weight: bold;">/</span>xl2tpd.conf <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>xl2tpd<span style="color: #000000; font-weight: bold;">/</span>xl2tpd.conf.bak
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;cat &gt; /etc/xl2tpd/xl2tpd.conf &lt;&lt;EOF
[global]
ipsec saref = yes
&nbsp;
[lns default]
ip range = <span style="color: #007800;">$NET</span>.2-<span style="color: #007800;">$NET</span>.255
local ip = <span style="color: #007800;">$NET</span>.1
refuse chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
EOF
&quot;</span></pre></div></div>

<p><strong>注意:</strong> /etc/xl2tpd/xl2tpd.conf文件中引用了$NET参数的值, 检查一下文件输出是否符合预期.</p>
<h5>4.2. 配置options.xl2tpd</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ppp<span style="color: #000000; font-weight: bold;">/</span>options.xl2tpd <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ppp<span style="color: #000000; font-weight: bold;">/</span>options.xl2tpd.bak
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;cat &gt; /etc/ppp/options.xl2tpd &lt;&lt;EOF
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
EOF
&quot;</span></pre></div></div>

<h5>4.3. 配置chap-secrets</h5>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ppp<span style="color: #000000; font-weight: bold;">/</span>chap-secrets <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ppp<span style="color: #000000; font-weight: bold;">/</span>chap-secrets.bak
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;cat &gt; /etc/ppp/chap-secrets &lt;&lt;EOF
# user      server      password    ip
<span style="color: #007800;">$USER1</span>       l2tpd       <span style="color: #007800;">$PASS1</span>       *
EOF
&quot;</span></pre></div></div>

<p><strong>注意:</strong> /etc/ppp/chap-secrets文件中引用了$USER1, $PASS1参数的值, 检查一下文件输出是否符合预期.</p>
<h4>5. 启动L2TP服务器</h4>
<p>至此, L2TP/IPsec服务器配置完成. 重启之后, 就可以使用了. 如果不希望重启, 可以运行下面的命令, 手动启动服务:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> invoke-rc.d xl2tpd restart
<span style="color: #c20cb9; font-weight: bold;">sudo</span> invoke-rc.d ipsec restart</pre></div></div>

<p>运行ipsec verify命令, 验证IPsec服务器的运行状态. 典型的检查结果如下: </p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># sudo ipsec verify</span>
Checking your system to see <span style="color: #000000; font-weight: bold;">if</span> IPsec got installed and started correctly:
Version check and ipsec on-path                             	<span style="color: #7a0874; font-weight: bold;">&#91;</span>OK<span style="color: #7a0874; font-weight: bold;">&#93;</span>
Linux Openswan U2.6.28<span style="color: #000000; font-weight: bold;">/</span>K2.6.32.16-linode28 <span style="color: #7a0874; font-weight: bold;">&#40;</span>netkey<span style="color: #7a0874; font-weight: bold;">&#41;</span>
Checking <span style="color: #000000; font-weight: bold;">for</span> IPsec support <span style="color: #000000; font-weight: bold;">in</span> kernel                        	<span style="color: #7a0874; font-weight: bold;">&#91;</span>OK<span style="color: #7a0874; font-weight: bold;">&#93;</span>
NETKEY detected, testing <span style="color: #000000; font-weight: bold;">for</span> disabled ICMP send_redirects   	<span style="color: #7a0874; font-weight: bold;">&#91;</span>OK<span style="color: #7a0874; font-weight: bold;">&#93;</span>
NETKEY detected, testing <span style="color: #000000; font-weight: bold;">for</span> disabled ICMP accept_redirects 	<span style="color: #7a0874; font-weight: bold;">&#91;</span>OK<span style="color: #7a0874; font-weight: bold;">&#93;</span>
Checking that pluto is running                              	<span style="color: #7a0874; font-weight: bold;">&#91;</span>OK<span style="color: #7a0874; font-weight: bold;">&#93;</span>
Pluto listening <span style="color: #000000; font-weight: bold;">for</span> IKE on udp <span style="color: #000000;">500</span>                          	<span style="color: #7a0874; font-weight: bold;">&#91;</span>OK<span style="color: #7a0874; font-weight: bold;">&#93;</span>
Pluto listening <span style="color: #000000; font-weight: bold;">for</span> NAT-T on udp <span style="color: #000000;">4500</span>                       	<span style="color: #7a0874; font-weight: bold;">&#91;</span>OK<span style="color: #7a0874; font-weight: bold;">&#93;</span>
Two or <span style="color: #c20cb9; font-weight: bold;">more</span> interfaces found, checking IP forwarding        	<span style="color: #7a0874; font-weight: bold;">&#91;</span>OK<span style="color: #7a0874; font-weight: bold;">&#93;</span>
Checking NAT and MASQUERADEing                              
Checking <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #ff0000;">'ip'</span> <span style="color: #7a0874; font-weight: bold;">command</span>                                   	<span style="color: #7a0874; font-weight: bold;">&#91;</span>OK<span style="color: #7a0874; font-weight: bold;">&#93;</span>
Checking <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #ff0000;">'iptables'</span> <span style="color: #7a0874; font-weight: bold;">command</span>                             	<span style="color: #7a0874; font-weight: bold;">&#91;</span>OK<span style="color: #7a0874; font-weight: bold;">&#93;</span>
Opportunistic Encryption Support                            	<span style="color: #7a0874; font-weight: bold;">&#91;</span>DISABLED<span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<h4>6. 测试L2TP服务器</h4>
<p>完成前面的步骤之后, 就可以用iPhone添加L2TP VPN连接, 测试L2TP服务器的有效性了. 按照本文的配置参数, 服务器的IP地址是192.168.1.1, 用户名是user, L2TP的密码和IPsec的预共享密钥都是1234.</p>
]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2010/08/30/ubuntu-install-l2tp-server/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Seccomp和系统调用过滤</title>
		<link>http://dipplum.com/2009/12/08/seccomp-syscall-filter/</link>
		<comments>http://dipplum.com/2009/12/08/seccomp-syscall-filter/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 02:13:43 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[sandbox]]></category>
		<category><![CDATA[seccomp]]></category>

		<guid isPermaLink="false">http://dipplum.com/2009/12/08/seccomp-syscall-filter/</guid>
		<description><![CDATA[Seccomp v1 Seccomp是2005年Andrea Arcangeli在Linux内核加的一个功能，为了给*Grid计算中的应用*提供sandbox模型。运行在Seccomp模式下的进程，只能执行下面几个系统调用： &#160;&#160;&#160; read(), write(), exit(), sigreturn() 通过Seccomp沙箱，和4个api的限制，保证进程不会影响到其他进程。 Seccomp v2 2009年的时候，Ingo Molnar扩展了Seccomp的实现，让其支持更加全面的系统调用过滤(syscall filtering)的功能。Google Chrome Browser好像用的沙箱模型就是类似Seccomp的系统调用过滤。 Filter的规则是一个数组，每个元素包括两个字段，分别是系统调用名和过滤规则： &#123; &#123; &#34;sys_read&#34;, &#34;fd == 0&#34; &#125;, &#123; &#34;sys_write&#34;, &#34;fd == 1&#34; &#125;, &#123; &#34;sys_sigreturn&#34;, &#34;1&#34; &#125;, &#123; &#34;sys_gettimeofday&#34;, &#34;tz == NULL&#34; &#125; 上面的第一条规则要求进程只能以fd = 0这个参数，调用sys_read。&#160; 参考资料 [1] Seccomp Wiki http://en.wikipedia.org/wiki/Seccomp [2] Seccomp and sandboxing http://lwn.net/Articles/332974/ [3] [...]]]></description>
			<content:encoded><![CDATA[<h4>Seccomp v1</h4>
<p>Seccomp是2005年Andrea Arcangeli在Linux内核加的一个功能，为了给*Grid计算中的应用*提供sandbox模型。运行在Seccomp模式下的进程，只能执行下面几个系统调用：    <br />&#160;&#160;&#160; read(), write(), exit(), sigreturn() </p>
<p>  <span id="more-461"></span>
<p>通过Seccomp沙箱，和4个api的限制，保证进程不会影响到其他进程。</p>
<h4>Seccomp v2</h4>
<p>2009年的时候，Ingo Molnar扩展了Seccomp的实现，让其支持更加全面的系统调用过滤(syscall filtering)的功能。Google Chrome Browser好像用的沙箱模型就是类似Seccomp的系统调用过滤。</p>
<p>Filter的规则是一个数组，每个元素包括两个字段，分别是系统调用名和过滤规则： </p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;sys_read&quot;</span><span style="color: #339933;">,</span>            <span style="color: #ff0000;">&quot;fd == 0&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;sys_write&quot;</span><span style="color: #339933;">,</span>        <span style="color: #ff0000;">&quot;fd == 1&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;sys_sigreturn&quot;</span><span style="color: #339933;">,</span>        <span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;sys_gettimeofday&quot;</span><span style="color: #339933;">,</span>        <span style="color: #ff0000;">&quot;tz == NULL&quot;</span> <span style="color: #009900;">&#125;</span></pre></div></div>

<p>上面的第一条规则要求进程只能以fd = 0这个参数，调用sys_read。&#160; </p>
<h4>参考资料</h4>
<p>[1] Seccomp Wiki <a href="http://en.wikipedia.org/wiki/Seccomp">http://en.wikipedia.org/wiki/Seccomp</a> </p>
<p>[2] Seccomp and sandboxing <a href="http://lwn.net/Articles/332974/">http://lwn.net/Articles/332974/</a> </p>
<p>[3] seccomp: Add bitmask of allowed system calls <a href="http://lwn.net/Articles/332987/">http://lwn.net/Articles/332987/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2009/12/08/seccomp-syscall-filter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>stratagus最新Windows版</title>
		<link>http://dipplum.com/2009/11/13/stratagus-svn-windows/</link>
		<comments>http://dipplum.com/2009/11/13/stratagus-svn-windows/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 09:12:23 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[stratagus]]></category>
		<category><![CDATA[visualc]]></category>
		<category><![CDATA[warcraft]]></category>
		<category><![CDATA[wargus]]></category>

		<guid isPermaLink="false">http://dipplum.com/2009/11/13/stratagus-svn-windows/</guid>
		<description><![CDATA[简介 stratagus的前身是freecraft。freecraft重写了Blizzard公司的经典游戏Warcraft II的RTS游戏引擎。后因版权问题改名。freecraft改名后分成了几个部分，stratagus项目承接了其游戏引擎的部分，wargus在stratagus引擎上进行二次开发，几乎完美重现了Warcaft II的功能。下面是Wargus/Stratagus的效果： 下载说明 Statagus已经在2年前停止开发了，开发人员用同样的引擎转去开发别的游戏了。最后一个版本是2.2.4。但SVN库里还陆续有大的变动，开发人员好像是会不时的merge一些新的功能过来。 我编译的是最新的Stratagus SVN版本r8003，截图上显示的是2.2.5，这个版本有bug，打上了好几处补丁。编译环境是Visual C++ 2008。 1. stratagus-r8003引擎本地下载，需要再下载2 2. 支持stratagus-r8003的Wargus游戏数据 网盘下载 3. 用VMWare ThinApp打包的单可执行程序，单独可运行 网盘下载 开发包下载 如果对源码感兴趣，想自己编译的，可以下载我的Patch和编译环境打包 1. r8003的patch文件，自己checkout的stratagus svn r8003目录，解压后覆盖之 2. stratagus引用的外部lib和头文件打包，用Visual C++ 2008编译，解压后放在stratagus源码上级目录]]></description>
			<content:encoded><![CDATA[<h4>简介</h4>
<p><a href="http://stratagus.sourceforge.net/" target="_blank">stratagus</a>的前身是freecraft。freecraft重写了Blizzard公司的经典游戏<a href="http://us.blizzard.com/en-us/games/legacy/" target="_blank">Warcraft II</a>的RTS游戏引擎。后因<a href="http://en.wikipedia.org/wiki/Stratagus" target="_blank">版权问题改名</a>。freecraft改名后分成了几个部分，stratagus项目承接了其游戏引擎的部分，wargus在stratagus引擎上进行二次开发，几乎完美重现了Warcaft II的功能。下面是Wargus/Stratagus的效果：</p>
<p><a href="http://dipplum.com/files/2009/11/stratagus1.png" rel="shadowbox[sbpost-441];player=img;"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="stratagus1" border="0" alt="stratagus1" src="http://dipplum.com/files/2009/11/stratagus1_thumb.png" width="244" height="184" /></a> <a href="http://dipplum.com/files/2009/11/stratagus2.png" rel="shadowbox[sbpost-441];player=img;"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="stratagus2" border="0" alt="stratagus2" src="http://dipplum.com/files/2009/11/stratagus2_thumb.png" width="244" height="184" /></a> <a href="http://dipplum.com/files/2009/11/stratagus3.png" rel="shadowbox[sbpost-441];player=img;"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="stratagus3" border="0" alt="stratagus3" src="http://dipplum.com/files/2009/11/stratagus3_thumb.png" width="244" height="184" /></a> <a href="http://dipplum.com/files/2009/11/stratagus4.png" rel="shadowbox[sbpost-441];player=img;"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="stratagus4" border="0" alt="stratagus4" src="http://dipplum.com/files/2009/11/stratagus4_thumb.png" width="244" height="184" /></a> </p>
</p>
</p>
<h4>下载说明</h4>
<p> <span id="more-441"></span>
<p>Statagus已经在2年前停止开发了，开发人员用同样的引擎转去开发别的游戏了。最后一个版本是2.2.4。但SVN库里还陆续有大的变动，开发人员好像是会不时的merge一些新的功能过来。</p>
<p>我编译的是最新的Stratagus SVN版本r8003，截图上显示的是2.2.5，这个版本有bug，打上了好几处补丁。编译环境是Visual C++ 2008。</p>
<p>1. stratagus-r8003引擎本地下载，需要再下载2 Note: There is a file embedded within this post, please visit this post to download the file.</p>
<p>2. 支持stratagus-r8003的Wargus游戏数据 <a href="http://is.gd/4U3om">网盘下载</a></p>
<p>3. 用VMWare ThinApp打包的单可执行程序，单独可运行 <a href="http://is.gd/4RO0k" target="_blank">网盘下载</a></p>
<h4>开发包下载</h4>
<p>如果对源码感兴趣，想自己编译的，可以下载我的Patch和编译环境打包</p>
<p>1. r8003的patch文件，自己checkout的stratagus svn r8003目录，解压后覆盖之 Note: There is a file embedded within this post, please visit this post to download the file.</p>
<p>2. stratagus引用的外部lib和头文件打包，用Visual C++ 2008编译，解压后放在stratagus源码上级目录 Note: There is a file embedded within this post, please visit this post to download the file.</p>
]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2009/11/13/stratagus-svn-windows/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>最近用scons的收获</title>
		<link>http://dipplum.com/2009/11/13/scons-tips/</link>
		<comments>http://dipplum.com/2009/11/13/scons-tips/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 07:59:28 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[make]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scons]]></category>

		<guid isPermaLink="false">http://dipplum.com/2009/11/13/scons-tips/</guid>
		<description><![CDATA[背景 Windows平台上的编译工程工具很多，Visual C++ 6的dsp文件，2003以后用的vcproj，以及最近2010支持的用msbuild编译的vcxproj，加上古老的nmake，cygwin、msys移植的make，等等很多。 make的问题是扩展性比较差，尤其是在Windows平台上，nmake的功能更弱，导致写一个工程文件很费劲，管理多个工程有大量的重复工作要做。make最大的问题是不能automake那种简洁的工程写法（automake同样存在扩展问题，m4语言不懂）. 最新的msbuild 4.0试用了一下，感觉不是很好，很费劲。因为最近迷恋上了命令行，一直不愿意安装完整的Visual Studio 2010 Beta 2，直接把2010的命令行拷贝出来用cl.exe之类的。想只装.Net Framework 4.0就试试msbuild，发现不行，把2010里的msbuild相关资源拷贝出来也不行。而且用XML手写工程文件很麻烦。 猛然想起之前听说过，鼎鼎大名，但之前简单了解后放弃了的scons。再次使用之后，才发现scons的妙处。 简介Scons Scons首页赫然是Eric Raymond的推荐，很是唬人的样子。Scons是python写的，这不重要。Scons脚本用语言是python，这是Scons最吸引人的地方。用python写工程文件无疑对我这种熟悉python的人有很大的吸引力。 实际上，Scons最大的优势，就是描述语言本身沿用python。这种设计极大的提升的Scons的扩展能力。Scons本身功能是否强大不重要，对于熟悉python的人来说，扩展Scons达到他的要求，变得比以前简单的多。下面是我用Scons写的一个zlib的工程文件，其中WinLib和WinDLL是我自己扩展的在Windows平台上编译静态库和动态库的方法（cl的宏定义和link的参数有所不同）。 target = 'libz' defs = 'ASMV ASMINF' incs = '.' &#160; Import&#40;'env'&#41; lib_src = Split&#40;'contrib/masmx86/inffas32.asm contrib/masmx86/gvmat32.asm adler32.c compress.c crc32.c deflate.c gzio.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c contrib/masmx86/gvmat32c.c'&#41; lib_src += env.RES&#40;'win32/zlib1.rc'&#41; dll_src = lib_src + Split&#40;'win32/zlib.def'&#41; [...]]]></description>
			<content:encoded><![CDATA[<h4>背景</h4>
<p>Windows平台上的编译工程工具很多，Visual C++ 6的dsp文件，2003以后用的vcproj，以及最近2010支持的用msbuild编译的vcxproj，加上古老的nmake，cygwin、msys移植的make，等等很多。</p>
<p>make的问题是扩展性比较差，尤其是在Windows平台上，nmake的功能更弱，导致写一个工程文件很费劲，管理多个工程有大量的重复工作要做。make最大的问题是不能automake那种简洁的工程写法（automake同样存在扩展问题，m4语言不懂）.</p>
<p>最新的msbuild 4.0试用了一下，感觉不是很好，很费劲。因为最近迷恋上了命令行，一直不愿意安装完整的Visual Studio 2010 Beta 2，直接把2010的命令行拷贝出来用cl.exe之类的。想只装.Net Framework 4.0就试试msbuild，发现不行，把2010里的msbuild相关资源拷贝出来也不行。而且用XML手写工程文件很麻烦。</p>
<p>猛然想起之前听说过，鼎鼎大名，但之前简单了解后放弃了的scons。再次使用之后，才发现scons的妙处。</p>
<h4></h4>
<p> <span id="more-432"></span><br />
<h4>简介Scons</h4>
<p>Scons首页赫然是Eric Raymond的推荐，很是唬人的样子。Scons是python写的，这不重要。Scons脚本用语言是python，这是Scons最吸引人的地方。用python写工程文件无疑对我这种熟悉python的人有很大的吸引力。</p>
<p>实际上，Scons最大的优势，就是描述语言本身沿用python。这种设计极大的提升的Scons的扩展能力。Scons本身功能是否强大不重要，对于熟悉python的人来说，扩展Scons达到他的要求，变得比以前简单的多。下面是我用Scons写的一个zlib的工程文件，其中WinLib和WinDLL是我自己扩展的在Windows平台上编译静态库和动态库的方法（cl的宏定义和link的参数有所不同）。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">target = <span style="color: #483d8b;">'libz'</span>
defs = <span style="color: #483d8b;">'ASMV ASMINF'</span>
incs = <span style="color: #483d8b;">'.'</span>
&nbsp;
Import<span style="color: black;">&#40;</span><span style="color: #483d8b;">'env'</span><span style="color: black;">&#41;</span>
lib_src = Split<span style="color: black;">&#40;</span><span style="color: #483d8b;">'contrib/masmx86/inffas32.asm contrib/masmx86/gvmat32.asm adler32.c compress.c crc32.c deflate.c gzio.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c contrib/masmx86/gvmat32c.c'</span><span style="color: black;">&#41;</span>
lib_src += env.<span style="color: black;">RES</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'win32/zlib1.rc'</span><span style="color: black;">&#41;</span>
dll_src = lib_src + Split<span style="color: black;">&#40;</span><span style="color: #483d8b;">'win32/zlib.def'</span><span style="color: black;">&#41;</span>
&nbsp;
Import<span style="color: black;">&#40;</span><span style="color: #483d8b;">'WinLib WinDLL'</span><span style="color: black;">&#41;</span>
lib = WinLib<span style="color: black;">&#40;</span>target, lib_src, CPPDEFINES=defs, CPPPATH=incs<span style="color: black;">&#41;</span>
dll = WinDLL<span style="color: black;">&#40;</span>target, dll_src, CPPDEFINES=defs, CPPPATH=incs<span style="color: black;">&#41;</span>
&nbsp;
Alias<span style="color: black;">&#40;</span>target, <span style="color: black;">&#91;</span>lib, dll<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>实际上Scons本身的功能比较有限，为了写成这个简洁的模式，还费了不少劲。</p>
<h4>Scons的特点</h4>
<p>简单列举下最近有体会的Scons的特点，权当备忘录了。</p>
<p>1. Variables的设计很好。</p>
<p>通过Variables可以扩展scons支持的命令行参数，限制参数种类（Bool，枚举，多选），可以把上次的参数保存到文件，下次编译不需要命令行输入过多的参数。下面摘下我的Variable定义：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #008000;">vars</span> = Variables<span style="color: black;">&#40;</span><span style="color: #483d8b;">'options.ini'</span><span style="color: black;">&#41;</span>
<span style="color: #008000;">vars</span>.<span style="color: black;">AddVariables</span><span style="color: black;">&#40;</span>
    BoolVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'verbose'</span>, <span style="color: #483d8b;">'Show verbose messages'</span>, <span style="color: #483d8b;">'no'</span><span style="color: black;">&#41;</span>,
    BoolVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'unicode'</span>, <span style="color: #483d8b;">'Use unicode API'</span>, <span style="color: #483d8b;">'yes'</span><span style="color: black;">&#41;</span>,
    BoolVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'debug'</span>, <span style="color: #483d8b;">'Generate debug code'</span>, <span style="color: #483d8b;">'no'</span><span style="color: black;">&#41;</span>,
    EnumVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'warn'</span>, <span style="color: #483d8b;">'Show warning level'</span>, <span style="color: #483d8b;">'no'</span>, <span style="color: black;">&#91;</span><span style="color: #483d8b;">'no'</span>, <span style="color: #483d8b;">'low'</span>, <span style="color: #483d8b;">'all'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>,
    EnumVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'optimize'</span>, <span style="color: #483d8b;">'Set optimization mode'</span>, <span style="color: #483d8b;">'normal'</span>, <span style="color: black;">&#91;</span><span style="color: #483d8b;">'normal'</span>, <span style="color: #483d8b;">'max'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>,
    PathVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'repos_root'</span>, <span style="color: #483d8b;">'Path to root of source repository'</span>, <span style="color: #483d8b;">'..'</span><span style="color: black;">&#41;</span>,
    PathVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'build_root'</span>, <span style="color: #483d8b;">'Path to root of build directory'</span>, <span style="color: #483d8b;">'build'</span>,
        PathVariable.<span style="color: black;">PathIsDirCreate</span><span style="color: black;">&#41;</span>,
    PathVariable<span style="color: black;">&#40;</span><span style="color: #483d8b;">'output_root'</span>, <span style="color: #483d8b;">'Path to output directory'</span>, <span style="color: #483d8b;">'.'</span>,
        PathVariable.<span style="color: black;">PathIsDirCreate</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span>
env = Environment<span style="color: black;">&#40;</span>ENV = <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span>, variables = <span style="color: #008000;">vars</span><span style="color: black;">&#41;</span></pre></div></div>

<p>2. Environment的设计也很好。</p>
<p>Environment可以保存全套的编译命令，参数配置，用Clone操作可以从一个基本编译环境作出很多变种，支持不同项目类型，不同配置的编译。Clone实在是太方便了。下面是前面提到的Windows平台下编译DLL和静态库、命令行程序的不同参数配置，用Clone操作可以在基本编译环境上，生成多个用于编译静态库、DLL等不同的编译环境，使用不同的参数编译。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">libEnv = env.<span style="color: black;">Clone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
libEnv.<span style="color: black;">Append</span><span style="color: black;">&#40;</span>CPPDEFINES = Split<span style="color: black;">&#40;</span><span style="color: #483d8b;">'_WINDOWS _WINDLL'</span><span style="color: black;">&#41;</span>, LINKFLAGS = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'/SUBSYSTEM:WINDOWS'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
dllEnv = env.<span style="color: black;">Clone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
dllEnv.<span style="color: black;">Append</span><span style="color: black;">&#40;</span>CPPDEFINES = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_WINDOWS'</span><span style="color: black;">&#93;</span>, LINKFLAGS = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'/SUBSYSTEM:WINDOWS'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
conEnv = env.<span style="color: black;">Clone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
conEnv.<span style="color: black;">Append</span><span style="color: black;">&#40;</span>CPPDEFINES = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_CONSOLE'</span><span style="color: black;">&#93;</span>, LINKFLAGS = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'/SUBSYSTEM:CONSOLE'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>题外话，关于Windows下编译不同工程的参数，<a href="http://binglongx.spaces.live.com/blog/cns!142CBF6D49079DE8!276.entry" target="_blank">这篇文章</a>总结的很全。</p>
<p>3. Builder的设计问题。</p>
<p>Scons可以用env.Library(&#8216;liba&#8217;, &#8216;a.c&#8217;)的方法用环境的定义编译静态库，或者用Program定义可执行程序。并且支持输入和环境定义不同的参数，如</p>
<p>env.Library(&#8216;liba&#8217;, &#8216;a.c&#8217;, CPPDEFINES = ['NEWMACRO'], CCFLAGS=['/Ox'])。</p>
<p>不过，很可惜，Builder默认是覆盖环境中现有参数，而不是追加。所以，要用多个编译参数稍有不同的程序和库编译只能用Clone后Append。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">tempEnv = libEnv.<span style="color: black;">Clone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
tempEnv.<span style="color: black;">Append</span><span style="color: black;">&#40;</span>CPPDEFINES = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'NEWMACRO'</span><span style="color: black;">&#93;</span>, CCFLAGS=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'/Ox'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
tempEnv.<span style="color: black;">Library</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'liba'</span>, <span style="color: #483d8b;">'a.c'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>或许我要求太高，不过这样写看起来实在太傻了。实际使用中，不同的程序用的编译参数就没有完全一样的，尤其是Include目录、宏定义、库路径、库这四个参数肯定有或多或少的不一样。不能追加的话，就只能Clone出很多个Env，甚至是一个Program或Library一个Env，这就失去了Env封装编译环境的通用意义了。</p>
<p>4. Sconscript与源码的位置问题</p>
<p>Scons设计时更多是支持将Sconscript放在源码同一目录下，甚至每个源码目录一个Soncscript。如果不习惯或者不能用这种方式，比如为别的项目写工程文件，遇到一些困扰。</p>
<p>Scons好在有类似make的VPATH功能，叫Repository，用着还行。</p>
<p>5. 源码和编译目录分开的问题</p>
<p>这个问题和上面类似，但更严重。Scons支持用VariantDir设定与源码目录不同的编译目录，但必须所有的文件都用编译目录的路径，如下</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">VariantDir<span style="color: black;">&#40;</span><span style="color: #483d8b;">'build_dir'</span>, <span style="color: #483d8b;">'src_dir'</span><span style="color: black;">&#41;</span>
Program<span style="color: black;">&#40;</span><span style="color: #483d8b;">'build_dir/prog'</span>, <span style="color: #483d8b;">'build_src/main.c'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>这就很傻了，明明源码在src_dir目录，一定要写成build_src。不这么写也行，那就写两个Sconcript文件，一个引用另外一个</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#SConscriptA</span>
Program<span style="color: black;">&#40;</span><span style="color: #483d8b;">'prog'</span>, <span style="color: #483d8b;">'src/main.c'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#SConscriptB</span>
SConscript<span style="color: black;">&#40;</span><span style="color: #483d8b;">'SconscriptA'</span>, variant_dir=<span style="color: #483d8b;">'build'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>要用好VariantDir，就必须写多个脚本。尤其是要支持编译同一程序的多个版本，还只能用两个脚本。SconscriptB可以按如下方式写，就能编译两个版本的prog，分别在debug和release目录下。用一个Sconscript完成同样功能实在是很费劲的。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">SConscript<span style="color: black;">&#40;</span><span style="color: #483d8b;">'SconscriptA'</span>, variant_dir=<span style="color: #483d8b;">'debug'</span><span style="color: black;">&#41;</span>
SConscript<span style="color: black;">&#40;</span><span style="color: #483d8b;">'SconscriptA'</span>, variant_dir=<span style="color: #483d8b;">'release'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>6. 同一个源码编译多份的问题</p>
<p>这个问题和上面类似，但不同。例如编译静态库和动态库都用一批源码，但编译参数不一样，Scons就会报错。但这个问题用variant_dir解决不方便。如下例：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">Program<span style="color: black;">&#40;</span><span style="color: #483d8b;">'hello1'</span>, <span style="color: #483d8b;">'hello.c'</span>, CCFLAGS=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'-Od'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
Program<span style="color: black;">&#40;</span><span style="color: #483d8b;">'hello2'</span>, <span style="color: #483d8b;">'hello.c'</span>, CCFLAGS=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'-Ox'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Scons报错如下：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">scons: <span style="color: #000000; font-weight: bold;">***</span> Two environments with different actions were specified <span style="color: #000000; font-weight: bold;">for</span> the same target:</pre></div></div>

<p>经过我多方论证，发现这个问题目前看来最佳、最简单的解决方法是给OBJ文件设置前缀。</p>
<pre>Program('hello1', 'hello.c', OBJPREFIX='dbg-', CCFLAGS=['-Od'])
Program('hello2', 'hello.c', OBJPREFIX='opt-', CCFLAGS=['-Ox'])</pre>
<p>7. 简化编译输出的问题</p>
<p>Scons支持自定义的编译输出。但有些命令不能替换，例如msvc工具集中的链接过程的输出。</p>
<p>暂时这么多吧&#8230;想到再补充。</p>
]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2009/11/13/scons-tips/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Visual C++ 2008编译libpng</title>
		<link>http://dipplum.com/2009/11/09/visualc-compile-libpng/</link>
		<comments>http://dipplum.com/2009/11/09/visualc-compile-libpng/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 05:23:39 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[libpng]]></category>
		<category><![CDATA[visualc]]></category>
		<category><![CDATA[win32]]></category>
		<category><![CDATA[zlib]]></category>

		<guid isPermaLink="false">http://dipplum.com/2009/11/09/visualc-compile-libpng/</guid>
		<description><![CDATA[1. 主页 http://www.libpng.org/pub/png/libpng.html 2. 最新稳定版本 1.2.40 &#160;&#160;&#160; 源码下载 http://download.sourceforge.net/libpng/lpng1240.zip 3. 编译依赖 &#160;&#160;&#160; 依赖zlib。要求名为zlib的目录位于和libpng源码平级的目录下。libpng会自行编译zlib的源码，而zlib 1.2.3版本中的汇编代码在VC 2008下编译存在问题，参见zlib的编译说明。 4. 编译方法 &#160;&#160;&#160; 打开源码中的projects\vc71\libpng.sln工程文件。编译DLL ASM Release和LIB ASM Release就可以了。会得到libpng.lib、libpng13.lib、libpng13.dll。 5. 注意 &#160;&#160;&#160; ligpng会编译自己的zlib1.dll和zlib.lib，不知道编译参数和zlib自己的工程文件是否一样，也不知道和zlib工程文件编译出的dll和lib会不会冲突。这个问题留待考察。]]></description>
			<content:encoded><![CDATA[<p>1. 主页 <a href="http://www.libpng.org/pub/png/libpng.html">http://www.libpng.org/pub/png/libpng.html</a></p>
<p>2. 最新稳定版本 1.2.40</p>
<p>&#160;&#160;&#160; 源码下载 <a href="http://download.sourceforge.net/libpng/lpng1240.zip">http://download.sourceforge.net/libpng/lpng1240.zip</a></p>
<p>3. 编译依赖</p>
<p>&#160;&#160;&#160; 依赖zlib。要求名为zlib的目录位于和libpng源码平级的目录下。libpng会自行编译zlib的源码，而zlib 1.2.3版本中的汇编代码在VC 2008下编译存在问题，参见<a href="http://dipplum.com/2009/11/08/visualc-compile-zlib/" target="_blank">zlib的编译说明</a>。</p>
<p>4. 编译方法</p>
<p>&#160;&#160;&#160; 打开源码中的projects\vc71\libpng.sln工程文件。编译DLL ASM Release和LIB ASM Release就可以了。会得到libpng.lib、libpng13.lib、libpng13.dll。</p>
<p>5. 注意</p>
<p>&#160;&#160;&#160; ligpng会编译自己的zlib1.dll和zlib.lib，不知道编译参数和zlib自己的工程文件是否一样，也不知道和zlib工程文件编译出的dll和lib会不会冲突。这个问题留待考察。</p>
]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2009/11/09/visualc-compile-libpng/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visual C++ 2008编译lua</title>
		<link>http://dipplum.com/2009/11/09/visualc-compile-lua/</link>
		<comments>http://dipplum.com/2009/11/09/visualc-compile-lua/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 02:39:43 +0000</pubDate>
		<dc:creator>li</dc:creator>
				<category><![CDATA[开源软件]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[visualc]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://dipplum.com/2009/11/09/visualc-compile-lua/</guid>
		<description><![CDATA[1. 项目主页 http://www.lua.org/ 2. 当前最新稳定版本 5.1.4，2008年8月发布 &#160;&#160;&#160; 源码下载 http://www.lua.org/ftp/lua-5.1.4.tar.gz 3. VC编译方法 &#160;&#160;&#160; 解压后，用Visual Studio 2008命令行环境进入lua目录，运行etc\luavs.bat。之后会在src目录下生成lua.exe、luac.exe、lua51.dll 4. 注意 &#160;&#160;&#160; 默认的luavs.bat只会生成DLL，如果需要编译静态链接库，可以自行修改luavs.bat，修改两处地方 &#160;&#160;&#160; 1. 删除cl.exe的编译选项 /DLUA_BUILD_AS_DLL &#160;&#160;&#160; 2. 生成DLL的命令改成 lib.exe /nologo /out:lua.lib *.obj]]></description>
			<content:encoded><![CDATA[<p>1. 项目主页 <a href="http://www.lua.org/">http://www.lua.org/</a></p>
<p>2. 当前最新稳定版本 5.1.4，2008年8月发布</p>
<p>&#160;&#160;&#160; 源码下载 <a href="http://www.lua.org/ftp/lua-5.1.4.tar.gz">http://www.lua.org/ftp/lua-5.1.4.tar.gz</a></p>
<p>3. VC编译方法</p>
<p>&#160;&#160;&#160; 解压后，用Visual Studio 2008命令行环境进入lua目录，运行etc\luavs.bat。之后会在src目录下生成lua.exe、luac.exe、lua51.dll</p>
<p>4. 注意</p>
<p>&#160;&#160;&#160; 默认的luavs.bat只会生成DLL，如果需要编译静态链接库，可以自行修改luavs.bat，修改两处地方</p>
<p>&#160;&#160;&#160; 1. 删除cl.exe的编译选项 /DLUA_BUILD_AS_DLL</p>
<p>&#160;&#160;&#160; 2. 生成DLL的命令改成 lib.exe /nologo /out:lua.lib *.obj</p>
]]></content:encoded>
			<wfw:commentRss>http://dipplum.com/2009/11/09/visualc-compile-lua/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

