Windows10 WSL(Ubuntu18.04)でawscliをインストールしてみた

最初のブログを書いてからだいぶ時間が経ちましたが、技術的なブログは1つだけ。
ブログは気が向いたら書けばいいと、すでに心の中で言い訳をしているごきげんまるです。

自分はWindows10にLinux(Ubuntu18.04)を入れて使っています。
Windows Subsystem for Linuxです。
ファイルシステムとかの制御はwindowsベースなのでいろいろと問題もあったりしますが、Vagrantなどを起動せずにLinuxが使えるのは便利ですね。

今回はそのUbuntuでawscliをインストールして使えるようにした話になります。

AWS CLIとは・・・

AWSCLIで構築したりすることができるツールです。CLIはそのままコマンドラインインターフェスの略ですね。
AWSは基本的にはコンソール画面からGUIでポチポチすればネットワークやサーバなどを構築できますが、それをコマンドでやれると何がいいかというと、Linuxなどのコマンドラインからスクリプトでいろんなことが自動で実行できるようになります。

今回、なぜAWSCLIを使うことになったかというと、お客様から、「AWS上で構築した環境が正しくパラメータが設定されているかの確認をやれるようにしてほしい。」というリクエストがあったからです。
table1個、EC2を1つ、S3のBucket1つというレベルであれば目視確認でいいのですが、作成しているのはtableで数十個という単位なので、目視確認は時間がかかる。。。
じゃあスクリプトで値を取ってきて、エクセルとかで比較できるようになれば簡単だねという話になり、実現するのに何を使おうかという中でAWSCLIならいけるんじゃね?ということで使うことにしてみました。
※terraformingも検討したのですが、一部の値がとってこれないことが机上の調査で分かったので、やめました。


じゃあ使おうとなった時に、いちいちAWS上にEC2をLinuxで構築してというは面倒。簡単に試しつつ使ってみたかったので、WSL上にあるUbuntuでやってみることに。

といっても、Ubuntuリポジトリにawscliの1.14があります。
なので、apt installとかapt updateをすればawscli1.14.44あたりが最新で入るはずです。

~$ apt search awscli
Sorting... Done
Full Text Search... Done
awscli/bionic 1.14.44-1ubuntu1 all
  Universal Command Line Environment for AWS


じゃあブログにならないじゃんという話なのですが、実はawscliの最新は1.16(2018/12/03現在)なので、Ubuntuリポジトリにあるのは古いバージョンです。
まぁ、リポジトリにあるのは古いバージョンというのはよくある話です。
1.14でももちろん使えるのですが、試していたところ1.14では使えないコマンドがあり、どうしてもそのコマンドが使いたいということで最新の1.16を入れることにしました。


Linux環境にpipをインストール

AWSのいいところ、それはだいたいの情報がAWSの公式サイトに上がっていることです。
LinuxにAWSCLIをインストールする方法もググれば上位にAWSの公式サイトの情報が出てきます。AWSがCloudで1番使われる理由もこの辺りがあるんだろうなぁ。と感心します。
たまにわかりづらいですが…。

docs.aws.amazon.com

これを見ながらやればいけるはず。
ということで、サイトに記載されている通りpythonの確認を実施。
Ubuntu18.04はPython3が入っています。

~$ python3 --version
Python 3.6.5

Python 3 バージョン 3.3以上が入っているので、Python3は問題なし。
ということで、pipのインストール確認を実施。

~$ which pip
~$

コマンドないなー。インストールされてないなーということで、pipのインストール実施。
pipのインストールはpypa.ioからスクリプトをダウンロードし、ダウンロードしたスクリプトを実行しPathを通せばOKとのこと。
楽勝っすね。
公式サイトにある通り、

~$ curl -O https://bootstrap.pypa.io/get-pip.py
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1622k  100 1622k    0     0   723k      0  0:00:02  0:00:02 --:--:--  723k
~$ python get-pip.py --user

Command 'python' not found, but can be installed with:

sudo apt install python3
sudo apt install python
sudo apt install python-minimal

You also have python3 installed, you can run 'python3' instead.

何も考えず、サイトにあったコマンドをそのまま実行したら怒られた。
まぁ、当たり前の話でPythonは3です。
なので、python3 get-pip.py --userにすればOK。

~$ python3 get-pip.py --user
Traceback (most recent call last):
  File "get-pip.py", line 20890, in <module>
    main()
  File "get-pip.py", line 197, in main
    bootstrap(tmpdir=tmpdir)
  File "get-pip.py", line 82, in bootstrap
    import pip._internal
  File "/tmp/tmp29c2waaw/pip.zip/pip/_internal/__init__.py", line 40, in <module>
  File "/tmp/tmp29c2waaw/pip.zip/pip/_internal/cli/autocompletion.py", line 8, in <module>
  File "/tmp/tmp29c2waaw/pip.zip/pip/_internal/cli/main_parser.py", line 8, in <module>
  File "/tmp/tmp29c2waaw/pip.zip/pip/_internal/cli/cmdoptions.py", line 17, in <module>
  File "/tmp/tmp29c2waaw/pip.zip/pip/_internal/locations.py", line 10, in <module>
ImportError: cannot import name 'sysconfig'

えっと。。。最後ImportErrorって書いてあるんすけど。。。
sysconfigがimportできないってことだけど、sysconfigはLinuxの標準ライブラリのはず。それがimport出来ないってことはここにあるはずの何かが足りないってことか。
と思ってググってみると、
Qiitaのブログで2018年5月からget-pip.pyを実行するとImportError: cannot import name 'sysconfig'が出るというブログを発見。
読ませていただいたところ、暫定的な解決策としてPPAを変えたらいけたということで、やってみることに。

~$ sudo add-apt-repository ppa:deadsnakes/ppa
~$ sudo apt-get update
~$ sudo apt-get install python3.6 python3.6-dev
~$ sudo python3.6 get-pip.py
Traceback (most recent call last):
  File "get-pip.py", line 20890, in <module>
    main()
  File "get-pip.py", line 197, in main
    bootstrap(tmpdir=tmpdir)
  File "get-pip.py", line 82, in bootstrap
    import pip._internal
  File "/tmp/tmpx467y94c/pip.zip/pip/_internal/__init__.py", line 40, in <module>
  File "/tmp/tmpx467y94c/pip.zip/pip/_internal/cli/autocompletion.py", line 8, in <module>
  File "/tmp/tmpx467y94c/pip.zip/pip/_internal/cli/main_parser.py", line 8, in <module>
  File "/tmp/tmpx467y94c/pip.zip/pip/_internal/cli/cmdoptions.py", line 17, in <module>
  File "/tmp/tmpx467y94c/pip.zip/pip/_internal/locations.py", line 10, in <module>
ImportError: cannot import name 'sysconfig'

ダメじゃああああああん orz。。
pipインストールできない。詰んだ。
※このブログを書いているときに分かったのですが、pypaのGitサイトでIssueが出ていて、そこを見れば簡単に解決出来たのですが、only英語であったのと、この時は英語読みたくない病が発病していた為、ちゃんと読まなかったのです…。

仕事で入れているんでなければここで諦めてSplatoon2でも始めるのですが、仕事でAWSCLIが必要であったことから、諦めたいけど諦めずに考えることに。
上で試したのは結局python3を入れなおすことで、今やりたいのはpipを入れること。
pipかぁ、pypa.io以外にpipのインストールスクリプトが置いてあるサイトはないのかな。
インストールスクリプト、、、
ん、インストールか。ダメもとでUbuntuリポジトリで探してみるかなぁ。

~$ apt search pip
~~大量出力~~

見るのメンドイ…。
そういえばUbuntuはコマンドうってみて無かった時にaptで入れろとか出るなぁ。

~$ pip --version

Command 'pip' not found, but can be installed with:

sudo apt install python-pip

(゚∀゚)キタコレ!!
Ubuntuリポジトリにpipあるやん!!!

ちょっと待てよ。pythonって書いてあるな。
python3も欲しいな。。。無いかなぁ。

~$ apt search python3-pip
Sorting... Done
Full Text Search... Done
python3-pip/bionic-updates 9.0.1-2.3~ubuntu1 all
  Python package installer


(゚∀゚)キタコレ!!
python3もあるじゃん!
両方インストールしてしまおう。

~$ sudo apt install python-pip python3-pip
~$ which pip
/usr/bin/pip
~$ which pip3
/usr/bin/pip3
pip --version
pip 9.0.1 from /usr/lib/python2.7/dist-packages (python 2.7)
~$ pip3 --version
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)

ということでようやっとAWSCLIインストールに必要となるpipのインストールが完了しました。
無駄に時間喰ったなぁ。。。

Linux環境にAWSCLIをインストール

ようやく本命のAWSCLIのインストールです。
pipを使ってインストール。

~$ pip install awscli --upgrade --user
Collecting awscli
~~中略~~
Successfully installed PyYAML-3.13 awscli-1.16.67 botocore-1.12.61 colorama-0.3.9 docutils-0.14 futures-3.2.0 jmespath-0.9.3 pyasn1-0.4.4 python-dateutil-2.7.5 rsa-3.4.2 s3transfer-0.1.13 six-1.11.0 urllib3-1.24.1

Successfully installedでawscli-1.16.71が出ているので、無事成功。
AWSCLIは簡単に入ったわー。よかったー。
コマンドを実行出来るか確認。

~$ aws --version

Command 'aws' not found, but can be installed with:

sudo apt install awscli

ちょwwwwwww
コマンド見当たらないとか出てるんですけどおおお

冷静にサイトを見ると、AWSCLI実行ファイルのパスを追加しないといけないらしい。

~$ export PATH=~/.local/bin:$PATH
~$ aws --version
aws-cli/1.16.67 Python/2.7.15rc1 Linux/4.4.0-17134-Microsoft botocore/1.12.57
~$ source .profile
~$ cat .profile
~~中略~~
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
    PATH="$HOME/.local/bin:$PATH"
fi

無事インストール完了しました。
ちなみにですが、インストールを実施した12/3頃はバージョンが1.16.67でしたが、今日(12/7)確認してみたら1.16.71になっていました。
AWS関連はupdateが早くて多い。。。

auditでコマンド実行履歴をログに取得してみた

どうも、ごきげんまるです。

 

皆さんは会社のLinuxサーバでログイン者のコマンド実行履歴を管理されていますか?

Linuxではコマンド履歴を取得する方法がいくつかあります。

私の現場では、Snoopy Loggerを使ってLinuxサーバのコマンド履歴を監査用として取得していましたが、AWSでAmazonLinux2でEC2インスタンスを作成した際にSnoopy Loggerがうまくインストールできない問題があったことから、Linux標準で用意されているauditに変更。その内容を書こうと思います。

aujditのログのローテートで少しはまった話についてはまた次回。。。

 

Snoopy Loggerとは

コマンドの実行履歴をsyslogに記録してくれるツールです。

github上に公開されており、いろいろなLinuxディストリビューションに対応しているツールで、インストール実行するとディストリビューションに応じたインストールが走ってくれる便利ツールです。

 

github.com

 

なぜSnoopy Loggerを使わなかったのか。

AmazonLinux2ではインストールがうまく行かなかった…。

gcc等のSnoopy Loggerで必要なパッケージを手動で入れる必要はありましたが、インストールシェルは実行でき、うまくいっているように見えるのですが、ログを見るとerrorを吐いて止まっている。

インストールログ:
~途中省略~

 

SNOOPY INSTALL: Building... make all-recursive
make[1]: Entering directory `/tmp/snoopy-2.4.6'
Making all in etc
make[2]: Entering directory `/tmp/snoopy-2.4.6/etc'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/tmp/snoopy-2.4.6/etc'
Making all in lib
make[2]: Entering directory `/tmp/snoopy-2.4.6/lib'
Making all in inih
make[3]: Entering directory `/tmp/snoopy-2.4.6/lib/inih'
Making all in src
make[4]: Entering directory `/tmp/snoopy-2.4.6/lib/inih/src'
CC ini.lo
CCLD libinih.la
make[4]: Leaving directory `/tmp/snoopy-2.4.6/lib/inih/src'
make[4]: Entering directory `/tmp/snoopy-2.4.6/lib/inih'
make[4]: Nothing to be done for `all-am'.
make[4]: Leaving directory `/tmp/snoopy-2.4.6/lib/inih'
make[3]: Leaving directory `/tmp/snoopy-2.4.6/lib/inih'
make[3]: Entering directory `/tmp/snoopy-2.4.6/lib'
make[3]: Nothing to be done for `all-am'.
make[3]: Leaving directory `/tmp/snoopy-2.4.6/lib'
make[2]: Leaving directory `/tmp/snoopy-2.4.6/lib'
Making all in src
make[2]: Entering directory `/tmp/snoopy-2.4.6/src'
Making all in eventsource
make[3]: Entering directory `/tmp/snoopy-2.4.6/src/eventsource'
CC libsnoopy_eventsource_execve_wrapper_la-execve_wrapper.lo
CCLD libsnoopy_eventsource_execve_wrapper.la
make[3]: Leaving directory `/tmp/snoopy-2.4.6/src/eventsource'
Making all in datasource
make[3]: Entering directory `/tmp/snoopy-2.4.6/src/datasource'
CC noop.lo
CC cmdline.lo
cmdline.c: In function 'snoopy_datasource_cmdline':
cmdline.c:71:79: error: comparison between pointer and zero character constant [-Werror=pointer-compare]
for (cmdLineArgCount=0 ; *(snoopy_inputdatastorage->argv+cmdLineArgCount) != '\0' ; cmdLineArgCount++);
^~
cmdline.c:71:30: note: did you mean to dereference the pointer?
for (cmdLineArgCount=0 ; *(snoopy_inputdatastorage->argv+cmdLineArgCount) != '\0' ; cmdLineArgCount++);
^
cc1: all warnings being treated as errors
make[3]: *** [cmdline.lo] Error 1
make[3]: Leaving directory `/tmp/snoopy-2.4.6/src/datasource'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/tmp/snoopy-2.4.6/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/tmp/snoopy-2.4.6'
make: *** [all] Error 2

 

 

 

おそらくですが、Snoopy LoggerはCentOSなどの一般的なLinuxディストリビューションには対応していますが、AmazonLinux2は対応していないのではないかと推測しています。

※調べる時間がその時は無かった…。

構築期限も差し迫っていたことから、AmazonLinux2でSnoopy Loggerを使うことはあきらめ、Linux標準のauditdを利用することに。

 

auditとは

Linux標準のセキュリティに関する情報を追跡するものらしいです。

今回やりたかったコマンドの実行履歴の取得もこのauditで実施できることから、今回はauditを利用することに。

設定自体は簡単で、AmazonLinux2ではデフォルトでパッケージが導入され、サービスが起動していることから、設定のみで利用可能でした。

 

 auditでコマンド履歴をaudit.logに記録するコマンド

 

auditctl -a exit,always -S execve

 

上記コマンドを実行すると、audit.log(AmazonLinux2では/var/log/audit/audit.log)にコマンドの履歴が記録されます。

可読性は…正直よくありません。1回のコマンド実行で数行のログが出力され、見づらいったらありゃしない。

まぁでも監査用のログなので、可読性は今回は捨てることに。

 

ただ、コマンドで実行した場合、当然ながらrebootなどでサーバが停止したりすれば再度実行が必要。

監査ログということもあり、サーバ起動時からログが取れないのは致命的なので、サーバ再起動等があってもコマンド履歴が取得できるよう、以下の通りauditのrulesに追記。

 

/etc/audit/rules.d/audit.rules 

-a exit,always -S execve

 

 これでauditを再起動すればauditctlコマンドを実行しなくてもコマンド履歴をログに取得できるようになりました。

 とりあえず、監査ログ取得ということであれば上記で対応は可能です。ただ、実際にセキュリティ事故等でコマンドを追うとなると正直読みづらく大変だと思うので、何かしら考えないといけないなぁと思っているところです。

 

 

 

 

まだブログの書き方に慣れておらず、ほかのブログのようにはきれいに書けない。。。

pre記法?とかを学ばないとダメですね。

最初の投稿

初めまして。システムエンジニアをやっているごきげんまるです。

開発のお手伝い、サーバエンジニア、ネットワークエンジニアを経て、現在はクラウドのインフラ周りの仕事を主にしています。

今まで自分が得てきた技術をアウトプットすることはなかったのですが、今までいろんな方々がWeb上に残してくれた技術アウトプットのおかげで仕事をずっとやってこれたこともあり、自分もほかの方々に少しでも何かの役に立てればということでブログをやってみようと思い始めました。

 

といっても飽きるのも早い性格なので、どこまで続くかはわかりませんが、気が向いた時に書きなぐろうと思っています。

よろしくお願いします。