Merge pull request #677 from bunkerity/dev

Merge branch "dev" into branch "staging"
This commit is contained in:
Théophile Diot 2023-10-04 17:06:59 +02:00 committed by GitHub
commit d1a0f66c98
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
214 changed files with 1830 additions and 3433 deletions

15
.gitattributes vendored Normal file
View file

@ -0,0 +1,15 @@
# Folders
src/deps/src/** linguist-vendored
src/common/core/modsecurity/files/** linguist-vendored
src/ui/static/js/editor/** linguist-vendored
src/ui/static/js/utils/purify/** linguist-vendored
src/ui/static/webfonts/** linguist-vendored
# Files
src/deps/misc/lua-pack.Makefile -linguist-vendored
src/deps/misc/ngx_http_modsecurity_access.c -linguist-vendored
src/ui/static/css/datepicker-foundation.css -linguist-vendored
src/ui/static/css/flatpickr.css -linguist-vendored
src/ui/static/css/flatpickr.dark.css -linguist-vendored
src/ui/static/js/tsparticles.bundle.min.js -linguist-vendored
src/ui/static/js/utils/flatpickr.js -linguist-vendored

View file

@ -131,7 +131,7 @@ jobs:
versionrpm: ${{ steps.getversionrpm.outputs.versionrpm }}
steps:
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Get VERSION
id: getversion
run: echo "version=$(cat src/VERSION | tr -d '\n')" >> "$GITHUB_OUTPUT"

View file

@ -19,13 +19,13 @@ jobs:
language: ["python", "javascript"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@ddccb873888234080b77e9bc2d4764d5ccaaccf9 # v2.21.9
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql.yml
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@ddccb873888234080b77e9bc2d4764d5ccaaccf9 # v2.21.9
with:
category: "/language:${{matrix.language}}"

View file

@ -45,7 +45,7 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Replace VERSION
if: inputs.RELEASE == 'testing'
run: ./misc/update-version.sh testing
@ -61,22 +61,22 @@ jobs:
SSH_IP: ${{ secrets.ARM_SSH_IP }}
SSH_CONFIG: ${{ secrets.ARM_SSH_CONFIG }}
- name: Setup Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
if: inputs.CACHE_SUFFIX != 'arm'
- name: Setup Buildx (ARM)
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
if: inputs.CACHE_SUFFIX == 'arm'
with:
endpoint: ssh://root@arm
platforms: linux/arm64,linux/arm/v7,linux/arm/v6
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to ghcr
if: inputs.PUSH == true
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@ -84,13 +84,13 @@ jobs:
# Compute metadata
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: bunkerity/${{ inputs.IMAGE }}
# Build cached image
- name: Build image
if: inputs.CACHE == true
uses: docker/build-push-action@v5
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
file: ${{ inputs.DOCKERFILE }}
@ -103,7 +103,7 @@ jobs:
# Build non-cached image
- name: Build image
if: inputs.CACHE != true
uses: docker/build-push-action@v5
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
file: ${{ inputs.DOCKERFILE }}
@ -115,7 +115,7 @@ jobs:
# Check OS vulnerabilities
- name: Check OS vulnerabilities
if: ${{ inputs.CACHE_SUFFIX != 'arm' }}
uses: aquasecurity/trivy-action@master
uses: aquasecurity/trivy-action@69cbbc0cbbf6a2b0bab8dcf0e9f2d7ead08e87e4 # master
with:
vuln-type: os
skip-dirs: /root/.cargo

View file

@ -33,7 +33,7 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Get ARM availabilities
id: availabilities
uses: scaleway/action-scw@c718eca1fcb9fec1fb1433752d61599c6a0ad2e9

View file

@ -5,14 +5,14 @@ permissions:
on:
schedule:
- cron: "0 1 5 * *"
- cron: "0 12 1 * *"
jobs:
mmdb-update:
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
fetch-depth: 0
token: ${{ secrets.BUNKERBOT_TOKEN }}
@ -52,7 +52,7 @@ jobs:
rm -f asn.mmdb country.mmdb
gunzip asn.mmdb.gz country.mmdb.gz
- name: Commit and push changes
uses: stefanzweifel/git-auto-commit-action@v4
uses: stefanzweifel/git-auto-commit-action@3ea6ae190baf489ba007f7c92608f33ce20ef04a # v4.16.0
with:
branch: dev
commit_message: "Monthly mmdb update"

View file

@ -88,7 +88,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- id: set-matrix
run: |
tests=$(find ./tests/core/ -maxdepth 1 -mindepth 1 -type d -printf "%f\n" | jq -c --raw-input --slurp 'split("\n")| .[0:-1]')
@ -126,12 +126,12 @@ jobs:
packages: write
steps:
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to ghcr
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -13,9 +13,9 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Install Python
uses: actions/setup-python@v4
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
with:
python-version: "3.10"
- name: Install doc requirements
@ -23,7 +23,7 @@ jobs:
- name: Install chromium
run: sudo apt install chromium-browser
- name: Install node
uses: actions/setup-node@v3
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1
with:
node-version: 18
- name: Install puppeteer
@ -32,7 +32,7 @@ jobs:
run: mkdocs serve & sleep 10
- name: Run pdf script
run: node docs/misc/pdf.js http://localhost:8000/print_page/ BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf 'BunkerWeb documentation v${{ inputs.VERSION }}'
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
path: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf

View file

@ -37,7 +37,7 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Replace VERSION
if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' || inputs.RELEASE == 'ui'
run: ./misc/update-version.sh ${{ inputs.RELEASE }}
@ -70,21 +70,21 @@ jobs:
SSH_IP: ${{ secrets.ARM_SSH_IP }}
SSH_CONFIG: ${{ secrets.ARM_SSH_CONFIG }}
- name: Setup Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
if: startsWith(env.ARCH, 'arm') == false
- name: Setup Buildx (ARM)
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
if: startsWith(env.ARCH, 'arm') == true
with:
endpoint: ssh://root@arm
platforms: linux/arm64,linux/arm/v7,linux/arm/v6
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to ghcr
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@ -92,7 +92,7 @@ jobs:
# Build testing package image
- name: Build package image
if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' || inputs.RELEASE == 'ui'
uses: docker/build-push-action@v5
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
load: true
@ -104,7 +104,7 @@ jobs:
# Build non-testing package image
- name: Build package image
if: inputs.RELEASE != 'testing' && inputs.RELEASE != 'dev'
uses: docker/build-push-action@v5
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
load: true
@ -127,7 +127,7 @@ jobs:
scp -r root@arm:/root/package-${{ inputs.LINUX }} ./package-${{ inputs.LINUX }}
env:
LARCH: ${{ env.LARCH }}
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: package-${{ inputs.LINUX }}-${{ env.LARCH }}
path: package-${{ inputs.LINUX }}/*.${{ inputs.PACKAGE }}
@ -135,12 +135,12 @@ jobs:
- name: Extract metadata
if: inputs.TEST == true
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ghcr.io/bunkerity/${{ inputs.LINUX }}-tests:${{ inputs.RELEASE }}
- name: Build test image
if: inputs.TEST == true
uses: docker/build-push-action@v5
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
file: tests/linux/Dockerfile-${{ inputs.LINUX }}

View file

@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
fetch-depth: 0
token: ${{ secrets.BUNKERBOT_TOKEN }}
@ -29,7 +29,7 @@ jobs:
run: |
git config --global user.name "BunkerBot"
git config --global user.email "bunkerbot@bunkerity.com"
- uses: actions/setup-python@v4
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
with:
python-version: "3.10"
- name: Install doc requirements

View file

@ -33,14 +33,14 @@ jobs:
steps:
# Prepare
- name: Check out repository code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to ghcr
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@ -56,19 +56,19 @@ jobs:
SSH_IP: ${{ secrets.ARM_SSH_IP }}
SSH_CONFIG: ${{ secrets.ARM_SSH_CONFIG }}
- name: Setup Buildx (ARM)
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
with:
endpoint: ssh://root@arm
platforms: linux/arm64,linux/arm/v7,linux/arm/v6
# Compute metadata
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: bunkerity/${{ inputs.IMAGE }}
# Build and push
- name: Build and push
uses: docker/build-push-action@v5
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
file: ${{ inputs.DOCKERFILE }}

View file

@ -15,15 +15,15 @@ jobs:
runs-on: ubuntu-latest
steps:
# Checkout
- uses: actions/checkout@v4
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
# Get PDF doc
- name: Get documentation
if: inputs.VERSION != 'testing'
uses: actions/download-artifact@v3
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
with:
name: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
# Create tag
- uses: rickstaa/action-create-tag@v1
- uses: rickstaa/action-create-tag@88dbf7ff6fe2405f8e8f6c6fdfd78829bc631f83 # v1.6.3
name: Create tag
if: inputs.VERSION != 'testing'
with:
@ -31,7 +31,7 @@ jobs:
message: "v${{ inputs.VERSION }}"
force_push_tag: true
# Create tag
- uses: rickstaa/action-create-tag@v1
- uses: rickstaa/action-create-tag@88dbf7ff6fe2405f8e8f6c6fdfd78829bc631f83 # v1.6.3
name: Create tag
if: inputs.VERSION == 'testing'
with:
@ -51,7 +51,7 @@ jobs:
# Create release
- name: Create release
if: inputs.VERSION != 'testing'
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
with:
body: |
Documentation : https://docs.bunkerweb.io/${{ inputs.VERSION }}/
@ -75,7 +75,7 @@ jobs:
# Create release
- name: Create release
if: inputs.VERSION == 'testing'
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
with:
body: |
**The testing version of BunkerWeb should not be used in production, please use the latest stable version instead.**

View file

@ -40,20 +40,20 @@ jobs:
steps:
# Prepare
- name: Check out repository code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Install ruby
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@52b8784594ec115fd17094752708121dc5dabb47 # v1.154.0
with:
ruby-version: "3.0"
- name: Install packagecloud
run: gem install package_cloud
# Download packages
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
if: inputs.LINUX != 'el'
with:
name: package-${{ inputs.LINUX }}-${{ inputs.PACKAGE_ARCH }}
path: /tmp/${{ inputs.LINUX }}
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
if: inputs.LINUX == 'el'
with:
name: package-rhel-${{ inputs.PACKAGE_ARCH }}
@ -70,7 +70,7 @@ jobs:
# run: sudo apt install -y rename && rename 's/[0-9]\.[0-9]\.[0-9]/testing/' /tmp/${{ inputs.LINUX }}/*.${{ inputs.PACKAGE }}
# Push package
- name: Push package to packagecloud
uses: danielmundi/upload-packagecloud@v1
uses: danielmundi/upload-packagecloud@46cd0e61152bf952dbc0d1759e609d3d22649030 # v1
with:
PACKAGE-NAME: /tmp/${{ inputs.LINUX }}/*.${{ inputs.PACKAGE }}
PACKAGECLOUD-USERNAME: bunkerity

View file

@ -139,7 +139,7 @@ jobs:
versionrpm: ${{ steps.getversionrpm.outputs.versionrpm }}
steps:
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Get VERSION
id: getversion
run: echo "version=$(cat src/VERSION | tr -d '\n')" >> "$GITHUB_OUTPUT"

View file

@ -21,7 +21,7 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Delete ARM VM
uses: scaleway/action-scw@c718eca1fcb9fec1fb1433752d61599c6a0ad2e9
with:

View file

@ -15,16 +15,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: "Checkout code"
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@v2.2.0
uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # v2.2.0
with:
results_file: results.sarif
results_format: sarif
publish_results: true
- name: "Upload SARIF results to code scanning"
uses: github/codeql-action/upload-sarif@v2
uses: github/codeql-action/upload-sarif@ddccb873888234080b77e9bc2d4764d5ccaaccf9 # v2.21.9
with:
sarif_file: results.sarif

View file

@ -23,14 +23,14 @@ jobs:
run: ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N "" && ssh-keygen -f ~/.ssh/id_rsa -y > ~/.ssh/id_rsa.pub && echo -e "Host *\n StrictHostKeyChecking no" > ~/.ssh/ssh_config
if: inputs.TYPE != 'k8s'
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Install terraform
uses: hashicorp/setup-terraform@v2
uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 # v2.0.3
- name: Install kubectl
uses: azure/setup-kubectl@v3
uses: azure/setup-kubectl@901a10e89ea615cf61f57ac05cecdf23e7de06d8 # v3.2
if: inputs.TYPE == 'k8s'
- name: Set up Python 3.11
uses: actions/setup-python@v4
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
if: inputs.TYPE != 'k8s'
with:
python-version: "3.11"
@ -54,7 +54,7 @@ jobs:
if: always()
env:
SECRET_KEY: ${{ secrets.SECRET_KEY }}
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
if: always()
with:
name: tf-${{ inputs.TYPE }}

View file

@ -20,10 +20,10 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Install terraform
uses: hashicorp/setup-terraform@v2
- uses: actions/download-artifact@v3
uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 # v2.0.3
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
with:
name: tf-${{ inputs.TYPE }}
path: /tmp
@ -34,7 +34,7 @@ jobs:
tar xf /tmp/terraform.tar -C / && mkdir ~/.ssh && touch ~/.ssh/id_rsa.pub
env:
SECRET_KEY: ${{ secrets.SECRET_KEY }}
- uses: azure/setup-kubectl@v3
- uses: azure/setup-kubectl@901a10e89ea615cf61f57ac05cecdf23e7de06d8 # v3.2
if: inputs.TYPE == 'k8s'
# Remove infra
- run: kubectl delete daemonsets,replicasets,services,deployments,pods,rc,ingress,statefulsets --all --all-namespaces --timeout=60s ; kubectl delete pvc --all --timeout=60s ; kubectl delete pv --all --timeout=60s

View file

@ -25,9 +25,9 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Login to ghcr
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@ -43,7 +43,7 @@ jobs:
if: inputs.TYPE == 'swarm'
- name: Install test dependencies
run: pip3 install --no-cache-dir --require-hashes -r tests/requirements.txt
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
with:
name: tf-k8s
path: /tmp
@ -66,9 +66,9 @@ jobs:
REG_USER: ${{ github.actor }}
REG_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: inputs.TYPE == 'k8s'
- uses: azure/setup-kubectl@v3
- uses: azure/setup-kubectl@901a10e89ea615cf61f57ac05cecdf23e7de06d8 # v3.2
if: inputs.TYPE == 'k8s'
- uses: azure/setup-helm@v3
- uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5
if: inputs.TYPE == 'k8s'
- name: Pull BW linux ubuntu test image
if: inputs.TYPE == 'linux'

View file

@ -89,7 +89,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- id: set-matrix
run: |
tests=$(find ./tests/core/ -maxdepth 1 -mindepth 1 -type d -printf "%f\n" | jq -c --raw-input --slurp 'split("\n")| .[0:-1]')
@ -174,12 +174,12 @@ jobs:
packages: write
steps:
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to ghcr
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -16,9 +16,9 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Set up Python 3.11
uses: actions/setup-python@v4
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
with:
python-version: "3.11"
cache: "pip"
@ -34,7 +34,7 @@ jobs:
sudo chmod 755 /opt/firefox /opt/firefox/firefox
rm -f firefox-setup.tar.bz2
- name: Download geckodriver
uses: nick-fields/retry@v2
uses: nick-fields/retry@14672906e672a08bd6eeb15720e9ed3ce869cdd4 # v2.9.0
with:
max_attempts: 3
timeout_minutes: 20
@ -45,7 +45,7 @@ jobs:
sudo chmod +x /usr/local/bin/geckodriver
rm -f geckodriver.tar.gz
- name: Login to ghcr
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -16,9 +16,9 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Login to ghcr
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -13,9 +13,9 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Set up Python 3.11
uses: actions/setup-python@v4
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
with:
python-version: "3.11"
cache: "pip"
@ -31,7 +31,7 @@ jobs:
sudo chmod 755 /opt/firefox /opt/firefox/firefox
rm -f firefox-setup.tar.bz2
- name: Download geckodriver
uses: nick-fields/retry@v2
uses: nick-fields/retry@14672906e672a08bd6eeb15720e9ed3ce869cdd4 # v2.9.0
with:
max_attempts: 3
timeout_minutes: 20
@ -42,7 +42,7 @@ jobs:
sudo chmod +x /usr/local/bin/geckodriver
rm -f geckodriver.tar.gz
- name: Login to ghcr
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -12,9 +12,9 @@ jobs:
steps:
# Prepare
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Login to ghcr
uses: docker/login-action@v3
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}

View file

@ -3,26 +3,52 @@
exclude: (^LICENSE.md$|^src/VERSION$|^src/(bw/misc/root-ca.pem$|deps/src/|common/core/modsecurity/files|ui/static/js/(editor/|utils/purify/|tsparticles\.bundle\.min\.js))|\.(svg|drawio|patch\d?|ascii|tf|tftpl)$)
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: f71fa2c1f9cf5cb705f73dffe4b21f7c61470ba9 # frozen: v4.4.0
hooks:
- id: check-case-conflict
- id: detect-private-key
- id: end-of-file-fixer
- id: requirements-txt-fixer
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
exclude: ^(mkdocs.yml|examples/bigbluebutton/docker-compose.yml)$
args: ["--allow-multiple-documents"]
- id: check-case-conflict
- repo: https://github.com/ambv/black
rev: 23.9.1
rev: e87737140f32d3cd7c44ede75f02dcd58e55820e # frozen: 23.9.1
hooks:
- id: black
name: Black Python Formatter
language_version: python3.9
- repo: https://github.com/pre-commit/mirrors-prettier
rev: fc260393cc4ec09f8fc0a5ba4437f481c8b55dc1 # frozen: v3.0.3
hooks:
- id: prettier
name: Prettier Code Formatter
- repo: https://github.com/pycqa/flake8
rev: 10f4af6dbcf93456ba7df762278ae61ba3120dc6 # frozen: 6.1.0
hooks:
- id: flake8
name: Flake8 Python Linter
args: ["--max-line-length=250", "--ignore=E266,E402,E722,W503"]
- repo: https://github.com/codespell-project/codespell
rev: 6e41aba91fb32e9feb741a6258eefeb9c6e4a482 # frozen: v2.2.6
hooks:
- id: codespell
name: Codespell Spell Checker
exclude: (^src/(common/core/.+/files|bw/loading)/.+.html|modsecurity-rules.conf.*)$
entry: codespell --ignore-regex="(tabEl|Widgits)" --skip src/ui/static/js/utils/flatpickr.js,CHANGELOG.md
language: python
types: [text]
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
rev: b813e6fe08b87541cb77296359ba1b7a50a00c98 # frozen: v8.18.0
hooks:
- id: gitleaks
- repo: https://github.com/koalaman/shellcheck-precommit
rev: v0.9.0
rev: 3f77b826548d8dc2d26675f077361c92773b50a7 # frozen: v0.9.0
hooks:
- id: shellcheck

View file

@ -7,6 +7,7 @@ src/deps/src/
mkdocs.yml
CHANGELOG.md
CONTRIBUTING.md
CODE_OF_CONDUCT.md
LICENSE.md
README.md
SECURITY.md

View file

@ -7,9 +7,14 @@
- [BUGFIX] Fix UI clearing configs folder at startup
- [BUGFIX] Fix Database not clearing old services when not using multisite
- [BUGFIX] Fix UI using the wrong database when generating the new config when using an external database
- [BUGFIX] Small fixes on linux paths creating unnecessary folders
- [BUGFIX] Fix ACME renewal fails on redirection enabled Service
- [MISC] Updated core dependencies
- [MISC] Updated self-signed job to regenerate the cert if the subject or the expiration date has changed
- [MISC] Jobs that download files from urls will now remove old cached files if urls are empty
- [MISC] Replaced gevent with gthread in UI for security reasons
- [MISC] Add HTML sanitization when injecting code in pages in the UI
- [MISC] Optimize the way the UI handles services creation and edition
## v1.5.2 - 2023/10/10

View file

@ -335,10 +335,10 @@ Please contact us at [contact@bunkerity.com](mailto:contact@bunkerity.com) if yo
## Community
To get free community support you can use the following medias :
To get free community support you can use the following media :
* The #help channel of BunkerWeb in the [Discord server](https://discord.com/invite/fTf46FmtyD)
* The help category of [GitHub dicussions](https://github.com/bunkerity/bunkerweb/discussions)
* The help category of [GitHub discussions](https://github.com/bunkerity/bunkerweb/discussions)
* The [/r/BunkerWeb](https://www.reddit.com/r/BunkerWeb) subreddit
* The [Server Fault](https://serverfault.com/) and [Super User](https://superuser.com/) forums

View file

@ -17,10 +17,10 @@ Please contact us at [contact@bunkerity.com](mailto:contact@bunkerity.com) if yo
## Where to get community support ?
To get free community support, you can use the following medias :
To get free community support, you can use the following media :
- The #help channel of BunkerWeb in the [Discord server](https://discord.com/invite/fTf46FmtyD)
- The help category of [GitHub dicussions](https://github.com/bunkerity/bunkerweb/discussions)
- The help category of [GitHub discussions](https://github.com/bunkerity/bunkerweb/discussions)
- The [/r/BunkerWeb](https://www.reddit.com/r/BunkerWeb) subreddit
- The [Server Fault](https://serverfault.com/) and [Super User](https://superuser.com/) forums

View file

@ -1,7 +1,7 @@
# Concepts
<figure markdown>
![Overwiew](assets/img/concepts.svg){ align=center, width="600" }
![Overview](assets/img/concepts.svg){ align=center, width="600" }
</figure>
## Integrations

View file

@ -14,7 +14,7 @@ def print_md_table(settings) -> MarkdownTableWriter:
f"`{setting}`",
"" if data["default"] == "" else f"`{data['default']}`",
data["context"],
"no" if not "multiple" in data else "yes",
"no" if "multiple" not in data else "yes",
data["help"],
]
for setting, data in settings.items()
@ -42,15 +42,19 @@ print(
file=doc,
)
print(
"This section contains the full list of settings supported by BunkerWeb. If you are not yet familiar with BunkerWeb, you should first read the [concepts](concepts.md) section of the documentation. Please follow the instructions for your own [integration](integrations.md) on how to apply the settings.\n",
"This section contains the full list of settings supported by BunkerWeb."
+ " If you are not yet familiar with BunkerWeb, you should first read the [concepts](concepts.md) section of the documentation."
+ " Please follow the instructions for your own [integration](integrations.md) on how to apply the settings.\n",
file=doc,
)
print(
"As a general rule when multisite mode is enabled, if you want to apply settings with multisite context to a specific server, you will need to add the primary (first) server name as a prefix like `www.example.com_USE_ANTIBOT=captcha` or `myapp.example.com_USE_GZIP=yes` for example.\n",
"As a general rule when multisite mode is enabled, if you want to apply settings with multisite context to a specific server, you will need to add the primary"
+ " (first) server name as a prefix like `www.example.com_USE_ANTIBOT=captcha` or `myapp.example.com_USE_GZIP=yes` for example.\n",
file=doc,
)
print(
'When settings are considered as "multiple", it means that you can have multiple groups of settings for the same feature by adding numbers as suffix like `REVERSE_PROXY_URL_1=/subdir`, `REVERSE_PROXY_HOST_1=http://myhost1`, `REVERSE_PROXY_URL_2=/anotherdir`, `REVERSE_PROXY_HOST_2=http://myhost2`, ... for example.\n',
'When settings are considered as "multiple", it means that you can have multiple groups of settings for the same feature by adding numbers as suffix like `REVERSE_PROXY_URL_1=/subdir`,'
+ " `REVERSE_PROXY_HOST_1=http://myhost1`, `REVERSE_PROXY_URL_2=/anotherdir`, `REVERSE_PROXY_HOST_2=http://myhost2`, ... for example.\n",
file=doc,
)

View file

@ -106,7 +106,7 @@ The first step is to install the plugin by putting the plugin files inside the c
When using the [Swarm integration](integrations.md#swarm), plugins must be written to the volume mounted on `/data/plugins` into the scheduler container.
!!! info "Swarm volume"
Configuring a Swarm volume that will persist when the scheduler service is running on different nodes is not covered is in this documentation. We will assume that you have a shared folder mounted on `/shared` accross all nodes.
Configuring a Swarm volume that will persist when the scheduler service is running on different nodes is not covered is in this documentation. We will assume that you have a shared folder mounted on `/shared` across all nodes.
The first thing to do is to create the plugins folder :
@ -460,7 +460,7 @@ Some helpers modules provide common helpful helpers :
- `self.logger` : print logs
- `bunkerweb.utils` : various useful functions
- `bunkerweb.datastore` : access the global shared data on one instance (key/value store)
- `bunkerweb.clusterstore` : access a Redis data store shared beetween BunkerWeb instances (key/value store)
- `bunkerweb.clusterstore` : access a Redis data store shared between BunkerWeb instances (key/value store)
To access the functions, you first need to **require** the modules :

View file

@ -2322,7 +2322,7 @@ BunkerWeb supports PHP using external or remote [PHP-FPM](https://www.php.net/ma
!!! warning "Feature is in beta"
This feature is not production-ready. Feel free to test it and report us any bug using [issues](https://github.com/bunkerity/bunkerweb/issues) in the GitHub repository.
By default, BunkerWeb will only listen on IPv4 adresses and won't use IPv6 for network communications. If you want to enable IPv6 support, you need to set `USE_IPV6=yes`. Please note that IPv6 configuration of your network and environment is out-of-the-scope of this documentation.
By default, BunkerWeb will only listen on IPv4 addresses and won't use IPv6 for network communications. If you want to enable IPv6 support, you need to set `USE_IPV6=yes`. Please note that IPv6 configuration of your network and environment is out-of-the-scope of this documentation.
=== "Docker"

View file

@ -4,9 +4,9 @@
#
# pip-compile --allow-unsafe --generate-hashes --strip-extras requirements.in
#
babel==2.12.1 \
--hash=sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610 \
--hash=sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455
babel==2.13.0 \
--hash=sha256:04c3e2d28d2b7681644508f836be388ae49e0cfe91465095340395b60d00f210 \
--hash=sha256:fbfcae1575ff78e26c7449136f1abbefc3c13ce542eeb13d43d50d8b047216ec
# via mkdocs-material
certifi==2023.7.22 \
--hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \
@ -267,9 +267,9 @@ pathvalidate==3.2.0 \
--hash=sha256:5e8378cf6712bff67fbe7a8307d99fa8c1a0cb28aa477056f8fc374f0dff24ad \
--hash=sha256:cc593caa6299b22b37f228148257997e2fa850eea2daf7e4cc9205cef6908dee
# via pytablewriter
platformdirs==3.10.0 \
--hash=sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d \
--hash=sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d
platformdirs==3.11.0 \
--hash=sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3 \
--hash=sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e
# via mkdocs
pygments==2.16.1 \
--hash=sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692 \
@ -353,95 +353,95 @@ pyyaml-env-tag==0.1 \
--hash=sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb \
--hash=sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069
# via mkdocs
regex==2023.8.8 \
--hash=sha256:0085da0f6c6393428bf0d9c08d8b1874d805bb55e17cb1dfa5ddb7cfb11140bf \
--hash=sha256:06c57e14ac723b04458df5956cfb7e2d9caa6e9d353c0b4c7d5d54fcb1325c46 \
--hash=sha256:09b7f4c66aa9d1522b06e31a54f15581c37286237208df1345108fcf4e050c18 \
--hash=sha256:0c59122ceccb905a941fb23b087b8eafc5290bf983ebcb14d2301febcbe199c7 \
--hash=sha256:1005c60ed7037be0d9dea1f9c53cc42f836188227366370867222bda4c3c6bd7 \
--hash=sha256:14898830f0a0eb67cae2bbbc787c1a7d6e34ecc06fbd39d3af5fe29a4468e2c9 \
--hash=sha256:14dc6f2d88192a67d708341f3085df6a4f5a0c7b03dec08d763ca2cd86e9f559 \
--hash=sha256:1e7d84d64c84ad97bf06f3c8cb5e48941f135ace28f450d86af6b6512f1c9a71 \
--hash=sha256:2162ae2eb8b079622176a81b65d486ba50b888271302190870b8cc488587d280 \
--hash=sha256:22283c769a7b01c8ac355d5be0715bf6929b6267619505e289f792b01304d898 \
--hash=sha256:239c3c2a339d3b3ddd51c2daef10874410917cd2b998f043c13e2084cb191684 \
--hash=sha256:293352710172239bf579c90a9864d0df57340b6fd21272345222fb6371bf82b3 \
--hash=sha256:2ae54a338191e1356253e7883d9d19f8679b6143703086245fb14d1f20196be9 \
--hash=sha256:2e73e5243af12d9cd6a9d6a45a43570dbe2e5b1cdfc862f5ae2b031e44dd95a8 \
--hash=sha256:2e9216e0d2cdce7dbc9be48cb3eacb962740a09b011a116fd7af8c832ab116ca \
--hash=sha256:3026cbcf11d79095a32d9a13bbc572a458727bd5b1ca332df4a79faecd45281c \
--hash=sha256:3611576aff55918af2697410ff0293d6071b7e00f4b09e005d614686ac4cd57c \
--hash=sha256:3ae646c35cb9f820491760ac62c25b6d6b496757fda2d51be429e0e7b67ae0ab \
--hash=sha256:3b8e6ea6be6d64104d8e9afc34c151926f8182f84e7ac290a93925c0db004bfd \
--hash=sha256:3d370ff652323c5307d9c8e4c62efd1956fb08051b0e9210212bc51168b4ff56 \
--hash=sha256:3f7454aa427b8ab9101f3787eb178057c5250478e39b99540cfc2b889c7d0586 \
--hash=sha256:40f029d73b10fac448c73d6eb33d57b34607f40116e9f6e9f0d32e9229b147d7 \
--hash=sha256:423adfa872b4908843ac3e7a30f957f5d5282944b81ca0a3b8a7ccbbfaa06103 \
--hash=sha256:4873ef92e03a4309b3ccd8281454801b291b689f6ad45ef8c3658b6fa761d7ac \
--hash=sha256:48c640b99213643d141550326f34f0502fedb1798adb3c9eb79650b1ecb2f177 \
--hash=sha256:4ae594c66f4a7e1ea67232a0846649a7c94c188d6c071ac0210c3e86a5f92109 \
--hash=sha256:4b694430b3f00eb02c594ff5a16db30e054c1b9589a043fe9174584c6efa8033 \
--hash=sha256:51d8ea2a3a1a8fe4f67de21b8b93757005213e8ac3917567872f2865185fa7fb \
--hash=sha256:54de2619f5ea58474f2ac211ceea6b615af2d7e4306220d4f3fe690c91988a61 \
--hash=sha256:551ad543fa19e94943c5b2cebc54c73353ffff08228ee5f3376bd27b3d5b9800 \
--hash=sha256:5543c055d8ec7801901e1193a51570643d6a6ab8751b1f7dd9af71af467538bb \
--hash=sha256:5cd9cd7170459b9223c5e592ac036e0704bee765706445c353d96f2890e816c8 \
--hash=sha256:5ec4b3f0aebbbe2fc0134ee30a791af522a92ad9f164858805a77442d7d18570 \
--hash=sha256:67ecd894e56a0c6108ec5ab1d8fa8418ec0cff45844a855966b875d1039a2e34 \
--hash=sha256:6ab2ed84bf0137927846b37e882745a827458689eb969028af8032b1b3dac78e \
--hash=sha256:704f63b774218207b8ccc6c47fcef5340741e5d839d11d606f70af93ee78e4d4 \
--hash=sha256:7098c524ba9f20717a56a8d551d2ed491ea89cbf37e540759ed3b776a4f8d6eb \
--hash=sha256:7aed90a72fc3654fba9bc4b7f851571dcc368120432ad68b226bd593f3f6c0b7 \
--hash=sha256:7ce606c14bb195b0e5108544b540e2c5faed6843367e4ab3deb5c6aa5e681208 \
--hash=sha256:7eb95fe8222932c10d4436e7a6f7c99991e3fdd9f36c949eff16a69246dee2dc \
--hash=sha256:80b80b889cb767cc47f31d2b2f3dec2db8126fbcd0cff31b3925b4dc6609dcdb \
--hash=sha256:82cd0a69cd28f6cc3789cc6adeb1027f79526b1ab50b1f6062bbc3a0ccb2dbc3 \
--hash=sha256:83215147121e15d5f3a45d99abeed9cf1fe16869d5c233b08c56cdf75f43a504 \
--hash=sha256:88900f521c645f784260a8d346e12a1590f79e96403971241e64c3a265c8ecdb \
--hash=sha256:91129ff1bb0619bc1f4ad19485718cc623a2dc433dff95baadbf89405c7f6b57 \
--hash=sha256:920974009fb37b20d32afcdf0227a2e707eb83fe418713f7a8b7de038b870d0b \
--hash=sha256:9233ac249b354c54146e392e8a451e465dd2d967fc773690811d3a8c240ac601 \
--hash=sha256:941460db8fe3bd613db52f05259c9336f5a47ccae7d7def44cc277184030a116 \
--hash=sha256:942f8b1f3b223638b02df7df79140646c03938d488fbfb771824f3d05fc083a8 \
--hash=sha256:964b16dcc10c79a4a2be9f1273fcc2684a9eedb3906439720598029a797b46e6 \
--hash=sha256:9691a549c19c22d26a4f3b948071e93517bdf86e41b81d8c6ac8a964bb71e5a6 \
--hash=sha256:96979d753b1dc3b2169003e1854dc67bfc86edf93c01e84757927f810b8c3c93 \
--hash=sha256:987b9ac04d0b38ef4f89fbc035e84a7efad9cdd5f1e29024f9289182c8d99e09 \
--hash=sha256:988631b9d78b546e284478c2ec15c8a85960e262e247b35ca5eaf7ee22f6050a \
--hash=sha256:9a96edd79661e93327cfeac4edec72a4046e14550a1d22aa0dd2e3ca52aec921 \
--hash=sha256:9b7408511fca48a82a119d78a77c2f5eb1b22fe88b0d2450ed0756d194fe7a9a \
--hash=sha256:9dd6082f4e2aec9b6a0927202c85bc1b09dcab113f97265127c1dc20e2e32495 \
--hash=sha256:a2ad5add903eb7cdde2b7c64aaca405f3957ab34f16594d2b78d53b8b1a6a7d6 \
--hash=sha256:a8c65c17aed7e15a0c824cdc63a6b104dfc530f6fa8cb6ac51c437af52b481c7 \
--hash=sha256:aadf28046e77a72f30dcc1ab185639e8de7f4104b8cb5c6dfa5d8ed860e57236 \
--hash=sha256:b076da1ed19dc37788f6a934c60adf97bd02c7eea461b73730513921a85d4235 \
--hash=sha256:b2aeab3895d778155054abea5238d0eb9a72e9242bd4b43f42fd911ef9a13470 \
--hash=sha256:b82edc98d107cbc7357da7a5a695901b47d6eb0420e587256ba3ad24b80b7d0b \
--hash=sha256:b8a0ccc8f2698f120e9e5742f4b38dc944c38744d4bdfc427616f3a163dd9de5 \
--hash=sha256:b993b6f524d1e274a5062488a43e3f9f8764ee9745ccd8e8193df743dbe5ee61 \
--hash=sha256:bb34d1605f96a245fc39790a117ac1bac8de84ab7691637b26ab2c5efb8f228c \
--hash=sha256:bd3366aceedf274f765a3a4bc95d6cd97b130d1dda524d8f25225d14123c01db \
--hash=sha256:c12f6f67495ea05c3d542d119d270007090bad5b843f642d418eb601ec0fa7be \
--hash=sha256:c662a4cbdd6280ee56f841f14620787215a171c4e2d1744c9528bed8f5816c96 \
--hash=sha256:c884d1a59e69e03b93cf0dfee8794c63d7de0ee8f7ffb76e5f75be8131b6400a \
--hash=sha256:ca339088839582d01654e6f83a637a4b8194d0960477b9769d2ff2cfa0fa36d2 \
--hash=sha256:cd2b6c5dfe0929b6c23dde9624483380b170b6e34ed79054ad131b20203a1a63 \
--hash=sha256:ce0f9fbe7d295f9922c0424a3637b88c6c472b75eafeaff6f910494a1fa719ef \
--hash=sha256:cf0633e4a1b667bfe0bb10b5e53fe0d5f34a6243ea2530eb342491f1adf4f739 \
--hash=sha256:cf9273e96f3ee2ac89ffcb17627a78f78e7516b08f94dc435844ae72576a276e \
--hash=sha256:d909b5a3fff619dc7e48b6b1bedc2f30ec43033ba7af32f936c10839e81b9217 \
--hash=sha256:d9b6627408021452dcd0d2cdf8da0534e19d93d070bfa8b6b4176f99711e7f90 \
--hash=sha256:de35342190deb7b866ad6ba5cbcccb2d22c0487ee0cbb251efef0843d705f0d4 \
--hash=sha256:e51c80c168074faa793685656c38eb7a06cbad7774c8cbc3ea05552d615393d8 \
--hash=sha256:e6bd1e9b95bc5614a7a9c9c44fde9539cba1c823b43a9f7bc11266446dd568e3 \
--hash=sha256:e7a9aaa5a1267125eef22cef3b63484c3241aaec6f48949b366d26c7250e0357 \
--hash=sha256:e951d1a8e9963ea51efd7f150450803e3b95db5939f994ad3d5edac2b6f6e2b4 \
--hash=sha256:e9941a4ada58f6218694f382e43fdd256e97615db9da135e77359da257a7168b \
--hash=sha256:f0640913d2c1044d97e30d7c41728195fc37e54d190c5385eacb52115127b882 \
--hash=sha256:f0ccf3e01afeb412a1a9993049cb160d0352dba635bbca7762b2dc722aa5742a \
--hash=sha256:f2181c20ef18747d5f4a7ea513e09ea03bdd50884a11ce46066bb90fe4213675 \
--hash=sha256:f2200e00b62568cfd920127782c61bc1c546062a879cdc741cfcc6976668dfcf \
--hash=sha256:fcbdc5f2b0f1cd0f6a56cdb46fe41d2cce1e644e3b68832f3eeebc5fb0f7712e
regex==2023.10.3 \
--hash=sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a \
--hash=sha256:00e871d83a45eee2f8688d7e6849609c2ca2a04a6d48fba3dff4deef35d14f07 \
--hash=sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca \
--hash=sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58 \
--hash=sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54 \
--hash=sha256:0f649fa32fe734c4abdfd4edbb8381c74abf5f34bc0b3271ce687b23729299ed \
--hash=sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff \
--hash=sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528 \
--hash=sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9 \
--hash=sha256:16f8740eb6dbacc7113e3097b0a36065a02e37b47c936b551805d40340fb9971 \
--hash=sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14 \
--hash=sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af \
--hash=sha256:3367007ad1951fde612bf65b0dffc8fd681a4ab98ac86957d16491400d661302 \
--hash=sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec \
--hash=sha256:39807cbcbe406efca2a233884e169d056c35aa7e9f343d4e78665246a332f597 \
--hash=sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b \
--hash=sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd \
--hash=sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767 \
--hash=sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f \
--hash=sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6 \
--hash=sha256:4a3ee019a9befe84fa3e917a2dd378807e423d013377a884c1970a3c2792d293 \
--hash=sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be \
--hash=sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41 \
--hash=sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc \
--hash=sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29 \
--hash=sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964 \
--hash=sha256:58837f9d221744d4c92d2cf7201c6acd19623b50c643b56992cbd2b745485d3d \
--hash=sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a \
--hash=sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc \
--hash=sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55 \
--hash=sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af \
--hash=sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930 \
--hash=sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e \
--hash=sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d \
--hash=sha256:6f85739e80d13644b981a88f529d79c5bdf646b460ba190bffcaf6d57b2a9863 \
--hash=sha256:706e7b739fdd17cb89e1fbf712d9dc21311fc2333f6d435eac2d4ee81985098c \
--hash=sha256:741ba2f511cc9626b7561a440f87d658aabb3d6b744a86a3c025f866b4d19e7f \
--hash=sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e \
--hash=sha256:76066d7ff61ba6bf3cb5efe2428fc82aac91802844c022d849a1f0f53820502d \
--hash=sha256:7979b834ec7a33aafae34a90aad9f914c41fd6eaa8474e66953f3f6f7cbd4368 \
--hash=sha256:7eece6fbd3eae4a92d7c748ae825cbc1ee41a89bb1c3db05b5578ed3cfcfd7cb \
--hash=sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52 \
--hash=sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8 \
--hash=sha256:82fcc1f1cc3ff1ab8a57ba619b149b907072e750815c5ba63e7aa2e1163384a4 \
--hash=sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac \
--hash=sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e \
--hash=sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2 \
--hash=sha256:91dc1d531f80c862441d7b66c4505cd6ea9d312f01fb2f4654f40c6fdf5cc37a \
--hash=sha256:979c24cbefaf2420c4e377ecd1f165ea08cc3d1fbb44bdc51bccbbf7c66a2cb4 \
--hash=sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa \
--hash=sha256:9b98b7681a9437262947f41c7fac567c7e1f6eddd94b0483596d320092004533 \
--hash=sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b \
--hash=sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588 \
--hash=sha256:9fd88f373cb71e6b59b7fa597e47e518282455c2734fd4306a05ca219a1991b0 \
--hash=sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915 \
--hash=sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841 \
--hash=sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a \
--hash=sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988 \
--hash=sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292 \
--hash=sha256:b3ab05a182c7937fb374f7e946f04fb23a0c0699c0450e9fb02ef567412d2fa3 \
--hash=sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c \
--hash=sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f \
--hash=sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420 \
--hash=sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9 \
--hash=sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f \
--hash=sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0 \
--hash=sha256:bfe50b61bab1b1ec260fa7cd91106fa9fece57e6beba05630afe27c71259c59b \
--hash=sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037 \
--hash=sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b \
--hash=sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee \
--hash=sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c \
--hash=sha256:c55853684fe08d4897c37dfc5faeff70607a5f1806c8be148f1695be4a63414b \
--hash=sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353 \
--hash=sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051 \
--hash=sha256:cc3f1c053b73f20c7ad88b0d1d23be7e7b3901229ce89f5000a8399746a6e039 \
--hash=sha256:ce615c92d90df8373d9e13acddd154152645c0dc060871abf6bd43809673d20a \
--hash=sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b \
--hash=sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e \
--hash=sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5 \
--hash=sha256:dac37cf08fcf2094159922edc7a2784cfcc5c70f8354469f79ed085f0328ebdf \
--hash=sha256:dd829712de97753367153ed84f2de752b86cd1f7a88b55a3a775eb52eafe8a94 \
--hash=sha256:e54ddd0bb8fb626aa1f9ba7b36629564544954fff9669b15da3610c22b9a0991 \
--hash=sha256:e77c90ab5997e85901da85131fd36acd0ed2221368199b65f0d11bca44549711 \
--hash=sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a \
--hash=sha256:ef71561f82a89af6cfcbee47f0fabfdb6e63788a9258e913955d89fdd96902ab \
--hash=sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a \
--hash=sha256:f4f2ca6df64cbdd27f27b34f35adb640b5d2d77264228554e68deda54456eb11 \
--hash=sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48
# via mkdocs-material
requests==2.31.0 \
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
@ -465,16 +465,16 @@ tcolorpy==0.1.4 \
--hash=sha256:d0926480aa5012f34877d69fc3b670f207dc165674e68ad07458fa6ee5b12724 \
--hash=sha256:f0dceb1cb95e554cee63024b3cd2fd8d4628c568773de2d1e6b4f0478461901c
# via pytablewriter
typepy==1.3.1 \
--hash=sha256:892566bff279368d63f02901aba0a3ce78cd7a319ec1f2bf6c8baab3520207a3 \
--hash=sha256:dfc37b888d6eed8542208389efa60ec8454e06fd84b276b45b2e33897f9d7825
typepy==1.3.2 \
--hash=sha256:b69fd48b9f50cdb3809906eef36b855b3134ff66c8893a4f8580abddb0b39517 \
--hash=sha256:d5d1022a424132622993800f1d2cd16cfdb691ac4e3b9c325f0fcb37799db1ae
# via
# dataproperty
# pytablewriter
# tabledata
urllib3==2.0.5 \
--hash=sha256:13abf37382ea2ce6fb744d4dad67838eec857c9f4f57009891805e0b5e123594 \
--hash=sha256:ef16afa8ba34a1f989db38e1dbbe0c302e4289a47856990d0682e374563ce35e
urllib3==2.0.6 \
--hash=sha256:7a7c7003b000adf9e7ca2a377c9688bbc54ed41b985789ed576570342a375cd2 \
--hash=sha256:b19e1a85d206b56d7df1d5e683df4a7725252a964e3993648dd0fb5a1c157564
# via requests
verspec==0.1.0 \
--hash=sha256:741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31 \

View file

@ -284,4 +284,4 @@ If you have bots that need to access your website, the recommended way to avoid
## Timezone
When using container-based integrations, the timezone of the container may not match the one of the host machine. To resolve that, you can set the `TZ` environment variable to the timezone of your choice on your containers (e.g. `TZ=Europe/Paris`). You will find the list of timezone identifers [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List).
When using container-based integrations, the timezone of the container may not match the one of the host machine. To resolve that, you can set the `TZ` environment variable to the timezone of your choice on your containers (e.g. `TZ=Europe/Paris`). You will find the list of timezone identifiers [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List).

View file

@ -18,7 +18,7 @@ services:
REVERSE_PROXY_URL: "/"
REVERSE_PROXY_HOST: "http://mydrupal"
CUSTOM_CONF_MODSEC_CRS_drupal: 'SecAction "id:900130,phase:1,nolog,pass,t:none,setvar:tx.crs_exclusions_drupal=1"'
# Onces the installation is done, you can remove these lines
# Once the installation is done, you can remove these lines
LIMIT_REQ_URL_1: "/core/install.php"
LIMIT_REQ_RATE_1: "5r/s"
labels:
@ -75,6 +75,7 @@ volumes:
bw-data:
db-data:
networks:
bw-universe:
ipam:

View file

@ -18,7 +18,7 @@ services:
USE_REVERSE_PROXY: "yes"
REVERSE_PROXY_URL: "/"
REVERSE_PROXY_HOST: "http://myps"
# Onces the installation is done, you can remove these lines
# Once the installation is done, you can remove these lines
LIMIT_REQ_URL_1: "/install/index.php"
LIMIT_REQ_RATE_1: "8r/s"
labels:
@ -85,6 +85,7 @@ volumes:
ps-data:
db-data:
networks:
bw-universe:
ipam:

View file

@ -1,4 +1,4 @@
version: "3.5"
version: "3.5"
services:
bunkerweb:

View file

@ -2,7 +2,7 @@ site_name: BunkerWeb
site_url: https://docs.bunkerweb.io/
repo_url: https://github.com/bunkerity/bunkerweb
site_description: Make your web services secure by default.
copyright: Bunkerity
copyright: Copyright &copy; <script>document.write(new Date().getFullYear())</script> Bunkerity
#remote_branch: ?
#remote_name: ?
@ -49,7 +49,6 @@ markdown_extensions:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
copyright: Copyright &copy; <script>document.write(new Date().getFullYear())</script> Bunkerity
extra:
version:
provider: mike

View file

@ -8,6 +8,8 @@ authors = [
[tool.black]
py39 = true
line-length = 250
include = '\.pyi?$'
exclude = '''
/(
| \.git

View file

@ -2,7 +2,6 @@
from os import getenv
from time import sleep
from typing import Optional
from copy import deepcopy
from ConfigCaller import ConfigCaller # type: ignore
@ -25,13 +24,20 @@ class Config(ConfigCaller):
"modsec",
"modsec-crs",
]
self.__configs = {
config_type: {} for config_type in self._supported_config_types
}
self.__configs = {config_type: {} for config_type in self._supported_config_types}
self.__config = {}
self._db = Database(self.__logger)
def _update_settings(self):
plugins = self._db.get_plugins()
if not plugins:
self.__logger.error("No plugins in database, can't update settings...")
return
self._settings = {}
for plugin in plugins:
self._settings.update(plugin["settings"])
def __get_full_env(self) -> dict:
env_instances = {"SERVER_NAME": ""}
for instance in self.__instances:
@ -106,9 +112,7 @@ class Config(ConfigCaller):
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}"
)
self.__logger.error(f"An error occurred when checking for changes in the database : {curr_changes}")
elif not any(curr_changes.values()):
break
else:
@ -134,9 +138,7 @@ class Config(ConfigCaller):
# save custom configs to database
if "custom_configs" in changes:
err = self._db.save_custom_configs(
custom_configs, "autoconf", changed=False
)
err = self._db.save_custom_configs(custom_configs, "autoconf", changed=False)
if err:
success = False
self.__logger.error(
@ -146,8 +148,6 @@ class Config(ConfigCaller):
# update changes in db
ret = self._db.checked_changes(changes, value=True)
if ret:
self.__logger.error(
f"An error occurred when setting the changes to checked in the database : {ret}"
)
self.__logger.error(f"An error occurred when setting the changes to checked in the database : {ret}")
return success

View file

@ -1,9 +1,9 @@
#!/usr/bin/python3
from abc import ABC, abstractmethod
from abc import abstractmethod
from os import getenv
from time import sleep
from typing import Literal, Optional, Union
from typing import Literal, Union
from Config import Config
@ -20,12 +20,8 @@ class Controller(Config):
self._type = ctrl_type
self._instances = []
self._services = []
self._configs = {
config_type: {} for config_type in self._supported_config_types
}
self._logger = setup_logger(
f"{self._type}-controller", getenv("LOG_LEVEL", "INFO")
)
self._configs = {config_type: {} for config_type in self._supported_config_types}
self._logger = setup_logger(f"{self._type}-controller", getenv("LOG_LEVEL", "INFO"))
def wait(self, wait_time: int) -> list:
all_ready = False
@ -105,7 +101,7 @@ class Controller(Config):
def _is_service_present(self, server_name):
for service in self._services:
if not "SERVER_NAME" in service or not service["SERVER_NAME"]:
if "SERVER_NAME" not in service or not service["SERVER_NAME"]:
continue
if server_name == service["SERVER_NAME"].strip().split(" ")[0]:
return True

View file

@ -13,9 +13,7 @@ class DockerController(Controller):
def __init__(self, docker_host):
super().__init__("docker")
self.__client = DockerClient(base_url=docker_host)
self.__custom_confs_rx = re_compile(
r"^bunkerweb.CUSTOM_CONF_(SERVER_HTTP|MODSEC_CRS|MODSEC)_(.+)$"
)
self.__custom_confs_rx = re_compile(r"^bunkerweb.CUSTOM_CONF_(SERVER_HTTP|MODSEC_CRS|MODSEC)_(.+)$")
def _get_controller_instances(self) -> List[Container]:
return self.__client.containers.list(filters={"label": "bunkerweb.INSTANCE"})
@ -27,10 +25,7 @@ class DockerController(Controller):
instance = {}
instance["name"] = controller_instance.name
instance["hostname"] = controller_instance.name
instance["health"] = (
controller_instance.status == "running"
and controller_instance.attrs["State"]["Health"]["Status"] == "healthy"
)
instance["health"] = controller_instance.status == "running" and controller_instance.attrs["State"]["Health"]["Status"] == "healthy"
instance["env"] = {}
for env in controller_instance.attrs["Config"]["Env"]:
variable = env.split("=")[0]
@ -53,9 +48,7 @@ class DockerController(Controller):
def _get_static_services(self) -> List[dict]:
services = []
variables = {}
for instance in self.__client.containers.list(
filters={"label": "bunkerweb.INSTANCE"}
):
for instance in self.__client.containers.list(filters={"label": "bunkerweb.INSTANCE"}):
if not instance.attrs or not instance.attrs.get("Config", {}).get("Env"):
continue
@ -70,9 +63,7 @@ class DockerController(Controller):
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"
):
if prefix == server_name and self._is_setting_context(real_variable, "multisite"):
service[real_variable] = value
services.append(service)
return services
@ -80,9 +71,7 @@ class DockerController(Controller):
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
for container in self.__client.containers.list(
filters={"label": "bunkerweb.SERVER_NAME"}
):
for container in self.__client.containers.list(filters={"label": "bunkerweb.SERVER_NAME"}):
labels = container.labels # type: ignore (labels is inside a container)
if isinstance(labels, list):
labels = {label: "" for label in labels}
@ -100,9 +89,7 @@ class DockerController(Controller):
result = self.__custom_confs_rx.search(variable)
if result is None:
continue
configs[result.group(1).lower().replace("_", "-")][
f"{server_name}/{result.group(2)}"
] = value
configs[result.group(1).lower().replace("_", "-")][f"{server_name}/{result.group(2)}"] = value
return configs
def apply_config(self) -> bool:
@ -117,16 +104,13 @@ class DockerController(Controller):
self._set_autoconf_load_db()
for _ in self.__client.events(decode=True, filters={"type": "container"}):
try:
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
):
if not self.update_needed(self._instances, self._services, configs=self._configs):
continue
self._logger.info(
"Caught Docker event, deploying new configuration ..."
)
self._logger.info("Caught Docker event, deploying new configuration ...")
if not self.apply_config():
self._logger.error("Error while deploying new configuration")
else:
@ -136,6 +120,4 @@ class DockerController(Controller):
self._set_autoconf_load_db()
except:
self._logger.error(
f"Exception while processing events :\n{format_exc()}"
)
self._logger.error(f"Exception while processing events :\n{format_exc()}")

View file

@ -1,4 +1,4 @@
FROM python:3.11.5-alpine@sha256:cd311c6a0164f34a7edbf364e05258b07d66d3f7bc155139dcb9bef88a186ded AS builder
FROM python:3.12.0-alpine@sha256:ae35274f417fc81ba6ee1fc84206e8517f28117566ee6a04a64f004c1409bdac AS builder
# Copy python requirements
COPY src/deps/requirements.txt /tmp/requirements-deps.txt
@ -34,7 +34,7 @@ COPY src/common/helpers helpers
COPY src/common/settings.json settings.json
COPY src/common/utils utils
FROM python:3.11.5-alpine@sha256:cd311c6a0164f34a7edbf364e05258b07d66d3f7bc155139dcb9bef88a186ded
FROM python:3.12.0-alpine@sha256:ae35274f417fc81ba6ee1fc84206e8517f28117566ee6a04a64f004c1409bdac
# Set default umask to prevent huge recursive chmod increasing the final image size
RUN umask 027

View file

@ -19,21 +19,12 @@ class IngressController(Controller):
self.__networkingv1 = client.NetworkingV1Api()
def _get_controller_instances(self) -> list:
return [
pod
for pod in self.__corev1.list_pod_for_all_namespaces(watch=False).items
if (
pod.metadata.annotations
and "bunkerweb.io/INSTANCE" in pod.metadata.annotations
)
]
return [pod for pod in self.__corev1.list_pod_for_all_namespaces(watch=False).items if (pod.metadata.annotations and "bunkerweb.io/INSTANCE" in pod.metadata.annotations)]
def _to_instances(self, controller_instance) -> List[dict]:
instance = {}
instance["name"] = controller_instance.metadata.name
instance["hostname"] = (
controller_instance.status.pod_ip or controller_instance.metadata.name
)
instance["hostname"] = controller_instance.status.pod_ip or controller_instance.metadata.name
health = False
if controller_instance.status.conditions:
for condition in controller_instance.status.conditions:
@ -48,9 +39,7 @@ class IngressController(Controller):
pod = container
break
if not pod:
self._logger.warning(
f"Missing container bunkerweb in pod {controller_instance.metadata.name}"
)
self._logger.warning(f"Missing container bunkerweb in pod {controller_instance.metadata.name}")
else:
for env in pod.env:
instance["env"][env.name] = env.value or ""
@ -159,10 +148,7 @@ class IngressController(Controller):
services = []
variables = {}
for instance in self.__corev1.list_pod_for_all_namespaces(watch=False).items:
if (
not instance.metadata.annotations
or not "bunkerweb.io/INSTANCE" in instance.metadata.annotations
):
if not instance.metadata.annotations or "bunkerweb.io/INSTANCE" not in instance.metadata.annotations:
continue
pod = None
@ -181,22 +167,15 @@ class IngressController(Controller):
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"
):
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:
if (
not configmap.metadata.annotations
or "bunkerweb.io/CONFIG_TYPE" not in configmap.metadata.annotations
):
for configmap in self.__corev1.list_config_map_for_all_namespaces(watch=False).items:
if not configmap.metadata.annotations or "bunkerweb.io/CONFIG_TYPE" not in configmap.metadata.annotations:
continue
config_type = configmap.metadata.annotations["bunkerweb.io/CONFIG_TYPE"]
@ -212,16 +191,12 @@ class IngressController(Controller):
continue
config_site = ""
if "bunkerweb.io/CONFIG_SITE" in configmap.metadata.annotations:
if not self._is_service_present(
configmap.metadata.annotations["bunkerweb.io/CONFIG_SITE"]
):
if not self._is_service_present(configmap.metadata.annotations["bunkerweb.io/CONFIG_SITE"]):
self._logger.warning(
f"Ignoring config {configmap.metadata.name} because {configmap.metadata.annotations['bunkerweb.io/CONFIG_SITE']} doesn't exist",
)
continue
config_site = (
f"{configmap.metadata.annotations['bunkerweb.io/CONFIG_SITE']}/"
)
config_site = f"{configmap.metadata.annotations['bunkerweb.io/CONFIG_SITE']}/"
for config_name, config_data in configmap.data.items():
configs[config_type][f"{config_site}{config_name}"] = config_data
return configs
@ -247,17 +222,16 @@ class IngressController(Controller):
for _ in w.stream(what):
self.__internal_lock.acquire()
locked = True
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
):
if not self.update_needed(self._instances, self._services, configs=self._configs):
self.__internal_lock.release()
locked = False
continue
self._logger.info(
f"Catched kubernetes event ({watch_type}), deploying new configuration ...",
f"Caught kubernetes event ({watch_type}), deploying new configuration ...",
)
try:
ret = self.apply_config()
@ -308,10 +282,7 @@ class IngressController(Controller):
def process_events(self):
self._set_autoconf_load_db()
watch_types = ("pod", "ingress", "configmap", "service")
threads = [
Thread(target=self.__watch, args=(watch_type,))
for watch_type in watch_types
]
threads = [Thread(target=self.__watch, args=(watch_type,)) for watch_type in watch_types]
for thread in threads:
thread.start()
for thread in threads:

View file

@ -26,9 +26,7 @@ class SwarmController(Controller):
def _to_instances(self, controller_instance) -> List[dict]:
instances = []
instance_env = {}
for env in controller_instance.attrs["Spec"]["TaskTemplate"]["ContainerSpec"][
"Env"
]:
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):
@ -61,12 +59,8 @@ class SwarmController(Controller):
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"):
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"]:
@ -80,9 +74,7 @@ class SwarmController(Controller):
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"
):
if prefix == server_name and self._is_setting_context(real_variable, "multisite"):
service[real_variable] = value
services.append(service)
return services
@ -91,15 +83,8 @@ class SwarmController(Controller):
configs = {}
for config_type in self._supported_config_types:
configs[config_type] = {}
for config in self.__client.configs.list(
filters={"label": "bunkerweb.CONFIG_TYPE"}
):
if (
not config.name
or not config.attrs
or not config.attrs.get("Spec", {}).get("Labels", {})
or not config.attrs.get("Spec", {}).get("Data", {})
):
for config in self.__client.configs.list(filters={"label": "bunkerweb.CONFIG_TYPE"}):
if not config.name or not config.attrs or not config.attrs.get("Spec", {}).get("Labels", {}) or not config.attrs.get("Spec", {}).get("Data", {}):
continue
config_type = config.attrs["Spec"]["Labels"]["bunkerweb.CONFIG_TYPE"]
@ -111,19 +96,13 @@ class SwarmController(Controller):
continue
config_site = ""
if "bunkerweb.CONFIG_SITE" in config.attrs["Spec"]["Labels"]:
if not self._is_service_present(
config.attrs["Spec"]["Labels"]["bunkerweb.CONFIG_SITE"]
):
if not self._is_service_present(config.attrs["Spec"]["Labels"]["bunkerweb.CONFIG_SITE"]):
self._logger.warning(
f"Ignoring config {config_name} because {config.attrs['Spec']['Labels']['bunkerweb.CONFIG_SITE']} doesn't exist",
)
continue
config_site = (
f"{config.attrs['Spec']['Labels']['bunkerweb.CONFIG_SITE']}/"
)
configs[config_type][f"{config_site}{config_name}"] = b64decode(
config.attrs["Spec"]["Data"]
)
config_site = f"{config.attrs['Spec']['Labels']['bunkerweb.CONFIG_SITE']}/"
configs[config_type][f"{config_site}{config_name}"] = b64decode(config.attrs["Spec"]["Data"])
return configs
def apply_config(self) -> bool:
@ -139,36 +118,27 @@ class SwarmController(Controller):
locked = False
error = False
try:
for _ in self.__client.events(
decode=True, filters={"type": event_type}
):
for _ in self.__client.events(decode=True, filters={"type": event_type}):
self.__internal_lock.acquire()
locked = True
try:
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
):
if not self.update_needed(self._instances, self._services, configs=self._configs):
self.__internal_lock.release()
locked = False
continue
self._logger.info(
f"Catched Swarm event ({event_type}), deploying new configuration ..."
)
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"
)
self._logger.error("Error while deploying new configuration")
else:
self._logger.info(
"Successfully deployed new configuration 🚀",
)
except:
self._logger.error(
f"Exception while processing Swarm event ({event_type}) :\n{format_exc()}"
)
self._logger.error(f"Exception while processing Swarm event ({event_type}) :\n{format_exc()}")
self.__internal_lock.release()
locked = False
except:
@ -187,10 +157,7 @@ class SwarmController(Controller):
def process_events(self):
self._set_autoconf_load_db()
event_types = ("service", "config")
threads = [
Thread(target=self.__event, args=(event_type,))
for event_type in event_types
]
threads = [Thread(target=self.__event, args=(event_type,)) for event_type in event_types]
for thread in threads:
thread.start()
for thread in threads:

View file

@ -7,10 +7,7 @@ from sys import exit as sys_exit, path as sys_path
from traceback import format_exc
from pathlib import Path
for deps_path in [
join(sep, "usr", "share", "bunkerweb", *paths)
for paths in (("deps", "python"), ("utils",), ("api",), ("db",))
]:
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",), ("api",), ("db",))]:
if deps_path not in sys_path:
sys_path.append(deps_path)

View file

@ -16,7 +16,7 @@ log "ENTRYPOINT" "" "Starting BunkerWeb v$(cat /usr/share/bunkerweb/VERSIO
# trap SIGTERM and SIGINT
function trap_exit() {
# shellcheck disable=SC2317
log "ENTRYPOINT" "" "Catched stop operation, stopping nginx ..."
log "ENTRYPOINT" "" "Caught stop operation, stopping nginx ..."
# shellcheck disable=SC2317
nginx -s stop
}
@ -25,7 +25,7 @@ trap "trap_exit" TERM INT QUIT
# trap SIGHUP
function trap_reload() {
# shellcheck disable=SC2317
log "ENTRYPOINT" "" "Catched reload operation"
log "ENTRYPOINT" "" "Caught reload operation"
# shellcheck disable=SC2317
if [ -f /var/run/bunkerweb/nginx.pid ] ; then
# shellcheck disable=SC2317

File diff suppressed because one or more lines are too long

View file

@ -20,7 +20,7 @@ function plugin:initialize(id, ctx)
end
end
self.is_request = multisite
-- Store common objets
-- Store common objects
self.logger = logger:new(self.id)
local use_redis, err = utils.get_variable("USE_REDIS", false)
if not use_redis then

View file

@ -64,17 +64,13 @@ class CLI(ApiCaller):
if redis_host:
redis_port = self.__variables.get("REDIS_PORT", "6379")
if not redis_port.isdigit():
self.__logger.error(
f"REDIS_PORT is not a valid port number: {redis_port}, defaulting to 6379"
)
self.__logger.error(f"REDIS_PORT is not a valid port number: {redis_port}, defaulting to 6379")
redis_port = "6379"
redis_port = int(redis_port)
redis_db = self.__variables.get("REDIS_DB", "0")
if not redis_db.isdigit():
self.__logger.error(
f"REDIS_DB is not a valid database number: {redis_db}, defaulting to 0"
)
self.__logger.error(f"REDIS_DB is not a valid database number: {redis_db}, defaulting to 0")
redis_db = "0"
redis_db = int(redis_db)
@ -83,18 +79,12 @@ class CLI(ApiCaller):
try:
redis_timeout = float(redis_timeout)
except ValueError:
self.__logger.error(
f"REDIS_TIMEOUT is not a valid timeout: {redis_timeout}, defaulting to 1000 ms"
)
self.__logger.error(f"REDIS_TIMEOUT is not a valid timeout: {redis_timeout}, defaulting to 1000 ms")
redis_timeout = 1000.0
redis_keepalive_pool = self.__variables.get(
"REDIS_KEEPALIVE_POOL", "10"
)
redis_keepalive_pool = self.__variables.get("REDIS_KEEPALIVE_POOL", "10")
if not redis_keepalive_pool.isdigit():
self.__logger.error(
f"REDIS_KEEPALIVE_POOL is not a valid number of connections: {redis_keepalive_pool}, defaulting to 10"
)
self.__logger.error(f"REDIS_KEEPALIVE_POOL is not a valid number of connections: {redis_keepalive_pool}, defaulting to 10")
redis_keepalive_pool = "10"
redis_keepalive_pool = int(redis_keepalive_pool)
@ -109,9 +99,7 @@ class CLI(ApiCaller):
ssl=self.__variables.get("REDIS_SSL", "no") == "yes",
)
else:
self.__logger.error(
"USE_REDIS is set to yes but REDIS_HOST is not set, disabling redis"
)
self.__logger.error("USE_REDIS is set to yes but REDIS_HOST is not set, disabling redis")
self.__use_redis = False
if not db_path.is_dir() or self.__integration not in (
@ -143,9 +131,7 @@ class CLI(ApiCaller):
return "autoconf"
elif integration_path.is_file():
return integration_path.read_text(encoding="utf-8").strip().lower()
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(
encoding="utf-8"
):
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(encoding="utf-8"):
return "docker"
return "linux"

View file

@ -6,10 +6,7 @@ from os.path import join
from sys import exit as sys_exit, path as sys_path
from traceback import format_exc
for deps_path in [
join(sep, "usr", "share", "bunkerweb", *paths)
for paths in (("deps", "python"), ("utils",), ("api",), ("db",))
]:
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",), ("api",), ("db",))]:
if deps_path not in sys_path:
sys_path.append(deps_path)
@ -25,9 +22,7 @@ if __name__ == "__main__":
subparsers = parser.add_subparsers(help="command", dest="command")
# Unban subparser
parser_unban = subparsers.add_parser(
"unban", help="remove a ban from the cache"
)
parser_unban = subparsers.add_parser("unban", help="remove a ban from the cache")
parser_unban.add_argument("ip", type=str, help="IP address to unban")
# Ban subparser

View file

@ -1,5 +1,5 @@
{-raw-}
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -1,5 +1,5 @@
{-raw-}
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -1,5 +1,5 @@
{-raw-}
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -1,5 +1,5 @@
{-raw-}
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -1,5 +1,5 @@
{-raw-}
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -10,10 +10,7 @@ from sys import exit as sys_exit, path as sys_path
from traceback import format_exc
from typing import Tuple
for deps_path in [
join(sep, "usr", "share", "bunkerweb", *paths)
for paths in (("deps", "python"), ("utils",), ("db",))
]:
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",), ("db",))]:
if deps_path not in sys_path:
sys_path.append(deps_path)
@ -63,10 +60,7 @@ try:
# Multisite case
if getenv("MULTISITE", "no") == "yes":
for first_server in getenv("SERVER_NAME", "").split(" "):
if (
getenv(f"{first_server}_USE_BLACKLIST", getenv("USE_BLACKLIST", "yes"))
== "yes"
):
if getenv(f"{first_server}_USE_BLACKLIST", getenv("USE_BLACKLIST", "yes")) == "yes":
blacklist_activated = True
break
# Singlesite case
@ -133,7 +127,7 @@ try:
blacklist_path.joinpath(f"{kind}.list").unlink(missing_ok=True)
deleted, err = del_file_in_db(f"{kind}.list", db)
if not deleted:
logger.warning(f"Coudn't delete {kind}.list from cache : {err}")
logger.warning(f"Couldn't delete {kind}.list from cache : {err}")
if all_fresh:
_exit(0)
@ -152,9 +146,7 @@ try:
resp = get(url, stream=True, timeout=10)
if resp.status_code != 200:
logger.warning(
f"Got status code {resp.status_code}, skipping..."
)
logger.warning(f"Got status code {resp.status_code}, skipping...")
continue
iterable = resp.iter_lines()
@ -203,9 +195,7 @@ try:
status = 1
except:
status = 2
logger.error(
f"Exception while getting blacklist from {url} :\n{format_exc()}"
)
logger.error(f"Exception while getting blacklist from {url} :\n{format_exc()}")
except:
status = 2

View file

@ -32,10 +32,7 @@ try:
# Multisite case
if getenv("MULTISITE", "no") == "yes":
for first_server in getenv("SERVER_NAME", "").split(" "):
if (
getenv(f"{first_server}_USE_BUNKERNET", getenv("USE_BUNKERNET", "yes"))
== "yes"
):
if getenv(f"{first_server}_USE_BUNKERNET", getenv("USE_BUNKERNET", "yes")) == "yes":
bunkernet_activated = True
break
# Singlesite case

View file

@ -19,10 +19,10 @@ for deps_path in [
if deps_path not in sys_path:
sys_path.append(deps_path)
from bunkernet import register, ping, get_id
from bunkernet import register, ping
from Database import Database # type: ignore
from logger import setup_logger # type: ignore
from jobs import get_file_in_db, set_file_in_db, del_file_in_db
from jobs import get_file_in_db, set_file_in_db, del_file_in_db # type: ignore
logger = setup_logger("BUNKERNET", getenv("LOG_LEVEL", "INFO"))
exit_status = 0
@ -38,10 +38,7 @@ try:
servers = servers.split(" ")
for first_server in servers:
if (
getenv(f"{first_server}_USE_BUNKERNET", getenv("USE_BUNKERNET", "yes"))
== "yes"
):
if getenv(f"{first_server}_USE_BUNKERNET", getenv("USE_BUNKERNET", "yes")) == "yes":
bunkernet_activated = True
break
# Singlesite case
@ -73,9 +70,7 @@ try:
logger.info("Registering instance on BunkerNet API ...")
ok, status, data = register()
if not ok:
logger.error(
f"Error while sending register request to BunkerNet API : {data}"
)
logger.error(f"Error while sending register request to BunkerNet API : {data}")
_exit(2)
elif status == 429:
logger.warning(
@ -102,23 +97,17 @@ try:
)
_exit(2)
elif data.get("result", "ko") != "ok":
logger.error(
f"Received error from BunkerNet API while sending register request : {data.get('data', {})}"
)
logger.error(f"Received error from BunkerNet API while sending register request : {data.get('data', {})}")
_exit(2)
bunkernet_id = data["data"]
instance_id_path.write_text(bunkernet_id, encoding="utf-8")
registered = True
exit_status = 1
logger.info(
f"Successfully registered on BunkerNet API with instance id {data['data']}"
)
logger.info(f"Successfully registered on BunkerNet API with instance id {data['data']}")
else:
bunkernet_id = bunkernet_id or instance_id_path.read_bytes()
bunkernet_id = bunkernet_id.decode()
logger.info(
f"Already registered on BunkerNet API with instance id {bunkernet_id}"
)
logger.info(f"Already registered on BunkerNet API with instance id {bunkernet_id}")
sleep(1)

View file

@ -6,9 +6,7 @@ from requests import request as requests_request, ReadTimeout
from typing import Literal, Optional, Tuple, Union
def request(
method: Union[Literal["POST"], Literal["GET"]], url: str, _id: Optional[str] = None
) -> Tuple[bool, Optional[int], Union[str, dict]]:
def request(method: Union[Literal["POST"], Literal["GET"]], url: str, _id: Optional[str] = None) -> Tuple[bool, Optional[int], Union[str, dict]]:
data = {"integration": get_integration(), "version": get_version()}
headers = {"User-Agent": f"BunkerWeb/{get_version()}"}
if _id is not None:
@ -51,19 +49,11 @@ def data() -> Tuple[bool, Optional[int], Union[str, dict]]:
def get_id() -> str:
return (
Path(sep, "var", "cache", "bunkerweb", "bunkernet", "instance.id")
.read_text(encoding="utf-8")
.strip()
)
return Path(sep, "var", "cache", "bunkerweb", "bunkernet", "instance.id").read_text(encoding="utf-8").strip()
def get_version() -> str:
return (
Path(sep, "usr", "share", "bunkerweb", "VERSION")
.read_text(encoding="utf-8")
.strip()
)
return Path(sep, "usr", "share", "bunkerweb", "VERSION").read_text(encoding="utf-8").strip()
def get_integration() -> str:
@ -78,9 +68,7 @@ def get_integration() -> str:
return "autoconf"
elif integration_path.is_file():
return integration_path.read_text(encoding="utf-8").strip().lower()
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(
encoding="utf-8"
):
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(encoding="utf-8"):
return "docker"
return "linux"

View file

@ -26,28 +26,20 @@ logger = setup_logger("CUSTOM-CERT", getenv("LOG_LEVEL", "INFO"))
db = None
def check_cert(
cert_path: str, key_path: str, first_server: Optional[str] = None
) -> bool:
def check_cert(cert_path: str, key_path: str, first_server: Optional[str] = None) -> bool:
try:
if not cert_path or not key_path:
logger.warning(
"Both variables CUSTOM_SSL_CERT and CUSTOM_SSL_KEY have to be set to use custom certificates"
)
logger.warning("Both variables CUSTOM_SSL_CERT and CUSTOM_SSL_KEY have to be set to use custom certificates")
return False
cert_path: Path = Path(normpath(cert_path))
key_path: Path = Path(normpath(key_path))
if not cert_path.is_file():
logger.warning(
f"Certificate file {cert_path} is not a valid file, ignoring the custom certificate"
)
logger.warning(f"Certificate file {cert_path} is not a valid file, ignoring the custom certificate")
return False
elif not key_path.is_file():
logger.warning(
f"Key file {key_path} is not a valid file, ignoring the custom certificate"
)
logger.warning(f"Key file {key_path} is not a valid file, ignoring the custom certificate")
return False
cert_cache_path = Path(
@ -66,9 +58,7 @@ def check_cert(
if old_hash == cert_hash:
return False
cached, err = cache_file(
cert_path, cert_cache_path, cert_hash, db, delete_file=False
)
cached, err = cache_file(cert_path, cert_cache_path, cert_hash, db, delete_file=False)
if not cached:
logger.error(f"Error while caching custom-cert cert.pem file : {err}")
@ -86,9 +76,7 @@ def check_cert(
key_hash = file_hash(key_path)
old_hash = cache_hash(key_cache_path, db)
if old_hash != key_hash:
cached, err = cache_file(
key_path, key_cache_path, key_hash, db, delete_file=False
)
cached, err = cache_file(key_path, key_cache_path, key_hash, db, delete_file=False)
if not cached:
logger.error(f"Error while caching custom-cert key.pem file : {err}")
@ -103,14 +91,10 @@ def check_cert(
status = 0
try:
Path(sep, "var", "cache", "bunkerweb", "customcert").mkdir(
parents=True, exist_ok=True
)
Path(sep, "var", "cache", "bunkerweb", "customcert").mkdir(parents=True, exist_ok=True)
if getenv("USE_CUSTOM_SSL", "no") == "yes" and getenv("SERVER_NAME", "") != "":
db = Database(
logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False
)
db = Database(logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False)
cert_path = getenv("CUSTOM_SSL_CERT", "")
key_path = getenv("CUSTOM_SSL_KEY", "")
@ -131,16 +115,11 @@ try:
servers = servers.split(" ")
for first_server in servers:
if not first_server or (
getenv(f"{first_server}_USE_CUSTOM_SSL", getenv("USE_CUSTOM_SSL", "no"))
!= "yes"
):
if not first_server or (getenv(f"{first_server}_USE_CUSTOM_SSL", getenv("USE_CUSTOM_SSL", "no")) != "yes"):
continue
if not db:
db = Database(
logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False
)
db = Database(logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False)
cert_path = getenv(f"{first_server}_CUSTOM_SSL_CERT", "")
key_path = getenv(f"{first_server}_CUSTOM_SSL_KEY", "")

View file

@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -10,10 +10,7 @@ from sys import exit as sys_exit, path as sys_path
from traceback import format_exc
from typing import Tuple
for deps_path in [
join(sep, "usr", "share", "bunkerweb", *paths)
for paths in (("deps", "python"), ("utils",), ("db",))
]:
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",), ("db",))]:
if deps_path not in sys_path:
sys_path.append(deps_path)
@ -63,10 +60,7 @@ try:
# Multisite case
if getenv("MULTISITE", "no") == "yes":
for first_server in getenv("SERVER_NAME", "").split(" "):
if (
getenv(f"{first_server}_USE_GREYLIST", getenv("USE_GREYLIST", "no"))
== "yes"
):
if getenv(f"{first_server}_USE_GREYLIST", getenv("USE_GREYLIST", "no")) == "yes":
greylist_activated = True
break
# Singlesite case
@ -117,7 +111,7 @@ try:
greylist_path.joinpath(f"{kind}.list").unlink(missing_ok=True)
deleted, err = del_file_in_db(f"{kind}.list", db)
if not deleted:
logger.warning(f"Coudn't delete {kind}.list from cache : {err}")
logger.warning(f"Couldn't delete {kind}.list from cache : {err}")
if all_fresh:
_exit(0)
@ -136,9 +130,7 @@ try:
resp = get(url, stream=True, timeout=10)
if resp.status_code != 200:
logger.warning(
f"Got status code {resp.status_code}, skipping..."
)
logger.warning(f"Got status code {resp.status_code}, skipping...")
continue
iterable = resp.iter_lines()
@ -187,9 +179,7 @@ try:
status = 1
except:
status = 2
logger.error(
f"Exception while getting greylist from {url} :\n{format_exc()}"
)
logger.error(f"Exception while getting greylist from {url} :\n{format_exc()}")
except:
status = 2

View file

@ -114,9 +114,7 @@ try:
with tar_open(fileobj=BytesIO(content), mode="r") as tar:
tar.extractall(path=temp_dir)
else:
logger.error(
f"Unknown file type for {plugin_url}, either zip or tar are supported, skipping..."
)
logger.error(f"Unknown file type for {plugin_url}, either zip or tar are supported, skipping...")
continue
except:
logger.error(

View file

@ -43,9 +43,7 @@ try:
with lock:
response = None
try:
response = get(
"https://db-ip.com/db/download/ip-to-asn-lite", timeout=5
)
response = get("https://db-ip.com/db/download/ip-to-asn-lite", timeout=5)
except RequestException:
logger.warning("Unable to check if asn.mmdb is the latest version")
@ -59,14 +57,10 @@ try:
_sha1.update(data)
if response.content.decode().find(_sha1.hexdigest()) != -1:
logger.info(
"asn.mmdb is already the latest version, skipping download..."
)
logger.info("asn.mmdb is already the latest version, skipping download...")
dl_mmdb = False
else:
logger.warning(
"Unable to check if asn.mmdb is the latest version, downloading it anyway..."
)
logger.warning("Unable to check if asn.mmdb is the latest version, downloading it anyway...")
db = Database(logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False)

View file

@ -43,9 +43,7 @@ try:
with lock:
response = None
try:
response = get(
"https://db-ip.com/db/download/ip-to-country-lite", timeout=5
)
response = get("https://db-ip.com/db/download/ip-to-country-lite", timeout=5)
except RequestException:
logger.warning("Unable to check if country.mmdb is the latest version")
@ -59,14 +57,10 @@ try:
_sha1.update(data)
if response.content.decode().find(_sha1.hexdigest()) != -1:
logger.info(
"country.mmdb is already the latest version, skipping download..."
)
logger.info("country.mmdb is already the latest version, skipping download...")
dl_mmdb = False
else:
logger.warning(
"Unable to check if country.mmdb is the latest version, downloading it anyway..."
)
logger.warning("Unable to check if country.mmdb is the latest version, downloading it anyway...")
db = Database(logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False)

View file

@ -39,9 +39,7 @@ try:
bw_integration = "Autoconf"
elif integration_path.is_file():
bw_integration = integration_path.read_text(encoding="utf-8").strip()
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(
encoding="utf-8"
):
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(encoding="utf-8"):
bw_integration = "Docker"
token = getenv("CERTBOT_TOKEN", "")
@ -49,9 +47,7 @@ try:
# Cluster case
if bw_integration in ("Docker", "Swarm", "Kubernetes", "Autoconf"):
db = Database(
logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False
)
db = Database(logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False)
lock = Lock()
with lock:
@ -69,9 +65,7 @@ try:
)
if not sent:
status = 1
logger.error(
f"Can't send API request to {api.endpoint}/lets-encrypt/challenge : {err}"
)
logger.error(f"Can't send API request to {api.endpoint}/lets-encrypt/challenge : {err}")
elif status != 200:
status = 1
logger.error(

View file

@ -39,18 +39,14 @@ try:
bw_integration = "Autoconf"
elif integration_path.is_file():
bw_integration = integration_path.read_text(encoding="utf-8").strip()
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(
encoding="utf-8"
):
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(encoding="utf-8"):
bw_integration = "Docker"
token = getenv("CERTBOT_TOKEN", "")
# Cluster case
if bw_integration in ("Docker", "Swarm", "Kubernetes", "Autoconf"):
db = Database(
logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False
)
db = Database(logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False)
lock = Lock()
with lock:
instances = db.get_instances()
@ -60,14 +56,10 @@ try:
f"http://{instance['hostname']}:{instance['port']}",
host=instance["server_name"],
)
sent, err, status, resp = api.request(
"DELETE", "/lets-encrypt/challenge", data={"token": token}
)
sent, err, status, resp = api.request("DELETE", "/lets-encrypt/challenge", data={"token": token})
if not sent:
status = 1
logger.error(
f"Can't send API request to {api.endpoint}/lets-encrypt/challenge : {err}"
)
logger.error(f"Can't send API request to {api.endpoint}/lets-encrypt/challenge : {err}")
elif status != 200:
status = 1
logger.error(

View file

@ -42,9 +42,7 @@ try:
bw_integration = "Autoconf"
elif integration_path.is_file():
bw_integration = integration_path.read_text(encoding="utf-8").strip()
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(
encoding="utf-8"
):
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(encoding="utf-8"):
bw_integration = "Docker"
token = getenv("CERTBOT_TOKEN", "")
@ -64,9 +62,7 @@ try:
tgz.seek(0, 0)
files = {"archive.tar.gz": tgz}
db = Database(
logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False
)
db = Database(logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False)
lock = Lock()
with lock:
@ -77,19 +73,13 @@ try:
host = instance["server_name"]
api = API(endpoint, host=host)
sent, err, status, resp = api.request(
"POST", "/lets-encrypt/certificates", files=files
)
sent, err, status, resp = api.request("POST", "/lets-encrypt/certificates", files=files)
if not sent:
status = 1
logger.error(
f"Can't send API request to {api.endpoint}/lets-encrypt/certificates : {err}"
)
logger.error(f"Can't send API request to {api.endpoint}/lets-encrypt/certificates : {err}")
elif status != 200:
status = 1
logger.error(
f"Error while sending API request to {api.endpoint}/lets-encrypt/certificates : status = {resp['status']}, msg = {resp['msg']}"
)
logger.error(f"Error while sending API request to {api.endpoint}/lets-encrypt/certificates : status = {resp['status']}, msg = {resp['msg']}")
else:
logger.info(
f"Successfully sent API request to {api.endpoint}/lets-encrypt/certificates",
@ -97,18 +87,12 @@ try:
sent, err, status, resp = api.request("POST", "/reload")
if not sent:
status = 1
logger.error(
f"Can't send API request to {api.endpoint}/reload : {err}"
)
logger.error(f"Can't send API request to {api.endpoint}/reload : {err}")
elif status != 200:
status = 1
logger.error(
f"Error while sending API request to {api.endpoint}/reload : status = {resp['status']}, msg = {resp['msg']}"
)
logger.error(f"Error while sending API request to {api.endpoint}/reload : status = {resp['status']}, msg = {resp['msg']}")
else:
logger.info(
f"Successfully sent API request to {api.endpoint}/reload"
)
logger.info(f"Successfully sent API request to {api.endpoint}/reload")
# Linux case
else:
if (

View file

@ -24,15 +24,13 @@ for deps_path in [
from Database import Database # type: ignore
from logger import setup_logger # type: ignore
from jobs import get_file_in_db, set_file_in_db
from jobs import get_file_in_db, set_file_in_db # type: ignore
logger = setup_logger("LETS-ENCRYPT.new", getenv("LOG_LEVEL", "INFO"))
status = 0
def certbot_new(
domains: str, email: str, letsencrypt_path: Path, letsencrypt_job_path: Path
) -> int:
def certbot_new(domains: str, email: str, letsencrypt_path: Path, letsencrypt_job_path: Path) -> int:
return run(
[
join(sep, "usr", "share", "bunkerweb", "deps", "python", "bin", "certbot"),
@ -60,8 +58,7 @@ def certbot_new(
+ (["--staging"] if getenv("USE_LETS_ENCRYPT_STAGING", "no") == "yes" else []),
stdin=DEVNULL,
stderr=STDOUT,
env=environ.copy()
| {"PYTHONPATH": join(sep, "usr", "share", "bunkerweb", "deps", "python")},
env=environ.copy() | {"PYTHONPATH": join(sep, "usr", "share", "bunkerweb", "deps", "python")},
).returncode
@ -81,8 +78,7 @@ def certbot_check_domains(domains: list[str], letsencrypt_path: Path) -> int:
stdout=PIPE,
stderr=STDOUT,
text=True,
env=environ.copy()
| {"PYTHONPATH": join(sep, "usr", "share", "bunkerweb", "deps", "python")},
env=environ.copy() | {"PYTHONPATH": join(sep, "usr", "share", "bunkerweb", "deps", "python")},
)
if proc.returncode != 0:
logger.error(f"Error while checking certificates :\n{proc.stdout}")
@ -91,10 +87,7 @@ def certbot_check_domains(domains: list[str], letsencrypt_path: Path) -> int:
needed_domains = set(domains)
for raw_domains in findall(r"^ Domains: (.*)$", proc.stdout, MULTILINE):
current_domains = raw_domains.split(" ")
if (
current_domains[0] == first_needed_domain
and set(current_domains) == needed_domains
):
if current_domains[0] == first_needed_domain and set(current_domains) == needed_domains:
return 1
return 0
@ -108,10 +101,7 @@ try:
use_letsencrypt = True
elif getenv("MULTISITE", "no") == "yes":
for first_server in getenv("SERVER_NAME", "").split(" "):
if (
first_server
and getenv(f"{first_server}_AUTO_LETS_ENCRYPT", "no") == "yes"
):
if first_server and getenv(f"{first_server}_AUTO_LETS_ENCRYPT", "no") == "yes":
use_letsencrypt = True
break
@ -123,12 +113,8 @@ try:
letsencrypt_path = Path(sep, "var", "cache", "bunkerweb", "letsencrypt")
letsencrypt_path.mkdir(parents=True, exist_ok=True)
letsencrypt_job_path = Path(
sep, "usr", "share", "bunkerweb", "core", "letsencrypt", "jobs"
)
Path(sep, "var", "lib", "bunkerweb", "letsencrypt").mkdir(
parents=True, exist_ok=True
)
letsencrypt_job_path = Path(sep, "usr", "share", "bunkerweb", "core", "letsencrypt", "jobs")
Path(sep, "var", "lib", "bunkerweb", "letsencrypt").mkdir(parents=True, exist_ok=True)
# Get env vars
bw_integration = "Linux"
@ -142,9 +128,7 @@ try:
bw_integration = "Autoconf"
elif integration_path.is_file():
bw_integration = integration_path.read_text(encoding="utf-8").strip()
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(
encoding="utf-8"
):
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(encoding="utf-8"):
bw_integration = "Docker"
# Extract letsencrypt folder if it exists in db
@ -209,9 +193,7 @@ try:
continue
else:
status = 1 if status == 0 else status
logger.info(
f"Certificate generation succeeded for domain(s) : {domains}"
)
logger.info(f"Certificate generation succeeded for domain(s) : {domains}")
# Singlesite case
elif getenv("AUTO_LETS_ENCRYPT", "no") == "yes" and getenv("SERVER_NAME"):
@ -243,9 +225,7 @@ try:
logger.error(f"Certificate generation failed for domain(s) : {domains}")
else:
status = 1
logger.info(
f"Certificate generation succeeded for domain(s) : {domains}"
)
logger.info(f"Certificate generation succeeded for domain(s) : {domains}")
# Put new folder in cache
bio = BytesIO()

View file

@ -1,6 +1,6 @@
#!/usr/bin/python3
from os import _exit, environ, getenv, listdir, sep
from os import _exit, environ, getenv, sep
from os.path import join
from pathlib import Path
from subprocess import DEVNULL, STDOUT, run
@ -23,7 +23,7 @@ for deps_path in [
from Database import Database # type: ignore
from logger import setup_logger # type: ignore
from jobs import get_file_in_db, set_file_in_db
from jobs import get_file_in_db, set_file_in_db # type: ignore
def renew(domain: str, letsencrypt_path: Path) -> int:
@ -53,8 +53,7 @@ def renew(domain: str, letsencrypt_path: Path) -> int:
],
stdin=DEVNULL,
stderr=STDOUT,
env=environ.copy()
| {"PYTHONPATH": join(sep, "usr", "share", "bunkerweb", "deps", "python")},
env=environ.copy() | {"PYTHONPATH": join(sep, "usr", "share", "bunkerweb", "deps", "python")},
check=False,
).returncode
@ -69,10 +68,7 @@ try:
use_letsencrypt = True
elif getenv("MULTISITE", "no") == "yes":
for first_server in getenv("SERVER_NAME", "").split(" "):
if (
first_server
and getenv(f"{first_server}_AUTO_LETS_ENCRYPT", "no") == "yes"
):
if first_server and getenv(f"{first_server}_AUTO_LETS_ENCRYPT", "no") == "yes":
use_letsencrypt = True
break
@ -83,9 +79,7 @@ try:
# Create directory if it doesn't exist
letsencrypt_path = Path(sep, "var", "cache", "bunkerweb", "letsencrypt")
letsencrypt_path.mkdir(parents=True, exist_ok=True)
Path(sep, "var", "lib", "bunkerweb", "letsencrypt").mkdir(
parents=True, exist_ok=True
)
Path(sep, "var", "lib", "bunkerweb", "letsencrypt").mkdir(parents=True, exist_ok=True)
# Get env vars
bw_integration = "Linux"
@ -99,9 +93,7 @@ try:
bw_integration = "Autoconf"
elif integration_path.is_file():
bw_integration = integration_path.read_text(encoding="utf-8").strip()
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(
encoding="utf-8"
):
elif os_release_path.is_file() and "Alpine" in os_release_path.read_text(encoding="utf-8"):
bw_integration = "Docker"
# Extract letsencrypt folder if it exists in db
@ -134,9 +126,7 @@ try:
getenv("AUTO_LETS_ENCRYPT", "no"),
)
!= "yes"
or not letsencrypt_path.joinpath(
"etc", "live", first_server, "cert.pem"
).exists()
or not letsencrypt_path.joinpath("etc", "live", first_server, "cert.pem").exists()
):
continue

View file

@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

View file

@ -35,10 +35,7 @@ try:
"AUTO_LETS_ENCRYPT",
"GENERATE_SELF_SIGNED_SSL",
):
if (
getenv(f"{first_server}_{check_var}", getenv(check_var, "no"))
== "yes"
):
if getenv(f"{first_server}_{check_var}", getenv(check_var, "no")) == "yes":
need_default_cert = True
break
if need_default_cert:
@ -99,9 +96,7 @@ try:
"Successfully generated self-signed certificate for default server",
)
db = Database(
logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False
)
db = Database(logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False)
cached, err = set_file_in_db(
"cert.pem",
@ -109,13 +104,9 @@ try:
db,
)
if not cached:
logger.error(
f"Error while saving default-server-cert cert.pem file to db cache : {err}"
)
logger.error(f"Error while saving default-server-cert cert.pem file to db cache : {err}")
else:
logger.info(
"Successfully saved default-server-cert cert.pem file to db cache"
)
logger.info("Successfully saved default-server-cert cert.pem file to db cache")
cached, err = set_file_in_db(
"cert.key",
@ -123,13 +114,9 @@ try:
db,
)
if not cached:
logger.error(
f"Error while saving default-server-cert cert.key file to db cache : {err}"
)
logger.error(f"Error while saving default-server-cert cert.key file to db cache : {err}")
else:
logger.info(
"Successfully saved default-server-cert cert.key file to db cache"
)
logger.info("Successfully saved default-server-cert cert.key file to db cache")
else:
logger.info(
"Skipping generation of self-signed certificate for default server (already present)",

View file

@ -23,9 +23,7 @@ logger = setup_logger("UPDATE-CHECK", getenv("LOG_LEVEL", "INFO"))
status = 0
try:
current_version = (
f"v{Path('/usr/share/bunkerweb/VERSION').read_text(encoding='utf-8').strip()}"
)
current_version = f"v{Path('/usr/share/bunkerweb/VERSION').read_text(encoding='utf-8').strip()}"
response = get(
"https://github.com/bunkerity/bunkerweb/releases/latest",

View file

@ -52,10 +52,7 @@ try:
servers = servers.split(" ")
for first_server in servers:
if (
getenv(f"{first_server}_USE_REAL_IP", getenv("USE_REAL_IP", "no"))
== "yes"
):
if getenv(f"{first_server}_USE_REAL_IP", getenv("USE_REAL_IP", "no")) == "yes":
realip_activated = True
break
@ -84,7 +81,7 @@ try:
tmp_realip_path.joinpath("combined.list").unlink(missing_ok=True)
deleted, err = del_file_in_db("combined.list", db)
if not deleted:
logger.warning(f"Coudn't delete combined.list from cache : {err}")
logger.warning(f"Couldn't delete combined.list from cache : {err}")
logger.info("RealIP list is already in cache, skipping download...")
_exit(0)
@ -118,9 +115,7 @@ try:
i += 1
except:
status = 2
logger.error(
f"Exception while getting RealIP list from {url} :\n{format_exc()}"
)
logger.error(f"Exception while getting RealIP list from {url} :\n{format_exc()}")
tmp_realip_path.joinpath("combined.list").write_bytes(content)

View file

@ -1,7 +1,9 @@
{% if REDIRECT_TO != "" +%}
{% if REDIRECT_TO_REQUEST_URI == "yes" +%}
return {{ REDIRECT_TO_STATUS_CODE }} {{ REDIRECT_TO }}$request_uri;
{% else +%}
return {{ REDIRECT_TO_STATUS_CODE }} {{ REDIRECT_TO }};
{% endif %}
location / {
{% if REDIRECT_TO_REQUEST_URI == "yes" +%}
return {{ REDIRECT_TO_STATUS_CODE }} {{ REDIRECT_TO }}$request_uri;
{% else +%}
return {{ REDIRECT_TO_STATUS_CODE }} {{ REDIRECT_TO }};
{% endif %}
}
{% endif %}

View file

@ -34,9 +34,7 @@ lock = Lock()
status = 0
def generate_cert(
first_server: str, days: str, subj: str, self_signed_path: Path
) -> Tuple[bool, int]:
def generate_cert(first_server: str, days: str, subj: str, self_signed_path: Path) -> Tuple[bool, int]:
if self_signed_path.joinpath(f"{first_server}.pem").is_file():
if (
run(
@ -61,19 +59,10 @@ def generate_cert(
self_signed_path.joinpath(f"{first_server}.pem").read_bytes(),
default_backend(),
)
if sorted(
attribute.rfc4514_string() for attribute in certificate.subject
) != sorted(v for v in subj.split("/") if v):
logger.warning(
f"Subject of self-signed certificate for {first_server} is different from the one in the configuration, regenerating ..."
)
elif (
certificate.not_valid_after - certificate.not_valid_before
!= timedelta(days=int(days))
):
logger.warning(
f"Expiration date of self-signed certificate for {first_server} is different from the one in the configuration, regenerating ..."
)
if sorted(attribute.rfc4514_string() for attribute in certificate.subject) != sorted(v for v in subj.split("/") if v):
logger.warning(f"Subject of self-signed certificate for {first_server} is different from the one in the configuration, regenerating ...")
elif certificate.not_valid_after - certificate.not_valid_before != timedelta(days=int(days)):
logger.warning(f"Expiration date of self-signed certificate for {first_server} is different from the one in the configuration, regenerating ...")
else:
return True, 0
@ -154,9 +143,7 @@ try:
continue
if not db:
db = Database(
logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False
)
db = Database(logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False)
ret, ret_status = generate_cert(
first_server,
@ -174,9 +161,7 @@ try:
# Singlesite case
elif getenv("GENERATE_SELF_SIGNED_SSL", "no") == "yes" and getenv("SERVER_NAME"):
db = Database(
logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False
)
db = Database(logger, sqlalchemy_string=getenv("DATABASE_URI", None), pool=False)
first_server = getenv("SERVER_NAME", "").split(" ")[0]
ret, ret_status = generate_cert(

View file

@ -10,10 +10,7 @@ from sys import exit as sys_exit, path as sys_path
from traceback import format_exc
from typing import Tuple
for deps_path in [
join(sep, "usr", "share", "bunkerweb", *paths)
for paths in (("deps", "python"), ("utils",), ("db",))
]:
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",), ("db",))]:
if deps_path not in sys_path:
sys_path.append(deps_path)
@ -63,14 +60,11 @@ try:
# Multisite case
if getenv("MULTISITE", "no") == "yes":
for first_server in getenv("SERVER_NAME", "").split(" "):
if (
getenv(f"{first_server}_USE_WHITELIST", getenv("USE_WHITELIST", "no"))
== "yes"
):
if getenv(f"{first_server}_USE_WHITELIST", getenv("USE_WHITELIST", "yes")) == "yes":
whitelist_activated = True
break
# Singlesite case
elif getenv("USE_WHITELIST", "no") == "yes":
elif getenv("USE_WHITELIST", "yes") == "yes":
whitelist_activated = True
if not whitelist_activated:
@ -117,7 +111,7 @@ try:
whitelist_path.joinpath(f"{kind}.list").unlink(missing_ok=True)
deleted, err = del_file_in_db(f"{kind}.list", db)
if not deleted:
logger.warning(f"Coudn't delete {kind}.list from cache : {err}")
logger.warning(f"Couldn't delete {kind}.list from cache : {err}")
if all_fresh:
_exit(0)
@ -136,9 +130,7 @@ try:
resp = get(url, stream=True, timeout=10)
if resp.status_code != 200:
logger.warning(
f"Got status code {resp.status_code}, skipping..."
)
logger.warning(f"Got status code {resp.status_code}, skipping...")
continue
iterable = resp.iter_lines()
@ -187,9 +179,7 @@ try:
status = 1
except:
status = 2
logger.error(
f"Exception while getting whitelist from {url} :\n{format_exc()}"
)
logger.error(f"Exception while getting whitelist from {url} :\n{format_exc()}")
except:
status = 2

File diff suppressed because it is too large Load diff

View file

@ -16,9 +16,7 @@ from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy.schema import UniqueConstraint
CONTEXTS_ENUM = Enum("global", "multisite", name="contexts_enum")
SETTINGS_TYPES_ENUM = Enum(
"password", "text", "check", "select", name="settings_types_enum"
)
SETTINGS_TYPES_ENUM = Enum("password", "text", "check", "select", name="settings_types_enum")
METHODS_ENUM = Enum("ui", "scheduler", "autoconf", "manual", name="methods_enum")
SCHEDULES_ENUM = Enum("once", "minute", "hour", "day", "week", name="schedules_enum")
CUSTOM_CONFIGS_TYPES_ENUM = Enum(
@ -57,9 +55,7 @@ class Plugins(Base):
data = Column(LargeBinary(length=(2**32) - 1), nullable=True)
checksum = Column(String(128), nullable=True)
settings = relationship(
"Settings", back_populates="plugin", cascade="all, delete-orphan"
)
settings = relationship("Settings", back_populates="plugin", cascade="all, delete-orphan")
jobs = relationship("Jobs", back_populates="plugin", cascade="all, delete-orphan")
pages = relationship("Plugin_pages", back_populates="plugin", cascade="all")
@ -88,12 +84,8 @@ class Settings(Base):
multiple = Column(String(128), nullable=True)
selects = relationship("Selects", back_populates="setting", cascade="all")
services = relationship(
"Services_settings", back_populates="setting", cascade="all"
)
global_value = relationship(
"Global_values", back_populates="setting", cascade="all"
)
services = relationship("Services_settings", back_populates="setting", cascade="all")
global_value = relationship("Global_values", back_populates="setting", cascade="all")
plugin = relationship("Plugins", back_populates="settings")
@ -118,12 +110,8 @@ class Services(Base):
id = Column(String(64), primary_key=True)
method = Column(METHODS_ENUM, nullable=False)
settings = relationship(
"Services_settings", back_populates="service", cascade="all"
)
custom_configs = relationship(
"Custom_configs", back_populates="service", cascade="all"
)
settings = relationship("Services_settings", back_populates="service", cascade="all")
custom_configs = relationship("Custom_configs", back_populates="service", cascade="all")
jobs_cache = relationship("Jobs_cache", back_populates="service", cascade="all")

View file

@ -1,4 +1,4 @@
cryptography==41.0.4
psycopg2-binary==2.9.8
psycopg2-binary==2.9.9
PyMySQL==1.1.0
sqlalchemy==2.0.21

View file

@ -83,133 +83,141 @@ cryptography==41.0.4 \
--hash=sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb \
--hash=sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f
# via -r requirements.in
greenlet==2.0.2 \
--hash=sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a \
--hash=sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a \
--hash=sha256:1087300cf9700bbf455b1b97e24db18f2f77b55302a68272c56209d5587c12d1 \
--hash=sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43 \
--hash=sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33 \
--hash=sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8 \
--hash=sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088 \
--hash=sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca \
--hash=sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343 \
--hash=sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645 \
--hash=sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db \
--hash=sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df \
--hash=sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3 \
--hash=sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86 \
--hash=sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2 \
--hash=sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a \
--hash=sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf \
--hash=sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7 \
--hash=sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394 \
--hash=sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40 \
--hash=sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3 \
--hash=sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6 \
--hash=sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74 \
--hash=sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0 \
--hash=sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3 \
--hash=sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91 \
--hash=sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5 \
--hash=sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9 \
--hash=sha256:8512a0c38cfd4e66a858ddd1b17705587900dd760c6003998e9472b77b56d417 \
--hash=sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8 \
--hash=sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b \
--hash=sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6 \
--hash=sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb \
--hash=sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73 \
--hash=sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b \
--hash=sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df \
--hash=sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9 \
--hash=sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f \
--hash=sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0 \
--hash=sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857 \
--hash=sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a \
--hash=sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249 \
--hash=sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30 \
--hash=sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292 \
--hash=sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b \
--hash=sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d \
--hash=sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b \
--hash=sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c \
--hash=sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca \
--hash=sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7 \
--hash=sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75 \
--hash=sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae \
--hash=sha256:d4606a527e30548153be1a9f155f4e283d109ffba663a15856089fb55f933e47 \
--hash=sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b \
--hash=sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470 \
--hash=sha256:d967650d3f56af314b72df7089d96cda1083a7fc2da05b375d2bc48c82ab3f3c \
--hash=sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564 \
--hash=sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9 \
--hash=sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099 \
--hash=sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0 \
--hash=sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5 \
--hash=sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19 \
--hash=sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1 \
--hash=sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526
greenlet==3.0.0 \
--hash=sha256:02a807b2a58d5cdebb07050efe3d7deaf915468d112dfcf5e426d0564aa3aa4a \
--hash=sha256:0b72b802496cccbd9b31acea72b6f87e7771ccfd7f7927437d592e5c92ed703c \
--hash=sha256:0d3f83ffb18dc57243e0151331e3c383b05e5b6c5029ac29f754745c800f8ed9 \
--hash=sha256:10b5582744abd9858947d163843d323d0b67be9432db50f8bf83031032bc218d \
--hash=sha256:123910c58234a8d40eaab595bc56a5ae49bdd90122dde5bdc012c20595a94c14 \
--hash=sha256:19834e3f91f485442adc1ee440171ec5d9a4840a1f7bd5ed97833544719ce10b \
--hash=sha256:1d363666acc21d2c204dd8705c0e0457d7b2ee7a76cb16ffc099d6799744ac99 \
--hash=sha256:211ef8d174601b80e01436f4e6905aca341b15a566f35a10dd8d1e93f5dbb3b7 \
--hash=sha256:269d06fa0f9624455ce08ae0179430eea61085e3cf6457f05982b37fd2cefe17 \
--hash=sha256:2e7dcdfad252f2ca83c685b0fa9fba00e4d8f243b73839229d56ee3d9d219314 \
--hash=sha256:334ef6ed8337bd0b58bb0ae4f7f2dcc84c9f116e474bb4ec250a8bb9bd797a66 \
--hash=sha256:343675e0da2f3c69d3fb1e894ba0a1acf58f481f3b9372ce1eb465ef93cf6fed \
--hash=sha256:37f60b3a42d8b5499be910d1267b24355c495064f271cfe74bf28b17b099133c \
--hash=sha256:38ad562a104cd41e9d4644f46ea37167b93190c6d5e4048fcc4b80d34ecb278f \
--hash=sha256:3c0d36f5adc6e6100aedbc976d7428a9f7194ea79911aa4bf471f44ee13a9464 \
--hash=sha256:3fd2b18432e7298fcbec3d39e1a0aa91ae9ea1c93356ec089421fabc3651572b \
--hash=sha256:4a1a6244ff96343e9994e37e5b4839f09a0207d35ef6134dce5c20d260d0302c \
--hash=sha256:4cd83fb8d8e17633ad534d9ac93719ef8937568d730ef07ac3a98cb520fd93e4 \
--hash=sha256:527cd90ba3d8d7ae7dceb06fda619895768a46a1b4e423bdb24c1969823b8362 \
--hash=sha256:553d6fb2324e7f4f0899e5ad2c427a4579ed4873f42124beba763f16032959af \
--hash=sha256:56867a3b3cf26dc8a0beecdb4459c59f4c47cdd5424618c08515f682e1d46692 \
--hash=sha256:621fcb346141ae08cb95424ebfc5b014361621b8132c48e538e34c3c93ac7365 \
--hash=sha256:63acdc34c9cde42a6534518e32ce55c30f932b473c62c235a466469a710bfbf9 \
--hash=sha256:6512592cc49b2c6d9b19fbaa0312124cd4c4c8a90d28473f86f92685cc5fef8e \
--hash=sha256:6672fdde0fd1a60b44fb1751a7779c6db487e42b0cc65e7caa6aa686874e79fb \
--hash=sha256:6a5b2d4cdaf1c71057ff823a19d850ed5c6c2d3686cb71f73ae4d6382aaa7a06 \
--hash=sha256:6a68d670c8f89ff65c82b936275369e532772eebc027c3be68c6b87ad05ca695 \
--hash=sha256:6bb36985f606a7c49916eff74ab99399cdfd09241c375d5a820bb855dfb4af9f \
--hash=sha256:73b2f1922a39d5d59cc0e597987300df3396b148a9bd10b76a058a2f2772fc04 \
--hash=sha256:7709fd7bb02b31908dc8fd35bfd0a29fc24681d5cc9ac1d64ad07f8d2b7db62f \
--hash=sha256:8060b32d8586e912a7b7dac2d15b28dbbd63a174ab32f5bc6d107a1c4143f40b \
--hash=sha256:80dcd3c938cbcac986c5c92779db8e8ce51a89a849c135172c88ecbdc8c056b7 \
--hash=sha256:813720bd57e193391dfe26f4871186cf460848b83df7e23e6bef698a7624b4c9 \
--hash=sha256:831d6f35037cf18ca5e80a737a27d822d87cd922521d18ed3dbc8a6967be50ce \
--hash=sha256:871b0a8835f9e9d461b7fdaa1b57e3492dd45398e87324c047469ce2fc9f516c \
--hash=sha256:952256c2bc5b4ee8df8dfc54fc4de330970bf5d79253c863fb5e6761f00dda35 \
--hash=sha256:96d9ea57292f636ec851a9bb961a5cc0f9976900e16e5d5647f19aa36ba6366b \
--hash=sha256:9a812224a5fb17a538207e8cf8e86f517df2080c8ee0f8c1ed2bdaccd18f38f4 \
--hash=sha256:9adbd8ecf097e34ada8efde9b6fec4dd2a903b1e98037adf72d12993a1c80b51 \
--hash=sha256:9de687479faec7db5b198cc365bc34addd256b0028956501f4d4d5e9ca2e240a \
--hash=sha256:a048293392d4e058298710a54dfaefcefdf49d287cd33fb1f7d63d55426e4355 \
--hash=sha256:aa15a2ec737cb609ed48902b45c5e4ff6044feb5dcdfcf6fa8482379190330d7 \
--hash=sha256:abe1ef3d780de56defd0c77c5ba95e152f4e4c4e12d7e11dd8447d338b85a625 \
--hash=sha256:ad6fb737e46b8bd63156b8f59ba6cdef46fe2b7db0c5804388a2d0519b8ddb99 \
--hash=sha256:b1660a15a446206c8545edc292ab5c48b91ff732f91b3d3b30d9a915d5ec4779 \
--hash=sha256:b505fcfc26f4148551826a96f7317e02c400665fa0883fe505d4fcaab1dabfdd \
--hash=sha256:b822fab253ac0f330ee807e7485769e3ac85d5eef827ca224feaaefa462dc0d0 \
--hash=sha256:bdd696947cd695924aecb3870660b7545a19851f93b9d327ef8236bfc49be705 \
--hash=sha256:bdfaeecf8cc705d35d8e6de324bf58427d7eafb55f67050d8f28053a3d57118c \
--hash=sha256:be557119bf467d37a8099d91fbf11b2de5eb1fd5fc5b91598407574848dc910f \
--hash=sha256:c3692ecf3fe754c8c0f2c95ff19626584459eab110eaab66413b1e7425cd84e9 \
--hash=sha256:c6b5ce7f40f0e2f8b88c28e6691ca6806814157ff05e794cdd161be928550f4c \
--hash=sha256:c94e4e924d09b5a3e37b853fe5924a95eac058cb6f6fb437ebb588b7eda79870 \
--hash=sha256:cc3e2679ea13b4de79bdc44b25a0c4fcd5e94e21b8f290791744ac42d34a0353 \
--hash=sha256:d1e22c22f7826096ad503e9bb681b05b8c1f5a8138469b255eb91f26a76634f2 \
--hash=sha256:d5539f6da3418c3dc002739cb2bb8d169056aa66e0c83f6bacae0cd3ac26b423 \
--hash=sha256:d55db1db455c59b46f794346efce896e754b8942817f46a1bada2d29446e305a \
--hash=sha256:e09dea87cc91aea5500262993cbd484b41edf8af74f976719dd83fe724644cd6 \
--hash=sha256:e52a712c38e5fb4fd68e00dc3caf00b60cb65634d50e32281a9d6431b33b4af1 \
--hash=sha256:e693e759e172fa1c2c90d35dea4acbdd1d609b6936115d3739148d5e4cd11947 \
--hash=sha256:ecf94aa539e97a8411b5ea52fc6ccd8371be9550c4041011a091eb8b3ca1d810 \
--hash=sha256:f351479a6914fd81a55c8e68963609f792d9b067fb8a60a042c585a621e0de4f \
--hash=sha256:f47932c434a3c8d3c86d865443fadc1fbf574e9b11d6650b656e602b1797908a
# via sqlalchemy
psycopg2-binary==2.9.8 \
--hash=sha256:01f9731761f711e42459f87bd2ad5d744b9773b5dd05446f3b579a0f077e78e3 \
--hash=sha256:0e3071c947bda6afc6fe2e7b64ebd64fb2cad1bc0e705a3594cb499291f2dfec \
--hash=sha256:14f85ff2d5d826a7ce9e6c31e803281ed5a096789f47f52cb728c88f488de01b \
--hash=sha256:15458c81b0d199ab55825007115f697722831656e6477a427783fe75c201c82b \
--hash=sha256:19d40993701e39c49b50e75cd690a6af796d7e7210941ee0fe49cf12b25840e5 \
--hash=sha256:1d669887df169a9b0c09e0f5b46891511850a9ddfcde3593408af9d9774c5c3a \
--hash=sha256:1dbad789ebd1e61201256a19dc2e90fed4706bc966ccad4f374648e5336b1ab4 \
--hash=sha256:1f279ba74f0d6b374526e5976c626d2ac3b8333b6a7b08755c513f4d380d3add \
--hash=sha256:205cecdd81ff4f1ddd687ce7d06879b9b80cccc428d8d6ebf36fcba08bb6d361 \
--hash=sha256:278ebd63ced5a5f3af5394cb75a9a067243eee21f42f0126c6f1cf85eaeb90f9 \
--hash=sha256:3723c3f009e2b2771f2491b330edb7091846f1aad0c08fbbd9a1383d6a0c0841 \
--hash=sha256:395c217156723fe21809dfe8f7a433c5bf8e9bce229944668e4ec709c37c5442 \
--hash=sha256:3ae22a0fa5c516b84ddb189157fabfa3f12eded5d630e1ce260a18e1771f8707 \
--hash=sha256:3b6928a502af71ca2ac9aad535e78c8309892ed3bfa7933182d4c760580c8af4 \
--hash=sha256:3b6c607ecb6a9c245ebe162d63ccd9222d38efa3c858bbe38d32810b08b8f87e \
--hash=sha256:3fd44b52bc9c74c1512662e8da113a1c55127adeeacebaf460babe766517b049 \
--hash=sha256:4336afc0e81726350bd5863e3c3116d8c12aa7f457d3d0b3b3dc36137fec6feb \
--hash=sha256:4879ee1d07a6b2c232ae6a74570f4788cd7a29b3cd38bc39bf60225b1d075c78 \
--hash=sha256:4960c881471ca710b81a67ef148c33ee121c1f8e47a639cf7e06537fe9fee337 \
--hash=sha256:4b8b2cdf3bce4dd91dc035fbff4eb812f5607dda91364dc216b0920b97b521c7 \
--hash=sha256:4bfabbd7e70785af726cc0209e8e64b926abf91741eca80678b221aad9e72135 \
--hash=sha256:4d6b592ecc8667e608b9e7344259fbfb428cc053df0062ec3ac75d8270cd5a9f \
--hash=sha256:5262713988d97a9d4cd54b682dec4a413b87b76790e5b16f480450550d11a8f7 \
--hash=sha256:54bf5c27bd5867a5fa5341fad29f0d5838e2fed617ef5346884baf8b8b16dd82 \
--hash=sha256:565edaf9f691b17a7fdbabd368b5b3e67d0fdc8f7f6b52177c1d3289f4e763fd \
--hash=sha256:59421806c1a0803ea7de9ed061d656c041a84db0da7e73266b98db4c7ba263da \
--hash=sha256:59f45cca0765aabb52a5822c72d5ff2ec46a28b1c1702de90dc0d306ec5c2001 \
--hash=sha256:5a0a6e4004697ec98035ff3b8dfc4dba8daa477b23ee891d831cd3cd65ace6be \
--hash=sha256:5aa0c99c12075c593dcdccbb8a7aaa714b716560cc99ef9206f9e75b77520801 \
--hash=sha256:5aef3296d44d05805e634dbbd2972aa8eb7497926dd86047f5e39a79c3ecc086 \
--hash=sha256:5cbe1e19f59950afd66764e3c905ecee9f2aee9f8df2ef35af6f7948ad93f620 \
--hash=sha256:5debcb23a052f3fb4c165789ea513b562b2fac0f0f4f53eaf3cf4dc648907ff8 \
--hash=sha256:5f955fe6301b84b6fd13970a05f3640fbb62ca3a0d19342356585006c830e038 \
--hash=sha256:6369f4bd4d27944498094dccced1ae7ca43376a59dbfe4c8b6a16e9e3dc3ccce \
--hash=sha256:63ce1dccfd08d9c5341ac82d62aa04345bc4bf41b5e5b7b2c6c172a28e0eda27 \
--hash=sha256:65403113ac3a4813a1409fb6a1e43c658b459cc8ed8afcc5f4baf02ec8be4334 \
--hash=sha256:673eafbdaa4ed9f5164c90e191c3895cc5f866b9b379fdb59f3a2294e914d9bd \
--hash=sha256:693a4e7641556f0b421a7d6c6a74058aead407d860ac1cb9d0bf25be0ca73de8 \
--hash=sha256:6e1bb4eb0d9925d65dabaaabcbb279fab444ba66d73f86d4c07dfd11f0139c06 \
--hash=sha256:6f5e70e40dae47a4dc7f8eb390753bb599b0f4ede314580e6faa3b7383695d19 \
--hash=sha256:80451e6b6b7c486828d5c7ed50769532bbb04ec3a411f1e833539d5c10eb691c \
--hash=sha256:8c84ff9682bc4520504c474e189b3de7c4a4029e529c8b775e39c95c33073767 \
--hash=sha256:91719f53ed2a95ebecefac48d855d811cba9d9fe300acc162993bdfde9bc1c3b \
--hash=sha256:9a971086db0069aef2fd22ccffb670baac427f4ee2174c4f5c7206254f1e6794 \
--hash=sha256:aeb09db95f38e75ae04e947d283e07be34d03c4c2ace4f0b73dbb9143d506e67 \
--hash=sha256:c68a2e1afb4f2a5bb4b7bb8f90298d21196ac1c66418523e549430b8c4b7cb1e \
--hash=sha256:c7ff2b6a79a92b1b169b03bb91b41806843f0cdf6055256554495bffed1d496d \
--hash=sha256:ccaa2ae03990cedde1f618ff11ec89fefa84622da73091a67b44553ca8be6711 \
--hash=sha256:cf60c599c40c266a01c458e9c71db7132b11760f98f08233f19b3e0a2153cbf1 \
--hash=sha256:d29efab3c5d6d978115855a0f2643e0ee8c6450dc536d5b4afec6f52ab99e99e \
--hash=sha256:d4a19a3332f2ac6d093e60a6f1c589f97eb9f9de7e27ea80d67f188384e31572 \
--hash=sha256:dc145a241e1f6381efb924bcf3e3462d6020b8a147363f9111eb0a9c89331ad7 \
--hash=sha256:de85105c568dc5f0f0efe793209ba83e4675d53d00faffc7a7c7a8bea9e0e19a \
--hash=sha256:e11373d8e4f1f46cf3065bf613f0df9854803dc95aa4a35354ffac19f8c52127 \
--hash=sha256:e271ad6692d50d70ca75db3bd461bfc26316de78de8fe1f504ef16dcea8f2312 \
--hash=sha256:e3142c7e51b92855cff300580de949e36a94ab3bfa8f353b27fe26535e9b3542 \
--hash=sha256:e46b0f4683539965ce849f2c13fc53e323bb08d84d4ba2e4b3d976f364c84210 \
--hash=sha256:e6ef615d48fa60361e57f998327046bd89679c25d06eee9e78156be5a7a76e03 \
--hash=sha256:e7bdc94217ae20ad03b375a991e107a31814053bee900ad8c967bf82ef3ff02e \
--hash=sha256:fc37de7e3a87f5966965fc874d33c9b68d638e6c3718fdf32a5083de563428b0
psycopg2-binary==2.9.9 \
--hash=sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9 \
--hash=sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77 \
--hash=sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e \
--hash=sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84 \
--hash=sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3 \
--hash=sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2 \
--hash=sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67 \
--hash=sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876 \
--hash=sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152 \
--hash=sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f \
--hash=sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a \
--hash=sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6 \
--hash=sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503 \
--hash=sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f \
--hash=sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493 \
--hash=sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996 \
--hash=sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f \
--hash=sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e \
--hash=sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59 \
--hash=sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94 \
--hash=sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7 \
--hash=sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682 \
--hash=sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420 \
--hash=sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae \
--hash=sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291 \
--hash=sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe \
--hash=sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980 \
--hash=sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692 \
--hash=sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119 \
--hash=sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716 \
--hash=sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472 \
--hash=sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b \
--hash=sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2 \
--hash=sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc \
--hash=sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c \
--hash=sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5 \
--hash=sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984 \
--hash=sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9 \
--hash=sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf \
--hash=sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0 \
--hash=sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f \
--hash=sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212 \
--hash=sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb \
--hash=sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be \
--hash=sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90 \
--hash=sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041 \
--hash=sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7 \
--hash=sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860 \
--hash=sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245 \
--hash=sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27 \
--hash=sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417 \
--hash=sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359 \
--hash=sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202 \
--hash=sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0 \
--hash=sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7 \
--hash=sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba \
--hash=sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1 \
--hash=sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd \
--hash=sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07 \
--hash=sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98 \
--hash=sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55 \
--hash=sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d \
--hash=sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972 \
--hash=sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f \
--hash=sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e \
--hash=sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26 \
--hash=sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957 \
--hash=sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53 \
--hash=sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52
# via -r requirements.in
pycparser==2.21 \
--hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \

View file

@ -57,14 +57,10 @@ class Configurator:
def get_settings(self) -> Dict[str, Any]:
return self.__settings
def get_plugins(
self, _type: Union[Literal["core"], Literal["external"]]
) -> List[Dict[str, Any]]:
def get_plugins(self, _type: Union[Literal["core"], Literal["external"]]) -> List[Dict[str, Any]]:
return self.__core_plugins if _type == "core" else self.__external_plugins
def get_plugins_settings(
self, _type: Union[Literal["core"], Literal["external"]]
) -> Dict[str, Any]:
def get_plugins_settings(self, _type: Union[Literal["core"], Literal["external"]]) -> Dict[str, Any]:
if _type == "core":
plugins = self.__core_plugins
else:
@ -77,7 +73,7 @@ class Configurator:
return plugins_settings
def __map_servers(self) -> Dict[str, List[str]]:
if not self.__multisite or not "SERVER_NAME" in self.__variables:
if not self.__multisite or "SERVER_NAME" not in self.__variables:
return {}
servers = {}
for server_name in self.__variables["SERVER_NAME"].strip().split(" "):
@ -96,11 +92,7 @@ class Configurator:
f"Ignoring {server_name}_SERVER_NAME because regex is not valid",
)
else:
names = (
self.__variables[f"{server_name}_SERVER_NAME"]
.strip()
.split(" ")
)
names = self.__variables[f"{server_name}_SERVER_NAME"].strip().split(" ")
servers[server_name] = names
return servers
@ -132,9 +124,7 @@ class Configurator:
if _type == "external":
plugin_content = BytesIO()
with tar_open(
fileobj=plugin_content, mode="w:gz", compresslevel=9
) as tar:
with tar_open(fileobj=plugin_content, mode="w:gz", compresslevel=9) as tar:
tar.add(
dirname(file),
arcname=basename(dirname(file)),
@ -170,10 +160,10 @@ class Configurator:
lines = f.readlines()
for line in lines:
line = line.strip()
if not line or line.startswith("#") or not "=" in line:
if not line or line.startswith("#") or "=" not in line:
continue
splitted = line.split("=", 1)
variables[splitted[0]] = splitted[1]
split = line.split("=", 1)
variables[split[0]] = split[1]
return variables
def get_config(self) -> Dict[str, Any]:
@ -268,9 +258,7 @@ class Configurator:
if variable in target:
return target, variable
for real_var, settings in target.items():
if "multiple" in settings and re_search(
f"^{real_var}_[0-9]+$", variable
):
if "multiple" in settings and re_search(f"^{real_var}_[0-9]+$", variable):
return target, real_var
return None, variable

View file

@ -63,27 +63,19 @@ class Templator:
templates.append(template)
return templates
def __write_config(
self, subpath: Optional[str] = None, config: Optional[Dict[str, Any]] = None
):
def __write_config(self, subpath: Optional[str] = None, config: Optional[Dict[str, Any]] = None):
real_path = Path(self.__output, subpath or "", "variables.env")
real_path.parent.mkdir(parents=True, exist_ok=True)
real_path.write_text(
"\n".join(f"{k}={v}" for k, v in (config or self.__config).items())
)
real_path.write_text("\n".join(f"{k}={v}" for k, v in (config or self.__config).items()))
def __render_global(self):
self.__write_config()
templates = self.__find_templates(
["global", "http", "stream", "default-server-http"]
)
templates = self.__find_templates(["global", "http", "stream", "default-server-http"])
for template in templates:
self.__render_template(template)
def __render_server(self, server: str):
templates = self.__find_templates(
["modsec", "modsec-crs", "server-http", "server-stream"]
)
templates = self.__find_templates(["modsec", "modsec-crs", "server-http", "server-stream"])
if self.__config.get("MULTISITE", "no") == "yes":
config = self.__config.copy()
for variable, value in self.__config.items():

View file

@ -12,10 +12,7 @@ from time import sleep
from traceback import format_exc
from typing import Any, Dict
for deps_path in [
join(sep, "usr", "share", "bunkerweb", *paths)
for paths in (("deps", "python"), ("utils",), ("api",))
]:
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",), ("api",))]:
if deps_path not in sys_path:
sys_path.append(deps_path)
@ -72,9 +69,7 @@ if __name__ == "__main__":
type=str,
help="path to the file containing environment variables",
)
parser.add_argument(
"--no-linux-reload", action="store_true", help="disable linux reload"
)
parser.add_argument("--no-linux-reload", action="store_true", help="disable linux reload")
args = parser.parse_args()
settings_path = Path(normpath(args.settings))
@ -183,10 +178,7 @@ if __name__ == "__main__":
)
templator.render()
if (
integration not in ("Autoconf", "Swarm", "Kubernetes", "Docker")
and not args.no_linux_reload
):
if integration not in ("Autoconf", "Swarm", "Kubernetes", "Docker") and not args.no_linux_reload:
retries = 0
while not Path(sep, "var", "run", "bunkerweb", "nginx.pid").exists():
if retries == 5:

View file

@ -298,9 +298,9 @@ six==1.16.0 \
# via
# kubernetes
# python-dateutil
urllib3==1.26.16 \
--hash=sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f \
--hash=sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14
urllib3==1.26.17 \
--hash=sha256:24d6a242c28d29af46c3fae832c36db3bbebcc533dd1bb549172cd739c82df21 \
--hash=sha256:94a757d178c9be92ef5539b8840d48dc9cf1b2709c9d6b588232a055c524458b
# via
# docker
# kubernetes

View file

@ -10,10 +10,7 @@ from time import sleep
from traceback import format_exc
from typing import Any
for deps_path in [
join(sep, "usr", "share", "bunkerweb", *paths)
for paths in (("deps", "python"), ("utils",), ("api",), ("db",))
]:
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",), ("api",), ("db",))]:
if deps_path not in sys_path:
sys_path.append(deps_path)
@ -24,9 +21,7 @@ from Database import Database # type: ignore
from Configurator import Configurator
from API import API # type: ignore
custom_confs_rx = re_compile(
r"^([0-9a-z\.-]*)_?CUSTOM_CONF_(HTTP|SERVER_STREAM|STREAM|DEFAULT_SERVER_HTTP|SERVER_HTTP|MODSEC_CRS|MODSEC)_(.+)$"
)
custom_confs_rx = re_compile(r"^([0-9a-z\.-]*)_?CUSTOM_CONF_(HTTP|SERVER_STREAM|STREAM|DEFAULT_SERVER_HTTP|SERVER_HTTP|MODSEC_CRS|MODSEC)_(.+)$")
def get_instance_configs_and_apis(instance: Any, db, _type="Docker"):
@ -36,17 +31,13 @@ def get_instance_configs_and_apis(instance: Any, db, _type="Docker"):
custom_confs = []
apis = []
for var in (
instance.attrs["Config"]["Env"]
if _type == "Docker"
else instance.attrs["Spec"]["TaskTemplate"]["ContainerSpec"]["Env"]
):
splitted = var.split("=", 1)
if custom_confs_rx.match(splitted[0]):
custom_conf = custom_confs_rx.search(splitted[0]).groups()
for var in instance.attrs["Config"]["Env"] if _type == "Docker" else instance.attrs["Spec"]["TaskTemplate"]["ContainerSpec"]["Env"]:
split = var.split("=", 1)
if custom_confs_rx.match(split[0]):
custom_conf = custom_confs_rx.search(split[0]).groups()
custom_confs.append(
{
"value": f"# CREATED BY ENV\n{splitted[1]}",
"value": f"# CREATED BY ENV\n{split[1]}",
"exploded": (
custom_conf[0],
custom_conf[1],
@ -54,18 +45,16 @@ def get_instance_configs_and_apis(instance: Any, db, _type="Docker"):
),
}
)
logger.info(
f"Found custom conf env var {'for service ' + custom_conf[0] if custom_conf[0] else 'without service'} with type {custom_conf[1]} and name {custom_conf[2]}"
)
logger.info(f"Found custom conf env var {'for service ' + custom_conf[0] if custom_conf[0] else 'without service'} with type {custom_conf[1]} and name {custom_conf[2]}")
else:
tmp_config[splitted[0]] = splitted[1]
tmp_config[split[0]] = split[1]
if not db and splitted[0] == "DATABASE_URI":
db = Database(logger, sqlalchemy_string=splitted[1], pool=False)
elif splitted[0] == "API_HTTP_PORT":
api_http_port = splitted[1]
elif splitted[0] == "API_SERVER_NAME":
api_server_name = splitted[1]
if not db and split[0] == "DATABASE_URI":
db = Database(logger, sqlalchemy_string=split[1], pool=False)
elif split[0] == "API_HTTP_PORT":
api_http_port = split[1]
elif split[0] == "API_SERVER_NAME":
api_server_name = split[1]
apis.append(
API(
@ -168,9 +157,7 @@ if __name__ == "__main__":
# Check existences and permissions
logger.info("Checking arguments ...")
files = [settings_path] + (
[Path(normpath(args.variables))] if args.variables else []
)
files = [settings_path] + ([Path(normpath(args.variables))] if args.variables else [])
paths_rx = [core_path, plugins_path]
for file in files:
if not file.is_file():
@ -217,19 +204,13 @@ if __name__ == "__main__":
),
}
)
logger.info(
f"Found custom conf env var {'for service ' + custom_conf[0] if custom_conf[0] else 'without service'} with type {custom_conf[1]} and name {custom_conf[2]}"
)
logger.info(f"Found custom conf env var {'for service ' + custom_conf[0] if custom_conf[0] else 'without service'} with type {custom_conf[1]} and name {custom_conf[2]}")
db = Database(logger, config_files.get("DATABASE_URI", None), pool=False)
else:
docker_client = DockerClient(
base_url=getenv("DOCKER_HOST", "unix:///var/run/docker.sock")
)
docker_client = DockerClient(base_url=getenv("DOCKER_HOST", "unix:///var/run/docker.sock"))
while not docker_client.containers.list(
filters={"label": "bunkerweb.INSTANCE"}
):
while not docker_client.containers.list(filters={"label": "bunkerweb.INSTANCE"}):
logger.info("Waiting for BunkerWeb instance ...")
sleep(5)
@ -239,16 +220,14 @@ if __name__ == "__main__":
custom_confs = []
apis = []
for instance in docker_client.containers.list(
filters={"label": "bunkerweb.INSTANCE"}
):
for instance in docker_client.containers.list(filters={"label": "bunkerweb.INSTANCE"}):
for var in instance.attrs["Config"]["Env"]:
splitted = var.split("=", 1)
if custom_confs_rx.match(splitted[0]):
custom_conf = custom_confs_rx.search(splitted[0]).groups()
split = var.split("=", 1)
if custom_confs_rx.match(split[0]):
custom_conf = custom_confs_rx.search(split[0]).groups()
custom_confs.append(
{
"value": f"# CREATED BY ENV\n{splitted[1]}",
"value": f"# CREATED BY ENV\n{split[1]}",
"exploded": (
custom_conf[0],
custom_conf[1],
@ -256,20 +235,16 @@ if __name__ == "__main__":
),
}
)
logger.info(
f"Found custom conf env var {'for service ' + custom_conf[0] if custom_conf[0] else 'without service'} with type {custom_conf[1]} and name {custom_conf[2]}"
)
logger.info(f"Found custom conf env var {'for service ' + custom_conf[0] if custom_conf[0] else 'without service'} with type {custom_conf[1]} and name {custom_conf[2]}")
else:
tmp_config[splitted[0]] = splitted[1]
tmp_config[split[0]] = split[1]
if not db and splitted[0] == "DATABASE_URI":
db = Database(
logger, sqlalchemy_string=splitted[1], pool=False
)
elif splitted[0] == "API_HTTP_PORT":
api_http_port = splitted[1]
elif splitted[0] == "API_SERVER_NAME":
api_server_name = splitted[1]
if not db and split[0] == "DATABASE_URI":
db = Database(logger, sqlalchemy_string=split[1], pool=False)
elif split[0] == "API_HTTP_PORT":
api_http_port = split[1]
elif split[0] == "API_SERVER_NAME":
api_server_name = split[1]
apis.append(
API(
@ -319,9 +294,7 @@ if __name__ == "__main__":
logger.info("Database tables initialized")
err = db.initialize_db(
version=Path(sep, "usr", "share", "bunkerweb", "VERSION")
.read_text()
.strip(),
version=Path(sep, "usr", "share", "bunkerweb", "VERSION").read_text().strip(),
integration=integration,
)
@ -344,9 +317,7 @@ if __name__ == "__main__":
err = db.save_config(config_files, args.method, changed=False)
if err:
logger.warning(
f"Couldn't save config to database : {err}, config may not work as expected"
)
logger.warning(f"Couldn't save config to database : {err}, config may not work as expected")
else:
changes.append("config")
logger.info("Config successfully saved to database")
@ -355,9 +326,7 @@ if __name__ == "__main__":
err1 = db.save_custom_configs(custom_confs, args.method, changed=False)
if err1:
logger.warning(
f"Couldn't save custom configs to database : {err1}, custom configs may not work as expected"
)
logger.warning(f"Couldn't save custom configs to database : {err1}, custom configs may not work as expected")
else:
changes.append("custom_configs")
logger.info("Custom configs successfully saved to database")
@ -377,9 +346,7 @@ if __name__ == "__main__":
else:
if "instances" not in changes:
changes.append("instances")
logger.info(
f"Instance {endpoint_data[0]} successfully saved to database"
)
logger.info(f"Instance {endpoint_data[0]} successfully saved to database")
else:
err = db.add_instance(
"127.0.0.1",
@ -397,9 +364,7 @@ if __name__ == "__main__":
# update changes in db
ret = db.checked_changes(changes, value=True)
if ret:
logger.error(
f"An error occurred when setting the changes to checked in the database : {ret}"
)
logger.error(f"An error occurred when setting the changes to checked in the database : {ret}")
except SystemExit as e:
sys_exit(e.code)
except:

View file

@ -7,10 +7,7 @@ from sys import path as sys_path
from tarfile import open as tar_open
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
for deps_path in [
join(sep, "usr", "share", "bunkerweb", *paths)
for paths in (("deps", "python"), ("utils",))
]:
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",))]:
if deps_path not in sys_path:
sys_path.append(deps_path)
@ -46,10 +43,7 @@ class ApiCaller:
config.load_incluster_config()
corev1 = kube_client.CoreV1Api()
for pod in corev1.list_pod_for_all_namespaces(watch=False).items:
if (
pod.metadata.annotations != None
and "bunkerweb.io/INSTANCE" in pod.metadata.annotations
):
if pod.metadata.annotations is not None and "bunkerweb.io/INSTANCE" in pod.metadata.annotations:
api_http_port = None
api_server_name = None
@ -66,20 +60,14 @@ class ApiCaller:
)
)
else:
docker_client = DockerClient(
base_url=getenv("DOCKER_HOST", "unix:///var/run/docker.sock")
)
docker_client = DockerClient(base_url=getenv("DOCKER_HOST", "unix:///var/run/docker.sock"))
if bw_integration == "Swarm":
for instance in docker_client.services.list(
filters={"label": "bunkerweb.INSTANCE"}
):
for instance in docker_client.services.list(filters={"label": "bunkerweb.INSTANCE"}):
api_http_port = None
api_server_name = None
for var in instance.attrs["Spec"]["TaskTemplate"]["ContainerSpec"][
"Env"
]:
for var in instance.attrs["Spec"]["TaskTemplate"]["ContainerSpec"]["Env"]:
if var.startswith("API_HTTP_PORT="):
api_http_port = var.replace("API_HTTP_PORT=", "", 1)
elif var.startswith("API_SERVER_NAME="):
@ -89,15 +77,12 @@ class ApiCaller:
self.__apis.append(
API(
f"http://{instance.name}.{task['NodeID']}.{task['ID']}:{api_http_port or getenv('API_HTTP_PORT', '5000')}",
host=api_server_name
or getenv("API_SERVER_NAME", "bwapi"),
host=api_server_name or getenv("API_SERVER_NAME", "bwapi"),
)
)
return
for instance in docker_client.containers.list(
filters={"label": "bunkerweb.INSTANCE"}
):
for instance in docker_client.containers.list(filters={"label": "bunkerweb.INSTANCE"}):
api_http_port = None
api_server_name = None
@ -160,9 +145,7 @@ class ApiCaller:
def send_files(self, path: str, url: str) -> bool:
ret = True
with BytesIO() as tgz:
with tar_open(
mode="w:gz", fileobj=tgz, dereference=True, compresslevel=3
) as tf:
with tar_open(mode="w:gz", fileobj=tgz, dereference=True, compresslevel=3) as tf:
tf.add(path, arcname=".")
tgz.seek(0, 0)
files = {"archive.tar.gz": tgz}

View file

@ -15,18 +15,10 @@ 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")):
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"]
)
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',
@ -39,23 +31,15 @@ class ConfigCaller:
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:
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 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]:
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():
@ -63,11 +47,7 @@ class ConfigCaller:
# 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", "") != ""
):
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

View file

@ -70,9 +70,7 @@ def is_cached_file(
return is_cached and cached_file
def get_file_in_db(
file: Union[str, Path], db, *, job_name: Optional[str] = None
) -> Optional[bytes]:
def get_file_in_db(file: Union[str, Path], db, *, job_name: Optional[str] = None) -> Optional[bytes]:
cached_file = db.get_job_cache_file(
job_name or basename(getsourcefile(_getframe(1))).replace(".py", ""),
normpath(file),
@ -98,8 +96,7 @@ def set_file_in_db(
service_id,
name,
content,
job_name=job_name
or basename(getsourcefile(_getframe(1))).replace(".py", ""),
job_name=job_name or basename(getsourcefile(_getframe(1))).replace(".py", ""),
checksum=checksum,
)
@ -113,9 +110,7 @@ def set_file_in_db(
def del_file_in_db(name: str, db) -> Tuple[bool, str]:
ret, err = True, "success"
try:
db.delete_job_cache(
name, job_name=basename(getsourcefile(_getframe(1))).replace(".py", "")
)
db.delete_job_cache(name, job_name=basename(getsourcefile(_getframe(1))).replace(".py", ""))
except:
return False, f"exception :\n{format_exc()}"
return ret, err
@ -145,9 +140,7 @@ def bytes_hash(bio: BufferedReader) -> str:
def cache_hash(cache: Union[str, Path], db=None) -> Optional[str]:
with suppress(BaseException):
return loads(Path(normpath(f"{cache}.md")).read_text(encoding="utf-8")).get(
"checksum", None
)
return loads(Path(normpath(f"{cache}.md")).read_text(encoding="utf-8")).get("checksum", None)
if db:
cached_file = db.get_job_cache_file(
basename(getsourcefile(_getframe(1))).replace(".py", ""),

View file

@ -30,24 +30,12 @@ basicConfig(
level=default_level,
)
getLogger("sqlalchemy.orm.mapper.Mapper").setLevel(
default_level if default_level != INFO else WARNING
)
getLogger("sqlalchemy.orm.relationships.RelationshipProperty").setLevel(
default_level if default_level != INFO else WARNING
)
getLogger("sqlalchemy.orm.strategies.LazyLoader").setLevel(
default_level if default_level != INFO else WARNING
)
getLogger("sqlalchemy.pool.impl.QueuePool").setLevel(
default_level if default_level != INFO else WARNING
)
getLogger("sqlalchemy.pool.impl.NullPool").setLevel(
default_level if default_level != INFO else WARNING
)
getLogger("sqlalchemy.engine.Engine").setLevel(
default_level if default_level != INFO else WARNING
)
getLogger("sqlalchemy.orm.mapper.Mapper").setLevel(default_level if default_level != INFO else WARNING)
getLogger("sqlalchemy.orm.relationships.RelationshipProperty").setLevel(default_level if default_level != INFO else WARNING)
getLogger("sqlalchemy.orm.strategies.LazyLoader").setLevel(default_level if default_level != INFO else WARNING)
getLogger("sqlalchemy.pool.impl.QueuePool").setLevel(default_level if default_level != INFO else WARNING)
getLogger("sqlalchemy.pool.impl.NullPool").setLevel(default_level if default_level != INFO else WARNING)
getLogger("sqlalchemy.engine.Engine").setLevel(default_level if default_level != INFO else WARNING)
# Edit the default levels of the logging module
addLevelName(CRITICAL, "🚨")

View file

@ -181,9 +181,9 @@ toposort==1.10 \
--hash=sha256:bfbb479c53d0a696ea7402601f4e693c97b0367837c8898bc6471adfca37a6bd \
--hash=sha256:cbdbc0d0bee4d2695ab2ceec97fe0679e9c10eab4b2a87a9372b929e70563a87
# via pip-compile-multi
urllib3==2.0.5 \
--hash=sha256:13abf37382ea2ce6fb744d4dad67838eec857c9f4f57009891805e0b5e123594 \
--hash=sha256:ef16afa8ba34a1f989db38e1dbbe0c302e4289a47856990d0682e374563ce35e
urllib3==2.0.6 \
--hash=sha256:7a7c7003b000adf9e7ca2a377c9688bbc54ed41b985789ed576570342a375cd2 \
--hash=sha256:b19e1a85d206b56d7df1d5e683df4a7725252a964e3993648dd0fb5a1c157564
# via requests
wheel==0.41.2 \
--hash=sha256:0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985 \

View file

@ -3,7 +3,7 @@
--license agpl3
--version %VERSION%
--architecture x86_64
--depends bash --depends epel-release --depends python39 --depends 'nginx = 1:1.24.0-1.el8.ngx' --depends libcurl-devel --depends libxml2 --depends yajl --depends lmdb-libs --depends GeoIP-devel --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends brotli --depends openssl
--depends bash --depends epel-release --depends python39 --depends 'nginx = 1:1.24.0-1.el8.ngx' --depends libcurl-devel --depends libxml2 --depends yajl --depends lmdb-libs --depends GeoIP-devel --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends brotli --depends openssl --depends libpq
--description "BunkerWeb %VERSION% for CentOS Stream 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 python3 --depends procps --depends python3-pip --depends 'nginx = 1.24.0-1~bullseye' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends lsof
--depends bash --depends python3 --depends procps --depends python3-pip --depends 'nginx = 1.24.0-1~bullseye' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends lsof --depends libpq5
--description "BunkerWeb %VERSION% for Debian 11"
--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 'nginx = 1:1.24.0-1.fc38' --depends libcurl-devel --depends libxml2 --depends yajl --depends lmdb-libs --depends geoip-devel --depends gd --depends sudo --depends procps --depends lsof --depends nginx-mod-stream --depends pcre
--depends bash --depends python3 --depends 'nginx = 1:1.24.0-1.fc38' --depends libcurl-devel --depends libxml2 --depends yajl --depends lmdb-libs --depends geoip-devel --depends gd --depends sudo --depends procps --depends lsof --depends nginx-mod-stream --depends pcre --depends libpq
--description "BunkerWeb %VERSION% for Fedora 38"
--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.24.0-1.el8.ngx' --depends libcurl-devel --depends libxml2 --depends yajl --depends file-libs --depends net-tools --depends gd --depends sudo --depends procps --depends lsof --depends geoip
--depends bash --depends python39 --depends 'nginx = 1:1.24.0-1.el8.ngx' --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
--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 python3 --depends python3-pip --depends 'nginx = 1.24.0-1~jammy' --depends libcurl4 --depends libgeoip-dev --depends libxml2 --depends libyajl2 --depends libmagic1 --depends net-tools --depends sudo --depends procps --depends lsof
--depends bash --depends python3 --depends python3-pip --depends 'nginx = 1.24.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
--description "BunkerWeb %VERSION% for Ubuntu 22.04"
--url "https://www.bunkerweb.io"
--maintainer "Bunkerity <contact at bunkerity dot com>"

View file

@ -226,7 +226,7 @@ function reload()
log "SYSTEMCTL" "" "BunkerWeb service reloaded ..."
}
# List of differents args
# List of different args
case $1 in
"start")
start

View file

@ -1,4 +1,7 @@
FROM python:3.11.5-alpine@sha256:cd311c6a0164f34a7edbf364e05258b07d66d3f7bc155139dcb9bef88a186ded AS builder
FROM python:3.12.0-alpine@sha256:ae35274f417fc81ba6ee1fc84206e8517f28117566ee6a04a64f004c1409bdac AS builder
# Install python dependencies
RUN apk add --no-cache --virtual .build-deps g++ gcc musl-dev jpeg-dev zlib-dev libffi-dev cairo-dev pango-dev gdk-pixbuf-dev openssl-dev cargo postgresql-dev
# Copy python requirements
COPY src/deps/requirements.txt /tmp/requirements-deps.txt
@ -12,9 +15,6 @@ RUN mkdir -p deps/python && \
cat /tmp/req/requirements.txt* > deps/requirements.txt && \
rm -rf /tmp/req
# Install python dependencies
RUN apk add --no-cache --virtual .build-deps g++ gcc musl-dev jpeg-dev zlib-dev libffi-dev cairo-dev pango-dev gdk-pixbuf-dev openssl-dev cargo postgresql-dev
# Install python requirements
RUN export MAKEFLAGS="-j$(nproc)" && \
pip install --no-cache-dir --ignore-installed --require-hashes -r /tmp/requirements-deps.txt && \
@ -38,7 +38,7 @@ COPY src/common/utils utils
COPY src/scheduler scheduler
COPY src/VERSION VERSION
FROM python:3.11.5-alpine@sha256:cd311c6a0164f34a7edbf364e05258b07d66d3f7bc155139dcb9bef88a186ded
FROM python:3.12.0-alpine@sha256:ae35274f417fc81ba6ee1fc84206e8517f28117566ee6a04a64f004c1409bdac
# Set default umask to prevent huge recursive chmod increasing the final image size
RUN umask 027
@ -49,7 +49,7 @@ COPY --from=builder --chown=0:101 /usr/share/bunkerweb /usr/share/bunkerweb
WORKDIR /usr/share/bunkerweb
# Add scheduler user, drop bwcli, install runtime dependencies, create data folders and set permissions
RUN apk add --no-cache bash libgcc libstdc++ openssl libmagic && \
RUN apk add --no-cache bash libgcc libstdc++ libpq openssl libmagic && \
ln -s /usr/local/bin/python3 /usr/bin/python3 && \
addgroup -g 101 scheduler && \
adduser -h /var/cache/nginx -g scheduler -s /bin/sh -G scheduler -D -H -u 101 scheduler && \

Some files were not shown because too many files have changed in this diff Show more