Skip to content

Commit 8839e65

Browse files
authored
Re-work drop root privileges (#378)
* Revert "Drop Privileges by Default / Specify User or Group ID" This reverts commit 9dd6578. * rework drop privileges
1 parent 04357d1 commit 8839e65

File tree

5 files changed

+32
-111
lines changed

5 files changed

+32
-111
lines changed

.github/workflows/opencanary_tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ jobs:
4747
- name: Copy config file
4848
run: cp opencanary/test/opencanary.conf .
4949
- name: Start OpenCanary
50-
run: opencanaryd --start --allow-run-as-root
50+
run: opencanaryd --start
5151
- name: Run Pytest
5252
run: pytest -s

Dockerfile.latest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ COPY opencanary ./opencanary
2626
ENTRYPOINT [ "opencanaryd" ]
2727

2828
# Set the default arguments to be used for the entrypoint
29-
CMD [ "--dev" ]
29+
CMD [ "--dev", "--uid=nobody", "--gid=nogroup" ]

Dockerfile.stable

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ RUN pip install scapy pcapy-ng
1515
ENTRYPOINT [ "opencanaryd" ]
1616

1717
# Set the default arguments to be used for the entrypoint
18-
CMD [ "--dev" ]
18+
CMD [ "--dev", "--uid=nobody", "--gid=nogroup" ]

README.md

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -152,48 +152,11 @@ To create an initial configuration, run as `root` (you may be prompted for a `su
152152
$ opencanaryd --copyconfig
153153
[*] A sample config file is ready /etc/opencanaryd/opencanary.conf
154154
155-
[*] Edit your configuration, then launch with "opencanaryd --start"
155+
[*] Edit your configuration, then launch with "opencanaryd --start --uid=nobody --gid=nogroup"
156156
```
157157

158158
This creates the path and file `/etc/opencanaryd/opencanary.conf`. You must now edit the config file to determine which services and logging options you want to enable.
159159

160-
### Setting privileges
161-
162-
OpenCanary requires root to bind to privileged ports, after which it attempts to drop to a less privileged
163-
user and group ID (default is `opencanary/nogroup`).
164-
165-
If this behaviour is not desired, one can use the `--allow-run-as-root` flag, e.g.,
166-
167-
```
168-
$ opencanaryd --start --allow-run-as-root
169-
```
170-
171-
Creating the `opencanary` user and giving necessary privileges, run `./bin/opencanaryd --createuser`. To drop to a
172-
custom user or group, simply use the `--uid` and `--gid` options respectively:
173-
174-
```
175-
$ opencanaryd --start --uid username --gid groupname
176-
```
177-
178-
By default, the `uid:gid` is `opencanary:nogroup`.
179-
180-
#### Installing and running OpenCanary on an isolated `opencanary` user
181-
182-
The recommended installation process would be as follows:
183-
184-
1. Obtain an installation candidate `opencanary-<version>.tar.gz` e.g., via [Installation via Git](#installation-via-git)
185-
2. Make sure all users can read this file, e.g, `sudo chmod 744 /path/to/opencanary-<version>.tar.gz`.
186-
3. Run the following commands as `opencanary`, i.e., `sudo su - opencanary`:
187-
1. Create virtual environment `pip3 install virtualenv && python3 -m virtualenv .venv`.
188-
2. Install Opencanary distribution `pip3 install /path/to/opencanary-<version>.tar.gz`.
189-
4. Activate the `opencanary` virtual environment from a user that is able to use `sudo`
190-
(necessary to bind to privileged ports), e.g., `source /home/opencanary/.venv/bin/activate`
191-
5. Navigate back to `opencanary`'s home, e.g., `cd /home/opencanary` or `cd /Users/opencanary`. If this step is not done,
192-
there may be issues when the `opencanary` user tries to navigate from this (possibly more privileged) directory.
193-
6. Run the `opencanaryd` binary as usual , e.g., `opencanaryd --start`.
194-
195-
This should drop to the `opencanary` user once bound to privileged ports, and safely operate in an isolated environment.
196-
197160
### Enabling protocol modules and alerting
198161

199162
Configuration is performed via the JSON config file. Edit the file, and when happy save and exit.
@@ -224,17 +187,22 @@ Start OpenCanary by running:
224187

225188
```
226189
$ . env/bin/activate
227-
$ opencanaryd --start --allow-run-as-root
190+
$ opencanaryd --start --uid=nobody --gid=nogroup
228191
```
229192

193+
With the `uid` and `gid` flags, OpenCanary drops root privileges after binding to its ports. This can be changed to other low-privileged user/group or omitted to keep running with root privileges.
194+
230195
### With pkgx
231196

232197
Start OpenCanary by running:
233198

234199
```
235-
$ sudo -E pkgx opencanaryd --start
200+
$ sudo -E pkgx opencanaryd --start --uid=nobody --gid=nogroup
236201
```
237202

203+
With the `uid` and `gid` flags, OpenCanary drops root privileges after binding to its ports. This can be changed to other low-privileged user/group or omitted to keep running with root privileges.
204+
205+
238206
### With docker-compose
239207

240208
The route requires [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/) to be installed.

bin/opencanaryd

Lines changed: 21 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,80 +3,54 @@ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
33
PIDFILE="${DIR}/opencanaryd.pid"
44

55
cmd=$1
6-
allow_run_as_root=false
7-
uid_=""
8-
gid_=""
96

107
function usage() {
118
echo -e "\n OpenCanary\n"
12-
echo -e "\topencanaryd [ --start | --dev | --stop | --restart | --copyconfig | --usermodule | --createuser | --version | --help ] [--allow-run-as-root | --uid=opencanary --gid=nogroup]\n\n"
9+
echo -e "\topencanaryd [ --start | --dev | --stop | --restart | --copyconfig | --usermodule | --version | --help ] [--uid=nobody] [--gid=nogroup]\n\n"
1310
echo -e "\t\t--start\tStarts the opencanaryd process"
1411
echo -e "\t\t--dev\tRun the opencanaryd process in the foreground"
1512
echo -e "\t\t--stop\tStops the opencanaryd process"
1613
echo -e "\t\t--usermodule\tRun opencanaryd in foreground with only usermodules enabled"
1714
echo -e "\t\t--copyconfig\tCreates a default config file at /etc/opencanaryd/opencanary.conf"
18-
echo -e "\t\t--createuser\tCreate the 'opencanary' user and respective home directory for isolation purposes"
1915
echo -e "\t\t--version\tDisplays the current opencanary version."
2016
echo -e "\t\t--"
2117
echo -e "\t\t--help\tThis help\n"
2218
echo -e "\toptions"
2319
echo -e "\t\t--allow-run-as-root\tDo not drop privileges of the opencanary once process starts"
24-
echo -e "\t\t--uid\tSpecify a user ID to drop privileges to"
25-
echo -e "\t\t--gid\tSpecify a group ID to drop privileges to"
26-
20+
echo -e "\t\t--uid\tSpecify a user or uid to drop privileges to"
21+
echo -e "\t\t--gid\tSpecify a group of gid to drop privileges to"
2722
}
2823

29-
# Use sudo when not running as root
30-
function sudo() {
31-
if [ "$EUID" -ne 0 ]; then
32-
$(which sudo) $*
33-
else
34-
# Strip `sudo -E` before running the remaining command
35-
${*:2}
36-
fi
37-
}
38-
39-
# Set options if supplied
24+
# Parse options
4025
for arg in "$@"; do
41-
case $arg in
26+
case $arg in
4227
--uid=*)
43-
uid_="${arg#*=}"
28+
readonly TWISTD_UID_FLAG=" --uid=${arg#*=}"
4429
;;
4530
--gid=*)
46-
gid_="${arg#*=}"
47-
;;
48-
--allow-run-as-root)
49-
allow_run_as_root=true
31+
readonly TWISTD_GID_FLAG=" --gid=${arg#*=}"
5032
;;
5133
esac
5234
done
5335

54-
# Build twistd command suffix based on options
55-
twist_permissions_opts=""
56-
57-
if [ "$allow_run_as_root" = false ]; then
58-
if [ -z "$uid_" ]; then
59-
uid_="opencanary"
60-
fi
61-
twist_permissions_opts="${twist_permissions_opts} --uid ${uid_}"
62-
63-
if [ -z "$gid_" ]; then
64-
gid_="nogroup"
65-
fi
66-
twist_permissions_opts="${twist_permissions_opts} --gid ${gid_}"
36+
if [[ -z $TWISTD_UID_FLAG || -z $TWISTD_GID_FLAG ]]; then
37+
echo "WARNING: OpenCanary will not drop root user or group privileges after launching. Set both --uid=nobody and --gid=nogroup (another other low privilege user/group) to silence this warning."
6738
fi
6839

69-
# Only run the following if we expect to run a sudoers command later
70-
if [[ "${cmd}" != "--help" && "${cmd}" != "--version" && "${cmd}" != "--createuser" && $(id $uid_ &>/dev/null; echo $?) -eq 0 ]]; then
71-
# Ensure logging file and HTTP static content perms are correct
72-
sudo touch /var/tmp/opencanary.log && sudo chmod 755 /var/tmp/opencanary.log
73-
sudo mkdir -p /etc/opencanaryd && sudo chown -R ${uid_}:${gid_} /etc/opencanaryd
74-
fi
40+
# Use sudo when not running as root
41+
function sudo() {
42+
if [ "$EUID" -ne 0 ]; then
43+
$(which sudo) $*
44+
else
45+
# Strip `sudo -E` before running the remaining command
46+
${*:2}
47+
fi
48+
}
7549

7650
if [ "${cmd}" == "--start" ]; then
77-
sudo -E "${DIR}/twistd" -y "${DIR}/opencanary.tac" --pidfile "${PIDFILE}" --syslog --prefix=opencanaryd $twist_permissions_opts
51+
sudo -E "${DIR}/twistd" -y "${DIR}/opencanary.tac" --pidfile "${PIDFILE}" --syslog --prefix=opencanaryd ${TWISTD_UID_FLAG:-} ${TWISTD_GID_FLAG:-}
7852
elif [ "${cmd}" == "--dev" ]; then
79-
sudo -E "${DIR}/twistd" -noy "${DIR}/opencanary.tac" $twist_permissions_opts
53+
sudo -E "${DIR}/twistd" -noy "${DIR}/opencanary.tac" ${TWISTD_UID_FLAG:-} ${TWISTD_GID_FLAG:-}
8054
elif [ "${cmd}" == "--usermodule" ]; then
8155
usermodconf=$(python -c "from pkg_resources import resource_filename; print(resource_filename('opencanary', 'data/settings-usermodule.json'))")
8256

@@ -93,7 +67,7 @@ elif [ "${cmd}" == "--usermodule" ]; then
9367
elif [ "${cmd}" == "--restart" ]; then
9468
pid=`sudo -E cat "${PIDFILE}"`
9569
sudo -E kill "$pid"
96-
sudo -E "${DIR}/twistd" -y "${DIR}/opencanary.tac" --pidfile "${PIDFILE}" --syslog --prefix=opencanaryd $twist_permissions_opts
70+
sudo -E "${DIR}/twistd" -y "${DIR}/opencanary.tac" --pidfile "${PIDFILE}" --syslog --prefix=opencanaryd ${TWISTD_UID_FLAG:-} ${TWISTD_GID_FLAG:-}
9771
elif [ "${cmd}" == "--stop" ]; then
9872
pid=`sudo -E cat "${PIDFILE}"`
9973
sudo -E kill "$pid"
@@ -105,29 +79,8 @@ elif [ "${cmd}" == "--copyconfig" ]; then
10579
defaultconf=$(python3 -c "from pkg_resources import resource_filename; print(resource_filename('opencanary', 'data/settings.json'))")
10680
sudo -E mkdir -p /etc/opencanaryd
10781
sudo -E cp "${defaultconf}" /etc/opencanaryd/opencanary.conf
108-
sudo chown ${uid_}:${gid_} /etc/opencanaryd && sudo chmod -R 600 /etc/opencanaryd
10982
echo -e "[*] A sample config file is ready /etc/opencanaryd/opencanary.conf\n"
11083
echo "[*] Edit your configuration, then launch with \"opencanaryd --start\""
111-
elif [ "${cmd}" == "--createuser" ]; then
112-
if id opencanary &>/dev/null; then
113-
echo "User 'opencanary' already exists."
114-
exit 1
115-
fi
116-
if [[ "$(uname)" == "Darwin" ]]; then # macos
117-
sudo dscl . -create /Users/opencanary
118-
sudo dscl . -create /Users/opencanary UserShell /bin/bash
119-
sudo dscl . -create /Users/opencanary RealName "OpenCanary"
120-
next_uid=$(($(dscl . -list /Users UniqueID | awk '$2 >= 1000 {print $2}' | sort -n | tail -n 1) + 2))
121-
sudo dscl . -create /Users/opencanary UniqueID "${next_uid}"
122-
sudo dscl . -create /Users/opencanary PrimaryGroupID $(dscl . -read /Groups/nogroup | awk '/PrimaryGroupID: / {print $2}')
123-
sudo dscl . -create /Users/opencanary NFSHomeDirectory /Users/opencanary
124-
sudo mkdir -p /Users/opencanary
125-
sudo chown opencanary:nogroup /Users/opencanary
126-
sudo chmod 755 /Users/opencanary
127-
else # other, e.g., Linux
128-
sudo useradd -m -s /bin/bash -c "OpenCanary" --gid nogroup opencanary
129-
sudo chown -R opencanary:nogroup /home/opencanary
130-
fi
13184
elif [ "${cmd}" == "--version" ]; then
13285
python -c "from opencanary import __version__; print(__version__);"
13386
else

0 commit comments

Comments
 (0)