本日も乙

ただの自己満足な備忘録。

Amazon Linux 2でsyslogに出力するBashのRPMを作成する

セキュリティ要件でサーバ内で実行した全ユーザのコマンド履歴を保存することが求められることがあります。いくつかの方法がありますが、Bash ではコマンド履歴を syslog に出力する機能が提供されており、今回はその方法を採用することにしました。

syslog に保存するには Bash をビルドし直す必要があります。Amazon Linux 1、CentOS、Ubuntu でその方法が見つかったのですが、Amazon Linux 2ではそれらしい情報がなかったので備忘として本記事に残します。

サーバ情報はこんな感じです。

$ uname -r
4.14.173-137.229.amzn2.x86_64

$ rpm -qa | grep bash
bash-4.2.46-33.amzn2.x86_64
bash-completion-2.1-6.amzn2.noarch

ビルドするために必要なパッケージをインストールします。

$ sudo su -
% yum install rpm-build texinfo bison ncurses-devel autoconf gettext gcc make

パッケージソース(SRPM)をとってきます。Amazon Linux 2では yumdownloader コマンドが使えます。

% yumdownloader --source bash
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Enabling amzn2extra-docker-source repository
Enabling amzn2-core-source repository
amzn2-core-source
amzn2extra-docker-source
(1/2): amzn2extra-docker-source/2/primary_db
(2/2): amzn2-core-source/2/primary_db
bash-4.2.46-33.amzn2.src.rpm

SRPM をインストールすると rpmbuild というディレクトリができます。

% rpm -ivh bash-4.2.46-33.amzn2.src.rpm

Bash ソースの修正

syslog に履歴を出力する設定を行います。

% cd ~/rpmbuild/SOURCES
% tar zxf bash-4.2.tar.gz
% cp -rpf bash-4.2{,.orig}
% cd bash-4.2

config-top.h で次のように修正します。ファシリティとログレベルも変えています。

 /* Define if you want each line saved to the history list in bashhist.c:
    bash_add_history() to be sent to syslog(). */
-/* #define SYSLOG_HISTORY */
+#define SYSLOG_HISTORY
 #if defined (SYSLOG_HISTORY)
-#  define SYSLOG_FACILITY LOG_USER
+#  define SYSLOG_FACILITY LOG_LOCAL6
-#  define SYSLOG_LEVEL LOG_INFO
+#  define SYSLOG_LEVEL LOG_DEBUG
 #endif

変更した箇所のパッチファイルを作成します。

% cd ~/rpmbuild/SOURCES
% diff -Npru bash-4.2.orig bash-4.2 > bash_history_rsyslog.patch

# パッチファイルの中身
% cat bash_history_rsyslog.patch
diff -Npru bash-4.2.orig/config-top.h bash-4.2/config-top.h
--- bash-4.2.orig/config-top.h  2009-12-22 20:29:39.000000000 +0000
+++ bash-4.2/config-top.h       2020-05-01 06:23:19.711013827 +0000
@@ -101,10 +101,10 @@

 /* Define if you want each line saved to the history list in bashhist.c:
    bash_add_history() to be sent to syslog(). */
-/* #define SYSLOG_HISTORY */
+#define SYSLOG_HISTORY
 #if defined (SYSLOG_HISTORY)
-#  define SYSLOG_FACILITY LOG_USER
-#  define SYSLOG_LEVEL LOG_INFO
+#  define SYSLOG_FACILITY LOG_LOCAL6
+#  define SYSLOG_LEVEL LOG_DEBUG
 #endif

 /* Define if you want to include code in shell.c to support wordexp(3) */

SPEC ファイルの修正

SPEC ファイル bash.spec を修正します。Release で適当なプレフィックスをつけます。後でインストールするときに既存の Bash パッケージと重複しないためです。
今回作成したパッチファイルを適用するための設定を追記します。Patch番号が重複しないように適宜変更してください。今回は Patch156 が最新だったので Patch157 で追記しました。
Patch155 で syslog の修正が入っていましたが、今回のパッチと競合してビルドできなかったので外しました。bash 5.0 だしいいよね。

% cd ~/rpmbuild/SPECS/
--- bash.spec.orig      2020-05-01 06:29:54.128019450 +0000
+++ bash.spec   2020-05-01 06:54:39.473960968 +0000
@@ -6,7 +6,7 @@
 Version: %{baseversion}%{patchleveltag}
 Name: bash
 Summary: The GNU Bourne Again shell
-Release: 33%{?dist}
+Release: 33%{?dist}_syslog
 Group: System Environment/Shells
 License: GPLv3+
 Url: http://www.gnu.org/software/bash
@@ -199,11 +199,15 @@
 Patch154: bash-4.3-dircomp-append-slash.patch

 #1160482 - Add a runtime option to enable history logging to syslog
-Patch155: bash-5.0-syslog-history.patch
+#Patch155: bash-5.0-syslog-history.patch

 #1573901 - RFE: (security) support bracketed paste mode
 Patch156: bash-4.4-bracketed-paste.patch

+#Enable detailed syslog info
+Patch157: bash_history_rsyslog.patch
+
 BuildRequires: texinfo bison
 BuildRequires: ncurses-devel
 BuildRequires: autoconf, gettext
@@ -336,8 +340,9 @@
 %patch152 -p1 -b .pipefd-leak
 %patch153 -p1 -b .wshouldquote
 %patch154 -p1 -b .append-slash
-%patch155 -p1 -b .syslog-history
+#%patch155 -p1 -b .syslog-history
 %patch156 -p1 -b .bracketed-paste
+%patch157 -p1 -b .history_rsyslog

 echo %{version} > _distribution
 echo %{release} > _patchlevel

ビルド

ビルドしている EC2 インスタンスタイプによりますが、私の環境(t3.small)では数分程度で完了しました。

% rpmbuild -ba bash.spec

# ビルドされたRPMファイルの確認
% ls ~/rpmbuild/RPMS/x86_64/
bash-4.2.46-33.amzn2_syslog.x86_64.rpm  bash-debuginfo-4.2.46-33.amzn2_syslog.x86_64.rpm  bash-doc-4.2.46-33.amzn2_syslog.x86_64.rpm

rsyslog の設定変更

このままだと syslog に出力されないため rsyslog の設定を変更します。
/etc/rsyslog.conf を次のように編集します。ファシリティとログレベルは先ほど設定した値(local6.debug)にします。

--- /etc/rsyslog.conf.orig      2019-11-14 22:39:45.000000000 +0000
+++ /etc/rsyslog.conf   2020-05-01 07:01:43.539621402 +0000
@@ -51,7 +51,7 @@

 # Log anything (except mail) of level info or higher.
 # Don't log private authentication messages!
-*.info;mail.none;authpriv.none;cron.none                /var/log/messages
+*.info;mail.none;authpriv.none;cron.none;local6.debug                /var/log/messages

rsyslog を再起動します。

% systemctl restart rsyslog

確認

ビルドした Bash パッケージをインストールして syslog に履歴が残るか確認します。

% rpm -Uvh ~/rpmbuild/RPMS/x86_64/bash-4.2.46-33.amzn2_syslog.x86_64.rpm
% rpm -qa | grep bash
bash-completion-2.1-6.amzn2.noarch
bash-4.2.46-33.amzn2_syslog.x86_64

# ログアウトして再度ログインする
% exit
$ ssh 

# 適当なコマンドを打つと syslog に履歴が残っているはず
$ ls
$ sudo tail /var/log/messages
...
May  1 07:04:00 ip-172-31-1-225 -bash: HISTORY: PID=15156 UID=1000 ls
May  1 07:04:04 ip-172-31-1-225 -bash: HISTORY: PID=15156 UID=1000 sudo tail /var/log/messages

ビルドした後は rpmbuild ディレクトリを削除すれば完了です。作成した RPM ファイルは S3 などに保存しておいてください。

% rm -rf ~/rpmbuild

参考