AnsibleからのWindows操作をSSHにしてみた
本業ネットワーク屋さんなのにWindows系の記事ばかりですが、勢いに任せて。
これまではWinRMで接続していたAnsible~Windowsホスト間を、SSH接続にしてみました。
Ansible関連の実践記事一覧はこちら。
目的
WinRMはなんでもできてダメー!ポートも怖いからダメー!
よくわからないからダメー!!どうしてもダメー!!セキュリティ的にだめー!
っていう条件が付いたときに、代替手段としてAnsibleの足回りとしてSSHを使えるようにするため。
WindowsのOpenSSHはベータ版ではありますが、今の動きを見ている限り、近いうちに公式に取り入れられてもおかしくなさそうです。
ベースにした資料
- ひよこ大佐のスライド
Red Hat Tech Nightでひよこ大佐がお話されていた資料です。
概要や参考リンクなど情報が詰まっており、とても助かりました。
Ansible本も刊行されたら必ず購入させていただきます。執筆頑張ってください!
RHTN: Ansible 2.8 x Windows - Speaker Deck
環境
Ansible側
WSL上のUbuntuで実行しました。先のことも想定してvirtualenv配下です。
(ansible28) ansible@ENVY360:~$ (ansible28) ansible@ENVY360:~$ ansible --version ansible 2.8.6 config file = None configured module search path = [u'/home/ansible/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /home/ansible/ansible28/local/lib/python2.7/site-packages/ansible executable location = /home/ansible/ansible28/bin/ansible python version = 2.7.15+ (default, Oct 7 2019, 17:39:04) [GCC 7.4.0] (ansible28) ansible@ENVY360:~$ ansible-config dump --only-changed (ansible28) ansible@ENVY360:~$
ansibleのバージョンは、つい先日出た脆弱性が修正されてるバージョンですね。
操作されるWindows側
- OS: Windows 2012 R2
IP設定もDHCPの初期状態からスタート。
例のごとく管理者パスワードはインベントリに合わせる。
…って書いてましたが、今回パスワードはインベントリに書かず、手動入力にしましたので、インベントリその他への記述は不要。
テスト用で操作するWindows側
- OS: Windows 10 Home
メイン環境なのでいろいろ入ってますが、割愛。
Ansibleモジュール利用前のSSH接続確認用でのTeraTermなどしか利用してません。
操作されるWindows側のセットアップ
公式なインストールガイドはこちら。
Install Win32 OpenSSH · PowerShell/Win32-OpenSSH Wiki · GitHub
OpenSSHのバイナリのダウンロード
公式手順として、最新版の確認方法がPowerShellで提供されていたりもしますが、以下URLよりブラウザで手動でダウンロード。
Release v8.0.0.0p1-Beta · PowerShell/Win32-OpenSSH · GitHub
ダウンロードしたファイルは「OpenSSH-Win64.zip」です。作業時点ではバージョンは8.0.0p1-betaとのこと。
なお、Windows Server側で作業をしているため、事前にIEのセキュリティ強化の構成などを無効化したりしています。
その後、ZIP圧縮されたファイルを展開し、デフォルトインストールパスとして指定されている C:\Program Files\OpenSSH として配置。
Windowsサービスとしてのsshdの登録
手順に従い、PowerShellを起動して、デフォルトのインストールパスに移動し、以下コマンドを入力。
powershell.exe -ExecutionPolicy Bypass -File install-sshd.ps1
-File の部分で絶対パスを指定すれば特に移動も必要ないと思います。
Windows FirewallでのTCP22の開放
手順に従い、そのままPowerShellで以下のコマンドを入力。
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
sshdサービスの起動
以下コマンドを入力し、sshdサービスを起動。
net start sshd
→正常にサービスが起動することを確認。
テスト用端末からパスワード認証での動作確認
ターミナルソフトでIPを指定→ハッシュが表示される!
ユーザ名とパスワードを入力しログイン→いけた!!
Ansible経由でのパスワード認証での疎通確認
こんなかんじのインベントリで
[win_2012] 192.168.10.249 [win_2012:vars] ansible_user=administrator ansible_connection=ssh ansible_shell_type=cmd
win_pingモジュールを起動するだけのPlaybookをたたく。-kオプション付けてパスワードを聞かれるように。
→sshpassというプログラムが足りないと怒られる…
※補足 実際にはこの時点で、known_hostsへのハッシュの追加を聞かれてます。いきなり鍵認証に進む方は、大抵設定されてると思いますがansible.cfgなどでハッシュの確認を無効化しておきましょう。
$ sudo apt-get install sshpass
入れてみて再チャレンジ!
キタ━━━━(゚∀゚)━━━━!!
認証を鍵認証にしてみる
さて、パスワード認証が終わったところで鍵認証に移行。まあ、よくあるハマりがありました。
鍵ファイルの配置場所とターミナルからの接続確認
該当のページ上のsshd_configドキュメントを読んでみると、以下がデフォルトパスとのこと。
“.ssh/authorized_keys .ssh/authorized_keys2”
ただし、注意事項があり、OpenSSH7.7以降のAdministratorsグループ用の鍵ファイルの位置は、以下パスがデフォルトであるとの記載あり。
%programdata%/ssh/administrators_authorized_keys
なるほどと思い、administratorsグループ側のパスに公開鍵ファイルを置いてみる。
いざターミナルで接続確認→繋がらず。なんか拒否られてる感じ。
確認してみたところ、以下パスにログが保管されてそうなディレクトリがあったのですが、ファイルは何もなし。
%programdata%/ssh/logs/
さらに、そこにsshd_configファイルを発見。覗いてみることに。
sshd_configの設定変更とログ確認
Windows側のOpensshの設定ファイル
%programdata%/ssh/sshd_config
Rootログインやら鍵認証やらは許可されている。
上述した、AdministratorGroupのパスワードの設定も末尾に入っている。
Match Group administrators AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
該当のページ上のsshd_configドキュメントを読んでみると、「ログをファイルベースにするには、LOCAL0のファシリティにしろ」とのこと。
ということで、設定変更しサービスを再起動し、再度鍵認証実施→ログ確認。
administrator@WIN-T4SRVR692IR C:\ProgramData\ssh\logs>more sshd.log 1148 2019-10-19 20:05:38.667 Server listening on :: port 22. 1148 2019-10-19 20:05:38.667 Server listening on 0.0.0.0 port 22. 856 2019-10-19 20:05:55.168 Accepted password for administrator from 192.168.10. 243 port 52224 ssh2 2752 2019-10-19 20:05:56.214 Received disconnect from 192.168.10.243 port 52224: 11: disconnected by server request 2752 2019-10-19 20:05:56.214 Disconnected from 192.168.10.243 port 52224 ↑ここまでパスワード認証 ↓ここから鍵認証 2164 2019-10-19 20:06:11.230 Authentication refused. 2164 2019-10-19 20:06:13.121 Received disconnect from 192.168.10.243 port 52229: 11: authentication cancelled [preauth]
原因は Authentication refused って書いてある。
となると、よくあるのはauthorized_keysが格納されているパスまでのパーミッション。
セキュリティ設定(パーミッション)の変更
確認してみたところ、 configなどが格納されている sshフォルダのパーミッションが甘そう。
なので、「Authenticated Users」のグループから全権限を外す。
※事後で権限つけてScreenShot撮ってるので、初期値は違う可能性があります。ご了承ください。
テスト用端末からの鍵認証の確認
キタ━━━━(゚∀゚)━━━━!!
Ansible経由での鍵認証での疎通確認
Ansible側のホストの$HOME/.ssh/id_rsa に秘密鍵を配置、パーミッション設定をしていざ実行…
キタ━━━━(゚∀゚)━━━━!!
感想
ということで、無事にAnsibleからのWindowsの操作をSSH経由で実施できる環境が整いました。
WinRMと比べてセットアップ工程が長いので、スクリプト化しないとだめかなあという気持ちになりました。
わからなかったところ
いつのまにかsshd_config とかが生成されていたので、これはどのタイミングなのかはまた調べてみようと思いました。
まだAnsibleの学習が進んでないこともあり、デフォルトシェルをcmdにするのかpowershellにするのがいいのか、というのはわかりませんでした。
FACILITY設定する前のログはイベントログ側にあるのか?未確認
また勉強します。
参考にした資料(まとめて再掲)
- ひよこ大佐のスライド
RHTN: Ansible 2.8 x Windows - Speaker Deck
- Win32-OpenSSH公式GitHub
[wiki]のページにいろいろ書かれています。
GitHub - PowerShell/Win32-OpenSSH: Win32 port of OpenSSH
- Win32-OpenSSHのMicrosoft自動翻訳ページ
上記公式GitHubがほぼ日本語に翻訳されてるので、とてもありがたかった…!