AnsibleでVPSの初期設定

### VPSの初期状態

- rootユーザーでSSHログイン許可
- ポートの制限なし


### やること

- rootユーザーでのSSHログイン禁止
- パスワードによるSSHログイン禁止
- ユーザーeiryuの作成（パスワードはpassword）
- Ansibleを実行するホストのホームディレクトリにある公開鍵を上記で作成したユーザーのホームディレクトリに配備
- SSH、HTTP、HTTPSなど必要ポートだけ外部からの通信を許可する設定にする


## 出来たもの

```bash
$ tree
.
├── hosts
├── iptables.j2
└── playbook.yml
```

```ansible:hosts
[vps]
xxx.xxx.xxx.xxx   # VPSのIP
```

```yaml:playbook.yml
- hosts: vps
  user: root
  vars:
    username: eiryu
    password: $1$t5VveYVT$IeumD04se5PDChz9PTWTk1
    ssh_port: 22

  tasks:
    - name: create iptables
      template: src=iptables.j2 dest=/etc/sysconfig/iptables
      notify: restart iptables

    - name: add user
      user: name={{ username }} password={{ password }} state=present

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

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

    - name: resister a public key
      authorized_key: user={{ username }} key="{{ lookup('file', '~/.ssh/id_rsa.pub') }}"




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

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

```iptables.j2
# Generated by iptables-save v1.4.21 on Sat Aug 29 17:58:08 2015
*nat
:PREROUTING ACCEPT [3025:191667]
:POSTROUTING ACCEPT [491:40221]
:OUTPUT ACCEPT [491:40221]
COMMIT
# Completed on Sat Aug 29 17:58:08 2015
# Generated by iptables-save v1.4.21 on Sat Aug 29 17:58:08 2015
*mangle
:PREROUTING ACCEPT [9336:2368496]
:INPUT ACCEPT [9336:2368496]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [6960:747028]
:POSTROUTING ACCEPT [6960:747028]
COMMIT
# Completed on Sat Aug 29 17:58:08 2015
# Generated by iptables-save v1.4.21 on Sat Aug 29 17:58:08 2015
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [4:464]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport {{ ssh_port }} -j ACCEPT
COMMIT
# Completed on Sat Aug 29 17:58:08 2015
```

以下コマンドで実行してrootパスワードを入力するとプロビジョニングが始まる。

`ansible-playbook -i hosts -vvvv playbook.yml --ask-pass`


### 考慮した点

sshdが再起動されるとrootで繋げなくなってしまうので、sshdの再起動はhandlersの最後に書いた。このことからAnsibleは都度都度接続しているっぽい。

iptablesの設定は、必要なコマンドをまずはVPSで打って、`iptables-save`で出力されたものを`iptables.j2`にしてsshポート番号だけ変数に置いている。

最初は以下のように.sshディレクトリを作って公開鍵をコピーするというのを自分でやっていたが、参考サイトでauthorized_keyというtaskを使っているのを見てそれを利用するようにした。

```yaml
    - file: path=/home/{{ username }}/.ssh state=directory owner={{ username }} group={{ username }} mode=0700
    - copy: src=~/.ssh/id_rsa.pub dest=/home/{{ username }}/.ssh/authorized_keys owner={{ username }} group={{ username }} mode=0600
```

authorized_keyはlookupで書かないとエラーになってしまった。`key=~/.ssh/id_rsa.pub`だとダメ。

Ansible歴はまだ1週間もないが、参考ページ等を見ながら雰囲気でそこそこ使えるので便利。

ふと思ったのは、なんとなくMavenに似てるということ。動かすコマンドじゃなくて設定を書いているあたり。


### 参考

- http://akiyoko.hatenablog.jp/entry/2013/12/16/020529
- https://help.sakura.ad.jp/app/answers/detail/a_id/2423
- http://qiita.com/meganii/items/8c91a43e52bd5d61cdde
- http://yutapon.hatenablog.com/entry/2014/04/08/102836
- http://docs.ansible.com/ansible/