Ubuntu下使用CIFS掛載Windows共享資源
前言
本篇記錄兩種在Ubuntu下掛載Windows CIFS的方式:mount
及/etc/fstab
。
方法一:mount
cifs-utils
是掛載SMB/CIFS shares所需的套件,使用以下指令安裝:
sudo apt update -y
sudo apt install cifs-utils -y
創建掛載的目標路徑,並實際掛載:
sudo mkdir /mnt/<your_target_dir>
sudo mount -t cifs -o vers=1.0,user=<yourusername>,password=<yourpassword> "//<windows_share_ip_addr>/<your_source_dir>" /mnt/<your_target_dir>
其中//<windows_share_ip_addr>/<your_source_dir>
是掛載的源目錄,/mnt/<your_target_dir>
是掛載的目標目錄。<yourusername>
及<yourpassword>
則是用於登入Windows CIFS share的帳號密碼。
如果出現以下錯誤:
mount error(95): Operation not supported
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)
參考挂载群晖NAS遇到mount error(95):Operation not supported,可以嘗試改用SMB協議3.0版或2.0版:
sudo mount -t cifs -o vers=3.0,user=<yourusername>,password=<yourpassword> "//<windows_share_ip_addr>/<your_source_dir>" /mnt/<your_target_dir>
sudo mount -t cifs -o vers=2.0,user=<yourusername>,password=<yourpassword> "//<windows_share_ip_addr>/<your_source_dir>" /mnt/<your_target_dir>
方法二:/etc/fstab
上面的做法是把帳號密碼以明文寫在指令中的,如果想用安全一點的方式,可以參考Mount Windows (CIFS) shares on Linux with credentials in a secure way。
它的做法是把帳號密碼記錄到一個只有root可讀的檔案裡,然後在掛載時到該檔案裡提取所需的帳號密碼。
編輯credential檔案:
sudo vim /root/.smbcred
填上登入Windows CIFS所需的帳號密碼:
username=<yourusername>
password=<yourpassword>
將它改成只有root可讀:
sudo chmod 400 /root/.smbcred
查看權限修改是否成功:
sudo ls -al /root/.smbcred
-r-------- 1 root root 32 Apr 29 17:31 /root/.smbcred
接下來編輯/etc/fstab
這個檔案:
sudo vim /etc/fstab
參考/etc/fstab 檔案說明,它的作用如下:
Linux 下有一個配置檔案 /etc/fstab,它的作用是設定硬碟分割區或其化儲存裝置,在開機時掛載點及如何掛載等選項。
在裡面加上如下內容:
//<windows_share_ip_addr>/<your_source_dir> /mnt/<your_target_dir> cifs credentials=/root/.smbcred 0 0
如果想指定SMB協議版本,參考Specify SMB 3.0 in /etc/fstab:
//<windows_share_ip_addr>/<your_source_dir> /mnt/<your_target_dir> cifs vers=3.0,credentials=/root/.smbcred 0 0
上面這種做法需要sudo權限,並且掛載目錄的擁有者會是root。
如果希望掛載後的目錄的擁有者是一個non-root的使用者(這樣一來對掛載目錄進行存取時就不必加sudo),參考mount share cifs folder without sudo,可以改為下述內容:
//<windows_share_ip_addr>/<your_source_dir> /mnt/<your_target_dir> cifs credentials=/home/<username>/.smbcred,noauto,user 0 0
然後記得要創建/mnt/<your_target_dir>
這個目錄:
sudo mkdir /mnt/<your_target_dir>
最後使用以下指令掛載:
mount /mnt/<your_target_dir>
注意如果使用root身份掛載,則掛載點的owner將會是root,對後續存取造成問題,所以掛載前要記得先切回一般使用者身份。
設定開機自動掛載
筆者是在Ubuntu 20.04的docker container裡進行測試的,照著方法二的步驟做了之後,發現docker container重啟後並未自動掛載。
試了CIFS mount through fstab not mounting at boot裡提到的幾個方法後都沒有用,最後是參考HowTo: Remount /etc/fstab Without Reboot in Linux,在/etc/bash.bashrc
裡加上:
sudo mount -a
但是這代表每次登入時都還要再輸入一次密碼,為了避免這種麻煩,可以仿照上面的方式,在家目錄建立一個只有root可讀的`.password``檔案:
sudo vim /home/<user_name>/.password
在裡面填入登入密碼,然後將/etc/bash.bashrc
裡的sudo mount -a
改成:
cat /home/<user_name>/.password | sudo -S mount -a
如此一來,在不同的使用者登入時,都會自動掛載。
上面這種做法需要sudo權限,如果希望一般的使用者也能mount,可以改用:
for dir in $(ls -d -1 "/mnt/"**/)
do
# returns 0 means already mount
findmnt $dir > /dev/null
res=$?
if [ $res -eq 1 ]; then
#echo "mount $dir"
mount $dir
cd $dir
fi
done
cd ~
參考What is the noauto mount flag for?,因為在/etc/fstab
中,掛載目錄都被加上了noauto
這個flag,所以mount -a
不會對它們進行自動掛載。上述腳本的邏輯為:尋找/mnt/
下的所有目錄,對其中尚未被掛載者,使用mount
進行掛載。
注:原來的判斷條件寫if ! findmnt $dir > /dev/null; then
,findmnt $dir > /dev/null
會回傳一個空字串,用新的寫法較合理
修改權限
一個使用場景是把Linux端的檔案備份到Windows share上。使用rsync
或cp
把檔案複製到Windows share上之後,嘗試登入Windows share查看,會發現只有掛載的用戶有權寫入及刪除。如果希望所有人都能對檔案進行修改,則需修改檔案的權限:
sudo chmod -R 777 /mnt/<your_target_dir>/
Troubleshooting
Unable to apply new capability set
如果在使用mount
指令時碰到如下錯誤:
Unable to apply new capability set.
參考docker&&samba|“Unable to apply new capability set”问题,在docker run
後面加上:
--privileged=true
給予container最高權限,即可解決。
bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount
如果在使用mount
指令時碰到如下錯誤:
mount: /mnt/<your_target_dir>: bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount.<type> helper program.
表示缺少掛載CIFS必要的套件。使用如下指令安裝:
sudo apt update -y
sudo apt install cifs-utils -y
Couldn’t chdir to /mnt/<your_target_dir>: No such file or directory
如果在使用mount
指令時碰到如下錯誤:
Couldn't chdir to /mnt/<your_target_dir>: No such file or directory
表示掛載的目標目錄不存在。在使用mount
指令之前,需要先手動創建掛載的目標目錄:
mkdir /mnt/<your_taget_dir>
Device or resource busy
如果在複製掛載目錄下的檔案或git push
時出現Device or resource busy
錯誤,可以嘗試重新掛載。筆者在重新掛載時出現了以下錯誤:
mount error(95): Operation not supported
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)
經過查找發現是掛載時使用的SMB協議版本太低,重新改用較高的SMB版本掛載就解決了。