Unselected Kids Blog

プログラミングを中心に好きなことを好きなように書くブログ

Centos7 + Nginx + Ruby on Rails をVPSにセットアップ その1

はじめに

自分用の備忘録です.
参考にしたURLを貼っているのでそこも読みつつ進めていってください.

セキュリティの初期設定に関しては以下のチェックシートを参考にしながらやってます.
セキュリティ対策チェックリスト [VPS・CentOS7編] - Qiita

初期設定

yum update

sudo yum -y update

ユーザ作成とsudo許可

CentOSでuserをsudo可能にする - Qiita

$ useradd sampleuser
$ passwd sampleuser
$ visudo

sampleuserにsudoを許可

sampleuser  ALL=(ALL)       ALL

sshをprot22から変更

CentOS7でSSHのポート番号を変更する - Qiita
22番ポートは攻撃の対象となるので2222番ポートに変更する.

vi /etc/ssh/sshd_config

sshd_configのProtを 22 から 2222 に変更

- # Port 22
+ Port 2222
#sshdを再起動
systemctl restart sshd
# ssh.xmlのコピーのssh-2222.xmlを作成
cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh-2222.xml
vi /etc/firewalld/services/ssh-2222.xml

/ssh-2222.xml を編集

-  <port protocol="tcp" port="22"/>
+  <port protocol="tcp" port="2222"/>
#2222ポートを許可
firewall-cmd --permanent --add-service=ssh-2222
#ssh(22ポート)のfirewallの許可一覧から削除
firewall-cmd --remove-service=ssh --zone=public --permanent
#firewallを再起動
firewall-cmd --reload

作成したユーザに秘密鍵公開鍵認証ログインを設定

ローカルPCにて鍵作成と鍵送信

ssh-keygen
cd .ssh
mv id_rsa vps_rsa
mv id_rsa.pub vps_rsa.pub
chmod 0600 vps_rsa vps_rsa.pub
#scpで鍵を送信
scp ./vps_rsa.pub sampleuser@ip

リーモートサーバにて鍵のセットアップ

mv vps_rsa.pub .ssh/authorized_keys

ローカルからsshができるか確認[sampleuser@ip ~]$になれば成功している.

ssh -i .ssh/id_rsa.pub sampleuser@ip

ローカルで ssh config もついでに書いておく.

Host vps
     HostName ip
     Port     2222
     IdentityFile ~/.ssh/vps_rsa
     User sampleuser

rootユーザへ直接ログインを禁止

rootでのSSHログインを禁止 - SSHサーバーの設定 - Linux入門 - Webkaru
configにてルートログインを禁止

sudo vim /etc/ssh/sshd_config
- PermitRootLogin yes
+ PermitRootLogin no
# sampleuser だけ ssh を許可
+ AllowUsers sampleuser

sshd を再起動

sudo systemctl restart sshd

パスワードログインを禁止

[CentOS]sshのパスワード認証方式を無効にする | ごった煮 - tips about programming and building a server
よりセキュア―な秘密鍵認証を利用するのでパスワードログインを禁止.
必ず秘密鍵認証でログインできることを確認してから行ってください.

sudo vim /etc/ssh/sshd_config
- PermitEmptyPasswords yes
- PasswordAuthentication yes
+ PermitEmptyPasswords no
+ PasswordAuthentication no

sshd を再起動

systemctl restart sshd

Denyhosts 導入

CentOSでSSHへのブルートフォースアタック(総当り)への対策2
何度もログインを試みるIPをブロックする Denyhosts を導入する.

yum install denyhosts
systemctl start denyhosts
systemctl enable denyhosts

/etc/denyhosts.confの以下のように編集

# ログインが成功した場合にリセットする(たまに失敗したりしていつか入れなくならないように)
+ RESET_ON_SUCCESS = yes
- #RESET_ON_SUCCESS = yes

ログインできなくなった時は以下のファイルから自分のipアドレスを削除しましょう.

/etc/hosts.deny
/var/lib/denyhosts/hosts
/var/lib/denyhosts/hosts-restricted
/var/lib/denyhosts/hosts-root
/var/lib/denyhosts/hosts-valid
/var/lib/denyhosts/users-hosts

Nginxセットアップ

パッケージのみで CentOS の Nginx を HTTP/2 対応にする - Qiita

インストール・起動・デフォルトで再起動設定

yum -y install epel-release 
yum -y install nginx  
systemctl enable nginx  
systemctl start nginx
systemctl status nginx.service

http、httpsをfirewallの許可一覧に追加
最後のfirewall のstatsの public に http、https が追加されていれば完了

firewall-cmd --permanent --add-service=http 
firewall-cmd --permanent --add-service=https
firewall-cmd --add-service=https 
firewall-cmd --reload
firewall-cmd --list-all-zones

Nginx セキュリティの設定

ここを見ながら設定していきました.
nginx/Railsのセキュリティ対策メモ - Qiita

ここから設定する項目の意味はここに載っているので読んでおきましょう.

セキュリティを強化する7つの便利なHTTPヘッダ

Nginxのバージョン番号を返さない

まずバージョン依存の虚弱性をつかれないようにNginxのバージョン情報などをレスポンスとして返さないようにする. /etc/nginx/niginx.confに以下を追加

http{
# Nginxのバージョン番号をエラーページとServer headerに含まれないようにします
server_tokens off;

X-XSS-Protection

「X-XSS-Protection」はWebブラウザのクロスサイトスクリプティングXSS)に対するフィルタ機能をを強制的に有効にするというものです.
/etc/nginx/conf.d/default.conf

#XSS対策
add_header X-XSS-Protection "1; mode=block";

ちなみにRailsを利用する場合にはデフォルトで設定されるので設定不要

Content-Security-Policy

Content-Security-Policy (以下CSP) を利用する場合、実行を許可するスクリプトの正しいドメインをブラウザに向けて指定することにより、XSS の発生する箇所を削減・根絶することができます。CSP をサポートするブラウザは、サーバから指定されたホワイトリストに載っているドメインスクリプトのみ実行し、他のスクリプトはすべて無視します。

Content Security Policy (CSP) - HTTP | MDN
/etc/nginx/conf.d/default.conf に以下を追記

add_header Content-Security-Policy "default-src 'self'";

Strict-Transport-Security

通常http通信をhttps通信にリダイレクトすると思います.この時ユーザ側は一旦http通信を行ってしまうので中間者攻撃を受けてしまうリスクが生じます.
Strict-Transport-Securityを利用することでWeb サイトはブラウザに対して、そのサイトでは HTTP を使用せず、代わりに HTTPS へ置き換えてアクセスすることを試みるように伝達することが可能になります.
HTTP Strict Transport Security - Web セキュリティ | MDN
/etc/nginx/conf.d/default.conf に以下を追記

add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";

X-Frame-Options(クリックジャッキング対策)

クリックジャッキング対応として、自身と生成元が同じフレーム内に限りページを表示する設定をします.
/etc/nginx/conf.d/default.conf に以下を追記

add_header X-Frame-Options SAMEORIGIN;

X-Content-Type-Options

サーバーが応答ヘッダー "X-Content-Type-Options: nosniff" を送信する場合、script 要素と styleSheet 要素は、誤った MIME タイプでの応答を拒否します。これは、MIME タイプの問題を悪用した攻撃を防ぐためのセキュリティ機能です。 MIME タイプのセキュリティ リスクの軽減 (Windows)

/etc/nginx/conf.d/default.conf

add_header X-Content-Type-Options nosniff;

設定を反映

Nginx を再起動して Welcame to Nginx が表示されれば完了.

systemctl restart nginx

Ruby on Rails のセットアップ

依存パッケージインストール

yum install gcc-c++ glibc-headers openssl-devel readline libyaml-devel readline-devel zlib zlib-devel git

rbenvインストール

git clone https://github.com/sstephenson/rbenv.git /usr/local/rbenv
echo 'export RBENV_ROOT="/usr/local/rbenv"' >> /etc/profile
echo 'export PATH="${RBENV_ROOT}/bin:${PATH}"' >> /etc/profile
echo 'eval "$(rbenv init -)"' >> /etc/profile

ruby-buildインストール

git clone https://github.com/sstephenson/ruby-build.git /usr/local/rbenv/plugins/ruby-build

Ruby install

お手元のバージョンをお使いください.
インストールとバージョンを指定

rbenv install -v 2.5.0
rbenv global 2.5.0

Ruby on Rails install

gem update --system
gem install --no-ri --no-rdoc rails
gem install bundler
rbenv rehash

Rails アプリの作成

Railsアプリを作成して / にアプセスすると hoge を表示する.

rails new sample
cd sample 
rails g controller index
vim app/view/index/index.html.erb # hogeを表示する
vim config/routes.rb # root :to => 'web#index'

Unicorn セットアップ

Nginx + Unicorn + Rails - Qiita
Gemfile に unicorn を追加

- gem 'puma'
+ gem 'uncorn'
bundle install

uncornの設定ファイルを以下のように作成する. /config/unicron.rb

File.expand_path: https://ruby-doc.org/core-2.2.0/File.html#method-c-expand_path
rails_root = File.expand_path('../../', __FILE__)
worker_processes 2
working_directory rails_root

listen "#{rails_root}/tmp/unicorn.sock" 
pid "#{rails_root}/tmp/unicorn.pid" 

stderr_path "#{rails_root}/log/unicorn_error.log"
stdout_path "#{rails_root}/log/unicorn.log"

デーモン化起動

unicorn_rails -c config/unicorn.rb -E development -D

停止

ps ax|grep unicorn|grep -v grep
kill 番号

Nginx と Unicorn を接続

defaultを直接いじる前にバックアップはとっておきましょう.
/etc/nginx/conf.d/default.conf

upstream unicorn {
  server unix:/Rails_root_path/tmp/unicorn.sock;
}

server {
    listen       80;
    server_name  localhost;

    add_header Content-Security-Policy "default-src 'self'";
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;

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

Nginxリスタート

systemctl restart nginx

これで hoge が表示されれば設定は完了です.