VPSの初期状態
- rootユーザーでSSHログイン許可
- ポートの制限なし
やること
- rootユーザーでのSSHログイン禁止
- パスワードによるSSHログイン禁止
- ユーザーeiryuの作成(パスワードはpassword)
- Ansibleを実行するホストのホームディレクトリにある公開鍵を上記で作成したユーザーのホームディレクトリに配備
- SSH、HTTP、HTTPSなど必要ポートだけ外部からの通信を許可する設定にする
出来たもの
$ tree
.
├── hosts
├── iptables.j2
└── playbook.yml
hosts
[vps]
xxx.xxx.xxx.xxx # VPSのIP
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を使っているのを見てそれを利用するようにした。
- 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に似てるということ。動かすコマンドじゃなくて設定を書いているあたり。