From a1b823c61fa35e89ecaf79f7103b0b81f3ed4e98 Mon Sep 17 00:00:00 2001 From: minie4 Date: Wed, 1 Mar 2023 21:55:32 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20Initial=20Version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 23 +++++++++++++++++ README.md | 30 ++++++++++++++++++++++ errorpage_template.html | 39 ++++++++++++++++++++++++++++ generate_errorpages.py | 25 ++++++++++++++++++ lighttpd.conf | 56 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 173 insertions(+) create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 errorpage_template.html create mode 100644 generate_errorpages.py create mode 100644 lighttpd.conf diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2ecf83c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM alpine + +RUN apk add --update --no-cache lighttpd python3 py3-pip nodejs php-cgi +RUN apk add --update --no-cache vim nano curl wget sed + +RUN apk add --update --no-cache php81-bcmath php81-calendar php81-common php81-ctype php81-curl php81-dom php81-embed php81-exif php81-fileinfo php81-ftp php81-gd php81-gettext php81-gmp php81-iconv php81-imap php81-intl php81-json php81-mbstring php81-openssl php81-pcntl php81-pdo php81-pdo_sqlite php81-pear php81-session php81-simplexml php81-sockets php81-sodium php81-sqlite3 php81-sysvmsg php81-sysvsem php81-sysvshm php81-tidy php81-tokenizer php81-xml php81-xmlreader php81-xmlwriter php81-xsl php81-zip php81-pecl-xhprof php81-pecl-xhprof-assets php81-pecl-uuid php81-pecl-protobuf php81-pecl-xdebug php81-pecl-memcached php81-pecl-ssh2 php81-pecl-imagick php81-pecl-imagick-dev php81-pecl-vips php81-pecl-ast php81-pecl-event php81-pecl-redis php81-pecl-apcu php81-pecl-mailparse php81-pecl-msgpack php81-pecl-yaml php81-brotli php81-pecl-amqp php81-pecl-couchbase php81-pecl-igbinary php81-pecl-lzf +RUN pip3 install requests scrapy beautifulsoup4 + +COPY lighttpd.conf /etc/lighttpd/lighttpd.conf +RUN rm -r /var/www/localhost && mkdir /var/www/html && chown -R lighttpd:lighttpd /var/www/html +RUN touch /run/lighttpd.pid && chown lighttpd:lighttpd /run/lighttpd.pid + +# Generate error pages +WORKDIR /tmp +COPY generate_errorpages.py ./ +COPY errorpage_template.html ./ +RUN mkdir /var/www/error_pages +RUN python3 /tmp/generate_errorpages.py /var/www/error_pages +RUN rm -rf /tmp + +WORKDIR / +USER lighttpd +CMD ["/usr/sbin/lighttpd", "-D", "-f", "/etc/lighttpd/lighttpd.conf"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..10f4721 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# Scripted CGI Server + +This Repository contains a Dockerfile to build a lighttpd cgi webserver that can not only run php, but also nodejs or python scripts on request. It may be useful for quickly deploying and updating small scripts and being able to trigger them via your browser or curl. + +## Usage + +Build the docker image + +``` +docker build -t cgi-server . +``` + +Run the container + +``` +docker run --restart unless-stopped -p 8080:80 -v /path/to/data:/var/www/html +``` + +Place either static .html files or script files (.py, .njs for nodejs or .php) in the data directory (mounted at `/var/www/html`) + +## Custom error pages + +To customize the error pages you could ... + +1. Change the template file `errorpage_template.html` before building the docker image +2. Mount a volume at `/var/www/error_pages/`, for example: + +``` +-v /path/to/error_pages:/var/www/error_pages +``` diff --git a/errorpage_template.html b/errorpage_template.html new file mode 100644 index 0000000..61a8f6d --- /dev/null +++ b/errorpage_template.html @@ -0,0 +1,39 @@ + + + + + + + {{title}} + + + + {{code}} +
+ {{description}} + + diff --git a/generate_errorpages.py b/generate_errorpages.py new file mode 100644 index 0000000..64af437 --- /dev/null +++ b/generate_errorpages.py @@ -0,0 +1,25 @@ +import sys + +file = open("errorpage_template.html", "r") +template_html = file.read() + +error_pages = { + "400": "Bad Request", + "401": "Unauthorized", + "403": "Forbidden", + "404": "Not Found", + "405": "Method Not Allowed", + "413": "Payload Too Large", + "418": "I'm a teapot", + "429": "Too Many Requests", + "500": "Internal Server Error", + "503": "Service Unavailable", + "522": "Connection Timed Out", + "599": "Network Connect Timeout Error" +} + +for error, description in error_pages.items(): + f = open(f"{sys.argv[1]}/{error}.html", "w") + html = template_html.replace("{{code}}", error).replace("{{description}}", description).replace("{{title}}", f"{error} {description}") + f.write(html) + f.close() \ No newline at end of file diff --git a/lighttpd.conf b/lighttpd.conf new file mode 100644 index 0000000..28b2654 --- /dev/null +++ b/lighttpd.conf @@ -0,0 +1,56 @@ +server.modules = ( + "mod_indexfile", + "mod_access", + "mod_alias", + "mod_redirect", + "mod_rewrite", + "mod_cgi" +) + +server.document-root = "/var/www/html" +server.errorfile-prefix = "/var/www/error_pages/" +server.errorlog = "/var/log/lighttpd/error.log" +server.pid-file = "/run/lighttpd.pid" +server.username = "lighttpd" +server.groupname = "lighttpd" +server.port = 80 + +# features +#https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_feature-flagsDetails +server.feature-flags += ("server.h2proto" => "enable") +server.feature-flags += ("server.h2c" => "enable") +server.feature-flags += ("server.graceful-shutdown-timeout" => 5) +#server.feature-flags += ("server.graceful-restart-bg" => "enable") + +# strict parsing and normalization of URL for consistency and security +# https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_http-parseoptsDetails +# (might need to explicitly set "url-path-2f-decode" = "disable" +# if a specific application is encoding URLs inside url-path) +server.http-parseopts = ( + "header-strict" => "enable",# default + "host-strict" => "enable",# default + "host-normalize" => "enable",# default + "url-normalize-unreserved"=> "enable",# recommended highly + "url-normalize-required" => "enable",# recommended + "url-ctrls-reject" => "enable",# recommended + "url-path-2f-decode" => "enable",# recommended highly (unless breaks app) + "url-path-dotseg-remove" => "enable",# recommended highly (unless breaks app) +) + +index-file.names = ( "index.html", "index.php", "index.py", "index.njs" ) +static-file.exclude-extensions = (".php", ".py", ".njs") +cgi.assign = (".php" => "/usr/bin/php-cgi", ".py" => "/usr/bin/python3" , ".njs" => "/usr/bin/node") + +$HTTP["url"] =~ "^/\.git/" { + url.access-deny = ("") +} +url.access-deny = ( "~", ".inc", ".env") + +include "mime-types.conf" + +#server.compat-module-load = "disable" +server.modules += ( + "mod_dirlisting", + "mod_staticfile", +) +