diff --git a/Dockerfile b/Dockerfile index e728db06154cca6868c7da4bfdee92fafe15d27e..65da15df0a16cd8f33eadab9ab21adf78306f032 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,49 @@ -FROM alpine:edge +# multi stage dockerfile +# it defines three different images +# 1. mumble-web +# 2. mumble-web with nginx +# 3. websockfiy as web socket -LABEL maintainer="Armin Co <armin.co@hs-bochum.de" +# mumble-web base image +FROM alpine:edge AS mumble-web +LABEL maintainer="Armin Co <armin.co@hs-bochum.de" # copy mumble-web repository into docker image COPY ./mumble-web /home/node - -# install git and npm -RUN apk add --no-cache git npm - -# "install" mumble-web +# install deps for building mumble web +RUN apk add --no-cache \ + git \ + nodejs \ + npm \ + && \ + adduser -D -g 1001 -u 1001 -h /home/node node && \ + mkdir -p /home/node && \ + mkdir -p /home/node/.npm-global && \ + mkdir -p /home/node/app && \ + chown -R node: /home/node +USER node +ENV PATH=/home/node/.npm-global/bin:$PATH +ENV NPM_CONFIG_PREFIX=/home/node/.npm-global +# build mumble-web RUN cd /home/node && \ npm install && \ npm run build && \ npm audit fix && \ npm audit + + +# add nginx as webserver to mumble web +FROM nginx:alpine AS mumble-web-nginx +USER root +COPY --from=mumble-web /home/node/dist /home/node/dist +RUN apk add --no-cache nginx && \ + adduser -D -g 'www' www && \ + mkdir /data +EXPOSE 443 + + +# websockify +FROM alpine:edge AS websockify +RUN echo http://nl.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories && \ + apk add --no-cache websockify +EXPOSE 64737 diff --git a/README.md b/README.md index a61380d0d67ad197e426306bcc158cff7993eaad..37961f893d5449fc3cbfae9cd8b7e012a7d0beb8 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,40 @@ # Build Mumble Web -A script to build the mumble-web app in a docker image. +You can use the `build_mumble_web.sh` script to build the mumble-web application, which +can be deployed with an webserver. The application +will be stored at `./dist`. The script will clone the [mumble-web](https://github.com/Johni0702/mumble-web) repository. If the repository already was cloned it will pull the latest commits. Afterwards the docker image, defined in the [Dockerfile](https://gitlab.cvh-server.de/aco/build-mumble-web/-/blob/master/Dockerfile), will be build. -**Dockerfile** +## build - - alpine:edge - - copy content of repository into image - - install git and npm - - npm: install, run build, audit fix, audit +To build the mumble-web application: just run the script! -The image contains the generated files of the app, which can be published by a webserver. -To copy these files out of the image it is necessary to create a container out of this image. -Therefore the command 'docker create' needs to be executed. -Afterwards the directory can be copied with 'docker cp'. - -The container and the image are not longer needed, so they will be removed at the end. - - -**Verifying commits** - -Commits made from the online editor are signed with the github web-flow key. -Other commits are not verified. - -[https://github.com/web-flow.gpg](https://github.com/web-flow.gpg) - - - -**Testing** +```bash +./build_mumble_web.sh +``` -To test if the generation of the website files was succesfully -a test version can be run with websockify. +## testing +If you want to test mumble web, you can deploy it together with mumble and websockify +via the provided 'docker-compose.yml' file. ``` -openssl req -newkey rsa:2048 -nodes -keyout test.key -x509 -days 365 -out test.crt -websockify --cert=test.crt --key=test.key --ssl-only --ssl-target --web=/home/node/dist 443 MUMBLE_SERVER:64738 +# to deploy run: +docker-compose up -d ``` +This will build two containers. One with mumble-web and nginx as a webserver and the second container +just contains websockify. The imae for the third container will not be build localy but +pulled from DockerHub. The container will serve murmur (mumble server) +for this test deployment. +The web application will be accessible via: [https://localhost](https://localhost). +The certificate is self signed, so your browser will warn you when you try to access the site. -**Deploy** -When the website is not deployed with websockify, it is still needed for the websocket. +**verifying the mumble-web repository** + +Commits made from the online editor are signed with the github web-flow key. +Other commits are not verified. -```websockify --ssl-target 64737 MUMBLE_SERVER:64738``` \ No newline at end of file +[https://github.com/web-flow.gpg](https://github.com/web-flow.gpg) \ No newline at end of file diff --git a/build_mumble_web.sh b/build_mumble_web.sh index 4588bf09b12b34dcecb304a0967fe27377aa8080..2eaca85bdc9a975ebd381cbfed1a28e1300d01d6 100755 --- a/build_mumble_web.sh +++ b/build_mumble_web.sh @@ -36,14 +36,19 @@ function verify_commit_HEAD() { cd ../ } +echo "buildung mumble-web" +echo "files will be stored at: ${DESTINATION_HOST}" + # check if git repository is already cloned # then pull updates # if not clone repository if cd $REPOSITORY then - git pull - cd ../ + echo "updating mumble-web repository" + git pull + cd ../ else + echo "cloning mumble-web repository" git clone $URL_GITHUB fi @@ -51,18 +56,15 @@ fi verify_commit_HEAD # build docker image -printf "\nBuilding image\n" -docker build -t $IMAGE_NAME . > build.log +echo "building mumble-web image" +echo "logs will be stored in: build.log" +time docker build --target mumble-web -t "${IMAGE_NAME}" . > build.log # create temporary container docker create --name $CONTAINER_NAME "${IMAGE_NAME}" # remove previously copied files -rm -rf dist/ -# copy files from container to host +rm -rf dist +# # copy files from container to host docker cp $CONTAINER_NAME:"${DIST_DIR}" $DESTINATION_HOST # remove created container docker rm -f $CONTAINER_NAME -# remove the created image -# otherwise it would only pull updates -# from other node dependenices -# if there was an update in the repository docker rmi $IMAGE_NAME \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..27d750e589881bb1d8b375e5e0ac5a8c48520818 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,33 @@ +version: '3.4' + +services: + mumble-web-nginx: + build: + context: ./ + target: mumble-web-nginx + container_name: mumble-web-nginx + ports: + - 443:443 + volumes: + - ./webserver:/data:ro + restart: unless-stopped + command: ["/data/entrypoint.sh"] + + websockify: + build: + context: ./ + target: websockify + container_name: websockify + ports: + - 64737:64737 + restart: unless-stopped + command: websockify --ssl-target 64737 murmur:64738 + + murmur: + container_name: murmur + image: coppit/mumble-server + ports: + - 64738:64738 + volumes: + - ./murmur:/data + restart: unless-stopped diff --git a/murmur/mumble-server.ini b/murmur/mumble-server.ini new file mode 100644 index 0000000000000000000000000000000000000000..4c09b4594560be6524fef8996929d9331a641f2a --- /dev/null +++ b/murmur/mumble-server.ini @@ -0,0 +1,199 @@ +# Murmur configuration file. +# +# General notes: +# * Settings in this file are default settings and many of them can be overridden +# with virtual server specific configuration via the Ice or DBus interface. +# * Due to the way this configuration file is read some rules have to be +# followed when specifying variable values (as in variable = value): +# * Make sure to quote the value when using commas in strings or passwords. +# NOT variable = super,secret BUT variable = "super,secret" +# * Make sure to escape special characters like '\' or '"' correctly +# NOT variable = """ BUT variable = "\"" +# NOT regex = \w* BUT regex = \\w* + +# Path to database. If blank, will search for +# murmur.sqlite in default locations or create it if not found. +database= + +# If you wish to use something other than SQLite, you'll need to set the name +# of the database above, and also uncomment the below. +# Sticking with SQLite is strongly recommended, as it's the most well tested +# and by far the fastest solution. +# +#dbDriver=QMYSQL +#dbUsername= +#dbPassword= +#dbHost= +#dbPort= +#dbPrefix=murmur_ +#dbOpts= + +# Murmur defaults to not using D-Bus. If you wish to use dbus, which is one of the +# RPC methods available in Murmur, please specify so here. +# +dbus=system + +# Alternate D-Bus service name. Only use if you are running distinct +# murmurd processes connected to the same D-Bus daemon. +#dbusservice=net.sourceforge.mumble.murmur + +# If you want to use ZeroC Ice to communicate with Murmur, you need +# to specify the endpoint to use. Since there is no authentication +# with ICE, you should only use it if you trust all the users who have +# shell access to your machine. +# Please see the ICE documentation on how to specify endpoints. +ice="tcp -h 127.0.0.1 -p 6502" + +# Ice primarily uses local sockets. This means anyone who has a +# user account on your machine can connect to the Ice services. +# You can set a plaintext "secret" on the Ice connection, and +# any script attempting to access must then have this secret +# (as context with name "secret"). +# Access is split in read (look only) and write (modify) +# operations. Write access always includes read access, +# unless read is explicitly denied (see note below). +# +# Note that if this is uncommented and with empty content, +# access will be denied. + +#icesecretread= +icesecretwrite= + +# How many login attempts do we tolerate from one IP +# inside a given timeframe before we ban the connection? +# Note that this is global (shared between all virtual servers), and that +# it counts both successfull and unsuccessfull connection attempts. +# Set either Attempts or Timeframe to 0 to disable. +#autobanAttempts = 10 +#autobanTimeframe = 120 +#autobanTime = 300 + +# Specifies the file Murmur should log to. By default, Murmur +# logs to the file 'murmur.log'. If you leave this field blank +# on Unix-like systems, Murmur will force itself into foreground +# mode which logs to the console. +logfile=/data/mumble-server.log + +# If set, Murmur will write its process ID to this file +# when running in daemon mode (when the -fg flag is not +# specified on the command line). Only available on +# Unix-like systems. +pidfile=/var/run/mumble-server/mumble-server.pid + +# The below will be used as defaults for new configured servers. +# If you're just running one server (the default), it's easier to +# configure it here than through D-Bus or Ice. +# +# Welcome message sent to clients when they connect. +welcometext="<br />Welcome to this server running <b>Murmur</b>.<br />Enjoy your stay!<br />" + +# Port to bind TCP and UDP sockets to. +port=64738 + +# Specific IP or hostname to bind to. +# If this is left blank (default), Murmur will bind to all available addresses. +#host= + +# Password to join server. +serverpassword= + +# Maximum bandwidth (in bits per second) clients are allowed +# to send speech at. +bandwidth=72000 + +# Maximum number of concurrent clients allowed. +users=100 + +# Amount of users with Opus support needed to force Opus usage, in percent. +# 0 = Always enable Opus, 100 = enable Opus if it's supported by all clients. +#opusthreshold=100 + +# Maximum depth of channel nesting. Note that some databases like MySQL using +# InnoDB will fail when operating on deeply nested channels. +#channelnestinglimit=10 + +# Regular expression used to validate channel names. +# (Note that you have to escape backslashes with \ ) +#channelname=[ \\-=\\w\\#\\[\\]\\{\\}\\(\\)\\@\\|]+ + +# Regular expression used to validate user names. +# (Note that you have to escape backslashes with \ ) +#username=[-=\\w\\[\\]\\{\\}\\(\\)\\@\\|\\.]+ + +# Maximum length of text messages in characters. 0 for no limit. +#textmessagelength=5000 + +# Maximum length of text messages in characters, with image data. 0 for no limit. +#imagemessagelength=131072 + +# Allow clients to use HTML in messages, user comments and channel descriptions? +#allowhtml=true + +# Murmur retains the per-server log entries in an internal database which +# allows it to be accessed over D-Bus/ICE. +# How many days should such entries be kept? +# Set to 0 to keep forever, or -1 to disable logging to the DB. +#logdays=31 + +# To enable public server registration, the serverpassword must be blank, and +# this must all be filled out. +# The password here is used to create a registry for the server name; subsequent +# updates will need the same password. Don't lose your password. +# The URL is your own website, and only set the registerHostname for static IP +# addresses. +# Only uncomment the 'registerName' parameter if you wish to give your "Root" channel a custom name. +# +#registerName=Mumble Server +#registerPassword=secret +#registerUrl=https://www.mumble.info/ +#registerHostname= + +# If this option is enabled, the server will announce its presence via the +# bonjour service discovery protocol. To change the name announced by bonjour +# adjust the registerName variable. +# See http://developer.apple.com/networking/bonjour/index.html for more information +# about bonjour. +#bonjour=True + +# If you have a proper SSL certificate, you can provide the filenames here. +# Otherwise, Murmur will create it's own certificate automatically. +#sslCert= +#sslKey= + +# The sslCiphers option chooses the cipher suites to make available for use +# in SSL/TLS. This option is server-wide, and cannot be set on a +# per-virtual-server basis. +# +# This option is specified using OpenSSL cipher list notation (see +# https://www.openssl.org/docs/apps/ciphers.html#CIPHER-LIST-FORMAT). +# +# It is recommended that you try your cipher string using 'openssl ciphers <string>' +# before setting it here, to get a feel for which cipher suites you will get. +# +# After setting this option, it is recommend that you inspect your Murmur log +# to ensure that Murmur is using the cipher suites that you expected it to. +# +# Note: Changing this option may impact the backwards compatibility of your +# Murmur server, and can remove the ability for older Mumble clients to be able +# to connect to it. +#sslCiphers=EECDH+AESGCM:AES256-SHA:AES128-SHA + +# If Murmur is started as root, which user should it switch to? +# This option is ignored if Murmur isn't started with root privileges. +uname=mumble-server + +# If this options is enabled, only clients which have a certificate are allowed +# to connect. +#certrequired=False + +# If enabled, clients are sent information about the servers version and operating +# system. +#sendversion=True + +# You can configure any of the configuration options for Ice here. We recommend +# leave the defaults as they are. +# Please note that this section has to be last in the configuration file. +# +[Ice] +Ice.Warn.UnknownProperties=1 +Ice.MessageSizeMax=65536 diff --git a/webserver/certs/test.crt b/webserver/certs/test.crt new file mode 100644 index 0000000000000000000000000000000000000000..e20f663ad867b929c1cac696dabe7687f9835857 --- /dev/null +++ b/webserver/certs/test.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUV/1KSmiz97r880nZQ91GAX8YFCUwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCREUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA2MTAwOTQ5MTZaFw0yMTA2 +MTAwOTQ5MTZaMEUxCzAJBgNVBAYTAkRFMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCer0AbjQ/nsil/oF1kznswiXnizix6iO7RVSxr07ys +4EFdYXgzm/qEG8uaRnSk6pgpLzAB5t0HE84f6oT+bBetJsyv5gdZsNoXQJb55GAn +ZxvxsckKBS8/qlvGg6gA6e6ZTS1ZIc15wEXwpYfcCGFXX839AcQRMqCFFDshUstH +tIjt2JS9e60+ZXD5Gvl/CtJ+faYWV7T+yIrvY5vCT05LEt+XPgIOP9rdnMKmcpBR +wlfLepYV3sbeAMuj6GIx7ZYAZfHTCj8CeiYyVRykGP3BRccocgz7ZsSgFqH6p6tM +FfVDeNXQUzvsjmIGYyPhXFnR/WYgoLZJEvPmgLgzYr5hAgMBAAGjUzBRMB0GA1Ud +DgQWBBT6OHE8Yd1AZnh9Mt5Q5yjRSYoVujAfBgNVHSMEGDAWgBT6OHE8Yd1AZnh9 +Mt5Q5yjRSYoVujAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAV +Vyc9epCKBsNXu1RyDmv0CqIPmSeJGkaTz9IFsMZ1GZhWF2XUCuRr+zWsBiOCf+zH +G5zKi5oU+crUQmaFvC9M3JxoeHjxzDsg6+kW+8acoCBxhRwml7e4cor+Z1Ghb9Rm +jOlQuuKnJy0UHp4JyLrxZrwhZuMfN16/jYNnAH9o7vYqvFMrfuZuPvSyPERp3EVL +DIGUy4+7kseP+Uc0U2vNDcMMllaqpKjFyDmoPQfsBldKKOFvyCYJdAkcXrm47SSf +IQvsRblPKvW6FTEOZ1fQKR2S8OTTqExq6uP0hoy1qmeRXI3m+5tmsYIxLdjZBD+Z +jsKklG3dnPSOY0BSIjdk +-----END CERTIFICATE----- diff --git a/webserver/certs/test.key b/webserver/certs/test.key new file mode 100644 index 0000000000000000000000000000000000000000..32cb48d6cac27e19e97a30c32f997015cc37d432 --- /dev/null +++ b/webserver/certs/test.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCer0AbjQ/nsil/ +oF1kznswiXnizix6iO7RVSxr07ys4EFdYXgzm/qEG8uaRnSk6pgpLzAB5t0HE84f +6oT+bBetJsyv5gdZsNoXQJb55GAnZxvxsckKBS8/qlvGg6gA6e6ZTS1ZIc15wEXw +pYfcCGFXX839AcQRMqCFFDshUstHtIjt2JS9e60+ZXD5Gvl/CtJ+faYWV7T+yIrv +Y5vCT05LEt+XPgIOP9rdnMKmcpBRwlfLepYV3sbeAMuj6GIx7ZYAZfHTCj8CeiYy +VRykGP3BRccocgz7ZsSgFqH6p6tMFfVDeNXQUzvsjmIGYyPhXFnR/WYgoLZJEvPm +gLgzYr5hAgMBAAECggEAdnn8UFWy0VfI+hweftxXR7btBPTQarCANlT0dJFDJoPM +6c6TM1063pXuHwKJpnPtJZqwqkrXLaiQ1m1/3IGR79qvKomBZWrQelnkHzFuxRyL +1ZnasxuJ2mv0V7QGpKAEX/sqZ4kAY+21imXcmOC85MKIBmXiIMD+7j1bpJavZZnt +RWYzpGBsz4cG3QARO76oxfoG3G4qKsbZrpB0ro5ZenB5Gp1c9WjeGmdlaKBi+qIH +zu4ltd++1TEfcM6lZAfd6dsyzD65N822xQLApUs6PXjCo2zQYfy7Yb8ob+2UsGda +mpwWoOsd8PCvqXirj4rOfAFVKr49BgygT4Gq9AlxPQKBgQDKfhKapxU+Fq/bRFNO +W50tv/FTK7O/gnQpm0X7E2TYKLm/4TQrPHG+ALqhJPArXEXgkaxXGHRm9pkfdrA3 +epm+WqV37rLRkVAHERPmZe42WfQ1Mr5E9jagDYM/a8vQANEse7mJvACjE5Cx5xIm +ARQ6RHPEuMxZeYfrVHwLneOgCwKBgQDInbjm+6OKk1WuzErTIF+aj0+NLm3z295T +f6ThXrC+Ube2h4UBKCxsvHV6BgiKj2hKFI9vK4LTGsGBZr5DeEA6eovt3pQZU6Q6 +6vCp/Ko4DAssyP+5BYW1PHOIUN8mQunGrrbkwWIi69fieQ/ZhNEFF1R6qc0Xa0lv +QAeqFFdCwwKBgQCMTu1PMgUbH5c9BMwAmKSBxeVO7xI+2gLprYjBH8AZs6Z52W9P +ojNiJ5kp/bFZKjfVErtrIivOCIMzdQdHefE8IA1V3BUV922PZ/r1A54bFRuNHRsQ +J9bT8mkGMghomZhXDWgTkyyR0wXI78b4hHjiovngzvfx668Nll3Zos7N3wKBgQCs +zYbOl6S4Ic7lQR2WnEUdeiI45uxY6GOqIsHgStMNLJCFTlhXtcYGZ5L9Z6MFzx8y +6GDgjmci9eIGV3y92x/f/1z2qQmCg1RsV6Czm2r32g/qJLx5H/ObOBYALkD40RxT +Qn1Rr+2bTPDpKARqBgiRTRY8jnSVnpljlZDEhL7hRwKBgQCdeqqkq5nO7uxmzq8Y +WM69JEvDTwCtRFi6748iWuntYqfKes5EajxzzhHk7Yb1AL2pyVWAqpxGPxi4Ed9b +j45SdyYmBs0mZwUpkwjCFF12vry+SXDvLrhygTmBEjRWpPBFKMewhy3RRi4fbsqg +IG9YnM1/WJOvjSQ0/ZvEKeJ6Bg== +-----END PRIVATE KEY----- diff --git a/webserver/conf/nginx.conf b/webserver/conf/nginx.conf new file mode 100644 index 0000000000000000000000000000000000000000..3236f87d6c293c5685a78a72c01859ecf420fcf1 --- /dev/null +++ b/webserver/conf/nginx.conf @@ -0,0 +1,44 @@ +user www; +worker_processes auto; + +error_log /var/log/nginx/error.log warn; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + sendfile on; + access_log /var/log/nginx/access.log; + keepalive_timeout 3000; + + server { + listen 443 ssl; + server_name localhost; + ssl_certificate /data/certs/test.crt; + ssl_certificate_key /data/certs/test.key; + + location / { + root /home/node/dist; + } + + location /demo { + resolver 127.0.0.11 valid=30s; + # get websockify ip address + # of the container it is running in + # name of the container has to be websockify + set $websock_address websockify; + proxy_pass http://$websock_address:64737; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } + } + + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } +} \ No newline at end of file diff --git a/webserver/entrypoint.sh b/webserver/entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..a49bd005c1633d5b6823719d48fb470008714bdd --- /dev/null +++ b/webserver/entrypoint.sh @@ -0,0 +1,4 @@ +# copy config for nginx +cp /data/conf/nginx.conf /etc/nginx/nginx.conf; +# start nginx +nginx -g 'daemon off;'; nginx -s reload; \ No newline at end of file