逝者已逝,众恶徒已正法,然天下居庙堂者与处江湖者,当以此为鉴,牢记生命之重,人权之重,民主之重,法治之重,无使天下善良百姓,徒为鱼肉。 ——孙志刚墓志铭
  • 一穷二白的给mongrel加上https - [朝花夕拾]

    2009-07-08

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://dear.blogbus.com/logs/42051377.html

    开发环境一直都是mongrel,产品环境用的apache。客户突然提出,要在作某几个涉及到敏感数据操作的地方,用https。

    先在一台开发机上尝试,用apt-get安装了apache,做了一些配置。然后gigix提出,最好编译一个apache放到svn上去,然后写脚本作自动化配置;尝试了一下,发现要编译apache的话,就得把openssl也得编了。。遂放弃。

    下面是一些搞的步骤:

    1. sudo apt-get install apache2

    2. sudo a2ensite default-ssl

    3. sudo /etc/init.d/apache2 reload

    4. sudo a2enmod ssl
    5. sudo a2enmod proxy
    6. sudo a2enmod proxy_http
    7. sudo a2enmod headers

    8. sudo /etc/init.d/apache restart

    9. sudo make-ssl-cert generate-default-snakeoil --force-overwrite

    10. chmod 755 /etc/ssl/private/

    11. cd /etc/apache2, run "sudo vi ports.conf", clear the contents in that file and copy/paste the contents below:

    NameVirtualHost *:80
    Listen 80

    <VirtualHost *:80>
      ServerName localhost
      ProxyPass / http://localhost:3000/
      ProxyPassReverse / http://localhost:3000
    </VirtualHost>

    <VirtualHost _default_:443>
       SSLEngine on
      ServerName localhost:443

      SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
      SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
      ProxyPass / http://localhost:3000/
      ProxyPassReverse / http://localhost:3000
      RequestHeader set X_FORWARDED_PROTO "https"
    </VirtualHost>

    <Proxy *>
      Order Deny,Allow
      Deny from all
      Allow from localhost
    </Proxy>

    <IfModule mod_ssl.c>
        # SSL name based virtual hosts are not yet supported, therefore no
        # NameVirtualHost statement here
        Listen 443
    </IfModule>

    做完上面的步骤,apache、mongrel、ssl这些已经搞定了。接下来就是rails的配置,

    先安装这个plugin:

    ruby script/plugin install ssl_requirement

    然后配置application controller:

    class ApplicationController < ActionController::Base
    include SslRequirement

    最后在controller里面需要用https的方法前面加上ssl_required,如:

    ssl_required :new, :signin, :forgot_password

    现在去页面执行操作,用firebug可以看到post请求已经被转发到https了。但到这里我们就遇到另外的问题了,因为我们并不想让所有的开发机器都去装apache,配https,只要这些配置在测试环境和产品环境中可以用就行了。所以就在config/{#projectname}.yml里面配了个:https_needed: false,而config/environments/production/{#projectname}.yml配的是:http_needed: true。这样QA在做测试的时候,只要改一下config/lpi.yml里面的参数就可以了。

    于是在controller里面的方法就变成了这样子:

    ssl_required :new, :signin, :forgot_password if PROJECT_ENV[:https_needed]

    这样一切就都就绪了。可是还有个小问题没有收尾:可能有很多方法都需要加ssl_required,而且可能会分散在不同的controller里面,在每个用到ssl_required的地方都放一个if PROJECT_ENV[:https_needed]就会显得很难看。解决方案很fansy,下篇博客再写。


    收藏到:Del.icio.us




    评论

  • 好,偶然看到有关你的信息,很想认识一下你。方便的话留下MSN。不要误会,俺可不
  • 你好,偶然看到有关你的信息,很想认识一下你。方便的话留下MSN。不要误会,俺可不是坏人~~