Ubuntu 伺服器初始設定:在全新安裝的 Ubuntu 伺服器上開始的 9 個步驟

測試環境Debian 系列Ubuntu 24.04.5 LTSroot · 一般使用者帳號
已確認 Ubuntu 伺服器初始設定作業

拿到新伺服器時,在部署任何服務之前,會先做一次 Ubuntu 伺服器初始設定。我們在 DigitalOcean 建立的 Ubuntu 24.04 伺服器上以 root 連線,從套件更新開始,依序設定 sudo 使用者、金鑰登入、防火牆、時區、自動安全更新到 swap,並確認重新開機後設定仍然保留。

下方的結果框是依此順序執行指令的輸出。伺服器 IP 203.0.113.10 是範例值,新建立的一般使用者名稱定為 deploy。

🎯 重點
套件更新與是否需要重新開機的確認
sudo 群組中的一般使用者 deploy
deploy 確認金鑰登入後 root 封鎖登入
ufw只允許 SSH、80、443 連接埠
時區變更與自動安全更新確認
2GB swap 檔案與重新開機後設定保留確認
前提條件
先讀文章ssh-keygenssh 指令
連線root可連線的 SSH 金鑰與 Ubuntu 24.04 伺服器

1️⃣ Ubuntu 套件更新

即使是剛建立的伺服器,也有等待安裝的更新。重新取得套件清單後,在實際安裝之前先確認會有哪些變更。

🔲 apt-get update

export DEBIAN_FRONTEND=noninteractive

下方的 apt-get 指令是先設定這個值之後再執行的。設定這個值後,安裝套件時不會跳出詢問設定的視窗,會直接套用預設答案。

apt-get update
Hit:1 http://mirrors.digitalocean.com/ubuntu noble InRelease
Hit:2 http://mirrors.digitalocean.com/ubuntu noble-updates InRelease
Hit:3 http://mirrors.digitalocean.com/ubuntu noble-backports InRelease
Hit:4 https://repos-droplet.digitalocean.com/apt/droplet-agent main InRelease
Hit:5 http://security.ubuntu.com/ubuntu noble-security InRelease
Reading package lists...

🔲 apt-get -s upgrade

apt-get -s upgrade
Calculating upgrade...
The following upgrades have been deferred due to phasing:
  libsqlite3-0
The following packages will be upgraded:
  apt apt-transport-https apt-utils bind9-dnsutils bind9-host bind9-libs
  cloud-init distro-info-data gir1.2-glib-2.0 git git-man libapt-pkg6.0t64
  libbrotli1 libglib2.0-0t64 libglib2.0-bin libglib2.0-data liblzma5
  libmspack0t64 libpcre2-8-0 python3-jwt python3-twisted tmux
  ubuntu-pro-client ubuntu-pro-client-l10n xz-utils zlib1g
26 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.

-s 選項是不安裝、只計算結果的模擬執行。這台伺服器有 26 個套件要升級,其中 libsqlite3-0 以 [deferred due to phasing] 被排除在這次升級之外。套件數量會因伺服器建立的時間與使用的映像檔而不同。

🔲 apt-get -y upgrade

apt-get -y upgrade
26 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
Need to get 15.4 MB of archives.
After this operation, 398 kB of additional disk space will be used.

安裝完成後,接著會列出重新啟動的服務。

Running kernel seems to be up-to-date.

Restarting services...
 /etc/needrestart/restart.d/systemd-manager
 systemctl restart cron.service fwupd.service multipathd.service packagekit.service polkit.service ssh.service systemd-journald.service systemd-networkd.service systemd-resolved.service systemd-timesyncd.service systemd-udevd.service udisks2.service

Service restarts being deferred:
 systemctl restart ModemManager.service
 /etc/needrestart/restart.d/dbus.service
 systemctl restart systemd-logind.service
 systemctl restart unattended-upgrades.service

安裝需要重新開機的更新時,會產生 /var/run/reboot-required 檔案。這次出現 [Running kernel seems to be up-to-date.],也沒有產生該檔案,因此不重新開機就進入下一步。

2️⃣ Ubuntu 新增使用者與 sudo 權限

平常的工作用一般使用者進行,只有管理指令用 sudo 執行。sudo 是用自己的密碼而不是 root 密碼提升權限,因此會留下誰執行了哪個指令的紀錄。

🔲 adduser deploy

adduser deploy
info: Adding user `deploy' ...
info: Selecting UID/GID from range 1000 to 59999 ...
info: Adding new group `deploy' (1000) ...
info: Adding new user `deploy' (1000) with group `deploy (1000)' ...
info: Creating home directory `/home/deploy' ...
info: Copying files from `/etc/skel' ...
New password: 
Retype new password: 
passwd: password updated successfully
Changing the user information for deploy
Enter the new value, or press ENTER for the default
	Full Name []: 
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] Y
info: Adding new user `deploy' to supplemental / extra groups `users' ...
info: Adding user `deploy' to group `users' ...

adduser 是包裝 useradd的工具,會建立家目錄與群組,然後依序詢問密碼與使用者資訊。密碼輸入時不會顯示在畫面上,姓名、電話等資訊可以直接按 Enter 留空。

🔲 usermod -aG sudo deploy

usermod -aG sudo deploy
groups deploy
deploy : deploy sudo users

🔲 su

加入 sudo 群組的使用者可以用 sudo 執行管理指令。用 su 切換到 deploy 帳號並確認權限。

su - deploy
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
whoami
deploy
sudo whoami
[sudo] password for deploy: 
root
exit

加上 sudo 後會詢問 deploy 的密碼,輸入正確時指令會以 root 權限執行。

3️⃣ 新使用者的 SSH 金鑰註冊

一開始只有 root 註冊了 SSH 金鑰,所以 deploy 無法用金鑰登入。將 root 的 authorized_keys 複製到 deploy 的家目錄。

🔲 install -o deploy -g deploy

install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
ls -la /home/deploy/.ssh
total 12
drwx------ 2 deploy deploy 4096 Nov  5 11:48 .
drwxr-x--- 3 deploy deploy 4096 Nov  5 11:48 ..
-rw------- 1 deploy deploy  100 Nov  5 11:48 authorized_keys

install 一次完成建立資料夾、複製,以及指定擁有者與權限。sshd 在接受登入之前會檢查使用者檔案的權限與擁有者(StrictModes),因此將 .ssh 資料夾設為 700,authorized_keys 設為 600。

🔲 ssh deploy@203.0.113.10

不要關閉目前開著的 root 視窗,先在新的終端機視窗確認能否以 deploy 連線。

ssh deploy@203.0.113.10
whoami
deploy
🧭 不會被鎖在外面的設定順序
說明圖解
🧭 步驟
🔑① 複製金鑰root 金鑰給 deploy
➜
🪟② 新視窗確認root 視窗保持開啟
➜
⛔③ 封鎖 root 登入PermitRootLogin no
➜
🪟④ 新視窗確認deploy 連線不變
✅⑤ 允許 SSHufw allow OpenSSH
➜
🧱⑥ 啟用 ufw只開放允許的連接埠
➜
🪟⑦ 新視窗確認連線不變
將 root 的 authorized_keys 複製到 deploy 的家目錄。
不要關閉目前開著的 root 視窗,在新的終端機視窗確認能否以 deploy 金鑰登入。
確認 deploy 能連線後再封鎖 root 登入。若新視窗無法連線,就在保持開啟的視窗中還原。
重新載入 SSH 設定後,在新視窗確認 deploy 連線是否仍然正常。
啟用防火牆之前,先加入允許 SSH 的規則。
一啟用,未允許的連線就會被封鎖,因此必須先加入允許 SSH 的規則。
啟用防火牆後,在新視窗確認能否再次以 deploy 連線。

4️⃣ 封鎖 SSH root 登入

Ubuntu 24.04 的 sshd_config 會在最上方的 Include 行先載入 /etc/ssh/sshd_config.d/ 資料夾中的檔案,同一項目以先讀到的值為準。因此變更設定前,要先確認目前套用的值以及該值所在的檔案。

/etc/ssh└─ sshd_config  最上方 Include /etc/ssh/sshd_config.d/*.conf   ├─ ① sshd_config.d/50-cloud-init.conf         PasswordAuthentication no   ├─ ② sshd_config.d/60-cloudimg-settings.conf  PasswordAuthentication no   └─ ③ sshd_config 第42行                         PermitRootLogin yes → no

🔲 sshd -T

sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication) '
permitrootlogin yes
passwordauthentication no
sudo grep -rn 'PasswordAuthentication' /etc/ssh/sshd_config.d/
/etc/ssh/sshd_config.d/60-cloudimg-settings.conf:1:PasswordAuthentication no
/etc/ssh/sshd_config.d/50-cloud-init.conf:1:PasswordAuthentication no

密碼登入已在 sshd_config.d 內的兩個檔案中關閉,要改的只有主檔案中 root 登入的那一行。

🔲 sed -i PermitRootLogin

sudo grep -n '^PermitRootLogin' /etc/ssh/sshd_config
42:PermitRootLogin yes
sudo sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sudo grep -n '^PermitRootLogin' /etc/ssh/sshd_config
42:PermitRootLogin no

🔲 systemctl reload ssh

sudo sshd -t
sudo systemctl reload ssh
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication) '
permitrootlogin no
passwordauthentication no

sshd -t 會檢查設定語法,沒有任何輸出就表示沒有錯誤。重新載入後,在新視窗確認 deploy 連線仍然正常,再以 root 連線看看是否被拒絕。

ssh root@203.0.113.10
root@203.0.113.10: Permission denied (publickey).

即使金鑰正確也無法以 root 登入,管理工作要以 deploy 連線後用 sudo 進行。

5️⃣ Ubuntu 防火牆 ufw

ufw 是 Ubuntu 的預設防火牆工具,但一開始是關閉的。一啟用,未允許的連線就會被封鎖,因此先加入允許 SSH 的規則,最後再啟用。

sudo ufw status verbose
Status: inactive

🔲 ufw allow OpenSSH

sudo ufw app list
Available applications:
  OpenSSH
sudo ufw allow OpenSSH
Rules updated
Rules updated (v6)
sudo ufw allow 80/tcp
Rules updated
Rules updated (v6)
sudo ufw allow 443/tcp
Rules updated
Rules updated (v6)
sudo ufw show added
Added user rules (see 'ufw status' for running firewall):
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp

OpenSSH 是開放 22 號連接埠的設定檔,80 與 443 是網頁伺服器使用的連接埠。規則會同時加入 IPv4 與 IPv6。

🔲 ufw enable

sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp (OpenSSH)           ALLOW IN    Anywhere                  
80/tcp                     ALLOW IN    Anywhere                  
443/tcp                    ALLOW IN    Anywhere                  
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)             
80/tcp (v6)                ALLOW IN    Anywhere (v6)             
443/tcp (v6)               ALLOW IN    Anywhere (v6)             

預設會封鎖傳入連線,只開放允許的三個連接埠,開機時也會啟用。啟用後在新視窗再次以 deploy 連線,並確認規則編號。

sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] OpenSSH                    ALLOW IN    Anywhere                  
[ 2] 80/tcp                     ALLOW IN    Anywhere                  
[ 3] 443/tcp                    ALLOW IN    Anywhere                  
[ 4] OpenSSH (v6)               ALLOW IN    Anywhere (v6)             
[ 5] 80/tcp (v6)                ALLOW IN    Anywhere (v6)             
[ 6] 443/tcp (v6)               ALLOW IN    Anywhere (v6)             

6️⃣ Ubuntu 時區設定

一開始的時區是 Etc/UTC。為了讓日誌與排程工作的時間符合伺服器所在地區,這台建立在新加坡地區的伺服器設定為 Asia/Singapore。

timedatectl
               Local time: Thu 2026-11-05 12:00:31 UTC
           Universal time: Thu 2026-11-05 12:00:31 UTC
                 RTC time: Thu 2026-11-05 12:00:31
                Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

🔲 timedatectl list-timezones

timedatectl list-timezones | grep Singapore
Asia/Singapore

🔲 timedatectl set-timezone

sudo timedatectl set-timezone Asia/Singapore
timedatectl
               Local time: Thu 2026-11-05 20:00:32 +08
           Universal time: Thu 2026-11-05 12:00:32 UTC
                 RTC time: Thu 2026-11-05 12:00:32
                Time zone: Asia/Singapore (+08, +0800)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

改變的只有 Local time 與 Time zone 兩行,時鐘同步(NTP)與 UTC 時間維持不變。

7️⃣ unattended upgrades 自動安全更新

Ubuntu 會用 unattended-upgrades 套件自動安裝安全更新,這個套件一開始就已安裝並啟用。因此這個步驟要確認它是否啟用,以及會自動安裝哪些內容。

🔲 dpkg-query -W

dpkg-query -W unattended-upgrades
unattended-upgrades	2.9.1+nmu4ubuntu1
systemctl is-enabled unattended-upgrades apt-daily.timer apt-daily-upgrade.timer
enabled
enabled
enabled

🔲 cat 20auto-upgrades

cat /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

兩個值中的 1 代表一天一次,改成 0 就會關閉自動更新。要安裝哪些內容由 50unattended-upgrades 檔案決定。

grep -vE '^[[:space:]]*(//|$)' /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
	"${distro_id}:${distro_codename}";
	"${distro_id}:${distro_codename}-security";
	"${distro_id}ESMApps:${distro_codename}-apps-security";
	"${distro_id}ESM:${distro_codename}-infra-security";
};
Unattended-Upgrade::Package-Blacklist {
};
Unattended-Upgrade::DevRelease "auto";

允許的來源中有 -security,沒有 -updates,因此一般更新不會自動安裝,只會安裝安全更新。若一般更新也要自動接收,就在這個檔案中取消 -updates 行的註解。

🔲 unattended-upgrade

sudo unattended-upgrade --dry-run --debug
Starting unattended upgrades script
Allowed origins are: o=Ubuntu,a=noble, o=Ubuntu,a=noble-security, o=UbuntuESMApps,a=noble-apps-security, o=UbuntuESM,a=noble-infra-security

這是同一次執行的最後兩行。

No packages found that can be upgraded unattended and no pending auto-removals
The list of kept packages can't be calculated in dry-run mode.

--dry-run 不安裝,只計算自動更新要做的事。因為已經完成套件更新,所以顯示沒有要自動安裝的套件。實際執行的紀錄會留在 /var/log/unattended-upgrades/ 資料夾。

sudo ls -l /var/log/unattended-upgrades/
total 32
-rw-r--r-- 1 root root     0 Nov  5 20:00 unattended-upgrades-dpkg.log
-rw-r--r-- 1 root root     0 Nov  5 17:34 unattended-upgrades-shutdown.log
-rw-r--r-- 1 root root 29093 Nov  5 20:04 unattended-upgrades.log

8️⃣ Ubuntu swap 記憶體設定

這台伺服器的記憶體是 1GB,一開始 swap 為 0。部署應用程式之前,先建立 2GB 的 swap 檔案,並登錄到 /etc/fstab,讓它在重新開機後也會啟用。

free -h
               total        used        free      shared  buff/cache   available
Mem:           961Mi       328Mi       161Mi       4.0Mi       631Mi       633Mi
Swap:             0B          0B          0B
df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        24G  2.0G   22G   9% /

🔲 fallocate -l 2G /swapfile

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
ls -lh /swapfile
-rw------- 1 root root 2.0G Nov  5 20:04 /swapfile

🔲 mkswap /swapfile

sudo mkswap /swapfile
Setting up swapspace version 1, size = 2 GiB (2147479552 bytes)
no label, UUID=0b43ccd8-5b4a-4048-9b84-eee12667b387

🔲 swapon /swapfile

sudo swapon /swapfile
swapon --show
NAME      TYPE SIZE USED PRIO
/swapfile file   2G   0B   -2
free -h
               total        used        free      shared  buff/cache   available
Mem:           961Mi       328Mi       160Mi       4.0Mi       632Mi       632Mi
Swap:          2.0Gi          0B       2.0Gi

🔲 tee -a /etc/fstab

swapon 只是現在啟用,若要重新開機後也啟用,就在 fstab 加一行。

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
/swapfile none swap sw 0 0

9️⃣ Ubuntu 伺服器初始設定確認

確認設定在重新開機後仍然保留,Ubuntu 初始設定就完成了。

🔲 systemctl reboot

sudo systemctl reboot

🔲 uptime -p

重新開機後,再次以 deploy 連線。

uptime -p
up 2 minutes
swapon --show
NAME      TYPE SIZE USED PRIO
/swapfile file   2G   0B   -2
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication) '
permitrootlogin no
passwordauthentication no
sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp (OpenSSH)           ALLOW IN    Anywhere                  
80/tcp                     ALLOW IN    Anywhere                  
443/tcp                    ALLOW IN    Anywhere                  
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)             
80/tcp (v6)                ALLOW IN    Anywhere (v6)             
443/tcp (v6)               ALLOW IN    Anywhere (v6)             
timedatectl | head -n 4
               Local time: Thu 2026-11-05 20:06:35 +08
           Universal time: Thu 2026-11-05 12:06:35 UTC
                 RTC time: Thu 2026-11-05 12:06:35
                Time zone: Asia/Singapore (+08, +0800)
systemctl is-active unattended-upgrades ssh.socket
active
active

swap、SSH 設定、防火牆、時區、自動更新都與重新開機前相同。接下來這台伺服器會用 PM2 與 Nginx 部署 Node.js 應用程式。

🔢 FAQ & 推薦內容

保持原樣即可。以 [deferred due to phasing] 被排除的套件是正在分階段發布的更新。Ubuntu 會先將部分更新只發布給部分伺服器,沒有問題後再擴大到所有伺服器。安全更新不採分階段發布,被排除的套件會在發布範圍擴大後,於下一次升級時一起安裝。

自動更新工作一天執行一次,由 apt-daily.timer 與 apt-daily-upgrade.timer 兩個計時器在固定時間後隨機延遲執行。這台伺服器的 apt-daily-upgrade.timer 下次執行排在隔天 06:27:59(+08)。若伺服器關機錯過該時間,可能會在下次開機時立刻執行,因此開機後 apt 工作有時會等待一下。

預設設定下不會重新開機。50unattended-upgrades 中 Automatic-Reboot 的預設值是 false,這台伺服器的設定中也沒有啟用該行。安裝需要重新開機的更新時會產生 /var/run/reboot-required 檔案,所以有該檔案時再自行重新開機。

ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Prove your humanity: 1   +   10   =