Allow the user that runs the app to be specified via an env var

See gh-16973
This commit is contained in:
Wagner Macedo 2019-05-26 17:06:43 -03:00 committed by Andy Wilkinson
parent ea6d9f3328
commit b57f35893c
7 changed files with 94 additions and 0 deletions

View File

@ -708,6 +708,11 @@ The following environment properties are supported with the default script:
The default depends on the way the jar was built but is usually `auto` (meaning it tries to guess if it is an init script by checking if it is a symlink in a directory called `init.d`).
You can explicitly set it to `service` so that the `stop\|start\|status\|restart` commands work or to `run` if you want to run the script in the foreground.
| `RUN_AS_USER`
| If set, the application will be executed as the informed user.
For security reasons, you should never run an user space application as `root`, therefore it's recommended to set this property.
Defaults to the user who owns the jar file.
| `USE_START_STOP_DAEMON`
| Whether the `start-stop-daemon` command, when it's available, should be used to control the process.
Defaults to `true`.

View File

@ -128,6 +128,26 @@ log_file="$LOG_FOLDER/$LOG_FILENAME"
# shellcheck disable=SC2012
[[ $(id -u) == "0" ]] && run_user=$(ls -ld "$jarfile" | awk '{print $3}')
# Force run as informed user (from environment variable)
if [[ -n "$RUN_AS_USER" ]]; then
# checks performed for all actions except 'status' and 'run'
if ! [[ "$action" =~ ^(status|run)$ ]]; then
# Issue a error if informed user is not valid
id -u "$RUN_AS_USER" || {
echoRed "Cannot run as '$RUN_AS_USER': no such user"
exit 5
}
# Issue a error if we are not root
[[ $(id -u) == 0 ]] || {
echoRed "root required to run as '$RUN_AS_USER'"
exit 6
}
fi
run_user="$RUN_AS_USER"
fi
# Issue a warning if the application will run as root
[[ $(id -u ${run_user}) == "0" ]] && { echoYellow "Application is running as root (UID 0). This is considered insecure."; }

View File

@ -267,6 +267,36 @@ public class SysVinitLaunchScriptIT {
assertThat(output).contains("Log written");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
public void launchWithRunAs(String os, String version) throws Exception {
String output = doTest(os, version, "launch-with-run-as.sh");
assertThat(output).contains("wagner root");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
public void launchWithRunAsInvalidUser(String os, String version) throws Exception {
String output = doTest(os, version, "launch-with-run-as-invalid-user.sh");
assertThat(output).contains("Status: 5");
assertThat(output).has(coloredString(AnsiColor.RED, "Cannot run as 'johndoe': no such user"));
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
public void launchWithRunAsPreferUserInformed(String os, String version) throws Exception {
String output = doTest(os, version, "launch-with-run-as-prefer-user-informed.sh");
assertThat(output).contains("wagner root");
}
@ParameterizedTest(name = "{0} {1}")
@MethodSource("parameters")
public void launchWithRunAsRootRequired(String os, String version) throws Exception {
String output = doTest(os, version, "launch-with-run-as-root-required.sh");
assertThat(output).contains("Status: 6");
assertThat(output).has(coloredString(AnsiColor.RED, "root required to run as 'wagner'"));
}
static List<Object[]> parameters() {
List<Object[]> parameters = new ArrayList<>();
for (File os : new File("src/test/resources/conf").listFiles()) {

View File

@ -0,0 +1,7 @@
source ./test-functions.sh
install_service
echo 'RUN_AS_USER=johndoe' > /test-service/spring-boot-app.conf
start_service
echo "Status: $?"

View File

@ -0,0 +1,13 @@
source ./test-functions.sh
install_service
useradd wagner
echo 'RUN_AS_USER=wagner' > /test-service/spring-boot-app.conf
useradd phil
chown phil /test-service/spring-boot-app.jar
start_service
await_app
ls -la /var/log/spring-boot-app.log

View File

@ -0,0 +1,9 @@
source ./test-functions.sh
install_service
useradd wagner
echo 'RUN_AS_USER=wagner' > /test-service/spring-boot-app.conf
echo "JAVA_HOME='$JAVA_HOME'" >> /test-service/spring-boot-app.conf
su - wagner -c "$(which service) spring-boot-app start"
echo "Status: $?"

View File

@ -0,0 +1,10 @@
source ./test-functions.sh
install_service
useradd wagner
echo 'RUN_AS_USER=wagner' > /test-service/spring-boot-app.conf
start_service
await_app
ls -la /var/log/spring-boot-app.log