ねことわたしとITと

技術系で興味のある事をお勉強がてらアウトプットしていきたいという願望

【スポンサーリンク】

初めてVPSを使ってみる話<Ansibleで初期設定編>

さた(@nuko_me)です。土曜日は遂にこのはちゃんと契約するに至りました。今までのシリーズはこんな感じ。

egg-sata.hateblo.jp
egg-sata.hateblo.jp

日曜日は1日休みだったので手元のMacから構成管理ツールのAnsible使ってリモートで最低限の初期設定をしちゃいました!
今回はその一連の流れを書いていきます。

Andibleって?

www.conoha.jp

上の記事に詳細に書かれてるので多分そちらを参照すると良いと思います。心の中では"あんしぶる"と呼んでいるんですが実際のとこどうなんでしょう?
簡単に言うと、サーバの構成をYAMLという形式で記述する事で、自動でセットアップ出来る便利ツールです。
1台のサーバにAnsibleをインストールする事で、複数台の構成をまとめて管理する事が出来ます。

お仕事でもAnsible使ってみたいねーって声が出てたりしていたので今回お勉強のために使ってみたいと思います!

初期設定と構成

今回ConoHaで立てたサーバGinoに施したい初期設定は以下の4点です。

①管理ユーザ(sata)を作ってsudo出来るようにする。
SSHのポート番号を変える。
③rootでログイン出来ないようにする。
④管理ユーザは秘密鍵でしかログインできないようにする。

・・・うん、本当に最低限の設定ですね。適当にしゅばばとやってもいいのですがここはAnsibleで。

構成は以下のとおりです!

OS X El Capitan ← Ansible導入
・ConoHa VPS (Gino)

ConoHaの方には特に何も入れる必要はありません。
構成管理ツールにはChefとか色々ありますが、管理する側とされる側双方にツールをインストールするのが面倒なので、片方にだけインストールすれば良いAnsibleは楽なのです。

Macで事前準備

今後の運用のために事前に準備をしておきます。
まず、さたさんはサーバ作成した際に鍵認証の設定をしています。sshコマンドを使う際に一々鍵のパスを指定するのは面倒なのでコンフィグファイルを作成して予め指定しておきます。

~/.ssh/config
Host Gino
	Hostname ***.***.***.***
	Port 10022
	User sata
	IdentityFile 秘密鍵のパス
Host ***.***.***.***
	Hostname ***.***.***.***
	User root
	IdentityFile 秘密鍵のパス
	IdentitiesOnly yes

初期設定用のrootログインと運用用とて分けています。事前に初期設定用のでログインできるか試しておきましょう。

$ ssh ***.***.***.***

Ansibleを入れてみる

手元のMacでAnsibleをインストールします。事前にHomebrewをインストールしておく必要があります。

$ brew update
$ brew install ansible

インストールが出来たら入ってるか忘れずに確認しましょう。

$ ansible --version
ansible 2.0.0.2

hostsを設定する

Ansibleを入れたら管理サーバの情報をinventoryファイルに記述します。
ファイル名はhostsとかにしましょう。デフォルトの/etc/ansible/hostsに上書きする形でもいいし、好きな場所に置いておいてもOKです。
書き方は以下の通り。

[ConoHa_root]
	***.***.***.***
[ConoHa]
	Gino:10022

[]の中にはAnsibleで用いる名前を付けましょう。下にはIPアドレスを定義しますが、~/.ssh/configで指定した名称を使うとわざわざIPアドレスを書かなくても大丈夫になります。
ポート番号が22番じゃない場合はちゃんと指定してあげましょう。

この後一応念のために疎通しているか確認をしましょう。

$ ansible ***.***.***.*** -i hostsのパス -m ping
***.***.***.*** | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

コマンドを叩いて上記のようにSUCCESSが出てきたら疎通成功です。

Playbookを書いてみる

hostsの設定が出来たら命令を実行させるために必要なPlaybookを書いていきます。
このPlaybookはYAMLという形式で書きますがよくよく読むと結構シンプルで分かりやすいです。
ひとまず今回は初期設定用に作ったのを紹介します。

conoha_init.yml
- hosts: ConoHa_root
  user: root 
  vars: 
    user_name: sata
    user_password: $*$****$*********************
    ssh_port: 10022
  tasks:
    - name: change SSH port
      lineinfile: dest=/etc/ssh/sshd_config regexp="^#Port" line="Port {{ ssh_port }}" state=present

    - name: allow port 22 > 10022
      lineinfile: dest=/etc/sysconfig/iptables regexp="^-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT" line="-A INPUT -m state --state NEW -m tcp -p tcp --dport {{ ssh_port }} -j ACCEPT" state=present
      notify: restart iptables

    - name: disallow root SSH access
      lineinfile: dest=/etc/ssh/sshd_config regexp="^#PermitRootLogin yes" line="PermitRootLogin no" state=present

    - name: disallow password authentication
      lineinfile: dest=/etc/ssh/sshd_config regexp="^#PasswordAuthentication " line="PasswordAuthentication no" state=present
      notify: restart sshd

    - name: Add a new user
      user: name={{user_name}} password={{ user_password }} groups=wheel state=present

    - name: allow wheel users to sudo
      lineinfile: dest=/etc/sudoers regexp="^#\s*(%wheel\s+ALL=\(ALL\)\s+NOPASSWD{{':'}}\s+ALL)" line="\1" backrefs=yes state=present

    - name: copy a public key
      shell: cp /root/.ssh/authorized_keys /home/{{user_name}}/.ssh/authorized_keys

    - name: owner change public key
      shell: chown -R {{user_name}}:wheel /home/{{user_name}}/.ssh/authorized_keys

  handlers:
    - name: restart sshd
      service: name=sshd state=restarted

    - name: restart iptables
      service: name=iptables state=restarted

ではPlaybookの中身についてじっくりと見ていきましょー!

定義部分
- hosts: ConoHa_root
  user: root 
  vars: 
    user_name: sata
    user_password: $*$****$*********************
    ssh_port: 10022

hostsの部分にはhostsに定義した名称を記します。userの部分にはこのPlaybook実行時に用いるSSHユーザを指定します。
varsでは変数を定義して、ユーザ名やユーザパスワードは最初の部分で変数化しています。
ちなみにパスワードは予め以下コマンドでHash化したものをあてています。

$ openssl passwd -salt **** -1 ********
SSHポート番号変更
    - name: change SSH port
      lineinfile: dest=/etc/ssh/sshd_config regexp="^#Port" line="Port {{ ssh_port }}" state=present

    - name: allow port 22 > 10022
      lineinfile: dest=/etc/sysconfig/iptables regexp="^-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT" line="-A INPUT -m state --state NEW -m tcp -p tcp --dport {{ ssh_port }} -j ACCEPT" state=present
      notify: restart iptables

nameにはタスク名を付けます。どんな命令なのか分かりやすい名前にしましょう。

「change SSH port」タスクでは、/etc/ssh/sshd_config内の#Portの部分をPort 10022に置換するという命令を出しています。
ちなみに最初に定義した変数は{{ 変数名 }}で使う事が出来るので、何度も使用する場合は積極的に使うのです。

「allow port 22 > 10022」タスクでは、iptablesで元々許可を出していた22番ポートを10022番ポートへの許可に切り替えるよ、置換するよという命令を出しています。
このタスクの後notifyで定義された「restart iptables」が動きますが、説明は後ほど。

rootでのSSH禁止
    - name: disallow root SSH access
      lineinfile: dest=/etc/ssh/sshd_config regexp="^#PermitRootLogin yes" line="PermitRootLogin no" state=present

「disallow root SSH access」タスクでは/etc/ssh/sshd_config内の#PermitRootLogin yesをPermitRootLogin noに置換するよという命令を出しています。

SSH認証でのパスワード禁止
    - name: disallow password authentication
      lineinfile: dest=/etc/ssh/sshd_config regexp="^#PasswordAuthentication " line="PasswordAuthentication no" state=present
      notify: restart sshd

このタスクも上記同様置換命令ですね。PasswordAuthenticationの部分をコメントを外してnoにしています。
このタスクの後notifyで定義された「restart sshd」が動きますが、説明はこれまた後ほど。

管理用ユーザ追加とsudo許可
    - name: Add a new user
      user: name={{user_name}} password={{ user_password }} groups=wheel state=present

    - name: allow wheel users to sudo
      lineinfile: dest=/etc/sudoers regexp="^#\s*(%wheel\s+ALL=\(ALL\)\s+NOPASSWD{{':'}}\s+ALL)" line="\1" backrefs=yes state=present

「Add a new user」タスクで管理用ユーザを作成します。
「allow wheel users to sudo」タスクでは/etc/sudoersファイルにて、作成した管理用ユーザに対してパスワード無しでのsudoの許可設定を施しています。

公開鍵コピー
    - name: copy a public key
      shell: cp /root/.ssh/authorized_keys /home/{{user_name}}/.ssh/authorized_keys

    - name: owner change public key
      shell: chown -R {{user_name}}:wheel /home/{{user_name}}/.ssh/authorized_keys

「copy a public key」タスクでは、rootユーザの公開鍵を管理用ユーザのホームディレクトリ内の.sshにコピーしています。
また、「owner change public key」でコピーした公開鍵の所有権を管理用ユーザに変えています。

各種設定反映のための再起動
  handlers:
    - name: restart sshd
      service: name=sshd state=restarted

    - name: restart iptables
      service: name=iptables state=restarted

handlersではtask処理後の動きを定義する事が出来ます。task内のnotifyで、handlersで定義した名称を指定します。
「restart sshd」「restart iptables」それぞれ各サービスの再起動を定義しています。

こんな感じで初期設定用にPlaybookを作成してみました。

Ansibleを実行してみる

それでは早速作成したPlaybookを使ってみます。使用する際は以下のコマンドを使います。

$ ansible-playbook -i hostsのパス Playbookのパス

実行するとこんな感じで結果が返ってきます。

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [***.***.***.***]

TASK [change SSH port] *********************************************************
changed: [***.***.***.***]

TASK [allow port 22 > 10022] ***************************************************
changed: [***.***.***.***]

TASK [disallow root SSH access] ************************************************
changed: [***.***.***.***]

TASK [disallow password authentication] ****************************************
changed: [***.***.***.***]

TASK [Add a new user] **********************************************************
ok: [***.***.***.***]

TASK [allow wheel users to sudo] ***********************************************
ok: [***.***.***.***]

TASK [copy a public key] *******************************************************
changed: [***.***.***.***]

TASK [owner change public key] *************************************************
changed: [***.***.***.***]
[WARNING]: Consider using file module with owner rather than running chown


RUNNING HANDLER [restart sshd] *************************************************
changed: [***.***.***.***]

RUNNING HANDLER [restart iptables] *********************************************
changed: [***.***.***.***]

PLAY RECAP *********************************************************************
***.***.***.***            : ok=11   changed=8    unreachable=0    failed=0

failedが1個も無くてとりあえずokとかchangedが出ていれば成功です。
おおお、こんな1ファイルにこねこね書くだけで設定完了するとか楽すぎる・・・!

最後に

今回は初期設定だけやってみましたがWordpressのインストールとか一通りの設定もこれでやっていきたいですね!
ちなみに今回Ansibleを使うにあたっては以下の記事も参考にさせていただきました!

qiita.com
qiita.com

次回はドメインの設定とかApacheとかnginxとかやりたいなあって思ってます。