mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Merge branch 'dev' into staging
This commit is contained in:
commit
05643ec240
36 changed files with 854 additions and 1642 deletions
9
.github/workflows/push-packagecloud.yml
vendored
9
.github/workflows/push-packagecloud.yml
vendored
|
|
@ -60,16 +60,23 @@ jobs:
|
|||
path: /tmp/${{ inputs.LINUX }}
|
||||
# Remove existing packages
|
||||
- name: Remove existing package
|
||||
if: inputs.LINUX != 'el9' && inputs.LINUX != 'ubuntu-noble'
|
||||
run: package_cloud yank bunkerity/${{ inputs.REPO }}/${{ inputs.LINUX }}/${{ inputs.VERSION }} bunkerweb${{ inputs.SEPARATOR }}${{ inputs.BW_VERSION }}${{ inputs.SEPARATOR }}${{ inputs.SUFFIX }}${{ inputs.PACKAGE_ARCH }}.${{ inputs.PACKAGE }}
|
||||
continue-on-error: true
|
||||
env:
|
||||
PACKAGECLOUD_TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }}
|
||||
- name: Remove existing package
|
||||
- name: Remove existing package el9
|
||||
if: inputs.LINUX == 'el9'
|
||||
run: package_cloud yank bunkerity/${{ inputs.REPO }}/el/9 bunkerweb${{ inputs.SEPARATOR }}${{ inputs.BW_VERSION }}${{ inputs.SEPARATOR }}${{ inputs.SUFFIX }}${{ inputs.PACKAGE_ARCH }}.${{ inputs.PACKAGE }}
|
||||
continue-on-error: true
|
||||
env:
|
||||
PACKAGECLOUD_TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }}
|
||||
- name: Remove existing package ubuntu-noble
|
||||
if: inputs.LINUX == 'ubuntu-noble'
|
||||
run: package_cloud yank bunkerity/${{ inputs.REPO }}/ubuntu/noble bunkerweb${{ inputs.SEPARATOR }}${{ inputs.BW_VERSION }}${{ inputs.SEPARATOR }}${{ inputs.SUFFIX }}${{ inputs.PACKAGE_ARCH }}.${{ inputs.PACKAGE }}
|
||||
continue-on-error: true
|
||||
env:
|
||||
PACKAGECLOUD_TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }}
|
||||
# Update name
|
||||
# - name: Rename package
|
||||
# if: inputs.BW_VERSION == 'testing'
|
||||
|
|
|
|||
25
.github/workflows/ui.yml
vendored
25
.github/workflows/ui.yml
vendored
|
|
@ -63,13 +63,34 @@ jobs:
|
|||
security-events: write
|
||||
|
||||
# UI tests
|
||||
prepare-tests-ui:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
- id: set-matrix
|
||||
run: |
|
||||
tests=$(find ./tests/ui/ -name "*_page.py" -type f -printf "%f\n" | jq -c --raw-input --slurp 'split("\n")| .[0:-1]')
|
||||
echo "tests=$tests" >> $GITHUB_OUTPUT
|
||||
outputs:
|
||||
tests: ${{ steps.set-matrix.outputs.tests }}
|
||||
tests-ui:
|
||||
needs: [codeql, build-containers]
|
||||
needs: [prepare-tests-ui, build-containers]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
test: ${{ fromJson(needs.prepare-tests-ui.outputs.tests) }}
|
||||
uses: ./.github/workflows/tests-ui.yml
|
||||
with:
|
||||
TEST: ${{ matrix.test }}
|
||||
RELEASE: ui
|
||||
tests-ui-linux:
|
||||
needs: [codeql, build-packages]
|
||||
needs: [prepare-tests-ui, build-packages]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
test: ${{ fromJson(needs.prepare-tests-ui.outputs.tests) }}
|
||||
uses: ./.github/workflows/tests-ui-linux.yml
|
||||
with:
|
||||
TEST: ${{ matrix.test }}
|
||||
RELEASE: ui
|
||||
|
|
|
|||
|
|
@ -32,6 +32,24 @@
|
|||
"regex": "^\\/[\\w\\].~:\\/?#\\[@!$\\&'\\(\\)*+,;=\\-]*$",
|
||||
"type": "text"
|
||||
},
|
||||
"ANTIBOT_TIME_RESOLVE": {
|
||||
"context": "multisite",
|
||||
"default": "60",
|
||||
"help": "Maximum time (in seconds) clients have to resolve the challenge. Once this time has passed, a new challenge will be generated.",
|
||||
"id": "antibot-time-resolve",
|
||||
"label": "Time to resolve",
|
||||
"regex": "^[0-9]+$",
|
||||
"type": "text"
|
||||
},
|
||||
"ANTIBOT_TIME_VALID": {
|
||||
"context": "multisite",
|
||||
"default": "86400",
|
||||
"help": "Maximum validity time of solved challenges. Once this time has passed, clients will need to resolve a new one.",
|
||||
"id": "antibot-time-valid",
|
||||
"label": "Time valid",
|
||||
"regex": "^[0-9]+$",
|
||||
"type": "text"
|
||||
},
|
||||
"ANTIBOT_RECAPTCHA_SCORE": {
|
||||
"context": "multisite",
|
||||
"default": "0.7",
|
||||
|
|
@ -94,24 +112,6 @@
|
|||
"label": "Turnstile secret",
|
||||
"regex": "^(0x[\\w\\-]+)?$",
|
||||
"type": "password"
|
||||
},
|
||||
"ANTIBOT_TIME_RESOLVE": {
|
||||
"context": "multisite",
|
||||
"default": "60",
|
||||
"help": "Maximum time (in seconds) clients have to resolve the challenge. Once this time has passed, a new challenge will be generated.",
|
||||
"id": "antibot-time-resolve",
|
||||
"label": "Time to resolve",
|
||||
"regex": "^[0-9]+$",
|
||||
"type": "text"
|
||||
},
|
||||
"ANTIBOT_TIME_VALID": {
|
||||
"context": "multisite",
|
||||
"default": "86400",
|
||||
"help": "Maximum validity time of solved challenges. Once this time has passed, clients will need to resolve a new one.",
|
||||
"id": "antibot-time-valid",
|
||||
"label": "Time valid",
|
||||
"regex": "^[0-9]+$",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,19 +14,10 @@
|
|||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"BACKUP_DIRECTORY": {
|
||||
"context": "global",
|
||||
"default": "/var/lib/bunkerweb/backups",
|
||||
"help": "The directory where the backup will be stored",
|
||||
"id": "backup-directory",
|
||||
"label": "Backup directory",
|
||||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BACKUP_SCHEDULE": {
|
||||
"context": "global",
|
||||
"default": "daily",
|
||||
"help": "The frequency of the backup",
|
||||
"help": "The frequency of the backup (daily, weekly or monthly)",
|
||||
"id": "backup-schedule",
|
||||
"label": "Backup schedule",
|
||||
"regex": "^(daily|weekly|monthly)$",
|
||||
|
|
@ -41,6 +32,15 @@
|
|||
"label": "Backup rotation",
|
||||
"regex": "^[1-9][0-9]*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BACKUP_DIRECTORY": {
|
||||
"context": "global",
|
||||
"default": "/var/lib/bunkerweb/backups",
|
||||
"help": "The directory where the backup will be stored",
|
||||
"id": "backup-directory",
|
||||
"label": "Backup directory",
|
||||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
"jobs": [
|
||||
|
|
|
|||
|
|
@ -23,15 +23,6 @@
|
|||
"regex": "^( *([1-5]\\d{2})(?!.*\\2) *)+$",
|
||||
"type": "text"
|
||||
},
|
||||
"BAD_BEHAVIOR_BAN_TIME": {
|
||||
"context": "multisite",
|
||||
"default": "86400",
|
||||
"help": "The duration time (in seconds) of a ban when the corresponding IP has reached the threshold.",
|
||||
"id": "bad-behavior-ban-time",
|
||||
"label": "Ban duration (in seconds)",
|
||||
"regex": "^\\d+",
|
||||
"type": "text"
|
||||
},
|
||||
"BAD_BEHAVIOR_THRESHOLD": {
|
||||
"context": "multisite",
|
||||
"default": "10",
|
||||
|
|
@ -49,6 +40,15 @@
|
|||
"label": "Period (in seconds)",
|
||||
"regex": "^\\d+",
|
||||
"type": "text"
|
||||
},
|
||||
"BAD_BEHAVIOR_BAN_TIME": {
|
||||
"context": "multisite",
|
||||
"default": "86400",
|
||||
"help": "The duration time (in seconds) of a ban when the corresponding IP has reached the threshold.",
|
||||
"id": "bad-behavior-ban-time",
|
||||
"label": "Ban duration (in seconds)",
|
||||
"regex": "^\\d+",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@
|
|||
"regex": "^(?! )( *(((\\b25[0-5]|\\b2[0-4]\\d|\\b[01]?\\d\\d?)(\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)){3})(\\/([1-2][0-9]?|3[0-2]?|[04-9]))?|(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]Z{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?\\d)?\\d)\\.){3}(25[0-5]|(2[0-4]|1?\\d)?\\d)|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?\\d)?\\d)\\.){3}(25[0-5]|(2[0-4]|1?\\d)?\\d))(\\/(12[0-8]|1[01][0-9]|[0-9][0-9]?))?)(?!.*\\D\\2([^\\d\\/]|$)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "https://www.dan.me.uk/torlist/?exit",
|
||||
"help": "List of URLs, separated with spaces, containing bad IP/network to block.",
|
||||
"id": "blacklist-ip-urls",
|
||||
"label": "Blacklist IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"BLACKLIST_RDNS": {
|
||||
"context": "multisite",
|
||||
"default": ".shodan.io .censys.io",
|
||||
"help": "List of reverse DNS suffixes, separated with spaces, to block.",
|
||||
"id": "blacklist-rdns",
|
||||
"label": "Blacklist reverse DNS",
|
||||
"regex": "^( *(([^ ]+)(?!.*\\3( |$))) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_RDNS_GLOBAL": {
|
||||
|
|
@ -41,24 +41,6 @@
|
|||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"BLACKLIST_RDNS": {
|
||||
"context": "multisite",
|
||||
"default": ".shodan.io .censys.io",
|
||||
"help": "List of reverse DNS suffixes, separated with spaces, to block.",
|
||||
"id": "blacklist-rdns",
|
||||
"label": "Blacklist reverse DNS",
|
||||
"regex": "^( *(([^ ]+)(?!.*\\3( |$))) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to block.",
|
||||
"id": "blacklist-rdns-urls",
|
||||
"label": "Blacklist reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_ASN": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -68,15 +50,6 @@
|
|||
"regex": "^^( *((ASN?)?(\\d+)\\b(?!.*[SN ]\\4\\b)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to block.",
|
||||
"id": "blacklist-asn-urls",
|
||||
"label": "Blacklist ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_USER_AGENT": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -86,15 +59,6 @@
|
|||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list",
|
||||
"help": "List of URLs, separated with spaces, containing bad User-Agent to block.",
|
||||
"id": "blacklist-user-agent-urls",
|
||||
"label": "Blacklist User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_URI": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -104,15 +68,6 @@
|
|||
"regex": "^( *(.*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_URI_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing bad URI to block.",
|
||||
"id": "blacklist-uri-urls",
|
||||
"label": "Blacklist URI URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_IP": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -122,15 +77,6 @@
|
|||
"regex": "^(?! )( *(((\\b25[0-5]|\\b2[0-4]\\d|\\b[01]?\\d\\d?)(\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)){3})(\\/([1-2][0-9]?|3[0-2]?|[04-9]))?|(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]Z{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?\\d)?\\d)\\.){3}(25[0-5]|(2[0-4]|1?\\d)?\\d)|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?\\d)?\\d)\\.){3}(25[0-5]|(2[0-4]|1?\\d)?\\d))(\\/(12[0-8]|1[01][0-9]|[0-9][0-9]?))?)(?!.*\\D\\2([^\\d\\/]|$)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing IP/network to ignore in the blacklist.",
|
||||
"id": "blacklist-ignore-ip-urls",
|
||||
"label": "Blacklist ignore IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_RDNS": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -140,15 +86,6 @@
|
|||
"regex": "^( *(([^ ]+)(?!.*\\3( |$))) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to ignore in the blacklist.",
|
||||
"id": "blacklist-ignore-rdns-urls",
|
||||
"label": "Blacklist ignore reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_ASN": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -158,15 +95,6 @@
|
|||
"regex": "^^( *((ASN?)?(\\d+)\\b(?!.*[SN ]\\4\\b)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to ignore in the blacklist.",
|
||||
"id": "blacklist-ignore-asn-urls",
|
||||
"label": "Blacklist ignore ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_USER_AGENT": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -176,15 +104,6 @@
|
|||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing User-Agent to ignore in the blacklist.",
|
||||
"id": "blacklist-ignore-user-agent-urls",
|
||||
"label": "Blacklist ignore User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_URI": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -194,6 +113,87 @@
|
|||
"regex": "^( *(.*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "https://www.dan.me.uk/torlist/?exit",
|
||||
"help": "List of URLs, separated with spaces, containing bad IP/network to block.",
|
||||
"id": "blacklist-ip-urls",
|
||||
"label": "Blacklist IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to block.",
|
||||
"id": "blacklist-rdns-urls",
|
||||
"label": "Blacklist reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to block.",
|
||||
"id": "blacklist-asn-urls",
|
||||
"label": "Blacklist ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list",
|
||||
"help": "List of URLs, separated with spaces, containing bad User-Agent to block.",
|
||||
"id": "blacklist-user-agent-urls",
|
||||
"label": "Blacklist User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_URI_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing bad URI to block.",
|
||||
"id": "blacklist-uri-urls",
|
||||
"label": "Blacklist URI URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing IP/network to ignore in the blacklist.",
|
||||
"id": "blacklist-ignore-ip-urls",
|
||||
"label": "Blacklist ignore IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to ignore in the blacklist.",
|
||||
"id": "blacklist-ignore-rdns-urls",
|
||||
"label": "Blacklist ignore reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to ignore in the blacklist.",
|
||||
"id": "blacklist-ignore-asn-urls",
|
||||
"label": "Blacklist ignore ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing User-Agent to ignore in the blacklist.",
|
||||
"id": "blacklist-ignore-user-agent-urls",
|
||||
"label": "Blacklist ignore User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"BLACKLIST_IGNORE_URI_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
|
|
|
|||
|
|
@ -23,6 +23,33 @@
|
|||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"CORS_ALLOW_METHODS": {
|
||||
"context": "multisite",
|
||||
"default": "GET, POST, OPTIONS",
|
||||
"help": "Value of the Access-Control-Allow-Methods header.",
|
||||
"id": "cors-allow-methods",
|
||||
"label": "Access-Control-Allow-Methods value",
|
||||
"regex": "^(\\*|(?![, ])(,? ?(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH)(?!.*\\3))*)?$",
|
||||
"type": "text"
|
||||
},
|
||||
"CORS_ALLOW_HEADERS": {
|
||||
"context": "multisite",
|
||||
"default": "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range",
|
||||
"help": "Value of the Access-Control-Allow-Headers header.",
|
||||
"id": "cors-allow-headers",
|
||||
"label": "Access-Control-Allow-Headers value",
|
||||
"regex": "^(\\*|(?![, ])(,? ?([\\w\\-]+)(?!.*\\3(?!.)))*)?$",
|
||||
"type": "text"
|
||||
},
|
||||
"CORS_ALLOW_CREDENTIALS": {
|
||||
"context": "multisite",
|
||||
"default": "no",
|
||||
"help": "Send the Access-Control-Allow-Credentials header.",
|
||||
"id": "cors-allow-credentials",
|
||||
"label": "Send Access-Control-Allow-Credentials",
|
||||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"CORS_EXPOSE_HEADERS": {
|
||||
"context": "multisite",
|
||||
"default": "Content-Length,Content-Range",
|
||||
|
|
@ -71,33 +98,6 @@
|
|||
"regex": "^\\d+$",
|
||||
"type": "text"
|
||||
},
|
||||
"CORS_ALLOW_CREDENTIALS": {
|
||||
"context": "multisite",
|
||||
"default": "no",
|
||||
"help": "Send the Access-Control-Allow-Credentials header.",
|
||||
"id": "cors-allow-credentials",
|
||||
"label": "Send Access-Control-Allow-Credentials",
|
||||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"CORS_ALLOW_METHODS": {
|
||||
"context": "multisite",
|
||||
"default": "GET, POST, OPTIONS",
|
||||
"help": "Value of the Access-Control-Allow-Methods header.",
|
||||
"id": "cors-allow-methods",
|
||||
"label": "Access-Control-Allow-Methods value",
|
||||
"regex": "^(\\*|(?![, ])(,? ?(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH)(?!.*\\3))*)?$",
|
||||
"type": "text"
|
||||
},
|
||||
"CORS_ALLOW_HEADERS": {
|
||||
"context": "multisite",
|
||||
"default": "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range",
|
||||
"help": "Value of the Access-Control-Allow-Headers header.",
|
||||
"id": "cors-allow-headers",
|
||||
"label": "Access-Control-Allow-Headers value",
|
||||
"regex": "^(\\*|(?![, ])(,? ?([\\w\\-]+)(?!.*\\3(?!.)))*)?$",
|
||||
"type": "text"
|
||||
},
|
||||
"CORS_DENY_REQUEST": {
|
||||
"context": "multisite",
|
||||
"default": "yes",
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@
|
|||
"regex": "^(?! )( *(((\\b25[0-5]|\\b2[0-4]\\d|\\b[01]?\\d\\d?)(\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)){3})(\\/([1-2][0-9]?|3[0-2]?|[04-9]))?|(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]Z{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?\\d)?\\d)\\.){3}(25[0-5]|(2[0-4]|1?\\d)?\\d)|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?\\d)?\\d)\\.){3}(25[0-5]|(2[0-4]|1?\\d)?\\d))(\\/(12[0-8]|1[01][0-9]|[0-9][0-9]?))?)(?!.*\\D\\2([^\\d\\/]|$)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_IP_URLS": {
|
||||
"context": "global",
|
||||
"GREYLIST_RDNS": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good IP/network to put into the greylist.",
|
||||
"id": "greylist-ip-urls",
|
||||
"label": "Greylist IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"help": "List of reverse DNS suffixes, separated with spaces, to put into the greylist.",
|
||||
"id": "greylist-rdns",
|
||||
"label": "Greylist reverse DNS",
|
||||
"regex": "^( *(([^ ]+)(?!.*\\3( |$))) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_RDNS_GLOBAL": {
|
||||
|
|
@ -41,24 +41,6 @@
|
|||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"GREYLIST_RDNS": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
"help": "List of reverse DNS suffixes, separated with spaces, to put into the greylist.",
|
||||
"id": "greylist-rdns",
|
||||
"label": "Greylist reverse DNS",
|
||||
"regex": "^( *(([^ ]+)(?!.*\\3( |$))) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to put into the greylist.",
|
||||
"id": "greylist-rdns-urls",
|
||||
"label": "Greylist reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_ASN": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -68,15 +50,6 @@
|
|||
"regex": "^^( *((ASN?)?(\\d+)\\b(?!.*[SN ]\\4\\b)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to put into the greylist.",
|
||||
"id": "greylist-asn-urls",
|
||||
"label": "Greylist ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_USER_AGENT": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -86,15 +59,6 @@
|
|||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good User-Agent to put into the greylist.",
|
||||
"id": "greylist-user-agent-urls",
|
||||
"label": "Greylist User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_URI": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -104,6 +68,42 @@
|
|||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good IP/network to put into the greylist.",
|
||||
"id": "greylist-ip-urls",
|
||||
"label": "Greylist IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to put into the greylist.",
|
||||
"id": "greylist-rdns-urls",
|
||||
"label": "Greylist reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to put into the greylist.",
|
||||
"id": "greylist-asn-urls",
|
||||
"label": "Greylist ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good User-Agent to put into the greylist.",
|
||||
"id": "greylist-user-agent-urls",
|
||||
"label": "Greylist User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"GREYLIST_URI_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
|
|
|
|||
|
|
@ -32,15 +32,6 @@
|
|||
"regex": "^(?! )( *(((\\b25[0-5]|\\b2[0-4]\\d|\\b[01]?\\d\\d?)(\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)){3})(\\/([1-2][0-9]?|3[0-2]?|[04-9]))?|(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]Z{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?\\d)?\\d)\\.){3}(25[0-5]|(2[0-4]|1?\\d)?\\d)|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?\\d)?\\d)\\.){3}(25[0-5]|(2[0-4]|1?\\d)?\\d))(\\/(12[0-8]|1[01][0-9]|[0-9][0-9]?))?)(?!.*\\D\\2([^\\d\\/]|$)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"REAL_IP_FROM_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs containing trusted IPs / networks, separated with spaces, where proxied requests come from.",
|
||||
"id": "real-ip-from-urls",
|
||||
"label": "Real IP from URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"REAL_IP_HEADER": {
|
||||
"context": "multisite",
|
||||
"default": "X-Forwarded-For",
|
||||
|
|
@ -58,6 +49,15 @@
|
|||
"label": "Real IP recursive",
|
||||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"REAL_IP_FROM_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs containing trusted IPs / networks, separated with spaces, where proxied requests come from.",
|
||||
"id": "real-ip-from-urls",
|
||||
"label": "Real IP from URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
"jobs": [
|
||||
|
|
|
|||
|
|
@ -68,24 +68,6 @@
|
|||
"regex": "^[0-9]+$",
|
||||
"type": "text"
|
||||
},
|
||||
"REDIS_KEEPALIVE_IDLE": {
|
||||
"context": "global",
|
||||
"default": "30000",
|
||||
"help": "Max idle time (in ms) before closing redis connection in the pool.",
|
||||
"id": "redis-keepalive-idle",
|
||||
"label": "Redis keepalive idle (ms)",
|
||||
"regex": "^[0-9]+$",
|
||||
"type": "text"
|
||||
},
|
||||
"REDIS_KEEPALIVE_POOL": {
|
||||
"context": "global",
|
||||
"default": "10",
|
||||
"help": "Max number of redis connection(s) kept in the pool.",
|
||||
"id": "redis-keepalive-pool",
|
||||
"label": "Redis keepalive pool",
|
||||
"regex": "^[0-9]+$",
|
||||
"type": "text"
|
||||
},
|
||||
"REDIS_USERNAME": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
|
|
@ -139,6 +121,24 @@
|
|||
"label": "Redis sentinel master",
|
||||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"REDIS_KEEPALIVE_IDLE": {
|
||||
"context": "global",
|
||||
"default": "30000",
|
||||
"help": "Max idle time (in ms) before closing redis connection in the pool.",
|
||||
"id": "redis-keepalive-idle",
|
||||
"label": "Redis keepalive idle (ms)",
|
||||
"regex": "^[0-9]+$",
|
||||
"type": "text"
|
||||
},
|
||||
"REDIS_KEEPALIVE_POOL": {
|
||||
"context": "global",
|
||||
"default": "10",
|
||||
"help": "Max number of redis connection(s) kept in the pool.",
|
||||
"id": "redis-keepalive-pool",
|
||||
"label": "Redis keepalive pool",
|
||||
"regex": "^[0-9]+$",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,15 @@
|
|||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"REVERSE_PROXY_CUSTOM_HOST": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
"help": "Override Host header sent to upstream server.",
|
||||
"id": "reverse-proxy-custom-host",
|
||||
"label": "Reverse proxy custom host",
|
||||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"REVERSE_PROXY_HOST": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -123,6 +132,46 @@
|
|||
"type": "text",
|
||||
"multiple": "reverse-proxy"
|
||||
},
|
||||
"REVERSE_PROXY_CONNECT_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
"default": "60s",
|
||||
"help": "Timeout when connecting to the proxied resource.",
|
||||
"id": "reverse-proxy-connect-timeout",
|
||||
"label": "Reverse proxy connect timeout",
|
||||
"regex": "^\\d+(ms?|[shdwMy])$",
|
||||
"type": "text",
|
||||
"multiple": "reverse-proxy"
|
||||
},
|
||||
"REVERSE_PROXY_READ_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
"default": "60s",
|
||||
"help": "Timeout when reading from the proxied resource.",
|
||||
"id": "reverse-proxy-read-timeout",
|
||||
"label": "Reverse proxy read timeout",
|
||||
"regex": "^\\d+(ms?|[shdwMy])$",
|
||||
"type": "text",
|
||||
"multiple": "reverse-proxy"
|
||||
},
|
||||
"REVERSE_PROXY_SEND_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
"default": "60s",
|
||||
"help": "Timeout when sending to the proxied resource.",
|
||||
"id": "reverse-proxy-send-timeout",
|
||||
"label": "Reverse proxy send timeout",
|
||||
"regex": "^\\d+(ms?|[shdwMy])$",
|
||||
"type": "text",
|
||||
"multiple": "reverse-proxy"
|
||||
},
|
||||
"REVERSE_PROXY_INCLUDES": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
"help": "Additional configuration to include in the location block, separated with spaces.",
|
||||
"id": "reverse-proxy-includes",
|
||||
"label": "Reverse proxy includes",
|
||||
"regex": "^(?! )( ?(\\w+)(?!.*\\b\\2\\b))*$",
|
||||
"type": "text",
|
||||
"multiple": "reverse-proxy"
|
||||
},
|
||||
"USE_PROXY_CACHE": {
|
||||
"context": "multisite",
|
||||
"default": "no",
|
||||
|
|
@ -212,55 +261,6 @@
|
|||
"label": "Reverse proxy bypass",
|
||||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"REVERSE_PROXY_CONNECT_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
"default": "60s",
|
||||
"help": "Timeout when connecting to the proxied resource.",
|
||||
"id": "reverse-proxy-connect-timeout",
|
||||
"label": "Reverse proxy connect timeout",
|
||||
"regex": "^\\d+(ms?|[shdwMy])$",
|
||||
"type": "text",
|
||||
"multiple": "reverse-proxy"
|
||||
},
|
||||
"REVERSE_PROXY_READ_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
"default": "60s",
|
||||
"help": "Timeout when reading from the proxied resource.",
|
||||
"id": "reverse-proxy-read-timeout",
|
||||
"label": "Reverse proxy read timeout",
|
||||
"regex": "^\\d+(ms?|[shdwMy])$",
|
||||
"type": "text",
|
||||
"multiple": "reverse-proxy"
|
||||
},
|
||||
"REVERSE_PROXY_SEND_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
"default": "60s",
|
||||
"help": "Timeout when sending to the proxied resource.",
|
||||
"id": "reverse-proxy-send-timeout",
|
||||
"label": "Reverse proxy send timeout",
|
||||
"regex": "^\\d+(ms?|[shdwMy])$",
|
||||
"type": "text",
|
||||
"multiple": "reverse-proxy"
|
||||
},
|
||||
"REVERSE_PROXY_INCLUDES": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
"help": "Additional configuration to include in the location block, separated with spaces.",
|
||||
"id": "reverse-proxy-includes",
|
||||
"label": "Reverse proxy includes",
|
||||
"regex": "^(?! )( ?(\\w+)(?!.*\\b\\2\\b))*$",
|
||||
"type": "text",
|
||||
"multiple": "reverse-proxy"
|
||||
},
|
||||
"REVERSE_PROXY_CUSTOM_HOST": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
"help": "Override Host header sent to upstream server.",
|
||||
"id": "reverse-proxy-custom-host",
|
||||
"label": "Reverse proxy custom host",
|
||||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@
|
|||
"regex": "^(?! )( *(((\\b25[0-5]|\\b2[0-4]\\d|\\b[01]?\\d\\d?)(\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)){3})(\\/([1-2][0-9]?|3[0-2]?|[04-9]))?|(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]Z{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?\\d)?\\d)\\.){3}(25[0-5]|(2[0-4]|1?\\d)?\\d)|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?\\d)?\\d)\\.){3}(25[0-5]|(2[0-4]|1?\\d)?\\d))(\\/(12[0-8]|1[01][0-9]|[0-9][0-9]?))?)(?!.*\\D\\2([^\\d\\/]|$)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good IP/network to whitelist.",
|
||||
"id": "whitelist-ip-urls",
|
||||
"label": "Whitelist IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"WHITELIST_RDNS": {
|
||||
"context": "multisite",
|
||||
"default": ".google.com .googlebot.com .yandex.ru .yandex.net .yandex.com .search.msn.com .baidu.com .baidu.jp .crawl.yahoo.net .fwd.linkedin.com .twitter.com .twttr.com .discord.com",
|
||||
"help": "List of reverse DNS suffixes, separated with spaces, to whitelist.",
|
||||
"id": "whitelist-rdns",
|
||||
"label": "Whitelist reverse DNS",
|
||||
"regex": "^( *(([^ ]+)(?!.*\\3( |$))) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_RDNS_GLOBAL": {
|
||||
|
|
@ -41,24 +41,6 @@
|
|||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"WHITELIST_RDNS": {
|
||||
"context": "multisite",
|
||||
"default": ".google.com .googlebot.com .yandex.ru .yandex.net .yandex.com .search.msn.com .baidu.com .baidu.jp .crawl.yahoo.net .fwd.linkedin.com .twitter.com .twttr.com .discord.com",
|
||||
"help": "List of reverse DNS suffixes, separated with spaces, to whitelist.",
|
||||
"id": "whitelist-rdns",
|
||||
"label": "Whitelist reverse DNS",
|
||||
"regex": "^( *(([^ ]+)(?!.*\\3( |$))) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist.",
|
||||
"id": "whitelist-rdns-urls",
|
||||
"label": "Whitelist reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_ASN": {
|
||||
"context": "multisite",
|
||||
"default": "32934",
|
||||
|
|
@ -68,15 +50,6 @@
|
|||
"regex": "^^( *((ASN?)?(\\d+)\\b(?!.*[SN ]\\4\\b)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to whitelist.",
|
||||
"id": "whitelist-asn-urls",
|
||||
"label": "Whitelist ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_USER_AGENT": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -86,15 +59,6 @@
|
|||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good User-Agent to whitelist.",
|
||||
"id": "whitelist-user-agent-urls",
|
||||
"label": "Whitelist User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_URI": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
|
|
@ -104,6 +68,42 @@
|
|||
"regex": "^( *(.*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good IP/network to whitelist.",
|
||||
"id": "whitelist-ip-urls",
|
||||
"label": "Whitelist IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist.",
|
||||
"id": "whitelist-rdns-urls",
|
||||
"label": "Whitelist reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to whitelist.",
|
||||
"id": "whitelist-asn-urls",
|
||||
"label": "Whitelist ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good User-Agent to whitelist.",
|
||||
"id": "whitelist-user-agent-urls",
|
||||
"label": "Whitelist User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
"type": "text"
|
||||
},
|
||||
"WHITELIST_URI_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
|
|
|
|||
|
|
@ -1,129 +1,129 @@
|
|||
{
|
||||
"name": "medium",
|
||||
"description": "Generic settings template with high security level required for your web service. False positives will certainly appear without any custom edit.",
|
||||
"steps": [
|
||||
"name": "medium",
|
||||
"description": "Generic settings template with high security level required for your web service. False positives will certainly appear without any custom edit.",
|
||||
"steps": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "yes",
|
||||
"REVERSE_PROXY_WS": "no",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''",
|
||||
"SERVE_FILES": "no"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable and configure HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes",
|
||||
"SSL_PROTOCOLS": "TLSv1.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"DENY_HTTP_STATUS": "444",
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD",
|
||||
"MAX_SIZES": "10m",
|
||||
"COOKIE_FLAGS": "* HttpOnly SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "object-src 'none'; form-action 'self'; frame-ancestors 'self';",
|
||||
"X_FRAME_OPTIONS": "SAMEORIGIN",
|
||||
"PERMISSIONS_POLICY": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()",
|
||||
"FEATURE_POLICY": "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 404 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "86400",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "5",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": "10",
|
||||
"LIMIT_CONN_MAX_HTTP2": "100",
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "2r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "captcha",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CORS",
|
||||
"description": "Configure Cross-Origin Resource Sharing (CORS) to allow/deny external requests to your web service.",
|
||||
"settings": {
|
||||
"USE_CORS": "yes",
|
||||
"CORS_ALLOW_ORIGIN": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Reverse scan",
|
||||
"description": "Configure reverse scan of client to detect open proxy or datacenter connections.",
|
||||
"settings": {
|
||||
"USE_REVERSE_SCAN": "yes",
|
||||
"REVERSE_SCAN_PORTS": "22 80 443 3128 8000 8080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes",
|
||||
"MODSECURITY_CRS_VERSION": "4"
|
||||
},
|
||||
"configs": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "yes",
|
||||
"REVERSE_PROXY_WS": "no",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''",
|
||||
"SERVE_FILES": "no"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable and configure HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes",
|
||||
"SSL_PROTOCOLS": "TLSv1.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"DENY_HTTP_STATUS": "444",
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD",
|
||||
"MAX_SIZES": "10m",
|
||||
"COOKIE_FLAGS": "* HttpOnly SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "object-src 'none'; form-action 'self'; frame-ancestors 'self';",
|
||||
"X_FRAME_OPTIONS": "SAMEORIGIN",
|
||||
"PERMISSIONS_POLICY": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()",
|
||||
"FEATURE_POLICY": "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 404 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "86400",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "5",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": "10",
|
||||
"LIMIT_CONN_MAX_HTTP2": "100",
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "2r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "captcha",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CORS",
|
||||
"description": "Configure Cross-Origin Resource Sharing (CORS) to allow/deny external requests to your web service.",
|
||||
"settings": {
|
||||
"USE_CORS": "yes",
|
||||
"CORS_ALLOW_ORIGIN": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Reverse scan",
|
||||
"description": "Configure reverse scan of client to detect open proxy or datacenter connections.",
|
||||
"settings": {
|
||||
"USE_REVERSE_SCAN": "yes",
|
||||
"REVERSE_SCAN_PORTS": "22 80 443 3128 8000 8080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes",
|
||||
"MODSECURITY_CRS_VERSION": "4"
|
||||
},
|
||||
"configs": [
|
||||
{
|
||||
"name": "template-high",
|
||||
"type": "modsec-crs",
|
||||
"data": "SecAction \"id:900000,phase:1,pass,t:none,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',setvar:tx.blocking_paranoia_level=4\""
|
||||
}
|
||||
]
|
||||
"name": "template-high",
|
||||
"type": "modsec-crs",
|
||||
"data": "SecAction \"id:900000,phase:1,pass,t:none,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.2.0',setvar:tx.blocking_paranoia_level=4\""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,111 +1,111 @@
|
|||
{
|
||||
"name": "low",
|
||||
"description": "Generic settings template with low security level to avoid false positives and get started with BunkerWeb.",
|
||||
"steps": [
|
||||
"name": "low",
|
||||
"description": "Generic settings template with low security level to avoid false positives and get started with BunkerWeb.",
|
||||
"steps": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "no",
|
||||
"REVERSE_PROXY_WS": "yes",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD|PUT|PATCH|OPTIONS|DELETE",
|
||||
"MAX_SIZES": "50m",
|
||||
"COOKIE_FLAGS": "* SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "",
|
||||
"X_FRAME_OPTIONS": "",
|
||||
"PERMISSIONS_POLICY": "",
|
||||
"FEATURE_POLICY": "",
|
||||
"KEEP_UPSTREAM_HEADERS": "*"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "3600",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "20",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": 20,
|
||||
"LIMIT_CONN_MAX_HTTP2": 200,
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "5r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "no"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "no",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes"
|
||||
},
|
||||
"configs": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "no",
|
||||
"REVERSE_PROXY_WS": "yes",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD|PUT|PATCH|OPTIONS|DELETE",
|
||||
"MAX_SIZES": "50m",
|
||||
"COOKIE_FLAGS": "* SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "",
|
||||
"X_FRAME_OPTIONS": "",
|
||||
"PERMISSIONS_POLICY": "",
|
||||
"FEATURE_POLICY": "",
|
||||
"KEEP_UPSTREAM_HEADERS": "*"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "3600",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "20",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": 20,
|
||||
"LIMIT_CONN_MAX_HTTP2": 200,
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "5r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "no"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "no",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes"
|
||||
},
|
||||
"configs": [
|
||||
{
|
||||
"name": "template-low",
|
||||
"type": "modsec-crs",
|
||||
"description": "Override ModSecurity CRS settings.",
|
||||
"data": "SecAction \"id:900110,phase:1,nolog,pass,t:none,setvar:tx.inbound_anomaly_score_threshold=7,setvar:tx.outbound_anomaly_score_threshold=4\""
|
||||
}
|
||||
]
|
||||
"name": "template-low",
|
||||
"type": "modsec-crs",
|
||||
"description": "Override ModSecurity CRS settings.",
|
||||
"data": "SecAction \"id:900110,phase:1,nolog,pass,t:none,setvar:tx.inbound_anomaly_score_threshold=7,setvar:tx.outbound_anomaly_score_threshold=4\""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,110 +1,110 @@
|
|||
{
|
||||
"name": "medium",
|
||||
"description": "Generic settings template with medium security level aimed for average web service in production. False positives may appear depending on your environment.",
|
||||
"steps": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "yes",
|
||||
"REVERSE_PROXY_WS": "no",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD",
|
||||
"MAX_SIZES": "10m",
|
||||
"COOKIE_FLAGS": "* HttpOnly SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "object-src 'none'; form-action 'self'; frame-ancestors 'self';",
|
||||
"X_FRAME_OPTIONS": "SAMEORIGIN",
|
||||
"PERMISSIONS_POLICY": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()",
|
||||
"FEATURE_POLICY": "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 404 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "86400",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "10",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": "10",
|
||||
"LIMIT_CONN_MAX_HTTP2": "100",
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "2r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "javascript",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CORS",
|
||||
"description": "Configure Cross-Origin Resource Sharing (CORS) to allow/deny external requests to your web service.",
|
||||
"settings": {
|
||||
"USE_CORS": "no",
|
||||
"CORS_ALLOW_ORIGIN": "*"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
"name": "medium",
|
||||
"description": "Generic settings template with medium security level aimed for average web service in production. False positives may appear depending on your environment.",
|
||||
"steps": [
|
||||
{
|
||||
"name": "Server configuration",
|
||||
"description": "Configure your server name and reverse proxy settings. Don't forget to add the corresponding DNS A entry pointing to your BunkerWeb IP.",
|
||||
"settings": {
|
||||
"SERVER_NAME": "www.example.com",
|
||||
"USE_REVERSE_PROXY": "yes",
|
||||
"REVERSE_PROXY_HOST": "http://my-upstream-server:8080",
|
||||
"REVERSE_PROXY_URL": "/",
|
||||
"REVERSE_PROXY_INTERCEPT_ERRORS": "yes",
|
||||
"REVERSE_PROXY_WS": "no",
|
||||
"REVERSE_PROXY_CUSTOM_HOST": "",
|
||||
"REVERSE_PROXY_HEADERS": "Accept-Encoding ''"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"description": "Enable/disable HTTPS for your service.",
|
||||
"settings": {
|
||||
"AUTO_LETS_ENCRYPT": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTP configuration",
|
||||
"description": "Miscellaneous settings related to HTTP protocol.",
|
||||
"settings": {
|
||||
"USE_GZIP": "yes",
|
||||
"USE_BROTLI": "yes",
|
||||
"ALLOWED_METHODS": "GET|POST|HEAD",
|
||||
"MAX_SIZES": "10m",
|
||||
"COOKIE_FLAGS": "* HttpOnly SameSite=Lax",
|
||||
"CONTENT_SECURITY_POLICY": "object-src 'none'; form-action 'self'; frame-ancestors 'self';",
|
||||
"X_FRAME_OPTIONS": "SAMEORIGIN",
|
||||
"PERMISSIONS_POLICY": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), usb=(), web-share=(), xr-spatial-tracking=()",
|
||||
"FEATURE_POLICY": "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animation 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; speaker-selection 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none';"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bad behavior",
|
||||
"description": "Configure automatic bans when detecting bad behaviors on your web service.",
|
||||
"settings": {
|
||||
"USE_BAD_BEHAVIOR": "yes",
|
||||
"BAD_BEHAVIOR_STATUS_CODES": "400 401 403 404 405 429 444",
|
||||
"BAD_BEHAVIOR_BAN_TIME": "86400",
|
||||
"BAD_BEHAVIOR_THRESHOLD": "10",
|
||||
"BAD_BEHAVIOR_COUNT_TIME": "60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Limit",
|
||||
"description": "Configure requests and connections limits on your web service.",
|
||||
"settings": {
|
||||
"USE_LIMIT_CONN": "yes",
|
||||
"LIMIT_CONN_MAX_HTTP1": "10",
|
||||
"LIMIT_CONN_MAX_HTTP2": "100",
|
||||
"USE_LIMIT_REQ": "yes",
|
||||
"LIMIT_REQ_URL": "/",
|
||||
"LIMIT_REQ_RATE": "2r/s"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "DNSBL",
|
||||
"description": "Enable/disable DNSBL protection. Might generate false positives especially if you have a worldwide audience.",
|
||||
"settings": {
|
||||
"USE_DNSBL": "yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"description": "Configure allowed countries to reach out your web service. Recommended if you protect a restricted area such as extranet or administration panel.",
|
||||
"settings": {
|
||||
"WHITELIST_COUNTRY": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antibot",
|
||||
"description": "Enable/disable and configure antibot protection globally on your web service.",
|
||||
"settings": {
|
||||
"USE_ANTIBOT": "javascript",
|
||||
"ANTIBOT_TIME_RESOLVE": "120",
|
||||
"ANTIBOT_TIME_VALID": "86400",
|
||||
"ANTIBOT_RECAPTCHA_SCORE": "0.7",
|
||||
"ANTIBOT_RECAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_RECAPTCHA_SECRET": "",
|
||||
"ANTIBOT_HCAPTCHA_SITEKEY": "",
|
||||
"ANTIBOT_HCAPTCHA_SECRET": "",
|
||||
"ANTIBOT_TURNSTILE_SITEKEY": "",
|
||||
"ANTIBOT_TURNSTILE_SECRET": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CORS",
|
||||
"description": "Configure Cross-Origin Resource Sharing (CORS) to allow/deny external requests to your web service.",
|
||||
"settings": {
|
||||
"USE_CORS": "no",
|
||||
"CORS_ALLOW_ORIGIN": "*"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModSecurity",
|
||||
"description": "Enable/disable and configure ModSecurity on your web service.",
|
||||
"settings": {
|
||||
"USE_MODSECURITY": "yes"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ COPY src/common/gen gen
|
|||
COPY src/common/helpers helpers
|
||||
COPY src/common/settings.json settings.json
|
||||
COPY src/common/utils utils
|
||||
COPY src/common/templates templates
|
||||
COPY src/scheduler scheduler
|
||||
COPY src/ui ui
|
||||
COPY src/VERSION VERSION
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ COPY src/common/gen gen
|
|||
COPY src/common/helpers helpers
|
||||
COPY src/common/settings.json settings.json
|
||||
COPY src/common/utils utils
|
||||
COPY src/common/templates templates
|
||||
COPY src/scheduler scheduler
|
||||
COPY src/ui ui
|
||||
COPY src/VERSION VERSION
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ COPY src/common/gen gen
|
|||
COPY src/common/helpers helpers
|
||||
COPY src/common/settings.json settings.json
|
||||
COPY src/common/utils utils
|
||||
COPY src/common/templates templates
|
||||
COPY src/scheduler scheduler
|
||||
COPY src/ui ui
|
||||
COPY src/VERSION VERSION
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ COPY src/common/gen gen
|
|||
COPY src/common/helpers helpers
|
||||
COPY src/common/settings.json settings.json
|
||||
COPY src/common/utils utils
|
||||
COPY src/common/templates templates
|
||||
COPY src/scheduler scheduler
|
||||
COPY src/ui ui
|
||||
COPY src/VERSION VERSION
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ COPY src/common/gen gen
|
|||
COPY src/common/helpers helpers
|
||||
COPY src/common/settings.json settings.json
|
||||
COPY src/common/utils utils
|
||||
COPY src/common/templates templates
|
||||
COPY src/scheduler scheduler
|
||||
COPY src/ui ui
|
||||
COPY src/VERSION VERSION
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ COPY src/common/gen gen
|
|||
COPY src/common/helpers helpers
|
||||
COPY src/common/settings.json settings.json
|
||||
COPY src/common/utils utils
|
||||
COPY src/common/templates templates
|
||||
COPY src/scheduler scheduler
|
||||
COPY src/ui ui
|
||||
COPY src/VERSION VERSION
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ COPY src/common/gen gen
|
|||
COPY src/common/helpers helpers
|
||||
COPY src/common/settings.json settings.json
|
||||
COPY src/common/utils utils
|
||||
COPY src/common/templates templates
|
||||
COPY src/scheduler scheduler
|
||||
COPY src/ui ui
|
||||
COPY src/VERSION VERSION
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ def generate_custom_configs(configs: List[Dict[str, Any]], *, original_path: Uni
|
|||
tmp_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
tmp_path.write_bytes(custom_config["data"])
|
||||
except OSError as e:
|
||||
logger.debug(format_exc())
|
||||
if custom_config["method"] != "manual":
|
||||
logger.error(
|
||||
f"Error while generating custom configs \"{custom_config['name']}\"{' for service ' + custom_config['service_id'] if custom_config['service_id'] else ''}: {e}"
|
||||
|
|
@ -189,6 +190,7 @@ def generate_external_plugins(plugins: List[Dict[str, Any]], *, original_path: U
|
|||
for job_file in chain(original_path.joinpath(plugin["id"], "jobs").glob("*"), original_path.joinpath(plugin["id"], "bwcli").glob("*")):
|
||||
job_file.chmod(job_file.stat().st_mode | S_IEXEC)
|
||||
except OSError as e:
|
||||
logger.debug(format_exc())
|
||||
if plugin["method"] != "manual":
|
||||
logger.error(f"Error while generating {'pro ' if pro else ''}external plugins \"{plugin['name']}\": {e}")
|
||||
except BaseException as e:
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ COPY src/common/gen gen
|
|||
COPY src/common/settings.json settings.json
|
||||
COPY src/common/utils utils
|
||||
COPY src/common/helpers helpers
|
||||
COPY src/common/templates templates
|
||||
COPY src/ui ui
|
||||
COPY src/VERSION VERSION
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ from src.ConfigFiles import ConfigFiles
|
|||
from src.Config import Config
|
||||
from src.ReverseProxied import ReverseProxied
|
||||
from src.User import AnonymousUser, User
|
||||
from src.Templates import get_ui_templates
|
||||
|
||||
from utils import check_settings, get_b64encoded_qr_image, path_to_dict, get_remain
|
||||
from common_utils import get_integration, get_version # type: ignore
|
||||
|
|
@ -154,6 +155,7 @@ try:
|
|||
SEND_FILE_MAX_AGE_DEFAULT=86400,
|
||||
SCRIPT_NONCE=sha256(urandom(32)).hexdigest(),
|
||||
DB=db,
|
||||
UI_TEMPLATES=get_ui_templates(),
|
||||
)
|
||||
except FileNotFoundError as e:
|
||||
app.logger.error(repr(e), e.filename)
|
||||
|
|
|
|||
31
src/ui/src/Templates.py
Normal file
31
src/ui/src/Templates.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
from json import loads
|
||||
from glob import glob
|
||||
from os import sep
|
||||
from os.path import join
|
||||
|
||||
|
||||
def get_ui_templates():
|
||||
ui_templates = []
|
||||
for template_file in glob(join(sep, "usr", "share", "bunkerweb", "templates", "*.json")):
|
||||
try:
|
||||
ui_template = {}
|
||||
with open(template_file, "r") as f:
|
||||
bw_template = loads(f.read())
|
||||
ui_template = {"name": bw_template["name"], "description": bw_template["description"]}
|
||||
ui_template["steps"] = []
|
||||
for bw_step in bw_template["steps"]:
|
||||
ui_step = {}
|
||||
ui_step["name"] = bw_step["name"]
|
||||
ui_step["description"] = bw_step["description"]
|
||||
ui_step["settings"] = []
|
||||
for setting, value in bw_step["settings"].items():
|
||||
ui_setting = {"setting_id": setting, "value": value}
|
||||
ui_step["settings"].append(ui_setting)
|
||||
ui_template["steps"].append(ui_step)
|
||||
ui_templates.append(ui_template)
|
||||
except Exception as e:
|
||||
# print(e)
|
||||
# TODO: log
|
||||
pass
|
||||
# print(ui_templates, flush=True)
|
||||
return ui_templates
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -6,8 +6,6 @@ import {
|
|||
CheckNoMatchFilter,
|
||||
showInvalid,
|
||||
SettingsAdvanced,
|
||||
SettingsSimple,
|
||||
SettingsSwitch,
|
||||
} from "./utils/settings.js";
|
||||
|
||||
class SettingsService {
|
||||
|
|
@ -24,12 +22,6 @@ class SettingsService {
|
|||
this.settingsMultiple,
|
||||
"services",
|
||||
);
|
||||
this.simpleSettings = new SettingsSimple(
|
||||
document.querySelector("[data-simple][data-services-modal-form]"),
|
||||
this.settingsMultiple,
|
||||
"services",
|
||||
);
|
||||
|
||||
this.initSettingsService();
|
||||
}
|
||||
|
||||
|
|
@ -117,133 +109,6 @@ class SettingsService {
|
|||
forceEnabled,
|
||||
emptyServerName,
|
||||
);
|
||||
|
||||
// Click on right security level dropdown btn
|
||||
// This will fire security level event listener
|
||||
this.simpleSettings.updateData(
|
||||
action,
|
||||
oldServName,
|
||||
operation,
|
||||
settings,
|
||||
forceEnabled,
|
||||
setMethodUI,
|
||||
emptyServerName,
|
||||
);
|
||||
const modeBtn = document.querySelector(
|
||||
"button[data-toggle-settings-mode-btn]",
|
||||
);
|
||||
const mode = modeBtn.getAttribute("data-toggle-settings-mode-btn");
|
||||
if (action === "new") {
|
||||
mode !== "simple" ? modeBtn.click() : null;
|
||||
document
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn="security-level"][value="standard"]`,
|
||||
)
|
||||
.click();
|
||||
document
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn="security-level"][value="custom"]`,
|
||||
)
|
||||
.setAttribute("disabled", "true");
|
||||
} else {
|
||||
mode !== "advanced" ? modeBtn.click() : null;
|
||||
document
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn="security-level"][value="custom"]`,
|
||||
)
|
||||
.removeAttribute("disabled");
|
||||
document
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn="security-level"][value="custom"]`,
|
||||
)
|
||||
.click();
|
||||
}
|
||||
}
|
||||
} catch (err) {}
|
||||
// security level
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.getAttribute("data-setting-select-dropdown-btn") ==
|
||||
"security-level"
|
||||
) {
|
||||
// get current common values
|
||||
const action = this.simpleSettings.currAction;
|
||||
const oldServName = this.simpleSettings.oldServName;
|
||||
const operation = this.simpleSettings.operation;
|
||||
const forceEnabled = this.simpleSettings.forceEnabled;
|
||||
const setMethodUI = this.simpleSettings.setMethodUI;
|
||||
const emptyServerName = this.simpleSettings.emptyServerName;
|
||||
// get custom security level settings of service if custom choose
|
||||
const value = e.target.closest("button").getAttribute("value");
|
||||
|
||||
// mainSettings is the settings of the service
|
||||
let mainSettings;
|
||||
|
||||
// Try to get settings in a valid format
|
||||
try {
|
||||
mainSettings = JSON.parse(
|
||||
document
|
||||
.querySelector(`[data-old-name][data-value="${oldServName}"]`)
|
||||
.closest("[data-services-service]")
|
||||
.getAttribute("data-settings"),
|
||||
);
|
||||
} catch (err) {}
|
||||
|
||||
try {
|
||||
if (!settings) {
|
||||
mainSettings = JSON.parse(
|
||||
document
|
||||
.querySelector(`[data-old-name][data-value="${oldServName}"]`)
|
||||
.closest("[data-services-service]")
|
||||
.getAttribute("data-settings")
|
||||
.replaceAll(`'`, `"`),
|
||||
);
|
||||
}
|
||||
} catch (err) {}
|
||||
|
||||
// In case we want a security level, we need to get the settings of the security level
|
||||
// In order to filter and merge both to avoid overriding disabled settings (method != ui|default)
|
||||
let compareSettings = null;
|
||||
if (value !== "custom") {
|
||||
// Try to get settings in a valid format
|
||||
try {
|
||||
compareSettings = JSON.parse(
|
||||
document
|
||||
.querySelector(`input#security-level-${value}`)
|
||||
.getAttribute("data-settings"),
|
||||
);
|
||||
} catch (err) {}
|
||||
|
||||
try {
|
||||
if (!compareSettings) {
|
||||
compareSettings = JSON.parse(
|
||||
document
|
||||
.querySelector(`input#security-level-${value}`)
|
||||
.getAttribute("data-settings")
|
||||
.replaceAll(`'`, `"`),
|
||||
);
|
||||
}
|
||||
} catch (err) {}
|
||||
}
|
||||
// No main settings if new
|
||||
if (action === "new") {
|
||||
mainSettings = JSON.parse(JSON.stringify(compareSettings));
|
||||
compareSettings = null;
|
||||
}
|
||||
|
||||
this.simpleSettings.setSimple(
|
||||
action,
|
||||
oldServName,
|
||||
operation,
|
||||
mainSettings,
|
||||
compareSettings,
|
||||
setMethodUI,
|
||||
forceEnabled,
|
||||
emptyServerName,
|
||||
true,
|
||||
);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
|
|
@ -260,9 +125,6 @@ class ServiceModal {
|
|||
"[data-services-tabs-select-header]",
|
||||
]);
|
||||
this.modalCard = this.modal.querySelector("[data-services-modal-card]");
|
||||
this.switchModeBtn = this.modal.querySelector(
|
||||
"[data-toggle-settings-mode-btn]",
|
||||
);
|
||||
//modal forms
|
||||
this.formNewEdit = this.modal.querySelector(
|
||||
"[data-advanced][data-services-modal-form]",
|
||||
|
|
@ -270,9 +132,7 @@ class ServiceModal {
|
|||
this.formDelete = this.modal.querySelector(
|
||||
"[data-services-modal-form-delete]",
|
||||
);
|
||||
this.simpleForm = this.modal.querySelector(
|
||||
"[data-simple][data-services-modal-form]",
|
||||
);
|
||||
|
||||
//container
|
||||
this.container = document.querySelector("main");
|
||||
this.currAction = "";
|
||||
|
|
@ -370,10 +230,9 @@ class ServiceModal {
|
|||
this.setCardViewportHeight(action === "delete" ? false : true);
|
||||
this.setHeaderActionsVisible(action === "delete" ? false : true);
|
||||
this.SetSelectTabsVisible(action === "delete" ? false : true);
|
||||
this.setModeVisible(action);
|
||||
this.resetFilterSettings();
|
||||
if (action === "edit" || action === "new" || action === "clone") {
|
||||
this.formNewEdit.classList.remove("hidden");
|
||||
this.simpleForm.classList.remove("hidden");
|
||||
|
||||
const oldNameValue = action === "edit" ? oldServName : "";
|
||||
|
||||
|
|
@ -401,6 +260,20 @@ class ServiceModal {
|
|||
this.openModal();
|
||||
}
|
||||
|
||||
resetFilterSettings() {
|
||||
// Reset select
|
||||
const selectTypeAll = document
|
||||
.querySelector("#filter-type[data-services-setting-select-dropdown]")
|
||||
.querySelector(
|
||||
'button[value="all"][data-services-setting-select-dropdown-btn="type"]',
|
||||
);
|
||||
selectTypeAll.click();
|
||||
const inpKeyword = this.modal.querySelector("input#settings-filter");
|
||||
inpKeyword.value = "";
|
||||
// dispatch event input
|
||||
inpKeyword.dispatchEvent(new Event("input"));
|
||||
}
|
||||
|
||||
setIsDraft(isDraft, method) {
|
||||
const draftVal = isDraft ? "yes" : "no";
|
||||
|
||||
|
|
@ -437,18 +310,12 @@ class ServiceModal {
|
|||
this.modal
|
||||
.querySelector("[data-toggle-draft-btn]")
|
||||
.classList.remove("hidden");
|
||||
this.modal
|
||||
.querySelector("[data-toggle-settings-mode-btn]")
|
||||
.classList.remove("hidden");
|
||||
}
|
||||
|
||||
if (!setVisible) {
|
||||
this.modal
|
||||
.querySelector("[data-toggle-draft-btn]")
|
||||
.classList.add("hidden");
|
||||
this.modal
|
||||
.querySelector("[data-toggle-settings-mode-btn]")
|
||||
.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -464,29 +331,8 @@ class ServiceModal {
|
|||
}
|
||||
}
|
||||
|
||||
switchMode(mode) {
|
||||
if (mode === "advanced") {
|
||||
this.formNewEdit.classList.remove("hidden");
|
||||
this.simpleForm.classList.add("hidden");
|
||||
}
|
||||
|
||||
if (mode === "simple") {
|
||||
this.formNewEdit.classList.add("hidden");
|
||||
this.simpleForm.classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
setModeVisible(action) {
|
||||
if (action === "new" || action === "clone" || action === "edit") {
|
||||
this.switchModeBtn.classList.remove("hidden");
|
||||
} else {
|
||||
this.switchModeBtn.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
hideForms() {
|
||||
this.formNewEdit.classList.add("hidden");
|
||||
this.simpleForm.classList.add("hidden");
|
||||
this.formDelete.classList.add("hidden");
|
||||
}
|
||||
|
||||
|
|
@ -842,13 +688,6 @@ const setFilterGlobal = new FilterSettings(
|
|||
|
||||
const settings = new SettingsService();
|
||||
|
||||
const switchSettings = new SettingsSwitch(
|
||||
document.querySelector("[data-toggle-settings-mode-btn]"),
|
||||
document.querySelector("main"),
|
||||
["advanced", "simple"],
|
||||
"services",
|
||||
);
|
||||
|
||||
const checkServiceModalKeyword = new CheckNoMatchFilter(
|
||||
document.querySelector("input#settings-filter"),
|
||||
"input",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -92,7 +92,15 @@
|
|||
}
|
||||
|
||||
.popover-settings-container {
|
||||
@apply z-[1000] h-fit max-w-[250px] transition-all duration-500 dark:brightness-90 transition rounded-md p-3 -translate-y-7 fixed bg-blue-500;
|
||||
@apply z-[1000] h-fit max-w-[250px] transition-all duration-500 dark:brightness-90 transition rounded-md p-3 -translate-y-7 fixed;
|
||||
}
|
||||
|
||||
.info.popover-settings-container {
|
||||
@apply bg-blue-500;
|
||||
}
|
||||
|
||||
.multisite.popover-settings-container {
|
||||
@apply bg-orange-500;
|
||||
}
|
||||
|
||||
.popover-tab {
|
||||
|
|
|
|||
14
src/ui/templates/services_modal.html
vendored
14
src/ui/templates/services_modal.html
vendored
|
|
@ -31,19 +31,6 @@
|
|||
<path d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button data-toggle-settings-mode-btn="advanced"
|
||||
class="transition hover:brightness-75 dark:hover:brightness-110 sm:ml-4 flex items-center border border-gray-700 dark:border-gray-300 dark:bg-slate-700 bg-gray-50/10 text-gray-800 rounded py-1 px-2 mt-1.5 sm:mt-0">
|
||||
<p data-toggle-settings-mode="simple"
|
||||
class="hidden dark:text-gray-100 mb-0 mr-2 pointer-events-none">Simple</p>
|
||||
<p data-toggle-settings-mode="advanced"
|
||||
class="dark:text-gray-100 mb-0 mr-2 pointer-events-none">Advanced</p>
|
||||
<svg data-toggle-settings-mode="simple" class="hidden translate-y-0.5 w-5 h-5 fill-gray-700 stroke-white/0 dark:fill-gray-300 pointer-events-none" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path fill-rule="evenodd" d="M7.84 1.804A1 1 0 0 1 8.82 1h2.36a1 1 0 0 1 .98.804l.331 1.652a6.993 6.993 0 0 1 1.929 1.115l1.598-.54a1 1 0 0 1 1.186.447l1.18 2.044a1 1 0 0 1-.205 1.251l-1.267 1.113a7.047 7.047 0 0 1 0 2.228l1.267 1.113a1 1 0 0 1 .206 1.25l-1.18 2.045a1 1 0 0 1-1.187.447l-1.598-.54a6.993 6.993 0 0 1-1.929 1.115l-.33 1.652a1 1 0 0 1-.98.804H8.82a1 1 0 0 1-.98-.804l-.331-1.652a6.993 6.993 0 0 1-1.929-1.115l-1.598.54a1 1 0 0 1-1.186-.447l-1.18-2.044a1 1 0 0 1 .205-1.251l1.267-1.114a7.05 7.05 0 0 1 0-2.227L1.821 7.773a1 1 0 0 1-.206-1.25l1.18-2.045a1 1 0 0 1 1.187-.447l1.598.54A6.992 6.992 0 0 1 7.51 3.456l.33-1.652ZM10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<svg data-toggle-settings-mode="advanced" class="translate-y-0.5 w-5 h-5 fill-gray-700 stroke-white/0 dark:fill-gray-300 pointer-events-none" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path fill-rule="evenodd" d="M8.34 1.804A1 1 0 0 1 9.32 1h1.36a1 1 0 0 1 .98.804l.295 1.473c.497.144.971.342 1.416.587l1.25-.834a1 1 0 0 1 1.262.125l.962.962a1 1 0 0 1 .125 1.262l-.834 1.25c.245.445.443.919.587 1.416l1.473.294a1 1 0 0 1 .804.98v1.361a1 1 0 0 1-.804.98l-1.473.295a6.95 6.95 0 0 1-.587 1.416l.834 1.25a1 1 0 0 1-.125 1.262l-.962.962a1 1 0 0 1-1.262.125l-1.25-.834a6.953 6.953 0 0 1-1.416.587l-.294 1.473a1 1 0 0 1-.98.804H9.32a1 1 0 0 1-.98-.804l-.295-1.473a6.957 6.957 0 0 1-1.416-.587l-1.25.834a1 1 0 0 1-1.262-.125l-.962-.962a1 1 0 0 1-.125-1.262l.834-1.25a6.957 6.957 0 0 1-.587-1.416l-1.473-.294A1 1 0 0 1 1 10.68V9.32a1 1 0 0 1 .804-.98l1.473-.295c.144-.497.342-.971.587-1.416l-.834-1.25a1 1 0 0 1 .125-1.262l.962-.962A1 1 0 0 1 5.38 3.03l1.25.834a6.957 6.957 0 0 1 1.416-.587l.294-1.473ZM13 10a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<button class="-translate-y-1"
|
||||
aria-label="close modal"
|
||||
|
|
@ -57,7 +44,6 @@
|
|||
</div>
|
||||
|
||||
{% include "services_modal_settings_advanced.html" %}
|
||||
{% include "services_modal_settings_simple.html" %}
|
||||
{% include "services_modal_delete.html" %}
|
||||
|
||||
</div>
|
||||
|
|
|
|||
156
src/ui/templates/services_modal_settings_simple.html
vendored
156
src/ui/templates/services_modal_settings_simple.html
vendored
|
|
@ -1,156 +0,0 @@
|
|||
{% set security_levels = ['standard', 'advanced', 'high', 'custom'] %}
|
||||
|
||||
{% set standard = {
|
||||
"USE_ANTIBOT": {
|
||||
"value": "javascript",
|
||||
"method": "default"
|
||||
},
|
||||
"SERVER_NAME": {
|
||||
"value": "test",
|
||||
"method": "default"
|
||||
},
|
||||
"LIMIT_REQ_URL": {
|
||||
"value": "/testfesf",
|
||||
"method": "default"
|
||||
},
|
||||
"LIMIT_REQ_RATE": {
|
||||
"value": "1r/s",
|
||||
"method": "default"
|
||||
},
|
||||
"LIMIT_REQ_URL_1": {
|
||||
"value": "/test",
|
||||
"method": "default"
|
||||
},
|
||||
"LIMIT_REQ_RATE_1": {
|
||||
"value": "3r/s",
|
||||
"method": "default"
|
||||
},
|
||||
"CUSTOM_CONFIG_MODSEC_1" : {
|
||||
"value": "test",
|
||||
"method": "default",
|
||||
"type" : "modsec",
|
||||
"name" : "modsec 1"
|
||||
},
|
||||
"CUSTOM_CONFIG_MODSEC_2" : {
|
||||
"value": "test 2",
|
||||
"method": "default",
|
||||
"type" : "modsec",
|
||||
"name" : "modsec 2"
|
||||
},
|
||||
}%}
|
||||
|
||||
{% set advanced = {
|
||||
"USE_ANTIBOT": {
|
||||
"value": "no",
|
||||
"method": "default"
|
||||
},
|
||||
}%}
|
||||
|
||||
{% set high = {
|
||||
"USE_ANTIBOT": {
|
||||
"value": "javascript",
|
||||
"method": "default"
|
||||
},
|
||||
}%}
|
||||
|
||||
{# When multiple, setting_id need to be a setting that is part of a multiple to get all settings on the same group #}
|
||||
{# On levels, we should set a list of dict with setting_id as key and value as value #}
|
||||
|
||||
{% set steps = [
|
||||
{
|
||||
"name" : "STEP 1 - STARTING UP",
|
||||
"description" : "we need some information to get started.",
|
||||
"settings" : [
|
||||
{"plugin_id" : "security-level", "setting_id": "SECURITY_LEVEL", "title" : "DEFINE SECURITY LEVEL", "subtitle" : "This will determine default settings value for the next steps. You'll be allow to modify settings to match your case if needed.", "setting" : {'context': 'global', 'default': 'standard', 'help': 'Determine the default settings value. You can override them.', 'id': 'security-level', 'label': 'Security level', 'regex': '^(security_levels[0]|security_levels[1]|security_levels[2]|security_levels[3])$', 'type': 'select', 'select': [security_levels[0], security_levels[1], security_levels[2], security_levels[3]]} },
|
||||
{"plugin_id" : "general", "setting_id": "SERVER_NAME", "title" : "DEFINE HOST", "subtitle" : "We need this to connect BunkerWeb to your application. You need to set your domain name."},
|
||||
{"plugin_id" : "limit", "setting_id": "LIMIT_REQ_URL", "title" : "Define header", "subtitle" : "test header multiple rendering" },
|
||||
],
|
||||
"configs": []
|
||||
},
|
||||
{
|
||||
"name" : "STEP 2 - ANTIBOT",
|
||||
"description" : "Avoid spammer and bot to access your website.",
|
||||
"settings" : [
|
||||
{"plugin_id" : "antibot", "setting_id": "USE_ANTIBOT", "title" : "Define the type of your antibot", "subtitle" : "Javascript, Captcha or Cookie don't need additionnal settings to be fill. Recaptcha, Hcaptcha and Turnstile need secret key and site key delivered from providers." },
|
||||
],
|
||||
"configs": [
|
||||
{"id" : "CUSTOM_CONFIG_MODSEC", "type" : "modsec", "name" : "modsecrules", "subtitle" : "This will determine the modsecurity rules to apply to this service."},
|
||||
]
|
||||
},
|
||||
]
|
||||
%}
|
||||
|
||||
{# Get setting for each settings on steps #}
|
||||
{% for step in steps %}
|
||||
{% for setting in step.get('settings') %}
|
||||
{% for plugin in plugins %}
|
||||
{% if setting["plugin_id"] == plugin["id"]%}
|
||||
|
||||
{% if setting.update({"setting" : plugin["settings"][setting["setting_id"]]})%}{%endif%}
|
||||
|
||||
{# Case multiple, get all settings on same group #}
|
||||
{% set is_multiple = plugin["settings"][setting["setting_id"]].get("multiple", "") %}
|
||||
{% if is_multiple %}
|
||||
{% set multiples = {"multiples" : []}%}
|
||||
{% for mult_setting, value in plugin["settings"].items() %}
|
||||
{% if value.get("multiple", "") == is_multiple %}
|
||||
{% set mult_value = value %}
|
||||
{% if mult_value.update({"name" : mult_setting}) %}{%endif%}
|
||||
{% if multiples["multiples"].append(mult_value) %}{%endif%}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if setting.update(multiples)%}{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
<input type="hidden" id="security-level-{{security_levels[0]}}" data-settings="{{ standard }}" />
|
||||
<input type="hidden" id="security-level-{{security_levels[1]}}" data-settings="{{ advanced }}" />
|
||||
<input type="hidden" id="security-level-{{security_levels[2]}}" data-settings="{{ high }}" />
|
||||
|
||||
<!-- new and edit form -->
|
||||
<form data-simple data-services-modal-form
|
||||
class="!hidden w-full h-[90vh] overflow-auto flex flex-col justify-between"
|
||||
id="form-simple-new"
|
||||
method="POST">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden" value="new" name="operation" />
|
||||
<input type="hidden" value="" name="OLD_SERVER_NAME" />
|
||||
<input type="hidden" value="no" name="is_draft" />
|
||||
<input type="hidden" value="easy" name="mode" />
|
||||
|
||||
{% for step in steps %}
|
||||
<div data-step="{{loop.index}}" class="flex flex-col {% if loop.index != 1 %} hidden {% endif %}">
|
||||
<div class="flex flex-col w-full items-start mt-2">
|
||||
<h2 class="ml-2 mr-1 text-xl transition duration-300 ease-in-out font-bold text-md uppercase dark:text-white/90 mb-0" data-simple-step>{{ step.get("name")}}</h2>
|
||||
<p class="ml-2 mr-1 text-base dark:text-gray-300 mb-1" data-simple-description>{{ step.get("description")}}</p>
|
||||
</div>
|
||||
<div class="w-full min-w-[300px] my-1 sm:my-0">
|
||||
<hr class="separator" />
|
||||
</div>
|
||||
{% set plugin_simple = step.get('settings') %}
|
||||
{% set configs = step.get('configs') %}
|
||||
{% include "settings_simple.html" %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- action button -->
|
||||
<div class="w-full flex-col items-center justify-center flex mt-10">
|
||||
<div class="flex justify-center">
|
||||
<button data-services-modal-close
|
||||
type="button"
|
||||
class="close-btn mb-4 mr-3 text-base">Close</button>
|
||||
<button data-simple-back
|
||||
type="button"
|
||||
disabled
|
||||
class="info-btn mb-4 mr-3 text-base">Back</button>
|
||||
<button data-simple-next type="button" class="mb-4 valid-btn">Continue</button>
|
||||
<button data-services-modal-submit type="submit" class="hidden mb-4 valid-btn">Save</button>
|
||||
</div>
|
||||
<!-- end action button-->
|
||||
<p data-services-modal-error-msg
|
||||
class="hidden text-red-500 font-bold dark:opacity-80 mb-0 text-center"></p>
|
||||
</div>
|
||||
</form>
|
||||
6
src/ui/templates/setting_header.html
vendored
6
src/ui/templates/setting_header.html
vendored
|
|
@ -1,7 +1,7 @@
|
|||
{% if setting_input %}
|
||||
{% set inp_name = setting_input['name'] %}
|
||||
{% set inp_name_mult = inp_name + "_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
{% set inp_name_multisite = inp_name + "-multisite_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
{% set inp_name_multisite = inp_name + "-multisite_SCHEMA" if setting_input["is_multiple"] else inp_name + "-multisite" %}
|
||||
{% set inp_label = setting_input['label'] %}
|
||||
{% set inp_help = setting_input['help'] %}
|
||||
{% set inp_context = setting_input['context'] %}
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
class="info popover-settings-container hidden"
|
||||
data-popover-content="{{ inp_name_mult }}">
|
||||
<p class="popover-settings-text">{{ inp_help }}</p>
|
||||
</div>
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
class="multisite popover-settings-container hidden"
|
||||
data-popover-content="{{ inp_name_multisite }}">
|
||||
<p class="popover-settings-text">Multisite (apply as default to services without specific value).</p>
|
||||
</div>
|
||||
|
|
|
|||
105
src/ui/templates/settings_simple.html
vendored
105
src/ui/templates/settings_simple.html
vendored
|
|
@ -1,105 +0,0 @@
|
|||
{% set current_endpoint = current_endpoint or url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
|
||||
<!-- plugin item -->
|
||||
<div class="w-full grid grid-cols-12">
|
||||
{% for setting_simple in plugin_simple %}
|
||||
{% set setting_input = { "name" : setting_simple.get('setting_id'), "multiples" : setting_simple.get("multiples", {}), "method" : setting_simple.get('setting').get("method", "default"), "help" : setting_simple.get('setting').get("help"), "label" : setting_simple.get('setting').get("label"), "id" : setting_simple.get('setting').get("id"), "type" : setting_simple.get('setting').get("type"), "default" : setting_simple.get('setting').get("default", "default"), "select" : setting_simple.get('setting').get("select"), "regex" : setting_simple.get('setting').get("regex"), "value" : setting_simple.get('setting').get("value"), "is_multiple" : True if setting_simple.get('setting').get("multiple", "") else False, "multiple_name" : setting_simple.get('setting').get('multiple') } %}
|
||||
<div data-simple id="{{ setting_simple['plugin_id'] }}-simple"
|
||||
class="w-full h-full px-1 mb-2 col-span-12 {% if not setting_input['is_multiple'] %} mt-2 md:col-span-6 {%else%} mt-4 {% endif %} grid grid-cols-12 h-full items-end">
|
||||
<!-- title and desc -->
|
||||
<div class="col-span-12" data-setting-header>
|
||||
<div class="flex flex-col justify-start items-start">
|
||||
<h5 class="sm:pl-3 sm:pr-2 mt-2 transition duration-300 ease-in-out font-bold text-base uppercase dark:text-white/90 mb-0">
|
||||
{{ setting_simple['title'] }}
|
||||
</h5>
|
||||
<p class="max-w-[550px] sm:pl-3 sm:pr-2 text-sm dark:text-gray-300 mb-0">{{ setting_simple['subtitle'] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% if not setting_input.get('is_multiple') %}
|
||||
<!-- end title and desc -->
|
||||
<div class="w-full col-span-12">
|
||||
<div data-setting-container data-{{ current_endpoint }}-type="{{ setting_input['type'] }}" data-{{ current_endpoint }}-context="{{ setting_input['context'] }}" class="relative mx-0 sm:mx-2 md:mx-3 lg:mx-4 my-2 col-span-12 md:my-3 md:col-span-6 2xl:my-3 2xl:col-span-4" id="form-edit-{{ current_endpoint }}-{{ setting_input["id"] }}">
|
||||
{% include "setting_header.html" %}
|
||||
{% include "setting_input.html" %}
|
||||
{% include "setting_select.html" %}
|
||||
{% include "setting_checkbox.html" %}
|
||||
{% include "setting_invalid.html"%}
|
||||
</div>
|
||||
<!-- end plugin settings -->
|
||||
</div>
|
||||
<!-- end plugin settings not multiple -->
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if setting_input.get('is_multiple') %}
|
||||
<!-- plugin multiple handler -->
|
||||
<div data-multiple-handler="{{ setting_input['multiple_name'] }}"
|
||||
class="flex items-center mx-4 mb-2 mt-5 col-span-12 ">
|
||||
<h5 class="input-title max-w-[150px] sm:max-w-[350px]">{{ setting_simple['plugin_id'] }}</h5>
|
||||
<button data-{{ attribute_name }}-multiple-add="{{ setting_input['multiple_name'] }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
Add
|
||||
</button>
|
||||
<button data-{{ attribute_name }}-multiple-toggle="{{ setting_input['multiple_name'] }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
SHOW / HIDE
|
||||
</button>
|
||||
</div>
|
||||
<!-- end plugin multiple handler-->
|
||||
<!-- multiple settings -->
|
||||
<div data-{{ attribute_name }}-settings-multiple="{{ setting_input['multiple_name'] }}_SCHEMA" class=" col-span-12 bg-gray-50 dark:bg-slate-900/30 hidden w-full mt-4 grid-cols-12 border dark:border-gray-700 rounded">
|
||||
{% for setting in setting_input.get("multiples") %}
|
||||
{% set setting_input = { "name" : setting.get("name"), "context" : setting.get("context"), "method" : setting.get("method", "default"), "help" : setting.get("help"), "label" : setting.get("label"), "id" : setting.get("id"), "type" : setting.get("type"), "default" : setting.get("default", "default"), "select" : setting.get("select"), "regex" : setting.get("regex"), "value" : setting.get("value", setting.get('default')), "is_multiple" : True} %}
|
||||
<div data-setting-container="{{ setting_input['name'] }}_SCHEMA" data-{{ attribute_name }}-type="{{ setting_input['type'] }}" data-{{ attribute_name }}-context="{{ setting_input['context'] }}" class="relative mx-2 md:mx-3 my-2 md:my-3 col-span-12 md:col-span-6 2xl:col-span-4" id="form-edit-{{ attribute_name }}-{{ setting_input['id'] }}_SCHEMA">
|
||||
<!-- title and info -->
|
||||
{% include "setting_header.html" %}
|
||||
{% include "setting_input.html" %}
|
||||
{% include "setting_select.html" %}
|
||||
{% include "setting_checkbox.html" %}
|
||||
{% include "setting_invalid.html"%}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div data-multiple-delete-container
|
||||
class="col-span-12 flex justify-center my-4">
|
||||
<button data-{{ attribute_name }}-multiple-delete="{{ setting_simple['plugin_id'] }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-red-500 hover:bg-red-500/80 focus:bg-red-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
<!-- end plugin settings -->
|
||||
</div>
|
||||
<!-- end multiple settings -->
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- custom configs -->
|
||||
{% for config in configs %}
|
||||
<div data-simple data-config-container
|
||||
class="w-full h-full px-1 mt-4 mb-2 col-span-12 grid grid-cols-12 h-full items-end">
|
||||
<!-- title and desc -->
|
||||
<div class="col-span-12" data-setting-header>
|
||||
<div class="flex flex-col justify-start items-start">
|
||||
<h5 class="sm:pl-3 sm:pr-2 mt-2 transition duration-300 ease-in-out font-bold text-base uppercase dark:text-white/90 mb-0">
|
||||
{{ config['title'] }}
|
||||
</h5>
|
||||
<p class="max-w-[550px] sm:pl-3 sm:pr-2 text-sm dark:text-gray-300 mb-0">{{ config['subtitle'] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div data-editor-container="{{config['id']}}_SCHEMA" data-default-type="{{config['type']}}" data-default-name="{{config['name']}}" class="hidden w-full col-span-12 px-4">
|
||||
<div class="mb-2 flex flex-wrap justify-start items-center" >
|
||||
<input disabled type="text"
|
||||
name="CONFIG_NAME"
|
||||
data-editor-filename
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 sm:ml-1 max-w-40 focus:valid:border-green-500 focus:file:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500 disabled:bg-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 dark:disabled:text-gray-300 disabled:text-gray-700"
|
||||
placeholder="{{config['name']}}"
|
||||
required />
|
||||
<p class="ml-1 mb-0 dark:text-white/80 text-gray-700/80 text-sm">
|
||||
.conf
|
||||
</p>
|
||||
</div>
|
||||
<textarea data-editor-input class="hidden"></textarea>
|
||||
<!-- editor-->
|
||||
<div data-editor class="text-base w-full h-50 overflow-hidden overflow-y-auto my-2 border border-gray-300 dark:border-slate-800">
|
||||
</div>
|
||||
<!-- editor-->
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
|
@ -20,7 +20,7 @@ try:
|
|||
|
||||
assert_button_click(DRIVER, "//button[@data-services-action='new']")
|
||||
|
||||
assert_button_click(DRIVER, "//button[@data-toggle-settings-mode-btn='simple']")
|
||||
# assert_button_click(DRIVER, "//button[@data-toggle-settings-mode-btn='simple']")
|
||||
|
||||
server_name_input = safe_get_element(DRIVER, By.ID, "SERVER_NAME")
|
||||
assert isinstance(server_name_input, WebElement), "Input is not a WebElement"
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ try:
|
|||
|
||||
log_info("Toggle modal checked, trying settings ...")
|
||||
|
||||
assert_button_click(DRIVER, "//button[@data-toggle-settings-mode-btn='simple']")
|
||||
# simple mode
|
||||
# assert_button_click(DRIVER, "//button[@data-toggle-settings-mode-btn='simple']")
|
||||
|
||||
log_info("Start trying combobox filter ...")
|
||||
|
||||
|
|
@ -270,19 +271,19 @@ try:
|
|||
|
||||
assert_button_click(DRIVER, "//button[@data-services-action='new']")
|
||||
|
||||
current_mode = DRIVER.execute_script("return document.querySelector('button[data-toggle-settings-mode-btn]').getAttribute('data-toggle-settings-mode-btn')")
|
||||
if current_mode != "simple":
|
||||
log_error(f"""Default mode for new service need to be simple and not {current_mode}...""")
|
||||
exit(1)
|
||||
# current_mode = DRIVER.execute_script("return document.querySelector('button[data-toggle-settings-mode-btn]').getAttribute('data-toggle-settings-mode-btn')")
|
||||
# if current_mode != "simple":
|
||||
# log_error(f"""Default mode for new service need to be simple and not {current_mode}...""")
|
||||
# exit(1)
|
||||
|
||||
# Switch to advanced mode
|
||||
DRIVER.execute_script("document.querySelector('button[data-toggle-settings-mode-btn]').click()")
|
||||
# # Switch to advanced mode
|
||||
# DRIVER.execute_script("document.querySelector('button[data-toggle-settings-mode-btn]').click()")
|
||||
|
||||
current_mode = DRIVER.execute_script("return document.querySelector('button[data-toggle-settings-mode-btn]').getAttribute('data-toggle-settings-mode-btn')")
|
||||
# current_mode = DRIVER.execute_script("return document.querySelector('button[data-toggle-settings-mode-btn]').getAttribute('data-toggle-settings-mode-btn')")
|
||||
|
||||
if current_mode != "advanced":
|
||||
log_error(f"""Switching mode needed to return advanced mode, but he have {current_mode}...""")
|
||||
exit(1)
|
||||
# if current_mode != "advanced":
|
||||
# log_error(f"""Switching mode needed to return advanced mode, but he have {current_mode}...""")
|
||||
# exit(1)
|
||||
|
||||
server_name_input = safe_get_element(DRIVER, By.XPATH, "//form[@data-services-modal-form and @data-advanced]//input[@id='SERVER_NAME']")
|
||||
assert isinstance(server_name_input, WebElement), "Input is not a WebElement"
|
||||
|
|
|
|||
Loading…
Reference in a new issue