diff --git a/Dockerfile b/Dockerfile index 26dd1ea..f6a5111 100644 --- a/Dockerfile +++ b/Dockerfile @@ -191,13 +191,13 @@ RUN true && \ chown -R :iofog-agent /var/run/iofog-agent && \ chown -R :iofog-agent /var/backups/iofog-agent && \ chown -R :iofog-agent /usr/share/iofog-agent && \ - chmod 774 -R /etc/iofog-agent && \ - chmod 774 -R /var/log/iofog-agent && \ - chmod 774 -R /var/lib/iofog-agent && \ - chmod 774 -R /var/run/iofog-agent && \ - chmod 774 -R /var/backups/iofog-agent && \ + chmod 750 -R /etc/iofog-agent && \ + chmod 750 -R /var/log/iofog-agent && \ + chmod 750 -R /var/lib/iofog-agent && \ + chmod 750 -R /var/run/iofog-agent && \ + chmod 750 -R /var/backups/iofog-agent && \ chmod 754 -R /usr/share/iofog-agent && \ - chmod 774 /etc/systemd/system/iofog-agent.service && \ + chmod 750 /etc/systemd/system/iofog-agent.service && \ chmod 754 /usr/bin/iofog-agent && \ chown :iofog-agent /usr/bin/iofog-agent && \ true diff --git a/Dockerfile-old b/Dockerfile-old index 7e2524b..6a6a48b 100644 --- a/Dockerfile-old +++ b/Dockerfile-old @@ -80,13 +80,13 @@ RUN true && \ chown -R :iofog-agent /var/run/iofog-agent && \ chown -R :iofog-agent /var/backups/iofog-agent && \ chown -R :iofog-agent /usr/share/iofog-agent && \ - chmod 774 -R /etc/iofog-agent && \ - chmod 774 -R /var/log/iofog-agent && \ - chmod 774 -R /var/lib/iofog-agent && \ - chmod 774 -R /var/run/iofog-agent && \ - chmod 774 -R /var/backups/iofog-agent && \ + chmod 750 -R /etc/iofog-agent && \ + chmod 750 -R /var/log/iofog-agent && \ + chmod 750 -R /var/lib/iofog-agent && \ + chmod 750 -R /var/run/iofog-agent && \ + chmod 750 -R /var/backups/iofog-agent && \ chmod 754 -R /usr/share/iofog-agent && \ - chmod 774 /etc/init.d/iofog-agent && \ + chmod 750 /etc/init.d/iofog-agent && \ chmod 754 /usr/bin/iofog-agent && \ chown :iofog-agent /usr/bin/iofog-agent && \ true diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/logging/LoggingService.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/logging/LoggingService.java index 51062a2..af30dcf 100755 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/logging/LoggingService.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/utils/logging/LoggingService.java @@ -118,6 +118,15 @@ public static void setupLogger() throws IOException { logDirectory.mkdirs(); + if (SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC) { + try { + Set perms = PosixFilePermissions.fromString("rwxr-x---"); + Files.setPosixFilePermissions(logDirectory.toPath(), perms); + } catch (Exception e) { + // Log directory may have been created by packaging with correct permissions + } + } + final String logFilePattern = logDirectory.getPath() + "/iofog-agent.%g.log"; if (maxFileSize < Constants.MiB) { @@ -210,7 +219,7 @@ public static void setupMicroserviceLogger(String microserviceUuid, long logSize LinkOption.NOFOLLOW_LINKS); fileAttributeView.setGroup(group); - Set perms = PosixFilePermissions.fromString("rwxrwx---"); + Set perms = PosixFilePermissions.fromString("rwxr-x---"); Files.setPosixFilePermissions(logDirectory.toPath(), perms); } else if (SystemUtils.IS_OS_WINDOWS) { diff --git a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/volume_mount/VolumeMountManager.java b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/volume_mount/VolumeMountManager.java index db08923..b5e053e 100644 --- a/iofog-agent-daemon/src/main/java/org/eclipse/iofog/volume_mount/VolumeMountManager.java +++ b/iofog-agent-daemon/src/main/java/org/eclipse/iofog/volume_mount/VolumeMountManager.java @@ -97,7 +97,8 @@ private void init() { LoggingService.logDebug(MODULE_NAME, "Creating volumes directory at: " + baseDirectory); Files.createDirectories(volumesPath); } - + setDirectoryPermissions(volumesPath); + // Load or create index file loadIndex(); // Rebuild type cache after loading index @@ -444,11 +445,13 @@ private void createVolumeMount(JsonObject volumeMount) { String typeDir = getTypeDirectory(type); Path mountPath = Paths.get(baseDirectory, typeDir, name); Files.createDirectories(mountPath); - + setDirectoryPermissions(mountPath); + // Create versioned directory String versionDirName = createVersionedDirectoryName(); Path versionDir = mountPath.resolve(versionDirName); Files.createDirectories(versionDir); + setDirectoryPermissions(versionDir); // Create files in versioned directory JsonObjectBuilder dataBuilder = Json.createObjectBuilder(); @@ -460,6 +463,7 @@ private void createVolumeMount(JsonObject volumeMount) { Path parentDir = filePath.getParent(); if (parentDir != null) { Files.createDirectories(parentDir); + setDirectoryPermissions(parentDir); } Files.write(filePath, decodedContent.getBytes()); // Set file permissions based on type @@ -491,6 +495,7 @@ private void createVolumeMount(JsonObject volumeMount) { Path parentDir = keyLink.getParent(); if (parentDir != null) { Files.createDirectories(parentDir); + setDirectoryPermissions(parentDir); } Files.createSymbolicLink(keyLink, buildRelativeDataTarget(mountPath, keyLink, keyRelativePath)); setSymlinkPermissions(keyLink); @@ -563,12 +568,14 @@ private void updateVolumeMount(JsonObject volumeMount) { String typeDir = getTypeDirectory(type); Path mountPath = Paths.get(baseDirectory, typeDir, name); Files.createDirectories(mountPath); - + setDirectoryPermissions(mountPath); + // Create new versioned directory String versionDirName = createVersionedDirectoryName(); Path versionDir = mountPath.resolve(versionDirName); Files.createDirectories(versionDir); - + setDirectoryPermissions(versionDir); + // Create files in new versioned directory JsonObjectBuilder dataBuilder = Json.createObjectBuilder(); data.forEach((key, value) -> { @@ -579,6 +586,7 @@ private void updateVolumeMount(JsonObject volumeMount) { Path parentDir = filePath.getParent(); if (parentDir != null) { Files.createDirectories(parentDir); + setDirectoryPermissions(parentDir); } Files.write(filePath, decodedContent.getBytes()); // Set file permissions based on type @@ -612,6 +620,7 @@ private void updateVolumeMount(JsonObject volumeMount) { Path parentDir = keyLink.getParent(); if (parentDir != null) { Files.createDirectories(parentDir); + setDirectoryPermissions(parentDir); } Files.createSymbolicLink(keyLink, buildRelativeDataTarget(mountPath, keyLink, keyRelativePath)); setSymlinkPermissions(keyLink); @@ -740,12 +749,13 @@ private void copyVersionedDirRecursively(Path sourceVersionedDir, Path targetVer Files.createDirectories(parentDir); } Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING); - setFilePermissions(targetFile, type); + setFilePermissionsForBindMount(targetFile); } catch (Exception e) { LoggingService.logWarning(MODULE_NAME, "Error copying file: " + sourceFile + " - " + e.getMessage()); } }); + setDirectoryPermissionsForBindMountRecursively(targetVersionedDir); } catch (IOException e) { LoggingService.logWarning(MODULE_NAME, "Error walking source versioned dir: " + e.getMessage()); } @@ -783,6 +793,7 @@ private void createKeySymlinksRecursively(Path mountPath, Path versionedDir) { Path parentDir = keyLink.getParent(); if (parentDir != null) { Files.createDirectories(parentDir); + setDirectoryPermissionsForBindMount(parentDir); } Files.createSymbolicLink(keyLink, buildRelativeDataTarget(mountPath, keyLink, relativePath)); setSymlinkPermissions(keyLink); @@ -884,7 +895,89 @@ private void setSymlinkPermissions(Path symlink) { LoggingService.logWarning(MODULE_NAME, "Error setting symlink permissions: " + e.getMessage()); } } - + + /** + * Sets directory permissions to 750 (rwxr-x---) for security. + * Restricts access to owner and group only, matching Kubernetes kubelet pattern. + * @param path Directory path + */ + private void setDirectoryPermissions(Path path) { + try { + if ((SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC) && Files.exists(path) && Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) { + Set perms = PosixFilePermissions.fromString("rwxr-x---"); + Files.setPosixFilePermissions(path, perms); + } + } catch (Exception e) { + LoggingService.logWarning(MODULE_NAME, "Could not set directory permissions: " + e.getMessage()); + } + } + + /** + * Recursively sets 750 permissions on a directory and all its descendants. + * Used after copyVersionedDirRecursively to secure nested directory structures. + */ + private void setDirectoryPermissionsRecursively(Path dir) { + try { + if (!(SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC) || !Files.exists(dir) || !Files.isDirectory(dir, LinkOption.NOFOLLOW_LINKS)) { + return; + } + Files.walk(dir, Integer.MAX_VALUE) + .filter(p -> Files.isDirectory(p, LinkOption.NOFOLLOW_LINKS)) + .forEach(this::setDirectoryPermissions); + } catch (IOException e) { + LoggingService.logWarning(MODULE_NAME, "Could not set directory permissions recursively: " + e.getMessage()); + } + } + + /** + * Sets directory permissions to 755 (rwxr-xr-x) for bind-mount targets. + * Allows non-root container processes to traverse and read mounted volumes. + * @param path Directory path + */ + private void setDirectoryPermissionsForBindMount(Path path) { + try { + if ((SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC) && Files.exists(path) && Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) { + Set perms = PosixFilePermissions.fromString("rwxr-xr-x"); + Files.setPosixFilePermissions(path, perms); + } + } catch (Exception e) { + LoggingService.logWarning(MODULE_NAME, "Could not set bind-mount directory permissions: " + e.getMessage()); + } + } + + /** + * Recursively sets 755 permissions on a directory and all its descendants. + * Used for per-microservice bind-mount target so non-root containers can access. + */ + private void setDirectoryPermissionsForBindMountRecursively(Path dir) { + try { + if (!(SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC) || !Files.exists(dir) || !Files.isDirectory(dir, LinkOption.NOFOLLOW_LINKS)) { + return; + } + Files.walk(dir, Integer.MAX_VALUE) + .filter(p -> Files.isDirectory(p, LinkOption.NOFOLLOW_LINKS)) + .forEach(this::setDirectoryPermissionsForBindMount); + } catch (IOException e) { + LoggingService.logWarning(MODULE_NAME, "Could not set bind-mount directory permissions recursively: " + e.getMessage()); + } + } + + /** + * Sets file permissions to 644 (rw-r--r--) for bind-mount targets. + * Allows non-root container processes to read both secrets and configmaps. + * @param path File path + */ + private void setFilePermissionsForBindMount(Path path) { + try { + if ((SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC) && Files.exists(path) && Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS)) { + Set perms = PosixFilePermissions.fromString("rw-r--r--"); + Files.setPosixFilePermissions(path, perms); + } + } catch (Exception e) { + LoggingService.logWarning(MODULE_NAME, "Could not set bind-mount file permissions: " + e.getMessage()); + } + } + /** * Deletes a volume mount * @param uuid UUID of the volume mount to delete @@ -959,7 +1052,8 @@ public String prepareMicroserviceVolumeMount(String microserviceUuid, String vol try { // Atomic directory creation (handles race conditions) Files.createDirectories(mountPath); - + setDirectoryPermissionsForBindMount(mountPath); + // Calculate source path String typeDir = getTypeDirectory(type); Path sourcePath = Paths.get(baseDirectory, typeDir, volumeName); @@ -981,6 +1075,7 @@ public String prepareMicroserviceVolumeMount(String microserviceUuid, String vol Path targetVersionedDir = mountPath.resolve(versionedDirName); if (!Files.exists(targetVersionedDir)) { Files.createDirectories(targetVersionedDir); + setDirectoryPermissionsForBindMount(targetVersionedDir); copyVersionedDirRecursively(sourceVersionedDir, targetVersionedDir, type); } @@ -1069,6 +1164,7 @@ private void syncMicroserviceSymlinks(String volumeName, VolumeMountType type) { Path targetVersionedDir = mountPath.resolve(versionedDirName); if (!Files.exists(targetVersionedDir)) { Files.createDirectories(targetVersionedDir); + setDirectoryPermissionsForBindMount(targetVersionedDir); copyVersionedDirRecursively(sourceVersionedDir, targetVersionedDir, type); } diff --git a/packaging/iofog-agent/debian.sh b/packaging/iofog-agent/debian.sh index ebef85f..a32ca6a 100644 --- a/packaging/iofog-agent/debian.sh +++ b/packaging/iofog-agent/debian.sh @@ -52,11 +52,12 @@ chown -R :iofog-agent /var/backups/iofog-agent chown -R :iofog-agent /usr/share/iofog-agent #echo "Changed ownership of directories to iofog-agent group" -chmod 774 -R /etc/iofog-agent -chmod 774 -R /var/log/iofog-agent -chmod 774 -R /var/lib/iofog-agent -chmod 774 -R /var/run/iofog-agent -chmod 774 -R /var/backups/iofog-agent +chmod 750 -R /etc/iofog-agent +chmod 750 -R /var/log/iofog-agent +chmod 750 -R /var/lib/iofog-agent +chmod 750 -R /var/run/iofog-agent +chmod 750 -R /var/backups/iofog-agent +chmod 750 -R /var/log/iofog-microservices chmod 754 -R /usr/share/iofog-agent #echo "Changed permissions of directories" @@ -64,7 +65,7 @@ mv /dev/random /dev/random.real ln -s /dev/urandom /dev/random #echo "Moved dev pipes for netty" -chmod 774 /etc/systemd/system/iofog-agent.service +chmod 750 /etc/systemd/system/iofog-agent.service #echo "Changed permissions on service script" chmod 754 /usr/bin/iofog-agent diff --git a/packaging/iofog-agent/rpm.sh b/packaging/iofog-agent/rpm.sh index 90a8810..e194da0 100644 --- a/packaging/iofog-agent/rpm.sh +++ b/packaging/iofog-agent/rpm.sh @@ -55,11 +55,12 @@ chown -R :iofog-agent /var/backups/iofog-agent chown -R :iofog-agent /usr/share/iofog-agent #echo "Changed ownership of directories to iofog-agent group" -chmod 774 -R /etc/iofog-agent -chmod 774 -R /var/log/iofog-agent -chmod 774 -R /var/lib/iofog-agent -chmod 774 -R /var/run/iofog-agent -chmod 774 -R /var/backups/iofog-agent +chmod 750 -R /etc/iofog-agent +chmod 750 -R /var/log/iofog-agent +chmod 750 -R /var/lib/iofog-agent +chmod 750 -R /var/run/iofog-agent +chmod 750 -R /var/backups/iofog-agent +chmod 750 -R /var/log/iofog-microservices chmod 754 -R /usr/share/iofog-agent #echo "Changed permissions of directories" @@ -67,7 +68,7 @@ mv /dev/random /dev/random.real ln -s /dev/urandom /dev/random #echo "Moved dev pipes for netty" -chmod 774 /etc/systemd/system/iofog-agent.service +chmod 750 /etc/systemd/system/iofog-agent.service #echo "Changed permissions on service script" chmod 754 /usr/bin/iofog-agent