Linuxサーバ同士のSSH接続やLinuxサーバを踏み台に別の機器にSSH接続する際に便利なコマンドを紹介していきます。
自動ログインと言えば、Teratermでの自動ログインなどありますが、これはソースコードがまるわかりなので、他人に使用させる場合は注意が必要です。
また、対話型の自動化に関しては、expectコマンドがありますが、そもそもexpectコマンドはSSH接続してコマンドを発行して終了するような、作業の自動化向きで単なるサーバ接続では使いにくいです。
そこでSSH自動接続に関して便利なsshpassについて書いていきます。
また、外部業者や関係者以外にシステムメンテナンスをさせる際に、パスワードを知らせずにシェルスクリプトをバイナリ化するshcについて書いていきたいと思います。
OSはCentOS 7.3を使用しています。
sshpassとshcを使ったセキュアなログインシェル作成
sshpassコマンドの実行
まずはコマンドをインストールします。
[root@localhost ~]# yum install -y sshpass 読み込んだプラグイン:fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: ftp.riken.jp * extras: ftp.riken.jp * updates: ftp.riken.jp 依存性の解決をしています --> トランザクションの確認を実行しています。 ---> パッケージ sshpass.x86_64 0:1.06-2.el7 を インストール --> 依存性解決を終了しました。 依存性を解決しました ======================================================================================================================================================================================================================================= Package アーキテクチャー バージョン リポジトリー 容量 ======================================================================================================================================================================================================================================= インストール中: sshpass x86_64 1.06-2.el7 extras 21 k トランザクションの要約 ======================================================================================================================================================================================================================================= インストール 1 パッケージ 総ダウンロード容量: 21 k インストール容量: 38 k Downloading packages: 警告: /var/cache/yum/x86_64/7/extras/packages/sshpass-1.06-2.el7.x86_64.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID f4a80eb5: NOKEY sshpass-1.06-2.el7.x86_64.rpm の公開鍵がインストールされていません sshpass-1.06-2.el7.x86_64.rpm | 21 kB 00:00:00 file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 から鍵を取得中です。 Importing GPG key 0xF4A80EB5: Userid : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>" Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5 Package : centos-release-7-1.1503.el7.centos.2.8.x86_64 (@anaconda) From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 Running transaction check Running transaction test Transaction test succeeded Running transaction インストール中 : sshpass-1.06-2.el7.x86_64 1/1 検証中 : sshpass-1.06-2.el7.x86_64 1/1 インストール: sshpass.x86_64 0:1.06-2.el7 完了しました! [root@localhost ~]#
次にコマンドを実行してみます。
今回は以下のサーバに接続します。
- IPアドレスが192.168.11.253
- ホスト名がdns
- パスワードがP@ssw0rd
[root@localhost ~]# sshpass -p P@ssw0rd ssh -o StrictHostKeyChecking=no root@192.168.11.253 Last login: Sat Nov 18 19:45:28 2017 [root@dns ~]#
パスワードを指定する事で自動ログインが出来ました。
-o StrictHostKeyChecking=noオプションを指定する事で、初回接続時のknow_hostsへの公開鍵追加のメッセージが出る関係で失敗するケースを回避できます。
あとはこのコマンドをシェルスクリプトのファイルにします。
[root@localhost ~]# vi auto_login.ssh #!/bin/bash sshpass -p P@ssw0rd ssh -o StrictHostKeyChecking=no root@192.168.11.253
次に権限を変更して、スクリプトとして実行します。
後程バイナリ化するので、元ファイルはrootユーザ以外実行できないように700でパーミッションを設定します。
[root@localhost ~]# chmod 700 auto_login.ssh [root@localhost ~]# ./auto_login.ssh Last login: Sat Nov 18 19:49:41 2017 from 192.168.11.2 [root@dns ~]#
問題なく実行が出来ました。
sshpassを使用すると簡単に自動ログインが可能になりましたね。
shcコマンドの実行
まずはソースファイルををダウンロードします。
yumではダウンロードできないので、wgetコマンドでhttp接続で取得します。
[root@localhost ~]# wget http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.9b.tgz --2017-11-18 20:00:00-- http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.9b.tgz www.datsi.fi.upm.es (www.datsi.fi.upm.es) をDNSに問いあわせています... 138.100.9.22 www.datsi.fi.upm.es (www.datsi.fi.upm.es)|138.100.9.22|:80 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 20687 (20K) [application/x-gzip] `shc-3.8.9b.tgz' に保存中 100%[========================================================================>] 20,687 36.7KB/s 時間 0.6s 2017-11-18 20:00:02 (36.7 KB/s) - `shc-3.8.9b.tgz' へ保存完了 [20687/20687] [root@localhost ~]#
ダウンロード完了した後にファイルを移動します。(使いやすいように任意に変えてください)
ディレクトリを移動してファイルを解凍します。
[root@localhost ~]# [root@localhost ~]# mv shc-3.8.9b.tgz /usr/local/src [root@localhost ~]# cd /usr/local/src [root@localhost src]# tar zxvf shc-3.8.9b.tgz shc-3.8.9b/CHANGES shc-3.8.9b/Copying shc-3.8.9b/match shc-3.8.9b/pru.sh shc-3.8.9b/shc-3.8.9b.c shc-3.8.9b/shc.c shc-3.8.9b/shc.1 shc-3.8.9b/shc.README shc-3.8.9b/shc.html shc-3.8.9b/test.bash shc-3.8.9b/test.csh shc-3.8.9b/test.ksh shc-3.8.9b/makefile shc-3.8.9b/testit [root@localhost src]#
次にmakeしていきますが、サーバにgccパッケージが入っていないと失敗するので、yumで一括でインストールします。
[root@localhost shc-3.8.9b]# yum -y install gcc 読み込んだプラグイン:fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: ftp.riken.jp * extras: ftp.riken.jp * updates: ftp.riken.jp 依存性の解決をしています --> トランザクションの確認を実行しています。 ---> パッケージ gcc.x86_64 0:4.8.5-16.el7 を インストール --> 依存性の処理をしています: libgomp = 4.8.5-16.el7 のパッケージ: gcc-4.8.5-16.el7.x86_64 --> 依存性の処理をしています: cpp = 4.8.5-16.el7 のパッケージ: gcc-4.8.5-16.el7.x86_64 --> 依存性の処理をしています: libgcc >= 4.8.5-16.el7 のパッケージ: gcc-4.8.5-16.el7.x86_64 --> 依存性の処理をしています: glibc-devel >= 2.2.90-12 のパッケージ: gcc-4.8.5-16.el7.x86_64 --> 依存性の処理をしています: libmpc.so.3()(64bit) のパッケージ: gcc-4.8.5-16.el7.x86_64 --> トランザクションの確認を実行しています。 ---> パッケージ cpp.x86_64 0:4.8.5-16.el7 を インストール ---> パッケージ glibc-devel.x86_64 0:2.17-196.el7 を インストール --> 依存性の処理をしています: glibc-headers = 2.17-196.el7 のパッケージ: glibc-devel-2.17-196.el7.x86_64 --> 依存性の処理をしています: glibc = 2.17-196.el7 のパッケージ: glibc-devel-2.17-196.el7.x86_64 --> 依存性の処理をしています: glibc-headers のパッケージ: glibc-devel-2.17-196.el7.x86_64 ---> パッケージ libgcc.x86_64 0:4.8.3-9.el7 を 更新 ---> パッケージ libgcc.x86_64 0:4.8.5-16.el7 を アップデート ---> パッケージ libgomp.x86_64 0:4.8.3-9.el7 を 更新 ---> パッケージ libgomp.x86_64 0:4.8.5-16.el7 を アップデート ---> パッケージ libmpc.x86_64 0:1.0.1-3.el7 を インストール --> トランザクションの確認を実行しています。 ---> パッケージ glibc.x86_64 0:2.17-78.el7 を 更新 --> 依存性の処理をしています: glibc = 2.17-78.el7 のパッケージ: glibc-common-2.17-78.el7.x86_64 ---> パッケージ glibc.x86_64 0:2.17-196.el7 を アップデート ---> パッケージ glibc-headers.x86_64 0:2.17-196.el7 を インストール --> 依存性の処理をしています: kernel-headers >= 2.2.1 のパッケージ: glibc-headers-2.17-196.el7.x86_64 --> 依存性の処理をしています: kernel-headers のパッケージ: glibc-headers-2.17-196.el7.x86_64 --> トランザクションの確認を実行しています。 ---> パッケージ glibc-common.x86_64 0:2.17-78.el7 を 更新 ---> パッケージ glibc-common.x86_64 0:2.17-196.el7 を アップデート ---> パッケージ kernel-headers.x86_64 0:3.10.0-693.5.2.el7 を インストール --> 依存性解決を終了しました。 依存性を解決しました ================================================================================================================== Package アーキテクチャー バージョン リポジトリー 容量 ================================================================================================================== インストール中: gcc x86_64 4.8.5-16.el7 base 16 M 依存性関連でのインストールをします: cpp x86_64 4.8.5-16.el7 base 5.9 M glibc-devel x86_64 2.17-196.el7 base 1.1 M glibc-headers x86_64 2.17-196.el7 base 675 k kernel-headers x86_64 3.10.0-693.5.2.el7 updates 6.0 M libmpc x86_64 1.0.1-3.el7 base 51 k 依存性関連での更新をします: glibc x86_64 2.17-196.el7 base 3.6 M glibc-common x86_64 2.17-196.el7 base 11 M libgcc x86_64 4.8.5-16.el7 base 98 k libgomp x86_64 4.8.5-16.el7 base 154 k トランザクションの要約 ================================================================================================================== インストール 1 パッケージ (+5 個の依存関係のパッケージ) 更新 ( 4 個の依存関係のパッケージ) 合計容量: 45 M 総ダウンロード容量: 30 M Downloading packages: (1/6): glibc-devel-2.17-196.el7.x86_64.rpm | 1.1 MB 00:00:00 (2/6): glibc-headers-2.17-196.el7.x86_64.rpm | 675 kB 00:00:00 (3/6): libmpc-1.0.1-3.el7.x86_64.rpm | 51 kB 00:00:00 (4/6): cpp-4.8.5-16.el7.x86_64.rpm | 5.9 MB 00:00:04 (5/6): kernel-headers-3.10.0-693.5.2.el7.x86_64.rpm | 6.0 MB 00:00:04 (6/6): gcc-4.8.5-16.el7.x86_64.rpm | 16 MB 00:00:10 ------------------------------------------------------------------------------------------------------------------ 合計 2.7 MB/s | 30 MB 00:00:10 Running transaction check Running transaction test Transaction test succeeded Running transaction 更新します : libgcc-4.8.5-16.el7.x86_64 1/14 更新します : glibc-common-2.17-196.el7.x86_64 2/14 更新します : glibc-2.17-196.el7.x86_64 3/14 warning: /etc/nsswitch.conf created as /etc/nsswitch.conf.rpmnew インストール中 : libmpc-1.0.1-3.el7.x86_64 4/14 インストール中 : cpp-4.8.5-16.el7.x86_64 5/14 更新します : libgomp-4.8.5-16.el7.x86_64 6/14 インストール中 : kernel-headers-3.10.0-693.5.2.el7.x86_64 7/14 インストール中 : glibc-headers-2.17-196.el7.x86_64 8/14 インストール中 : glibc-devel-2.17-196.el7.x86_64 9/14 インストール中 : gcc-4.8.5-16.el7.x86_64 10/14 整理中 : libgomp-4.8.3-9.el7.x86_64 11/14 整理中 : glibc-2.17-78.el7.x86_64 12/14 整理中 : glibc-common-2.17-78.el7.x86_64 13/14 整理中 : libgcc-4.8.3-9.el7.x86_64 14/14 検証中 : libgcc-4.8.5-16.el7.x86_64 1/14 検証中 : kernel-headers-3.10.0-693.5.2.el7.x86_64 2/14 検証中 : glibc-headers-2.17-196.el7.x86_64 3/14 検証中 : glibc-common-2.17-196.el7.x86_64 4/14 検証中 : libgomp-4.8.5-16.el7.x86_64 5/14 検証中 : cpp-4.8.5-16.el7.x86_64 6/14 検証中 : gcc-4.8.5-16.el7.x86_64 7/14 検証中 : glibc-devel-2.17-196.el7.x86_64 8/14 検証中 : glibc-2.17-196.el7.x86_64 9/14 検証中 : libmpc-1.0.1-3.el7.x86_64 10/14 検証中 : glibc-2.17-78.el7.x86_64 11/14 検証中 : glibc-common-2.17-78.el7.x86_64 12/14 検証中 : libgcc-4.8.3-9.el7.x86_64 13/14 検証中 : libgomp-4.8.3-9.el7.x86_64 14/14 インストール: gcc.x86_64 0:4.8.5-16.el7 依存性関連をインストールしました: cpp.x86_64 0:4.8.5-16.el7 glibc-devel.x86_64 0:2.17-196.el7 glibc-headers.x86_64 0:2.17-196.el7 kernel-headers.x86_64 0:3.10.0-693.5.2.el7 libmpc.x86_64 0:1.0.1-3.el7 依存性を更新しました: glibc.x86_64 0:2.17-196.el7 glibc-common.x86_64 0:2.17-196.el7 libgcc.x86_64 0:4.8.5-16.el7 libgomp.x86_64 0:4.8.5-16.el7 完了しました! [root@localhost shc-3.8.9b]#
makeしていきますが、いきなり実行するとmake testしろと返ってくるので、testから実行していきます。
ログが長くなるので、実行するコマンドを書いていきます。
[root@localhost shc-3.8.9b]# make test [root@localhost shc-3.8.9b]# make strings [root@localhost shc-3.8.9b]# make expiration
make expirationを実行する以下のようにエラーが返ってきます。
ですが、コマンドは使えるようになっているので特に気にしなくても問題ありません。
[root@localhost shc-3.8.9b]# make expiration *** Compiling "match" to expired date CFLAGS="-Wall " ./shc -v -T -vv -e `date "+%d/%m/%Y"` -f match shc -e Sat Nov 18 00:00:00 2017 shc -e Sat Nov 18 00:00:00 2017 shc shll=sh shc [-i]=-c shc [-x]=exec '%s' "$@" shc [-l]= shc opts= shc: cc -Wall match.x.c -o match.x shc: strip match.x shc: chmod go-r match.x *** Running a compiled test script! *** It must fail showing "./match.x: has expired!" ./match.x ./match.x: has expired! Please contact your provider make: *** [til_yesterday] エラー 1 [root@localhost shc-3.8.9b]#
shcのディレクトリ内にmatch.x.cのファイルが生成されていれば問題ありません。
ファイルが出来ていない場合は、makeコマンドでエラーがあると思うので確認してみてください。
[root@localhost shc-3.8.9b]# ls CHANGES makefile match.x pru.sh shc-3.8.9b.c shc.README shc.html test.csh testit Copying match match.x.c shc shc.1 shc.c test.bash test.ksh [root@localhost shc-3.8.9b]#
先ほど作成したsshpassのシェルスクリプトをバイナリ化していきます。
[root@localhost shc-3.8.9b]# ./shc -v -f /root/auto_login.ssh shc shll=bash shc [-i]=-c shc [-x]=exec '%s' "$@" shc [-l]= shc opts= shc: cc /root/auto_login.ssh.x.c -o /root/auto_login.ssh.x shc: strip /root/auto_login.ssh.x shc: chmod go-r /root/auto_login.ssh.x [root@localhost shc-3.8.9b]#
シェルスクリプトのあるディレクトリを参照すると、以下のようにファイルが作成されています。
今回は.x拡張子のファイルを使用していきます。
[root@localhost shc-3.8.9b]# ls -ltr /root/auto* -rwx------. 1 root root 89 11月 18 19:52 /root/auto_login.ssh -rw-r--r--. 1 root root 9490 11月 18 20:14 /root/auto_login.ssh.x.c -rwx--x--x. 1 root root 11200 11月 18 20:14 /root/auto_login.ssh.x [root@localhost shc-3.8.9b]#
シェルスクリプトは実行権限だけでは実行できないので、.x拡張子のファイルの権限を755に変更します。
また、testuserというユーザのホームディレクトリへファイルをコピーします。
[root@localhost shc-3.8.9b]# chmod 755 /root/auto_login.ssh.x [root@localhost shc-3.8.9b]# cp -rp /root/auto_login.ssh.x /home/testuser/
スイッチユーザをします。
[root@localhost shc-3.8.9b]# su - testuser 最終ログイン: 2017/11/18 (土) 18:21:44 JST日時 :0 [testuser@localhost ~]$
ファイルを参照するとバイナリ化されているため以下のように映りました。
ターミナルソフトによっては画面が崩れるので注意してください。
[root@dns ~]# cat auto_login.ssh.x M F*!#!##ui ~]# ex%t TT@T@DDPtd\\@\@||QtdRtd [teð àser@localhHst ~]` ( à à ` ` ` `c !`o H ~]$ t5 % user@localhost ~]$ cat auto_login.ssh.x @@$@8@% h% h% h% h% h% h% h% hp% `% h P% h @% h0% h % h¥ú è%r h%j h%b h%Z h%R h%J h%B h%: hp%2 h`%* hP%" h@% h0% h %
これでバイナリ化されているが分かったので、次はサーバへログインできるか確認します。
バイナリファイルを実行します。
[testuser@localhost ~]$ ./auto_login.ssh.x Warning: Permanently added '192.168.11.253' (ECDSA) to the list of known hosts. Last login: Sat Nov 18 19:53:41 2017 from 192.168.11.11 [root@dns ~]# [root@dns ~]#
正常に接続出来ました。
これでパスワードを知られずに、SSH接続だけさせる事が出来ました。
パスワードの代理入力などをいちいちしなくて良いように、このようなバイナリ化した接続用のスクリプトを用意するのも効率化の一環ですね。
機会があればぜひ使ってみてください。