今まではAnsibleで構成管理していましたが、現場ではコンテナで、個人でも使用頻度が低く、OS変更やバージョンアップの手間の方が大きくなって来たので、構成管理を止めて、メモを残す事にしました。
OSは、今まではCentOSを好んで使っていましたが、Streamになり、安定重視ではなくなった。
今回の目的、Dockerホストとしては、Ubuntuの方が良さそうですが、メモリが少ないので(2GB)、安定・軽量重視でDebianを選択しました。
バージョンは、LTSサポートが契約期間よりも長いものを選択しています。
- サーバー初期設定
- shをbashに切り替える
- Firewalldでポート制限
- TCP Wrapperで制限
- SSH設定変更
- パッケージを更新・追加
- viをvimに変更
- コンソールを使いやすく
- 不要なサービスを止める
- rsyslogを追加・設定変更
- その他設定変更
- メール送信できるようにする
- メール通知
サーバー初期設定
元々、手動でやっていた手順は、下記にまとめています。
スワップは2GBだったので、2GB追加して、4GBにしています。
shをbashに切り替える
矢印キーが使えるようにするなど、使いやすくします。
rootはOK
# echo $SHELL /bin/bash
admin(ユーザー)
$ echo $SHELL /bin/sh $ su - # sudo chsh -s /bin/bash admin $ su - admin
Firewalldでポート制限
VPSでもポート制限できますが、サーバー側でもしておいた方が安全です。
# apt install -y firewalld
自動起動で接続できなくなったので、VPSコンソールで設定しました。
# firewall-cmd --permanent --add-port=22123/tcp # firewall-cmd --reload
# firewall-cmd --list-ports 22123/tcp
TCP Wrapperで制限
同様に、制限しておいた方が安全です。
# cp -a /etc/hosts.allow /etc/hosts.allow,def # vi /etc/hosts.allow
### START ###
sshd: ALL
### END ###
# cp -a /etc/hosts.deny /etc/hosts.deny,def # vi /etc/hosts.deny
### START ###
ALL: ALL
### END ###
SSH設定変更
ポート変更、PW認証、rootログイン禁止は、サーバー初期設定で対応済みですが、
もう少し、カスタマイズしておきます。
# vi /etc/ssh/sshd_config
### START ###
LoginGraceTime 30s
### END ###
### START ###
MaxAuthTries 3
### END ###
### START ###
UseDNS no
### END ###
# systemctl restart sshd
パッケージを更新・追加
最新化と、使いそうなパッケージを追加(telnet, wget, jqは有ったので省略)しています。
# apt update # apt upgrade -y # apt autoremove -y # apt install -y ncat curl ftp git nkf
viをvimに変更
viは使いにくいので、vim-athena(クリップボード対応で軽量)に変更しています。
# apt install -y vim-athena
rootとadmin(ユーザー)で実行
#$ vi ~/.vimrc
syntax on
set clipboard=unnamedplus
コンソールを使いやすく
llやlをよく使う。合わせて推奨の設定(少しカスタマイズ)を追加しています。
rootとadmin(ユーザー)で実行
cp -a ~/.bashrc ~/.bashrc,def vi ~/.bashrc
### START ###
export LS_OPTIONS='--color=auto'
eval "$(dircolors)"
alias ls='ls $LS_OPTIONS'
alias ll='ls -lF'
alias l='ls -lAF'
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
### END ###
source ~/.bashrc
不要なサービスを止める
不要なものを停止して、脆弱性が見つかった時の影響を少なくしておきます。
# systemctl list-units --type=service --state=running UNIT LOAD ACTIVE SUB DESCRIPTION acpid.service loaded active running ACPI event daemon cron.service loaded active running Regular background program processing daemon dbus.service loaded active running D-Bus System Message Bus getty@tty1.service loaded active running Getty on tty1 ntpsec.service loaded active running Network Time Service qemu-guest-agent.service loaded active running QEMU Guest Agent serial-getty@ttyS0.service loaded active running Serial Getty on ttyS0 ssh.service loaded active running OpenBSD Secure Shell server systemd-journald.service loaded active running Journal Service systemd-logind.service loaded active running User Login Management systemd-resolved.service loaded active running Network Name Resolution systemd-udevd.service loaded active running Rule-based Manager for Device Events and Files user@1000.service loaded active running User Manager for UID 1000
acpid.service: ACPIイベント用。物理マシンなら有効だが、DockerやVMで不要なら停止可能
# systemctl stop acpid.service Warning: Stopping acpid.service, but it can still be activated by: acpid.path acpid.socket # systemctl stop acpid.service acpid.socket acpid.path # systemctl disable acpid.service acpid.socket acpid.path
rsyslogを追加・設定変更
システムのログを/var/logに出力するようにしておきます。
# apt install -y rsyslog # systemctl enable --now rsyslog
ファイル名を連番(.1)ではなく、日付(-20251101)にして、gzipで圧縮するようにしておきます。
# cp -a /etc/logrotate.conf /etc/logrotate.conf,def # vi /etc/logrotate.conf
### START ###
dateext
### END ###
### START ###
compress
### END ###
その他設定変更
/etc/hosts
今は問題になる事は少なそうですが、
localhostで127.0.0.1(IPv4)にリクエストされるように変更しておきます。
# cp -a /etc/hosts /etc/hosts,def # vi /etc/hosts
127.0.0.1 localhost
### START ###
# 127.0.1.1 localhost
### END ###
### START ###
#::1 localhost ip6-localhost ip6-loopback
::1 ip6-localhost ip6-loopback
### END ###
/etc/sysctl.conf
よりセキュアにする為の設定です。
# cp -a /etc/sysctl.conf /etc/sysctl.conf,def # vi /etc/sysctl.conf
### START ###
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.all.rp_filter=1
### END ###
### START ###
net.ipv4.tcp_syncookies=1
### END ###
### START ###
net.ipv4.ip_forward=1
### END ###
### START ###
net.ipv6.conf.all.forwarding=1
### END ###
### START ###
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
### END ###
### START ###
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
### END ###
### START ###
net.ipv4.conf.all.log_martians = 1
### END ###
# sysctl -p
/etc/security/limits.conf
安定性やパフォーマンス向上の為、ファイルディスクリプタ数の上限をあげておきます。
# cp -a /etc/security/limits.conf /etc/security/limits.conf,def # vi /etc/security/limits.conf
### START ###
* soft nofile 65536
* hard nofile 65536
### END ###
メール送信できるようにする
# apt install -y postfix bsd-mailx General mail configuration type: Local only System mail name: (ホスト名)※DNSで名前解決できるもの。TXTレコードもあった方がベスト # cp -a /etc/postfix/main.cf /etc/postfix/main.cf,def # vi /etc/postfix/main.cf
### START ###
# inet_interfaces = loopback-only
inet_interfaces = all
### END ###
### START ###
# default_transport = error
# relay_transport = error
### END ###
# systemctl enable --now postfix
aliases
# cp -a /etc/aliases /etc/aliases,def # vi /etc/aliases
### START ###
root: notice
notice: (転送先のメールアドレス)ex. admin+notice@example.com
warning: (転送先のメールアドレス)ex. admin+warning@example.com
critical: (転送先のメールアドレス)ex. admin+critical@example.com
### END ###
# newaliases
動作確認
メール送信して、受信できること
# echo "test" | mail -s "test for `hostname`" root
メール通知
ログ通知(logwatch)
# apt install -y logwatch # cd /usr/share/logwatch/default.conf # cp -a logwatch.conf logwatch.conf,def # vi logwatch.conf
### START ###
#Output = stdout
Output = mail
### END ###
動作確認
昨日分yesterday(今日ならtoday)を実行して、メールが受信できること
# logwatch --range yesterday
再起動通知: 不正再起動検知
再起動時間が短い場合は、監視だけでは気付けない場合があるのと、
想定外の再起動や、障害時の切り分けがし易いようにしています。
# crontab -e
### START ###
@reboot (/bin/date; dmesg) | /usr/bin/mail -s "Rebooted notice of `hostname`" warning
### END ###
動作確認
再起動して、メールが受信できること
# reboot
SSHログイン通知: 不正ログイン検知
毎回送ると大量になる事があるので、5分毎にまとめて送信するようにします。
ログインしたらファイルに出力
# cd /var/spool # touch .notice_ssh_login # chmod 622 .notice_ssh_login # cd /var/log # touch ssh_login.log # chmod 662 ssh_login.log # chown root:adm ssh_login.log # vi /etc/ssh/sshrc
### START ###
echo "`date +"%Y/%m/%d %H:%M:%S"` $SSH_CLIENT $SSH_TTY $USER" | tee -a /var/spool/.notice_ssh_login >> /var/log/ssh_login.log
### END ###
5分毎にファイルの内容を送信
# cd /usr/local/bin # vi notice_ssh_login.sh
#!/bin/sh
BATCH_NAME='notice_ssh_login'
LOG_FILE="/var/log/$BATCH_NAME.log"
TARGET_PATH='/var/spool/.notice_ssh_login'
ATTR_CODE=622
GROUP_NAME='root'
error_msg=''
write_log() {
echo -e "`date +"%Y/%m/%d %H:%M:%S"` ($$) [$1] $2" >> $LOG_FILE
[ $1 = 'ERROR' ] && error_msg="$error_msg[$1] $2\n"
}
send_error_mail() {
[ -z "$error_msg" ] && return
echo -e "$error_msg" | mail -s "[WARNING]$BATCH_NAME report for `hostname`" -r crond warning
write_log 'INFO' 'Send error mail'
}
send_report_mail() {
if [ ! -e "$TARGET_PATH" ]; then
write_log 'ERROR' "Not found $TARGET_PATH"
return
fi
if [ ! -s "$TARGET_PATH" ]; then
write_log 'INFO' 'Skip send mail'
return
fi
new=${TARGET_PATH}.new
touch $new > /dev/null 2>> $LOG_FILE
if [ $? -ne 0 ]; then
write_log 'ERROR' "Touch $new"
return
fi
chmod $ATTR_CODE $new > /dev/null 2>> $LOG_FILE
if [ $? -ne 0 ]; then
write_log 'ERROR' "Chmod $new"
return
fi
chgrp $GROUP_NAME $new > /dev/null 2>> $LOG_FILE
if [ $? -ne 0 ]; then
write_log 'ERROR' "Chgrp $new"
return
fi
old=${TARGET_PATH}.old
mv $TARGET_PATH $old > /dev/null 2>> $LOG_FILE
if [ $? -ne 0 ]; then
write_log 'ERROR' "Move $TARGET_PATH -> $old"
return
fi
mv $new $TARGET_PATH > /dev/null 2>> $LOG_FILE
if [ $? -ne 0 ]; then
write_log 'ERROR' "Move $new -> $TARGET_PATH"
return
fi
cat $old | mail -s "$BATCH_NAME report for `hostname`" -r crond root
write_log 'INFO' 'Send mail'
}
write_log 'INFO' '=== START ==='
send_report_mail
send_error_mail
write_log 'INFO' '=== END ==='
# chmod 740 notice_ssh_login.sh # chown root:adm notice_ssh_login.sh # vi /etc/cron.d/notice_ssh_login
### START ###
*/5 * * * * root /usr/local/bin/notice_ssh_login.sh
### END ###
logrotate
ログのパーミッションやグループが変わらないようにしておきます。
# vi /etc/logrotate.d/ssh_login
### START ###
/var/log/ssh_login.log {
missingok
create 0662 root adm
}
### END ###
# vi /etc/logrotate.d/notice_ssh_login
### START ###
/var/log/notice_ssh_login.log {
missingok
create 0662 root adm
}
### END ###
