<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>天外之家</title>
    <description>天外之音的博客</description>
    <link>http://www.tianwaihome.com/</link>
    <atom:link href="http://www.tianwaihome.com/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Fri, 15 Jul 2022 07:41:09 +0000</pubDate>
    <lastBuildDate>Fri, 15 Jul 2022 07:41:09 +0000</lastBuildDate>
    <generator>Jekyll v3.9.2</generator>
    
      <item>
        <title>VMware Fusion 10 Pro 序列号</title>
        <description>&lt;font color=&quot;red&quot;&gt;2017年10月10号更新&lt;/font&gt;
&lt;p&gt;VMware Fusion 10 Pro 终于出来了，支持macOS High Sierra.&lt;/p&gt;

&lt;p&gt;下载地址在此：&lt;/p&gt;

&lt;p&gt;http://www.vmware.com/cn/products/fusion/fusion-evaluation&lt;/p&gt;

&lt;p&gt;提供几枚key：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;FG3TU-DDX1M-084CY-MFYQX-QC0RD&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 10 Oct 2017 11:56:12 +0000</pubDate>
        <link>http://www.tianwaihome.com/2017/10/vmware-fusion-10-pro-key.html</link>
        <guid isPermaLink="true">http://www.tianwaihome.com/2017/10/vmware-fusion-10-pro-key.html</guid>
        
        
        <category>VMware</category>
        
      </item>
    
      <item>
        <title>使用ULB的时候如何优雅的启动后端服务程序</title>
        <description>&lt;p&gt;第一弹的后端有很多很多个实例来提供服务，使用了Ucloud提供的ULB负载均衡器来对外接收请求，之前在重启后端服务程序的时候，往往要进控制台在ULB里把对应的服务给禁用了，然后重启完再启用，如果有很多台机器的话，要一个个操作，非常非常的麻烦。&lt;/p&gt;

&lt;p&gt;最近想到，能不能用ULB的状态检查功能来自动禁用对应的服务，这样服务重启以后也会自动的恢复，免去人工操作的步骤。&lt;/p&gt;

&lt;p&gt;ULB支持两种状态检查方法：端口检查和HTTP检查。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/uploads/2015/05/QQ20160522-0.png&quot; alt=&quot;QQ20160522-0&quot; /&gt;&lt;/p&gt;

&lt;p&gt;端口检查就是ULB会去ping后端服务的端口，如果端口联通就判定为可用，否则判定后端服务不可用，但是这么做有个延迟，ULB是两秒检查一次，如果三次检查发现有问题才会切换，这样就会有6秒的时间，后端服务已经关闭了，但是ULB依然会把连接发过去，会造成很多用户连接失败。&lt;/p&gt;

&lt;p&gt;HTTP检查好像是最近加的功能，通过一个HTTP请求来判断，如果返回200，说明服务可用，其他返回值说明服务不可用，这个方法可以很方便的使用，后端程序提供一个URL来进行检查，正常情况下，这个URL返回的是200，当需要重启的时候，先把该URL的返回值设置为其他值，比如404，然后等若干秒以后，ULB把流量切换走了，再关闭端口，进行重启的步骤，这样有效的避免了在重启过程中用户无法连接的问题。&lt;/p&gt;

&lt;p&gt;以下是我们的tornado相关代码&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HealthHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tornado&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RequestHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Global&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_in_stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tornado&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HTTPError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;404&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;如此一来，每次部署程序的时候只要挨个重启后端服务就行了，不需要登录控制台操作ULB了。&lt;/p&gt;

</description>
        <pubDate>Sat, 21 May 2016 20:56:12 +0000</pubDate>
        <link>http://www.tianwaihome.com/2016/05/ucloud-ulb-restart-rs.html</link>
        <guid isPermaLink="true">http://www.tianwaihome.com/2016/05/ucloud-ulb-restart-rs.html</guid>
        
        
        <category>Linux</category>
        
      </item>
    
      <item>
        <title>VMware Fusion 8 Pro 序列号</title>
        <description>&lt;font color=&quot;red&quot;&gt;2015年8月29号更新&lt;/font&gt;
&lt;p&gt;VMware Fusion 8 Pro 终于出来了，支持OS X El Capitan 和 Windows 10.&lt;/p&gt;

&lt;p&gt;下载地址在此：&lt;/p&gt;

&lt;p&gt;http://www.vmware.com/cn/products/fusion/fusion-evaluation&lt;/p&gt;

&lt;p&gt;提供几枚key：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;FA3RK-FHGD5-M88TZ-V4WEZ-MVAW0&lt;/li&gt;
  &lt;li&gt;FU75U-4KD5L-0845Z-JEXNZ-MLKD8&lt;/li&gt;
  &lt;li&gt;UV7XK-4PXEJ-080WY-4WXQT-NC0ZF&lt;/li&gt;
  &lt;li&gt;VC79R-6NF81-M84XZ-VNW5G-NKUW8&lt;/li&gt;
  &lt;li&gt;GC1HA-01Z14-H8D2P-04NNZ-Z6RY0&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 29 Aug 2015 20:56:12 +0000</pubDate>
        <link>http://www.tianwaihome.com/2015/08/vmware-fusion-8-pro-key.html</link>
        <guid isPermaLink="true">http://www.tianwaihome.com/2015/08/vmware-fusion-8-pro-key.html</guid>
        
        
        <category>VMware</category>
        
      </item>
    
      <item>
        <title>编译OpenSSL到 Android</title>
        <description>&lt;p&gt;今天研究怎么把OpenSSL编译成Android原生库，记录一下。&lt;/p&gt;

&lt;h2 id=&quot;1-安装ndk&quot;&gt;1 安装NDK&lt;/h2&gt;

&lt;p&gt;首先，你得有NDK，&lt;a href=&quot;https://developer.android.com/tools/sdk/ndk/index.html&quot;&gt;下载NDK&lt;/a&gt;，然后将其解压到一个地方就可以了。我安装NDK的目录是：&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;/Volumes/DATA/develop/android-ndk-r10d&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;2-初始化android交叉编译工具&quot;&gt;2 初始化Android交叉编译工具&lt;/h2&gt;

&lt;p&gt;使用NDK的功能初始化一个Android的GCC工具：&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;NDK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/Volumes/DATA/develop/android-ndk-r10d
&lt;span class=&quot;nv&quot;&gt;$NDK&lt;/span&gt;/build/tools/make-standalone-toolchain.sh &lt;span class=&quot;nt&quot;&gt;--platform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;android-19 &lt;span class=&quot;nt&quot;&gt;--toolchain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;arm-linux-androideabi-4.6 &lt;span class=&quot;nt&quot;&gt;--install-dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;/android-toolchain-arm&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;可以根据大家的需求选择Android版本号和GCC版本，我这里选择的是Android 4.4和GCC4.6。&lt;/p&gt;

&lt;p&gt;然后大家会在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android-toolchain-arm&lt;/code&gt; 目录下找到生成的交叉编译器&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/uploads/2015/05/QQ20150514-1@2x.png&quot; alt=&quot;QQ20150514-1@2x&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;3-获取openssl&quot;&gt;3 获取OpenSSL&lt;/h2&gt;

&lt;p&gt;使用Git可以获取最新代码&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone git://git.openssl.org/openssl.git&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;当然在Windows上要对git进行配置&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;openssl
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config core.autocrlf &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config core.eol lf
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git checkout .&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;4-设置环境变量&quot;&gt;4 设置环境变量&lt;/h2&gt;

&lt;p&gt;需要设置一下环境变量，使用刚刚设置好的交叉编译器，
其实也很简单，改一下 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PATH&lt;/code&gt; 就可以了&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/Volumes/DATA/develop/android-ndk-r10d/android-toolchain-arm/arm-linux-androideabi/bin:&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ANDROID_DEV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/Volumes/DATA/develop/android-ndk-r10d/platforms/android-19/arch-arm/usr&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;记得把上面的地址改成你的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android-toolchain-arm&lt;/code&gt; 地址&lt;/p&gt;

&lt;h2 id=&quot;5-编译&quot;&gt;5 编译&lt;/h2&gt;

&lt;p&gt;最后一步是编译了&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./Configure android-armv7
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;make &lt;span class=&quot;nt&quot;&gt;-j&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-j&lt;/code&gt; 选项的意思是，尽可能的使用多的线程进行编译。&lt;/p&gt;

&lt;p&gt;这么编译出来的是静态库，也就是包含 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libssl.a&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libcrypto.a&lt;/code&gt;。
如果想编译成动态库，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./Configure&lt;/code&gt; 的时候添加 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shared&lt;/code&gt; 选项即可&lt;/p&gt;

&lt;p&gt;其实编译很简单。&lt;/p&gt;

</description>
        <pubDate>Thu, 14 May 2015 15:00:12 +0000</pubDate>
        <link>http://www.tianwaihome.com/2015/05/compile-openssl-for-android.html</link>
        <guid isPermaLink="true">http://www.tianwaihome.com/2015/05/compile-openssl-for-android.html</guid>
        
        
        <category>Android</category>
        
      </item>
    
      <item>
        <title>nginx: worker process is shutting down 原因解析</title>
        <description>&lt;p&gt;今天配置服务器的时候，发现了很多的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nginx: worker process is shutting down&lt;/code&gt; 。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/uploads/2015/03/QQ20150331-1.png&quot; alt=&quot;nginx: worker process is shutting down&quot; /&gt;&lt;/p&gt;

&lt;p&gt;顿时整个人都警觉起来了，是不是服务出问题了。&lt;/p&gt;

&lt;p&gt;后来查资料后发现，这个完全不是问题，出现这个的原因是因为我重启 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nginx&lt;/code&gt; 的时候用了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;service nginx reload&lt;/code&gt; ，这是一种平滑重启的方案，不会把已有的连接断掉，而这些维护已有连接的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nginx&lt;/code&gt; 进程则会进入 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nginx: worker process is shutting down&lt;/code&gt; 状态，稍微等一等就好了。&lt;/p&gt;

&lt;p&gt;果然，过了10分钟， &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nginx: worker process is shutting down&lt;/code&gt; 进行就都消失了。&lt;/p&gt;
</description>
        <pubDate>Tue, 31 Mar 2015 17:00:12 +0000</pubDate>
        <link>http://www.tianwaihome.com/2015/03/nginx-worker-process-is-shutting-down.html</link>
        <guid isPermaLink="true">http://www.tianwaihome.com/2015/03/nginx-worker-process-is-shutting-down.html</guid>
        
        
        <category>web</category>
        
      </item>
    
      <item>
        <title>Nginx做反向代理时缓存问题总结</title>
        <description>&lt;p&gt;今天给 &lt;a href=&quot;http://www.opencas.org/&quot; target=&quot;_blank&quot;&gt;中科院镜像服务器&lt;/a&gt; 做了双机负载均衡，使用Nginx进行反向代理，遇到一些缓存的问题，总结如下。&lt;/p&gt;

&lt;h3 id=&quot;缓存过期时间&quot;&gt;缓存过期时间&lt;/h3&gt;

&lt;p&gt;在配置的时候，有如下三个地方可以设置缓存过期时间：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;inactive=1d&lt;/li&gt;
  &lt;li&gt;proxy_cache_valid 200 304 1h&lt;/li&gt;
  &lt;li&gt;expires 10m&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;其实解释起来很简单：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;inactive=1d 是指多久未访问以后清除缓存&lt;/li&gt;
  &lt;li&gt;proxy_cache_valid 200 304 1h 是指距离缓存产生时间多久以后清除缓存&lt;/li&gt;
  &lt;li&gt;expires 10m 这个不是控制服务器端的，而是指在Http Response header里指定的过期时间，是给客户端看的。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;temp的问题&quot;&gt;temp的问题&lt;/h3&gt;

&lt;p&gt;Nginx进行反代的时候，遇到超出文件大小 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proxy_buffer_size&lt;/code&gt; 的时候，是一次性把文件都加载到Temp目录，然后再发送给用户。&lt;/p&gt;

&lt;p&gt;如果设置了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proxy_buffering off&lt;/code&gt; 则不会加载到Temp目录，而是同步的从上游进行加载。&lt;/p&gt;

&lt;p&gt;可以通过设置 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proxy_max_temp_file_size&lt;/code&gt; 参数来设置最大可以缓存的文件大小。&lt;/p&gt;

&lt;h3 id=&quot;206-和-byte-range-的问题&quot;&gt;206 和 Byte Range 的问题&lt;/h3&gt;

&lt;p&gt;Byte Range允许客户端向服务器请求一部分文件，而不是整个文件。大部分支持多线程下载和断点下载的软件都是用的这个功能。这个时候服务器返回的Http Code是206 Partial Requests.&lt;/p&gt;

&lt;p&gt;但是Nginx做反代的时候，如果没有好好的设置，这个功能可能会引来Dos攻击。&lt;/p&gt;

&lt;p&gt;因为默认做反代的时候，Nginx向后端服务器请求的时候是不会把 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Range&lt;/code&gt; 参数加上的，而是会去请求整个文件，比方说有一个1G的文件，每次请求1M，Nginx会在每次请求的时候去后端请求一个完整的1G文件，然后取出其中的1M发给客户端，这个时候中间的流量会暴增，导致整个服务器宕机。今天因为这个问题导致我检查了很久。&lt;/p&gt;

&lt;p&gt;解决方案也很简单，把 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Range&lt;/code&gt; 加到Header里就行了。&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;proxy_set_header Range &lt;span class=&quot;nv&quot;&gt;$http_range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
proxy_set_header If-Range &lt;span class=&quot;nv&quot;&gt;$http_if_range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
proxy_no_cache &lt;span class=&quot;nv&quot;&gt;$http_range&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$http_if_range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</description>
        <pubDate>Tue, 31 Mar 2015 17:00:12 +0000</pubDate>
        <link>http://www.tianwaihome.com/2015/03/nginx-proxy-cache.html</link>
        <guid isPermaLink="true">http://www.tianwaihome.com/2015/03/nginx-proxy-cache.html</guid>
        
        
        <category>web</category>
        
      </item>
    
      <item>
        <title>Mac下安装使用pypy</title>
        <description>&lt;p&gt;PyPy是一个比CPython更好的解释器。
在Mac上测试使用了一下。&lt;/p&gt;

&lt;h3 id=&quot;安装&quot;&gt;安装&lt;/h3&gt;

&lt;p&gt;如果你有 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;homebrew&lt;/code&gt; 的话，安装过程会非常简单&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;pypy&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;这样就会自动搜索安装了&lt;/p&gt;

&lt;h3 id=&quot;使用&quot;&gt;使用&lt;/h3&gt;

&lt;p&gt;在命令行里使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pypy&lt;/code&gt; 代替 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python&lt;/code&gt; 就可以了。&lt;/p&gt;

&lt;h3 id=&quot;pip&quot;&gt;pip&lt;/h3&gt;

&lt;p&gt;当然忘不了伟大的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt; 方法也很简单。&lt;/p&gt;

&lt;p&gt;brew安装以后会自动生成以下两个文件：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;easy_install_pypy&lt;/li&gt;
  &lt;li&gt;pip_pypy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;使用两个代替 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt; 或者 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;easy_install&lt;/code&gt; 就可以了。&lt;/p&gt;

&lt;p&gt;是不是很简单啊&lt;/p&gt;

&lt;h3 id=&quot;测试&quot;&gt;测试&lt;/h3&gt;

&lt;p&gt;对我目前的一个项目进行了一下测试&lt;/p&gt;

&lt;h4 id=&quot;cpython&quot;&gt;cPython&lt;/h4&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ab &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; 1000 &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; 20 &lt;span class=&quot;s2&quot;&gt;&quot;http://127.0.0.1:8000/v0.2/posts?page=1&amp;amp;perPage=15&quot;&lt;/span&gt;
This is ApacheBench, Version 2.3 &amp;lt;&lt;span class=&quot;nv&quot;&gt;$Revision&lt;/span&gt;: 1554214 &lt;span class=&quot;nv&quot;&gt;$&amp;gt;&lt;/span&gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;be patient&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        TornadoServer/4.1
Server Hostname:        127.0.0.1
Server Port:            8000

Document Path:          /v0.2/posts?page&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1&amp;amp;perPage&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;15
Document Length:        14127 bytes

Concurrency Level:      20
Time taken &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;tests:   16.366 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      14493000 bytes
HTML transferred:       14127000 bytes
Requests per second:    61.10 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#/sec] (mean)&lt;/span&gt;
Time per request:       327.311 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ms] &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;mean&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Time per request:       16.366 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ms] &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;mean, across all concurrent requests&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Transfer rate:          864.82 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Kbytes/sec] received

Connection Times &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       2
Processing:    87  324  32.6    317     453
Waiting:       87  324  32.6    317     453
Total:         89  324  32.5    317     453

Percentage of the requests served within a certain &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  50%    317
  66%    328
  75%    332
  80%    336
  90%    359
  95%    368
  98%    434
  99%    444
 100%    453 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;longest request&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;内存占有率是 40M&lt;/p&gt;

&lt;h4 id=&quot;pypy&quot;&gt;pypy&lt;/h4&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ab &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; 1000 &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; 20 &lt;span class=&quot;s2&quot;&gt;&quot;http://127.0.0.1:8000/v0.2/posts?page=1&amp;amp;perPage=15&quot;&lt;/span&gt;
This is ApacheBench, Version 2.3 &amp;lt;&lt;span class=&quot;nv&quot;&gt;$Revision&lt;/span&gt;: 1554214 &lt;span class=&quot;nv&quot;&gt;$&amp;gt;&lt;/span&gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;be patient&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        TornadoServer/4.1
Server Hostname:        127.0.0.1
Server Port:            8000

Document Path:          /v0.2/posts?page&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1&amp;amp;perPage&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;15
Document Length:        14127 bytes

Concurrency Level:      20
Time taken &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;tests:   27.627 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      14493000 bytes
HTML transferred:       14127000 bytes
Requests per second:    36.20 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#/sec] (mean)&lt;/span&gt;
Time per request:       552.548 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ms] &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;mean&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Time per request:       27.627 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ms] &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;mean, across all concurrent requests&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Transfer rate:          512.29 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Kbytes/sec] received

Connection Times &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       2
Processing:    27  548 266.5    516    8026
Waiting:       27  547 266.5    516    8026
Total:         28  548 266.5    516    8027

Percentage of the requests served within a certain &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  50%    516
  66%    552
  75%    572
  80%    587
  90%    614
  95%    672
  98%   1104
  99%   1245
 100%   8027 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;longest request&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;内存占用飙到了 240M&lt;/p&gt;

&lt;p&gt;而且性能不是很理想，难道是我的使用方法不对，等过段时间再进行研究吧。&lt;/p&gt;
</description>
        <pubDate>Sun, 29 Mar 2015 23:25:12 +0000</pubDate>
        <link>http://www.tianwaihome.com/2015/03/mac-install-pypy.html</link>
        <guid isPermaLink="true">http://www.tianwaihome.com/2015/03/mac-install-pypy.html</guid>
        
        
        <category>Mac</category>
        
      </item>
    
      <item>
        <title>M2Crypto操作X509证书</title>
        <description>&lt;p&gt;在Python的所有OpenSSL封装里，这个库是最好用最完全的。&lt;/p&gt;

&lt;p&gt;其中的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M2Crypto.X509&lt;/code&gt; 则是对X509的一个封装，下面就来看看如何使用M2Crypto操作X509证书。&lt;/p&gt;

&lt;p&gt;关于M2Crypto，完整的API可以看这里：&lt;a href=&quot;http://www.heikkitoivonen.net/m2crypto/api/&quot;&gt;http://www.heikkitoivonen.net/m2crypto/api/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;一般来说，产生一张X509证书的过程如下：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;申请者生成非对称加密算法的密钥，如RSA，DSA还有最新流行的ECC等。&lt;/li&gt;
  &lt;li&gt;申请者生成电子证书请求文件(X509_Request)。其中包含申请者的身份信息、公钥，并且用自己的私钥签名。&lt;/li&gt;
  &lt;li&gt;CA读取电子证书请求文件。核查身份信息是否正确。如果身份信息正确就对电子证书进行签名。其中包含CA的身份信息、申请者的身份信息、申请者的公钥、电子证书的起始有效时间，电子证书的结束有效时间。通常还会记录这是CA所颁发的第几个证书。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;产生私钥&quot;&gt;产生私钥&lt;/h3&gt;

&lt;p&gt;可以使用&lt;a href=&quot;/2015/03/openssl-ca.html#generate-key&quot;&gt;OpenSSL命令产生私钥&lt;/a&gt;或者使用M2Crypto来产生：&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#此函数生成一个2048位的RSA密钥，将其转化成PEM格式返回
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;M2Crypto&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;genrsa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BIO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MemoryBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rsa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RSA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gen_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2048&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65537&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rsa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save_key_bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;其中的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2048&lt;/code&gt; 指的是密钥位数，65537是生成因子，据OpenSSL的文档说，这个函数通常是三个奇数 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;17&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;65537&lt;/code&gt; 之一，而在使用OpenSSL命令生成私钥的时候，可以看出往往使用的是65537。&lt;/p&gt;

&lt;h3 id=&quot;生成证书请求&quot;&gt;生成证书请求&lt;/h3&gt;

&lt;p&gt;可以使用&lt;a href=&quot;/2015/03/openssl-ca.html#generate-request&quot;&gt;OpenSSL来生成证书请求&lt;/a&gt;或者使用M2Crypto来生成&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;M2Crypto&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#首先载入密钥文件。此文件同时保存了申请者的私钥与公钥。
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pkey_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;prikey.pem&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pkey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EVP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_key_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pkey_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;no_passphrase_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X509&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_pubkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#包含公钥
#req.set_version(1)
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#身份信息不是简单的字符串。而是X509_Name对象。
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X509&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X509_Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#CN是Common Name的意思。如果是一个网站的电子证书，就要写成网站的域名
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;WangYang&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#Organization Unit，通常是指部门吧，组织内单元
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OU&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SKLOIS&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#Organization。通常是指公司
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;IIE&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#State or Province。州或者省
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ST&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Beijing&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#Locale。
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Beijing&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#国家。不能直接写国家名字，比如China之类的，而应该是国家代码。
#CN代表中国。US代表美国，JP代表日本
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;CN&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#包含通信节点的身份信息
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sha256&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#使用通信节点的密钥进行签名，sha1已经不安全了，这里使用sha256
&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;req.pem&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;wb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_pem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#写入到文件&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;ca签发证书&quot;&gt;CA签发证书&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;/2015/03/openssl-ca.html&quot;&gt;关于如何产生一个CA&lt;/a&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;M2Crypto&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#首先读取证书请求文件。
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;req.pem&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#返回一个X509.Request类型代表证书请求文件
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X509&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_request_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#首先验证一下，是不是真的是使用它本身的私钥签名的。
#如果是，返回非0值。如果不是，说明这是一个非法的证书请求文件。
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;verify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_pubkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#接下来载入CA的电子证书。与CA的密钥不一样，CA的电子证书包含了CA的身份信息。
#CA的电子证书会分发给各个通信节点。
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ca_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ca.pem&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ca&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X509&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_cert_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ca_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#可以使用check_ca()方法判断这个证书文件是不是CA。
#本质是判断它是不是自签名。如果是的话，就返回非0值。如果不是的话就返回0。
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ca&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;check_ca&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#接下来载入CA的密钥
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cakey_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cakey.pem&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#一般CA的密钥要加密保存。回调函数返回密码
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cakey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EVP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_key_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cakey_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1234&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#接下来开始生成电子证书
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X509&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X509&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#首先，设定开始生效时间与结束生效时间
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timezone&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#当前时间，单位是秒
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#开始生效时间。证书的时间类型不是普通的Python datetime类型。
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ASN1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ASN1_UTCTIME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;nowPlusYear&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ASN1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ASN1_UTCTIME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#结束生效时间
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nowPlusYear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;365&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#一年以后。
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_not_before&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_not_after&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nowPlusYear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#把证书请求附带的身份信息复制过来
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#设置颁发者的身份信息，把CA电子证书内身份信息复制过来
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_issuer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ca&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#序列号是指，CA颁发的第几个电子证书文件
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_serial_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#把证书请求内的公钥复制过来
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_pubkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_pubkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#使用CA的秘钥进行签名。
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cakey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sha1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cert.pem&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;wb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_pem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;#保存文件。&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;接下来我们就可以看到一张由我们的CA签发的证书了。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/uploads/2015/03/20150326102938.png&quot; alt=&quot;证书&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Thu, 26 Mar 2015 10:15:12 +0000</pubDate>
        <link>http://www.tianwaihome.com/2015/03/m2crypto-x509.html</link>
        <guid isPermaLink="true">http://www.tianwaihome.com/2015/03/m2crypto-x509.html</guid>
        
        
        <category>web</category>
        
      </item>
    
      <item>
        <title>OpenSSL建立CA</title>
        <description>&lt;p&gt;OpenSSL的用法网上有一大堆，大多讲的特别繁琐，在这里将使用OpenSSL建立CA的过程记录一下。&lt;/p&gt;

&lt;h2 id=&quot;generate-key&quot;&gt;生成 RSA 密钥对&lt;/h2&gt;

&lt;p&gt;第一步是建立密钥对：&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;openssl genrsa &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; cakey.pem 2048&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;若想对私钥进行加密可以用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-des3&lt;/code&gt; 参数&lt;/p&gt;

&lt;h2 id=&quot;generate-request&quot;&gt;生成 CA 证书请求&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;openssl req &lt;span class=&quot;nt&quot;&gt;-new&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-days&lt;/span&gt; 365 &lt;span class=&quot;nt&quot;&gt;-sha256&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-key&lt;/span&gt; cakey.pem &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; careq.pem&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;现在都是sha256了，sha1已经被证明是不安全的东西了。&lt;/p&gt;

&lt;h2 id=&quot;对-ca-证书请求进行签名&quot;&gt;对 CA 证书请求进行签名&lt;/h2&gt;

&lt;p&gt;由于是CA，所以是自签名的&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;openssl ca &lt;span class=&quot;nt&quot;&gt;-selfsign&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-in&lt;/span&gt; careq.pem &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; cacert.pem&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;然后就搞定了，生成的cacert.pem就是CA证书&lt;/p&gt;

&lt;h2 id=&quot;一步到位&quot;&gt;一步到位&lt;/h2&gt;

&lt;p&gt;当然上面的过程还是很繁琐的，有没有一步到位的办法呢，当然是有的。&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;openssl req &lt;span class=&quot;nt&quot;&gt;-new&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-x509&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-days&lt;/span&gt; 365 &lt;span class=&quot;nt&quot;&gt;-key&lt;/span&gt; cakey.pem &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; cacert.pem&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;当然，key还是要单独生成的。&lt;/p&gt;
</description>
        <pubDate>Wed, 25 Mar 2015 21:04:12 +0000</pubDate>
        <link>http://www.tianwaihome.com/2015/03/openssl-ca.html</link>
        <guid isPermaLink="true">http://www.tianwaihome.com/2015/03/openssl-ca.html</guid>
        
        
        <category>web</category>
        
      </item>
    
      <item>
        <title>把博客迁移到了jekyll</title>
        <description>&lt;p&gt;抛弃了使用多年的Wordpress，转而使用jekyll并且部署到了Github Pages上。&lt;/p&gt;

&lt;p&gt;实在不想折腾了，果然还是如 阮一峰所说:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.ruanyifeng.com/blog/2012/08/blogging_with_jekyll.html&quot; target=&quot;_blank&quot;&gt;喜欢写Blog的人，会经历三个阶段&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;第一阶段，刚接触Blog，觉得很新鲜，试着选择一个免费空间来写。&lt;/p&gt;

  &lt;p&gt;第二阶段，发现免费空间限制太多，就自己购买域名和空间，搭建独立博客。&lt;/p&gt;

  &lt;p&gt;第三阶段，觉得独立博客的管理太麻烦，最好在保留控制权的前提下，让别人来管，自己只负责写文章。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;看来我是到了第三个阶段了，不想折腾了。&lt;/p&gt;
</description>
        <pubDate>Mon, 23 Mar 2015 12:53:12 +0000</pubDate>
        <link>http://www.tianwaihome.com/2015/03/move-blog-to-jekyll.html</link>
        <guid isPermaLink="true">http://www.tianwaihome.com/2015/03/move-blog-to-jekyll.html</guid>
        
        
        <category>Other</category>
        
      </item>
    
  </channel>
</rss>
