Skip to content

Commit fc3e51a

Browse files
authored
Merge pull request #93 from linuxserver/harden-bookworm
add new container env vars and hardening setup bookworm
2 parents 464ef4b + 3e3edbe commit fc3e51a

File tree

13 files changed

+439
-121
lines changed

13 files changed

+439
-121
lines changed

Dockerfile

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,29 @@ RUN \
1616
https://github.com/selkies-project/selkies.git \
1717
/src && \
1818
cd /src && \
19-
git checkout -f 89e39cf7d58c8f7c87ac5922b56b84f745ddeeab
19+
git checkout -f 29466e687d2dbed57f657e47b69fab217a81ef1f
2020

2121
RUN \
22-
echo "**** build frontend ****" && \
23-
cd /src && \
24-
cd addons/gst-web-core && \
25-
npm install && \
26-
npm run build && \
27-
cp dist/selkies-core.js ../selkies-dashboard/src && \
28-
cd ../selkies-dashboard && \
22+
echo "**** build shared core library ****" && \
23+
cd /src/addons/gst-web-core && \
2924
npm install && \
3025
npm run build && \
31-
mkdir dist/src dist/nginx && \
32-
cp ../universal-touch-gamepad/universalTouchGamepad.js dist/src/ && \
33-
cp ../gst-web-core/nginx/* dist/nginx/ && \
34-
cp -r ../gst-web-core/dist/jsdb dist/ && \
26+
echo "**** build multiple dashboards ****" && \
27+
DASHBOARDS="selkies-dashboard selkies-dashboard-zinc selkies-dashboard-wish" && \
3528
mkdir /buildout && \
36-
cp -ar dist/* /buildout/
29+
for DASH in $DASHBOARDS; do \
30+
cd /src/addons/$DASH && \
31+
cp ../gst-web-core/dist/selkies-core.js src/ && \
32+
npm install && \
33+
npm run build && \
34+
mkdir -p dist/src dist/nginx && \
35+
cp ../gst-web-core/dist/selkies-core.js dist/src/ && \
36+
cp ../universal-touch-gamepad/universalTouchGamepad.js dist/src/ && \
37+
cp ../gst-web-core/nginx/* dist/nginx/ && \
38+
cp -r ../gst-web-core/dist/jsdb dist/ && \
39+
mkdir -p /buildout/$DASH && \
40+
cp -ar dist/* /buildout/$DASH/; \
41+
done
3742

3843
# Runtime stage
3944
FROM ghcr.io/linuxserver/baseimage-debian:bookworm
@@ -184,7 +189,7 @@ RUN \
184189
| awk '/tag_name/{print $4;exit}' FS='[""]') && \
185190
curl -o \
186191
/tmp/selkies.tar.gz -L \
187-
"https://github.com/selkies-project/selkies/archive/89e39cf7d58c8f7c87ac5922b56b84f745ddeeab.tar.gz" && \
192+
"https://github.com/selkies-project/selkies/archive/29466e687d2dbed57f657e47b69fab217a81ef1f.tar.gz" && \
188193
cd /tmp && \
189194
tar xf selkies.tar.gz && \
190195
cd selkies-* && \
@@ -226,6 +231,9 @@ RUN \
226231
-e 's|</keyboard>| <keybind key="C-S-d"><action name="ToggleDecorations"/></keybind>\n</keyboard>|' \
227232
-e 's|<number>4</number>|<number>1</number>|' \
228233
/etc/xdg/openbox/rc.xml && \
234+
sed -i \
235+
's/--startup/--replace --startup/g' \
236+
/usr/bin/openbox-session && \
229237
echo "**** user perms ****" && \
230238
sed -e 's/%sudo ALL=(ALL:ALL) ALL/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' \
231239
-i /etc/sudoers && \
@@ -270,7 +278,7 @@ RUN \
270278

271279
# add local files
272280
COPY /root /
273-
COPY --from=frontend /buildout /usr/share/selkies/www
281+
COPY --from=frontend /buildout /usr/share/selkies
274282
COPY --from=xvfb / /
275283

276284
# ports and volumes

Dockerfile.aarch64

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,29 @@ RUN \
1616
https://github.com/selkies-project/selkies.git \
1717
/src && \
1818
cd /src && \
19-
git checkout -f 89e39cf7d58c8f7c87ac5922b56b84f745ddeeab
19+
git checkout -f 29466e687d2dbed57f657e47b69fab217a81ef1f
2020

2121
RUN \
22-
echo "**** build frontend ****" && \
23-
cd /src && \
24-
cd addons/gst-web-core && \
25-
npm install && \
26-
npm run build && \
27-
cp dist/selkies-core.js ../selkies-dashboard/src && \
28-
cd ../selkies-dashboard && \
22+
echo "**** build shared core library ****" && \
23+
cd /src/addons/gst-web-core && \
2924
npm install && \
3025
npm run build && \
31-
mkdir dist/src dist/nginx && \
32-
cp ../universal-touch-gamepad/universalTouchGamepad.js dist/src/ && \
33-
cp ../gst-web-core/nginx/* dist/nginx/ && \
34-
cp -r ../gst-web-core/dist/jsdb dist/ && \
26+
echo "**** build multiple dashboards ****" && \
27+
DASHBOARDS="selkies-dashboard selkies-dashboard-zinc selkies-dashboard-wish" && \
3528
mkdir /buildout && \
36-
cp -ar dist/* /buildout/
29+
for DASH in $DASHBOARDS; do \
30+
cd /src/addons/$DASH && \
31+
cp ../gst-web-core/dist/selkies-core.js src/ && \
32+
npm install && \
33+
npm run build && \
34+
mkdir -p dist/src dist/nginx && \
35+
cp ../gst-web-core/dist/selkies-core.js dist/src/ && \
36+
cp ../universal-touch-gamepad/universalTouchGamepad.js dist/src/ && \
37+
cp ../gst-web-core/nginx/* dist/nginx/ && \
38+
cp -r ../gst-web-core/dist/jsdb dist/ && \
39+
mkdir -p /buildout/$DASH && \
40+
cp -ar dist/* /buildout/$DASH/; \
41+
done
3742

3843
# Runtime stage
3944
FROM ghcr.io/linuxserver/baseimage-debian:arm64v8-bookworm
@@ -182,7 +187,7 @@ RUN \
182187
| awk '/tag_name/{print $4;exit}' FS='[""]') && \
183188
curl -o \
184189
/tmp/selkies.tar.gz -L \
185-
"https://github.com/selkies-project/selkies/archive/89e39cf7d58c8f7c87ac5922b56b84f745ddeeab.tar.gz" && \
190+
"https://github.com/selkies-project/selkies/archive/29466e687d2dbed57f657e47b69fab217a81ef1f.tar.gz" && \
186191
cd /tmp && \
187192
tar xf selkies.tar.gz && \
188193
cd selkies-* && \
@@ -224,6 +229,9 @@ RUN \
224229
-e 's|</keyboard>| <keybind key="C-S-d"><action name="ToggleDecorations"/></keybind>\n</keyboard>|' \
225230
-e 's|<number>4</number>|<number>1</number>|' \
226231
/etc/xdg/openbox/rc.xml && \
232+
sed -i \
233+
's/--startup/--replace --startup/g' \
234+
/usr/bin/openbox-session && \
227235
echo "**** user perms ****" && \
228236
sed -e 's/%sudo ALL=(ALL:ALL) ALL/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' \
229237
-i /etc/sudoers && \
@@ -268,7 +276,7 @@ RUN \
268276

269277
# add local files
270278
COPY /root /
271-
COPY --from=frontend /buildout /usr/share/selkies/www
279+
COPY --from=frontend /buildout /usr/share/selkies
272280
COPY --from=xvfb / /
273281

274282
# ports and volumes

README.md

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,51 @@ All application settings are passed via environment variables:
3434
| CUSTOM_USER | HTTP Basic auth username, abc is default. |
3535
| PASSWORD | HTTP Basic auth password, abc is default. If unset there will be no auth |
3636
| SUBFOLDER | Subfolder for the application if running a subfolder reverse proxy, need both slashes IE `/subfolder/` |
37-
| TITLE | The page title displayed on the web browser, default "Selkies - webrtc". |
37+
| TITLE | The page title displayed on the web browser, default "Selkies". |
38+
| DASHBOARD | Allows the user to set their dashboard. Options: `selkies-dashboard`, `selkies-dashboard-zinc`, `selkies-dashboard-wish`. |
39+
| FILE_MANAGER_PATH | Modifies the default upload/download file path, path must have proper permissions for abc user. |
3840
| START_DOCKER | If set to false a container with privilege will not automatically start the DinD Docker setup. |
3941
| DISABLE_IPV6 | If set to true or any value this will disable IPv6 |
4042
| LC_ALL | Set the Language for the container to run as IE `fr_FR.UTF-8` `ar_AE.UTF-8` |
4143
| NO_DECOR | If set the application will run without window borders for use as a PWA. (Decor can be enabled and disabled with Ctrl+Shift+d) |
4244
| NO_FULL | Do not autmatically fullscreen applications when using openbox. |
4345
| DISABLE_ZINK | Do not set the Zink environment variables if a video card is detected (userspace applications will use CPU rendering) |
46+
| MAX_RES | Pass a larger maximum resolution for the container default is 16k `15360x8640` |
4447
| WATERMARK_PNG | Full path inside the container to a watermark png IE `/usr/share/selkies/www/icon.png` |
4548
| WATERMARK_LOCATION | Where to paint the image over the stream integer options below |
46-
| MAX_RES | Pass a larger maximum resolution for the container default is 16k `15360x8640` |
4749

48-
* 1 - Top Left
49-
* 2 - Top Right
50-
* 3 - Bottom Left
51-
* 4 - Bottom Right
52-
* 5 - Centered
53-
* 6 - Animated
50+
**`WATERMARK_LOCATION` Options:**
51+
- **1**: Top Left
52+
- **2**: Top Right
53+
- **3**: Bottom Left
54+
- **4**: Bottom Right
55+
- **5**: Centered
56+
- **6**: Animated
57+
58+
## Hardening
59+
60+
These variables can be used to lock down the desktop environment for single-application use cases or to restrict user capabilities.
61+
62+
### Meta Variables
63+
64+
These variables act as presets, enabling multiple hardening options at once. Individual options can still be set to override the preset.
65+
66+
| Variable | Description |
67+
| :----: | --- |
68+
| **`HARDEN_DESKTOP`** | Enables `DISABLE_OPEN_TOOLS`, `DISABLE_SUDO`, and `DISABLE_TERMINALS`. Also sets related Selkies UI settings (`SELKIES_FILE_TRANSFERS`, `SELKIES_COMMAND_ENABLED`, `SELKIES_UI_SIDEBAR_SHOW_FILES`, `SELKIES_UI_SIDEBAR_SHOW_APPS`) if they are not explicitly set by the user. |
69+
| **`HARDEN_OPENBOX`** | Enables `DISABLE_CLOSE_BUTTON`, `DISABLE_MOUSE_BUTTONS`, and `HARDEN_KEYBINDS`. It also flags `RESTART_APP` if not set by the user, ensuring the primary application is automatically restarted if closed. |
70+
71+
### Individual Hardening Variables
72+
73+
| Variable | Description |
74+
| :--- | --- |
75+
| **`DISABLE_OPEN_TOOLS`** | If true, disables `xdg-open` and `exo-open` binaries by removing their execute permissions. |
76+
| **`DISABLE_SUDO`** | If true, disables the `sudo` command by removing its execute permissions and invalidating the passwordless sudo configuration. |
77+
| **`DISABLE_TERMINALS`** | If true, disables common terminal emulators by removing their execute permissions and hiding them from the Openbox right-click menu. |
78+
| **`DISABLE_CLOSE_BUTTON`** | If true, removes the close button from window title bars in the Openbox window manager. |
79+
| **`DISABLE_MOUSE_BUTTONS`** | If true, disables the right-click and middle-click context menus and actions within the Openbox window manager. |
80+
| **`HARDEN_KEYBINDS`** | If true, disables default Openbox keybinds that can bypass other hardening options (e.g., `Alt+F4` to close windows, `Alt+Escape` to show the root menu). |
81+
| **`RESTART_APP`** | If true, enables a watchdog service that automatically restarts the main application if it is closed. The user's autostart script is made read-only and root owned to prevent tampering. |
5482

5583
## Selkies application settings
5684

@@ -334,7 +362,7 @@ services:
334362
devices:
335363
- driver: nvidia
336364
count: 1
337-
capabilities: [compute,video,graphics,utility]
365+
capabilities: [gpu]
338366
```
339367
340368
# Development

readme-vars.yml

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,51 @@ full_custom_readme: |
3838
| CUSTOM_USER | HTTP Basic auth username, abc is default. |
3939
| PASSWORD | HTTP Basic auth password, abc is default. If unset there will be no auth |
4040
| SUBFOLDER | Subfolder for the application if running a subfolder reverse proxy, need both slashes IE `/subfolder/` |
41-
| TITLE | The page title displayed on the web browser, default "Selkies - webrtc". |
41+
| TITLE | The page title displayed on the web browser, default "Selkies". |
42+
| DASHBOARD | Allows the user to set their dashboard. Options: `selkies-dashboard`, `selkies-dashboard-zinc`, `selkies-dashboard-wish`. |
43+
| FILE_MANAGER_PATH | Modifies the default upload/download file path, path must have proper permissions for abc user. |
4244
| START_DOCKER | If set to false a container with privilege will not automatically start the DinD Docker setup. |
4345
| DISABLE_IPV6 | If set to true or any value this will disable IPv6 |
4446
| LC_ALL | Set the Language for the container to run as IE `fr_FR.UTF-8` `ar_AE.UTF-8` |
4547
| NO_DECOR | If set the application will run without window borders for use as a PWA. (Decor can be enabled and disabled with Ctrl+Shift+d) |
4648
| NO_FULL | Do not autmatically fullscreen applications when using openbox. |
4749
| DISABLE_ZINK | Do not set the Zink environment variables if a video card is detected (userspace applications will use CPU rendering) |
50+
| MAX_RES | Pass a larger maximum resolution for the container default is 16k `15360x8640` |
4851
| WATERMARK_PNG | Full path inside the container to a watermark png IE `/usr/share/selkies/www/icon.png` |
4952
| WATERMARK_LOCATION | Where to paint the image over the stream integer options below |
50-
| MAX_RES | Pass a larger maximum resolution for the container default is 16k `15360x8640` |
5153
52-
* 1 - Top Left
53-
* 2 - Top Right
54-
* 3 - Bottom Left
55-
* 4 - Bottom Right
56-
* 5 - Centered
57-
* 6 - Animated
54+
**`WATERMARK_LOCATION` Options:**
55+
- **1**: Top Left
56+
- **2**: Top Right
57+
- **3**: Bottom Left
58+
- **4**: Bottom Right
59+
- **5**: Centered
60+
- **6**: Animated
61+
62+
## Hardening
63+
64+
These variables can be used to lock down the desktop environment for single-application use cases or to restrict user capabilities.
65+
66+
### Meta Variables
67+
68+
These variables act as presets, enabling multiple hardening options at once. Individual options can still be set to override the preset.
69+
70+
| Variable | Description |
71+
| :----: | --- |
72+
| **`HARDEN_DESKTOP`** | Enables `DISABLE_OPEN_TOOLS`, `DISABLE_SUDO`, and `DISABLE_TERMINALS`. Also sets related Selkies UI settings (`SELKIES_FILE_TRANSFERS`, `SELKIES_COMMAND_ENABLED`, `SELKIES_UI_SIDEBAR_SHOW_FILES`, `SELKIES_UI_SIDEBAR_SHOW_APPS`) if they are not explicitly set by the user. |
73+
| **`HARDEN_OPENBOX`** | Enables `DISABLE_CLOSE_BUTTON`, `DISABLE_MOUSE_BUTTONS`, and `HARDEN_KEYBINDS`. It also flags `RESTART_APP` if not set by the user, ensuring the primary application is automatically restarted if closed. |
74+
75+
### Individual Hardening Variables
76+
77+
| Variable | Description |
78+
| :--- | --- |
79+
| **`DISABLE_OPEN_TOOLS`** | If true, disables `xdg-open` and `exo-open` binaries by removing their execute permissions. |
80+
| **`DISABLE_SUDO`** | If true, disables the `sudo` command by removing its execute permissions and invalidating the passwordless sudo configuration. |
81+
| **`DISABLE_TERMINALS`** | If true, disables common terminal emulators by removing their execute permissions and hiding them from the Openbox right-click menu. |
82+
| **`DISABLE_CLOSE_BUTTON`** | If true, removes the close button from window title bars in the Openbox window manager. |
83+
| **`DISABLE_MOUSE_BUTTONS`** | If true, disables the right-click and middle-click context menus and actions within the Openbox window manager. |
84+
| **`HARDEN_KEYBINDS`** | If true, disables default Openbox keybinds that can bypass other hardening options (e.g., `Alt+F4` to close windows, `Alt+Escape` to show the root menu). |
85+
| **`RESTART_APP`** | If true, enables a watchdog service that automatically restarts the main application if it is closed. The user's autostart script is made read-only and root owned to prevent tampering. |
5886
5987
## Selkies application settings
6088
@@ -338,7 +366,7 @@ full_custom_readme: |
338366
devices:
339367
- driver: nvidia
340368
count: 1
341-
capabilities: [compute,video,graphics,utility]
369+
capabilities: [gpu]
342370
```
343371
344372
# Development

root/defaults/default.conf

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ server {
44
listen 3000 default_server;
55
listen [::]:3000 default_server;
66
location SUBFOLDER {
7-
alias /usr/share/selkies/www/;
7+
alias /usr/share/selkies/web/;
88
index index.html index.htm;
99
try_files $uri $uri/ =404;
1010
}
@@ -42,11 +42,15 @@ server {
4242
fancyindex on;
4343
fancyindex_footer SUBFOLDERnginx/footer.html;
4444
fancyindex_header SUBFOLDERnginx/header.html;
45-
alias REPLACE_HOME/Desktop/;
45+
alias REPLACE_DOWNLOADS_PATH/;
46+
if (-f $request_filename) {
47+
add_header Content-Disposition "attachment";
48+
add_header X-Content-Type-Options "nosniff";
49+
}
4650
}
4751
error_page 500 502 503 504 /50x.html;
4852
location = SUBFOLDER50x.html {
49-
root /usr/share/selkies/www/;
53+
root /usr/share/selkies/web/;
5054
}
5155
}
5256

@@ -58,7 +62,7 @@ server {
5862
ssl_certificate /config/ssl/cert.pem;
5963
ssl_certificate_key /config/ssl/cert.key;
6064
location SUBFOLDER {
61-
alias /usr/share/selkies/www/;
65+
alias /usr/share/selkies/web/;
6266
index index.html index.htm;
6367
try_files $uri $uri/ =404;
6468
}
@@ -96,12 +100,14 @@ server {
96100
fancyindex on;
97101
fancyindex_footer SUBFOLDERnginx/footer.html;
98102
fancyindex_header SUBFOLDERnginx/header.html;
99-
alias REPLACE_HOME/Desktop/;
103+
alias REPLACE_DOWNLOADS_PATH/;
104+
if (-f $request_filename) {
105+
add_header Content-Disposition "attachment";
106+
add_header X-Content-Type-Options "nosniff";
107+
}
100108
}
101109
error_page 500 502 503 504 /50x.html;
102110
location = SUBFOLDER50x.html {
103-
root /usr/share/selkies/www/;
111+
root /usr/share/selkies/web/;
104112
}
105113
}
106-
107-

root/etc/s6-overlay/s6-rc.d/init-nginx/run

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ CHPORT="${CUSTOM_HTTPS_PORT:-3001}"
99
CWS="${CUSTOM_WS_PORT:-8082}"
1010
CUSER="${CUSTOM_USER:-abc}"
1111
SFOLDER="${SUBFOLDER:-/}"
12+
FILE_MANAGER_PATH="${FILE_MANAGER_PATH:-$HOME/Desktop}"
13+
DASHBOARD="${DASHBOARD:-selkies-dashboard}"
14+
SELKIES_FILE_TRANSFERS="${SELKIES_FILE_TRANSFERS:-upload,download}"
15+
HARDEN_DESKTOP="${HARDEN_DESKTOP:-false}"
1216

1317
# create self signed cert
1418
if [ ! -f "/config/ssl/cert.pem" ]; then
@@ -28,8 +32,11 @@ sed -i "s/3000/$CPORT/g" ${NGINX_CONFIG}
2832
sed -i "s/3001/$CHPORT/g" ${NGINX_CONFIG}
2933
sed -i "s/CWS/$CWS/g" ${NGINX_CONFIG}
3034
sed -i "s|SUBFOLDER|$SFOLDER|g" ${NGINX_CONFIG}
31-
sed -i "s|REPLACE_HOME|$HOME|g" ${NGINX_CONFIG}
32-
s6-setuidgid abc mkdir -p $HOME/Desktop
35+
sed -i "s|REPLACE_DOWNLOADS_PATH|$FILE_MANAGER_PATH|g" ${NGINX_CONFIG}
36+
s6-setuidgid abc mkdir -p ${FILE_MANAGER_PATH}
37+
if [[ $SELKIES_FILE_TRANSFERS != *"download"* ]] || [[ ${HARDEN_DESKTOP,,} == "true" ]]; then
38+
sed -i '/files {/,/^ }/d' ${NGINX_CONFIG}
39+
fi
3340
if [ ! -z ${DISABLE_IPV6+x} ]; then
3441
sed -i '/listen \[::\]/d' ${NGINX_CONFIG}
3542
fi
@@ -44,7 +51,34 @@ if [ ! -z ${DEV_MODE+x} ]; then
4451
${NGINX_CONFIG}
4552
fi
4653

47-
# copy favicon
54+
# set dashboard and icon
55+
rm -Rf \
56+
/usr/share/selkies/web
57+
cp -a \
58+
/usr/share/selkies/$DASHBOARD \
59+
/usr/share/selkies/web
60+
sed -i "s|REPLACE_DOWNLOADS_PATH|$FILE_MANAGER_PATH|g" /usr/share/selkies/web/nginx/footer.html
61+
cp \
62+
/usr/share/selkies/www/icon.png \
63+
/usr/share/selkies/web/favicon.ico
4864
cp \
4965
/usr/share/selkies/www/icon.png \
50-
/usr/share/selkies/www/favicon.ico
66+
/usr/share/selkies/web/icon.png
67+
# manifest creation
68+
echo "{
69+
\"name\": \"${TITLE}\",
70+
\"short_name\": \"${TITLE}\",
71+
\"manifest_version\": 2,
72+
\"version\": \"1.0.0\",
73+
\"display\": \"fullscreen\",
74+
\"background_color\": \"#000000\",
75+
\"theme_color\": \"#000000\",
76+
\"icons\": [
77+
{
78+
\"src\": \"icon.png\",
79+
\"type\": \"image/png\",
80+
\"sizes\": \"180x180\"
81+
}
82+
],
83+
\"start_url\": \"/\"
84+
}" > /usr/share/selkies/web/manifest.json

0 commit comments

Comments
 (0)