tjinjin's blog

インフラ要素多めの個人メモ

nginxの基本的な設定をやってみた

仕事でnginxを触る機会があり(というか奪い取り)、まったくわからなかったので検証しました。

到達目標

  • nginxで受けたリクエストをunicornに連携
  • アクセスログをltsvの形式で出力する
  • 特定ディレクトリ配下のIPを制限する
  • 静的ファイルをnginx側で返却する(ストア)
  • ファイルサイズの制限をする
  • httpsでアクセスする

環境構築

railsでサンプルアプリを作成する

こちらのサイトを参考にさせていただきました。

qiita.com

nginxをインストールする

  • MacでやってたのでHomebrewで導入しました。
$ brew install nginx

検証する

nginx -> unicornへ連携する

Homebrewで導入すると/usr/local/etc/nginxに設定ファイルがあるので、修正します。unicorn側でsocketを指定してnginx側でproxyとしてそのsocketにリクエストをフォワードするイメージですね。

# httpディレクティブ内
    server {
        listen       8080;
        server_name  test;

        root <application_directory>/unicorn_sample/;

        error_page   500 502 503 504  /50x.html;
        try_files $uri/index.html $uri @unicorn;

        location @unicorn {
                   proxy_set_header X-Real-IP $remote_addr;
                   proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
                   proxy_set_header Host $http_host;
                   proxy_pass http://unicorn;
        }
    }

    upstream unicorn {
        server unix:/tmp/unicorn.sock;
    }
  • @unicornの部分は名前付きロケーションで、そのブロックには直接アクセスされません。この例ではtry_filesのブロックからアクセスされます。try_filesでは指定されたパラメータ順にファイルの存在がチェックされ、マッチしたものをレスポンスとして返却されます。前から順にファイルの参照を行いなければ@unicornに対して同じ処理を継続してくれます。

ログをLTSV形式にする。

これは簡単でnginx.confもしくは各サーバのconf内のlog_formatの形式を変更し、access_logの部分でltsfを指定すればよいみたいです。LTSVとはLabeled Tab-Separated Valueでfluentdなどで扱い易い形式です。

log_format ltsv  "time:$time_local"
                      "\thost:$remote_addr"
                      "\tforwardedfor:$http_x_forwarded_for"
                      "\treq:$request"
                      "\tstatus:$status"
                      "\tsize:$body_bytes_sent"
                      "\treferer:$http_referer"
                      "\tua:$http_user_agent"
                      "\treqtime:$request_time"
                      "\tvhost:$host";
    access_log  logs/access.log  ltsv;

nginxのログファイルを確認し、LTSV形式になっていることが確認できました。

特定ディレクトリへのアクセスを禁止する

管理コンソールなどの管理者画面は一般ユーザからの覗かれてはいけない部分です。なので、その場合はIPで制限します。今回は検証なので、静的コンテンツに対しアクセス禁止させてみます。

location /assets/ {
    deny all;
}

公開ディレクトリ配下に/assets/があり、そこを見せないようにしました。制限前は通常にアクセスできましたが、設定後nginxの再起動をすると403でエラーとなるようになりました。locationブロック内の指定は上から読まれるみたいなので、一番はじめにdeny all;とするとその後の設定に関係なく誰もアクセスできないようです。

 location /assets/ {
     allow  192.168.0.0/24;
     deny all;
}

上記設定だと192.168.1のネットワークからの通信は許可され、その他は拒否されました。

静的ファイルをnginx側で返却する

公開用のディレクトリを作成し、URIをチェックしファイルが存在する場合はそのファイルを返却します。location毎に設定を分けることで実現できます。

location /assets/ {
            root /var/www/test/current/public;
        }

        location ~* /(robots.txt|favicon.ico) {
            root /var/www/test/current/public;
        }

        location / {
            proxy_pass http://unicorn;
            break;
        }

上記の例ではassetsに対するアクセスとrobotx.txt/faicon.icoファイルへのアクセスについては公開ディレクトリを探し、その他についてはunicornへ連携されます。最初に書いたunicornの設定と違う書き方にしてみましたが、どっちがいいんですかね。あとで調べたいと思います。

ファイルサイズを制限する

ファイルアップロードなどをする際にnginxで止めずにバックエンドに連携するために設定です。デフォルトでは1Mなので、それを超える際にはclient_max_body_sizeを指定する必要があります。ただし、10Mのファイルも実際はすこし大きくなるので多めに見積もるようです。これを超えると413エラーが返却されます。

client_max_body_size 10m;

httpsでアクセスする

httpsでnginxは待ち受けさせます。

おれおれ証明書を作成する

$ openssl req -newkey rsa:2048 -nodes -out test.csr -keyout test.key
Generating a 2048 bit RSA private key
# 適当に入力
$ openssl x509 -req -days 365 -in test.csr -signkey test.key -out test.crt

作成後、設定ファイルの書き換えを実施します。

server {
        listen 4443 default ssl;
        ssl_prefer_server_ciphers on;
        ssl_protocols TLSv1;
        ssl_ciphers RC4:HIGH:!aNULL:!MD5:@STRENGTH;
        ssl_session_cache shared:WEB:10m;
        ssl_certificate /usr/local/etc/nginx/test.crt;
        ssl_certificate_key /usr/local/etc/nginx/test.key;
        location / {
          proxy_set_header X-FORWARDED-PROTO https;
          proxy_pass http://unicorn;
        }

作成したcrtとkeyを指定してやり、unicornに流すときはhttpにしました。(httpsでもできるみたいだが、unicornにも設定が必要みたいです。)とりあえずということで設定は適当なので、マネは非推奨です。

ブラウザから安全でないページとの警告がありますが、構わずアクセスしてhttpsでアクセスすることを確認できました。

まとめ

実際に使うとなるとコンテンツの圧縮やキャッシュの最適化など、もっとチューニングできるところがあると思います。パフォーマンス・チューニングできるスキルをつけていきたいと思います。

参考

nginx + unicorn + Railsの設定方法 - Qiita

macにHomebrewでnginxを入れて起動してみる - source

Rails 4.2 + Unicorn + Nginx でアプリケーションサーバの構築 - Qiita

nginx連載5回目: nginxの設定、その3 - locationディレクティブ - インフラエンジニアway - Powered by HEARTBEATS

nginx documentation

LTSV FAQ - LTSV って何? どういうところが良いの? - naoyaのはてなダイアリー

Nginx で location の判定方法と優先順位を調べる | レンタルサーバー・自宅サーバー設定・構築のヒント