こんにちは。日々是発見が楽しみな西山です。
私はプライベートでもLinuxを弄り倒して、何かやりたいことがあるとぽんぽんインスタンスを作る人間です。
当然ながら、OSインストール直後のインスタンスには自分好みのアプリも、デフォルトと違う普段使いの設定も入っていません。それを毎回コマンドを叩いてセットアップするのは地味に面倒で、どうにか一発でできればいいのに……と長年考えていました。
……はい、今回のお話は全然難しいことではなく、よくある初期設定スクリプトを改めて自作してみた、という内容です。
シェルスクリプト? Codedeploy? CloudInit?
大げさなものを作りたくなかったので、実装は「シェルスクリプトをWebサーバーからダウンロードして実行する」方法にしました。
もちろんクラウド各社のデプロイスクリプト機能を使ったり、弊宅のようなオンプレでもCloudInitなどを使えますが、この初期設定スクリプトは色々な環境(ProxmoxのVM、CT、クラウドインスタンスなど)で使い回したかったので、あえてレガシーなシェルスクリプトで実装しています。
汎用性を損なわない、という点には気を使って制作したので、ここに掲載したコードは皆様好きにコピーして、各々使いやすいように改造して使ってもらえれば幸いです。
何をしてくれるのか
あらかじめ、アクセス可能なWebサーバーの適当なディレクトリ(例では /deploy )にスクリプトをアップロードしておきます。※Webサーバー上で実行権限を付ける必要はありません。
公開鍵や.vimrc、conf類は /deploy/files 以下に置いておきます。
インストールが済んだまっさらのAlmaLinux上にログインして su - でルートユーザーになり、/root ディレクトリで
curl -O https://example.com/deploy/setup.sh && chmod +x setup.sh && ./setup.sh
と実行すると、以下の処理を順番に実行します。
-
dnf update + 常用アプリインストール
-
タイムゾーンを日本に変更
-
デフォルトエディタを既定のnanoからvimに変更
-
sshユーザーの公開鍵を追加、カスタマイズした.vimrcとhistory設定を追加
-
カスタマイズしたsysctl.confの設置、sshdのパスワード認証禁止、chronyのタイムサーバーを日本のmfeedに変更
#!/bin/bash
# Exit immediately if a command exits with a non-zero status
set -e
# Variable definitions
BASE_URL="https://example.net/deploy/files"
CHRONY_CONF="/etc/chrony.conf"
SSHD_CONFIG="/etc/ssh/sshd_config"
NORMAL_USER="myuser"
echo "--- 1. System Update & package installation ---"
dnf install -y epel-release
dnf update -y
dnf install -y vim less tar which openssh-server
echo "--- 2. Set Timezone ---"
timedatectl set-timezone Asia/Tokyo
echo "--- 3. Set default editor ---"
update-alternatives --set editor /usr/bin/vim.basic
echo "--- 4. Setup SSH authorized_keys ---"
# Ensure the .ssh directory exists with correct permissions
# root user
mkdir -p ~/.ssh
chmod 700 ~/.ssh
#Normal user
mkdir -p /home/${NORMAL_USER}/.ssh
chmod 700 /home/${NORMAL_USER}/.ssh
# Download authorized_keys file from the web server
# root user
curl -L "${BASE_URL}/authorized_keys" -o ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# Normal user
curl -L "${BASE_URL}/authorized_keys" -o /home/${NORMAL_USER}/.ssh/authorized_keys
chmod 600 /home/${NORMAL_USER}/.ssh/authorized_keys
chown ${NORMAL_USER}: -R /home/${NORMAL_USER}/.ssh
echo "--- 5. Set vimrc ---"
# Download vimrc file from the web server
# root user
curl -L "${BASE_URL}/vimrc" -o ~/.vimrc
# Normal user
curl -L "${BASE_URL}/vimrc" -o /home/${NORMAL_USER}/.vimrc
echo "--- 6. Set history setting ---"
# Download history setting file from the web server
curl -L "${BASE_URL}/history_settings.sh" -o /etc/profile.d/history_settings.sh
echo "--- 7. Set sysctl ---"
# Download sysctl file from the web server
curl -L "${BASE_URL}/98-custom.conf" -o /etc/sysctl.d/98-custom.conf
echo "--- 8. Configure SSHD (Disable Password Authentication) ---"
if [ -f "$SSHD_CONFIG" ]; then
# Backup the original sshd_config
cp "$SSHD_CONFIG" "${SSHD_CONFIG}.bak"
# Replace PasswordAuthentication yes (or commented out version) with no
# This regex handles both '^PasswordAuthentication' and '^#PasswordAuthentication'
sed -i 's/^#?PasswordAuthentications+yes/PasswordAuthentication no/' "$SSHD_CONFIG"
# Ensure it's set to no even if the line didn't exist in the 'yes' format
if ! grep -q "^PasswordAuthentication" "$SSHD_CONFIG"; then
echo "PasswordAuthentication no" >> "$SSHD_CONFIG"
fi
# Restart sshd to apply changes
systemctl restart sshd
echo "SSHD configuration updated: Password authentication disabled."
fi
echo "--- 9. Configure chrony (NTP) ---"
if [ -f "$CHRONY_CONF" ]; then
# Create a backup of the original configuration
cp "$CHRONY_CONF" "${CHRONY_CONF}.bak"
# Comment out lines starting with 'server' or 'pool'
sed -i -e 's/^(server )/#1/' -e 's/^(pool )/#1/' "$CHRONY_CONF"
# Append the custom NTP server to the end of the file
echo "pool ntp.jst.mfeed.ad.jp iburst" >> "$CHRONY_CONF"
echo "Configuration updated. Backup created at ${CHRONY_CONF}.bak"
else
# Create a new file if it does not exist
echo "!!! No chrony conf file !!!"
fi
# Restart and enable the chrony service
systemctl restart chronyd
systemctl enable chronyd
echo "--- Setup completed successfully ---"

