Ubuntu 伺服器初始設定:在全新安裝的 Ubuntu 伺服器上開始的 9 個步驟
拿到新伺服器時,在部署任何服務之前,會先做一次 Ubuntu 伺服器初始設定。我們在 DigitalOcean 建立的 Ubuntu 24.04 伺服器上以 root 連線,從套件更新開始,依序設定 sudo 使用者、金鑰登入、防火牆、時區、自動安全更新到 swap,並確認重新開機後設定仍然保留。
下方的結果框是依此順序執行指令的輸出。伺服器 IP 203.0.113.10 是範例值,新建立的一般使用者名稱定為 deploy。
1️⃣ Ubuntu 套件更新
即使是剛建立的伺服器,也有等待安裝的更新。重新取得套件清單後,在實際安裝之前先確認會有哪些變更。
🔲 apt-get update
export DEBIAN_FRONTEND=noninteractive下方的 apt-get 指令是先設定這個值之後再執行的。設定這個值後,安裝套件時不會跳出詢問設定的視窗,會直接套用預設答案。
apt-get updateHit: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 upgradeCalculating 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 upgrade26 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 deployinfo: 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 deploygroups deploydeploy : deploy sudo users🔲 su
加入 sudo 群組的使用者可以用 sudo 執行管理指令。用 su 切換到 deploy 帳號並確認權限。
su - deployTo run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.whoamideploysudo whoami[sudo] password for deploy:
rootexit加上 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/.sshinstall -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keysls -la /home/deploy/.sshtotal 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_keysinstall 一次完成建立資料夾、複製,以及指定擁有者與權限。sshd 在接受登入之前會檢查使用者檔案的權限與擁有者(StrictModes),因此將 .ssh 資料夾設為 700,authorized_keys 設為 600。
🔲 ssh deploy@203.0.113.10
不要關閉目前開著的 root 視窗,先在新的終端機視窗確認能否以 deploy 連線。
ssh deploy@203.0.113.10whoamideploy4️⃣ 封鎖 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 nosudo 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_config42:PermitRootLogin yessudo sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_configsudo grep -n '^PermitRootLogin' /etc/ssh/sshd_config42:PermitRootLogin no🔲 systemctl reload ssh
sudo sshd -tsudo systemctl reload sshsudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication) 'permitrootlogin no
passwordauthentication nosshd -t 會檢查設定語法,沒有任何輸出就表示沒有錯誤。重新載入後,在新視窗確認 deploy 連線仍然正常,再以 root 連線看看是否被拒絕。
ssh root@203.0.113.10root@203.0.113.10: Permission denied (publickey).即使金鑰正確也無法以 root 登入,管理工作要以 deploy 連線後用 sudo 進行。
5️⃣ Ubuntu 防火牆 ufw
ufw 是 Ubuntu 的預設防火牆工具,但一開始是關閉的。一啟用,未允許的連線就會被封鎖,因此先加入允許 SSH 的規則,最後再啟用。
sudo ufw status verboseStatus: inactive🔲 ufw allow OpenSSH
sudo ufw app listAvailable applications:
OpenSSHsudo ufw allow OpenSSHRules updated
Rules updated (v6)sudo ufw allow 80/tcpRules updated
Rules updated (v6)sudo ufw allow 443/tcpRules updated
Rules updated (v6)sudo ufw show addedAdded user rules (see 'ufw status' for running firewall):
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcpOpenSSH 是開放 22 號連接埠的設定檔,80 與 443 是網頁伺服器使用的連接埠。規則會同時加入 IPv4 與 IPv6。
🔲 ufw enable
sudo ufw enableCommand may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startupsudo ufw status verboseStatus: 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 numberedStatus: 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 SingaporeAsia/Singapore🔲 timedatectl set-timezone
sudo timedatectl set-timezone Asia/Singaporetimedatectl 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-upgradesunattended-upgrades 2.9.1+nmu4ubuntu1systemctl is-enabled unattended-upgrades apt-daily.timer apt-daily-upgrade.timerenabled
enabled
enabled🔲 cat 20auto-upgrades
cat /etc/apt/apt.conf.d/20auto-upgradesAPT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";兩個值中的 1 代表一天一次,改成 0 就會關閉自動更新。要安裝哪些內容由 50unattended-upgrades 檔案決定。
grep -vE '^[[:space:]]*(//|$)' /etc/apt/apt.conf.d/50unattended-upgradesUnattended-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 --debugStarting 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.log8️⃣ 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 0Bdf -h /Filesystem Size Used Avail Use% Mounted on
/dev/vda1 24G 2.0G 22G 9% /🔲 fallocate -l 2G /swapfile
sudo fallocate -l 2G /swapfilesudo chmod 600 /swapfilels -lh /swapfile-rw------- 1 root root 2.0G Nov 5 20:04 /swapfile🔲 mkswap /swapfile
sudo mkswap /swapfileSetting up swapspace version 1, size = 2 GiB (2147479552 bytes)
no label, UUID=0b43ccd8-5b4a-4048-9b84-eee12667b387🔲 swapon /swapfile
sudo swapon /swapfileswapon --showNAME TYPE SIZE USED PRIO
/swapfile file 2G 0B -2free -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 09️⃣ Ubuntu 伺服器初始設定確認
確認設定在重新開機後仍然保留,Ubuntu 初始設定就完成了。
🔲 systemctl reboot
sudo systemctl reboot🔲 uptime -p
重新開機後,再次以 deploy 連線。
uptime -pup 2 minutesswapon --showNAME TYPE SIZE USED PRIO
/swapfile file 2G 0B -2sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication) 'permitrootlogin no
passwordauthentication nosudo ufw status verboseStatus: 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.socketactive
activeswap、SSH 設定、防火牆、時區、自動更新都與重新開機前相同。接下來這台伺服器會用 PM2 與 Nginx 部署 Node.js 應用程式。
🔢 FAQ & 推薦內容
ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。