From fc125d41e8a1957d14e49b41cac54316a3232c97 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 8 Nov 2015 15:36:04 -0500 Subject: [PATCH] Add user-auth plugin trigger This plugin trigger should allow users to pair down the available commands for a given user. While this does not affect help output - or any output at all - this is a good first step in allowing administrative access to certain commands while still allowing users to deploy/manage given applications. Note that because of how dokku works, all parsing of commands must be done within the pluginhook, and we cannot give visibility into the actual command or application that will be affected by a given run. --- docs/development/plugin-triggers.md | 41 +++++++++++++++++++++++++++++ dokku | 6 +++++ plugins/common/functions | 9 +++++++ 3 files changed, 56 insertions(+) diff --git a/docs/development/plugin-triggers.md b/docs/development/plugin-triggers.md index 4e9cdf0b6..260b98933 100644 --- a/docs/development/plugin-triggers.md +++ b/docs/development/plugin-triggers.md @@ -719,3 +719,44 @@ APP="$1"; HOSTNAME=$(hostname -s) mail -s "$APP containers on $HOSTNAME failed to retire" ops@example.com ``` + +### `user-auth` + +This is a special plugin trigger that is executed on *every* command run. As dokku sometimes internally invokes the `dokku` command, special care should be taken to properly handle internal command redirects. + +Note that the trigger should exit as follows: + +- `0` to continue running as normal +- `1` to halt execution of the command + +The `SSH_USER` is the original ssh user. If you are running remote commands, this user will typically be `dokku`, and as such should not be trusted when checking permissions. If you are connected via ssh as a different user who then invokes `dokku`, the value of this variable will be that user's name (`root`, `myuser`, etc.). + +The `SSH_NAME` is the `NAME` variable set via the `sshcommand acl-add` command. If you have set a user via the `dokku-installer`, this value will be set to `admin`. For installs via debian package, this value *may* be `default`. For reference, the following command can be run as the root user to specify a specific `NAME` for a given ssh key: + +```shell +sshcommand acl-add dokku NAME < $PATH_TO_SSH_KEY +``` + +Note that the `NAME` value is set at the first ssh key match. If an ssh key is set in the `/home/dokku/.ssh/authorized_keys` multiple times, the first match will decide the value. + +- Description: Allows you to deny access to a dokku command by either ssh user or associated ssh-command NAME user. +- Invoked by `dokku` +- Arguments: `$SSH_USER $SSH_NAME $DOKKU_COMMAND` +- Example: + +```shell +#!/usr/bin/env bash +# Allow root/admin users to do everything +# Deny plugin access to default users +# Allow access to all other commands + +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x + +SSH_USER=$1 +SSH_NAME=$2 +shift 2 +[[ "$SSH_USER" == "root" ]] && exit 0 +[[ "$SSH_NAME" == "admin" ]] && exit 0 +[[ "$SSH_NAME" == "default" && $1 == plugin:* ]] && exit 1 +exit 0 +``` diff --git a/dokku b/dokku index a2452e38f..b5962e283 100755 --- a/dokku +++ b/dokku @@ -50,6 +50,7 @@ fi ! has_tty && DOKKU_QUIET_OUTPUT=1 if [[ $(id -un) != "dokku" && $1 != plugin:*install* && $1 != "plugin:update" ]]; then + export SSH_USER=$(id -un) sudo -u dokku -E -H $0 "$@" exit $? fi @@ -65,6 +66,11 @@ if [[ -n "$SSH_ORIGINAL_COMMAND" ]]; then fi fi +if ! dokku_auth "$@" ; then + dokku_log_fail "Access denied" + exit 1 +fi + case "$1" in receive) APP="$2"; IMAGE=$(get_app_image_name $APP); IMAGE_SOURCE_TYPE="$3"; TMP_WORK_DIR="$4" diff --git a/plugins/common/functions b/plugins/common/functions index f3930baac..9cadbebe3 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -346,3 +346,12 @@ get_available_port() { fi done } + +dokku_auth() { + export SSH_USER=${SSH_USER:=$USER} + export SSH_NAME=${NAME:="default"} + if ! plugn trigger user-auth $SSH_USER $SSH_NAME "$@" ; then + return 1 + fi + return 0 +}