Merge pull request #1235 from bunkerity/dev

Merge branch "dev" into branch "staging"
This commit is contained in:
Théophile Diot 2024-06-03 13:24:12 +01:00 committed by GitHub
commit 6ae24726e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
53 changed files with 371 additions and 386 deletions

View file

@ -35,12 +35,12 @@ jobs:
python -m pip install --no-cache-dir --require-hashes -r src/common/db/requirements.txt
echo "CODEQL_PYTHON=$(which python)" >> $GITHUB_ENV
- name: Initialize CodeQL
uses: github/codeql-action/init@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
uses: github/codeql-action/init@f079b8493333aace61c81488f8bd40919487bd9f # v3.25.7
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql.yml
setup-python-dependencies: false
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
uses: github/codeql-action/analyze@f079b8493333aace61c81488f8bd40919487bd9f # v3.25.7
with:
category: "/language:${{matrix.language}}"

View file

@ -25,6 +25,6 @@ jobs:
results_format: sarif
publish_results: true
- name: "Upload SARIF results to code scanning"
uses: github/codeql-action/upload-sarif@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
uses: github/codeql-action/upload-sarif@f079b8493333aace61c81488f8bd40919487bd9f # v3.25.7
with:
sarif_file: results.sarif

View file

@ -69,7 +69,7 @@ jobs:
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo -E apt install -y nginx=1.26.0-1~noble
sudo -E apt install -y nginx=1.26.1-2~noble
- name: Fix version without a starting number
if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev'
run: echo "force-bad-version" | sudo tee -a /etc/dpkg/dpkg.cfg

View file

@ -69,7 +69,7 @@ jobs:
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo -E apt install -y nginx=1.26.0-1~noble
sudo -E apt install -y nginx=1.26.1-2~noble
- name: Fix version without a starting number
if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' || inputs.RELEASE == 'ui'
run: echo "force-bad-version" | sudo tee -a /etc/dpkg/dpkg.cfg

View file

@ -19,8 +19,8 @@
- [UI] Add OVERRIDE_ADMIN_CREDS environment variable to allow overriding the default admin credentials even if an admin user already exists
- [UI] Optimize the way the UI handles the requests and the responses
- [MISC] Update logger format and datefmt for better readability
- [DEPS] Updated NGINX version to v1.26.0
- [DEPS] Updated stream-lua-nginx-module version to the latest commit to incorporate the latest changes and fixes for NGINX v1.26.0
- [DEPS] Updated NGINX version to v1.26.1 (except fedora as it is not available yet, so it is v1.26.0)
- [DEPS] Updated stream-lua-nginx-module version to the latest commit to incorporate the latest changes and fixes for NGINX v1.26
- [DEPS] Updated coreruleset-v4 version to v4.3.0
- [DEPS] Updated lua-resty-openssl version to v1.4.0

View file

@ -320,7 +320,7 @@ Supported Linux distributions for BunkerWeb (amd64/x86_64 and arm64/aarch64 arch
- Red Hat Enterprise Linux (RHEL) 8.9
- Red Hat Enterprise Linux (RHEL) 9.4
Please ensure that you have **NGINX 1.26.0 installed before installing BunkerWeb**. For all distributions, except Fedora, it is mandatory to use prebuilt packages from the [official NGINX repository](https://nginx.org/en/linux_packages.html). Compiling NGINX from source or using packages from different repositories will not work with the official prebuilt packages of BunkerWeb. However, you have the option to build BunkerWeb from source.
Please ensure that you have **NGINX 1.26.1 installed before installing BunkerWeb**. For all distributions, except Fedora, it is mandatory to use prebuilt packages from the [official NGINX repository](https://nginx.org/en/linux_packages.html). Compiling NGINX from source or using packages from different repositories will not work with the official prebuilt packages of BunkerWeb. However, you have the option to build BunkerWeb from source.
To simplify the installation process, Linux package repositories for BunkerWeb are available on [PackageCloud](https://packagecloud.io/bunkerity/bunkerweb). They provide a bash script that automatically adds and trusts the repository. You can follow the provided script for automatic setup, or opt for [manual installation](https://packagecloud.io/bunkerity/bunkerweb/install) instructions if you prefer.
@ -337,11 +337,11 @@ To simplify the installation process, Linux package repositories for BunkerWeb a
| sudo tee /etc/apt/sources.list.d/nginx.list
```
You should now be able to install NGINX 1.26.0 :
You should now be able to install NGINX 1.26.1 :
```shell
sudo apt update && \
sudo apt install -y nginx=1.26.0-1~$(lsb_release -cs)
sudo apt install -y nginx=1.26.1-2~$(lsb_release -cs)
```
!!! warning "Testing/dev version"
@ -384,11 +384,11 @@ To simplify the installation process, Linux package repositories for BunkerWeb a
| sudo tee /etc/apt/sources.list.d/nginx.list
```
You should now be able to install NGINX 1.26.0 :
You should now be able to install NGINX 1.26.1 :
```shell
sudo apt update && \
sudo apt install -y nginx=1.26.0-1~$(lsb_release -cs)
sudo apt install -y nginx=1.26.1-2~$(lsb_release -cs)
```
!!! warning "Testing/dev version"
@ -420,6 +420,9 @@ To simplify the installation process, Linux package repositories for BunkerWeb a
=== "Fedora"
!!! info "NGINX 1.26.1"
Fedora does not provide NGINX 1.26.1 in its official repositories therefore we need to install the 1.26.0 version.
Fedora already provides NGINX 1.26.0 that we support :
```shell
@ -471,10 +474,10 @@ To simplify the installation process, Linux package repositories for BunkerWeb a
module_hotfixes=true
```
You should now be able to install NGINX 1.26.0 :
You should now be able to install NGINX 1.26.1 :
```shell
sudo dnf install nginx-1.26.0
sudo dnf install nginx-1.26.1
```
Optional step : if you want to automatically enable the [setup wizard](web-ui.md#setup-wizard) when BunkerWeb is installed, export the following variable :

View file

@ -137,7 +137,7 @@ Besides the HTTPS / SSL/TLS configuration, the following settings related to HTT
| `AUTO_REDIRECT_HTTP_TO_HTTPS` | `yes` | When set to `yes`, will redirect every HTTP request to HTTPS only if BunkerWeb is configured with HTTPS. |
| `SSL_PROTOCOLS` | `TLSv1.2 TLSv1.3` | List of supported SSL/TLS protocols when SSL is enabled. |
| `HTTP2` | `yes` | When set to `yes`, will enable HTTP2 protocol support when using HTTPS. |
| `HTTP3` | `yes` | When set to `yes`, will enable HTTP3 protocol support when using HTTPS. |
| `HTTP3` | `no` | When set to `yes`, will enable HTTP3 protocol support when using HTTPS. |
| `HTTP3_ALT_SVC_PORT` | `443` | HTTP3 alternate service port. This value will be used as part of the Alt-Svc header. |
| `LISTEN_HTTP` | `yes` | When set to `no`, BunkerWeb will not listen for HTTP requests. Useful if you want HTTPS only for example. |

View file

@ -4,13 +4,13 @@ from contextlib import suppress
from os import getenv
from time import sleep
from copy import deepcopy
from typing import Any, Dict, List, Optional
from ConfigCaller import ConfigCaller # type: ignore
from Database import Database # type: ignore
from logger import setup_logger # type: ignore
class Config(ConfigCaller):
class Config:
def __init__(self):
super().__init__()
self.__logger = setup_logger("Config", getenv("LOG_LEVEL", "INFO"))
@ -40,48 +40,64 @@ class Config(ConfigCaller):
self._settings.update(plugin["settings"])
def __get_full_env(self) -> dict:
env_instances = {"SERVER_NAME": ""}
for instance in self.__instances:
for variable, value in instance["env"].items():
env_instances[variable] = value
env_services = {}
config = {"SERVER_NAME": "", "MULTISITE": "yes"}
for service in self.__services:
server_name = service["SERVER_NAME"].split(" ")[0]
if not server_name:
continue
for variable, value in service.items():
env_services[f"{server_name}_{variable}"] = value
env_instances["SERVER_NAME"] += f" {server_name}"
env_instances["SERVER_NAME"] = env_instances["SERVER_NAME"].strip()
return self._full_env(env_instances, env_services)
if self._db.is_setting(variable, multisite=True):
config[f"{server_name}_{variable}"] = value
config["SERVER_NAME"] += f" {server_name}"
config["SERVER_NAME"] = config["SERVER_NAME"].strip()
return config
def update_needed(self, instances, services, configs={}) -> bool:
def update_needed(self, instances: List[Dict[str, Any]], services: List[Dict[str, str]], configs: Optional[Dict[str, Dict[str, bytes]]] = None) -> bool:
if instances != self.__instances:
return True
elif services != self.__services:
return True
elif configs != self.__configs:
elif (configs or {}) != self.__configs:
return True
return False
def wait_applying(self):
def have_to_wait(self) -> bool:
curr_changes = self._db.check_changes()
return isinstance(curr_changes, str) or any(curr_changes.values())
def wait_applying(self, startup: bool = False):
i = 0
while i < 10:
curr_changes = self._db.check_changes()
if isinstance(curr_changes, str):
self.__logger.error(f"An error occurred when checking for changes in the database : {curr_changes}")
if not startup:
self.__logger.error(f"An error occurred when checking for changes in the database : {curr_changes}")
elif not any(curr_changes.values()):
break
else:
self.__logger.warning(
"Scheduler is already applying a configuration, retrying in 5 seconds ...",
)
self.__logger.warning("Scheduler is already applying a configuration, retrying in 5 seconds ...")
i += 1
sleep(5)
if i >= 10:
if i >= 60:
raise Exception("Too many retries while waiting for scheduler to apply configuration...")
def apply(self, instances, services, configs={}, first=False) -> bool:
def apply(
self, instances: List[Dict[str, Any]], services: List[Dict[str, str]], configs: Optional[Dict[str, Dict[str, bytes]]] = None, first: bool = False
) -> bool:
success = True
err = self._try_database_readonly()
if err:
return False
while not self._db.is_initialized():
self.__logger.warning("Database is not initialized, retrying in 5 seconds ...")
sleep(5)
self.wait_applying()
configs = configs or {}
changes = []
if instances != self.__instances or first:
self.__instances = instances
@ -112,33 +128,10 @@ class Config(ConfigCaller):
custom_configs.append(
{
"value": data,
"exploded": [
site,
config_type,
name.replace(".conf", ""),
],
"exploded": [site, config_type, name.replace(".conf", "")],
}
)
err = self._try_database_readonly()
if err:
return False
while not self._db.is_initialized():
self.__logger.warning("Database is not initialized, retrying in 5 seconds ...")
sleep(5)
# wait until changes are applied
while True:
curr_changes = self._db.check_changes()
if isinstance(curr_changes, str):
self.__logger.error(f"An error occurred when checking for changes in the database : {curr_changes}")
elif not any(curr_changes.values()):
break
else:
self.__logger.warning("Scheduler is already applying a configuration, retrying in 5 seconds ...")
sleep(5)
# update instances in database
if "instances" in changes:
err = self._db.update_instances(self.__instances, changed=False)

View file

@ -66,25 +66,21 @@ class Controller(Config):
def _to_services(self, controller_service):
pass
@abstractmethod
def _get_static_services(self):
pass
def _set_autoconf_load_db(self):
if not self._loaded:
ret = self._db.set_autoconf_load(True)
if ret:
self._logger.warning(
f"Can't set autoconf loaded metadata to true in database: {ret}",
)
self._logger.warning(f"Can't set autoconf loaded metadata to true in database: {ret}")
else:
self._loaded = True
def get_services(self):
while not self._get_controller_services():
sleep(1)
services = []
for controller_service in self._get_controller_services():
services.extend(self._to_services(controller_service))
services.extend(self._get_static_services())
return services
@abstractmethod

View file

@ -1,5 +1,6 @@
#!/usr/bin/env python3
from time import sleep
from typing import Any, Dict, List
from docker import DockerClient
from re import compile as re_compile
@ -30,8 +31,7 @@ class DockerController(Controller):
for env in controller_instance.attrs["Config"]["Env"]:
variable = env.split("=")[0]
value = env.replace(f"{variable}=", "", 1)
if self._is_setting(variable):
instance["env"][variable] = value
instance["env"][variable] = value
return [instance]
def _to_services(self, controller_service) -> List[dict]:
@ -39,35 +39,9 @@ class DockerController(Controller):
for variable, value in controller_service.labels.items():
if not variable.startswith("bunkerweb."):
continue
real_variable = variable.replace("bunkerweb.", "", 1)
if not self._is_setting_context(real_variable, "multisite"):
continue
service[real_variable] = value
service[variable.replace("bunkerweb.", "", 1)] = value
return [service]
def _get_static_services(self) -> List[dict]:
services = []
variables = {}
for instance in self.__client.containers.list(filters={"label": "bunkerweb.INSTANCE"}):
if not instance.attrs or not instance.attrs.get("Config", {}).get("Env"):
continue
for env in instance.attrs["Config"]["Env"]:
variable = env.split("=")[0]
value = env.replace(f"{variable}=", "", 1)
variables[variable] = value
if "SERVER_NAME" in variables and variables["SERVER_NAME"].strip():
for server_name in variables["SERVER_NAME"].strip().split(" "):
service = {"SERVER_NAME": server_name}
for variable, value in variables.items():
prefix = variable.split("_")[0]
real_variable = variable.replace(f"{prefix}_", "", 1)
if prefix == server_name and self._is_setting_context(real_variable, "multisite"):
service[real_variable] = value
services.append(service)
return services
def get_configs(self) -> Dict[str, Dict[str, Any]]:
configs = {config_type: {} for config_type in self._supported_config_types}
# get site configs from labels
@ -85,9 +59,7 @@ class DockerController(Controller):
# check if server_name exists
if not self._is_service_present(server_name):
self._logger.warning(
f"Ignoring config because {server_name} doesn't exist",
)
self._logger.warning(f"Ignoring config because {server_name} doesn't exist")
continue
for variable, value in labels.items():
@ -117,24 +89,34 @@ class DockerController(Controller):
def process_events(self):
self._set_autoconf_load_db()
for event in self.__client.events(decode=True, filters={"type": "container"}):
applied = False
try:
if not self.__process_event(event):
continue
self.wait_applying()
self._update_settings()
self._instances = self.get_instances()
self._services = self.get_services()
self._configs = self.get_configs()
if not self.update_needed(self._instances, self._services, configs=self._configs):
continue
self._logger.info("Caught Docker event, deploying new configuration ...")
if not self.apply_config():
self._logger.error("Error while deploying new configuration")
else:
self._logger.info(
"Successfully deployed new configuration 🚀",
)
to_apply = False
while not applied:
waiting = self.have_to_wait()
self._update_settings()
self._instances = self.get_instances()
self._services = self.get_services()
self._configs = self.get_configs()
self._set_autoconf_load_db()
if not to_apply and not self.update_needed(self._instances, self._services, configs=self._configs):
applied = True
continue
to_apply = True
if waiting:
sleep(1)
continue
self._logger.info("Caught Docker event, deploying new configuration ...")
if not self.apply_config():
self._logger.error("Error while deploying new configuration")
else:
self._logger.info("Successfully deployed new configuration 🚀")
self._set_autoconf_load_db()
applied = True
except:
self._logger.error(f"Exception while processing events :\n{format_exc()}")

View file

@ -55,9 +55,7 @@ class IngressController(Controller):
) in controller_service.metadata.annotations.items():
if not annotation.startswith("bunkerweb.io/"):
continue
variable = annotation.replace("bunkerweb.io/", "", 1)
if self._is_setting(variable):
instance["env"][variable] = value
instance["env"][annotation.replace("bunkerweb.io/", "", 1)] = value
return [instance]
def _get_controller_services(self) -> list:
@ -139,9 +137,7 @@ class IngressController(Controller):
server_name = service["SERVER_NAME"].strip().split(" ")[0]
if not variable.startswith(f"{server_name}_"):
continue
variable = variable.replace(f"{server_name}_", "", 1)
if self._is_setting_context(variable, "multisite"):
service[variable] = value
service[variable.replace(f"{server_name}_", "", 1)] = value
# parse tls
if controller_service.spec.tls:
@ -175,34 +171,6 @@ class IngressController(Controller):
service["CUSTOM_SSL_KEY_DATA"] = secret_tls.data["tls.key"]
return services
def _get_static_services(self) -> List[dict]:
services = []
variables = {}
for instance in self.__corev1.list_pod_for_all_namespaces(watch=False).items:
if not instance.metadata.annotations or "bunkerweb.io/INSTANCE" not in instance.metadata.annotations:
continue
pod = None
for container in instance.spec.containers:
if container.name == "bunkerweb":
pod = container
break
if not pod:
continue
variables = {env.name: env.value or "" for env in pod.env}
if "SERVER_NAME" in variables and variables["SERVER_NAME"].strip():
for server_name in variables["SERVER_NAME"].strip().split(" "):
service = {"SERVER_NAME": server_name}
for variable, value in variables.items():
prefix = variable.split("_")[0]
real_variable = variable.replace(f"{prefix}_", "", 1)
if prefix == server_name and self._is_setting_context(real_variable, "multisite"):
service[real_variable] = value
services.append(service)
return services
def get_configs(self) -> dict:
configs = {config_type: {} for config_type in self._supported_config_types}
for configmap in self.__corev1.list_config_map_for_all_namespaces(watch=False).items:
@ -270,42 +238,49 @@ class IngressController(Controller):
while True:
locked = False
error = False
applied = False
try:
for event in w.stream(what):
applied = False
self.__internal_lock.acquire()
locked = True
if not self.__process_event(event):
self.__internal_lock.release()
locked = False
continue
self.wait_applying()
self._update_settings()
self._instances = self.get_instances()
self._services = self.get_services()
self._configs = self.get_configs()
if not self.update_needed(self._instances, self._services, configs=self._configs):
self.__internal_lock.release()
locked = False
continue
self._logger.info(
f"Caught kubernetes event ({watch_type}), deploying new configuration ...",
)
try:
ret = self.apply_config()
if not ret:
self._logger.error(
"Error while deploying new configuration ...",
)
else:
self._logger.info(
"Successfully deployed new configuration 🚀",
)
self._set_autoconf_load_db()
except:
self._logger.error(
f"Exception while deploying new configuration :\n{format_exc()}",
)
to_apply = False
while not applied:
waiting = self.have_to_wait()
self._update_settings()
self._instances = self.get_instances()
self._services = self.get_services()
self._configs = self.get_configs()
if not to_apply and not self.update_needed(self._instances, self._services, configs=self._configs):
self.__internal_lock.release()
locked = False
applied = True
continue
to_apply = True
if waiting:
sleep(1)
continue
self._logger.info(f"Caught kubernetes event ({watch_type}), deploying new configuration ...")
try:
ret = self.apply_config()
if not ret:
self._logger.error("Error while deploying new configuration ...")
else:
self._logger.info("Successfully deployed new configuration 🚀")
self._set_autoconf_load_db()
except:
self._logger.error(f"Exception while deploying new configuration :\n{format_exc()}")
applied = True
self.__internal_lock.release()
locked = False
except ApiException as e:

View file

@ -35,8 +35,7 @@ class SwarmController(Controller):
for env in controller_instance.attrs["Spec"]["TaskTemplate"]["ContainerSpec"]["Env"]:
variable = env.split("=")[0]
value = env.replace(f"{variable}=", "", 1)
if self._is_setting(variable):
instance_env[variable] = value
instance_env[variable] = value
for task in controller_instance.tasks():
if task["DesiredState"] != "running":
@ -57,35 +56,9 @@ class SwarmController(Controller):
for variable, value in controller_service.attrs["Spec"]["Labels"].items():
if not variable.startswith("bunkerweb."):
continue
real_variable = variable.replace("bunkerweb.", "", 1)
if not self._is_setting_context(real_variable, "multisite"):
continue
service[real_variable] = value
service[variable.replace("bunkerweb.", "", 1)] = value
return [service]
def _get_static_services(self) -> List[dict]:
services = []
variables = {}
for instance in self.__client.services.list(filters={"label": "bunkerweb.INSTANCE"}):
if not instance.attrs or not instance.attrs.get("Spec", {}).get("TaskTemplate", {}).get("ContainerSpec", {}).get("Env"):
continue
for env in instance.attrs["Spec"]["TaskTemplate"]["ContainerSpec"]["Env"]:
variable = env.split("=")[0]
value = env.replace(f"{variable}=", "", 1)
variables[variable] = value
if "SERVER_NAME" in variables and variables["SERVER_NAME"].strip():
for server_name in variables["SERVER_NAME"].strip().split(" "):
service = {}
service["SERVER_NAME"] = server_name
for variable, value in variables.items():
prefix = variable.split("_")[0]
real_variable = variable.replace(f"{prefix}_", "", 1)
if prefix == server_name and self._is_setting_context(real_variable, "multisite"):
service[real_variable] = value
services.append(service)
return services
def get_configs(self) -> Dict[str, Dict[str, Any]]:
self.__swarm_configs = []
configs = {}
@ -148,36 +121,51 @@ class SwarmController(Controller):
while True:
locked = False
error = False
applied = False
try:
for event in self.__client.events(decode=True, filters={"type": event_type}):
applied = False
self.__internal_lock.acquire()
locked = True
if not self.__process_event(event):
self.__internal_lock.release()
locked = False
continue
try:
self.wait_applying()
self._update_settings()
self._instances = self.get_instances()
self._services = self.get_services()
self._configs = self.get_configs()
if not self.update_needed(self._instances, self._services, configs=self._configs):
self.__internal_lock.release()
locked = False
continue
self._logger.info(f"Caught Swarm event ({event_type}), deploying new configuration ...")
if not self.apply_config():
self._logger.error("Error while deploying new configuration")
else:
self._logger.info(
"Successfully deployed new configuration 🚀",
)
self._set_autoconf_load_db()
except:
to_apply = False
while not applied:
waiting = self.have_to_wait()
self._update_settings()
self._instances = self.get_instances()
self._services = self.get_services()
self._configs = self.get_configs()
if not to_apply and not self.update_needed(self._instances, self._services, configs=self._configs):
self.__internal_lock.release()
locked = False
applied = True
continue
to_apply = True
if waiting:
sleep(1)
continue
self._logger.info(f"Caught Swarm event ({event_type}), deploying new configuration ...")
if not self.apply_config():
self._logger.error("Error while deploying new configuration")
else:
self._logger.info(
"Successfully deployed new configuration 🚀",
)
self._set_autoconf_load_db()
applied = True
except BaseException:
self._logger.error(f"Exception while processing Swarm event ({event_type}) :\n{format_exc()}")
self.__internal_lock.release()
locked = False
finally:
self.__internal_lock.release()
locked = False
except:
self._logger.error(
f"Exception while reading Swarm event ({event_type}) :\n{format_exc()}",

View file

@ -59,11 +59,7 @@ try:
logger.info(f"Instance #{i} : {instance['name']}")
i += 1
# Run first configuration
ret = controller.apply_config()
if not ret:
logger.error("Error while applying initial configuration")
_exit(1)
controller.wait_applying(True)
# Process events
Path(sep, "var", "tmp", "bunkerweb", "autoconf.healthy").write_text("ok")

View file

@ -1,4 +1,4 @@
FROM nginx:1.26.0-alpine-slim@sha256:be13c98f606eef87521627d5c794a98ac1e5a8fcb085e75acdc0c9d66a28666c AS builder
FROM nginx:1.26.1-alpine-slim@sha256:3df0d85b2e46d4195e7436c22694ef65944c48624282292cadfbf58ee0ad34ce AS builder
# Install temporary requirements for the dependencies
RUN apk add --no-cache bash autoconf libtool automake geoip-dev g++ gcc curl-dev libxml2-dev pcre-dev make linux-headers musl-dev gd-dev gnupg brotli-dev openssl-dev patch readline-dev yajl yajl-dev yajl-tools py3-pip
@ -42,7 +42,7 @@ COPY src/common/utils utils
COPY src/VERSION VERSION
COPY misc/*.ascii misc/
FROM nginx:1.26.0-alpine-slim@sha256:be13c98f606eef87521627d5c794a98ac1e5a8fcb085e75acdc0c9d66a28666c
FROM nginx:1.26.1-alpine-slim@sha256:3df0d85b2e46d4195e7436c22694ef65944c48624282292cadfbf58ee0ad34ce
# Set default umask to prevent huge recursive chmod increasing the final image size
RUN umask 027

View file

@ -390,6 +390,16 @@ class Database:
except (ProgrammingError, OperationalError, DatabaseError):
return False
def is_setting(self, setting: str, *, multisite: bool = False) -> bool:
"""Check if the setting exists in the database and optionally if it's multisite"""
with self.__db_session() as session:
try:
if multisite:
return session.query(Settings).filter_by(id=setting, context="multisite").first() is not None
return session.query(Settings).filter_by(name=setting).first() is not None
except (ProgrammingError, OperationalError):
return False
def initialize_db(self, version: str, integration: str = "Unknown") -> str:
"""Initialize the database"""
with self.__db_session() as session:
@ -1167,7 +1177,11 @@ class Database:
services = config.get("SERVER_NAME", [])
if isinstance(services, str):
services = services.split(" ")
services = services.strip().split(" ")
for i, service in enumerate(services):
if not service:
services.pop(i)
if db_services:
missing_ids = [service.id for service in db_services if service.method == method and service.id not in services]
@ -1247,7 +1261,10 @@ class Database:
changed_plugins.add(setting.plugin_id)
to_put.append(Services_settings(service_id=server_name, setting_id=key, value=value, suffix=suffix, method=method))
elif method in (service_setting.method, "autoconf") and service_setting.value != value:
elif (
method == service_setting.method
or (service_setting.method not in ("scheduler", "autoconf") and method in ("scheduler", "autoconf"))
) and service_setting.value != value:
changed_plugins.add(setting.plugin_id)
query = session.query(Services_settings).filter(
Services_settings.service_id == server_name,
@ -1277,7 +1294,9 @@ class Database:
changed_plugins.add(setting.plugin_id)
to_put.append(Global_values(setting_id=key, value=value, suffix=suffix, method=method))
elif method in (global_value.method, "autoconf") and global_value.value != value:
elif (
method == global_value.method or (global_value.method not in ("scheduler", "autoconf") and method in ("scheduler", "autoconf"))
) and global_value.value != value:
changed_plugins.add(setting.plugin_id)
query = session.query(Global_values).filter(Global_values.setting_id == key, Global_values.suffix == suffix)
@ -1320,14 +1339,16 @@ class Database:
changed_plugins.add(setting.plugin_id)
to_put.append(Global_values(setting_id=key, value=value, suffix=suffix, method=method))
elif global_value.method == method and value != global_value.value:
elif (
method == global_value.method or (global_value.method not in ("scheduler", "autoconf") and method in ("scheduler", "autoconf"))
) and value != global_value.value:
changed_plugins.add(setting.plugin_id)
query = session.query(Global_values).filter(Global_values.setting_id == key, Global_values.suffix == suffix)
if value == setting.default:
query.delete()
continue
query.update({Global_values.value: value})
query.update({Global_values.value: value, Global_values.method: method})
if changed_services:
changed_plugins = set(plugin.id for plugin in session.query(Plugins).with_entities(Plugins.id).all())
@ -1423,12 +1444,12 @@ class Database:
if not custom_conf:
to_put.append(Custom_configs(**custom_config))
elif custom_config["checksum"] != custom_conf.checksum and method in (custom_conf.method, "autoconf"):
elif custom_config["checksum"] != custom_conf.checksum and (
method == custom_conf.method or (custom_conf.method not in ("scheduler", "autoconf") and method in ("scheduler", "autoconf"))
):
custom_conf.data = custom_config["data"]
custom_conf.checksum = custom_config["checksum"]
if method == "autoconf":
custom_conf.method = method
custom_conf.method = method
if changed:
with suppress(ProgrammingError, OperationalError):
metadata = session.query(Metadata).get(1)

View file

@ -86,6 +86,9 @@ class Configurator:
return {}
servers = {}
for server_name in self.__variables["SERVER_NAME"].strip().split(" "):
if not server_name:
continue
if not re_search(self.__settings["SERVER_NAME"]["regex"], server_name):
self.__logger.warning(f"Ignoring server name {server_name} because regex is not valid")
continue

View file

@ -1,59 +0,0 @@
#!/usr/bin/env python3
from glob import glob
from json import JSONDecodeError, loads
from os import sep
from os.path import join
from pathlib import Path
from re import match
from traceback import format_exc
from typing import Any, Dict, Literal, Union
from logger import setup_logger
class ConfigCaller:
def __init__(self):
self.__logger = setup_logger("Config", "INFO")
self._settings = loads(Path(sep, "usr", "share", "bunkerweb", "settings.json").read_text(encoding="utf-8"))
for plugin in glob(join(sep, "usr", "share", "bunkerweb", "core", "*", "plugin.json")) + glob(
join(sep, "etc", "bunkerweb", "plugins", "*", "plugin.json")
):
try:
self._settings.update(loads(Path(plugin).read_text(encoding="utf-8"))["settings"])
except KeyError:
self.__logger.error(
f'Error while loading plugin metadata file at {plugin} : missing "settings" key',
)
except JSONDecodeError:
self.__logger.error(
f"Exception while loading plugin metadata file at {plugin} :\n{format_exc()}",
)
def _is_setting(self, setting) -> bool:
return setting in self._settings
def _is_setting_context(self, setting: str, context: Union[Literal["global"], Literal["multisite"]]) -> bool:
if self._is_setting(setting):
return self._settings[setting]["context"] == context
elif match(r"^.+_\d+$", setting):
multiple_setting = "_".join(setting.split("_")[:-1])
return (
self._is_setting(multiple_setting) and self._settings[multiple_setting]["context"] == context and "multiple" in self._settings[multiple_setting]
)
return False
def _full_env(self, env_instances: Dict[str, Any], env_services: Dict[str, Any]) -> Dict[str, Any]:
full_env = {}
# Fill with default values
for k, v in self._settings.items():
full_env[k] = v["default"]
# Replace with instances values
for k, v in env_instances.items():
full_env[k] = v
if not self._is_setting_context(k, "global") and env_instances.get("MULTISITE", "no") == "yes" and env_instances.get("SERVER_NAME", "") != "":
for server_name in env_instances["SERVER_NAME"].split(" "):
full_env[f"{server_name}_{k}"] = v
# Replace with services values
full_env = full_env | env_services
return full_env

View file

@ -29,9 +29,9 @@
},
{
"id": "nginx",
"name": "Nginx v1.26.0",
"name": "Nginx v1.26.1",
"url": "https://github.com/nginx/nginx.git",
"commit": "361f6bf4b1cd5057d8f6365d1c0a94f3d72824e4"
"commit": "02725ce722bc7b34fa307d611eac3956ef744efa"
},
{
"id": "ngx_brotli",

View file

@ -478,3 +478,4 @@ f8134640e8615448205785cf00b0bc810489b495 release-1.25.1
294a3d07234f8f65d7b0e0b0e2c5b05c12c5da0a release-1.25.3
173a0a7dbce569adbb70257c6ec4f0f6bc585009 release-1.25.4
8618e4d900cc71082fbe7dc72af087937d64faf5 release-1.25.5
a58202a8c41bf0bd97eef1b946e13105a105520d release-1.26.0

View file

@ -19,7 +19,7 @@ else
#include <atomic_ops.h>"
ngx_feature_path=
ngx_feature_libs="-latomic_ops"
ngx_feature_test="long n = 0;
ngx_feature_test="AO_t n = 0;
if (!AO_compare_and_swap(&n, 0, 1))
return 1;
if (AO_fetch_and_add(&n, 1) != 1)

View file

@ -5,6 +5,62 @@
<change_log title="nginx">
<changes ver="1.26.1" date="2024-05-29">
<change type="security">
<para lang="ru">
при использовании HTTP/3 обработка специально созданной QUIC-сессии могла
приводить к падению рабочего процесса, отправке клиенту содержимого памяти
рабочего процесса на системах с MTU больше 4096 байт, а также потенциально
могла иметь другие последствия
(CVE-2024-32760, CVE-2024-31079, CVE-2024-35200, CVE-2024-34161).<br/>
Спасибо Nils Bars из CISPA.
</para>
<para lang="en">
when using HTTP/3, processing of a specially crafted QUIC session might
cause a worker process crash, worker process memory disclosure on systems
with MTU larger than 4096 bytes, or might have potential other impact
(CVE-2024-32760, CVE-2024-31079, CVE-2024-35200, CVE-2024-34161).<br/>
Thanks to Nils Bars of CISPA.
</para>
</change>
<change type="bugfix">
<para lang="ru">
уменьшено потребление памяти для долгоживущих запросов,
если используются директивы gzip, gunzip, ssi, sub_filter или grpc_pass.
</para>
<para lang="en">
reduced memory consumption for long-lived requests
if "gzip", "gunzip", "ssi", "sub_filter", or "grpc_pass" directives are used.
</para>
</change>
<change type="bugfix">
<para lang="ru">
nginx не собирался gcc 14,
если использовался параметр --with-atomic.<br/>
Спасибо Edgar Bonet.
</para>
<para lang="en">
nginx could not be built by gcc 14
if the --with-atomic option was used.<br/>
Thanks to Edgar Bonet.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в HTTP/3.
</para>
<para lang="en">
in HTTP/3.
</para>
</change>
</changes>
<changes ver="1.26.0" date="2024-04-23">
<change>

View file

@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
#define nginx_version 1026000
#define NGINX_VERSION "1.26.0"
#define nginx_version 1026001
#define NGINX_VERSION "1.26.1"
#define NGINX_VER "nginx/" NGINX_VERSION
#ifdef NGX_BUILD

View file

@ -117,7 +117,10 @@ ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
ngx_debug_point();
ctx->in = ctx->in->next;
cl = ctx->in;
ctx->in = cl->next;
ngx_free_chain(ctx->pool, cl);
continue;
}
@ -203,7 +206,10 @@ ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
/* delete the completed buf from the ctx->in chain */
if (ngx_buf_size(ctx->in->buf) == 0) {
ctx->in = ctx->in->next;
cl = ctx->in;
ctx->in = cl->next;
ngx_free_chain(ctx->pool, cl);
}
cl = ngx_alloc_chain_link(ctx->pool);

View file

@ -648,6 +648,7 @@ ngx_quic_free_buffer(ngx_connection_t *c, ngx_quic_buffer_t *qb)
ngx_quic_free_chain(c, qb->chain);
qb->chain = NULL;
qb->last_chain = NULL;
}

View file

@ -326,6 +326,11 @@ ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
ngx_quic_crypto_frame_t *f;
qc = ngx_quic_get_connection(c);
if (!ngx_quic_keys_available(qc->keys, pkt->level, 0)) {
return NGX_OK;
}
ctx = ngx_quic_get_send_ctx(qc, pkt->level);
f = &frame->u.crypto;

View file

@ -1750,6 +1750,14 @@ ngx_quic_parse_transport_params(u_char *p, u_char *end, ngx_quic_tp_t *tp,
return NGX_ERROR;
}
if ((size_t) (end - p) < len) {
ngx_log_error(NGX_LOG_INFO, log, 0,
"quic failed to parse"
" transport param id:0x%xL, data length %uL too long",
id, len);
return NGX_ERROR;
}
rc = ngx_quic_parse_transport_param(p, p + len, id, tp);
if (rc == NGX_ERROR) {

View file

@ -1231,7 +1231,7 @@ ngx_http_grpc_body_output_filter(void *data, ngx_chain_t *in)
ngx_buf_t *b;
ngx_int_t rc;
ngx_uint_t next, last;
ngx_chain_t *cl, *out, **ll;
ngx_chain_t *cl, *out, *ln, **ll;
ngx_http_upstream_t *u;
ngx_http_grpc_ctx_t *ctx;
ngx_http_grpc_frame_t *f;
@ -1459,7 +1459,10 @@ ngx_http_grpc_body_output_filter(void *data, ngx_chain_t *in)
last = 1;
}
ln = in;
in = in->next;
ngx_free_chain(r->pool, ln);
}
ctx->in = in;

View file

@ -333,6 +333,8 @@ static ngx_int_t
ngx_http_gunzip_filter_add_data(ngx_http_request_t *r,
ngx_http_gunzip_ctx_t *ctx)
{
ngx_chain_t *cl;
if (ctx->zstream.avail_in || ctx->flush != Z_NO_FLUSH || ctx->redo) {
return NGX_OK;
}
@ -344,8 +346,11 @@ ngx_http_gunzip_filter_add_data(ngx_http_request_t *r,
return NGX_DECLINED;
}
ctx->in_buf = ctx->in->buf;
ctx->in = ctx->in->next;
cl = ctx->in;
ctx->in_buf = cl->buf;
ctx->in = cl->next;
ngx_free_chain(r->pool, cl);
ctx->zstream.next_in = ctx->in_buf->pos;
ctx->zstream.avail_in = ctx->in_buf->last - ctx->in_buf->pos;
@ -374,6 +379,7 @@ static ngx_int_t
ngx_http_gunzip_filter_get_buf(ngx_http_request_t *r,
ngx_http_gunzip_ctx_t *ctx)
{
ngx_chain_t *cl;
ngx_http_gunzip_conf_t *conf;
if (ctx->zstream.avail_out) {
@ -383,8 +389,12 @@ ngx_http_gunzip_filter_get_buf(ngx_http_request_t *r,
conf = ngx_http_get_module_loc_conf(r, ngx_http_gunzip_filter_module);
if (ctx->free) {
ctx->out_buf = ctx->free->buf;
ctx->free = ctx->free->next;
cl = ctx->free;
ctx->out_buf = cl->buf;
ctx->free = cl->next;
ngx_free_chain(r->pool, cl);
ctx->out_buf->flush = 0;

View file

@ -985,10 +985,14 @@ static void
ngx_http_gzip_filter_free_copy_buf(ngx_http_request_t *r,
ngx_http_gzip_ctx_t *ctx)
{
ngx_chain_t *cl;
ngx_chain_t *cl, *ln;
for (cl = ctx->copied; cl; cl = cl->next) {
ngx_pfree(r->pool, cl->buf->start);
for (cl = ctx->copied; cl; /* void */) {
ln = cl;
cl = cl->next;
ngx_pfree(r->pool, ln->buf->start);
ngx_free_chain(r->pool, ln);
}
ctx->copied = NULL;

View file

@ -482,9 +482,13 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
while (ctx->in || ctx->buf) {
if (ctx->buf == NULL) {
ctx->buf = ctx->in->buf;
ctx->in = ctx->in->next;
cl = ctx->in;
ctx->buf = cl->buf;
ctx->in = cl->next;
ctx->pos = ctx->buf->pos;
ngx_free_chain(r->pool, cl);
}
if (ctx->state == ssi_start_state) {

View file

@ -335,9 +335,13 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
while (ctx->in || ctx->buf) {
if (ctx->buf == NULL) {
ctx->buf = ctx->in->buf;
ctx->in = ctx->in->next;
cl = ctx->in;
ctx->buf = cl->buf;
ctx->in = cl->next;
ctx->pos = ctx->buf->pos;
ngx_free_chain(r->pool, cl);
}
if (ctx->buf->flush || ctx->buf->recycled) {

View file

@ -810,6 +810,7 @@ ngx_http_v3_parse_field_lri(ngx_connection_t *c,
st->literal.length = st->pint.value;
if (st->literal.length == 0) {
st->value.data = (u_char *) "";
goto done;
}
@ -932,6 +933,7 @@ ngx_http_v3_parse_field_l(ngx_connection_t *c,
st->literal.length = st->pint.value;
if (st->literal.length == 0) {
st->value.data = (u_char *) "";
goto done;
}
@ -1072,6 +1074,7 @@ ngx_http_v3_parse_field_lpbi(ngx_connection_t *c,
st->literal.length = st->pint.value;
if (st->literal.length == 0) {
st->value.data = (u_char *) "";
goto done;
}

View file

@ -134,7 +134,17 @@ ngx_http_v3_init(ngx_connection_t *c)
}
}
return ngx_http_v3_send_settings(c);
if (ngx_http_v3_send_settings(c) != NGX_OK) {
return NGX_ERROR;
}
if (h3scf->max_table_capacity > 0) {
if (ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER) == NULL) {
return NGX_ERROR;
}
}
return NGX_OK;
}
@ -398,14 +408,12 @@ ngx_http_v3_wait_request_handler(ngx_event_t *rev)
void
ngx_http_v3_reset_stream(ngx_connection_t *c)
{
ngx_http_v3_session_t *h3c;
ngx_http_v3_srv_conf_t *h3scf;
h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module);
ngx_http_v3_session_t *h3c;
h3c = ngx_http_v3_get_session(c);
if (h3scf->max_table_capacity > 0 && !c->read->eof && !h3c->hq
if (!c->read->eof && !h3c->hq
&& h3c->known_streams[NGX_HTTP_V3_STREAM_SERVER_DECODER]
&& (c->quic->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0)
{
(void) ngx_http_v3_send_cancel_stream(c, c->quic->id);

View file

@ -308,7 +308,7 @@ ngx_http_v3_set_capacity(ngx_connection_t *c, ngx_uint_t capacity)
prev_max = dt->capacity / 32;
if (max > prev_max) {
elts = ngx_alloc(max * sizeof(void *), c->log);
elts = ngx_alloc((max + 1) * sizeof(void *), c->log);
if (elts == NULL) {
return NGX_ERROR;
}

View file

@ -20,8 +20,6 @@ static void ngx_http_v3_close_uni_stream(ngx_connection_t *c);
static void ngx_http_v3_uni_read_handler(ngx_event_t *rev);
static void ngx_http_v3_uni_dummy_read_handler(ngx_event_t *wev);
static void ngx_http_v3_uni_dummy_write_handler(ngx_event_t *wev);
static ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c,
ngx_uint_t type);
void
@ -307,7 +305,7 @@ ngx_http_v3_uni_dummy_write_handler(ngx_event_t *wev)
}
static ngx_connection_t *
ngx_connection_t *
ngx_http_v3_get_uni_stream(ngx_connection_t *c, ngx_uint_t type)
{
u_char buf[NGX_HTTP_V3_VARLEN_INT_LEN];

View file

@ -19,6 +19,8 @@ ngx_int_t ngx_http_v3_register_uni_stream(ngx_connection_t *c, uint64_t type);
ngx_int_t ngx_http_v3_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id);
ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c,
ngx_uint_t type);
ngx_int_t ngx_http_v3_send_settings(ngx_connection_t *c);
ngx_int_t ngx_http_v3_send_goaway(ngx_connection_t *c, uint64_t id);
ngx_int_t ngx_http_v3_send_ack_section(ngx_connection_t *c,

View file

@ -1,7 +1,7 @@
FROM debian:bookworm-slim@sha256:d02c76d82364cedca16ba3ed6f9102406fa9fa8833076a609cabf14270f43dfc as builder
ENV OS=debian
ENV NGINX_VERSION 1.26.0
ENV NGINX_VERSION 1.26.1
# Install Nginx and dependencies
RUN apt update && \
@ -11,7 +11,7 @@ RUN apt update && \
echo "deb-src https://nginx.org/packages/debian/ bookworm nginx" >> /etc/apt/sources.list.d/nginx.list && \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62 && \
apt-get update && \
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-1~bookworm
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-2~bookworm
WORKDIR /tmp/bunkerweb/deps

View file

@ -1,7 +1,7 @@
FROM redhat/ubi8:8.10@sha256:f4292f415f60632a0ff9c0646c4fa859d8b2e1e88a16faa90c6decd1951aea88 as builder
ENV OS=rhel
ENV NGINX_VERSION 1.26.0
ENV NGINX_VERSION 1.26.1
# Copy rocky repo
COPY src/linux/rocky-8.repo /etc/yum.repos.d/rocky.repo
@ -17,7 +17,7 @@ RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-8
RUN dnf install -y wget make yum-utils && \
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm && \
dnf install -y --setopt=install_weak_deps=False readline-devel python39 python39-devel python39-setuptools brotli brotli-devel gperftools-devel perl libxslt-devel libxml2 yajl yajl-devel libxslt bash gd gd-devel gcc-c++ curl znc-modtcl gawk libtool pcre-devel automake autoconf gcc make openssl-devel git zlib-devel libxml2-devel pkgconf libcurl-devel geoip-devel && \
dnf install -y https://nginx.org/packages/rhel/8/$(uname -m)/RPMS/nginx-${NGINX_VERSION}-1.el8.ngx.$(uname -m).rpm
dnf install -y https://nginx.org/packages/rhel/8/$(uname -m)/RPMS/nginx-${NGINX_VERSION}-2.el8.ngx.$(uname -m).rpm
WORKDIR /tmp/bunkerweb/deps

View file

@ -1,7 +1,7 @@
FROM redhat/ubi9:9.4@sha256:d7158916ab85c7463d33f89d45d26c70d064aaa28debe219fa088b8110194663 as builder
ENV OS=rhel
ENV NGINX_VERSION 1.26.0
ENV NGINX_VERSION 1.26.1
# Copy rocky repo
COPY src/linux/rocky-9.repo /etc/yum.repos.d/rocky.repo
@ -18,9 +18,9 @@ RUN dnf install -y wget make yum-utils && \
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm && \
dnf install -y --skip-broken --setopt=install_weak_deps=False --nobest openssl-libs openssl-devel && \
dnf install -y --skip-broken --setopt=install_weak_deps=False readline-devel python39 brotli brotli-devel gperftools-devel perl libxslt-devel libxml2 yajl libxslt bash gd gd-devel gcc-c++ znc-modtcl gawk libtool pcre-devel automake autoconf gcc make git zlib-devel libxml2-devel pkgconf libcurl-devel libmaxminddb && \
wget https://nginx.org/packages/rhel/9/$(uname -m)/RPMS/nginx-${NGINX_VERSION}-1.el9.ngx.$(uname -m).rpm && \
dnf install nginx-${NGINX_VERSION}-1.el9.ngx.$(uname -m).rpm -y && \
rm -rf nginx-${NGINX_VERSION}-1.el9.ngx.$(uname -m).rpm
wget https://nginx.org/packages/rhel/9/$(uname -m)/RPMS/nginx-${NGINX_VERSION}-2.el9.ngx.$(uname -m).rpm && \
dnf install nginx-${NGINX_VERSION}-2.el9.ngx.$(uname -m).rpm -y && \
rm -rf nginx-${NGINX_VERSION}-2.el9.ngx.$(uname -m).rpm
WORKDIR /tmp/bunkerweb/deps

View file

@ -1,7 +1,7 @@
FROM ubuntu:24.04@sha256:562456a05a0dbd62a671c1854868862a4687bf979a96d48ae8e766642cd911e8 as builder
ENV OS=ubuntu
ENV NGINX_VERSION 1.26.0
ENV NGINX_VERSION 1.26.1
# Install Nginx and dependencies
RUN apt update && \
@ -11,7 +11,7 @@ RUN apt update && \
echo "deb-src https://nginx.org/packages/ubuntu/ noble nginx" >> /etc/apt/sources.list.d/nginx.list && \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62 && \
apt-get update && \
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-1~noble
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-2~noble
WORKDIR /tmp/bunkerweb/deps

View file

@ -1,7 +1,7 @@
FROM ubuntu:22.04@sha256:2af372c1e2645779643284c7dc38775e3dbbc417b2d784a27c5a9eb784014fb8 as builder
ENV OS=ubuntu
ENV NGINX_VERSION 1.26.0
ENV NGINX_VERSION 1.26.1
# Install Nginx and dependencies
RUN apt update && \
@ -11,7 +11,7 @@ RUN apt update && \
echo "deb-src https://nginx.org/packages/ubuntu/ jammy nginx" >> /etc/apt/sources.list.d/nginx.list && \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62 && \
apt-get update && \
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-1~jammy
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-2~jammy
WORKDIR /tmp/bunkerweb/deps

View file

@ -3,7 +3,7 @@
--license agpl3
--version %VERSION%
--architecture %ARCH%
--depends bash --depends python3 --depends procps --depends python3-pip --depends 'nginx = 1.26.0-1~bookworm' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends lsof --depends libpq5 --depends libpcre3 --depends libcap2-bin --depends logrotate --depends mariadb-client --depends postgresql-client --depends sqlite3 --depends unzip
--depends bash --depends python3 --depends procps --depends python3-pip --depends 'nginx = 1.26.1-2~bookworm' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends lsof --depends libpq5 --depends libpcre3 --depends libcap2-bin --depends logrotate --depends mariadb-client --depends postgresql-client --depends sqlite3 --depends unzip
--description "BunkerWeb %VERSION% for Debian 12"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"

View file

@ -3,7 +3,7 @@
--license agpl3
--version %VERSION%
--architecture %ARCH%
--depends bash --depends python39 --depends 'nginx >= 1:1.26.0' --depends 'nginx < 1:1.27.0' --depends libcurl-devel --depends libxml2 --depends yajl --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends geoip --depends libpq --depends libcap --depends openssl --depends sqlite --depends unzip
--depends bash --depends python39 --depends 'nginx >= 1:1.26.1' --depends 'nginx < 1:1.27.0' --depends libcurl-devel --depends libxml2 --depends yajl --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends geoip --depends libpq --depends libcap --depends openssl --depends sqlite --depends unzip
--description "BunkerWeb %VERSION% for RHEL 8"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"

View file

@ -3,7 +3,7 @@
--license agpl3
--version %VERSION%
--architecture %ARCH%
--depends bash --depends python39 --depends 'nginx >= 1:1.26.0' --depends 'nginx < 1:1.27.0' --depends libcurl-devel --depends libxml2 --depends yajl --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends libmaxminddb --depends libpq --depends libcap --depends openssl --depends mysql --depends postgresql --depends sqlite --depends unzip
--depends bash --depends python39 --depends 'nginx >= 1:1.26.1' --depends 'nginx < 1:1.27.0' --depends libcurl-devel --depends libxml2 --depends yajl --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends libmaxminddb --depends libpq --depends libcap --depends openssl --depends mysql --depends postgresql --depends sqlite --depends unzip
--description "BunkerWeb %VERSION% for RHEL 9"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"

View file

@ -3,7 +3,7 @@
--license agpl3
--version %VERSION%
--architecture %ARCH%
--depends bash --depends python3 --depends python3-pip --depends 'nginx = 1.26.0-1~noble' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends procps --depends lsof --depends libpq5 --depends libcap2-bin --depends logrotate --depends mariadb-client --depends postgresql-client --depends sqlite3 --depends unzip --depends libpcre3
--depends bash --depends python3 --depends python3-pip --depends 'nginx = 1.26.1-2~noble' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends procps --depends lsof --depends libpq5 --depends libcap2-bin --depends logrotate --depends mariadb-client --depends postgresql-client --depends sqlite3 --depends unzip --depends libpcre3
--description "BunkerWeb %VERSION% for Ubuntu 24.04"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"

View file

@ -3,7 +3,7 @@
--license agpl3
--version %VERSION%
--architecture %ARCH%
--depends bash --depends python3 --depends python3-pip --depends 'nginx = 1.26.0-1~jammy' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends procps --depends lsof --depends libpq5 --depends libcap2-bin --depends logrotate --depends mariadb-client --depends postgresql-client --depends sqlite3 --depends unzip --depends libpcre3
--depends bash --depends python3 --depends python3-pip --depends 'nginx = 1.26.1-2~jammy' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends procps --depends lsof --depends libpq5 --depends libcap2-bin --depends logrotate --depends mariadb-client --depends postgresql-client --depends sqlite3 --depends unzip --depends libpcre3
--description "BunkerWeb %VERSION% for Ubuntu 22.04"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"

View file

@ -4,7 +4,7 @@ import tempfile
import time
import pathlib
NGINX_VERSION = "1.26.0"
NGINX_VERSION = "1.26.1"
distro = sys.argv[1]
if distro == "ubuntu":
@ -595,7 +595,7 @@ elif distro == "debian":
echo "deb-src https://nginx.org/packages/debian/ bookworm nginx" >> /etc/apt/sources.list.d/nginx.list && \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62 && \
apt-get update && \
apt-get install -y --no-install-recommends nginx=1.26.0-1~bookworm
apt-get install -y --no-install-recommends nginx=1.26.1-2~bookworm
apt install /data/bunkerweb.deb -y
"""
@ -947,7 +947,7 @@ elif distro == "debian":
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update && sudo apt install -y nginx=1.26.0-1~bookworm
sudo apt update && sudo apt install -y nginx=1.26.1-2~bookworm
curl -s https://packagecloud.io/install/repositories/bunkerity/bunkerweb/script.deb.sh | sudo bash && \
sudo apt update && \
sudo apt install -y bunkerweb=1.4.5
@ -1647,15 +1647,15 @@ elif distro.startswith("rhel"):
bash_script = (
"""
dnf install yum-utils wget sudo -y
wget https://nginx.org/packages/rhel/9/x86_64/RPMS/nginx-1.26.0-1.el9.ngx.x86_64.rpm
dnf install nginx-1.26.0-1.el9.ngx.x86_64.rpm -y
wget https://nginx.org/packages/rhel/9/x86_64/RPMS/nginx-1.26.1-2.el9.ngx.x86_64.rpm
dnf install nginx-1.26.1-2.el9.ngx.x86_64.rpm -y
dnf install /data/bunkerweb.rpm -y
"""
if distro.endswith("9")
else """
dnf install yum-utils wget sudo -y
wget https://nginx.org/packages/rhel/8/x86_64/RPMS/nginx-1.26.0-1.el8.ngx.x86_64.rpm
dnf install nginx-1.26.0-1.el8.ngx.x86_64.rpm -y
wget https://nginx.org/packages/rhel/8/x86_64/RPMS/nginx-1.26.1-2.el8.ngx.x86_64.rpm
dnf install nginx-1.26.1-2.el8.ngx.x86_64.rpm -y
dnf install /data/bunkerweb.rpm -y
"""
)

View file

@ -1,26 +0,0 @@
FROM quay.io/centos/centos:stream8@sha256:a8692b39e546eed9177d495db1edfd97bb6de70b9527f58aeb72f90b687c3426
RUN yum install -y initscripts # for old "service"
ENV container=docker
ENV NGINX_VERSION 1.26.0
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
COPY src/linux/nginx.repo /etc/yum.repos.d/nginx.repo
RUN dnf install php-fpm curl yum-utils epel-release which -y && \
dnf install nginx-${NGINX_VERSION} -y
COPY ./package-centos/*.rpm /opt
VOLUME /run /tmp
CMD /usr/sbin/init

View file

@ -3,7 +3,7 @@ FROM debian:bookworm@sha256:b16cef8cbcb20935c0f052e37fc3d38dc92bfec0bcfb894c3285
ENV container docker
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive
ENV NGINX_VERSION 1.26.0
ENV NGINX_VERSION 1.26.1
RUN apt-get update \
&& apt-get install -y systemd systemd-sysv \
@ -29,7 +29,7 @@ RUN apt update && \
echo "deb-src https://nginx.org/packages/debian/ bookworm nginx" >> /etc/apt/sources.list.d/nginx.list && \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62 && \
apt-get update && \
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-1~bookworm
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-2~bookworm
COPY ./package-debian/*.deb /opt

View file

@ -1,6 +1,6 @@
FROM redhat/ubi8-init:8.10-2.1716501369@sha256:3c716a2207328b0f799e52ed8a9442859c7d6209028a9218d4307386ff5452df
ENV NGINX_VERSION 1.26.0
ENV NGINX_VERSION 1.26.1
# Copy rocky repo
COPY src/linux/rocky-8.repo /etc/yum.repos.d/rocky.repo

View file

@ -1,6 +1,6 @@
FROM redhat/ubi9-init:9.4-6.1716477011@sha256:df8e043878f3f459d6fcf3e9abce3f9f6e1526a3695bf0ac487d780e031ac8ab
ENV NGINX_VERSION 1.26.0
ENV NGINX_VERSION 1.26.1
# Copy rocky repo
COPY src/linux/rocky-9.repo /etc/yum.repos.d/rocky.repo

View file

@ -3,7 +3,7 @@ FROM ubuntu:24.04@sha256:562456a05a0dbd62a671c1854868862a4687bf979a96d48ae8e7666
ENV container docker
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive
ENV NGINX_VERSION 1.26.0
ENV NGINX_VERSION 1.26.1
RUN apt-get update \
&& apt-get install -y systemd systemd-sysv \
@ -29,7 +29,7 @@ RUN apt update && \
echo "deb-src https://nginx.org/packages/ubuntu/ noble nginx" >> /etc/apt/sources.list.d/nginx.list && \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62 && \
apt-get update && \
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-1~noble
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-2~noble
COPY ./package-ubuntu/*.deb /opt

View file

@ -3,7 +3,7 @@ FROM ubuntu:22.04@sha256:a6d2b38300ce017add71440577d5b0a90460d0e57fd7aec21dd0d1b
ENV container docker
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive
ENV NGINX_VERSION 1.26.0
ENV NGINX_VERSION 1.26.1
RUN apt-get update \
&& apt-get install -y systemd systemd-sysv \
@ -29,7 +29,7 @@ RUN apt update && \
echo "deb-src https://nginx.org/packages/ubuntu/ jammy nginx" >> /etc/apt/sources.list.d/nginx.list && \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62 && \
apt-get update && \
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-1~jammy
apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-2~jammy
COPY ./package-ubuntu-jammy/*.deb /opt