This is an automated email from the ASF dual-hosted git repository.
ramackri pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new b4fd13c20 RANGER-5716: Fix swapped client IP and resource in KMS
Ranger audits (#1118)
b4fd13c20 is described below
commit b4fd13c20be154e7fc0b1377f16ea5b5c1327e12
Author: Ramachandran Krishnan <[email protected]>
AuthorDate: Fri Jul 31 07:39:14 2026 +0530
RANGER-5716: Fix swapped client IP and resource in KMS Ranger audits (#1118)
Pass the HTTP client address and key name to the correct assertAccess
overload for invalidate cache and reencrypt operations so Ranger audit
records show the real client IP and key resource instead of swapping them.
Co-authored-by: ramk <[email protected]>
---
.../apache/hadoop/crypto/key/kms/server/KMS.java | 48 ++++++++++++----------
.../hadoop/crypto/key/kms/server/TestKMS.java | 9 +++-
2 files changed, 33 insertions(+), 24 deletions(-)
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMS.java
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMS.java
index 49ff02fcd..424e89aa7 100644
--- a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMS.java
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMS.java
@@ -111,7 +111,7 @@ public Response createKey(Map jsonKey, @Context
HttpServletRequest request) thro
validateKeyName(name);
- assertAccess(Type.CREATE, user, KMSOp.CREATE_KEY, name,
request.getRemoteAddr());
+ assertAccess(Type.CREATE, user, KMSOp.CREATE_KEY, name,
getClientIp(request));
final String cipher = (String)
jsonKey.get(KMSRESTConstants.CIPHER_FIELD);
final String material = (String)
jsonKey.get(KMSRESTConstants.MATERIAL_FIELD);
@@ -123,7 +123,7 @@ public Response createKey(Map jsonKey, @Context
HttpServletRequest request) thro
Map<String, String> attributes = (Map<String, String>)
jsonKey.get(KMSRESTConstants.ATTRIBUTES_FIELD);
if (material != null) {
- assertAccess(Type.SET_KEY_MATERIAL, user, KMSOp.CREATE_KEY,
name, request.getRemoteAddr());
+ assertAccess(Type.SET_KEY_MATERIAL, user, KMSOp.CREATE_KEY,
name, getClientIp(request));
}
final KeyProvider.Options options = new
KeyProvider.Options(KMSWebApp.getConfiguration());
@@ -155,7 +155,7 @@ public Response createKey(Map jsonKey, @Context
HttpServletRequest request) thro
kmsAudit.ok(user, KMSOp.CREATE_KEY, name, "UserProvidedMaterial:"
+ (material != null) + " Description:" + description);
- if (!KMSWebApp.getACLs().hasAccess(Type.GET, user,
request.getRemoteAddr())) {
+ if (!KMSWebApp.getACLs().hasAccess(Type.GET, user,
getClientIp(request))) {
keyVersion = removeKeyMaterial(keyVersion);
}
@@ -199,7 +199,7 @@ public Response deleteKey(@PathParam("name") final String
name, @Context HttpSer
UserGroupInformation user = HttpUserGroupInformation.get();
- assertAccess(Type.DELETE, user, KMSOp.DELETE_KEY, name,
request.getRemoteAddr());
+ assertAccess(Type.DELETE, user, KMSOp.DELETE_KEY, name,
getClientIp(request));
checkNotEmpty(name, "name");
@@ -235,14 +235,14 @@ public Response rolloverKey(@PathParam("name") final
String name, Map jsonMateri
UserGroupInformation user = HttpUserGroupInformation.get();
- assertAccess(Type.ROLLOVER, user, KMSOp.ROLL_NEW_VERSION, name,
request.getRemoteAddr());
+ assertAccess(Type.ROLLOVER, user, KMSOp.ROLL_NEW_VERSION, name,
getClientIp(request));
checkNotEmpty(name, "name");
final String material = (String)
jsonMaterial.get(KMSRESTConstants.MATERIAL_FIELD);
if (material != null) {
- assertAccess(Type.SET_KEY_MATERIAL, user,
KMSOp.ROLL_NEW_VERSION, name, request.getRemoteAddr());
+ assertAccess(Type.SET_KEY_MATERIAL, user,
KMSOp.ROLL_NEW_VERSION, name, getClientIp(request));
}
KeyVersion keyVersion =
user.doAs((PrivilegedExceptionAction<KeyVersion>) () -> {
@@ -261,7 +261,7 @@ public Response rolloverKey(@PathParam("name") final String
name, Map jsonMateri
kmsAudit.ok(user, KMSOp.ROLL_NEW_VERSION, name,
"UserProvidedMaterial:" + (material != null) + " NewVersion:" +
keyVersion.getVersionName());
- if (!KMSWebApp.getACLs().hasAccess(Type.GET, user,
request.getRemoteAddr())) {
+ if (!KMSWebApp.getACLs().hasAccess(Type.GET, user,
getClientIp(request))) {
keyVersion = removeKeyMaterial(keyVersion);
}
@@ -279,7 +279,7 @@ public Response rolloverKey(@PathParam("name") final String
name, Map jsonMateri
@POST
@Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" +
KMSRESTConstants.INVALIDATECACHE_RESOURCE)
- public Response invalidateCache(@PathParam("name") final String name)
throws Exception {
+ public Response invalidateCache(@PathParam("name") final String name,
@Context HttpServletRequest request) throws Exception {
LOG.debug("==> invalidateCache({})", name);
try (APIMetric apiMetric =
kmsMetricsCollector.createAPIMetric(KMSMetrics.KMSMetric.INVALIDATE_CACHE_COUNT,
KMSMetrics.KMSMetric.INVALIDATE_CACHE_ELAPSED_TIME)) {
@@ -289,7 +289,7 @@ public Response invalidateCache(@PathParam("name") final
String name) throws Exc
UserGroupInformation user = HttpUserGroupInformation.get();
- assertAccess(Type.ROLLOVER, user, KMSOp.INVALIDATE_CACHE, name);
+ assertAccess(Type.ROLLOVER, user, KMSOp.INVALIDATE_CACHE, name,
getClientIp(request));
user.doAs((PrivilegedExceptionAction<Void>) () -> {
provider.invalidateCache(name);
@@ -323,7 +323,7 @@ public Response
getKeysMetadata(@QueryParam(KMSRESTConstants.KEY) List<String> k
final UserGroupInformation user =
HttpUserGroupInformation.get();
final String[] keyNames = keyNamesList.toArray(new
String[0]);
- assertAccess(Type.GET_METADATA, user, KMSOp.GET_KEYS_METADATA,
request.getRemoteAddr());
+ assertAccess(Type.GET_METADATA, user, KMSOp.GET_KEYS_METADATA,
getClientIp(request));
KeyProvider.Metadata[] keysMeta =
user.doAs((PrivilegedExceptionAction<KeyProvider.Metadata[]>) () ->
provider.getKeysMetadata(keyNames));
Object json =
KMSServerJSONUtils.toJSON(keyNames, keysMeta);
@@ -353,7 +353,7 @@ public Response getKeyNames(@Context HttpServletRequest
request) throws Exceptio
UserGroupInformation user = HttpUserGroupInformation.get();
- assertAccess(Type.GET_KEYS, user, KMSOp.GET_KEYS,
request.getRemoteAddr());
+ assertAccess(Type.GET_KEYS, user, KMSOp.GET_KEYS,
getClientIp(request));
List<String> json =
user.doAs((PrivilegedExceptionAction<List<String>>) provider::getKeys);
@@ -398,7 +398,7 @@ public Response getMetadata(@PathParam("name") final String
name, @Context HttpS
checkNotEmpty(name, "name");
- assertAccess(Type.GET_METADATA, user, KMSOp.GET_METADATA, name,
request.getRemoteAddr());
+ assertAccess(Type.GET_METADATA, user, KMSOp.GET_METADATA, name,
getClientIp(request));
KeyProvider.Metadata metadata =
user.doAs((PrivilegedExceptionAction<KeyProvider.Metadata>) () ->
provider.getMetadata(name));
Object json = KMSServerJSONUtils.toJSON(name,
metadata);
@@ -428,7 +428,7 @@ public Response getCurrentVersion(@PathParam("name") final
String name, @Context
checkNotEmpty(name, "name");
- assertAccess(Type.GET, user, KMSOp.GET_CURRENT_KEY, name,
request.getRemoteAddr());
+ assertAccess(Type.GET, user, KMSOp.GET_CURRENT_KEY, name,
getClientIp(request));
KeyVersion keyVersion =
user.doAs((PrivilegedExceptionAction<KeyVersion>) () ->
provider.getCurrentKey(name));
Object json = KMSUtil.toJSON(keyVersion);
@@ -458,7 +458,7 @@ public Response getKeyVersion(@PathParam("versionName")
final String versionName
checkNotEmpty(versionName, "versionName");
- assertAccess(Type.GET, user, KMSOp.GET_KEY_VERSION,
request.getRemoteAddr());
+ assertAccess(Type.GET, user, KMSOp.GET_KEY_VERSION,
getClientIp(request));
KeyVersion keyVersion =
user.doAs((PrivilegedExceptionAction<KeyVersion>) () ->
provider.getKeyVersion(versionName));
@@ -491,7 +491,7 @@ public Response generateDataKey(@PathParam("name") final
String name, @Context H
EncryptedKeyVersion encryptedKeyVersion = null;
try (APIMetric apiMetric =
kmsMetricsCollector.createAPIMetric(KMSMetrics.KMSMetric.EEK_GENERATE_COUNT,
KMSMetrics.KMSMetric.EEK_GENERATE_ELAPSED_TIME)) {
- assertAccess(Type.GENERATE_EEK, user, KMSOp.GENERATE_EEK,
name, request.getRemoteAddr());
+ assertAccess(Type.GENERATE_EEK, user, KMSOp.GENERATE_EEK,
name, getClientIp(request));
encryptedKeyVersion =
user.doAs((PrivilegedExceptionAction<EncryptedKeyVersion>) () ->
provider.generateEncryptedKey(name));
kmsAudit.ok(user, KMSOp.GENERATE_EEK, name, "generateDataKey
execution");
@@ -499,7 +499,7 @@ public Response generateDataKey(@PathParam("name") final
String name, @Context H
KeyVersion retKeyVersion = null;
try (APIMetric apiMetric =
kmsMetricsCollector.createAPIMetric(KMSMetrics.KMSMetric.EEK_DECRYPT_COUNT,
KMSMetrics.KMSMetric.EEK_DECRYPT_ELAPSED_TIME)) {
- assertAccess(Type.DECRYPT_EEK, user, KMSOp.DECRYPT_EEK, name,
request.getRemoteAddr());
+ assertAccess(Type.DECRYPT_EEK, user, KMSOp.DECRYPT_EEK, name,
getClientIp(request));
EncryptedKeyVersion finalEncryptedKeyVersion =
encryptedKeyVersion;
retKeyVersion =
user.doAs((PrivilegedExceptionAction<KeyVersion>) () -> {
@@ -547,7 +547,7 @@ public Response generateEncryptedKeys(@PathParam("name")
final String name, @Que
if (edekOp.equals(KMSRESTConstants.EEK_GENERATE)) {
final List<EncryptedKeyVersion> retEdeks = new LinkedList<>();
- assertAccess(Type.GENERATE_EEK, user, KMSOp.GENERATE_EEK,
name, request.getRemoteAddr());
+ assertAccess(Type.GENERATE_EEK, user, KMSOp.GENERATE_EEK,
name, getClientIp(request));
try {
user.doAs((PrivilegedExceptionAction<Void>) () -> {
for (int i = 0; i < numKeys; i++) {
@@ -599,7 +599,7 @@ public Response generateEncryptedKeys(@PathParam("name")
final String name, @Que
@Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" +
KMSRESTConstants.REENCRYPT_BATCH_SUB_RESOURCE)
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
- public Response reencryptEncryptedKeys(@PathParam("name") final String
name, final List<Map> jsonPayload) throws Exception {
+ public Response reencryptEncryptedKeys(@PathParam("name") final String
name, final List<Map> jsonPayload, @Context HttpServletRequest request) throws
Exception {
LOG.debug("==> reencryptEncryptedKeys(name={}, count={})", name,
(jsonPayload != null ? jsonPayload.size() : 0));
final Stopwatch sw = Stopwatch.createStarted();
@@ -616,7 +616,7 @@ public Response reencryptEncryptedKeys(@PathParam("name")
final String name, fin
LOG.warn("Payload size {} too big for reencryptEncryptedKeys
from" + " user {}.", jsonPayload.size(), user);
}
- assertAccess(Type.GENERATE_EEK, user, KMSOp.REENCRYPT_EEK_BATCH,
name);
+ assertAccess(Type.GENERATE_EEK, user, KMSOp.REENCRYPT_EEK_BATCH,
name, getClientIp(request));
final List<EncryptedKeyVersion> ekvs =
KMSUtil.parseJSONEncKeyVersions(name, jsonPayload);
@@ -685,7 +685,7 @@ public Response
handleEncryptedKeyOp(@PathParam("versionName") final String vers
KMSWebApp.getDecryptEEKCallsMeter().mark();
apiMetric.setMetrics(KMSMetrics.KMSMetric.EEK_DECRYPT_COUNT,
KMSMetrics.KMSMetric.EEK_DECRYPT_ELAPSED_TIME);
- assertAccess(Type.DECRYPT_EEK, user, KMSOp.DECRYPT_EEK,
keyName, request.getRemoteAddr());
+ assertAccess(Type.DECRYPT_EEK, user, KMSOp.DECRYPT_EEK,
keyName, getClientIp(request));
KeyVersion retKeyVersion =
user.doAs((PrivilegedExceptionAction<KeyVersion>) () -> {
KMSEncryptedKeyVersion ekv = new
KMSEncryptedKeyVersion(keyName, versionName, iv,
KeyProviderCryptoExtension.EEK, encMaterial);
@@ -700,7 +700,7 @@ public Response
handleEncryptedKeyOp(@PathParam("versionName") final String vers
KMSWebApp.getReencryptEEKCallsMeter().mark();
apiMetric.setMetrics(KMSMetrics.KMSMetric.EEK_REENCRYPT_COUNT,
KMSMetrics.KMSMetric.EEK_REENCRYPT_ELAPSED_TIME);
- assertAccess(Type.GENERATE_EEK, user, KMSOp.REENCRYPT_EEK,
keyName);
+ assertAccess(Type.GENERATE_EEK, user, KMSOp.REENCRYPT_EEK,
keyName, getClientIp(request));
EncryptedKeyVersion retEncryptedKeyVersion =
user.doAs((PrivilegedExceptionAction<EncryptedKeyVersion>) () -> {
KMSEncryptedKeyVersion ekv = new
KMSEncryptedKeyVersion(keyName, versionName, iv,
KeyProviderCryptoExtension.EEK, encMaterial);
@@ -748,7 +748,7 @@ public Response getKeyVersions(@PathParam("name") final
String name, @Context Ht
checkNotEmpty(name, "name");
- assertAccess(Type.GET, user, KMSOp.GET_KEY_VERSIONS, name,
request.getRemoteAddr());
+ assertAccess(Type.GET, user, KMSOp.GET_KEY_VERSIONS, name,
getClientIp(request));
List<KeyVersion> ret =
user.doAs((PrivilegedExceptionAction<List<KeyVersion>>) () ->
provider.getKeyVersions(name));
Object json = KMSServerJSONUtils.toJSON(ret);
@@ -765,6 +765,10 @@ public Response getKeyVersions(@PathParam("name") final
String name, @Context Ht
}
}
+ private static String getClientIp(HttpServletRequest request) {
+ return request != null ? request.getRemoteAddr() : null;
+ }
+
private void assertAccess(Type aclType, UserGroupInformation ugi, KMSOp
operation, String clientIp) throws AccessControlException {
KMSWebApp.getACLs().assertAccess(aclType, ugi, operation, null,
clientIp);
}
diff --git
a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java
b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java
index 65a01e107..ec0cdb804 100644
--- a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java
+++ b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java
@@ -142,10 +142,12 @@ public void testReencryptEncryptedKeys() throws Exception
{
Field meterField = KMSWebApp.class.getDeclaredField("adminCallsMeter");
meterField.setAccessible(true);
meterField.set(null, dummyMeter);
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ lenient().when(request.getRemoteAddr()).thenReturn("127.0.0.1");
KMS kms = new KMS();
try {
- kms.reencryptEncryptedKeys(keyName, jsonPayload);
+ kms.reencryptEncryptedKeys(keyName, jsonPayload, request);
fail("Expected exception due to missing provider/user context");
} catch (Exception e) {
System.out.println("Caught expected exception: " + e.getMessage());
@@ -435,10 +437,13 @@ void testInvalidateCacheWithOnlyInputValues() throws
Exception {
meterField.setAccessible(true);
meterField.set(null, dummyMeter);
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ lenient().when(request.getRemoteAddr()).thenReturn("127.0.0.1");
+
KMS kms = new KMS();
try {
- kms.invalidateCache(keyName);
+ kms.invalidateCache(keyName, request);
fail("Expected exception due to missing dependencies
(provider/user)");
} catch (Exception e) {
System.out.println("Expected exception: " + e.getMessage());