From 862fbd41d46c94a54226c10068cec5596b96d20f Mon Sep 17 00:00:00 2001 From: Alexey Golubev Date: Mon, 13 Jan 2020 15:22:54 +0300 Subject: [PATCH] Add prof of concept none pivilage execution Use 'DS_PORT' env to use custom https port sudo docker run -e DS_PORT=1234 -itd -p80:1234 \ onlyoffice/documentserver --- config/nginx/nginx | 196 +++++++++++++++++++++++++++++ config/nginx/nginx.conf | 63 ++++++++++ config/supervisor/supervisor | 8 +- config/supervisor/supervisord.conf | 6 +- run-document-server.sh | 11 ++ 5 files changed, 277 insertions(+), 7 deletions(-) create mode 100644 config/nginx/nginx create mode 100644 config/nginx/nginx.conf diff --git a/config/nginx/nginx b/config/nginx/nginx new file mode 100644 index 0000000..1c68faf --- /dev/null +++ b/config/nginx/nginx @@ -0,0 +1,196 @@ +#!/bin/sh + +### BEGIN INIT INFO +# Provides: nginx +# Required-Start: $local_fs $remote_fs $network $syslog $named +# Required-Stop: $local_fs $remote_fs $network $syslog $named +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: starts the nginx web server +# Description: starts nginx using start-stop-daemon +### END INIT INFO + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/sbin/nginx +NAME=nginx +DESC=nginx + +# Include nginx defaults if available +if [ -r /etc/default/nginx ]; then + . /etc/default/nginx +fi + +STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/5/KILL/5}" + +test -x $DAEMON || exit 0 + +. /lib/init/vars.sh +. /lib/lsb/init-functions + +# Try to extract nginx pidfile +PID=$(cat /etc/nginx/nginx.conf | grep -Ev '^\s*#' | awk 'BEGIN { RS="[;{}]" } { if ($1 == "pid") print $2 }' | head -n1) +if [ -z "$PID" ]; then + PID=/tmp/nginx.pid +fi + +if [ -n "$ULIMIT" ]; then + # Set ulimit if it is set in /etc/default/nginx + ulimit $ULIMIT +fi + +start_nginx() { + # Start the daemon/service + # + # Returns: + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PID --chuid www-data:www-data --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PID --chuid www-data:www-data --exec $DAEMON -- \ + $DAEMON_OPTS 2>/dev/null \ + || return 2 +} + +test_config() { + # Test the nginx configuration + $DAEMON -t $DAEMON_OPTS >/dev/null 2>&1 +} + +stop_nginx() { + # Stops the daemon/service + # + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=$STOP_SCHEDULE --pidfile $PID --name $NAME + RETVAL="$?" + sleep 1 + return "$RETVAL" +} + +reload_nginx() { + # Function that sends a SIGHUP to the daemon/service + start-stop-daemon --stop --signal HUP --quiet --pidfile $PID --name $NAME + return 0 +} + +rotate_logs() { + # Rotate log files + start-stop-daemon --stop --signal USR1 --quiet --pidfile $PID --name $NAME + return 0 +} + +upgrade_nginx() { + # Online upgrade nginx executable + # http://nginx.org/en/docs/control.html + # + # Return + # 0 if nginx has been successfully upgraded + # 1 if nginx is not running + # 2 if the pid files were not created on time + # 3 if the old master could not be killed + if start-stop-daemon --stop --signal USR2 --quiet --pidfile $PID --name $NAME; then + # Wait for both old and new master to write their pid file + while [ ! -s "${PID}.oldbin" ] || [ ! -s "${PID}" ]; do + cnt=`expr $cnt + 1` + if [ $cnt -gt 10 ]; then + return 2 + fi + sleep 1 + done + # Everything is ready, gracefully stop the old master + if start-stop-daemon --stop --signal QUIT --quiet --pidfile "${PID}.oldbin" --name $NAME; then + return 0 + else + return 3 + fi + else + return 1 + fi +} + +case "$1" in + start) + log_daemon_msg "Starting $DESC" "$NAME" + start_nginx + case "$?" in + 0|1) log_end_msg 0 ;; + 2) log_end_msg 1 ;; + esac + ;; + stop) + log_daemon_msg "Stopping $DESC" "$NAME" + stop_nginx + case "$?" in + 0|1) log_end_msg 0 ;; + 2) log_end_msg 1 ;; + esac + ;; + restart) + log_daemon_msg "Restarting $DESC" "$NAME" + + # Check configuration before stopping nginx + if ! test_config; then + log_end_msg 1 # Configuration error + exit $? + fi + + stop_nginx + case "$?" in + 0|1) + start_nginx + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + reload|force-reload) + log_daemon_msg "Reloading $DESC configuration" "$NAME" + + # Check configuration before stopping nginx + # + # This is not entirely correct since the on-disk nginx binary + # may differ from the in-memory one, but that's not common. + # We prefer to check the configuration and return an error + # to the administrator. + if ! test_config; then + log_end_msg 1 # Configuration error + exit $? + fi + + reload_nginx + log_end_msg $? + ;; + configtest|testconfig) + log_daemon_msg "Testing $DESC configuration" + test_config + log_end_msg $? + ;; + status) + status_of_proc -p $PID "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + upgrade) + log_daemon_msg "Upgrading binary" "$NAME" + upgrade_nginx + log_end_msg $? + ;; + rotate) + log_daemon_msg "Re-opening $DESC log files" "$NAME" + rotate_logs + log_end_msg $? + ;; + *) + echo "Usage: $NAME {start|stop|restart|reload|force-reload|status|configtest|rotate|upgrade}" >&2 + exit 3 + ;; +esac \ No newline at end of file diff --git a/config/nginx/nginx.conf b/config/nginx/nginx.conf new file mode 100644 index 0000000..9af3b9e --- /dev/null +++ b/config/nginx/nginx.conf @@ -0,0 +1,63 @@ +user www-data; +worker_processes 1; +pid /tmp/nginx.pid; + +events { + worker_connections 524288; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_tokens off; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; + + ## + # Logging Settings + ## + + access_log off; + error_log /var/log/nginx/error.log; + + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} \ No newline at end of file diff --git a/config/supervisor/supervisor b/config/supervisor/supervisor index 1e612e0..34046ea 100644 --- a/config/supervisor/supervisor +++ b/config/supervisor/supervisor @@ -30,8 +30,8 @@ DESC=supervisor test -x $DAEMON || exit 0 -LOGDIR=/var/log/supervisor -PIDFILE=/var/run/$NAME.pid +LOGDIR=/tmp +PIDFILE=/tmp/$NAME.pid PS_COUNT=0 DODTIME=5 # Time to wait for the server to die, in seconds # If this value is set too low you might not @@ -101,7 +101,7 @@ case "$1" in rm -f "$PIDFILE" fi echo -n "Starting $DESC: " - start-stop-daemon --start --quiet --pidfile $PIDFILE \ + start-stop-daemon --start --quiet --chuid ds:ds --pidfile $PIDFILE \ --startas $DAEMON -- $DAEMON_OPTS test -f $PIDFILE || sleep 1 if running ; then @@ -152,7 +152,7 @@ case "$1" in echo -n "Restarting $DESC: " start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE [ -n "$DODTIME" ] && sleep $DODTIME - start-stop-daemon --start --quiet --pidfile $PIDFILE \ + start-stop-daemon --start --quiet --chuid ds:ds --pidfile $PIDFILE \ --startas $DAEMON -- $DAEMON_OPTS echo "$NAME." ;; diff --git a/config/supervisor/supervisord.conf b/config/supervisor/supervisord.conf index 27ef634..d844de9 100644 --- a/config/supervisor/supervisord.conf +++ b/config/supervisor/supervisord.conf @@ -4,9 +4,9 @@ port = 127.0.0.1:9001 [supervisord] -logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) -pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) -childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) +logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log) +pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +childlogdir=/tmp ; ('AUTO' child log dir, default $TEMP) ; the below section must remain in the config file for RPC ; (supervisorctl/web interface) to work, additional interfaces may be diff --git a/run-document-server.sh b/run-document-server.sh index 67d26f4..37aa536 100755 --- a/run-document-server.sh +++ b/run-document-server.sh @@ -48,6 +48,8 @@ JSON="${JSON_BIN} -q -f ${ONLYOFFICE_DEFAULT_CONFIG}" JSON_LOG="${JSON_BIN} -q -f ${ONLYOFFICE_LOG4JS_CONFIG}" JSON_EXAMPLE="${JSON_BIN} -q -f ${ONLYOFFICE_EXAMPLE_CONFIG}" +DS_PORT=${DS_PORT:-80} + LOCAL_SERVICES=() PG_ROOT=/var/lib/postgresql @@ -286,6 +288,8 @@ update_nginx_settings(){ fi else ln -sf ${NGINX_ONLYOFFICE_PATH}/ds.conf.tmpl ${NGINX_ONLYOFFICE_CONF} + # set up default listening port + sed 's,\(listen.\+:\)\([0-9]\+\)\(.*;\),'"\1${DS_PORT}\3"',' -i ${NGINX_ONLYOFFICE_CONF} fi # check if ipv6 supported otherwise remove it from nginx config @@ -303,6 +307,10 @@ update_supervisor_settings(){ cp ${SYSCONF_TEMPLATES_DIR}/supervisor/supervisor /etc/init.d/ # Copy modified supervisor config cp ${SYSCONF_TEMPLATES_DIR}/supervisor/supervisord.conf /etc/supervisor/supervisord.conf + # Copy modified nginx start script + cp ${SYSCONF_TEMPLATES_DIR}/nginx/nginx /etc/init.d/ + # Copy modified ngnix config + cp ${SYSCONF_TEMPLATES_DIR}/nginx/nginx.conf /etc/nginx/nginx.conf } update_log_settings(){ @@ -331,6 +339,9 @@ for i in ${LOG_DIR} ${LIB_DIR} ${DATA_DIR}; do chmod -R 755 "$i" done +touch ${DS_LOG_DIR}/nginx.error.log +chown www-data:www-data ${DS_LOG_DIR}/nginx.error.log + if [ ${ONLYOFFICE_DATA_CONTAINER_HOST} = "localhost" ]; then read_setting