Tag: Nginx



2014年 9月 8

MojoliciousでHTTP(S)の振り分けをリバースプロキシのバックエンドでも出来るようにしてみる
が、さいきんのバーションでは変更があったらしくmojoliciousをばーじょんあっぷしたらうごかない。

こちらのGistが参考になる。
「MojoliciousでHTTP(S)の振り分けをリバースプロキシのバックエンドでも出来るようにしてみる」の例(Apache + mod_proxy)

抜粋すると、

proxy_set_header X-Forwarded-HTTPS
ではなく、

proxy_set_header X-Forwarded-Proto $scheme;
がひつよう(になったらしい)

追記リンク:
MojoliciousのリバースプロキシのSSLの検知方法が変わります – サンプルコードによるPerl入門


Filed under: Mojolicious,perl

Trackback Uri






2013年 11月 6

追記(解決編)

という事で、検証して頂きまして、うまくいかない原因が判明しました。以下のgistが最高に参考になります。@hayajo++

素晴らしいgist

以下原文


SSL専用のページとどちらでもいいページとSSLでアクセスして欲しくないページをrouterのところで出来れば楽だと考えて、試行錯誤してみたけどなかなかうまく行きません。

以前の記事

結論から言うとHTTP -> HTTPSの場合はなんとかうまくいきます。が、HTTPS -> HTTPの場合はどうしてもうまくいかない。

redirect_toメソッドでリダイレクトする場合、同ホスト・同じpathに限りLocationヘッダに設定されるURLがなぜかhttpsとなってしまう = リダイレクトが無限ループする。…なぜだ??

なので、mataタグを使ったリダイレクトでその場しのぎをしてみます。

Nginxの設定

proxy_set_header X-Forwarded-HTTPS を使えばいいのではとコメント頂いて助かりました。ただ、proxy_set_header X-Forwarded-HTTPS 1(on);とかだと常にHTTPSの通信と伝えられてしまうみたいなので、

  location / {
          if ($scheme = "https"){
              set $mode "on";
          }
          proxy_set_header X-Forwarded-HTTPS $mode;
  }

のように条件式を入れて使っています。

リダイレクト用 テンプレートを用意する

HTTPS -> HTTP にリダイレクトする場合にどうしてもうまくいかないのでリダイレクト用のテンプレートを使います。

<head>
  <meta http-equiv="refresh" content="0;url=<%= $self->req->url->to_abs->scheme('http') %>">
</head>

mojolicious

sub startup {
  $self = shift;
....

  # Routes
  my $routes = $self->routes;

  # SSL onry
  my $ssl_rotes = $routes->under(
    sub{
      my $self = shift;
      return 1 if $self->req->is_secure;
      $self->redirect_to($self->req->url->to_abs->scheme('https'));
    }
  );

  # http onry
  my $not_ssl_routes = $routes->under(
    sub{
      my $self = shift;
      return 1 if !$self->req->is_secure;
      # $self->redirect_to($self->req->url->to_abs->scheme('http')); # これだとリダイレクトが無限ループする
      $self->render(template =>'redirect');
    }
  );

  # SSL onry route
  $ssl_rotes->route('/login')->to('login#index');
  $ssl_rotes->route('/join')->to('join#index');

  # not SSL routes
  $not_ssl_routes->route('/')->to('top#index');
  $not_ssl_routes->route('/entry/:id', id => qr/\d+/)->to('entry#index', id => 1 );

  # Any Routes
  $routes->route('/:controller')->to(action => 'index');
  $routes->route('/:controller/:action')->to();
  $routes->route('/:controller/:action/:id')->to();
}

なんかイマイチ納得行かないけれど妥協。

おまけ

確認方法

opensslを使ってコマンドラインで確認してみるとLocationヘッダがhttpsになっているのが確認できる。

$ openssl s_client -connect localhost:443
...
    Start Time: 1383817749
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
GET / HTTP/1.1
Host:local

HTTP/1.1 302 Found
Server: nginx/1.4.3
Date: Thu, 07 Nov 2013 09:49:29 GMT
Content-Length: 0
Location: https://local/
Connection: keep-alive

Filed under: Mojolicious

Trackback Uri






2013年 11月 3

リバースプロキシの後ろでwebアプリを動かすテストしたいのでlocal環境にNginxを入れる。

Nginxのインストール

$ sudo port install nginx +ssl

追記:SSLを使う場合は +ssl が必要みたい
A Guide to PHP, MySQL and Nginx on Macports

設定ファイルを作成

$ cd /opt/local/nginx
$ sudo cp nginx.conf.default nginx.conf
$ sudo cp mime.types.default mime.types

Nginx起動

$ sudo nginx

ブラウザで検証

ブラウザでhttp://localhost にアクセス
safariでNginxの確認

おk


Filed under: Mac,開発環境

Trackback Uri






2013年 5月 5

問題点

この問題は Mojoliciousでhttps(SSL)専用ページとhttp専用ページの振り分けをroutesのbridgeを使って行うを実装した時に起こる問題です。

件のエントリーの実装でもスタンドアロンのサーバで公開する場合には問題にならないのですが、Nginx等のリバースプロクシの後ろにアプリケーションサーバを置いて運用する場合に問題が起きます。

通常、webサーバであるNginxとクライアントの間ではSSL通信を行い、バックエンドのアプリケーションサーバ(Starman等)とNginxの間では通常のhttpで通信すると思います。

           SSL通信
クライアント   ---   Nginx
                     |     http通信
                   Starman

この場合だと、件のエントリーの

  # SSL onry routes
  my $ssl_rotes = $routes->bridge->to(
    cb => sub{
      my $self = shift;
 
      my $req = $self->req;
      return 1 if $req->is_secure;
      
      $self->redirect_to($req->url->to_abs->scheme('https'));
      return;
    }
  );

ようにschemeで判定してhttps~にリダイレクトする場合、Nginxとアプリケーションは常にhttpで通信しているのでリダイレクトが無限ループしてしまいます。

Nginxとアプリケーション間をSSLにすればよいのですが、(アプリケーション側の)ポートを開けたり指定しなくてはならなくなったりと色々面倒なことになりそうです…。

対策

Nginxの設定でリダイレクトを使うか、SSLの場合はリンクをhttpsで指定するかしか無さそう。

例えばstartupの中で下記のようなhelperを定義して、

  # helper method
  $self->helper(
    url_for_http => sub {
      my $self = shift;      
      my $url = $self->url_for(@_)->to_abs->scheme('http');
      return $url;
    }
  );
  $self->helper(
    url_for_https => sub {
      my $self = shift;      
      my $url = $self->url_for(@_)->to_abs->scheme('https');
      return $url;
    }
  );

templateで

<%= link_to url_for_http('/') => begin %>httpを強要<% end %>
<%= link_to url_for_https('/ssl_onry') => begin %>セキュアなページへのリンク<% end %>

のように使うしか無いのかな。


Filed under: Mojolicious

Trackback Uri






2012年 10月 16

epelでNginxをyumでインストールする場合、バージョンが0.8.55と古い。

================================================================================
 Package         Arch         Version                    Repository        Size
================================================================================
Installing:
 nginx           i386         0.8.55-2.el5               epel             390 k
Installing for dependencies:
 gd              i386         2.0.33-9.4.el5_4.2         base             154 k
 geoip           i386         1.4.6-1.el5.rf             rpmforge         782 k
 libXpm          i386         3.5.5-3                    base              45 k
 libxslt         i386         1.1.17-4.el5_8.3           updates          420 k

Transaction Summary
================================================================================
Install       5 Package(s)
Upgrade       0 Package(s)

Nginx公式リポジトリを使えば簡単に最新版のNginxをインストールできるようです。

  • CentOS-6へ最新版のnginxを3分でインストールする方法 – Y-Ken Studio
  • nginx: download にRHEL 5, RHEL 6, CentOS 5, CentOS 6 用のリポジトリが用意されています。

    リポジトリを登録

    OSのバージョンにあったリポジトリをインストールします。

    # rpm -ivh http://nginx.org/packages/centos/5/noarch/RPMS/nginx-release-centos-5-0.el5.ngx.noarch.rpm

    インストール

    # yum install nginx
    
    
    ==================================================================================
     Package         Arch           Version                     Repository       Size
    ==================================================================================
    Installing:
     nginx           i386           1.2.3-1.el5.ngx             nginx           350 k
    
    Transaction Summary
    ==================================================================================
    Install       1 Package(s)
    Upgrade       0 Package(s)
    
    Total download size: 350 k
    Is this ok [y/N]: y
    

    Filed under: CentOS5.x,インストールメモ,サーバ管理

    Trackback Uri