通過 Amazon EFS 對 NFS 文件系統權限進行細粒度控制

傳統的NFS服務是企業應用裏非常常見的網絡存儲服務。用戶在搭建NFS服務時,需要對權限進行相應的設置,以防止未授權的客戶端非法訪問遠程文件存儲。NFS的權限管理主要依賴Linux文件系統的文件權限管理機制,並通過 /etc/exports 進行文件系統共享的參數設置,如授權客戶端的網段,是否只讀等。如果需要更進一步的認證機制,需要部署Kerberos,相應的配置也並不輕鬆。

當我們將現有的NFS服務遷移上雲,或是需要在雲的環境下面構建NFS服務時,同樣也要考慮到權限的控制。 AWS上提供了Amazon Elastic File System (EFS),是託管的NFS服務。用戶可以基於EFS快速的部署一個超過PB級別的NFS文件系統。用戶不需要管理文件系統的底層存儲機制,只要往EFS寫入文件或刪除文件,EFS即可自動進行擴展和收縮。同時這些數據也是跨多個可用區來進行保護,相當於實現了同城災備的保護級別。

在權限控制這塊,EFS在NFS文件權限控制的基礎上,結合AWS雲上已有的安全認證機制,如安全組(Security Group),身份與訪問管理服務(IAM)和EFS獨特的接入點(Access Point)機制,簡化了權限控制的配置工作,同時可以更爲細粒度的進行管理和審計。

1. 通過安全組進行客戶端訪問控制

安全組可以理解爲是AWS VPC中掛載到虛擬網卡上的防火牆,通過設定規則可以指定入站和出站的白名單。在之前的博客中,我們演示瞭如何通過嚮導快速部署一個EFS文件系統,其中掛載目標和EC2實例均使用的是VPC的默認安全組,因此二者之前的所有網絡流量都是放通的。接下來我們可以創建自定義的安全組來做更爲精細的權限控制。

如下圖所示:
在這裏插入圖片描述

我們可以爲掛載目標和EC2實例各創建一個安全組(分別命名爲efsmountpoint和nfsclient,如果EC2實例已有安全組則可利用現有安全組)。EC2實例的安全組可按照業務需求開通相應的入站端口即可,出站默認是所有流量放通。掛載目標的安全組入站規則設置爲放通NFS端口2049,來源可以設置爲EC2實例的安全組id(即nfsclient),這樣即可以通過安全組限制只有指定的EC2實例能夠掛載文件系統。

如下是控制檯上關於掛載目標安全組的設置截圖:
在這裏插入圖片描述

注意到每個掛載目標最多可以同時設置5個安全組。

2. 通過IAM對NFS客戶端進行授權

安全組可以對訪問文件系統的EC2實例進行訪問控制,如果需要進一步控制訪問權限,如讀寫權限,能否以Root用戶訪問等,則可以結合IAM服務來進行更細粒度的控制。

通過AWS Identity and Access Management (IAM) 可以安全地管理對 AWS 服務和資源的訪問。可以使用 IAM 創建和管理 AWS 用戶和組,並使用各種權限來允許或拒絕他們對 AWS 資源的訪問。同時,EFS的文件系統也提供了文件系統策略,可以設置針對文件系統的相應權限。

在這裏插入圖片描述

2.1 爲文件系統設置只讀策略

EFS文件系統創建出來後,默認的文件系統策略是全放通,即任何NFS客戶端均可以對其完全訪問。用戶可以通過設置文件系統策略,來進一步對文件系統權限進行控制。這些權限包括:

elasticfilesystem:ClientMount : 允許客戶端以只讀方式掛載文件系統
elasticfilesystem:ClientWrite : 允許客戶端對文件系統進行寫入
elasticfilesystem:ClientRootAccess : 允許客戶端以Root用戶進行訪問
比如我們希望文件系統給予所有用戶只讀權限,則可以配置如下的文件系統策略:

{
    "Version": "2012-10-17",
    "Id": "efs-policy-wizard-f37947df-cdbb-40c9-8fe2-fb38bedd362e",
    "Statement": [
        {
            "Sid": "efs-statement-204c3f1d-6499-4a4f-9fa5-86592173888e",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "elasticfilesystem:ClientMount",
            "Resource": "arn:aws-cn:elasticfilesystem:cn-northwest-1:402202783068:file-system/fs-57789eb2"
        }
    ]
}

接下來我們可以掛載這個文件系統進行讀寫測試:

$ sudo mount -t efs fs-57789eb2 /mnt/efs
$ touch /mnt/efs/test
touch: cannot touch '/mnt/efs/test': Read-only file system

可以看到客戶端掛載後就是一個只讀的文件系統,無法進行修改,也無法以Root用戶訪問。這是一個典型的基於資源(Resource-based)的IAM策略,通過進一步修改這個IAM策略(即指定Principal)我們還可以爲某個特定的用戶設置允許或拒絕相應的權限。

注意到NFS客戶端發起EFS文件系統掛載命令時,這個操作會被CloudTrail服務所記錄下來,EventName爲“NewClientConnection”,從CloudTrail詳細日誌的 “userIdentity”和”serviceEventDetail”中我們可以看到詳細的IAM權限檢查結果

{
    "eventVersion": "1.05",
    "userIdentity": {
        "type": "AWSAccount",
        "principalId": "",
        "accountId": "ANONYMOUS_PRINCIPAL"
        
...中間省略...

    "serviceEventDetails": {
        "permissions": {
            "ClientRootAccess": false,
            "ClientMount": true,
            "ClientWrite": false
        },
        "sourceIpAddress": "172.31.44.108"
    }
}

從這個記錄可以看到,這個掛載操作是匿名用戶發起,EFS根據文件系統權限,給予NFS客戶端只讀的權限。

2.2 爲EC2實例授予讀寫權限

如果我們希望某個EC2實例做爲管理節點,具有文件系統的讀寫權限,那應該如何配置呢?其中一種可行的方式是創建一個IAM角色(本示例中該角色命爲FSWrite),併爲這個角色配置具有文件系統寫權限的策略,通過將這個IAM角色附加給管理節點的EC2實例,從而使該實例上運行的程序具有對文件系統的寫操作權限,如下是相應的策略的示例:

{
    "Version": "2012-10-17",
    "Id": "efsid",
    "Statement": [
        {
            "Sid": "efssid",
            "Effect": "Allow",
            "Action": [
                "elasticfilesystem:ClientWrite",
                "elasticfilesystem:ClientRootAccess"
            ],
            "Resource": "arn:aws-cn:elasticfilesystem:cn-northwest-1:402202783068:file-system/fs-57789eb2"
        }
    ]
}

在這個管理節點的EC2上面進行掛載時,如果直接使用mount命令並用默認參數進行掛載的話,並不會去使用EC2所附加的角色權限,因此需要使用如下命令及參數進行掛載:

$ sudo mount -t efs fs-57789eb2:/ -o tls,iam /mnt/efs

其中:

tls: NFS客戶端與EFS之間的通信需要使用TLS1.2進行加密,
iam: 使用mount程序所運行環境的IAM權限,這個例子中使用的是附加到EC2的角色。使用iam選項時需要同時啓用tls選項
檢查CloudTrail中的日誌,可以看到IAM權限檢查的結果:

{
    "eventVersion": "1.05",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "AROAV3JJHNVOITSOOW6BF:i-04e69fb201d65ce6e",
        "arn": "arn:aws-cn:sts::402202783068:assumed-role/FSWrite/i-04e69fb201d65ce6e",

...中間省略...

    "serviceEventDetails": {
        "permissions": {
            "ClientRootAccess": true,
            "ClientMount": true,
            "ClientWrite": true
        },
        "sourceIpAddress": "172.31.44.108"
    }
}

從這個記錄可以看到,這個掛載操作使用了FSWrite這個角色,EFS根據角色權限,給予NFS客戶端寫入的權限和Root訪問的權限。

3 通過接入點(Access Points)設置用戶訪問權限

接下來我們再看一下,如何進一步對NFS客戶端進行權限的控制,包括限制操作系統用戶身份和限制可訪問的文件系統路徑等。這裏會使用到EFS的接入點(Access Points)設置。

接着上面的例子,假設我們希望這個管理節點的EC2實例,在寫入EFS文件系統時,強制使用操作系統用戶id爲1003, 用戶組id也爲1003, 同時限制這個用戶只能往 /data 目錄下面進行數據寫入。那我們可以配置如下的接入點:
在這裏插入圖片描述

在這個接入點配置裏,我們設置了:

POSIX用戶: 這裏我們可以設置通過該接入點訪問時,強制使用的操作系統用戶ID/組ID。本示例中我們使用了用戶ID和組ID均爲1003,以便與現有操作系統用戶區分。
目錄:這裏我們可以設置通過接入點訪問時做爲根目錄的路徑,如果該目錄不存在,則在第一次通過接入點訪問時EFS會自動創建。如果不指定則默認使用文件系統根目錄。本示例中我們指定了/data做爲根目錄
擁有者用戶與權限:這裏我們可以設置根目錄擁有者的用戶ID和組ID,同時我們也可以指定這個根目錄的權限。本示例我們指定擁有者用戶ID和組ID均爲1003,權限是755
接着我們需要修改管理員所使用的IAM角色(即FSWrite)的策略,限制其只能通過該接入點訪問時才賦予寫權限:

{
    "Version": "2012-10-17",
    "Id": "efsid",
    "Statement": [
        {
            "Sid": "efssid",
            "Effect": "Allow",
            "Action": [
                "elasticfilesystem:ClientWrite",
                "elasticfilesystem:ClientRootAccess"
            ],
            "Resource": "arn:aws-cn:elasticfilesystem:cn-northwest-1:402202783068:file-system/fs-57789eb2",
            "Condition": {
                "StringEquals": {
                    "elasticfilesystem:AccessPointArn": "arn:aws-cn:elasticfilesystem:cn-northwest-1:402202783068:access-point/fsap-068adf52269d7df77"
                }
            }
        }
    ]
}

可以看到這個策略修改的地方是最後的”Condition”段,增加了指定接入點ARN爲fsap-068adf52269d7df77 。

接下來我們在管理節點的EC2實例(附加了FSWrite角色)上,通過這個接入點進行掛載,掛載時需要使用 -o tls,iam,accesspoint 參數指定接入點,啓用TLS和IAM權限認證:

$ sudo mount -t efs fs-57789eb2:/ -o tls,iam,accesspoint=fsap-068adf52269d7df77 /mnt/efs

接入我們進行寫入測試:

$ touch /mnt/efs/test1
$ ls -l /mnt/efs/test1
-rw-rw-r-- 1 1003 1003 0 Feb  7 13:25 /mnt/efs/test1
$ id
uid=1000(ec2-user) gid=1000(ec2-user) groups=1000(ec2-user),4(adm),10(wheel),190(systemd-journal)

可以看到我們獲得了寫入權限,同時寫入的文件所有者用戶ID和組ID均爲接入點所指定的1003,而不是當前命令行的用戶id 1000
注意到我們角色的策略裏雖然賦予了Rootaccess的權限,但此時即使客戶端使用root用戶發起請求,EFS還是會以接入點的用戶id爲準:

$ sudo touch /mnt/efs/test2
$ ls -l /mnt/efs/test2
-rw-rw-r-- 1 1003 1003 0 Feb  7 14:47 /mnt/efs/test2

接下來我們檢查接入點是否指定了/data做爲根目錄。我們重新掛載文件系統,這次掛載不使用任何接入點:

$ sudo umount /mnt/efs
$ sudo mount -t efs fs-57789eb2:/ /mnt/efs

檢查相關的目錄和文件:

$ ls -l /mnt/efs/data
total 8
-rw-rw-r-- 1 1003 1003 0 Feb  7 13:25 test1
-rw-rw-r-- 1 1003 1003 0 Feb  7 14:47 test2

可以看到/data目錄被自動創建出來,剛纔通過接入點掛載後創建的文件test1和test2也在其中。

接下來我們檢查,如果不通過這個接入點,我們是否還可以通過IAM角色FSWrite獲取寫入權限:

$ sudo umount /mnt/efs
$ sudo mount -t efs fs-57789eb2:/ -o tls,iam /mnt/efs
$ touch /mnt/efs/test2
touch: cannot touch '/mnt/efs/test2': Read-only file system

可以看到不通過這個接入點訪問時,這個角色(FSWrite)也就沒有對文件系統的寫入權限。
上述示例可以看到,通過將IAM策略與接入點進行結合,我們可以更細粒度的進行NFS客戶端的權限設置,以便滿足日常管理維護的安全需求。

小結

通過上面的演示,我們可以看到,EFS在NFS文件權限控制的基礎上,結合安全組(Security Group),身份與訪問管理服務(IAM)和EFS獨特的接入點(Access Point)機制,簡化權限控制的配置工作,並進行細粒度的權限管理和審計。

參考資料
EFS IAM策略配置: https://docs.aws.amazon.com/efs/latest/ug/iam-access-control-nfs-efs.html
EFS 安全組配置: https://docs.aws.amazon.com/efs/latest/ug/network-access.html
EFS 接入點配置: https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html
CloudTrail 對 EFS 訪問日誌記錄: https://docs.aws.amazon.com/efs/latest/ug/logging-using-cloudtrail.html

本篇作者

林俊
AWS解決方案架構師,主要負責企業客戶的解決方案諮詢與架構設計優化,同時致力於AWS雲存儲及IoT類服務的應用和推廣。

原文鏈接:https://aws.amazon.com/cn/blogs/china/fine-grained-control-of-nfs-file-system-permissions-with-amazon-efs/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章