NIFI-4187 Resolved issue where restart failed due to missing sensitive key file.

Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com>

This closes #2073.
This commit is contained in:
Andy LoPresto 2017-08-10 16:16:29 -07:00 committed by Pierre Villard
parent a6e8f0afe3
commit 760fd75bee
1 changed files with 47 additions and 31 deletions

View File

@ -33,13 +33,13 @@ import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute; import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFilePermission; import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions; import java.nio.file.attribute.PosixFilePermissions;
import java.nio.file.FileAlreadyExistsException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -1032,35 +1032,9 @@ public class RunNiFi {
cmd.add("-Dapp=NiFi"); cmd.add("-Dapp=NiFi");
cmd.add("-Dorg.apache.nifi.bootstrap.config.log.dir=" + nifiLogDir); cmd.add("-Dorg.apache.nifi.bootstrap.config.log.dir=" + nifiLogDir);
cmd.add("org.apache.nifi.NiFi"); cmd.add("org.apache.nifi.NiFi");
if (props.containsKey(NIFI_BOOTSTRAP_SENSITIVE_KEY) && !StringUtils.isBlank(props.get(NIFI_BOOTSTRAP_SENSITIVE_KEY))) { if (isSensitiveKeyPresent(props)) {
Path sensitiveKeyFile = Paths.get(confDir+"/sensitive.key"); Path sensitiveKeyFile = createSensitiveKeyFile(confDir);
writeSensitiveKeyFile(props, sensitiveKeyFile);
try {
// Initially create file with the empty permission set (so nobody can get a file descriptor on it):
Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);
sensitiveKeyFile = Files.createFile(sensitiveKeyFile, attr);
// Then, once created, add owner-only rights:
perms.add(PosixFilePermission.OWNER_WRITE);
perms.add(PosixFilePermission.OWNER_READ);
attr = PosixFilePermissions.asFileAttribute(perms);
Files.setPosixFilePermissions(sensitiveKeyFile, perms);
} catch (final FileAlreadyExistsException faee) {
cmdLogger.error("The sensitive.key file {} already exists. That shouldn't have been. Aborting.", sensitiveKeyFile);
System.exit(1);
} catch (final Exception e) {
cmdLogger.error("Other failure relating to setting permissions on {}. "
+ "(so that only the owner can read it). "
+ "This is fatal to the bootstrap process for security reasons. Exception was: {}", sensitiveKeyFile, e);
System.exit(1);
}
BufferedWriter sensitiveKeyWriter = Files.newBufferedWriter(sensitiveKeyFile, StandardCharsets.UTF_8);
sensitiveKeyWriter.write(props.get(NIFI_BOOTSTRAP_SENSITIVE_KEY));
sensitiveKeyWriter.close();
cmd.add("-K " + sensitiveKeyFile.toFile().getAbsolutePath()); cmd.add("-K " + sensitiveKeyFile.toFile().getAbsolutePath());
} }
@ -1156,6 +1130,11 @@ public class RunNiFi {
setNiFiStarted(false); setNiFiStarted(false);
} }
if (isSensitiveKeyPresent(props)) {
Path sensitiveKeyFile = createSensitiveKeyFile(confDir);
writeSensitiveKeyFile(props, sensitiveKeyFile);
}
defaultLogger.warn("Apache NiFi appears to have died. Restarting..."); defaultLogger.warn("Apache NiFi appears to have died. Restarting...");
process = builder.start(); process = builder.start();
handleLogging(process); handleLogging(process);
@ -1197,6 +1176,43 @@ public class RunNiFi {
} }
} }
private void writeSensitiveKeyFile(Map<String, String> props, Path sensitiveKeyFile) throws IOException {
BufferedWriter sensitiveKeyWriter = Files.newBufferedWriter(sensitiveKeyFile, StandardCharsets.UTF_8);
sensitiveKeyWriter.write(props.get(NIFI_BOOTSTRAP_SENSITIVE_KEY));
sensitiveKeyWriter.close();
}
private Path createSensitiveKeyFile(File confDir) {
Path sensitiveKeyFile = Paths.get(confDir+"/sensitive.key");
try {
// Initially create file with the empty permission set (so nobody can get a file descriptor on it):
Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);
sensitiveKeyFile = Files.createFile(sensitiveKeyFile, attr);
// Then, once created, add owner-only rights:
perms.add(PosixFilePermission.OWNER_WRITE);
perms.add(PosixFilePermission.OWNER_READ);
attr = PosixFilePermissions.asFileAttribute(perms);
Files.setPosixFilePermissions(sensitiveKeyFile, perms);
} catch (final FileAlreadyExistsException faee) {
cmdLogger.error("The sensitive.key file {} already exists. That shouldn't have been. Aborting.", sensitiveKeyFile);
System.exit(1);
} catch (final Exception e) {
cmdLogger.error("Other failure relating to setting permissions on {}. "
+ "(so that only the owner can read it). "
+ "This is fatal to the bootstrap process for security reasons. Exception was: {}", sensitiveKeyFile, e);
System.exit(1);
}
return sensitiveKeyFile;
}
private boolean isSensitiveKeyPresent(Map<String, String> props) {
return props.containsKey(NIFI_BOOTSTRAP_SENSITIVE_KEY) && !StringUtils.isBlank(props.get(NIFI_BOOTSTRAP_SENSITIVE_KEY));
}
private void handleLogging(final Process process) { private void handleLogging(final Process process) {
final Set<Future<?>> existingFutures = loggingFutures; final Set<Future<?>> existingFutures = loggingFutures;
if (existingFutures != null) { if (existingFutures != null) {