Linux

維護 setgid 位(在 bower 安裝或 gulp 建構之後)

  • May 14, 2014

我們在遇到以下情況時執行 Web 伺服器:

  1. www-data 使用者執行 Web 伺服器,並且必須對文件具有讀寫訪問權限
  2. 部署使用者部署所有程式碼
  3. bob 和 alice 使用者可以通過 ssh 登錄並在本地更改配置

所有使用者都必須對 /var/www/mysite 具有讀寫訪問權限。我們目前通過擁有 /var/www/site 到 www-data 的組來實現這一點。然後我們在組上設置 write + setgid 位,以確保所有子目錄都具有相同的權限。

現在,這一切都執行良好了一段時間,但我們在以下場景中遇到了問題:

  1. 我們使用 bower 來安裝帶有bower install. 第一次執行的使用者bower install擁有該public/bower_components目錄並且沒有設置 setgid 位
  2. 我們使用 gulp 來縮小 javascripts from public/scripts/srctopublic/scripts/dist並且第一個執行的使用者gulp build擁有這些文件

在這兩種情況下,afind path/to/dir -type d -exec chmod g+ws {} \;確實可以緩解問題,但是否可以首先解決此問題?我們已經在目錄上設置了 setgid 位/var/www/mysite,那麼為什麼不bower install遵循這個權限集呢?

如果沒有,有沒有更好的方法來解決這個問題?我們曾考慮在部署自動化過程中設置位,但如果使用者忘記了 setgid 位,我們認為自動化部署也可能會卡住。

Posix ACL 是做到這一點的唯一明確優雅的方式,這就是我處理共享讀/寫資源衝突的方式,尤其是在基於 Web 的系統上。這是一個執行範例。

在我的範例中,我有一個名為/var/www/html/share. 此外,我還有使用者alice、、和bob``deploy``bower

首先,我創建了一個名為的組html,然後將使用者添加到該組中。

groupadd html
for i in alice bob deploy bower; do usermod -a -G html $user; done

現在,我已將針對該html組的文件 ACL 添加到該文件夾中。

setfacl -m g:html:rwx /var/www/html/share
setfacl -d -m g:html:rwx /var/www/html/share

第二個命令很重要,它會導致繼承發生。

現在,我們可以測試它的行為。

# for user in alice bob bower deploy; do \
   sudo -u $user touch "/var/www/html/share/file_${user}" \
done

[root@localhost html]# ls -l /var/www/html/share/
total 0
-rw-rw-r--+ 1 alice  alice  0 May 13 23:08 file_alice
-rw-rw-r--+ 1 bob    bob    0 May 13 23:08 file_bob
-rw-rw-r--+ 1 bower  bower  0 May 13 23:08 file_bower
-rw-rw-r--+ 1 deploy deploy 0 May 13 23:08 file_deploy
[root@localhost html]# 

乍一看,文件所有權似乎都很簡單,並且不允許一個使用者與另一個使用者互動。但是,我們可以使用getfacl顯示更多資訊的 ACL 檢查 ACL。

# getfacl file_Al
getfacl: file_Al: No such file or directory
[root@localhost share]# getfacl file_alice 
# file: file_alice
# owner: alice
# group: alice
user::rw-
group::r-x          #effective:r--
group:html:rwx          #effective:rw-
mask::rw-
other::r--

您可以看到該html組可以控制這些文件。

**注意:**標準的 unix GROUP 權限表示針對權限的遮罩。與rw文件一樣,它對 ACL 也有效rw,儘管授予的實際權限是rwx.

讓我們測試其他使用者可以修改/刪除這些文件。

# sudo -u alice /bin/bash
[alice@localhost share]$ pwd
/var/www/html/share
[alice@localhost share]$ echo "hello world" >>file_alice
[alice@localhost share]$ echo "hello world" >>file_bob
[alice@localhost share]$ echo "hello world" >>file_deploy
[alice@localhost share]$ echo "hello world" >>file_bower
[alice@localhost share]$ ll
total 16
-rw-rw-r--+ 1 alice  alice  12 May 13 23:15 file_alice
-rw-rw-r--+ 1 bob    bob    12 May 13 23:15 file_bob
-rw-rw-r--+ 1 bower  bower  12 May 13 23:15 file_bower
-rw-rw-r--+ 1 deploy deploy 12 May 13 23:15 file_deploy
[alice@localhost share]$ rm file_deploy

最後,棘手的一點。當愛麗絲創建目錄時會發生什麼?

[alice@localhost share]$ mkdir dir_alice;
[alice@localhost share]$ ls -l 
total 12
drwxrwxr-x+ 1 alice alice  0 May 13 23:16 dir_alice
-rw-rw-r--+ 1 alice alice 12 May 13 23:15 file_alice
-rw-rw-r--+ 1 bob   bob   12 May 13 23:15 file_bob
-rw-rw-r--+ 1 bower bower 12 May 13 23:15 file_bower
[alice@localhost share]$ getfacl dir_alice
# file: dir_alice
# owner: alice
# group: alice
user::rwx
group::r-x
group:html:rwx
mask::rwx
other::r-x
default:user::rwx
default:group::r-x
default:group:html:rwx
default:mask::rwx
default:other::r-x

因為我們傳遞-dsetfacl它指示新目錄也繼承(並將該繼承應用於進一步的子目錄)。因此,現在作為使用者,deploy我們可以在該新子目錄中添加和編輯現有文件。

[alice@localhost share]$ touch dir_alice/file_indir_alice
[alice@localhost share]$ exit
exit
# sudo -u deploy /bin/bash
[deploy@localhost share]$ cd /var/www/html/share/dir_alice/
[deploy@localhost dir_alice]$ touch file_indir_deploy
[deploy@localhost dir_alice]$ rm file_indir_alice 
[deploy@localhost dir_alice]$ 

引用自:https://serverfault.com/questions/593179