文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

ansibleを学ぶ:vol05:対象サーバのid_rsa.pubを対象サーバのauthorized_keysに登録する

ansibleの勉強シリーズ第5回です。


f:id:treeapps:20160219001058p:plain

今さらansibleかよ!

今さらsshするのかよ!

というツッコミはさておき、今回自分のサーバにパスワード無しでsshするために、自分のサーバにある公開鍵(id_rsa.pub)を、自分のサーバのauthorized_keysに登録してしまおう、というものです。

環境

ローカル mac
リモート linux等
ansible v2.0

authorized_keysへの登録

やりたいこと

対象サーバにあるid_rsa.pubを、対象サーバのauthorized_keysに登録します。

それをする事で、パスワード入力無しに「ssh localhost」をできるようにします。

コード

- shell: "cat /home/{{ user }}/.ssh/id_rsa.pub"
  register: public_key_contents

- lineinfile: >
    dest=/home/{{ user }}/.ssh/authorized_keys
    line='{{ public_key_contents.stdout }}'
    state=present

こんな感じでできます。

id_rsa.pubをcatしてそれを変数に保存しておき、lineinfileでauthorized_keysの末尾に追記するだけです。こんな単純なコードですが、ちゃんと冪等性を維持しています。

この方法以外にも、素直にauthorized_keyモジュールを使うという手もあります。その場合は、事前にansible適用先サーバで公開鍵を作成してローカルにコピーしておき、その公開鍵をansible適用先、つまり自分自身に登録する形になります。authorized_keyモジュールはローカルに事前に保存しておいた鍵をリモートに登録するものなので、ローカルに保存したくない、リモートtoリモートでやりたい場合等では使えません。

known_hostsへの登録

自分自身のサーバにパス無しでsshができるようになりましたが、このままだと初回アクセス時に以下のようにfinger printの表示が出てしまいます。

tree:test tree$ ssh vagrant@192.168.33.31
The authenticity of host '192.168.33.31 (192.168.33.31)' can't be established.
RSA key fingerprint is SHA256:1ifn3fhh6SiYRahCHO40FYelaCiIEN1Jqd96WLpt85g.
Are you sure you want to continue connecting (yes/no)?

やりたいこと

このように、初回ssh時にfinger printが表示されないように、プロビジョニングの時点で自分自身をknown_hostsに登録する事で、finger print表示を抑制します。

「自分自身」というのは、「localhost」「127.0.0.1」「Private IP」の3種類があるので、3種類登録してみます。

コード

- shell: "ssh-keyscan localhost | grep -v OpenSSH"
  register: localhost

- lineinfile: >
    dest=/home/{{ user }}/.ssh/known_hosts
    line='{{ localhost.stdout }}'
    state=present

- shell: "ssh-keyscan 127.0.0.1 | grep -v OpenSSH"
  register: localip

- lineinfile: >
    dest=/home/{{ user }}/.ssh/known_hosts
    line='{{ localip.stdout }}'
    state=present

- shell: "ssh-keyscan {{ ansible_eth0.ipv4.address }} | grep -v OpenSSH"
  register: privateip

- lineinfile: >
    dest=/home/{{ user }}/.ssh/known_hosts
    line='{{ privateip.stdout }}'
    state=present

ssh-keyscanコマンドを利用する事で、known_hostsに登録する文字列を生成する事ができます。本来ならssh-keyscan実行結果の標準出力をそのままknown_hostsに書き込みたいところですが、できないようなので(できるのですかね?)、一旦registerで変数に標準出力を保存し、lineinfile経由でknown_hostsに書き込みます。lineinfileを使うので、自動的に冪等性は維持されます。

「grep -v OpenSSH」ですが、以下のようにssh-keyscanの実行結果に余計なコメント行が含まれてしまうので、それを除去するためにつけています。

[vagrant@test ~]$ ssh-keyscan localhost
# localhost SSH-2.0-OpenSSH_5.3
localhost ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAl5q+/LdM3FZ6QIr6lJrvkuwHYSn06dm5VhDZNkLQUsyGW1AILcTh9ve8Za7uS+a+5xuVL2R9AkHFmKZA2XyM4EDs2KNOJveP4EGiRdqV3RnD+OGOAxnyv7DGnxeVdy7tHviOvdedJVTrCTeKWdbi0+Jk9Fpjdvd97aEMqq/rTjis1sEVJ4hrFRSFkD+HwIWJ1z2M3JTO1DKkzzTGD6zrun75WZlFexydnbiXjBcLdJZ/CN1t8h/WbQ4UjaDZxRvTUy0GmlyKrmnNsOnejZsvB+LDN0wD3KQAUl2PrIu7Y4y14oGndz/Ew5T572AhvHrJq/jPB/Tvv8Pxdc7M35feYw==

なお、自分自身のサーバのIPは「ansible_eth0.ipv4.address」で取得できます。
Variables — Ansible Documentation

雑感

まだまだ世の中にはオンプレミス全開の案件は多く、ansibleによるプロビジョニングに頼りたくなる事もあると思います。大人の事情(インフラだけ別会社に握られていてクラウドに移行できない等)で移行できない人も沢山いると思います。

本当ならでDockerでコンテナを細かく分けて云々〜、とやりたいところですが、インフラがオンプレだし、オンプレ前提で自身のサーバにファイルを保存しまくるアプリの設計になっていたりして、docker化するには無理があるプロジェクトも多い事でしょう。

そこで諦めてお手製オレオレ環境構築シェルスクリプトに頼るのではなく、学習も楽なansibleを使ってdevelopment環境をクラウド上に構築する等して、少しでもインフラに纏わる作業を減らしていきたいですね。昔ながらのインフラ担当による環境構築手順も無く独自のインストールパスにソフトウェアをインストールしてしまうような、秘伝のタレ満載なサーバ構築の状況を覆していきたいですね。

Ansible実践ガイド 第2版 (impress top gear)

Ansible実践ガイド 第2版 (impress top gear)

ansibleを学ぶ:vol01:vagrantを使ってansibleを動かしてみる - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol02:Oracle JDK1.8のインストール、ユーザパスワード設定等 - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol03:実行中のホスト名を書き込む、変数の値に変数を使用する - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol04:よくハマる部分とその解決法 - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol05:対象サーバのid_rsa.pubを対象サーバのauthorized_keysに登録する - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol06:mysql-serverのインストールからcreate databaseまでを自動化する - 文系プログラマによるTIPSブログ
ansibleを学ぶ:vol07:figletで動的にホスト名をmotdに書き込んでニヤニヤする - 文系プログラマによるTIPSブログ