-
Notifications
You must be signed in to change notification settings - Fork 0
/
docker-jumpshell-helper.sh
executable file
·131 lines (123 loc) · 3.82 KB
/
docker-jumpshell-helper.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#! /bin/bash
# USAGE:
# <BASENAME> ls - list containers having a label owner=<USER> with "ID NAME" format
# <BASENAME> exec <ID> - run interactive bash shell inside container <ID>
# <BASENAME> exec <ID> <ARGS> - run ARGS using bash shell inside container <ID>
# <BASENAME> logs <ID> - tail and follow logs of container <ID>
set -e
GROUP_PREFIX='jumpshell-'
LOG='/var/log/jumpshell.log'
function error() {
echo "`date '+%F %T'` ERROR $@" >> $LOG
echo "ERROR: $@" >&2
exit -1
}
function user_in_group() {
groups "$1" | sed -re 's!^.*: !!;s!\s+!\n!g' | grep -q '^'"$2"'$'
}
function docker_ls() {
user="$1"
if ! user_in_group "$user" jumpshell
then
return -1
fi
if user_in_group "$user" jumpshell-all
then
docker ps --format="{{.ID}} {{.Names}}"
return 0
fi
docker ps --format="{{.ID}} {{.Names}}" --filter=label=owner="$user"
for group in `groups "$user" | cut -d ':' -f 2- `
do
if [[ "$group" == ${GROUP_PREFIX}* ]]
then
g=`echo "$group" | sed -re "s#^${GROUP_PREFIX}##;"`
docker ps --format="{{.ID}} {{.Names}}" --filter=label=group="$g"
fi
done
}
function docker_authorize() {
user="$1"
container="$2"
if ! user_in_group "$user" jumpshell
then
return -1
fi
if user_in_group "$user" jumpshell-all
then
return 0
fi
owner=`docker inspect --type=container -f '{{.Config.Labels.owner}}' "$container"`
[ "x$owner" == "x$user" ] && return 0
valid_group=`docker inspect --type=container -f '{{.Config.Labels.group}}' "$container"`
for group in `groups "$user" | cut -d ':' -f 2- `
do
if [[ "$group" == ${GROUP_PREFIX}* ]]
then
g=`echo "$group" | sed -re "s#^${GROUP_PREFIX}##;"`
[ "x$g" == "x${valid_group}" ] && return 0
fi
done
return -1
}
# make sure it's running as root
[ $UID -ne 0 ] && {
# if no root sudo itself
exec sudo -- "$0" "$@"
} || {
user="$SUDO_USER"
# TODO pass SSH_CONNECTION="${SSH_CONNECTION}" to sudo or any way to log it
# echo "got connection ${user} ${LOG_SSH_CONNECTION}" >> $LOG
[ "x$user" == "x" ] && error "can't run without sudo"
# remove command from args
CMD="$1"
shift
if [ "x$CMD" == "xls" ]
then
docker_ls "$user"
elif [ "x$CMD" == "xlogs" ]
then
[ $# -eq 0 ] && error "No container id passed"
# remove container from args
CONTAINER="$1"
shift
if docker_authorize "$user" "$CONTAINER"
then
docker logs -f --tail=20 "$CONTAINER"
else
error "you are not allowed to access this container"
fi
elif [ "x$CMD" == "xexec" ]
then
[ $# -eq 0 ] && error "No container id passed"
# remove container from args
CONTAINER="$1"
shift
if docker_authorize "$user" "$CONTAINER"
then
shell=`docker inspect --type=container -f '{{.Config.Labels.shell}}' "$CONTAINER" | grep '^/' || :`
if [ "x$shell" == "x" ]
then
if docker exec -i "$CONTAINER" /bin/bash -c ":"
then
shell="/bin/bash"
else
shell="/bin/sh"
fi
fi
echo "`date '+%F %T'` INFO user=${user} container=${CONTAINER} shell=${shell} passed=$@" >> $LOG
if [ $# -eq 0 ]
then
exec docker exec -ti "$CONTAINER" "$shell"
else
OPT='-i'
[ -t 0 ] && [ -t 1 ] && OPT="-ti"
exec docker exec "$OPT" "$CONTAINER" "$shell" "$@"
fi
else
error "you are not allowed to access this container"
fi
else
error "unsupported command $@"
fi
}