Linuxの初期設定を自動化してみた

西山
2026-02-24
2026-02-24

こんにちは。日々是発見が楽しみな西山です。

私はプライベートでも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

と実行すると、以下の処理を順番に実行します。

  1. dnf update + 常用アプリインストール

  2. タイムゾーンを日本に変更

  3. デフォルトエディタを既定のnanoからvimに変更

  4. sshユーザーの公開鍵を追加、カスタマイズした.vimrcとhistory設定を追加

  5. カスタマイズした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 ---"