UI - copy from helpers, systemd service and instances page update
This commit is contained in:
parent
f771ec43f1
commit
4dd1ff8479
163
compile.sh
163
compile.sh
@ -1,163 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
function git_secure_checkout() {
|
|
||||||
path="$1"
|
|
||||||
commit="$2"
|
|
||||||
ret=$(pwd)
|
|
||||||
cd $path
|
|
||||||
git checkout "${commit}^{commit}"
|
|
||||||
if [ $? -ne 0 ] ; then
|
|
||||||
echo "[!] Commit hash $commit is absent from submodules $path !"
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
cd $ret
|
|
||||||
}
|
|
||||||
|
|
||||||
function git_secure_clone() {
|
|
||||||
repo="$1"
|
|
||||||
commit="$2"
|
|
||||||
folder=$(echo "$repo" | sed -E "s@https://github.com/.*/(.*)\.git@\1@")
|
|
||||||
git clone "$repo"
|
|
||||||
cd "$folder"
|
|
||||||
git checkout "${commit}^{commit}"
|
|
||||||
if [ $? -ne 0 ] ; then
|
|
||||||
echo "[!] Commit hash $commit is absent from repository $repo !"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
cd ..
|
|
||||||
}
|
|
||||||
|
|
||||||
NTASK=$(nproc)
|
|
||||||
|
|
||||||
# install build dependencies
|
|
||||||
apk add --no-cache --virtual build autoconf libtool automake git geoip-dev yajl-dev g++ gcc curl-dev libxml2-dev pcre-dev make linux-headers libmaxminddb-dev musl-dev lua-dev gd-dev gnupg brotli-dev openssl-dev
|
|
||||||
|
|
||||||
# compile and install ModSecurity library
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/SpiderLabs/ModSecurity.git 753145fbd1d6751a6b14fdd700921eb3cc3a1d35
|
|
||||||
cd ModSecurity
|
|
||||||
./build.sh
|
|
||||||
git submodule init
|
|
||||||
git submodule update
|
|
||||||
git_secure_checkout bindings/python 47a6925df187f96e4593afab18dc92d5f22bd4d5
|
|
||||||
git_secure_checkout others/libinjection bf234eb2f385b969c4f803b35fda53cffdd93922
|
|
||||||
git_secure_checkout test/test-cases/secrules-language-tests d03f4c1e930440df46c1faa37d820a919704d9da
|
|
||||||
./configure --enable-static=no --disable-doxygen-doc --disable-dependency-tracking
|
|
||||||
make -j $NTASK
|
|
||||||
make install-strip
|
|
||||||
|
|
||||||
# download and install CRS rules
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/coreruleset/coreruleset.git 7776fe23f127fd2315bad0e400bdceb2cabb97dc
|
|
||||||
cd coreruleset
|
|
||||||
mkdir /opt/owasp
|
|
||||||
cp -r rules /opt/owasp/crs
|
|
||||||
cp crs-setup.conf.example /opt/owasp/crs.conf
|
|
||||||
|
|
||||||
# get nginx modules
|
|
||||||
cd /tmp
|
|
||||||
# ModSecurity connector for nginx
|
|
||||||
git_secure_clone https://github.com/SpiderLabs/ModSecurity-nginx.git 2497e6ac654d0b117b9534aa735b757c6b11c84f
|
|
||||||
# headers more
|
|
||||||
git_secure_clone https://github.com/openresty/headers-more-nginx-module.git d6d7ebab3c0c5b32ab421ba186783d3e5d2c6a17
|
|
||||||
# geoip
|
|
||||||
git_secure_clone https://github.com/leev/ngx_http_geoip2_module.git 1cabd8a1f68ea3998f94e9f3504431970f848fbf
|
|
||||||
# cookie
|
|
||||||
git_secure_clone https://github.com/AirisX/nginx_cookie_flag_module.git c4ff449318474fbbb4ba5f40cb67ccd54dc595d4
|
|
||||||
# brotli
|
|
||||||
git_secure_clone https://github.com/google/ngx_brotli.git 9aec15e2aa6feea2113119ba06460af70ab3ea62
|
|
||||||
|
|
||||||
# LUA requirements
|
|
||||||
git_secure_clone https://github.com/openresty/luajit2.git fe32831adcb3f5fe9259a9ce404fc54e1399bba3
|
|
||||||
cd luajit2
|
|
||||||
make -j $NTASK
|
|
||||||
make install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/openresty/lua-resty-core.git b7d0a681bb41e6e3f29e8ddc438ef26fd819bb19
|
|
||||||
cd lua-resty-core
|
|
||||||
make install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/openresty/lua-resty-lrucache.git b2035269ac353444ac65af3969692bcae4fc1605
|
|
||||||
cd lua-resty-lrucache
|
|
||||||
make install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/openresty/lua-resty-dns.git 24c9a69808aedfaf029ae57707cdef75d83e2d19
|
|
||||||
cd lua-resty-dns
|
|
||||||
make install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/bungle/lua-resty-session.git f300870ce4eee3f4903e0565c589f1faf0c1c5aa
|
|
||||||
cd lua-resty-session
|
|
||||||
cp -r lib/resty/* /usr/local/lib/lua/resty
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/bungle/lua-resty-random.git 17b604f7f7dd217557ca548fc1a9a0d373386480
|
|
||||||
cd lua-resty-random
|
|
||||||
make install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/openresty/lua-resty-string.git 9a543f8531241745f8814e8e02475351042774ec
|
|
||||||
cd lua-resty-string
|
|
||||||
make install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/openresty/lua-cjson.git 0df488874f52a881d14b5876babaa780bb6200ee
|
|
||||||
cd lua-cjson
|
|
||||||
make -j $NTASK
|
|
||||||
make install
|
|
||||||
make install-extra
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/ittner/lua-gd.git 2ce8e478a8591afd71e607506bc8c64b161bbd30
|
|
||||||
cd lua-gd
|
|
||||||
make -j $NTASK
|
|
||||||
make INSTALL_PATH=/usr/local/lib/lua/5.1 install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/ledgetech/lua-resty-http.git 984fdc26054376384e3df238fb0f7dfde01cacf1
|
|
||||||
cd lua-resty-http
|
|
||||||
make install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/Neopallium/lualogging.git cadc4e8fd652be07a65b121a3e024838db330c15
|
|
||||||
cd lualogging
|
|
||||||
cp -r src/* /usr/local/lib/lua
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/diegonehab/luasocket.git 5b18e475f38fcf28429b1cc4b17baee3b9793a62
|
|
||||||
cd luasocket
|
|
||||||
make -j $NTASK
|
|
||||||
make CDIR_linux=lib/lua/5.1 LDIR_linux=lib/lua install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/brunoos/luasec.git c6704919bdc85f3324340bdb35c2795a02f7d625
|
|
||||||
cd luasec
|
|
||||||
make linux -j $NTASK
|
|
||||||
make LUACPATH=/usr/local/lib/lua/5.1 LUAPATH=/usr/local/lib/lua install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/crowdsecurity/lua-cs-bouncer.git 3c235c813fc453dcf51a391bc9e9a36ca77958b0
|
|
||||||
cd lua-cs-bouncer
|
|
||||||
mkdir /usr/local/lib/lua/crowdsec
|
|
||||||
cp lib/*.lua /usr/local/lib/lua/crowdsec
|
|
||||||
sed -i 's/require "lrucache"/require "resty.lrucache"/' /usr/local/lib/lua/crowdsec/CrowdSec.lua
|
|
||||||
sed -i 's/require "config"/require "crowdsec.config"/' /usr/local/lib/lua/crowdsec/CrowdSec.lua
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/hamishforbes/lua-resty-iputils.git 3151d6485e830421266eee5c0f386c32c835dba4
|
|
||||||
cd lua-resty-iputils
|
|
||||||
make LUA_LIB_DIR=/usr/local/lib/lua install
|
|
||||||
cd /tmp
|
|
||||||
git_secure_clone https://github.com/openresty/lua-nginx-module.git 2d23bc4f0a29ed79aaaa754c11bffb1080aa44ba
|
|
||||||
export LUAJIT_LIB=/usr/local/lib
|
|
||||||
export LUAJIT_INC=/usr/local/include/luajit-2.1
|
|
||||||
|
|
||||||
# compile and install dynamic modules
|
|
||||||
cd /tmp
|
|
||||||
wget https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
|
|
||||||
wget https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz.asc
|
|
||||||
gpg --import /tmp/nginx-keys/*.key
|
|
||||||
check=$(gpg --verify /tmp/nginx-${NGINX_VERSION}.tar.gz.asc /tmp/nginx-${NGINX_VERSION}.tar.gz 2>&1 | grep "^gpg: Good signature from ")
|
|
||||||
if [ "$check" = "" ] ; then
|
|
||||||
echo "[!] Wrong signature from nginx source !"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
tar -xvzf nginx-${NGINX_VERSION}.tar.gz
|
|
||||||
cd nginx-$NGINX_VERSION
|
|
||||||
CONFARGS=$(nginx -V 2>&1 | sed -n -e 's/^.*arguments: //p')
|
|
||||||
CONFARGS=${CONFARGS/-Os -fomit-frame-pointer -g/-Os}
|
|
||||||
./configure $CONFARGS --add-dynamic-module=/tmp/ModSecurity-nginx --add-dynamic-module=/tmp/headers-more-nginx-module --add-dynamic-module=/tmp/ngx_http_geoip2_module --add-dynamic-module=/tmp/nginx_cookie_flag_module --add-dynamic-module=/tmp/lua-nginx-module --add-dynamic-module=/tmp/ngx_brotli
|
|
||||||
make -j $NTASK modules
|
|
||||||
cp ./objs/*.so /usr/lib/nginx/modules
|
|
||||||
|
|
||||||
# remove build dependencies
|
|
||||||
apk del build
|
|
||||||
@ -91,7 +91,7 @@ elif [ "$OS" = "centos" ] ; then
|
|||||||
do_and_check_cmd yum install -y $CENTOS_DEPS
|
do_and_check_cmd yum install -y $CENTOS_DEPS
|
||||||
fi
|
fi
|
||||||
do_and_check_cmd pip3 install --upgrade pip
|
do_and_check_cmd pip3 install --upgrade pip
|
||||||
do_and_check_cmd pip3 install jinja2 certbot
|
do_and_check_cmd pip3 install jinja2 certbot docker requests flask gunicorn
|
||||||
do_and_check_cmd pip3 install cryptography --upgrade
|
do_and_check_cmd pip3 install cryptography --upgrade
|
||||||
|
|
||||||
# Clone the repo
|
# Clone the repo
|
||||||
@ -133,6 +133,11 @@ do_and_check_cmd cp -r /tmp/bunkerized-nginx/defaults /opt/bunkerized-nginx
|
|||||||
echo "[*] Copy settings"
|
echo "[*] Copy settings"
|
||||||
do_and_check_cmd cp /tmp/bunkerized-nginx/settings.json /opt/bunkerized-nginx
|
do_and_check_cmd cp /tmp/bunkerized-nginx/settings.json /opt/bunkerized-nginx
|
||||||
|
|
||||||
|
# Copy UI
|
||||||
|
echo "[*] Copy UI"
|
||||||
|
do_and_check_cmd cp -r /tmp/bunkerized-nginx/ui /opt/bunkerized-nginx
|
||||||
|
do_and_check_cmd cp /tmp/bunkerized-nginx/ui/bunkerized-nginx-ui.service /etc/systemd/system
|
||||||
|
|
||||||
# Copy bunkerized-nginx
|
# Copy bunkerized-nginx
|
||||||
echo "[*] Copy bunkerized-nginx"
|
echo "[*] Copy bunkerized-nginx"
|
||||||
do_and_check_cmd cp /tmp/bunkerized-nginx/helpers/bunkerized-nginx /usr/local/bin
|
do_and_check_cmd cp /tmp/bunkerized-nginx/helpers/bunkerized-nginx /usr/local/bin
|
||||||
@ -216,6 +221,9 @@ do_and_check_cmd chmod u+rx /opt
|
|||||||
do_and_check_cmd chown -R nginx:nginx /etc/nginx
|
do_and_check_cmd chown -R nginx:nginx /etc/nginx
|
||||||
do_and_check_cmd find /etc/nginx -type f -exec chmod 0774 {} \;
|
do_and_check_cmd find /etc/nginx -type f -exec chmod 0774 {} \;
|
||||||
do_and_check_cmd find /etc/nginx -type d -exec chmod 0775 {} \;
|
do_and_check_cmd find /etc/nginx -type d -exec chmod 0775 {} \;
|
||||||
|
# Set permissions for /etc/systemd/system/bunkerized-nginx-ui.service
|
||||||
|
do_and_check_cmd chown root:root /etc/systemd/system/bunkerized-nginx-ui.service
|
||||||
|
do_and_check_cmd chmod 744 /etc/systemd/system/bunkerized-nginx-ui.service
|
||||||
|
|
||||||
# Prepare log files and folders
|
# Prepare log files and folders
|
||||||
echo "[*] Prepare log files and folders"
|
echo "[*] Prepare log files and folders"
|
||||||
@ -228,19 +236,17 @@ fi
|
|||||||
if [ ! -e /var/log/nginx/error.log ] ; then
|
if [ ! -e /var/log/nginx/error.log ] ; then
|
||||||
do_and_check_cmd touch /var/log/nginx/error.log
|
do_and_check_cmd touch /var/log/nginx/error.log
|
||||||
fi
|
fi
|
||||||
|
if [ ! -e /var/log/nginx/modsec_audit.log ] ; then
|
||||||
|
do_and_check_cmd touch /var/log/nginx/modsec_audit.log
|
||||||
|
fi
|
||||||
if [ ! -e /var/log/nginx/jobs.log ] ; then
|
if [ ! -e /var/log/nginx/jobs.log ] ; then
|
||||||
do_and_check_cmd touch /var/log/nginx/jobs.log
|
do_and_check_cmd touch /var/log/nginx/jobs.log
|
||||||
fi
|
fi
|
||||||
do_and_check_cmd touch /var/log/nginx/modsec_audit.log
|
if [ ! -e /var/log/nginx/ui.log ] ; then
|
||||||
do_and_check_cmd touch /var/log/nginx/error.log
|
do_and_check_cmd touch /var/log/nginx/ui.log
|
||||||
|
fi
|
||||||
do_and_check_cmd chown -R root:nginx /var/log/nginx
|
do_and_check_cmd chown -R root:nginx /var/log/nginx
|
||||||
do_and_check_cmd chown root:nginx /var/log/nginx/access.log
|
do_and_check_cmd chmod -R 770 /var/log/nginx/
|
||||||
do_and_check_cmd chown root:nginx /var/log/nginx/error.log
|
|
||||||
do_and_check_cmd chown root:nginx /var/log/nginx/jobs.log
|
|
||||||
do_and_check_cmd chmod 770 /var/log/nginx/access.log
|
|
||||||
do_and_check_cmd chmod 770 /var/log/nginx/error.log
|
|
||||||
do_and_check_cmd chmod 770 /var/log/nginx/jobs.log
|
|
||||||
do_and_check_cmd chmod -R 770 /var/log/nginx
|
|
||||||
|
|
||||||
# Prepare Let's Encrypt files and folders
|
# Prepare Let's Encrypt files and folders
|
||||||
echo "[*] Prepare Let's Encrypt files and folders"
|
echo "[*] Prepare Let's Encrypt files and folders"
|
||||||
|
|||||||
@ -10,6 +10,10 @@ api_list["^/reload$"] = function ()
|
|||||||
return os.execute("/usr/sbin/nginx -s reload") == 0
|
return os.execute("/usr/sbin/nginx -s reload") == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
api_list["^/stop$"] = function ()
|
||||||
|
return os.execute("/usr/sbin/nginx -s quit") == 0
|
||||||
|
end
|
||||||
|
|
||||||
function M.is_api_call (api_uri, api_whitelist_ip)
|
function M.is_api_call (api_uri, api_whitelist_ip)
|
||||||
local whitelist = iputils.parse_cidrs(api_whitelist_ip)
|
local whitelist = iputils.parse_cidrs(api_whitelist_ip)
|
||||||
if iputils.ip_in_cidrs(ngx.var.remote_addr, whitelist) and ngx.var.request_uri:sub(1, #api_uri) .. "/" == api_uri .. "/" then
|
if iputils.ip_in_cidrs(ngx.var.remote_addr, whitelist) and ngx.var.request_uri:sub(1, #api_uri) .. "/" == api_uri .. "/" then
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import json, uuid, glob, copy, re, subprocess
|
|||||||
class Config :
|
class Config :
|
||||||
|
|
||||||
def __init__(self) :
|
def __init__(self) :
|
||||||
with open("/opt/settings.json", "r") as f :
|
with open("/opt/bunkerized-nginx/settings.json", "r") as f :
|
||||||
self.__settings = json.loads(f.read())
|
self.__settings = json.loads(f.read())
|
||||||
|
|
||||||
def __env_to_dict(self, filename) :
|
def __env_to_dict(self, filename) :
|
||||||
@ -37,7 +37,7 @@ class Config :
|
|||||||
conf["SERVER_NAME"] = " ".join(servers)
|
conf["SERVER_NAME"] = " ".join(servers)
|
||||||
env_file = "/tmp/" + str(uuid.uuid4()) + ".env"
|
env_file = "/tmp/" + str(uuid.uuid4()) + ".env"
|
||||||
self.__dict_to_env(env_file, conf)
|
self.__dict_to_env(env_file, conf)
|
||||||
proc = subprocess.run(["/bin/su", "-c", "/opt/gen/main.py --settings /opt/settings.json --templates /opt/confs --output /etc/nginx --variables " + env_file, "nginx"], capture_output=True)
|
proc = subprocess.run(["/opt/bunkerized-nginx/gen/main.py", "--settings", "/opt/bunkerized-nginx/settings.json", "--templates", "/opt/bunkerized-nginx/confs", "--output", "/etc/nginx", "--variables", env_file], capture_output=True)
|
||||||
stderr = proc.stderr.decode("ascii")
|
stderr = proc.stderr.decode("ascii")
|
||||||
#stdout = proc.stdout.decode("ascii")
|
#stdout = proc.stdout.decode("ascii")
|
||||||
if stderr != "" or proc.returncode != 0 :
|
if stderr != "" or proc.returncode != 0 :
|
||||||
|
|||||||
@ -5,11 +5,11 @@ RUN chmod +x /tmp/dependencies.sh && \
|
|||||||
/tmp/dependencies.sh && \
|
/tmp/dependencies.sh && \
|
||||||
rm -f /tmp/dependencies.sh
|
rm -f /tmp/dependencies.sh
|
||||||
|
|
||||||
COPY gen/ /opt/gen
|
COPY gen/ /opt/bunkerized-nginx/gen
|
||||||
COPY confs/site/ /opt/confs/site
|
COPY confs/site/ /opt/bunkerized-nginx/confs/site
|
||||||
COPY confs/global/ /opt/confs/global
|
COPY confs/global/ /opt/bunkerized-nginx/confs/global
|
||||||
COPY ui/ /opt/entrypoint
|
COPY ui/ /opt/bunkerized-nginx/ui
|
||||||
COPY settings.json /opt
|
COPY settings.json /opt/bunkerized-nginx
|
||||||
|
|
||||||
COPY ui/prepare.sh /tmp
|
COPY ui/prepare.sh /tmp
|
||||||
RUN chmod +x /tmp/prepare.sh && \
|
RUN chmod +x /tmp/prepare.sh && \
|
||||||
@ -18,6 +18,6 @@ RUN chmod +x /tmp/prepare.sh && \
|
|||||||
|
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
|
||||||
WORKDIR /opt/entrypoint
|
WORKDIR /opt/bunkerized-nginx/ui
|
||||||
ENV FLASK_APP entrypoint.py
|
USER nginx:nginx
|
||||||
ENTRYPOINT ["/usr/bin/python3", "-m", "flask", "run", "--host=0.0.0.0"]
|
ENTRYPOINT ["/usr/bin/gunicorn", "--bind", "unix:bunkerized-nginx-ui.sock", "-m", "007", "wsgi:app"]
|
||||||
12
ui/bunkerized-nginx-ui.service
Normal file
12
ui/bunkerized-nginx-ui.service
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Web UI for bunkerized-nginx
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=nginx
|
||||||
|
Group=nginx
|
||||||
|
WorkingDirectory=/opt/bunkerized-nginx/ui
|
||||||
|
ExecStart=gunicorn --bind unix:bunkerized-nginx-ui.sock -m 007 wsgi:app
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
apk add py3-pip bash
|
apk add py3-pip bash
|
||||||
pip3 install docker flask flask-login
|
pip3 install docker flask flask-login requests gunicorn
|
||||||
|
|||||||
@ -2,20 +2,18 @@
|
|||||||
|
|
||||||
from flask import Flask, render_template, current_app, request
|
from flask import Flask, render_template, current_app, request
|
||||||
|
|
||||||
|
from src.Instances import Instances
|
||||||
|
|
||||||
from Docker import Docker
|
from Docker import Docker
|
||||||
from Config import Config
|
from Config import Config
|
||||||
import utils
|
import utils
|
||||||
import os, json, re, copy, traceback
|
import os, json, re, copy, traceback
|
||||||
|
|
||||||
app = Flask(__name__, static_url_path="/", static_folder="static", template_folder="templates")
|
app = Flask(__name__, static_url_path="/", static_folder="static", template_folder="templates")
|
||||||
ABSOLUTE_URI = ""
|
|
||||||
if "ABSOLUTE_URI" in os.environ :
|
vars = utils.get_variables()
|
||||||
ABSOLUTE_URI = os.environ["ABSOLUTE_URI"]
|
app.config["ABSOLUTE_URI"] = vars["ABSOLUTE_URI"]
|
||||||
DOCKER_HOST = "unix:///var/run/docker.sock"
|
app.config["INSTANCES"] = Instances(vars["DOCKER_HOST"], vars["API_URI"])
|
||||||
if "DOCKER_HOST" in os.environ :
|
|
||||||
DOCKER_HOST = os.environ["DOCKER_HOST"]
|
|
||||||
app.config["ABSOLUTE_URI"] = ABSOLUTE_URI
|
|
||||||
app.config["DOCKER"] = Docker(DOCKER_HOST)
|
|
||||||
app.config["CONFIG"] = Config()
|
app.config["CONFIG"] = Config()
|
||||||
app.jinja_env.globals.update(env_to_summary_class=utils.env_to_summary_class)
|
app.jinja_env.globals.update(env_to_summary_class=utils.env_to_summary_class)
|
||||||
app.jinja_env.globals.update(form_service_gen=utils.form_service_gen)
|
app.jinja_env.globals.update(form_service_gen=utils.form_service_gen)
|
||||||
@ -26,7 +24,7 @@ app.jinja_env.globals.update(form_service_gen_multiple_values=utils.form_service
|
|||||||
@app.route('/home')
|
@app.route('/home')
|
||||||
def home() :
|
def home() :
|
||||||
try :
|
try :
|
||||||
instances_number = len(app.config["DOCKER"].get_instances())
|
instances_number = len(app.config["INSTANCES"].get_instances())
|
||||||
services_number = len(app.config["CONFIG"].get_services())
|
services_number = len(app.config["CONFIG"].get_services())
|
||||||
return render_template("home.html", title="Home", instances_number=instances_number, services_number=services_number)
|
return render_template("home.html", title="Home", instances_number=instances_number, services_number=services_number)
|
||||||
except Exception as e :
|
except Exception as e :
|
||||||
@ -40,7 +38,7 @@ def instances() :
|
|||||||
if request.method == "POST" :
|
if request.method == "POST" :
|
||||||
|
|
||||||
# Check operation
|
# Check operation
|
||||||
if not "operation" in request.form or not request.form["operation"] in ["reload", "start", "stop", "restart", "delete"] :
|
if not "operation" in request.form or not request.form["operation"] in ["reload", "start", "stop", "restart"] :
|
||||||
raise Exception("Missing operation parameter on /instances.")
|
raise Exception("Missing operation parameter on /instances.")
|
||||||
|
|
||||||
# Check that all fields are present
|
# Check that all fields are present
|
||||||
@ -49,18 +47,16 @@ def instances() :
|
|||||||
|
|
||||||
# Do the operation
|
# Do the operation
|
||||||
if request.form["operation"] == "reload" :
|
if request.form["operation"] == "reload" :
|
||||||
operation = app.config["DOCKER"].reload_instance(request.form["INSTANCE_ID"])
|
operation = app.config["INSTANCES"].reload_instance(request.form["INSTANCE_ID"])
|
||||||
elif request.form["operation"] == "start" :
|
elif request.form["operation"] == "start" :
|
||||||
operation = app.config["DOCKER"].start_instance(request.form["INSTANCE_ID"])
|
operation = app.config["INSTANCES"].start_instance(request.form["INSTANCE_ID"])
|
||||||
elif request.form["operation"] == "stop" :
|
elif request.form["operation"] == "stop" :
|
||||||
operation = app.config["DOCKER"].stop_instance(request.form["INSTANCE_ID"])
|
operation = app.config["INSTANCES"].stop_instance(request.form["INSTANCE_ID"])
|
||||||
elif request.form["operation"] == "restart" :
|
elif request.form["operation"] == "restart" :
|
||||||
operation = app.config["DOCKER"].restart_instance(request.form["INSTANCE_ID"])
|
operation = app.config["INSTANCES"].restart_instance(request.form["INSTANCE_ID"])
|
||||||
elif request.form["operation"] == "delete" :
|
|
||||||
operation = app.config["DOCKER"].delete_instance(request.form["INSTANCE_ID"])
|
|
||||||
|
|
||||||
# Display instances
|
# Display instances
|
||||||
instances = app.config["DOCKER"].get_instances()
|
instances = app.config["INSTANCES"].get_instances()
|
||||||
return render_template("instances.html", title="Instances", instances=instances, operation=operation)
|
return render_template("instances.html", title="Instances", instances=instances, operation=operation)
|
||||||
|
|
||||||
except Exception as e :
|
except Exception as e :
|
||||||
|
|||||||
@ -8,7 +8,10 @@ adduser -h /var/cache/nginx -g nginx -s /bin/sh -G nginx -D -H -u 101 nginx
|
|||||||
chown -R root:nginx /opt
|
chown -R root:nginx /opt
|
||||||
find /opt -type f -exec chmod 0740 {} \;
|
find /opt -type f -exec chmod 0740 {} \;
|
||||||
find /opt -type d -exec chmod 0750 {} \;
|
find /opt -type d -exec chmod 0750 {} \;
|
||||||
chmod ugo+x /opt/entrypoint/*
|
chmod 750 /opt/bunkerized-nginx/gen/main.py
|
||||||
chmod ugo+x /opt/gen/main.py
|
|
||||||
chmod 770 /opt
|
# prepare /var/log
|
||||||
chmod 440 /opt/settings.json
|
mkdir /var/log/nginx
|
||||||
|
chown root:nginx /var/log/nginx
|
||||||
|
chmod 750 /var/log/nginx
|
||||||
|
ln -s /proc/1/fd/1 /var/log/nginx/ui.log
|
||||||
@ -2,15 +2,16 @@ import docker, os, requests
|
|||||||
|
|
||||||
class Instances :
|
class Instances :
|
||||||
|
|
||||||
def __init__(self, docker_host, api) :
|
def __init__(self, docker_host, api_uri) :
|
||||||
try :
|
try :
|
||||||
self.__docker = docker.DockerClient(base_url=docker_host)
|
self.__docker = docker.DockerClient(base_url=docker_host)
|
||||||
except :
|
except :
|
||||||
self.__docker = None
|
self.__docker = None
|
||||||
self.__api = api
|
self.__api_uri = api_uri
|
||||||
|
|
||||||
def __instance(self, name, type, status, data=None) :
|
def __instance(self, id, name, type, status, data=None) :
|
||||||
instance = {}
|
instance = {}
|
||||||
|
instance["id"] = id
|
||||||
instance["name"] = name
|
instance["name"] = name
|
||||||
instance["type"] = type
|
instance["type"] = type
|
||||||
instance["status"] = status
|
instance["status"] = status
|
||||||
@ -27,7 +28,7 @@ class Instances :
|
|||||||
hosts.append(host)
|
hosts.append(host)
|
||||||
for host in hosts :
|
for host in hosts :
|
||||||
try :
|
try :
|
||||||
req = requests.post("http://" + host + ":8080" + self.__api + order)
|
req = requests.post("http://" + host + ":8080" + self.__api_uri + order)
|
||||||
if not req or req.status_code != 200 or req.text != "ok" :
|
if not req or req.status_code != 200 or req.text != "ok" :
|
||||||
result = False
|
result = False
|
||||||
except :
|
except :
|
||||||
@ -40,14 +41,16 @@ class Instances :
|
|||||||
if self.__docker != None :
|
if self.__docker != None :
|
||||||
if self.__docker.swarm == None :
|
if self.__docker.swarm == None :
|
||||||
for instance in self.__docker.containers.list(all=True, filters={"label" : "bunkerized-nginx.UI"}) :
|
for instance in self.__docker.containers.list(all=True, filters={"label" : "bunkerized-nginx.UI"}) :
|
||||||
|
id = instance.id
|
||||||
name = instance.name
|
name = instance.name
|
||||||
type = "container"
|
type = "container"
|
||||||
status = "down"
|
status = "down"
|
||||||
if instance.status == "running" :
|
if instance.status == "running" :
|
||||||
status = "up"
|
status = "up"
|
||||||
instances.append(self.__instance(name, type, status, instance))
|
instances.append(self.__instance(id, name, type, status, instance))
|
||||||
else :
|
else :
|
||||||
for instance in self.__docker.services.list(all=True, filters={"label" : "bunkerized-nginx.UI"}) :
|
for instance in self.__docker.services.list(all=True, filters={"label" : "bunkerized-nginx.UI"}) :
|
||||||
|
id = instance.id
|
||||||
name = instance.name
|
name = instance.name
|
||||||
type = "service"
|
type = "service"
|
||||||
status = "down"
|
status = "down"
|
||||||
@ -55,16 +58,17 @@ class Instances :
|
|||||||
running_tasks = instance.attrs["ServiceStatus"]["RunningTasks"]
|
running_tasks = instance.attrs["ServiceStatus"]["RunningTasks"]
|
||||||
if desired_tasks > 0 and (desired_tasks == running_tasks) :
|
if desired_tasks > 0 and (desired_tasks == running_tasks) :
|
||||||
status = "up"
|
status = "up"
|
||||||
instances.append(self.__instance(name, type, status, instance))
|
instances.append(self.__instance(id, name, type, status, instance))
|
||||||
|
|
||||||
# Local instance
|
# Local instance
|
||||||
if os.path.exists("/usr/sbin/nginx") :
|
if os.path.exists("/usr/sbin/nginx") :
|
||||||
|
id = "local"
|
||||||
name = "local"
|
name = "local"
|
||||||
type = "local"
|
type = "local"
|
||||||
status = "down"
|
status = "down"
|
||||||
if os.path.exists("/tmp/nginx.pid") :
|
if os.path.exists("/tmp/nginx.pid") :
|
||||||
status = "up"
|
status = "up"
|
||||||
instances.append(self.__instance(name, type, status))
|
instances.append(self.__instance(id, name, type, status))
|
||||||
|
|
||||||
return instances
|
return instances
|
||||||
|
|
||||||
@ -99,7 +103,7 @@ class Instances :
|
|||||||
proc = subprocess.run(["/usr/sbin/nginx", "-g", "daemon on;"], capture_output=True)
|
proc = subprocess.run(["/usr/sbin/nginx", "-g", "daemon on;"], capture_output=True)
|
||||||
result = proc.returncode == 0
|
result = proc.returncode == 0
|
||||||
elif instance["type"] == "container" or instance["type"] == "service" :
|
elif instance["type"] == "container" or instance["type"] == "service" :
|
||||||
result = self.__api_request(instance, "/start")
|
result = False #self.__api_request(instance, "/start")
|
||||||
if result :
|
if result :
|
||||||
return "Instance " + instance["name"] + " has been started."
|
return "Instance " + instance["name"] + " has been started."
|
||||||
return "Can't start " + instance["name"]
|
return "Can't start " + instance["name"]
|
||||||
@ -123,7 +127,7 @@ class Instances :
|
|||||||
proc = subprocess.run(["/usr/sbin/nginx", "-g", "daemon on;"], capture_output=True)
|
proc = subprocess.run(["/usr/sbin/nginx", "-g", "daemon on;"], capture_output=True)
|
||||||
result = proc.returncode == 0
|
result = proc.returncode == 0
|
||||||
elif instance["type"] == "container" or instance["type"] == "service" :
|
elif instance["type"] == "container" or instance["type"] == "service" :
|
||||||
result = self.__api_request(instance, "/restart")
|
result = False #self.__api_request(instance, "/restart")
|
||||||
if result :
|
if result :
|
||||||
return "Instance " + instance["name"] + " has been restarted."
|
return "Instance " + instance["name"] + " has been restarted."
|
||||||
return "Can't restart " + instance["name"]
|
return "Can't restart " + instance["name"]
|
||||||
@ -17,11 +17,9 @@
|
|||||||
|
|
||||||
{% for instance in instances %}
|
{% for instance in instances %}
|
||||||
{% set color = "dark" %}
|
{% set color = "dark" %}
|
||||||
{% if instance["status"] == "running" %}
|
{% if instance["status"] == "up" %}
|
||||||
{% set color = "success" %}
|
{% set color = "success" %}
|
||||||
{% elif instance["status"] == "created" or instance["status"] == "restarting" or instance["status"] == "paused" %}
|
{% elif instance["status"] == "down" %}
|
||||||
{% set color = "warning" %}
|
|
||||||
{% elif instance["status"] == "exited" or instance["status"] == "dead" %}
|
|
||||||
{% set color = "danger" %}
|
{% set color = "danger" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -34,27 +32,20 @@
|
|||||||
{{ instance["name"] }}
|
{{ instance["name"] }}
|
||||||
<div class="btn-group mx-2 float-end" role="group">
|
<div class="btn-group mx-2 float-end" role="group">
|
||||||
<button id="btnGroupDrop1" class="btn btn-sm dropdown-toggle btn-light" data-bs-toggle="dropdown" aria-expanded="false">
|
<button id="btnGroupDrop1" class="btn btn-sm dropdown-toggle btn-light" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<i class="fas fa-cogs"> manage container</i>
|
<i class="fas fa-cogs"> manage instance</i>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
|
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
|
||||||
<li><a class="dropdown-item" href="#" onClick="return startInstance('{{ instance["id"] }}');">Start</a></li>
|
{% if instance["type"] == "local" %}<li><a class="dropdown-item" href="#" onClick="return startInstance('{{ instance["id"] }}');">Start</a></li>{% endif %}
|
||||||
<li><a class="dropdown-item" href="#" onClick="return stopInstance('{{ instance["id"] }}');">Stop</a></li>
|
<li><a class="dropdown-item" href="#" onClick="return stopInstance('{{ instance["id"] }}');">Stop</a></li>
|
||||||
<li><a class="dropdown-item" href="#" onClick="return restartInstance('{{ instance["id"] }}');">Restart</a></li>
|
{% if instance["type"] == "local" %}<li><a class="dropdown-item" href="#" onClick="return restartInstance('{{ instance["id"] }}');">Restart</a></li>{% endif %}
|
||||||
<li><a class="dropdown-item" href="#" onClick="return deleteInstance('{{ instance["id"] }}');">Delete</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-sm mx-2 float-end btn-light" onClick="reloadInstance('{{ instance["id"] }}');"><i class="fas fa-redo-alt"></i> reload nginx</button>
|
<button class="btn btn-sm mx-2 float-end btn-light" onClick="reloadInstance('{{ instance["id"] }}');"><i class="fas fa-redo-alt"></i> Reload configuration</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body text-dark">
|
<div class="card-body text-dark">
|
||||||
<h5 class="card-title">Status : {{ instance["status"] }}</h5>
|
<h5 class="card-title">Status : {{ instance["status"] }}</h5>
|
||||||
<span class="card-text">
|
<span class="card-text">
|
||||||
Environment variables :<br />
|
TODO
|
||||||
{% set envfilter = ["PATH", "NGINX_VERSION", "NJS_VERSION", "PKG_RELEASE"] %}
|
|
||||||
{% for env in instance.attrs["Config"]["Env"] %}
|
|
||||||
{% if not env.startswith("PATH=") and not env.startswith("NGINX_VERSION=") and not env.startswith("NJS_VERSION=") and not env.startswith("PKG_RELEASE=") %}
|
|
||||||
{{ env }}<br />
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
15
ui/utils.py
15
ui/utils.py
@ -1,9 +1,20 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import datetime, re, json
|
import datetime, re, json, os
|
||||||
|
|
||||||
|
def get_variables() :
|
||||||
|
vars = {}
|
||||||
|
vars["DOCKER_HOST"] = "unix:///var/run/docker.sock"
|
||||||
|
vars["API_URI"] = ""
|
||||||
|
vars["ABSOLUTE_URI"] = ""
|
||||||
|
for k in vars :
|
||||||
|
if k in os.environ :
|
||||||
|
vars[k] = os.environ[k]
|
||||||
|
return vars
|
||||||
|
|
||||||
def log(event) :
|
def log(event) :
|
||||||
print("[" + str(datetime.datetime.now().replace(microsecond=0)) + "] " + event, flush=True)
|
with open("/var/log/nginx/ui.log", "a") as f :
|
||||||
|
f.write("[" + str(datetime.datetime.now().replace(microsecond=0)) + "] " + event + "\n")
|
||||||
|
|
||||||
def env_to_summary_class(var, value) :
|
def env_to_summary_class(var, value) :
|
||||||
if type(var) is list and type(value) is list :
|
if type(var) is list and type(value) is list :
|
||||||
|
|||||||
4
ui/wsgi.py
Normal file
4
ui/wsgi.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
from entrypoint import app
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run()
|
||||||
Loading…
x
Reference in New Issue
Block a user