[#377] Add check of Source IP #377
3 changed files with 36 additions and 11 deletions
|
@ -415,6 +415,7 @@ func determineProperties(r *http.Request, decoder XMLDecoder, resolver BucketRes
|
||||||
res := map[string]string{
|
res := map[string]string{
|
||||||
s3.PropertyKeyOwner: owner,
|
s3.PropertyKeyOwner: owner,
|
||||||
common.PropertyKeyFrostFSIDGroupID: chain.FormCondSliceContainsValue(groups),
|
common.PropertyKeyFrostFSIDGroupID: chain.FormCondSliceContainsValue(groups),
|
||||||
|
common.PropertyKeyFrostFSSourceIP: GetReqInfo(r.Context()).RemoteHost,
|
||||||
}
|
}
|
||||||
queries := GetReqInfo(r.Context()).URL.Query()
|
queries := GetReqInfo(r.Context()).URL.Query()
|
||||||
|
|
||||||
|
|
|
@ -62,10 +62,11 @@ func (c *centerMock) Authenticate(*http.Request) (*middleware.Box, error) {
|
||||||
type middlewareSettingsMock struct {
|
type middlewareSettingsMock struct {
|
||||||
denyByDefault bool
|
denyByDefault bool
|
||||||
aclEnabled bool
|
aclEnabled bool
|
||||||
|
sourceIPHeader string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *middlewareSettingsMock) SourceIPHeader() string {
|
func (r *middlewareSettingsMock) SourceIPHeader() string {
|
||||||
return ""
|
return r.sourceIPHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *middlewareSettingsMock) NamespaceHeader() string {
|
func (r *middlewareSettingsMock) NamespaceHeader() string {
|
||||||
|
|
|
@ -254,7 +254,7 @@ func TestDefaultBehaviorPolicyChecker(t *testing.T) {
|
||||||
|
|
||||||
// check we cannot access if rules not found when settings is enabled
|
// check we cannot access if rules not found when settings is enabled
|
||||||
chiRouter.middlewareSettings.denyByDefault = true
|
chiRouter.middlewareSettings.denyByDefault = true
|
||||||
createBucketErr(chiRouter, ns, bktName, apiErrors.ErrAccessDenied)
|
createBucketErr(chiRouter, ns, bktName, nil, apiErrors.ErrAccessDenied)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaultPolicyCheckerWithUserTags(t *testing.T) {
|
func TestDefaultPolicyCheckerWithUserTags(t *testing.T) {
|
||||||
|
@ -265,7 +265,7 @@ func TestDefaultPolicyCheckerWithUserTags(t *testing.T) {
|
||||||
allowOperations(router, ns, []string{"s3:CreateBucket"}, engineiam.Conditions{
|
allowOperations(router, ns, []string{"s3:CreateBucket"}, engineiam.Conditions{
|
||||||
engineiam.CondStringEquals: engineiam.Condition{fmt.Sprintf(common.PropertyKeyFormatFrostFSIDUserClaim, "tag-test"): []string{"test"}},
|
engineiam.CondStringEquals: engineiam.Condition{fmt.Sprintf(common.PropertyKeyFormatFrostFSIDUserClaim, "tag-test"): []string{"test"}},
|
||||||
})
|
})
|
||||||
createBucketErr(router, ns, bktName, apiErrors.ErrAccessDenied)
|
createBucketErr(router, ns, bktName, nil, apiErrors.ErrAccessDenied)
|
||||||
|
|
||||||
tags := make(map[string]string)
|
tags := make(map[string]string)
|
||||||
tags["tag-test"] = "test"
|
tags["tag-test"] = "test"
|
||||||
|
@ -291,7 +291,7 @@ func TestACLAPE(t *testing.T) {
|
||||||
putObjectErr(router, ns, bktNameNew, objName, nil, apiErrors.ErrAccessDenied)
|
putObjectErr(router, ns, bktNameNew, objName, nil, apiErrors.ErrAccessDenied)
|
||||||
|
|
||||||
// Deny because of deny by default
|
// Deny because of deny by default
|
||||||
createBucketErr(router, ns, bktName, apiErrors.ErrAccessDenied)
|
createBucketErr(router, ns, bktName, nil, apiErrors.ErrAccessDenied)
|
||||||
listBucketsErr(router, ns, apiErrors.ErrAccessDenied)
|
listBucketsErr(router, ns, apiErrors.ErrAccessDenied)
|
||||||
|
|
||||||
// Allow operations and check
|
// Allow operations and check
|
||||||
|
@ -322,7 +322,7 @@ func TestACLAPE(t *testing.T) {
|
||||||
|
|
||||||
// Deny operations and check
|
// Deny operations and check
|
||||||
denyOperations(router, ns, []string{"s3:CreateBucket", "s3:ListAllMyBuckets"}, nil)
|
denyOperations(router, ns, []string{"s3:CreateBucket", "s3:ListAllMyBuckets"}, nil)
|
||||||
createBucketErr(router, ns, bktName, apiErrors.ErrAccessDenied)
|
createBucketErr(router, ns, bktName, nil, apiErrors.ErrAccessDenied)
|
||||||
listBucketsErr(router, ns, apiErrors.ErrAccessDenied)
|
listBucketsErr(router, ns, apiErrors.ErrAccessDenied)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -617,6 +617,25 @@ func TestAccessBoxAttributesCheck(t *testing.T) {
|
||||||
listObjectsV1(router, ns, bktName, "", "", "")
|
listObjectsV1(router, ns, bktName, "", "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSourceIPCheck(t *testing.T) {
|
||||||
|
router := prepareRouter(t)
|
||||||
|
|
||||||
|
ns, bktName, hdr := "", "bucket", "Source-Ip"
|
||||||
|
router.middlewareSettings.denyByDefault = true
|
||||||
|
|
||||||
|
// Add policy and check
|
||||||
|
allowOperations(router, ns, []string{"s3:CreateBucket"}, engineiam.Conditions{
|
||||||
|
engineiam.CondIPAddress: engineiam.Condition{"aws:SourceIp": []string{"192.0.2.0/24"}},
|
||||||
|
})
|
||||||
|
|
||||||
|
router.middlewareSettings.sourceIPHeader = hdr
|
||||||
|
header := map[string][]string{hdr: {"192.0.3.0"}}
|
||||||
|
createBucketErr(router, ns, bktName, header, apiErrors.ErrAccessDenied)
|
||||||
|
|
||||||
|
router.middlewareSettings.sourceIPHeader = ""
|
||||||
|
createBucket(router, ns, bktName)
|
||||||
|
}
|
||||||
|
|
||||||
func allowOperations(router *routerMock, ns string, operations []string, conditions engineiam.Conditions) {
|
func allowOperations(router *routerMock, ns string, operations []string, conditions engineiam.Conditions) {
|
||||||
addPolicy(router, ns, "allow", engineiam.AllowEffect, operations, conditions)
|
addPolicy(router, ns, "allow", engineiam.AllowEffect, operations, conditions)
|
||||||
}
|
}
|
||||||
|
@ -661,19 +680,23 @@ func createSpecificBucket(router *routerMock, bktName string, old bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createBucket(router *routerMock, namespace, bktName string) {
|
func createBucket(router *routerMock, namespace, bktName string) {
|
||||||
w := createBucketBase(router, namespace, bktName)
|
w := createBucketBase(router, namespace, bktName, nil)
|
||||||
resp := readResponse(router.t, w)
|
resp := readResponse(router.t, w)
|
||||||
require.Equal(router.t, s3middleware.CreateBucketOperation, resp.Method)
|
require.Equal(router.t, s3middleware.CreateBucketOperation, resp.Method)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createBucketErr(router *routerMock, namespace, bktName string, errCode apiErrors.ErrorCode) {
|
func createBucketErr(router *routerMock, namespace, bktName string, header http.Header, errCode apiErrors.ErrorCode) {
|
||||||
w := createBucketBase(router, namespace, bktName)
|
w := createBucketBase(router, namespace, bktName, header)
|
||||||
assertAPIError(router.t, w, errCode)
|
assertAPIError(router.t, w, errCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createBucketBase(router *routerMock, namespace, bktName string) *httptest.ResponseRecorder {
|
func createBucketBase(router *routerMock, namespace, bktName string, header http.Header) *httptest.ResponseRecorder {
|
||||||
w, r := httptest.NewRecorder(), httptest.NewRequest(http.MethodPut, "/"+bktName, nil)
|
w, r := httptest.NewRecorder(), httptest.NewRequest(http.MethodPut, "/"+bktName, nil)
|
||||||
r.Header.Set(FrostfsNamespaceHeader, namespace)
|
r.Header.Set(FrostfsNamespaceHeader, namespace)
|
||||||
|
for key := range header {
|
||||||
|
r.Header.Set(key, header.Get(key))
|
||||||
|
}
|
||||||
|
|
||||||
router.ServeHTTP(w, r)
|
router.ServeHTTP(w, r)
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue