3.1 準備動作
在 Linux 中,有一個最高權限的使用者帳號稱為 root
,這個帳號能夠對系統做任何事,因此你必須確保它不被他人竊取。當有人想要嘗試登入你的電腦時,他第一個會做的就是以 root
的身份來嘗試登入,因為這個帳號大家都知道,他只要猜密碼就可以了。為了避免這個問題,首先要做的就是讓 root
無法登入,既然無法登入,那密碼怎麼猜也沒用,這也就是為什麼我們需要先建立一個一般使用者,然後永遠只以一般使用者的帳號來登入系統。
使用一般使用者帳號來登入系統還是有風險,因為你仍然要輸入密碼,只要有密碼就能猜,能猜就可能被猜中;一個更加安全的方法是使用加密金鑰,你 (本機) 一把、伺服器一把,傳輸資料加、解密都靠它。
因為 Vagrant 已經建立了一個以加密連線方式登入的帳號 vagrant
,所以我們會用它來登入虛擬機器,但一般來說,你會以 root
登入一台初次安裝的伺服器。
首先,請先確認 Vagrant 的虛擬機器已經啟動並且登入:
vagrant up
vagrant ssh
這裡請你想像這台虛擬機器是遠在天邊的一台伺服器。
當你登入虛擬機器後,會是 vagrant
這個使用者帳號,我們要先把它切換成 root
:
[vagrant@localhost ~]$ su
# 接著輸入密碼 vagrant
# 確認目前身份
[root@localhost vagrant]# whoami
你會發現一般使用者和 root
的提示符號不同,一般使用者是 $
錢字號,root
則是 #
井字號。指令 su
可以用來切換身份為 root
。
到此為止是使用 Vagrant 環境所必須做的動作,之後的內容請想像你真的在操作一台剛安裝好的伺服器。
3.2 建立使用者
我們將練習建立一個 tony 使用者,並且使用金鑰來登入。
# 建立名稱為 tony 的使用者
adduser tony
# 設定 tony 使用者的密碼
passwd tony
如果你不想要這個使用者,可以刪除它:
# 刪除名為 tony 的使用者(保留家目錄)
userdel tony
# 同上,但同時刪除家目錄
userdel -r tony
使用者的家目錄在 /home
目錄底下,例如 tony 使用者的家目錄就是 /home/tony
。
註:請不要刪除 Vagrant 內建的 vagrant 使用者,因為 Vagrant 預設是使用該帳號登入。
3.3 使用金鑰登入伺服器
我們會使用終端機透過連線程式連到遠端的伺服器,早期是使用 telnet 來連線,但是它的缺點是以明碼傳輸資料,資料未經加密,會有被竊取的風險,因此後來都使用 SSH (Secure SHell) 來連線。SSH 是使用金鑰對來達成加密,金鑰由公鑰 (public key) 及私鑰 (private key) 配對使用。
當你第一次使用 SSH 連線到伺服器時,指令會像這樣:
ssh root@yourserver.com
伺服器會自行產生金鑰,並且傳送公鑰到你的電腦,你會收到是否要信任此公鑰的訊息,當你輸入 yes 後,就可以使用加密連線來通訊,接著輸入密碼來登入此伺服器,因為連線已經加密,所以不用擔心密碼被看見。
3.3.1 小心中間人攻擊
使用金鑰的連線方式仍是有風險的,由於公鑰是由伺服器送給你的,在這傳送的過程中,任何人都可能拿到這把公鑰。於是有心人就可以偷走這把公鑰,然後轉送它自己的公鑰給你,你會誤以為這是伺服器給你的公鑰而信任並使用它來傳送資料,這個有心人就可以在你和伺服器之間當成中間人,完全取得你和伺服器所傳送的資料,這就是中間人攻擊 (Man-in-the-middle attack, MITM)。中間人攻擊可以藉由身份驗證 (第三方的憑證認證機構來驗明正身) 和篡改檢測 (以連線時間過長來判斷是否被攻擊) 來防禦。
下圖為中間人攻擊的示意圖: 圖片來源:Miraceti - https://commons.wikimedia.org/w/index.php?curid=5672044
3.3.2 密碼驗證 vs 金鑰驗證
通常連線到伺服器的第一件事就是輸入帳號及密碼,但是每次登入都要做重複的事,久了就會覺得麻煩,二來如果帳號及密碼被猜到就完了,這就是密碼驗證的小缺點。相對來說,使用金鑰驗證就很方便,除了第一次使用需要設定以外,之後就可以直接登入,完全不用輸入密碼,當然也就不用擔心密碼被偷或被猜中的問題,唯一要注意的就是私鑰要保管好。
3.3.3 金鑰使用流程
首先,你在本機電腦中自行產生金鑰對,包含公鑰及私鑰,然後將公鑰以安全的方式上傳到遠端伺服器。當你在本機上透過 SSH 和遠端伺服器連線時,伺服器會以公鑰加密一段隨機文字,然後傳給本機;本機使用私鑰解開該加密的隨機文字,然後回傳結果給伺服器,伺服器確認正確後就會允許連線。
假設你有 5 台伺服器要管理,只要將公鑰分別存放到這 5 台伺服器上即可,擁有私鑰的本機就能成功連線,這也就是為什麼私鑰很重要,被偷了的話,任何人都可以使用該私鑰進行連線。
在產生金鑰對時也可以對私鑰設定密碼 (passphrase),假如私鑰被偷的話,就必須輸入對的密碼才能使用。但這樣在登入時就又會要求你輸入密碼,只不過這次不是伺服器上帳號的密碼,而是私鑰的密碼。
3.3.4 實戰 SSH 金鑰設定
步驟一:在本機上產生金鑰對在 Mac/Linux 上使用 ssh-keygen
指令來產生金鑰:
ssh-keygen -t rsa
它會詢問你要將金鑰存放在哪裡,預設的位置在使用者家目錄下的 .ssh
隱藏目錄中,例如: (Mac) /Users/tony/.ssh/ ,其中的 id_rsa
是私鑰的檔案名稱,id_rsa.pub
則是公鑰的檔案名稱。你可以直接按 Enter 使用預設值即可。
接著它會問你密碼 (passphrase),也就是私鑰的密碼,你可以留空白直接按 Enter,這樣的好處是,之後遠端連線登入伺服器時可以不用輸入密碼,比較方便。
完成後可以到使用者家目錄下的 .ssh
目錄查看是否有出現 id_rsd
及 id_rsa.pub
兩個檔案。這裡要注意,必須小心把私鑰保存好,例如備份,公鑰不見了可以由私鑰再次產生,但是私鑰沒了就沒了,只能再產生一個新的,而這個新的可無法登入你原本的伺服器,你得重新上傳這把和新私鑰配對的公鑰才行。如果私鑰被偷走,那個人就能透過私鑰連線到你的伺服器,請務必小心。
現在你已經擁有金鑰對,接下來就是把公鑰放到遠端伺服器上。
首先使用一般使用者帳號透過 ssh 連線登入,記住!絕對不要使用 root
帳號來登入。當你登入伺服器後,進入家目錄底下的 .ssh
目錄,沒有此目錄的話請自行建立 mkdir .ssh
,裡面應該會有 authorized_keys
這個檔案,沒有的話一樣自行建立 touch authorized_keys
,這個檔案會儲存公鑰,所有的公鑰都存放在這裡。
你有兩種方式來上傳公鑰:
# 本機輸入
ssh-copy-id username@123.45.56.78
# 這個指令會去預設目錄 ~/.ssh/id_rsa.pub 取公鑰上傳
# 如果你的目錄不一樣,可以加上 -i 選項來指定位置
ssh-copy-id -i ~/.ssh/id_rsa.pub username@123.45.56.78
# 這個 username 是指遠端伺服器的帳號,例如 tony
# 或是本機輸入
cat ~/.ssh/id_rsa.pub | ssh username@123.45.56.78 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# 將 id_rsa.pub 的內容輸出,透過 SSH 傳送到遠端伺服器帳號的 authorized_keys 檔案中
步驟三:權限設定
為了確保你的公鑰的安全,我們要設定這個目錄及檔案只有我本人可以讀取,假設帳號為 tony :
cd /home/tony
# 把 .ssh 目錄擁有者改為 tony
chown -R tony:tony .ssh
# 修改 .ssh 目錄的權限,只有 tony 能讀寫及進入
chmod 700 /home/tony/.ssh
# 修改 authorized_keys 檔案的權限,只有 tony 能讀寫
chmod 600 authorized_keys
# RedHat 系的 Fedora 及 CentOS 必須重新還原 SELinux 的類型
restorecon -Rv /home/tony/.ssh
# 最後記得重新啟動 sshd
systemctl restart sshd
這樣就完成了。現在 tony 這個使用者帳號已經可以使用 ssh 連線到伺服器了:
ssh tony@192.168.8.8 # 這個 ip 是前面的 Vagrant 設定檔指定的
來測試看看能否用 tony 登入吧。
要登出伺服器,有三種方式:
- 快速鍵 ctrl + d (建議用這個)
- 輸入 logout
- 輸入 exit
如果以上操作都順利的話,你現在已經完成登入安全的一半工作了。
3.4 關於 root
3.4.1 sudo
因為 root
的權限太大,實務上我們不會使用 root
的身分來操作系統,而是在需要的時候才使用 sudo
指令暫時取得 root
的權限來執行操作。如果每個帳號都能這麼做,那就沒有安全可言了,因此我們必須限制只有某些帳號才可以擁有 sudo
的能力,CentOS 為此設計了一個 wheel
群組,只有屬於 wheel
群組的使用者才能使用 sudo
。
首先,將可以使用 sudo
的使用者帳號加入 wheel
群組:
# 先查看目前帳號所屬群組
groups tony
# 結果 tony : tony
# 將帳號加入 wheel 群組
sudo usermod -aG wheel tony
# 再次查看結果
groups tony
# 結果 tony : tony wheel
現在帳號已經加入 wheel
群組了。接著要確認是否有把 wheel
群組設定為可以使用 sudo
:
sudo visudo
# 等同於 sudo vim /etc/sudoers
# 接下來會在 vi 中編輯內容
# 直接輸入 /%wheel 來搜尋,會找到以下內容
# Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL # <-- 確認這行的註解有拿掉,意義如下
# %群組名稱 來源主機=(可切換帳號) 可執行的指令
# 完成後存檔離開 (esc -> :wq)
如果你要查看目前有哪些使用者帳號屬於 wheel
群組:
getent group wheel
# 結果 wheel:x:10:tony
3.4.2 su
隨便一個使用者就能切換成 root
也是非常危險的事,所以我們要讓非 wheel
群組的使用者無法使用 su
指令來切換成 root
:
sudo vim /etc/pam.d/su
auth required pam_wheel.so use_uid # <-- 取消這行註解
接著編輯 /etc/login.defs
檔案:
sudo vim /etc/login.defs
# 將 "SU_WHEEL_ONLY yes" 加到 login.defs 檔尾
SU_WHEEL_ONLY yes
使用 su
指令會要求 root
的密碼,使用 sudo
則是使用當前使用者的密碼;有時候可以搭配使用 sudo su
,就不需要輸入 root
的密碼。
3.5 加強 SSH 安全
當你確定可以使用金鑰的方式來連線伺服器後,就可以把其他登入方式封掉,來保證連線的極度安全。
以下我們會修改 SSH 伺服器的設定檔 /etc/ssh/sshd_config
來做 3 件事:
sudo vim /etc/ssh/sshd_config
# 編輯時,請善用斜線加字串來搜尋,例如 /PermitRootLogin
- 將
#PermitRootLogin yes
改成PermitRootLogin no
這個動作會禁止使用root
帳號來登入。駭客要猜中你的帳號沒那麼容易,但root
這個帳號大家都知道,只要去猜它的密碼,猜中了就成了這台機器的神,所以禁止使用root
登入是很重要的事。請使用一般使用者帳號登入後,再視情況切換為root
。 - 將
#PasswordAuthentication yes
改成PasswordAuthentication no
猜中密碼這件事是有可能的,但是如果不能使用密碼來驗證登入,那連猜都沒得猜了,所以我們把使用密碼驗證這個功能禁止。但是你的使用者帳號仍然要設定密碼,絕對不要使用空白密碼。 - 將
#PermitEmptyPasswords no
改成PermitEmptyPasswords no
這個動作會禁止使用空白密碼。請記住絕對不要使用空白密碼,任何帳號都是,尤其是root
。
以上 3 個原始設定都是被註解掉沒有使用,現在我們將其啟用並且都設為不允許,請記得存檔後離開。
再提醒一次!請先確認你可以使用金鑰來連線登入伺服器,否則當 sshd_config 的設定生效後,你將無法使用一般方式登入伺服器。
記得要重新啟動 SSH 伺服器:
systemctl restart sshd
繼續閱讀:動手學 VPS 架站:使用 CentOS 7 + Nginx + PHP-FPM + MariaDB (6) - 防火牆
由 Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀
我要留言
留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。