【Nginx】httpからhttpsに自動でリダイレクトする方法

はじめに

最近、アプリエンジニアからインフラエンジニアに片足突っ込みがちなことを
やっており、件名の通りのことをやったのでメモ。

環境

  • Nginx 1.10.1で動作確認しています。
  • アプリ単位でconfファイルが作成されていること。
  • Nginx + unicorn + Ruby on Railsでアプリを作成しています。

前提条件

  • SSLオレオレ証明書発行済で、とりあえずTOPページが表示できること。
  • confファイルは「sample.conf」とします。
  • nginx.confからsample.confを呼び出せること。

解決策

まず、nginx.confからsample.confを使えるようにします。

# /etc/nginx/nginx.conf
user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log;
pid       /var/run/nginx.pid;

events {
  worker_connections 1024;
}

http {
  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  log_format ltsv 'domain:$host\t'
                  'host:$remote_addr\t'
                  'user:$remote_user\t'
                  'time:$time_local\t'
                  'method:$request_method\t'
                  'path:$request_uri\t'
                  'protocol:$server_protocol\t'
                  'status:$status\t'
                  'size:$body_bytes_sent\t'
                  'referer:$http_referer\t'
                  'agent:$http_user_agent\t'
                  'response_time:$request_time\t'
                  'cookie:$http_cookie\t'
                  'set_cookie:$sent_http_set_cookie\t'
                  'upstream_addr:$upstream_addr\t'
                  'upstream_cache_status:$upstream_cache_status\t'
                  'upstream_response_time:$upstream_response_time';

  access_log /var/log/nginx/access.log ltsv;
  sendfile on;
  keepalive_timeout 65;

  upstream sample_app {
    # Ruby on Railsでunicornを使う場合の設定
    server unix:/var/www/sample_app/current/tmp/sockets/unicorn.sock
    fail_timeout=0;
  }

  include /etc/nginx/conf.d/*.conf;
}

ログフォーマット以外はほぼ初期設定のままです。

次にsample.confです。

# /etc/nginx/conf.d/sample.conf
server {
  listen 80;
  server_name sample_app;
  # ここがポイント
  return 301 https://$host$request_uri;
}

server {
  listen 443;
  server_name sample_app;

  ssl                  on;
  ssl_certificate      /etc/nginx/ssl/server.crt;
  ssl_certificate_key  /etc/nginx/ssl/server.key;

  ssl_session_timeout  5m;

  ssl_protocols  SSLv2 SSLv3 TLSv1;
  ssl_ciphers  HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers   on;

  root /var/www/sample_app/current/public;

  location ~ ^/assets/ {
    include /etc/nginx/mime.types;
    root    /var/www/sample_app/current/public;
  }

  location / {
    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_set_header X-Forwarded-Proto https;
    proxy_redirect off;
    proxy_connect_timeout   300;
    proxy_send_timeout      300;
    proxy_read_timeout      300;

    if (!-f $request_filename) {
      proxy_pass http://sample_app;
      break;
    }
  }
}

ポイントとしては、80ポートで受付した際に301でリダイレクトするところです。
こうすればhttpでアクセスされても、httpsにリダイレクトされて処理されます。

インフラ周りは素人ですが、なんとか設定することができました。
Javaのアプリエンジニアばかりやっていので、Apache周りの設定はわかりませんが
Nginxの方がシンプルに記述できるので、とても好きです。
これからもちょくちょくNginxを触っていこうと思います。