diff --git a/.github/.gitleaks.toml b/.github/.gitleaks.toml index 024b8ce51..32c27b355 100644 --- a/.github/.gitleaks.toml +++ b/.github/.gitleaks.toml @@ -536,11 +536,11 @@ secretGroup = 4 [allowlist] description = "global allow lists" -regexes = ['''219-09-9999''', '''078-05-1120''', '''(9[0-9]{2}|666)-\d{2}-\d{4}''', '''RPM-GPG-KEY.*'''] +regexes = ['''219-09-9999''', '''078-05-1120''', '''(9[0-9]{2}|666)-\d{2}-\d{4}''', '''RPM-GPG-KEY.*''', '''.*:.*StrelkaHexDump.*''', '''.*:.*PLACEHOLDER.*''', '''ssl_.*password''', '''integration_key\s=\s"so-logs-"'''] paths = [ '''gitleaks.toml''', '''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''', '''(go.mod|go.sum)$''', - '''salt/nginx/files/enterprise-attack.json''' + '''(.*?)whl$ ] diff --git a/.github/DISCUSSION_TEMPLATE/2-4.yml b/.github/DISCUSSION_TEMPLATE/2-4.yml new file mode 100644 index 000000000..dca40818a --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/2-4.yml @@ -0,0 +1,199 @@ +body: + - type: markdown + attributes: + value: | + ⚠️ This category is solely for conversations related to Security Onion 2.4 ⚠️ + + If your organization needs more immediate, enterprise grade professional support, with one-on-one virtual meetings and screensharing, contact us via our website: https://securityonion.com/support + - type: dropdown + attributes: + label: Version + description: Which version of Security Onion 2.4.x are you asking about? + options: + - + - 2.4.10 + - 2.4.20 + - 2.4.30 + - 2.4.40 + - 2.4.50 + - 2.4.60 + - 2.4.70 + - 2.4.80 + - 2.4.90 + - 2.4.100 + - 2.4.110 + - 2.4.111 + - 2.4.120 + - 2.4.130 + - 2.4.140 + - 2.4.141 + - 2.4.150 + - 2.4.160 + - 2.4.170 + - Other (please provide detail below) + validations: + required: true + - type: dropdown + attributes: + label: Installation Method + description: How did you install Security Onion? + options: + - + - Security Onion ISO image + - Cloud image (Amazon, Azure, Google) + - Network installation on Red Hat derivative like Oracle, Rocky, Alma, etc. (unsupported) + - Network installation on Ubuntu (unsupported) + - Network installation on Debian (unsupported) + - Other (please provide detail below) + validations: + required: true + - type: dropdown + attributes: + label: Description + description: > + Is this discussion about installation, configuration, upgrading, or other? + options: + - + - installation + - configuration + - upgrading + - other (please provide detail below) + validations: + required: true + - type: dropdown + attributes: + label: Installation Type + description: > + When you installed, did you choose Import, Eval, Standalone, Distributed, or something else? + options: + - + - Import + - Eval + - Standalone + - Distributed + - other (please provide detail below) + validations: + required: true + - type: dropdown + attributes: + label: Location + description: > + Is this deployment in the cloud, on-prem with Internet access, or airgap? + options: + - + - cloud + - on-prem with Internet access + - airgap + - other (please provide detail below) + validations: + required: true + - type: dropdown + attributes: + label: Hardware Specs + description: > + Does your hardware meet or exceed the minimum requirements for your installation type as shown at https://docs.securityonion.net/en/2.4/hardware.html? + options: + - + - Meets minimum requirements + - Exceeds minimum requirements + - Does not meet minimum requirements + - other (please provide detail below) + validations: + required: true + - type: input + attributes: + label: CPU + description: How many CPU cores do you have? + validations: + required: true + - type: input + attributes: + label: RAM + description: How much RAM do you have? + validations: + required: true + - type: input + attributes: + label: Storage for / + description: How much storage do you have for the / partition? + validations: + required: true + - type: input + attributes: + label: Storage for /nsm + description: How much storage do you have for the /nsm partition? + validations: + required: true + - type: dropdown + attributes: + label: Network Traffic Collection + description: > + Are you collecting network traffic from a tap or span port? + options: + - + - tap + - span port + - other (please provide detail below) + validations: + required: true + - type: dropdown + attributes: + label: Network Traffic Speeds + description: > + How much network traffic are you monitoring? + options: + - + - Less than 1Gbps + - 1Gbps to 10Gbps + - more than 10Gbps + validations: + required: true + - type: dropdown + attributes: + label: Status + description: > + Does SOC Grid show all services on all nodes as running OK? + options: + - + - Yes, all services on all nodes are running OK + - No, one or more services are failed (please provide detail below) + validations: + required: true + - type: dropdown + attributes: + label: Salt Status + description: > + Do you get any failures when you run "sudo salt-call state.highstate"? + options: + - + - Yes, there are salt failures (please provide detail below) + - No, there are no failures + validations: + required: true + - type: dropdown + attributes: + label: Logs + description: > + Are there any additional clues in /opt/so/log/? + options: + - + - Yes, there are additional clues in /opt/so/log/ (please provide detail below) + - No, there are no additional clues + validations: + required: true + - type: textarea + attributes: + label: Detail + description: Please read our discussion guidelines at https://github.com/Security-Onion-Solutions/securityonion/discussions/1720 and then provide detailed information to help us help you. + placeholder: |- + STOP! Before typing, please read our discussion guidelines at https://github.com/Security-Onion-Solutions/securityonion/discussions/1720 in their entirety! + + If your organization needs more immediate, enterprise grade professional support, with one-on-one virtual meetings and screensharing, contact us via our website: https://securityonion.com/support + validations: + required: true + - type: checkboxes + attributes: + label: Guidelines + options: + - label: I have read the discussion guidelines at https://github.com/Security-Onion-Solutions/securityonion/discussions/1720 and assert that I have followed the guidelines. + required: true diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE deleted file mode 100644 index e02405f16..000000000 --- a/.github/ISSUE_TEMPLATE +++ /dev/null @@ -1,12 +0,0 @@ -PLEASE STOP AND READ THIS INFORMATION! - -If you are creating an issue just to ask a question, you will likely get faster and better responses by posting to our discussions forum instead: -https://securityonion.net/discuss - -If you think you have found a possible bug or are observing a behavior that you weren't expecting, use the discussion forum to start a conversation about it instead of creating an issue. - -If you are very familiar with the latest version of the product and are confident you have found a bug in Security Onion, you can continue with creating an issue here, but please make sure you have done the following: -- duplicated the issue on a fresh installation of the latest version -- provide information about your system and how you installed Security Onion -- include relevant log files -- include reproduction steps diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..43b490b49 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: This option is for experienced community members to report a confirmed, reproducible bug +title: '' +labels: '' +assignees: '' + +--- +PLEASE STOP AND READ THIS INFORMATION! + +If you are creating an issue just to ask a question, you will likely get faster and better responses by posting to our discussions forum at https://securityonion.net/discuss. + +If you think you have found a possible bug or are observing a behavior that you weren't expecting, use the discussion forum at https://securityonion.net/discuss to start a conversation about it instead of creating an issue. + +If you are very familiar with the latest version of the product and are confident you have found a bug in Security Onion, you can continue with creating an issue here, but please make sure you have done the following: +- duplicated the issue on a fresh installation of the latest version +- provide information about your system and how you installed Security Onion +- include relevant log files +- include reproduction steps + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..5758e82cf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Security Onion Discussions + url: https://securityonion.com/discussions + about: Please ask and answer questions here diff --git a/.github/workflows/close-threads.yml b/.github/workflows/close-threads.yml new file mode 100644 index 000000000..41b267f2b --- /dev/null +++ b/.github/workflows/close-threads.yml @@ -0,0 +1,33 @@ +name: 'Close Threads' + +on: + schedule: + - cron: '50 1 * * *' + workflow_dispatch: + +permissions: + issues: write + pull-requests: write + discussions: write + +concurrency: + group: lock-threads + +jobs: + close-threads: + if: github.repository_owner == 'security-onion-solutions' + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v5 + with: + days-before-issue-stale: -1 + days-before-issue-close: 60 + stale-issue-message: "This issue is stale because it has been inactive for an extended period. Stale issues convey that the issue, while important to someone, is not critical enough for the author, or other community members to work on, sponsor, or otherwise shepherd the issue through to a resolution." + close-issue-message: "This issue was closed because it has been stale for an extended period. It will be automatically locked in 30 days, after which no further commenting will be available." + days-before-pr-stale: 45 + days-before-pr-close: 60 + stale-pr-message: "This PR is stale because it has been inactive for an extended period. The longer a PR remains stale the more out of date with the main branch it becomes." + close-pr-message: "This PR was closed because it has been stale for an extended period. It will be automatically locked in 30 days. If there is still a commitment to finishing this PR re-open it before it is locked." diff --git a/.github/workflows/contrib.yml b/.github/workflows/contrib.yml index 1cb3b773b..2cbdb2788 100644 --- a/.github/workflows/contrib.yml +++ b/.github/workflows/contrib.yml @@ -11,14 +11,14 @@ jobs: steps: - name: "Contributor Check" if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' - uses: cla-assistant/github-action@v2.1.3-beta + uses: cla-assistant/github-action@v2.3.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PERSONAL_ACCESS_TOKEN : ${{ secrets.PERSONAL_ACCESS_TOKEN }} with: path-to-signatures: 'signatures_v1.json' path-to-document: 'https://securityonionsolutions.com/cla' - allowlist: dependabot[bot],jertel,dougburks,TOoSmOotH,weslambert,defensivedepth,m0duspwnens + allowlist: dependabot[bot],jertel,dougburks,TOoSmOotH,defensivedepth,m0duspwnens remote-organization-name: Security-Onion-Solutions remote-repository-name: licensing diff --git a/.github/workflows/lock-threads.yml b/.github/workflows/lock-threads.yml new file mode 100644 index 000000000..f5d46ed46 --- /dev/null +++ b/.github/workflows/lock-threads.yml @@ -0,0 +1,26 @@ +name: 'Lock Threads' + +on: + schedule: + - cron: '50 2 * * *' + workflow_dispatch: + +permissions: + issues: write + pull-requests: write + discussions: write + +concurrency: + group: lock-threads + +jobs: + lock-threads: + if: github.repository_owner == 'security-onion-solutions' + runs-on: ubuntu-latest + steps: + - uses: jertel/lock-threads@main + with: + include-discussion-currently-open: true + discussion-inactive-days: 90 + issue-inactive-days: 30 + pr-inactive-days: 30 diff --git a/.github/workflows/pythontest.yml b/.github/workflows/pythontest.yml index 018b02890..49f2b32b9 100644 --- a/.github/workflows/pythontest.yml +++ b/.github/workflows/pythontest.yml @@ -1,10 +1,6 @@ name: python-test on: - push: - paths: - - "salt/sensoroni/files/analyzers/**" - - "salt/manager/tools/sbin" pull_request: paths: - "salt/sensoroni/files/analyzers/**" @@ -17,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.10"] + python-version: ["3.13"] python-code-path: ["salt/sensoroni/files/analyzers", "salt/manager/tools/sbin"] steps: @@ -36,4 +32,4 @@ jobs: flake8 ${{ matrix.python-code-path }} --show-source --max-complexity=12 --doctests --max-line-length=200 --statistics - name: Test with pytest run: | - pytest ${{ matrix.python-code-path }} --cov=${{ matrix.python-code-path }} --doctest-modules --cov-report=term --cov-fail-under=100 --cov-config=pytest.ini + PYTHONPATH=${{ matrix.python-code-path }} pytest ${{ matrix.python-code-path }} --cov=${{ matrix.python-code-path }} --doctest-modules --cov-report=term --cov-fail-under=100 --cov-config=pytest.ini diff --git a/.gitignore b/.gitignore index 7f446a041..fc9d41531 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ - # Created by https://www.gitignore.io/api/macos,windows # Edit at https://www.gitignore.io/?templates=macos,windows @@ -67,4 +66,12 @@ __pycache__ # Analyzer dev/test config files *_dev.yaml -site-packages \ No newline at end of file +site-packages + +# Project Scope Directory +.projectScope/ +.clinerules +cline_docs/ + +# vscode settings +.vscode/ diff --git a/DOWNLOAD_AND_VERIFY_ISO.md b/DOWNLOAD_AND_VERIFY_ISO.md index a6b5469f0..2e0b2aa5d 100644 --- a/DOWNLOAD_AND_VERIFY_ISO.md +++ b/DOWNLOAD_AND_VERIFY_ISO.md @@ -1,18 +1,17 @@ -### 2.4.30-20231113 ISO image released on 2023/11/13 - +### 2.4.160-20250625 ISO image released on 2025/06/25 ### Download and Verify -2.4.30-20231113 ISO image: -https://download.securityonion.net/file/securityonion/securityonion-2.4.30-20231113.iso +2.4.160-20250625 ISO image: +https://download.securityonion.net/file/securityonion/securityonion-2.4.160-20250625.iso -MD5: 15EB5A74782E4C2D5663D29E275839F6 -SHA1: BBD4A7D77ADDA94B866F1EFED846A83DDFD34D73 -SHA256: 4509EB8E11DB49C6CD3905C74C5525BDB1F773488002179A846E00DE8E499988 +MD5: 78CF5602EFFAB84174C56AD2826E6E4E +SHA1: FC7EEC3EC95D97D3337501BAA7CA8CAE7C0E15EA +SHA256: 0ED965E8BEC80EE16AE90A0F0F96A3046CEF2D92720A587278DDDE3B656C01C2 Signature for ISO image: -https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.30-20231113.iso.sig +https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.160-20250625.iso.sig Signing key: https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.4/main/KEYS @@ -26,27 +25,29 @@ wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2. Download the signature file for the ISO: ``` -wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.30-20231113.iso.sig +wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.160-20250625.iso.sig ``` Download the ISO image: ``` -wget https://download.securityonion.net/file/securityonion/securityonion-2.4.30-20231113.iso +wget https://download.securityonion.net/file/securityonion/securityonion-2.4.160-20250625.iso ``` Verify the downloaded ISO image using the signature file: ``` -gpg --verify securityonion-2.4.30-20231113.iso.sig securityonion-2.4.30-20231113.iso +gpg --verify securityonion-2.4.160-20250625.iso.sig securityonion-2.4.160-20250625.iso ``` The output should show "Good signature" and the Primary key fingerprint should match what's shown below: ``` -gpg: Signature made Mon 13 Nov 2023 09:23:21 AM EST using RSA key ID FE507013 +gpg: Signature made Wed 25 Jun 2025 10:13:33 AM EDT using RSA key ID FE507013 gpg: Good signature from "Security Onion Solutions, LLC " gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: C804 A93D 36BE 0C73 3EA1 9644 7C10 60B7 FE50 7013 ``` +If it fails to verify, try downloading again. If it still fails to verify, try downloading from another computer or another network. + Once you've verified the ISO image, you're ready to proceed to our Installation guide: https://docs.securityonion.net/en/2.4/installation.html diff --git a/HOTFIX b/HOTFIX index d3f5a12fa..e69de29bb 100644 --- a/HOTFIX +++ b/HOTFIX @@ -1 +0,0 @@ - diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..77329e94a --- /dev/null +++ b/LICENSE @@ -0,0 +1,53 @@ +Elastic License 2.0 (ELv2) + +Acceptance + + By using the software, you agree to all of the terms and conditions below. + +Copyright License + + The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations and conditions below. + +Limitations + + You may not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the software. + + You may not move, change, disable, or circumvent the license key functionality in the software, and you may not remove or obscure any functionality in the software that is protected by the license key. + + You may not alter, remove, or obscure any licensing, copyright, or other notices of the licensor in the software. Any use of the licensor’s trademarks is subject to applicable law. + +Patents + + The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for sale, import and have imported the software, in each case subject to the limitations and conditions in this license. This license does not cover any patent claims that you cause to be infringed by modifications or additions to the software. If you or your company make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company. + +Notices + + You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms. + + If you modify the software, you must include in any modified copies of the software prominent notices stating that you have modified the software. + +No Other Rights + + These terms do not imply any licenses other than those expressly granted in these terms. + +Termination + + If you use the software in violation of these terms, such use is not licensed, and your licenses will automatically terminate. If the licensor provides you with a notice of your violation, and you cease all violation of this license no later than 30 days after you receive that notice, your licenses will be reinstated retroactively. However, if you violate these terms after such reinstatement, any additional violation of these terms will cause your licenses to terminate automatically and permanently. + +No Liability + + As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim. + +Definitions + + The licensor is the entity offering these terms, and the software is the software the licensor makes available under these terms, including any portion of it. + + you refers to the individual or entity agreeing to these terms. + + your company is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. control means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. + + your licenses are all the licenses granted to you for the software under these terms. + + use means anything you do with the software requiring one of your licenses. + + trademark means trademarks, service marks, and similar rights. diff --git a/README.md b/README.md index 19a560419..530a21813 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,22 @@ Alerts ![Alerts](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/50_alerts.png) Dashboards -![Dashboards](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/51_dashboards.png) +![Dashboards](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/53_dashboards.png) Hunt -![Hunt](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/52_hunt.png) +![Hunt](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/56_hunt.png) + +Detections +![Detections](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/57_detections.png) PCAP -![PCAP](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/53_pcap.png) +![PCAP](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/62_pcap.png) Grid -![Grid](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/57_grid.png) +![Grid](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/75_grid.png) Config -![Config](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/61_config.png) +![Config](https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion-docs/2.4/images/87_config.png) ### Release Notes diff --git a/SECURITY.md b/SECURITY.md index 771d087a1..5001e4cd0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -5,9 +5,11 @@ | Version | Supported | | ------- | ------------------ | | 2.4.x | :white_check_mark: | -| 2.3.x | :white_check_mark: | +| 2.3.x | :x: | | 16.04.x | :x: | +Security Onion 2.3 has reached End Of Life and is no longer supported. + Security Onion 16.04 has reached End Of Life and is no longer supported. ## Reporting a Vulnerability diff --git a/VERSION b/VERSION index 29630cd6d..032d0bb01 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.4.40 +2.4.170 diff --git a/assets/images/screenshots/analyzers/echotrail.png b/assets/images/screenshots/analyzers/echotrail.png new file mode 100644 index 000000000..21c0909d1 Binary files /dev/null and b/assets/images/screenshots/analyzers/echotrail.png differ diff --git a/assets/images/screenshots/analyzers/elasticsearch.png b/assets/images/screenshots/analyzers/elasticsearch.png new file mode 100644 index 000000000..ba867e7f4 Binary files /dev/null and b/assets/images/screenshots/analyzers/elasticsearch.png differ diff --git a/assets/images/screenshots/analyzers/sublime.png b/assets/images/screenshots/analyzers/sublime.png new file mode 100644 index 000000000..6ea83d760 Binary files /dev/null and b/assets/images/screenshots/analyzers/sublime.png differ diff --git a/files/firewall/assigned_hostgroups.local.map.yaml b/files/firewall/assigned_hostgroups.local.map.yaml index be34cb0be..025b32131 100644 --- a/files/firewall/assigned_hostgroups.local.map.yaml +++ b/files/firewall/assigned_hostgroups.local.map.yaml @@ -19,4 +19,4 @@ role: receiver: standalone: searchnode: - sensor: + sensor: \ No newline at end of file diff --git a/files/salt/master/master b/files/salt/master/master index b93fa93de..2333a50aa 100644 --- a/files/salt/master/master +++ b/files/salt/master/master @@ -41,7 +41,8 @@ file_roots: base: - /opt/so/saltstack/local/salt - /opt/so/saltstack/default/salt - + - /nsm/elastic-fleet/artifacts + - /opt/so/rules/nids # The master_roots setting configures a master-only copy of the file_roots dictionary, # used by the state compiler. diff --git a/pillar/elasticsearch/nodes.sls b/pillar/elasticsearch/nodes.sls new file mode 100644 index 000000000..588b51217 --- /dev/null +++ b/pillar/elasticsearch/nodes.sls @@ -0,0 +1,34 @@ +{% set node_types = {} %} +{% for minionid, ip in salt.saltutil.runner( + 'mine.get', + tgt='elasticsearch:enabled:true', + fun='network.ip_addrs', + tgt_type='pillar') | dictsort() +%} + +# only add a node to the pillar if it returned an ip from the mine +{% if ip | length > 0%} +{% set hostname = minionid.split('_') | first %} +{% set node_type = minionid.split('_') | last %} +{% if node_type not in node_types.keys() %} +{% do node_types.update({node_type: {hostname: ip[0]}}) %} +{% else %} +{% if hostname not in node_types[node_type] %} +{% do node_types[node_type].update({hostname: ip[0]}) %} +{% else %} +{% do node_types[node_type][hostname].update(ip[0]) %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} + + +elasticsearch: + nodes: +{% for node_type, values in node_types.items() %} + {{node_type}}: +{% for hostname, ip in values.items() %} + {{hostname}}: + ip: {{ip}} +{% endfor %} +{% endfor %} diff --git a/pillar/hypervisor/nodes.sls b/pillar/hypervisor/nodes.sls new file mode 100644 index 000000000..a25239d8d --- /dev/null +++ b/pillar/hypervisor/nodes.sls @@ -0,0 +1,34 @@ +{% set node_types = {} %} +{% for minionid, ip in salt.saltutil.runner( + 'mine.get', + tgt='G@role:so-hypervisor or G@role:so-managerhype', + fun='network.ip_addrs', + tgt_type='compound') | dictsort() +%} + +# only add a node to the pillar if it returned an ip from the mine +{% if ip | length > 0%} +{% set hostname = minionid.split('_') | first %} +{% set node_type = minionid.split('_') | last %} +{% if node_type not in node_types.keys() %} +{% do node_types.update({node_type: {hostname: ip[0]}}) %} +{% else %} +{% if hostname not in node_types[node_type] %} +{% do node_types[node_type].update({hostname: ip[0]}) %} +{% else %} +{% do node_types[node_type][hostname].update(ip[0]) %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} + + +hypervisor: + nodes: +{% for node_type, values in node_types.items() %} + {{node_type}}: +{% for hostname, ip in values.items() %} + {{hostname}}: + ip: {{ip}} +{% endfor %} +{% endfor %} diff --git a/pillar/kafka/nodes.sls b/pillar/kafka/nodes.sls new file mode 100644 index 000000000..ba14c219e --- /dev/null +++ b/pillar/kafka/nodes.sls @@ -0,0 +1,2 @@ +kafka: + nodes: \ No newline at end of file diff --git a/pillar/logstash/nodes.sls b/pillar/logstash/nodes.sls index a77978821..4cea7737a 100644 --- a/pillar/logstash/nodes.sls +++ b/pillar/logstash/nodes.sls @@ -1,16 +1,15 @@ {% set node_types = {} %} -{% set cached_grains = salt.saltutil.runner('cache.grains', tgt='*') %} {% for minionid, ip in salt.saltutil.runner( 'mine.get', - tgt='G@role:so-manager or G@role:so-managersearch or G@role:so-standalone or G@role:so-searchnode or G@role:so-heavynode or G@role:so-receiver or G@role:so-fleet ', + tgt='logstash:enabled:true', fun='network.ip_addrs', - tgt_type='compound') | dictsort() + tgt_type='pillar') | dictsort() %} # only add a node to the pillar if it returned an ip from the mine {% if ip | length > 0%} -{% set hostname = cached_grains[minionid]['host'] %} -{% set node_type = minionid.split('_')[1] %} +{% set hostname = minionid.split('_') | first %} +{% set node_type = minionid.split('_') | last %} {% if node_type not in node_types.keys() %} {% do node_types.update({node_type: {hostname: ip[0]}}) %} {% else %} diff --git a/pillar/node_data/ips.sls b/pillar/node_data/ips.sls index 5801d36f1..a2528a476 100644 --- a/pillar/node_data/ips.sls +++ b/pillar/node_data/ips.sls @@ -24,6 +24,7 @@ {% endif %} {% endfor %} +{% if node_types %} node_data: {% for node_type, host_values in node_types.items() %} {% for hostname, details in host_values.items() %} @@ -33,3 +34,6 @@ node_data: role: {{node_type}} {% endfor %} {% endfor %} +{% else %} +node_data: False +{% endif %} diff --git a/pillar/redis/nodes.sls b/pillar/redis/nodes.sls new file mode 100644 index 000000000..618b31715 --- /dev/null +++ b/pillar/redis/nodes.sls @@ -0,0 +1,34 @@ +{% set node_types = {} %} +{% for minionid, ip in salt.saltutil.runner( + 'mine.get', + tgt='redis:enabled:true', + fun='network.ip_addrs', + tgt_type='pillar') | dictsort() +%} + +# only add a node to the pillar if it returned an ip from the mine +{% if ip | length > 0%} +{% set hostname = minionid.split('_') | first %} +{% set node_type = minionid.split('_') | last %} +{% if node_type not in node_types.keys() %} +{% do node_types.update({node_type: {hostname: ip[0]}}) %} +{% else %} +{% if hostname not in node_types[node_type] %} +{% do node_types[node_type].update({hostname: ip[0]}) %} +{% else %} +{% do node_types[node_type][hostname].update(ip[0]) %} +{% endif %} +{% endif %} +{% endif %} +{% endfor %} + + +redis: + nodes: +{% for node_type, values in node_types.items() %} + {{node_type}}: +{% for hostname, ip in values.items() %} + {{hostname}}: + ip: {{ip}} +{% endfor %} +{% endfor %} diff --git a/pillar/top.sls b/pillar/top.sls index 53ec8a330..1fdb59deb 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -16,16 +16,24 @@ base: - sensoroni.adv_sensoroni - telegraf.soc_telegraf - telegraf.adv_telegraf + - versionlock.soc_versionlock + - versionlock.adv_versionlock + - soc.license '* and not *_desktop': - firewall.soc_firewall - firewall.adv_firewall - nginx.soc_nginx - nginx.adv_nginx - - node_data.ips - '*_manager or *_managersearch': + 'salt-cloud:driver:libvirt': + - match: grain + - vm.soc_vm + - vm.adv_vm + + '*_manager or *_managersearch or *_managerhype': - match: compound + - node_data.ips {% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %} - elasticsearch.auth {% endif %} @@ -42,17 +50,18 @@ base: - logstash.adv_logstash - soc.soc_soc - soc.adv_soc - - soc.license - - soctopus.soc_soctopus - - soctopus.adv_soctopus - kibana.soc_kibana - kibana.adv_kibana - kratos.soc_kratos - kratos.adv_kratos + - hydra.soc_hydra + - hydra.adv_hydra + - redis.nodes - redis.soc_redis - redis.adv_redis - influxdb.soc_influxdb - influxdb.adv_influxdb + - elasticsearch.nodes - elasticsearch.soc_elasticsearch - elasticsearch.adv_elasticsearch - elasticfleet.soc_elasticfleet @@ -61,12 +70,15 @@ base: - elastalert.adv_elastalert - backup.soc_backup - backup.adv_backup - - curator.soc_curator - - curator.adv_curator - - soctopus.soc_soctopus - - soctopus.adv_soctopus - minions.{{ grains.id }} - minions.adv_{{ grains.id }} + - kafka.nodes + - kafka.soc_kafka + - kafka.adv_kafka + - hypervisor.nodes + - hypervisor.soc_hypervisor + - hypervisor.adv_hypervisor + - stig.soc_stig '*_sensor': - healthcheck.sensor @@ -82,8 +94,10 @@ base: - suricata.adv_suricata - minions.{{ grains.id }} - minions.adv_{{ grains.id }} + - stig.soc_stig '*_eval': + - node_data.ips - secrets - healthcheck.eval - elasticsearch.index_templates @@ -94,6 +108,7 @@ base: - kibana.secrets {% endif %} - kratos.soc_kratos + - kratos.adv_kratos - elasticsearch.soc_elasticsearch - elasticsearch.adv_elasticsearch - elasticfleet.soc_elasticfleet @@ -106,17 +121,12 @@ base: - idstools.adv_idstools - soc.soc_soc - soc.adv_soc - - soc.license - - soctopus.soc_soctopus - - soctopus.adv_soctopus - kibana.soc_kibana - kibana.adv_kibana - strelka.soc_strelka - strelka.adv_strelka - - curator.soc_curator - - curator.adv_curator - - kratos.soc_kratos - - kratos.adv_kratos + - hydra.soc_hydra + - hydra.adv_hydra - redis.soc_redis - redis.adv_redis - influxdb.soc_influxdb @@ -135,6 +145,7 @@ base: - minions.adv_{{ grains.id }} '*_standalone': + - node_data.ips - logstash.nodes - logstash.soc_logstash - logstash.adv_logstash @@ -151,10 +162,14 @@ base: - idstools.adv_idstools - kratos.soc_kratos - kratos.adv_kratos + - hydra.soc_hydra + - hydra.adv_hydra + - redis.nodes - redis.soc_redis - redis.adv_redis - influxdb.soc_influxdb - influxdb.adv_influxdb + - elasticsearch.nodes - elasticsearch.soc_elasticsearch - elasticsearch.adv_elasticsearch - elasticfleet.soc_elasticfleet @@ -165,15 +180,10 @@ base: - manager.adv_manager - soc.soc_soc - soc.adv_soc - - soc.license - - soctopus.soc_soctopus - - soctopus.adv_soctopus - kibana.soc_kibana - kibana.adv_kibana - strelka.soc_strelka - strelka.adv_strelka - - curator.soc_curator - - curator.adv_curator - backup.soc_backup - backup.adv_backup - zeek.soc_zeek @@ -186,6 +196,10 @@ base: - suricata.adv_suricata - minions.{{ grains.id }} - minions.adv_{{ grains.id }} + - stig.soc_stig + - kafka.nodes + - kafka.soc_kafka + - kafka.adv_kafka '*_heavynode': - elasticsearch.auth @@ -194,8 +208,6 @@ base: - logstash.adv_logstash - elasticsearch.soc_elasticsearch - elasticsearch.adv_elasticsearch - - curator.soc_curator - - curator.adv_curator - redis.soc_redis - redis.adv_redis - zeek.soc_zeek @@ -221,15 +233,21 @@ base: - logstash.nodes - logstash.soc_logstash - logstash.adv_logstash + - elasticsearch.nodes - elasticsearch.soc_elasticsearch - elasticsearch.adv_elasticsearch {% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %} - elasticsearch.auth {% endif %} + - redis.nodes - redis.soc_redis - redis.adv_redis - minions.{{ grains.id }} - minions.adv_{{ grains.id }} + - stig.soc_stig + - kafka.nodes + - kafka.soc_kafka + - kafka.adv_kafka '*_receiver': - logstash.nodes @@ -242,8 +260,11 @@ base: - redis.adv_redis - minions.{{ grains.id }} - minions.adv_{{ grains.id }} + - kafka.nodes + - kafka.soc_kafka '*_import': + - node_data.ips - secrets - elasticsearch.index_templates {% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %} @@ -253,6 +274,7 @@ base: - kibana.secrets {% endif %} - kratos.soc_kratos + - kratos.adv_kratos - elasticsearch.soc_elasticsearch - elasticsearch.adv_elasticsearch - elasticfleet.soc_elasticfleet @@ -263,17 +285,12 @@ base: - manager.adv_manager - soc.soc_soc - soc.adv_soc - - soc.license - - soctopus.soc_soctopus - - soctopus.adv_soctopus - kibana.soc_kibana - kibana.adv_kibana - - curator.soc_curator - - curator.adv_curator - backup.soc_backup - backup.adv_backup - - kratos.soc_kratos - - kratos.adv_kratos + - hydra.soc_hydra + - hydra.adv_hydra - redis.soc_redis - redis.adv_redis - influxdb.soc_influxdb @@ -292,6 +309,7 @@ base: - minions.adv_{{ grains.id }} '*_fleet': + - node_data.ips - backup.soc_backup - backup.adv_backup - logstash.nodes @@ -302,6 +320,12 @@ base: - minions.{{ grains.id }} - minions.adv_{{ grains.id }} + '*_hypervisor': + - minions.{{ grains.id }} + - minions.adv_{{ grains.id }} + '*_desktop': - minions.{{ grains.id }} - minions.adv_{{ grains.id }} + - stig.soc_stig + diff --git a/pyci.sh b/pyci.sh index e85287063..8cbee5e75 100755 --- a/pyci.sh +++ b/pyci.sh @@ -15,12 +15,16 @@ TARGET_DIR=${1:-.} PATH=$PATH:/usr/local/bin -if ! which pytest &> /dev/null || ! which flake8 &> /dev/null ; then - echo "Missing dependencies. Consider running the following command:" - echo " python -m pip install flake8 pytest pytest-cov" +if [ ! -d .venv ]; then + python -m venv .venv +fi + +source .venv/bin/activate + +if ! pip install flake8 pytest pytest-cov pyyaml; then + echo "Unable to install dependencies." exit 1 fi -pip install pytest pytest-cov flake8 "$TARGET_DIR" "--config=${HOME_DIR}/pytest.ini" -python3 -m pytest "--cov-config=${HOME_DIR}/pytest.ini" "--cov=$TARGET_DIR" --doctest-modules --cov-report=term --cov-fail-under=100 "$TARGET_DIR" \ No newline at end of file +python3 -m pytest "--cov-config=${HOME_DIR}/pytest.ini" "--cov=$TARGET_DIR" --doctest-modules --cov-report=term --cov-fail-under=100 "$TARGET_DIR" diff --git a/salt/_modules/qcow2.py b/salt/_modules/qcow2.py new file mode 100644 index 000000000..6e71dc459 --- /dev/null +++ b/salt/_modules/qcow2.py @@ -0,0 +1,246 @@ +#!py + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +""" +Salt module for managing QCOW2 image configurations and VM hardware settings. This module provides functions +for modifying network configurations within QCOW2 images and adjusting virtual machine hardware settings. +It serves as a Salt interface to the so-qcow2-modify-network and so-kvm-modify-hardware scripts. + +The module offers two main capabilities: +1. Network Configuration: Modify network settings (DHCP/static IP) within QCOW2 images +2. Hardware Configuration: Adjust VM hardware settings (CPU, memory, PCI passthrough) + +This module is intended to work with Security Onion's virtualization infrastructure and is typically +used in conjunction with salt-cloud for VM provisioning and management. +""" + +import logging +import subprocess +import shlex + +log = logging.getLogger(__name__) + +__virtualname__ = 'qcow2' + +def __virtual__(): + return __virtualname__ + +def modify_network_config(image, interface, mode, vm_name, ip4=None, gw4=None, dns4=None, search4=None): + ''' + Usage: + salt '*' qcow2.modify_network_config image= interface= mode= vm_name= [ip4=] [gw4=] [dns4=] [search4=] + + Options: + image + Path to the QCOW2 image file that will be modified + interface + Network interface name to configure (e.g., 'enp1s0') + mode + Network configuration mode, either 'dhcp4' or 'static4' + vm_name + Full name of the VM (hostname_role) + ip4 + IPv4 address with CIDR notation (e.g., '192.168.1.10/24') + Required when mode='static4' + gw4 + IPv4 gateway address (e.g., '192.168.1.1') + Required when mode='static4' + dns4 + Comma-separated list of IPv4 DNS servers (e.g., '8.8.8.8,8.8.4.4') + Optional for both DHCP and static configurations + search4 + DNS search domain for IPv4 (e.g., 'example.local') + Optional for both DHCP and static configurations + + Examples: + 1. **Configure DHCP:** + ```bash + salt '*' qcow2.modify_network_config image='/nsm/libvirt/images/sool9/sool9.qcow2' interface='enp1s0' mode='dhcp4' + ``` + This configures enp1s0 to use DHCP for IP assignment + + 2. **Configure Static IP:** + ```bash + salt '*' qcow2.modify_network_config image='/nsm/libvirt/images/sool9/sool9.qcow2' interface='enp1s0' mode='static4' ip4='192.168.1.10/24' gw4='192.168.1.1' dns4='192.168.1.1,8.8.8.8' search4='example.local' + ``` + This sets a static IP configuration with DNS servers and search domain + + Notes: + - The QCOW2 image must be accessible and writable by the salt minion + - The image should not be in use by a running VM when modified + - Network changes take effect on next VM boot + - Requires so-qcow2-modify-network script to be installed + + Description: + This function modifies network configuration within a QCOW2 image file by executing + the so-qcow2-modify-network script. It supports both DHCP and static IPv4 configuration. + The script mounts the image, modifies the network configuration files, and unmounts + safely. All operations are logged for troubleshooting purposes. + + Exit Codes: + 0: Success + 1: Invalid parameters or configuration + 2: Image access or mounting error + 3: Network configuration error + 4: System command error + 255: Unexpected error + + Logging: + - All operations are logged to the salt minion log + - Log entries are prefixed with 'qcow2 module:' + - Error conditions include detailed error messages and stack traces + - Success/failure status is logged for verification + ''' + + cmd = ['/usr/sbin/so-qcow2-modify-network', '-I', image, '-i', interface, '-n', vm_name] + + if mode.lower() == 'dhcp4': + cmd.append('--dhcp4') + elif mode.lower() == 'static4': + cmd.append('--static4') + if not ip4 or not gw4: + raise ValueError('Both ip4 and gw4 are required for static configuration.') + cmd.extend(['--ip4', ip4, '--gw4', gw4]) + if dns4: + cmd.extend(['--dns4', dns4]) + if search4: + cmd.extend(['--search4', search4]) + else: + raise ValueError("Invalid mode '{}'. Expected 'dhcp4' or 'static4'.".format(mode)) + + log.info('qcow2 module: Executing command: {}'.format(' '.join(shlex.quote(arg) for arg in cmd))) + + try: + result = subprocess.run(cmd, capture_output=True, text=True, check=False) + ret = { + 'retcode': result.returncode, + 'stdout': result.stdout, + 'stderr': result.stderr + } + if result.returncode != 0: + log.error('qcow2 module: Script execution failed with return code {}: {}'.format(result.returncode, result.stderr)) + else: + log.info('qcow2 module: Script executed successfully.') + return ret + except Exception as e: + log.error('qcow2 module: An error occurred while executing the script: {}'.format(e)) + raise + +def modify_hardware_config(vm_name, cpu=None, memory=None, pci=None, start=False): + ''' + Usage: + salt '*' qcow2.modify_hardware_config vm_name= [cpu=] [memory=] [pci=] [pci=] [start=] + + Options: + vm_name + Name of the virtual machine to modify + cpu + Number of virtual CPUs to assign (positive integer) + Optional - VM's current CPU count retained if not specified + memory + Amount of memory to assign in MiB (positive integer) + Optional - VM's current memory size retained if not specified + pci + PCI hardware ID(s) to passthrough to the VM (e.g., '0000:c7:00.0') + Can be specified multiple times for multiple devices + Optional - no PCI passthrough if not specified + start + Boolean flag to start the VM after modification + Optional - defaults to False + + Examples: + 1. **Modify CPU and Memory:** + ```bash + salt '*' qcow2.modify_hardware_config vm_name='sensor1' cpu=4 memory=8192 + ``` + This assigns 4 CPUs and 8GB memory to the VM + + 2. **Enable PCI Passthrough:** + ```bash + salt '*' qcow2.modify_hardware_config vm_name='sensor1' pci='0000:c7:00.0' pci='0000:c4:00.0' start=True + ``` + This configures PCI passthrough and starts the VM + + 3. **Complete Hardware Configuration:** + ```bash + salt '*' qcow2.modify_hardware_config vm_name='sensor1' cpu=8 memory=16384 pci='0000:c7:00.0' start=True + ``` + This sets CPU, memory, PCI passthrough, and starts the VM + + Notes: + - VM must be stopped before modification unless only the start flag is set + - Memory is specified in MiB (1024 = 1GB) + - PCI devices must be available and not in use by the host + - CPU count should align with host capabilities + - Requires so-kvm-modify-hardware script to be installed + + Description: + This function modifies the hardware configuration of a KVM virtual machine using + the so-kvm-modify-hardware script. It can adjust CPU count, memory allocation, + and PCI device passthrough. Changes are applied to the VM's libvirt configuration. + The VM can optionally be started after modifications are complete. + + Exit Codes: + 0: Success + 1: Invalid parameters + 2: VM state error (running when should be stopped) + 3: Hardware configuration error + 4: System command error + 255: Unexpected error + + Logging: + - All operations are logged to the salt minion log + - Log entries are prefixed with 'qcow2 module:' + - Hardware configuration changes are logged + - Errors include detailed messages and stack traces + - Final status of modification is logged + ''' + + cmd = ['/usr/sbin/so-kvm-modify-hardware', '-v', vm_name] + + if cpu is not None: + if isinstance(cpu, int) and cpu > 0: + cmd.extend(['-c', str(cpu)]) + else: + raise ValueError('cpu must be a positive integer.') + if memory is not None: + if isinstance(memory, int) and memory > 0: + cmd.extend(['-m', str(memory)]) + else: + raise ValueError('memory must be a positive integer.') + if pci: + # Handle PCI IDs (can be a single device or comma-separated list) + if isinstance(pci, str): + devices = [dev.strip() for dev in pci.split(',') if dev.strip()] + elif isinstance(pci, list): + devices = pci + else: + devices = [pci] + + # Add each device with its own -p flag + for device in devices: + cmd.extend(['-p', str(device)]) + if start: + cmd.append('-s') + + log.info('qcow2 module: Executing command: {}'.format(' '.join(shlex.quote(arg) for arg in cmd))) + + try: + result = subprocess.run(cmd, capture_output=True, text=True, check=False) + ret = { + 'retcode': result.returncode, + 'stdout': result.stdout, + 'stderr': result.stderr + } + if result.returncode != 0: + log.error('qcow2 module: Script execution failed with return code {}: {}'.format(result.returncode, result.stderr)) + else: + log.info('qcow2 module: Script executed successfully.') + return ret + except Exception as e: + log.error('qcow2 module: An error occurred while executing the script: {}'.format(e)) + raise diff --git a/salt/_runners/setup_hypervisor.py b/salt/_runners/setup_hypervisor.py new file mode 100644 index 000000000..6ddd571c9 --- /dev/null +++ b/salt/_runners/setup_hypervisor.py @@ -0,0 +1,1092 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. +# +# Note: Per the Elastic License 2.0, the second limitation states: +# +# "You may not move, change, disable, or circumvent the license key functionality +# in the software, and you may not remove or obscure any functionality in the +# software that is protected by the license key." + +""" +This runner performs the initial setup required for hypervisor hosts in the Security Onion environment. +It handles downloading the Oracle Linux KVM image, setting up SSH keys for secure communication, +and creating virtual machines with cloud-init configuration. + +Usage: + salt-run setup_hypervisor. [arguments] + +Options: + vm_name: Name for the virtual machine (alphanumeric, hyphens, underscores) + disk_size: Size of the VM disk with unit (e.g., '220G', '300G') + minion_id: Salt minion ID of the hypervisor (optional) + +Examples: + # Complete environment setup (default VM 'sool9' with 220G disk) + salt-run setup_hypervisor.setup_environment + + # Setup with custom VM name and disk size + salt-run setup_hypervisor.setup_environment myvm 300G + + # Regenerate SSH keys + salt-run setup_hypervisor.regenerate_ssh_keys + + # Create additional VM + salt-run setup_hypervisor.create_vm myvm2 300G + + Notes: + - Verifies Security Onion license + - Downloads and validates Oracle Linux KVM image if needed + - Generates Ed25519 SSH keys if not present + - Creates/recreates VM based on environment changes + - Forces hypervisor configuration via highstate after successful setup (when minion_id provided) + + Description: + The setup process includes: + 1. License validation + 2. Oracle Linux KVM image download and checksum verification + 3. SSH key generation for secure VM access + 4. Cloud-init configuration for VM provisioning + 5. VM creation with specified disk size + 6. Hypervisor configuration via highstate (when minion_id provided and setup successful) + +Exit Codes: + Success: Returns dictionary with 'success': True and VM details + Failure: Returns dictionary with 'success': False and error message + +Logging: + All operations are logged to: + - Standard output (INFO level and above) + - System log with 'setup_hypervisor' tag +""" + +import base64 +import hashlib +import logging +import os +import pwd +import requests +import salt.client +import salt.utils.files +import socket +import sys +import time +import yaml +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ed25519 +# Configure logging +log = logging.getLogger(__name__) +log.setLevel(logging.DEBUG) + + +def _set_ownership_and_perms(path: str, mode: int): + """Set ownership to socore:socore and apply file mode.""" + try: + socore_uid = pwd.getpwnam('socore').pw_uid + socore_gid = pwd.getpwnam('socore').pw_gid + os.chown(path, socore_uid, socore_gid) + os.chmod(path, mode) + log.debug(f"Set ownership socore:socore and mode {oct(mode)} for {path}") + except KeyError: + log.warning(f"socore user not found, skipping ownership/permission change for {path}") + except Exception as e: + log.warning(f"Failed to set ownership/permissions for {path}: {str(e)}") + +def _read_and_encode_key(key_path: str) -> str: + """Read a key file and return its base64 encoded content.""" + try: + with salt.utils.files.fopen(key_path, 'rb') as f: + content = f.read() + return base64.b64encode(content).decode('utf-8') + except Exception as e: + log.error("Error reading key file %s: %s", key_path, str(e)) + raise + +def _check_license(): + """Check if the license file exists and contains required values.""" + license_path = '/opt/so/saltstack/local/pillar/soc/license.sls' + + if not os.path.exists(license_path): + log.error("License file not found at %s", license_path) + return False + + try: + with salt.utils.files.fopen(license_path, 'r') as f: + license_data = yaml.safe_load(f) + + if not license_data: + log.error("Empty or invalid license file") + return False + + license_id = license_data.get('license_id') + features = license_data.get('features', []) + + if not license_id: + log.error("No license_id found in license file") + return False + + if 'vrt' not in features: + log.error("vrt feature not found in license") + return False + + log.info("License validation successful") + return True + + except Exception as e: + log.error("Error reading license file: %s", str(e)) + return False + +def _check_file_exists(path): + """Check if a file exists and create its directory if needed.""" + if os.path.exists(path): + return True + os.makedirs(os.path.dirname(path), exist_ok=True) + return False + +def _validate_image_checksum(path, expected_sha256): + """ + Validate the checksum of an existing image file. + Returns: + bool: True if checksum matches, False otherwise + """ + sha256_hash = hashlib.sha256() + with salt.utils.files.fopen(path, 'rb') as f: + for chunk in iter(lambda: f.read(4096), b''): + sha256_hash.update(chunk) + + downloaded_sha256 = sha256_hash.hexdigest() + if downloaded_sha256 != expected_sha256: + log.error("Checksum validation failed for %s - expected: %s, got: %s", + path, expected_sha256, downloaded_sha256) + return False + + log.info("Checksum validation successful for %s", path) + return True + +# Constants +IMAGE_URL = "https://yum.oracle.com/templates/OracleLinux/OL9/u5/x86_64/OL9U5_x86_64-kvm-b253.qcow2" +IMAGE_SHA256 = "3b00bbbefc8e78dd28d9f538834fb9e2a03d5ccdc2cadf2ffd0036c0a8f02021" +IMAGE_PATH = "/nsm/libvirt/boot/OL9U5_x86_64-kvm-b253.qcow2" +MANAGER_HOSTNAME = socket.gethostname() + +def _download_image(): + """ + Download and validate the Oracle Linux KVM image. + Returns: + bool: True if successful or file exists with valid checksum, False on error + """ + # Check if file already exists and validate checksum + if _check_file_exists(IMAGE_PATH): + if _validate_image_checksum(IMAGE_PATH, IMAGE_SHA256): + return True + else: + log.warning("Existing image has invalid checksum, will re-download") + os.unlink(IMAGE_PATH) + + log.info("Starting image download process") + + try: + # Download file + log.info("Downloading Oracle Linux KVM image from %s to %s", IMAGE_URL, IMAGE_PATH) + response = requests.get(IMAGE_URL, stream=True) + response.raise_for_status() + + # Get total file size for progress tracking + total_size = int(response.headers.get('content-length', 0)) + downloaded_size = 0 + last_log_time = 0 + + # Save file with progress logging + with salt.utils.files.fopen(IMAGE_PATH, 'wb') as f: + for chunk in response.iter_content(chunk_size=8192): + f.write(chunk) + downloaded_size += len(chunk) + + # Log progress every second + current_time = time.time() + if current_time - last_log_time >= 1: + progress = (downloaded_size / total_size) * 100 if total_size > 0 else 0 + log.info("Progress - %.1f%% (%d/%d bytes)", + progress, downloaded_size, total_size) + last_log_time = current_time + + # Validate downloaded file + if not _validate_image_checksum(IMAGE_PATH, IMAGE_SHA256): + os.unlink(IMAGE_PATH) + return False + + log.info("Successfully downloaded and validated Oracle Linux KVM image") + return True + + except Exception as e: + log.error("Error downloading hypervisor image: %s", str(e)) + if os.path.exists(IMAGE_PATH): + os.unlink(IMAGE_PATH) + return False + +def _check_ssh_keys_exist(): + """ + Check if SSH keys already exist. + Returns: + bool: True if both private and public keys exist, False otherwise + """ + key_dir = '/etc/ssh/auth_keys/soqemussh' + key_path = f'{key_dir}/id_ed25519' + pub_key_path = f'{key_path}.pub' + dest_dir = '/opt/so/saltstack/local/salt/libvirt/ssh/keys' + dest_path = os.path.join(dest_dir, os.path.basename(pub_key_path)) + + if os.path.exists(key_path) and os.path.exists(pub_key_path) and os.path.exists(dest_path): + log.info("SSH keys already exist") + return True + return False + +def _setup_ssh_keys(): + """ + Generate and set up SSH keys. + Returns: + bool: True if successful, False on error + """ + try: + key_dir = '/etc/ssh/auth_keys/soqemussh' + key_path = f'{key_dir}/id_ed25519' + pub_key_path = f'{key_path}.pub' + + # Check if keys already exist + if _check_ssh_keys_exist(): + return True + + # Create key directories if they don't exist and set permissions + log.info("Setting up SSH directory and keys") + parent_dir = os.path.dirname(key_dir) # /etc/ssh/auth_keys + os.makedirs(parent_dir, exist_ok=True) + os.chmod(parent_dir, 0o700) + + os.makedirs(key_dir, exist_ok=True) + os.chmod(key_dir, 0o700) + + # Generate new ed25519 key pair + log.info("Generating new SSH keys") + private_key = ed25519.Ed25519PrivateKey.generate() + public_key = private_key.public_key() + + # Serialize private key + private_bytes = private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.OpenSSH, + encryption_algorithm=serialization.NoEncryption() + ) + + # Serialize public key and format it as an OpenSSH public key + public_bytes = public_key.public_bytes( + encoding=serialization.Encoding.OpenSSH, + format=serialization.PublicFormat.OpenSSH + ) + public_bytes = public_bytes + f' soqemussh@{MANAGER_HOSTNAME}\n'.encode('utf-8') + + # Write the keys to files + with salt.utils.files.fopen(key_path, 'wb') as f: + f.write(private_bytes) + + with salt.utils.files.fopen(pub_key_path, 'wb') as f: + f.write(public_bytes) + + # Set proper permissions + os.chmod(key_path, 0o600) + os.chmod(pub_key_path, 0o640) + + log.info("SSH keys generated successfully") + + # Copy public key to saltstack directory + dest_dir = '/opt/so/saltstack/local/salt/libvirt/ssh/keys' + os.makedirs(dest_dir, exist_ok=True) + dest_path = os.path.join(dest_dir, os.path.basename(pub_key_path)) + + with salt.utils.files.fopen(pub_key_path, 'rb') as src: + with salt.utils.files.fopen(dest_path, 'wb') as dst: + dst.write(src.read()) + + log.info("Public key copied to %s", dest_dir) + return True + + except Exception as e: + log.error("Error setting up SSH keys: %s", str(e)) + return False + +def _check_vm_exists(vm_name: str) -> bool: + """ + Check if VM files already exist. + Returns: + bool: True if VM files exist, False otherwise + """ + base_dir = '/opt/so/saltstack/local/salt/libvirt/images' + vm_dir = f'{base_dir}/{vm_name}' + vm_image = os.path.join(vm_dir, f'{vm_name}.qcow2') + cidata_iso = os.path.join(vm_dir, f'{vm_name}-cidata.iso') + + required_files = [ + vm_image, + cidata_iso, + os.path.join(vm_dir, 'meta-data'), + os.path.join(vm_dir, 'user-data'), + os.path.join(vm_dir, 'network-data') + ] + + exists = all(os.path.exists(f) for f in required_files) + if exists: + log.info("VM %s already exists", vm_name) + return exists + +def _ensure_hypervisor_host_dir(minion_id: str = None): + """ + Ensure the hypervisor host directory exists. + + This function creates the directory structure for a hypervisor host if it doesn't exist. + The path is: /opt/so/saltstack/local/salt/hypervisor/hosts/ + + Args: + minion_id (str, optional): Salt minion ID of the hypervisor. + + Returns: + bool: True if directory exists or was created successfully, False otherwise + """ + if not minion_id: + log.warning("No minion_id provided, skipping host directory creation") + return True + + try: + # Extract hostname from minion_id by removing role suffix (anything after first underscore) + hostname = minion_id.split('_', 1)[0] if '_' in minion_id else minion_id + + # Define the directory path + host_dir = f'/opt/so/saltstack/local/salt/hypervisor/hosts/{hostname}' + + # Check if directory exists and create it if it doesn't + if os.path.exists(host_dir): + log.info(f"Hypervisor host directory already exists: {host_dir}") + # Create the VMs file if it doesn't exist + vms_file = f'/opt/so/saltstack/local/salt/hypervisor/hosts/{hostname}VMs' + if not os.path.exists(vms_file): + with salt.utils.files.fopen(vms_file, 'w') as f: + f.write('[]') + log.info(f"Created empty VMs file: {vms_file}") + + # Set proper ownership for the VMs file + try: + socore_uid = pwd.getpwnam('socore').pw_uid + socore_gid = pwd.getpwnam('socore').pw_gid + os.chown(vms_file, socore_uid, socore_gid) + log.info(f"Set ownership to socore:socore for {vms_file}") + except (KeyError, Exception) as e: + log.warning(f"Failed to set ownership for VMs file: {str(e)}") + return True + + # Create all necessary parent directories + os.makedirs(host_dir, exist_ok=True) + log.info(f"Created hypervisor host directory: {host_dir}") + + # Create the VMs file with an empty JSON array + vms_file = f'/opt/so/saltstack/local/salt/hypervisor/hosts/{hostname}VMs' + with salt.utils.files.fopen(vms_file, 'w') as f: + f.write('[]') + log.info(f"Created empty VMs file: {vms_file}") + + # Set proper ownership (socore:socore) + try: + socore_uid = pwd.getpwnam('socore').pw_uid + socore_gid = pwd.getpwnam('socore').pw_gid + os.chown(host_dir, socore_uid, socore_gid) + os.chown(vms_file, socore_uid, socore_gid) + + # Also set ownership for parent directories if they were just created + parent_dir = os.path.dirname(host_dir) # /opt/so/saltstack/local/salt/hypervisor/hosts + if os.path.exists(parent_dir): + os.chown(parent_dir, socore_uid, socore_gid) + + parent_dir = os.path.dirname(parent_dir) # /opt/so/saltstack/local/salt/hypervisor + if os.path.exists(parent_dir): + os.chown(parent_dir, socore_uid, socore_gid) + + log.info(f"Set ownership to socore:socore for {host_dir} and {vms_file}") + except KeyError: + log.warning("socore user not found, skipping ownership change") + except Exception as e: + log.warning(f"Failed to set ownership: {str(e)}") + + return True + except Exception as e: + log.error(f"Error creating hypervisor host directory: {str(e)}") + return False + +def _apply_dyanno_hypervisor_state(): + """ + Apply the soc.dyanno.hypervisor state on the salt master. + + This function applies the soc.dyanno.hypervisor state on the salt master + to update the hypervisor annotation and ensure all hypervisor host directories exist. + + Returns: + bool: True if state was applied successfully, False otherwise + """ + try: + log.info("Applying soc.dyanno.hypervisor state on salt master") + + # Initialize the LocalClient + local = salt.client.LocalClient() + + # Target the salt master to apply the soc.dyanno.hypervisor state + target = MANAGER_HOSTNAME + '_*' + state_result = local.cmd(target, 'state.apply', ['soc.dyanno.hypervisor', "pillar={'baseDomain': {'status': 'PreInit'}}", 'concurrent=True'], tgt_type='glob') + log.debug(f"state_result: {state_result}") + # Check if state was applied successfully + if state_result: + success = True + for minion, states in state_result.items(): + if not isinstance(states, dict): + log.error(f"Unexpected result format from {minion}: {states}") + success = False + continue + + for state_id, state_data in states.items(): + if not state_data.get('result', False): + log.error(f"State {state_id} failed on {minion}: {state_data.get('comment', 'No comment')}") + success = False + + if success: + log.info("Successfully applied soc.dyanno.hypervisor state") + return True + else: + log.error("Failed to apply soc.dyanno.hypervisor state") + return False + else: + log.error("No response from salt master when applying soc.dyanno.hypervisor state") + return False + + except Exception as e: + log.error(f"Error applying soc.dyanno.hypervisor state: {str(e)}") + return False + +def _apply_cloud_config_state(): + """ + Apply the salt.cloud.config state on the salt master. + + Returns: + bool: True if state was applied successfully, False otherwise + """ + try: + log.info("Applying salt.cloud.config state on salt master") + + # Initialize the LocalClient + local = salt.client.LocalClient() + + # Target the salt master to apply the soc.dyanno.hypervisor state + target = MANAGER_HOSTNAME + '_*' + state_result = local.cmd(target, 'state.apply', ['salt.cloud.config', 'concurrent=True'], tgt_type='glob') + log.debug(f"state_result: {state_result}") + # Check if state was applied successfully + if state_result: + success = True + for minion, states in state_result.items(): + if not isinstance(states, dict): + log.error(f"Unexpected result format from {minion}: {states}") + success = False + continue + + for state_id, state_data in states.items(): + if not state_data.get('result', False): + log.error(f"State {state_id} failed on {minion}: {state_data.get('comment', 'No comment')}") + success = False + + if success: + log.info("Successfully applied salt.cloud.config state") + return True + else: + log.error("Failed to apply salt.cloud.config state") + return False + else: + log.error("No response from salt master when applying salt.cloud.config state") + return False + + except Exception as e: + log.error(f"Error applying salt.cloud.config state: {str(e)}") + return False + +def setup_environment(vm_name: str = 'sool9', disk_size: str = '220G', minion_id: str = None): + """ + Main entry point to set up the hypervisor environment. + + This function orchestrates the complete setup process for a Security Onion hypervisor, + including image management, SSH key setup, and VM creation. It ensures all components + are properly configured and validates the environment at each step. + + Args: + vm_name (str, optional): Name for the VM to create. Must contain only + alphanumeric characters, hyphens, or underscores. + Defaults to 'sool9'. + disk_size (str, optional): Size of the VM disk with unit (e.g., '220G', '300G'). + Must end with 'G' or 'M'. Defaults to '220G'. + minion_id (str, optional): Salt minion ID of the hypervisor. When provided, + forces the hypervisor to apply its configuration via + highstate after successful environment setup (image + download, SSH keys, VM creation). + + Returns: + dict: A dictionary containing: + - success (bool): True if setup completed successfully + - error (str): Error message if setup failed, None otherwise + - vm_result (dict): Details about VM creation if successful + + Notes: + - Verifies Security Onion license + - Downloads and validates Oracle Linux KVM image if needed + - Generates Ed25519 SSH keys if not present + - Creates/recreates VM based on environment changes + - Forces hypervisor configuration via highstate after successful setup + (when minion_id is provided) + + Example: + result = setup_environment('myvm', '300G', 'hypervisor1') + if result['success']: + print(f"VM created at {result['vm_result']['vm_dir']}") + else: + print(f"Setup failed: {result['error']}") + """ + # Check license before proceeding + if not _check_license(): + return { + 'success': False, + 'error': 'Invalid license or missing vrt feature', + 'vm_result': None + } + + # Ensure hypervisor host directory exists + if not _ensure_hypervisor_host_dir(minion_id): + return { + 'success': False, + 'error': 'Failed to create hypervisor host directory', + 'vm_result': None + } + + if minion_id: + # Initialize the LocalClient + local = salt.client.LocalClient() + + # Add retry logic for mine.update + max_retries = 10 + retry_delay = 3 + mine_update_success = False + + for attempt in range(1, max_retries + 1): + mine_update_result = local.cmd(minion_id, 'mine.update') + log.debug(f"mine_update_result: {mine_update_result}") + + # Check if mine.update was successful + if mine_update_result and all(mine_update_result.values()): + log.info(f"mine.update successful on attempt {attempt}") + mine_update_success = True + break + else: + log.warning(f"mine.update failed on attempt {attempt}/{max_retries}, retrying in {retry_delay} seconds...") + time.sleep(retry_delay) + + if not mine_update_success: + log.error(f"mine.update failed after {max_retries} attempts") + + # Apply the soc.dyanno.hypervisor state on the salt master + if not _apply_cloud_config_state(): + log.warning("Failed to apply salt.cloud.config state, continuing with setup") + # We don't return an error here as we want to continue with the setup process + + # Apply the soc.dyanno.hypervisor state on the salt master + if not _apply_dyanno_hypervisor_state(): + log.warning("Failed to apply soc.dyanno.hypervisor state, continuing with setup") + # We don't return an error here as we want to continue with the setup process + + log.info("Starting setup_environment in setup_hypervisor runner") + + # Check if environment is already set up + image_exists = _check_file_exists(IMAGE_PATH) + image_valid = image_exists and _validate_image_checksum(IMAGE_PATH, IMAGE_SHA256) + keys_exist = _check_ssh_keys_exist() + vm_exists = _check_vm_exists(vm_name) + + # Track if we need to create/recreate VM + create_vm_needed = False + + # Handle image setup if needed + if not image_valid: + log.info("Starting image download/validation process") + if not _download_image(): + log.error("Image download failed") + return { + 'success': False, + 'error': 'Image download failed', + 'vm_result': None + } + create_vm_needed = True + + # Handle SSH key setup if needed + if not keys_exist: + log.info("Setting up SSH keys") + if not _setup_ssh_keys(): + log.error("SSH key setup failed") + return { + 'success': False, + 'error': 'SSH key setup failed', + 'vm_result': None + } + create_vm_needed = True + + # Create/recreate VM if needed + if create_vm_needed or not vm_exists: + if vm_exists: + log.info("Environment changes detected, recreating VM %s", vm_name) + else: + log.info("Creating new VM %s", vm_name) + vm_result = create_vm(vm_name, disk_size) + else: + log.info("No changes detected, using existing VM %s", vm_name) + vm_result = { + 'success': True, + 'vm_dir': f'/opt/so/saltstack/local/salt/libvirt/images/{vm_name}' + } + + success = vm_result.get('success', False) + log.info("Setup environment completed with status: %s", "SUCCESS" if success else "FAILED") + + # If setup was successful and we have a minion_id, run highstate + if success and minion_id: + log.info("Running highstate on hypervisor %s", minion_id) + try: + # Initialize the LocalClient + local = salt.client.LocalClient() + # Run highstate on the hypervisor + highstate_result = local.cmd(minion_id, 'state.highstate', [], timeout=1800) + if highstate_result and minion_id in highstate_result: + log.info("Highstate initiated on %s", minion_id) + else: + log.error("Highstate failed or timed out on %s", minion_id) + return { + 'success': False, + 'error': 'Highstate failed or timed out', + 'vm_result': None + } + except Exception as e: + log.error("Error running highstate on %s: %s", minion_id, str(e)) + return { + 'success': False, + 'error': f'Error running highstate: {str(e)}', + 'vm_result': None + } + + return { + 'success': success, + 'error': vm_result.get('error') if not success else None, + 'vm_result': vm_result + } + +def create_vm(vm_name: str, disk_size: str = '220G'): + """ + Creates a new virtual machine with cloud-init configuration. + + This function handles the complete VM creation process, including directory setup, + image management, and cloud-init configuration. It ensures proper setup of the VM + environment with all necessary components. + + Args: + vm_name (str): Name for the VM. Must contain only alphanumeric characters, + hyphens, or underscores. + disk_size (str): Size of the VM disk with unit (e.g., '220G', '300G'). + Must end with 'G' or 'M'. Defaults to '220G'. + + Returns: + dict: A dictionary containing: + - success (bool): True if VM creation completed successfully + - error (str): Error message if creation failed + - vm_dir (str): Path to VM directory if successful + + Notes: + - Validates Security Onion license + - Creates cloud-init ISO for VM configuration + - Copies and resizes base Oracle Linux image + - Compresses final image for efficiency + - Generates SHA256 hash for verification + - Configures repositories and GPG keys + - Sets up system services and storage + + Example: + result = create_vm('myvm', '300G') + if result['success']: + print(f"VM created at {result['vm_dir']}") + else: + print(f"Creation failed: {result['error']}") + """ + # Check license before proceeding + if not _check_license(): + return { + 'success': False, + 'error': 'Invalid license or missing vrt feature', + } + + try: + # Input validation + if not isinstance(vm_name, str) or not vm_name: + log.error("Invalid VM name") + return {'success': False, 'error': 'Invalid VM name'} + + if not vm_name.isalnum() and not all(c in '-_' for c in vm_name if not c.isalnum()): + log.error("VM name must contain only alphanumeric characters, hyphens, or underscores") + return {'success': False, 'error': 'Invalid VM name format'} + + # Validate disk size format + if not isinstance(disk_size, str) or not disk_size.endswith(('G', 'M')): + log.error("Invalid disk size format. Must end with G or M") + return {'success': False, 'error': 'Invalid disk size format'} + + try: + size_num = int(disk_size[:-1]) + if size_num <= 0: + raise ValueError + except ValueError: + log.error("Invalid disk size number") + return {'success': False, 'error': 'Invalid disk size number'} + + # Ensure base image exists + if not os.path.exists(IMAGE_PATH): + log.error("Base image not found at %s", IMAGE_PATH) + return {'success': False, 'error': 'Base image not found'} + + # Set up directory structure + base_dir = '/opt/so/saltstack/local/salt/libvirt/images' + vm_dir = f'{base_dir}/{vm_name}' + os.makedirs(vm_dir, exist_ok=True) + # Set ownership and permissions for the VM directory + _set_ownership_and_perms(vm_dir, mode=0o750) + + # Read the SSH public key + pub_key_path = '/opt/so/saltstack/local/salt/libvirt/ssh/keys/id_ed25519.pub' + try: + with salt.utils.files.fopen(pub_key_path, 'r') as f: + ssh_pub_key = f.read().strip() + except Exception as e: + log.error("Failed to read SSH public key: %s", str(e)) + return {'success': False, 'error': 'Failed to read SSH public key'} + + # Read pillar data for soqemussh password hash + pillar_path = '/opt/so/saltstack/local/pillar/vm/soc_vm.sls' + password_hash = None + passwd_line = "" # Default to empty if no hash found + try: + if os.path.exists(pillar_path): + with salt.utils.files.fopen(pillar_path, 'r') as f: + pillar_data = yaml.safe_load(f) + if pillar_data: + password_hash = pillar_data.get('vm', {}).get('user', {}).get('soqemussh', {}).get('passwordHash') + if password_hash: + passwd_line = f" passwd: {password_hash}\n" + log.info("Found soqemussh password hash in pillar.") + else: + log.info("No soqemussh password hash found in pillar, omitting passwd line.") + except Exception as e: + log.warning(f"Error reading or parsing pillar file {pillar_path}: {str(e)}. Omitting passwd line.") + + # Read and encode GPG keys + keys_dir = '/opt/so/saltstack/default/salt/repo/client/files/oracle/keys' + oracle_key = _read_and_encode_key(os.path.join(keys_dir, 'RPM-GPG-KEY-oracle')) + epel_key = _read_and_encode_key(os.path.join(keys_dir, 'RPM-GPG-KEY-EPEL-9')) + salt_key = _read_and_encode_key(os.path.join(keys_dir, 'SALT-PROJECT-GPG-PUBKEY-2023.pub')) + docker_key = _read_and_encode_key(os.path.join(keys_dir, 'docker.pub')) + securityonion_key = _read_and_encode_key(os.path.join(keys_dir, 'securityonion.pub')) + + # Create meta-data + meta_data = f"""instance-id: {vm_name} +local-hostname: {vm_name} +""" + meta_data_path = os.path.join(vm_dir, 'meta-data') + # Create empty file, set perms, then write + open(meta_data_path, 'a').close() + _set_ownership_and_perms(meta_data_path, mode=0o640) + with salt.utils.files.fopen(meta_data_path, 'w') as f: + f.write(meta_data) + log.info("Created meta-data") + + # Create network-data + network_data = """network: + config: disabled""" + network_data_path = os.path.join(vm_dir, 'network-data') + # Create empty file, set perms, then write + open(network_data_path, 'a').close() + _set_ownership_and_perms(network_data_path, mode=0o640) + with salt.utils.files.fopen(network_data_path, 'w') as f: + f.write(network_data) + log.info("Created network-data") + + # Create user-data + user_data = f"""#cloud-config +preserve_hostname: False +hostname: {vm_name} +fqdn: {vm_name}.local + +# The passwd hash will be removed at release and is being used for debugging during development +users: + - default + - name: soqemussh + groups: ['wheel'] + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + lock_passwd: false +{passwd_line} ssh_authorized_keys: + - {ssh_pub_key} + +# Configure where output will go +output: + all: ">> /var/log/cloud-init.log" + +# configure interaction with ssh server +ssh_genkeytypes: ['ed25519', 'rsa'] + +# set timezone for VM +timezone: UTC + +write_files: + - path: /etc/yum.repos.d/securityonion.repo + content: | + [securityonion] + name=Security Onion Repo + baseurl=https://{MANAGER_HOSTNAME}/repo + enabled=1 + gpgcheck=1 + sslverify=0 + - path: /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle + encoding: b64 + content: | + {oracle_key} + - path: /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9 + encoding: b64 + content: | + {epel_key} + - path: /etc/pki/rpm-gpg/SALT-PROJECT-GPG-PUBKEY-2023.pub + encoding: b64 + content: | + {salt_key} + - path: /etc/pki/rpm-gpg/docker.pub + encoding: b64 + content: | + {docker_key} + - path: /etc/pki/rpm-gpg/securityonion.pub + encoding: b64 + content: | + {securityonion_key} + +# Run on every boot - this will only run *after* the first boot and successful cloud-init run +bootcmd: + - if [ -f /var/lib/cloud/instance/boot-finished ]; then touch /etc/cloud/cloud-init.disabled; fi + +runcmd: + # Import GPG keys and remove repo files except securityonion.repo + - rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle + - rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9 + - rpm --import /etc/pki/rpm-gpg/SALT-PROJECT-GPG-PUBKEY-2023.pub + - rpm --import /etc/pki/rpm-gpg/docker.pub + - rpm --import /etc/pki/rpm-gpg/securityonion.pub + - for f in /etc/yum.repos.d/*.repo; do if [ "$(basename $f)" != "securityonion.repo" ]; then rm -f "$f"; fi; done + - systemctl enable --now serial-getty@ttyS0.service + - systemctl enable --now NetworkManager + - systemctl enable --now qemu-guest-agent + - growpart /dev/vda 2 + - pvresize /dev/vda2 + - lvextend -l +100%FREE /dev/vg_main/lv_root + - xfs_growfs /dev/vg_main/lv_root + - rm -f /etc/sysconfig/network-scripts/ifcfg-eth0 + +power_state: + delay: "now" + mode: poweroff + timeout: 30 + condition: True + message: Cloud-init completed, powering off +""" + user_data_path = os.path.join(vm_dir, 'user-data') + # Create empty file, set perms, then write + open(user_data_path, 'a').close() + _set_ownership_and_perms(user_data_path, mode=0o640) + with salt.utils.files.fopen(user_data_path, 'w') as f: + f.write(user_data) + log.info("Created user-data") + + # Copy and resize base image + base_image = IMAGE_PATH + vm_image = os.path.join(vm_dir, f'{vm_name}.qcow2') + + # Copy base image with progress logging + import shutil + log.info("Copying base image to %s", vm_image) + shutil.copy2(base_image, vm_image) + # Set ownership and permissions for the copied image + _set_ownership_and_perms(vm_image, mode=0o640) + log.info("Base image copy complete") + + # Get current image size + import subprocess + try: + result = subprocess.run(['qemu-img', 'info', '--output=json', vm_image], + check=True, capture_output=True, text=True) + import json + info = json.loads(result.stdout) + current_size = info.get('virtual-size', 0) + requested_size = int(disk_size[:-1]) * (1024**3 if disk_size.endswith('G') else 1024**2) + + # Only resize if requested size is larger + if requested_size > current_size: + log.info("Resizing image to %s", disk_size) + try: + result = subprocess.run(['qemu-img', 'resize', '-f', 'qcow2', vm_image, disk_size], + check=True, capture_output=True, text=True) + log.info("Image resize complete") + except subprocess.CalledProcessError as e: + log.error("Failed to resize image: %s", e.stderr) + raise + else: + log.info("Image already at or larger than requested size") + except subprocess.CalledProcessError as e: + log.error("Failed to get image info: %s", e.stderr) + raise + except json.JSONDecodeError as e: + log.error("Failed to parse image info: %s", str(e)) + raise + + # Compress image + temp_image = f"{vm_image}.temp" + log.info("Compressing image") + + # Start compression in a subprocess + process = subprocess.Popen(['qemu-img', 'convert', '-O', 'qcow2', '-c', vm_image, temp_image], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + # Monitor progress by checking output file size + source_size = os.path.getsize(vm_image) + last_log_time = 0 + + while process.poll() is None: # While compression is running + current_time = time.time() + if current_time - last_log_time >= 1: # Log every second + if os.path.exists(temp_image): + compressed_size = os.path.getsize(temp_image) + progress = (compressed_size / source_size) * 100 + log.info("Compression progress - %.1f%% (%d/%d bytes)", + progress, compressed_size, source_size) + last_log_time = current_time + + # Check if compression completed successfully + if process.returncode == 0: + os.replace(temp_image, vm_image) + # Set ownership and permissions for the compressed image + _set_ownership_and_perms(vm_image, mode=0o640) + log.info("Image compression complete") + else: + error = process.stderr.read().decode('utf-8') + log.error("Failed to compress image: %s", error) + if os.path.exists(temp_image): + os.unlink(temp_image) + raise subprocess.CalledProcessError(process.returncode, 'qemu-img convert', stderr=error) + + # Create cloud-init ISO + cidata_iso = os.path.join(vm_dir, f'{vm_name}-cidata.iso') + subprocess.run(['mkisofs', '-output', cidata_iso, '-volid', 'CIDATA', '-rock', + user_data_path, meta_data_path, network_data_path], + check=True, capture_output=True) + # Set ownership and permissions for the created ISO + _set_ownership_and_perms(cidata_iso, mode=0o640) + log.info("Created cidata ISO") + + # Generate SHA256 hash of the qcow2 image + sha256_hash = hashlib.sha256() + with salt.utils.files.fopen(vm_image, 'rb') as f: + for chunk in iter(lambda: f.read(4096), b''): + sha256_hash.update(chunk) + + # Write hash to file + hash_file = os.path.join(vm_dir, f'{vm_name}.sha256') + with salt.utils.files.fopen(hash_file, 'w') as f: + f.write(sha256_hash.hexdigest()) + # Set ownership and permissions for the hash file + _set_ownership_and_perms(hash_file, mode=0o640) + + log.info("Generated SHA256 hash for %s", vm_image) + + return { + 'success': True, + 'vm_dir': vm_dir + } + + except Exception as e: + log.error("Error creating VM: %s", str(e)) + return {'success': False, 'error': str(e)} + +def regenerate_ssh_keys(): + """ + Regenerates SSH keys used for hypervisor VM access. + + This function handles the complete process of SSH key regeneration, including + validation, cleanup of existing keys, and generation of new keys with proper + permissions and distribution. + + Returns: + bool: True if keys were successfully regenerated, False otherwise + + Notes: + - Validates Security Onion license + - Removes existing keys if present + - Generates new Ed25519 key pair + - Sets secure permissions (600 for private, 644 for public) + - Distributes public key to required locations + + Description: + The function performs these steps: + 1. Validates Security Onion license + 2. Checks for existing SSH keys + 3. Removes old keys if present + 4. Creates required directories with secure permissions + 5. Generates new Ed25519 key pair + 6. Sets appropriate file permissions + 7. Distributes public key to required locations + + Example: + if regenerate_ssh_keys(): + print("SSH keys successfully regenerated") + else: + print("Failed to regenerate SSH keys") + """ + log.info("Starting SSH key regeneration") + try: + # Verify current state + if not _check_ssh_keys_exist(): + log.warning("No existing SSH keys found to regenerate") + return _setup_ssh_keys() + + # Remove existing keys + key_dir = '/etc/ssh/auth_keys/soqemussh' + key_path = f'{key_dir}/id_ed25519' + pub_key_path = f'{key_path}.pub' + dest_dir = '/opt/so/saltstack/local/salt/libvirt/ssh/keys' + dest_path = os.path.join(dest_dir, os.path.basename(pub_key_path)) + + for path in [key_path, pub_key_path, dest_path]: + try: + os.unlink(path) + log.info("Removed existing key: %s", path) + except FileNotFoundError: + log.warning("Key file not found: %s", path) + + # Generate new keys + if _setup_ssh_keys(): + log.info("SSH keys regenerated successfully") + return True + + log.error("Failed to regenerate SSH keys") + return False + + except Exception as e: + log.error("Error regenerating SSH keys: %s", str(e)) + return False diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index 4e3e57f9c..3edda8a4c 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -1,258 +1,178 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. +{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one + or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at + https://securityonion.net/license; you may not use this file except in compliance with the + Elastic License 2.0. #} {% set ISAIRGAP = salt['pillar.get']('global:airgap', False) %} {% import_yaml 'salt/minion.defaults.yaml' as saltversion %} {% set saltversion = saltversion.salt.minion.version %} -{# this is the list we are returning from this map file, it gets built below #} -{% set allowed_states= [] %} +{# Define common state groups to reduce redundancy #} +{% set base_states = [ + 'common', + 'patch.os.schedule', + 'motd', + 'salt.minion-check', + 'sensoroni', + 'salt.lasthighstate', + 'salt.minion' +] %} + +{% set ssl_states = [ + 'ssl', + 'telegraf', + 'firewall', + 'schedule', + 'docker_clean' +] %} + +{% set manager_states = [ + 'salt.master', + 'ca', + 'registry', + 'manager', + 'nginx', + 'influxdb', + 'soc', + 'kratos', + 'hydra', + 'elasticfleet', + 'elastic-fleet-package-registry', + 'idstools', + 'suricata.manager', + 'utility' +] %} + +{% set sensor_states = [ + 'pcap', + 'suricata', + 'healthcheck', + 'tcpreplay', + 'zeek', + 'strelka' +] %} + +{% set kafka_states = [ + 'kafka' +] %} + +{% set stig_states = [ + 'stig' +] %} + +{% set elastic_stack_states = [ + 'elasticsearch', + 'elasticsearch.auth', + 'kibana', + 'kibana.secrets', + 'elastalert', + 'logstash', + 'redis' +] %} + +{# Initialize the allowed_states list #} +{% set allowed_states = [] %} {% if grains.saltversion | string == saltversion | string %} + {# Map role-specific states #} + {% set role_states = { + 'so-eval': ( + ssl_states + + manager_states + + sensor_states + + elastic_stack_states | reject('equalto', 'logstash') | list + ), + 'so-heavynode': ( + ssl_states + + sensor_states + + ['elasticagent', 'elasticsearch', 'logstash', 'redis', 'nginx'] + ), + 'so-idh': ( + ssl_states + + ['idh'] + ), + 'so-import': ( + ssl_states + + manager_states + + sensor_states | reject('equalto', 'strelka') | reject('equalto', 'healthcheck') | list + + ['elasticsearch', 'elasticsearch.auth', 'kibana', 'kibana.secrets', 'strelka.manager'] + ), + 'so-manager': ( + ssl_states + + manager_states + + ['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users', 'strelka.manager'] + + stig_states + + kafka_states + + elastic_stack_states + ), + 'so-managerhype': ( + ssl_states + + manager_states + + ['salt.cloud', 'strelka.manager', 'hypervisor', 'libvirt'] + + stig_states + + kafka_states + + elastic_stack_states + ), + 'so-managersearch': ( + ssl_states + + manager_states + + ['strelka.manager'] + + stig_states + + kafka_states + + elastic_stack_states + ), + 'so-searchnode': ( + ssl_states + + ['kafka.ca', 'kafka.ssl', 'elasticsearch', 'logstash', 'nginx'] + + stig_states + ), + 'so-standalone': ( + ssl_states + + manager_states + + sensor_states + + stig_states + + kafka_states + + elastic_stack_states + ), + 'so-sensor': ( + ssl_states + + sensor_states + + ['nginx'] + + stig_states + ), + 'so-fleet': ( + ssl_states + + ['logstash', 'nginx', 'healthcheck', 'elasticfleet'] + ), + 'so-receiver': ( + ssl_states + + kafka_states + + stig_states + + ['logstash', 'redis'] + ), + 'so-hypervisor': ( + ssl_states + + stig_states + + ['hypervisor', 'libvirt'] + ), + 'so-desktop': ( + ['ssl', 'docker_clean', 'telegraf'] + + stig_states + ) + } %} - {% set allowed_states= salt['grains.filter_by']({ - 'so-eval': [ - 'salt.master', - 'ca', - 'ssl', - 'registry', - 'manager', - 'nginx', - 'telegraf', - 'influxdb', - 'soc', - 'kratos', - 'elasticfleet', - 'elastic-fleet-package-registry', - 'firewall', - 'idstools', - 'suricata.manager', - 'healthcheck', - 'pcap', - 'suricata', - 'utility', - 'schedule', - 'soctopus', - 'tcpreplay', - 'docker_clean' - ], - 'so-heavynode': [ - 'ssl', - 'nginx', - 'telegraf', - 'firewall', - 'pcap', - 'suricata', - 'healthcheck', - 'elasticagent', - 'schedule', - 'tcpreplay', - 'docker_clean' - ], - 'so-idh': [ - 'ssl', - 'telegraf', - 'firewall', - 'idh', - 'schedule', - 'docker_clean' - ], - 'so-import': [ - 'salt.master', - 'ca', - 'ssl', - 'registry', - 'manager', - 'nginx', - 'soc', - 'kratos', - 'influxdb', - 'telegraf', - 'firewall', - 'idstools', - 'suricata.manager', - 'pcap', - 'utility', - 'suricata', - 'zeek', - 'schedule', - 'tcpreplay', - 'docker_clean', - 'elasticfleet', - 'elastic-fleet-package-registry' - ], - 'so-manager': [ - 'salt.master', - 'ca', - 'ssl', - 'registry', - 'manager', - 'nginx', - 'telegraf', - 'influxdb', - 'soc', - 'kratos', - 'elasticfleet', - 'elastic-fleet-package-registry', - 'firewall', - 'idstools', - 'suricata.manager', - 'utility', - 'schedule', - 'soctopus', - 'docker_clean' - ], - 'so-managersearch': [ - 'salt.master', - 'ca', - 'ssl', - 'registry', - 'nginx', - 'telegraf', - 'influxdb', - 'soc', - 'kratos', - 'elastic-fleet-package-registry', - 'elasticfleet', - 'firewall', - 'manager', - 'idstools', - 'suricata.manager', - 'utility', - 'schedule', - 'soctopus', - 'docker_clean' - ], - 'so-searchnode': [ - 'ssl', - 'nginx', - 'telegraf', - 'firewall', - 'schedule', - 'docker_clean' - ], - 'so-standalone': [ - 'salt.master', - 'ca', - 'ssl', - 'registry', - 'manager', - 'nginx', - 'telegraf', - 'influxdb', - 'soc', - 'kratos', - 'elastic-fleet-package-registry', - 'elasticfleet', - 'firewall', - 'idstools', - 'suricata.manager', - 'pcap', - 'suricata', - 'healthcheck', - 'utility', - 'schedule', - 'soctopus', - 'tcpreplay', - 'docker_clean' - ], - 'so-sensor': [ - 'ssl', - 'telegraf', - 'firewall', - 'nginx', - 'pcap', - 'suricata', - 'healthcheck', - 'schedule', - 'tcpreplay', - 'docker_clean' - ], - 'so-fleet': [ - 'ssl', - 'telegraf', - 'firewall', - 'logstash', - 'healthcheck', - 'schedule', - 'elasticfleet', - 'docker_clean' - ], - 'so-receiver': [ - 'ssl', - 'telegraf', - 'firewall', - 'schedule', - 'docker_clean' - ], - 'so-desktop': [ - 'ssl', - 'docker_clean', - 'telegraf' - ], - }, grain='role') %} - - {% if grains.role in ['so-eval', 'so-manager', 'so-managersearch', 'so-standalone'] %} - {% do allowed_states.append('mysql') %} - {% endif %} - - {%- if grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %} - {% do allowed_states.append('zeek') %} - {%- endif %} - - {% if grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %} - {% do allowed_states.append('strelka') %} - {% endif %} - - {% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-searchnode', 'so-managersearch', 'so-heavynode', 'so-import'] %} - {% do allowed_states.append('elasticsearch') %} - {% endif %} - - {% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %} - {% do allowed_states.append('elasticsearch.auth') %} - {% endif %} - - {% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %} - {% do allowed_states.append('kibana') %} - {% do allowed_states.append('kibana.secrets') %} - {% endif %} - - {% if grains.role in ['so-eval', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-manager'] %} - {% do allowed_states.append('curator') %} - {% endif %} - - {% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %} - {% do allowed_states.append('elastalert') %} - {% endif %} - - {% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %} - {% do allowed_states.append('playbook') %} - {% endif %} - - {% if grains.role in ['so-manager', 'so-standalone', 'so-searchnode', 'so-managersearch', 'so-heavynode', 'so-receiver'] %} - {% do allowed_states.append('logstash') %} - {% endif %} - - {% if grains.role in ['so-manager', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-receiver', 'so-eval'] %} - {% do allowed_states.append('redis') %} - {% endif %} - - {# all nodes on the right salt version can run the following states #} - {% do allowed_states.append('common') %} - {% do allowed_states.append('patch.os.schedule') %} - {% do allowed_states.append('motd') %} - {% do allowed_states.append('salt.minion-check') %} - {% do allowed_states.append('sensoroni') %} - {% do allowed_states.append('salt.lasthighstate') %} + {# Get states for the current role #} + {% if grains.role in role_states %} + {% set allowed_states = role_states[grains.role] %} + {% endif %} + {# Add base states that apply to all roles #} + {% for state in base_states %} + {% do allowed_states.append(state) %} + {% endfor %} {% endif %} - +{# Add airgap state if needed #} {% if ISAIRGAP %} - {% do allowed_states.append('airgap') %} + {% do allowed_states.append('airgap') %} {% endif %} - -{# all nodes can always run salt.minion state #} -{% do allowed_states.append('salt.minion') %} diff --git a/salt/backup/defaults.yaml b/salt/backup/defaults.yaml index 1aae64910..dde128a80 100644 --- a/salt/backup/defaults.yaml +++ b/salt/backup/defaults.yaml @@ -4,4 +4,5 @@ backup: - /etc/pki - /etc/salt - /nsm/kratos + - /nsm/hydra destination: "/nsm/backup" \ No newline at end of file diff --git a/salt/bpf/pcap.map.jinja b/salt/bpf/pcap.map.jinja index c1d7562cc..4d8fef460 100644 --- a/salt/bpf/pcap.map.jinja +++ b/salt/bpf/pcap.map.jinja @@ -1,7 +1,10 @@ -{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %} -{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %} -{% import 'bpf/macros.jinja' as MACROS %} - -{{ MACROS.remove_comments(BPFMERGED, 'pcap') }} - -{% set PCAPBPF = BPFMERGED.pcap %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% if GLOBALS.pcap_engine == "TRANSITION" %} +{% set PCAPBPF = ["ip and host 255.255.255.1 and port 1"] %} +{% else %} +{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %} +{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %} +{% import 'bpf/macros.jinja' as MACROS %} +{{ MACROS.remove_comments(BPFMERGED, 'pcap') }} +{% set PCAPBPF = BPFMERGED.pcap %} +{% endif %} diff --git a/salt/bpf/soc_bpf.yaml b/salt/bpf/soc_bpf.yaml index 379eaa022..d93ec98fd 100644 --- a/salt/bpf/soc_bpf.yaml +++ b/salt/bpf/soc_bpf.yaml @@ -1,6 +1,6 @@ bpf: pcap: - description: List of BPF filters to apply to PCAP. + description: List of BPF filters to apply to Stenographer. multiline: True forcedType: "[]string" helpLink: bpf.html diff --git a/salt/ca/files/signing_policies.conf b/salt/ca/files/signing_policies.conf index cb57cc640..4fc04aacc 100644 --- a/salt/ca/files/signing_policies.conf +++ b/salt/ca/files/signing_policies.conf @@ -1,6 +1,3 @@ -mine_functions: - x509.get_pem_entries: [/etc/pki/ca.crt] - x509_signing_policies: filebeat: - minions: '*' @@ -37,7 +34,7 @@ x509_signing_policies: - ST: Utah - L: Salt Lake City - basicConstraints: "critical CA:false" - - keyUsage: "critical keyEncipherment" + - keyUsage: "critical keyEncipherment digitalSignature" - subjectKeyIdentifier: hash - authorityKeyIdentifier: keyid,issuer:always - extendedKeyUsage: serverAuth @@ -70,3 +67,17 @@ x509_signing_policies: - authorityKeyIdentifier: keyid,issuer:always - days_valid: 820 - copypath: /etc/pki/issued_certs/ + kafka: + - minions: '*' + - signing_private_key: /etc/pki/ca.key + - signing_cert: /etc/pki/ca.crt + - C: US + - ST: Utah + - L: Salt Lake City + - basicConstraints: "critical CA:false" + - keyUsage: "digitalSignature, keyEncipherment" + - subjectKeyIdentifier: hash + - authorityKeyIdentifier: keyid,issuer:always + - extendedKeyUsage: "serverAuth, clientAuth" + - days_valid: 820 + - copypath: /etc/pki/issued_certs/ diff --git a/salt/common/init.sls b/salt/common/init.sls index 8c0089fc0..7137ff11f 100644 --- a/salt/common/init.sls +++ b/salt/common/init.sls @@ -4,7 +4,6 @@ {% from 'vars/globals.map.jinja' import GLOBALS %} include: - - common.soup_scripts - common.packages {% if GLOBALS.role in GLOBALS.manager_roles %} - manager.elasticsearch # needed for elastic_curl_config state @@ -15,6 +14,11 @@ net.core.wmem_default: sysctl.present: - value: 26214400 +# Users are not a fan of console messages +kernel.printk: + sysctl.present: + - value: "3 4 1 3" + # Remove variables.txt from /tmp - This is temp rmvariablesfile: file.absent: @@ -102,7 +106,7 @@ Etc/UTC: timezone.system # Sync curl configuration for Elasticsearch authentication -{% if GLOBALS.role in ['so-eval', 'so-heavynode', 'so-import', 'so-manager', 'so-managersearch', 'so-searchnode', 'so-standalone'] %} +{% if GLOBALS.is_manager or GLOBALS.role in ['so-heavynode', 'so-searchnode'] %} elastic_curl_config: file.managed: - name: /opt/so/conf/elasticsearch/curl.config @@ -124,6 +128,11 @@ common_sbin: - user: 939 - group: 939 - file_mode: 755 + - show_changes: False +{% if GLOBALS.role == 'so-heavynode' %} + - exclude_pat: + - so-pcap-import +{% endif %} common_sbin_jinja: file.recurse: @@ -133,6 +142,33 @@ common_sbin_jinja: - group: 939 - file_mode: 755 - template: jinja + - show_changes: False +{% if GLOBALS.role == 'so-heavynode' %} + - exclude_pat: + - so-import-pcap +{% endif %} + +{% if GLOBALS.role == 'so-heavynode' %} +remove_so-pcap-import_heavynode: + file.absent: + - name: /usr/sbin/so-pcap-import + +remove_so-import-pcap_heavynode: + file.absent: + - name: /usr/sbin/so-import-pcap +{% endif %} + +{% if not GLOBALS.is_manager%} +# prior to 2.4.50 these scripts were in common/tools/sbin on the manager because of soup and distributed to non managers +# these two states remove the scripts from non manager nodes +remove_soup: + file.absent: + - name: /usr/sbin/soup + +remove_so-firewall: + file.absent: + - name: /usr/sbin/so-firewall +{% endif %} so-status_script: file.managed: @@ -166,6 +202,7 @@ sostatus_log: file.managed: - name: /opt/so/log/sostatus/status.log - mode: 644 + - replace: False # Install sostatus check cron. This is used to populate Grid. so-status_check_cron: @@ -179,6 +216,14 @@ so-status_check_cron: - month: '*' - dayweek: '*' +# This cronjob/script runs a check if the node needs restarted, but should be used for future status checks as well +common_status_check_cron: + cron.present: + - name: '/usr/sbin/so-common-status-check > /dev/null 2>&1' + - identifier: common_status_check + - user: root + - minute: '*/10' + remove_post_setup_cron: cron.absent: - name: 'PATH=$PATH:/usr/sbin salt-call state.highstate' diff --git a/salt/common/packages.sls b/salt/common/packages.sls index c5d2729fd..cd8af4bb0 100644 --- a/salt/common/packages.sls +++ b/salt/common/packages.sls @@ -1,6 +1,6 @@ -{% from 'vars/globals.map.jinja' import GLOBALS %} - -{% if GLOBALS.os_family == 'Debian' %} +# we cannot import GLOBALS from vars/globals.map.jinja in this state since it is called in setup.virt.init +# since it is early in setup of a new VM, the pillars imported in GLOBALS are not yet defined +{% if grains.os_family == 'Debian' %} commonpkgs: pkg.installed: - skip_suggestions: True @@ -27,6 +27,7 @@ commonpkgs: - vim - tar - unzip + - bc {% if grains.oscodename != 'focal' %} - python3-rich {% endif %} @@ -45,7 +46,7 @@ python-rich: {% endif %} {% endif %} -{% if GLOBALS.os_family == 'RedHat' %} +{% if grains.os_family == 'RedHat' %} remove_mariadb: pkg.removed: @@ -56,6 +57,7 @@ commonpkgs: - skip_suggestions: True - pkgs: - python3-dnf-plugin-versionlock + - bc - curl - device-mapper-persistent-data - fuse diff --git a/salt/common/soup_scripts.sls b/salt/common/soup_scripts.sls index 041649200..24e6c6152 100644 --- a/salt/common/soup_scripts.sls +++ b/salt/common/soup_scripts.sls @@ -1,23 +1,142 @@ -# Sync some Utilities -soup_scripts: - file.recurse: - - name: /usr/sbin - - user: root - - group: root - - file_mode: 755 - - source: salt://common/tools/sbin - - include_pat: - - so-common - - so-image-common +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. -soup_manager_scripts: - file.recurse: - - name: /usr/sbin - - user: root - - group: root - - file_mode: 755 - - source: salt://manager/tools/sbin - - include_pat: - - so-firewall - - so-repo-sync - - soup +{% if '2.4' in salt['cp.get_file_str']('/etc/soversion') %} + +{% import_yaml '/opt/so/saltstack/local/pillar/global/soc_global.sls' as SOC_GLOBAL %} +{% if SOC_GLOBAL.global.airgap %} +{% set UPDATE_DIR='/tmp/soagupdate/SecurityOnion' %} +{% else %} +{% set UPDATE_DIR='/tmp/sogh/securityonion' %} +{% endif %} +{% set SOVERSION = salt['file.read']('/etc/soversion').strip() %} + +remove_common_soup: + file.absent: + - name: /opt/so/saltstack/default/salt/common/tools/sbin/soup + +remove_common_so-firewall: + file.absent: + - name: /opt/so/saltstack/default/salt/common/tools/sbin/so-firewall + +# This section is used to put the scripts in place in the Salt file system +# in case a state run tries to overwrite what we do in the next section. +copy_so-common_common_tools_sbin: + file.copy: + - name: /opt/so/saltstack/default/salt/common/tools/sbin/so-common + - source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-common + - force: True + - preserve: True + +copy_so-image-common_common_tools_sbin: + file.copy: + - name: /opt/so/saltstack/default/salt/common/tools/sbin/so-image-common + - source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-image-common + - force: True + - preserve: True + +copy_soup_manager_tools_sbin: + file.copy: + - name: /opt/so/saltstack/default/salt/manager/tools/sbin/soup + - source: {{UPDATE_DIR}}/salt/manager/tools/sbin/soup + - force: True + - preserve: True + +copy_so-firewall_manager_tools_sbin: + file.copy: + - name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-firewall + - source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-firewall + - force: True + - preserve: True + +copy_so-yaml_manager_tools_sbin: + file.copy: + - name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-yaml.py + - source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-yaml.py + - force: True + - preserve: True + +copy_so-repo-sync_manager_tools_sbin: + file.copy: + - name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-repo-sync + - source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-repo-sync + - preserve: True + +copy_bootstrap-salt_manager_tools_sbin: + file.copy: + - name: /opt/so/saltstack/default/salt/salt/scripts/bootstrap-salt.sh + - source: {{UPDATE_DIR}}/salt/salt/scripts/bootstrap-salt.sh + - preserve: True + +# This section is used to put the new script in place so that it can be called during soup. +# It is faster than calling the states that normally manage them to put them in place. +copy_so-common_sbin: + file.copy: + - name: /usr/sbin/so-common + - source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-common + - force: True + - preserve: True + +copy_so-image-common_sbin: + file.copy: + - name: /usr/sbin/so-image-common + - source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-image-common + - force: True + - preserve: True + +copy_soup_sbin: + file.copy: + - name: /usr/sbin/soup + - source: {{UPDATE_DIR}}/salt/manager/tools/sbin/soup + - force: True + - preserve: True + +copy_so-firewall_sbin: + file.copy: + - name: /usr/sbin/so-firewall + - source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-firewall + - force: True + - preserve: True + +copy_so-yaml_sbin: + file.copy: + - name: /usr/sbin/so-yaml.py + - source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-yaml.py + - force: True + - preserve: True + +copy_so-repo-sync_sbin: + file.copy: + - name: /usr/sbin/so-repo-sync + - source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-repo-sync + - force: True + - preserve: True + +copy_bootstrap-salt_sbin: + file.copy: + - name: /usr/sbin/bootstrap-salt.sh + - source: {{UPDATE_DIR}}/salt/salt/scripts/bootstrap-salt.sh + - force: True + - preserve: True + +{# this is added in 2.4.120 to remove salt repo files pointing to saltproject.io to accomodate the move to broadcom and new bootstrap-salt script #} +{% if salt['pkg.version_cmp'](SOVERSION, '2.4.120') == -1 %} +{% set saltrepofile = '/etc/yum.repos.d/salt.repo' %} +{% if grains.os_family == 'Debian' %} +{% set saltrepofile = '/etc/apt/sources.list.d/salt.list' %} +{% endif %} +remove_saltproject_io_repo_manager: + file.absent: + - name: {{ saltrepofile }} +{% endif %} + +{% else %} +fix_23_soup_sbin: + cmd.run: + - name: curl -s -f -o /usr/sbin/soup https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.3/main/salt/common/tools/sbin/soup +fix_23_soup_salt: + cmd.run: + - name: curl -s -f -o /opt/so/saltstack/defalt/salt/common/tools/sbin/soup https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.3/main/salt/common/tools/sbin/soup +{% endif %} diff --git a/salt/common/tools/sbin/so-checkin b/salt/common/tools/sbin/so-checkin index db35af410..13ea9acd9 100755 --- a/salt/common/tools/sbin/so-checkin +++ b/salt/common/tools/sbin/so-checkin @@ -5,8 +5,13 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. - - . /usr/sbin/so-common -salt-call state.highstate -l info +cat << EOF + +so-checkin will run a full salt highstate to apply all salt states. If a highstate is already running, this request will be queued and so it may pause for a few minutes before you see any more output. For more information about so-checkin and salt, please see: +https://docs.securityonion.net/en/2.4/salt.html + +EOF + +salt-call state.highstate -l info queue=True diff --git a/salt/common/tools/sbin/so-common b/salt/common/tools/sbin/so-common index e09d2c8ae..203b54cd0 100755 --- a/salt/common/tools/sbin/so-common +++ b/salt/common/tools/sbin/so-common @@ -8,12 +8,6 @@ # Elastic agent is not managed by salt. Because of this we must store this base information in a # script that accompanies the soup system. Since so-common is one of those special soup files, # and since this same logic is required during installation, it's included in this file. -ELASTIC_AGENT_TARBALL_VERSION="8.10.4" -ELASTIC_AGENT_URL="https://repo.securityonion.net/file/so-repo/prod/2.4/elasticagent/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz" -ELASTIC_AGENT_MD5_URL="https://repo.securityonion.net/file/so-repo/prod/2.4/elasticagent/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.md5" -ELASTIC_AGENT_FILE="/nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz" -ELASTIC_AGENT_MD5="/nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.md5" -ELASTIC_AGENT_EXPANSION_DIR=/nsm/elastic-fleet/artifacts/beats/elastic-agent DEFAULT_SALT_DIR=/opt/so/saltstack/default DOC_BASE_URL="https://docs.securityonion.net/en/2.4" @@ -31,6 +25,11 @@ if ! echo "$PATH" | grep -q "/usr/sbin"; then export PATH="$PATH:/usr/sbin" fi +# See if a proxy is set. If so use it. +if [ -f /etc/profile.d/so-proxy.sh ]; then + . /etc/profile.d/so-proxy.sh +fi + # Define a banner to separate sections banner="=========================================================================" @@ -100,6 +99,17 @@ add_interface_bond0() { fi } +airgap_playbooks() { + SRC_DIR=$1 + # Copy playbooks if using airgap + mkdir -p /nsm/airgap-resources + # Purge old airgap playbooks to ensure SO only uses the latest released playbooks + rm -fr /nsm/airgap-resources/playbooks + tar xf $SRC_DIR/airgap-resources/playbooks.tgz -C /nsm/airgap-resources/ + chown -R socore:socore /nsm/airgap-resources/playbooks + git config --global --add safe.directory /nsm/airgap-resources/playbooks +} + check_container() { docker ps | grep "$1:" > /dev/null 2>&1 return $? @@ -169,6 +179,46 @@ check_salt_minion_status() { return $status } +# Compare es versions and return the highest version +compare_es_versions() { + # Save the original IFS + local OLD_IFS="$IFS" + + IFS=. + local i ver1=($1) ver2=($2) + + # Restore the original IFS + IFS="$OLD_IFS" + + # Determine the maximum length between the two version arrays + local max_len=${#ver1[@]} + if [[ ${#ver2[@]} -gt $max_len ]]; then + max_len=${#ver2[@]} + fi + + # Compare each segment of the versions + for ((i=0; i 10#${ver2[i]})); then + echo "$1" + return 0 + fi + if ((10#${ver1[i]} < 10#${ver2[i]})); then + echo "$2" + return 0 + fi + done + + echo "$1" # If versions are equal, return either + return 0 +} + copy_new_files() { # Copy new files over to the salt dir cd $UPDATE_DIR @@ -179,6 +229,21 @@ copy_new_files() { cd /tmp } +create_local_directories() { + echo "Creating local pillar and salt directories if needed" + PILLARSALTDIR=$1 + local_salt_dir="/opt/so/saltstack/local" + for i in "pillar" "salt"; do + for d in $(find $PILLARSALTDIR/$i -type d); do + suffixdir=${d//$PILLARSALTDIR/} + if [ ! -d "$local_salt_dir/$suffixdir" ]; then + mkdir -p $local_salt_dir$suffixdir + fi + done + chown -R socore:socore $local_salt_dir/$i + done +} + disable_fastestmirror() { sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf } @@ -243,6 +308,31 @@ fail() { exit 1 } +get_agent_count() { + if [ -f /opt/so/log/agents/agentstatus.log ]; then + AGENTCOUNT=$(cat /opt/so/log/agents/agentstatus.log | grep -wF active | awk '{print $2}' | sed 's/,//') + [[ -z "$AGENTCOUNT" ]] && AGENTCOUNT="0" + else + AGENTCOUNT=0 + fi +} + +get_elastic_agent_vars() { + local path="${1:-/opt/so/saltstack/default}" + local defaultsfile="${path}/salt/elasticsearch/defaults.yaml" + + if [ -f "$defaultsfile" ]; then + ELASTIC_AGENT_TARBALL_VERSION=$(egrep " +version: " $defaultsfile | awk -F: '{print $2}' | tr -d '[:space:]') + ELASTIC_AGENT_URL="https://repo.securityonion.net/file/so-repo/prod/2.4/elasticagent/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz" + ELASTIC_AGENT_MD5_URL="https://repo.securityonion.net/file/so-repo/prod/2.4/elasticagent/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.md5" + ELASTIC_AGENT_FILE="/nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz" + ELASTIC_AGENT_MD5="/nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.md5" + ELASTIC_AGENT_EXPANSION_DIR=/nsm/elastic-fleet/artifacts/beats/elastic-agent + else + fail "Could not find salt/elasticsearch/defaults.yaml" + fi +} + get_random_value() { length=${1:-20} head -c 5000 /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $length | head -n 1 @@ -329,7 +419,7 @@ lookup_salt_value() { local="" fi - salt-call --no-color ${kind}.get ${group}${key} --out=${output} ${local} + salt-call -lerror --no-color ${kind}.get ${group}${key} --out=${output} ${local} } lookup_pillar() { @@ -366,6 +456,13 @@ is_feature_enabled() { return 1 } +read_feat() { + if [ -f /opt/so/log/sostatus/lks_enabled ]; then + lic_id=$(cat /opt/so/saltstack/local/pillar/soc/license.sls | grep license_id: | awk '{print $2}') + echo "$lic_id/$(cat /opt/so/log/sostatus/lks_enabled)/$(cat /opt/so/log/sostatus/fps_enabled)" + fi +} + require_manager() { if is_manager_node; then echo "This is a manager, so we can proceed." @@ -559,6 +656,15 @@ status () { printf "\n=========================================================================\n$(date) | $1\n=========================================================================\n" } +sync_options() { + set_version + set_os + salt_minion_count + get_agent_count + + echo "$VERSION/$OS/$(uname -r)/$MINIONCOUNT:$AGENTCOUNT/$(read_feat)" +} + systemctl_func() { local action=$1 local echo_action=$1 @@ -583,6 +689,8 @@ has_uppercase() { } update_elastic_agent() { + local path="${1:-/opt/so/saltstack/default}" + get_elastic_agent_vars "$path" echo "Checking if Elastic Agent update is necessary..." download_and_verify "$ELASTIC_AGENT_URL" "$ELASTIC_AGENT_MD5_URL" "$ELASTIC_AGENT_FILE" "$ELASTIC_AGENT_MD5" "$ELASTIC_AGENT_EXPANSION_DIR" } diff --git a/salt/common/tools/sbin/so-common-status-check b/salt/common/tools/sbin/so-common-status-check new file mode 100644 index 000000000..cbef7309e --- /dev/null +++ b/salt/common/tools/sbin/so-common-status-check @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +import sys +import subprocess +import os +import json + +sys.path.append('/opt/saltstack/salt/lib/python3.10/site-packages/') +import salt.config +import salt.loader + +__opts__ = salt.config.minion_config('/etc/salt/minion') +__grains__ = salt.loader.grains(__opts__) + +def check_needs_restarted(): + osfam = __grains__['os_family'] + val = '0' + outfile = "/opt/so/log/sostatus/needs_restarted" + + if osfam == 'Debian': + if os.path.exists('/var/run/reboot-required'): + val = '1' + elif osfam == 'RedHat': + cmd = 'needs-restarting -r > /dev/null 2>&1' + try: + needs_restarting = subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError: + val = '1' + else: + fail("Unsupported OS") + + with open(outfile, 'w') as f: + f.write(val) + +def check_for_fps(): + feat = 'fps' + feat_full = feat.replace('ps', 'ips') + fps = 0 + try: + result = subprocess.run([feat_full + '-mode-setup', '--is-enabled'], stdout=subprocess.PIPE) + if result.returncode == 0: + fps = 1 + except: + fn = '/proc/sys/crypto/' + feat_full + '_enabled' + try: + with open(fn, 'r') as f: + contents = f.read() + if '1' in contents: + fps = 1 + except: + # Unknown, so assume 0 + fps = 0 + + with open('/opt/so/log/sostatus/fps_enabled', 'w') as f: + f.write(str(fps)) + +def check_for_lks(): + feat = 'Lks' + feat_full = feat.replace('ks', 'uks') + lks = 0 + result = subprocess.run(['lsblk', '-p', '-J'], check=True, stdout=subprocess.PIPE) + data = json.loads(result.stdout) + for device in data['blockdevices']: + if 'children' in device: + for gc in device['children']: + if 'children' in gc: + try: + arg = 'is' + feat_full + result = subprocess.run(['cryptsetup', arg, gc['name']], stdout=subprocess.PIPE) + if result.returncode == 0: + lks = 1 + except FileNotFoundError: + for ggc in gc['children']: + if 'crypt' in ggc['type']: + lks = 1 + if lks: + break + with open('/opt/so/log/sostatus/lks_enabled', 'w') as f: + f.write(str(lks)) + +def fail(msg): + print(msg, file=sys.stderr) + sys.exit(1) + +def main(): + proc = subprocess.run(['id', '-u'], stdout=subprocess.PIPE, encoding="utf-8") + if proc.stdout.strip() != "0": + fail("This program must be run as root") + # Ensure that umask is 0022 so that files created by this script have rw-r-r permissions + org_umask = os.umask(0o022) + check_needs_restarted() + check_for_fps() + check_for_lks() + # Restore umask to whatever value was set before this script was run. SXIG sets to 0077 rw--- + os.umask(org_umask) + +if __name__ == "__main__": + main() diff --git a/salt/common/tools/sbin/so-docker-prune b/salt/common/tools/sbin/so-docker-prune index 224cbd222..156c3b002 100755 --- a/salt/common/tools/sbin/so-docker-prune +++ b/salt/common/tools/sbin/so-docker-prune @@ -4,22 +4,16 @@ # or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. - - - -import sys, argparse, re, docker +import sys, argparse, re, subprocess, json from packaging.version import Version, InvalidVersion from itertools import groupby, chain - def get_image_name(string) -> str: return ':'.join(string.split(':')[:-1]) - def get_so_image_basename(string) -> str: return get_image_name(string).split('/so-')[-1] - def get_image_version(string) -> str: ver = string.split(':')[-1] if ver == 'latest': @@ -35,56 +29,75 @@ def get_image_version(string) -> str: return '999999.9.9' return ver +def run_command(command): + process = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + if process.returncode != 0: + print(f"Error executing command: {command}", file=sys.stderr) + print(f"Error message: {process.stderr}", file=sys.stderr) + exit(1) + return process.stdout def main(quiet): - client = docker.from_env() - - # Prune old/stopped containers - if not quiet: print('Pruning old containers') - client.containers.prune() - - image_list = client.images.list(filters={ 'dangling': False }) - - # Map list of image objects to flattened list of tags (format: "name:version") - tag_list = list(chain.from_iterable(list(map(lambda x: x.attrs.get('RepoTags'), image_list)))) - - # Filter to only SO images (base name begins with "so-") - tag_list = list(filter(lambda x: re.match(r'^.*\/so-[^\/]*$', get_image_name(x)), tag_list)) - - # Group tags into lists by base name (sort by same projection first) - tag_list.sort(key=lambda x: get_so_image_basename(x)) - grouped_tag_lists = [ list(it) for _, it in groupby(tag_list, lambda x: get_so_image_basename(x)) ] - - no_prunable = True - for t_list in grouped_tag_lists: try: - # Group tags by version, in case multiple images exist with the same version string - t_list.sort(key=lambda x: Version(get_image_version(x)), reverse=True) - grouped_t_list = [ list(it) for _,it in groupby(t_list, lambda x: get_image_version(x)) ] - - # Keep the 2 most current version groups - if len(grouped_t_list) <= 2: - continue - else: - no_prunable = False - for group in grouped_t_list[2:]: - for tag in group: - if not quiet: print(f'Removing image {tag}') + # Prune old/stopped containers using docker CLI + if not quiet: print('Pruning old containers') + run_command('docker container prune -f') + + # Get list of images using docker CLI + images_json = run_command('docker images --format "{{json .}}"') + + # Parse the JSON output + image_list = [] + for line in images_json.strip().split('\n'): + if line: # Skip empty lines + image_list.append(json.loads(line)) + + # Extract tags in the format "name:version" + tag_list = [] + for img in image_list: + # Skip dangling images + if img.get('Repository') != "" and img.get('Tag') != "": + tag = f"{img.get('Repository')}:{img.get('Tag')}" + # Filter to only SO images (base name begins with "so-") + if re.match(r'^.*\/so-[^\/]*$', get_image_name(tag)): + tag_list.append(tag) + + # Group tags into lists by base name (sort by same projection first) + tag_list.sort(key=lambda x: get_so_image_basename(x)) + grouped_tag_lists = [list(it) for k, it in groupby(tag_list, lambda x: get_so_image_basename(x))] + + no_prunable = True + for t_list in grouped_tag_lists: try: - client.images.remove(tag, force=True) - except docker.errors.ClientError as e: - print(f'Could not remove image {tag}, continuing...') - except (docker.errors.APIError, InvalidVersion) as e: - print(f'so-{get_so_image_basename(t_list[0])}: {e}', file=sys.stderr) - exit(1) + # Group tags by version, in case multiple images exist with the same version string + t_list.sort(key=lambda x: Version(get_image_version(x)), reverse=True) + grouped_t_list = [list(it) for k, it in groupby(t_list, lambda x: get_image_version(x))] + # Keep the 2 most current version groups + if len(grouped_t_list) <= 2: + continue + else: + no_prunable = False + for group in grouped_t_list[2:]: + for tag in group: + if not quiet: print(f'Removing image {tag}') + try: + run_command(f'docker rmi -f {tag}') + except Exception as e: + print(f'Could not remove image {tag}, continuing...') + except (InvalidVersion) as e: + print(f'so-{get_so_image_basename(t_list[0])}: {e}', file=sys.stderr) + exit(1) + except Exception as e: + print('Unhandled exception occurred:') + print(f'so-{get_so_image_basename(t_list[0])}: {e}', file=sys.stderr) + exit(1) + + if no_prunable and not quiet: + print('No Security Onion images to prune') + except Exception as e: - print('Unhandled exception occurred:') - print(f'so-{get_so_image_basename(t_list[0])}: {e}', file=sys.stderr) - exit(1) - - if no_prunable and not quiet: - print('No Security Onion images to prune') - + print(f"Error: {e}", file=sys.stderr) + exit(1) if __name__ == "__main__": main_parser = argparse.ArgumentParser(add_help=False) diff --git a/salt/common/tools/sbin/so-image-common b/salt/common/tools/sbin/so-image-common index 7e510e3ad..7fd35d5ac 100755 --- a/salt/common/tools/sbin/so-image-common +++ b/salt/common/tools/sbin/so-image-common @@ -29,6 +29,7 @@ container_list() { "so-influxdb" "so-kibana" "so-kratos" + "so-hydra" "so-nginx" "so-pcaptools" "so-soc" @@ -42,7 +43,6 @@ container_list() { ) elif [ $MANAGERCHECK != 'so-helix' ]; then TRUSTED_CONTAINERS=( - "so-curator" "so-elastalert" "so-elastic-agent" "so-elastic-agent-builder" @@ -51,16 +51,15 @@ container_list() { "so-idh" "so-idstools" "so-influxdb" + "so-kafka" "so-kibana" "so-kratos" + "so-hydra" "so-logstash" - "so-mysql" "so-nginx" "so-pcaptools" - "so-playbook" "so-redis" "so-soc" - "so-soctopus" "so-steno" "so-strelka-backend" "so-strelka-filestream" @@ -68,7 +67,7 @@ container_list() { "so-strelka-manager" "so-suricata" "so-telegraf" - "so-zeek" + "so-zeek" ) else TRUSTED_CONTAINERS=( @@ -115,6 +114,10 @@ update_docker_containers() { container_list fi + # all the images using ELASTICSEARCHDEFAULTS.elasticsearch.version + # does not include so-elastic-fleet since that container uses so-elastic-agent image + local IMAGES_USING_ES_VERSION=("so-elasticsearch") + rm -rf $SIGNPATH >> "$LOG_FILE" 2>&1 mkdir -p $SIGNPATH >> "$LOG_FILE" 2>&1 @@ -142,15 +145,36 @@ update_docker_containers() { $PROGRESS_CALLBACK $i fi + if [[ " ${IMAGES_USING_ES_VERSION[*]} " =~ [[:space:]]${i}[[:space:]] ]]; then + # this is an es container so use version defined in elasticsearch defaults.yaml + local UPDATE_DIR='/tmp/sogh/securityonion' + if [ ! -d "$UPDATE_DIR" ]; then + UPDATE_DIR=/securityonion + fi + local v1=0 + local v2=0 + if [[ -f "$UPDATE_DIR/salt/elasticsearch/defaults.yaml" ]]; then + v1=$(egrep " +version: " "$UPDATE_DIR/salt/elasticsearch/defaults.yaml" | awk -F: '{print $2}' | tr -d '[:space:]') + fi + if [[ -f "$DEFAULT_SALT_DIR/salt/elasticsearch/defaults.yaml" ]]; then + v2=$(egrep " +version: " "$DEFAULT_SALT_DIR/salt/elasticsearch/defaults.yaml" | awk -F: '{print $2}' | tr -d '[:space:]') + fi + local highest_es_version=$(compare_es_versions "$v1" "$v2") + local image=$i:$highest_es_version$IMAGE_TAG_SUFFIX + local sig_url=https://sigs.securityonion.net/es-$highest_es_version/$image.sig + else + # this is not an es container so use the so version for the version + local image=$i:$VERSION$IMAGE_TAG_SUFFIX + local sig_url=https://sigs.securityonion.net/$VERSION/$image.sig + fi # Pull down the trusted docker image - local image=$i:$VERSION$IMAGE_TAG_SUFFIX run_check_net_err \ "docker pull $CONTAINER_REGISTRY/$IMAGEREPO/$image" \ "Could not pull $image, please ensure connectivity to $CONTAINER_REGISTRY" >> "$LOG_FILE" 2>&1 # Get signature run_check_net_err \ - "curl --retry 5 --retry-delay 60 -A '$CURLTYPE/$CURRENTVERSION/$OS/$(uname -r)' https://sigs.securityonion.net/$VERSION/$i:$VERSION$IMAGE_TAG_SUFFIX.sig --output $SIGNPATH/$image.sig" \ + "curl --retry 5 --retry-delay 60 -A '$CURLTYPE/$CURRENTVERSION/$OS/$(uname -r)' $sig_url --output $SIGNPATH/$image.sig" \ "Could not pull signature file for $image, please ensure connectivity to https://sigs.securityonion.net " \ noretry >> "$LOG_FILE" 2>&1 # Dump our hash values diff --git a/salt/common/tools/sbin/so-ip-update b/salt/common/tools/sbin/so-ip-update index 7278afb94..6a330f644 100755 --- a/salt/common/tools/sbin/so-ip-update +++ b/salt/common/tools/sbin/so-ip-update @@ -49,10 +49,6 @@ if [ "$CONTINUE" == "y" ]; then sed -i "s|$OLD_IP|$NEW_IP|g" $file done - echo "Granting MySQL root user permissions on $NEW_IP" - docker exec -i so-mysql mysql --user=root --password=$(lookup_pillar_secret 'mysql') -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'$NEW_IP' IDENTIFIED BY '$(lookup_pillar_secret 'mysql')' WITH GRANT OPTION;" &> /dev/null - echo "Removing MySQL root user from $OLD_IP" - docker exec -i so-mysql mysql --user=root --password=$(lookup_pillar_secret 'mysql') -e "DROP USER 'root'@'$OLD_IP';" &> /dev/null echo "Updating Kibana dashboards" salt-call state.apply kibana.so_savedobjects_defaults -l info queue=True diff --git a/salt/common/tools/sbin/so-log-check b/salt/common/tools/sbin/so-log-check index d2582ff94..96881aa56 100755 --- a/salt/common/tools/sbin/so-log-check +++ b/salt/common/tools/sbin/so-log-check @@ -95,6 +95,8 @@ if [[ $EXCLUDE_STARTUP_ERRORS == 'Y' ]]; then EXCLUDED_ERRORS="$EXCLUDED_ERRORS|shutdown process" # server not yet ready (logstash waiting on elastic) EXCLUDED_ERRORS="$EXCLUDED_ERRORS|contain valid certificates" # server not yet ready (logstash waiting on elastic) EXCLUDED_ERRORS="$EXCLUDED_ERRORS|failedaction" # server not yet ready (logstash waiting on elastic) + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|block in start_workers" # server not yet ready (logstash waiting on elastic) + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|block in buffer_initialize" # server not yet ready (logstash waiting on elastic) EXCLUDED_ERRORS="$EXCLUDED_ERRORS|no route to host" # server not yet ready EXCLUDED_ERRORS="$EXCLUDED_ERRORS|not running" # server not yet ready EXCLUDED_ERRORS="$EXCLUDED_ERRORS|unavailable" # server not yet ready @@ -110,6 +112,7 @@ if [[ $EXCLUDE_STARTUP_ERRORS == 'Y' ]]; then EXCLUDED_ERRORS="$EXCLUDED_ERRORS|influxsize kbytes" # server not yet ready (telegraf waiting on influx) EXCLUDED_ERRORS="$EXCLUDED_ERRORS|expected field at" # server not yet ready (telegraf waiting on health data) EXCLUDED_ERRORS="$EXCLUDED_ERRORS|connection timed out" # server not yet ready (telegraf plugin unable to connect) + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|command timed out" # server not yet ready (telegraf plugin waiting for script to finish) EXCLUDED_ERRORS="$EXCLUDED_ERRORS|cached the public key" # server not yet ready (salt minion waiting on key acceptance) EXCLUDED_ERRORS="$EXCLUDED_ERRORS|no ingest nodes" # server not yet ready (logstash waiting on elastic) EXCLUDED_ERRORS="$EXCLUDED_ERRORS|failed to poll" # server not yet ready (sensoroni waiting on soc) @@ -120,6 +123,12 @@ if [[ $EXCLUDE_STARTUP_ERRORS == 'Y' ]]; then EXCLUDED_ERRORS="$EXCLUDED_ERRORS|timeout retrieving container" # Telegraf unable to reach Docker engine, rare EXCLUDED_ERRORS="$EXCLUDED_ERRORS|error while communicating" # Elasticsearch MS -> HN "sensor" temporarily unavailable EXCLUDED_ERRORS="$EXCLUDED_ERRORS|tls handshake error" # Docker registry container when new node comes onlines + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Unable to get license information" # Logstash trying to contact ES before it's ready + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|process already finished" # Telegraf script finished just as the auto kill timeout kicked in + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|No shard available" # Typical error when making a query before ES has finished loading all indices + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|responded with status-code 503" # telegraf getting 503 from ES during startup + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|process_cluster_event_timeout_exception" # logstash waiting for elasticsearch to start + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|not configured for GeoIP" # SO does not bundle the maxminddb with Zeek fi if [[ $EXCLUDE_FALSE_POSITIVE_ERRORS == 'Y' ]]; then @@ -144,6 +153,11 @@ if [[ $EXCLUDE_FALSE_POSITIVE_ERRORS == 'Y' ]]; then EXCLUDED_ERRORS="$EXCLUDED_ERRORS|status 200" # false positive (request successful, contained error string in content) EXCLUDED_ERRORS="$EXCLUDED_ERRORS|app_layer.error" # false positive (suricata 7) in stats.log e.g. app_layer.error.imap.parser | Total | 0 EXCLUDED_ERRORS="$EXCLUDED_ERRORS|is not an ip string literal" # false positive (Open Canary logging out blank IP addresses) + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|syncing rule" # false positive (rule sync log line includes rule name which can contain 'error') + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|request_unauthorized" # false positive (login failures to Hydra result in an 'error' log) + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|adding index lifecycle policy" # false positive (elasticsearch policy names contain 'error') + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|adding ingest pipeline" # false positive (elasticsearch ingest pipeline names contain 'error') + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|updating index template" # false positive (elasticsearch index or template names contain 'error') fi if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then @@ -152,15 +166,11 @@ if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then EXCLUDED_ERRORS="$EXCLUDED_ERRORS|fail\\(error\\)" # redis/python generic stack line, rely on other lines for actual error EXCLUDED_ERRORS="$EXCLUDED_ERRORS|urlerror" # idstools connection timeout EXCLUDED_ERRORS="$EXCLUDED_ERRORS|timeouterror" # idstools connection timeout - EXCLUDED_ERRORS="$EXCLUDED_ERRORS|forbidden" # playbook EXCLUDED_ERRORS="$EXCLUDED_ERRORS|_ml" # Elastic ML errors EXCLUDED_ERRORS="$EXCLUDED_ERRORS|context canceled" # elastic agent during shutdown - EXCLUDED_ERRORS="$EXCLUDED_ERRORS|exited with code 128" # soctopus errors during forced restart by highstate EXCLUDED_ERRORS="$EXCLUDED_ERRORS|geoip databases update" # airgap can't update GeoIP DB EXCLUDED_ERRORS="$EXCLUDED_ERRORS|filenotfounderror" # bug in 2.4.10 filecheck salt state caused duplicate cronjobs EXCLUDED_ERRORS="$EXCLUDED_ERRORS|salt-minion-check" # bug in early 2.4 place Jinja script in non-jinja salt dir causing cron output errors - EXCLUDED_ERRORS="$EXCLUDED_ERRORS|generating elastalert config" # playbook expected error - EXCLUDED_ERRORS="$EXCLUDED_ERRORS|activerecord" # playbook expected error EXCLUDED_ERRORS="$EXCLUDED_ERRORS|monitoring.metrics" # known issue with elastic agent casting the field incorrectly if an integer value shows up before a float EXCLUDED_ERRORS="$EXCLUDED_ERRORS|repodownload.conf" # known issue with reposync on pre-2.4.20 EXCLUDED_ERRORS="$EXCLUDED_ERRORS|missing versions record" # stenographer corrupt index @@ -168,6 +178,10 @@ if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then EXCLUDED_ERRORS="$EXCLUDED_ERRORS|error parsing signature" # Malformed Suricata rule, from upstream provider EXCLUDED_ERRORS="$EXCLUDED_ERRORS|sticky buffer has no matches" # Non-critical Suricata error EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Unable to determine destination index stats" # Elastic transform temporary error + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|cannot join on an empty table" # InfluxDB flux query, import nodes + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|exhausting result iterator" # InfluxDB flux query mismatched table results (temporary data issue) + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|failed to finish run" # InfluxDB rare error, self-recoverable + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Unable to gather disk name" # InfluxDB known error, can't read disks because the container doesn't have them mounted EXCLUDED_ERRORS="$EXCLUDED_ERRORS|iteration" EXCLUDED_ERRORS="$EXCLUDED_ERRORS|communication packets" EXCLUDED_ERRORS="$EXCLUDED_ERRORS|use of closed" @@ -196,7 +210,16 @@ if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then EXCLUDED_ERRORS="$EXCLUDED_ERRORS|req.LocalMeta.host.ip" # known issue in GH EXCLUDED_ERRORS="$EXCLUDED_ERRORS|sendmail" # zeek EXCLUDED_ERRORS="$EXCLUDED_ERRORS|stats.log" + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Unknown column" # Elastalert errors from running EQL queries + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|parsing_exception" # Elastalert EQL parsing issue. Temp. EXCLUDED_ERRORS="$EXCLUDED_ERRORS|context deadline exceeded" + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Error running query:" # Specific issues with detection rules + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|detect-parse" # Suricata encountering a malformed rule + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|integrity check failed" # Detections: Exclude false positive due to automated testing + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|syncErrors" # Detections: Not an actual error + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Initialized license manager" # SOC log: before fields.status was changed to fields.licenseStatus + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|from NIC checksum offloading" # zeek reporter.log + EXCLUDED_ERRORS="$EXCLUDED_ERRORS|marked for removal" # docker container getting recycled fi RESULT=0 @@ -205,7 +228,9 @@ RESULT=0 CONTAINER_IDS=$(docker ps -q) exclude_container so-kibana # kibana error logs are too verbose with large varieties of errors most of which are temporary exclude_container so-idstools # ignore due to known issues and noisy logging -exclude_container so-playbook # ignore due to several playbook known issues +exclude_container so-playbook # Playbook is removed as of 2.4.70, disregard output in stopped containers +exclude_container so-mysql # MySQL is removed as of 2.4.70, disregard output in stopped containers +exclude_container so-soctopus # Soctopus is removed as of 2.4.70, disregard output in stopped containers for container_id in $CONTAINER_IDS; do container_name=$(docker ps --format json | jq ". | select(.ID==\"$container_id\")|.Names") @@ -223,7 +248,18 @@ exclude_log "kibana.log" # kibana error logs are too verbose with large variet exclude_log "spool" # disregard zeek analyze logs as this is data specific exclude_log "import" # disregard imported test data the contains error strings exclude_log "update.log" # ignore playbook updates due to several known issues -exclude_log "playbook.log" # ignore due to several playbook known issues +exclude_log "cron-cluster-delete.log" # ignore since Curator has been removed +exclude_log "cron-close.log" # ignore since Curator has been removed +exclude_log "curator.log" # ignore since Curator has been removed +exclude_log "playbook.log" # Playbook is removed as of 2.4.70, logs may still be on disk +exclude_log "mysqld.log" # MySQL is removed as of 2.4.70, logs may still be on disk +exclude_log "soctopus.log" # Soctopus is removed as of 2.4.70, logs may still be on disk +exclude_log "agentstatus.log" # ignore this log since it tracks agents in error state +exclude_log "detections_runtime-status_yara.log" # temporarily ignore this log until Detections is more stable +exclude_log "/nsm/kafka/data/" # ignore Kafka data directory from log check. + +# Include Zeek reporter.log to detect errors after running known good pcap(s) through sensor +echo "/nsm/zeek/spool/logger/reporter.log" >> /tmp/log_check_files for log_file in $(cat /tmp/log_check_files); do status "Checking log file $log_file" diff --git a/salt/common/tools/sbin/so-luks-tpm-regen b/salt/common/tools/sbin/so-luks-tpm-regen new file mode 100644 index 000000000..50058b504 --- /dev/null +++ b/salt/common/tools/sbin/so-luks-tpm-regen @@ -0,0 +1,98 @@ +#!/bin/bash +# +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0." + +set -e +# This script is intended to be used in the case the ISO install did not properly setup TPM decrypt for LUKS partitions at boot. +if [ -z $NOROOT ]; then + # Check for prerequisites + if [ "$(id -u)" -ne 0 ]; then + echo "This script must be run using sudo!" + exit 1 + fi +fi +ENROLL_TPM=N + +while [[ $# -gt 0 ]]; do + case $1 in + --enroll-tpm) + ENROLL_TPM=Y + ;; + *) + echo "Usage: $0 [options]" + echo "" + echo "where options are:" + echo " --enroll-tpm for when TPM enrollment was not selected during ISO install." + echo "" + exit 1 + ;; + esac + shift +done + +check_for_tpm() { + echo -n "Checking for TPM: " + if [ -d /sys/class/tpm/tpm0 ]; then + echo -e "tpm0 found." + TPM="yes" + # Check if TPM is using sha1 or sha256 + if [ -d /sys/class/tpm/tpm0/pcr-sha1 ]; then + echo -e "TPM is using sha1.\n" + TPM_PCR="sha1" + elif [ -d /sys/class/tpm/tpm0/pcr-sha256 ]; then + echo -e "TPM is using sha256.\n" + TPM_PCR="sha256" + fi + else + echo -e "No TPM found.\n" + exit 1 + fi +} + +check_for_luks_partitions() { + echo "Checking for LUKS partitions" + for part in $(lsblk -o NAME,FSTYPE -ln | grep crypto_LUKS | awk '{print $1}'); do + echo "Found LUKS partition: $part" + LUKS_PARTITIONS+=("$part") + done + if [ ${#LUKS_PARTITIONS[@]} -eq 0 ]; then + echo -e "No LUKS partitions found.\n" + exit 1 + fi + echo "" +} + +enroll_tpm_in_luks() { + read -s -p "Enter the LUKS passphrase used during ISO install: " LUKS_PASSPHRASE + echo "" + for part in "${LUKS_PARTITIONS[@]}"; do + echo "Enrolling TPM for LUKS device: /dev/$part" + if [ "$TPM_PCR" == "sha1" ]; then + clevis luks bind -d /dev/$part tpm2 '{"pcr_bank":"sha1","pcr_ids":"7"}' <<< $LUKS_PASSPHRASE + elif [ "$TPM_PCR" == "sha256" ]; then + clevis luks bind -d /dev/$part tpm2 '{"pcr_bank":"sha256","pcr_ids":"7"}' <<< $LUKS_PASSPHRASE + fi + done + } + +regenerate_tpm_enrollment_token() { + for part in "${LUKS_PARTITIONS[@]}"; do + clevis luks regen -d /dev/$part -s 1 -q + done +} + +check_for_tpm +check_for_luks_partitions + +if [[ $ENROLL_TPM == "Y" ]]; then + enroll_tpm_in_luks +else + regenerate_tpm_enrollment_token +fi + +echo "Running dracut" +dracut -fv +echo -e "\nTPM configuration complete. Reboot the system to verify the TPM is correctly decrypting the LUKS partition(s) at boot.\n" \ No newline at end of file diff --git a/salt/common/tools/sbin/so-nsm-clear b/salt/common/tools/sbin/so-nsm-clear index 3d9596238..c9e5e86d2 100755 --- a/salt/common/tools/sbin/so-nsm-clear +++ b/salt/common/tools/sbin/so-nsm-clear @@ -41,8 +41,13 @@ done if [ $SKIP -ne 1 ]; then # Inform user we are about to delete all data echo - echo "This script will delete all NIDS data (PCAP, Suricata, Zeek)" - echo "If you would like to proceed, please type "AGREE" and hit ENTER." + echo "This script will delete all NSM data from /nsm." + echo + echo "This includes Suricata data, Zeek data, and full packet capture (PCAP)." + echo + echo "This will NOT delete any Suricata or Zeek logs that have already been ingested into Elasticsearch." + echo + echo "If you would like to proceed, then type AGREE and press ENTER." echo # Read user input read INPUT @@ -54,8 +59,8 @@ delete_pcap() { [ -d $PCAP_DATA ] && so-pcap-stop && rm -rf $PCAP_DATA/* && so-pcap-start } delete_suricata() { - SURI_LOG="/opt/so/log/suricata/eve.json" - [ -f $SURI_LOG ] && so-suricata-stop && rm -f $SURI_LOG && so-suricata-start + SURI_LOG="/nsm/suricata/" + [ -d $SURI_LOG ] && so-suricata-stop && rm -rf $SURI_LOG/* && so-suricata-start } delete_zeek() { ZEEK_LOG="/nsm/zeek/logs/" diff --git a/salt/common/tools/sbin/so_logging_utils.py b/salt/common/tools/sbin/so_logging_utils.py new file mode 100644 index 000000000..dae734ac6 --- /dev/null +++ b/salt/common/tools/sbin/so_logging_utils.py @@ -0,0 +1,53 @@ +#!/usr/bin/python3 + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +import logging +import os +import sys + +def setup_logging(logger_name, log_file_path, log_level=logging.INFO, format_str='%(asctime)s - %(levelname)s - %(message)s'): + """ + Sets up logging for a script. + + Parameters: + logger_name (str): The name of the logger. + log_file_path (str): The file path for the log file. + log_level (int): The logging level (e.g., logging.INFO, logging.DEBUG). + format_str (str): The format string for log messages. + + Returns: + logging.Logger: Configured logger object. + """ + logger = logging.getLogger(logger_name) + logger.setLevel(log_level) + + # Create directory for log file if it doesn't exist + log_file_dir = os.path.dirname(log_file_path) + if log_file_dir and not os.path.exists(log_file_dir): + try: + os.makedirs(log_file_dir) + except OSError as e: + print(f"Error creating directory {log_file_dir}: {e}") + sys.exit(1) + + # Create handlers + c_handler = logging.StreamHandler() + f_handler = logging.FileHandler(log_file_path) + c_handler.setLevel(log_level) + f_handler.setLevel(log_level) + + # Create formatter and add it to handlers + formatter = logging.Formatter(format_str) + c_handler.setFormatter(formatter) + f_handler.setFormatter(formatter) + + # Add handlers to the logger if they are not already added + if not logger.hasHandlers(): + logger.addHandler(c_handler) + logger.addHandler(f_handler) + + return logger diff --git a/salt/common/tools/sbin_jinja/so-import-pcap b/salt/common/tools/sbin_jinja/so-import-pcap index b8a90421f..5f2370a4a 100755 --- a/salt/common/tools/sbin_jinja/so-import-pcap +++ b/salt/common/tools/sbin_jinja/so-import-pcap @@ -63,7 +63,7 @@ function status { function pcapinfo() { PCAP=$1 ARGS=$2 - docker run --rm -v "$PCAP:/input.pcap" --entrypoint capinfos {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-pcaptools:{{ VERSION }} /input.pcap $ARGS + docker run --rm -v "$PCAP:/input.pcap" --entrypoint capinfos {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-pcaptools:{{ VERSION }} /input.pcap -ae $ARGS } function pcapfix() { @@ -89,6 +89,7 @@ function suricata() { -v ${LOG_PATH}:/var/log/suricata/:rw \ -v ${NSM_PATH}/:/nsm/:rw \ -v "$PCAP:/input.pcap:ro" \ + -v /dev/null:/nsm/suripcap:rw \ -v /opt/so/conf/suricata/bpf:/etc/suricata/bpf:ro \ {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-suricata:{{ VERSION }} \ --runmode single -k none -r /input.pcap > $LOG_PATH/console.log 2>&1 @@ -247,7 +248,7 @@ fi START_OLDEST_SLASH=$(echo $START_OLDEST | sed -e 's/-/%2F/g') END_NEWEST_SLASH=$(echo $END_NEWEST | sed -e 's/-/%2F/g') if [[ $VALID_PCAPS_COUNT -gt 0 ]] || [[ $SKIPPED_PCAPS_COUNT -gt 0 ]]; then - URL="https://{{ URLBASE }}/#/dashboards?q=$HASH_FILTERS%20%7C%20groupby%20-sankey%20event.dataset%20event.category%2a%20%7C%20groupby%20-pie%20event.category%20%7C%20groupby%20-bar%20event.module%20%7C%20groupby%20event.dataset%20%7C%20groupby%20event.module%20%7C%20groupby%20event.category%20%7C%20groupby%20observer.name%20%7C%20groupby%20source.ip%20%7C%20groupby%20destination.ip%20%7C%20groupby%20destination.port&t=${START_OLDEST_SLASH}%2000%3A00%3A00%20AM%20-%20${END_NEWEST_SLASH}%2000%3A00%3A00%20AM&z=UTC" + URL="https://{{ URLBASE }}/#/dashboards?q=$HASH_FILTERS%20%7C%20groupby%20event.module*%20%7C%20groupby%20-sankey%20event.module*%20event.dataset%20%7C%20groupby%20event.dataset%20%7C%20groupby%20source.ip%20%7C%20groupby%20destination.ip%20%7C%20groupby%20destination.port%20%7C%20groupby%20network.protocol%20%7C%20groupby%20rule.name%20rule.category%20event.severity_label%20%7C%20groupby%20dns.query.name%20%7C%20groupby%20file.mime_type%20%7C%20groupby%20http.virtual_host%20http.uri%20%7C%20groupby%20notice.note%20notice.message%20notice.sub_message%20%7C%20groupby%20ssl.server_name%20%7C%20groupby%20source_geo.organization_name%20source.geo.country_name%20%7C%20groupby%20destination_geo.organization_name%20destination.geo.country_name&t=${START_OLDEST_SLASH}%2000%3A00%3A00%20AM%20-%20${END_NEWEST_SLASH}%2000%3A00%3A00%20AM&z=UTC" status "Import complete!" status diff --git a/salt/common/tools/sbin_jinja/so-raid-status b/salt/common/tools/sbin_jinja/so-raid-status index 0249f4ccd..3fe238c23 100755 --- a/salt/common/tools/sbin_jinja/so-raid-status +++ b/salt/common/tools/sbin_jinja/so-raid-status @@ -9,6 +9,9 @@ . /usr/sbin/so-common +software_raid=("SOSMN" "SOSMN-DE02" "SOSSNNV" "SOSSNNV-DE02" "SOS10k-DE02" "SOS10KNV" "SOS10KNV-DE02" "SOS10KNV-DE02" "SOS2000-DE02" "SOS-GOFAST-LT-DE02" "SOS-GOFAST-MD-DE02" "SOS-GOFAST-HV-DE02") +hardware_raid=("SOS1000" "SOS1000F" "SOSSN7200" "SOS5000" "SOS4000") + {%- if salt['grains.get']('sosmodel', '') %} {%- set model = salt['grains.get']('sosmodel') %} model={{ model }} @@ -16,44 +19,70 @@ model={{ model }} if [[ $model =~ ^(SO2AMI01|SO2AZI01|SO2GCI01)$ ]]; then exit 0 fi + +for i in "${software_raid[@]}"; do + if [[ "$model" == $i ]]; then + is_softwareraid=true + is_hwraid=false + break + fi +done + +for i in "${hardware_raid[@]}"; do + if [[ "$model" == $i ]]; then + is_softwareraid=false + is_hwraid=true + break + fi +done + {%- else %} echo "This is not an appliance" exit 0 {%- endif %} -if [[ $model =~ ^(SOS10K|SOS500|SOS1000|SOS1000F|SOS4000|SOSSN7200|SOSSNNV|SOSMN)$ ]]; then - is_bossraid=true -fi -if [[ $model =~ ^(SOSSNNV|SOSMN)$ ]]; then - is_swraid=true -fi -if [[ $model =~ ^(SOS10K|SOS500|SOS1000|SOS1000F|SOS4000|SOSSN7200)$ ]]; then - is_hwraid=true -fi check_nsm_raid() { PERCCLI=$(/opt/raidtools/perccli/perccli64 /c0/v0 show|grep RAID|grep Optl) MEGACTL=$(/opt/raidtools/megasasctl |grep optimal) - - if [[ $APPLIANCE == '1' ]]; then + if [[ "$model" == "SOS500" || "$model" == "SOS500-DE02" ]]; then + #This doesn't have raid + HWRAID=0 + else if [[ -n $PERCCLI ]]; then HWRAID=0 elif [[ -n $MEGACTL ]]; then HWRAID=0 else HWRAID=1 - fi - + fi fi } check_boss_raid() { MVCLI=$(/usr/local/bin/mvcli info -o vd |grep status |grep functional) + MVTEST=$(/usr/local/bin/mvcli info -o vd | grep "No adapter") + BOSSNVMECLI=$(/usr/local/bin/mnv_cli info -o vd -i 0 | grep Functional) - if [[ -n $MVCLI ]]; then - BOSSRAID=0 + # Is this NVMe Boss Raid? + if [[ "$model" =~ "-DE02" ]]; then + if [[ -n $BOSSNVMECLI ]]; then + BOSSRAID=0 + else + BOSSRAID=1 + fi else - BOSSRAID=1 + # Check to see if this is a SM based system + if [[ -z $MVTEST ]]; then + if [[ -n $MVCLI ]]; then + BOSSRAID=0 + else + BOSSRAID=1 + fi + else + # This doesn't have boss raid so lets make it 0 + BOSSRAID=0 + fi fi } @@ -72,14 +101,13 @@ SWRAID=0 BOSSRAID=0 HWRAID=0 -if [[ $is_hwraid ]]; then +if [[ "$is_hwraid" == "true" ]]; then check_nsm_raid + check_boss_raid fi -if [[ $is_bossraid ]]; then - check_boss_raid -fi -if [[ $is_swraid ]]; then +if [[ "$is_softwareraid" == "true" ]]; then check_software_raid + check_boss_raid fi sum=$(($SWRAID + $BOSSRAID + $HWRAID)) @@ -90,4 +118,4 @@ else RAIDSTATUS=1 fi -echo "nsmraid=$RAIDSTATUS" > /opt/so/log/raid/status.log \ No newline at end of file +echo "nsmraid=$RAIDSTATUS" > /opt/so/log/raid/status.log diff --git a/salt/common/tools/sbin_jinja/so-salt-emit-vm-deployment-status-event b/salt/common/tools/sbin_jinja/so-salt-emit-vm-deployment-status-event new file mode 100644 index 000000000..fe51485e6 --- /dev/null +++ b/salt/common/tools/sbin_jinja/so-salt-emit-vm-deployment-status-event @@ -0,0 +1,132 @@ +#!/opt/saltstack/salt/bin/python3 + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. +# +# Note: Per the Elastic License 2.0, the second limitation states: +# +# "You may not move, change, disable, or circumvent the license key functionality +# in the software, and you may not remove or obscure any functionality in the +# software that is protected by the license key." + +{% if 'vrt' in salt['pillar.get']('features', []) -%} + +""" +Script for emitting VM deployment status events to the Salt event bus. + +This script provides functionality to emit status events for VM deployment operations, +used by various Security Onion VM management tools. + +Usage: + so-salt-emit-vm-deployment-status-event -v -H -s + +Arguments: + -v, --vm-name Name of the VM (hostname_role) + -H, --hypervisor Name of the hypervisor + -s, --status Current deployment status of the VM + +Example: + so-salt-emit-vm-deployment-status-event -v sensor1_sensor -H hypervisor1 -s "Creating" +""" + +import sys +import argparse +import logging +import salt.client +from typing import Dict, Any + +# Configure logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s' +) +log = logging.getLogger(__name__) + +def emit_event(vm_name: str, hypervisor: str, status: str) -> bool: + """ + Emit a VM deployment status event to the salt event bus. + + Args: + vm_name: Name of the VM (hostname_role) + hypervisor: Name of the hypervisor + status: Current deployment status of the VM + + Returns: + bool: True if event was sent successfully, False otherwise + + Raises: + ValueError: If status is not a valid deployment status + """ + log.info("Attempting to emit deployment event...") + + try: + caller = salt.client.Caller() + event_data = { + 'vm_name': vm_name, + 'hypervisor': hypervisor, + 'status': status + } + + # Use consistent event tag structure + event_tag = f'soc/dyanno/hypervisor/{status.lower()}' + + ret = caller.cmd( + 'event.send', + event_tag, + event_data + ) + + if not ret: + log.error("Failed to emit VM deployment status event: %s", event_data) + return False + + log.info("Successfully emitted VM deployment status event: %s", event_data) + return True + + except Exception as e: + log.error("Error emitting VM deployment status event: %s", str(e)) + return False + +def parse_args(): + """Parse command line arguments.""" + parser = argparse.ArgumentParser( + description='Emit VM deployment status events to the Salt event bus.' + ) + parser.add_argument('-v', '--vm-name', required=True, + help='Name of the VM (hostname_role)') + parser.add_argument('-H', '--hypervisor', required=True, + help='Name of the hypervisor') + parser.add_argument('-s', '--status', required=True, + help='Current deployment status of the VM') + return parser.parse_args() + +def main(): + """Main entry point for the script.""" + try: + args = parse_args() + + success = emit_event( + vm_name=args.vm_name, + hypervisor=args.hypervisor, + status=args.status + ) + + if not success: + sys.exit(1) + + except Exception as e: + log.error("Failed to emit status event: %s", str(e)) + sys.exit(1) + +if __name__ == '__main__': + main() + +{%- else -%} + +echo "Hypervisor nodes are a feature supported only for customers with a valid license. \ + Contact Security Onion Solutions, LLC via our website at https://securityonionsolutions.com \ + for more information about purchasing a license to enable this feature." + +{% endif -%} diff --git a/salt/common/tools/sbin/so-tcpreplay b/salt/common/tools/sbin_jinja/so-tcpreplay similarity index 96% rename from salt/common/tools/sbin/so-tcpreplay rename to salt/common/tools/sbin_jinja/so-tcpreplay index 99314c289..969ca699f 100755 --- a/salt/common/tools/sbin/so-tcpreplay +++ b/salt/common/tools/sbin_jinja/so-tcpreplay @@ -10,7 +10,7 @@ . /usr/sbin/so-common . /usr/sbin/so-image-common -REPLAYIFACE=${REPLAYIFACE:-$(lookup_pillar interface sensor)} +REPLAYIFACE=${REPLAYIFACE:-"{{salt['pillar.get']('sensor:interface', '')}}"} REPLAYSPEED=${REPLAYSPEED:-10} mkdir -p /opt/so/samples diff --git a/salt/curator/config.sls b/salt/curator/config.sls deleted file mode 100644 index 89ff53b2a..000000000 --- a/salt/curator/config.sls +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls.split('.')[0] in allowed_states %} -{% from "curator/map.jinja" import CURATORMERGED %} - -# Create the group -curatorgroup: - group.present: - - name: curator - - gid: 934 - -# Add user -curator: - user.present: - - uid: 934 - - gid: 934 - - home: /opt/so/conf/curator - - createhome: False - -# Create the log directory -curlogdir: - file.directory: - - name: /opt/so/log/curator - - user: 934 - - group: 939 - -curactiondir: - file.directory: - - name: /opt/so/conf/curator/action - - user: 934 - - group: 939 - - makedirs: True - -actionconfs: - file.recurse: - - name: /opt/so/conf/curator/action - - source: salt://curator/files/action - - user: 934 - - group: 939 - - template: jinja - - defaults: - CURATORMERGED: {{ CURATORMERGED.elasticsearch.index_settings }} - -curconf: - file.managed: - - name: /opt/so/conf/curator/curator.yml - - source: salt://curator/files/curator.yml - - user: 934 - - group: 939 - - mode: 660 - - template: jinja - - show_changes: False - -curator_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://curator/tools/sbin - - user: 934 - - group: 939 - - file_mode: 755 - -curator_sbin_jinja: - file.recurse: - - name: /usr/sbin - - source: salt://curator/tools/sbin_jinja - - user: 934 - - group: 939 - - file_mode: 755 - - template: jinja - -{% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - -{% endif %} diff --git a/salt/curator/defaults.yaml b/salt/curator/defaults.yaml deleted file mode 100644 index eb518264f..000000000 --- a/salt/curator/defaults.yaml +++ /dev/null @@ -1,100 +0,0 @@ -curator: - enabled: False - elasticsearch: - index_settings: - logs-import-so: - close: 73000 - delete: 73001 - logs-strelka-so: - close: 30 - delete: 365 - logs-suricata-so: - close: 30 - delete: 365 - logs-syslog-so: - close: 30 - delete: 365 - logs-zeek-so: - close: 30 - delete: 365 - logs-elastic_agent-metricbeat-default: - close: 30 - delete: 365 - logs-elastic_agent-osquerybeat-default: - close: 30 - delete: 365 - logs-elastic_agent-fleet_server-default: - close: 30 - delete: 365 - logs-elastic_agent-filebeat-default: - close: 30 - delete: 365 - logs-elastic_agent-default: - close: 30 - delete: 365 - logs-system-auth-default: - close: 30 - delete: 365 - logs-system-application-default: - close: 30 - delete: 365 - logs-system-security-default: - close: 30 - delete: 365 - logs-system-system-default: - close: 30 - delete: 365 - logs-system-syslog-default: - close: 30 - delete: 365 - logs-windows-powershell-default: - close: 30 - delete: 365 - logs-windows-sysmon_operational-default: - close: 30 - delete: 365 - so-beats: - close: 30 - delete: 365 - so-elasticsearch: - close: 30 - delete: 365 - so-firewall: - close: 30 - delete: 365 - so-ids: - close: 30 - delete: 365 - so-import: - close: 73000 - delete: 73001 - so-kratos: - close: 30 - delete: 365 - so-kibana: - close: 30 - delete: 365 - so-logstash: - close: 30 - delete: 365 - so-netflow: - close: 30 - delete: 365 - so-osquery: - close: 30 - delete: 365 - so-ossec: - close: 30 - delete: 365 - so-redis: - close: 30 - delete: 365 - so-strelka: - close: 30 - delete: 365 - so-syslog: - close: 30 - delete: 365 - so-zeek: - close: 30 - delete: 365 diff --git a/salt/curator/disabled.sls b/salt/curator/disabled.sls index acf9e3701..07346aa02 100644 --- a/salt/curator/disabled.sls +++ b/salt/curator/disabled.sls @@ -1,22 +1,17 @@ # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls.split('.')[0] in allowed_states %} - -include: - - curator.sostatus - so-curator: docker_container.absent: - force: True so-curator_so-status.disabled: - file.comment: + file.line: - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-curator$ + - match: ^so-curator$ + - mode: delete so-curator-cluster-close: cron.absent: @@ -26,10 +21,14 @@ so-curator-cluster-delete: cron.absent: - identifier: so-curator-cluster-delete -{% else %} +delete_curator_configuration: + file.absent: + - name: /opt/so/conf/curator + - recurse: True -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - -{% endif %} +{% set files = salt.file.find(path='/usr/sbin', name='so-curator*') %} +{% if files|length > 0 %} +delete_curator_scripts: + file.absent: + - names: {{files|yaml}} +{% endif %} \ No newline at end of file diff --git a/salt/curator/enabled.sls b/salt/curator/enabled.sls deleted file mode 100644 index b2574569f..000000000 --- a/salt/curator/enabled.sls +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls.split('.')[0] in allowed_states %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'docker/docker.map.jinja' import DOCKER %} - -include: - - curator.config - - curator.sostatus - -so-curator: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-curator:{{ GLOBALS.so_version }} - - start: True - - hostname: curator - - name: so-curator - - user: curator - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-curator'].ip }} - - interactive: True - - tty: True - - binds: - - /opt/so/conf/curator/curator.yml:/etc/curator/config/curator.yml:ro - - /opt/so/conf/curator/action/:/etc/curator/action:ro - - /opt/so/log/curator:/var/log/curator:rw - {% if DOCKER.containers['so-curator'].custom_bind_mounts %} - {% for BIND in DOCKER.containers['so-curator'].custom_bind_mounts %} - - {{ BIND }} - {% endfor %} - {% endif %} - {% if DOCKER.containers['so-curator'].extra_hosts %} - - extra_hosts: - {% for XTRAHOST in DOCKER.containers['so-curator'].extra_hosts %} - - {{ XTRAHOST }} - {% endfor %} - {% endif %} - {% if DOCKER.containers['so-curator'].extra_env %} - - environment: - {% for XTRAENV in DOCKER.containers['so-curator'].extra_env %} - - {{ XTRAENV }} - {% endfor %} - {% endif %} - - require: - - file: actionconfs - - file: curconf - - file: curlogdir - - watch: - - file: curconf - -delete_so-curator_so-status.disabled: - file.uncomment: - - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-curator$ - -so-curator-cluster-close: - cron.present: - - name: /usr/sbin/so-curator-cluster-close > /opt/so/log/curator/cron-close.log 2>&1 - - identifier: so-curator-cluster-close - - user: root - - minute: '2' - - hour: '*/1' - - daymonth: '*' - - month: '*' - - dayweek: '*' - -so-curator-cluster-delete: - cron.present: - - name: /usr/sbin/so-curator-cluster-delete > /opt/so/log/curator/cron-cluster-delete.log 2>&1 - - identifier: so-curator-cluster-delete - - user: root - - minute: '*/5' - - hour: '*' - - daymonth: '*' - - month: '*' - - dayweek: '*' - -{% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - -{% endif %} diff --git a/salt/curator/files/action/delete.yml b/salt/curator/files/action/delete.yml deleted file mode 100644 index c81a9e548..000000000 --- a/salt/curator/files/action/delete.yml +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{% import_yaml 'elasticsearch/defaults.yaml' as ELASTICDEFAULTS %} -{% set ELASTICMERGED = salt['pillar.get']('elasticsearch:retention', ELASTICDEFAULTS.elasticsearch.retention, merge=true) %} - -{{ ELASTICMERGED.retention_pct }} - -{%- set log_size_limit = salt['pillar.get']('elasticsearch:log_size_limit') %} -actions: - 1: - action: delete_indices - description: >- - Delete indices when {{log_size_limit}}(GB) is exceeded. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-.*|so-.*|.ds-logs-.*-so.*)$' - - filtertype: pattern - kind: regex - value: '^(so-case.*)$' - exclude: True - - filtertype: space - source: creation_date - use_age: True - disk_space: {{log_size_limit}} diff --git a/salt/curator/files/action/logs-elastic_agent-default-close.yaml b/salt/curator/files/action/logs-elastic_agent-default-close.yaml deleted file mode 100644 index 03c1ea81d..000000000 --- a/salt/curator/files/action/logs-elastic_agent-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-elastic_agent-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent default indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-elastic_agent-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-elastic_agent-default-delete.yaml b/salt/curator/files/action/logs-elastic_agent-default-delete.yaml deleted file mode 100644 index dee51c758..000000000 --- a/salt/curator/files/action/logs-elastic_agent-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-elastic_agent-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent default indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-elastic_agent-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-elastic_agent-filebeat-default-close.yaml b/salt/curator/files/action/logs-elastic_agent-filebeat-default-close.yaml deleted file mode 100644 index 2d7e897cf..000000000 --- a/salt/curator/files/action/logs-elastic_agent-filebeat-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-elastic_agent-filebeat-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent Filebeat indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-elastic_agent.filebeat-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-elastic_agent-filebeat-default-delete.yaml b/salt/curator/files/action/logs-elastic_agent-filebeat-default-delete.yaml deleted file mode 100644 index dfa51f260..000000000 --- a/salt/curator/files/action/logs-elastic_agent-filebeat-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-elastic_agent-filebeat-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent Filebeat indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-elastic_agent.filebeat-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-elastic_agent-fleet_server-default-close.yaml b/salt/curator/files/action/logs-elastic_agent-fleet_server-default-close.yaml deleted file mode 100644 index 0fd1d6129..000000000 --- a/salt/curator/files/action/logs-elastic_agent-fleet_server-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-elastic_agent-fleet_server-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent Fleet Server indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-elastic_agent.fleet_server-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-elastic_agent-fleet_server-default-delete.yaml b/salt/curator/files/action/logs-elastic_agent-fleet_server-default-delete.yaml deleted file mode 100644 index 6fa775ba8..000000000 --- a/salt/curator/files/action/logs-elastic_agent-fleet_server-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-elastic_agent-fleet_server-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete import indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-elastic_agent.fleet_server-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-elastic_agent-metricbeat-default-close.yaml b/salt/curator/files/action/logs-elastic_agent-metricbeat-default-close.yaml deleted file mode 100644 index cedf64eeb..000000000 --- a/salt/curator/files/action/logs-elastic_agent-metricbeat-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-elastic_agent-metricbeat-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent Metricbeat indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-elastic_agent.metricbeat-default-.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-elastic_agent-metricbeat-default-delete.yaml b/salt/curator/files/action/logs-elastic_agent-metricbeat-default-delete.yaml deleted file mode 100644 index c69e1130a..000000000 --- a/salt/curator/files/action/logs-elastic_agent-metricbeat-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-elastic_agent-metricbeat-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent Metricbeat indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-elastic_agent.metricbeat-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-elastic_agent-osquerybeat-default-close.yaml b/salt/curator/files/action/logs-elastic_agent-osquerybeat-default-close.yaml deleted file mode 100644 index e25b7f2b8..000000000 --- a/salt/curator/files/action/logs-elastic_agent-osquerybeat-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-elastic_agent-osquerybeat-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent Osquerybeat indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-elastic_agent.osquerybeat-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-elastic_agent-osquerybeat-default-delete.yaml b/salt/curator/files/action/logs-elastic_agent-osquerybeat-default-delete.yaml deleted file mode 100644 index bce3b7e63..000000000 --- a/salt/curator/files/action/logs-elastic_agent-osquerybeat-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-elastic_agent-osquerybeat-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent Osquerybeat indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-elastic_agent.osquerybeat-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-elastic_agent-osquerybeat-delete.yaml b/salt/curator/files/action/logs-elastic_agent-osquerybeat-delete.yaml deleted file mode 100644 index b46a5fc73..000000000 --- a/salt/curator/files/action/logs-elastic_agent-osquerybeat-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-import-so'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete import indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-import-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-import-so-close.yml b/salt/curator/files/action/logs-import-so-close.yml deleted file mode 100644 index e2d28fd06..000000000 --- a/salt/curator/files/action/logs-import-so-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-import-so'].close %} -actions: - 1: - action: close - description: >- - Close import indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-import-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-import-so-delete.yml b/salt/curator/files/action/logs-import-so-delete.yml deleted file mode 100644 index b46a5fc73..000000000 --- a/salt/curator/files/action/logs-import-so-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-import-so'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete import indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-import-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-strelka-so-close.yml b/salt/curator/files/action/logs-strelka-so-close.yml deleted file mode 100644 index c4b57995d..000000000 --- a/salt/curator/files/action/logs-strelka-so-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-strelka-so'].close %} -actions: - 1: - action: close - description: >- - Close Strelka indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-strelka-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-strelka-so-delete.yml b/salt/curator/files/action/logs-strelka-so-delete.yml deleted file mode 100644 index d01bdcc83..000000000 --- a/salt/curator/files/action/logs-strelka-so-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-strelka-so'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Strelka indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-strelka-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-suricata-so-close.yml b/salt/curator/files/action/logs-suricata-so-close.yml deleted file mode 100644 index c99a85285..000000000 --- a/salt/curator/files/action/logs-suricata-so-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-suricata-so'].close %} -actions: - 1: - action: close - description: >- - Close Suricata indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-suricata-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-suricata-so-delete.yml b/salt/curator/files/action/logs-suricata-so-delete.yml deleted file mode 100644 index 765ba1293..000000000 --- a/salt/curator/files/action/logs-suricata-so-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-suricata-so'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Suricata indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-suricata-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-syslog-so-close.yml b/salt/curator/files/action/logs-syslog-so-close.yml deleted file mode 100644 index 3ccf7834b..000000000 --- a/salt/curator/files/action/logs-syslog-so-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-syslog-so'].close %} -actions: - 1: - action: close - description: >- - Close syslog indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-syslog-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-syslog-so-delete.yml b/salt/curator/files/action/logs-syslog-so-delete.yml deleted file mode 100644 index 274d06711..000000000 --- a/salt/curator/files/action/logs-syslog-so-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-syslog-so'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete syslog indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-syslog-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-system-application-default-close.yaml b/salt/curator/files/action/logs-system-application-default-close.yaml deleted file mode 100644 index 4a04ebbb7..000000000 --- a/salt/curator/files/action/logs-system-application-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-system-application-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent system application indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-system.application-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-system-application-default-delete.yaml b/salt/curator/files/action/logs-system-application-default-delete.yaml deleted file mode 100644 index b15c06fcb..000000000 --- a/salt/curator/files/action/logs-system-application-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-system-application-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent system application indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-system.application-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-system-auth-default-close.yaml b/salt/curator/files/action/logs-system-auth-default-close.yaml deleted file mode 100644 index 287997e87..000000000 --- a/salt/curator/files/action/logs-system-auth-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-system-auth-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent system auth indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-system.auth-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-system-auth-default-delete.yaml b/salt/curator/files/action/logs-system-auth-default-delete.yaml deleted file mode 100644 index 9a1cc6a9a..000000000 --- a/salt/curator/files/action/logs-system-auth-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-system-auth-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent system auth indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-system.auth-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-system-security-default-close.yaml b/salt/curator/files/action/logs-system-security-default-close.yaml deleted file mode 100644 index 2506ca357..000000000 --- a/salt/curator/files/action/logs-system-security-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-system-security-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent system security indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-system.security-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-system-security-default-delete.yaml b/salt/curator/files/action/logs-system-security-default-delete.yaml deleted file mode 100644 index 0bac45aeb..000000000 --- a/salt/curator/files/action/logs-system-security-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-system-security-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent system security indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-system.security-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-system-syslog-default-close.yaml b/salt/curator/files/action/logs-system-syslog-default-close.yaml deleted file mode 100644 index 8da3afd45..000000000 --- a/salt/curator/files/action/logs-system-syslog-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-system-syslog-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent system syslog indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-system.syslog-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-system-syslog-default-delete.yaml b/salt/curator/files/action/logs-system-syslog-default-delete.yaml deleted file mode 100644 index 1a7d217e9..000000000 --- a/salt/curator/files/action/logs-system-syslog-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-system-syslog-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent system syslog indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-system.syslog-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-system-system-default-close.yaml b/salt/curator/files/action/logs-system-system-default-close.yaml deleted file mode 100644 index 401125e08..000000000 --- a/salt/curator/files/action/logs-system-system-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-system-system-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent system system indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-system.system-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-system-system-default-delete.yaml b/salt/curator/files/action/logs-system-system-default-delete.yaml deleted file mode 100644 index 4701d0492..000000000 --- a/salt/curator/files/action/logs-system-system-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-system-system-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent system system indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-system.system-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-windows-powershell-default-close.yaml b/salt/curator/files/action/logs-windows-powershell-default-close.yaml deleted file mode 100644 index 8f878f4c9..000000000 --- a/salt/curator/files/action/logs-windows-powershell-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-windows-powershell-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent Windows Powershell indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-windows.powershell-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-windows-powershell-default-delete.yaml b/salt/curator/files/action/logs-windows-powershell-default-delete.yaml deleted file mode 100644 index 447f8102b..000000000 --- a/salt/curator/files/action/logs-windows-powershell-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-windows-powershell-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent Windows Powershell indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-windows.powershell-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-windows-sysmon_operational-default-close.yaml b/salt/curator/files/action/logs-windows-sysmon_operational-default-close.yaml deleted file mode 100644 index 8cd9c99f3..000000000 --- a/salt/curator/files/action/logs-windows-sysmon_operational-default-close.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-windows-sysmon_operational-default'].close %} -actions: - 1: - action: close - description: >- - Close Elastic Agent Windows Sysmon operational indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-windows.sysmon_operational-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-windows-sysmon_operational-default-delete.yaml b/salt/curator/files/action/logs-windows-sysmon_operational-default-delete.yaml deleted file mode 100644 index a1413bc1c..000000000 --- a/salt/curator/files/action/logs-windows-sysmon_operational-default-delete.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-windows-sysmon_operational-default'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Elastic Agent Windows Sysmon operational indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-windows.sysmon_operational-default.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/logs-zeek-so-close.yml b/salt/curator/files/action/logs-zeek-so-close.yml deleted file mode 100644 index 020c89cbc..000000000 --- a/salt/curator/files/action/logs-zeek-so-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['logs-zeek-so'].close %} -actions: - 1: - action: close - description: >- - Close Zeek indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-zeek-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/logs-zeek-so-delete.yml b/salt/curator/files/action/logs-zeek-so-delete.yml deleted file mode 100644 index 5acfc50a7..000000000 --- a/salt/curator/files/action/logs-zeek-so-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['logs-zeek-so'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Zeek indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(.ds-logs-zeek-so.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/so-beats-close.yml b/salt/curator/files/action/so-beats-close.yml deleted file mode 100644 index 88c7ce91a..000000000 --- a/salt/curator/files/action/so-beats-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-beats'].close %} -actions: - 1: - action: close - description: >- - Close Beats indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-beats.*|so-beats.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-beats-delete.yml b/salt/curator/files/action/so-beats-delete.yml deleted file mode 100644 index c4e1f8b4e..000000000 --- a/salt/curator/files/action/so-beats-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-beats'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete beats indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-beats.*|so-beats.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-elasticsearch-close.yml b/salt/curator/files/action/so-elasticsearch-close.yml deleted file mode 100644 index e4d8824bd..000000000 --- a/salt/curator/files/action/so-elasticsearch-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-elasticsearch'].close %} -actions: - 1: - action: close - description: >- - Close elasticsearch indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-elasticsearch.*|so-elasticsearch.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-elasticsearch-delete.yml b/salt/curator/files/action/so-elasticsearch-delete.yml deleted file mode 100644 index 3c6bf4aac..000000000 --- a/salt/curator/files/action/so-elasticsearch-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-elasticsearch'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete elasticsearch indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-elasticsearch.*|so-elasticsearch.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-firewall-close.yml b/salt/curator/files/action/so-firewall-close.yml deleted file mode 100644 index 18d30737d..000000000 --- a/salt/curator/files/action/so-firewall-close.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - - -{%- set cur_close_days = CURATORMERGED['so-firewall'].close %} -actions: - 1: - action: close - description: >- - Close Firewall indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-firewall.*|so-firewall.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-firewall-delete.yml b/salt/curator/files/action/so-firewall-delete.yml deleted file mode 100644 index 5143e2fe9..000000000 --- a/salt/curator/files/action/so-firewall-delete.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - - -{%- set DELETE_DAYS = CURATORMERGED['so-firewall'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete firewall indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-firewall.*|so-firewall.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-ids-close.yml b/salt/curator/files/action/so-ids-close.yml deleted file mode 100644 index 359e0a4cc..000000000 --- a/salt/curator/files/action/so-ids-close.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - - -{%- set cur_close_days = CURATORMERGED['so-ids'].close %} -actions: - 1: - action: close - description: >- - Close IDS indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-ids.*|so-ids.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-ids-delete.yml b/salt/curator/files/action/so-ids-delete.yml deleted file mode 100644 index 6cf120fef..000000000 --- a/salt/curator/files/action/so-ids-delete.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - - -{%- set DELETE_DAYS = CURATORMERGED['so-ids'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete IDS indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-ids.*|so-ids.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-import-close.yml b/salt/curator/files/action/so-import-close.yml deleted file mode 100644 index 7a60b9343..000000000 --- a/salt/curator/files/action/so-import-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-import'].close %} -actions: - 1: - action: close - description: >- - Close Import indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-import.*|so-import.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-import-delete.yml b/salt/curator/files/action/so-import-delete.yml deleted file mode 100644 index 36e213b26..000000000 --- a/salt/curator/files/action/so-import-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-import'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete import indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-import.*|so-import.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-kibana-close.yml b/salt/curator/files/action/so-kibana-close.yml deleted file mode 100644 index 7c29ed294..000000000 --- a/salt/curator/files/action/so-kibana-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-kibana'].close %} -actions: - 1: - action: close - description: >- - Close kibana indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-kibana.*|so-kibana.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-kibana-delete.yml b/salt/curator/files/action/so-kibana-delete.yml deleted file mode 100644 index 971a178fe..000000000 --- a/salt/curator/files/action/so-kibana-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-kibana'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete kibana indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-kibana.*|so-kibana.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-kratos-close.yml b/salt/curator/files/action/so-kratos-close.yml deleted file mode 100644 index d5fc3385c..000000000 --- a/salt/curator/files/action/so-kratos-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-kratos'].close %} -actions: - 1: - action: close - description: >- - Close kratos indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-kratos.*|so-kratos.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-kratos-delete.yml b/salt/curator/files/action/so-kratos-delete.yml deleted file mode 100644 index d7cb2c4ad..000000000 --- a/salt/curator/files/action/so-kratos-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-kratos'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete kratos indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-kratos.*|so-kratos.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-logstash-close.yml b/salt/curator/files/action/so-logstash-close.yml deleted file mode 100644 index 34402d95c..000000000 --- a/salt/curator/files/action/so-logstash-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-logstash'].close %} -actions: - 1: - action: close - description: >- - Close logstash indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-logstash.*|so-logstash.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-logstash-delete.yml b/salt/curator/files/action/so-logstash-delete.yml deleted file mode 100644 index 1ca1a6f6c..000000000 --- a/salt/curator/files/action/so-logstash-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-logstash'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete logstash indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-logstash.*|so-logstash.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-netflow-close.yml b/salt/curator/files/action/so-netflow-close.yml deleted file mode 100644 index 359d6f1f1..000000000 --- a/salt/curator/files/action/so-netflow-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-netflow'].close %} -actions: - 1: - action: close - description: >- - Close netflow indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-netflow.*|so-netflow.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-netflow-delete.yml b/salt/curator/files/action/so-netflow-delete.yml deleted file mode 100644 index 63adaa393..000000000 --- a/salt/curator/files/action/so-netflow-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-netflow'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete netflow indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-netflow.*|so-netflow.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-osquery-close.yml b/salt/curator/files/action/so-osquery-close.yml deleted file mode 100644 index 59b6a92b2..000000000 --- a/salt/curator/files/action/so-osquery-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-osquery'].close %} -actions: - 1: - action: close - description: >- - Close osquery indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-osquery.*|so-osquery.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-osquery-delete.yml b/salt/curator/files/action/so-osquery-delete.yml deleted file mode 100644 index b6263b0e8..000000000 --- a/salt/curator/files/action/so-osquery-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-osquery'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete import indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-osquery.*|so-osquery.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - diff --git a/salt/curator/files/action/so-ossec-close.yml b/salt/curator/files/action/so-ossec-close.yml deleted file mode 100644 index ac0691ad8..000000000 --- a/salt/curator/files/action/so-ossec-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-ossec'].close %} -actions: - 1: - action: close - description: >- - Close ossec indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-ossec.*|so-ossec.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-ossec-delete.yml b/salt/curator/files/action/so-ossec-delete.yml deleted file mode 100644 index e24fe3819..000000000 --- a/salt/curator/files/action/so-ossec-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-ossec'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete ossec indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-ossec.*|so-ossec.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-redis-close.yml b/salt/curator/files/action/so-redis-close.yml deleted file mode 100644 index f7c5ef4c6..000000000 --- a/salt/curator/files/action/so-redis-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-redis'].close %} -actions: - 1: - action: close - description: >- - Close redis indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-redis.*|so-redis.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-redis-delete.yml b/salt/curator/files/action/so-redis-delete.yml deleted file mode 100644 index 1c7f95ded..000000000 --- a/salt/curator/files/action/so-redis-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-redis'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete redis indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-redis.*|so-redis.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-strelka-close.yml b/salt/curator/files/action/so-strelka-close.yml deleted file mode 100644 index 9d908d6d2..000000000 --- a/salt/curator/files/action/so-strelka-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-strelka'].close %} -actions: - 1: - action: close - description: >- - Close Strelka indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-strelka.*|so-strelka.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-strelka-delete.yml b/salt/curator/files/action/so-strelka-delete.yml deleted file mode 100644 index 90cf88e46..000000000 --- a/salt/curator/files/action/so-strelka-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-strelka'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Strelka indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-strelka.*|so-strelka.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-syslog-close.yml b/salt/curator/files/action/so-syslog-close.yml deleted file mode 100644 index e5a58e437..000000000 --- a/salt/curator/files/action/so-syslog-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-syslog'].close %} -actions: - 1: - action: close - description: >- - Close syslog indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-syslog.*|so-syslog.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-syslog-delete.yml b/salt/curator/files/action/so-syslog-delete.yml deleted file mode 100644 index c11d2ef5a..000000000 --- a/salt/curator/files/action/so-syslog-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-syslog'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete syslog indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-syslog.*|so-syslog.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/action/so-zeek-close.yml b/salt/curator/files/action/so-zeek-close.yml deleted file mode 100644 index 1e9ea59e4..000000000 --- a/salt/curator/files/action/so-zeek-close.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set cur_close_days = CURATORMERGED['so-zeek'].close %} -actions: - 1: - action: close - description: >- - Close Zeek indices older than {{cur_close_days}} days. - options: - delete_aliases: False - timeout_override: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-zeek.*|so-zeek.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{cur_close_days}} - exclude: diff --git a/salt/curator/files/action/so-zeek-delete.yml b/salt/curator/files/action/so-zeek-delete.yml deleted file mode 100644 index 1f8522696..000000000 --- a/salt/curator/files/action/so-zeek-delete.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{%- set DELETE_DAYS = CURATORMERGED['so-zeek'].delete %} -actions: - 1: - action: delete_indices - description: >- - Delete Zeek indices when older than {{ DELETE_DAYS }} days. - options: - ignore_empty_list: True - disable_action: False - filters: - - filtertype: pattern - kind: regex - value: '^(logstash-zeek.*|so-zeek.*)$' - - filtertype: age - source: name - direction: older - timestring: '%Y.%m.%d' - unit: days - unit_count: {{ DELETE_DAYS }} - exclude: - - \ No newline at end of file diff --git a/salt/curator/files/curator.yml b/salt/curator/files/curator.yml deleted file mode 100644 index 4ea1dddf7..000000000 --- a/salt/curator/files/curator.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% if GLOBALS.role in ['so-searchnode', 'so-heavynode'] %} - {%- set elasticsearch = GLOBALS.node_ip -%} -{% elif GLOBALS.role in ['so-eval', 'so-managersearch', 'so-standalone', 'so-manager'] %} - {%- set elasticsearch = GLOBALS.manager_ip -%} -{%- endif %} -{%- set ES_USER = salt['pillar.get']('elasticsearch:auth:users:so_elastic_user:user', '') %} -{%- set ES_PASS = salt['pillar.get']('elasticsearch:auth:users:so_elastic_user:pass', '') %} - ---- -# Remember, leave a key empty if there is no value. None will be a string, -# not a Python "NoneType" -elasticsearch: - client: - hosts: - - https://{{elasticsearch}}:9200 - cloud_id: - ca_certs: - client_cert: - client_key: - verify_certs: False - request_timeout: 30 - other_settings: - api_key: - id: - api_key: - master_only: False - username: "{{ ES_USER }}" - password: "{{ ES_PASS }}" - -logging: - loglevel: INFO - logfile: '/var/log/curator/curator.log' - logformat: default - blacklist: ['elasticsearch', 'urllib3'] diff --git a/salt/curator/init.sls b/salt/curator/init.sls deleted file mode 100644 index 201195b60..000000000 --- a/salt/curator/init.sls +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{% from 'curator/map.jinja' import CURATORMERGED %} - -include: -{% if CURATORMERGED.enabled %} - - curator.enabled -{% else %} - - curator.disabled -{% endif %} diff --git a/salt/curator/soc_curator.yaml b/salt/curator/soc_curator.yaml deleted file mode 100644 index 5e5b1fcc6..000000000 --- a/salt/curator/soc_curator.yaml +++ /dev/null @@ -1,108 +0,0 @@ -curator: - enabled: - description: You can enable or disable Curator. - helpLink: curator.html - elasticsearch: - index_settings: - logs-import-so: - close: &close - description: Age, in days, when Curator closes the index. - helpLink: curator.html - forcedType: int - delete: &delete - description: Age, in days, when Curator deletes the index. - helpLink: curator.html - forcedType: int - logs-strelka-so: - close: *close - delete: *delete - logs-suricata-so: - close: *close - delete: *delete - logs-syslog-so: - close: *close - delete: *delete - logs-zeek-so: - close: *close - delete: *delete - logs-elastic_agent-metricbeat-default: - close: *close - delete: *delete - logs-elastic_agent-osquerybeat-default: - close: *close - delete: *delete - logs-elastic_agent-fleet_server-default: - close: *close - delete: *delete - logs-elastic_agent-filebeat-default: - close: *close - delete: *delete - logs-elastic_agent-default: - close: *close - delete: *delete - logs-system-auth-default: - close: *close - delete: *delete - logs-system-application-default: - close: *close - delete: *delete - logs-system-security-default: - close: *close - delete: *delete - logs-system-system-default: - close: *close - delete: *delete - logs-system-syslog-default: - close: *close - delete: *delete - logs-windows-powershell-default: - close: *close - delete: *delete - logs-windows-sysmon_operational-default: - close: *close - delete: *delete - so-beats: - close: *close - delete: *delete - so-elasticsearch: - close: *close - delete: *delete - so-firewall: - close: *close - delete: *delete - so-ids: - close: *close - delete: *delete - so-import: - close: *close - delete: *delete - so-kratos: - close: *close - delete: *delete - so-kibana: - close: *close - delete: *delete - so-logstash: - close: *close - delete: *delete - so-netflow: - close: *close - delete: *delete - so-osquery: - close: *close - delete: *delete - so-ossec: - close: *close - delete: *delete - so-redis: - close: *close - delete: *delete - so-strelka: - close: *close - delete: *delete - so-syslog: - close: *close - delete: *delete - so-zeek: - close: *close - delete: *delete diff --git a/salt/curator/tools/sbin/so-curator-close b/salt/curator/tools/sbin/so-curator-close deleted file mode 100644 index af66a03df..000000000 --- a/salt/curator/tools/sbin/so-curator-close +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -APP=close -lf=/tmp/$APP-pidLockFile -# create empty lock file if none exists -cat /dev/null >> $lf -read lastPID < $lf -# if lastPID is not null and a process with that pid exists , exit -[ ! -z "$lastPID" -a -d /proc/$lastPID ] && exit -echo $$ > $lf - -/usr/sbin/so-curator-closed-delete > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-zeek-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-beats-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-firewall-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-ids-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-import-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-kibana-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-kratos-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-osquery-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-ossec-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-strelka-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-syslog-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/logs-import-so-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/logs-strelka-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/logs-suricata-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/logs-syslog-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/logs-zeek-close.yml > /dev/null 2>&1; diff --git a/salt/curator/tools/sbin/so-curator-cluster-close b/salt/curator/tools/sbin/so-curator-cluster-close deleted file mode 100755 index 4359dcfc1..000000000 --- a/salt/curator/tools/sbin/so-curator-cluster-close +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -APP=close -lf=/tmp/$APP-pidLockFile -# create empty lock file if none exists -cat /dev/null >> $lf -read lastPID < $lf -# if lastPID is not null and a process with that pid exists , exit -[ ! -z "$lastPID" -a -d /proc/$lastPID ] && exit -echo $$ > $lf - -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-zeek-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-beats-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-firewall-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-ids-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-import-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-kratos-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-osquery-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-ossec-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-strelka-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-syslog-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/logs-import-so-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/logs-strelka-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/logs-suricata-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/logs-syslog-close.yml > /dev/null 2>&1; -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/logs-zeek-close.yml > /dev/null 2>&1; diff --git a/salt/curator/tools/sbin/so-curator-delete b/salt/curator/tools/sbin/so-curator-delete deleted file mode 100644 index 2d128bfdf..000000000 --- a/salt/curator/tools/sbin/so-curator-delete +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - - -APP=delete -lf=/tmp/$APP-pidLockFile -# create empty lock file if none exists -cat /dev/null >> $lf -read lastPID < $lf -# if lastPID is not null and a process with that pid exists , exit -[ ! -z "$lastPID" -a -d /proc/$lastPID ] && exit -echo $$ > $lf - -docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/delete.yml > /dev/null 2>&1 diff --git a/salt/curator/tools/sbin_jinja/so-curator-cluster-delete-delete b/salt/curator/tools/sbin_jinja/so-curator-cluster-delete-delete deleted file mode 100755 index e0c5144bc..000000000 --- a/salt/curator/tools/sbin_jinja/so-curator-cluster-delete-delete +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% import_yaml 'elasticsearch/defaults.yaml' as ELASTICDEFAULTS %} -{%- set ELASTICSEARCH_HOST = GLOBALS.node_ip -%} -{%- set RETENTION = salt['pillar.get']('elasticsearch:retention', ELASTICDEFAULTS.elasticsearch.retention, merge=true) -%} - -LOG="/opt/so/log/curator/so-curator-cluster-delete.log" -ALERT_LOG="/opt/so/log/curator/alert.log" -LOG_SIZE_LIMIT_GB=$(/usr/sbin/so-elasticsearch-cluster-space-total {{ RETENTION.retention_pct}}) -LOG_SIZE_LIMIT=$(( "$LOG_SIZE_LIMIT_GB" * 1000 * 1000 * 1000 )) -ITERATION=0 -MAX_ITERATIONS=10 - -overlimit() { - [[ $(/usr/sbin/so-elasticsearch-cluster-space-used) -gt ${LOG_SIZE_LIMIT} ]] -} - -########################### -# Check for 2 conditions: # -########################### -# 1. Check if Elasticsearch indices are using more disk space than LOG_SIZE_LIMIT -# 2. Check if the maximum number of iterations - MAX_ITERATIONS - has been exceeded. If so, exit. -# Closed indices will be deleted first. If we are able to bring disk space under LOG_SIZE_LIMIT, or the number of iterations has exceeded the maximum allowed number of iterations, we will break out of the loop. - -while overlimit && [[ $ITERATION -lt $MAX_ITERATIONS ]]; do - - # If we can't query Elasticsearch, then immediately return false. - /usr/sbin/so-elasticsearch-query _cat/indices?h=index,status > /dev/null 2>&1 - [ $? -eq 1 ] && echo "$(date) - Could not query Elasticsearch." >> ${LOG} && exit - - # We iterate through the closed and open indices - CLOSED_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'close$' | awk '{print $1}' | grep -vE "playbook|so-case" | grep -E "(logstash-|so-|.ds-logs-)" | sort -t- -k3) - OPEN_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'open$' | awk '{print $1}' | grep -vE "playbook|so-case" | grep -E "(logstash-|so-|.ds-logs-)" | sort -t- -k3) - - for INDEX in ${CLOSED_INDICES} ${OPEN_INDICES}; do - # Now that we've sorted the indices from oldest to newest, we need to check each index to see if it is assigned as the current write index for a data stream - # To do so, we need to identify to which data stream this index is associated - # We extract the data stream name using the pattern below - DATASTREAM_PATTERN="logs-[a-zA-Z_.]+-[a-zA-Z_.]+" - DATASTREAM=$(echo "${INDEX}" | grep -oE "$DATASTREAM_PATTERN") - # We look up the data stream, and determine the write index. If there is only one backing index, we delete the entire data stream - BACKING_INDICES=$(/usr/sbin/so-elasticsearch-query _data_stream/${DATASTREAM} | jq -r '.data_streams[0].indices | length') - if [ "$BACKING_INDICES" -gt 1 ]; then - CURRENT_WRITE_INDEX=$(/usr/sbin/so-elasticsearch-query _data_stream/$DATASTREAM | jq -r .data_streams[0].indices[-1].index_name) - # We make sure we are not trying to delete a write index - if [ "${INDEX}" != "${CURRENT_WRITE_INDEX}" ]; then - # This should not be a write index, so we should be allowed to delete it - printf "\n$(date) - Used disk space exceeds LOG_SIZE_LIMIT (${LOG_SIZE_LIMIT_GB} GB) - Deleting ${INDEX} index...\n" >> ${LOG} - /usr/sbin/so-elasticsearch-query ${INDEX} -XDELETE >> ${LOG} 2>&1 - fi - fi - if ! overlimit ; then - exit - fi - ((ITERATION++)) - done - if [[ $ITERATION -ge $MAX_ITERATIONS ]]; then - alert_id=$(uuidgen) - printf "\n$(date) -> Maximum iteration limit reached ($MAX_ITERATIONS). Unable to bring disk below threshold. Writing alert ($alert_id) to ${ALERT_LOG}\n" >> ${LOG} - printf "\n$(date),$alert_id,Maximum iteration limit reached ($MAX_ITERATIONS). Unable to bring disk below threshold.\n" >> ${ALERT_LOG} - fi -done diff --git a/salt/desktop/packages.sls b/salt/desktop/packages.sls index 841d34744..b2a028e60 100644 --- a/salt/desktop/packages.sls +++ b/salt/desktop/packages.sls @@ -35,6 +35,7 @@ desktop_packages: - bluez-libs - bluez-obexd - bolt + - brasero - bzip2 - bzip2-libs - c-ares @@ -333,6 +334,7 @@ desktop_packages: - pulseaudio-libs - pulseaudio-libs-glib2 - pulseaudio-utils + - putty - sane-airscan - sane-backends - sane-backends-drivers-cameras diff --git a/salt/docker/defaults.yaml b/salt/docker/defaults.yaml index a5d6c5d6d..2d7ad4e1c 100644 --- a/salt/docker/defaults.yaml +++ b/salt/docker/defaults.yaml @@ -51,6 +51,14 @@ docker: custom_bind_mounts: [] extra_hosts: [] extra_env: [] + 'so-hydra': + final_octet: 30 + port_bindings: + - 0.0.0.0:4444:4444 + - 0.0.0.0:4445:4445 + custom_bind_mounts: [] + extra_hosts: [] + extra_env: [] 'so-logstash': final_octet: 29 port_bindings: @@ -67,13 +75,6 @@ docker: custom_bind_mounts: [] extra_hosts: [] extra_env: [] - 'so-mysql': - final_octet: 30 - port_bindings: - - 0.0.0.0:3306:3306 - custom_bind_mounts: [] - extra_hosts: [] - extra_env: [] 'so-nginx': final_octet: 31 port_bindings: @@ -81,13 +82,14 @@ docker: - 443:443 - 8443:8443 - 7788:7788 + - 7789:7789 custom_bind_mounts: [] extra_hosts: [] extra_env: [] - 'so-playbook': - final_octet: 32 + 'so-nginx-fleet-node': + final_octet: 31 port_bindings: - - 0.0.0.0:3000:3000 + - 8443:8443 custom_bind_mounts: [] extra_hosts: [] extra_env: [] @@ -111,13 +113,6 @@ docker: custom_bind_mounts: [] extra_hosts: [] extra_env: [] - 'so-soctopus': - final_octet: 35 - port_bindings: - - 0.0.0.0:7000:7000 - custom_bind_mounts: [] - extra_hosts: [] - extra_env: [] 'so-strelka-backend': final_octet: 36 custom_bind_mounts: [] @@ -159,11 +154,6 @@ docker: custom_bind_mounts: [] extra_hosts: [] extra_env: [] - 'so-curator': - final_octet: 43 - custom_bind_mounts: [] - extra_hosts: [] - extra_env: [] 'so-elastic-fleet-package-registry': final_octet: 44 port_bindings: @@ -199,8 +189,20 @@ docker: custom_bind_mounts: [] extra_hosts: [] extra_env: [] + ulimits: + - memlock=524288000 'so-zeek': final_octet: 99 custom_bind_mounts: [] extra_hosts: [] extra_env: [] + 'so-kafka': + final_octet: 88 + port_bindings: + - 0.0.0.0:9092:9092 + - 0.0.0.0:29092:29092 + - 0.0.0.0:9093:9093 + - 0.0.0.0:8778:8778 + custom_bind_mounts: [] + extra_hosts: [] + extra_env: [] diff --git a/salt/docker/init.sls b/salt/docker/init.sls index 769c58af8..5a0d1f61a 100644 --- a/salt/docker/init.sls +++ b/salt/docker/init.sls @@ -20,41 +20,41 @@ dockergroup: dockerheldpackages: pkg.installed: - pkgs: - - containerd.io: 1.6.21-1 - - docker-ce: 5:24.0.3-1~debian.12~bookworm - - docker-ce-cli: 5:24.0.3-1~debian.12~bookworm - - docker-ce-rootless-extras: 5:24.0.3-1~debian.12~bookworm + - containerd.io: 1.7.21-1 + - docker-ce: 5:27.2.0-1~debian.12~bookworm + - docker-ce-cli: 5:27.2.0-1~debian.12~bookworm + - docker-ce-rootless-extras: 5:27.2.0-1~debian.12~bookworm - hold: True - update_holds: True {% elif grains.oscodename == 'jammy' %} dockerheldpackages: pkg.installed: - pkgs: - - containerd.io: 1.6.21-1 - - docker-ce: 5:24.0.2-1~ubuntu.22.04~jammy - - docker-ce-cli: 5:24.0.2-1~ubuntu.22.04~jammy - - docker-ce-rootless-extras: 5:24.0.2-1~ubuntu.22.04~jammy + - containerd.io: 1.7.21-1 + - docker-ce: 5:27.2.0-1~ubuntu.22.04~jammy + - docker-ce-cli: 5:27.2.0-1~ubuntu.22.04~jammy + - docker-ce-rootless-extras: 5:27.2.0-1~ubuntu.22.04~jammy - hold: True - update_holds: True {% else %} dockerheldpackages: pkg.installed: - pkgs: - - containerd.io: 1.4.9-1 - - docker-ce: 5:20.10.8~3-0~ubuntu-focal - - docker-ce-cli: 5:20.10.5~3-0~ubuntu-focal - - docker-ce-rootless-extras: 5:20.10.5~3-0~ubuntu-focal + - containerd.io: 1.7.21-1 + - docker-ce: 5:27.2.0-1~ubuntu.20.04~focal + - docker-ce-cli: 5:27.2.0-1~ubuntu.20.04~focal + - docker-ce-rootless-extras: 5:27.2.0-1~ubuntu.20.04~focal - hold: True - update_holds: True -{% endif %} +{% endif %} {% else %} dockerheldpackages: pkg.installed: - pkgs: - - containerd.io: 1.6.21-3.1.el9 - - docker-ce: 24.0.4-1.el9 - - docker-ce-cli: 24.0.4-1.el9 - - docker-ce-rootless-extras: 24.0.4-1.el9 + - containerd.io: 1.7.21-3.1.el9 + - docker-ce: 3:27.2.0-1.el9 + - docker-ce-cli: 1:27.2.0-1.el9 + - docker-ce-rootless-extras: 27.2.0-1.el9 - hold: True - update_holds: True {% endif %} diff --git a/salt/docker/soc_docker.yaml b/salt/docker/soc_docker.yaml index d227a3e85..dacbf2302 100644 --- a/salt/docker/soc_docker.yaml +++ b/salt/docker/soc_docker.yaml @@ -45,14 +45,13 @@ docker: so-influxdb: *dockerOptions so-kibana: *dockerOptions so-kratos: *dockerOptions + so-hydra: *dockerOptions so-logstash: *dockerOptions - so-mysql: *dockerOptions so-nginx: *dockerOptions - so-playbook: *dockerOptions + so-nginx-fleet-node: *dockerOptions so-redis: *dockerOptions so-sensoroni: *dockerOptions so-soc: *dockerOptions - so-soctopus: *dockerOptions so-strelka-backend: *dockerOptions so-strelka-filestream: *dockerOptions so-strelka-frontend: *dockerOptions @@ -60,11 +59,47 @@ docker: so-strelka-gatekeeper: *dockerOptions so-strelka-coordinator: *dockerOptions so-elastalert: *dockerOptions - so-curator: *dockerOptions so-elastic-fleet-package-registry: *dockerOptions so-idh: *dockerOptions so-elastic-agent: *dockerOptions so-telegraf: *dockerOptions so-steno: *dockerOptions - so-suricata: *dockerOptions + so-suricata: + final_octet: + description: Last octet of the container IP address. + helpLink: docker.html + readonly: True + advanced: True + global: True + port_bindings: + description: List of port bindings for the container. + helpLink: docker.html + advanced: True + multiline: True + forcedType: "[]string" + custom_bind_mounts: + description: List of custom local volume bindings. + advanced: True + helpLink: docker.html + multiline: True + forcedType: "[]string" + extra_hosts: + description: List of additional host entries for the container. + advanced: True + helpLink: docker.html + multiline: True + forcedType: "[]string" + extra_env: + description: List of additional ENV entries for the container. + advanced: True + helpLink: docker.html + multiline: True + forcedType: "[]string" + ulimits: + description: Ulimits for the container, in bytes. + advanced: True + helpLink: docker.html + multiline: True + forcedType: "[]string" so-zeek: *dockerOptions + so-kafka: *dockerOptions \ No newline at end of file diff --git a/salt/elastalert/config.sls b/salt/elastalert/config.sls index 252aa83c0..25d5bf5f8 100644 --- a/salt/elastalert/config.sls +++ b/salt/elastalert/config.sls @@ -82,6 +82,36 @@ elastasomodulesync: - group: 933 - makedirs: True +elastacustomdir: + file.directory: + - name: /opt/so/conf/elastalert/custom + - user: 933 + - group: 933 + - makedirs: True + +elastacustomsync: + file.recurse: + - name: /opt/so/conf/elastalert/custom + - source: salt://elastalert/files/custom + - user: 933 + - group: 933 + - makedirs: True + - file_mode: 660 + - show_changes: False + +elastapredefinedsync: + file.recurse: + - name: /opt/so/conf/elastalert/predefined + - source: salt://elastalert/files/predefined + - user: 933 + - group: 933 + - makedirs: True + - template: jinja + - file_mode: 660 + - context: + elastalert: {{ ELASTALERTMERGED }} + - show_changes: False + elastaconf: file.managed: - name: /opt/so/conf/elastalert/elastalert_config.yaml diff --git a/salt/elastalert/defaults.yaml b/salt/elastalert/defaults.yaml index a01c80952..393932992 100644 --- a/salt/elastalert/defaults.yaml +++ b/salt/elastalert/defaults.yaml @@ -1,5 +1,6 @@ elastalert: enabled: False + alerter_parameters: "" config: rules_folder: /opt/elastalert/rules/ scan_subdirectories: true diff --git a/salt/elastalert/enabled.sls b/salt/elastalert/enabled.sls index e4b3642db..6a1ff1440 100644 --- a/salt/elastalert/enabled.sls +++ b/salt/elastalert/enabled.sls @@ -30,6 +30,8 @@ so-elastalert: - /opt/so/rules/elastalert:/opt/elastalert/rules/:ro - /opt/so/log/elastalert:/var/log/elastalert:rw - /opt/so/conf/elastalert/modules/:/opt/elastalert/modules/:ro + - /opt/so/conf/elastalert/predefined/:/opt/elastalert/predefined/:ro + - /opt/so/conf/elastalert/custom/:/opt/elastalert/custom/:ro - /opt/so/conf/elastalert/elastalert_config.yaml:/opt/elastalert/config.yaml:ro {% if DOCKER.containers['so-elastalert'].custom_bind_mounts %} {% for BIND in DOCKER.containers['so-elastalert'].custom_bind_mounts %} diff --git a/salt/elastalert/files/custom/placeholder b/salt/elastalert/files/custom/placeholder new file mode 100644 index 000000000..42e4ae4f0 --- /dev/null +++ b/salt/elastalert/files/custom/placeholder @@ -0,0 +1 @@ +THIS IS A PLACEHOLDER FILE \ No newline at end of file diff --git a/salt/elastalert/files/modules/so/playbook-es.py b/salt/elastalert/files/modules/so/playbook-es.py deleted file mode 100644 index 3a43c26c1..000000000 --- a/salt/elastalert/files/modules/so/playbook-es.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at -# https://securityonion.net/license; you may not use this file except in compliance with the -# Elastic License 2.0. - - -from time import gmtime, strftime -import requests,json -from elastalert.alerts import Alerter - -import urllib3 -urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) - -class PlaybookESAlerter(Alerter): - """ - Use matched data to create alerts in elasticsearch - """ - - required_options = set(['play_title','play_url','sigma_level']) - - def alert(self, matches): - for match in matches: - today = strftime("%Y.%m.%d", gmtime()) - timestamp = strftime("%Y-%m-%d"'T'"%H:%M:%S"'.000Z', gmtime()) - headers = {"Content-Type": "application/json"} - - creds = None - if 'es_username' in self.rule and 'es_password' in self.rule: - creds = (self.rule['es_username'], self.rule['es_password']) - - payload = {"tags":"alert","rule": { "name": self.rule['play_title'],"case_template": self.rule['play_id'],"uuid": self.rule['play_id'],"category": self.rule['rule.category']},"event":{ "severity": self.rule['event.severity'],"module": self.rule['event.module'],"dataset": self.rule['event.dataset'],"severity_label": self.rule['sigma_level']},"kibana_pivot": self.rule['kibana_pivot'],"soc_pivot": self.rule['soc_pivot'],"play_url": self.rule['play_url'],"sigma_level": self.rule['sigma_level'],"event_data": match, "@timestamp": timestamp} - url = f"https://{self.rule['es_host']}:{self.rule['es_port']}/logs-playbook.alerts-so/_doc/" - requests.post(url, data=json.dumps(payload), headers=headers, verify=False, auth=creds) - - def get_info(self): - return {'type': 'PlaybookESAlerter'} diff --git a/salt/elastalert/files/modules/so/securityonion-es.py b/salt/elastalert/files/modules/so/securityonion-es.py new file mode 100644 index 000000000..d9bb8009e --- /dev/null +++ b/salt/elastalert/files/modules/so/securityonion-es.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + + +from time import gmtime, strftime +import requests,json +from elastalert.alerts import Alerter + +import urllib3 +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +class SecurityOnionESAlerter(Alerter): + """ + Use matched data to create alerts in Elasticsearch. + """ + + required_options = set(['detection_title', 'sigma_level']) + optional_fields = ['sigma_category', 'sigma_product', 'sigma_service'] + + def alert(self, matches): + for match in matches: + timestamp = strftime("%Y-%m-%d"'T'"%H:%M:%S"'.000Z', gmtime()) + headers = {"Content-Type": "application/json"} + + creds = None + if 'es_username' in self.rule and 'es_password' in self.rule: + creds = (self.rule['es_username'], self.rule['es_password']) + + # Start building the rule dict + rule_info = { + "name": self.rule['detection_title'], + "uuid": self.rule['detection_public_id'] + } + + # Add optional fields if they are present in the rule + for field in self.optional_fields: + rule_key = field.split('_')[-1] # Assumes field format "sigma_" + if field in self.rule: + rule_info[rule_key] = self.rule[field] + + # Construct the payload with the conditional rule_info + payload = { + "tags": "alert", + "rule": rule_info, + "event": { + "severity": self.rule['event.severity'], + "module": self.rule['event.module'], + "dataset": self.rule['event.dataset'], + "severity_label": self.rule['sigma_level'] + }, + "sigma_level": self.rule['sigma_level'], + "event_data": match, + "@timestamp": timestamp + } + url = f"https://{self.rule['es_host']}:{self.rule['es_port']}/logs-detections.alerts-so/_doc/" + requests.post(url, data=json.dumps(payload), headers=headers, verify=False, auth=creds) + + def get_info(self): + return {'type': 'SecurityOnionESAlerter'} diff --git a/salt/elastalert/files/predefined/jira_auth.yaml b/salt/elastalert/files/predefined/jira_auth.yaml new file mode 100644 index 000000000..9bf0425c0 --- /dev/null +++ b/salt/elastalert/files/predefined/jira_auth.yaml @@ -0,0 +1,6 @@ +{% if elastalert.get('jira_user', '') | length > 0 and elastalert.get('jira_pass', '') | length > 0 %} +user: {{ elastalert.jira_user }} +password: {{ elastalert.jira_pass }} +{% else %} +apikey: {{ elastalert.get('jira_api_key', '') }} +{% endif %} \ No newline at end of file diff --git a/salt/elastalert/files/predefined/smtp_auth.yaml b/salt/elastalert/files/predefined/smtp_auth.yaml new file mode 100644 index 000000000..d09d101f1 --- /dev/null +++ b/salt/elastalert/files/predefined/smtp_auth.yaml @@ -0,0 +1,2 @@ +user: {{ elastalert.get('smtp_user', '') }} +password: {{ elastalert.get('smtp_pass', '') }} diff --git a/salt/elastalert/map.jinja b/salt/elastalert/map.jinja index cc395d8ee..b8ceca277 100644 --- a/salt/elastalert/map.jinja +++ b/salt/elastalert/map.jinja @@ -13,3 +13,19 @@ {% do ELASTALERTDEFAULTS.elastalert.config.update({'es_password': pillar.elasticsearch.auth.users.so_elastic_user.pass}) %} {% set ELASTALERTMERGED = salt['pillar.get']('elastalert', ELASTALERTDEFAULTS.elastalert, merge=True) %} + +{% if 'ntf' in salt['pillar.get']('features', []) %} + {% set params = ELASTALERTMERGED.get('alerter_parameters', '') | load_yaml %} + {% if params != None and params | length > 0 %} + {% do ELASTALERTMERGED.config.update(params) %} + {% endif %} + + {% if ELASTALERTMERGED.get('smtp_user', '') | length > 0 %} + {% do ELASTALERTMERGED.config.update({'smtp_auth_file': '/opt/elastalert/predefined/smtp_auth.yaml'}) %} + {% endif %} + + {% if ELASTALERTMERGED.get('jira_user', '') | length > 0 or ELASTALERTMERGED.get('jira_key', '') | length > 0 %} + {% do ELASTALERTMERGED.config.update({'jira_account_file': '/opt/elastalert/predefined/jira_auth.yaml'}) %} + {% endif %} + +{% endif %} diff --git a/salt/elastalert/soc_elastalert.yaml b/salt/elastalert/soc_elastalert.yaml index cde09b83e..764ec87fc 100644 --- a/salt/elastalert/soc_elastalert.yaml +++ b/salt/elastalert/soc_elastalert.yaml @@ -1,7 +1,100 @@ elastalert: enabled: - description: You can enable or disable Elastalert. + description: Enables or disables the ElastAlert 2 process. This process is critical for ensuring alerts arrive in SOC, and for outbound notification delivery. helpLink: elastalert.html + alerter_parameters: + title: Custom Configuration Parameters + description: Optional configuration parameters made available as defaults for all rules and alerters. Use YAML format for these parameters, and reference the ElastAlert 2 documentation, located at https://elastalert2.readthedocs.io, for available configuration parameters. Requires a valid Security Onion license key. + global: True + multiline: True + syntax: yaml + helpLink: elastalert.html + forcedType: string + jira_api_key: + title: Jira API Key + description: Optional configuration parameter for Jira API Key, used instead of the Jira username and password. Requires a valid Security Onion license key. + global: True + sensitive: True + helpLink: elastalert.html + forcedType: string + jira_pass: + title: Jira Password + description: Optional configuration parameter for Jira password. Requires a valid Security Onion license key. + global: True + sensitive: True + helpLink: elastalert.html + forcedType: string + jira_user: + title: Jira Username + description: Optional configuration parameter for Jira username. Requires a valid Security Onion license key. + global: True + helpLink: elastalert.html + forcedType: string + smtp_pass: + title: SMTP Password + description: Optional configuration parameter for SMTP password, required for authenticating email servers. Requires a valid Security Onion license key. + global: True + sensitive: True + helpLink: elastalert.html + forcedType: string + smtp_user: + title: SMTP Username + description: Optional configuration parameter for SMTP username, required for authenticating email servers. Requires a valid Security Onion license key. + global: True + helpLink: elastalert.html + forcedType: string + files: + custom: + alertmanager_ca__crt: + description: Optional custom Certificate Authority for connecting to an AlertManager server. To utilize this custom file, the alertmanager_ca_certs key must be set to /opt/elastalert/custom/alertmanager_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key. + global: True + file: True + helpLink: elastalert.html + gelf_ca__crt: + description: Optional custom Certificate Authority for connecting to a Graylog server. To utilize this custom file, the graylog_ca_certs key must be set to /opt/elastalert/custom/graylog_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key. + global: True + file: True + helpLink: elastalert.html + http_post_ca__crt: + description: Optional custom Certificate Authority for connecting to a generic HTTP server, via the legacy HTTP POST alerter. To utilize this custom file, the http_post_ca_certs key must be set to /opt/elastalert/custom/http_post2_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key. + global: True + file: True + helpLink: elastalert.html + http_post2_ca__crt: + description: Optional custom Certificate Authority for connecting to a generic HTTP server, via the newer HTTP POST 2 alerter. To utilize this custom file, the http_post2_ca_certs key must be set to /opt/elastalert/custom/http_post2_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key. + global: True + file: True + helpLink: elastalert.html + ms_teams_ca__crt: + description: Optional custom Certificate Authority for connecting to Microsoft Teams server. To utilize this custom file, the ms_teams_ca_certs key must be set to /opt/elastalert/custom/ms_teams_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key. + global: True + file: True + helpLink: elastalert.html + pagerduty_ca__crt: + description: Optional custom Certificate Authority for connecting to PagerDuty server. To utilize this custom file, the pagerduty_ca_certs key must be set to /opt/elastalert/custom/pagerduty_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key. + global: True + file: True + helpLink: elastalert.html + rocket_chat_ca__crt: + description: Optional custom Certificate Authority for connecting to PagerDuty server. To utilize this custom file, the rocket_chart_ca_certs key must be set to /opt/elastalert/custom/rocket_chat_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key. + global: True + file: True + helpLink: elastalert.html + smtp__crt: + description: Optional custom certificate for connecting to an SMTP server. To utilize this custom file, the smtp_cert_file key must be set to /opt/elastalert/custom/smtp.crt in the Alerter Parameters setting. Requires a valid Security Onion license key. + global: True + file: True + helpLink: elastalert.html + smtp__key: + description: Optional custom certificate key for connecting to an SMTP server. To utilize this custom file, the smtp_key_file key must be set to /opt/elastalert/custom/smtp.key in the Alerter Parameters setting. Requires a valid Security Onion license key. + global: True + file: True + helpLink: elastalert.html + slack_ca__crt: + description: Optional custom Certificate Authority for connecting to Slack. To utilize this custom file, the slack_ca_certs key must be set to /opt/elastalert/custom/slack_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key. + global: True + file: True + helpLink: elastalert.html config: disable_rules_on_error: description: Disable rules on failure. diff --git a/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml b/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml index 70886c447..3d8a2112b 100644 --- a/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml +++ b/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml @@ -1,4 +1,4 @@ elastic_fleet_package_registry: enabled: - description: You can enable or disable Elastic Fleet Package Registry. + description: Enables or disables the Fleet package registry process. This process must remain enabled to allow Elastic Agent packages to be updated. advanced: True diff --git a/salt/elasticagent/enabled.sls b/salt/elasticagent/enabled.sls index 7d0f401e9..3c20c916f 100644 --- a/salt/elasticagent/enabled.sls +++ b/salt/elasticagent/enabled.sls @@ -8,7 +8,6 @@ {% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'docker/docker.map.jinja' import DOCKER %} - include: - elasticagent.config - elasticagent.sostatus diff --git a/salt/elasticagent/soc_elasticagent.yaml b/salt/elasticagent/soc_elasticagent.yaml new file mode 100644 index 000000000..a24ac1985 --- /dev/null +++ b/salt/elasticagent/soc_elasticagent.yaml @@ -0,0 +1,4 @@ +elasticagent: + enabled: + description: Enables or disables the Elastic Agent process. This process must remain enabled to allow collection of node events. + advanced: True diff --git a/salt/elasticfleet/config.sls b/salt/elasticfleet/config.sls index 5d5d3e826..f347a3c80 100644 --- a/salt/elasticfleet/config.sls +++ b/salt/elasticfleet/config.sls @@ -6,6 +6,7 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% from 'vars/globals.map.jinja' import GLOBALS %} {% if sls.split('.')[0] in allowed_states %} +{% from 'elasticfleet/map.jinja' import ELASTICFLEETMERGED %} {% set node_data = salt['pillar.get']('node_data') %} # Add EA Group @@ -29,6 +30,7 @@ elasticfleet_sbin: - user: 947 - group: 939 - file_mode: 755 + - show_changes: False elasticfleet_sbin_jinja: file.recurse: @@ -40,6 +42,7 @@ elasticfleet_sbin_jinja: - template: jinja - exclude_pat: - so-elastic-fleet-package-upgrade # exclude this because we need to watch it for changes + - show_changes: False eaconfdir: file.directory: @@ -62,6 +65,14 @@ eastatedir: - group: 939 - makedirs: True +custommappingsdir: + file.directory: + - name: /nsm/custom-mappings + - user: 947 + - group: 939 + - makedirs: True + + eapackageupgrade: file.managed: - name: /usr/sbin/so-elastic-fleet-package-upgrade @@ -72,6 +83,56 @@ eapackageupgrade: - template: jinja {% if GLOBALS.role != "so-fleet" %} + +{% if not GLOBALS.airgap %} +soresourcesrepoclone: + git.latest: + - name: https://github.com/Security-Onion-Solutions/securityonion-resources.git + - target: /nsm/securityonion-resources + - rev: 'main' + - depth: 1 + - force_reset: True +{% endif %} + +elasticdefendconfdir: + file.directory: + - name: /opt/so/conf/elastic-fleet/defend-exclusions/rulesets + - user: 947 + - group: 939 + - makedirs: True + +elasticdefenddisabled: + file.managed: + - name: /opt/so/conf/elastic-fleet/defend-exclusions/disabled-filters.yaml + - source: salt://elasticfleet/files/soc/elastic-defend-disabled-filters.yaml + - user: 947 + - group: 939 + - mode: 600 + +elasticdefendcustom: + file.managed: + - name: /opt/so/conf/elastic-fleet/defend-exclusions/rulesets/custom-filters-raw + - source: salt://elasticfleet/files/soc/elastic-defend-custom-filters.yaml + - user: 947 + - group: 939 + - mode: 600 + +{% if ELASTICFLEETMERGED.config.defend_filters.enable_auto_configuration %} +{% set ap = "present" %} +{% else %} +{% set ap = "absent" %} +{% endif %} +cron-elastic-defend-filters: + cron.{{ap}}: + - name: python3 /sbin/so-elastic-defend-manage-filters.py -c /opt/so/conf/elasticsearch/curl.config -d /opt/so/conf/elastic-fleet/defend-exclusions/disabled-filters.yaml -i /nsm/securityonion-resources/event_filters/ -i /opt/so/conf/elastic-fleet/defend-exclusions/rulesets/custom-filters/ &>> /opt/so/log/elasticfleet/elastic-defend-manage-filters.log + - identifier: elastic-defend-filters + - user: root + - minute: '0' + - hour: '3' + - daymonth: '*' + - month: '*' + - dayweek: '*' + eaintegrationsdir: file.directory: - name: /opt/so/conf/elastic-fleet/integrations @@ -86,6 +147,7 @@ eadynamicintegration: - user: 947 - group: 939 - template: jinja + - show_changes: False eaintegration: file.recurse: @@ -93,6 +155,7 @@ eaintegration: - source: salt://elasticfleet/files/integrations - user: 947 - group: 939 + - show_changes: False eaoptionalintegrationsdir: file.directory: @@ -103,9 +166,9 @@ eaoptionalintegrationsdir: {% for minion in node_data %} {% set role = node_data[minion]["role"] %} -{% if role in [ "eval","fleet","heavynode","import","manager","managersearch","standalone" ] %} -{% set optional_integrations = salt['pillar.get']('elasticfleet:optional_integrations', {}) %} -{% set integration_keys = salt['pillar.get']('elasticfleet:optional_integrations', {}).keys() %} +{% if role in [ "eval","fleet","heavynode","import","manager", "managerhype", "managersearch","standalone" ] %} +{% set optional_integrations = ELASTICFLEETMERGED.optional_integrations %} +{% set integration_keys = optional_integrations.keys() %} fleet_server_integrations_{{ minion }}: file.directory: - name: /opt/so/conf/elastic-fleet/integrations-optional/FleetServer_{{ minion }} diff --git a/salt/elasticfleet/defaults.yaml b/salt/elasticfleet/defaults.yaml index 004dea94d..d6cdd7351 100644 --- a/salt/elasticfleet/defaults.yaml +++ b/salt/elasticfleet/defaults.yaml @@ -1,5 +1,6 @@ elasticfleet: enabled: False + enable_manager_output: True config: server: custom_fqdn: [] @@ -7,9 +8,14 @@ elasticfleet: endpoints_enrollment: '' es_token: '' grid_enrollment: '' + defend_filters: + enable_auto_configuration: False + subscription_integrations: False + auto_upgrade_integrations: False logging: zeek: excluded: + - analyzer - broker - capture_loss - cluster @@ -28,71 +34,20 @@ elasticfleet: - stderr - stdout packages: - - apache - - auditd - - auth0 - - aws - - azure - - barracuda - - carbonblack_edr - - checkpoint - - cisco_asa - - cisco_duo - - cisco_meraki - - cisco_umbrella - - cloudflare - - crowdstrike - - darktrace - elastic_agent - elasticsearch - endpoint - - f5_bigip - - fim - - fireeye - fleet_server - - fortinet - - fortinet_fortigate - - gcp - - github - - google_workspace - http_endpoint - httpjson - - juniper - - juniper_srx - - kafka_log - - lastpass - log - - m365_defender - - microsoft_defender_endpoint - - microsoft_dhcp - - mimecast - - netflow - - o365 - - okta - osquery_manager - - panw - - pfsense - - pulse_connect_secure - redis - - sentinel_one - - snyk - - sonicwall_firewall - - sophos - - sophos_central - - symantec_endpoint - system - tcp - - tenable_sc - - ti_abusech - - ti_misp - - ti_otx - - ti_recordedfuture - udp - - vsphere - windows - - zscaler_zia - - zscaler_zpa - - 1password + - winlog optional_integrations: sublime_platform: enabled_nodes: [] @@ -100,3 +55,8 @@ elasticfleet: base_url: https://api.platform.sublimesecurity.com poll_interval: 5m limit: 100 + kismet: + base_url: http://localhost:2501 + poll_interval: 1m + api_key: + enabled_nodes: [] diff --git a/salt/elasticfleet/enabled.sls b/salt/elasticfleet/enabled.sls index fef85d24c..5a52f3a41 100644 --- a/salt/elasticfleet/enabled.sls +++ b/salt/elasticfleet/enabled.sls @@ -17,12 +17,21 @@ include: - elasticfleet.sostatus - ssl +{% if grains.role not in ['so-fleet'] %} +# Wait for Elasticsearch to be ready - no reason to try running Elastic Fleet server if ES is not ready +wait_for_elasticsearch_elasticfleet: + cmd.run: + - name: so-elasticsearch-wait +{% endif %} + # If enabled, automatically update Fleet Logstash Outputs {% if ELASTICFLEETMERGED.config.server.enable_auto_configuration and grains.role not in ['so-import', 'so-eval', 'so-fleet'] %} so-elastic-fleet-auto-configure-logstash-outputs: cmd.run: - name: /usr/sbin/so-elastic-fleet-outputs-update - - retry: True + - retry: + attempts: 4 + interval: 30 {% endif %} # If enabled, automatically update Fleet Server URLs & ES Connection @@ -30,15 +39,35 @@ so-elastic-fleet-auto-configure-logstash-outputs: so-elastic-fleet-auto-configure-server-urls: cmd.run: - name: /usr/sbin/so-elastic-fleet-urls-update - - retry: True + - retry: + attempts: 4 + interval: 30 {% endif %} -# Automatically update Fleet Server Elasticsearch URLs +# Automatically update Fleet Server Elasticsearch URLs & Agent Artifact URLs {% if grains.role not in ['so-fleet'] %} so-elastic-fleet-auto-configure-elasticsearch-urls: cmd.run: - name: /usr/sbin/so-elastic-fleet-es-url-update - - retry: True + - retry: + attempts: 4 + interval: 30 + +so-elastic-fleet-auto-configure-artifact-urls: + cmd.run: + - name: /usr/sbin/so-elastic-fleet-artifacts-url-update + - retry: + attempts: 4 + interval: 30 + +{% endif %} + +# Sync Elastic Agent artifacts to Fleet Node +{% if grains.role in ['so-fleet'] %} +elasticagent_syncartifacts: + file.recurse: + - name: /nsm/elastic-fleet/artifacts/beats + - source: salt://beats {% endif %} {% if SERVICETOKEN != '' %} @@ -114,7 +143,26 @@ so-elastic-fleet-integrations: so-elastic-agent-grid-upgrade: cmd.run: - name: /usr/sbin/so-elastic-agent-grid-upgrade - - retry: True + - retry: + attempts: 12 + interval: 5 + +so-elastic-fleet-integration-upgrade: + cmd.run: + - name: /usr/sbin/so-elastic-fleet-integration-upgrade + +so-elastic-fleet-addon-integrations: + cmd.run: + - name: /usr/sbin/so-elastic-fleet-optional-integrations-load + +{% if ELASTICFLEETMERGED.config.defend_filters.enable_auto_configuration %} +so-elastic-defend-manage-filters-file-watch: + cmd.run: + - name: python3 /sbin/so-elastic-defend-manage-filters.py -c /opt/so/conf/elasticsearch/curl.config -d /opt/so/conf/elastic-fleet/defend-exclusions/disabled-filters.yaml -i /nsm/securityonion-resources/event_filters/ -i /opt/so/conf/elastic-fleet/defend-exclusions/rulesets/custom-filters/ &>> /opt/so/log/elasticfleet/elastic-defend-manage-filters.log + - onchanges: + - file: elasticdefendcustom + - file: elasticdefenddisabled +{% endif %} {% endif %} delete_so-elastic-fleet_so-status.disabled: diff --git a/salt/elasticfleet/files/integrations-dynamic/fleet-server/fleet-server.json b/salt/elasticfleet/files/integrations-dynamic/fleet-server/fleet-server.json new file mode 100644 index 000000000..116f78500 --- /dev/null +++ b/salt/elasticfleet/files/integrations-dynamic/fleet-server/fleet-server.json @@ -0,0 +1,19 @@ +{ + "package": { + "name": "fleet_server", + "version": "" + }, + "name": "fleet_server-1", + "namespace": "default", + "policy_id": "FleetServer_hostname", + "vars": {}, + "inputs": { + "fleet_server-fleet-server": { + "enabled": true, + "vars": { + "custom": "server.ssl.supported_protocols: [\"TLSv1.2\", \"TLSv1.3\"]\nserver.ssl.cipher_suites: [ \"ECDHE-RSA-AES-128-GCM-SHA256\", \"ECDHE-RSA-AES-256-GCM-SHA384\", \"ECDHE-RSA-AES-128-CBC-SHA\", \"ECDHE-RSA-AES-256-CBC-SHA\", \"RSA-AES-128-GCM-SHA256\", \"RSA-AES-256-GCM-SHA384\"]" + }, + "streams": {} + } + } +} diff --git a/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/import-zeek-logs.json b/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/import-zeek-logs.json index 0979f98b6..492db03dc 100644 --- a/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/import-zeek-logs.json +++ b/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/import-zeek-logs.json @@ -27,6 +27,7 @@ } } } - } + }, + "force": true } {%- endraw -%} diff --git a/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/kratos-logs.json b/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/kratos-logs.json new file mode 100644 index 000000000..f6b01cdff --- /dev/null +++ b/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/kratos-logs.json @@ -0,0 +1,46 @@ +{%- set identities = salt['sqlite3.fetch']('/nsm/kratos/db/db.sqlite', 'SELECT id, json_extract(traits, "$.email") as email FROM identities;') -%} +{%- set valid_identities = false -%} +{%- if identities -%} + {%- set valid_identities = true -%} + {%- for id, email in identities -%} + {%- if not id or not email -%} + {%- set valid_identities = false -%} + {%- break -%} + {%- endif -%} + {%- endfor -%} +{%- endif -%} +{ + "package": { + "name": "log", + "version": "" + }, + "name": "kratos-logs", + "namespace": "so", + "description": "Kratos logs", + "policy_id": "so-grid-nodes_general", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.logs": { + "enabled": true, + "vars": { + "paths": [ + "/opt/so/log/kratos/kratos.log" + ], + "data_stream.dataset": "kratos", + "tags": ["so-kratos"], + {%- if valid_identities -%} + "processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- add_fields:\n target: event\n fields:\n category: iam\n module: kratos\n- if:\n has_fields:\n - identity_id\n then:{% for id, email in identities %}\n - if:\n equals:\n identity_id: \"{{ id }}\"\n then:\n - add_fields:\n target: ''\n fields:\n user.name: \"{{ email }}\"{% endfor %}", + {%- else -%} + "processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- add_fields:\n target: event\n fields:\n category: iam\n module: kratos", + {%- endif -%} + "custom": "pipeline: kratos" + } + } + } + } + }, + "force": true +} + diff --git a/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/zeek-logs.json b/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/zeek-logs.json index 32bff857b..5462dc861 100644 --- a/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/zeek-logs.json +++ b/salt/elasticfleet/files/integrations-dynamic/grid-nodes_general/zeek-logs.json @@ -28,6 +28,7 @@ } } } - } + }, + "force": true } {%- endraw -%} diff --git a/salt/elasticfleet/files/integrations-optional/kismet.json b/salt/elasticfleet/files/integrations-optional/kismet.json new file mode 100644 index 000000000..9a333f31c --- /dev/null +++ b/salt/elasticfleet/files/integrations-optional/kismet.json @@ -0,0 +1,36 @@ +{% from 'elasticfleet/map.jinja' import ELASTICFLEETMERGED %} +{% raw %} +{ + "package": { + "name": "httpjson", + "version": "" + }, + "name": "kismet-logs", + "namespace": "so", + "description": "Kismet Logs", + "policy_id": "FleetServer_{% endraw %}{{ NAME }}{% raw %}", + "inputs": { + "generic-httpjson": { + "enabled": true, + "streams": { + "httpjson.generic": { + "enabled": true, + "vars": { + "data_stream.dataset": "kismet", + "request_url": "{% endraw %}{{ ELASTICFLEETMERGED.optional_integrations.kismet.base_url }}{% raw %}/devices/last-time/-600/devices.tjson", + "request_interval": "{% endraw %}{{ ELASTICFLEETMERGED.optional_integrations.kismet.poll_interval }}{% raw %}", + "request_method": "GET", + "request_transforms": "- set:\r\n target: header.Cookie\r\n value: 'KISMET={% endraw %}{{ ELASTICFLEETMERGED.optional_integrations.kismet.api_key }}{% raw %}'", + "request_redirect_headers_ban_list": [], + "oauth_scopes": [], + "processors": "", + "tags": [], + "pipeline": "kismet.common" + } + } + } + } + }, + "force": true +} +{% endraw %} \ No newline at end of file diff --git a/salt/elasticfleet/files/integrations-optional/sublime_platform.json b/salt/elasticfleet/files/integrations-optional/sublime_platform.json index 8feedc879..0116ed936 100644 --- a/salt/elasticfleet/files/integrations-optional/sublime_platform.json +++ b/salt/elasticfleet/files/integrations-optional/sublime_platform.json @@ -39,6 +39,7 @@ } } } - } + }, + "force": true } {%- endraw -%} diff --git a/salt/elasticfleet/files/integrations/elastic-defend/elastic-defend-endpoints.json b/salt/elasticfleet/files/integrations/elastic-defend/elastic-defend-endpoints.json index de35f803b..87870c7bc 100644 --- a/salt/elasticfleet/files/integrations/elastic-defend/elastic-defend-endpoints.json +++ b/salt/elasticfleet/files/integrations/elastic-defend/elastic-defend-endpoints.json @@ -3,25 +3,30 @@ "namespace": "default", "description": "", "package": { - "name": "endpoint", - "title": "Elastic Defend", - "version": "8.10.2" + "name": "endpoint", + "title": "Elastic Defend", + "version": "8.17.0", + "requires_root": true }, "enabled": true, "policy_id": "endpoints-initial", - "inputs": [{ - "type": "ENDPOINT_INTEGRATION_CONFIG", + "vars": {}, + "inputs": [ + { + "type": "endpoint", "enabled": true, - "streams": [], "config": { - "_config": { - "value": { - "type": "endpoint", - "endpointConfig": { - "preset": "DataCollection" - } - } + "integration_config": { + "value": { + "type": "endpoint", + "endpointConfig": { + "preset": "DataCollection" + } } - } - }] -} + } + }, + "streams": [] + } + ] + } + \ No newline at end of file diff --git a/salt/elasticfleet/files/integrations/endpoints-initial/osquery.json b/salt/elasticfleet/files/integrations/endpoints-initial/osquery.json index f1774b905..b3d6c4609 100644 --- a/salt/elasticfleet/files/integrations/endpoints-initial/osquery.json +++ b/salt/elasticfleet/files/integrations/endpoints-initial/osquery.json @@ -16,5 +16,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/endpoints-initial/system-endpoints.json b/salt/elasticfleet/files/integrations/endpoints-initial/system-endpoints.json index b6a21249a..699c07ec3 100644 --- a/salt/elasticfleet/files/integrations/endpoints-initial/system-endpoints.json +++ b/salt/elasticfleet/files/integrations/endpoints-initial/system-endpoints.json @@ -73,5 +73,6 @@ "system-system/metrics": { "enabled": false } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/endpoints-initial/windows-defender.json b/salt/elasticfleet/files/integrations/endpoints-initial/windows-defender.json new file mode 100644 index 000000000..ab7e0783f --- /dev/null +++ b/salt/elasticfleet/files/integrations/endpoints-initial/windows-defender.json @@ -0,0 +1,29 @@ +{ + "package": { + "name": "winlog", + "version": "" + }, + "name": "windows-defender", + "namespace": "default", + "description": "Windows Defender - Operational logs", + "policy_id": "endpoints-initial", + "inputs": { + "winlogs-winlog": { + "enabled": true, + "streams": { + "winlog.winlogs": { + "enabled": true, + "vars": { + "channel": "Microsoft-Windows-Windows Defender/Operational", + "data_stream.dataset": "winlog.winlog", + "preserve_original_event": false, + "providers": [], + "ignore_older": "72h", + "language": 0, + "tags": [] } + } + } + } + }, + "force": true +} diff --git a/salt/elasticfleet/files/integrations/endpoints-initial/windows-endpoints.json b/salt/elasticfleet/files/integrations/endpoints-initial/windows-endpoints.json index b17986a53..8e9813741 100644 --- a/salt/elasticfleet/files/integrations/endpoints-initial/windows-endpoints.json +++ b/salt/elasticfleet/files/integrations/endpoints-initial/windows-endpoints.json @@ -63,5 +63,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/elasticsearch-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/elasticsearch-logs.json index 4c22f92ee..a2aaf5e0a 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/elasticsearch-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/elasticsearch-logs.json @@ -102,5 +102,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/kratos-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/hydra-logs.json similarity index 67% rename from salt/elasticfleet/files/integrations/grid-nodes_general/kratos-logs.json rename to salt/elasticfleet/files/integrations/grid-nodes_general/hydra-logs.json index b1fb71077..f1b1dace9 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/kratos-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/hydra-logs.json @@ -3,9 +3,9 @@ "name": "log", "version": "" }, - "name": "kratos-logs", + "name": "hydra-logs", "namespace": "so", - "description": "Kratos logs", + "description": "Hydra logs", "policy_id": "so-grid-nodes_general", "inputs": { "logs-logfile": { @@ -15,15 +15,16 @@ "enabled": true, "vars": { "paths": [ - "/opt/so/log/kratos/kratos.log" + "/opt/so/log/hydra/hydra.log" ], - "data_stream.dataset": "kratos", - "tags": ["so-kratos"], - "processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: iam\n module: kratos", - "custom": "pipeline: kratos" + "data_stream.dataset": "hydra", + "tags": ["so-hydra"], + "processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: iam\n module: hydra", + "custom": "pipeline: hydra" } } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/idh-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/idh-logs.json index 29cc1a879..db4b1a8f6 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/idh-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/idh-logs.json @@ -25,5 +25,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/import-evtx-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/import-evtx-logs.json index 4887a1a01..46717f3e1 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/import-evtx-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/import-evtx-logs.json @@ -20,13 +20,14 @@ ], "data_stream.dataset": "import", "custom": "", - "processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/evtx/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n- drop_fields:\n fields: [\"host\"]\n ignore_missing: true\n- add_fields:\n target: data_stream\n fields:\n type: logs\n dataset: system.security\n- add_fields:\n target: event\n fields:\n dataset: system.security\n module: system\n imported: true\n- add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.security-1.34.0\n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-Sysmon/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.sysmon_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.sysmon_operational\n module: windows\n imported: true\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.sysmon_operational-1.24.0\n- if:\n equals:\n winlog.channel: 'Application'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.application\n - add_fields:\n target: event\n fields:\n dataset: system.application\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.application-1.34.0\n- if:\n equals:\n winlog.channel: 'System'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.system\n - add_fields:\n target: event\n fields:\n dataset: system.system\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.system-1.34.0\n \n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-PowerShell/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.powershell_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.powershell_operational\n module: windows\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.powershell_operational-1.24.0\n- add_fields:\n target: data_stream\n fields:\n dataset: import", - "tags": [ + "processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/evtx/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n- drop_fields:\n fields: [\"host\"]\n ignore_missing: true\n- add_fields:\n target: data_stream\n fields:\n type: logs\n dataset: system.security\n- add_fields:\n target: event\n fields:\n dataset: system.security\n module: system\n imported: true\n- add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.security-1.67.0\n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-Sysmon/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.sysmon_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.sysmon_operational\n module: windows\n imported: true\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.sysmon_operational-2.5.0\n- if:\n equals:\n winlog.channel: 'Application'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.application\n - add_fields:\n target: event\n fields:\n dataset: system.application\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.application-1.67.0\n- if:\n equals:\n winlog.channel: 'System'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.system\n - add_fields:\n target: event\n fields:\n dataset: system.system\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.system-1.67.0\n \n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-PowerShell/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.powershell_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.powershell_operational\n module: windows\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.powershell_operational-2.5.0\n- add_fields:\n target: data_stream\n fields:\n dataset: import", + "tags": [ "import" ] } } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/import-suricata-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/import-suricata-logs.json index 3b8cffcc1..c9b036e36 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/import-suricata-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/import-suricata-logs.json @@ -25,5 +25,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/osquery-grid-nodes.json b/salt/elasticfleet/files/integrations/grid-nodes_general/osquery-grid-nodes.json index 0349c9fc3..5527607bd 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/osquery-grid-nodes.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/osquery-grid-nodes.json @@ -16,5 +16,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/redis-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/redis-logs.json index 6b9cbffaf..b822421eb 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/redis-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/redis-logs.json @@ -72,5 +72,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/rita-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/rita-logs.json new file mode 100644 index 000000000..a97faaa5f --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/rita-logs.json @@ -0,0 +1,34 @@ +{ + "package": { + "name": "log", + "version": "" + }, + "name": "rita-logs", + "namespace": "so", + "description": "RITA Logs", + "policy_id": "so-grid-nodes_general", + "vars": {}, + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.logs": { + "enabled": true, + "vars": { + "paths": [ + "/nsm/rita/beacons.csv", + "/nsm/rita/exploded-dns.csv", + "/nsm/rita/long-connections.csv" + ], + "exclude_files": [], + "ignore_older": "72h", + "data_stream.dataset": "rita", + "tags": [], + "processors": "- dissect:\n tokenizer: \"/nsm/rita/%{pipeline}.csv\"\n field: \"log.file.path\"\n trim_chars: \".csv\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"pipeline\").split(\"-\");\n if (pl.length > 1) {\n pl = pl[1];\n }\n else {\n pl = pl[0];\n }\n event.Put(\"@metadata.pipeline\", \"rita.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: rita", + "custom": "exclude_lines: ['^Score', '^Source', '^Domain', '^No results']" + } + } + } + } + } +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/so-ip-mappings.json b/salt/elasticfleet/files/integrations/grid-nodes_general/so-ip-mappings.json new file mode 100644 index 000000000..fdcd36815 --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/so-ip-mappings.json @@ -0,0 +1,35 @@ +{ + "package": { + "name": "log", + "version": "" + }, + "name": "so-ip-mappings", + "namespace": "so", + "description": "IP Description mappings", + "policy_id": "so-grid-nodes_general", + "vars": {}, + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.logs": { + "enabled": true, + "vars": { + "paths": [ + "/nsm/custom-mappings/ip-descriptions.csv" + ], + "data_stream.dataset": "hostnamemappings", + "tags": [ + "so-ip-mappings" + ], + "processors": "- decode_csv_fields:\n fields:\n message: decoded.csv\n separator: \",\"\n ignore_missing: false\n overwrite_keys: true\n trim_leading_space: true\n fail_on_error: true\n\n- extract_array:\n field: decoded.csv\n mappings:\n so.ip_address: '0'\n so.description: '1'\n\n- script:\n lang: javascript\n source: >\n function process(event) {\n var ip = event.Get('so.ip_address');\n var validIpRegex = /^((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)$/\n if (!validIpRegex.test(ip)) {\n event.Cancel();\n }\n }\n- fingerprint:\n fields: [\"so.ip_address\"]\n target_field: \"@metadata._id\"\n", + "custom": "" + } + } + } + } + }, + "force": true +} + + diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/soc-auth-sync-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/soc-auth-sync-logs.json index 3aa740881..aa39c177b 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/soc-auth-sync-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/soc-auth-sync-logs.json @@ -25,5 +25,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/soc-detections-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/soc-detections-logs.json new file mode 100644 index 000000000..5649b481d --- /dev/null +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/soc-detections-logs.json @@ -0,0 +1,35 @@ +{ + "policy_id": "so-grid-nodes_general", + "package": { + "name": "log", + "version": "" + }, + "name": "soc-detections-logs", + "description": "Security Onion Console - Detections Logs", + "namespace": "so", + "inputs": { + "logs-logfile": { + "enabled": true, + "streams": { + "log.logs": { + "enabled": true, + "vars": { + "paths": [ + "/opt/so/log/soc/detections_runtime-status_sigma.log", + "/opt/so/log/soc/detections_runtime-status_yara.log" + ], + "exclude_files": [], + "ignore_older": "72h", + "data_stream.dataset": "soc", + "tags": [ + "so-soc" + ], + "processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"soc\"\n process_array: true\n max_depth: 2\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: detections\n- rename:\n fields:\n - from: \"soc.fields.sourceIp\"\n to: \"source.ip\"\n - from: \"soc.fields.status\"\n to: \"http.response.status_code\"\n - from: \"soc.fields.method\"\n to: \"http.request.method\"\n - from: \"soc.fields.path\"\n to: \"url.path\"\n - from: \"soc.message\"\n to: \"event.action\"\n - from: \"soc.level\"\n to: \"log.level\"\n ignore_missing: true", + "custom": "pipeline: common" + } + } + } + } + }, + "force": true +} diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/soc-salt-relay-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/soc-salt-relay-logs.json index 840f36f6b..cc92092e9 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/soc-salt-relay-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/soc-salt-relay-logs.json @@ -25,5 +25,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/soc-sensoroni-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/soc-sensoroni-logs.json index 60ee95f45..61ad057f4 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/soc-sensoroni-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/soc-sensoroni-logs.json @@ -25,5 +25,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/soc-server-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/soc-server-logs.json index b789adc1d..a875e4bfc 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/soc-server-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/soc-server-logs.json @@ -25,5 +25,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/strelka-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/strelka-logs.json index 089b5d4f8..89e9bbe8e 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/strelka-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/strelka-logs.json @@ -25,5 +25,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/suricata-logs.json b/salt/elasticfleet/files/integrations/grid-nodes_general/suricata-logs.json index a9d857b24..c3b04fd86 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/suricata-logs.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/suricata-logs.json @@ -25,5 +25,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/syslog-tcp-514.json b/salt/elasticfleet/files/integrations/grid-nodes_general/syslog-tcp-514.json index 80baa45ca..4088f5a87 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/syslog-tcp-514.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/syslog-tcp-514.json @@ -28,5 +28,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/syslog-udp-514.json b/salt/elasticfleet/files/integrations/grid-nodes_general/syslog-udp-514.json index 653c788b5..22821dea8 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/syslog-udp-514.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/syslog-udp-514.json @@ -11,7 +11,7 @@ "udp-udp": { "enabled": true, "streams": { - "udp.generic": { + "udp.udp": { "enabled": true, "vars": { "listen_address": "0.0.0.0", @@ -20,14 +20,17 @@ "pipeline": "syslog", "max_message_size": "10KiB", "keep_null": false, - "processors": "- add_fields:\n target: event\n fields: \n module: syslog\n", + "processors": "- add_fields:\n target: event\n fields: \n module: syslog", "tags": [ "syslog" ], - "syslog_options": "field: message\n#format: auto\n#timezone: Local" + "syslog_options": "field: message\n#format: auto\n#timezone: Local\n", + "preserve_original_event": false, + "custom": "" } } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_general/system-grid-nodes.json b/salt/elasticfleet/files/integrations/grid-nodes_general/system-grid-nodes.json index a5c4c3e81..4ee4d2b65 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_general/system-grid-nodes.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_general/system-grid-nodes.json @@ -16,6 +16,9 @@ "paths": [ "/var/log/auth.log*", "/var/log/secure*" + ], + "tags": [ + "so-grid-node" ] } }, @@ -25,7 +28,11 @@ "paths": [ "/var/log/messages*", "/var/log/syslog*" - ] + ], + "tags": [ + "so-grid-node" + ], + "processors": "- if:\n contains:\n message: \"salt-minion\"\n then: \n - dissect:\n tokenizer: \"%{} %{} %{} %{} %{} %{}: [%{log.level}] %{*}\"\n field: \"message\"\n trim_values: \"all\"\n target_prefix: \"\"\n - drop_event:\n when:\n equals:\n log.level: \"INFO\"" } } } @@ -36,5 +43,6 @@ "system-system/metrics": { "enabled": false } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_heavy/osquery-grid-nodes.json b/salt/elasticfleet/files/integrations/grid-nodes_heavy/osquery-grid-nodes.json index b1454d4bd..b1d69a44f 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_heavy/osquery-grid-nodes.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_heavy/osquery-grid-nodes.json @@ -16,5 +16,6 @@ } } } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/integrations/grid-nodes_heavy/system-grid-nodes.json b/salt/elasticfleet/files/integrations/grid-nodes_heavy/system-grid-nodes.json index 3df514f0b..42918cc97 100644 --- a/salt/elasticfleet/files/integrations/grid-nodes_heavy/system-grid-nodes.json +++ b/salt/elasticfleet/files/integrations/grid-nodes_heavy/system-grid-nodes.json @@ -16,6 +16,9 @@ "paths": [ "/var/log/auth.log*", "/var/log/secure*" + ], + "tags": [ + "so-grid-node" ] } }, @@ -25,6 +28,9 @@ "paths": [ "/var/log/messages*", "/var/log/syslog*" + ], + "tags": [ + "so-grid-node" ] } } @@ -36,5 +42,6 @@ "system-system/metrics": { "enabled": false } - } + }, + "force": true } diff --git a/salt/elasticfleet/files/soc/elastic-defend-custom-filters.yaml b/salt/elasticfleet/files/soc/elastic-defend-custom-filters.yaml new file mode 100644 index 000000000..ed8121a71 --- /dev/null +++ b/salt/elasticfleet/files/soc/elastic-defend-custom-filters.yaml @@ -0,0 +1,27 @@ +title: 'Template 1' +id: 'This needs to be a UUIDv4 id - https://www.uuidgenerator.net/version4' +description: 'Short description detailing what this rule is filtering and why.' +references: 'Relevant urls, etc' +author: '@SecurityOnion' +date: 'MM/DD/YY' +event_type: 'dns_query' +filter_type: 'exclude' +filter: + selection_1: + TargetField: 'QueryName' + Condition: 'end with' + Pattern: '.thawte.com' +--- +title: 'Template 2' +id: 'This needs to be a UUIDv4 id - https://www.uuidgenerator.net/version4' +description: 'Short description detailing what this rule is filtering and why.' +references: 'Relevant urls, etc' +author: '@SecurityOnion' +date: 'MM/DD/YY' +event_type: 'process_creation' +filter_type: 'exclude' +filter: + selection_1: + TargetField: 'ParentImage' + Condition: 'is' + Pattern: 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngentask.exe' \ No newline at end of file diff --git a/salt/elasticfleet/files/soc/elastic-defend-disabled-filters.yaml b/salt/elasticfleet/files/soc/elastic-defend-disabled-filters.yaml new file mode 100644 index 000000000..52a646385 --- /dev/null +++ b/salt/elasticfleet/files/soc/elastic-defend-disabled-filters.yaml @@ -0,0 +1,3 @@ +'9EDAA51C-BB12-49D9-8748-2B61371F2E7D': + Date: '10/10/2024' + Notes: 'Example Disabled Filter - Leave this entry here, just copy and paste as needed.' \ No newline at end of file diff --git a/salt/elasticfleet/integration-defaults.map.jinja b/salt/elasticfleet/integration-defaults.map.jinja new file mode 100644 index 000000000..5449e791e --- /dev/null +++ b/salt/elasticfleet/integration-defaults.map.jinja @@ -0,0 +1,133 @@ +{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one + or more contributor license agreements. Licensed under the Elastic License 2.0; you may not use + this file except in compliance with the Elastic License 2.0. #} + + +{% import_json '/opt/so/state/esfleet_package_components.json' as ADDON_PACKAGE_COMPONENTS %} +{% import_yaml 'elasticfleet/defaults.yaml' as ELASTICFLEETDEFAULTS %} + +{% set CORE_ESFLEET_PACKAGES = ELASTICFLEETDEFAULTS.get('elasticfleet', {}).get('packages', {}) %} +{% set ADDON_INTEGRATION_DEFAULTS = {} %} + +{# Some fleet integrations don't follow the standard naming convention #} +{% set WEIRD_INTEGRATIONS = { + 'awsfirehose.logs': 'awsfirehose', + 'awsfirehose.metrics': 'aws.cloudwatch', + 'cribl.logs': 'cribl', + 'sentinel_one_cloud_funnel.logins': 'sentinel_one_cloud_funnel.login', + 'azure_application_insights.app_insights': 'azure.app_insights', + 'azure_application_insights.app_state': 'azure.app_state', + 'azure_billing.billing': 'azure.billing', + 'azure_functions.metrics': 'azure.function', + 'azure_metrics.compute_vm_scaleset': 'azure.compute_vm_scaleset', + 'azure_metrics.compute_vm': 'azure.compute_vm', + 'azure_metrics.container_instance': 'azure.container_instance', + 'azure_metrics.container_registry': 'azure.container_registry', + 'azure_metrics.container_service': 'azure.container_service', + 'azure_metrics.database_account': 'azure.database_account', + 'azure_metrics.monitor': 'azure.monitor', + 'azure_metrics.storage_account': 'azure.storage_account', + 'azure_openai.metrics': 'azure.open_ai', + 'beat.state': 'beats.stack_monitoring.state', + 'beat.stats': 'beats.stack_monitoring.stats', + 'enterprisesearch.health': 'enterprisesearch.stack_monitoring.health', + 'enterprisesearch.stats': 'enterprisesearch.stack_monitoring.stats', + 'kibana.cluster_actions': 'kibana.stack_monitoring.cluster_actions', + 'kibana.cluster_rules': 'kibana.stack_monitoring.cluster_rules', + 'kibana.node_actions': 'kibana.stack_monitoring.node_actions', + 'kibana.node_rules': 'kibana.stack_monitoring.node_rules', + 'kibana.stats': 'kibana.stack_monitoring.stats', + 'kibana.status': 'kibana.stack_monitoring.status', + 'logstash.node_cel': 'logstash.stack_monitoring.node', + 'logstash.node_stats': 'logstash.stack_monitoring.node_stats', + 'synthetics.browser': 'synthetics-browser', + 'synthetics.browser_network': 'synthetics-browser.network', + 'synthetics.browser_screenshot': 'synthetics-browser.screenshot', + 'synthetics.http': 'synthetics-http', + 'synthetics.icmp': 'synthetics-icmp', + 'synthetics.tcp': 'synthetics-tcp' + } %} + +{% for pkg in ADDON_PACKAGE_COMPONENTS %} +{% if pkg.name in CORE_ESFLEET_PACKAGES %} +{# skip core integrations #} +{% elif pkg.name not in CORE_ESFLEET_PACKAGES %} +{# generate defaults for each integration #} +{% if pkg.es_index_patterns is defined and pkg.es_index_patterns is not none %} +{% for pattern in pkg.es_index_patterns %} +{% if "metrics-" in pattern.name %} +{% set integration_type = "metrics-" %} +{% elif "logs-" in pattern.name %} +{% set integration_type = "logs-" %} +{% else %} +{% set integration_type = "" %} +{% endif %} +{% set component_name = pkg.name ~ "." ~ pattern.title %} +{# fix weirdly named components #} +{% if component_name in WEIRD_INTEGRATIONS %} +{% set component_name = WEIRD_INTEGRATIONS[component_name] %} +{% endif %} +{# component_name_x maintains the functionality of merging local pillar changes with generated 'defaults' via SOC UI #} +{% set component_name_x = component_name.replace(".","_x_") %} +{# pillar overrides/merge expects the key names to follow the naming in elasticsearch/defaults.yaml eg. so-logs-1password_x_item_usages . The _x_ is replaced later on in elasticsearch/template.map.jinja #} +{% set integration_key = "so-" ~ integration_type ~ component_name_x %} + +{# Default integration settings #} +{% set integration_defaults = { + "index_sorting": false, + "index_template": { + "composed_of": [integration_type ~ component_name ~ "@package", integration_type ~ component_name ~ "@custom", "so-fleet_integrations.ip_mappings-1", "so-fleet_globals-1", "so-fleet_agent_id_verification-1"], + "data_stream": { + "allow_custom_routing": false, + "hidden": false + }, + "ignore_missing_component_templates": [integration_type ~ component_name ~ "@custom"], + "index_patterns": [pattern.name], + "priority": 501, + "template": { + "settings": { + "index": { + "lifecycle": {"name": "so-" ~ integration_type ~ component_name ~ "-logs"}, + "number_of_replicas": 0 + } + } + } + }, + "policy": { + "phases": { + "cold": { + "actions": { + "set_priority": {"priority": 0} + }, + "min_age": "60d" + }, + "delete": { + "actions": { + "delete": {} + }, + "min_age": "365d" + }, + "hot": { + "actions": { + "rollover": { + "max_age": "30d", + "max_primary_shard_size": "50gb" + }, + "set_priority": {"priority": 100} + }, + "min_age": "0ms" + }, + "warm": { + "actions": { + "set_priority": {"priority": 50} + }, + "min_age": "30d" + } + } + } + } %} +{% do ADDON_INTEGRATION_DEFAULTS.update({integration_key: integration_defaults}) %} +{% endfor %} +{% endif %} +{% endif %} +{% endfor %} diff --git a/salt/elasticfleet/soc_elasticfleet.yaml b/salt/elasticfleet/soc_elasticfleet.yaml index 8685a96e5..450e044e6 100644 --- a/salt/elasticfleet/soc_elasticfleet.yaml +++ b/salt/elasticfleet/soc_elasticfleet.yaml @@ -1,15 +1,55 @@ elasticfleet: enabled: - description: You can enable or disable Elastic Fleet. + description: Enables or disables the Elastic Fleet process. This process is critical for managing Elastic Agents. advanced: True helpLink: elastic-fleet.html + enable_manager_output: + description: Setting this option to False should only be considered if there is at least one receiver node in the grid. If True, Elastic Agent will send events to the manager and receivers. If False, events will only be send to the receivers. + advanced: True + global: True + forcedType: bool + helpLink: elastic-fleet.html + files: + soc: + elastic-defend-disabled-filters__yaml: + title: Disabled Elastic Defend filters + description: Enter the ID of the filter that should be disabled. + syntax: yaml + file: True + global: True + helpLink: elastic-fleet.html + advanced: True + elastic-defend-custom-filters__yaml: + title: Custom Elastic Defend filters + description: Enter custom filters seperated by --- + syntax: yaml + file: True + global: True + helpLink: elastic-fleet.html + advanced: True logging: zeek: excluded: description: This is a list of Zeek logs that are excluded from being shipped through the data processing pipeline. If you remove a log from this list, Elastic Agent will attempt to process it. If an ingest node pipeline is not available to process the logs, you may experience errors. forcedType: "[]string" - helpLink: zeek.html + helpLink: zeek.html config: + defend_filters: + enable_auto_configuration: + description: Enable auto-configuration and management of the Elastic Defend Exclusion filters. + global: True + helpLink: elastic-fleet.html + advanced: True + subscription_integrations: + description: Enable the installation of integrations that require an Elastic license. + global: True + forcedType: bool + helpLink: elastic-fleet.html + auto_upgrade_integrations: + description: Enables or disables automatically upgrading Elastic Agent integrations. + global: True + forcedType: bool + helpLink: elastic-fleet.html server: custom_fqdn: description: Custom FQDN for Agents to connect to. One per line. @@ -73,3 +113,29 @@ elasticfleet: helpLink: elastic-fleet.html advanced: True forcedType: int + kismet: + base_url: + description: Base URL for Kismet. + global: True + helpLink: elastic-fleet.html + advanced: True + forcedType: string + poll_interval: + description: Poll interval for wireless device data from Kismet. Integration is currently configured to return devices seen as active by any Kismet sensor within the last 10 minutes. + global: True + helpLink: elastic-fleet.html + advanced: True + forcedType: string + api_key: + description: API key for Kismet. + global: True + helpLink: elastic-fleet.html + advanced: True + forcedType: string + sensitive: True + enabled_nodes: + description: Fleet nodes with the Kismet integration enabled. Enter one per line. + global: True + helpLink: elastic-fleet.html + advanced: True + forcedType: "[]string" diff --git a/salt/elasticfleet/tools/sbin/so-elastic-defend-manage-filters.py b/salt/elasticfleet/tools/sbin/so-elastic-defend-manage-filters.py new file mode 100644 index 000000000..f7ce39d1d --- /dev/null +++ b/salt/elasticfleet/tools/sbin/so-elastic-defend-manage-filters.py @@ -0,0 +1,251 @@ +from datetime import datetime +import sys +import getopt +from so_elastic_defend_filters_helper import * +import logging + +logging.basicConfig(level=logging.INFO, format='%(message)s') + +# Define mappings for Target Field, Event Type, Conditions +TARGET_FIELD_MAPPINGS = { + "Image": "process.executable", + "ParentImage": "process.parent.executable", + "CommandLine": "process.command_line", + "ParentCommandLine": "process.parent.command_line", + "DestinationHostname": "destination.domain", + "QueryName": "dns.question.name", + "DestinationIp": "destination.ip", + "TargetObject": "registry.path", + "TargetFilename": "file.path" +} + +DATASET_MAPPINGS = { + "process_create": "endpoint.events.process", + "network_connection": "endpoint.events.network", + "file_create": "endpoint.events.file", + "file_delete": "endpoint.events.file", + "registry_event": "endpoint.events.registry", + "dns_query": "endpoint.events.network" +} + +CONDITION_MAPPINGS = { + "is": ("included", "match"), + "end with": ("included", "wildcard"), + "begin with": ("included", "wildcard"), + "contains": ("included", "wildcard") +} + +# Extract entries for a rule +def extract_entries(data, event_type): + entries = [] + filter_data = data.get('filter', {}) + for value in filter_data.values(): + target_field = TARGET_FIELD_MAPPINGS.get(value.get('TargetField', '')) + condition = value.get('Condition', '') + pattern = value.get('Pattern', '') + + if condition not in CONDITION_MAPPINGS: + logging.error(f"Invalid condition: {condition}") + + # Modify the pattern based on the condition + pattern = modify_pattern(condition, pattern) + + operator, match_type = CONDITION_MAPPINGS[condition] + + entries.append({ + "field": target_field, + "operator": operator, + "type": match_type, + "value": pattern + }) + + # Add the event.dataset entry from DATASET_MAPPINGS + dataset_value = DATASET_MAPPINGS.get(event_type, '') + if dataset_value: + entries.append({ + "field": "event.dataset", + "operator": "included", + "type": "match", + "value": dataset_value + }) + else: + logging.error(f"No dataset mapping found for event_type: {event_type}") + + return entries + +# Build the JSON +def build_json_entry(entries, guid, event_type, context): + return { + "comments": [], + "entries": entries, + "item_id": guid, + "name": f"SO - {event_type} - {guid}", + "description": f"{context}\n\n <<- Note: This filter is managed by Security Onion. ->>", + "namespace_type": "agnostic", + "tags": ["policy:all"], + "type": "simple", + "os_types": ["windows"], + "entries": entries + } + +# Check to see if the rule is disabled +# If it is, make sure it is not active +def disable_check(guid, disabled_rules, username, password): + if guid in disabled_rules: + logging.info(f"Rule {guid} is in the disabled rules list, confirming that is is actually disabled...") + existing_rule = api_request("GET", guid, username, password) + + if existing_rule: + if api_request("DELETE", guid, username, password): + logging.info(f"Successfully deleted rule {guid}") + return True, "deleted" + else: + logging.error(f"Error deleting rule {guid}.") + return True, "Error deleting" + return True, "NOP" + return False, None + +def modify_pattern(condition, pattern): + """ + Modify the pattern based on the condition. + - 'end with': Add '*' to the beginning of the pattern. + - 'begin with': Add '*' to the end of the pattern. + - 'contains': Add '*' to both the beginning and end of the pattern. + """ + if isinstance(pattern, list): + # Apply modification to each pattern in the list if it's a list of patterns + return [modify_pattern(condition, p) for p in pattern] + + if condition == "end with": + return f"*{pattern}" + elif condition == "begin with": + return f"{pattern}*" + elif condition == "contains": + return f"*{pattern}*" + return pattern + + +def process_rule_update_or_create(guid, json_entry, username, password): + existing_rule = api_request("GET", guid, username, password) + + if existing_rule: + existing_rule_data = extract_relevant_fields(existing_rule) + new_rule_data = extract_relevant_fields(json_entry) + if generate_hash(existing_rule_data) != generate_hash(new_rule_data): + logging.info(f"Updating rule {guid}") + json_entry.pop("list_id", None) + api_request("PUT", guid, username, password, json_data=json_entry) + return "updated" + logging.info(f"Rule {guid} is up to date.") + return "no_change" + else: + logging.info(f"Creating new rule {guid}") + json_entry["list_id"] = "endpoint_event_filters" + api_request("POST", guid, username, password, json_data=json_entry) + return "new" + +# Main function for processing rules +def process_rules(yaml_files, disabled_rules, username, password): + stats = {"rule_count": 0, "new": 0, "updated": 0, "no_change": 0, "disabled": 0, "deleted": 0} + for data in yaml_files: + logging.info(f"Processing rule: {data.get('id', '')}") + event_type = data.get('event_type', '') + guid = data.get('id', '') + dataset = DATASET_MAPPINGS.get(event_type, '') + context = data.get('description', '') + + rule_deleted, state = disable_check(guid, disabled_rules, username, password) + if rule_deleted: + stats["disabled"] += 1 + if state == "deleted": + stats["deleted"] += 1 + continue + + # Extract entries and build JSON + entries = extract_entries(data, event_type) + json_entry = build_json_entry(entries, guid, event_type, context) + + # Process rule creation or update + status = process_rule_update_or_create(guid, json_entry, username, password) + + stats[status] += 1 + stats["rule_count"] += 1 + return stats + +def parse_args(argv): + try: + opts, args = getopt.getopt(argv, "i:d:c:f:", ["input=", "disabled=", "credentials=", "flags_file="]) + except getopt.GetoptError: + print("Usage: python so-elastic-defend-manage-filters.py -c -d -i [-f ]") + sys.exit(2) + return opts + +def load_flags(file_path): + with open(file_path, 'r') as flags_file: + return flags_file.read().splitlines() + +def validate_inputs(credentials_file, disabled_file, yaml_directories): + if not credentials_file or not disabled_file or not yaml_directories: + print("Usage: python so-elastic-defend-manage-filters.py -c -d -i [-f ]") + sys.exit(2) + +def main(argv): + credentials_file = "" + disabled_file = "" + yaml_directories = [] + + opts = parse_args(argv) + + for opt, arg in opts: + if opt in ("-c", "--credentials"): + credentials_file = arg + elif opt in ("-d", "--disabled"): + disabled_file = arg + elif opt in ("-i", "--input"): + yaml_directories.append(arg) + elif opt in ("-f", "--flags_file"): + flags = load_flags(arg) + return main(argv + flags) + + timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + logging.info(f"\n{timestamp}") + + validate_inputs(credentials_file, disabled_file, yaml_directories) + + credentials = load_credentials(credentials_file) + if not credentials: + raise Exception("Failed to load credentials") + + username, password = extract_auth_details(credentials) + if not username or not password: + raise Exception("Invalid credentials format") + + custom_rules_input = '/opt/so/conf/elastic-fleet/defend-exclusions/rulesets/custom-filters-raw' + custom_rules_output = '/opt/so/conf/elastic-fleet/defend-exclusions/rulesets/custom-filters' + prepare_custom_rules(custom_rules_input, custom_rules_output) + disabled_rules = load_disabled(disabled_file) + + total_stats = {"rule_count": 0, "new": 0, "updated": 0, "no_change": 0, "disabled": 0, "deleted": 0} + + for yaml_dir in yaml_directories: + yaml_files = load_yaml_files(yaml_dir) + stats = process_rules(yaml_files, disabled_rules, username, password) + + for key in total_stats: + total_stats[key] += stats[key] + + logging.info(f"\nProcessing Summary") + logging.info(f" - Total processed rules: {total_stats['rule_count']}") + logging.info(f" - New rules: {total_stats['new']}") + logging.info(f" - Updated rules: {total_stats['updated']}") + logging.info(f" - Disabled rules: {total_stats['deleted']}") + logging.info(f" - Rules with no changes: {total_stats['no_change']}") + logging.info(f"Rule status Summary") + logging.info(f" - Active rules: {total_stats['rule_count'] - total_stats['disabled']}") + logging.info(f" - Disabled rules: {total_stats['disabled']}") + timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + logging.info(f"Execution completed at: {timestamp}") + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/salt/elasticfleet/tools/sbin/so-elastic-fleet-common b/salt/elasticfleet/tools/sbin/so-elastic-fleet-common index 48ff3518a..d8d0bdb1e 100644 --- a/salt/elasticfleet/tools/sbin/so-elastic-fleet-common +++ b/salt/elasticfleet/tools/sbin/so-elastic-fleet-common @@ -97,11 +97,84 @@ elastic_fleet_package_install() { curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d '{"force":true}' "localhost:5601/api/fleet/epm/packages/$PKG/$VERSION" } +elastic_fleet_bulk_package_install() { + BULK_PKG_LIST=$1 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X POST -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d@$1 "localhost:5601/api/fleet/epm/packages/_bulk" +} + elastic_fleet_package_is_installed() { PACKAGE=$1 curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET -H 'kbn-xsrf: true' "localhost:5601/api/fleet/epm/packages/$PACKAGE" | jq -r '.item.status' } +elastic_fleet_installed_packages() { + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET -H 'kbn-xsrf: true' -H 'Content-Type: application/json' "localhost:5601/api/fleet/epm/packages/installed?perPage=500" +} + +elastic_fleet_agent_policy_ids() { + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies" | jq -r .items[].id + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve agent policies." + exit 1 + fi +} + +elastic_fleet_agent_policy_names() { + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies" | jq -r .items[].name + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve agent policies." + exit 1 + fi +} + +elastic_fleet_integration_policy_names() { + AGENT_POLICY=$1 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies/$AGENT_POLICY" | jq -r .item.package_policies[].name + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve integrations for '$AGENT_POLICY'." + exit 1 + fi +} + +elastic_fleet_integration_policy_package_name() { + AGENT_POLICY=$1 + INTEGRATION=$2 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies/$AGENT_POLICY" | jq -r --arg INTEGRATION "$INTEGRATION" '.item.package_policies[] | select(.name==$INTEGRATION)| .package.name' + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve package name for '$INTEGRATION' in '$AGENT_POLICY'." + exit 1 + fi +} + +elastic_fleet_integration_policy_package_version() { + AGENT_POLICY=$1 + INTEGRATION=$2 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies/$AGENT_POLICY" | jq -r --arg INTEGRATION "$INTEGRATION" '.item.package_policies[] | select(.name==$INTEGRATION)| .package.version' + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve package version for '$INTEGRATION' in '$AGENT_POLICY'." + exit 1 + fi +} + +elastic_fleet_integration_id() { + AGENT_POLICY=$1 + INTEGRATION=$2 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/agent_policies/$AGENT_POLICY" | jq -r --arg INTEGRATION "$INTEGRATION" '.item.package_policies[] | select(.name==$INTEGRATION)| .id' + if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve integration ID for '$INTEGRATION' in '$AGENT_POLICY'." + exit 1 + fi +} + +elastic_fleet_integration_policy_dryrun_upgrade() { + INTEGRATION_ID=$1 + curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -H "Content-Type: application/json" -H 'kbn-xsrf: true' -L -X POST "localhost:5601/api/fleet/package_policies/upgrade/dryrun" -d "{\"packagePolicyIds\":[\"$INTEGRATION_ID\"]}" + if [ $? -ne 0 ]; then + echo "Error: Failed to complete dry run for '$INTEGRATION_ID'." + exit 1 + fi +} + elastic_fleet_policy_create() { NAME=$1 diff --git a/salt/elasticfleet/tools/sbin/so-elastic-fleet-integration-policy-elastic-fleet-server b/salt/elasticfleet/tools/sbin/so-elastic-fleet-integration-policy-elastic-fleet-server new file mode 100644 index 000000000..8f7c8b8b4 --- /dev/null +++ b/salt/elasticfleet/tools/sbin/so-elastic-fleet-integration-policy-elastic-fleet-server @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +. /usr/sbin/so-elastic-fleet-common + +# Get all the fleet policies +json_output=$(curl -s -K /opt/so/conf/elasticsearch/curl.config -L -X GET "localhost:5601/api/fleet/agent_policies" -H 'kbn-xsrf: true') + +# Extract the IDs that start with "FleetServer_" +POLICY=$(echo "$json_output" | jq -r '.items[] | select(.id | startswith("FleetServer_")) | .id') + +# Iterate over each ID in the POLICY variable +for POLICYNAME in $POLICY; do + printf "\nUpdating Policy: $POLICYNAME\n" + + # First get the Integration ID + INTEGRATION_ID=$(/usr/sbin/so-elastic-fleet-agent-policy-view "$POLICYNAME" | jq -r '.item.package_policies[] | select(.package.name == "fleet_server") | .id') + + # Modify the default integration policy to update the policy_id and an with the correct naming + UPDATED_INTEGRATION_POLICY=$(jq --arg policy_id "$POLICYNAME" --arg name "fleet_server-$POLICYNAME" ' + .policy_id = $policy_id | + .name = $name' /opt/so/conf/elastic-fleet/integrations/fleet-server/fleet-server.json) + + # Now update the integration policy using the modified JSON + elastic_fleet_integration_update "$INTEGRATION_ID" "$UPDATED_INTEGRATION_POLICY" +done \ No newline at end of file diff --git a/salt/elasticfleet/tools/sbin/so-elastic-fleet-integration-policy-load b/salt/elasticfleet/tools/sbin/so-elastic-fleet-integration-policy-load index 518d29d26..26414a94b 100644 --- a/salt/elasticfleet/tools/sbin/so-elastic-fleet-integration-policy-load +++ b/salt/elasticfleet/tools/sbin/so-elastic-fleet-integration-policy-load @@ -12,7 +12,10 @@ if [ ! -f /opt/so/state/eaintegrations.txt ]; then # First, check for any package upgrades /usr/sbin/so-elastic-fleet-package-upgrade - # Second, configure Elastic Defend Integration seperately + # Second, update Fleet Server policies + /sbin/so-elastic-fleet-integration-policy-elastic-fleet-server + + # Third, configure Elastic Defend Integration seperately /usr/sbin/so-elastic-fleet-integration-policy-elastic-defend # Initial Endpoints diff --git a/salt/elasticfleet/tools/sbin/so-elastic-fleet-package-list b/salt/elasticfleet/tools/sbin/so-elastic-fleet-package-list index 7e68c6e83..a52920a42 100755 --- a/salt/elasticfleet/tools/sbin/so-elastic-fleet-package-list +++ b/salt/elasticfleet/tools/sbin/so-elastic-fleet-package-list @@ -10,6 +10,6 @@ SESSIONCOOKIE=$(curl -s -K /opt/so/conf/elasticsearch/curl.config -c - -X GET http://localhost:5601/ | grep sid | awk '{print $7}') # List configured package policies -curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/epm/packages" -H 'kbn-xsrf: true' | jq +curl -s -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X GET "localhost:5601/api/fleet/epm/packages?prerelease=true" -H 'kbn-xsrf: true' | jq echo diff --git a/salt/elasticfleet/tools/sbin/so_elastic_defend_filters_helper.py b/salt/elasticfleet/tools/sbin/so_elastic_defend_filters_helper.py new file mode 100644 index 000000000..90031a237 --- /dev/null +++ b/salt/elasticfleet/tools/sbin/so_elastic_defend_filters_helper.py @@ -0,0 +1,128 @@ + +import hashlib +import os +import json +import yaml +import requests +from requests.auth import HTTPBasicAuth +import shutil + +# Extract 'entries', 'description' and 'os_types' fields +def extract_relevant_fields(filter): + return { + 'entries': filter.get('entries', []), + 'description': filter.get('description', '') + } + +# Sort for consistency, so that a hash can be generated +def sorted_data(value): + if isinstance(value, dict): + # Recursively sort the dictionary by key + return {k: sorted_data(v) for k, v in sorted(value.items())} + elif isinstance(value, list): + # Sort lists; for dictionaries, sort by a specific key + return sorted(value, key=lambda x: tuple(sorted(x.items())) if isinstance(x, dict) else x) + return value + +# Generate a hash based on sorted relevant fields +def generate_hash(data): + sorted_data_string = json.dumps(sorted_data(data), sort_keys=True) + return hashlib.sha256(sorted_data_string.encode('utf-8')).hexdigest() + +# Load Elasticsearch credentials from the config file +def load_credentials(config_path): + with open(config_path, 'r') as file: + for line in file: + if line.startswith("user"): + credentials = line.split('=', 1)[1].strip().strip('"') + return credentials + return None + +# Extract username and password from credentials +def extract_auth_details(credentials): + if ':' in credentials: + return credentials.split(':', 1) + return None, None + +# Generalized API request function +def api_request(method, guid, username, password, json_data=None): + headers = { + 'kbn-xsrf': 'true', + 'Content-Type': 'application/json' + } + auth = HTTPBasicAuth(username, password) + + if method == "POST": + url = "http://localhost:5601/api/exception_lists/items?namespace_type=agnostic" + else: + url = f"http://localhost:5601/api/exception_lists/items?item_id={guid}&namespace_type=agnostic" + + response = requests.request(method, url, headers=headers, auth=auth, json=json_data) + + if response.status_code in [200, 201]: + return response.json() if response.content else True + elif response.status_code == 404 and method == "GET": + return None + else: + print(f"Error with {method} request: {response.status_code} - {response.text}") + return False + + +# Load YAML data for GUIDs to skip +def load_disabled(disabled_file_path): + if os.path.exists(disabled_file_path): + with open(disabled_file_path, 'r') as file: + return yaml.safe_load(file) or {} + return {} + +def load_yaml_files(*dirs): + yaml_files = [] + + for dir_path in dirs: + if os.path.isdir(dir_path): + # Recurse through the directory and subdirectories + for root, dirs, files in os.walk(dir_path): + for file_name in files: + if file_name.endswith(".yaml"): + full_path = os.path.join(root, file_name) + with open(full_path, 'r') as f: + try: + yaml_content = yaml.safe_load(f) + yaml_files.append(yaml_content) + except yaml.YAMLError as e: + print(f"Error loading {full_path}: {e}") + else: + print(f"Invalid directory: {dir_path}") + + return yaml_files + +def prepare_custom_rules(input_file, output_dir): + # Clear the output directory first + if os.path.exists(output_dir): + shutil.rmtree(output_dir) + os.makedirs(output_dir, exist_ok=True) + + try: + # Load the YAML file + with open(input_file, 'r') as f: + docs = yaml.safe_load_all(f) + + for doc in docs: + if 'id' not in doc: + print(f"Skipping rule, no 'id' found: {doc}") + continue + if doc.get('title') in ["Template 1", "Template 2"]: + print(f"Skipping template rule with title: {doc['title']}") + continue + # Create a filename using the 'id' field + file_name = os.path.join(output_dir, f"{doc['id']}.yaml") + + # Write the individual YAML file + with open(file_name, 'w') as output_file: + yaml.dump(doc, output_file, default_flow_style=False) + print(f"Created file: {file_name}") + + except yaml.YAMLError as e: + print(f"Error parsing YAML: {e}") + except Exception as e: + print(f"Error processing file: {e}") \ No newline at end of file diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-agent-gen-installers b/salt/elasticfleet/tools/sbin_jinja/so-elastic-agent-gen-installers index 275bc6a11..d25c18e29 100755 --- a/salt/elasticfleet/tools/sbin_jinja/so-elastic-agent-gen-installers +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-agent-gen-installers @@ -13,13 +13,16 @@ LOG="/opt/so/log/elasticfleet/so-elastic-agent-gen-installers.log" +# get the variables needed such as ELASTIC_AGENT_TARBALL_VERSION +get_elastic_agent_vars + # Check to see if we are already running NUM_RUNNING=$(pgrep -cf "/bin/bash /sbin/so-elastic-agent-gen-installers") [ "$NUM_RUNNING" -gt 1 ] && echo "$(date) - $NUM_RUNNING gen installers script processes running...exiting." >>$LOG && exit 0 for i in {1..30} do - ENROLLMENTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/enrollment_api_keys" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq .list | jq -r -c '.[] | select(.policy_id | contains("endpoints-initial")) | .api_key') + ENROLLMENTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/enrollment_api_keys?perPage=100" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq .list | jq -r -c '.[] | select(.policy_id | contains("endpoints-initial")) | .api_key') FLEETHOST=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/fleet_server_hosts/grid-default' | jq -r '.item.host_urls[]' | paste -sd ',') if [[ $FLEETHOST ]] && [[ $ENROLLMENTOKEN ]]; then break; else sleep 10; fi done @@ -36,6 +39,7 @@ printf "\n### Creating a temp directory at /nsm/elastic-agent-workspace\n" rm -rf /nsm/elastic-agent-workspace mkdir -p /nsm/elastic-agent-workspace + printf "\n### Extracting outer tarball and then each individual tarball/zip\n" tar -xf /nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz -C /nsm/elastic-agent-workspace/ unzip -q /nsm/elastic-agent-workspace/elastic-agent-*.zip -d /nsm/elastic-agent-workspace/ @@ -46,7 +50,7 @@ do done printf "\n### Stripping out unused components" -find /nsm/elastic-agent-workspace/elastic-agent-*/data/elastic-agent-*/components -maxdepth 1 -regex '.*fleet.*\|.*packet.*\|.*apm.*\|.*audit.*\|.*heart.*\|.*cloud.*' -delete +find /nsm/elastic-agent-workspace/elastic-agent-*/data/elastic-agent-*/components -maxdepth 1 -regex '.*fleet.*\|.*packet.*\|.*apm.*\|.*heart.*\|.*cloud.*' -delete printf "\n### Tarring everything up again" for OS in "${OSARCH[@]}" @@ -72,5 +76,17 @@ do printf "\n### $GOOS/$GOARCH Installer Generated...\n" done -printf "\n### Cleaning up temp files in /nsm/elastic-agent-workspace" +printf "\n\n### Generating MSI...\n" +cp /opt/so/saltstack/local/salt/elasticfleet/files/so_agent-installers/so-elastic-agent_windows_amd64 /opt/so/saltstack/local/salt/elasticfleet/files/so_agent-installers/so-elastic-agent_windows_amd64.exe +docker run \ +--mount type=bind,source=/opt/so/saltstack/local/salt/elasticfleet/files/so_agent-installers/,target=/output/ -w /output \ +{{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent-builder:{{ GLOBALS.so_version }} wixl -o so-elastic-agent_windows_amd64_msi --arch x64 /workspace/so-elastic-agent.wxs +printf "\n### MSI Generated...\n" + +printf "\n### Cleaning up temp files \n" rm -rf /nsm/elastic-agent-workspace +rm -rf /opt/so/saltstack/local/salt/elasticfleet/files/so_agent-installers/so-elastic-agent_windows_amd64.exe + +printf "\n### Copying so_agent-installers to /nsm/elastic-fleet/ for nginx.\n" +\cp -vr /opt/so/saltstack/local/salt/elasticfleet/files/so_agent-installers/ /nsm/elastic-fleet/ +chmod 644 /nsm/elastic-fleet/so_agent-installers/* diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-agent-grid-upgrade b/salt/elasticfleet/tools/sbin_jinja/so-elastic-agent-grid-upgrade index b1ca8c476..449d26c99 100644 --- a/salt/elasticfleet/tools/sbin_jinja/so-elastic-agent-grid-upgrade +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-agent-grid-upgrade @@ -1,8 +1,11 @@ +#!/bin/bash + # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # or more contributor license agreements. Licensed under the Elastic License 2.0; you may not use # this file except in compliance with the Elastic License 2.0. . /usr/sbin/so-common +{%- import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS %} # Only run on Managers if ! is_manager_node; then @@ -11,7 +14,7 @@ if ! is_manager_node; then fi # Get current list of Grid Node Agents that need to be upgraded -RAW_JSON=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "http://localhost:5601/api/fleet/agents?perPage=20&page=1&kuery=policy_id%20%3A%20so-grid-nodes_%2A&showInactive=false&showUpgradeable=true&getStatusSummary=true") +RAW_JSON=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "http://localhost:5601/api/fleet/agents?perPage=20&page=1&kuery=NOT%20agent.version%20:%20%22{{ELASTICSEARCHDEFAULTS.elasticsearch.version}}%22%20and%20policy_id%20:%20%22so-grid-nodes_general%22&showInactive=false&getStatusSummary=true") # Check to make sure that the server responded with good data - else, bail from script CHECKSUM=$(jq -r '.page' <<< "$RAW_JSON") @@ -25,14 +28,14 @@ OUTDATED_LIST=$(jq -r '.items | map(.id) | (tojson)' <<< "$RAW_JSON") if [ "$OUTDATED_LIST" != '[]' ]; then AGENTNUMBERS=$(jq -r '.total' <<< "$RAW_JSON") - printf "Initiating upgrades for $AGENTNUMBERS Agents to Elastic $ELASTIC_AGENT_TARBALL_VERSION...\n\n" + printf "Initiating upgrades for $AGENTNUMBERS Agents to Elastic {{ELASTICSEARCHDEFAULTS.elasticsearch.version}}...\n\n" # Generate updated JSON payload - JSON_STRING=$(jq -n --arg ELASTICVERSION $ELASTIC_AGENT_TARBALL_VERSION --arg UPDATELIST $OUTDATED_LIST '{"version": $ELASTICVERSION,"agents": $UPDATELIST }') + JSON_STRING=$(jq -n --arg ELASTICVERSION {{ELASTICSEARCHDEFAULTS.elasticsearch.version}} --arg UPDATELIST $OUTDATED_LIST '{"version": $ELASTICVERSION,"agents": $UPDATELIST }') # Update Node Agents curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "http://localhost:5601/api/fleet/agents/bulk_upgrade" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" else printf "No Agents need updates... Exiting\n\n" exit 0 -fi \ No newline at end of file +fi diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-artifacts-url-update b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-artifacts-url-update new file mode 100644 index 000000000..721525668 --- /dev/null +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-artifacts-url-update @@ -0,0 +1,90 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0; you may not use +# this file except in compliance with the Elastic License 2.0. +{% from 'vars/globals.map.jinja' import GLOBALS %} + +. /usr/sbin/so-common + +# Only run on Managers +if ! is_manager_node; then + printf "Not a Manager Node... Exiting" + exit 0 +fi + +# Function to check if an array contains a value +array_contains () { + local array="$1[@]" + local seeking=$2 + local in=1 + for element in "${!array}"; do + if [[ $element == "$seeking" ]]; then + in=0 + break + fi + done + return $in +} + +# Query for the current Grid Nodes that are running Logstash (which includes Fleet Nodes) +LOGSTASHNODES='{{ salt['pillar.get']('logstash:nodes', {}) | tojson }}' + +# Initialize an array for new hosts from Fleet Nodes +declare -a NEW_LIST=() + +# Query for Fleet Nodes & add them to the list (Hostname) +if grep -q "fleet" <<< "$LOGSTASHNODES"; then + readarray -t FLEETNODES < <(jq -r '.fleet | keys_unsorted[]' <<< "$LOGSTASHNODES") + for NODE in "${FLEETNODES[@]}"; do + URL="http://$NODE:8443/artifacts/" + NAME="FleetServer_$NODE" + NEW_LIST+=("$URL=$NAME") + done +fi + +# Create an array for expected hosts and their names +declare -A expected_urls=( + ["http://{{ GLOBALS.url_base }}:8443/artifacts/"]="FleetServer_{{ GLOBALS.hostname }}" + ["https://artifacts.elastic.co/downloads/"]="Elastic Artifacts" +) + +# Merge NEW_LIST into expected_urls +for entry in "${NEW_LIST[@]}"; do + # Extract URL and Name from each entry + IFS='=' read -r URL NAME <<< "$entry" + # Add to expected_urls, automatically handling URL as key and NAME as value + expected_urls["$URL"]="$NAME" +done + +# Fetch the current hosts from the API +current_urls=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/agent_download_sources' | jq -r .items[].host) + +# Convert current hosts to an array +IFS=$'\n' read -rd '' -a current_urls_array <<<"$current_urls" + +# Flag to track if any host was added +any_url_added=0 + +# Check each expected host +for host in "${!expected_urls[@]}"; do + array_contains current_urls_array "$host" || { + echo "$host (${expected_urls[$host]}) is missing. Adding it..." + + # Prepare the JSON payload + JSON_STRING=$( jq -n \ + --arg NAME "${expected_urls[$host]}" \ + --arg URL "$host" \ + '{"name":$NAME,"host":$URL}' ) + + # Create the missing host + curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/agent_download_sources" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" + + # Flag that an artifact URL was added + any_url_added=1 + } + +done + + +if [[ $any_url_added -eq 0 ]]; then + echo "All expected artifact URLs are present. No updates needed." +fi diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-es-url-update b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-es-url-update index 5d5b7e7e0..3da6b3e78 100644 --- a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-es-url-update +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-es-url-update @@ -1,3 +1,5 @@ +#!/bin/bash + # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # or more contributor license agreements. Licensed under the Elastic License 2.0; you may not use # this file except in compliance with the Elastic License 2.0. diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-integration-upgrade b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-integration-upgrade new file mode 100644 index 000000000..54540ba33 --- /dev/null +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-integration-upgrade @@ -0,0 +1,73 @@ +#!/bin/bash +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. +{%- import_yaml 'elasticfleet/defaults.yaml' as ELASTICFLEETDEFAULTS %} +{%- set SUPPORTED_PACKAGES = salt['pillar.get']('elasticfleet:packages', default=ELASTICFLEETDEFAULTS.elasticfleet.packages, merge=True) %} +{%- set AUTO_UPGRADE_INTEGRATIONS = salt['pillar.get']('elasticfleet:config:auto_upgrade_integrations', default=false) %} + +. /usr/sbin/so-elastic-fleet-common + +curl_output=$(curl -s -K /opt/so/conf/elasticsearch/curl.config -c - -X GET http://localhost:5601/) +if [ $? -ne 0 ]; then + echo "Error: Failed to connect to Kibana." + exit 1 +fi + +IFS=$'\n' +agent_policies=$(elastic_fleet_agent_policy_ids) +if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve agent policies." + exit 1 +fi + +default_packages=({% for pkg in SUPPORTED_PACKAGES %}"{{ pkg }}"{% if not loop.last %} {% endif %}{% endfor %}) + +for AGENT_POLICY in $agent_policies; do + integrations=$(elastic_fleet_integration_policy_names "$AGENT_POLICY") + for INTEGRATION in $integrations; do + if ! [[ "$INTEGRATION" == "elastic-defend-endpoints" ]] && ! [[ "$INTEGRATION" == "fleet_server-"* ]]; then + # Get package name so we know what package to look for when checking the current and latest available version + PACKAGE_NAME=$(elastic_fleet_integration_policy_package_name "$AGENT_POLICY" "$INTEGRATION") + {%- if not AUTO_UPGRADE_INTEGRATIONS %} + if [[ " ${default_packages[@]} " =~ " $PACKAGE_NAME " ]]; then + {%- endif %} + # Get currently installed version of package + PACKAGE_VERSION=$(elastic_fleet_integration_policy_package_version "$AGENT_POLICY" "$INTEGRATION") + + # Get latest available version of package + AVAILABLE_VERSION=$(elastic_fleet_package_latest_version_check "$PACKAGE_NAME") + + # Get integration ID + INTEGRATION_ID=$(elastic_fleet_integration_id "$AGENT_POLICY" "$INTEGRATION") + + if [[ "$PACKAGE_VERSION" != "$AVAILABLE_VERSION" ]]; then + # Dry run of the upgrade + echo "" + echo "Current $PACKAGE_NAME package version ($PACKAGE_VERSION) is not the same as the latest available package ($AVAILABLE_VERSION)..." + echo "Upgrading $INTEGRATION..." + echo "Starting dry run..." + DRYRUN_OUTPUT=$(elastic_fleet_integration_policy_dryrun_upgrade "$INTEGRATION_ID") + DRYRUN_ERRORS=$(echo "$DRYRUN_OUTPUT" | jq .[].hasErrors) + + # If no errors with dry run, proceed with actual upgrade + if [[ "$DRYRUN_ERRORS" == "false" ]]; then + echo "No errors detected. Proceeding with upgrade..." + elastic_fleet_integration_policy_upgrade "$INTEGRATION_ID" + if [ $? -ne 0 ]; then + echo "Error: Upgrade failed for $PACKAGE_NAME with integration ID '$INTEGRATION_ID'." + exit 1 + fi + else + echo "Errors detected during dry run for $PACKAGE_NAME policy upgrade..." + exit 1 + fi + fi + {%- if not AUTO_UPGRADE_INTEGRATIONS %} + fi + {%- endif %} + fi + done +done +echo diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-optional-integrations-load b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-optional-integrations-load new file mode 100644 index 000000000..26d775e82 --- /dev/null +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-optional-integrations-load @@ -0,0 +1,169 @@ +#!/bin/bash + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0; you may not use +# this file except in compliance with the Elastic License 2.0. +{%- import_yaml 'elasticfleet/defaults.yaml' as ELASTICFLEETDEFAULTS %} +{% set SUB = salt['pillar.get']('elasticfleet:config:subscription_integrations', default=false) %} +{% set AUTO_UPGRADE_INTEGRATIONS = salt['pillar.get']('elasticfleet:config:auto_upgrade_integrations', default=false) %} +{%- set SUPPORTED_PACKAGES = salt['pillar.get']('elasticfleet:packages', default=ELASTICFLEETDEFAULTS.elasticfleet.packages, merge=True) %} + +. /usr/sbin/so-common +. /usr/sbin/so-elastic-fleet-common + +# Check that /opt/so/state/estemplates.txt exists to signal that Elasticsearch +# has completed its first run of core-only integrations/indices/components/ilm +STATE_FILE_SUCCESS=/opt/so/state/estemplates.txt +INSTALLED_PACKAGE_LIST=/tmp/esfleet_installed_packages.json +BULK_INSTALL_PACKAGE_LIST=/tmp/esfleet_bulk_install.json +BULK_INSTALL_PACKAGE_TMP=/tmp/esfleet_bulk_install_tmp.json +BULK_INSTALL_OUTPUT=/opt/so/state/esfleet_bulk_install_results.json +PACKAGE_COMPONENTS=/opt/so/state/esfleet_package_components.json + +PENDING_UPDATE=false + +# Integrations which are included in the package registry, but excluded from automatic installation via this script. +# Requiring some level of manual Elastic Stack configuration before installation +EXCLUDED_INTEGRATIONS=('apm') + +version_conversion(){ + version=$1 + echo "$version" | awk -F '.' '{ printf("%d%03d%03d\n", $1, $2, $3); }' +} + +compare_versions() { + version1=$1 + version2=$2 + + # Convert versions to numbers + num1=$(version_conversion "$version1") + num2=$(version_conversion "$version2") + + # Compare using bc + if (( $(echo "$num1 < $num2" | bc -l) )); then + echo "less" + elif (( $(echo "$num1 > $num2" | bc -l) )); then + echo "greater" + else + echo "equal" + fi +} + +IFS=$'\n' +agent_policies=$(elastic_fleet_agent_policy_ids) +if [ $? -ne 0 ]; then + echo "Error: Failed to retrieve agent policies." + exit 1 +fi + +default_packages=({% for pkg in SUPPORTED_PACKAGES %}"{{ pkg }}"{% if not loop.last %} {% endif %}{% endfor %}) + +in_use_integrations=() + +for AGENT_POLICY in $agent_policies; do + integrations=$(elastic_fleet_integration_policy_names "$AGENT_POLICY") + for INTEGRATION in $integrations; do + PACKAGE_NAME=$(elastic_fleet_integration_policy_package_name "$AGENT_POLICY" "$INTEGRATION") + # non-default integrations that are in-use in any policy + if ! [[ " ${default_packages[@]} " =~ " $PACKAGE_NAME " ]]; then + in_use_integrations+=("$PACKAGE_NAME") + fi + done +done + +if [[ -f $STATE_FILE_SUCCESS ]]; then + if retry 3 1 "curl -s -K /opt/so/conf/elasticsearch/curl.config --output /dev/null --silent --head --fail localhost:5601/api/fleet/epm/packages"; then + # Package_list contains all integrations beta / non-beta. + latest_package_list=$(/usr/sbin/so-elastic-fleet-package-list) + echo '{ "packages" : []}' > $BULK_INSTALL_PACKAGE_LIST + rm -f $INSTALLED_PACKAGE_LIST + echo $latest_package_list | jq '{packages: [.items[] | {name: .name, latest_version: .version, installed_version: .savedObject.attributes.install_version, subscription: .conditions.elastic.subscription }]}' >> $INSTALLED_PACKAGE_LIST + + while read -r package; do + # get package details + package_name=$(echo "$package" | jq -r '.name') + latest_version=$(echo "$package" | jq -r '.latest_version') + installed_version=$(echo "$package" | jq -r '.installed_version') + subscription=$(echo "$package" | jq -r '.subscription') + bulk_package=$(echo "$package" | jq '{name: .name, version: .latest_version}' ) + + if [[ ! "${EXCLUDED_INTEGRATIONS[@]}" =~ "$package_name" ]]; then + {% if not SUB %} + if [[ "$subscription" != "basic" && "$subscription" != "null" && -n "$subscription" ]]; then + # pass over integrations that require non-basic elastic license + echo "$package_name integration requires an Elastic license of $subscription or greater... skipping" + continue + else + if [[ "$installed_version" == "null" || -z "$installed_version" ]]; then + echo "$package_name is not installed... Adding to next update." + jq --argjson package "$bulk_package" '.packages += [$package]' $BULK_INSTALL_PACKAGE_LIST > $BULK_INSTALL_PACKAGE_TMP && mv $BULK_INSTALL_PACKAGE_TMP $BULK_INSTALL_PACKAGE_LIST + + PENDING_UPDATE=true + else + results=$(compare_versions "$latest_version" "$installed_version") + if [ $results == "greater" ]; then + {#- When auto_upgrade_integrations is false, skip upgrading in_use_integrations #} + {%- if not AUTO_UPGRADE_INTEGRATIONS %} + if ! [[ " ${in_use_integrations[@]} " =~ " $package_name " ]]; then + {%- endif %} + echo "$package_name is at version $installed_version latest version is $latest_version... Adding to next update." + jq --argjson package "$bulk_package" '.packages += [$package]' $BULK_INSTALL_PACKAGE_LIST > $BULK_INSTALL_PACKAGE_TMP && mv $BULK_INSTALL_PACKAGE_TMP $BULK_INSTALL_PACKAGE_LIST + + PENDING_UPDATE=true + {%- if not AUTO_UPGRADE_INTEGRATIONS %} + else + echo "skipping available upgrade for in use integration - $package_name." + fi + {%- endif %} + fi + fi + fi + {% else %} + if [[ "$installed_version" == "null" || -z "$installed_version" ]]; then + echo "$package_name is not installed... Adding to next update." + jq --argjson package "$bulk_package" '.packages += [$package]' $BULK_INSTALL_PACKAGE_LIST > $BULK_INSTALL_PACKAGE_TMP && mv $BULK_INSTALL_PACKAGE_TMP $BULK_INSTALL_PACKAGE_LIST + PENDING_UPDATE=true + else + results=$(compare_versions "$latest_version" "$installed_version") + if [ $results == "greater" ]; then + {#- When auto_upgrade_integrations is false, skip upgrading in_use_integrations #} + {%- if not AUTO_UPGRADE_INTEGRATIONS %} + if ! [[ " ${in_use_integrations[@]} " =~ " $package_name " ]]; then + {%- endif %} + echo "$package_name is at version $installed_version latest version is $latest_version... Adding to next update." + jq --argjson package "$bulk_package" '.packages += [$package]' $BULK_INSTALL_PACKAGE_LIST > $BULK_INSTALL_PACKAGE_TMP && mv $BULK_INSTALL_PACKAGE_TMP $BULK_INSTALL_PACKAGE_LIST + PENDING_UPDATE=true + {%- if not AUTO_UPGRADE_INTEGRATIONS %} + else + echo "skipping available upgrade for in use integration - $package_name." + fi + {%- endif %} + fi + fi + {% endif %} + else + echo "Skipping $package_name..." + fi + done <<< "$(jq -c '.packages[]' "$INSTALLED_PACKAGE_LIST")" + + if [ "$PENDING_UPDATE" = true ]; then + # Run bulk install of packages + elastic_fleet_bulk_package_install $BULK_INSTALL_PACKAGE_LIST > $BULK_INSTALL_OUTPUT + else + echo "Elastic integrations don't appear to need installation/updating..." + fi + # Write out file for generating index/component/ilm templates + latest_installed_package_list=$(elastic_fleet_installed_packages) + echo $latest_installed_package_list | jq '[.items[] | {name: .name, es_index_patterns: .dataStreams}]' > $PACKAGE_COMPONENTS + + else + # This is the installation of add-on integrations and upgrade of existing integrations. Exiting without error, next highstate will attempt to re-run. + echo "Elastic Fleet does not appear to be responding... Exiting... " + exit 0 + fi +else + # This message will appear when an update to core integration is made and this script is run at the same time as + # elasticsearch.enabled -> detects change to core index settings -> deletes estemplates.txt + echo "Elasticsearch may not be fully configured yet or is currently updating core index settings." + exit 0 +fi diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-outputs-update b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-outputs-update index b88b564ed..b5d6e1bfe 100644 --- a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-outputs-update +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-outputs-update @@ -1,3 +1,5 @@ +#!/bin/bash + # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # or more contributor license agreements. Licensed under the Elastic License 2.0; you may not use # this file except in compliance with the Elastic License 2.0. @@ -19,59 +21,104 @@ function update_logstash_outputs() { # Update Logstash Outputs curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/outputs/so-manager_logstash" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" | jq } +function update_kafka_outputs() { + # Make sure SSL configuration is included in policy updates for Kafka output. SSL is configured in so-elastic-fleet-setup + SSL_CONFIG=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "http://localhost:5601/api/fleet/outputs/so-manager_kafka" | jq -r '.item.ssl') -# Get current list of Logstash Outputs -RAW_JSON=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/outputs/so-manager_logstash') + JSON_STRING=$(jq -n \ + --arg UPDATEDLIST "$NEW_LIST_JSON" \ + --argjson SSL_CONFIG "$SSL_CONFIG" \ + '{"name": "grid-kafka","type": "kafka","hosts": $UPDATEDLIST,"is_default": true,"is_default_monitoring": true,"config_yaml": "","ssl": $SSL_CONFIG}') + # Update Kafka outputs + curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/outputs/so-manager_kafka" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" | jq +} -# Check to make sure that the server responded with good data - else, bail from script -CHECKSUM=$(jq -r '.item.id' <<< "$RAW_JSON") -if [ "$CHECKSUM" != "so-manager_logstash" ]; then - printf "Failed to query for current Logstash Outputs..." - exit 1 -fi +{% if GLOBALS.pipeline == "KAFKA" %} + # Get current list of Kafka Outputs + RAW_JSON=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/outputs/so-manager_kafka') -# Get the current list of Logstash outputs & hash them -CURRENT_LIST=$(jq -c -r '.item.hosts' <<< "$RAW_JSON") -CURRENT_HASH=$(sha1sum <<< "$CURRENT_LIST" | awk '{print $1}') + # Check to make sure that the server responded with good data - else, bail from script + CHECKSUM=$(jq -r '.item.id' <<< "$RAW_JSON") + if [ "$CHECKSUM" != "so-manager_kafka" ]; then + printf "Failed to query for current Kafka Outputs..." + exit 1 + fi -# Create array & add initial elements -if [ "{{ GLOBALS.hostname }}" = "{{ GLOBALS.url_base }}" ]; then - NEW_LIST=("{{ GLOBALS.url_base }}:5055") -else - NEW_LIST=("{{ GLOBALS.url_base }}:5055" "{{ GLOBALS.hostname }}:5055") -fi + # Get the current list of kafka outputs & hash them + CURRENT_LIST=$(jq -c -r '.item.hosts' <<< "$RAW_JSON") + CURRENT_HASH=$(sha1sum <<< "$CURRENT_LIST" | awk '{print $1}') + + declare -a NEW_LIST=() + + # Query for the current Grid Nodes that are running kafka + KAFKANODES=$(salt-call --out=json pillar.get kafka:nodes | jq '.local') + + # Query for Kafka nodes with Broker role and add hostname to list + while IFS= read -r line; do + NEW_LIST+=("$line") + done < <(jq -r 'to_entries | .[] | select(.value.role | contains("broker")) | .key + ":9092"' <<< $KAFKANODES) + + {# If global pipeline isn't set to KAFKA then assume default of REDIS / logstash #} +{% else %} + # Get current list of Logstash Outputs + RAW_JSON=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/outputs/so-manager_logstash') + + # Check to make sure that the server responded with good data - else, bail from script + CHECKSUM=$(jq -r '.item.id' <<< "$RAW_JSON") + if [ "$CHECKSUM" != "so-manager_logstash" ]; then + printf "Failed to query for current Logstash Outputs..." + exit 1 + fi + + # Get the current list of Logstash outputs & hash them + CURRENT_LIST=$(jq -c -r '.item.hosts' <<< "$RAW_JSON") + CURRENT_HASH=$(sha1sum <<< "$CURRENT_LIST" | awk '{print $1}') + + declare -a NEW_LIST=() + + {# If we select to not send to manager via SOC, then omit the code that adds manager to NEW_LIST #} + {% if ELASTICFLEETMERGED.enable_manager_output %} + # Create array & add initial elements + if [ "{{ GLOBALS.hostname }}" = "{{ GLOBALS.url_base }}" ]; then + NEW_LIST+=("{{ GLOBALS.url_base }}:5055") + else + NEW_LIST+=("{{ GLOBALS.url_base }}:5055" "{{ GLOBALS.hostname }}:5055") + fi + {% endif %} + + # Query for FQDN entries & add them to the list + {% if ELASTICFLEETMERGED.config.server.custom_fqdn | length > 0 %} + CUSTOMFQDNLIST=('{{ ELASTICFLEETMERGED.config.server.custom_fqdn | join(' ') }}') + readarray -t -d ' ' CUSTOMFQDN < <(printf '%s' "$CUSTOMFQDNLIST") + for CUSTOMNAME in "${CUSTOMFQDN[@]}" + do + NEW_LIST+=("$CUSTOMNAME:5055") + done + {% endif %} + + # Query for the current Grid Nodes that are running Logstash + LOGSTASHNODES=$(salt-call --out=json pillar.get logstash:nodes | jq '.local') + + # Query for Receiver Nodes & add them to the list + if grep -q "receiver" <<< $LOGSTASHNODES; then + readarray -t RECEIVERNODES < <(jq -r ' .receiver | keys_unsorted[]' <<< $LOGSTASHNODES) + for NODE in "${RECEIVERNODES[@]}" + do + NEW_LIST+=("$NODE:5055") + done + fi + + # Query for Fleet Nodes & add them to the list + if grep -q "fleet" <<< $LOGSTASHNODES; then + readarray -t FLEETNODES < <(jq -r ' .fleet | keys_unsorted[]' <<< $LOGSTASHNODES) + for NODE in "${FLEETNODES[@]}" + do + NEW_LIST+=("$NODE:5055") + done + fi -# Query for FQDN entries & add them to the list -{% if ELASTICFLEETMERGED.config.server.custom_fqdn | length > 0 %} -CUSTOMFQDNLIST=('{{ ELASTICFLEETMERGED.config.server.custom_fqdn | join(' ') }}') -readarray -t -d ' ' CUSTOMFQDN < <(printf '%s' "$CUSTOMFQDNLIST") -for CUSTOMNAME in "${CUSTOMFQDN[@]}" -do - NEW_LIST+=("$CUSTOMNAME:5055") -done {% endif %} -# Query for the current Grid Nodes that are running Logstash -LOGSTASHNODES=$(salt-call --out=json pillar.get logstash:nodes | jq '.local') - -# Query for Receiver Nodes & add them to the list -if grep -q "receiver" <<< $LOGSTASHNODES; then - readarray -t RECEIVERNODES < <(jq -r ' .receiver | keys_unsorted[]' <<< $LOGSTASHNODES) - for NODE in "${RECEIVERNODES[@]}" - do - NEW_LIST+=("$NODE:5055") - done -fi - -# Query for Fleet Nodes & add them to the list -if grep -q "fleet" <<< $LOGSTASHNODES; then - readarray -t FLEETNODES < <(jq -r ' .fleet | keys_unsorted[]' <<< $LOGSTASHNODES) - for NODE in "${FLEETNODES[@]}" - do - NEW_LIST+=("$NODE:5055") - done -fi - # Sort & hash the new list of Logstash Outputs NEW_LIST_JSON=$(jq --compact-output --null-input '$ARGS.positional' --args -- "${NEW_LIST[@]}") NEW_HASH=$(sha1sum <<< "$NEW_LIST_JSON" | awk '{print $1}') @@ -80,9 +127,28 @@ NEW_HASH=$(sha1sum <<< "$NEW_LIST_JSON" | awk '{print $1}') if [ "$NEW_HASH" = "$CURRENT_HASH" ]; then printf "\nHashes match - no update needed.\n" printf "Current List: $CURRENT_LIST\nNew List: $NEW_LIST_JSON\n" + + # Since output can be KAFKA or LOGSTASH, we need to check if the policy set as default matches the value set in GLOBALS.pipeline and update if needed + printf "Checking if the correct output policy is set as default\n" + OUTPUT_DEFAULT=$(jq -r '.item.is_default' <<< $RAW_JSON) + OUTPUT_DEFAULT_MONITORING=$(jq -r '.item.is_default_monitoring' <<< $RAW_JSON) + if [[ "$OUTPUT_DEFAULT" = "false" || "$OUTPUT_DEFAULT_MONITORING" = "false" ]]; then + printf "Default output policy needs to be updated.\n" + {%- if GLOBALS.pipeline == "KAFKA" and 'gmd' in salt['pillar.get']('features', []) %} + update_kafka_outputs + {%- else %} + update_logstash_outputs + {%- endif %} + else + printf "Default output policy is set - no update needed.\n" + fi exit 0 else printf "\nHashes don't match - update needed.\n" printf "Current List: $CURRENT_LIST\nNew List: $NEW_LIST_JSON\n" + {%- if GLOBALS.pipeline == "KAFKA" and 'gmd' in salt['pillar.get']('features', []) %} + update_kafka_outputs + {%- else %} update_logstash_outputs + {%- endif %} fi diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup index 9c06cb7c2..deb16dadf 100755 --- a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup @@ -11,6 +11,35 @@ INTCA=/etc/pki/tls/certs/intca.crt . /usr/sbin/so-common . /usr/sbin/so-elastic-fleet-common +# Deleting Elastic Fleet data... + +# Check to make sure that Elasticsearch is up & ready +RETURN_CODE=0 +wait_for_web_response "https://localhost:9200/_cat/indices/.kibana*" "green open" 300 "curl -K /opt/so/conf/elasticsearch/curl.config" +RETURN_CODE=$? + +if [[ "$RETURN_CODE" != "0" ]]; then + status "Elasticsearch not accessible, exiting Elastic Fleet setup..." + exit 1 +fi + +ALIASES=".fleet-servers .fleet-policies-leader .fleet-policies .fleet-agents .fleet-artifacts .fleet-enrollment-api-keys .kibana_ingest" +for ALIAS in ${ALIASES} +do + # Get all concrete indices from alias + INDXS=$(curl -K /opt/so/conf/kibana/curl.config -s -k -L -H "Content-Type: application/json" "https://localhost:9200/_resolve/index/${ALIAS}" | jq -r '.aliases[].indices[]') + + # Delete all resolved indices + for INDX in ${INDXS} + do + status "Deleting $INDX" + curl -K /opt/so/conf/kibana/curl.config -s -k -L -H "Content-Type: application/json" "https://localhost:9200/${INDX}" -XDELETE + done +done + +# Restarting Kibana... +so-kibana-restart + # Check to make sure that Kibana API is up & ready RETURN_CODE=0 wait_for_web_response "http://localhost:5601/api/fleet/settings" "fleet" 300 "curl -K /opt/so/conf/elasticsearch/curl.config" @@ -24,7 +53,8 @@ fi printf "\n### Create ES Token ###\n" ESTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/service_tokens" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq -r .value) -### Create Outputs & Fleet URLs ### +### Create Outputs, Fleet Policy and Fleet URLs ### +# Create the Manager Elasticsearch Output first and set it as the default output printf "\nAdd Manager Elasticsearch Output...\n" ESCACRT=$(openssl x509 -in $INTCA) JSON_STRING=$( jq -n \ @@ -33,7 +63,21 @@ JSON_STRING=$( jq -n \ curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/outputs" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" printf "\n\n" -printf "\nCreate Logstash Output Config if node is not an Import or Eval install\n" +# Create the Manager Fleet Server Host Agent Policy +# This has to be done while the Elasticsearch Output is set to the default Output +printf "Create Manager Fleet Server Policy...\n" +elastic_fleet_policy_create "FleetServer_{{ GLOBALS.hostname }}" "Fleet Server - {{ GLOBALS.hostname }}" "false" "120" + +# Modify the default integration policy to update the policy_id with the correct naming +UPDATED_INTEGRATION_POLICY=$(jq --arg policy_id "FleetServer_{{ GLOBALS.hostname }}" --arg name "fleet_server-{{ GLOBALS.hostname }}" ' +.policy_id = $policy_id | +.name = $name' /opt/so/conf/elastic-fleet/integrations/fleet-server/fleet-server.json) + +# Add the Fleet Server Integration to the new Fleet Policy +elastic_fleet_integration_create "$UPDATED_INTEGRATION_POLICY" + +# Now we can create the Logstash Output and set it to to be the default Output +printf "\n\nCreate Logstash Output Config if node is not an Import or Eval install\n" {% if grains.role not in ['so-import', 'so-eval'] %} LOGSTASHCRT=$(openssl x509 -in /etc/pki/elasticfleet-logstash.crt) LOGSTASHKEY=$(openssl rsa -in /etc/pki/elasticfleet-logstash.key) @@ -48,6 +92,11 @@ curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fl printf "\n\n" {%- endif %} +printf "\nCreate Kafka Output Config if node is not an Import or Eval install\n" +{% if grains.role not in ['so-import', 'so-eval'] %} +/usr/sbin/so-kafka-fleet-output-policy +{% endif %} + # Add Manager Hostname & URL Base to Fleet Host URLs printf "\nAdd SO-Manager Fleet URL\n" if [ "{{ GLOBALS.hostname }}" = "{{ GLOBALS.url_base }}" ]; then @@ -67,16 +116,6 @@ printf "\n\n" # Load Elasticsearch templates /usr/sbin/so-elasticsearch-templates-load -# Manager Fleet Server Host -elastic_fleet_policy_create "FleetServer_{{ GLOBALS.hostname }}" "Fleet Server - {{ GLOBALS.hostname }}" "true" "120" - -#Temp Fixup for ES Output bug -JSON_STRING=$( jq -n \ - --arg NAME "FleetServer_{{ GLOBALS.hostname }}" \ - '{"name": $NAME,"description": $NAME,"namespace":"default","monitoring_enabled":["logs"],"inactivity_timeout":120,"data_output_id":"so-manager_elasticsearch"}' - ) -curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/agent_policies/FleetServer_{{ GLOBALS.hostname }}" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" - # Initial Endpoints Policy elastic_fleet_policy_create "endpoints-initial" "Initial Endpoint Policy" "false" "1209600" @@ -131,4 +170,4 @@ salt-call state.apply elasticfleet queue=True # Generate installers & install Elastic Agent on the node so-elastic-agent-gen-installers salt-call state.apply elasticfleet.install_agent_grid queue=True -exit 0 \ No newline at end of file +exit 0 diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-urls-update b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-urls-update index 31c7becca..5f7637cd3 100644 --- a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-urls-update +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-urls-update @@ -1,3 +1,5 @@ +#!/bin/bash + # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # or more contributor license agreements. Licensed under the Elastic License 2.0; you may not use # this file except in compliance with the Elastic License 2.0. diff --git a/salt/elasticfleet/tools/sbin_jinja/so-kafka-fleet-output-policy b/salt/elasticfleet/tools/sbin_jinja/so-kafka-fleet-output-policy new file mode 100644 index 000000000..a5ea79922 --- /dev/null +++ b/salt/elasticfleet/tools/sbin_jinja/so-kafka-fleet-output-policy @@ -0,0 +1,52 @@ +#!/bin/bash +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% if GLOBALS.role in ['so-manager', 'so-standalone', 'so-managersearch'] %} + +. /usr/sbin/so-common + +# Check to make sure that Kibana API is up & ready +RETURN_CODE=0 +wait_for_web_response "http://localhost:5601/api/fleet/settings" "fleet" 300 "curl -K /opt/so/conf/elasticsearch/curl.config" +RETURN_CODE=$? + +if [[ "$RETURN_CODE" != "0" ]]; then + printf "Kibana API not accessible, can't setup Elastic Fleet output policy for Kafka..." + exit 1 +fi + +output=$(curl -sK /opt/so/conf/elasticsearch/curl.config -L "http://localhost:5601/api/fleet/outputs" | jq -r .items[].id) + +if ! echo "$output" | grep -q "so-manager_kafka"; then + KAFKACRT=$(openssl x509 -in /etc/pki/elasticfleet-kafka.crt) + KAFKAKEY=$(openssl rsa -in /etc/pki/elasticfleet-kafka.key) + KAFKACA=$(openssl x509 -in /etc/pki/tls/certs/intca.crt) + KAFKA_OUTPUT_VERSION="2.6.0" + JSON_STRING=$( jq -n \ + --arg KAFKACRT "$KAFKACRT" \ + --arg KAFKAKEY "$KAFKAKEY" \ + --arg KAFKACA "$KAFKACA" \ + --arg MANAGER_IP "{{ GLOBALS.manager_ip }}:9092" \ + --arg KAFKA_OUTPUT_VERSION "$KAFKA_OUTPUT_VERSION" \ + '{ "name": "grid-kafka", "id": "so-manager_kafka", "type": "kafka", "hosts": [ $MANAGER_IP ], "is_default": false, "is_default_monitoring": false, "config_yaml": "", "ssl": { "certificate_authorities": [ $KAFKACA ], "certificate": $KAFKACRT, "key": $KAFKAKEY, "verification_mode": "full" }, "proxy_id": null, "client_id": "Elastic", "version": $KAFKA_OUTPUT_VERSION, "compression": "none", "auth_type": "ssl", "partition": "round_robin", "round_robin": { "group_events": 10 }, "topics":[{"topic":"default-securityonion"}], "headers": [ { "key": "", "value": "" } ], "timeout": 30, "broker_timeout": 30, "required_acks": 1 }' + ) + curl -sK /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/outputs" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" -o /dev/null + refresh_output=$(curl -sK /opt/so/conf/elasticsearch/curl.config -L "http://localhost:5601/api/fleet/outputs" | jq -r .items[].id) + + if ! echo "$refresh_output" | grep -q "so-manager_kafka"; then + echo -e "\nFailed to setup Elastic Fleet output policy for Kafka...\n" + exit 1 + elif echo "$refresh_output" | grep -q "so-manager_kafka"; then + echo -e "\nSuccessfully setup Elastic Fleet output policy for Kafka...\n" + fi + +elif echo "$output" | grep -q "so-manager_kafka"; then + echo -e "\nElastic Fleet output policy for Kafka already exists...\n" +fi +{% else %} +echo -e "\nNo update required...\n" +{% endif %} \ No newline at end of file diff --git a/salt/elasticsearch/auth.sls b/salt/elasticsearch/auth.sls index f3aefa6b9..a7de4ef8f 100644 --- a/salt/elasticsearch/auth.sls +++ b/salt/elasticsearch/auth.sls @@ -15,7 +15,7 @@ elastic_auth_pillar: file.managed: - name: /opt/so/saltstack/local/pillar/elasticsearch/auth.sls - - mode: 600 + - mode: 640 - reload_pillar: True - contents: | elasticsearch: diff --git a/salt/elasticsearch/ca.sls b/salt/elasticsearch/ca.sls index 5485bb676..188450311 100644 --- a/salt/elasticsearch/ca.sls +++ b/salt/elasticsearch/ca.sls @@ -4,7 +4,7 @@ # Elastic License 2.0. {% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls.split('.')[0] in allowed_states %} +{% if sls.split('.')[0] in allowed_states or sls in allowed_states %} {% from 'vars/globals.map.jinja' import GLOBALS %} # Move our new CA over so Elastic and Logstash can use SSL with the internal CA diff --git a/salt/elasticsearch/config.map.jinja b/salt/elasticsearch/config.map.jinja index 4e57199af..cfbab8524 100644 --- a/salt/elasticsearch/config.map.jinja +++ b/salt/elasticsearch/config.map.jinja @@ -1,23 +1,37 @@ +{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one + or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at + https://securityonion.net/license; you may not use this file except in compliance with the + Elastic License 2.0. #} + {% from 'vars/globals.map.jinja' import GLOBALS %} {% import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS with context %} {% set HIGHLANDER = salt['pillar.get']('global:highlander', False) %} -{# ES_LOGSTASH_NODES is the same as LOGSTASH_NODES from logstash/map.jinja but heavynodes and fleet nodes are removed #} -{% set ES_LOGSTASH_NODES = [] %} -{% set node_data = salt['pillar.get']('logstash:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %} +{# this is a list of dicts containing hostname:ip for elasticsearch nodes that need to know about each other for cluster #} +{% set ELASTICSEARCH_SEED_HOSTS = [] %} +{% set node_data = salt['pillar.get']('elasticsearch:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %} {% for node_type, node_details in node_data.items() | sort %} -{% if node_type not in ['heavynode', 'fleet'] %} +{% if node_type != 'heavynode' %} {% for hostname in node_data[node_type].keys() %} -{% do ES_LOGSTASH_NODES.append({hostname:node_details[hostname].ip}) %} +{% do ELASTICSEARCH_SEED_HOSTS.append({hostname:node_details[hostname].ip}) %} {% endfor %} {% endif %} {% endfor %} -{% if grains.id.split('_') | last in ['manager','managersearch','standalone'] %} - {% if ES_LOGSTASH_NODES | length > 1 %} +{# this is a list of dicts containing hostname:ip of all nodes running elasticsearch #} +{% set ELASTICSEARCH_NODES = [] %} +{% set node_data = salt['pillar.get']('elasticsearch:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %} +{% for node_type, node_details in node_data.items() %} +{% for hostname in node_data[node_type].keys() %} +{% do ELASTICSEARCH_NODES.append({hostname:node_details[hostname].ip}) %} +{% endfor %} +{% endfor %} + +{% if grains.id.split('_') | last in ['manager','managerhype','managersearch','standalone'] %} + {% if ELASTICSEARCH_SEED_HOSTS | length > 1 %} {% do ELASTICSEARCHDEFAULTS.elasticsearch.config.update({'discovery': {'seed_hosts': []}}) %} - {% for NODE in ES_LOGSTASH_NODES %} + {% for NODE in ELASTICSEARCH_SEED_HOSTS %} {% do ELASTICSEARCHDEFAULTS.elasticsearch.config.discovery.seed_hosts.append(NODE.keys()|first) %} {% endfor %} {% endif %} diff --git a/salt/elasticsearch/config.sls b/salt/elasticsearch/config.sls index 23e11a710..147975bb1 100644 --- a/salt/elasticsearch/config.sls +++ b/salt/elasticsearch/config.sls @@ -47,6 +47,7 @@ elasticsearch_sbin: - file_mode: 755 - exclude_pat: - so-elasticsearch-pipelines # exclude this because we need to watch it for changes, we sync it in another state + - show_changes: False elasticsearch_sbin_jinja: file.recurse: @@ -60,6 +61,7 @@ elasticsearch_sbin_jinja: - so-elasticsearch-ilm-policy-load # exclude this because we need to watch it for changes, we sync it in another state - defaults: GLOBALS: {{ GLOBALS }} + - show_changes: False so-elasticsearch-ilm-policy-load-script: file.managed: @@ -69,6 +71,7 @@ so-elasticsearch-ilm-policy-load-script: - group: 939 - mode: 754 - template: jinja + - show_changes: False so-elasticsearch-pipelines-script: file.managed: @@ -77,6 +80,7 @@ so-elasticsearch-pipelines-script: - user: 930 - group: 939 - mode: 754 + - show_changes: False esingestdir: file.directory: @@ -110,6 +114,7 @@ esingestdynamicconf: - user: 930 - group: 939 - template: jinja + - show_changes: False esingestconf: file.recurse: @@ -117,6 +122,25 @@ esingestconf: - source: salt://elasticsearch/files/ingest - user: 930 - group: 939 + - show_changes: False + +# Remove .fleet_final_pipeline-1 because we are using global@custom now +so-fleet-final-pipeline-remove: + file.absent: + - name: /opt/so/conf/elasticsearch/ingest/.fleet_final_pipeline-1 + +# Auto-generate Elasticsearch ingest node pipelines from pillar +{% for pipeline, config in ELASTICSEARCHMERGED.pipelines.items() %} +es_ingest_conf_{{pipeline}}: + file.managed: + - name: /opt/so/conf/elasticsearch/ingest/{{ pipeline }} + - source: salt://elasticsearch/base-template.json.jinja + - defaults: + TEMPLATE_CONFIG: {{ config }} + - template: jinja + - onchanges_in: + - file: so-pipelines-reload +{% endfor %} eslog4jfile: file.managed: @@ -135,6 +159,7 @@ esyml: - defaults: ESCONFIG: {{ ELASTICSEARCHMERGED.config }} - template: jinja + - show_changes: False esroles: file.recurse: @@ -144,6 +169,7 @@ esroles: - template: jinja - user: 930 - group: 939 + - show_changes: False nsmesdir: file.directory: diff --git a/salt/elasticsearch/defaults.yaml b/salt/elasticsearch/defaults.yaml index 02c2529a6..1f81e95d2 100644 --- a/salt/elasticsearch/defaults.yaml +++ b/salt/elasticsearch/defaults.yaml @@ -1,4 +1,7 @@ elasticsearch: + enabled: false + version: 8.17.3 + index_clean: true config: action: destructive_requires_name: true @@ -54,7 +57,6 @@ elasticsearch: enabled: true key: /usr/share/elasticsearch/config/elasticsearch.key verification_mode: none - enabled: false index_settings: global_overrides: index_template: @@ -70,7 +72,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -94,6 +96,7 @@ elasticsearch: composed_of: - case-mappings - case-settings + ignore_missing_component_templates: [] index_patterns: - so-case* priority: 500 @@ -108,15 +111,23 @@ elasticsearch: match_mapping_type: string settings: index: + lifecycle: + name: so-case-logs mapping: total_fields: limit: 1500 number_of_replicas: 0 + auto_expand_replicas: 0-2 number_of_shards: 1 refresh_interval: 30s sort: field: '@timestamp' order: desc + policy: + phases: + hot: + actions: {} + min_age: 0ms so-common: close: 30 delete: 365 @@ -151,6 +162,7 @@ elasticsearch: - http-mappings - dtc-http-mappings - log-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -183,6 +195,7 @@ elasticsearch: - common-dynamic-mappings - winlog-mappings data_stream: {} + ignore_missing_component_templates: [] index_patterns: - logs-*-so* priority: 1 @@ -214,7 +227,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -233,6 +246,44 @@ elasticsearch: priority: 50 min_age: 30d warm: 7 + so-detection: + index_sorting: false + index_template: + composed_of: + - detection-mappings + - detection-settings + ignore_missing_component_templates: [] + index_patterns: + - so-detection* + priority: 500 + template: + mappings: + date_detection: false + dynamic_templates: + - strings_as_keyword: + mapping: + ignore_above: 1024 + type: keyword + match_mapping_type: string + settings: + index: + lifecycle: + name: so-detection-logs + mapping: + total_fields: + limit: 1500 + number_of_replicas: 0 + auto_expand_replicas: 0-2 + number_of_shards: 1 + refresh_interval: 1s + sort: + field: '@timestamp' + order: desc + policy: + phases: + hot: + actions: {} + min_age: 0ms so-endgame: index_sorting: false index_template: @@ -266,6 +317,7 @@ elasticsearch: - http-mappings - dtc-http-mappings - log-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -295,6 +347,7 @@ elasticsearch: - common-settings - common-dynamic-mappings - winlog-mappings + ignore_missing_component_templates: [] index_patterns: - endgame* priority: 500 @@ -326,7 +379,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -376,6 +429,7 @@ elasticsearch: - http-mappings - dtc-http-mappings - log-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -400,6 +454,7 @@ elasticsearch: - dtc-user_agent-mappings - common-settings - common-dynamic-mappings + ignore_missing_component_templates: [] index_patterns: - so-idh-* priority: 500 @@ -431,7 +486,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -482,6 +537,7 @@ elasticsearch: - http-mappings - dtc-http-mappings - log-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -512,6 +568,7 @@ elasticsearch: - common-dynamic-mappings - winlog-mappings data_stream: {} + ignore_missing_component_templates: [] index_patterns: - logs-import-so* priority: 500 @@ -544,7 +601,129 @@ elasticsearch: actions: set_priority: priority: 0 + min_age: 60d + delete: + actions: + delete: {} + min_age: 365d + hot: + actions: + rollover: + max_age: 30d + max_primary_shard_size: 50gb + set_priority: + priority: 100 + min_age: 0ms + warm: + actions: + set_priority: + priority: 50 min_age: 30d + so-ip-mappings: + index_sorting: false + index_template: + composed_of: + - so-ip-mappings + ignore_missing_component_templates: [] + index_patterns: + - so-ip* + priority: 500 + template: + mappings: + date_detection: false + dynamic_templates: + - strings_as_keyword: + mapping: + ignore_above: 1024 + type: keyword + match_mapping_type: string + settings: + index: + mapping: + total_fields: + limit: 1500 + lifecycle: + name: so-ip-mappings-logs + number_of_replicas: 0 + number_of_shards: 1 + refresh_interval: 30s + sort: + field: '@timestamp' + order: desc + policy: + phases: + hot: + actions: {} + min_age: 0ms + so-items: + index_sorting: false + index_template: + composed_of: + - so-items-mappings + ignore_missing_component_templates: [] + index_patterns: + - .items-default-** + priority: 500 + template: + mappings: + date_detection: false + settings: + index: + lifecycle: + name: so-items-logs + rollover_alias: .items-default + mapping: + total_fields: + limit: 10000 + number_of_replicas: 0 + number_of_shards: 1 + refresh_interval: 30s + routing: + allocation: + include: + _tier_preference: data_content + sort: + field: '@timestamp' + order: desc + policy: + phases: + hot: + actions: + rollover: + max_size: 50gb + min_age: 0ms + so-kismet: + index_sorting: false + index_template: + composed_of: + - kismet-mappings + - source-mappings + - client-mappings + - device-mappings + - network-mappings + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + data_stream: + allow_custom_routing: false + hidden: false + ignore_missing_component_templates: [] + index_patterns: + - logs-kismet-so* + priority: 501 + template: + settings: + index: + lifecycle: + name: so-kismet-logs + number_of_replicas: 0 + policy: + phases: + cold: + actions: + set_priority: + priority: 0 + min_age: 60d delete: actions: delete: {} @@ -594,6 +773,7 @@ elasticsearch: - http-mappings - dtc-http-mappings - log-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -621,6 +801,7 @@ elasticsearch: data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: [] index_patterns: - logs-kratos-so* priority: 500 @@ -652,7 +833,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -671,11 +852,160 @@ elasticsearch: priority: 50 min_age: 30d warm: 7 + so-hydra: + close: 30 + delete: 365 + index_sorting: false + index_template: + composed_of: + - agent-mappings + - dtc-agent-mappings + - base-mappings + - dtc-base-mappings + - client-mappings + - dtc-client-mappings + - container-mappings + - destination-mappings + - dtc-destination-mappings + - pb-override-destination-mappings + - dll-mappings + - dns-mappings + - dtc-dns-mappings + - ecs-mappings + - dtc-ecs-mappings + - error-mappings + - event-mappings + - dtc-event-mappings + - file-mappings + - dtc-file-mappings + - group-mappings + - host-mappings + - dtc-host-mappings + - http-mappings + - dtc-http-mappings + - log-mappings + - metadata-mappings + - network-mappings + - dtc-network-mappings + - observer-mappings + - dtc-observer-mappings + - organization-mappings + - package-mappings + - process-mappings + - dtc-process-mappings + - related-mappings + - rule-mappings + - dtc-rule-mappings + - server-mappings + - service-mappings + - dtc-service-mappings + - source-mappings + - dtc-source-mappings + - pb-override-source-mappings + - threat-mappings + - tls-mappings + - url-mappings + - user_agent-mappings + - dtc-user_agent-mappings + - common-settings + - common-dynamic-mappings + data_stream: + allow_custom_routing: false + hidden: false + ignore_missing_component_templates: [] + index_patterns: + - logs-hydra-so* + priority: 500 + template: + mappings: + date_detection: false + dynamic_templates: + - strings_as_keyword: + mapping: + ignore_above: 1024 + type: keyword + match_mapping_type: string + settings: + index: + lifecycle: + name: so-hydra-logs + mapping: + total_fields: + limit: 5000 + number_of_replicas: 0 + number_of_shards: 1 + refresh_interval: 30s + sort: + field: '@timestamp' + order: desc + policy: + phases: + cold: + actions: + set_priority: + priority: 0 + min_age: 60d + delete: + actions: + delete: {} + min_age: 365d + hot: + actions: + rollover: + max_age: 30d + max_primary_shard_size: 50gb + set_priority: + priority: 100 + min_age: 0ms + warm: + actions: + set_priority: + priority: 50 + min_age: 30d + warm: 7 + so-lists: + index_sorting: false + index_template: + composed_of: + - so-lists-mappings + ignore_missing_component_templates: [] + index_patterns: + - .lists-default-** + priority: 500 + template: + mappings: + date_detection: false + settings: + index: + lifecycle: + name: so-lists-logs + rollover_alias: .lists-default + mapping: + total_fields: + limit: 10000 + number_of_replicas: 0 + number_of_shards: 1 + refresh_interval: 30s + routing: + allocation: + include: + _tier_preference: data_content + sort: + field: '@timestamp' + order: desc + policy: + phases: + hot: + actions: + rollover: + max_size: 50gb + min_age: 0ms so-logs: index_sorting: false index_template: composed_of: - so-data-streams-mappings + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 - so-logs-mappings @@ -683,6 +1013,7 @@ elasticsearch: data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: [] index_patterns: - logs-*-* priority: 225 @@ -715,7 +1046,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -733,33 +1064,52 @@ elasticsearch: set_priority: priority: 50 min_age: 30d - so-logs-1password_x_item_usages: + so-logs-detections_x_alerts: index_sorting: false index_template: composed_of: - - logs-1password.item_usages@package - - logs-1password.item_usages@custom + - so-data-streams-mappings - so-fleet_globals-1 - so-fleet_agent_id_verification-1 + - so-logs-mappings + - so-logs-settings data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: [] index_patterns: - - logs-1password.item_usages-* + - logs-detections.alerts-* priority: 501 template: + mappings: + _meta: + managed: true + managed_by: security_onion + package: + name: elastic_agent settings: index: lifecycle: - name: so-logs-1password.item_usages-logs + name: so-logs-detections.alerts-so + mapping: + total_fields: + limit: 5001 number_of_replicas: 0 + sort: + field: '@timestamp' + order: desc policy: + _meta: + managed: true + managed_by: security_onion + package: + name: elastic_agent phases: cold: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -767,1943 +1117,7 @@ elasticsearch: hot: actions: rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-1password_x_signin_attempts: - index_sorting: false - index_template: - composed_of: - - logs-1password.signin_attempts@package - - logs-1password.signin_attempts@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-1password.signin_attempts-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-1password.signin_attempts-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-apache_x_access: - index_sorting: false - index_template: - composed_of: - - logs-apache.access@package - - logs-apache.access@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-apache.access-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-apache.access-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-apache_x_error: - index_sorting: false - index_template: - composed_of: - - logs-apache.error@package - - logs-apache.error@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-apache.error-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-apache.error-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-auditd_x_log: - index_sorting: false - index_template: - composed_of: - - logs-auditd.log@package - - logs-auditd.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-auditd.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-auditd.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-auth0_x_logs: - index_sorting: false - index_template: - composed_of: - - logs-auth0.logs@package - - logs-auth0.logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-auth0.logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-auth0.logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-aws_x_cloudtrail: - index_sorting: false - index_template: - composed_of: - - logs-aws.cloudtrail@package - - logs-aws.cloudtrail@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-aws.cloudtrail-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-aws.cloudtrail-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-aws_x_cloudwatch_logs: - index_sorting: false - index_template: - composed_of: - - logs-aws.cloudwatch_logs@package - - logs-aws.cloudwatch_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-aws.cloudwatch_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-aws.cloudwatch_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-aws_x_ec2_logs: - index_sorting: false - index_template: - composed_of: - - logs-aws.ec2_logs@package - - logs-aws.ec2_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-aws.ec2_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-aws.ec2_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-aws_x_elb_logs: - index_sorting: false - index_template: - composed_of: - - logs-aws.elb_logs@package - - logs-aws.elb_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-aws.elb_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-aws.elb_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-aws_x_firewall_logs: - index_sorting: false - index_template: - composed_of: - - logs-aws.firewall_logs@package - - logs-aws.firewall_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-aws.firewall_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-aws.firewall_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-aws_x_route53_public_logs: - index_sorting: false - index_template: - composed_of: - - logs-aws.route53_public_logs@package - - logs-aws.route53_public_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-aws.route53_public_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-aws.route53_public_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-aws_x_route53_resolver_logs: - index_sorting: false - index_template: - composed_of: - - logs-aws.route53_resolver_logs@package - - logs-aws.route53_resolver_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-aws.route53_resolver_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-aws.route53_resolver_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-aws_x_s3access: - index_sorting: false - index_template: - composed_of: - - logs-aws.s3access@package - - logs-aws.s3access@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-aws.s3access-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-aws.s3access-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-aws_x_vpcflow: - index_sorting: false - index_template: - composed_of: - - logs-aws.vpcflow@package - - logs-aws.vpcflow@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-aws.vpcflow-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-aws.vpcflow-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-aws_x_waf: - index_sorting: false - index_template: - composed_of: - - logs-aws.waf@package - - logs-aws.waf@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-aws.waf-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-aws.waf-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-azure_x_activitylogs: - index_sorting: false - index_template: - composed_of: - - logs-azure.activitylogs@package - - logs-azure.activitylogs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-azure.activitylogs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-azure.activitylogs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-azure_x_application_gateway: - index_sorting: false - index_template: - composed_of: - - logs-azure.application_gateway@package - - logs-azure.application_gateway@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-azure.application_gateway-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-azure.application_gateway-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-azure_x_auditlogs: - index_sorting: false - index_template: - composed_of: - - logs-azure.auditlogs@package - - logs-azure.auditlogs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-azure.auditlogs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-azure.auditlogs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-azure_x_eventhub: - index_sorting: false - index_template: - composed_of: - - logs-azure.eventhub@package - - logs-azure.eventhub@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-azure.eventhub-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-azure.eventhub-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-azure_x_firewall_logs: - index_sorting: false - index_template: - composed_of: - - logs-azure.firewall_logs@package - - logs-azure.firewall_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-azure.firewall_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-azure.firewall_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-azure_x_identity_protection: - index_sorting: false - index_template: - composed_of: - - logs-azure.identity_protection@package - - logs-azure.identity_protection@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-azure.identity_protection-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-azure.identity_protection-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-azure_x_platformlogs: - index_sorting: false - index_template: - composed_of: - - logs-azure.platformlogs@package - - logs-azure.platformlogs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-azure.platformlogs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-azure.platformlogs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-azure_x_provisioning: - index_sorting: false - index_template: - composed_of: - - logs-azure.provisioning@package - - logs-azure.provisioning@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-azure.provisioning-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-azure.provisioning-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-azure_x_signinlogs: - index_sorting: false - index_template: - composed_of: - - logs-azure.signinlogs@package - - logs-azure.signinlogs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-azure.signinlogs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-azure.signinlogs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-azure_x_springcloudlogs: - index_sorting: false - index_template: - composed_of: - - logs-azure.springcloudlogs@package - - logs-azure.springcloudlogs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-azure.springcloudlogs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-azure.springcloudlogs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-barracuda_x_waf: - index_sorting: false - index_template: - composed_of: - - logs-barracuda.waf@package - - logs-barracuda.waf@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-barracuda.waf-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-barracuda.waf-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-carbonblack_edr_x_log: - index_sorting: false - index_template: - composed_of: - - logs-carbonblack_edr.log@package - - logs-carbonblack_edr.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-carbonblack_edr.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-carbonblack_edr.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-checkpoint_x_firewall: - index_sorting: False - index_template: - index_patterns: - - "logs-checkpoint.firewall-*" - template: - settings: - index: - lifecycle: - name: so-logs-checkpoint.firewall-logs - number_of_replicas: 0 - composed_of: - - "logs-checkpoint.firewall@package" - - "logs-checkpoint.firewall@custom" - - "so-fleet_globals-1" - - "so-fleet_agent_id_verification-1" - priority: 501 - data_stream: - hidden: false - allow_custom_routing: false - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cisco_asa_x_log: - index_sorting: false - index_template: - composed_of: - - logs-cisco_asa.log@package - - logs-cisco_asa.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cisco_asa.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cisco_asa.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cisco_duo_x_admin: - index_sorting: false - index_template: - composed_of: - - logs-cisco_duo.admin@package - - logs-cisco_duo.admin@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cisco_duo.admin-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cisco_duo.admin-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cisco_duo_x_auth: - index_sorting: false - index_template: - composed_of: - - logs-cisco_duo.auth@package - - logs-cisco_duo.auth@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cisco_duo.auth-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cisco_duo.auth-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cisco_duo_x_offline_enrollment: - index_sorting: false - index_template: - composed_of: - - logs-cisco_duo.offline_enrollment@package - - logs-cisco_duo.offline_enrollment@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cisco_duo.offline_enrollment-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cisco_duo.offline_enrollment-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cisco_duo_x_summary: - index_sorting: false - index_template: - composed_of: - - logs-cisco_duo.summary@package - - logs-cisco_duo.summary@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cisco_duo.summary-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cisco_duo.summary-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cisco_duo_x_telephony: - index_sorting: false - index_template: - composed_of: - - logs-cisco_duo.telephony@package - - logs-cisco_duo.telephony@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cisco_duo.telephony-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cisco_duo.telephony-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cisco_meraki_x_events: - index_sorting: false - index_template: - composed_of: - - logs-cisco_meraki.events@package - - logs-cisco_meraki.events@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cisco_meraki.events-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cisco_meraki.events-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cisco_meraki_x_log: - index_sorting: false - index_template: - composed_of: - - logs-cisco_meraki.log@package - - logs-cisco_meraki.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cisco_meraki.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cisco_meraki.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cisco_umbrella_x_log: - index_sorting: false - index_template: - composed_of: - - logs-cisco_umbrella.log@package - - logs-cisco_umbrella.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cisco_umbrella.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cisco_umbrella.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cloudflare_x_audit: - index_sorting: false - index_template: - composed_of: - - logs-cloudflare.audit@package - - logs-cloudflare.audit@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cloudflare.audit-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cloudflare.audit-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-cloudflare_x_logpull: - index_sorting: false - index_template: - composed_of: - - logs-cloudflare.logpull@package - - logs-cloudflare.logpull@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-cloudflare.logpull-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-cloudflare.logpull-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-crowdstrike_x_falcon: - index_sorting: false - index_template: - composed_of: - - logs-crowdstrike.falcon@package - - logs-crowdstrike.falcon@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-crowdstrike.falcon-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-crowdstrike.falcon-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-crowdstrike_x_fdr: - index_sorting: false - index_template: - composed_of: - - logs-crowdstrike.fdr@package - - logs-crowdstrike.fdr@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-crowdstrike.fdr-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-crowdstrike.fdr-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-darktrace_x_ai_analyst_alert: - index_sorting: false - index_template: - composed_of: - - logs-darktrace.ai_analyst_alert@package - - logs-darktrace.ai_analyst_alert@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-darktrace.ai_analyst_alert-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-darktrace.ai_analyst_alert-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-darktrace_x_model_breach_alert: - index_sorting: false - index_template: - composed_of: - - logs-darktrace.model_breach_alert@package - - logs-darktrace.model_breach_alert@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-darktrace.model_breach_alert-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-darktrace.model_breach_alert-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-darktrace_x_system_status_alert: - index_sorting: false - index_template: - composed_of: - - logs-darktrace.system_status_alert@package - - logs-darktrace.system_status_alert@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-darktrace.system_status_alert-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-darktrace.system_status_alert-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d + max_age: 1d max_primary_shard_size: 50gb set_priority: priority: 100 @@ -2720,11 +1134,14 @@ elasticsearch: - event-mappings - logs-elastic_agent@package - logs-elastic_agent@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-elastic_agent@custom index_patterns: - logs-elastic_agent-* priority: 501 @@ -2737,15 +1154,65 @@ elasticsearch: name: elastic_agent settings: index: + codec: best_compression lifecycle: name: so-logs-elastic_agent-logs mapping: total_fields: limit: 5000 + ignore_malformed: true number_of_replicas: 0 sort: field: '@timestamp' order: desc + query: + default_field: + - cloud.account.id + - cloud.availability_zone + - cloud.instance.id + - cloud.instance.name + - cloud.machine.type + - cloud.provider + - cloud.region + - cloud.project.id + - cloud.image.id + - container.id + - container.image.name + - container.name + - host.architecture + - host.hostname + - host.id + - host.mac + - host.name + - host.os.family + - host.os.kernel + - host.os.name + - host.os.platform + - host.os.version + - host.os.build + - host.os.codename + - host.type + - ecs.version + - agent.build.original + - agent.ephemeral_id + - agent.id + - agent.name + - agent.type + - agent.version + - log.level + - message + - elastic_agent.id + - elastic_agent.process + - elastic_agent.version + - component.id + - component.type + - component.binary + - component.state + - component.old_state + - unit.id + - unit.type + - unit.state + - unit.old_state policy: _meta: managed: true @@ -2757,7 +1224,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -2781,11 +1248,14 @@ elasticsearch: composed_of: - logs-elastic_agent.apm_server@package - logs-elastic_agent.apm_server@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-elastic_agent.apm_server@custom index_patterns: - logs-elastic_agent.apm_server-* priority: 501 @@ -2818,7 +1288,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -2842,11 +1312,14 @@ elasticsearch: composed_of: - logs-elastic_agent.auditbeat@package - logs-elastic_agent.auditbeat@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-elastic_agent.auditbeat@custom index_patterns: - logs-elastic_agent.auditbeat-* priority: 501 @@ -2879,7 +1352,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -2903,8 +1376,11 @@ elasticsearch: composed_of: - logs-elastic_agent.cloudbeat@package - logs-elastic_agent.cloudbeat@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 + ignore_missing_component_templates: + - logs-elastic_agent.cloudbeat@custom index_patterns: - logs-elastic_agent.cloudbeat-* priority: 501 @@ -2937,7 +1413,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -2962,11 +1438,14 @@ elasticsearch: - event-mappings - logs-elastic_agent.endpoint_security@package - logs-elastic_agent.endpoint_security@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-elastic_agent.endpoint_security@custom index_patterns: - logs-elastic_agent.endpoint_security-* priority: 501 @@ -2993,7 +1472,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3018,11 +1497,14 @@ elasticsearch: - event-mappings - logs-elastic_agent.filebeat@package - logs-elastic_agent.filebeat@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-elastic_agent.filebeat@custom index_patterns: - logs-elastic_agent.filebeat-* priority: 501 @@ -3049,7 +1531,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3074,11 +1556,14 @@ elasticsearch: - event-mappings - logs-elastic_agent.fleet_server@package - logs-elastic_agent.fleet_server@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-elastic_agent.fleet_server@custom index_patterns: - logs-elastic_agent.fleet_server-* priority: 501 @@ -3102,7 +1587,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3126,8 +1611,11 @@ elasticsearch: composed_of: - logs-elastic_agent.heartbeat@package - logs-elastic_agent.heartbeat@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 + ignore_missing_component_templates: + - logs-elastic_agent.heartbeat@custom index_patterns: - logs-elastic_agent.heartbeat-* priority: 501 @@ -3160,7 +1648,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3185,11 +1673,14 @@ elasticsearch: - event-mappings - logs-elastic_agent.metricbeat@package - logs-elastic_agent.metricbeat@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-elastic_agent.metricbeat@custom index_patterns: - logs-elastic_agent.metricbeat-* priority: 501 @@ -3216,7 +1707,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3241,11 +1732,14 @@ elasticsearch: - event-mappings - logs-elastic_agent.osquerybeat@package - logs-elastic_agent.osquerybeat@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-elastic_agent.osquerybeat@custom index_patterns: - logs-elastic_agent.osquerybeat-* priority: 501 @@ -3272,7 +1766,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3296,11 +1790,14 @@ elasticsearch: composed_of: - logs-elastic_agent.packetbeat@package - logs-elastic_agent.packetbeat@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-elastic_agent.packetbeat@custom index_patterns: - logs-elastic_agent.packetbeat-* priority: 501 @@ -3333,7 +1830,125 @@ elasticsearch: actions: set_priority: priority: 0 + min_age: 60d + delete: + actions: + delete: {} + min_age: 365d + hot: + actions: + rollover: + max_age: 30d + max_primary_shard_size: 50gb + set_priority: + priority: 100 + min_age: 0ms + warm: + actions: + set_priority: + priority: 50 min_age: 30d + so-logs-endpoint_x_actions: + index_sorting: false + index_template: + composed_of: + - .logs-endpoint.actions@package + - .logs-endpoint.actions@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + data_stream: + allow_custom_routing: false + hidden: false + ignore_missing_component_templates: + - .logs-endpoint.actions@custom + index_patterns: + - logs-endpoint.actions-* + priority: 501 + template: + settings: + index: + lifecycle: + name: so-logs-endpoint.actions-logs + mapping: + total_fields: + limit: 5000 + number_of_replicas: 0 + sort: + field: '@timestamp' + order: desc + policy: + _meta: + managed: true + managed_by: security_onion + package: + name: elastic_agent + phases: + cold: + actions: + set_priority: + priority: 0 + min_age: 60d + delete: + actions: + delete: {} + min_age: 365d + hot: + actions: + rollover: + max_age: 30d + max_primary_shard_size: 50gb + set_priority: + priority: 100 + min_age: 0ms + warm: + actions: + set_priority: + priority: 50 + min_age: 30d + so-logs-endpoint_x_action_x_responses: + index_sorting: false + index_template: + composed_of: + - .logs-endpoint.action.responses@package + - .logs-endpoint.action.responses@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + data_stream: + allow_custom_routing: false + hidden: false + ignore_missing_component_templates: + - .logs-endpoint.action.responses@custom + index_patterns: + - logs-endpoint.action.responses-* + priority: 501 + template: + settings: + index: + lifecycle: + name: so-logs-endpoint.actions-logs + mapping: + total_fields: + limit: 5000 + number_of_replicas: 0 + sort: + field: '@timestamp' + order: desc + policy: + _meta: + managed: true + managed_by: security_onion + package: + name: elastic_agent + phases: + cold: + actions: + set_priority: + priority: 0 + min_age: 60d delete: actions: delete: {} @@ -3355,14 +1970,17 @@ elasticsearch: index_sorting: false index_template: composed_of: - - event-mappings - - logs-endpoint.alerts@custom - logs-endpoint.alerts@package + - logs-endpoint.alerts@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-endpoint.alerts@custom index_patterns: - logs-endpoint.alerts-* priority: 501 @@ -3389,7 +2007,82 @@ elasticsearch: actions: set_priority: priority: 0 + min_age: 60d + delete: + actions: + delete: {} + min_age: 365d + hot: + actions: + rollover: + max_age: 30d + max_primary_shard_size: 50gb + set_priority: + priority: 100 + min_age: 0ms + warm: + actions: + set_priority: + priority: 50 min_age: 30d + so-logs-endpoint_x_diagnostic_x_collection: + index_sorting: false + index_template: + composed_of: + - .logs-endpoint.diagnostic.collection@package + - .logs-endpoint.diagnostic.collection@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + data_stream: + allow_custom_routing: false + hidden: false + ignore_missing_component_templates: + - .logs-endpoint.diagnostic.collection@custom + index_patterns: + - .logs-endpoint.diagnostic.collection-* + priority: 501 + template: + settings: + index: + codec: best_compression + lifecycle: + name: so-logs-endpoint.diagnostic.collection-logs + mapping: + total_fields: + limit: 5000 + ignore_malformed: true + number_of_replicas: 0 + sort: + field: '@timestamp' + order: desc + query: + default_field: + - ecs.version + - event.action + - event.category + - event.code + - event.dataset + - event.hash + - event.id + - event.kind + - event.module + - event.outcome + - event.provider + - event.type + policy: + _meta: + managed: true + managed_by: security_onion + package: + name: elastic_agent + phases: + cold: + actions: + set_priority: + priority: 0 + min_age: 60d delete: actions: delete: {} @@ -3411,14 +2104,17 @@ elasticsearch: index_sorting: false index_template: composed_of: - - event-mappings - - logs-endpoint.events.api@custom - logs-endpoint.events.api@package + - logs-endpoint.events.api@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-endpoint.events.api@custom index_patterns: - logs-endpoint.events.api-* priority: 501 @@ -3445,7 +2141,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3467,14 +2163,17 @@ elasticsearch: index_sorting: false index_template: composed_of: - - event-mappings - - logs-endpoint.events.file@custom - logs-endpoint.events.file@package + - logs-endpoint.events.file@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-endpoint.events.file@custom index_patterns: - logs-endpoint.events.file-* priority: 501 @@ -3501,7 +2200,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3523,14 +2222,17 @@ elasticsearch: index_sorting: false index_template: composed_of: - - event-mappings - - logs-endpoint.events.library@custom - logs-endpoint.events.library@package + - logs-endpoint.events.library@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-endpoint.events.library@custom index_patterns: - logs-endpoint.events.library-* priority: 501 @@ -3557,7 +2259,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3579,14 +2281,17 @@ elasticsearch: index_sorting: false index_template: composed_of: - - event-mappings - - logs-endpoint.events.network@custom - logs-endpoint.events.network@package + - logs-endpoint.events.network@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-endpoint.events.network@custom index_patterns: - logs-endpoint.events.network-* priority: 501 @@ -3613,7 +2318,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3635,14 +2340,17 @@ elasticsearch: index_sorting: false index_template: composed_of: - - event-mappings - - logs-endpoint.events.process@custom - logs-endpoint.events.process@package + - logs-endpoint.events.process@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-endpoint.events.process@custom index_patterns: - logs-endpoint.events.process-* priority: 501 @@ -3669,7 +2377,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3691,14 +2399,17 @@ elasticsearch: index_sorting: false index_template: composed_of: - - event-mappings - - logs-endpoint.events.registry@custom - logs-endpoint.events.registry@package + - logs-endpoint.events.registry@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-endpoint.events.registry@custom index_patterns: - logs-endpoint.events.registry-* priority: 501 @@ -3725,7 +2436,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3747,14 +2458,17 @@ elasticsearch: index_sorting: false index_template: composed_of: - - event-mappings - - logs-endpoint.events.security@custom - logs-endpoint.events.security@package + - logs-endpoint.events.security@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-endpoint.events.security@custom index_patterns: - logs-endpoint.events.security-* priority: 501 @@ -3781,7 +2495,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -3799,1397 +2513,48 @@ elasticsearch: set_priority: priority: 50 min_age: 30d - so-logs-f5_bigip_x_log: + so-logs-endpoint_x_heartbeat: index_sorting: false index_template: composed_of: - - logs-f5_bigip.log@package - - logs-f5_bigip.log@custom + - .logs-endpoint.heartbeat@package + - .logs-endpoint.heartbeat@custom + - event-mappings + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - .logs-endpoint.heartbeat@custom index_patterns: - - logs-f5_bigip.log-* + - .logs-endpoint.heartbeat-* priority: 501 template: settings: index: lifecycle: - name: so-logs-f5_bigip.log-logs + name: so-logs-endpoint.heartbeat-logs + mapping: + total_fields: + limit: 5000 number_of_replicas: 0 + sort: + field: '@timestamp' + order: desc policy: + _meta: + managed: true + managed_by: security_onion + package: + name: elastic_agent phases: cold: actions: set_priority: priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-fim_x_event: - index_sorting: false - index_template: - composed_of: - - logs-fim.event@package - - logs-fim.event@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-fim.event-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-fim.event-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-fireeye_x_nx: - index_sorting: false - index_template: - composed_of: - - logs-fireeye.nx@package - - logs-fireeye.nx@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-fireeye.nx-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-fireeye.nx-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-fortinet_fortigate_x_log: - index_sorting: false - index_template: - composed_of: - - logs-fortinet_fortigate.log@package - - logs-fortinet_fortigate.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-fortinet_fortigate.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-fortinet_fortigate.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-fortinet_x_clientendpoint: - index_sorting: false - index_template: - composed_of: - - logs-fortinet.clientendpoint@package - - logs-fortinet.clientendpoint@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-fortinet.clientendpoint-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-fortinet.clientendpoint-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-fortinet_x_firewall: - index_sorting: false - index_template: - composed_of: - - logs-fortinet.firewall@package - - logs-fortinet.firewall@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-fortinet.firewall-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-fortinet.firewall-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-fortinet_x_fortimail: - index_sorting: false - index_template: - composed_of: - - logs-fortinet.fortimail@package - - logs-fortinet.fortimail@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-fortinet.fortimail-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-fortinet.fortimail-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-fortinet_x_fortimanager: - index_sorting: false - index_template: - composed_of: - - logs-fortinet.fortimanager@package - - logs-fortinet.fortimanager@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-fortinet.fortimanager-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-fortinet.fortimanager-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-gcp_x_audit: - index_sorting: false - index_template: - composed_of: - - logs-gcp.audit@package - - logs-gcp.audit@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-gcp.audit-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-gcp.audit-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-gcp_x_dns: - index_sorting: false - index_template: - composed_of: - - logs-gcp.dns@package - - logs-gcp.dns@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-gcp.dns-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-gcp.dns-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-gcp_x_firewall: - index_sorting: false - index_template: - composed_of: - - logs-gcp.firewall@package - - logs-gcp.firewall@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-gcp.firewall-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-gcp.firewall-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-gcp_x_loadbalancing_logs: - index_sorting: false - index_template: - composed_of: - - logs-gcp.loadbalancing_logs@package - - logs-gcp.loadbalancing_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-gcp.loadbalancing_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-gcp.loadbalancing_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-gcp_x_vpcflow: - index_sorting: false - index_template: - composed_of: - - logs-gcp.vpcflow@package - - logs-gcp.vpcflow@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-gcp.vpcflow-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-gcp.vpcflow-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-github_x_audit: - index_sorting: false - index_template: - composed_of: - - logs-github.audit@package - - logs-github.audit@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-github.audit-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-github.audit-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-github_x_code_scanning: - index_sorting: false - index_template: - composed_of: - - logs-github.code_scanning@package - - logs-github.code_scanning@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-github.code_scanning-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-github.code_scanning-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-github_x_dependabot: - index_sorting: false - index_template: - composed_of: - - logs-github.dependabot@package - - logs-github.dependabot@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-github.dependabot-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-github.dependabot-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-github_x_issues: - index_sorting: false - index_template: - composed_of: - - logs-github.issues@package - - logs-github.issues@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-github.issues-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-github.issues-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-github_x_secret_scanning: - index_sorting: false - index_template: - composed_of: - - logs-github.secret_scanning@package - - logs-github.secret_scanning@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-github.secret_scanning-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-github.secret_scanning-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_access_transparency: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.access_transparency@package - - logs-google_workspace.access_transparency@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.access_transparency-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.access_transparency-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_admin: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.admin@package - - logs-google_workspace.admin@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.admin-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.admin-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_alert: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.alert@package - - logs-google_workspace.alert@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.alert-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.alert-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_context_aware_access: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.context_aware_access@package - - logs-google_workspace.context_aware_access@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.context_aware_access-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.context_aware_access-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_device: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.device@package - - logs-google_workspace.device@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.device-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.device-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_drive: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.drive@package - - logs-google_workspace.drive@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.drive-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.drive-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_gcp: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.gcp@package - - logs-google_workspace.gcp@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.gcp-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.gcp-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_group_enterprise: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.group_enterprise@package - - logs-google_workspace.group_enterprise@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.group_enterprise-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.group_enterprise-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_groups: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.groups@package - - logs-google_workspace.groups@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.groups-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.groups-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_login: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.login@package - - logs-google_workspace.login@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.login-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.login-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_rules: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.rules@package - - logs-google_workspace.rules@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.rules-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.rules-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_saml: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.saml@package - - logs-google_workspace.saml@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.saml-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.saml-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_token: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.token@package - - logs-google_workspace.token@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.token-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.token-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-google_workspace_x_user_accounts: - index_sorting: false - index_template: - composed_of: - - logs-google_workspace.user_accounts@package - - logs-google_workspace.user_accounts@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-google_workspace.user_accounts-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-google_workspace.user_accounts-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -5213,11 +2578,15 @@ elasticsearch: composed_of: - logs-http_endpoint.generic@package - logs-http_endpoint.generic@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-http_endpoint.generic@package + - logs-http_endpoint.generic@custom index_patterns: - logs-http_endpoint.generic-* priority: 501 @@ -5233,7 +2602,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -5257,11 +2626,14 @@ elasticsearch: composed_of: - logs-httpjson.generic@package - logs-httpjson.generic@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-httpjson.generic@custom index_patterns: - logs-httpjson.generic-* priority: 501 @@ -5277,1063 +2649,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-juniper_srx_x_log: - index_sorting: false - index_template: - composed_of: - - logs-juniper_srx.log@package - - logs-juniper_srx.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-juniper_srx.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-juniper_srx.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-juniper_x_junos: - index_sorting: false - index_template: - composed_of: - - logs-juniper.junos@package - - logs-juniper.junos@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-juniper.junos-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-juniper.junos-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-juniper_x_netscreen: - index_sorting: false - index_template: - composed_of: - - logs-juniper.netscreen@package - - logs-juniper.netscreen@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-juniper.netscreen-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-juniper.netscreen-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-juniper_x_srx: - index_sorting: false - index_template: - composed_of: - - logs-juniper.srx@package - - logs-juniper.srx@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-juniper.srx-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-juniper.srx-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-kafka_log_x_generic: - index_sorting: false - index_template: - composed_of: - - logs-kafka_log.generic@package - - logs-kafka_log.generic@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-kafka_log.generic-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-kafka_log.generic-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-lastpass_x_detailed_shared_folder: - index_sorting: false - index_template: - composed_of: - - logs-lastpass.detailed_shared_folder@package - - logs-lastpass.detailed_shared_folder@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-lastpass.detailed_shared_folder-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-lastpass.detailed_shared_folder-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-lastpass_x_event_report: - index_sorting: false - index_template: - composed_of: - - logs-lastpass.event_report@package - - logs-lastpass.event_report@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-lastpass.event_report-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-lastpass.event_report-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-lastpass_x_user: - index_sorting: false - index_template: - composed_of: - - logs-lastpass.user@package - - logs-lastpass.user@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-lastpass.user-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-lastpass.user-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-m365_defender_x_event: - index_sorting: false - index_template: - composed_of: - - logs-m365_defender.event@package - - logs-m365_defender.event@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-m365_defender.event-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-m365_defender.event-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-m365_defender_x_incident: - index_sorting: false - index_template: - composed_of: - - logs-m365_defender.incident@package - - logs-m365_defender.incident@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-m365_defender.incident-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-m365_defender.incident-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-m365_defender_x_log: - index_sorting: false - index_template: - composed_of: - - logs-m365_defender.log@package - - logs-m365_defender.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-m365_defender.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-m365_defender.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-microsoft_defender_endpoint_x_log: - index_sorting: false - index_template: - composed_of: - - logs-microsoft_defender_endpoint.log@package - - logs-microsoft_defender_endpoint.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-microsoft_defender_endpoint.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-microsoft_defender_endpoint.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-microsoft_dhcp_x_log: - index_sorting: false - index_template: - composed_of: - - logs-microsoft_dhcp.log@package - - logs-microsoft_dhcp.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-microsoft_dhcp.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-microsoft_dhcp.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-mimecast_x_audit_events: - index_sorting: false - index_template: - composed_of: - - logs-mimecast.audit_events@package - - logs-mimecast.audit_events@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-mimecast.audit_events-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-mimecast.audit_events-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-mimecast_x_dlp_logs: - index_sorting: false - index_template: - composed_of: - - logs-mimecast.dlp_logs@package - - logs-mimecast.dlp_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-mimecast.dlp_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-mimecast.dlp_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-mimecast_x_siem_logs: - index_sorting: false - index_template: - composed_of: - - logs-mimecast.siem_logs@package - - logs-mimecast.siem_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-mimecast.siem_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-mimecast.siem_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-mimecast_x_threat_intel_malware_customer: - index_sorting: false - index_template: - composed_of: - - logs-mimecast.threat_intel_malware_customer@package - - logs-mimecast.threat_intel_malware_customer@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-mimecast.threat_intel_malware_customer-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-mimecast.threat_intel_malware_customer-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-mimecast_x_threat_intel_malware_grid: - index_sorting: false - index_template: - composed_of: - - logs-mimecast.threat_intel_malware_grid@package - - logs-mimecast.threat_intel_malware_grid@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-mimecast.threat_intel_malware_grid-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-mimecast.threat_intel_malware_grid-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-mimecast_x_ttp_ap_logs: - index_sorting: false - index_template: - composed_of: - - logs-mimecast.ttp_ap_logs@package - - logs-mimecast.ttp_ap_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-mimecast.ttp_ap_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-mimecast.ttp_ap_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-mimecast_x_ttp_ip_logs: - index_sorting: false - index_template: - composed_of: - - logs-mimecast.ttp_ip_logs@package - - logs-mimecast.ttp_ip_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-mimecast.ttp_ip_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-mimecast.ttp_ip_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-mimecast_x_ttp_url_logs: - index_sorting: false - index_template: - composed_of: - - logs-mimecast.ttp_url_logs@package - - logs-mimecast.ttp_url_logs@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-mimecast.ttp_url_logs-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-mimecast.ttp_url_logs-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-netflow_x_log: - index_sorting: false - index_template: - composed_of: - - logs-netflow.log@package - - logs-netflow.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-netflow.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-netflow.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-o365_x_audit: - index_sorting: false - index_template: - composed_of: - - logs-o365.audit@package - - logs-o365.audit@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-o365.audit-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-o365.audit-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-okta_x_system: - index_sorting: false - index_template: - composed_of: - - logs-okta.system@package - - logs-okta.system@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-okta.system-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-okta.system-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -6361,6 +2677,7 @@ elasticsearch: name: elastic_agent composed_of: - logs-osquery_manager.action.responses + ignore_missing_component_templates: [] index_patterns: - .logs-osquery_manager.action.responses* priority: 501 @@ -6368,6 +2685,59 @@ elasticsearch: settings: index: number_of_replicas: 0 + so-logs-osquery-manager_x_action_x_responses: + index_sorting: false + index_template: + _meta: + managed: true + managed_by: security_onion + package: + name: elastic_agent + data_stream: + allow_custom_routing: false + hidden: false + composed_of: + - logs-osquery_manager.action.responses@package + - logs-osquery_manager.action.responses@custom + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + ignore_missing_component_templates: + - logs-osquery_manager.action.responses@custom + index_patterns: + - logs-osquery_manager.action.responses* + priority: 501 + template: + settings: + lifecycle: + name: + so-logs-osquery-manager.action.responses-logs + index: + number_of_replicas: 0 + policy: + phases: + cold: + actions: + set_priority: + priority: 0 + min_age: 60d + delete: + actions: + delete: {} + min_age: 365d + hot: + actions: + rollover: + max_age: 30d + max_primary_shard_size: 50gb + set_priority: + priority: 100 + min_age: 0ms + warm: + actions: + set_priority: + priority: 50 + min_age: 30d so-logs-osquery-manager-actions: index_sorting: false index_template: @@ -6378,32 +2748,41 @@ elasticsearch: name: elastic_agent composed_of: - logs-osquery_manager.actions + ignore_missing_component_templates: [] index_patterns: - - .logs-osquery_manager.actions* + - .logs-osquery_manager.actions-* priority: 501 template: settings: index: number_of_replicas: 0 - so-logs-panw_x_panos: + so-logs-osquery-manager_x_result: index_sorting: false index_template: - composed_of: - - logs-panw.panos@package - - logs-panw.panos@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 + _meta: + managed: true + managed_by: security_onion + package: + name: elastic_agent data_stream: allow_custom_routing: false hidden: false + composed_of: + - logs-osquery_manager.result@package + - logs-osquery_manager.result@custom + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + ignore_missing_component_templates: + - logs-osquery_manager.result@custom index_patterns: - - logs-panw.panos-* + - logs-osquery_manager.result* priority: 501 template: settings: index: lifecycle: - name: so-logs-panw.panos-logs + name: so-logs-osquery-manager.result-logs number_of_replicas: 0 policy: phases: @@ -6411,7 +2790,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -6429,649 +2808,97 @@ elasticsearch: set_priority: priority: 50 min_age: 30d - so-logs-pfsense_x_log: + so-logs-soc: + close: 30 + delete: 365 index_sorting: false index_template: composed_of: - - logs-pfsense.log@package - - logs-pfsense.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false + - agent-mappings + - dtc-agent-mappings + - base-mappings + - dtc-base-mappings + - client-mappings + - dtc-client-mappings + - container-mappings + - destination-mappings + - dtc-destination-mappings + - pb-override-destination-mappings + - dll-mappings + - dns-mappings + - dtc-dns-mappings + - ecs-mappings + - dtc-ecs-mappings + - error-mappings + - event-mappings + - dtc-event-mappings + - file-mappings + - dtc-file-mappings + - group-mappings + - host-mappings + - dtc-host-mappings + - http-mappings + - dtc-http-mappings + - log-mappings + - metadata-mappings + - network-mappings + - dtc-network-mappings + - observer-mappings + - dtc-observer-mappings + - organization-mappings + - package-mappings + - process-mappings + - dtc-process-mappings + - related-mappings + - rule-mappings + - dtc-rule-mappings + - server-mappings + - service-mappings + - dtc-service-mappings + - source-mappings + - dtc-source-mappings + - pb-override-source-mappings + - threat-mappings + - tls-mappings + - url-mappings + - user_agent-mappings + - dtc-user_agent-mappings + - common-settings + - common-dynamic-mappings + data_stream: {} + ignore_missing_component_templates: [] index_patterns: - - logs-pfsense.log-* - priority: 501 + - logs-soc-so* + priority: 500 template: + mappings: + date_detection: false + dynamic_templates: + - strings_as_keyword: + mapping: + ignore_above: 1024 + type: keyword + match_mapping_type: string settings: index: lifecycle: - name: so-logs-pfsense.log-logs + name: so-logs-soc-logs + mapping: + total_fields: + limit: 5000 number_of_replicas: 0 + number_of_shards: 1 + refresh_interval: 30s + sort: + field: '@timestamp' + order: desc policy: phases: cold: actions: set_priority: priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-pulse_connect_secure_x_log: - index_sorting: false - index_template: - composed_of: - - logs-pulse_connect_secure.log@package - - logs-pulse_connect_secure.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-pulse_connect_secure.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-pulse_connect_secure.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-sentinel_one_x_activity: - index_sorting: false - index_template: - composed_of: - - logs-sentinel_one.activity@package - - logs-sentinel_one.activity@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-sentinel_one.activity-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-sentinel_one.activity-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-sentinel_one_x_agent: - index_sorting: false - index_template: - composed_of: - - logs-sentinel_one.agent@package - - logs-sentinel_one.agent@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-sentinel_one.agent-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-sentinel_one.agent-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-sentinel_one_x_alert: - index_sorting: false - index_template: - composed_of: - - logs-sentinel_one.alert@package - - logs-sentinel_one.alert@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-sentinel_one.alert-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-sentinel_one.alert-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-sentinel_one_x_group: - index_sorting: false - index_template: - composed_of: - - logs-sentinel_one.group@package - - logs-sentinel_one.group@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-sentinel_one.group-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-sentinel_one.group-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-sentinel_one_x_threat: - index_sorting: false - index_template: - composed_of: - - logs-sentinel_one.threat@package - - logs-sentinel_one.threat@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-sentinel_one.threat-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-sentinel_one.threat-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-snyk_x_audit: - index_sorting: false - index_template: - composed_of: - - logs-snyk.audit@package - - logs-snyk.audit@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-snyk.audit-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-snyk.audit-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-snyk_x_vulnerabilities: - index_sorting: false - index_template: - composed_of: - - logs-snyk.vulnerabilities@package - - logs-snyk.vulnerabilities@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-snyk.vulnerabilities-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-snyk.vulnerabilities-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-sonicwall_firewall_x_log: - index_sorting: false - index_template: - composed_of: - - logs-sonicwall_firewall.log@package - - logs-sonicwall_firewall.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-sonicwall_firewall.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-sonicwall_firewall.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-sophos_central_x_alert: - index_sorting: false - index_template: - composed_of: - - logs-sophos_central.alert@package - - logs-sophos_central.alert@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-sophos_central.alert-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-sophos_central.alert-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-sophos_central_x_event: - index_sorting: false - index_template: - composed_of: - - logs-sophos_central.event@package - - logs-sophos_central.event@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-sophos_central.event-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-sophos_central.event-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-sophos_x_utm: - index_sorting: false - index_template: - composed_of: - - logs-sophos.utm@package - - logs-sophos.utm@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-sophos.utm-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-sophos.utm-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-sophos_x_xg: - index_sorting: false - index_template: - composed_of: - - logs-sophos.xg@package - - logs-sophos.xg@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-sophos.xg-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-sophos.xg-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-symantec_endpoint_x_log: - index_sorting: false - index_template: - composed_of: - - logs-symantec_endpoint.log@package - - logs-symantec_endpoint.log@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-symantec_endpoint.log-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-symantec_endpoint.log-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -7089,6 +2916,7 @@ elasticsearch: set_priority: priority: 50 min_age: 30d + warm: 7 so-logs-system_x_application: index_sorting: false index_template: @@ -7096,11 +2924,15 @@ elasticsearch: - event-mappings - logs-system.application@package - logs-system.application@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 + - so-system-mappings data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-system.application@custom index_patterns: - logs-system.application* priority: 501 @@ -7116,7 +2948,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -7141,11 +2973,15 @@ elasticsearch: - event-mappings - logs-system.auth@package - logs-system.auth@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 + - so-system-mappings data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-system.auth@custom index_patterns: - logs-system.auth* priority: 501 @@ -7161,7 +2997,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -7186,11 +3022,15 @@ elasticsearch: - event-mappings - logs-system.security@package - logs-system.security@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 + - so-system-mappings data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-system.security@custom index_patterns: - logs-system.security* priority: 501 @@ -7206,7 +3046,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -7231,11 +3071,15 @@ elasticsearch: - event-mappings - logs-system.syslog@package - logs-system.syslog@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 + - so-system-mappings data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-system.syslog@custom index_patterns: - logs-system.syslog* priority: 501 @@ -7251,7 +3095,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -7276,11 +3120,15 @@ elasticsearch: - event-mappings - logs-system.system@package - logs-system.system@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 + - so-system-mappings data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-system.system@custom index_patterns: - logs-system.system* priority: 501 @@ -7296,579 +3144,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-tenable_sc_x_asset: - index_sorting: false - index_template: - composed_of: - - logs-tenable_sc.asset@package - - logs-tenable_sc.asset@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-tenable_sc.asset-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-tenable_sc.asset-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-tenable_sc_x_plugin: - index_sorting: false - index_template: - composed_of: - - logs-tenable_sc.plugin@package - - logs-tenable_sc.plugin@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-tenable_sc.plugin-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-tenable_sc.plugin-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-tenable_sc_x_vulnerability: - index_sorting: false - index_template: - composed_of: - - logs-tenable_sc.vulnerability@package - - logs-tenable_sc.vulnerability@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-tenable_sc.vulnerability-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-tenable_sc.vulnerability-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-ti_abusech_x_malware: - index_sorting: false - index_template: - composed_of: - - logs-ti_abusech.malware@package - - logs-ti_abusech.malware@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-ti_abusech.malware-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-ti_abusech.malware-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-ti_abusech_x_malwarebazaar: - index_sorting: false - index_template: - composed_of: - - logs-ti_abusech.malwarebazaar@package - - logs-ti_abusech.malwarebazaar@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-ti_abusech.malwarebazaar-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-ti_abusech.malwarebazaar-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-ti_abusech_x_threatfox: - index_sorting: false - index_template: - composed_of: - - logs-ti_abusech.threatfox@package - - logs-ti_abusech.threatfox@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-ti_abusech.threatfox-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-ti_abusech.threatfox-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-ti_abusech_x_url: - index_sorting: false - index_template: - composed_of: - - logs-ti_abusech.url@package - - logs-ti_abusech.url@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-ti_abusech.url-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-ti_abusech.url-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-ti_misp_x_threat: - index_sorting: false - index_template: - composed_of: - - logs-ti_misp.threat@package - - logs-ti_misp.threat@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-ti_misp.threat-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-ti_misp.threat-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-ti_misp_x_threat_attributes: - index_sorting: false - index_template: - composed_of: - - logs-ti_misp.threat_attributes@package - - logs-ti_misp.threat_attributes@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-ti_misp.threat_attributes-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-ti_misp.threat_attributes-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-ti_otx_x_threat: - index_sorting: false - index_template: - composed_of: - - logs-ti_otx.threat@package - - logs-ti_otx.threat@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-ti_otx.threat-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-ti_otx.threat-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-ti_recordedfuture_x_latest_ioc-template: - index_sorting: false - index_template: - composed_of: - - logs-ti_recordedfuture.latest_ioc-template@package - - logs-ti_recordedfuture.latest_ioc-template@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-ti_recordedfuture.latest_ioc-template-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-ti_recordedfuture.latest_ioc-template-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-ti_recordedfuture_x_threat: - index_sorting: false - index_template: - composed_of: - - logs-ti_recordedfuture.threat@package - - logs-ti_recordedfuture.threat@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-ti_recordedfuture.threat-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-ti_recordedfuture.threat-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-vsphere_x_log: - index_sorting: False - index_template: - index_patterns: - - "logs-vsphere.log-*" - template: - settings: - index: - lifecycle: - name: so-logs-vsphere.log-logs - number_of_replicas: 0 - composed_of: - - "logs-vsphere.log@package" - - "logs-vsphere.log@custom" - - "so-fleet_globals-1" - - "so-fleet_agent_id_verification-1" - priority: 501 - data_stream: - hidden: false - allow_custom_routing: false - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -7892,11 +3168,14 @@ elasticsearch: composed_of: - logs-windows.forwarded@package - logs-windows.forwarded@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-windows.forwarded@custom index_patterns: - logs-windows.forwarded* priority: 501 @@ -7912,7 +3191,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -7936,11 +3215,14 @@ elasticsearch: composed_of: - logs-windows.powershell@package - logs-windows.powershell@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-windows.powershell@custom index_patterns: - logs-windows.powershell-* priority: 501 @@ -7956,7 +3238,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -7980,11 +3262,14 @@ elasticsearch: composed_of: - logs-windows.powershell_operational@package - logs-windows.powershell_operational@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-windows.powershell_operational@custom index_patterns: - logs-windows.powershell_operational-* priority: 501 @@ -8000,7 +3285,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -8024,11 +3309,14 @@ elasticsearch: composed_of: - logs-windows.sysmon_operational@package - logs-windows.sysmon_operational@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-windows.sysmon_operational@custom index_patterns: - logs-windows.sysmon_operational-* priority: 501 @@ -8044,7 +3332,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -8062,25 +3350,29 @@ elasticsearch: set_priority: priority: 50 min_age: 30d - so-logs-zscaler_zia_x_alerts: + so-logs-winlog_x_winlog: index_sorting: false index_template: composed_of: - - logs-zscaler_zia.alerts@package - - logs-zscaler_zia.alerts@custom + - logs-winlog.winlog@package + - logs-winlog.winlog@custom + - so-fleet_integrations.ip_mappings-1 - so-fleet_globals-1 - so-fleet_agent_id_verification-1 data_stream: allow_custom_routing: false hidden: false + ignore_missing_component_templates: + - logs-winlog.winlog@package + - logs-winlog.winlog@custom index_patterns: - - logs-zscaler_zia.alerts-* + - logs-winlog.winlog-* priority: 501 template: settings: index: lifecycle: - name: so-logs-zscaler_zia.alerts-logs + name: so-logs-winlog.winlog-logs number_of_replicas: 0 policy: phases: @@ -8088,535 +3380,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-zscaler_zia_x_dns: - index_sorting: false - index_template: - composed_of: - - logs-zscaler_zia.dns@package - - logs-zscaler_zia.dns@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-zscaler_zia.dns-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-zscaler_zia.dns-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-zscaler_zia_x_firewall: - index_sorting: false - index_template: - composed_of: - - logs-zscaler_zia.firewall@package - - logs-zscaler_zia.firewall@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-zscaler_zia.firewall-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-zscaler_zia.firewall-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-zscaler_zia_x_tunnel: - index_sorting: false - index_template: - composed_of: - - logs-zscaler_zia.tunnel@package - - logs-zscaler_zia.tunnel@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-zscaler_zia.tunnel-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-zscaler_zia.tunnel-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-zscaler_zia_x_web: - index_sorting: false - index_template: - composed_of: - - logs-zscaler_zia.web@package - - logs-zscaler_zia.web@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-zscaler_zia.web-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-zscaler_zia.web-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-zscaler_zpa_x_app_connector_status: - index_sorting: false - index_template: - composed_of: - - logs-zscaler_zpa.app_connector_status@package - - logs-zscaler_zpa.app_connector_status@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-zscaler_zpa.app_connector_status-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-zscaler_zpa.app_connector_status-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-zscaler_zpa_x_audit: - index_sorting: false - index_template: - composed_of: - - logs-zscaler_zpa.audit@package - - logs-zscaler_zpa.audit@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-zscaler_zpa.audit-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-zscaler_zpa.audit-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-zscaler_zpa_x_browser_access: - index_sorting: false - index_template: - composed_of: - - logs-zscaler_zpa.browser_access@package - - logs-zscaler_zpa.browser_access@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-zscaler_zpa.browser_access-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-zscaler_zpa.browser_access-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-zscaler_zpa_x_user_activity: - index_sorting: false - index_template: - composed_of: - - logs-zscaler_zpa.user_activity@package - - logs-zscaler_zpa.user_activity@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-zscaler_zpa.user_activity-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-zscaler_zpa.user_activity-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-logs-zscaler_zpa_x_user_status: - index_sorting: false - index_template: - composed_of: - - logs-zscaler_zpa.user_status@package - - logs-zscaler_zpa.user_status@custom - - so-fleet_globals-1 - - so-fleet_agent_id_verification-1 - data_stream: - allow_custom_routing: false - hidden: false - index_patterns: - - logs-zscaler_zpa.user_status-* - priority: 501 - template: - settings: - index: - lifecycle: - name: so-logs-zscaler_zpa.user_status-logs - number_of_replicas: 0 - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-metrics-vsphere_x_datastore: - index_sorting: False - index_template: - index_patterns: - - "metrics-vsphere.datastore-*" - template: - settings: - index: - lifecycle: - name: so-metrics-vsphere.datastore-logs - number_of_replicas: 0 - composed_of: - - "metrics-vsphere.datastore@package" - - "metrics-vsphere.datastore@custom" - - "so-fleet_globals-1" - - "so-fleet_agent_id_verification-1" - priority: 501 - data_stream: - hidden: false - allow_custom_routing: false - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-metrics-vsphere_x_host: - index_sorting: False - index_template: - index_patterns: - - "metrics-vsphere.host-*" - template: - settings: - index: - lifecycle: - name: so-metrics-vsphere.host-logs - number_of_replicas: 0 - composed_of: - - "metrics-vsphere.host@package" - - "metrics-vsphere.host@custom" - - "so-fleet_globals-1" - - "so-fleet_agent_id_verification-1" - priority: 501 - data_stream: - hidden: false - allow_custom_routing: false - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d - delete: - actions: - delete: {} - min_age: 365d - hot: - actions: - rollover: - max_age: 30d - max_primary_shard_size: 50gb - set_priority: - priority: 100 - min_age: 0ms - warm: - actions: - set_priority: - priority: 50 - min_age: 30d - so-metrics-vsphere_x_virtualmachine: - index_sorting: False - index_template: - index_patterns: - - "metrics-vsphere.virtualmachine-*" - template: - settings: - index: - lifecycle: - name: so-metrics-vsphere.virtualmachine-logs - number_of_replicas: 0 - composed_of: - - "metrics-vsphere.virtualmachine@package" - - "metrics-vsphere.virtualmachine@custom" - - "so-fleet_globals-1" - - "so-fleet_agent_id_verification-1" - priority: 501 - data_stream: - hidden: false - allow_custom_routing: false - policy: - phases: - cold: - actions: - set_priority: - priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -8667,6 +3431,7 @@ elasticsearch: - dtc-http-mappings - log-mappings - logstash-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -8695,6 +3460,7 @@ elasticsearch: - vulnerability-mappings - common-settings - common-dynamic-mappings + ignore_missing_component_templates: [] index_patterns: - logs-logstash-default* priority: 500 @@ -8726,7 +3492,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -8744,6 +3510,195 @@ elasticsearch: set_priority: priority: 50 min_age: 30d + so-metrics-endpoint_x_metadata: + index_sorting: false + index_template: + composed_of: + - metrics-endpoint.metadata@package + - metrics-endpoint.metadata@custom + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + data_stream: + allow_custom_routing: false + hidden: false + ignore_missing_component_templates: + - metrics-endpoint.metadata@custom + index_patterns: + - metrics-endpoint.metadata-* + priority: 501 + template: + settings: + index: + lifecycle: + name: so-metrics-endpoint.metadata-logs + number_of_replicas: 0 + policy: + phases: + cold: + actions: + set_priority: + priority: 0 + min_age: 60d + delete: + actions: + delete: {} + min_age: 365d + hot: + actions: + rollover: + max_age: 30d + max_primary_shard_size: 50gb + set_priority: + priority: 100 + min_age: 0ms + warm: + actions: + set_priority: + priority: 50 + min_age: 30d + so-metrics-endpoint_x_metrics: + index_sorting: false + index_template: + composed_of: + - metrics-endpoint.metrics@package + - metrics-endpoint.metrics@custom + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + data_stream: + allow_custom_routing: false + hidden: false + ignore_missing_component_templates: + - metrics-endpoint.metrics@custom + index_patterns: + - metrics-endpoint.metrics-* + priority: 501 + template: + settings: + index: + lifecycle: + name: so-metrics-endpoint.metrics-logs + number_of_replicas: 0 + policy: + phases: + cold: + actions: + set_priority: + priority: 0 + min_age: 60d + delete: + actions: + delete: {} + min_age: 365d + hot: + actions: + rollover: + max_age: 30d + max_primary_shard_size: 50gb + set_priority: + priority: 100 + min_age: 0ms + warm: + actions: + set_priority: + priority: 50 + min_age: 30d + so-metrics-endpoint_x_policy: + index_sorting: false + index_template: + composed_of: + - metrics-endpoint.policy@package + - metrics-endpoint.policy@custom + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + data_stream: + allow_custom_routing: false + hidden: false + ignore_missing_component_templates: + - metrics-endpoint.policy@custom + index_patterns: + - metrics-endpoint.policy-* + priority: 501 + template: + settings: + index: + lifecycle: + name: so-metrics-endpoint.policy-logs + number_of_replicas: 0 + policy: + phases: + cold: + actions: + set_priority: + priority: 0 + min_age: 60d + delete: + actions: + delete: {} + min_age: 365d + hot: + actions: + rollover: + max_age: 30d + max_primary_shard_size: 50gb + set_priority: + priority: 100 + min_age: 0ms + warm: + actions: + set_priority: + priority: 50 + min_age: 30d + so-metrics-fleet_server_x_agent_status: + index_sorting: false + index_template: + composed_of: + - metrics@tsdb-settings + - metrics-fleet_server.agent_status@package + - metrics-fleet_server.agent_status@custom + - ecs@mappings + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + data_stream: + allow_custom_routing: false + hidden: false + ignore_missing_component_templates: + - metrics-fleet_server.agent_status@custom + index_patterns: + - metrics-fleet_server.agent_status-* + priority: 501 + template: + settings: + index: + mode: time_series + number_of_replicas: 0 + so-metrics-fleet_server_x_agent_versions: + index_sorting: false + index_template: + composed_of: + - metrics@tsdb-settings + - metrics-fleet_server.agent_versions@package + - metrics-fleet_server.agent_versions@custom + - ecs@mappings + - so-fleet_integrations.ip_mappings-1 + - so-fleet_globals-1 + - so-fleet_agent_id_verification-1 + data_stream: + allow_custom_routing: false + hidden: false + ignore_missing_component_templates: + - metrics-fleet_server.agent_versions@custom + index_patterns: + - metrics-fleet_server.agent_versions-* + priority: 501 + template: + settings: + index: + mode: time_series + number_of_replicas: 0 so-redis: index_sorting: false index_template: @@ -8776,6 +3731,7 @@ elasticsearch: - http-mappings - dtc-http-mappings - log-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -8805,6 +3761,7 @@ elasticsearch: - vulnerability-mappings - common-settings - common-dynamic-mappings + ignore_missing_component_templates: [] index_patterns: - logs-redis-default* priority: 500 @@ -8836,7 +3793,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -8887,6 +3844,7 @@ elasticsearch: - http-mappings - dtc-http-mappings - log-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -8917,6 +3875,7 @@ elasticsearch: - common-settings - common-dynamic-mappings data_stream: {} + ignore_missing_component_templates: [] index_patterns: - logs-strelka-so* priority: 500 @@ -8948,7 +3907,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -8998,6 +3957,7 @@ elasticsearch: - http-mappings - dtc-http-mappings - log-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -9028,6 +3988,7 @@ elasticsearch: - common-settings - common-dynamic-mappings data_stream: {} + ignore_missing_component_templates: [] index_patterns: - logs-suricata-so* priority: 500 @@ -9059,7 +4020,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -9067,7 +4028,120 @@ elasticsearch: hot: actions: rollover: - max_age: 30d + max_age: 1d + max_primary_shard_size: 50gb + set_priority: + priority: 100 + min_age: 0ms + warm: + actions: + set_priority: + priority: 50 + min_age: 30d + so-suricata_x_alerts: + index_sorting: false + index_template: + composed_of: + - agent-mappings + - dtc-agent-mappings + - base-mappings + - dtc-base-mappings + - client-mappings + - dtc-client-mappings + - cloud-mappings + - container-mappings + - data_stream-mappings + - destination-mappings + - dtc-destination-mappings + - pb-override-destination-mappings + - dll-mappings + - dns-mappings + - dtc-dns-mappings + - ecs-mappings + - dtc-ecs-mappings + - error-mappings + - event-mappings + - dtc-event-mappings + - file-mappings + - dtc-file-mappings + - group-mappings + - host-mappings + - dtc-host-mappings + - http-mappings + - dtc-http-mappings + - log-mappings + - metadata-mappings + - network-mappings + - dtc-network-mappings + - observer-mappings + - dtc-observer-mappings + - orchestrator-mappings + - organization-mappings + - package-mappings + - process-mappings + - dtc-process-mappings + - registry-mappings + - related-mappings + - rule-mappings + - dtc-rule-mappings + - server-mappings + - service-mappings + - dtc-service-mappings + - source-mappings + - dtc-source-mappings + - pb-override-source-mappings + - suricata-mappings + - threat-mappings + - tls-mappings + - tracing-mappings + - url-mappings + - user_agent-mappings + - dtc-user_agent-mappings + - vulnerability-mappings + - common-settings + - common-dynamic-mappings + data_stream: {} + ignore_missing_component_templates: [] + index_patterns: + - logs-suricata.alerts-* + priority: 500 + template: + mappings: + date_detection: false + dynamic_templates: + - strings_as_keyword: + mapping: + ignore_above: 1024 + type: keyword + match_mapping_type: string + settings: + index: + lifecycle: + name: so-suricata.alerts-logs + mapping: + total_fields: + limit: 5000 + number_of_replicas: 0 + number_of_shards: 1 + refresh_interval: 30s + sort: + field: '@timestamp' + order: desc + policy: + phases: + cold: + actions: + set_priority: + priority: 0 + min_age: 60d + delete: + actions: + delete: {} + min_age: 365d + hot: + actions: + rollover: + max_age: 1d max_primary_shard_size: 50gb set_priority: priority: 100 @@ -9109,6 +4183,7 @@ elasticsearch: - http-mappings - dtc-http-mappings - log-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -9140,6 +4215,7 @@ elasticsearch: - common-settings - common-dynamic-mappings data_stream: {} + ignore_missing_component_templates: [] index_patterns: - logs-syslog-so* priority: 500 @@ -9171,7 +4247,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -9221,6 +4297,7 @@ elasticsearch: - http-mappings - dtc-http-mappings - log-mappings + - metadata-mappings - network-mappings - dtc-network-mappings - observer-mappings @@ -9253,6 +4330,7 @@ elasticsearch: - common-settings - common-dynamic-mappings data_stream: {} + ignore_missing_component_templates: [] index_patterns: - logs-zeek-so* priority: 500 @@ -9284,7 +4362,7 @@ elasticsearch: actions: set_priority: priority: 0 - min_age: 30d + min_age: 60d delete: actions: delete: {} @@ -9302,6 +4380,87 @@ elasticsearch: set_priority: priority: 50 min_age: 30d + pipelines: + custom001: + description: Custom Pipeline + processors: + - set: + field: tags + value: custom001 + - pipeline: + name: common + custom002: + description: Custom Pipeline + processors: + - set: + field: tags + value: custom002 + - pipeline: + name: common + custom003: + description: Custom Pipeline + processors: + - set: + field: tags + value: custom003 + - pipeline: + name: common + custom004: + description: Custom Pipeline + processors: + - set: + field: tags + value: custom004 + - pipeline: + name: common + custom005: + description: Custom Pipeline + processors: + - set: + field: tags + value: custom005 + - pipeline: + name: common + custom006: + description: Custom Pipeline + processors: + - set: + field: tags + value: custom006 + - pipeline: + name: common + custom007: + description: Custom Pipeline + processors: + - set: + field: tags + value: custom007 + - pipeline: + name: common + custom008: + description: Custom Pipeline + processors: + - set: + field: tags + value: custom008 + - pipeline: + name: common + custom009: + description: Custom Pipeline + processors: + - set: + field: tags + value: custom009 + - pipeline: + name: common + custom010: + description: Custom Pipeline + processors: + - set: + field: tags + value: custom010 + - pipeline: + name: common retention: retention_pct: 50 so_roles: @@ -9342,6 +4501,14 @@ elasticsearch: - data - remote_cluster_client - transform + so-managerhype: + config: + node: + roles: + - master + - data + - remote_cluster_client + - transform so-managersearch: config: node: diff --git a/salt/elasticsearch/disabled.sls b/salt/elasticsearch/disabled.sls index 210ad59a4..2453f9f77 100644 --- a/salt/elasticsearch/disabled.sls +++ b/salt/elasticsearch/disabled.sls @@ -18,6 +18,10 @@ so-elasticsearch_so-status.disabled: - name: /opt/so/conf/so-status/so-status.conf - regex: ^so-elasticsearch$ +so-elasticsearch-indices-delete: + cron.absent: + - identifier: so-elasticsearch-indices-delete + {% else %} {{sls}}_state_not_allowed: diff --git a/salt/playbook/sostatus.sls b/salt/elasticsearch/download.sls similarity index 59% rename from salt/playbook/sostatus.sls rename to salt/elasticsearch/download.sls index f635746d3..c7891dcdc 100644 --- a/salt/playbook/sostatus.sls +++ b/salt/elasticsearch/download.sls @@ -1,16 +1,16 @@ # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one -# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS %} -append_so-playbook_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-playbook - - unless: grep -q so-playbook /opt/so/conf/so-status/so-status.conf +so-elasticsearch_image: + docker_image.present: + - name: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elasticsearch:{{ ELASTICSEARCHDEFAULTS.elasticsearch.version }} {% else %} diff --git a/salt/elasticsearch/enabled.sls b/salt/elasticsearch/enabled.sls index f7ab7749f..49f34314b 100644 --- a/salt/elasticsearch/enabled.sls +++ b/salt/elasticsearch/enabled.sls @@ -7,8 +7,8 @@ {% if sls.split('.')[0] in allowed_states %} {% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'logstash/map.jinja' import LOGSTASH_NODES %} -{% from 'elasticsearch/config.map.jinja' import ES_LOGSTASH_NODES %} +{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCH_NODES %} +{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCH_SEED_HOSTS %} {% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %} {% set TEMPLATES = salt['pillar.get']('elasticsearch:templates', {}) %} {% from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS %} @@ -19,21 +19,26 @@ include: so-elasticsearch: docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elasticsearch:{{ GLOBALS.so_version }} + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elasticsearch:{{ ELASTICSEARCHMERGED.version }} - hostname: elasticsearch - name: so-elasticsearch - user: elasticsearch - networks: - sobridge: - ipv4_address: {{ DOCKER.containers['so-elasticsearch'].ip }} - - extra_hosts: {{ LOGSTASH_NODES }} + - extra_hosts: + {% for node in ELASTICSEARCH_NODES %} + {% for hostname, ip in node.items() %} + - {{hostname}}:{{ip}} + {% endfor %} + {% endfor %} {% if DOCKER.containers['so-elasticsearch'].extra_hosts %} {% for XTRAHOST in DOCKER.containers['so-elasticsearch'].extra_hosts %} - {{ XTRAHOST }} {% endfor %} {% endif %} - environment: - {% if ES_LOGSTASH_NODES | length == 1 or GLOBALS.role == 'so-heavynode' %} + {% if (GLOBALS.role in GLOBALS.manager_roles and ELASTICSEARCH_SEED_HOSTS | length == 1) or GLOBALS.role == 'so-heavynode' %} - discovery.type=single-node {% endif %} - ES_JAVA_OPTS=-Xms{{ GLOBALS.elasticsearch.es_heap }} -Xmx{{ GLOBALS.elasticsearch.es_heap }} -Des.transport.cname_in_publish_address=true -Dlog4j2.formatMsgNoLookups=true @@ -111,6 +116,7 @@ escomponenttemplates: - clean: True - onchanges_in: - file: so-elasticsearch-templates-reload + - show_changes: False # Auto-generate templates from defaults file {% for index, settings in ES_INDEX_SETTINGS.items() %} @@ -122,6 +128,7 @@ es_index_template_{{index}}: - defaults: TEMPLATE_CONFIG: {{ settings.index_template }} - template: jinja + - show_changes: False - onchanges_in: - file: so-elasticsearch-templates-reload {% endif %} @@ -141,12 +148,13 @@ es_template_{{TEMPLATE.split('.')[0] | replace("/","_") }}: {% endif %} - user: 930 - group: 939 + - show_changes: False - onchanges_in: - file: so-elasticsearch-templates-reload {% endfor %} {% endif %} -{% if GLOBALS.role in GLOBALS.manager_roles %} +{% if GLOBALS.role in GLOBALS.manager_roles %} so-es-cluster-settings: cmd.run: - name: /usr/sbin/so-elasticsearch-cluster-settings @@ -155,7 +163,7 @@ so-es-cluster-settings: - require: - docker_container: so-elasticsearch - file: elasticsearch_sbin_jinja -{% endif %} +{% endif %} so-elasticsearch-ilm-policy-load: cmd.run: @@ -195,6 +203,30 @@ so-elasticsearch-roles-load: - require: - docker_container: so-elasticsearch - file: elasticsearch_sbin_jinja + +{% if grains.role in ['so-managersearch', 'so-manager', 'so-managerhype'] %} +{% set ap = "absent" %} +{% endif %} +{% if grains.role in ['so-eval', 'so-standalone', 'so-heavynode'] %} +{% if ELASTICSEARCHMERGED.index_clean %} +{% set ap = "present" %} +{% else %} +{% set ap = "absent" %} +{% endif %} +{% endif %} +{% if grains.role in ['so-eval', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-manager'] %} +so-elasticsearch-indices-delete: + cron.{{ap}}: + - name: /usr/sbin/so-elasticsearch-indices-delete > /opt/so/log/elasticsearch/cron-elasticsearch-indices-delete.log 2>&1 + - identifier: so-elasticsearch-indices-delete + - user: root + - minute: '*/5' + - hour: '*' + - daymonth: '*' + - month: '*' + - dayweek: '*' +{% endif %} + {% endif %} {% else %} diff --git a/salt/elasticsearch/files/ingest-dynamic/common b/salt/elasticsearch/files/ingest-dynamic/common index b2c13f983..e84702909 100644 --- a/salt/elasticsearch/files/ingest-dynamic/common +++ b/salt/elasticsearch/files/ingest-dynamic/common @@ -57,10 +57,12 @@ { "convert": { "field": "log.id.uid", "type": "string", "ignore_failure": true, "ignore_missing": true } }, { "convert": { "field": "agent.id", "type": "string", "ignore_failure": true, "ignore_missing": true } }, { "convert": { "field": "event.severity", "type": "integer", "ignore_failure": true, "ignore_missing": true } }, - { "set": { "field": "event.dataset", "ignore_empty_value":true, "copy_from": "event.dataset_temp" }}, + { "set": { "field": "event.dataset", "ignore_empty_value":true, "copy_from": "event.dataset_temp" } }, { "set": { "if": "ctx.event?.dataset != null && !ctx.event.dataset.contains('.')", "field": "event.dataset", "value": "{{event.module}}.{{event.dataset}}" } }, - { "split": { "if": "ctx.event?.dataset != null && ctx.event.dataset.contains('.')", "field": "event.dataset", "separator": "\\.", "target_field": "dataset_tag_temp" } }, - { "append": { "if": "ctx.dataset_tag_temp != null", "field": "tags", "value": "{{dataset_tag_temp.1}}" }}, + { "split": { "if": "ctx.event?.dataset != null && ctx.event.dataset.contains('.')", "field": "event.dataset", "separator": "\\.", "target_field": "dataset_tag_temp" } }, + { "append": { "if": "ctx.dataset_tag_temp != null", "field": "tags", "value": "{{dataset_tag_temp.1}}" } }, + { "grok": { "if": "ctx.http?.response?.status_code != null", "field": "http.response.status_code", "patterns": ["%{NUMBER:http.response.status_code:long} %{GREEDYDATA}"]} }, + { "set": { "if": "ctx?.metadata?.kafka != null" , "field": "kafka.id", "value": "{{metadata.kafka.partition}}{{metadata.kafka.offset}}{{metadata.kafka.timestamp}}", "ignore_failure": true } }, { "remove": { "field": [ "message2", "type", "fields", "category", "module", "dataset", "dataset_tag_temp", "event.dataset_temp" ], "ignore_missing": true, "ignore_failure": true } } {%- endraw %} {%- if HIGHLANDER %} @@ -71,7 +73,9 @@ } } {%- endif %} -{%- raw %} +{%- raw %} + , + { "pipeline": { "name": "global@custom", "ignore_missing_pipeline": true, "description": "[Fleet] Global pipeline for all data streams" } } ] } {% endraw %} diff --git a/salt/elasticsearch/files/ingest/.fleet_final_pipeline-1 b/salt/elasticsearch/files/ingest/.fleet_final_pipeline-1 deleted file mode 100644 index 52b6bae7a..000000000 --- a/salt/elasticsearch/files/ingest/.fleet_final_pipeline-1 +++ /dev/null @@ -1,104 +0,0 @@ -{ - "version": 3, - "_meta": { - "managed_by": "fleet", - "managed": true - }, - "description": "Final pipeline for processing all incoming Fleet Agent documents. \n", - "processors": [ - { - "date": { - "description": "Add time when event was ingested (and remove sub-seconds to improve storage efficiency)", - "tag": "truncate-subseconds-event-ingested", - "field": "_ingest.timestamp", - "target_field": "event.ingested", - "formats": [ - "ISO8601" - ], - "output_format": "date_time_no_millis", - "ignore_failure": true - } - }, - { - "remove": { - "description": "Remove any pre-existing untrusted values.", - "field": [ - "event.agent_id_status", - "_security" - ], - "ignore_missing": true - } - }, - { - "set_security_user": { - "field": "_security", - "properties": [ - "authentication_type", - "username", - "realm", - "api_key" - ] - } - }, - { - "script": { - "description": "Add event.agent_id_status based on the API key metadata and the agent.id contained in the event.\n", - "tag": "agent-id-status", - "source": "boolean is_user_trusted(def ctx, def users) {\n if (ctx?._security?.username == null) {\n return false;\n }\n\n def user = null;\n for (def item : users) {\n if (item?.username == ctx._security.username) {\n user = item;\n break;\n }\n }\n\n if (user == null || user?.realm == null || ctx?._security?.realm?.name == null) {\n return false;\n }\n\n if (ctx._security.realm.name != user.realm) {\n return false;\n }\n\n return true;\n}\n\nString verified(def ctx, def params) {\n // No agent.id field to validate.\n if (ctx?.agent?.id == null) {\n return \"missing\";\n }\n\n // Check auth metadata from API key.\n if (ctx?._security?.authentication_type == null\n // Agents only use API keys.\n || ctx._security.authentication_type != 'API_KEY'\n // Verify the API key owner before trusting any metadata it contains.\n || !is_user_trusted(ctx, params.trusted_users)\n // Verify the API key has metadata indicating the assigned agent ID.\n || ctx?._security?.api_key?.metadata?.agent_id == null) {\n return \"auth_metadata_missing\";\n }\n\n // The API key can only be used represent the agent.id it was issued to.\n if (ctx._security.api_key.metadata.agent_id != ctx.agent.id) {\n // Potential masquerade attempt.\n return \"mismatch\";\n }\n\n return \"verified\";\n}\n\nif (ctx?.event == null) {\n ctx.event = [:];\n}\n\nctx.event.agent_id_status = verified(ctx, params);", - "params": { - "trusted_users": [ - { - "username": "elastic/fleet-server", - "realm": "_service_account" - }, - { - "username": "cloud-internal-agent-server", - "realm": "found" - }, - { - "username": "elastic", - "realm": "reserved" - } - ] - } - } - }, - { - "remove": { - "field": "_security", - "ignore_missing": true - } - }, - { "set": { "ignore_failure": true, "field": "event.module", "value": "elastic_agent" } }, - { "split": { "if": "ctx.event?.dataset != null && ctx.event.dataset.contains('.')", "field": "event.dataset", "separator": "\\.", "target_field": "module_temp" } }, - { "set": { "if": "ctx.module_temp != null", "override": true, "field": "event.module", "value": "{{module_temp.0}}" } }, - { "gsub": { "if": "ctx.event?.dataset != null && ctx.event.dataset.contains('.')", "field": "event.dataset", "pattern": "^[^.]*.", "replacement": "", "target_field": "dataset_tag_temp" } }, - { "append": { "if": "ctx.dataset_tag_temp != null", "field": "tags", "value": "{{dataset_tag_temp}}" } }, - { "set": { "if": "ctx.network?.direction == 'egress'", "override": true, "field": "network.initiated", "value": "true" } }, - { "set": { "if": "ctx.network?.direction == 'ingress'", "override": true, "field": "network.initiated", "value": "false" } }, - { "set": { "if": "ctx.network?.type == 'ipv4'", "override": true, "field": "destination.ipv6", "value": "false" } }, - { "set": { "if": "ctx.network?.type == 'ipv6'", "override": true, "field": "destination.ipv6", "value": "true" } }, - { "set": { "if": "ctx.tags.0 == 'import'", "override": true, "field": "data_stream.dataset", "value": "import" } }, - { "set": { "if": "ctx.tags.0 == 'import'", "override": true, "field": "data_stream.namespace", "value": "so" } }, - { "date": { "if": "ctx.event?.module == 'system'", "field": "event.created", "target_field": "@timestamp", "formats": ["yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'"] } }, - { "community_id":{ "if": "ctx.event?.dataset == 'endpoint.events.network'", "ignore_failure":true } }, - { "remove": { "field": [ "message2", "type", "fields", "category", "module", "dataset", "event.dataset_temp", "dataset_tag_temp", "module_temp" ], "ignore_missing": true, "ignore_failure": true } } - ], - "on_failure": [ - { - "remove": { - "field": "_security", - "ignore_missing": true, - "ignore_failure": true - } - }, - { - "append": { - "field": "error.message", - "value": [ - "failed in Fleet agent final_pipeline: {{ _ingest.on_failure_message }}" - ] - } - } - ] -} diff --git a/salt/elasticsearch/files/ingest/common.nids b/salt/elasticsearch/files/ingest/common.nids index 53a3f7b79..84d170c93 100644 --- a/salt/elasticsearch/files/ingest/common.nids +++ b/salt/elasticsearch/files/ingest/common.nids @@ -1,17 +1,17 @@ { "description" : "common.nids", "processors" : [ - { "convert": { "if": "ctx.rule.uuid != null", "field": "rule.uuid", "type": "integer" } }, - { "set": { "if": "ctx.rule?.uuid < 1000000", "field": "rule.reference", "value": "https://www.snort.org/search?query={{rule.gid}}-{{rule.uuid}}" } }, - { "set": { "if": "ctx.rule?.uuid > 1999999", "field": "rule.reference", "value": "https://doc.emergingthreats.net/{{rule.uuid}}" } }, - { "convert": { "if": "ctx.rule.uuid != null", "field": "rule.uuid", "type": "string" } }, - { "dissect": { "if": "ctx.rule.name != null", "field": "rule.name", "pattern" : "%{rule_type} %{rest_of_rulename} ", "ignore_failure": true } }, - { "set": { "if": "ctx.rule_type == 'GPL'", "field": "rule.ruleset", "value": "Snort GPL" } }, - { "set": { "if": "ctx.rule_type == 'ET'", "field": "rule.ruleset", "value": "Emerging Threats" } }, - { "set": { "if": "ctx.rule.severity == 3", "field": "event.severity", "value": 1, "override": true } }, - { "set": { "if": "ctx.rule.severity == 2", "field": "event.severity", "value": 2, "override": true } }, - { "set": { "if": "ctx.rule.severity == 1", "field": "event.severity", "value": 3, "override": true } }, - { "remove": { "field": ["rule_type", "rest_of_rulename", "host"], "ignore_failure": true } }, - { "pipeline": { "name": "common" } } + { "convert": { "if": "ctx.rule.uuid != null", "field": "rule.uuid", "type": "integer" } }, + { "set": { "if": "ctx.rule?.uuid < 1000000", "field": "rule.reference", "value": "https://www.snort.org/rule_docs/{{rule.gid}}-{{rule.uuid}}" } }, + { "set": { "if": "ctx.rule?.uuid > 1999999", "field": "rule.reference", "value": "https://community.emergingthreats.net" } }, + { "convert": { "if": "ctx.rule.uuid != null", "field": "rule.uuid", "type": "string" } }, + { "dissect": { "if": "ctx.rule.name != null", "field": "rule.name", "pattern" : "%{rule_type} %{rest_of_rulename} ", "ignore_failure": true } }, + { "set": { "if": "ctx.rule_type == 'GPL'", "field": "rule.ruleset", "value": "Snort GPL" } }, + { "set": { "if": "ctx.rule_type == 'ET'", "field": "rule.ruleset", "value": "Emerging Threats" } }, + { "set": { "if": "ctx.rule.severity == 3", "field": "event.severity", "value": 1, "override": true } }, + { "set": { "if": "ctx.rule.severity == 2", "field": "event.severity", "value": 2, "override": true } }, + { "set": { "if": "ctx.rule.severity == 1", "field": "event.severity", "value": 3, "override": true } }, + { "remove": { "field": ["rule_type", "rest_of_rulename", "host"], "ignore_failure": true } }, + { "pipeline": { "name": "common" } } ] } diff --git a/salt/elasticsearch/files/ingest/filterlog b/salt/elasticsearch/files/ingest/filterlog index 52d83dd0a..13369e151 100644 --- a/salt/elasticsearch/files/ingest/filterlog +++ b/salt/elasticsearch/files/ingest/filterlog @@ -4,15 +4,15 @@ { "dissect": { "field": "real_message", - "pattern" : "%{rule.uuid},%{rule.sub_uuid},%{firewall.anchor},%{firewall.tracker_id},%{interface.name},%{rule.reason},%{rule.action},%{network.direction},%{ip.version},%{firewall.sub_message}", + "pattern" : "%{rule.uuid},%{rule.sub_uuid},%{firewall.anchor},%{rule.id},%{observer.ingress.interface.name},%{event.reason},%{event.action},%{network.direction},%{ip.version},%{firewall.sub_message}", "on_failure" : [ {"set" : {"field" : "error.message","value" : "{{ _ingest.on_failure_message }}"}}] } }, { "dissect": { - "if": "ctx.ip.version == '4'", + "if": "ctx.ip?.version == '4'", "field": "firewall.sub_message", - "pattern" : "%{ip.tos},%{ip.ecn},%{ip.ttl},%{ip.id},%{ip.offset},%{ip.flags},%{network.transport_id},%{network.transport},%{data.length},%{source.ip},%{destination.ip},%{ip_sub_msg}", + "pattern" : "%{pfsense.ip.tos},%{pfsense.ip.ecn},%{pfsense.ip.ttl},%{pfsense.ip.id},%{pfsense.ip.offset},%{pfsense.ip.flags},%{network.iana_number},%{network.transport},%{network.bytes},%{source.address},%{destination.address},%{ip_sub_msg}", "on_failure" : [ {"set" : {"field" : "error.message","value" : "{{ _ingest.on_failure_message }}"}}] } }, @@ -20,7 +20,7 @@ "dissect": { "if": "ctx.ip?.version == '6'", "field": "firewall.sub_message", - "pattern" : "%{network.class},%{network.flow_label},%{network.hop_limit},%{network.transport},%{network.transport_id},%{data.length},%{source.ip},%{destination.ip},%{ip_sub_msg}", + "pattern" : "%{pfsense.ip.tos},%{pfsense.ip.flow_label},%{network.hop_limit},%{network.transport},%{network.iana_number},%{network.bytes},%{source.address},%{destination.address},%{ip_sub_msg}", "on_failure" : [ {"set" : {"field" : "error.message","value" : "{{ _ingest.on_failure_message }}"}}] } }, @@ -28,7 +28,7 @@ "dissect": { "if": "ctx.network?.transport == 'tcp'", "field": "ip_sub_msg", - "pattern" : "%{source.port},%{destination.port},%{data.length},%{tcp.flags},", + "pattern" : "%{source.port},%{destination.port},%{pfsense.tcp.length},%{pfsense.tcp.flags},", "on_failure" : [ {"set" : {"field" : "error.message","value" : "{{ _ingest.on_failure_message }}"}}] } }, @@ -36,24 +36,33 @@ "dissect": { "if": "ctx.network?.transport == 'udp'", "field": "ip_sub_msg", - "pattern" : "%{source.port},%{destination.port},%{data.length}", + "pattern" : "%{source.port},%{destination.port},%{pfsense.udp.length}", "on_failure" : [ {"set" : {"field" : "error.message","value" : "{{ _ingest.on_failure_message }}"}}] } }, { "split": { - "if": "ctx.ip.version =='6' && ctx.network?.transport == 'Options'", + "if": "ctx.ip?.version =='6' && ctx.network?.transport == 'Options'", "field": "ip_sub_msg", "target_field": "ip.options", "separator" : ",", "on_failure" : [ {"set" : {"field" : "error.message","value" : "{{ _ingest.on_failure_message }}"}}] } }, - { "set": { "if": "ctx.network?.transport_id == '0'", "field": "network.transport", "value": "icmp", "override": true } }, - { "community_id": {} }, - { "set": { "field": "event.module", "value": "pfsense", "override": true } }, - { "set": { "field": "event.dataset", "value": "firewall", "override": true } }, - { "set": { "field": "category", "value": "network", "override": true } }, - { "remove": { "field": ["real_message", "ip_sub_msg", "firewall.sub_message"], "ignore_failure": true } } + { "lowercase": { "field": "network.transport", "ignore_failure": true } }, + { "set": { "field": "destination.ip", "value": "{{{destination.address}}}", "override": true } }, + { "set": { "field": "source.ip", "value": "{{{source.address}}}", "override": true } }, + { "set": { "if": "ctx.ip?.version == '4'", "field": "network.type", "value": "ipv4", "override": true} }, + { "set": { "if": "ctx.ip?.version == '6'", "field": "network.type", "value": "ipv6", "override": true} }, + { "set": { "if": "ctx.network?.direction == 'in'", "field": "network.direction", "value": "inbound", "override": true} }, + { "set": { "if": "ctx.network?.direction == 'out'", "field": "network.direction", "value": "outbound", "override": true} }, + { "set": { "field": "category", "value": "network", "override": true } }, + { "set": { "field": "event.dataset", "value": "firewall", "override": true } }, + { "set": { "field": "event.kind", "value": "event", "override": true } }, + { "set": { "field": "event.module", "value": "pfsense", "override": true } }, + { "set": { "field": "event.provider", "value": "filterlog", "override": true } }, + { "set": { "field": "observer.type", "value": "firewall", "override": true } }, + { "community_id":{ } }, + { "remove": { "field": ["real_message", "ip_sub_msg", "firewall.sub_message"], "ignore_failure": true } } ] } diff --git a/salt/elasticsearch/files/ingest/global@custom b/salt/elasticsearch/files/ingest/global@custom new file mode 100644 index 000000000..ccf57b2d7 --- /dev/null +++ b/salt/elasticsearch/files/ingest/global@custom @@ -0,0 +1,30 @@ +{ + "version": 3, + "_meta": { + "managed_by": "securityonion", + "managed": true + }, + "description": "Custom pipeline for processing all incoming Fleet Agent documents. \n", + "processors": [ + { "set": { "ignore_failure": true, "field": "event.module", "value": "elastic_agent" } }, + { "split": { "if": "ctx.event?.dataset != null && ctx.event.dataset.contains('.')", "field": "event.dataset", "separator": "\\.", "target_field": "module_temp" } }, + { "split": { "if": "ctx.data_stream?.dataset != null && ctx.data_stream?.dataset.contains('.')", "field":"data_stream.dataset", "separator":"\\.", "target_field":"datastream_dataset_temp", "ignore_missing":true } }, + { "set": { "if": "ctx.module_temp != null", "override": true, "field": "event.module", "value": "{{module_temp.0}}" } }, + { "set": { "if": "ctx.datastream_dataset_temp != null && ctx.datastream_dataset_temp[0] == 'network_traffic'", "field":"event.module", "value":"{{ datastream_dataset_temp.0 }}", "ignore_failure":true, "ignore_empty_value":true, "description":"Fix EA network packet capture" } }, + { "gsub": { "if": "ctx.event?.dataset != null && ctx.event.dataset.contains('.')", "field": "event.dataset", "pattern": "^[^.]*.", "replacement": "", "target_field": "dataset_tag_temp" } }, + { "append": { "if": "ctx.dataset_tag_temp != null", "field": "tags", "value": "{{dataset_tag_temp}}", "allow_duplicates": false } }, + { "set": { "if": "ctx.network?.direction == 'egress'", "override": true, "field": "network.initiated", "value": "true" } }, + { "set": { "if": "ctx.network?.direction == 'ingress'", "override": true, "field": "network.initiated", "value": "false" } }, + { "set": { "if": "ctx.network?.type == 'ipv4'", "override": true, "field": "destination.ipv6", "value": "false" } }, + { "set": { "if": "ctx.network?.type == 'ipv6'", "override": true, "field": "destination.ipv6", "value": "true" } }, + { "set": { "if": "ctx.tags != null && ctx.tags.contains('import')", "override": true, "field": "data_stream.dataset", "value": "import" } }, + { "set": { "if": "ctx.tags != null && ctx.tags.contains('import')", "override": true, "field": "data_stream.namespace", "value": "so" } }, + { "community_id":{ "if": "ctx.event?.dataset == 'endpoint.events.network'", "ignore_failure":true } }, + { "set": { "if": "ctx.event?.module == 'fim'", "override": true, "field": "event.module", "value": "file_integrity" } }, + { "rename": { "if": "ctx.winlog?.provider_name == 'Microsoft-Windows-Windows Defender'", "ignore_missing": true, "field": "winlog.event_data.Threat Name", "target_field": "winlog.event_data.threat_name" } }, + { "set": { "if": "ctx?.metadata?.kafka != null" , "field": "kafka.id", "value": "{{metadata.kafka.partition}}{{metadata.kafka.offset}}{{metadata.kafka.timestamp}}", "ignore_failure": true } }, + {"append": {"field":"related.ip","value":["{{source.ip}}","{{destination.ip}}"],"allow_duplicates":false,"if":"ctx?.event?.dataset == 'endpoint.events.network' && ctx?.source?.ip != null","ignore_failure":true}}, + {"foreach": {"field":"host.ip","processor":{"append":{"field":"related.ip","value":"{{_ingest._value}}","allow_duplicates":false}},"if":"ctx?.event?.module == 'endpoint'","description":"Extract IPs from Elastic Agent events (host.ip) and adds them to related.ip"}}, + { "remove": { "field": [ "message2", "type", "fields", "category", "module", "dataset", "event.dataset_temp", "dataset_tag_temp", "module_temp", "datastream_dataset_temp" ], "ignore_missing": true, "ignore_failure": true } } + ] +} diff --git a/salt/elasticsearch/files/ingest/hydra b/salt/elasticsearch/files/ingest/hydra new file mode 100644 index 000000000..6bb2c22d8 --- /dev/null +++ b/salt/elasticsearch/files/ingest/hydra @@ -0,0 +1,9 @@ +{ + "description" : "hydra", + "processors" : [ + {"set":{"field":"audience","value":"access","override":false,"ignore_failure":true}}, + {"set":{"field":"event.dataset","ignore_empty_value":true,"ignore_failure":true,"value":"hydra.{{{audience}}}","media_type":"text/plain"}}, + {"set":{"field":"event.action","ignore_failure":true,"copy_from":"msg" }}, + { "pipeline": { "name": "common" } } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/import.wel b/salt/elasticsearch/files/ingest/import.wel deleted file mode 100644 index d03cd34e4..000000000 --- a/salt/elasticsearch/files/ingest/import.wel +++ /dev/null @@ -1,11 +0,0 @@ -{ - "description" : "import.wel", - "processors" : [ - { "set": { "field": "event.ingested", "value": "{{ @timestamp }}" } }, - { "set" : { "field" : "@timestamp", "value" : "{{ event.created }}" } }, - { "remove": { "field": [ "event_record_id", "event.created" , "timestamp" , "winlog.event_data.UtcTime" ], "ignore_failure": true } }, - { "pipeline": { "if": "ctx.winlog?.channel == 'Microsoft-Windows-Sysmon/Operational'", "name": "sysmon" } }, - { "pipeline": { "if": "ctx.winlog?.channel != 'Microsoft-Windows-Sysmon/Operational'", "name":"win.eventlogs" } }, - { "pipeline": { "name": "common" } } - ] -} diff --git a/salt/elasticsearch/files/ingest/kismet.ad_hoc b/salt/elasticsearch/files/ingest/kismet.ad_hoc new file mode 100644 index 000000000..adfbd7901 --- /dev/null +++ b/salt/elasticsearch/files/ingest/kismet.ad_hoc @@ -0,0 +1,10 @@ +{ + "processors": [ + { + "rename": { + "field": "message2.kismet_device_base_macaddr", + "target_field": "network.wireless.bssid" + } + } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/kismet.ap b/salt/elasticsearch/files/ingest/kismet.ap new file mode 100644 index 000000000..a864c09e4 --- /dev/null +++ b/salt/elasticsearch/files/ingest/kismet.ap @@ -0,0 +1,50 @@ +{ + "processors": [ + { + "rename": { + "field": "message2.dot11_device.dot11_device_last_beaconed_ssid_record.dot11_advertisedssid_cloaked", + "target_field": "network.wireless.ssid_cloaked", + "if": "ctx?.message2?.dot11_device?.dot11_device_last_beaconed_ssid_record?.dot11_advertisedssid_cloaked != null" + } + }, + { + "rename": { + "field": "message2.dot11_device.dot11_device_last_beaconed_ssid_record.dot11_advertisedssid_ssid", + "target_field": "network.wireless.ssid", + "if": "ctx?.message2?.dot11_device?.dot11_device_last_beaconed_ssid_record?.dot11_advertisedssid_ssid != null" + } + }, + { + "set": { + "field": "network.wireless.ssid", + "value": "Hidden", + "if": "ctx?.network?.wireless?.ssid_cloaked != null && ctx?.network?.wireless?.ssid_cloaked == 1" + } + }, + { + "rename": { + "field": "message2.dot11_device.dot11_device_last_beaconed_ssid_record.dot11_advertisedssid_dot11e_channel_utilization_perc", + "target_field": "network.wireless.channel_utilization", + "if": "ctx?.message2?.dot11_device?.dot11_device_last_beaconed_ssid_record?.dot11_advertisedssid_dot11e_channel_utilization_perc != null" + } + }, + { + "rename": { + "field": "message2.dot11_device.dot11_device_last_bssid", + "target_field": "network.wireless.bssid" + } + }, + { + "foreach": { + "field": "message2.dot11_device.dot11_device_associated_client_map", + "processor": { + "append": { + "field": "network.wireless.associated_clients", + "value": "{{_ingest._key}}" + } + }, + "if": "ctx?.message2?.dot11_device?.dot11_device_associated_client_map != null" + } + } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/kismet.bridged b/salt/elasticsearch/files/ingest/kismet.bridged new file mode 100644 index 000000000..b61635e3a --- /dev/null +++ b/salt/elasticsearch/files/ingest/kismet.bridged @@ -0,0 +1,16 @@ +{ + "processors": [ + { + "rename": { + "field": "message2.kismet_device_base_macaddr", + "target_field": "client.mac" + } + }, + { + "rename": { + "field": "message2.dot11_device.dot11_device_last_bssid", + "target_field": "network.wireless.bssid" + } + } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/kismet.client b/salt/elasticsearch/files/ingest/kismet.client new file mode 100644 index 000000000..6da0a071b --- /dev/null +++ b/salt/elasticsearch/files/ingest/kismet.client @@ -0,0 +1,29 @@ +{ + "processors": [ + { + "rename": { + "field": "message2.kismet_device_base_macaddr", + "target_field": "client.mac" + } + }, + { + "rename": { + "field": "message2.dot11_device.dot11_device_last_bssid", + "target_field": "network.wireless.last_connected_bssid", + "if": "ctx?.message2?.dot11_device?.dot11_device_last_bssid != null" + } + }, + { + "foreach": { + "field": "message2.dot11_device.dot11_device_client_map", + "processor": { + "append": { + "field": "network.wireless.known_connected_bssid", + "value": "{{_ingest._key}}" + } + }, + "if": "ctx?.message2?.dot11_device?.dot11_device_client_map != null" + } + } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/kismet.common b/salt/elasticsearch/files/ingest/kismet.common new file mode 100644 index 000000000..14d439105 --- /dev/null +++ b/salt/elasticsearch/files/ingest/kismet.common @@ -0,0 +1,159 @@ +{ + "processors": [ + { + "json": { + "field": "message", + "target_field": "message2" + } + }, + { + "date": { + "field": "message2.kismet_device_base_mod_time", + "formats": [ + "epoch_second" + ], + "target_field": "@timestamp" + } + }, + { + "set": { + "field": "event.category", + "value": "network" + } + }, + { + "dissect": { + "field": "message2.kismet_device_base_type", + "pattern": "%{wifi} %{device_type}" + } + }, + { + "lowercase": { + "field": "device_type" + } + }, + { + "set": { + "field": "event.dataset", + "value": "kismet.{{device_type}}" + } + }, + { + "set": { + "field": "event.dataset", + "value": "kismet.wds_ap", + "if": "ctx?.device_type == 'wds ap'" + } + }, + { + "set": { + "field": "event.dataset", + "value": "kismet.ad_hoc", + "if": "ctx?.device_type == 'ad-hoc'" + } + }, + { + "set": { + "field": "event.module", + "value": "kismet" + } + }, + { + "rename": { + "field": "message2.kismet_device_base_packets_tx_total", + "target_field": "source.packets" + } + }, + { + "rename": { + "field": "message2.kismet_device_base_num_alerts", + "target_field": "kismet.alerts.count" + } + }, + { + "rename": { + "field": "message2.kismet_device_base_channel", + "target_field": "network.wireless.channel", + "if": "ctx?.message2?.kismet_device_base_channel != ''" + } + }, + { + "rename": { + "field": "message2.kismet_device_base_frequency", + "target_field": "network.wireless.frequency", + "if": "ctx?.message2?.kismet_device_base_frequency != 0" + } + }, + { + "rename": { + "field": "message2.kismet_device_base_last_time", + "target_field": "kismet.last_seen" + } + }, + { + "date": { + "field": "kismet.last_seen", + "formats": [ + "epoch_second" + ], + "target_field": "kismet.last_seen" + } + }, + { + "rename": { + "field": "message2.kismet_device_base_first_time", + "target_field": "kismet.first_seen" + } + }, + { + "date": { + "field": "kismet.first_seen", + "formats": [ + "epoch_second" + ], + "target_field": "kismet.first_seen" + } + }, + { + "rename": { + "field": "message2.kismet_device_base_seenby", + "target_field": "kismet.seenby" + } + }, + { + "foreach": { + "field": "kismet.seenby", + "processor": { + "pipeline": { + "name": "kismet.seenby" + } + } + } + }, + { + "rename": { + "field": "message2.kismet_device_base_manuf", + "target_field": "device.manufacturer" + } + }, + { + "pipeline": { + "name": "{{event.dataset}}" + } + }, + { + "remove": { + "field": [ + "message2", + "message", + "device_type", + "wifi", + "agent", + "host", + "event.created" + ], + "ignore_failure": true + } + } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/kismet.device b/salt/elasticsearch/files/ingest/kismet.device new file mode 100644 index 000000000..49d0c7ad7 --- /dev/null +++ b/salt/elasticsearch/files/ingest/kismet.device @@ -0,0 +1,9 @@ +{ + "processors": [ + { + "pipeline": { + "name": "kismet.client" + } + } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/kismet.seenby b/salt/elasticsearch/files/ingest/kismet.seenby new file mode 100644 index 000000000..d41220d76 --- /dev/null +++ b/salt/elasticsearch/files/ingest/kismet.seenby @@ -0,0 +1,52 @@ +{ + "processors": [ + { + "rename": { + "field": "_ingest._value.kismet_common_seenby_num_packets", + "target_field": "_ingest._value.packets_seen", + "ignore_missing": true + } + }, + { + "rename": { + "field": "_ingest._value.kismet_common_seenby_uuid", + "target_field": "_ingest._value.serial_number", + "ignore_missing": true + } + }, + { + "rename": { + "field": "_ingest._value.kismet_common_seenby_first_time", + "target_field": "_ingest._value.first_seen", + "ignore_missing": true + } + }, + { + "rename": { + "field": "_ingest._value.kismet_common_seenby_last_time", + "target_field": "_ingest._value.last_seen", + "ignore_missing": true + } + }, + { + "date": { + "field": "_ingest._value.first_seen", + "formats": [ + "epoch_second" + ], + "target_field": "_ingest._value.first_seen", + "ignore_failure": true + } + }, + { + "date": { + "field": "_ingest._value.last_seen", + "formats": [ + "epoch_second" + ], + "target_field": "_ingest._value.last_seen", + "ignore_failure": true + } + } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/kismet.wds b/salt/elasticsearch/files/ingest/kismet.wds new file mode 100644 index 000000000..1e426c463 --- /dev/null +++ b/salt/elasticsearch/files/ingest/kismet.wds @@ -0,0 +1,10 @@ +{ + "processors": [ + { + "rename": { + "field": "message2.kismet_device_base_macaddr", + "target_field": "client.mac" + } + } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/kismet.wds_ap b/salt/elasticsearch/files/ingest/kismet.wds_ap new file mode 100644 index 000000000..4d10b211b --- /dev/null +++ b/salt/elasticsearch/files/ingest/kismet.wds_ap @@ -0,0 +1,22 @@ +{ + "processors": [ + { + "rename": { + "field": "message2.kismet_device_base_commonname", + "target_field": "network.wireless.bssid" + } + }, + { + "foreach": { + "field": "message2.dot11_device.dot11_device_associated_client_map", + "processor": { + "append": { + "field": "network.wireless.associated_clients", + "value": "{{_ingest._key}}" + } + }, + "if": "ctx?.message2?.dot11_device?.dot11_device_associated_client_map != null" + } + } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/logs-pfsense.log-1.21.0 b/salt/elasticsearch/files/ingest/logs-pfsense.log-1.21.0 new file mode 100644 index 000000000..7c4f2575f --- /dev/null +++ b/salt/elasticsearch/files/ingest/logs-pfsense.log-1.21.0 @@ -0,0 +1,420 @@ +{ + "description": "Pipeline for PFsense", + "_meta": { + "managed_by": "fleet", + "managed": true, + "package": { + "name": "pfsense" + } + }, + "processors": [ + { + "set": { + "field": "ecs.version", + "value": "8.17.0" + } + }, + { + "set": { + "field": "observer.vendor", + "value": "netgate" + } + }, + { + "set": { + "field": "observer.type", + "value": "firewall" + } + }, + { + "rename": { + "field": "message", + "target_field": "event.original", + "ignore_missing": true, + "if": "ctx.event?.original == null" + } + }, + { + "set": { + "field": "event.kind", + "value": "event" + } + }, + { + "set": { + "field": "event.timezone", + "value": "{{{_tmp.tz_offset}}}", + "if": "ctx._tmp?.tz_offset != null && ctx._tmp?.tz_offset != 'local'" + } + }, + { + "grok": { + "description": "Parse syslog header", + "field": "event.original", + "patterns": [ + "^(%{ECS_SYSLOG_PRI})?%{TIMESTAMP} %{GREEDYDATA:message}" + ], + "pattern_definitions": { + "ECS_SYSLOG_PRI": "<%{NONNEGINT:log.syslog.priority:long}>(\\d )?", + "TIMESTAMP": "(?:%{BSD_TIMESTAMP_FORMAT}|%{SYSLOG_TIMESTAMP_FORMAT})", + "BSD_TIMESTAMP_FORMAT": "%{SYSLOGTIMESTAMP:_tmp.timestamp}(%{SPACE}%{BSD_PROCNAME}|%{SPACE}%{OBSERVER}%{SPACE}%{BSD_PROCNAME})(\\[%{POSINT:process.pid:long}\\])?:", + "BSD_PROCNAME": "(?:\\b%{NAME:process.name}|\\(%{NAME:process.name}\\))", + "NAME": "[[[:alnum:]]_-]+", + "SYSLOG_TIMESTAMP_FORMAT": "%{TIMESTAMP_ISO8601:_tmp.timestamp8601}%{SPACE}%{OBSERVER}%{SPACE}%{PROCESS}%{SPACE}(%{POSINT:process.pid:long}|-) - (-|%{META})", + "TIMESTAMP_ISO8601": "%{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE:event.timezone}?", + "OBSERVER": "(?:%{IP:observer.ip}|%{HOSTNAME:observer.name})", + "UNIXPATH": "(/([\\w_%!$@:.,+~-]+|\\\\.)*)*", + "PROCESS": "(\\(%{DATA:process.name}\\)|(?:%{UNIXPATH})%{BASEPATH:process.name})", + "BASEPATH": "[[[:alnum:]]_%!$@:.,+~-]+", + "META": "\\[[^\\]]*\\]" + } + } + }, + { + "date": { + "if": "ctx._tmp.timestamp8601 != null", + "field": "_tmp.timestamp8601", + "target_field": "@timestamp", + "formats": [ + "ISO8601" + ] + } + }, + { + "date": { + "if": "ctx.event?.timezone != null && ctx._tmp?.timestamp != null", + "field": "_tmp.timestamp", + "target_field": "@timestamp", + "formats": [ + "MMM d HH:mm:ss", + "MMM d HH:mm:ss", + "MMM dd HH:mm:ss" + ], + "timezone": "{{{ event.timezone }}}" + } + }, + { + "grok": { + "description": "Set Event Provider", + "field": "process.name", + "patterns": [ + "^%{HYPHENATED_WORDS:event.provider}" + ], + "pattern_definitions": { + "HYPHENATED_WORDS": "\\b[A-Za-z0-9_]+(-[A-Za-z_]+)*\\b" + } + } + }, + { + "pipeline": { + "name": "logs-pfsense.log-1.21.0-firewall", + "if": "ctx.event.provider == 'filterlog'" + } + }, + { + "pipeline": { + "name": "logs-pfsense.log-1.21.0-openvpn", + "if": "ctx.event.provider == 'openvpn'" + } + }, + { + "pipeline": { + "name": "logs-pfsense.log-1.21.0-ipsec", + "if": "ctx.event.provider == 'charon'" + } + }, + { + "pipeline": { + "name": "logs-pfsense.log-1.21.0-dhcp", + "if": "[\"dhcpd\", \"dhclient\", \"dhcp6c\"].contains(ctx.event.provider)" + } + }, + { + "pipeline": { + "name": "logs-pfsense.log-1.21.0-unbound", + "if": "ctx.event.provider == 'unbound'" + } + }, + { + "pipeline": { + "name": "logs-pfsense.log-1.21.0-haproxy", + "if": "ctx.event.provider == 'haproxy'" + } + }, + { + "pipeline": { + "name": "logs-pfsense.log-1.21.0-php-fpm", + "if": "ctx.event.provider == 'php-fpm'" + } + }, + { + "pipeline": { + "name": "logs-pfsense.log-1.21.0-squid", + "if": "ctx.event.provider == 'squid'" + } + }, + { + "pipeline": { + "name": "logs-pfsense.log-1.21.0-snort", + "if": "ctx.event.provider == 'snort'" + } + }, + { + "pipeline": { + "name": "logs-pfsense.log-1.21.0-suricata", + "if": "ctx.event.provider == 'suricata'" + } + }, + { + "drop": { + "if": "![\"filterlog\", \"openvpn\", \"charon\", \"dhcpd\", \"dhclient\", \"dhcp6c\", \"unbound\", \"haproxy\", \"php-fpm\", \"squid\", \"snort\", \"suricata\"].contains(ctx.event?.provider)" + } + }, + { + "append": { + "field": "event.category", + "value": "network", + "if": "ctx.network != null" + } + }, + { + "convert": { + "field": "source.address", + "target_field": "source.ip", + "type": "ip", + "ignore_failure": true, + "ignore_missing": true + } + }, + { + "convert": { + "field": "destination.address", + "target_field": "destination.ip", + "type": "ip", + "ignore_failure": true, + "ignore_missing": true + } + }, + { + "set": { + "field": "network.type", + "value": "ipv6", + "if": "ctx.source?.ip != null && ctx.source.ip.contains(\":\")" + } + }, + { + "set": { + "field": "network.type", + "value": "ipv4", + "if": "ctx.source?.ip != null && ctx.source.ip.contains(\".\")" + } + }, + { + "geoip": { + "field": "source.ip", + "target_field": "source.geo", + "ignore_missing": true + } + }, + { + "geoip": { + "field": "destination.ip", + "target_field": "destination.geo", + "ignore_missing": true + } + }, + { + "geoip": { + "ignore_missing": true, + "database_file": "GeoLite2-ASN.mmdb", + "field": "source.ip", + "target_field": "source.as", + "properties": [ + "asn", + "organization_name" + ] + } + }, + { + "geoip": { + "database_file": "GeoLite2-ASN.mmdb", + "field": "destination.ip", + "target_field": "destination.as", + "properties": [ + "asn", + "organization_name" + ], + "ignore_missing": true + } + }, + { + "rename": { + "field": "source.as.asn", + "target_field": "source.as.number", + "ignore_missing": true + } + }, + { + "rename": { + "field": "source.as.organization_name", + "target_field": "source.as.organization.name", + "ignore_missing": true + } + }, + { + "rename": { + "field": "destination.as.asn", + "target_field": "destination.as.number", + "ignore_missing": true + } + }, + { + "rename": { + "field": "destination.as.organization_name", + "target_field": "destination.as.organization.name", + "ignore_missing": true + } + }, + { + "community_id": { + "target_field": "network.community_id", + "ignore_failure": true + } + }, + { + "grok": { + "field": "observer.ingress.interface.name", + "patterns": [ + "%{DATA}.%{NONNEGINT:observer.ingress.vlan.id}" + ], + "ignore_missing": true, + "ignore_failure": true + } + }, + { + "set": { + "field": "network.vlan.id", + "copy_from": "observer.ingress.vlan.id", + "ignore_empty_value": true + } + }, + { + "append": { + "field": "related.ip", + "value": "{{{destination.ip}}}", + "allow_duplicates": false, + "if": "ctx.destination?.ip != null" + } + }, + { + "append": { + "field": "related.ip", + "value": "{{{source.ip}}}", + "allow_duplicates": false, + "if": "ctx.source?.ip != null" + } + }, + { + "append": { + "field": "related.ip", + "value": "{{{source.nat.ip}}}", + "allow_duplicates": false, + "if": "ctx.source?.nat?.ip != null" + } + }, + { + "append": { + "field": "related.hosts", + "value": "{{{destination.domain}}}", + "if": "ctx.destination?.domain != null" + } + }, + { + "append": { + "field": "related.user", + "value": "{{{user.name}}}", + "if": "ctx.user?.name != null" + } + }, + { + "set": { + "field": "network.direction", + "value": "{{{network.direction}}}bound", + "if": "ctx.network?.direction != null && ctx.network?.direction =~ /^(in|out)$/" + } + }, + { + "remove": { + "field": [ + "_tmp" + ], + "ignore_failure": true + } + }, + { + "script": { + "lang": "painless", + "description": "This script processor iterates over the whole document to remove fields with null values.", + "source": "void handleMap(Map map) {\n for (def x : map.values()) {\n if (x instanceof Map) {\n handleMap(x);\n } else if (x instanceof List) {\n handleList(x);\n }\n }\n map.values().removeIf(v -> v == null || (v instanceof String && v == \"-\"));\n}\nvoid handleList(List list) {\n for (def x : list) {\n if (x instanceof Map) {\n handleMap(x);\n } else if (x instanceof List) {\n handleList(x);\n }\n }\n}\nhandleMap(ctx);\n" + } + }, + { + "remove": { + "field": "event.original", + "if": "ctx.tags == null || !(ctx.tags.contains('preserve_original_event'))", + "ignore_failure": true, + "ignore_missing": true + } + }, + { + "pipeline": { + "name": "global@custom", + "ignore_missing_pipeline": true, + "description": "[Fleet] Global pipeline for all data streams" + } + }, + { + "pipeline": { + "name": "logs@custom", + "ignore_missing_pipeline": true, + "description": "[Fleet] Pipeline for all data streams of type `logs`" + } + }, + { + "pipeline": { + "name": "logs-pfsense.integration@custom", + "ignore_missing_pipeline": true, + "description": "[Fleet] Pipeline for all data streams of type `logs` defined by the `pfsense` integration" + } + }, + { + "pipeline": { + "name": "logs-pfsense.log@custom", + "ignore_missing_pipeline": true, + "description": "[Fleet] Pipeline for the `pfsense.log` dataset" + } + } + ], + "on_failure": [ + { + "remove": { + "field": [ + "_tmp" + ], + "ignore_failure": true + } + }, + { + "set": { + "field": "event.kind", + "value": "pipeline_error" + } + }, + { + "append": { + "field": "error.message", + "value": "{{{ _ingest.on_failure_message }}}" + } + } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/logs-pfsense.log-1.21.0-suricata b/salt/elasticsearch/files/ingest/logs-pfsense.log-1.21.0-suricata new file mode 100644 index 000000000..9cb10c2bb --- /dev/null +++ b/salt/elasticsearch/files/ingest/logs-pfsense.log-1.21.0-suricata @@ -0,0 +1,36 @@ +{ + "description": "Pipeline for parsing pfSense Suricata logs.", + "processors": [ + { "set": { + "field": "event.module", + "value": "suricata" + } + }, + { + "pipeline": { + "name": "suricata.common_pfsense" + } + } + ], + "on_failure": [ + { + "set": { + "field": "event.kind", + "value": "pipeline_error" + } + }, + { + "append": { + "field": "error.message", + "value": "{{{ _ingest.on_failure_message }}}" + } + } + ], + "_meta": { + "managed_by": "fleet", + "managed": true, + "package": { + "name": "pfsense" + } + } +} diff --git a/salt/elasticsearch/files/ingest/rita.beacon b/salt/elasticsearch/files/ingest/rita.beacons similarity index 100% rename from salt/elasticsearch/files/ingest/rita.beacon rename to salt/elasticsearch/files/ingest/rita.beacons diff --git a/salt/elasticsearch/files/ingest/rita.connection b/salt/elasticsearch/files/ingest/rita.connections similarity index 100% rename from salt/elasticsearch/files/ingest/rita.connection rename to salt/elasticsearch/files/ingest/rita.connections diff --git a/salt/elasticsearch/files/ingest/strelka.file b/salt/elasticsearch/files/ingest/strelka.file index a74a7c622..d9aed3b29 100644 --- a/salt/elasticsearch/files/ingest/strelka.file +++ b/salt/elasticsearch/files/ingest/strelka.file @@ -56,6 +56,7 @@ { "set": { "if": "ctx.exiftool?.Subsystem != null", "field": "host.subsystem", "value": "{{exiftool.Subsystem}}", "ignore_failure": true }}, { "set": { "if": "ctx.scan?.yara?.matches instanceof List", "field": "rule.name", "value": "{{scan.yara.matches.0}}" }}, { "set": { "if": "ctx.rule?.name != null", "field": "event.dataset", "value": "alert", "override": true }}, + { "set": { "if": "ctx.rule?.name != null", "field": "rule.uuid", "value": "{{rule.name}}", "override": true }}, { "rename": { "field": "file.flavors.mime", "target_field": "file.mime_type", "ignore_missing": true }}, { "set": { "if": "ctx.rule?.name != null && ctx.rule?.score == null", "field": "event.severity", "value": 3, "override": true } }, { "convert" : { "if": "ctx.rule?.score != null", "field" : "rule.score","type": "integer"}}, @@ -67,7 +68,8 @@ { "set": { "if": "ctx.scan?.pe?.image_version == '0'", "field": "scan.pe.image_version", "value": "0.0", "override": true } }, { "set": { "field": "observer.name", "value": "{{agent.name}}" }}, { "convert" : { "field" : "scan.exiftool","type": "string", "ignore_missing":true }}, - { "remove": { "field": ["host", "path", "message", "exiftool", "scan.yara.meta"], "ignore_missing": true } }, - { "pipeline": { "name": "common" } } + { "convert" : { "field" : "scan.pe.flags","type": "string", "ignore_missing":true }}, + { "remove": { "field": ["host", "path", "message", "exiftool", "scan.yara.meta"], "ignore_missing": true } }, + { "pipeline": { "name": "common" } } ] } diff --git a/salt/elasticsearch/files/ingest/suricata.alert b/salt/elasticsearch/files/ingest/suricata.alert index 87d5144ed..3d0241e48 100644 --- a/salt/elasticsearch/files/ingest/suricata.alert +++ b/salt/elasticsearch/files/ingest/suricata.alert @@ -1,6 +1,7 @@ { "description" : "suricata.alert", "processors" : [ + { "set": { "if": "ctx.event?.imported != true", "field": "_index", "value": "logs-suricata.alerts-so" } }, { "set": { "field": "tags","value": "alert" }}, { "rename":{ "field": "message2.alert", "target_field": "rule", "ignore_failure": true } }, { "rename":{ "field": "rule.signature", "target_field": "rule.name", "ignore_failure": true } }, @@ -8,6 +9,7 @@ { "rename":{ "field": "rule.signature_id", "target_field": "rule.uuid", "ignore_failure": true } }, { "rename":{ "field": "rule.signature_id", "target_field": "rule.signature", "ignore_failure": true } }, { "rename":{ "field": "message2.payload_printable", "target_field": "network.data.decoded", "ignore_failure": true } }, + { "dissect": { "field": "rule.rule", "pattern": "%{?prefix}content:\"%{dns.query_name}\"%{?remainder}", "ignore_missing": true, "ignore_failure": true } }, { "pipeline": { "name": "common.nids" } } ] -} +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/suricata.alert_pfsense b/salt/elasticsearch/files/ingest/suricata.alert_pfsense new file mode 100644 index 000000000..32b0a285d --- /dev/null +++ b/salt/elasticsearch/files/ingest/suricata.alert_pfsense @@ -0,0 +1,16 @@ +{ + "description" : "suricata.alert", + "processors" : [ + { "set": { "field": "data_stream.dataset", "value": "suricata" } }, + { "set": { "field": "data_stream.namespace", "value": "so" } }, + { "set": { "field": "_index", "value": "logs-suricata.alerts-so" } }, + { "set": { "field": "tags","value": "alert" }}, + { "rename":{ "field": "message2.alert", "target_field": "rule", "ignore_failure": true } }, + { "rename":{ "field": "rule.signature", "target_field": "rule.name", "ignore_failure": true } }, + { "rename":{ "field": "rule.ref", "target_field": "rule.version", "ignore_failure": true } }, + { "rename":{ "field": "rule.signature_id", "target_field": "rule.uuid", "ignore_failure": true } }, + { "rename":{ "field": "rule.signature_id", "target_field": "rule.signature", "ignore_failure": true } }, + { "rename":{ "field": "message2.payload_printable", "target_field": "network.data.decoded", "ignore_failure": true } }, + { "pipeline": { "name": "common.nids" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/suricata.common b/salt/elasticsearch/files/ingest/suricata.common index 6b6a03a60..102b5dac8 100644 --- a/salt/elasticsearch/files/ingest/suricata.common +++ b/salt/elasticsearch/files/ingest/suricata.common @@ -4,6 +4,7 @@ { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, { "rename": { "field": "message2.pkt_src", "target_field": "network.packet_source","ignore_failure": true } }, { "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_failure": true } }, + { "rename": { "field": "message2.in_iface", "target_field": "observer.ingress.interface.name", "ignore_failure": true } }, { "rename": { "field": "message2.flow_id", "target_field": "log.id.uid", "ignore_failure": true } }, { "rename": { "field": "message2.src_ip", "target_field": "source.ip", "ignore_failure": true } }, { "rename": { "field": "message2.src_port", "target_field": "source.port", "ignore_failure": true } }, @@ -17,6 +18,13 @@ { "set": { "field": "event.ingested", "value": "{{@timestamp}}" } }, { "date": { "field": "message2.timestamp", "target_field": "@timestamp", "formats": ["ISO8601", "UNIX"], "timezone": "UTC", "ignore_failure": true } }, { "remove":{ "field": "agent", "ignore_failure": true } }, + {"append":{"field":"related.ip","value":["{{source.ip}}","{{destination.ip}}"],"allow_duplicates":false,"ignore_failure":true}}, + { + "script": { + "source": "boolean isPrivate(def ip) { if (ip == null) return false; int dot1 = ip.indexOf('.'); if (dot1 == -1) return false; int dot2 = ip.indexOf('.', dot1 + 1); if (dot2 == -1) return false; int first = Integer.parseInt(ip.substring(0, dot1)); if (first == 10) return true; if (first == 192 && ip.startsWith('168.', dot1 + 1)) return true; if (first == 172) { int second = Integer.parseInt(ip.substring(dot1 + 1, dot2)); return second >= 16 && second <= 31; } return false; } String[] fields = new String[] {\"source\", \"destination\"}; for (int i = 0; i < fields.length; i++) { def field = fields[i]; def ip = ctx[field]?.ip; if (ip != null) { if (ctx.network == null) ctx.network = new HashMap(); if (isPrivate(ip)) { if (ctx.network.private_ip == null) ctx.network.private_ip = new ArrayList(); if (!ctx.network.private_ip.contains(ip)) ctx.network.private_ip.add(ip); } else { if (ctx.network.public_ip == null) ctx.network.public_ip = new ArrayList(); if (!ctx.network.public_ip.contains(ip)) ctx.network.public_ip.add(ip); } } }", + "ignore_failure": false + } + }, { "pipeline": { "if": "ctx?.event?.dataset != null", "name": "suricata.{{event.dataset}}" } } ] } diff --git a/salt/elasticsearch/files/ingest/suricata.common_pfsense b/salt/elasticsearch/files/ingest/suricata.common_pfsense new file mode 100644 index 000000000..04da7b482 --- /dev/null +++ b/salt/elasticsearch/files/ingest/suricata.common_pfsense @@ -0,0 +1,23 @@ +{ + "description" : "suricata.common", + "processors" : [ + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.pkt_src", "target_field": "network.packet_source","ignore_failure": true } }, + { "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_failure": true } }, + { "rename": { "field": "message2.in_iface", "target_field": "observer.ingress.interface.name", "ignore_failure": true } }, + { "rename": { "field": "message2.flow_id", "target_field": "log.id.uid", "ignore_failure": true } }, + { "rename": { "field": "message2.src_ip", "target_field": "source.ip", "ignore_failure": true } }, + { "rename": { "field": "message2.src_port", "target_field": "source.port", "ignore_failure": true } }, + { "rename": { "field": "message2.dest_ip", "target_field": "destination.ip", "ignore_failure": true } }, + { "rename": { "field": "message2.dest_port", "target_field": "destination.port", "ignore_failure": true } }, + { "rename": { "field": "message2.vlan", "target_field": "network.vlan.id", "ignore_failure": true } }, + { "rename": { "field": "message2.community_id", "target_field": "network.community_id", "ignore_missing": true } }, + { "rename": { "field": "message2.xff", "target_field": "xff.ip", "ignore_missing": true } }, + { "set": { "field": "event.dataset", "value": "{{ message2.event_type }}" } }, + { "set": { "field": "observer.name", "value": "{{agent.name}}" } }, + { "set": { "field": "event.ingested", "value": "{{@timestamp}}" } }, + { "date": { "field": "message2.timestamp", "target_field": "@timestamp", "formats": ["ISO8601", "UNIX"], "timezone": "UTC", "ignore_failure": true } }, + { "remove":{ "field": "agent", "ignore_failure": true } }, + { "pipeline": { "if": "ctx?.event?.dataset != null", "name": "suricata.{{event.dataset}}_pfsense" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/suricata.ike b/salt/elasticsearch/files/ingest/suricata.ike new file mode 100644 index 000000000..890b99baf --- /dev/null +++ b/salt/elasticsearch/files/ingest/suricata.ike @@ -0,0 +1,21 @@ +{ + "description" : "suricata.ike", + "processors" : [ + { "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_missing": true } }, + { "rename": { "field": "message2.app_proto", "target_field": "network.protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.alg_auth", "target_field": "ike.algorithm.authentication", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.alg_enc", "target_field": "ike.algorithm.encryption", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.alg_esn", "target_field": "ike.algorithm.esn", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.alg_dh", "target_field": "ike.algorithm.dh", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.alg_prf", "target_field": "ike.algorithm.prf", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.exchange_type", "target_field": "ike.exchange_type", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.payload", "target_field": "ike.payload", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.role", "target_field": "ike.role", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.init_spi", "target_field": "ike.spi.initiator", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.resp_spi", "target_field": "ike.spi.responder", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.version_major", "target_field": "ike.version.major", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.version_minor", "target_field": "ike.version.minor", "ignore_missing": true } }, + { "rename": { "field": "message2.ike.ikev2.errors", "target_field": "ike.ikev2.errors", "ignore_missing": true } }, + { "pipeline": { "name": "common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/suricata.ikev2 b/salt/elasticsearch/files/ingest/suricata.ikev2 deleted file mode 100644 index 1916f6369..000000000 --- a/salt/elasticsearch/files/ingest/suricata.ikev2 +++ /dev/null @@ -1,8 +0,0 @@ -{ - "description" : "suricata.ikev2", - "processors" : [ - { "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_missing": true } }, - { "rename": { "field": "message2.app_proto", "target_field": "network.protocol", "ignore_missing": true } }, - { "pipeline": { "name": "common" } } - ] -} diff --git a/salt/elasticsearch/files/ingest/zeek.common b/salt/elasticsearch/files/ingest/zeek.common index 3265e20be..ff62a9d5d 100644 --- a/salt/elasticsearch/files/ingest/zeek.common +++ b/salt/elasticsearch/files/ingest/zeek.common @@ -12,12 +12,14 @@ { "rename": { "field": "message2.id.orig_p", "target_field": "source.port", "ignore_missing": true } }, { "rename": { "field": "message2.id.resp_h", "target_field": "destination.ip", "ignore_missing": true } }, { "rename": { "field": "message2.id.resp_p", "target_field": "destination.port", "ignore_missing": true } }, - { "community_id": {} }, + { "rename": { "field": "message2.community_id", "target_field": "network.community_id", "ignore_missing": true } }, + { "community_id": { "if": "ctx.network?.community_id == null" } }, { "set": { "if": "ctx.source?.ip != null", "field": "client.ip", "value": "{{source.ip}}" } }, { "set": { "if": "ctx.source?.port != null", "field": "client.port", "value": "{{source.port}}" } }, { "set": { "if": "ctx.destination?.ip != null", "field": "server.ip", "value": "{{destination.ip}}" } }, { "set": { "if": "ctx.destination?.port != null", "field": "server.port", "value": "{{destination.port}}" } }, { "set": { "field": "observer.name", "value": "{{agent.name}}" } }, + { "append": { "if": "ctx.network?.protocol != null && ctx.network?.protocol.contains(\"openvpn\")","field": "tags","value": ["{{network.protocol}}"],"allow_duplicates": false,"ignore_failure": true}}, { "date": { "field": "message2.ts", "target_field": "@timestamp", "formats": ["ISO8601", "UNIX"], "ignore_failure": true } }, { "remove": { "field": ["agent"], "ignore_failure": true } }, { "pipeline": { "name": "common" } } diff --git a/salt/elasticsearch/files/ingest/zeek.conn b/salt/elasticsearch/files/ingest/zeek.conn index 8b458e032..6051d93a1 100644 --- a/salt/elasticsearch/files/ingest/zeek.conn +++ b/salt/elasticsearch/files/ingest/zeek.conn @@ -38,6 +38,8 @@ { "set": { "if": "ctx.connection?.state == 'SH'", "field": "connection.state_description", "value": "Originator sent a SYN followed by a FIN, we never saw a SYN ACK from the responder (hence the connection was 'half' open)" } }, { "set": { "if": "ctx.connection?.state == 'SHR'", "field": "connection.state_description", "value": "Responder sent a SYN ACK followed by a FIN, we never saw a SYN from the originator" } }, { "set": { "if": "ctx.connection?.state == 'OTH'", "field": "connection.state_description", "value": "No SYN seen, just midstream traffic (a 'partial connection' that was not later closed)" } }, + { "set": { "if": "ctx.network?.protocol != null && ctx.network?.protocol.contains(\"ipsec\")", "field": "network.protocol", "value": "ipsec"}}, + { "set": { "if": "ctx.network?.protocol != null && ctx.network?.protocol.contains(\"openvpn\")", "field": "network.protocol", "value": "openvpn"}}, { "pipeline": { "name": "zeek.common" } } ] } diff --git a/salt/elasticsearch/files/ingest/zeek.dns b/salt/elasticsearch/files/ingest/zeek.dns index 57a9347a5..5616310bd 100644 --- a/salt/elasticsearch/files/ingest/zeek.dns +++ b/salt/elasticsearch/files/ingest/zeek.dns @@ -20,7 +20,8 @@ { "rename": { "field": "message2.RD", "target_field": "dns.recursion.desired", "ignore_missing": true } }, { "rename": { "field": "message2.RA", "target_field": "dns.recursion.available", "ignore_missing": true } }, { "rename": { "field": "message2.Z", "target_field": "dns.reserved", "ignore_missing": true } }, - { "rename": { "field": "message2.answers", "target_field": "dns.answers.name", "ignore_missing": true } }, + { "rename": { "field": "message2.answers", "target_field": "dns.answers.name", "ignore_missing": true } }, + { "script": { "lang": "painless", "if": "ctx.dns != null && ctx.dns.answers != null && ctx.dns.answers.name != null", "source": "def ips = []; for (item in ctx.dns.answers.name) { if (item =~ /^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$/ || item =~ /^([a-fA-F0-9:]+:+)+[a-fA-F0-9]+$/) { ips.add(item); } } ctx.dns.resolved_ip = ips;" } }, { "rename": { "field": "message2.TTLs", "target_field": "dns.ttls", "ignore_missing": true } }, { "rename": { "field": "message2.rejected", "target_field": "dns.query.rejected", "ignore_missing": true } }, { "script": { "lang": "painless", "source": "ctx.dns.query.length = ctx.dns.query.name.length()", "ignore_failure": true } }, @@ -28,4 +29,4 @@ { "pipeline": { "if": "ctx.dns?.query?.name != null && ctx.dns.query.name.contains('.')", "name": "dns.tld" } }, { "pipeline": { "name": "zeek.common" } } ] -} +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/zeek.http2 b/salt/elasticsearch/files/ingest/zeek.http2 new file mode 100644 index 000000000..eeeecef8c --- /dev/null +++ b/salt/elasticsearch/files/ingest/zeek.http2 @@ -0,0 +1,37 @@ +{ + "description" : "zeek.http2", + "processors" : [ + { "set": { "field": "event.dataset", "value": "http2" } }, + { "set": { "field": "network.transport", "value": "tcp" } }, + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.trans_depth", "target_field": "http.trans_depth", "ignore_missing": true } }, + { "rename": { "field": "message2.method", "target_field": "http.method", "ignore_missing": true } }, + { "rename": { "field": "message2.host", "target_field": "http.virtual_host", "ignore_missing": true } }, + { "rename": { "field": "message2.uri", "target_field": "http.uri", "ignore_missing": true } }, + { "rename": { "field": "message2.referrer", "target_field": "http.referrer", "ignore_missing": true } }, + { "rename": { "field": "message2.version", "target_field": "http.version", "ignore_missing": true } }, + { "rename": { "field": "message2.user_agent", "target_field": "http.useragent", "ignore_missing": true } }, + { "rename": { "field": "message2.request_body_len", "target_field": "http.request.body.length", "ignore_missing": true } }, + { "rename": { "field": "message2.response_body_len", "target_field": "http.response.body.length", "ignore_missing": true } }, + { "rename": { "field": "message2.status_code", "target_field": "http.status_code", "ignore_missing": true } }, + { "rename": { "field": "message2.status_msg", "target_field": "http.status_message", "ignore_missing": true } }, + { "rename": { "field": "message2.info_code", "target_field": "http.info_code", "ignore_missing": true } }, + { "rename": { "field": "message2.info_msg", "target_field": "http.info_message", "ignore_missing": true } }, + { "rename": { "field": "message2.username", "target_field": "http.user", "ignore_missing": true } }, + { "rename": { "field": "message2.password", "target_field": "http.password", "ignore_missing": true } }, + { "rename": { "field": "message2.proxied", "target_field": "http.proxied", "ignore_missing": true } }, + { "rename": { "field": "message2.orig_fuids", "target_field": "log.id.orig_fuids", "ignore_missing": true } }, + { "rename": { "field": "message2.orig_filenames", "target_field": "file.orig_filenames", "ignore_missing": true } }, + { "rename": { "field": "message2.orig_mime_types", "target_field": "file.orig_mime_types", "ignore_missing": true } }, + { "rename": { "field": "message2.resp_fuids", "target_field": "log.id.resp_fuids", "ignore_missing": true } }, + { "rename": { "field": "message2.resp_filenames", "target_field": "file.resp_filenames", "ignore_missing": true } }, + { "rename": { "field": "message2.resp_mime_types", "target_field": "file.resp_mime_types", "ignore_missing": true } }, + { "rename": { "field": "message2.stream_id", "target_field": "http2.stream_id", "ignore_missing": true } }, + { "remove": { "field": "message2.tags", "ignore_failure": true } }, + { "remove": { "field": ["host"], "ignore_failure": true } }, + { "script": { "lang": "painless", "source": "ctx.uri_length = ctx.uri.length()", "ignore_failure": true } }, + { "script": { "lang": "painless", "source": "ctx.useragent_length = ctx.useragent.length()", "ignore_failure": true } }, + { "script": { "lang": "painless", "source": "ctx.virtual_host_length = ctx.virtual_host.length()", "ignore_failure": true } }, + { "pipeline": { "name": "zeek.common" } } + ] +} diff --git a/salt/elasticsearch/files/ingest/zeek.ipsec b/salt/elasticsearch/files/ingest/zeek.ipsec new file mode 100644 index 000000000..bf2872ebc --- /dev/null +++ b/salt/elasticsearch/files/ingest/zeek.ipsec @@ -0,0 +1,38 @@ +{ + "description": "zeek.ipsec", + "processors": [ + {"set": { "field": "event.dataset","value": "ipsec"}}, + {"json": { "field": "message","target_field": "message2","ignore_failure": true}}, + {"rename": {"field": "message2.initiator_spi","target_field": "ipsec.initiator_spi","ignore_missing": true}}, + {"rename": {"field": "message2.responder_spi","target_field": "ipsec.responder_spi","ignore_missing": true}}, + {"rename": {"field": "message2.maj_ver","target_field": "ipsec.maj_version","ignore_missing": true}}, + {"rename": {"field": "message2.min_ver","target_field": "ipsec.min_version","ignore_missing": true}}, + {"set": {"ignore_failure": true,"field": "ipsec.version","value": "{{ipsec.maj_version}}.{{ipsec.min_version}}"}}, + {"rename": {"field": "message2.exchange_type","target_field": "ipsec.exchange_type","ignore_missing": true}}, + {"rename": {"field": "message2.flag_e","target_field": "ipsec.flag_e","ignore_missing": true}}, + {"rename": {"field": "message2.flag_c","target_field": "ipsec.flag_c","ignore_missing": true}}, + {"rename": {"field": "message2.flag_a","target_field": "ipsec.flag_a","ignore_missing": true}}, + {"rename": {"field": "message2.flag_i","target_field": "ipsec.flag_i","ignore_missing": true}}, + {"rename": {"field": "message2.flag_v","target_field": "ipsec.flag_v","ignore_missing": true}}, + {"rename": {"field": "message2.flag_r","target_field": "ipsec.flag_r","ignore_missing": true}}, + {"rename": {"field": "message2.message_id","target_field": "ipsec.message_id","ignore_missing": true}}, + {"rename": {"field": "message2.vendor_ids","target_field": "ipsec.vendor_ids","ignore_missing": true}}, + {"rename": {"field": "message2.notify_messages","target_field": "ipsec.notify_messages","ignore_missing": true}}, + {"rename": {"field": "message2.transforms","target_field": "ipsec.transforms","ignore_missing": true}}, + {"rename": {"field": "message2.ke_dh_groups","target_field": "ipsec.ke_dh_groups","ignore_missing": true}}, + {"rename": {"field": "message2.proposals","target_field": "ipsec.proposals","ignore_missing": true}}, + {"rename": {"field": "message2.certificates","target_field": "ipsec.certificates","ignore_missing": true}}, + {"rename": {"field": "message2.transform_attributes","target_field": "ipsec.transform_attributes","ignore_missing": true}}, + {"rename": {"field": "message2.length","target_field": "ipsec.length","ignore_missing": true}}, + {"rename": {"field": "message2.hash","target_field": "ipsec.hash","ignore_missing": true}}, + {"rename": {"field": "message2.doi","target_field": "ipsec.doi","ignore_missing": true}}, + {"rename": {"field": "message2.situation","target_field": "ipsec.situation","ignore_missing": true}}, + {"script": { + "lang": "painless", + "description": "Remove ipsec fields with empty arrays", + "source": "if (ctx.containsKey('ipsec') && ctx.ipsec instanceof Map) {\n for (String field : ['certificates', 'ke_dh_groups', 'notify_messages', 'proposals', 'transforms', 'transform_attributes', 'vendor_ids']) {\n if (ctx.ipsec[field] instanceof List && ctx.ipsec[field].isEmpty()) {\n ctx.ipsec.remove(field);\n }\n }\n }", + "ignore_failure": true + }}, + {"pipeline": {"name": "zeek.common"}} + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/zeek.ldap b/salt/elasticsearch/files/ingest/zeek.ldap new file mode 100644 index 000000000..b7fef825a --- /dev/null +++ b/salt/elasticsearch/files/ingest/zeek.ldap @@ -0,0 +1,25 @@ +{ + "description": "zeek.ldap", + "processors": [ + {"set": {"field": "event.dataset", "value": "ldap"}}, + {"json": {"field": "message", "target_field": "message2", "ignore_failure": true}}, + {"rename": {"field": "message2.message_id", "target_field": "ldap.message_id", "ignore_missing": true}}, + {"rename": {"field": "message2.opcode", "target_field": "ldap.opcode", "ignore_missing": true}}, + {"rename": {"field": "message2.result", "target_field": "ldap.result", "ignore_missing": true}}, + {"rename": {"field": "message2.diagnostic_message", "target_field": "ldap.diagnostic_message", "ignore_missing": true}}, + {"rename": {"field": "message2.version", "target_field": "ldap.version", "ignore_missing": true}}, + {"rename": {"field": "message2.object", "target_field": "ldap.object", "ignore_missing": true}}, + {"rename": {"field": "message2.argument", "target_field": "ldap.argument", "ignore_missing": true}}, + {"rename": {"field": "message2.scope", "target_field": "ldap_search.scope", "ignore_missing":true}}, + {"rename": {"field": "message2.deref_aliases", "target_field": "ldap_search.deref_aliases", "ignore_missing":true}}, + {"rename": {"field": "message2.base_object", "target_field": "ldap.object", "ignore_missing":true}}, + {"rename": {"field": "message2.result_count", "target_field": "ldap_search.result_count", "ignore_missing":true}}, + {"rename": {"field": "message2.filter", "target_field": "ldap_search.filter", "ignore_missing":true}}, + {"rename": {"field": "message2.attributes", "target_field": "ldap_search.attributes", "ignore_missing":true}}, + {"script": {"source": "if (ctx.containsKey('ldap') && ctx.ldap.containsKey('diagnostic_message') && ctx.ldap.diagnostic_message != null) {\n String message = ctx.ldap.diagnostic_message;\n\n // get user and property from SASL success\n if (message.toLowerCase().contains(\"sasl(0): successful result\")) {\n Pattern pattern = /user:\\s*([^ ]+)\\s*property:\\s*([^ ]+)/i;\n Matcher matcher = pattern.matcher(message);\n if (matcher.find()) {\n ctx.ldap.user_email = matcher.group(1); // Extract user email\n ctx.ldap.property = matcher.group(2); // Extract property\n }\n }\n if (message.toLowerCase().contains(\"ldaperr:\")) {\n Pattern pattern = /comment:\\s*([^,]+)/i;\n Matcher matcher = pattern.matcher(message);\n\n if (matcher.find()) {\n ctx.ldap.comment = matcher.group(1);\n }\n }\n }","ignore_failure": true}}, + {"script": {"source": "if (ctx.containsKey('ldap') && ctx.ldap.containsKey('object') && ctx.ldap.object != null) {\n String message = ctx.ldap.object;\n\n // parse common name from ldap object\n if (message.toLowerCase().contains(\"cn=\")) {\n Pattern pattern = /cn=([^,]+)/i;\n Matcher matcher = pattern.matcher(message);\n if (matcher.find()) {\n ctx.ldap.common_name = matcher.group(1); // Extract CN\n }\n }\n // build domain from ldap object\n if (message.toLowerCase().contains(\"dc=\")) {\n Pattern dcPattern = /dc=([^,]+)/i;\n Matcher dcMatcher = dcPattern.matcher(message);\n\n StringBuilder domainBuilder = new StringBuilder();\n while (dcMatcher.find()) {\n if (domainBuilder.length() > 0 ){\n domainBuilder.append(\".\");\n }\n domainBuilder.append(dcMatcher.group(1));\n }\n if (domainBuilder.length() > 0) {\n ctx.ldap.domain = domainBuilder.toString();\n }\n }\n // create list of any organizational units from ldap object\n if (message.toLowerCase().contains(\"ou=\")) {\n Pattern ouPattern = /ou=([^,]+)/i;\n Matcher ouMatcher = ouPattern.matcher(message);\n ctx.ldap.organizational_unit = [];\n\n while (ouMatcher.find()) {\n ctx.ldap.organizational_unit.add(ouMatcher.group(1));\n }\n if(ctx.ldap.organizational_unit.isEmpty()) {\n ctx.remove(\"ldap.organizational_unit\");\n }\n }\n}\n","ignore_failure": true}}, + {"remove": {"field": "message2.tags","ignore_failure": true}}, + {"remove": {"field": ["host"],"ignore_failure": true}}, + {"pipeline": {"name": "zeek.common"}} + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/zeek.ldap_search b/salt/elasticsearch/files/ingest/zeek.ldap_search new file mode 100644 index 000000000..9bddf41b9 --- /dev/null +++ b/salt/elasticsearch/files/ingest/zeek.ldap_search @@ -0,0 +1,25 @@ +{ + "description":"zeek.ldap_search", + "processors":[ + {"set": {"field": "event.dataset", "value":"ldap_search"}}, + {"json": {"field": "message", "target_field": "message2", "ignore_failure": true}}, + {"rename": {"field": "message2.message_id", "target_field": "ldap.message_id", "ignore_missing": true}}, + {"rename": {"field": "message2.opcode", "target_field": "ldap.opcode", "ignore_missing": true}}, + {"rename": {"field": "message2.result", "target_field": "ldap.result", "ignore_missing": true}}, + {"rename": {"field": "message2.diagnostic_message", "target_field": "ldap.diagnostic_message", "ignore_missing": true}}, + {"rename": {"field": "message2.version", "target_field": "ldap.version", "ignore_missing": true}}, + {"rename": {"field": "message2.object", "target_field": "ldap.object", "ignore_missing": true}}, + {"rename": {"field": "message2.argument", "target_field": "ldap.argument", "ignore_missing": true}}, + {"rename": {"field": "message2.scope", "target_field": "ldap_search.scope", "ignore_missing":true}}, + {"rename": {"field": "message2.deref_aliases", "target_field": "ldap_search.deref_aliases", "ignore_missing":true}}, + {"rename": {"field": "message2.base_object", "target_field": "ldap.object", "ignore_missing":true}}, + {"rename": {"field": "message2.result_count", "target_field": "ldap_search.result_count", "ignore_missing":true}}, + {"rename": {"field": "message2.filter", "target_field": "ldap_search.filter", "ignore_missing":true}}, + {"rename": {"field": "message2.attributes", "target_field": "ldap_search.attributes", "ignore_missing":true}}, + {"script": {"source": "if (ctx.containsKey('ldap') && ctx.ldap.containsKey('diagnostic_message') && ctx.ldap.diagnostic_message != null) {\n String message = ctx.ldap.diagnostic_message;\n\n // get user and property from SASL success\n if (message.toLowerCase().contains(\"sasl(0): successful result\")) {\n Pattern pattern = /user:\\s*([^ ]+)\\s*property:\\s*([^ ]+)/i;\n Matcher matcher = pattern.matcher(message);\n if (matcher.find()) {\n ctx.ldap.user_email = matcher.group(1); // Extract user email\n ctx.ldap.property = matcher.group(2); // Extract property\n }\n }\n if (message.toLowerCase().contains(\"ldaperr:\")) {\n Pattern pattern = /comment:\\s*([^,]+)/i;\n Matcher matcher = pattern.matcher(message);\n\n if (matcher.find()) {\n ctx.ldap.comment = matcher.group(1);\n }\n }\n }","ignore_failure": true}}, + {"script": {"source": "if (ctx.containsKey('ldap') && ctx.ldap.containsKey('object') && ctx.ldap.object != null) {\n String message = ctx.ldap.object;\n\n // parse common name from ldap object\n if (message.toLowerCase().contains(\"cn=\")) {\n Pattern pattern = /cn=([^,]+)/i;\n Matcher matcher = pattern.matcher(message);\n if (matcher.find()) {\n ctx.ldap.common_name = matcher.group(1); // Extract CN\n }\n }\n // build domain from ldap object\n if (message.toLowerCase().contains(\"dc=\")) {\n Pattern dcPattern = /dc=([^,]+)/i;\n Matcher dcMatcher = dcPattern.matcher(message);\n\n StringBuilder domainBuilder = new StringBuilder();\n while (dcMatcher.find()) {\n if (domainBuilder.length() > 0 ){\n domainBuilder.append(\".\");\n }\n domainBuilder.append(dcMatcher.group(1));\n }\n if (domainBuilder.length() > 0) {\n ctx.ldap.domain = domainBuilder.toString();\n }\n }\n // create list of any organizational units from ldap object\n if (message.toLowerCase().contains(\"ou=\")) {\n Pattern ouPattern = /ou=([^,]+)/i;\n Matcher ouMatcher = ouPattern.matcher(message);\n ctx.ldap.organizational_unit = [];\n\n while (ouMatcher.find()) {\n ctx.ldap.organizational_unit.add(ouMatcher.group(1));\n }\n if(ctx.ldap.organizational_unit.isEmpty()) {\n ctx.remove(\"ldap.organizational_unit\");\n }\n }\n}\n","ignore_failure": true}}, + {"remove": {"field": "message2.tags", "ignore_failure": true}}, + {"remove": {"field": ["host"], "ignore_failure": true}}, + {"pipeline": {"name": "zeek.common"}} + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/zeek.ntp b/salt/elasticsearch/files/ingest/zeek.ntp new file mode 100644 index 000000000..6c500c770 --- /dev/null +++ b/salt/elasticsearch/files/ingest/zeek.ntp @@ -0,0 +1,16 @@ +{ + "description" : "zeek.ntp", + "processors":[ + {"set": {"field":"event.dataset", "value":"ntp", "ignore_failure":true}}, + {"json": {"field":"message", "target_field":"message2", "ignore_failure":true}}, + {"rename": {"field":"message2.version", "target_field":"ntp.version", "ignore_missing":true}}, + {"rename": {"field":"message2.mode", "target_field":"ntp.mode", "ignore_missing":true}}, + {"rename": {"field":"message2.poll", "target_field":"ntp.poll", "ignore_missing":true}}, + {"rename": {"field":"message2.precision", "target_field":"ntp.precision", "ignore_missing":true}}, + {"rename": {"field":"message2.org_time", "target_field":"ntp.org_time", "ignore_missing":true}}, + {"rename": {"field":"message2.xmt_time", "target_field":"ntp.xmt_time", "ignore_missing":true}}, + {"date": {"field":"ntp.org_time", "target_field":"ntp.org_time", "formats":["UNIX", "UNIX_MS"], "ignore_failure": true, "if":"ctx?.ntp?.org_time != null"}}, + {"date": {"field":"ntp.xmt_time", "target_field":"ntp.xmt_time", "formats":["UNIX", "UNIX_MS"], "ignore_failure": true, "if":"ctx?.ntp?.xmt_time != null"}}, + {"pipeline":{"name":"zeek.common"}} + ] +} diff --git a/salt/elasticsearch/files/ingest/zeek.quic b/salt/elasticsearch/files/ingest/zeek.quic new file mode 100644 index 000000000..9a58bda82 --- /dev/null +++ b/salt/elasticsearch/files/ingest/zeek.quic @@ -0,0 +1,18 @@ +{ + "description" : "zeek.quic", + "processors" : [ + { "set": { "field": "event.dataset", "value": "quic" } }, + { "set": { "field": "network.transport", "value": "udp" } }, + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.version", "target_field": "quic.version", "ignore_missing": true } }, + { "rename": { "field": "message2.client_initial_dcid", "target_field": "quic.client_initial_dcid", "ignore_missing": true } }, + { "rename": { "field": "message2.client_scid", "target_field": "quic.client_scid", "ignore_missing": true } }, + { "rename": { "field": "message2.server_scid", "target_field": "quic.server_scid", "ignore_missing": true } }, + { "rename": { "field": "message2.server_name", "target_field": "quic.server_name", "ignore_missing": true } }, + { "rename": { "field": "message2.client_protocol", "target_field": "quic.client_protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.history", "target_field": "quic.history", "ignore_missing": true } }, + { "remove": { "field": "message2.tags", "ignore_failure": true } }, + { "remove": { "field": ["host"], "ignore_failure": true } }, + { "pipeline": { "name": "zeek.common" } } + ] +} \ No newline at end of file diff --git a/salt/elasticsearch/files/ingest/zeek.software b/salt/elasticsearch/files/ingest/zeek.software index f5d3d1013..11298ba0b 100644 --- a/salt/elasticsearch/files/ingest/zeek.software +++ b/salt/elasticsearch/files/ingest/zeek.software @@ -11,7 +11,7 @@ { "dot_expander": { "field": "version.minor2", "path": "message2", "ignore_failure": true } }, { "rename": { "field": "message2.version.minor2", "target_field": "software.version.minor2", "ignore_missing": true } }, { "dot_expander": { "field": "version.minor3", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.version.minor3", "target_field": "version.minor3", "ignore_missing": true } }, + { "rename": { "field": "message2.version.minor3", "target_field": "software.version.minor3", "ignore_missing": true } }, { "dot_expander": { "field": "version.addl", "path": "message2", "ignore_failure": true } }, { "rename": { "field": "message2.version.addl", "target_field": "software.version.additional_info", "ignore_missing": true } }, { "rename": { "field": "message2.host", "target_field": "source.ip", "ignore_missing": true } }, diff --git a/salt/elasticsearch/files/ingest/zeek.ssl b/salt/elasticsearch/files/ingest/zeek.ssl index 8ae7c8728..87174d3d2 100644 --- a/salt/elasticsearch/files/ingest/zeek.ssl +++ b/salt/elasticsearch/files/ingest/zeek.ssl @@ -1,26 +1,40 @@ { "description" : "zeek.ssl", "processors" : [ - { "set": { "field": "event.dataset", "value": "ssl" } }, - { "remove": { "field": ["host"], "ignore_failure": true } }, - { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.version", "target_field": "ssl.version", "ignore_missing": true } }, - { "rename": { "field": "message2.cipher", "target_field": "ssl.cipher", "ignore_missing": true } }, - { "rename": { "field": "message2.curve", "target_field": "ssl.curve", "ignore_missing": true } }, - { "rename": { "field": "message2.server_name", "target_field": "ssl.server_name", "ignore_missing": true } }, - { "rename": { "field": "message2.resumed", "target_field": "ssl.resumed", "ignore_missing": true } }, - { "rename": { "field": "message2.last_alert", "target_field": "ssl.last_alert", "ignore_missing": true } }, - { "rename": { "field": "message2.next_protocol", "target_field": "ssl.next_protocol", "ignore_missing": true } }, - { "rename": { "field": "message2.established", "target_field": "ssl.established", "ignore_missing": true } }, - { "rename": { "field": "message2.cert_chain_fuids", "target_field": "ssl.certificate.chain_fuids", "ignore_missing": true } }, - { "rename": { "field": "message2.client_cert_chain_fuids", "target_field": "ssl.client.certificate.chain_fuids", "ignore_missing": true } }, - { "rename": { "field": "message2.subject", "target_field": "ssl.certificate.subject", "ignore_missing": true } }, - { "rename": { "field": "message2.issuer", "target_field": "ssl.certificate.issuer", "ignore_missing": true } }, - { "rename": { "field": "message2.client_subject", "target_field": "ssl.client.subject", "ignore_missing": true } }, - { "rename": { "field": "message2.client_issuer", "target_field": "ssl.client.issuer", "ignore_missing": true } }, - { "rename": { "field": "message2.validation_status","target_field": "ssl.validation_status", "ignore_missing": true } }, - { "rename": { "field": "message2.ja3", "target_field": "hash.ja3", "ignore_missing": true } }, - { "rename": { "field": "message2.ja3s", "target_field": "hash.ja3s", "ignore_missing": true } }, + { "set": { "field": "event.dataset", "value": "ssl" } }, + { "remove": { "field": ["host"], "ignore_failure": true } }, + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.version", "target_field": "ssl.version", "ignore_missing": true } }, + { "rename": { "field": "message2.cipher", "target_field": "ssl.cipher", "ignore_missing": true } }, + { "rename": { "field": "message2.curve", "target_field": "ssl.curve", "ignore_missing": true } }, + { "rename": { "field": "message2.server_name", "target_field": "ssl.server_name", "ignore_missing": true } }, + { "rename": { "field": "message2.resumed", "target_field": "ssl.resumed", "ignore_missing": true } }, + { "rename": { "field": "message2.last_alert", "target_field": "ssl.last_alert", "ignore_missing": true } }, + { "rename": { "field": "message2.next_protocol", "target_field": "ssl.next_protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.established", "target_field": "ssl.established", "ignore_missing": true } }, + { "rename": { "if": "ctx.message2?.cert_chain_fps != null", "field": "message2.cert_chain_fps", "target_field": "tls.server.hash.sha256", "ignore_missing": true } }, + { "rename": { "field": "message2?.cert_chain_fuids", "target_field": "ssl.certificate.chain_fuids", "ignore_missing": true } }, + { "rename": { "if": "ctx.message2?.client_cert_chain_fps != null", "field": "message2.client_cert_chain_fps", "target_field": "tls.client.hash.sha256", "ignore_failure": true, "ignore_missing": true } }, + { "rename": { "field": "message2.client_cert_chain_fuids", "target_field": "ssl.client.certificate.chain_fuids", "ignore_missing": true } }, + { "rename": { "field": "message2.subject", "target_field": "ssl.certificate.subject", "ignore_missing": true } }, + { "rename": { "field": "message2.issuer", "target_field": "ssl.certificate.issuer", "ignore_missing": true } }, + { "rename": { "field": "message2.client_subject", "target_field": "ssl.client.subject", "ignore_missing": true } }, + { "rename": { "field": "message2.client_issuer", "target_field": "ssl.client.issuer", "ignore_missing": true } }, + { "rename": { "field": "message2.validation_status","target_field": "ssl.validation_status", "ignore_missing": true } }, + { "rename": { "field": "message2.ja3", "target_field": "hash.ja3", "ignore_missing": true } }, + { "rename": { "field": "message2.ja3s", "target_field": "hash.ja3s", "ignore_missing": true } }, + { "foreach": + { + "if": "ctx?.tls?.client?.hash?.sha256 !=null", + "field": "tls.client.hash.sha256", + "processor": { + "append": { + "field": "hash.sha256", + "value": "{{_ingest._value}}" + } + } + } + }, { "pipeline": { "name": "zeek.common_ssl" } } ] } diff --git a/salt/elasticsearch/files/ingest/zeek.traceroute b/salt/elasticsearch/files/ingest/zeek.traceroute new file mode 100644 index 000000000..f34f58cb0 --- /dev/null +++ b/salt/elasticsearch/files/ingest/zeek.traceroute @@ -0,0 +1,10 @@ +{ + "description":"zeek.traceroute", + "processors":[ + {"set": {"field":"event.dataset", "value":"traceroute" }}, + {"json": {"field":"message", "target_field":"message2" }}, + {"rename": {"field":"message2.src", "target_field":"source.ip", "ignore_missing":true,"ignore_failure":true}}, + {"rename": {"field":"message2.dst", "target_field":"destination.ip", "ignore_missing":true,"ignore_failure":true}}, + {"pipeline": {"name":"zeek.common"}} + ] +} diff --git a/salt/elasticsearch/files/ingest/zeek.x509 b/salt/elasticsearch/files/ingest/zeek.x509 index 640ea81e3..64d06131a 100644 --- a/salt/elasticsearch/files/ingest/zeek.x509 +++ b/salt/elasticsearch/files/ingest/zeek.x509 @@ -3,44 +3,45 @@ "processors" : [ { "set": { "field": "event.dataset", "value": "x509" } }, { "remove": { "field": ["host"], "ignore_failure": true } }, - { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.id", "target_field": "log.id.fuid", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.version", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.version", "target_field": "x509.certificate.version", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.serial", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.serial", "target_field": "x509.certificate.serial", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.subject", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.subject", "target_field": "x509.certificate.subject", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.issuer", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.issuer", "target_field": "x509.certificate.issuer", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.not_valid_before", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.not_valid_before", "target_field": "x509.certificate.not_valid_before", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.not_valid_after", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.not_valid_after", "target_field": "x509.certificate.not_valid_after", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.key_alg", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.key_alg", "target_field": "x509.certificate.key.algorithm", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.sig_alg", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.sig_alg", "target_field": "x509.certificate.signing_algorithm", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.key_type", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.key_type", "target_field": "x509.certificate.key.type", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.key_length", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.key_length", "target_field": "x509.certificate.key.length", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.exponent", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.exponent", "target_field": "x509.certificate.exponent", "ignore_missing": true } }, - { "dot_expander": { "field": "certificate.curve", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.certificate.curve", "target_field": "x509.certificate.curve", "ignore_missing": true } }, - { "dot_expander": { "field": "san.dns", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.san.dns", "target_field": "x509.san_dns", "ignore_missing": true } }, - { "dot_expander": { "field": "san.uri", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.san.uri", "target_field": "x509.san_uri", "ignore_missing": true } }, - { "dot_expander": { "field": "san.email", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.san.email", "target_field": "x509.san_email", "ignore_missing": true } }, - { "dot_expander": { "field": "san.ip", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.san.ip", "target_field": "x509.san_ip", "ignore_missing": true } }, - { "dot_expander": { "field": "basic_constraints.ca", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.basic_constraints.ca", "target_field": "x509.basic_constraints.ca", "ignore_missing": true } }, - { "dot_expander": { "field": "basic_constraints.path_length", "path": "message2", "ignore_failure": true } }, - { "rename": { "field": "message2.basic_constraints.path_length", "target_field": "x509.basic_constraints.path_length", "ignore_missing": true } }, - { "pipeline": { "name": "zeek.common_ssl" } } + { "json": { "field": "message", "target_field": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.id", "target_field": "log.id.fuid", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.version", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.version", "target_field": "x509.certificate.version", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.serial", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.serial", "target_field": "x509.certificate.serial", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.subject", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.subject", "target_field": "x509.certificate.subject", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.issuer", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.issuer", "target_field": "x509.certificate.issuer", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.not_valid_before", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.not_valid_before", "target_field": "x509.certificate.not_valid_before", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.not_valid_after", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.not_valid_after", "target_field": "x509.certificate.not_valid_after", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.key_alg", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.key_alg", "target_field": "x509.certificate.key.algorithm", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.sig_alg", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.sig_alg", "target_field": "x509.certificate.signing_algorithm", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.key_type", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.key_type", "target_field": "x509.certificate.key.type", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.key_length", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.key_length", "target_field": "x509.certificate.key.length", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.exponent", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.exponent", "target_field": "x509.certificate.exponent", "ignore_missing": true } }, + { "dot_expander": { "field": "certificate.curve", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.certificate.curve", "target_field": "x509.certificate.curve", "ignore_missing": true } }, + { "dot_expander": { "field": "san.dns", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.san.dns", "target_field": "x509.san_dns", "ignore_missing": true } }, + { "dot_expander": { "field": "san.uri", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.san.uri", "target_field": "x509.san_uri", "ignore_missing": true } }, + { "dot_expander": { "field": "san.email", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.san.email", "target_field": "x509.san_email", "ignore_missing": true } }, + { "dot_expander": { "field": "san.ip", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.san.ip", "target_field": "x509.san_ip", "ignore_missing": true } }, + { "dot_expander": { "field": "basic_constraints.ca", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.basic_constraints.ca", "target_field": "x509.basic_constraints.ca", "ignore_missing": true } }, + { "dot_expander": { "field": "basic_constraints.path_length", "path": "message2", "ignore_failure": true } }, + { "rename": { "field": "message2.basic_constraints.path_length", "target_field": "x509.basic_constraints.path_length", "ignore_missing": true } }, + { "rename": { "field": "message2.fingerprint", "target_field": "hash.sha256", "ignore_missing": true } }, + { "pipeline": { "name": "zeek.common_ssl" } } ] } diff --git a/salt/elasticsearch/roles/analyst.json b/salt/elasticsearch/roles/analyst.json index 2fd10ab47..90ff95ad4 100644 --- a/salt/elasticsearch/roles/analyst.json +++ b/salt/elasticsearch/roles/analyst.json @@ -27,7 +27,8 @@ "monitor", "read", "read_cross_cluster", - "view_index_metadata" + "view_index_metadata", + "write" ] } ], diff --git a/salt/elasticsearch/roles/limited-analyst.json b/salt/elasticsearch/roles/limited-analyst.json index 9186b732e..6511e5f44 100644 --- a/salt/elasticsearch/roles/limited-analyst.json +++ b/salt/elasticsearch/roles/limited-analyst.json @@ -13,7 +13,8 @@ "monitor", "read", "read_cross_cluster", - "view_index_metadata" + "view_index_metadata", + "write" ] } ], diff --git a/salt/elasticsearch/soc_elasticsearch.yaml b/salt/elasticsearch/soc_elasticsearch.yaml index ce795fe5a..c268cc493 100644 --- a/salt/elasticsearch/soc_elasticsearch.yaml +++ b/salt/elasticsearch/soc_elasticsearch.yaml @@ -1,14 +1,24 @@ elasticsearch: enabled: - description: You can enable or disable Elasticsearch. + description: Enables or disables the Elasticsearch process. This process provides the log event storage system. WARNING - Disabling this process is unsupported. + advanced: True helpLink: elasticsearch.html + version: + description: "This specifies the version of the following containers: so-elastic-fleet-package-registry, so-elastic-agent, so-elastic-fleet, so-kibana, so-logstash and so-elasticsearch. Modifying this value in the Elasticsearch defaults.yaml will result in catastrophic grid failure." + readonly: True + global: True + advanced: True esheap: description: Specify the memory heap size in (m)egabytes for Elasticsearch. helpLink: elasticsearch.html + index_clean: + description: Determines if indices should be considered for deletion by available disk space in the cluster. Otherwise, indices will only be deleted by the age defined in the ILM settings. This setting only applies to EVAL, STANDALONE, and HEAVY NODE installations. Other installations can only use ILM settings. + forcedType: bool + helpLink: elasticsearch.html retention: retention_pct: decription: Total percentage of space used by Elasticsearch for multi node clusters - helpLink: elasticsearch.yaml + helpLink: elasticsearch.html global: True config: cluster: @@ -45,6 +55,35 @@ elasticsearch: description: Max number of boolean clauses per query. global: True helpLink: elasticsearch.html + pipelines: + custom001: &pipelines + description: + description: Description of the ingest node pipeline + global: True + advanced: True + helpLink: elasticsearch.html + processors: + description: Processors for the ingest node pipeline + global: True + advanced: True + multiline: True + helpLink: elasticsearch.html + custom002: *pipelines + custom003: *pipelines + custom004: *pipelines + custom005: *pipelines + custom006: *pipelines + custom007: *pipelines + custom008: *pipelines + custom009: *pipelines + custom010: *pipelines + managed_integrations: + description: List of integrations to add into SOC config UI. Enter the full or partial integration name. Eg. 1password, 1pass + forcedType: "[]string" + multiline: True + global: True + advanced: True + helpLink: elasticsearch.html index_settings: global_overrides: index_template: @@ -73,12 +112,9 @@ elasticsearch: description: The order to sort by. Must set index_sorting to True. global: True helpLink: elasticsearch.html + policy: phases: hot: - max_age: - description: Maximum age of index. ex. 7d - This determines when the index should be moved out of the hot tier. - global: True - helpLink: elasticsearch.html actions: set_priority: priority: @@ -97,7 +133,9 @@ elasticsearch: helpLink: elasticsearch.html cold: min_age: - description: Minimum age of index. ex. 30d - This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed. + description: Minimum age of index. ex. 60d - This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed. It’s important to note that this is calculated relative to the rollover date (NOT the original creation date of the index). For example, if you have an index that is set to rollover after 30 days and cold min_age set to 60 then there will be 30 days from index creation to rollover and then an additional 60 days before moving to cold tier. + regex: ^[0-9]{1,5}d$ + forcedType: string global: True helpLink: elasticsearch.html actions: @@ -108,10 +146,11 @@ elasticsearch: helpLink: elasticsearch.html warm: min_age: - description: Minimum age of index. ex. 30d - This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed. - regex: ^\[0-9\]{1,5}d$ + description: Minimum age of index. ex. 30d - This determines when the index should be moved to the warm tier. Nodes in the warm tier generally don’t need to be as fast as those in the hot tier. It’s important to note that this is calculated relative to the rollover date (NOT the original creation date of the index). For example, if you have an index that is set to rollover after 30 days and warm min_age set to 30 then there will be 30 days from index creation to rollover and then an additional 30 days before moving to warm tier. + regex: ^[0-9]{1,5}d$ forcedType: string global: True + helpLink: elasticsearch.html actions: set_priority: priority: @@ -121,7 +160,9 @@ elasticsearch: helpLink: elasticsearch.html delete: min_age: - description: Minimum age of index. ex. 90d - This determines when the index should be deleted. + description: Minimum age of index. ex. 90d - This determines when the index should be deleted. It’s important to note that this is calculated relative to the rollover date (NOT the original creation date of the index). For example, if you have an index that is set to rollover after 30 days and delete min_age set to 90 then there will be 30 days from index creation to rollover and then an additional 90 days before deletion. + regex: ^[0-9]{1,5}d$ + forcedType: string global: True helpLink: elasticsearch.html so-logs: &indexSettings @@ -133,7 +174,7 @@ elasticsearch: index_template: index_patterns: description: Patterns for matching multiple indices or tables. - forceType: "[]string" + forcedType: "[]string" multiline: True global: True advanced: True @@ -248,7 +289,9 @@ elasticsearch: helpLink: elasticsearch.html warm: min_age: - description: Minimum age of index. This determines when the index should be moved to the hot tier. + description: Minimum age of index. ex. 30d - This determines when the index should be moved to the warm tier. Nodes in the warm tier generally don’t need to be as fast as those in the hot tier. It’s important to note that this is calculated relative to the rollover date (NOT the original creation date of the index). For example, if you have an index that is set to rollover after 30 days and warm min_age set to 30 then there will be 30 days from index creation to rollover and then an additional 30 days before moving to warm tier. + regex: ^[0-9]{1,5}d$ + forcedType: string global: True advanced: True helpLink: elasticsearch.html @@ -273,7 +316,9 @@ elasticsearch: helpLink: elasticsearch.html cold: min_age: - description: Minimum age of index. This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed. + description: Minimum age of index. ex. 60d - This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed. It’s important to note that this is calculated relative to the rollover date (NOT the original creation date of the index). For example, if you have an index that is set to rollover after 30 days and cold min_age set to 60 then there will be 30 days from index creation to rollover and then an additional 60 days before moving to cold tier. + regex: ^[0-9]{1,5}d$ + forcedType: string global: True advanced: True helpLink: elasticsearch.html @@ -287,7 +332,9 @@ elasticsearch: helpLink: elasticsearch.html delete: min_age: - description: Minimum age of index. This determines when the index should be deleted. + description: Minimum age of index. ex. 90d - This determines when the index should be deleted. It’s important to note that this is calculated relative to the rollover date (NOT the original creation date of the index). For example, if you have an index that is set to rollover after 30 days and delete min_age set to 90 then there will be 30 days from index creation to rollover and then an additional 90 days before deletion. + regex: ^[0-9]{1,5}d$ + forcedType: string global: True advanced: True helpLink: elasticsearch.html @@ -318,119 +365,14 @@ elasticsearch: so-logs-windows_x_powershell: *indexSettings so-logs-windows_x_powershell_operational: *indexSettings so-logs-windows_x_sysmon_operational: *indexSettings - so-logs-apache_x_access: *indexSettings - so-logs-apache_x_error: *indexSettings - so-logs-auditd_x_log: *indexSettings - so-logs-aws_x_cloudtrail: *indexSettings - so-logs-aws_x_cloudwatch_logs: *indexSettings - so-logs-aws_x_ec2_logs: *indexSettings - so-logs-aws_x_elb_logs: *indexSettings - so-logs-aws_x_firewall_logs: *indexSettings - so-logs-aws_x_route53_public_logs: *indexSettings - so-logs-aws_x_route53_resolver_logs: *indexSettings - so-logs-aws_x_s3access: *indexSettings - so-logs-aws_x_vpcflow: *indexSettings - so-logs-aws_x_waf: *indexSettings - so-logs-azure_x_activitylogs: *indexSettings - so-logs-azure_x_application_gateway: *indexSettings - so-logs-azure_x_auditlogs: *indexSettings - so-logs-azure_x_eventhub: *indexSettings - so-logs-azure_x_firewall_logs: *indexSettings - so-logs-azure_x_identity_protection: *indexSettings - so-logs-azure_x_platformlogs: *indexSettings - so-logs-azure_x_provisioning: *indexSettings - so-logs-azure_x_signinlogs: *indexSettings - so-logs-azure_x_springcloudlogs: *indexSettings - so-logs-barracuda_x_waf: *indexSettings - so-logs-cisco_asa_x_log: *indexSettings - so-logs-cloudflare_x_audit: *indexSettings - so-logs-cloudflare_x_logpull: *indexSettings - so-logs-crowdstrike_x_falcon: *indexSettings - so-logs-crowdstrike_x_fdr: *indexSettings - so-logs-darktrace_x_ai_analyst_alert: *indexSettings - so-logs-darktrace_x_model_breach_alert: *indexSettings - so-logs-darktrace_x_system_status_alert: *indexSettings - so-logs-f5_bigip_x_log: *indexSettings - so-logs-fim_x_event: *indexSettings - so-logs-fortinet_x_clientendpoint: *indexSettings - so-logs-fortinet_x_firewall: *indexSettings - so-logs-fortinet_x_fortimail: *indexSettings - so-logs-fortinet_x_fortimanager: *indexSettings - so-logs-fortinet_x_fortigate: *indexSettings - so-logs-gcp_x_audit: *indexSettings - so-logs-gcp_x_dns: *indexSettings - so-logs-gcp_x_firewall: *indexSettings - so-logs-gcp_x_loadbalancing_logs: *indexSettings - so-logs-gcp_x_vpcflow: *indexSettings - so-logs-github_x_audit: *indexSettings - so-logs-github_x_code_scanning: *indexSettings - so-logs-github_x_dependabot: *indexSettings - so-logs-github_x_issues: *indexSettings - so-logs-github_x_secret_scanning: *indexSettings - so-logs-google_workspace_x_access_transparency: *indexSettings - so-logs-google_workspace_x_admin: *indexSettings - so-logs-google_workspace_x_alert: *indexSettings - so-logs-google_workspace_x_context_aware_access: *indexSettings - so-logs-google_workspace_x_device: *indexSettings - so-logs-google_workspace_x_drive: *indexSettings - so-logs-google_workspace_x_gcp: *indexSettings - so-logs-google_workspace_x_group_enterprise: *indexSettings - so-logs-google_workspace_x_groups: *indexSettings - so-logs-google_workspace_x_login: *indexSettings - so-logs-google_workspace_x_rules: *indexSettings - so-logs-google_workspace_x_saml: *indexSettings - so-logs-google_workspace_x_token: *indexSettings - so-logs-google_workspace_x_user_accounts: *indexSettings + so-logs-winlog_x_winlog: *indexSettings + so-logs-detections_x_alerts: *indexSettings so-logs-http_endpoint_x_generic: *indexSettings so-logs-httpjson_x_generic: *indexSettings - so-logs-juniper_x_junos: *indexSettings - so-logs-juniper_x_netscreen: *indexSettings - so-logs-juniper_x_srx: *indexSettings - so-logs-juniper_srx_x_log: *indexSettings - so-logs-kafka_log_x_generic: *indexSettings - so-logs-lastpass_x_detailed_shared_folder: *indexSettings - so-logs-lastpass_x_event_report: *indexSettings - so-logs-lastpass_x_user: *indexSettings - so-logs-m365_defender_x_event: *indexSettings - so-logs-m365_defender_x_incident: *indexSettings - so-logs-m365_defender_x_log: *indexSettings - so-logs-microsoft_defender_endpoint_x_log: *indexSettings - so-logs-microsoft_dhcp_x_log: *indexSettings - so-logs-netflow_x_log: *indexSettings - so-logs-o365_x_audit: *indexSettings - so-logs-okta_x_system: *indexSettings - so-logs-panw_x_panos: *indexSettings - so-logs-pfsense_x_log: *indexSettings - so-logs-sentinel_one_x_activity: *indexSettings - so-logs-sentinel_one_x_agent: *indexSettings - so-logs-sentinel_one_x_alert: *indexSettings - so-logs-sentinel_one_x_group: *indexSettings - so-logs-sentinel_one_x_threat: *indexSettings - so-logs-sonicwall_firewall_x_log: *indexSettings - so-logs-symantec_endpoint_x_log: *indexSettings - so-logs-ti_abusech_x_malware: *indexSettings - so-logs-ti_abusech_x_malwarebazaar: *indexSettings - so-logs-ti_abusech_x_threatfox: *indexSettings - so-logs-ti_abusech_x_url: *indexSettings - so-logs-ti_misp_x_threat: *indexSettings - so-logs-ti_misp_x_threat_attributes: *indexSettings - so-logs-ti_otx_x_threat: *indexSettings - so-logs-ti_recordedfuture_x_latest_ioc-template: *indexSettings - so-logs-ti_recordedfuture_x_threat: *indexSettings - so-logs-zscaler_zia_x_alerts: *indexSettings - so-logs-zscaler_zia_x_dns: *indexSettings - so-logs-zscaler_zia_x_firewall: *indexSettings - so-logs-zscaler_zia_x_tunnel: *indexSettings - so-logs-zscaler_zia_x_web: *indexSettings - so-logs-zscaler_zpa_x_app_connector_status: *indexSettings - so-logs-zscaler_zpa_x_audit: *indexSettings - so-logs-zscaler_zpa_x_browser_access: *indexSettings - so-logs-zscaler_zpa_x_user_activity: *indexSettings - so-logs-zscaler_zpa_x_user_status: *indexSettings - so-logs-1password_x_item_usages: *indexSettings - so-logs-1password_x_signin_attempts: *indexSettings so-logs-osquery-manager-actions: *indexSettings so-logs-osquery-manager-action_x_responses: *indexSettings + so-logs-osquery-manager_x_action_x_responses: *indexSettings + so-logs-osquery-manager_x_result: *indexSettings so-logs-elastic_agent_x_apm_server: *indexSettings so-logs-elastic_agent_x_auditbeat: *indexSettings so-logs-elastic_agent_x_cloudbeat: *indexSettings @@ -450,18 +392,80 @@ elasticsearch: so-logs-elastic_agent_x_metricbeat: *indexSettings so-logs-elastic_agent_x_osquerybeat: *indexSettings so-logs-elastic_agent_x_packetbeat: *indexSettings + so-metrics-endpoint_x_metadata: *indexSettings + so-metrics-endpoint_x_metrics: *indexSettings + so-metrics-endpoint_x_policy: *indexSettings + so-metrics-nginx_x_stubstatus: *indexSettings + so-metrics-vsphere_x_datastore: *indexSettings + so-metrics-vsphere_x_host: *indexSettings + so-metrics-vsphere_x_virtualmachine: *indexSettings so-case: *indexSettings so-common: *indexSettings so-endgame: *indexSettings so-idh: *indexSettings so-suricata: *indexSettings + so-suricata_x_alerts: *indexSettings so-import: *indexSettings so-kratos: *indexSettings + so-hydra: *indexSettings + so-kismet: *indexSettings so-logstash: *indexSettings so-redis: *indexSettings so-strelka: *indexSettings so-syslog: *indexSettings so-zeek: *indexSettings + so-metrics-fleet_server_x_agent_status: &fleetMetricsSettings + index_sorting: + description: Sorts the index by event time, at the cost of additional processing resource consumption. + advanced: True + readonly: True + helpLink: elasticsearch.html + index_template: + ignore_missing_component_templates: + description: Ignore component templates if they aren't in Elasticsearch. + advanced: True + readonly: True + helpLink: elasticsearch.html + index_patterns: + description: Patterns for matching multiple indices or tables. + advanced: True + readonly: True + helpLink: elasticsearch.html + template: + settings: + index: + mode: + description: Type of mode used for this index. Time series indices can be used for metrics to reduce necessary storage. + advanced: True + readonly: True + helpLink: elasticsearch.html + number_of_replicas: + description: Number of replicas required for this index. Multiple replicas protects against data loss, but also increases storage costs. + advanced: True + readonly: True + helpLink: elasticsearch.html + composed_of: + description: The index template is composed of these component templates. + advanced: True + readonly: True + helpLink: elasticsearch.html + priority: + description: The priority of the index template. + advanced: True + readonly: True + helpLink: elasticsearch.html + data_stream: + hidden: + description: Hide the data stream. + advanced: True + readonly: True + helpLink: elasticsearch.html + allow_custom_routing: + description: Allow custom routing for the data stream. + advanced: True + readonly: True + helpLink: elasticsearch.html + so-metrics-fleet_server_x_agent_versions: *fleetMetricsSettings so_roles: so-manager: &soroleSettings config: diff --git a/salt/elasticsearch/template.map.jinja b/salt/elasticsearch/template.map.jinja index f5a124a9a..aa90cb81b 100644 --- a/salt/elasticsearch/template.map.jinja +++ b/salt/elasticsearch/template.map.jinja @@ -1,16 +1,31 @@ +{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one + or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at + https://securityonion.net/license; you may not use this file except in compliance with the + Elastic License 2.0. #} + {% import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS %} {% set DEFAULT_GLOBAL_OVERRIDES = ELASTICSEARCHDEFAULTS.elasticsearch.index_settings.pop('global_overrides') %} {% set PILLAR_GLOBAL_OVERRIDES = {} %} -{% if salt['pillar.get']('elasticsearch:index_settings') is defined %} -{% set ES_INDEX_PILLAR = salt['pillar.get']('elasticsearch:index_settings') %} -{% if ES_INDEX_PILLAR.global_overrides is defined %} -{% set PILLAR_GLOBAL_OVERRIDES = ES_INDEX_PILLAR.pop('global_overrides') %} -{% endif %} +{% set ES_INDEX_PILLAR = salt['pillar.get']('elasticsearch:index_settings', {}) %} +{% if ES_INDEX_PILLAR.global_overrides is defined %} +{% set PILLAR_GLOBAL_OVERRIDES = ES_INDEX_PILLAR.pop('global_overrides') %} {% endif %} {% set ES_INDEX_SETTINGS_ORIG = ELASTICSEARCHDEFAULTS.elasticsearch.index_settings %} +{# start generation of integration default index_settings #} +{% if salt['file.file_exists']('/opt/so/state/esfleet_package_components.json') %} +{% set check_package_components = salt['file.stats']('/opt/so/state/esfleet_package_components.json') %} +{% if check_package_components.size > 1 %} +{% from 'elasticfleet/integration-defaults.map.jinja' import ADDON_INTEGRATION_DEFAULTS %} +{% for index, settings in ADDON_INTEGRATION_DEFAULTS.items() %} +{% do ES_INDEX_SETTINGS_ORIG.update({index: settings}) %} +{% endfor %} +{% endif%} +{% endif %} +{# end generation of integration default index_settings #} + {% set ES_INDEX_SETTINGS_GLOBAL_OVERRIDES = {} %} {% for index in ES_INDEX_SETTINGS_ORIG.keys() %} {% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES.update({index: salt['defaults.merge'](ELASTICSEARCHDEFAULTS.elasticsearch.index_settings[index], PILLAR_GLOBAL_OVERRIDES, in_place=False)}) %} @@ -19,6 +34,28 @@ {% set ES_INDEX_SETTINGS = {} %} {% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES.update(salt['defaults.merge'](ES_INDEX_SETTINGS_GLOBAL_OVERRIDES, ES_INDEX_PILLAR, in_place=False)) %} {% for index, settings in ES_INDEX_SETTINGS_GLOBAL_OVERRIDES.items() %} + +{# prevent this action from being performed on custom defined indices. #} +{# the custom defined index is not present in either of the dictionaries and fails to reder. #} +{% if index in ES_INDEX_SETTINGS_ORIG and index in ES_INDEX_SETTINGS_GLOBAL_OVERRIDES %} + +{# dont merge policy from the global_overrides if policy isn't defined in the original index settingss #} +{# this will prevent so-elasticsearch-ilm-policy-load from trying to load policy on non ILM manged indices #} +{% if not ES_INDEX_SETTINGS_ORIG[index].policy is defined and ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy is defined %} +{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].pop('policy') %} +{% endif %} + +{# this prevents and index from inderiting a policy phase from global overrides if it wasnt defined in the defaults. #} +{% if ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy is defined %} +{% for phase in ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy.phases.copy() %} +{% if ES_INDEX_SETTINGS_ORIG[index].policy.phases[phase] is not defined %} +{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy.phases.pop(phase) %} +{% endif %} +{% endfor %} +{% endif %} + +{% endif %} + {% if settings.index_template is defined %} {% if not settings.get('index_sorting', False) | to_bool and settings.index_template.template.settings.index.sort is defined %} {% do settings.index_template.template.settings.index.pop('sort') %} diff --git a/salt/elasticsearch/templates/component/ecs/device.json b/salt/elasticsearch/templates/component/ecs/device.json new file mode 100644 index 000000000..a281f2c1e --- /dev/null +++ b/salt/elasticsearch/templates/component/ecs/device.json @@ -0,0 +1,36 @@ +{ + "_meta": { + "documentation": "https://www.elastic.co/guide/en/ecs/current/ecs-device.html", + "ecs_version": "1.12.2" + }, + "template": { + "mappings": { + "properties": { + "device": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "manufacturer": { + "ignore_above": 1024, + "type": "keyword" + }, + "model": { + "properties": { + "identifier": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/salt/elasticsearch/templates/component/ecs/kismet.json b/salt/elasticsearch/templates/component/ecs/kismet.json new file mode 100644 index 000000000..a03236ab8 --- /dev/null +++ b/salt/elasticsearch/templates/component/ecs/kismet.json @@ -0,0 +1,32 @@ +{ + "_meta": { + "documentation": "https://www.elastic.co/guide/en/ecs/current/ecs-base.html", + "ecs_version": "1.12.2" + }, + "template": { + "mappings": { + "properties": { + "kismet": { + "properties": { + "alerts": { + "properties": { + "count": { + "type": "long" + } + } + }, + "first_seen": { + "type": "date" + }, + "last_seen": { + "type": "date" + }, + "seenby": { + "type": "nested" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/salt/elasticsearch/templates/component/ecs/log.json b/salt/elasticsearch/templates/component/ecs/log.json index e79661b5e..4f51be287 100644 --- a/salt/elasticsearch/templates/component/ecs/log.json +++ b/salt/elasticsearch/templates/component/ecs/log.json @@ -29,7 +29,7 @@ "file": { "properties": { "line": { - "type": "integer" + "type": "long" }, "name": { "ignore_above": 1024, diff --git a/salt/elasticsearch/templates/component/ecs/metadata.json b/salt/elasticsearch/templates/component/ecs/metadata.json new file mode 100644 index 000000000..55da6f07c --- /dev/null +++ b/salt/elasticsearch/templates/component/ecs/metadata.json @@ -0,0 +1,26 @@ +{ + "template": { + "mappings": { + "dynamic_templates": [], + "properties": { + "metadata": { + "properties": { + "kafka": { + "properties": { + "timestamp": { + "type": "date" + } + } + } + } + } + } + } + }, + "_meta": { + "_meta": { + "documentation": "https://www.elastic.co/guide/en/ecs/current/ecs-log.html", + "ecs_version": "1.12.2" + } + } +} \ No newline at end of file diff --git a/salt/elasticsearch/templates/component/ecs/network.json b/salt/elasticsearch/templates/component/ecs/network.json index c2e35efd0..8cc6bdc37 100644 --- a/salt/elasticsearch/templates/component/ecs/network.json +++ b/salt/elasticsearch/templates/component/ecs/network.json @@ -77,6 +77,43 @@ "type": "keyword" } } + }, + "wireless": { + "properties": { + "associated_clients": { + "ignore_above": 1024, + "type": "keyword" + }, + "bssid": { + "ignore_above": 1024, + "type": "keyword" + }, + "channel": { + "ignore_above": 1024, + "type": "keyword" + }, + "channel_utilization": { + "type": "float" + }, + "frequency": { + "type": "double" + }, + "ssid": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssid_cloaked": { + "type": "integer" + }, + "known_connected_bssid": { + "ignore_above": 1024, + "type": "keyword" + }, + "last_connected_bssid": { + "ignore_above": 1024, + "type": "keyword" + } + } } } } diff --git a/salt/elasticsearch/templates/component/ecs/zeek.json b/salt/elasticsearch/templates/component/ecs/zeek.json index f14349263..b0617305e 100644 --- a/salt/elasticsearch/templates/component/ecs/zeek.json +++ b/salt/elasticsearch/templates/component/ecs/zeek.json @@ -603,6 +603,89 @@ } } }, + "ipsec": { + "properties": { + "certificates": { + "ignore_above": 1024, + "type": "keyword" + }, + "exchange_type": { + "type": "short" + }, + "flag_a": { + "type": "boolean" + }, + "flag_c": { + "type": "boolean" + }, + "flag_e": { + "type": "boolean" + }, + "flag_i": { + "type": "boolean" + }, + "flag_r": { + "type": "boolean" + }, + "flag_v": { + "type": "boolean" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "initiator_spi": { + "ignore_above": 1024, + "type": "keyword" + }, + "ke_dh_groups": { + "type": "short" + }, + "length": { + "type": "long" + }, + "maj_version": { + "type": "short" + }, + "message_id": { + "type": "long" + }, + "min_version": { + "type": "short" + }, + "notify_messages": { + "ignore_above": 1024, + "type": "keyword" + }, + "proposals": { + "type": "long" + }, + "responder_spi": { + "ignore_above": 1024, + "type": "keyword" + }, + "situation": { + "ignore_above": 1024, + "type": "keyword" + }, + "transform_attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "transforms": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor_ids": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "irc": { "properties": { "addl": { @@ -751,6 +834,81 @@ } } }, + "ldap": { + "type": "object", + "properties": { + "message_id": { + "type": "short" + }, + "opcode": { + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "diagnostic_message": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "type": "short" + }, + "object": { + "ignore_above": 1024, + "type": "keyword" + }, + "argument": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_email": { + "ignore_above": 1024, + "type": "keyword" + }, + "property": { + "ignore_above": 1024, + "type": "keyword" + }, + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ldap_search": { + "type": "object", + "properties": { + "scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "deref_aliases": { + "ignore_above": 1024, + "type": "keyword" + }, + "result_count": { + "type": "long" + }, + "filter": { + "ignore_above": 1024, + "type": "keyword" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "modbus": { "properties": { "exception": { @@ -1089,6 +1247,38 @@ } } }, + "quic": { + "type": "object", + "properties": { + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "type": "short" + }, + "client_initial_dcid": { + "ignore_above": 1024, + "type": "keyword" + }, + "client_scid": { + "ignore_above": 1024, + "type": "keyword" + }, + "server_scid": { + "ignore_above": 1024, + "type": "keyword" + }, + "client_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "history": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "radius": { "properties": { "connect_info": { diff --git a/salt/elasticsearch/templates/component/elastic-agent/logs-elastic_agent@package.json b/salt/elasticsearch/templates/component/elastic-agent/logs-elastic_agent@package.json deleted file mode 100644 index 2390705f3..000000000 --- a/salt/elasticsearch/templates/component/elastic-agent/logs-elastic_agent@package.json +++ /dev/null @@ -1,382 +0,0 @@ - {"template": { - "settings": { - "index": { - "lifecycle": { - "name": "logs" - }, - "codec": "best_compression", - "default_pipeline": "logs-elastic_agent-1.13.1", - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "query": { - "default_field": [ - "cloud.account.id", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.provider", - "cloud.region", - "cloud.project.id", - "cloud.image.id", - "container.id", - "container.image.name", - "container.name", - "host.architecture", - "host.hostname", - "host.id", - "host.mac", - "host.name", - "host.os.family", - "host.os.kernel", - "host.os.name", - "host.os.platform", - "host.os.version", - "host.os.build", - "host.os.codename", - "host.type", - "ecs.version", - "agent.build.original", - "agent.ephemeral_id", - "agent.id", - "agent.name", - "agent.type", - "agent.version", - "log.level", - "message", - "elastic_agent.id", - "elastic_agent.process", - "elastic_agent.version", - "component.id", - "component.type", - "component.binary", - "component.state", - "component.old_state", - "unit.id", - "unit.type", - "unit.state", - "unit.old_state" - ] - } - } - }, - "mappings": { - "dynamic": false, - "dynamic_templates": [ - { - "container.labels": { - "path_match": "container.labels.*", - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string" - } - } - ], - "properties": { - "container": { - "properties": { - "image": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "agent": { - "properties": { - "build": { - "properties": { - "original": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "elastic_agent": { - "properties": { - "process": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "snapshot": { - "type": "boolean" - } - } - }, - "message": { - "type": "text" - }, - "cloud": { - "properties": { - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "instance": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "machine": { - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "project": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - }, - "account": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "component": { - "properties": { - "binary": { - "ignore_above": 1024, - "type": "keyword" - }, - "old_state": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "wildcard" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "unit": { - "properties": { - "old_state": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "wildcard" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "@timestamp": { - "type": "date" - }, - "ecs": { - "properties": { - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "data_stream": { - "properties": { - "namespace": { - "type": "constant_keyword" - }, - "type": { - "type": "constant_keyword" - }, - "dataset": { - "type": "constant_keyword" - } - } - }, - "host": { - "properties": { - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "build": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "codename": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword", - "fields": { - "text": { - "type": "text" - } - } - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "containerized": { - "type": "boolean" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "architecture": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "event": { - "properties": { - "dataset": { - "type": "constant_keyword" - } - } - } - } - } - }, - "_meta": { - "package": { - "name": "elastic_agent" - }, - "managed_by": "fleet", - "managed": true - } - } diff --git a/salt/elasticsearch/templates/component/elastic-agent/logs-osquery_manager.result@custom.json b/salt/elasticsearch/templates/component/elastic-agent/logs-osquery_manager.result@custom.json new file mode 100644 index 000000000..83a68c814 --- /dev/null +++ b/salt/elasticsearch/templates/component/elastic-agent/logs-osquery_manager.result@custom.json @@ -0,0 +1,49 @@ +{ + "template": { + "mappings": { + "dynamic_templates": [ + { + "action_data.ecs_mapping": { + "path_match": "action_data.ecs_mapping.*", + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "action_data": { + "dynamic": true, + "type": "object", + "properties": { + "ecs_mapping": { + "dynamic": true, + "type": "object" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "saved_query_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/salt/elasticsearch/templates/component/elastic-agent/logs-elastic_agent@custom.json b/salt/elasticsearch/templates/component/elastic-agent/logs-soc@package.json similarity index 55% rename from salt/elasticsearch/templates/component/elastic-agent/logs-elastic_agent@custom.json rename to salt/elasticsearch/templates/component/elastic-agent/logs-soc@package.json index fe77af1db..a2ad15b79 100644 --- a/salt/elasticsearch/templates/component/elastic-agent/logs-elastic_agent@custom.json +++ b/salt/elasticsearch/templates/component/elastic-agent/logs-soc@package.json @@ -1,12 +1,10 @@ { - "template": { - "settings": {} - }, + "template": {}, "_meta": { "package": { - "name": "elastic_agent" + "name": "log" }, "managed_by": "fleet", "managed": true } -} +} \ No newline at end of file diff --git a/salt/elasticsearch/templates/component/elastic-agent/logs-system.syslog@custom.json b/salt/elasticsearch/templates/component/elastic-agent/logs-system.syslog@custom.json new file mode 100644 index 000000000..95a902bb9 --- /dev/null +++ b/salt/elasticsearch/templates/component/elastic-agent/logs-system.syslog@custom.json @@ -0,0 +1,50 @@ +{ + "template": { + "mappings": { + "properties": { + "error": { + "properties": { + "message": { + "type": "match_only_text" + } + } + }, + "host": { + "properties":{ + "ip": { + "type": "ip" + } + } + }, + "related": { + "properties":{ + "ip": { + "type": "ip" + } + } + }, + "destination": { + "properties":{ + "ip": { + "type": "ip" + } + } + }, + "source": { + "properties":{ + "ip": { + "type": "ip" + } + } + } + } + } + }, + "_meta": { + "package": { + "name": "system" + }, + "managed_by": "fleet", + "managed": true + } +} diff --git a/salt/elasticsearch/templates/component/elastic-agent/logs@custom.json b/salt/elasticsearch/templates/component/elastic-agent/logs@custom.json new file mode 100644 index 000000000..61a69003f --- /dev/null +++ b/salt/elasticsearch/templates/component/elastic-agent/logs@custom.json @@ -0,0 +1,9 @@ +{ + "template": { + "settings": { + "index": { + "number_of_replicas": "0" + } + } + } +} \ No newline at end of file diff --git a/salt/elasticsearch/templates/component/elastic-agent/metrics@custom.json b/salt/elasticsearch/templates/component/elastic-agent/metrics@custom.json new file mode 100644 index 000000000..61a69003f --- /dev/null +++ b/salt/elasticsearch/templates/component/elastic-agent/metrics@custom.json @@ -0,0 +1,9 @@ +{ + "template": { + "settings": { + "index": { + "number_of_replicas": "0" + } + } + } +} \ No newline at end of file diff --git a/salt/elasticsearch/templates/component/elastic-agent/so-fleet_globals-1.json b/salt/elasticsearch/templates/component/elastic-agent/so-fleet_globals-1.json index 5df7e7fe9..183031d4e 100644 --- a/salt/elasticsearch/templates/component/elastic-agent/so-fleet_globals-1.json +++ b/salt/elasticsearch/templates/component/elastic-agent/so-fleet_globals-1.json @@ -5,6 +5,7 @@ "managed_by": "security_onion", "managed": true }, + "date_detection": false, "dynamic_templates": [ { "strings_as_keyword": { @@ -16,7 +17,19 @@ } } ], - "date_detection": false + "properties": { + "metadata": { + "properties": { + "kafka": { + "properties": { + "timestamp": { + "type": "date" + } + } + } + } + } + } } }, "_meta": { diff --git a/salt/elasticsearch/templates/component/elastic-agent/so-fleet_integrations.ip_mappings-1.json b/salt/elasticsearch/templates/component/elastic-agent/so-fleet_integrations.ip_mappings-1.json new file mode 100644 index 000000000..d6f516272 --- /dev/null +++ b/salt/elasticsearch/templates/component/elastic-agent/so-fleet_integrations.ip_mappings-1.json @@ -0,0 +1,59 @@ +{ + "template": { + "mappings": { + "properties": { + "host": { + "properties": { + "ip": { + "type": "ip" + } + } + }, + "related": { + "properties": { + "ip": { + "type": "ip" + } + } + }, + "destination": { + "properties": { + "ip": { + "type": "ip" + } + } + }, + "source": { + "properties": { + "ip": { + "type": "ip" + } + } + }, + "metadata": { + "properties": { + "input": { + "properties": { + "beats": { + "properties": { + "host": { + "properties": { + "ip": { + "type": "ip" + } + } + } + } + } + } + } + } + } + } + } + }, + "_meta": { + "managed_by": "security_onion", + "managed": true + } +} \ No newline at end of file diff --git a/salt/elasticsearch/templates/component/elastic-agent/so-items-mappings.json b/salt/elasticsearch/templates/component/elastic-agent/so-items-mappings.json new file mode 100644 index 000000000..85e6c1984 --- /dev/null +++ b/salt/elasticsearch/templates/component/elastic-agent/so-items-mappings.json @@ -0,0 +1,112 @@ +{ + "template": { + "mappings": { + "dynamic": "strict", + "properties": { + "binary": { + "type": "binary" + }, + "boolean": { + "type": "boolean" + }, + "byte": { + "type": "byte" + }, + "created_at": { + "type": "date" + }, + "created_by": { + "type": "keyword" + }, + "date": { + "type": "date" + }, + "date_nanos": { + "type": "date_nanos" + }, + "date_range": { + "type": "date_range" + }, + "deserializer": { + "type": "keyword" + }, + "double": { + "type": "double" + }, + "double_range": { + "type": "double_range" + }, + "float": { + "type": "float" + }, + "float_range": { + "type": "float_range" + }, + "geo_point": { + "type": "geo_point" + }, + "geo_shape": { + "type": "geo_shape" + }, + "half_float": { + "type": "half_float" + }, + "integer": { + "type": "integer" + }, + "integer_range": { + "type": "integer_range" + }, + "ip": { + "type": "ip" + }, + "ip_range": { + "type": "ip_range" + }, + "keyword": { + "type": "keyword" + }, + "list_id": { + "type": "keyword" + }, + "long": { + "type": "long" + }, + "long_range": { + "type": "long_range" + }, + "meta": { + "type": "object", + "enabled": false + }, + "serializer": { + "type": "keyword" + }, + "shape": { + "type": "shape" + }, + "short": { + "type": "short" + }, + "text": { + "type": "text" + }, + "tie_breaker_id": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "updated_by": { + "type": "keyword" + } + } + }, + "aliases": {} + }, + "version": 2, + "_meta": { + "managed": true, + "description": "default mappings for the .items index template installed by Kibana/Security" + } +} diff --git a/salt/elasticsearch/templates/component/elastic-agent/so-lists-mappings.json b/salt/elasticsearch/templates/component/elastic-agent/so-lists-mappings.json new file mode 100644 index 000000000..b2b5fda23 --- /dev/null +++ b/salt/elasticsearch/templates/component/elastic-agent/so-lists-mappings.json @@ -0,0 +1,55 @@ +{ + "template": { + "mappings": { + "dynamic": "strict", + "properties": { + "created_at": { + "type": "date" + }, + "created_by": { + "type": "keyword" + }, + "description": { + "type": "keyword" + }, + "deserializer": { + "type": "keyword" + }, + "immutable": { + "type": "boolean" + }, + "meta": { + "type": "object", + "enabled": false + }, + "name": { + "type": "keyword" + }, + "serializer": { + "type": "keyword" + }, + "tie_breaker_id": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "updated_by": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "aliases": {} + }, + "version": 2, + "_meta": { + "managed": true, + "description": "default mappings for the .lists index template installed by Kibana/Security" + } +} diff --git a/salt/elasticsearch/templates/component/so/detection-mappings.json b/salt/elasticsearch/templates/component/so/detection-mappings.json new file mode 100644 index 000000000..4dd5b45e7 --- /dev/null +++ b/salt/elasticsearch/templates/component/so/detection-mappings.json @@ -0,0 +1,163 @@ +{ + "template": { + "mappings": { + "properties": { + "so_audit_doc_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "@timestamp": { + "type": "date" + }, + "so_kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "so_operation": { + "ignore_above": 1024, + "type": "keyword" + }, + "so_detection": { + "properties": { + "publicId": { + "ignore_above": 1024, + "type": "keyword" + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + }, + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "type": "text" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "ignore_above": 1024, + "type": "keyword" + }, + "content": { + "type": "text" + }, + "isEnabled": { + "type": "boolean" + }, + "isReporting": { + "type": "boolean" + }, + "isCommunity": { + "type": "boolean" + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "engine": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "sourceCreated": { + "type": "date" + }, + "sourceUpdated": { + "type": "date" + }, + "overrides": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "isEnabled": { + "type": "boolean" + }, + "createdAt": { + "type": "date" + }, + "updatedAt": { + "type": "date" + }, + "note": { + "type": "text" + }, + "regex": { + "type": "text" + }, + "value": { + "type": "text" + }, + "thresholdType": { + "ignore_above": 1024, + "type": "keyword" + }, + "track": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "text" + }, + "count": { + "type": "long" + }, + "seconds": { + "type": "long" + }, + "customFilter": { + "type": "text" + } + } + } + } + }, + "so_detectioncomment": { + "properties": { + "createTime": { + "type": "date" + }, + "detectionId": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "type": "text" + }, + "userId": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + }, + "_meta": { + "ecs_version": "1.12.2" + } +} diff --git a/salt/elasticsearch/templates/component/so/detection-settings.json b/salt/elasticsearch/templates/component/so/detection-settings.json new file mode 100644 index 000000000..7b0947a4c --- /dev/null +++ b/salt/elasticsearch/templates/component/so/detection-settings.json @@ -0,0 +1,7 @@ +{ + "template": {}, + "version": 1, + "_meta": { + "description": "default settings for common Security Onion Detections indices" + } +} \ No newline at end of file diff --git a/salt/elasticsearch/templates/component/so/so-ip-mappings.json b/salt/elasticsearch/templates/component/so/so-ip-mappings.json new file mode 100644 index 000000000..a61eae5fd --- /dev/null +++ b/salt/elasticsearch/templates/component/so/so-ip-mappings.json @@ -0,0 +1,25 @@ +{ + "_meta": { + "documentation": "https://www.elastic.co/guide/en/ecs/current/ecs-network.html", + "ecs_version": "1.12.2" + }, + "template": { + "mappings": { + "properties": { + "@timestamp": { + "type": "date" + }, + "so": { + "properties": { + "ip_address": { + "type": "ip" + }, + "description": { + "type": "text" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/salt/elasticsearch/templates/component/so/so-scan-mappings.json b/salt/elasticsearch/templates/component/so/so-scan-mappings.json index 008a6ab10..2d11acba0 100644 --- a/salt/elasticsearch/templates/component/so/so-scan-mappings.json +++ b/salt/elasticsearch/templates/component/so/so-scan-mappings.json @@ -14,16 +14,19 @@ }, "pe": { "properties": { - "sections": { + "flags": { + "type": "text" + }, + "image_version": { + "type": "float" + }, + "sections": { "properties": { "entropy": { "type": "float" } } - }, - "image_version": { - "type": "float" - } + } } }, "elf": { diff --git a/salt/elasticsearch/templates/component/so/so-system-mappings.json b/salt/elasticsearch/templates/component/so/so-system-mappings.json new file mode 100644 index 000000000..17319ab9f --- /dev/null +++ b/salt/elasticsearch/templates/component/so/so-system-mappings.json @@ -0,0 +1,36 @@ +{ + "template": { + "mappings": { + "properties": { + "host": { + "properties":{ + "ip": { + "type": "ip" + } + } + }, + "related": { + "properties":{ + "ip": { + "type": "ip" + } + } + }, + "destination": { + "properties":{ + "ip": { + "type": "ip" + } + } + }, + "source": { + "properties":{ + "ip": { + "type": "ip" + } + } + } + } + } + } +} diff --git a/salt/elasticsearch/tools/sbin/so-elastic-clear b/salt/elasticsearch/tools/sbin/so-elastic-clear index 085327fc4..af7b91ce2 100755 --- a/salt/elasticsearch/tools/sbin/so-elastic-clear +++ b/salt/elasticsearch/tools/sbin/so-elastic-clear @@ -67,7 +67,7 @@ if [ $SKIP -ne 1 ]; then echo echo "This script will delete all data (documents, indices, etc.) in the Elasticsearch database." echo - echo "If you would like to proceed, please type "AGREE" and hit ENTER." + echo "If you would like to proceed, then type AGREE and press ENTER." echo # Read user input read INPUT diff --git a/salt/elasticsearch/tools/sbin/so-elastic-diagnose b/salt/elasticsearch/tools/sbin/so-elastic-diagnose index a94384fe8..971667c7a 100755 --- a/salt/elasticsearch/tools/sbin/so-elastic-diagnose +++ b/salt/elasticsearch/tools/sbin/so-elastic-diagnose @@ -11,7 +11,7 @@ . /usr/sbin/so-common # Check for log files -for FILE in /opt/so/log/elasticsearch/*.log /opt/so/log/logstash/*.log /opt/so/log/kibana/*.log /opt/so/log/elastalert/*.log /opt/so/log/curator/*.log /opt/so/log/freqserver/*.log /opt/so/log/nginx/*.log; do +for FILE in /opt/so/log/elasticsearch/*.log /opt/so/log/logstash/*.log /opt/so/log/kibana/*.log /opt/so/log/elastalert/*.log /opt/so/log/freqserver/*.log /opt/so/log/nginx/*.log; do # If file exists, then look for errors or warnings if [ -f $FILE ]; then diff --git a/salt/elasticsearch/tools/sbin/so-elasticsearch-ilm-start b/salt/elasticsearch/tools/sbin/so-elasticsearch-ilm-start index d9c63f8ea..c13d91fe5 100755 --- a/salt/elasticsearch/tools/sbin/so-elasticsearch-ilm-start +++ b/salt/elasticsearch/tools/sbin/so-elasticsearch-ilm-start @@ -1,4 +1,4 @@ -/bin/bash +#!/bin/bash # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at # https://securityonion.net/license; you may not use this file except in compliance with the @@ -6,6 +6,6 @@ . /usr/sbin/so-common - echo "Starting ILM..." curl -K /opt/so/conf/elasticsearch/curl.config -s -k -L -X POST https://localhost:9200/_ilm/start +echo diff --git a/salt/elasticsearch/tools/sbin/so-elasticsearch-ilm-stop b/salt/elasticsearch/tools/sbin/so-elasticsearch-ilm-stop index 034082699..e53a4939a 100755 --- a/salt/elasticsearch/tools/sbin/so-elasticsearch-ilm-stop +++ b/salt/elasticsearch/tools/sbin/so-elasticsearch-ilm-stop @@ -8,3 +8,4 @@ echo "Stopping ILM..." curl -K /opt/so/conf/elasticsearch/curl.config -s -k -L -X POST https://localhost:9200/_ilm/stop +echo diff --git a/salt/curator/tools/sbin/so-curator-cluster-delete b/salt/elasticsearch/tools/sbin/so-elasticsearch-indices-delete similarity index 92% rename from salt/curator/tools/sbin/so-curator-cluster-delete rename to salt/elasticsearch/tools/sbin/so-elasticsearch-indices-delete index 0f7945b78..036ff844f 100755 --- a/salt/curator/tools/sbin/so-curator-cluster-delete +++ b/salt/elasticsearch/tools/sbin/so-elasticsearch-indices-delete @@ -14,4 +14,4 @@ read lastPID < $lf [ ! -z "$lastPID" -a -d /proc/$lastPID ] && exit echo $$ > $lf -/usr/sbin/so-curator-cluster-delete-delete +/usr/sbin/so-elasticsearch-indices-delete-delete diff --git a/salt/elasticsearch/tools/sbin/so-elasticsearch-indices-growth b/salt/elasticsearch/tools/sbin/so-elasticsearch-indices-growth new file mode 100644 index 000000000..3381947eb --- /dev/null +++ b/salt/elasticsearch/tools/sbin/so-elasticsearch-indices-growth @@ -0,0 +1,113 @@ +#!/bin/bash + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +INFLUX_URL="https://localhost:8086/api/v2" + +. /usr/sbin/so-common + +request() { + curl -skK /opt/so/conf/influxdb/curl.config "$INFLUX_URL/$@" +} + +lookup_org_id() { + response=$(request orgs?org=Security+Onion) + echo "$response" | jq -r ".orgs[] | select(.name == \"Security Onion\").id" +} + +ORG_ID=$(lookup_org_id) + +run_flux_query() { + local query=$1 + request "query?org=$ORG_ID" -H 'Accept:application/csv' -H 'Content-type:application/vnd.flux' -d "$query" -XPOST 2>/dev/null +} + +read_csv_result() { + local result="$1" + echo "$result" | grep '^,_result,' | head -1 | awk -F',' '{print $NF}' | tr -d '\r\n\t ' +} + +bytes_to_gb() { + local bytes="${1:-0}" + if [[ "$bytes" =~ ^-?[0-9]+$ ]]; then + echo "$bytes" | awk '{printf "%.2f", $1 / 1024 / 1024 / 1024}' + else + echo "0.00" + fi +} + +indexes_query='from(bucket: "telegraf/so_long_term") +|> range(start: -7d) +|> filter(fn: (r) => r._measurement == "elasticsearch_index_size") +|> distinct(column: "_field") +|> keep(columns: ["_field"])' + +indexes_result=$(run_flux_query "$indexes_query") +indexes=$(echo "$indexes_result" | tail -n +2 | cut -d',' -f4 | grep -v '^$' | grep -v '^_field$' | sed 's/\r$//' | sort -u) + +printf "%-50s %15s %15s %15s\n" "Index Name" "Last 24hr (GB)" "Last 7d (GB)" "Last 30d (GB)" +printf "%-50s %15s %15s %15s\n" "$(printf '%.0s-' {1..50})" "$(printf '%.0s-' {1..15})" "$(printf '%.0s-' {1..15})" "$(printf '%.0s-' {1..15})" + +for index in $indexes; do + [[ -z "$index" ]] && continue + current_query="from(bucket: \"telegraf/so_long_term\") + |> range(start: -4h) + |> filter(fn: (r) => r._measurement == \"elasticsearch_index_size\" and r._field == \"$index\") + |> last() + |> keep(columns: [\"_value\"])" + current_result=$(run_flux_query "$current_query") + current_size=$(read_csv_result "$current_result") + current_size=${current_size:-0} + + size_24h_query="from(bucket: \"telegraf/so_long_term\") + |> range(start: -25h, stop: -23h) + |> filter(fn: (r) => r._measurement == \"elasticsearch_index_size\" and r._field == \"$index\") + |> last() + |> keep(columns: [\"_value\"])" + size_24h_result=$(run_flux_query "$size_24h_query") + size_24h_ago=$(read_csv_result "$size_24h_result") + size_24h_ago=${size_24h_ago:-$current_size} + + size_7d_query="from(bucket: \"telegraf/so_long_term\") + |> range(start: -7d8h, stop: -7d) + |> filter(fn: (r) => r._measurement == \"elasticsearch_index_size\" and r._field == \"$index\") + |> last() + |> keep(columns: [\"_value\"])" + size_7d_result=$(run_flux_query "$size_7d_query") + size_7d_ago=$(read_csv_result "$size_7d_result") + size_7d_ago=${size_7d_ago:-$current_size} + + size_30d_query="from(bucket: \"telegraf/so_long_term\") + |> range(start: -30d8h, stop: -30d) + |> filter(fn: (r) => r._measurement == \"elasticsearch_index_size\" and r._field == \"$index\") + |> last() + |> keep(columns: [\"_value\"])" + size_30d_result=$(run_flux_query "$size_30d_query") + size_30d_ago=$(read_csv_result "$size_30d_result") + size_30d_ago=${size_30d_ago:-$current_size} + + # if an index was recently cleaned up by ilm it will result in a negative number for 'index growth'. + growth_24h=$(( current_size > size_24h_ago ? current_size - size_24h_ago : 0 )) + + growth_7d=$(( current_size > size_7d_ago ? current_size - size_7d_ago : 0 )) + + growth_30d=$(( current_size > size_30d_ago ? current_size - size_30d_ago : 0 )) + + growth_24h_gb=$(bytes_to_gb "$growth_24h") + growth_7d_gb=$(bytes_to_gb "$growth_7d") + growth_30d_gb=$(bytes_to_gb "$growth_30d") + + # Only results for indices with atleast 1 metric above 0.00 + if [[ "$growth_24h_gb" != "0.00" ]] || [[ "$growth_7d_gb" != "0.00" ]] || [[ "$growth_30d_gb" != "0.00" ]]; then + printf "%020.2f|%-50s %15s %15s %15s\n" \ + "$growth_24h" \ + "$index" \ + "$growth_24h_gb" \ + "$growth_7d_gb" \ + "$growth_30d_gb" + fi +done | sort -t'|' -k1,1nr | cut -d'|' -f2- + diff --git a/salt/elasticsearch/tools/sbin/so-elasticsearch-pipelines b/salt/elasticsearch/tools/sbin/so-elasticsearch-pipelines index 71c40c1ca..b76a0e0f0 100755 --- a/salt/elasticsearch/tools/sbin/so-elasticsearch-pipelines +++ b/salt/elasticsearch/tools/sbin/so-elasticsearch-pipelines @@ -20,7 +20,7 @@ if [ ! -f /opt/so/state/espipelines.txt ]; then cd ${ELASTICSEARCH_INGEST_PIPELINES} echo "Loading pipelines..." - for i in .[a-z]* *; + for i in *; do echo $i; retry 5 5 "so-elasticsearch-query _ingest/pipeline/$i -d@$i -XPUT | grep '{\"acknowledged\":true}'" || fail "Could not load pipeline: $i" diff --git a/salt/elasticsearch/tools/sbin/so-index-list b/salt/elasticsearch/tools/sbin/so-index-list index 1e4595b35..572e55cba 100755 --- a/salt/elasticsearch/tools/sbin/so-index-list +++ b/salt/elasticsearch/tools/sbin/so-index-list @@ -5,6 +5,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. +. /usr/sbin/so-common - -curl -K /opt/so/conf/elasticsearch/curl.config-X GET -k -L "https://localhost:9200/_cat/indices?v&s=index" +curl -K /opt/so/conf/elasticsearch/curl.config -s -k -L "https://localhost:9200/_cat/indices?pretty&v&s=index" diff --git a/salt/elasticsearch/tools/sbin_jinja/so-catrust b/salt/elasticsearch/tools/sbin_jinja/so-catrust index fe4ff58bc..16fd3ffdb 100644 --- a/salt/elasticsearch/tools/sbin_jinja/so-catrust +++ b/salt/elasticsearch/tools/sbin_jinja/so-catrust @@ -6,13 +6,14 @@ # Elastic License 2.0. . /usr/sbin/so-common +get_elastic_agent_vars # Exit on errors, since all lines must succeed set -e # Check to see if we have extracted the ca cert. if [ ! -f /opt/so/saltstack/local/salt/elasticsearch/cacerts ]; then - docker run -v /etc/pki/ca.crt:/etc/ssl/ca.crt --name so-elasticsearchca --user root --entrypoint jdk/bin/keytool {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elasticsearch:{{ GLOBALS.so_version }} -keystore /usr/share/elasticsearch/jdk/lib/security/cacerts -alias SOSCA -import -file /etc/ssl/ca.crt -storepass changeit -noprompt + docker run -v /etc/pki/ca.crt:/etc/ssl/ca.crt --name so-elasticsearchca --user root --entrypoint jdk/bin/keytool {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elasticsearch:$ELASTIC_AGENT_TARBALL_VERSION -keystore /usr/share/elasticsearch/jdk/lib/security/cacerts -alias SOSCA -import -file /etc/ssl/ca.crt -storepass changeit -noprompt docker cp so-elasticsearchca:/usr/share/elasticsearch/jdk/lib/security/cacerts /opt/so/saltstack/local/salt/elasticsearch/cacerts docker cp so-elasticsearchca:/etc/ssl/certs/ca-certificates.crt /opt/so/saltstack/local/salt/elasticsearch/tls-ca-bundle.pem docker rm so-elasticsearchca diff --git a/salt/elasticsearch/tools/sbin_jinja/so-elastic-restart b/salt/elasticsearch/tools/sbin_jinja/so-elastic-restart index 1b5e9bf03..c5b9b71cd 100755 --- a/salt/elasticsearch/tools/sbin_jinja/so-elastic-restart +++ b/salt/elasticsearch/tools/sbin_jinja/so-elastic-restart @@ -23,10 +23,6 @@ /usr/sbin/so-restart logstash $1 {%- endif %} -{%- if GLOBALS.role in ['so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-searchnode']%} -/usr/sbin/so-restart curator $1 -{%- endif %} - {%- if GLOBALS.role in ['so-eval','so-manager', 'so-managersearch', 'so-standalone']%} /usr/sbin/so-restart elastalert $1 {%- endif %} diff --git a/salt/elasticsearch/tools/sbin_jinja/so-elastic-start b/salt/elasticsearch/tools/sbin_jinja/so-elastic-start index 6be969e9d..2a82dad21 100755 --- a/salt/elasticsearch/tools/sbin_jinja/so-elastic-start +++ b/salt/elasticsearch/tools/sbin_jinja/so-elastic-start @@ -22,10 +22,6 @@ /usr/sbin/so-start logstash $1 {%- endif %} -{%- if GLOBALS.role in ['so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-searchnode']%} -/usr/sbin/so-start curator $1 -{%- endif %} - {%- if GLOBALS.role in ['so-eval','so-manager', 'so-managersearch', 'so-standalone']%} /usr/sbin/so-start elastalert $1 {%- endif %} diff --git a/salt/elasticsearch/tools/sbin_jinja/so-elastic-stop b/salt/elasticsearch/tools/sbin_jinja/so-elastic-stop index b6ea04964..c4caa599c 100755 --- a/salt/elasticsearch/tools/sbin_jinja/so-elastic-stop +++ b/salt/elasticsearch/tools/sbin_jinja/so-elastic-stop @@ -22,10 +22,6 @@ /usr/sbin/so-stop logstash $1 {%- endif %} -{%- if GLOBALS.role in ['so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-searchnode']%} -/usr/sbin/so-stop curator $1 -{%- endif %} - {%- if GLOBALS.role in ['so-eval','so-manager', 'so-managersearch', 'so-standalone']%} /usr/sbin/so-stop elastalert $1 {%- endif %} diff --git a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-settings b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-settings index 9048b85b1..fb1bfa08b 100755 --- a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-settings +++ b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-settings @@ -4,7 +4,7 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. {%- from 'vars/globals.map.jinja' import GLOBALS %} -{%- set node_data = salt['pillar.get']('logstash:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %} +{%- set node_data = salt['pillar.get']('elasticsearch:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %} . /usr/sbin/so-common diff --git a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-space-total b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-space-total index 3faa2a7a9..e50733349 100755 --- a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-space-total +++ b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-space-total @@ -40,9 +40,9 @@ fi # Iterate through the output of _cat/allocation for each node in the cluster to determine the total available space {% if GLOBALS.role == 'so-manager' %} -for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | grep -v {{ GLOBALS.manager }} | awk '{print $5}'); do +for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | grep -v "{{ GLOBALS.manager }}$" | awk '{print $8}'); do {% else %} -for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | awk '{print $5}'); do +for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | awk '{print $8}'); do {% endif %} size=$(echo $i | grep -oE '[0-9].*' | awk '{print int($1+0.5)}') unit=$(echo $i | grep -oE '[A-Za-z]+') diff --git a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-space-used b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-space-used index 5d8a60e22..b18e84d71 100755 --- a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-space-used +++ b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-space-used @@ -13,10 +13,10 @@ TOTAL_USED_SPACE=0 # Iterate through the output of _cat/allocation for each node in the cluster to determine the total used space {% if GLOBALS.role == 'so-manager' %} # Get total disk space - disk.total -for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | grep -v {{ GLOBALS.manager }} | awk '{print $3}'); do +for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | grep -v "{{ GLOBALS.manager }}$" | awk '{print $6}'); do {% else %} # Get disk space taken up by indices - disk.indices -for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | awk '{print $2}'); do +for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | awk '{print $5}'); do {% endif %} size=$(echo $i | grep -oE '[0-9].*' | awk '{print int($1+0.5)}') unit=$(echo $i | grep -oE '[A-Za-z]+') diff --git a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load index b00fcbedf..04a7a8ab0 100755 --- a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load +++ b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load @@ -10,10 +10,26 @@ {%- for index, settings in ES_INDEX_SETTINGS.items() %} {%- if settings.policy is defined %} -echo -echo "Setting up {{ index }}-logs policy..." -curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/{{ index }}-logs" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }' -echo +{%- if index == 'so-logs-detections.alerts' %} + echo + echo "Setting up so-logs-detections.alerts-so policy..." + curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/{{ index }}-so" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }' + echo +{%- elif index == 'so-logs-soc' %} + echo + echo "Setting up so-soc-logs policy..." + curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/so-soc-logs" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }' + echo + echo + echo "Setting up {{ index }}-logs policy..." + curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/{{ index }}-logs" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }' + echo +{%- else %} + echo + echo "Setting up {{ index }}-logs policy..." + curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/{{ index }}-logs" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }' + echo +{%- endif %} {%- endif %} {%- endfor %} echo diff --git a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-indices-delete-delete b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-indices-delete-delete new file mode 100755 index 000000000..a00437a25 --- /dev/null +++ b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-indices-delete-delete @@ -0,0 +1,79 @@ +#!/bin/bash +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% import_yaml 'elasticsearch/defaults.yaml' as ELASTICDEFAULTS %} +{%- set ELASTICSEARCH_HOST = GLOBALS.node_ip -%} +{%- set RETENTION = salt['pillar.get']('elasticsearch:retention', ELASTICDEFAULTS.elasticsearch.retention, merge=true) -%} + +LOG="/opt/so/log/elasticsearch/so-elasticsearch-indices-delete.log" +ALERT_LOG="/opt/so/log/elasticsearch/indices-delete-alert.log" +LOG_SIZE_LIMIT_GB=$(/usr/sbin/so-elasticsearch-cluster-space-total {{ RETENTION.retention_pct}}) +LOG_SIZE_LIMIT=$(( "$LOG_SIZE_LIMIT_GB" * 1000 * 1000 * 1000 )) +ITERATION=0 +MAX_ITERATIONS=10 + +overlimit() { + [[ $(/usr/sbin/so-elasticsearch-cluster-space-used) -gt ${LOG_SIZE_LIMIT} ]] +} + +########################### +# Check for 2 conditions: # +########################### +# 1. Check if Elasticsearch indices are using more disk space than LOG_SIZE_LIMIT +# 2. Check if the maximum number of iterations - MAX_ITERATIONS - has been exceeded. If so, exit. +# Closed indices will be deleted first. If we are able to bring disk space under LOG_SIZE_LIMIT, or the number of iterations has exceeded the maximum allowed number of iterations, we will break out of the loop. + + +while overlimit && [[ $ITERATION -lt $MAX_ITERATIONS ]]; do + + # If we can't query Elasticsearch, then immediately return false. + /usr/sbin/so-elasticsearch-query _cat/indices?h=index,status > /dev/null 2>&1 + [ $? -eq 1 ] && echo "$(date) - Could not query Elasticsearch." >> ${LOG} && exit + + # We iterate through the closed and open indices + CLOSED_SO_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'close$' | awk '{print $1}' | grep -E "(^logstash-.*|^so-.*)" | grep -vE "so-case|so-detection" | sort -t- -k3) + CLOSED_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'close$' | awk '{print $1}' | grep -E "^.ds-logs-.*" | grep -v "suricata" | sort -t- -k4) + OPEN_SO_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'open$' | awk '{print $1}' | grep -E "(^logstash-.*|^so-.*)" | grep -vE "so-case|so-detection" | sort -t- -k3) + OPEN_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'open$' | awk '{print $1}' | grep -E "^.ds-logs-.*" | grep -v "suricata" | sort -t- -k4) + + for INDEX in ${CLOSED_SO_INDICES} ${OPEN_SO_INDICES} ${CLOSED_INDICES} ${OPEN_INDICES}; do + # Check if index is an older index. If it is an older index, delete it before moving on to newer indices. + if [[ "$INDEX" =~ "^logstash-.*|so-.*" ]]; then + printf "\n$(date) - Used disk space exceeds LOG_SIZE_LIMIT (${LOG_SIZE_LIMIT_GB} GB) - Deleting ${INDEX} index...\n" >> ${LOG} + /usr/sbin/so-elasticsearch-query ${INDEX} -XDELETE >> ${LOG} 2>&1 + else + # Now that we've sorted the indices from oldest to newest, we need to check each index to see if it is assigned as the current write index for a data stream + # To do so, we need to identify to which data stream this index is associated + # We extract the data stream name using the pattern below + DATASTREAM_PATTERN="logs-[a-zA-Z_.]+-[a-zA-Z_.]+" + DATASTREAM=$(echo "${INDEX}" | grep -oE "$DATASTREAM_PATTERN") + # We look up the data stream, and determine the write index. If there is only one backing index, we delete the entire data stream + BACKING_INDICES=$(/usr/sbin/so-elasticsearch-query _data_stream/${DATASTREAM} | jq -r '.data_streams[0].indices | length') + if [ "$BACKING_INDICES" -gt 1 ]; then + CURRENT_WRITE_INDEX=$(/usr/sbin/so-elasticsearch-query _data_stream/$DATASTREAM | jq -r .data_streams[0].indices[-1].index_name) + # We make sure we are not trying to delete a write index + if [ "${INDEX}" != "${CURRENT_WRITE_INDEX}" ]; then + # This should not be a write index, so we should be allowed to delete it + printf "\n$(date) - Used disk space exceeds LOG_SIZE_LIMIT (${LOG_SIZE_LIMIT_GB} GB) - Deleting ${INDEX} index...\n" >> ${LOG} + /usr/sbin/so-elasticsearch-query ${INDEX} -XDELETE >> ${LOG} 2>&1 + fi + else + printf "\n$(date) - Used disk space exceeds LOG_SIZE_LIMIT (${LOG_SIZE_LIMIT_GB} GB) - There is only one backing index (${INDEX}). Deleting ${DATASTREAM} data stream...\n" >> ${LOG} + /usr/sbin/so-elasticsearch-query _data_stream/$DATASTREAM -XDELETE >> ${LOG} 2>&1 + fi + fi + if ! overlimit ; then + exit + fi + ((ITERATION++)) + done + if [[ $ITERATION -ge $MAX_ITERATIONS ]]; then + alert_id=$(uuidgen) + printf "\n$(date) -> Maximum iteration limit reached ($MAX_ITERATIONS). Unable to bring disk below threshold. Writing alert ($alert_id) to ${ALERT_LOG}\n" >> ${LOG} + printf "\n$(date),$alert_id,Maximum iteration limit reached ($MAX_ITERATIONS). Unable to bring disk below threshold.\n" >> ${ALERT_LOG} + fi +done diff --git a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-templates-load b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-templates-load index 8f45d6c36..758f601eb 100755 --- a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-templates-load +++ b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-templates-load @@ -5,7 +5,6 @@ # Elastic License 2.0. {%- import_yaml 'elasticfleet/defaults.yaml' as ELASTICFLEETDEFAULTS %} {% from 'vars/globals.map.jinja' import GLOBALS %} -{%- set SUPPORTED_PACKAGES = salt['pillar.get']('elasticfleet:packages', default=ELASTICFLEETDEFAULTS.elasticfleet.packages, merge=True) %} STATE_FILE_INITIAL=/opt/so/state/estemplates_initial_load_attempt.txt STATE_FILE_SUCCESS=/opt/so/state/estemplates.txt @@ -24,6 +23,9 @@ else echo "This is the initial template load" fi +# If soup is running, ignore errors +pgrep soup > /dev/null && should_exit_on_failure=0 + load_failures=0 load_template() { @@ -31,7 +33,7 @@ load_template() { file=$2 echo "Loading template file $i" - if ! retry 3 5 "so-elasticsearch-query $uri -d@$file -XPUT" "{\"acknowledged\":true}"; then + if ! retry 3 1 "so-elasticsearch-query $uri -d@$file -XPUT" "{\"acknowledged\":true}"; then if [[ $should_exit_on_failure -eq 1 ]]; then fail "Could not load template file: $file" else @@ -68,9 +70,9 @@ if [ ! -f $STATE_FILE_SUCCESS ]; then echo -n "Waiting for ElasticSearch..." retry 240 1 "so-elasticsearch-query / -k --output /dev/null --silent --head --fail" || fail "Connection attempt timed out. Unable to connect to ElasticSearch. \nPlease try: \n -checking log(s) in /var/log/elasticsearch/\n -running 'sudo docker ps' \n -running 'sudo so-elastic-restart'" {% if GLOBALS.role != 'so-heavynode' %} - SESSIONCOOKIE=$(curl -s -K /opt/so/conf/elasticsearch/curl.config -c - -X GET http://localhost:5601/ | grep sid | awk '{print $7}') - INSTALLED=$(elastic_fleet_package_is_installed {{ SUPPORTED_PACKAGES[0] }} ) - if [ "$INSTALLED" != "installed" ]; then + TEMPLATE="logs-endpoint.alerts@package" + INSTALLED=$(so-elasticsearch-query _component_template/$TEMPLATE | jq -r .component_templates[0].name) + if [ "$INSTALLED" != "$TEMPLATE" ]; then echo echo "Packages not yet installed." echo @@ -133,8 +135,8 @@ if [ ! -f $STATE_FILE_SUCCESS ]; then for i in $pattern; do TEMPLATE=${i::-14} COMPONENT_PATTERN=${TEMPLATE:3} - MATCH=$(echo "$TEMPLATE" | grep -E "^so-logs-|^so-metrics" | grep -v osquery) - if [[ -n "$MATCH" && ! "$COMPONENT_LIST" =~ "$COMPONENT_PATTERN" ]]; then + MATCH=$(echo "$TEMPLATE" | grep -E "^so-logs-|^so-metrics" | grep -vE "detections|osquery") + if [[ -n "$MATCH" && ! "$COMPONENT_LIST" =~ "$COMPONENT_PATTERN" && ! "$COMPONENT_PATTERN" =~ logs-http_endpoint\.generic|logs-winlog\.winlog ]]; then load_failures=$((load_failures+1)) echo "Component template does not exist for $COMPONENT_PATTERN. The index template will not be loaded. Load failures: $load_failures" else @@ -153,7 +155,7 @@ if [ ! -f $STATE_FILE_SUCCESS ]; then cd - >/dev/null if [[ $load_failures -eq 0 ]]; then - echo "All template loaded successfully" + echo "All templates loaded successfully" touch $STATE_FILE_SUCCESS else echo "Encountered $load_failures templates that were unable to load, likely due to missing dependencies that will be available later; will retry on next highstate" diff --git a/salt/firewall/containers.map.jinja b/salt/firewall/containers.map.jinja index 02e8a4644..2d1135e5f 100644 --- a/salt/firewall/containers.map.jinja +++ b/salt/firewall/containers.map.jinja @@ -2,7 +2,6 @@ {% if GLOBALS.role == 'so-eval' %} {% set NODE_CONTAINERS = [ - 'so-curator', 'so-dockerregistry', 'so-elasticsearch', 'so-elastic-fleet', @@ -10,11 +9,10 @@ 'so-influxdb', 'so-kibana', 'so-kratos', - 'so-mysql', + 'so-hydra', 'so-nginx', 'so-redis', 'so-soc', - 'so-soctopus', 'so-strelka-coordinator', 'so-strelka-gatekeeper', 'so-strelka-frontend', @@ -23,22 +21,21 @@ 'so-strelka-filestream' ] %} -{% elif GLOBALS.role == 'so-manager' or GLOBALS.role == 'so-standalone' or GLOBALS.role == 'so-managersearch' %} +{% elif GLOBALS.role in ['so-manager', 'so-standalone','so-managersearch', 'so-managerhype'] %} {% set NODE_CONTAINERS = [ - 'so-curator', 'so-dockerregistry', 'so-elasticsearch', 'so-elastic-fleet', 'so-elastic-fleet-package-registry', 'so-influxdb', + 'so-kafka', 'so-kibana', 'so-kratos', + 'so-hydra', 'so-logstash', - 'so-mysql', 'so-nginx', 'so-redis', 'so-soc', - 'so-soctopus', 'so-strelka-coordinator', 'so-strelka-gatekeeper', 'so-strelka-frontend', @@ -56,7 +53,6 @@ {% elif GLOBALS.role == 'so-heavynode' %} {% set NODE_CONTAINERS = [ - 'so-curator', 'so-elasticsearch', 'so-elastic-agent', 'so-logstash', @@ -79,6 +75,7 @@ 'so-influxdb', 'so-kibana', 'so-kratos', + 'so-hydra', 'so-nginx', 'so-soc' ] %} @@ -87,6 +84,7 @@ {% set NODE_CONTAINERS = [ 'so-logstash', 'so-redis', + 'so-kafka' ] %} {% elif GLOBALS.role == 'so-idh' %} @@ -98,6 +96,7 @@ {% set NODE_CONTAINERS = [ 'so-elastic-fleet', 'so-logstash', + 'so-nginx-fleet-node' ] %} {% elif GLOBALS.role == 'so-sensor' %} diff --git a/salt/firewall/defaults.yaml b/salt/firewall/defaults.yaml index 75df49b25..9caaf725a 100644 --- a/salt/firewall/defaults.yaml +++ b/salt/firewall/defaults.yaml @@ -10,13 +10,17 @@ firewall: elasticsearch_rest: [] endgame: [] eval: [] + external_suricata: [] + external_kafka: [] fleet: [] heavynode: [] + hypervisor: [] idh: [] import: [] localhost: - 127.0.0.1 manager: [] + managerhype: [] managersearch: [] receiver: [] searchnode: [] @@ -86,31 +90,39 @@ firewall: tcp: - 3765 udp: [] + external_suricata: + tcp: + - 7789 + udp: [] influxdb: tcp: - 8086 udp: [] + kafka_controller: + tcp: + - 9093 + udp: [] + kafka_data: + tcp: + - 9092 + udp: [] + kafka_external_access: + tcp: + - 29092 + udp: [] kibana: tcp: - 5601 udp: [] localrules: - tcp: - - 7788 - udp: [] - mysql: tcp: - - 3306 + - 7788 udp: [] nginx: tcp: - 80 - 443 udp: [] - playbook: - tcp: - - 3000 - udp: [] redis: tcp: - 6379 @@ -178,8 +190,6 @@ firewall: hostgroups: eval: portgroups: - - playbook - - mysql - kibana - redis - influxdb @@ -218,6 +228,9 @@ firewall: analyst: portgroups: - nginx + external_suricata: + portgroups: + - external_suricata customhostgroup0: portgroups: [] customhostgroup1: @@ -363,8 +376,6 @@ firewall: hostgroups: manager: portgroups: - - playbook - - mysql - kibana - redis - influxdb @@ -466,6 +477,11 @@ firewall: endgame: portgroups: - endgame + external_suricata: + portgroups: + - external_suricata + external_kafka: + portgroups: [] desktop: portgroups: - docker_registry @@ -475,6 +491,15 @@ firewall: - elastic_agent_control - elastic_agent_data - elastic_agent_update + hypervisor: + portgroups: + - yum + - docker_registry + - influxdb + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + - sensoroni customhostgroup0: portgroups: [] customhostgroup1: @@ -527,6 +552,218 @@ firewall: desktop: portgroups: - salt_manager + hypervisor: + portgroups: + - salt_manager + self: + portgroups: + - syslog + syslog: + portgroups: + - syslog + customhostgroup0: + portgroups: [] + customhostgroup1: + portgroups: [] + customhostgroup2: + portgroups: [] + customhostgroup3: + portgroups: [] + customhostgroup4: + portgroups: [] + customhostgroup5: + portgroups: [] + customhostgroup6: + portgroups: [] + customhostgroup7: + portgroups: [] + customhostgroup8: + portgroups: [] + customhostgroup9: + portgroups: [] + managerhype: + chain: + DOCKER-USER: + hostgroups: + managerhype: + portgroups: + - kibana + - redis + - influxdb + - elasticsearch_rest + - elasticsearch_node + - docker_registry + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + - localrules + - sensoroni + fleet: + portgroups: + - elasticsearch_rest + - docker_registry + - influxdb + - sensoroni + - yum + - beats_5044 + - beats_5644 + - beats_5056 + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + idh: + portgroups: + - docker_registry + - influxdb + - sensoroni + - yum + - beats_5044 + - beats_5644 + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + sensor: + portgroups: + - beats_5044 + - beats_5644 + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + - yum + - docker_registry + - influxdb + - sensoroni + searchnode: + portgroups: + - redis + - elasticsearch_rest + - elasticsearch_node + - beats_5644 + - yum + - docker_registry + - influxdb + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + - sensoroni + heavynode: + portgroups: + - redis + - elasticsearch_rest + - elasticsearch_node + - beats_5644 + - yum + - docker_registry + - influxdb + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + - sensoroni + receiver: + portgroups: + - yum + - docker_registry + - influxdb + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + - sensoroni + analyst: + portgroups: + - nginx + beats_endpoint: + portgroups: + - beats_5044 + beats_endpoint_ssl: + portgroups: + - beats_5644 + elasticsearch_rest: + portgroups: + - elasticsearch_rest + elastic_agent_endpoint: + portgroups: + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + endgame: + portgroups: + - endgame + external_suricata: + portgroups: + - external_suricata + desktop: + portgroups: + - docker_registry + - influxdb + - sensoroni + - yum + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + hypervisor: + portgroups: + - yum + - docker_registry + - influxdb + - elastic_agent_control + - elastic_agent_data + - elastic_agent_update + - sensoroni + customhostgroup0: + portgroups: [] + customhostgroup1: + portgroups: [] + customhostgroup2: + portgroups: [] + customhostgroup3: + portgroups: [] + customhostgroup4: + portgroups: [] + customhostgroup5: + portgroups: [] + customhostgroup6: + portgroups: [] + customhostgroup7: + portgroups: [] + customhostgroup8: + portgroups: [] + customhostgroup9: + portgroups: [] + INPUT: + hostgroups: + anywhere: + portgroups: + - ssh + dockernet: + portgroups: + - all + fleet: + portgroups: + - salt_manager + idh: + portgroups: + - salt_manager + localhost: + portgroups: + - all + sensor: + portgroups: + - salt_manager + searchnode: + portgroups: + - salt_manager + heavynode: + portgroups: + - salt_manager + receiver: + portgroups: + - salt_manager + desktop: + portgroups: + - salt_manager + hypervisor: + portgroups: + - salt_manager self: portgroups: - syslog @@ -559,8 +796,6 @@ firewall: hostgroups: managersearch: portgroups: - - playbook - - mysql - kibana - redis - influxdb @@ -660,6 +895,11 @@ firewall: endgame: portgroups: - endgame + external_suricata: + portgroups: + - external_suricata + external_kafka: + portgroups: [] desktop: portgroups: - docker_registry @@ -756,8 +996,6 @@ firewall: - all standalone: portgroups: - - playbook - - mysql - kibana - redis - influxdb @@ -769,7 +1007,6 @@ firewall: - beats_5044 - beats_5644 - beats_5056 - - redis - elasticsearch_node - elastic_agent_control - elastic_agent_data @@ -859,6 +1096,11 @@ firewall: endgame: portgroups: - endgame + external_suricata: + portgroups: + - external_suricata + external_kafka: + portgroups: [] strelka_frontend: portgroups: - strelka_frontend @@ -1225,6 +1467,9 @@ firewall: - elastic_agent_control - elastic_agent_data - elastic_agent_update + external_suricata: + portgroups: + - external_suricata analyst: portgroups: - nginx @@ -1283,31 +1528,53 @@ firewall: chain: DOCKER-USER: hostgroups: + desktop: + portgroups: + - elastic_agent_data fleet: portgroups: - - beats_5056 + - elastic_agent_data + idh: + portgroups: + - elastic_agent_data sensor: portgroups: - - beats_5044 - - beats_5644 - elastic_agent_data searchnode: portgroups: - redis - - beats_5644 + - elastic_agent_data + standalone: + portgroups: + - redis + - elastic_agent_data + manager: + portgroups: + - elastic_agent_data + managersearch: + portgroups: + - redis + - elastic_agent_data self: portgroups: - redis - - beats_5644 + - elastic_agent_data beats_endpoint: portgroups: - beats_5044 beats_endpoint_ssl: portgroups: - beats_5644 + elastic_agent_endpoint: + portgroups: + - elastic_agent_data endgame: portgroups: - endgame + external_kafka: + portgroups: [] + receiver: + portgroups: [] customhostgroup0: portgroups: [] customhostgroup1: @@ -1428,3 +1695,64 @@ firewall: portgroups: [] customhostgroup9: portgroups: [] + hypervisor: + chain: + DOCKER-USER: + hostgroups: + customhostgroup0: + portgroups: [] + customhostgroup1: + portgroups: [] + customhostgroup2: + portgroups: [] + customhostgroup3: + portgroups: [] + customhostgroup4: + portgroups: [] + customhostgroup5: + portgroups: [] + customhostgroup6: + portgroups: [] + customhostgroup7: + portgroups: [] + customhostgroup8: + portgroups: [] + customhostgroup9: + portgroups: [] + INPUT: + hostgroups: + anywhere: + portgroups: + - ssh + dockernet: + portgroups: + - all + localhost: + portgroups: + - all + manager: + portgroups: [] + managersearch: + portgroups: [] + standalone: + portgroups: [] + customhostgroup0: + portgroups: [] + customhostgroup1: + portgroups: [] + customhostgroup2: + portgroups: [] + customhostgroup3: + portgroups: [] + customhostgroup4: + portgroups: [] + customhostgroup5: + portgroups: [] + customhostgroup6: + portgroups: [] + customhostgroup7: + portgroups: [] + customhostgroup8: + portgroups: [] + customhostgroup9: + portgroups: [] diff --git a/salt/firewall/iptables.jinja b/salt/firewall/iptables.jinja index 074663e15..48a0808e7 100644 --- a/salt/firewall/iptables.jinja +++ b/salt/firewall/iptables.jinja @@ -91,6 +91,10 @@ COMMIT -A INPUT -m conntrack --ctstate INVALID -j DROP -A INPUT -p icmp -j ACCEPT -A INPUT -j LOGGING +{% if GLOBALS.role in ['so-hypervisor', 'so-managerhyper'] -%} +-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT +-A FORWARD -i br0 -o br0 -j ACCEPT +{%- endif %} -A FORWARD -j DOCKER-USER -A FORWARD -j DOCKER-ISOLATION-STAGE-1 -A FORWARD -o sobridge -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT diff --git a/salt/firewall/map.jinja b/salt/firewall/map.jinja index 74b3a66be..4347d2b31 100644 --- a/salt/firewall/map.jinja +++ b/salt/firewall/map.jinja @@ -18,4 +18,41 @@ {% endfor %} {% endif %} -{% set FIREWALL_MERGED = salt['pillar.get']('firewall', FIREWALL_DEFAULT.firewall, merge=True) %} +{# Only add Kafka firewall items when Kafka enabled #} +{% set role = GLOBALS.role.split('-')[1] %} + +{% if GLOBALS.pipeline == 'KAFKA' %} +{% set KAFKA_EXTERNAL_ACCESS = salt['pillar.get']('kafka:config:external_access:enabled', default=False) %} +{% set kafka_node_type = salt['pillar.get']('kafka:nodes:'+ GLOBALS.hostname + ':role') %} + +{% if role in ['manager', 'managersearch', 'standalone'] %} +{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups[role].portgroups.append('kafka_controller') %} +{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.receiver.portgroups.append('kafka_controller') %} +{% endif %} + +{% if role == 'receiver' %} +{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.self.portgroups.append('kafka_controller') %} +{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.standalone.portgroups.append('kafka_controller') %} +{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.manager.portgroups.append('kafka_controller') %} +{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.managersearch.portgroups.append('kafka_controller') %} +{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.receiver.portgroups.append('kafka_controller') %} +{% endif %} + +{% if role in ['manager', 'managersearch', 'standalone', 'receiver'] %} +{% for r in ['manager', 'managersearch', 'standalone', 'receiver', 'fleet', 'idh', 'sensor', 'searchnode','heavynode', 'elastic_agent_endpoint', 'desktop'] %} +{% if FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups[r] is defined %} +{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups[r].portgroups.append('kafka_data') %} +{% endif %} +{% endfor %} +{% endif %} + +{% if KAFKA_EXTERNAL_ACCESS %} +{# Kafka external access only applies for Kafka nodes with the broker role. #} +{% if role in ['manager', 'managersearch', 'standalone', 'receiver'] and 'broker' in kafka_node_type %} +{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.external_kafka.portgroups.append('kafka_external_access') %} +{% endif %} +{% endif %} + +{% endif %} + +{% set FIREWALL_MERGED = salt['pillar.get']('firewall', FIREWALL_DEFAULT.firewall, merge=True) %} \ No newline at end of file diff --git a/salt/firewall/soc_firewall.yaml b/salt/firewall/soc_firewall.yaml index 209484b6e..8aa42cd05 100644 --- a/salt/firewall/soc_firewall.yaml +++ b/salt/firewall/soc_firewall.yaml @@ -3,24 +3,26 @@ firewall: analyst: &hostgroupsettings description: List of IP or CIDR blocks to allow access to this hostgroup. forcedType: "[]string" - helplink: firewall.html + helpLink: firewall.html multiline: True regex: ^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?)?$ regexFailureMessage: You must enter a valid IP address or CIDR. + duplicates: True anywhere: &hostgroupsettingsadv description: List of IP or CIDR blocks to allow access to this hostgroup. forcedType: "[]string" - helplink: firewall.html + helpLink: firewall.html multiline: True advanced: True regex: ^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?)?$ regexFailureMessage: You must enter a valid IP address or CIDR. + duplicates: True beats_endpoint: *hostgroupsettings beats_endpoint_ssl: *hostgroupsettings dockernet: &ROhostgroupsettingsadv description: List of IP or CIDR blocks to allow access to this hostgroup. forcedType: "[]string" - helplink: firewall.html + helpLink: firewall.html multiline: True advanced: True readonly: True @@ -30,8 +32,11 @@ firewall: elasticsearch_rest: *hostgroupsettingsadv endgame: *hostgroupsettingsadv eval: *hostgroupsettings + external_suricata: *hostgroupsettings + external_kafka: *hostgroupsettings fleet: *hostgroupsettings heavynode: *hostgroupsettings + hypervisor: *hostgroupsettings idh: *hostgroupsettings import: *hostgroupsettings localhost: *ROhostgroupsettingsadv @@ -53,6 +58,7 @@ firewall: multiline: True regex: ^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?)?$ regexFailureMessage: You must enter a valid IP address or CIDR. + duplicates: True customhostgroup1: *customhostgroupsettings customhostgroup2: *customhostgroupsettings customhostgroup3: *customhostgroupsettings @@ -67,15 +73,17 @@ firewall: tcp: &tcpsettings description: List of TCP ports for this port group. forcedType: "[]string" - helplink: firewall.html + helpLink: firewall.html advanced: True multiline: True + duplicates: True udp: &udpsettings description: List of UDP ports for this port group. forcedType: "[]string" - helplink: firewall.html + helpLink: firewall.html advanced: True multiline: True + duplicates: True agrules: tcp: *tcpsettings udp: *udpsettings @@ -112,24 +120,30 @@ firewall: endgame: tcp: *tcpsettings udp: *udpsettings + external_suricata: + tcp: *tcpsettings + udp: *udpsettings influxdb: tcp: *tcpsettings udp: *udpsettings + kafka_controller: + tcp: *tcpsettings + udp: *udpsettings + kafka_data: + tcp: *tcpsettings + udp: *udpsettings + kafka_external_access: + tcp: *tcpsettings + udp: *udpsettings kibana: tcp: *tcpsettings udp: *udpsettings localrules: tcp: *tcpsettings udp: *udpsettings - mysql: - tcp: *tcpsettings - udp: *udpsettings nginx: tcp: *tcpsettings udp: *udpsettings - playbook: - tcp: *tcpsettings - udp: *udpsettings redis: tcp: *tcpsettings udp: *udpsettings @@ -193,6 +207,7 @@ firewall: multiline: True forcedType: "[]string" helpLink: firewall.html + duplicates: True sensor: portgroups: *portgroupsdocker searchnode: @@ -209,6 +224,8 @@ firewall: portgroups: *portgroupsdocker elastic_agent_endpoint: portgroups: *portgroupsdocker + external_suricata: + portgroups: *portgroupsdocker strelka_frontend: portgroups: *portgroupsdocker syslog: @@ -246,6 +263,7 @@ firewall: multiline: True forcedType: "[]string" helpLink: firewall.html + duplicates: True dockernet: portgroups: *portgroupshost localhost: @@ -363,6 +381,8 @@ firewall: portgroups: *portgroupsdocker endgame: portgroups: *portgroupsdocker + external_suricata: + portgroups: *portgroupsdocker analyst: portgroups: *portgroupsdocker desktop: @@ -456,6 +476,8 @@ firewall: portgroups: *portgroupsdocker analyst: portgroups: *portgroupsdocker + external_suricata: + portgroups: *portgroupsdocker desktop: portgroups: *portgroupsdocker customhostgroup0: @@ -547,6 +569,8 @@ firewall: portgroups: *portgroupsdocker endgame: portgroups: *portgroupsdocker + external_suricata: + portgroups: *portgroupsdocker strelka_frontend: portgroups: *portgroupsdocker syslog: @@ -821,6 +845,8 @@ firewall: portgroups: *portgroupsdocker analyst: portgroups: *portgroupsdocker + external_suricata: + portgroups: *portgroupsdocker desktop: portgroups: *portgroupsdocker customhostgroup0: @@ -938,7 +964,6 @@ firewall: portgroups: *portgroupshost customhostgroup9: portgroups: *portgroupshost - idh: chain: DOCKER-USER: diff --git a/salt/global/defaults.yaml b/salt/global/defaults.yaml new file mode 100644 index 000000000..5daa942c8 --- /dev/null +++ b/salt/global/defaults.yaml @@ -0,0 +1,3 @@ +global: + pcapengine: STENO + pipeline: REDIS \ No newline at end of file diff --git a/salt/global/map.jinja b/salt/global/map.jinja new file mode 100644 index 000000000..54abb8c79 --- /dev/null +++ b/salt/global/map.jinja @@ -0,0 +1,2 @@ +{% import_yaml 'global/defaults.yaml' as GLOBALDEFAULTS %} +{% set GLOBALMERGED = salt['pillar.get']('global', GLOBALDEFAULTS.global, merge=True) %} diff --git a/salt/global/soc_global.yaml b/salt/global/soc_global.yaml index 14d637d50..047bb525b 100644 --- a/salt/global/soc_global.yaml +++ b/salt/global/soc_global.yaml @@ -10,10 +10,22 @@ global: regex: ^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?)?$ regexFailureMessage: You must enter a valid IP address or CIDR. mdengine: - description: What engine to use for meta data generation. Options are ZEEK and SURICATA. + description: Which engine to use for meta data generation. Options are ZEEK and SURICATA. regex: ^(ZEEK|SURICATA)$ + options: + - ZEEK + - SURICATA regexFailureMessage: You must enter either ZEEK or SURICATA. global: True + pcapengine: + description: Which engine to use for generating pcap. Options are STENO, SURICATA or TRANSITION. + regex: ^(STENO|SURICATA|TRANSITION)$ + options: + - STENO + - SURICATA + - TRANSITION + regexFailureMessage: You must enter either STENO, SURICATA or TRANSITION. + global: True ids: description: Which IDS engine to use. Currently only Suricata is supported. global: True @@ -23,7 +35,7 @@ global: description: Used for handling of authentication cookies. global: True airgap: - description: Sets airgap mode. + description: Airgapped systems do not have network connectivity to the internet. This setting represents how this grid was configured during initial setup. While it is technically possible to manually switch systems between airgap and non-airgap, there are some nuances and additional steps involved. For that reason this setting is marked read-only. Contact your support representative for guidance if there is a need to change this setting. global: True readonly: True imagerepo: @@ -31,9 +43,13 @@ global: global: True advanced: True pipeline: - description: Sets which pipeline technology for events to use. Currently only Redis is supported. + description: Sets which pipeline technology for events to use. The use of Kafka requires a Security Onion Pro license. + regex: ^(REDIS|KAFKA)$ + options: + - REDIS + - KAFKA + regexFailureMessage: You must enter either REDIS or KAFKA. global: True - readonly: True advanced: True repo_host: description: Specify the host where operating system packages will be served from. diff --git a/salt/hydra/config.sls b/salt/hydra/config.sls new file mode 100644 index 000000000..f74726cc1 --- /dev/null +++ b/salt/hydra/config.sls @@ -0,0 +1,51 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} +{% from "hydra/map.jinja" import HYDRAMERGED %} + +hydradir: + file.directory: + - name: /nsm/hydra + - user: 928 + - group: 928 + - mode: 700 + - makedirs: True + +hydradbdir: + file.directory: + - name: /nsm/hydra/db + - user: 928 + - group: 928 + - mode: 700 + - makedirs: True + +hydralogdir: + file.directory: + - name: /opt/so/log/hydra + - user: 928 + - group: 928 + - makedirs: True + +hydraconfig: + file.managed: + - name: /opt/so/conf/hydra/hydra.yaml + - source: salt://hydra/files/hydra.yaml.jinja + - user: 928 + - group: 928 + - mode: 600 + - template: jinja + - makedirs: True + - defaults: + HYDRAMERGED: {{ HYDRAMERGED }} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/hydra/defaults.yaml b/salt/hydra/defaults.yaml new file mode 100644 index 000000000..cbea72b97 --- /dev/null +++ b/salt/hydra/defaults.yaml @@ -0,0 +1,30 @@ +hydra: + enabled: False + config: + serve: + public: + port: 4444 + admin: + port: 4445 + urls: + self: + issuer: https://URL_BASE/connect + public: https://URL_BASE/connect + admin: http://localhost:4445 + + secrets: + system: [] + ttl: + access_token: 1h + oidc: + subject_identifiers: + supported_types: + - pairwise + - public + pairwise: + salt: "" + log: + level: debug + format: json + sqa: + opt_out: true \ No newline at end of file diff --git a/salt/mysql/disabled.sls b/salt/hydra/disabled.sls similarity index 88% rename from salt/mysql/disabled.sls rename to salt/hydra/disabled.sls index 805a755e4..c940a5bd6 100644 --- a/salt/mysql/disabled.sls +++ b/salt/hydra/disabled.sls @@ -7,16 +7,16 @@ {% if sls.split('.')[0] in allowed_states %} include: - - mysql.sostatus + - hydra.sostatus -so-mysql: +so-hydra: docker_container.absent: - force: True -so-mysql_so-status.disabled: +so-hydra_so-status.disabled: file.comment: - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-mysql$ + - regex: ^so-hydra$ {% else %} diff --git a/salt/hydra/enabled.sls b/salt/hydra/enabled.sls new file mode 100644 index 000000000..e0f03e184 --- /dev/null +++ b/salt/hydra/enabled.sls @@ -0,0 +1,103 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. +# +# Note: Per the Elastic License 2.0, the second limitation states: +# +# "You may not move, change, disable, or circumvent the license key functionality +# in the software, and you may not remove or obscure any functionality in the +# software that is protected by the license key." + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% if 'api' in salt['pillar.get']('features', []) %} + +include: + - hydra.config + - hydra.sostatus + +so-hydra: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-hydra:{{ GLOBALS.so_version }} + - hostname: hydra + - name: so-hydra + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-hydra'].ip }} + - binds: + - /opt/so/conf/hydra/:/hydra-conf:ro + - /opt/so/log/hydra/:/hydra-log:rw + - /nsm/hydra/db:/hydra-data:rw + {% if DOCKER.containers['so-hydra'].custom_bind_mounts %} + {% for BIND in DOCKER.containers['so-hydra'].custom_bind_mounts %} + - {{ BIND }} + {% endfor %} + {% endif %} + - port_bindings: + {% for BINDING in DOCKER.containers['so-hydra'].port_bindings %} + - {{ BINDING }} + {% endfor %} + {% if DOCKER.containers['so-hydra'].extra_hosts %} + - extra_hosts: + {% for XTRAHOST in DOCKER.containers['so-hydra'].extra_hosts %} + - {{ XTRAHOST }} + {% endfor %} + {% endif %} + {% if DOCKER.containers['so-hydra'].extra_env %} + - environment: + {% for XTRAENV in DOCKER.containers['so-hydra'].extra_env %} + - {{ XTRAENV }} + {% endfor %} + {% endif %} + - restart_policy: unless-stopped + - watch: + - file: hydraconfig + - require: + - file: hydraconfig + - file: hydralogdir + - file: hydradir + +delete_so-hydra_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-hydra$ + +wait_for_hydra: + http.wait_for_successful_query: + - name: 'http://{{ GLOBALS.manager }}:4444/' + - ssl: True + - verify_ssl: False + - status: + - 200 + - 301 + - 302 + - 404 + - status_type: list + - wait_for: 300 + - request_interval: 10 + - require: + - docker_container: so-hydra + +{% else %} + +{{sls}}_no_license_detected: + test.fail_without_changes: + - name: {{sls}}_no_license_detected + - comment: + - "This is a feature supported only for customers with a valid license. + Contact Security Onion Solutions, LLC via our website at https://securityonionsolutions.com + for more information about purchasing a license to enable this feature." +include: + - hydra.disabled +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/hydra/files/hydra.yaml.jinja b/salt/hydra/files/hydra.yaml.jinja new file mode 100644 index 000000000..fe6a33546 --- /dev/null +++ b/salt/hydra/files/hydra.yaml.jinja @@ -0,0 +1 @@ +{{ HYDRAMERGED.config | yaml(false) }} diff --git a/salt/mysql/init.sls b/salt/hydra/init.sls similarity index 74% rename from salt/mysql/init.sls rename to salt/hydra/init.sls index 48e4f558c..eb7792bca 100644 --- a/salt/mysql/init.sls +++ b/salt/hydra/init.sls @@ -1,14 +1,13 @@ - # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% from 'mysql/map.jinja' import MYSQLMERGED %} +{% from 'hydra/map.jinja' import HYDRAMERGED %} include: -{% if MYSQLMERGED.enabled %} - - mysql.enabled +{% if HYDRAMERGED.enabled %} + - hydra.enabled {% else %} - - mysql.disabled + - hydra.disabled {% endif %} diff --git a/salt/hydra/map.jinja b/salt/hydra/map.jinja new file mode 100644 index 000000000..81e92073e --- /dev/null +++ b/salt/hydra/map.jinja @@ -0,0 +1,13 @@ +{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one + or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at + https://securityonion.net/license; you may not use this file except in compliance with the + Elastic License 2.0. #} + +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% import_yaml 'hydra/defaults.yaml' as HYDRADEFAULTS %} + +{% do HYDRADEFAULTS.hydra.config.urls.self.update({'issuer': HYDRADEFAULTS.hydra.config.urls.self.issuer | replace("URL_BASE", GLOBALS.url_base)}) %} +{% do HYDRADEFAULTS.hydra.config.urls.self.update({'public': HYDRADEFAULTS.hydra.config.urls.self.public | replace("URL_BASE", GLOBALS.url_base)}) %} +{% do HYDRADEFAULTS.hydra.config.urls.self.update({'admin': HYDRADEFAULTS.hydra.config.urls.self.admin | replace("URL_BASE", GLOBALS.url_base)}) %} + +{% set HYDRAMERGED = salt['pillar.get']('hydra', default=HYDRADEFAULTS.hydra, merge=true) %} \ No newline at end of file diff --git a/salt/hydra/soc_hydra.yaml b/salt/hydra/soc_hydra.yaml new file mode 100644 index 000000000..40e07ab1b --- /dev/null +++ b/salt/hydra/soc_hydra.yaml @@ -0,0 +1,29 @@ +hydra: + enabled: + description: Enables or disables the API authentication system, used for service account authentication. Enabling this feature requires a valid Security Onion license key. Defaults to False. + helpLink: connect.html + global: True + config: + ttl: + access_token: + description: Amount of time that the generated access token will be valid. Specified in the form of 2h, which means 2 hours. + global: True + forcedType: string + helpLink: connect.html + log: + level: + description: Log level to use for Kratos logs. + global: True + helpLink: connect.html + format: + description: Log output format for Kratos logs. + global: True + helpLink: connect.html + secrets: + system: + description: Secrets used for token generation. Generated during installation. + global: True + sensitive: True + advanced: True + forcedType: "[]string" + helpLink: connect.html diff --git a/salt/mysql/sostatus.sls b/salt/hydra/sostatus.sls similarity index 83% rename from salt/mysql/sostatus.sls rename to salt/hydra/sostatus.sls index 2f5dbba06..8878bed4f 100644 --- a/salt/mysql/sostatus.sls +++ b/salt/hydra/sostatus.sls @@ -6,11 +6,11 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} -append_so-mysql_so-status.conf: +append_so-hydra_so-status.conf: file.append: - name: /opt/so/conf/so-status/so-status.conf - - text: so-mysql - - unless: grep -q so-mysql /opt/so/conf/so-status/so-status.conf + - text: so-hydra + - unless: grep -q so-hydra /opt/so/conf/so-status/so-status.conf {% else %} diff --git a/salt/hypervisor/defaults.yaml b/salt/hypervisor/defaults.yaml new file mode 100644 index 000000000..06509828c --- /dev/null +++ b/salt/hypervisor/defaults.yaml @@ -0,0 +1,58 @@ +hypervisor: + model: + testModel: + hardware: + cpu: 128 + memory: 128 + disk: + 1: pci_0000_c7_00_0 + 2: pci_0000_c8_00_0 + copper: + 1: pci_0000_c4_00_0 + 2: pci_0000_c4_00_1 + 3: pci_0000_c4_00_2 + 4: pci_0000_c4_00_3 + sfp: + 5: pci_0000_02_00_0 + 6: pci_0000_02_00_1 + 7: pci_0000_41_00_0 + 8: pci_0000_41_00_1 + model1: + hardware: + cpu: 128 + memory: 128 + disk: + 1: pci_0000_c7_00_0 + 2: pci_0000_c8_00_0 + copper: + 1: pci_0000_c4_00_0 + 2: pci_0000_c4_00_1 + 3: pci_0000_c4_00_2 + 4: pci_0000_c4_00_3 + sfp: + 5: pci_0000_02_00_0 + 6: pci_0000_02_00_1 + 7: pci_0000_41_00_0 + 8: pci_0000_41_00_1 + model2: + cpu: 256 + memory: 256 + disk: + 1: pci_0000_c7_00_0 + 2: pci_0000_c8_00_0 + 3: pci_0000_c9_00_0 + 4: pci_0000_c10_00_0 + copper: + 1: pci_0000_c4_00_0 + 2: pci_0000_c4_00_1 + 3: pci_0000_c4_00_2 + 4: pci_0000_c4_00_3 + 5: pci_0000_c5_00_0 + 6: pci_0000_c5_00_1 + 7: pci_0000_c5_00_2 + 8: pci_0000_c5_00_3 + sfp: + 9: pci_0000_02_00_0 + 10: pci_0000_02_00_1 + 11: pci_0000_41_00_0 + 12: pci_0000_41_00_1 \ No newline at end of file diff --git a/salt/hypervisor/hosts/README b/salt/hypervisor/hosts/README new file mode 100644 index 000000000..406fd0bec --- /dev/null +++ b/salt/hypervisor/hosts/README @@ -0,0 +1 @@ +This directory will contain hypervisor hosts. We need this README in place to ensure /opt/so/saltstack/local/salt/hypervisor/hosts directory gets created during setup. diff --git a/salt/hypervisor/init.sls b/salt/hypervisor/init.sls new file mode 100644 index 000000000..4a2edad75 --- /dev/null +++ b/salt/hypervisor/init.sls @@ -0,0 +1,49 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. +# +# Note: Per the Elastic License 2.0, the second limitation states: +# +# "You may not move, change, disable, or circumvent the license key functionality +# in the software, and you may not remove or obscure any functionality in the +# software that is protected by the license key." + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls in allowed_states %} +{% if 'vrt' in salt['pillar.get']('features', []) %} + +hypervisor_log_dir: + file.directory: + - name: /opt/so/log/hypervisor + +hypervisor_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://hypervisor/tools/sbin + - file_mode: 744 + +hypervisor_sbin_jinja: + file.recurse: + - name: /usr/sbin + - source: salt://hypervisor/tools/sbin_jinja + - template: jinja + - file_mode: 744 + +{% else %} +{{sls}}_no_license_detected: + test.fail_without_changes: + - name: {{sls}}_no_license_detected + - comment: + - "Hypervisor nodes are a feature supported only for customers with a valid license. + Contact Security Onion Solutions, LLC via our website at https://securityonionsolutions.com + for more information about purchasing a license to enable this feature." +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/hypervisor/map.jinja b/salt/hypervisor/map.jinja new file mode 100644 index 000000000..dae3985d4 --- /dev/null +++ b/salt/hypervisor/map.jinja @@ -0,0 +1,164 @@ +{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one + or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at + https://securityonion.net/license; you may not use this file except in compliance with the + Elastic License 2.0. + + Note: Per the Elastic License 2.0, the second limitation states: + + "You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key." #} + +{% if 'vrt' in salt['pillar.get']('features', []) %} + +{# Import defaults.yaml for model hardware capabilities #} +{% import_yaml 'hypervisor/defaults.yaml' as DEFAULTS %} + +{# Get hypervisor nodes from pillar #} +{% set NODES = salt['pillar.get']('hypervisor:nodes', {}) %} + +{# Build enhanced HYPERVISORS structure #} +{% set HYPERVISORS = {} %} +{% do salt.log.debug('salt/hypervisor/map.jinja: NODES content: ' ~ NODES | tojson) %} +{% for role, hypervisors in NODES.items() %} + {% do salt.log.debug('salt/hypervisor/map.jinja: Processing role: ' ~ role) %} + {% do HYPERVISORS.update({role: {}}) %} + {% for hypervisor, config in hypervisors.items() %} + {% do salt.log.debug('salt/hypervisor/map.jinja: Processing hypervisor: ' ~ hypervisor ~ ' with config: ' ~ config | tojson) %} + {# Get model from cached grains using Salt runner #} + {% set grains = salt.saltutil.runner('cache.grains', tgt=hypervisor ~ '_*', tgt_type='glob') %} + {% set model = '' %} + {% if grains %} + {% set minion_id = grains.keys() | first %} + {% set model = grains[minion_id].get('sosmodel', '') %} + {% endif %} + {% set model_config = DEFAULTS.hypervisor.model.get(model, {}) %} + + {# Get VM list from VMs file #} + {% set vms = {} %} + {% set vm_list = [] %} + {% set vm_list_file = 'hypervisor/hosts/' ~ hypervisor ~ 'VMs' %} + {% do salt.log.debug('salt/hypervisor/map.jinja: VM list file: ' ~ vm_list_file) %} + {% if salt['file.file_exists']('/opt/so/saltstack/local/salt/' ~ vm_list_file) %} + {% import_json vm_list_file as vm_list %} + {% endif %} + {% if vm_list %} + {% do salt.log.debug('salt/hypervisor/map.jinja: VM list content: ' ~ vm_list | tojson) %} + {% else %} + {# we won't get here if the vm_list_file doesn't exist because we will get TemplateNotFound on the import_json #} + {% do salt.log.debug('salt/hypervisor/map.jinja: VM list empty: ' ~ vm_list_file) %} + {% endif %} + + {# Load status and configuration for each VM #} + {% for vm in vm_list %} + {# Get VM details from list entry #} + {% set hostname = vm.get('hostname', '') %} + {% set role = vm.get('role', '') %} + {% do salt.log.debug('salt/hypervisor/map.jinja: Processing VM - hostname: ' ~ hostname ~ ', role: ' ~ role) %} + + {# Load VM configuration from config file #} + {% set vm_file = 'hypervisor/hosts/' ~ hypervisor ~ '/' ~ hostname ~ '_' ~ role %} + {% do salt.log.debug('salt/hypervisor/map.jinja: VM config file: ' ~ vm_file) %} + {% import_json vm_file as vm_state %} + {% if vm_state %} + {% do salt.log.debug('salt/hypervisor/map.jinja: VM config content: ' ~ vm_state | tojson) %} + {% set vm_data = {'config': vm_state.config} %} + + {# Load VM status from status file #} + {% set status_file = vm_file ~ '.status' %} + {% do salt.log.debug('salt/hypervisor/map.jinja: VM status file: ' ~ status_file) %} + {% import_json status_file as status_data %} + {% if status_data %} + {% do salt.log.debug('salt/hypervisor/map.jinja: VM status content: ' ~ status_data | tojson) %} + {% do vm_data.update({'status': status_data}) %} + {% else %} + {% do salt.log.debug('salt/hypervisor/map.jinja: Status file empty: ' ~ status_file) %} + {% do vm_data.update({ + 'status': { + 'status': '', + 'details': null, + 'timestamp': '' + } + }) %} + {% endif %} + {% do vms.update({hostname ~ '_' ~ role: vm_data}) %} + {% else %} + {% do salt.log.debug('salt/hypervisor/map.jinja: Config file empty: ' ~ vm_file) %} + {% endif %} + {% endfor %} + + {# Find and add destroyed VMs from status files #} + {% set processed_vms = [] %} + {% for vm_full_name, vm_data in vms.items() %} + {% do processed_vms.append(vm_full_name) %} + {% endfor %} + + {# Find all status files for this hypervisor #} + {% set relative_path = 'hypervisor/hosts/' ~ hypervisor %} + {% set absolute_path = '/opt/so/saltstack/local/salt/' ~ relative_path %} + {% do salt.log.debug('salt/hypervisor/map.jinja: Scanning for status files in: ' ~ absolute_path) %} + + {# Try to find status files using file.find with absolute path #} + {% set status_files = salt['file.find'](absolute_path, name='*_*.status', type='f') %} + {% do salt.log.debug('salt/hypervisor/map.jinja: Found status files: ' ~ status_files | tojson) %} + + {# Convert absolute paths back to relative paths for processing #} + {% set relative_status_files = [] %} + {% for status_file in status_files %} + {% set relative_file = status_file | replace('/opt/so/saltstack/local/salt/', '') %} + {% do relative_status_files.append(relative_file) %} + {% endfor %} + {% set status_files = relative_status_files %} + + {% do salt.log.debug('salt/hypervisor/map.jinja: Converted to relative paths: ' ~ status_files | tojson) %} + + {% for status_file in status_files %} + {# Extract the VM name from the filename #} + {% set basename = status_file.split('/')[-1] %} + {% set vm_name = basename.replace('.status', '') %} + {% set hostname = vm_name.split('_')[0] %} + + {# Skip already processed VMs #} + {% if vm_name in processed_vms %} + {% continue %} + {% endif %} + + {# Read the status file #} + {% do salt.log.debug('salt/hypervisor/map.jinja: Processing potential destroyed VM status file: ' ~ status_file) %} + {% import_json status_file as status_data %} + + {# Only process files with "Destroyed Instance" status #} + {% if status_data and status_data.status == 'Destroyed Instance' %} + {% do salt.log.debug('salt/hypervisor/map.jinja: Found VM with Destroyed Instance status: ' ~ vm_name) %} + + {# Add to vms with minimal config #} + {% do vms.update({ + vm_name: { + 'status': status_data, + 'config': {} + } + }) %} + {% endif %} + {% endfor %} + + {# Merge node config with model capabilities and VM states #} + {% do HYPERVISORS[role].update({ + hypervisor: { + 'config': config, + 'model': model, + 'hardware': model_config.get('hardware', {}), + 'vms': vms + } + }) %} + {% endfor %} +{% endfor %} + +{% else %} + +{% do salt.log.error( + 'Hypervisor nodes are a feature supported only for customers with a valid license.' + 'Contact Security Onion Solutions, LLC via our website at https://securityonionsolutions.com' + 'for more information about purchasing a license to enable this feature.' +) %} + +{% endif %} diff --git a/salt/hypervisor/tools/sbin/so-nvme-raid1.sh b/salt/hypervisor/tools/sbin/so-nvme-raid1.sh new file mode 100644 index 000000000..79ccbb33c --- /dev/null +++ b/salt/hypervisor/tools/sbin/so-nvme-raid1.sh @@ -0,0 +1,221 @@ +#!/bin/bash + +################################################################# +# RAID-1 Setup Script for NVMe Drives +################################################################# +# +# DESCRIPTION: +# This script automatically sets up a RAID-1 (mirrored) array using two NVMe drives +# (/dev/nvme0n1 and /dev/nvme1n1) and mounts it at /nsm with XFS filesystem. +# +# FUNCTIONALITY: +# - Detects and reports existing RAID configurations +# - Thoroughly cleans target drives of any existing data/configurations +# - Creates GPT partition tables with RAID-type partitions +# - Establishes RAID-1 array (/dev/md0) for data redundancy +# - Formats the array with XFS filesystem for performance +# - Automatically mounts at /nsm and configures for boot persistence +# - Provides monitoring information for resync operations +# +# SAFETY FEATURES: +# - Requires root privileges +# - Exits gracefully if RAID already exists and is mounted +# - Performs comprehensive cleanup to avoid conflicts +# - Forces partition table updates and waits for system recognition +# +# PREREQUISITES: +# - Two NVMe drives: /dev/nvme0n1 and /dev/nvme1n1 +# - Root access +# - mdadm, sgdisk, and standard Linux utilities +# +# WARNING: This script will DESTROY all data on the target drives! +# +# USAGE: sudo ./raid_setup.sh +# +################################################################# + +# Exit on any error +set -e + +# Function to log messages +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" +} + +# Function to check if running as root +check_root() { + if [ "$EUID" -ne 0 ]; then + log "Error: Please run as root" + exit 1 + fi +} + +# Function to check if RAID is already set up +check_existing_raid() { + if [ -e "/dev/md0" ]; then + if mdadm --detail /dev/md0 &>/dev/null; then + local raid_state=$(mdadm --detail /dev/md0 | grep "State" | awk '{print $3}') + local mount_point="/nsm" + + log "Found existing RAID array /dev/md0 (State: $raid_state)" + + if mountpoint -q "$mount_point"; then + log "RAID is already mounted at $mount_point" + log "Current RAID details:" + mdadm --detail /dev/md0 + + # Check if resyncing + if grep -q "resync" /proc/mdstat; then + log "RAID is currently resyncing:" + grep resync /proc/mdstat + log "You can monitor progress with: watch -n 60 cat /proc/mdstat" + else + log "RAID is fully synced and operational" + fi + + # Show disk usage + log "Current disk usage:" + df -h "$mount_point" + + exit 0 + fi + fi + fi + + # Check if any of the target devices are in use + for device in "/dev/nvme0n1" "/dev/nvme1n1"; do + if lsblk -o NAME,MOUNTPOINT "$device" | grep -q "nsm"; then + log "Error: $device is already mounted at /nsm" + exit 1 + fi + + if mdadm --examine "$device" &>/dev/null || mdadm --examine "${device}p1" &>/dev/null; then + log "Error: $device appears to be part of an existing RAID array" + log "To reuse this device, you must first:" + log "1. Unmount any filesystems" + log "2. Stop the RAID array: mdadm --stop /dev/md0" + log "3. Zero the superblock: mdadm --zero-superblock ${device}p1" + exit 1 + fi + done +} + +# Function to ensure devices are not in use +ensure_devices_free() { + local device=$1 + + log "Cleaning up device $device" + + # Kill any processes using the device + fuser -k "${device}"* 2>/dev/null || true + + # Force unmount any partitions + for part in "${device}"*; do + if mount | grep -q "$part"; then + umount -f "$part" 2>/dev/null || true + fi + done + + # Stop any MD arrays using this device + for md in $(ls /dev/md* 2>/dev/null || true); do + if mdadm --detail "$md" 2>/dev/null | grep -q "$device"; then + mdadm --stop "$md" 2>/dev/null || true + fi + done + + # Clear MD superblock + mdadm --zero-superblock "${device}"* 2>/dev/null || true + + # Remove LVM PV if exists + pvremove -ff -y "$device" 2>/dev/null || true + + # Clear all signatures + wipefs -af "$device" 2>/dev/null || true + + # Delete partition table + dd if=/dev/zero of="$device" bs=512 count=2048 2>/dev/null || true + dd if=/dev/zero of="$device" bs=512 seek=$(( $(blockdev --getsz "$device") - 2048 )) count=2048 2>/dev/null || true + + # Force kernel to reread + blockdev --rereadpt "$device" 2>/dev/null || true + partprobe -s "$device" 2>/dev/null || true + sleep 2 +} + +# Main script +main() { + log "Starting RAID setup script" + + # Check if running as root + check_root + + # Check for existing RAID setup + check_existing_raid + + # Clean up any existing MD arrays + log "Cleaning up existing MD arrays" + mdadm --stop --scan 2>/dev/null || true + + # Clear mdadm configuration + log "Clearing mdadm configuration" + echo "DEVICE partitions" > /etc/mdadm.conf + + # Clean and prepare devices + for device in "/dev/nvme0n1" "/dev/nvme1n1"; do + ensure_devices_free "$device" + + log "Creating new partition table on $device" + sgdisk -Z "$device" + sgdisk -o "$device" + + log "Creating RAID partition" + sgdisk -n 1:0:0 -t 1:fd00 "$device" + + partprobe "$device" + udevadm settle + sleep 5 + done + + log "Final verification of partition availability" + if ! [ -b "/dev/nvme0n1p1" ] || ! [ -b "/dev/nvme1n1p1" ]; then + log "Error: Partitions not available after creation" + exit 1 + fi + + log "Creating RAID array" + mdadm --create /dev/md0 --level=1 --raid-devices=2 \ + --metadata=1.2 \ + /dev/nvme0n1p1 /dev/nvme1n1p1 \ + --force --run + + log "Creating XFS filesystem" + mkfs.xfs -f /dev/md0 + + log "Creating mount point" + mkdir -p /nsm + + log "Updating fstab" + sed -i '/\/dev\/md0/d' /etc/fstab + echo "/dev/md0 /nsm xfs defaults,nofail 0 0" >> /etc/fstab + + log "Reloading systemd daemon" + systemctl daemon-reload + + log "Mounting filesystem" + mount -a + + log "Saving RAID configuration" + mdadm --detail --scan > /etc/mdadm.conf + + log "RAID setup complete" + log "RAID array details:" + mdadm --detail /dev/md0 + + if grep -q "resync" /proc/mdstat; then + log "RAID is currently resyncing. You can monitor progress with:" + log "watch -n 60 cat /proc/mdstat" + fi +} + +# Run main function +main "$@" diff --git a/salt/hypervisor/tools/sbin/so-qcow2-network-predictable b/salt/hypervisor/tools/sbin/so-qcow2-network-predictable new file mode 100644 index 000000000..64ec53953 --- /dev/null +++ b/salt/hypervisor/tools/sbin/so-qcow2-network-predictable @@ -0,0 +1,424 @@ +#!/usr/bin/python3 + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +""" +Script for configuring network interface predictability in Security Onion VMs. +This script modifies the necessary files to ensure consistent network interface naming. + +The script performs the following operations: +1. Modifies the BLS entry to set net.ifnames=1 +2. Removes any existing persistent network rules +3. Updates GRUB configuration + +**Usage:** + so-qcow2-network-predictable -n [-I ] + +**Options:** + -n, --name Domain name of the VM to configure + -I, --image (Optional) Path to the QCOW2 image. If not provided, + defaults to /nsm/libvirt/images//.qcow2 + +**Examples:** + +1. **Configure using domain name:** + ```bash + so-qcow2-network-predictable -n sool9 + ``` + This command will: + - Use default image path: /nsm/libvirt/images/sool9/sool9.qcow2 + - Configure network interface predictability + +2. **Configure using custom image path:** + ```bash + so-qcow2-network-predictable -n sool9 -I /path/to/custom/image.qcow2 + ``` + This command will: + - Use the specified image path + - Configure network interface predictability + +**Notes:** +- The VM must not be running when executing this script +- Requires root privileges +- Will automatically find and modify the appropriate BLS entry +- Removes /etc/udev/rules.d/70-persistent-net.rules if it exists +- Updates GRUB configuration after changes + +**Exit Codes:** +- 0: Success +- 1: General error (invalid arguments, file operations, etc.) +- 2: VM is running +- 3: Required files not found +- 4: Permission denied + +**Logging:** +- Logs are written to /opt/so/log/hypervisor/so-qcow2-network-predictable.log +- Both file and console logging are enabled +- Log entries include: + - Timestamps + - Operation details + - Error messages + - Configuration changes +""" + +import argparse +import guestfs +import glob +import libvirt +import logging +import os +import re +import sys +from so_logging_utils import setup_logging + +# Set up logging +logger = setup_logging( + logger_name='so-qcow2-network-predictable', + log_file_path='/opt/so/log/hypervisor/so-qcow2-network-predictable.log', + log_level=logging.INFO, + format_str='%(asctime)s - %(levelname)s - %(message)s' +) + +def check_domain_status(domain_name): + """ + Check if the specified domain exists and is not running. + + Args: + domain_name (str): Name of the libvirt domain to check + + Returns: + bool: True if domain exists and is not running, False otherwise + + Raises: + RuntimeError: If domain is running or connection to libvirt fails + """ + try: + conn = libvirt.open('qemu:///system') + try: + dom = conn.lookupByName(domain_name) + is_running = dom.isActive() + if is_running: + logger.error(f"Domain '{domain_name}' is running - cannot modify configuration") + raise RuntimeError(f"Domain '{domain_name}' must not be running") + logger.info(f"Domain '{domain_name}' exists and is not running") + return True + except libvirt.libvirtError as e: + if "no domain with matching name" in str(e): + logger.error(f"Domain '{domain_name}' not found") + raise RuntimeError(f"Domain '{domain_name}' not found") + raise + finally: + conn.close() + except libvirt.libvirtError as e: + logger.error(f"Failed to connect to libvirt: {e}") + raise RuntimeError(f"Failed to connect to libvirt: {e}") + +def modify_bls_entry(g): + """ + Find and modify the BLS entry to set net.ifnames=1. + + Args: + g: Mounted guestfs handle + + Returns: + bool: True if successful, False if no changes needed + + Raises: + RuntimeError: If BLS entry cannot be found or modified + """ + bls_dir = "/boot/loader/entries" + logger.info(f"Checking BLS directory: {bls_dir}") + if g.is_dir(bls_dir): + logger.info("BLS directory exists") + else: + logger.info("Listing /boot contents:") + try: + boot_contents = g.ls("/boot") + logger.info(f"/boot contains: {boot_contents}") + if g.is_dir("/boot/loader"): + logger.info("Listing /boot/loader contents:") + loader_contents = g.ls("/boot/loader") + logger.info(f"/boot/loader contains: {loader_contents}") + except Exception as e: + logger.error(f"Error listing /boot contents: {e}") + raise RuntimeError(f"BLS directory not found: {bls_dir}") + + # Find BLS entry file + entries = g.glob_expand(f"{bls_dir}/*.conf") + logger.info(f"Found BLS entries: {entries}") + if not entries: + logger.error("No BLS entry files found") + raise RuntimeError("No BLS entry files found") + + # Use the first entry found + bls_file = entries[0] + logger.info(f"Found BLS entry file: {bls_file}") + + try: + logger.info(f"Reading BLS file contents from: {bls_file}") + content = g.read_file(bls_file).decode('utf-8') + logger.info("Current BLS file content:") + logger.info("---BEGIN BLS CONTENT---") + logger.info(content) + logger.info("---END BLS CONTENT---") + + lines = content.splitlines() + modified = False + + for i, line in enumerate(lines): + if line.startswith('options '): + logger.info(f"Found options line: {line}") + + # First remove any existing net.ifnames parameters (both =0 and =1) + new_line = re.sub(r'\s*net\.ifnames=[01]\s*', ' ', line) + # Also remove any quoted versions + new_line = re.sub(r'\s*"net\.ifnames=[01]"\s*', ' ', new_line) + # Clean up multiple spaces + new_line = re.sub(r'\s+', ' ', new_line).strip() + + # Now add net.ifnames=1 at the end + new_line = f"{new_line} net.ifnames=1" + + if new_line != line: + lines[i] = new_line + modified = True + logger.info(f"Updated options line. New line: {new_line}") + break + + if modified: + new_content = '\n'.join(lines) + '\n' + logger.info("New BLS file content:") + logger.info("---BEGIN NEW BLS CONTENT---") + logger.info(new_content) + logger.info("---END NEW BLS CONTENT---") + g.write(bls_file, new_content.encode('utf-8')) + logger.info("Successfully updated BLS entry") + return True + + logger.info("No changes needed for BLS entry") + return False + + except Exception as e: + logger.error(f"Failed to modify BLS entry: {e}") + raise RuntimeError(f"Failed to modify BLS entry: {e}") + +def remove_persistent_net_rules(g): + """ + Remove the persistent network rules file if it exists. + + Args: + g: Mounted guestfs handle + + Returns: + bool: True if file was removed, False if it didn't exist + """ + rules_file = "/etc/udev/rules.d/70-persistent-net.rules" + logger.info(f"Checking for persistent network rules file: {rules_file}") + try: + if g.is_file(rules_file): + logger.info("Found persistent network rules file, removing...") + g.rm(rules_file) + logger.info(f"Successfully removed persistent network rules file: {rules_file}") + return True + logger.info("No persistent network rules file found") + return False + except Exception as e: + logger.error(f"Failed to remove persistent network rules: {e}") + raise RuntimeError(f"Failed to remove persistent network rules: {e}") + +def update_grub_config(g): + """ + Update GRUB configuration. + + Args: + g: Mounted guestfs handle + + Raises: + RuntimeError: If GRUB update fails + """ + try: + # First, read the current grubenv to get the existing kernelopts + logger.info("Reading current grubenv...") + grubenv_content = g.read_file('/boot/grub2/grubenv').decode('utf-8') + logger.info("Current grubenv content:") + logger.info(grubenv_content) + + # Extract current kernelopts + kernelopts_match = re.search(r'^kernelopts="([^"]+)"', grubenv_content, re.MULTILINE) + if kernelopts_match: + current_kernelopts = kernelopts_match.group(1) + logger.info(f"Current kernelopts: {current_kernelopts}") + + # Remove any existing net.ifnames parameters + new_kernelopts = re.sub(r'\s*net\.ifnames=[01]\s*', ' ', current_kernelopts) + # Clean up multiple spaces + new_kernelopts = re.sub(r'\s+', ' ', new_kernelopts).strip() + # Add net.ifnames=1 + new_kernelopts = f"{new_kernelopts} net.ifnames=1" + + logger.info(f"New kernelopts: {new_kernelopts}") + + # Update grubenv with the new kernelopts + logger.info("Setting kernelopts with net.ifnames=1...") + output_editenv = g.command(['grub2-editenv', '-', 'set', f'kernelopts={new_kernelopts}']) + logger.info("grub2-editenv output:") + logger.info(output_editenv) + else: + # If we can't find existing kernelopts, use the default + logger.warning("Could not find existing kernelopts, using default") + output_editenv = g.command(['grub2-editenv', '-', 'set', 'kernelopts=console=tty0 no_timer_check biosdevname=0 resume=/dev/mapper/vg_main-lv_swap rd.lvm.lv=vg_main/lv_root rd.lvm.lv=vg_main/lv_swap net.ifnames=1 crashkernel=1G-64G:448M,64G-:512M']) + logger.info("grub2-editenv output:") + logger.info(output_editenv) + + logger.info("Updating grubby with net.ifnames=1...") + # First remove any existing net.ifnames arguments + output_grubby_remove = g.command(['grubby', '--update-kernel=ALL', '--remove-args=net.ifnames=0 net.ifnames=1']) + logger.info("grubby remove output:") + logger.info(output_grubby_remove) + + # Then add net.ifnames=1 + output_grubby_add = g.command(['grubby', '--update-kernel=ALL', '--args=net.ifnames=1']) + logger.info("grubby add output:") + logger.info(output_grubby_add) + + logger.info("Updating GRUB configuration...") + output_mkconfig = g.command(['grub2-mkconfig', '-o', '/boot/grub2/grub.cfg']) + logger.info("GRUB update output:") + logger.info(output_mkconfig) + logger.info("Successfully updated GRUB configuration") + except Exception as e: + logger.error(f"Failed to update GRUB configuration: {e}") + raise RuntimeError(f"Failed to update GRUB configuration: {e}") + +def configure_network_predictability(domain_name, image_path=None): + """ + Configure network interface predictability for a VM. + + Args: + domain_name (str): Name of the domain to configure + image_path (str, optional): Path to the QCOW2 image + + Raises: + RuntimeError: If configuration fails + """ + # Check domain status + check_domain_status(domain_name) + + # Use default image path if none provided + if not image_path: + image_path = f"/nsm/libvirt/images/{domain_name}/{domain_name}.qcow2" + + if not os.path.exists(image_path): + logger.error(f"Image file not found: {image_path}") + raise RuntimeError(f"Image file not found: {image_path}") + + if not os.access(image_path, os.R_OK | os.W_OK): + logger.error(f"Permission denied: Cannot access image file {image_path}") + raise RuntimeError(f"Permission denied: Cannot access image file {image_path}") + + logger.info(f"Configuring network predictability for domain: {domain_name}") + logger.info(f"Using image: {image_path}") + + g = guestfs.GuestFS(python_return_dict=True) + try: + logger.info("Initializing guestfs...") + g.set_network(False) + g.selinux = False + g.add_drive_opts(image_path, format="qcow2") + g.launch() + + logger.info("Inspecting operating system...") + roots = g.inspect_os() + if not roots: + raise RuntimeError("No operating system found in image") + + root = roots[0] + logger.info(f"Found root filesystem: {root}") + logger.info(f"Operating system type: {g.inspect_get_type(root)}") + logger.info(f"Operating system distro: {g.inspect_get_distro(root)}") + logger.info(f"Operating system major version: {g.inspect_get_major_version(root)}") + logger.info(f"Operating system minor version: {g.inspect_get_minor_version(root)}") + + logger.info("Getting mount points...") + mountpoints = g.inspect_get_mountpoints(root) + logger.info(f"Found mount points: {mountpoints}") + logger.info("Converting mount points to sortable list...") + # Convert dictionary to list of tuples + mountpoints = list(mountpoints.items()) + logger.info(f"Converted mount points: {mountpoints}") + logger.info("Sorting mount points by path length for proper mount order...") + mountpoints.sort(key=lambda m: len(m[0])) + logger.info(f"Mount order will be: {[mp[0] for mp in mountpoints]}") + + for mp_path, mp_device in mountpoints: + try: + logger.info(f"Attempting to mount {mp_device} at {mp_path}") + g.mount(mp_device, mp_path) + logger.info(f"Successfully mounted {mp_device} at {mp_path}") + except Exception as e: + logger.warning(f"Could not mount {mp_device} at {mp_path}: {str(e)}") + # Continue with other mounts + + # Perform configuration steps + bls_modified = modify_bls_entry(g) + rules_removed = remove_persistent_net_rules(g) + + if bls_modified or rules_removed: + update_grub_config(g) + logger.info("Network predictability configuration completed successfully") + else: + logger.info("No changes were necessary") + + except Exception as e: + raise RuntimeError(f"Failed to configure network predictability: {e}") + finally: + try: + logger.info("Unmounting all filesystems...") + g.umount_all() + logger.info("Successfully unmounted all filesystems") + except Exception as e: + logger.warning(f"Error unmounting filesystems: {e}") + g.close() + +def parse_arguments(): + """Parse command line arguments.""" + parser = argparse.ArgumentParser( + description="Configure network interface predictability for Security Onion VMs" + ) + parser.add_argument("-n", "--name", required=True, + help="Domain name of the VM to configure") + parser.add_argument("-I", "--image", + help="Path to the QCOW2 image (optional)") + return parser.parse_args() + +def main(): + """Main entry point for the script.""" + try: + args = parse_arguments() + configure_network_predictability(args.name, args.image) + sys.exit(0) + except RuntimeError as e: + if "must not be running" in str(e): + logger.error(str(e)) + sys.exit(2) + elif "not found" in str(e): + logger.error(str(e)) + sys.exit(3) + elif "Permission denied" in str(e): + logger.error(str(e)) + sys.exit(4) + else: + logger.error(str(e)) + sys.exit(1) + except KeyboardInterrupt: + logger.error("Operation cancelled by user") + sys.exit(1) + except Exception as e: + logger.error(f"Unexpected error: {e}") + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/salt/hypervisor/tools/sbin/so-wait-cloud-init b/salt/hypervisor/tools/sbin/so-wait-cloud-init new file mode 100644 index 000000000..322b89208 --- /dev/null +++ b/salt/hypervisor/tools/sbin/so-wait-cloud-init @@ -0,0 +1,206 @@ +#!/usr/bin/python3 + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +""" +Script for waiting for cloud-init to complete on a Security Onion VM. +Monitors VM state to ensure proper cloud-init initialization and shutdown. + +**Usage:** + so-wait-cloud-init -n + +**Options:** + -n, --name Domain name of the VM to monitor + +**Exit Codes:** +- 0: Success (cloud-init completed and VM shutdown) +- 1: General error +- 2: VM never started +- 3: VM stopped too quickly +- 4: VM failed to shutdown + +**Description:** +This script monitors a VM's state to ensure proper cloud-init initialization and completion: +1. Waits for VM to start running +2. Verifies VM remains running (not an immediate crash) +3. Waits for VM to shutdown (indicating cloud-init completion) +4. Verifies VM remains shutdown + +The script is typically used in the libvirt.images state after creating a new VM +to ensure cloud-init completes its initialization before proceeding with further +configuration. + +**Logging:** +- Logs are written to /opt/so/log/hypervisor/so-wait-cloud-init.log +- Both file and console logging are enabled +- Log entries include: + - Timestamps + - State changes + - Error conditions + - Verification steps +""" + +import argparse +import logging +import subprocess +import sys +import time +from so_logging_utils import setup_logging + +# Set up logging +logger = setup_logging( + logger_name='so-wait-cloud-init', + log_file_path='/opt/so/log/hypervisor/so-wait-cloud-init.log', + log_level=logging.INFO, + format_str='%(asctime)s - %(levelname)s - %(message)s' +) + +def check_vm_running(domain_name): + """ + Check if VM is in running state. + + Args: + domain_name (str): Name of the domain to check + + Returns: + bool: True if VM is running, False otherwise + """ + try: + result = subprocess.run(['virsh', 'list', '--state-running', '--name'], + capture_output=True, text=True, check=True) + return domain_name in result.stdout.splitlines() + except subprocess.CalledProcessError as e: + logger.error(f"Failed to check VM state: {e}") + return False + +def wait_for_vm_start(domain_name, timeout=300): + """ + Wait for VM to start running. + + Args: + domain_name (str): Name of the domain to monitor + timeout (int): Maximum time to wait in seconds + + Returns: + bool: True if VM started, False if timeout occurred + """ + logger.info(f"Waiting for VM {domain_name} to start...") + start_time = time.time() + + while time.time() - start_time < timeout: + if check_vm_running(domain_name): + logger.info("VM is running") + return True + time.sleep(1) + + logger.error(f"Timeout waiting for VM {domain_name} to start") + return False + +def verify_vm_running(domain_name): + """ + Verify VM remains running after initial start. + + Args: + domain_name (str): Name of the domain to verify + + Returns: + bool: True if VM is still running after verification period + """ + logger.info("Verifying VM remains running...") + time.sleep(5) # Wait to ensure VM is stable + + if not check_vm_running(domain_name): + logger.error("VM stopped too quickly after starting") + return False + + logger.info("VM verified running") + return True + +def wait_for_vm_shutdown(domain_name, timeout=600): + """ + Wait for VM to shutdown. + + Args: + domain_name (str): Name of the domain to monitor + timeout (int): Maximum time to wait in seconds + + Returns: + bool: True if VM shutdown, False if timeout occurred + """ + logger.info("Waiting for cloud-init to complete and VM to shutdown...") + start_time = time.time() + check_count = 0 + + while time.time() - start_time < timeout: + if not check_vm_running(domain_name): + logger.info("VM has shutdown") + return True + + # Log status every minute (after 12 checks at 5 second intervals) + check_count += 1 + if check_count % 12 == 0: + elapsed = int(time.time() - start_time) + logger.info(f"Still waiting for cloud-init... ({elapsed} seconds elapsed)") + + time.sleep(5) + + logger.error(f"Timeout waiting for VM {domain_name} to shutdown") + return False + +def verify_vm_shutdown(domain_name): + """ + Verify VM remains shutdown. + + Args: + domain_name (str): Name of the domain to verify + + Returns: + bool: True if VM remains shutdown after verification period + """ + logger.info("Verifying VM remains shutdown...") + time.sleep(5) # Wait to ensure VM state is stable + + if check_vm_running(domain_name): + logger.error("VM is still running after shutdown check") + return False + + logger.info("VM verified shutdown") + return True + +def main(): + parser = argparse.ArgumentParser( + description="Wait for cloud-init to complete on a Security Onion VM" + ) + parser.add_argument("-n", "--name", required=True, + help="Domain name of the VM to monitor") + args = parser.parse_args() + + try: + # Wait for VM to start + if not wait_for_vm_start(args.name): + sys.exit(2) # VM never started + + # Verify VM remains running + if not verify_vm_running(args.name): + sys.exit(3) # VM stopped too quickly + + # Wait for VM to shutdown + if not wait_for_vm_shutdown(args.name): + sys.exit(4) # VM failed to shutdown + + # Verify VM remains shutdown + if not verify_vm_shutdown(args.name): + sys.exit(4) # VM failed to stay shutdown + + logger.info("Cloud-init completed successfully") + sys.exit(0) + + except Exception as e: + logger.error(f"Unexpected error: {e}") + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/salt/hypervisor/tools/sbin/so_vm_utils.py b/salt/hypervisor/tools/sbin/so_vm_utils.py new file mode 100644 index 000000000..a6820b885 --- /dev/null +++ b/salt/hypervisor/tools/sbin/so_vm_utils.py @@ -0,0 +1,60 @@ +#!/usr/bin/python3 + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +import sys +import time +import libvirt +import logging + +def stop_vm(conn, vm_name, logger): + """ + Stops the specified virtual machine if it is running. + + Parameters: + conn (libvirt.virConnect): The libvirt connection object. + vm_name (str): The name of the virtual machine. + logger (logging.Logger): The logger object. + + Returns: + libvirt.virDomain: The domain object of the VM. + + Raises: + SystemExit: If the VM cannot be found or an error occurs. + """ + try: + dom = conn.lookupByName(vm_name) + if dom.isActive(): + logger.info(f"Shutting down VM '{vm_name}'...") + dom.shutdown() + # Wait for the VM to shut down + while dom.isActive(): + time.sleep(1) + logger.info(f"VM '{vm_name}' has been stopped.") + else: + logger.info(f"VM '{vm_name}' is already stopped.") + return dom + except libvirt.libvirtError as e: + logger.error(f"Failed to stop VM '{vm_name}': {e}") + sys.exit(1) + +def start_vm(dom, logger): + """ + Starts the specified virtual machine. + + Parameters: + dom (libvirt.virDomain): The domain object of the VM. + logger (logging.Logger): The logger object. + + Raises: + SystemExit: If the VM cannot be started. + """ + try: + dom.create() + logger.info(f"VM '{dom.name()}' started successfully.") + except libvirt.libvirtError as e: + logger.error(f"Failed to start VM '{dom.name()}': {e}") + sys.exit(1) diff --git a/salt/hypervisor/tools/sbin_jinja/so-kvm-modify-hardware b/salt/hypervisor/tools/sbin_jinja/so-kvm-modify-hardware new file mode 100644 index 000000000..ebd606b1e --- /dev/null +++ b/salt/hypervisor/tools/sbin_jinja/so-kvm-modify-hardware @@ -0,0 +1,365 @@ +#!/usr/bin/python3 + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. +# +# Note: Per the Elastic License 2.0, the second limitation states: +# +# "You may not move, change, disable, or circumvent the license key functionality +# in the software, and you may not remove or obscure any functionality in the +# software that is protected by the license key." + +{% if 'vrt' in salt['pillar.get']('features', []) %} + +""" +Script for managing hardware configurations of KVM virtual machines. This script provides +functionality to modify CPU, memory, and PCI device settings without manual XML editing +or direct libvirt interaction. + +The script offers three main configuration capabilities: +1. CPU Management: Adjust virtual CPU count +2. Memory Management: Modify memory allocation +3. PCI Passthrough: Configure PCI device passthrough for direct hardware access + +This script is designed to work with Security Onion's virtualization infrastructure and is typically +used during VM provisioning and hardware reconfiguration tasks. + +**Usage:** + so-kvm-modify-hardware -v [-c ] [-m ] [-p ] [-p ...] [-s] + +**Options:** + -v, --vm Name of the virtual machine to modify. + -c, --cpu Number of virtual CPUs to assign. + -m, --memory Amount of memory to assign in MiB. + -p, --pci PCI hardware ID(s) to passthrough to the VM (e.g., 0000:00:1f.2). Can be specified multiple times. + Format: domain:bus:device.function + -s, --start Start the VM after modification. + +**Examples:** + +1. **Modify CPU and Memory with Multiple PCI Devices:** + + ```bash + so-kvm-modify-hardware -v vm1_sensor -c 4 -m 8192 -p 0000:c7:00.0 -p 0000:c8:00.0 -s + ``` + + This command modifies a VM with the following settings: + - VM Name: `vm1_sensor` + - Hardware Configuration: + - CPUs: `4` + - Memory: `8192` MiB + - PCI Device Passthrough: `0000:c7:00.0`, `0000:c8:00.0` + - The VM is started after modification due to the `-s` flag + +2. **Add PCI Device Without Other Changes:** + + ```bash + so-kvm-modify-hardware -v vm2_master -p 0000:c7:00.0 + ``` + + This command adds a single PCI device passthrough to the VM: + - VM Name: `vm2_master` + - PCI Device: `0000:c7:00.0` + - Existing CPU and memory settings are preserved + +3. **Update Resource Allocation:** + + ```bash + so-kvm-modify-hardware -v vm3_search -c 2 -m 4096 + ``` + + This command updates only compute resources: + - VM Name: `vm3_search` + - CPUs: `2` + - Memory: `4096` MiB + - VM remains stopped after modification + +4. **Add Multiple PCI Devices:** + + ```bash + so-kvm-modify-hardware -v vm4_node -p 0000:c7:00.0 -p 0000:c4:00.0 -p 0000:c4:00.1 -s + ``` + + This command adds multiple PCI devices and starts the VM: + - VM Name: `vm4_node` + - PCI Devices: `0000:c7:00.0`, `0000:c4:00.0`, `0000:c4:00.1` + - VM is started after modification + +**Notes:** + +- The script automatically stops the VM if it's running before making modifications. +- At least one modification option (-c, -m, or -p) should be provided. +- The PCI hardware IDs must be in the format `domain:bus:device.function` (e.g., `0000:c7:00.0`). +- Multiple PCI devices can be added by using the `-p` option multiple times. +- Without the `-s` flag, the VM remains stopped after modification. +- Existing hardware configurations are preserved if not explicitly modified. + +**Description:** + +The `so-kvm-modify-hardware` script modifies hardware parameters of KVM virtual machines using the following process: + +1. **VM State Management:** + - Connects to the local libvirt daemon + - Stops the VM if it's currently running + - Retrieves current VM configuration + +2. **Hardware Configuration:** + - Modifies CPU count if specified + - Updates memory allocation if specified + - Adds PCI device passthrough configurations if specified + - All changes are made through libvirt XML configuration + +3. **VM Redefinition:** + - Applies the new configuration by redefining the VM + - Optionally starts the VM if requested + - Ensures clean shutdown and startup during modifications + +4. **Error Handling:** + - Validates all input parameters + - Ensures proper XML structure + - Provides detailed error messages for troubleshooting + +**Exit Codes:** + +- `0`: Success +- `1`: An error occurred during execution + +**Logging:** + +- Logs are written to `/opt/so/log/hypervisor/so-kvm-modify-hardware.log` +- Both file and console logging are enabled for real-time monitoring +- Log entries include timestamps and severity levels +- Detailed error messages are logged for troubleshooting +""" + +import argparse +import sys +import libvirt +import logging +import socket +import xml.etree.ElementTree as ET +from io import StringIO +from so_vm_utils import start_vm, stop_vm +from so_logging_utils import setup_logging +import subprocess + +# Get hypervisor name from local hostname +HYPERVISOR = socket.gethostname() + +# Custom log handler to capture output +class StringIOHandler(logging.Handler): + def __init__(self): + super().__init__() + self.strio = StringIO() + + def emit(self, record): + msg = self.format(record) + self.strio.write(msg + '\n') + + def get_value(self): + return self.strio.getvalue() + +def parse_arguments(): + parser = argparse.ArgumentParser(description='Modify hardware parameters of a KVM virtual machine.') + parser.add_argument('-v', '--vm', required=True, help='Name of the virtual machine to modify.') + parser.add_argument('-c', '--cpu', type=int, help='Number of virtual CPUs to assign.') + parser.add_argument('-m', '--memory', type=int, help='Amount of memory to assign in MiB.') + parser.add_argument('-p', '--pci', action='append', help='PCI hardware ID(s) to passthrough to the VM (e.g., 0000:00:1f.2). Can be specified multiple times.') + parser.add_argument('-s', '--start', action='store_true', help='Start the VM after modification.') + args = parser.parse_args() + return args + +def modify_vm(dom, cpu_count, memory_amount, pci_ids, logger): + try: + # Get the XML description of the VM + xml_desc = dom.XMLDesc() + root = ET.fromstring(xml_desc) + + # Modify CPU count + if cpu_count is not None: + vcpu_elem = root.find('./vcpu') + if vcpu_elem is not None: + vcpu_elem.text = str(cpu_count) + logger.info(f"Set CPU count to {cpu_count}.") + else: + logger.error("Could not find element in XML.") + sys.exit(1) + + # Modify memory amount + if memory_amount is not None: + memory_elem = root.find('./memory') + current_memory_elem = root.find('./currentMemory') + if memory_elem is not None and current_memory_elem is not None: + memory_elem.text = str(memory_amount * 1024) # Convert MiB to KiB + current_memory_elem.text = str(memory_amount * 1024) + logger.info(f"Set memory to {memory_amount} MiB.") + else: + logger.error("Could not find elements in XML.") + sys.exit(1) + + # Add PCI device passthrough(s) + if pci_ids: + devices_elem = root.find('./devices') + if devices_elem is not None: + for pci_id in pci_ids: + hostdev_elem = ET.SubElement(devices_elem, 'hostdev', attrib={ + 'mode': 'subsystem', + 'type': 'pci', + 'managed': 'yes' + }) + source_elem = ET.SubElement(hostdev_elem, 'source') + # Split PCI ID into components (domain:bus:slot.function) + parts = pci_id.split(':') + if len(parts) != 3: + logger.error(f"Invalid PCI ID format: {pci_id}. Expected format: domain:bus:slot.function") + sys.exit(1) + domain_id = parts[0] + bus = parts[1] + slot_func = parts[2].split('.') + if len(slot_func) != 2: + logger.error(f"Invalid PCI ID format: {pci_id}. Expected format: domain:bus:slot.function") + sys.exit(1) + slot = slot_func[0] + function = slot_func[1] + address_attrs = { + 'domain': f'0x{domain_id}', + 'bus': f'0x{bus}', + 'slot': f'0x{slot}', + 'function': f'0x{function}' + } + ET.SubElement(source_elem, 'address', attrib=address_attrs) + logger.info(f"Added PCI device passthrough for {pci_id}.") + else: + logger.error("Could not find element in XML.") + sys.exit(1) + + # Convert XML back to string + new_xml_desc = ET.tostring(root, encoding='unicode') + return new_xml_desc + except Exception as e: + logger.error(f"Failed to modify VM XML: {e}") + sys.exit(1) + +def redefine_vm(conn, new_xml_desc, logger): + try: + conn.defineXML(new_xml_desc) + logger.info("VM redefined with new hardware parameters.") + except libvirt.libvirtError as e: + logger.error(f"Failed to redefine VM: {e}") + sys.exit(1) + +def main(): + # Set up logging using the so_logging_utils library + string_handler = StringIOHandler() + string_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) + logger = setup_logging( + logger_name='so-kvm-modify-hardware', + log_file_path='/opt/so/log/hypervisor/so-kvm-modify-hardware.log', + log_level=logging.INFO, + format_str='%(asctime)s - %(levelname)s - %(message)s' + ) + logger.addHandler(string_handler) + + try: + args = parse_arguments() + + vm_name = args.vm + cpu_count = args.cpu + memory_amount = args.memory + pci_ids = args.pci # This will be a list or None + start_vm_flag = args.start + + # Connect to libvirt + try: + conn = libvirt.open(None) + except libvirt.libvirtError as e: + logger.error(f"Failed to open connection to libvirt: {e}") + try: + subprocess.run([ + 'so-salt-emit-vm-deployment-status-event', + '-v', vm_name, + '-H', HYPERVISOR, + '-s', 'Hardware Configuration Failed' + ], check=True) + except subprocess.CalledProcessError as e: + logger.error(f"Failed to emit failure status event: {e}") + sys.exit(1) + + # Stop VM if running + dom = stop_vm(conn, vm_name, logger) + + # Modify VM XML + new_xml_desc = modify_vm(dom, cpu_count, memory_amount, pci_ids, logger) + + # Redefine VM + redefine_vm(conn, new_xml_desc, logger) + + # Start VM if -s or --start argument is provided + if start_vm_flag: + dom = conn.lookupByName(vm_name) + start_vm(dom, logger) + logger.info(f"VM '{vm_name}' started successfully.") + else: + logger.info("VM start flag not provided; VM will remain stopped.") + + # Close connection + conn.close() + + # Send success status event + try: + subprocess.run([ + 'so-salt-emit-vm-deployment-status-event', + '-v', vm_name, + '-H', HYPERVISOR, + '-s', 'Hardware Configuration' + ], check=True) + except subprocess.CalledProcessError as e: + logger.error(f"Failed to emit success status event: {e}") + + except KeyboardInterrupt: + error_msg = "Operation cancelled by user" + logger.error(error_msg) + try: + subprocess.run([ + 'so-salt-emit-vm-deployment-status-event', + '-v', vm_name, + '-H', HYPERVISOR, + '-s', 'Hardware Configuration Failed' + ], check=True) + except subprocess.CalledProcessError as e: + logger.error(f"Failed to emit failure status event: {e}") + sys.exit(1) + except Exception as e: + error_msg = str(e) + if "Failed to open connection to libvirt" in error_msg: + error_msg = f"Failed to connect to libvirt: {error_msg}" + elif "Failed to redefine VM" in error_msg: + error_msg = f"Failed to apply hardware changes: {error_msg}" + elif "Failed to modify VM XML" in error_msg: + error_msg = f"Failed to update hardware configuration: {error_msg}" + else: + error_msg = f"An error occurred: {error_msg}" + logger.error(error_msg) + try: + subprocess.run([ + 'so-salt-emit-vm-deployment-status-event', + '-v', vm_name, + '-h', HYPERVISOR, + '-s', 'Hardware Configuration Failed' + ], check=True) + except subprocess.CalledProcessError as e: + logger.error(f"Failed to emit failure status event: {e}") + sys.exit(1) + +if __name__ == '__main__': + main() + +{%- else -%} + +echo "Hypervisor nodes are a feature supported only for customers with a valid license. \ + Contact Security Onion Solutions, LLC via our website at https://securityonionsolutions.com \ + for more information about purchasing a license to enable this feature." + +{% endif -%} diff --git a/salt/hypervisor/tools/sbin_jinja/so-qcow2-modify-network b/salt/hypervisor/tools/sbin_jinja/so-qcow2-modify-network new file mode 100644 index 000000000..527131f3f --- /dev/null +++ b/salt/hypervisor/tools/sbin_jinja/so-qcow2-modify-network @@ -0,0 +1,531 @@ +#!/usr/bin/python3 + +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. +# +# Note: Per the Elastic License 2.0, the second limitation states: +# +# "You may not move, change, disable, or circumvent the license key functionality +# in the software, and you may not remove or obscure any functionality in the +# software that is protected by the license key." + +{% if 'vrt' in salt['pillar.get']('features', []) -%} + +""" +Script for modifying network configurations within QCOW2 virtual machine images. This script provides +functionality to update NetworkManager settings, supporting both DHCP and static IP configurations +without requiring the VM to be running. + +The script offers two main configuration modes: +1. DHCP Configuration: Enable automatic IP address assignment +2. Static IP Configuration: Set specific IP address, gateway, DNS servers, and search domains + +For both configuration modes, the script automatically sets the following NetworkManager connection properties: +- connection.autoconnect: yes (ensures interface connects automatically) +- connection.autoconnect-priority: 999 (sets connection priority) +- connection.autoconnect-retries: -1 (unlimited connection retries) +- connection.multi-connect: 0 (single connection mode) +- connection.wait-device-timeout: -1 (wait indefinitely for device) + +This script is designed to work with Security Onion's virtualization infrastructure and is typically +used during VM provisioning and network reconfiguration tasks. + +**Usage:** + so-qcow2-modify-network -I -i (--dhcp4 | --static4 --ip4 --gw4 ) + [--dns4 ] [--search4 ] + +**Options:** + -I, --image Path to the QCOW2 image. + -i, --interface Network interface to modify (e.g., enp1s0). + --dhcp4 Configure interface for DHCP (IPv4). + --static4 Configure interface for static IPv4 settings. + --ip4 IPv4 address (e.g., 192.168.1.10/24). Required for static IPv4 configuration. + --gw4 IPv4 gateway (e.g., 192.168.1.1). Required for static IPv4 configuration. + --dns4 Comma-separated list of IPv4 DNS servers (e.g., 8.8.8.8,8.8.4.4). + --search4 DNS search domain for IPv4. + +**Examples:** + +1. **Static IP Configuration with DNS and Search Domain:** + + ```bash + so-qcow2-modify-network -I /nsm/libvirt/images/sool9/sool9.qcow2 -i enp1s0 --static4 \ + --ip4 192.168.1.10/24 --gw4 192.168.1.1 --dns4 192.168.1.1,192.168.1.2 --search4 example.local + ``` + + This command configures the network settings in the QCOW2 image with: + - Static IPv4 configuration: + - IP Address: `192.168.1.10/24` + - Gateway: `192.168.1.1` + - DNS Servers: `192.168.1.1`, `192.168.1.2` + - DNS Search Domain: `example.local` + +2. **DHCP Configuration:** + + ```bash + so-qcow2-modify-network -I /nsm/libvirt/images/sool9/sool9.qcow2 -i enp1s0 --dhcp4 + ``` + + This command configures the network interface to use DHCP for automatic IP address assignment. + +3. **Static IP Configuration without DNS Settings:** + + ```bash + so-qcow2-modify-network -I /nsm/libvirt/images/sool9/sool9.qcow2 -i enp1s0 --static4 \ + --ip4 192.168.1.20/24 --gw4 192.168.1.1 + ``` + + This command sets only the basic static IP configuration: + - IP Address: `192.168.1.20/24` + - Gateway: `192.168.1.1` + +**Notes:** + +- When using `--static4`, both `--ip4` and `--gw4` options are required. +- The script validates IP addresses, DNS servers, and interface names before making any changes. +- DNS servers can be specified as a comma-separated list for multiple servers. +- The script requires write permissions for the QCOW2 image file. +- Interface names must contain only alphanumeric characters, underscores, and hyphens. + +**Description:** + +The `so-qcow2-modify-network` script modifies network configuration within a QCOW2 image using the following process: + +1. **Image Access:** + - Mounts the QCOW2 image using libguestfs + - Locates and accesses the NetworkManager configuration directory + +2. **Configuration Update:** + - Reads the existing network configuration for the specified interface + - Updates IPv4 settings based on provided parameters + - Supports both DHCP and static IP configurations + - Validates all input parameters before making changes + +3. **File Management:** + - Creates or updates the NetworkManager connection file + - Maintains proper file permissions and format + - Safely unmounts the image after changes + +**Exit Codes:** + +- `0`: Success +- Non-zero: An error occurred during execution + +**Logging:** + +- Logs are written to `/opt/so/log/hypervisor/so-qcow2-modify-network.log` +- Both file and console logging are enabled for real-time monitoring +- Log entries include: + - Timestamps in ISO 8601 format + - Severity levels (INFO, WARNING, ERROR) + - Detailed error messages for troubleshooting +- Critical operations logged: + - Network configuration changes + - Image mount/unmount operations + - Validation failures + - File access errors +""" + +import argparse +import guestfs +import re +import sys +import logging +import os +import socket +import ipaddress +import configparser +import uuid +from io import StringIO +import libvirt +from so_logging_utils import setup_logging +import subprocess + +# Get hypervisor name from local hostname +HYPERVISOR = socket.gethostname() + +# Custom log handler to capture output +class StringIOHandler(logging.Handler): + def __init__(self): + super().__init__() + self.strio = StringIO() + + def emit(self, record): + msg = self.format(record) + self.strio.write(msg + '\n') + + def get_value(self): + return self.strio.getvalue() + +# Set up logging using the so_logging_utils library +string_handler = StringIOHandler() +string_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) +logger = setup_logging( + logger_name='so-qcow2-modify-network', + log_file_path='/opt/so/log/hypervisor/so-qcow2-modify-network.log', + log_level=logging.INFO, + format_str='%(asctime)s - %(levelname)s - %(message)s' +) +logger.addHandler(string_handler) + +NETWORK_CONFIG_DIR = "/etc/NetworkManager/system-connections" + +def validate_ip_address(ip_str, description="IP address"): + try: + ipaddress.IPv4Interface(ip_str) + except ValueError: + try: + ipaddress.IPv4Address(ip_str) + except ValueError: + raise ValueError(f"Invalid {description}: {ip_str}") + +def validate_dns_addresses(dns_str): + dns_list = dns_str.split(',') + for dns in dns_list: + dns = dns.strip() + validate_ip_address(dns, description="DNS server address") + +def validate_interface_name(interface_name): + if not re.match(r'^[a-zA-Z0-9_\-]+$', interface_name): + raise ValueError(f"Invalid interface name: {interface_name}") + +def check_base_domain_status(image_path): + """ + Check if the base domain corresponding to the image path is currently running. + Base domains should not be running when modifying their configuration. + + Parameters: + image_path (str): Path to the QCOW2 image. + + Returns: + bool: True if the base domain is running, False otherwise. + """ + base_domain = os.path.basename(os.path.dirname(image_path)) + logger.info(f"Verifying base domain status for image: {image_path}") + logger.info(f"Checking if base domain '{base_domain}' is running...") + + try: + conn = libvirt.open('qemu:///system') + try: + dom = conn.lookupByName(base_domain) + is_running = dom.isActive() + if is_running: + logger.error(f"Base domain '{base_domain}' is running - cannot modify configuration") + return is_running + except libvirt.libvirtError: + logger.info(f"Base domain '{base_domain}' not found or not running") + return False + finally: + conn.close() + except libvirt.libvirtError as e: + logger.error(f"Failed to connect to libvirt: {e}") + return False + +def update_network_config(content, mode, ip=None, gateway=None, dns=None, search_domain=None): + config = configparser.ConfigParser(strict=False) + config.optionxform = str + config.read_string(content) + + # Ensure connection section exists and set required properties + if 'connection' not in config.sections(): + logger.info("Creating new connection section in network configuration") + config.add_section('connection') + + # Set mandatory connection properties + config.set('connection', 'autoconnect', 'yes') + config.set('connection', 'autoconnect-priority', '999') + config.set('connection', 'autoconnect-retries', '-1') + config.set('connection', 'multi-connect', '0') + config.set('connection', 'wait-device-timeout', '-1') + + # Ensure ipv4 section exists + if 'ipv4' not in config.sections(): + logger.info("Creating new IPv4 section in network configuration") + config.add_section('ipv4') + + if mode == "dhcp4": + logger.info("Configuring DHCP settings:") + logger.info(" method: auto (DHCP enabled)") + logger.info(" Removing any existing static configuration") + config.set('ipv4', 'method', 'auto') + config.remove_option('ipv4', 'address1') + config.remove_option('ipv4', 'addresses') + config.remove_option('ipv4', 'dns') + config.remove_option('ipv4', 'dns-search') + elif mode == "static4": + logger.info("Configuring static IP settings:") + logger.info(" method: manual (static configuration)") + config.set('ipv4', 'method', 'manual') + if ip and gateway: + logger.info(f" Setting address: {ip}") + logger.info(f" Setting gateway: {gateway}") + config.set('ipv4', 'address1', f"{ip},{gateway}") + else: + logger.error("Missing required IP address or gateway for static configuration") + raise ValueError("Both IP address and gateway are required for static configuration.") + if dns: + logger.info(f" Setting DNS servers: {dns}") + config.set('ipv4', 'dns', f"{dns};") + else: + logger.info(" No DNS servers specified") + config.remove_option('ipv4', 'dns') + if search_domain: + logger.info(f" Setting search domain: {search_domain}") + config.set('ipv4', 'dns-search', f"{search_domain};") + else: + logger.info(" No search domain specified") + config.remove_option('ipv4', 'dns-search') + else: + raise ValueError(f"Invalid mode '{mode}'. Expected 'dhcp4' or 'static4'.") + + output = StringIO() + config.write(output, space_around_delimiters=False) + updated_content = output.getvalue() + output.close() + + return updated_content + +def modify_network_config(image_path, interface, mode, ip=None, gateway=None, dns=None, search_domain=None): + """ + Modifies network configuration in a QCOW2 image, ensuring specific connection settings are set. + + Handles both eth0 and predictable network interface names (e.g., enp1s0). + If the requested interface configuration is not found but eth0.nmconnection exists, + it will be renamed and updated with the proper interface configuration. + """ + # Check if base domain is running + if check_base_domain_status(image_path): + raise RuntimeError("Cannot modify network configuration while base domain is running") + + if not os.access(image_path, os.W_OK): + logger.error(f"Permission denied: Cannot write to image file {image_path}") + raise PermissionError(f"Write permission denied for image file: {image_path}") + + logger.info(f"Configuring network for VM image: {image_path}") + logger.info(f"Network configuration details for interface {interface}:") + logger.info(f" Mode: {mode.upper()}") + if mode == "static4": + logger.info(f" IP Address: {ip}") + logger.info(f" Gateway: {gateway}") + logger.info(f" DNS Servers: {dns if dns else 'Not configured'}") + logger.info(f" Search Domain: {search_domain if search_domain else 'Not configured'}") + + g = guestfs.GuestFS(python_return_dict=True) + try: + logger.info("Initializing GuestFS and mounting image...") + g.set_network(False) + g.selinux = False + g.add_drive_opts(image_path, format="qcow2") + g.launch() + except RuntimeError as e: + logger.error(f"Failed to initialize GuestFS: {e}") + raise RuntimeError(f"Failed to initialize GuestFS or launch appliance: {e}") + + try: + os_list = g.inspect_os() + if not os_list: + logger.error(f"No operating system found in image: {image_path}") + raise RuntimeError(f"Unable to find any OS in {image_path}.") + + root_fs = os_list[0] + try: + g.mount(root_fs, "/") + logger.info("Successfully mounted VM image filesystem") + except RuntimeError as e: + logger.error(f"Failed to mount filesystem: {e}") + raise RuntimeError(f"Failed to mount the filesystem: {e}") + + if not g.is_dir(NETWORK_CONFIG_DIR): + logger.error(f"NetworkManager configuration directory not found: {NETWORK_CONFIG_DIR}") + raise FileNotFoundError(f"NetworkManager configuration directory not found in the image at {NETWORK_CONFIG_DIR}.") + + requested_config_path = f"{NETWORK_CONFIG_DIR}/{interface}.nmconnection" + eth0_config_path = f"{NETWORK_CONFIG_DIR}/eth0.nmconnection" + config_file_path = None + current_content = None + + # Try to read the requested interface config first + try: + file_content = g.read_file(requested_config_path) + current_content = file_content.decode('utf-8') + config_file_path = requested_config_path + logger.info(f"Found existing network configuration for interface {interface}") + except RuntimeError: + # If not found, try eth0 config + try: + file_content = g.read_file(eth0_config_path) + current_content = file_content.decode('utf-8') + config_file_path = eth0_config_path + logger.info("Found eth0 network configuration, will update for new interface") + except RuntimeError: + logger.error(f"No network configuration found for either {interface} or eth0") + raise FileNotFoundError(f"No network configuration found at {requested_config_path} or {eth0_config_path}") + except UnicodeDecodeError: + logger.error(f"Failed to decode network configuration file") + raise ValueError(f"Failed to decode the configuration file") + + # If using eth0 config, update interface-specific fields + if config_file_path == eth0_config_path: + config = configparser.ConfigParser(strict=False) + config.optionxform = str + config.read_string(current_content) + + if 'connection' not in config.sections(): + config.add_section('connection') + + # Update interface-specific fields + config.set('connection', 'id', interface) + config.set('connection', 'interface-name', interface) + config.set('connection', 'uuid', str(uuid.uuid4())) + + # Write updated content back to string + output = StringIO() + config.write(output, space_around_delimiters=False) + current_content = output.getvalue() + output.close() + + # Update config file path to new interface name + config_file_path = requested_config_path + + logger.info("Applying network configuration changes...") + updated_content = update_network_config(current_content, mode, ip, gateway, dns, search_domain) + + try: + g.write(config_file_path, updated_content.encode('utf-8')) + # Set proper permissions (600) on the network configuration file + g.chmod(0o600, config_file_path) + logger.info("Successfully wrote updated network configuration with proper permissions (600)") + + # If we renamed eth0 to the new interface, remove the old eth0 config + if config_file_path == requested_config_path and eth0_config_path != requested_config_path: + try: + g.rm(eth0_config_path) + logger.info("Removed old eth0 configuration file") + except RuntimeError: + logger.warning("Could not remove old eth0 configuration file - it may have already been removed") + + except RuntimeError as e: + logger.error(f"Failed to write network configuration: {e}") + raise IOError(f"Failed to write updated configuration to {config_file_path}: {e}") + + logger.info(f"Successfully updated network configuration:") + logger.info(f" Image: {image_path}") + logger.info(f" Interface: {interface}") + logger.info(f" Mode: {mode.upper()}") + if mode == "static4": + logger.info(f" Settings applied:") + logger.info(f" IP Address: {ip}") + logger.info(f" Gateway: {gateway}") + logger.info(f" DNS Servers: {dns if dns else 'Not configured'}") + logger.info(f" Search Domain: {search_domain if search_domain else 'Not configured'}") + + except Exception as e: + raise e + finally: + g.umount_all() + g.close() + +def parse_arguments(): + parser = argparse.ArgumentParser(description="Modify IPv4 settings in a QCOW2 image for a specified network interface.") + parser.add_argument("-I", "--image", required=True, help="Path to the QCOW2 image.") + parser.add_argument("-i", "--interface", required=True, help="Network interface to modify (e.g., enp1s0).") + parser.add_argument("-n", "--vm-name", required=True, help="Full name of the VM (hostname_role).") + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument("--dhcp4", action="store_true", help="Configure interface for DHCP (IPv4).") + group.add_argument("--static4", action="store_true", help="Configure interface for static IPv4 settings.") + parser.add_argument("--ip4", help="IPv4 address (e.g., 192.168.1.10/24). Required for static IPv4 configuration.") + parser.add_argument("--gw4", help="IPv4 gateway (e.g., 192.168.1.1). Required for static IPv4 configuration.") + parser.add_argument("--dns4", help="Comma-separated list of IPv4 DNS servers (e.g., 8.8.8.8,8.8.4.4).") + parser.add_argument("--search4", help="DNS search domain for IPv4.") + + args = parser.parse_args() + + if args.static4: + if not args.ip4 or not args.gw4: + parser.error("Both --ip4 and --gw4 are required for static IPv4 configuration.") + return args + +def main(): + try: + logger.info("Starting network configuration update...") + args = parse_arguments() + + logger.info("Validating interface name...") + validate_interface_name(args.interface) + + if args.dhcp4: + mode = "dhcp4" + logger.info("Using DHCP configuration mode") + elif args.static4: + mode = "static4" + logger.info("Using static IP configuration mode") + if not args.ip4 or not args.gw4: + logger.error("Missing required parameters for static configuration") + raise ValueError("Both --ip4 and --gw4 are required for static IPv4 configuration.") + + logger.info("Validating IP addresses...") + validate_ip_address(args.ip4, description="IPv4 address") + validate_ip_address(args.gw4, description="IPv4 gateway") + if args.dns4: + validate_dns_addresses(args.dns4) + else: + logger.error("No configuration mode specified") + raise ValueError("Either --dhcp4 or --static4 must be specified.") + + modify_network_config(args.image, args.interface, mode, args.ip4, args.gw4, args.dns4, args.search4) + logger.info("Network configuration update completed successfully") + + # Send success status event + try: + subprocess.run([ + 'so-salt-emit-vm-deployment-status-event', + '-v', args.vm_name, + '-H', HYPERVISOR, + '-s', 'IP Configuration' + ], check=True) + except subprocess.CalledProcessError as e: + logger.error(f"Failed to emit success status event: {e}") + + except KeyboardInterrupt: + error_msg = "Operation cancelled by user" + logger.error(error_msg) + try: + subprocess.run([ + 'so-salt-emit-vm-deployment-status-event', + '-v', args.vm_name, + '-H', HYPERVISOR, + '-s', 'IP Configuration Failed' + ], check=True) + except subprocess.CalledProcessError as e: + logger.error(f"Failed to emit failure status event: {e}") + sys.exit(1) + except Exception as e: + error_msg = str(e) + if "base domain is running" in error_msg: + logger.error("Cannot proceed: Base domain must not be running when modifying network configuration") + error_msg = "Base domain must not be running when modifying network configuration" + else: + logger.error(f"An error occurred: {e}") + try: + subprocess.run([ + 'so-salt-emit-vm-deployment-status-event', + '-v', args.vm_name, + '-H', HYPERVISOR, + '-s', 'IP Configuration Failed' + ], check=True) + except subprocess.CalledProcessError as e: + logger.error(f"Failed to emit failure status event: {e}") + sys.exit(1) + +if __name__ == '__main__': + main() + +{%- else -%} + +echo "Hypervisor nodes are a feature supported only for customers with a valid license. \ + Contact Security Onion Solutions, LLC via our website at https://securityonionsolutions.com \ + for more information about purchasing a license to enable this feature." + +{% endif -%} diff --git a/salt/idh/config.sls b/salt/idh/config.sls index dcde9c8e5..91f809f9e 100644 --- a/salt/idh/config.sls +++ b/salt/idh/config.sls @@ -43,6 +43,29 @@ idhconfdir: - group: 939 - makedirs: True +idhhttpskinsdir: + file.directory: + - name: /opt/so/conf/idh/http-skins + - user: 939 + - group: 939 + - makedirs: True + +# Copy over default http skins +idhhttpskins: + file.recurse: + - name: /opt/so/conf/idh/http-skins + - user: 939 + - group: 939 + - source: salt://idh/skins/http/opencanary + +# Copy over custom http skins +idhcustomhttpskins: + file.recurse: + - name: /opt/so/conf/idh/http-skins + - user: 939 + - group: 939 + - source: salt://idh/skins/http/custom + # Create a log directory idhlogdir: file.directory: diff --git a/salt/idh/enabled.sls b/salt/idh/enabled.sls index 7ef0ebb46..e08e6647f 100644 --- a/salt/idh/enabled.sls +++ b/salt/idh/enabled.sls @@ -20,6 +20,7 @@ so-idh: - network_mode: host - binds: - /nsm/idh:/var/tmp:rw + - /opt/so/conf/idh/http-skins:/usr/local/lib/python3.12/site-packages/opencanary/modules/data/http/skin:ro - /opt/so/conf/idh/opencanary.conf:/etc/opencanaryd/opencanary.conf:ro {% if DOCKER.containers['so-idh'].custom_bind_mounts %} {% for BIND in DOCKER.containers['so-idh'].custom_bind_mounts %} diff --git a/salt/idh/openssh/config.sls b/salt/idh/openssh/config.sls index d358bb5be..5e2acd8d2 100644 --- a/salt/idh/openssh/config.sls +++ b/salt/idh/openssh/config.sls @@ -11,6 +11,8 @@ idh_sshd_selinux: - sel_type: ssh_port_t - prereq: - file: openssh_config + - require: + - pkg: python_selinux_mgmt_tools {% endif %} openssh_config: diff --git a/salt/idh/openssh/init.sls b/salt/idh/openssh/init.sls index ba0a8ab04..79d082502 100644 --- a/salt/idh/openssh/init.sls +++ b/salt/idh/openssh/init.sls @@ -15,3 +15,9 @@ openssh: - enable: False - name: {{ openssh_map.service }} {% endif %} + +{% if grains.os_family == 'RedHat' %} +python_selinux_mgmt_tools: + pkg.installed: + - name: policycoreutils-python-utils +{% endif %} diff --git a/salt/idh/skins/http/custom/basicCustomLogin/403.html b/salt/idh/skins/http/custom/basicCustomLogin/403.html new file mode 100644 index 000000000..6bc5d8eda --- /dev/null +++ b/salt/idh/skins/http/custom/basicCustomLogin/403.html @@ -0,0 +1,10 @@ + + +403 Forbidden + +

Forbidden

+

You don't have permission to access [[URL]] +on this server.

+
+
[[BANNER]] Server
+ diff --git a/salt/idh/skins/http/custom/basicCustomLogin/404.html b/salt/idh/skins/http/custom/basicCustomLogin/404.html new file mode 100644 index 000000000..631b905ec --- /dev/null +++ b/salt/idh/skins/http/custom/basicCustomLogin/404.html @@ -0,0 +1,9 @@ + + +404 Not Found + +

Not Found

+

The requested URL [[URL]] was not found on this server.

+
+
[[BANNER]] Server
+ diff --git a/salt/idh/skins/http/custom/basicCustomLogin/index.html b/salt/idh/skins/http/custom/basicCustomLogin/index.html new file mode 100644 index 000000000..3a62e843e --- /dev/null +++ b/salt/idh/skins/http/custom/basicCustomLogin/index.html @@ -0,0 +1,41 @@ + + + Login + + + +
+
+

Network Storage v5.13

+ +

Login failed

+ +
+
+
CustomUsername:
+
+
Password:
+
+
+
+
+
+
+
+ + diff --git a/salt/idh/skins/http/opencanary/basicLogin/403.html b/salt/idh/skins/http/opencanary/basicLogin/403.html new file mode 100644 index 000000000..6bc5d8eda --- /dev/null +++ b/salt/idh/skins/http/opencanary/basicLogin/403.html @@ -0,0 +1,10 @@ + + +403 Forbidden + +

Forbidden

+

You don't have permission to access [[URL]] +on this server.

+
+
[[BANNER]] Server
+ diff --git a/salt/idh/skins/http/opencanary/basicLogin/404.html b/salt/idh/skins/http/opencanary/basicLogin/404.html new file mode 100644 index 000000000..631b905ec --- /dev/null +++ b/salt/idh/skins/http/opencanary/basicLogin/404.html @@ -0,0 +1,9 @@ + + +404 Not Found + +

Not Found

+

The requested URL [[URL]] was not found on this server.

+
+
[[BANNER]] Server
+ diff --git a/salt/idh/skins/http/opencanary/basicLogin/index.html b/salt/idh/skins/http/opencanary/basicLogin/index.html new file mode 100644 index 000000000..73b776a0f --- /dev/null +++ b/salt/idh/skins/http/opencanary/basicLogin/index.html @@ -0,0 +1,41 @@ + + + Login + + + +
+
+

Network Storage v5.13

+ +

Login failed

+ +
+
+
Username:
+
+
Password:
+
+
+
+
+
+
+
+ + diff --git a/salt/idh/skins/http/opencanary/nasLogin/403.html b/salt/idh/skins/http/opencanary/nasLogin/403.html new file mode 100644 index 000000000..6bc5d8eda --- /dev/null +++ b/salt/idh/skins/http/opencanary/nasLogin/403.html @@ -0,0 +1,10 @@ + + +403 Forbidden + +

Forbidden

+

You don't have permission to access [[URL]] +on this server.

+
+
[[BANNER]] Server
+ diff --git a/salt/idh/skins/http/opencanary/nasLogin/404.html b/salt/idh/skins/http/opencanary/nasLogin/404.html new file mode 100644 index 000000000..631b905ec --- /dev/null +++ b/salt/idh/skins/http/opencanary/nasLogin/404.html @@ -0,0 +1,9 @@ + + +404 Not Found + +

Not Found

+

The requested URL [[URL]] was not found on this server.

+
+
[[BANNER]] Server
+ diff --git a/salt/idh/skins/http/opencanary/nasLogin/index.html b/salt/idh/skins/http/opencanary/nasLogin/index.html new file mode 100644 index 000000000..47b1dd3d3 --- /dev/null +++ b/salt/idh/skins/http/opencanary/nasLogin/index.html @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + +Synology DiskStation + + + + + + + + + + + +
+ +
+ + + + + + diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/css/desktop.css b/salt/idh/skins/http/opencanary/nasLogin/static/css/desktop.css new file mode 100644 index 000000000..85bcd44ad --- /dev/null +++ b/salt/idh/skins/http/opencanary/nasLogin/static/css/desktop.css @@ -0,0 +1 @@ +.scrollgeneric{line-height:1px;font-size:1px;position:absolute;top:0;left:0}.vscrollerbase,.hscrollerbase{width:0px;height:0px}.vscrollerbar,.hscrollerbar{background-position:0 0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=20);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=20);opacity:0.2;-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0.2s;-moz-transition-duration:0.2s;-o-transition-duration:0.2s;transition-duration:0.2s}.vscrollerbar:hover,.hscrollerbar:hover{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=30);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=30);opacity:0.3}.vscrollerbar:active,.hscrollerbar:active{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=40);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);opacity:0.4}.vscrollerbar{width:10px;margin-left:-10px}.hscrollerbar{height:10px;margin-top:-10px}.vscrollerbar{background-image:url("images/scrollbar/scrollbar_black_v.png");background-repeat:repeat-y}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .vscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_black_v.png");background-size:10px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .vscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_black_v.png");background-size:10px;outline:1px green dashed}}.white-scrollerbar .vscrollerbar{background-image:url("images/scrollbar/scrollbar_white_v.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .white-scrollerbar .vscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_white_v.png");background-size:10px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .white-scrollerbar .vscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_white_v.png");background-size:10px;outline:1px green dashed}}.hscrollerbar{background-image:url "images/scrollbar/scrollbar_black_h.png";background-repeat:repeat-x}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .hscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_black_h.png");background-size:10px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .hscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_black_h.png");background-size:10px;outline:1px green dashed}}.white-scrollerbar .hscrollerbar{background-image:url "images/scrollbar/scrollbar_white_h.png"}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .white-scrollerbar .hscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_white_h.png");background-size:10px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .white-scrollerbar .hscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_white_h.png");background-size:10px;outline:1px green dashed}}.flexcrollactive{outline:none}.vscrollerbar{background-image:url("../../../scripts/scrollbar/images/scrollbar/scrollbar_black_v.png");background-repeat:repeat-y}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .vscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_black_v.png");background-size:10px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .vscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_black_v.png");background-size:10px;outline:1px green dashed}}.white-scrollerbar .vscrollerbar{background-image:url("../../../scripts/scrollbar/images/scrollbar/scrollbar_white_v.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .white-scrollerbar .vscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_white_v.png");background-size:10px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .white-scrollerbar .vscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_white_v.png");background-size:10px;outline:1px green dashed}}.hscrollerbar{background-image:url("../../../scripts/scrollbar/images/scrollbar/scrollbar_black_h.png");background-repeat:repeat-x}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .hscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_black_h.png");background-size:10px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .hscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_black_h.png");background-size:10px;outline:1px green dashed}}.white-scrollerbar .hscrollerbar{background-image:url("../../../scripts/scrollbar/images/scrollbar/scrollbar_white_h.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .white-scrollerbar .hscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_white_h.png");background-size:10px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .white-scrollerbar .hscrollerbar{background-image:url("../img/synohdpack/images/scrollbar/scrollbar_white_h.png");background-size:10px;outline:1px green dashed}}body{font-size:12px}body,.normal-font{color:#505a64}.disable-font{color:#96a0aa}.note-font{color:#00a66e}.link-font{font-weight:bold}.link-font{color:#0086e5}.green-status{color:#1ca600}.red-status{color:#fa4b4b}.orange-status{color:#ff7f00}a,.blue-status{color:#0086e5}.sds-logo{position:absolute;display:inline-block;height:32px;right:20px;bottom:8px}.sds-logo.light .logo-0{background-image:url("../images/login/light/0.png");width:17px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.light .logo-0{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/0.png");background-size:17px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.light .logo-0{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/0.png");background-size:17px 32px;outline:1px green dashed}}.sds-logo.light .logo-1{background-image:url("../images/login/light/1.png");width:17px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.light .logo-1{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/1.png");background-size:17px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.light .logo-1{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/1.png");background-size:17px 32px;outline:1px green dashed}}.sds-logo.light .logo-2{background-image:url("../images/login/light/2.png");width:17px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.light .logo-2{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/2.png");background-size:17px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.light .logo-2{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/2.png");background-size:17px 32px;outline:1px green dashed}}.sds-logo.light .logo-3{background-image:url("../images/login/light/3.png");width:17px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.light .logo-3{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/3.png");background-size:17px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.light .logo-3{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/3.png");background-size:17px 32px;outline:1px green dashed}}.sds-logo.light .logo-4{background-image:url("../images/login/light/4.png");width:17px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.light .logo-4{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/4.png");background-size:17px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.light .logo-4{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/4.png");background-size:17px 32px;outline:1px green dashed}}.sds-logo.light .logo-5dot{background-image:url("../images/login/light/5dot.png");width:19px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.light .logo-5dot{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/5dot.png");background-size:19px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.light .logo-5dot{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/5dot.png");background-size:19px 32px;outline:1px green dashed}}.sds-logo.light .logo-DSM{background-image:url("../images/login/light/DSM.png");width:56px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.light .logo-DSM{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/DSM.png");background-size:56px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.light .logo-DSM{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/DSM.png");background-size:56px 32px;outline:1px green dashed}}.sds-logo.light .logo-synology{background-image:url("../images/login/light/synology.png");width:111px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.light .logo-synology{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/synology.png");background-size:111px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.light .logo-synology{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/synology.png");background-size:111px 32px;outline:1px green dashed}}.sds-logo.light .logo-beta{background-image:url("../images/login/light/beta.png");width:45px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.light .logo-beta{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/beta.png");background-size:45px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.light .logo-beta{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/beta.png");background-size:45px 32px;outline:1px green dashed}}.sds-logo.dark .logo-0{background-image:url("../images/login/dark/0.png");width:17px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.dark .logo-0{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/0.png");background-size:17px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.dark .logo-0{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/0.png");background-size:17px 32px;outline:1px green dashed}}.sds-logo.dark .logo-1{background-image:url("../images/login/dark/1.png");width:17px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.dark .logo-1{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/1.png");background-size:17px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.dark .logo-1{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/1.png");background-size:17px 32px;outline:1px green dashed}}.sds-logo.dark .logo-2{background-image:url("../images/login/dark/2.png");width:17px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.dark .logo-2{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/2.png");background-size:17px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.dark .logo-2{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/2.png");background-size:17px 32px;outline:1px green dashed}}.sds-logo.dark .logo-3{background-image:url("../images/login/dark/3.png");width:17px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.dark .logo-3{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/3.png");background-size:17px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.dark .logo-3{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/3.png");background-size:17px 32px;outline:1px green dashed}}.sds-logo.dark .logo-4{background-image:url("../images/login/dark/4.png");width:17px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.dark .logo-4{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/4.png");background-size:17px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.dark .logo-4{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/4.png");background-size:17px 32px;outline:1px green dashed}}.sds-logo.dark .logo-5dot{background-image:url("../images/login/dark/5dot.png");width:19px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.dark .logo-5dot{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/5dot.png");background-size:19px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.dark .logo-5dot{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/5dot.png");background-size:19px 32px;outline:1px green dashed}}.sds-logo.dark .logo-DSM{background-image:url("../images/login/dark/DSM.png");width:56px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.dark .logo-DSM{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/DSM.png");background-size:56px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.dark .logo-DSM{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/DSM.png");background-size:56px 32px;outline:1px green dashed}}.sds-logo.dark .logo-synology{background-image:url("../images/login/dark/synology.png");width:111px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.dark .logo-synology{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/synology.png");background-size:111px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.dark .logo-synology{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/synology.png");background-size:111px 32px;outline:1px green dashed}}.sds-logo.dark .logo-beta{background-image:url("../images/login/dark/beta.png");width:45px;height:32px;display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-logo.dark .logo-beta{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/beta.png");background-size:45px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-logo.dark .logo-beta{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/beta.png");background-size:45px 32px;outline:1px green dashed}}#sds-desktop .sds-logo{bottom:12px}#sds-login .sds-logo{bottom:28px}#sds-copyright{position:absolute;width:248px;height:20px;bottom:8px;right:20px}#sds-copyright.light .logo-copyright_2014{background-image:url("../images/login/light/copyright_2014.png");height:100%}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-copyright.light .logo-copyright_2014{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/copyright_2014.png");background-size:248px 20px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-copyright.light .logo-copyright_2014{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/copyright_2014.png");background-size:248px 20px;outline:1px green dashed}}#sds-copyright.light .logo-copyright_2015{background-image:url("../images/login/light/copyright_2015.png");height:100%}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-copyright.light .logo-copyright_2015{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/copyright_2015.png");background-size:248px 20px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-copyright.light .logo-copyright_2015{background-image:url("../img/synohdpack/images/dsm/resources/images/login/light/copyright_2015.png");background-size:248px 20px;outline:1px green dashed}}#sds-copyright.dark .logo-copyright_2014{background-image:url("../images/login/dark/copyright_2014.png");height:100%}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-copyright.dark .logo-copyright_2014{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/copyright_2014.png");background-size:248px 20px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-copyright.dark .logo-copyright_2014{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/copyright_2014.png");background-size:248px 20px;outline:1px green dashed}}#sds-copyright.dark .logo-copyright_2015{background-image:url("../images/login/dark/copyright_2015.png");height:100%}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-copyright.dark .logo-copyright_2015{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/copyright_2015.png");background-size:248px 20px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-copyright.dark .logo-copyright_2015{background-image:url("../img/synohdpack/images/dsm/resources/images/login/dark/copyright_2015.png");background-size:248px 20px;outline:1px green dashed}}#sds-bug-report-container,#sds-mobile-edition-container{position:absolute;bottom:0px;height:36px;width:100%;text-align:center}#sds-mobile-edition,#sds-bug-report{position:absolute;bottom:0px;background-position:0 0}#sds-mobile-edition:hover,#sds-bug-report:hover{background-position:0 -40px;cursor:pointer}#sds-mobile-edition:active,#sds-bug-report:active{background-position:0 -80px}#sds-mobile-edition{background-image:url("../images/bt_dsm_mobile.png");left:50%;margin-left:-84px;width:168px;height:40px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-mobile-edition{background-image:url("../img/synohdpack/images/dsm/resources/images/bt_dsm_mobile.png");background-size:168px 160px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-mobile-edition{background-image:url("../img/synohdpack/images/dsm/resources/images/bt_dsm_mobile.png");background-size:168px 160px;outline:1px green dashed}}#sds-bug-report{background-image:url("../images/bt_bugs.png");left:50%;margin-left:-84px;width:168px;height:40px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-bug-report{background-image:url("../img/synohdpack/images/dsm/resources/images/bt_bugs.png");background-size:168px 160px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-bug-report{background-image:url("../img/synohdpack/images/dsm/resources/images/bt_bugs.png");background-size:168px 160px;outline:1px green dashed}}.desktop-timeout-mask.ext-el-mask{background-color:#000000;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=20);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=20);opacity:0.2}.x-window-tl .x-window-header{font-family:verdana, tahoma, arial ,sans-serif;background-size:16px 16px}.sds-desktop-dd-ct li.launch-icon,li.launch-icon .image,li.launch-icon .image .virtual-group-icon-background{width:64px;height:64px;background-size:64px 64px}.sds-desktop-dd-ct li.launch-icon.classical,li.launch-icon.classical .image,li.launch-icon.classical .image .virtual-group-icon-background{width:48px;height:48px;background-size:48px 48px}#sds-desktop li.launch-icon{width:136px;height:100px;padding-top:16px;position:absolute;float:left;overflow:visible;cursor:pointer}#sds-desktop li.launch-icon.classical{height:84px}.sds-desktop-dd-ct{position:absolute;width:144px;height:240px;overflow:visible;top:-10000px;list-style:none}.sds-desktop-dd-ct li.launch-icon .text,.sds-desktop-dd-ct li.launch-icon .text a{white-space:normal;visibility:hidden}.sds-desktop-dd-ct .sds-desktop-icon-selected{border-radius:0;-moz-border-radius:0;background-color:transparent;filter:none}li.launch-icon .image{position:relative;background-position:center center;background-repeat:no-repeat;margin:0 auto 4px auto}li.launch-icon .image .virtual-group-icon-background{position:absolute;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=75);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=75);opacity:0.75;background:#282d32;background:#282d32;border-radius:5px}.sds-launch-icon-dragging-proxy.x-dd-drop-ok-add .x-dd-drop-icon{width:64px;height:64px;background-image:url(../images/icon_drag_add.png)}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-launch-icon-dragging-proxy.x-dd-drop-ok-add .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/icon_drag_add.png");background-size:36px 36px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-launch-icon-dragging-proxy.x-dd-drop-ok-add .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/icon_drag_add.png");background-size:36px 36px;outline:1px green dashed}}.sds-launch-icon-dragging-proxy.x-dd-drop-nodrop .x-dd-drop-icon{width:64px;height:64px;background-image:url(../images/icon_drag_ban.png)}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-launch-icon-dragging-proxy.x-dd-drop-nodrop .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/icon_drag_ban.png");background-size:36px 36px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-launch-icon-dragging-proxy.x-dd-drop-nodrop .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/icon_drag_ban.png");background-size:36px 36px;outline:1px green dashed}}.classical.sds-launch-icon-dragging-proxy.x-dd-drop-ok-add .x-dd-drop-icon,.classical.sds-launch-icon-dragging-proxy.x-dd-drop-nodrop .x-dd-drop-icon{width:48px;height:48px}.sds-grouping-preview-icon{position:absolute;width:24px;height:24px}.classical .sds-grouping-preview-icon{width:16px;height:16px}.sds-grouping-big-preview-icon{position:absolute;visibility:hidden;left:8px;top:8px;width:48px;height:48px}.classical .sds-grouping-big-preview-icon{width:32px;height:32px}#sds-desktop{overflow:hidden;position:absolute;width:100%;height:100%;border:0 none;overflow:hidden;cursor:default;zoom:1;top:39px}#sds-desktop.sds-desktop-hide{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=0);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);opacity:0}#sds-desktop.semi-transparent{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=60);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=60);opacity:0.6}#sds-desktop.sent-back{z-index:0}.ext-ie8m #sds-desktop.semi-transparent .x-window,.ext-ie8m #sds-desktop.semi-transparent .x-ie-shadow{z-index:0 !important}.sds-launch-icon-dragging-proxy .x-dd-drag-ghost{border:none !important;background-color:transparent !important;opacity:1 !important;filter:none !important}.sds-launch-icon-dragging-proxy .x-dd-drag-ghost .text{visibility:hidden !important}.sds-launch-icon-dragging-proxy .image{white-space:normal}.sds-launch-icon-dragging-proxy li{list-style:none}#sds-sub-container{position:absolute;width:316px;height:192px;overflow:visible;z-index:14002;border-radius:5px}#sds-sub-container .virtual-group-background{position:absolute;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=75);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=75);opacity:0.75;background:#282d32;background:#282d32;top:0px;left:0px;right:0px;bottom:0px;box-shadow:0 2px 4px rgba(0,0,0,0.5);border-radius:5px}#sds-sub-container .virtual-group-background .virtual-group-arrow{left:-22px;top:84px;position:absolute;overflow:hidden;width:22px;height:35px}#sds-sub-container .virtual-group-background .virtual-group-arrow.right-arrow{left:316px}.ext-ie8m #sds-sub-container .virtual-group-background .virtual-group-arrow{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=75);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=75);opacity:0.75;left:-12px;width:0px;height:0px;border:12px solid transparent;border-right-color:#282d32;border-left-width:0px}.ext-ie8m #sds-sub-container .virtual-group-background .virtual-group-arrow.right-arrow{border-left-color:#282d32;border-left-width:12px;border-right-width:0px;left:316px}#sds-sub-container .virtual-group-background .virtual-group-arrow::after{background:#282d32;background:#282d32;content:'';position:absolute;left:6px;width:16px;height:16px;-webkit-transform-origin:right top;-moz-transform-origin:right top;-ms-transform-origin:right top;-o-transform-origin:right top;transform-origin:right top;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg);box-shadow:0 2px 4px rgba(0,0,0,0.5)}#sds-sub-container .virtual-group-background .virtual-group-arrow.right-arrow::after{left:0px;-webkit-transform-origin:left top;-moz-transform-origin:left top;-ms-transform-origin:left top;-o-transform-origin:left top;transform-origin:left top;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}#sds-sub-container hr{margin:0px 10px;position:relative;border:0px solid;border-top-width:1px;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=50);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=50);opacity:0.5;border-color:#b4bec8;border-color:#b4bec8}#sds-sub-container .sds-sub-container-desc{color:#FFF;font-size:14px;font-weight:bold;margin:7px 20px;padding:2px;width:268px;height:18px;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;white-space:nowrap;font-family:verdana, tahoma, arial, helvetica, sans-serif;border:2px solid transparent;background-color:transparent}#sds-sub-container .sds-sub-container-desc:hover{border-color:#3182c1;background-color:#b4d7f0;color:#000}#sds-sub-container .sds-sub-container-desc:focus{border-color:#3182c1;background-color:#FFF;color:#000}#sds-sub-container .sds-sub-container-div-ct{height:152px;width:276px;overflow:hidden;padding:0 20px}.ext-ie8m #sds-sub-container .sds-sub-container-div-ct div.mcontentwrapper,.ext-ie8m #sds-sub-container .sds-sub-container-div-ct div.scrollwrapper{height:100% !important}#sds-sub-container .sds-sub-container-div-ct .sds-desktop-shortcut li.launch-icon .text,#sds-sub-container .sds-sub-container-div-ct .sds-desktop-shortcut li.launch-icon .text a{overflow:hidden}#sds-sub-container .sds-desktop-shortcut{float:none;width:276px;margin:0px}#sds-sub-container .sds-desktop-shortcut li{float:none;height:84px;padding-top:0}#sds-sub-container .sds-desktop-shortcut li.launch-icon{width:64px;height:128px;margin:0px;padding:0px;overflow:visible}#sds-sub-container .sds-desktop-shortcut li.launch-icon div.image{margin:0px auto}#sds-sub-container .sds-desktop-shortcut li.launch-icon .text,#sds-sub-container .sds-desktop-shortcut li.launch-icon .text a{color:#FFFFFF}#sds-sub-container.classical{height:176px}#sds-sub-container.classical .sds-sub-container-div-ct{height:136px}#sds-sub-container.classical .sds-desktop-shortcut li.launch-icon{width:74px;height:112px}#sds-sub-container-shim{background-color:#000;opacity:0;filter:alpha(opacity=0);position:absolute;width:100%;height:100%;left:0px;top:0px;border:0px;z-index:14000}html,body{height:100%;overflow-x:hidden;overflow-y:hidden;user-select:none;-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none}body{position:relative}*::-moz-focus-inner{border:0;padding:0}input{position:relative}input[type=text],input[type=password],input[type=textarea]{user-select:text;-moz-user-select:text;-khtml-user-select:text;-webkit-user-select:text;-ms-user-select:text}input[type=text][readonly],input[type=password][readonly],input[type=textarea][readonly]{user-select:none;-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none}.x-box-item input{position:static}.x-window-header{height:18px}.x-window-header-text{line-height:18px;white-space:nowrap;display:block;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis}.x-masked{overflow:visible !important}.sds-window-mask{z-index:102}.ext-el-mask{z-index:20000}#sds-wallpaper{visibility:hidden;position:absolute;z-index:-2}.ext-ie #sds-desktop{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNgAAIAAAUAAen63NgAAAAASUVORK5CYII=)}.x-window-ml{padding-left:0px}.x-window-mr{padding-right:0px}.x-window-mc,.x-window-dlg .x-window-mc,.x-window-plain .x-window-mc{border-width:0 1px 0 1px !important;border-style:solid !important;border-color:#D0D0D0 #AAAFB4 !important}.x-window-dlg .x-window-mc{border-bottom:0 !important}.x-window-maximized .x-window-mc{border-left:1px solid #AAAFB4;border-right:1px solid #AAAFB4}.x-window-body{background-color:#FAFAFA;border-top:1px solid #AAA;border-bottom:1px solid #AAA}.x-window-dlg .x-window-footer{margin-left:-6px}.x-panel-nofooter .x-panel-bc,.x-panel-nofooter .x-window-bc{height:0px}.x-window-maximized .x-window-bc{height:0}.x-resizable-over .x-resizable-handle-southeast,.x-resizable-pinned .x-resizable-handle-southeast{width:12px;height:12px;margin:3px;background:transparent;-moz-opacity:1.0;opacity:1.0;filter:none}ul.x-tab-strip li{margin-left:4px}.x-tab-strip span.x-tab-strip-text{padding-left:10px;padding-right:10px;color:#3C3C3C}.x-tab-strip-active span.x-tab-strip-text{color:#002D4D}.x-form-display-field{padding-top:3px;padding-bottom:4px}.ext-gecko .x-form-display-field,.ext-strict .ext-ie7 .x-form-display-field{padding-top:3px;padding-bottom:4px}.x-form-check-wrap{padding:2px 0}.ext-ie7 .x-form-check-wrap{padding:1px 0}.x-window-mc{background:#ffffff none}.x-border-layout-ct,.x-panel-body{background:transparent none}.x-tree .x-panel-body{background-color:transparent}.x-window .x-toolbar-cell .x-btn{margin:2px 3px}.x-window .x-btn button{padding-left:15px;padding-right:15px}.x-window-bbar .x-toolbar-cell .x-btn,.x-panel-bbar .x-toolbar-cell .x-btn{margin:0}.x-window-bbar .x-btn button,.x-panel-bbar .x-btn button{padding:0}.ext-opera .x-form-field-trigger-wrap{overflow:hidden}ul.sds-desktop-shortcut{position:relative;float:left;width:86px;margin:0 0 0 16px}li.launch-icon .text,li.launch-icon .text a{width:100%;font-size:12px;line-height:16px;text-align:center;margin:0 auto;overflow:visible;text-overflow:ellipsis;-o-text-overflow:ellipsis}li.launch-icon{list-style-type:none}li.launch-icon.transition-cls{transition-property:left, top;transition-duration:0.5s;-webkit-transition-property:left, top;-webkit-transition-duration:0.5s;-moz-transition-property:left, top;-moz-transition-duration:0.5s;-o-transition-property:left, top;-o-transition-duration:0.5s}#sds-desktop li.launch-icon .text,#sds-desktop li.launch-icon .text a{color:#FFFFFF}.ext-chrome.syno-cjk #sds-appview .app-panel-title,.ext-chrome.syno-cjk #sds-appview .sds-appview-app-item-title,.ext-chrome.syno-cjk #sds-desktop li.launch-icon .text,.ext-chrome.syno-cjk #sds-desktop li.launch-icon .text a{text-shadow:none}#sds-desktop li.launch-icon.x-btn-click .text,#sds-desktop li.launch-icon.x-btn-click .text a{color:#8C8C8C}.sds-desktop-select-range{position:absolute;background-color:rgba(255,255,255,0.3);border:solid 1px white;opacity:1}.ext-ie .sds-desktop-select-range{background:transparent;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4CFFFFFF,endColorstr=#4CFFFFFF);zoom:1}.sds-desktop-icon-selected{background-color:rgba(255,255,255,0.3);border-radius:10px;-moz-border-radius:10px}.ext-ie .sds-desktop-icon-selected{background:transparent;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4CFFFFFF,endColorstr=#4CFFFFFF);zoom:1}.sds-launchbox li.launch-icon{position:absolute;width:95px;height:98px;margin:12px 0 0 7px}.sds-launchbox li.launch-icon .image{width:48px;height:48px}.sds-launchbox li.launch-icon .text,.sds-launchbox li.launch-icon .text a{font-size:11px;color:#3C3C3C}.sds-launchbox li.launch-icon.x-btn-over .text,.sds-launchbox li.launch-icon.x-btn-over .text a{color:#000000}.sds-launchbox li.launch-icon.x-btn-click .text,.sds-launchbox li.launch-icon.x-btn-click .text a{font-size:11px;color:#3C3C3C}.x-panel-body,.x-tab-panel-body,.x-tab-panel-footer,.x-window-plain .x-window-mc{background-color:#FAFAFA}.x-fieldset,.x-tab-panel-bwrap,.x-tab-panel-body{border-color:#7AAACC}.x-tab-panel-header-plain .x-tab-strip-spacer,.x-tab-panel-footer-plain .x-tab-strip-spacer{background-color:#D2EDFD;border-color:#3D7299}ul.x-tab-strip-top{border-bottom-color:#3D7299}.x-btn button{color:#3C3C3C}.x-tab-strip-top .x-tab-right,.x-tab-strip-top .x-tab-left,.x-tab-strip-top .x-tab-strip-inner{background-image:url(../images/tab_a.png)}.x-tab-strip-top .x-tab-right{padding-left:8px;background-position:0 0}.x-tab-strip-top .x-tab-left{padding-right:8px;background-position:right -100px}.x-tab-strip-top .x-tab-strip-inner{background-position:0 -50px}.x-tab-strip-top .x-tab-strip-over .x-tab-right{background-position:0 -150px}.x-tab-strip-top .x-tab-strip-over .x-tab-left{background-position:right -250px}.x-tab-strip-top .x-tab-strip-over .x-tab-strip-inner{background-position:0 -200px}.x-tab-strip-top .x-tab-strip-active .x-tab-right{background-position:0 -300px}.x-tab-strip-top .x-tab-strip-active .x-tab-left{background-position:right -400px}.x-tab-strip-top .x-tab-strip-active .x-tab-strip-inner{background-position:0 -350px}ul.x-tab-strip-bottom{background:url("../images/tab_bg_b.png") repeat-x !important;padding-bottom:2px;border-top-color:#AAAFB4}.x-tab-panel-noborder .x-tab-panel-footer-noborder{background-color:#F6F7F8;border-color:#AAAFB4}.x-layout-split.x-splitbar-v{background:url("../images/split_hcolumn.png") repeat-x scroll 0 0 transparent}.x-tab-strip-bottom .x-tab-right,.x-tab-strip-bottom .x-tab-left,.x-tab-strip-bottom .x-tab-strip-inner{background-image:url("../images/tab_b.png") !important}.x-tab-strip-bottom .x-tab-right{background-position:right -128px;padding-right:5px}.x-tab-strip-bottom .x-tab-left{background-position:0 -28px;padding-left:5px;padding-right:0}.x-tab-strip-bottom .x-tab-strip-inner{background-position:0 -78px;height:23px}.x-tab-strip-bottom .x-tab-strip-over .x-tab-right{background-position:right -278px}.x-tab-strip-bottom .x-tab-strip-over .x-tab-left{background-position:0 -178px}.x-tab-strip-bottom .x-tab-strip-over .x-tab-strip-inner{background-position:0 -228px}.x-tab-strip-bottom .x-tab-strip-active .x-tab-right{background-position:right -427px}.x-tab-strip-bottom .x-tab-strip-active .x-tab-left{background-position:0 -327px}.x-tab-strip-bottom .x-tab-strip-active .x-tab-strip-inner{background-position:0 -377px}.deactive-win .x-tool-minimize{background-position:0 -306px}.deactive-win .x-tool-maximize{background-position:0 -288px}.deactive-win .x-tool-close{background-position:0 -270px}.deactive-win .x-tool-restore{background-position:0 -324px}.deactive-win .x-tool-help{background-position:0 -342px}.x-tool-minimize{background-position:0 -108px;background-image:url(../images/bt_rt.png);width:18px;height:18px}.x-tool-minimize-over{background-position:0 -126px}.x-tool-maximize{background-position:0 -54px;background-image:url(../images/bt_rt.png);width:18px;height:18px}.x-tool-maximize-over{background-position:0 -72px}.x-tool-close{background-position:0 0;background-image:url(../images/bt_rt.png);width:18px;height:18px}.x-tool-close-over{background-position:0 -18px}.x-tool-restore{background-position:0 -162px;background-image:url(../images/bt_rt.png);width:18px;height:18px}.x-tool-restore-over{background-position:0 -180px;background-image:url(../images/bt_rt.png)}.x-tool-help{background-position:0 -216px;background-image:url(../images/bt_rt.png);width:18px;height:18px}.x-tool-help-over{background-position:0 -234px;background-image:url(../images/bt_rt.png)}.sds-window .x-btn .sds-window-tbar-help{background-position:0 0;background-image:url(../images/help_a.png);width:22px;height:22px;padding:0px}.sds-window .x-btn-over .sds-window-tbar-help{background-position:0 -22px}.sds-window .x-btn-click .sds-window-tbar-help{background-position:0 -44px}.active-win .x-window-tl{background-image:url("../images/title3_01.png");padding-left:8px}.active-win .x-window-tr{background-image:url("../images/title3_03.png");padding-right:8px}.active-win .x-window-tc{background-image:url("../images/title3_02.png")}.active-win .x-window-tbar .x-toolbar{background-image:url("../images/title3_02.png");background-position:0 -26px}.deactive-win .x-window-tl{background-image:url("../images/title3_01.png");padding-left:8px;background-position:0 -88px}.deactive-win .x-window-tr{background-image:url("../images/title3_03.png");padding-right:8px;background-position:right -88px}.deactive-win .x-window-tc{background-image:url("../images/title3_02.png");background-position:0 -88px}.deactive-win .x-window-tbar .x-toolbar{background-image:url("../images/title3_02.png");background-position:0 -114px}.active-win .x-window-bl{background-image:url("../images/bottom48_01.png")}.active-win .x-window-br{background-image:url("../images/bottom48_03_01.png");padding-right:8px}.active-win .x-window-bc{background-image:url("../images/bottom48_02_01.png")}.deactive-win .x-window-bl{background-image:url("../images/bottom48_01.png");background-position:-8px bottom}.deactive-win .x-window-br{background-image:url("../images/bottom48_03_02.png");padding-right:8px}.deactive-win .x-window-bc{background-image:url("../images/bottom48_02_02.png")}.pre-load-deactive-win-x-window-br{background-image:url("../images/bottom48_03_02.png");position:-9999px -99999px}.x-fieldset legend{color:#003C66}.sds-window .x-window-bc .x-window-footer{padding:0}body,.ext-el-mask-msg div,.x-tab-strip span.x-tab-strip-text,.x-form-field,.x-form-grow-sizer,.x-form-grow-sizer,.x-form-item,.x-form-invalid-msg,.x-fieldset legend,.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label,.x-grid-group-hd div.x-grid-group-title,.x-grid-empty,.x-tip .x-tip-mc,.x-tip .x-tip-header-text,.x-tip .x-tip-body,.x-window-mc,.x-window-dlg .ext-mb-textarea{font-family:verdana, tahoma, arial, helvetica, sans-serif}.x-small-editor .x-form-field,.ext-webkit .x-small-editor .x-form-field,.x-grid3-hd-row td,.x-grid3-row td,.x-grid3-summary-row td,.x-grid3-topbar,.x-grid3-bottombar,.x-tree-node,.x-date-inner th,.x-date-inner a,.x-date-mp td,.x-date-mp-btns button,.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label,.x-list-header-inner div em,.x-list-body dt em{font-family:verdana, arial, tahoma, helvetica, sans-serif}.x-btn{font-family:verdana, tahoma, helvetica}.x-btn button{font-family:verdana, arial, tahoma, helvetica}.x-dd-drag-ghost{font-family:verdana, arial, helvetica, sans-serif}.x-date-middle,.x-date-left,.x-date-right{font-family:verdana, "sans serif", tahoma, verdana, helvetica}.x-menu-list-item{font-family:verdana, arial, tahoma, sans-serif}.x-combo-list,.x-combo-list-hd,.x-combo-list-small,.x-panel-tl .x-panel-header,.x-panel-mc{font-family:verdana, tahoma, arial, helvetica, sans-serif}.x-btn button{font-family:verdana, arial,tahoma,verdana,helvetica}.x-ie-shadow{background-color:#333}.x-shadow .xsmc{background-image:url(../images/shadow-c.png)}.x-shadow .xsml,.x-shadow .xsmr{background-image:url(../images/shadow-lr.png)}.x-shadow .xstl,.x-shadow .xstc,.x-shadow .xstr,.x-shadow .xsbl,.x-shadow .xsbc,.x-shadow .xsbr{background-image:url(../images/shadow.png)}.without-dirty-red-grid .x-grid3-dirty-cell{background:none}.x-grid-group-hd{background-image:url(../images/grid_title_bg.png);padding-top:2px;border:none}.x-grid-group-hd div.x-grid-group-title{color:#003C66}.x-grid3-row{background-color:#FAFAFA}.x-grid3-row-alt{background-color:#F5F5F5}.x-grid3-row-over{background-image:none;background-color:#E6F0FA;border-color:#DCE6F0}.x-grid3-row-selected{background-color:#CEE0F3 !important}.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell{border-right-color:#E1E6EB}.x-btn-icon .x-btn-small .x-btn-tl,.x-btn-icon .x-btn-small .x-btn-tr,.x-btn-icon .x-btn-small .x-btn-tc,.x-btn-icon .x-btn-small .x-btn-ml,.x-btn-icon .x-btn-small .x-btn-mr,.x-btn-icon .x-btn-small .x-btn-mc,.x-btn-icon .x-btn-small .x-btn-bl,.x-btn-icon .x-btn-small .x-btn-br,.x-btn-icon .x-btn-small .x-btn-bc{background-image:none}.x-btn-icon .x-btn-small .x-tbar-page-first{width:22px;height:18px;background-image:url(../images/bt_pagebar.png) !important;background-position:0 0}.x-btn-icon .x-btn-small .x-tbar-loading{width:22px;height:18px;background-image:url(../images/bt_pagebar.png) !important;background-position:0 -72px}.x-btn-icon .x-btn-small .x-tbar-page-last{width:22px;height:18px;background-image:url(../images/bt_pagebar.png) !important;background-position:0 -54px}.x-btn-icon .x-btn-small .x-tbar-page-next{width:22px;height:18px;background-image:url(../images/bt_pagebar.png) !important;background-position:0 -36px}.x-btn-icon .x-btn-small .x-tbar-page-prev{width:22px;height:18px;background-image:url(../images/bt_pagebar.png) !important;background-position:0 -18px}.x-btn-icon.x-item-disabled .x-tbar-loading,.x-btn-icon .x-btn-small .x-item-disabled .x-tbar-loading{width:22px;height:18px;background-image:url(../images/bt_pagebar.png) !important;background-position:0 -342px}.x-btn-icon.x-item-disabled .x-tbar-page-first,.x-btn-icon .x-btn-small .x-item-disabled .x-tbar-page-first{width:22px;height:18px;background-image:url(../images/bt_pagebar.png) !important;background-position:0 -270px}.x-btn-icon.x-item-disabled .x-tbar-page-last,.x-btn-icon .x-btn-small .x-item-disabled .x-tbar-page-last{width:22px;height:18px;background-image:url(../images/bt_pagebar.png) !important;background-position:0 -324px}.x-btn-icon.x-item-disabled .x-tbar-page-next,.x-btn-icon .x-btn-small .x-item-disabled .x-tbar-page-next{width:22px;height:18px;background-image:url(../images/bt_pagebar.png) !important;background-position:0 -306px}.x-btn-icon.x-item-disabled .x-tbar-page-prev,.x-btn-icon .x-btn-small .x-item-disabled .x-tbar-page-prev{width:22px;height:18px;background-image:url(../images/bt_pagebar.png) !important;background-position:0 -288px}.x-btn-over .x-btn-small .x-tbar-page-first{background-image:url(../images/bt_pagebar.png) !important;background-position:0 -90px}.x-btn-over .x-btn-small .x-tbar-loading{background-image:url(../images/bt_pagebar.png) !important;background-position:0 -162px}.x-btn-over .x-btn-small .x-tbar-page-last{background-image:url(../images/bt_pagebar.png) !important;background-position:0 -144px}.x-btn-over .x-btn-small .x-tbar-page-next{background-image:url(../images/bt_pagebar.png) !important;background-position:0 -126px}.x-btn-over .x-btn-small .x-tbar-page-prev{background-image:url(../images/bt_pagebar.png) !important;background-position:0 -108px}.x-btn-click .x-btn-small .x-tbar-page-first{background-image:url(../images/bt_pagebar.png) !important;background-position:0 -180px}.x-btn-click .x-btn-small .x-tbar-loading{background-image:url(../images/bt_pagebar.png) !important;background-position:0 -252px}.x-btn-click .x-btn-small .x-tbar-page-last{background-image:url(../images/bt_pagebar.png) !important;background-position:0 -234px}.x-btn-click .x-btn-small .x-tbar-page-next{background-image:url(../images/bt_pagebar.png) !important;background-position:0 -216px}.x-btn-click .x-btn-small .x-tbar-page-prev{background-image:url(../images/bt_pagebar.png) !important;background-position:0 -198px}.x-btn-tl,.x-btn-tr,.x-btn-tc,.x-btn-bl,.x-btn-br,.x-btn-bc{background-image:none;display:none}.x-btn-icon .x-btn-small .x-tbar-loading-process{background-image:url("../images/desktop/icon_loading.gif") !important;height:18px;width:22px}.x-btn-tl,.x-btn-tr,.x-btn-tc,.x-btn-bl,.x-btn-br,.x-btn-bc{background-image:none;display:none}.x-btn-ml,.x-btn-mr,.x-btn-mc{background-image:url("../images/bt_b.png");height:22px}.x-btn-ml{background-position:0 0 !important}.x-btn-mc{background-position:0 -22px !important}.x-btn-mr{background-position:right -44px !important}.x-btn-over .x-btn-ml{background-position:0 -66px !important}.x-btn-over .x-btn-mc{background-position:0 -88px !important}.x-btn-over .x-btn-mr{background-position:right -110px !important}.x-btn-click .x-btn-ml{background-position:0 -132px !important}.x-btn-click .x-btn-mc{background-position:0 -154px !important}.x-btn-click .x-btn-mr{background-position:right -176px !important}.x-item-disabled .x-btn-ml{background-position:0 -198px !important}.x-item-disabled .x-btn-mc{background-position:0 -220px !important}.x-item-disabled .x-btn-mr{background-position:right -242px !important}.x-btn-text{color:#3C3C3C}.x-btn-over .x-btn-text{color:#004A80}.x-btn-click .x-btn-text{color:#003C66}.x-item-disabled .x-btn-text{color:#8C8C8C}.x-form-field-wrap .x-form-trigger{background-image:url("../images/trigger.png");border-bottom-color:#6E7378}.x-form-field-wrap .x-form-date-trigger{background-image:url("../images/date-trigger.png");border-bottom-color:#6E7378}.x-form-field-wrap .x-form-trigger-over{border-bottom-color:#2E6C99}.x-trigger-wrap-focus .x-form-trigger{border-bottom-color:#2E6C99}.x-form-focus,textarea.x-form-focus{border-color:#2E6C99}.x-form-text,textarea.x-form-field{border-color:#6E7378}.active-win .x-window-tl .x-window-header{color:#3c3c3c}.deactive-win .x-window-tl .x-window-header{color:#787878}.x-window-dlg.sds-window .x-window-body{background:#D2D7DC;border-top:1px solid #AAAAAA !important}.x-window-dlg.sds-window .x-window-bc{padding-bottom:8px}.x-item-disabled{opacity:1 !important;-moz-opacity:1 !important;filter:none !important}input.x-item-disabled.x-form-text,.x-item-disabled input.x-form-text,input.x-item-disabled.x-form-file,.x-item-disabled input.x-form-file{background:#EEE;border:1px solid #AAA}.ext-webkit input.x-item-disabled.x-form-file,.ext-webkit .x-item-disabled input.x-form-file{background:none;border:none}.x-fieldset-header-text{line-height:1.5}#sds-apply-preview-form{position:absolute;background-image:url(../images/preview_bar_bg.png);width:100%;height:39px;color:#ddd;padding-top:5px;z-index:20001}#sds-apply-preview-form div.x-form-item{float:left;padding:2px 8px 0px}.ext-ie #sds-apply-preview-form div.x-form-item{padding:6px 8px 0px}#sds-apply-preview-form .x-btn{float:left;padding-left:10px}#sds-apply-preview-form td{background-image:none}#sds-apply-preview-form td.x-btn-ml,#sds-apply-preview-form td.x-btn-mc,#sds-apply-preview-form td.x-btn-mr{height:24px;background-image:url(../images/preview_bar_bt.png)}#sds-apply-preview-form .x-btn td.x-btn-ml,#sds-apply-preview-form .x-btn td.x-btn-mr{width:6px}#sds-apply-preview-form .x-btn td.x-btn-ml{background-position:0px 0px !important}#sds-apply-preview-form .x-btn td.x-btn-mc{background-position:0px -24px !important}#sds-apply-preview-form .x-btn td.x-btn-mr{background-position:0px -48px !important}#sds-apply-preview-form .x-btn-over td.x-btn-ml{background-position:0px -72px !important}#sds-apply-preview-form .x-btn-over td.x-btn-mc{background-position:0px -96px !important}#sds-apply-preview-form .x-btn-over td.x-btn-mr{background-position:0px -120px !important}#sds-apply-preview-form button{color:#fff}.x-tip .x-tip-body,.x-window-dlg .ext-mb-text,.x-window-dlg .ext-mb-content{word-wrap:break-word}.x-panel-ghost-simple{z-index:12000;position:absolute;border:2px solid #808080;cursor:move !important}.x-tree-node-collapsed .x-tree-node-icon{background-image:url("../images/folder.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .x-tree-node-collapsed .x-tree-node-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/folder.png");background-size:16px 16px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .x-tree-node-collapsed .x-tree-node-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/folder.png");background-size:16px 16px;outline:1px green dashed}}.x-tree-node-expanded .x-tree-node-icon{background-image:url("../images/folder.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .x-tree-node-expanded .x-tree-node-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/folder.png");background-size:16px 16px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .x-tree-node-expanded .x-tree-node-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/folder.png");background-size:16px 16px;outline:1px green dashed}}.ext-ie9 .x-btn button,.ext-ie8 .x-btn button{padding-top:0px}.ext-ie9.syno-cjk .x-form-check-wrap{line-height:15px}.ext-ie9.syno-cjk .x-btn .ux-pathbutton-center button{padding-top:4px;line-height:16px}.ext-ie9.syno-cjk .x-btn button,.ext-ie8.syno-cjk .x-btn button{padding-top:2px}.syno-webfm .file-drag-over .ext-el-mask{background-color:#75fa32;background-color:rgba(117,250,50,0.05)}.syno-webfm .file-drag-over .ext-el-mask-msg{background-color:transparent !important;background-image:url(../images/drop_files_texts_area.png);width:258px;height:48px;border:0 !important;padding:0;box-shadow:0px 0px 0px !important}.syno-webfm .file-drag-over .ext-el-mask-msg div{background-color:transparent !important;border-color:transparent;font-size:16px;width:258px;line-height:48px;text-align:center;border:0px !important;padding:0;color:#FFFFFF !important}.file-drag-over.file-drop-curved .ext-el-mask{background-color:#8ab8e6;-moz-opacity:0.75;opacity:0.75}.file-drag-over.file-drop-curved .ext-el-mask-msg{height:108px;width:236px;background-image:url(../images/drop_files_area_curved.png);background-color:transparent !important;border:0 !important;padding:0 !important}.file-drag-over.file-drop-curved .ext-el-mask-msg div{font-size:13px;color:#000;padding-top:50px;height:58px;text-align:center;line-height:58px;background-color:transparent !important;border:none;margin-right:auto;margin-left:auto}.ext-gecko4 .x-window-tc,.x-window-bc{background-color:gray}.ext-gecko4 .x-window-bl,.ext-gecko4 .x-window-br{border-bottom-right-radius:2px}.ext-gecko4 .x-window-bl{background-color:gray;border-bottom-left-radius:2px}.ext-gecko4 .x-window-tl,.ext-gecko4 .x-window-tr{background-color:gray;border-top-right-radius:2px}.ext-gecko4 .x-window-tl{border-top-left-radius:2px}.syno-input-non-border{background-color:#FAFAFA;background-image:none;border:1px solid transparent !important;padding:0;margin:0}.sds-expose-mask{position:absolute;left:0px;top:0px;width:100%;height:100%;background:#000;opacity:0;transition-delay:0s;transition-property:opacity;transition-duration:0.8s;-webkit-transition-delay:0s;-webkit-transition-property:opacity;-webkit-transition-duration:0.8s;-moz-transition-delay:0s;-moz-transition-property:opacity;-moz-transition-duration:0.8s}.sds-expose-win-mask{position:absolute;left:0px;top:0px;width:100%;height:100%;background:transparent;z-index:9999;box-shadow:0 0 10px 10px rgba(0,0,0,0.3);-moz-box-shadow:0 0 10px 10px rgba(0,0,0,0.3);border-radius:5px;-moz-border-radius:5px}.sds-expose-win-mask.sds-expose-win-over{box-shadow:0 0 10px 10px rgba(255,255,255,0.5);-moz-box-shadow:0 0 10px 10px rgba(255,255,255,0.5);border-radius:5px;-moz-border-radius:5px}.sds-expose-win-transform{-webkit-transform-origin:0% 0%;-moz-transform-origin:0% 0%;-o-transform-origin:0% 0%;transform-origin:0% 0%;-webkit-transition-delay:0.1s;-webkit-transition-property:-webkit-transform;-webkit-transition-duration:0.8s;-webkit-backface-visibility:hidden;-webkit-perspective:1000;-moz-transition-delay:0.1s;-moz-transition-property:-moz-transform;-moz-transition-duration:0.8s;transition-delay:0.1s;transition-property:transform;transition-duration:0.8s}.sds-expose-win-transform.sds-expose-win-transform-restore{transition-duration:0.3s;-webkit-transition-duration:0.3s;-moz-transition-duration:0.3s}.sds-expose-win-hidden{position:absolute !important;top:-10000px !important;left:-10000px !important}.sds-expose-desc-ct{position:absolute;text-align:center;z-index:12000;cursor:default}.sds-expose-desc-img{display:inline-block}.sds-expose-desc-text{display:inline-block;font-size:12pt;color:#FFFFFF;font-weight:bold;vertical-align:4px;margin-left:15px;text-shadow:0.1em 0.1em 0.1em #000000}.sds-grouping-show-big-preview .sds-grouping-preview-icon{visibility:hidden}.sds-grouping-show-big-preview .sds-grouping-big-preview-icon{visibility:visible}.x-dd-drag-ghost .sds-grouping-show-big-preview .sds-grouping-preview-icon{visibility:visible;position:relative !important;left:7px !important;top:6px !important;padding:0 1px}.x-dd-drag-ghost .sds-grouping-show-big-preview .sds-grouping-big-preview-icon{visibility:hidden}.sds-launch-icon-input{position:absolute;border-color:#3182c1;background-color:#FFF;color:#000;font-size:14px;padding:1px;width:86px;font-family:verdana, tahoma, arial, helvetica, sans-serif;border:2px solid transparent}.sds-ellipsis{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}.ext-strict .ext-ie9 .x-date-menu{height:auto}.x-tree-node,.launch-icon,.x-grid3-cell,.x-menu-item{-webkit-touch-callout:none}input.x-form-text{border-radius:0}#sds-desktop.sds-is-gesture-switching .x-shadow{visibility:hidden}.sds-hidden-scrollpanel .x-list-body-inner{display:inline-block;width:100%;height:100%}.x-panel-ghost ul{background-color:#f2f2f2}.x-panel-ghost{background-color:transparent}.sds-user-about-mask{position:absolute;top:0;left:0;right:0;bottom:0;background-color:#000000;z-index:1000;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=20);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=20);opacity:0.2}a{text-decoration:none}.ext-ie9 #sds-desktop li.launch-icon .text,.ext-ie8m #sds-desktop li.launch-icon .text,.ext-ie9 #sds-desktop li.launch-icon .text a,.ext-ie8m #sds-desktop li.launch-icon .text a,.ext-ie9 #sds-login-dialog-title,.ext-ie8m #sds-login-dialog-title{filter:none !important}input[type=text]::-ms-clear{display:none}input[type=password]::-ms-reveal{display:none}div{-ms-touch-action:none;touch-action:none}.ext-ie11 .x-tree-node-indent img,.ext-ie11 .x-tree-node-icon,.ext-ie11 .x-tree-ec-icon{vertical-align:middle !important}.sds-switch-win-gesture-hide-to-left{-webkit-transform-origin:0% 0%;-moz-transform-origin:0% 0%;-ms-transform-origin:0% 0%;-o-transform-origin:0% 0%;transform-origin:0% 0%;-webkit-transition-delay:0.1s;-moz-transition-delay:0.1s;-o-transition-delay:0.1s;transition-delay:0.1s;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;transition-property:transform;-webkit-transition-duration:0.8s;-moz-transition-duration:0.8s;-o-transition-duration:0.8s;transition-duration:0.8s;-webkit-transform:translate3d(-2000px, 0px, 0);-moz-transform:translate3d(-2000px, 0px, 0);-ms-transform:translate3d(-2000px, 0px, 0);-o-transform:translate3d(-2000px, 0px, 0);transform:translate3d(-2000px, 0px, 0);-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;-moz-perspective:1000;-ms-perspective:1000;-o-perspective:1000;perspective:1000}.sds-switch-win-gesture-hide-to-right{-webkit-transform-origin:0% 0%;-moz-transform-origin:0% 0%;-ms-transform-origin:0% 0%;-o-transform-origin:0% 0%;transform-origin:0% 0%;-webkit-transition-delay:0.1s;-moz-transition-delay:0.1s;-o-transition-delay:0.1s;transition-delay:0.1s;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;transition-property:transform;-webkit-transition-duration:0.8s;-moz-transition-duration:0.8s;-o-transition-duration:0.8s;transition-duration:0.8s;-webkit-transform:translate3d(2000px, 0px, 0);-moz-transform:translate3d(2000px, 0px, 0);-ms-transform:translate3d(2000px, 0px, 0);-o-transform:translate3d(2000px, 0px, 0);transform:translate3d(2000px, 0px, 0);-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;-moz-perspective:1000;-ms-perspective:1000;-o-perspective:1000;perspective:1000}.sds-switch-win-gesture-show-from-left{-webkit-transform-origin:0% 0%;-moz-transform-origin:0% 0%;-ms-transform-origin:0% 0%;-o-transform-origin:0% 0%;transform-origin:0% 0%;-webkit-transform:translate3d(-2000px, 0px, 0);-moz-transform:translate3d(-2000px, 0px, 0);-ms-transform:translate3d(-2000px, 0px, 0);-o-transform:translate3d(-2000px, 0px, 0);transform:translate3d(-2000px, 0px, 0)}.sds-switch-win-gesture-show-from-right{-webkit-transform-origin:0% 0%;-moz-transform-origin:0% 0%;-ms-transform-origin:0% 0%;-o-transform-origin:0% 0%;transform-origin:0% 0%;-webkit-transform:translate3d(2000px, 0px, 0);-moz-transform:translate3d(2000px, 0px, 0);-ms-transform:translate3d(2000px, 0px, 0);-o-transform:translate3d(2000px, 0px, 0);transform:translate3d(2000px, 0px, 0)}.sds-switch-win-gesture-show-force-hidden{visibility:hidden !important}.sds-switch-win-gesture-show-transition{-webkit-transition-delay:0.1s;-moz-transition-delay:0.1s;-o-transition-delay:0.1s;transition-delay:0.1s;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;transition-property:transform;-webkit-transition-duration:0.5s;-moz-transition-duration:0.5s;-o-transition-duration:0.5s;transition-duration:0.5s;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;-moz-perspective:1000;-ms-perspective:1000;-o-perspective:1000;perspective:1000}.sds-widget-window .x-window-tl .x-window-header .x-tool,.sds-widget-window .x-window-tl .x-window-header.sds-widget-over .x-tool{-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0.2s;-moz-transition-duration:0.2s;-o-transition-duration:0.2s;transition-duration:0.2s}.sds-window-v5 .ext-el-mask-msg div,.sds-widget-window .ext-el-mask-msg div{line-height:24px;font-size:16px;color:#505A64;border:0px}.sds-window-v5 .ext-el-mask-msg,.sds-widget-window .ext-el-mask-msg{-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;padding:0;border-color:#C8D2DC;overflow:hidden;box-shadow:0px 1px 4px rgba(0,0,0,0.25)}.sds-window-v5,.sds-widget-window{box-shadow:0px 2px 8px rgba(0,0,0,0.5)}.sds-window-v5 .x-panel-tbar .x-toolbar-layout-ct,.sds-widget-window .x-panel-tbar .x-toolbar-layout-ct{padding-bottom:8px}.ext-ie8 .sds-window-v5,.ext-ie8 .sds-widget-window{border:1px solid #999;border-top-style:none}.sds-window-v5.sds-window-v5-no-shadow,.sds-window-v5-no-shadow.sds-widget-window{box-shadow:none}.sds-window-v5.no-resize .x-resizable-handle,.no-resize.sds-widget-window .x-resizable-handle{width:0px !important;height:0px !important}.sds-window-v5 .ext-el-mask,.sds-widget-window .ext-el-mask{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=50);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=50);opacity:0.5;background-color:#FFFFFF}.sds-window-v5 .ext-el-mask-msg,.sds-widget-window .ext-el-mask-msg{background-color:#FFFFFF}.sds-window-v5 .ext-el-mask-msg div,.sds-widget-window .ext-el-mask-msg div{padding:7px 20px 7px 20px;background-color:#FFFFFF}.sds-window-v5 .x-window-tl,.sds-widget-window .x-window-tl,.sds-window-v5 .x-window-tc,.sds-widget-window .x-window-tc,.sds-window-v5 .x-window-tr,.sds-widget-window .x-window-tr{background-image:none}.sds-window-v5 .x-window-ml,.sds-widget-window .x-window-ml,.sds-window-v5 .x-window-mc,.sds-widget-window .x-window-mc,.sds-window-v5 .x-window-mr,.sds-widget-window .x-window-mr{background-image:none}.sds-window-v5 .x-window-bwrap .x-window-bl,.sds-widget-window .x-window-bwrap .x-window-bl,.sds-window-v5 .x-window-bwrap .x-window-bc,.sds-widget-window .x-window-bwrap .x-window-bc,.sds-window-v5 .x-window-bwrap .x-window-br,.sds-widget-window .x-window-bwrap .x-window-br{background-image:none;padding:0}.sds-window-v5 .x-window-mc,.sds-widget-window .x-window-mc{border:0 !important;background-color:#FFFFFF}.sds-window-v5 .x-window-tl,.sds-widget-window .x-window-tl{background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwODZlNSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #0086e5), color-stop(100%, #ffffff));background-image:-webkit-linear-gradient(#0086e5,#ffffff);background-image:-moz-linear-gradient(#0086e5,#ffffff);background-image:-o-linear-gradient(#0086e5,#ffffff);background-image:linear-gradient(#0086e5,#ffffff);background-color:#FFFFFF;border-top:3px solid #0086E5;padding-left:12px;padding-bottom:0}.sds-window-v5 .x-window-tr,.sds-widget-window .x-window-tr{padding-right:12px}.sds-window-v5 .x-window-header,.sds-widget-window .x-window-header{height:24px;padding:4px 0 5px 0;padding-left:0px !important;background-size:24px 24px}.sds-window-v5 .x-window-header-text,.sds-widget-window .x-window-header-text{line-height:24px;font-size:13px;font-weight:bold;text-align:center;color:#0086E5}.sds-window-v5 .x-tool,.sds-widget-window .x-tool{width:24px;height:24px;margin-left:8px;background-image:url("../images/rt_button.png");background-repeat:no-repeat}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5 .x-tool,.synohdpack .sds-widget-window .x-tool{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/rt_button.png");background-size:24px 768px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5 .x-tool,.synohdpackdebug .sds-widget-window .x-tool{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/rt_button.png");background-size:24px 768px;outline:1px green dashed}}.sds-window-v5 .x-tool-close,.sds-widget-window .x-tool-close{background-position:0 0px}.sds-window-v5 .x-tool-close-over,.sds-widget-window .x-tool-close-over{background-position:0 -24px}.sds-window-v5 .x-tool-maximize,.sds-widget-window .x-tool-maximize{background-position:0 -96px}.sds-window-v5 .x-tool-maximize-over,.sds-widget-window .x-tool-maximize-over{background-position:0 -120px}.sds-window-v5 .x-tool-restore,.sds-widget-window .x-tool-restore{background-position:0 -192px}.sds-window-v5 .x-tool-restore-over,.sds-widget-window .x-tool-restore-over{background-position:0 -216px}.sds-window-v5 .x-tool-minimize,.sds-widget-window .x-tool-minimize{background-position:0 -288px}.sds-window-v5 .x-tool-minimize-over,.sds-widget-window .x-tool-minimize-over{background-position:0 -312px}.sds-window-v5 .x-tool-help,.sds-widget-window .x-tool-help{background-position:0 -384px}.sds-window-v5 .x-tool-help-over,.sds-widget-window .x-tool-help-over{background-position:0 -408px}.sds-window-v5.deactive-win .x-window-tl,.deactive-win.sds-widget-window .x-window-tl{border-top-color:#8C96A0;background-image:linear-gradient(#e6ebf0,#ffffff);background-position:0 0}.sds-window-v5.deactive-win .x-window-header,.deactive-win.sds-widget-window .x-window-header{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=60);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=60);opacity:0.6}.sds-window-v5.deactive-win .x-window-header-text,.deactive-win.sds-widget-window .x-window-header-text{color:#8C96A0}.sds-window-v5.deactive-win .x-tool-close,.deactive-win.sds-widget-window .x-tool-close{background-position:0 -72px}.sds-window-v5.deactive-win .x-tool-maximize,.deactive-win.sds-widget-window .x-tool-maximize{background-position:0 -168px}.sds-window-v5.deactive-win .x-tool-restore,.deactive-win.sds-widget-window .x-tool-restore{background-position:0 -264px}.sds-window-v5.deactive-win .x-tool-minimize,.deactive-win.sds-widget-window .x-tool-minimize{background-position:0 -360px}.sds-window-v5.deactive-win .x-tool-help,.deactive-win.sds-widget-window .x-tool-help{background-position:0 -456px}.sds-window-v5.syno-window-hide .vscrollerbar.scrollgeneric,.syno-window-hide.sds-widget-window .vscrollerbar.scrollgeneric,.sds-window-v5.syno-window-hide .hscrollerbar.scrollgeneric,.syno-window-hide.sds-widget-window .hscrollerbar.scrollgeneric{visibility:hidden !important}.sds-window-v5.x-window-maximized .x-window-tc,.x-window-maximized.sds-widget-window .x-window-tc{background-color:transparent}.sds-window-v5 .x-window-tbar .x-toolbar,.sds-widget-window .x-window-tbar .x-toolbar{background-image:none;background-color:white;padding:0 12px;border:0}.sds-window-v5 .x-window-body,.sds-widget-window .x-window-body{border:none;background-color:#FFF}.sds-window-v5 .x-window-bl,.sds-widget-window .x-window-bl{background-color:#FFF}.sds-window-v5 .x-window-bc,.sds-widget-window .x-window-bc{background-color:transparent}.sds-window-v5 .x-window-br,.sds-widget-window .x-window-br{padding-right:6px}.sds-window-v5 .x-panel-body,.sds-widget-window .x-panel-body{background-color:transparent}.sds-window-v5 .x-window-bc .x-window-footer,.sds-widget-window .x-window-bc .x-window-footer{padding:0}.sds-window-v5 .x-mask-loading div,.sds-widget-window .x-mask-loading div{padding:7px 20px 7px 52px;background-position:20px;background-image:url("../../../scripts/ext-3.4/ux/images/Components/icon_loading.gif")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5 .x-mask-loading div,.synohdpack .sds-widget-window .x-mask-loading div{background-image:url("../img/synohdpack/images/Components/icon_loading.gif");background-size:24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5 .x-mask-loading div,.synohdpackdebug .sds-widget-window .x-mask-loading div{background-image:url("../img/synohdpack/images/Components/icon_loading.gif");background-size:24px;outline:1px green dashed}}.sds-window-v5.x-window .x-toolbar-cell .x-btn,.x-window.sds-widget-window .x-toolbar-cell .x-btn{margin:0px 3px}.sds-window-v5 .x-toolbar,.sds-widget-window .x-toolbar{background-color:transparent;background-image:none}.sds-widget-window{width:322px;box-shadow:none;background:#f5faff;background:rgba(245,250,255,0.85);border:1px solid #AFB9C3}.ext-ie8 .sds-widget-window{border-top-style:solid}.sds-widget-window.x-window-maximized.scale-item.add-wdiget-effect{-webkit-transform:scale(0.8, 0.8);-moz-transform:scale(0.8, 0.8);-ms-transform:scale(0.8, 0.8);-o-transform:scale(0.8, 0.8);transform:scale(0.8, 0.8)}.sds-widget-window .x-window-mc{background-color:transparent}.sds-widget-window.sds-widget-window-medium .x-window-body{margin-bottom:1px}.sds-widget-window .x-window-body{-webkit-transition-property:height;-moz-transition-property:height;-o-transition-property:height;transition-property:height;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0.2s;-moz-transition-duration:0.2s;-o-transition-duration:0.2s;transition-duration:0.2s;margin-bottom:3px;background-color:transparent}.sds-widget-window.x-window-maximized .x-window-tl .x-window-tc{padding:0px}.sds-widget-window .x-window-tl{background-color:transparent !important;padding:1px 0 2px 4px;background-image:none !important;border-top:0px !important}.sds-widget-window .x-window-tl .x-window-header{background-repeat:no-repeat;padding:4px 0 4px 0;background-size:32px}.sds-widget-window .x-window-tl .x-window-header .icon-click{cursor:pointer;position:absolute;top:4px;width:32px;height:30px}.sds-widget-window .x-window-tl .x-window-header .x-window-header-text{text-align:left;color:#505A64;padding-left:34px;cursor:move}.sds-widget-window .x-window-tl .x-window-header .x-tool-add{background-position:0 -384px}.sds-widget-window .x-window-tl .x-window-header .x-tool-add.x-tool-disabled{background-position:0 -456px !important;cursor:move}.sds-widget-window .x-window-tl .x-window-header .x-tool-add-over{background-position:0 -408px}.sds-widget-window .x-window-tl .x-window-header .x-tool-pin{background-position:0 -480px}.sds-widget-window .x-window-tl .x-window-header .x-tool-pin.x-tool-disabled{background-position:0 -552px !important;cursor:move}.sds-widget-window .x-window-tl .x-window-header .x-tool-pin.x-tool-toggled{background-position:0 -528px}.sds-widget-window .x-window-tl .x-window-header .x-tool-pin-over{background-position:0 -504px}.sds-widget-window .x-window-tl .x-window-header .x-tool-close:active{background-position:0 -48px}.sds-widget-window .x-window-tl .x-window-header .x-tool-maximize:active{background-position:0 -144px}.sds-widget-window .x-window-tl .x-window-header .x-tool-restore:active{background-position:0 -240px}.sds-widget-window .x-window-tl .x-window-header .x-tool-minimize:active{background-position:0 -336px}.sds-widget-window .x-window-tl .x-window-header .x-tool-add:active{background-position:0 -432px}.sds-widget-window .x-window-tl .x-window-header .x-tool-pin:active{background-position:0 -528px}.sds-widget-window .x-window-tl .x-window-header .x-tool{opacity:0;visibility:hidden;background-image:url("../images/widget_window/widget_rt_button.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-widget-window .x-window-tl .x-window-header .x-tool{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/widget_window/widget_rt_button.png");background-size:24px 672px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-widget-window .x-window-tl .x-window-header .x-tool{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/widget_window/widget_rt_button.png");background-size:24px 672px;outline:1px green dashed}}.sds-widget-window .x-window-tl .x-window-header.sds-widget-over .x-tool{opacity:1;visibility:visible}.sds-widget-window .x-window-tr{padding-right:6px}.sds-widget-window.x-panel-ghost .x-tool{visibility:hidden}.sds-widget-window.x-window-maximized .x-window-draggable .x-window-header-text{cursor:move}.sds-widget-window.sds-widget-window-nodrop{cursor:no-drop}.sds-widget-window.sds-widget-window-nodrop .x-window-draggable .x-window-header-text{cursor:no-drop}.sds-widget-window .x-grid3-body,.sds-widget-window .x-grid3-row,.sds-widget-window .x-table-layout-ct{width:100% !important}.sds-widget-window .syno-sysinfo-system-health,.sds-widget-window .resource-monitor-widget,.sds-widget-window .sys-storage-grid{margin-top:-4px}.sds-window-v5.x-window-dlg,.x-window-dlg.sds-widget-window{color:#505a64}.ext-ie8 .sds-window-v5.x-window-dlg,.ext-ie8 .x-window-dlg.sds-widget-window{border-top-style:solid}.sds-window-v5.x-window-dlg input,.x-window-dlg.sds-widget-window input,.sds-window-v5.x-window-dlg textarea,.x-window-dlg.sds-widget-window textarea{color:#505a64}.sds-window-v5.x-window-dlg .x-window-tl,.x-window-dlg.sds-widget-window .x-window-tl{border-top:none;padding-bottom:0px}.sds-window-v5.x-window-dlg .ext-mb-icon,.x-window-dlg.sds-widget-window .ext-mb-icon{width:48px;height:48px}.sds-window-v5.x-window-dlg .ext-mb-question,.x-window-dlg.sds-widget-window .ext-mb-question{background-image:url("../images/icon_question.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5.x-window-dlg .ext-mb-question,.synohdpack .x-window-dlg.sds-widget-window .ext-mb-question{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/icon_question.png");background-size:48px 48px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5.x-window-dlg .ext-mb-question,.synohdpackdebug .x-window-dlg.sds-widget-window .ext-mb-question{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/icon_question.png");background-size:48px 48px;outline:1px green dashed}}.sds-window-v5.x-window-dlg .x-window-footer,.x-window-dlg.sds-widget-window .x-window-footer{padding:24px 20px 20px 20px;margin-left:0px}.sds-window-v5.x-window-dlg td.x-toolbar-cell,.x-window-dlg.sds-widget-window td.x-toolbar-cell{padding:0 0 0 10px}.sds-window-v5.x-window-dlg .x-toolbar-cell .x-btn,.x-window-dlg.sds-widget-window .x-toolbar-cell .x-btn{margin:0}.sds-window-v5.x-window-dlg .syno-mb-custom-btn,.x-window-dlg.sds-widget-window .syno-mb-custom-btn{position:absolute;bottom:20px;left:84px}.sds-window-v5.x-window-dlg .ext-mb-input,.x-window-dlg.sds-widget-window .ext-mb-input{height:24px}.sds-window-v5.x-window-dlg .ext-mb-content,.x-window-dlg.sds-widget-window .ext-mb-content{line-height:28px}.sds-window-v5.x-window-dlg .x-dlg-icon .ext-mb-content,.x-window-dlg.sds-widget-window .x-dlg-icon .ext-mb-content{margin-left:64px}.sds-window-v5.x-window-dlg .syno-mb-progress-status,.x-window-dlg.sds-widget-window .syno-mb-progress-status{position:absolute;right:20px;bottom:4px;line-height:16px}.sds-window-v5.x-window-dlg .syno-mb-progress .x-progress-text,.x-window-dlg.sds-widget-window .syno-mb-progress .x-progress-text{display:none}.sds-window-v5 .x-progress-wrap,.sds-widget-window .x-progress-wrap{border:none;margin-bottom:4px}.sds-window-v5 .x-progress-inner,.sds-widget-window .x-progress-inner{background:#D2DCE6;border-radius:3px;overflow:hidden;height:16px}.sds-window-v5 .x-progress-bar,.sds-widget-window .x-progress-bar{position:relative;background-color:#0086E5;background-image:none;border:none}.sds-window-v5 .x-progress-bar::before,.sds-widget-window .x-progress-bar::before{content:'';width:100%;height:100%;position:absolute;top:0;left:0;border-radius:3px;background-image:repeating-linear-gradient(-45deg, transparent, transparent 6.5px, rgba(255,255,255,0.15) 1px, rgba(255,255,255,0.15) 13px)}.sds-window-v5 .syno-ux-tab-panel .x-tab-panel-body,.sds-widget-window .syno-ux-tab-panel .x-tab-panel-body{padding-top:5px}.sds-window-v5 .syno-ux-tab-panel form.x-form,.sds-widget-window .syno-ux-tab-panel form.x-form{padding:0 10px}.sds-window-v5 .syno-ux-tab-panel form.x-form .syno-ux-fieldset,.sds-widget-window .syno-ux-tab-panel form.x-form .syno-ux-fieldset{margin:0 -10px 8px -10px}.sds-window-v5 .syno-ux-tab-panel .syno-ux-formpanel-has-fieldset form.x-form,.sds-widget-window .syno-ux-tab-panel .syno-ux-formpanel-has-fieldset form.x-form{padding-left:0;padding-right:0}.sds-window-v5 .syno-ux-tab-panel .syno-ux-formpanel-has-fieldset form.x-form .x-form-item,.sds-widget-window .syno-ux-tab-panel .syno-ux-formpanel-has-fieldset form.x-form .x-form-item{margin-left:10px;margin-right:10px}.sds-window-v5 .syno-ux-tab-panel .syno-ux-formpanel-has-fieldset form.x-form .syno-ux-fieldset,.sds-widget-window .syno-ux-tab-panel .syno-ux-formpanel-has-fieldset form.x-form .syno-ux-fieldset{margin-left:0;margin-right:0}.sds-window-v5 .syno-ux-tab-panel .syno-ux-formpanel-has-fieldset form.x-form .syno-ux-fieldset .x-form-item,.sds-widget-window .syno-ux-tab-panel .syno-ux-formpanel-has-fieldset form.x-form .syno-ux-fieldset .x-form-item{margin-left:0;margin-right:0}.sds-window .x-statusbar .x-window-bc{background-image:url(/scripts/ext-3/resources/images/gray/window/top-bottom.png)}.sds-window .x-statusbar .x-status-text{height:20px;line-height:20px;padding-left:25px !important;background-position:1px 2px}.sds-window .x-statusbar .x-toolbar-right{padding-right:16px}.sds-window .x-statusbar .x-toolbar-right .x-btn{padding-top:6px;padding-bottom:6px}.sds-window .x-window-body .x-statusbar .x-toolbar-right .x-btn{padding-top:0;padding-bottom:0}.sds-window .x-tab-panel-fbar.x-statusbar .x-status-text,.sds-window .x-panel-fbar.x-statusbar .x-status-text{white-space:normal;line-height:14px;background-position:1px 0px}.sds-window-v5 .x-window-footer .x-statusbar,.sds-widget-window .x-window-footer .x-statusbar{padding-left:20px;padding-right:20px}.sds-window-v5 .x-window-footer .x-statusbar .x-toolbar-ct,.sds-widget-window .x-window-footer .x-statusbar .x-toolbar-ct{background-image:url("../images/shadow_footbar.png");background-repeat:repeat-x;background-color:transparent;border:0px;padding-top:4px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5 .x-window-footer .x-statusbar .x-toolbar-ct,.synohdpack .sds-widget-window .x-window-footer .x-statusbar .x-toolbar-ct{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/shadow_footbar.png");background-size:8px 4px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5 .x-window-footer .x-statusbar .x-toolbar-ct,.synohdpackdebug .sds-widget-window .x-window-footer .x-statusbar .x-toolbar-ct{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/shadow_footbar.png");background-size:8px 4px;outline:1px green dashed}}.sds-window-v5 .x-window-footer .x-statusbar .x-toolbar-cell,.sds-widget-window .x-window-footer .x-statusbar .x-toolbar-cell{padding:0}.sds-window-v5 .x-window-footer .x-statusbar .x-toolbar-right .syno-ux-button,.sds-widget-window .x-window-footer .x-statusbar .x-toolbar-right .syno-ux-button{margin:8px 10px 8px 0px}.x-dd-drag-proxy .x-dd-drag-ghost{padding:0px}.x-dd-drag-proxy .x-dd-drop-icon{top:0px;left:0px}.x-dd-drop-ok,.x-dd-drop-ok-add,.x-tree-drop-ok-append,.x-tree-drop-ok-above,.x-tree-drop-ok-between,.x-tree-drop-ok-below,.x-dd-drop-nodrop{background-color:#FFFFFF;-webkit-box-shadow:0px 1px 4px #000;-moz-box-shadow:0px 1px 4px #000;box-shadow:0px 1px 4px #000;-webkit-box-shadow:0px 1px 4px rgba(0,0,0,0.25);-moz-box-shadow:0px 1px 4px rgba(0,0,0,0.25);box-shadow:0px 1px 4px rgba(0,0,0,0.25);border:1px;border-color:#C8D2DC;border-radius:3px;padding:7px 11px 7px 41px}.x-dd-drop-ok .x-dd-drop-icon,.x-dd-drop-ok-add .x-dd-drop-icon,.x-tree-drop-ok-append .x-dd-drop-icon,.x-tree-drop-ok-above .x-dd-drop-icon,.x-tree-drop-ok-between .x-dd-drop-icon,.x-tree-drop-ok-below .x-dd-drop-icon,.x-dd-drop-nodrop .x-dd-drop-icon{width:24px;height:24px;left:10px;top:7px;background-image:url("../images/item_drag_status.png");background-position:0 0}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .x-dd-drop-ok .x-dd-drop-icon,.synohdpack .x-dd-drop-ok-add .x-dd-drop-icon,.synohdpack .x-tree-drop-ok-append .x-dd-drop-icon,.synohdpack .x-tree-drop-ok-above .x-dd-drop-icon,.synohdpack .x-tree-drop-ok-between .x-dd-drop-icon,.synohdpack .x-tree-drop-ok-below .x-dd-drop-icon,.synohdpack .x-dd-drop-nodrop .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/item_drag_status.png");background-size:72px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .x-dd-drop-ok .x-dd-drop-icon,.synohdpackdebug .x-dd-drop-ok-add .x-dd-drop-icon,.synohdpackdebug .x-tree-drop-ok-append .x-dd-drop-icon,.synohdpackdebug .x-tree-drop-ok-above .x-dd-drop-icon,.synohdpackdebug .x-tree-drop-ok-between .x-dd-drop-icon,.synohdpackdebug .x-tree-drop-ok-below .x-dd-drop-icon,.synohdpackdebug .x-dd-drop-nodrop .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/item_drag_status.png");background-size:72px 24px;outline:1px green dashed}}.x-dd-drop-ok .x-dd-drag-ghost,.x-dd-drop-ok-add .x-dd-drag-ghost,.x-tree-drop-ok-append .x-dd-drag-ghost,.x-tree-drop-ok-above .x-dd-drag-ghost,.x-tree-drop-ok-between .x-dd-drag-ghost,.x-tree-drop-ok-below .x-dd-drag-ghost,.x-dd-drop-nodrop .x-dd-drag-ghost{border:none;color:#505A64;font-size:16px;line-height:24px;height:24px}.x-dd-drop-ok .x-dd-drag-ghost .x-tree-node-icon,.x-dd-drop-ok-add .x-dd-drag-ghost .x-tree-node-icon,.x-tree-drop-ok-append .x-dd-drag-ghost .x-tree-node-icon,.x-tree-drop-ok-above .x-dd-drag-ghost .x-tree-node-icon,.x-tree-drop-ok-between .x-dd-drag-ghost .x-tree-node-icon,.x-tree-drop-ok-below .x-dd-drag-ghost .x-tree-node-icon,.x-dd-drop-nodrop .x-dd-drag-ghost .x-tree-node-icon{display:none}.x-dd-drop-ok .x-dd-drag-ghost .x-grid3-hd-inner,.x-dd-drop-ok .x-dd-drag-ghost span,.x-dd-drop-ok-add .x-dd-drag-ghost .x-grid3-hd-inner,.x-dd-drop-ok-add .x-dd-drag-ghost span,.x-tree-drop-ok-append .x-dd-drag-ghost .x-grid3-hd-inner,.x-tree-drop-ok-append .x-dd-drag-ghost span,.x-tree-drop-ok-above .x-dd-drag-ghost .x-grid3-hd-inner,.x-tree-drop-ok-above .x-dd-drag-ghost span,.x-tree-drop-ok-between .x-dd-drag-ghost .x-grid3-hd-inner,.x-tree-drop-ok-between .x-dd-drag-ghost span,.x-tree-drop-ok-below .x-dd-drag-ghost .x-grid3-hd-inner,.x-tree-drop-ok-below .x-dd-drag-ghost span,.x-dd-drop-nodrop .x-dd-drag-ghost .x-grid3-hd-inner,.x-dd-drop-nodrop .x-dd-drag-ghost span{padding:0px;color:#505A64;font-size:16px;line-height:24px}.x-dd-drop-ok .x-dd-drag-ghost .x-grid3-hd-inner,.x-dd-drop-ok-add .x-dd-drag-ghost .x-grid3-hd-inner,.x-tree-drop-ok-append .x-dd-drag-ghost .x-grid3-hd-inner,.x-tree-drop-ok-above .x-dd-drag-ghost .x-grid3-hd-inner,.x-tree-drop-ok-between .x-dd-drag-ghost .x-grid3-hd-inner,.x-tree-drop-ok-below .x-dd-drag-ghost .x-grid3-hd-inner,.x-dd-drop-nodrop .x-dd-drag-ghost .x-grid3-hd-inner{border:none;background-color:white;background-image:none}.x-dd-drop-ok .x-dd-drop-icon{background-position:-24px 0}.x-dd-drop-nodrop .x-dd-drop-icon{background-position:-48px 0}.x-dd-drop-nodrop.x-dd-drag-repair{display:none}.sds-launch-icon-dragging-proxy .sds-application-notify-badge-num{display:none}.sds-launch-icon-dragging-proxy .x-dd-drag-ghost{border:none !important;background-color:transparent !important;opacity:1 !important;filter:none !important}.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-reposition-ok,.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-nodrop,.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-ok-add,.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-ok,.x-dd-drag-proxy.x-dd-drop-nodrop.x-dd-drag-repair{background-color:transparent;border:none;padding:0px;box-shadow:none}.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-reposition-ok .x-dd-drag-ghost,.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-nodrop .x-dd-drag-ghost,.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-ok-add .x-dd-drag-ghost,.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-ok .x-dd-drag-ghost,.x-dd-drag-proxy.x-dd-drop-nodrop.x-dd-drag-repair .x-dd-drag-ghost{width:82px}.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-ok-add .x-dd-drop-icon{width:36px;height:36px;top:40px;left:46px;background-image:url("../images/icon_drag_add.png");background-position:center}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-ok-add .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/icon_drag_add.png");background-size:36px 36px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-ok-add .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/icon_drag_add.png");background-size:36px 36px;outline:1px green dashed}}.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-ok .x-dd-drop-icon,.sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-nodrop .x-dd-drop-icon{width:36px;height:36px;top:40px;left:46px;background-image:url("../images/icon_drag_ban.png");background-position:center}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-ok .x-dd-drop-icon,.synohdpack .sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-nodrop .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/icon_drag_ban.png");background-size:36px 36px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-ok .x-dd-drop-icon,.synohdpackdebug .sds-launch-icon-dragging-proxy.x-dd-drag-proxy.x-dd-drop-nodrop .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/icon_drag_ban.png");background-size:36px 36px;outline:1px green dashed}}.sds-launch-icon-dragging-proxy .x-dd-drag-ghost .text{visibility:hidden !important}.sds-launch-icon-dragging-proxy .image{white-space:normal}.sds-launch-icon-dragging-proxy li{list-style:none}.sds-launch-icon-dragging-proxy li.launch-icon .image{margin-left:6px;margin-top:6px}.sds-shim-for-iframe{position:absolute;top:0;width:100%;height:100%;zIndex:20;background-color:transparent}#sds-taskbar{z-index:5;position:relative;height:39px;background:repeat-x scroll 0 0 transparent;background-image:url("../images/taskbar/taskbar_bg.png")}#sds-taskbar .x-btn-tl,#sds-taskbar .x-btn-tc,#sds-taskbar .x-btn-tr,#sds-taskbar .x-btn-bl,#sds-taskbar .x-btn-bc,#sds-taskbar .x-btn-br{display:none}#sds-taskbar .x-btn tr:first-child,#sds-taskbar .x-btn tr:last-child{display:none}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bg.png");background-size:4px 39px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bg.png");background-size:4px 39px;outline:1px green dashed}}#sds-taskbar-shadow{z-index:4;position:absolute;width:100%;height:43px;background:repeat-x scroll 0 39px transparent;background-image:url("../images/taskbar/taskbar_shadow.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar-shadow{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_shadow.png");background-size:4px 4px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar-shadow{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_shadow.png");background-size:4px 4px;outline:1px green dashed}}#sds-taskbar li .x-btn-text{padding:0}#sds-taskbar-panel-wrap{background:transparent;height:39px}.sds-taskbar-overflow-menu-button.x-btn-noicon.x-box-item{padding:3px 25px 3px 15px;width:72px;background:no-repeat;background-image:url("../images/taskbar/taskbar_split.png");background-position:62px 5px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-taskbar-overflow-menu-button.x-btn-noicon.x-box-item{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_split.png");background-size:2px 28px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-taskbar-overflow-menu-button.x-btn-noicon.x-box-item{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_split.png");background-size:2px 28px;outline:1px green dashed}}.sds-taskbar-overflow-menu-button .x-btn-ml,.sds-taskbar-overflow-menu-button .x-btn-mr,.sds-taskbar-overflow-menu-button .x-btn-tl,.sds-taskbar-overflow-menu-button .x-btn-tc,.sds-taskbar-overflow-menu-button .x-btn-tr,.sds-taskbar-overflow-menu-button .x-btn-bl,.sds-taskbar-overflow-menu-button .x-btn-bc,.sds-taskbar-overflow-menu-button .x-btn-br{display:none}.sds-taskbar-overflow-menu-button .x-btn-mc{background:no-repeat;background-image:url("../images/taskbar/more_apps.png");background-position:0px 0px !important;width:32px;height:32px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-taskbar-overflow-menu-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/more_apps.png");background-size:32px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-taskbar-overflow-menu-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/more_apps.png");background-size:32px 96px;outline:1px green dashed}}.sds-taskbar-overflow-menu-button.x-btn-over .x-btn-mc{background-position:0px -32px !important}.sds-taskbar-overflow-menu-button.x-btn-click .x-btn-mc{background-position:0px -64px !important}#sds-taskbar-right .x-btn-ml,#sds-taskbar-right .x-btn-mr,#sds-taskbar-right .x-btn-tl,#sds-taskbar-right .x-btn-tc,#sds-taskbar-right .x-btn-tr,#sds-taskbar-right .x-btn-bl,#sds-taskbar-right .x-btn-bc,#sds-taskbar-right .x-btn-br{display:none}#sds-taskbar-right .sds-taskbar-right-left,#sds-taskbar-right .sds-taskbar-right-center,#sds-taskbar-right .sds-taskbar-right-right{height:39px;float:left}#sds-taskbar-right .sds-taskbar-right-left{width:20px;background:no-repeat;background-image:url("../images//taskbar/taskbar_split.png");background-position:10px 6px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar-right .sds-taskbar-right-left{background-image:url("../img/synohdpack/images/dsm/resources/css/../images//taskbar/taskbar_split.png");background-size:2px 28px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar-right .sds-taskbar-right-left{background-image:url("../img/synohdpack/images/dsm/resources/css/../images//taskbar/taskbar_split.png");background-size:2px 28px;outline:1px green dashed}}#sds-taskbar-right .sds-taskbar-right-right{width:6px}#sds-taskbar-right table,#sds-taskbar-right table button{width:32px;height:32px}#sds-taskbar-right .x-btn-mc{width:202px;height:32px;background-image:none;background-color:transparent}.sds-tray-panel{box-shadow:0px 2px 6px rgba(0,0,0,0.5);background-color:#FFFFFF;border:0px none;padding:4px 10px;color:#505050}.sds-tray-panel .x-panel-body{background-color:#FFFFFF;border:none}.sds-tray-panel .x-panel-header{background:transparent;border:0;border-bottom:solid 1px #EBF0F5;text-align:center}.sds-tray-panel .x-panel-header .x-panel-header-text{font-size:13px;color:#505A64;font-weight:bold;line-height:23px}.sds-tray-panel .sds-tray-panel-arrow{background:transparent;width:24px;height:18px;position:absolute;overflow:hidden}.ext-ie8m .sds-tray-panel .sds-tray-panel-arrow{width:0px;height:0px;border:10px solid transparent;border-bottom-width:13px;border-bottom-color:#fff;border-top-width:0px}.sds-tray-panel .sds-tray-panel-arrow::after{background:#fff;background:#fff;content:'';position:absolute;bottom:0px;left:2px;width:14px;height:14px;-webkit-transform-origin:left bottom;-moz-transform-origin:left bottom;-ms-transform-origin:left bottom;-o-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg);box-shadow:2px 2px 6px rgba(0,0,0,0.5)}#sds-taskbar-notification-button,#sds-taskbar-user-button,#sds-taskbar-search-button,#sds-taskbar-widget-button,#sds-taskbar-preview-button{float:left;margin:0px 6px 0px 6px;padding-top:4px;cursor:pointer}#sds-taskbar-user-button .x-btn-mc{background-image:url("../images/taskbar/tray_icon_user_menu.png");background-position:0px 0px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar-user-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/tray_icon_user_menu.png");background-size:32px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar-user-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/tray_icon_user_menu.png");background-size:32px 96px;outline:1px green dashed}}#sds-taskbar-user-button .x-btn-over .x-btn-mc{background-position:0px -32px !important}#sds-taskbar-user-button .x-btn-click .x-btn-mc,#sds-taskbar-user-button .x-btn-pressed .x-btn-mc{background-position:0px -64px !important}#sds-taskbar-search-button .x-btn-mc{background-image:url("../images/taskbar/tray_icon_search.png");background-position:0px 0px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar-search-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/tray_icon_search.png");background-size:32px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar-search-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/tray_icon_search.png");background-size:32px 96px;outline:1px green dashed}}#sds-taskbar-search-button .x-btn-over .x-btn-mc{background-position:0px -32px !important}#sds-taskbar-search-button .x-btn-click .x-btn-mc,#sds-taskbar-search-button .x-btn-pressed .x-btn-mc{background-position:0px -64px !important}#sds-taskbar-notification-button .x-btn-mc{background-image:url("../images/taskbar/tray_icon_notification.png");background-position:0px 0px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar-notification-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/tray_icon_notification.png");background-size:32px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar-notification-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/tray_icon_notification.png");background-size:32px 96px;outline:1px green dashed}}#sds-taskbar-notification-button .x-btn-over .x-btn-mc{background-position:0px -32px !important}#sds-taskbar-notification-button .x-btn-click .x-btn-mc,#sds-taskbar-notification-button .x-btn-pressed .x-btn-mc{background-position:0px -64px !important}#sds-taskbar-widget-button .x-btn-mc{background-image:url("../images/taskbar/tray_icon_widget.png");background-position:0px 0px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar-widget-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/tray_icon_widget.png");background-size:32px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar-widget-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/tray_icon_widget.png");background-size:32px 96px;outline:1px green dashed}}#sds-taskbar-widget-button .x-btn-over .x-btn-mc{background-position:0px -32px !important}#sds-taskbar-widget-button .x-btn-click .x-btn-mc,#sds-taskbar-widget-button .x-btn-pressed .x-btn-mc{background-position:0px -64px !important}#sds-taskbar-preview-button .x-btn-mc{background-image:url("../images/taskbar/tray_icon_pilot_view.png");background-position:0px 0px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar-preview-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/tray_icon_pilot_view.png");background-size:32px 128px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar-preview-button .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/tray_icon_pilot_view.png");background-size:32px 128px;outline:1px green dashed}}#sds-taskbar-preview-button .x-btn-over .x-btn-mc{background-position:0px -32px !important}#sds-taskbar-preview-button .x-btn-click .x-btn-mc,#sds-taskbar-preview-button .x-btn-pressed .x-btn-mc{background-position:0px -64px !important}#sds-taskbar-preview-button .x-item-disabled .x-btn-mc{background-position:0px -96px !important}#sds-taskbar-showall{float:left}#sds-taskbar-showall .x-btn-ml,#sds-taskbar-showall .x-btn-mr{display:none}#sds-taskbar-showall .x-btn-text{width:22px;height:39px}#sds-taskbar-showall .x-btn-mc{background:transparent no-repeat;background-image:url("../images/taskbar/showdesktop.png") !important;background-position:0px 0px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar-showall .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/showdesktop.png") !important;background-size:22px 117px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar-showall .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/showdesktop.png") !important;background-size:22px 117px;outline:1px green dashed}}#sds-taskbar-showall .x-btn-over .x-btn-mc{background-position:0px -39px !important}#sds-taskbar-showall .x-btn-click .x-btn-mc{background-position:0px -78px !important}#sds-taskbar-startbutton{float:left}#sds-taskbar-startbutton .x-btn-ml{display:none}#sds-taskbar-startbutton .x-btn-text{width:89px;height:39px}#sds-taskbar-startbutton .x-btn-mc{background:transparent no-repeat;background-image:url("../images/taskbar/taskbar_bt_apps.png") !important;background-position:0px 0px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar-startbutton .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bt_apps.png") !important;background-size:89px 117px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar-startbutton .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bt_apps.png") !important;background-size:89px 117px;outline:1px green dashed}}#sds-taskbar-startbutton .x-btn-over .x-btn-mc{background-position:0px -39px !important}#sds-taskbar-startbutton .x-btn-click .x-btn-mc{background-position:0px -78px !important}#sds-taskbar-startbutton .x-btn-pressed .x-btn-mc{background-position:0px -78px !important}#sds-taskbar-startbutton .x-btn-mr{background:transparent no-repeat;background-position:right 0px !important;background-image:url("../images/taskbar/taskbar_bt_widgets_shadow.png") !important;width:8px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbar-startbutton .x-btn-mr{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bt_widgets_shadow.png") !important;background-size:8px 39px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbar-startbutton .x-btn-mr{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bt_widgets_shadow.png") !important;background-size:8px 39px;outline:1px green dashed}}#sds-taskbar-startbutton .x-btn-pressed .x-btn-mr{visibility:hidden}#sds-tray-panel{right:0 !important;left:auto !important;padding:4px 0 3px 0}#sds-tray-panel .sds-tray-strip-wrap{width:100%;zoom:1}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-device{background-image:url("../../modules/ExternalDevices/images/tray_icon_device.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-device{background-image:url("../img/synohdpack/images/dsm/modules/ExternalDevices/images/tray_icon_device.png");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-device{background-image:url("../img/synohdpack/images/dsm/modules/ExternalDevices/images/tray_icon_device.png");background-size:32px;outline:1px green dashed}}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-disk-port{background-image:url("../../modules/PollingTask/images/tray_icon_disk_port.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-disk-port{background-image:url("../img/synohdpack/images/dsm/modules/PollingTask/images/tray_icon_disk_port.png");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-disk-port{background-image:url("../img/synohdpack/images/dsm/modules/PollingTask/images/tray_icon_disk_port.png");background-size:32px;outline:1px green dashed}}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-upload{background-image:url(../../modules/FileTaskMonitor/images/tray_icon_upload.png);background-position:0 0 !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-upload{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_upload.png");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-upload{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_upload.png");background-size:32px;outline:1px green dashed}}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-upload{background-image:url(../../modules/FileTaskMonitor/images/tray_icon_upload.gif);background-position:0 0 !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-upload{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_upload.gif");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-upload{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_upload.gif");background-size:32px;outline:1px green dashed}}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-bgtask{background-image:url(../../modules/FileTaskMonitor/images/tray_icon_bgtask.png);background-position:0 0 !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-bgtask{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_bgtask.png");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-bgtask{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_bgtask.png");background-size:32px;outline:1px green dashed}}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-bgtask{background-image:url(../../modules/FileTaskMonitor/images/tray_icon_bgtask.gif);background-position:0 0 !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-bgtask{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_bgtask.gif");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-bgtask{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_bgtask.gif");background-size:32px;outline:1px green dashed}}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-download{background-image:url(../../modules/FileTaskMonitor/images/tray_icon_download.png);background-position:0 0 !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-download{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_download.png");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-download{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_download.png");background-size:32px;outline:1px green dashed}}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-download{background-image:url(../../modules/FileTaskMonitor/images/tray_icon_download.gif);background-position:0 0 !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-download{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_download.gif");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-download{background-image:url("../img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_download.gif");background-size:32px;outline:1px green dashed}}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-creating-thumbnail{background-image:url(../../modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.png);background-position:0 0 !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-creating-thumbnail{background-image:url("../img/synohdpack/images/dsm/modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.png");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-static-creating-thumbnail{background-image:url("../img/synohdpack/images/dsm/modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.png");background-size:32px;outline:1px green dashed}}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-creating-thumbnail{background-image:url(../../modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.gif);background-position:0 0 !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-creating-thumbnail{background-image:url("../img/synohdpack/images/dsm/modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.gif");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon .x-btn-mc .sds-tray-item-ani-creating-thumbnail{background-image:url("../img/synohdpack/images/dsm/modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.gif");background-size:32px;outline:1px green dashed}}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon button{background-position:0px 0px !important}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon.x-btn-over button{background-position:0px -32px !important}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon.x-btn-click button{background-position:0px -64px !important}#sds-tray-panel .sds-tray-strip-wrap .x-btn.x-btn-icon.x-btn-pressed button{background-position:0px -64px !important}#sds-tray-panel .sds-tray-strip{display:block;zoom:1}#sds-tray-panel .sds-widget-tray{cursor:pointer;margin:0px 6px 0px 6px}#sds-tray-panel li{float:right}#sds-tray-panel li .x-btn-text{height:32px;width:32px;margin:0px 6px 0px 6px}#sds-tray-panel .x-btn-ml,#sds-tray-panel .x-btn-mr{background:none transparent;display:none}#sds-tray-panel .x-btn-mc{background:none transparent}.sds-tray-item-notification{position:relative}#sds-taskbuttons-panel li{position:relative;float:left}#sds-taskbuttons-panel li .loading{position:absolute;left:0;top:0;width:62px;height:39px;background:no-repeat scroll center center transparent;background-image:url("../images/desktop/taskbar_spinner.gif")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbuttons-panel li .loading{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/desktop/taskbar_spinner.gif");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbuttons-panel li .loading{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/desktop/taskbar_spinner.gif");background-size:24px 24px;outline:1px green dashed}}#sds-taskbuttons-panel li.sds-taskbuttons-edge{float:left;margin:0 !important;padding:0 !important;border:0 none !important;font-size:1px !important;line-height:1px !important;overflow:hidden;zoom:1;background:transparent !important;width:1px}#sds-taskbuttons-panel li .x-btn-text{width:62px;height:39px}#sds-taskbuttons-panel li .x-btn-ml,#sds-taskbuttons-panel li .x-btn-mr{display:none}#sds-taskbuttons-panel li .x-btn.x-btn-icon button{background-size:32px 32px}#sds-taskbuttons-panel li .x-btn.x-btn-icon.launched .x-btn-mc{background:transparent no-repeat;background-image:url("../images/taskbar/taskbar_bt.png") !important;background-position:0px 0px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbuttons-panel li .x-btn.x-btn-icon.launched .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bt.png") !important;background-size:186px 39px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbuttons-panel li .x-btn.x-btn-icon.launched .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bt.png") !important;background-size:186px 39px;outline:1px green dashed}}#sds-taskbuttons-panel li .x-btn.x-btn-icon.x-btn-over .x-btn-mc{background:transparent no-repeat;background-image:url("../images/taskbar/taskbar_bt.png") !important;background-position:-62px 0px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbuttons-panel li .x-btn.x-btn-icon.x-btn-over .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bt.png") !important;background-size:186px 39px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbuttons-panel li .x-btn.x-btn-icon.x-btn-over .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bt.png") !important;background-size:186px 39px;outline:1px green dashed}}#sds-taskbuttons-panel li .x-btn.x-btn-icon.x-btn-click .x-btn-mc,#sds-taskbuttons-panel li .x-btn.x-btn-icon.launched.active .x-btn-mc{background:transparent no-repeat;background-image:url("../images/taskbar/taskbar_bt.png") !important;background-position:-124px 0px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-taskbuttons-panel li .x-btn.x-btn-icon.x-btn-click .x-btn-mc,.synohdpack #sds-taskbuttons-panel li .x-btn.x-btn-icon.launched.active .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bt.png") !important;background-size:186px 39px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-taskbuttons-panel li .x-btn.x-btn-icon.x-btn-click .x-btn-mc,.synohdpackdebug #sds-taskbuttons-panel li .x-btn.x-btn-icon.launched.active .x-btn-mc{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_bt.png") !important;background-size:186px 39px;outline:1px green dashed}}.sds-user-menu{min-width:140px;padding:4px 10px 4px 10px;position:absolute;top:39px;right:0px;overflow:hidden;z-index:12000;background:#fff repeat-x;background-image:url("../images/taskbar/taskbar_shadow.png");box-shadow:-2px 5px 8px rgba(0,0,0,0.5);user-select:none;-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-user-menu{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_shadow.png");background-size:4px 4px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-user-menu{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_shadow.png");background-size:4px 4px;outline:1px green dashed}}.sds-user-menu .x-menu{background-color:transparent !important;background-image:none !important}.sds-user-menu .x-menu .x-menu-item-text{font-size:12px;line-height:32px;padding-left:6px}.sds-user-menu .x-menu .x-menu-item-icon{top:4px}.sds-user-menu .x-menu-item{padding-top:0;padding-bottom:0}.sds-user-menu .x-menu-sep-li{height:7px}.sds-user-menu .x-menu-sep-li .x-menu-sep{margin:0px;border-bottom-color:#EBF0F5;background-color:transparent}.sds-user-menu .x-menu-list-item{padding:0px}.sds-user-menu .x-menu-item-active,.sds-user-menu .x-menu-item-active .x-menu-item{background-image:none;background-color:transparent;border-color:transparent;border:0px}.sds-user-menu .sds-user-menu-username{display:inline-block;width:136px;font-weight:bold;color:#505A64;line-height:24px;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.sds-user-menu .sds-user-menu-options{width:24px;height:24px;background-image:url("../images/taskbar/user_menu_options.png");background-position:0 0}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-user-menu .sds-user-menu-options{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/user_menu_options.png");background-size:24px 72px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-user-menu .sds-user-menu-options{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/user_menu_options.png");background-size:24px 72px;outline:1px green dashed}}.sds-user-menu .sds-user-menu-restart{width:24px;height:24px;background-image:url("../images/taskbar/user_menu_restart.png");background-position:0 0}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-user-menu .sds-user-menu-restart{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/user_menu_restart.png");background-size:24px 72px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-user-menu .sds-user-menu-restart{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/user_menu_restart.png");background-size:24px 72px;outline:1px green dashed}}.sds-user-menu .sds-user-menu-shutdown{width:24px;height:24px;background-image:url("../images/taskbar/user_menu_shutdown.png");background-position:0 0}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-user-menu .sds-user-menu-shutdown{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/user_menu_shutdown.png");background-size:24px 72px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-user-menu .sds-user-menu-shutdown{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/user_menu_shutdown.png");background-size:24px 72px;outline:1px green dashed}}.sds-user-menu .sds-user-menu-logout{width:24px;height:24px;background-image:url("../images/taskbar/user_menu_logout.png");background-position:0 0}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-user-menu .sds-user-menu-logout{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/user_menu_logout.png");background-size:24px 72px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-user-menu .sds-user-menu-logout{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/user_menu_logout.png");background-size:24px 72px;outline:1px green dashed}}.sds-user-menu .sds-user-menu-about{width:24px;height:24px;background-image:url("../images/taskbar/user_menu_about.png");background-position:0 0}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-user-menu .sds-user-menu-about{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/user_menu_about.png");background-size:24px 72px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-user-menu .sds-user-menu-about{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/user_menu_about.png");background-size:24px 72px;outline:1px green dashed}}.sds-user-menu .sds-user-menu-options-over img,.sds-user-menu .sds-user-menu-restart-over img,.sds-user-menu .sds-user-menu-about-over img,.sds-user-menu .sds-user-menu-shutdown-over img,.sds-user-menu .sds-user-menu-logout-over img{background-position:0px -24px !important}.sds-user-menu .sds-user-menu-options-over .x-menu-item-text,.sds-user-menu .sds-user-menu-restart-over .x-menu-item-text,.sds-user-menu .sds-user-menu-about-over .x-menu-item-text,.sds-user-menu .sds-user-menu-shutdown-over .x-menu-item-text,.sds-user-menu .sds-user-menu-logout-over .x-menu-item-text{color:#78828C}.sds-user-menu .sds-user-menu-options-click img,.sds-user-menu .sds-user-menu-restart-click img,.sds-user-menu .sds-user-menu-about-click img,.sds-user-menu .sds-user-menu-shutdown-click img,.sds-user-menu .sds-user-menu-logout-click img{background-position:0px -48px !important}.sds-user-menu .sds-user-menu-options-click .x-menu-item-text,.sds-user-menu .sds-user-menu-restart-click .x-menu-item-text,.sds-user-menu .sds-user-menu-about-click .x-menu-item-text,.sds-user-menu .sds-user-menu-shutdown-click .x-menu-item-text,.sds-user-menu .sds-user-menu-logout-click .x-menu-item-text{color:#0086E5}.sds-overflow-menu{min-width:240px;position:absolute;top:39px;overflow:hidden;z-index:12000;user-select:none;-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none}.sds-overflow-menu .x-menu{background-color:transparent !important;background-image:none !important}.sds-overflow-menu .x-menu .x-menu-item-text{font-size:13px;line-height:48px;padding-left:20px}.sds-overflow-menu .x-menu .x-menu-item-text:hover{height:100%}.sds-overflow-menu .x-menu .x-menu-item-icon{top:8px;left:8px;height:32px;width:32px}.sds-overflow-menu .x-menu-item{padding-top:0;padding-bottom:0}.sds-overflow-menu .x-menu-sep-li{height:7px}.sds-overflow-menu .x-menu-sep-li .x-menu-sep{margin:0px;border-bottom-color:#EBF0F5;background-color:transparent}.sds-overflow-menu .x-menu-list{padding:0px}.sds-overflow-menu .x-menu-list-item{padding:0px}.sds-overflow-menu .x-menu-item-active,.sds-overflow-menu .x-menu-item-active .x-menu-item{background-image:none;background-color:transparent;border-color:transparent;border:0px;color:#78828C}.sds-overflow-menu .sds-overflow-items-click .x-menu-item-text{color:#0086E5}.sds-taskbutton-overflowed{visibility:hidden !important}.sds-user-menu.sds-overflow-menu .x-menu .x-menu-item .x-menu-item-icon{left:4px;top:4px}.sds-previewbox{box-shadow:0px 2px 6px rgba(0,0,0,0.5);position:absolute;top:46px;left:0px;width:240px;height:180px;z-index:13000;user-select:none;-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-webkit-transform:translate3d(0, 0, 0)}.sds-previewbox .sds-previewbox-mc{margin:0px 10px;height:160px}.sds-previewbox .sds-previewbox-background{z-index:-1;zoom:1;position:absolute;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=85);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=85);opacity:0.85;background:#f5faff;background:#f5faff;top:0px;left:0px;right:0px;bottom:0px}.sds-previewbox .sds-previewbox-win{position:absolute}.sds-previewbox .sds-previewbox-win-mask{position:absolute;background:transparent;z-index:9999;width:100%;height:100%;top:0px;box-shadow:0px 3px 6px rgba(0,0,0,0.5)}.sds-previewbox .sds-previewbox-arrow{position:absolute;top:-18px;left:108px;width:24px;height:18px;overflow:hidden}.ext-ie8m .sds-previewbox .sds-previewbox-arrow{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=85);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=85);opacity:0.85;width:0px;height:0px;border:10px solid transparent;border-bottom-width:13px;border-bottom-color:#f5faff;border-top-width:0px}.sds-previewbox .sds-previewbox-arrow::after{background:#f5faff;background:rgba(245,250,255,0.85);content:'';position:absolute;bottom:0px;left:2px;width:14px;height:14px;-webkit-transform-origin:left bottom;-moz-transform-origin:left bottom;-ms-transform-origin:left bottom;-o-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg);box-shadow:2px 2px 6px rgba(0,0,0,0.5)}.sds-previewbox-desc{color:#28323C;font-size:13px;font-weight:bold;padding:6px 0px;text-align:center;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;white-space:nowrap}.sds-previewbox-win-transform{transform-origin:0% 0%;-webkit-transform-origin:0% 0%;-moz-transform-origin:0% 0%;-o-transform-origin:0% 0%;-ms-transform-origin:0% 0%}.sds-previewbox-transition{transition-delay:0s;transition-property:top, left, opacity;transition-duration:0.8s;-webkit-transition-delay:0s;-webkit-transition-property:top, left, opacity;-webkit-transition-duration:0.8s;-moz-transition-delay:0s;-moz-transition-property:top, left, opacity;-moz-transition-duration:0.8s;-o-transition-delay:0s;-o-transition-property:top, left, opacity;-o-transition-duration:0.8s;-ms-transition-delay:0s;-ms-transition-property:top, left, opacity;-ms-transition-duration:0.8s}.sds-tray-msg-window{background-color:white;box-shadow:0px 2px 6px rgba(0,0,0,0.5);border-radius:3px}.sds-tray-msg-window .x-tool-close{position:absolute;right:2px;top:2px;background-image:url("../images/rt_button.png");width:24px;height:24px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-tray-msg-window .x-tool-close{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/rt_button.png");background-size:24px 768px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-tray-msg-window .x-tool-close{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/rt_button.png");background-size:24px 768px;outline:1px green dashed}}.sds-tray-msg-window .x-tool-close-over{background-position:0 -24px}.sds-tray-msg-window .x-plain-tl .x-plain-header{overflow:hidden;zoom:1;padding:5px 12px 5px 12px;font-size:15px;color:#0086E5;height:17px}.sds-tray-msg-window .x-plain-body{overflow:hidden;position:relative;padding:0px 12px 10px 12px;font-size:12px;color:#505A64;word-wrap:break-word}.sds-taskbar-no-display{display:none}.sds-appview-searchfiled{top:5px;left:-10px}.sds-searchbox{position:absolute;top:39px;right:0px;overflow:hidden;z-index:12000;width:340px;background:#fff repeat-x;background-image:url("../images/taskbar/taskbar_shadow.png");user-select:none;-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;box-shadow:-2px 5px 8px rgba(0,0,0,0.5)}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-searchbox{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_shadow.png");background-size:4px 4px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-searchbox{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/taskbar/taskbar_shadow.png");background-size:4px 4px;outline:1px green dashed}}.sds-searchbox .sds-searchbox-input-wrap{right:-10px;top:10px}.sds-searchbox .sds-searchbox-header .x-small-editor .sds-searchbox-input{width:265px;height:26px !important;line-height:24px;background-color:transparent;background-image:none;padding:0 4px 0 0;padding-left:27px;padding-right:22px;border-color:#C8D2DC}.sds-searchbox .sds-searchbox-header .x-small-editor .sds-searchbox-input:hover{border-color:#B4BEC8}.sds-searchbox .sds-searchbox-header .x-small-editor .sds-searchbox-input.x-form-focus{border-color:#0086E6}.sds-searchbox .sds-searchbox-header .x-toolbar{background-image:none;background-color:transparent;background-repeat:no-repeat;padding:0;border:none;overflow:visible}.sds-searchbox .sds-searchbox-header .x-toolbar .x-toolbar-ct{height:42px}.sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-left{background-image:url(/scripts/ext-3/ux/images/Components/icon_search.png);width:24px;height:24px;margin:2px 0px 0px 4px;background-position:0 0}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-left{background-image:url("../img/synohdpack/images/Components/icon_search.png");background-size:24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-left{background-image:url("../img/synohdpack/images/Components/icon_search.png");background-size:24px;outline:1px green dashed}}.sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-cancel{background-image:url(/scripts/ext-3.4/ux/images/Components/icon_search_clear.png);background-position:0 -0px;left:290px;width:24px;height:24px;margin-top:3px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-cancel{background-image:url("../img/synohdpack/images/Components/icon_search_clear.png");background-size:24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-cancel{background-image:url("../img/synohdpack/images/Components/icon_search_clear.png");background-size:24px;outline:1px green dashed}}.sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-cancel.x-btn-over{background-position:0 -24px}.sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-cancel.x-btn-click{background-position:0 -48px}.sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-cancel .x-btn-ml,.sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-cancel .x-btn-mr{display:none}.sds-searchbox .sds-searchbox-header .x-toolbar .sds-searchbox-input-cancel .x-btn-mc{background-image:none !important}.sds-searchbox .sds-searchbox-header .x-toolbar .ext-chrome .sds-searchbox-input-cancel{left:290px}.sds-searchbox .x-toolbar td{vertical-align:baseline}.sds-searchbox.sds-searchbox-init-state .sds-searchbox-header .x-toolbar-ct{height:48px}.sds-searchbox.sds-searchbox-init-state .sds-searchbox-bwrap{display:none}.sds-searchbox .sds-search-result{overflow-x:hidden;overflow-y:hidden;font-size:12px;padding:0px 0px 10px 10px}.sds-searchbox .sds-search-result .section{padding:0px 0px 0px 8px;color:#0086E5;background:transparent;font-size:15px;line-height:32px}.sds-searchbox .sds-search-result .sds-searchbox-result-splitline{height:8px}.sds-searchbox .sds-search-result .sds-searchbox-result-item{padding:4px 0 4px 8px;line-height:16px;white-space:nowrap;width:322px;cursor:pointer}.sds-searchbox .sds-search-result .sds-searchbox-result-item:hover{background:#F5FaFF}.sds-searchbox .sds-search-result .sds-searchbox-result-item:active{background:#E6F5FF}.sds-searchbox .sds-search-result .sds-searchbox-result-item .topic{padding-left:8px;font-size:11px}.sds-searchbox .sds-search-result .sds-searchbox-result-item .topic div{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;width:168px}.sds-searchbox .sds-search-result .sds-searchbox-result-item .module{color:#96A0AA;font-size:12px}.sds-searchbox .sds-search-result .sds-searchbox-result-item .module div{width:110px;right:0px;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;text-align:right}.sds-searchbox.sds-searchbox-init-state .sds-searchbox-input-cancel{display:none}.ext-opera .sds-searchbox .x-toolbar-left{vertical-align:middle}.ext-opera .sds-searchbox .x-toolbar-right{vertical-align:top}.sds-user-about-window.x-window-dlg .sds-user-about-desc{line-height:20px;height:120px;margin-bottom:8px}.sds-user-about-window.x-window-dlg .sds-user-about-terms-and-cond{line-height:20px;font-weight:bold;margin-bottom:24px}.syno-sds-appview{outline:none}.syno-sds-appview:after{content:"";position:absolute;height:8px;width:100%;bottom:0px;z-index:10;background-repeat:no-repeat;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0icmdiYSgwLDAsMCwwKSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0icmdiYSgwLDAsMCwwLjQpIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0,0,0,0)), color-stop(100%, rgba(0,0,0,0.4)));background-image:-webkit-linear-gradient(top, rgba(0,0,0,0),rgba(0,0,0,0.4));background-image:-moz-linear-gradient(top, rgba(0,0,0,0),rgba(0,0,0,0.4));background-image:-o-linear-gradient(top, rgba(0,0,0,0),rgba(0,0,0,0.4));background-image:linear-gradient(top, rgba(0,0,0,0),rgba(0,0,0,0.4))}.syno-sds-appview .crossbrowser-background{position:absolute;width:inherit;height:inherit;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=70);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=70);opacity:0.7}.syno-sds-appview .syno-sds-appview-container{outline:none;padding:16px 0px 0px 0px}.syno-sds-appview .syno-sds-appview-container.hide-scroll .vscrollerbar{visibility:hidden !important}.syno-sds-appview .app-panel-title{color:#FFFFFF;height:32px;line-height:32px;padding-left:32px;font-size:13px;font-weight:bold;text-shadow:0px 1px 3px #000000;margin-bottom:8px}.syno-sds-appview .system-app-panel-title{visibility:hidden}.syno-sds-appview .search-result-app-panel-title{background-image:url(../images/desktop/icon_app_category.png);background-position:0 -96px;background-repeat:no-repeat}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-sds-appview .search-result-app-panel-title{background-image:url("../img/synohdpack/images/dsm/resources/images/desktop/icon_app_category.png");background-size:32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-sds-appview .search-result-app-panel-title{background-image:url("../img/synohdpack/images/dsm/resources/images/desktop/icon_app_category.png");background-size:32px;outline:1px green dashed}}.syno-sds-appview .sds-app-items-panel{display:inline-block}.syno-sds-appview .sds-app-items-panel.frequently-used-panel{height:136px;overflow:hidden}.syno-sds-appview .sds-appview-app-item{width:136px;height:120px;padding:16px 8px 0px 8px;float:left;cursor:pointer}.syno-sds-appview .sds-appview-app-item.new-app{background-image:url(../images/desktop/spotlight.png);background-position:8px 0px;background-repeat:no-repeat;overflow:visible}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-sds-appview .sds-appview-app-item.new-app{background-image:url("../img/synohdpack/images/dsm/resources/images/desktop/spotlight.png");background-size:136px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-sds-appview .sds-appview-app-item.new-app{background-image:url("../img/synohdpack/images/dsm/resources/images/desktop/spotlight.png");background-size:136px;outline:1px green dashed}}.syno-sds-appview .sds-appview-app-item img{opacity:1;width:72px;margin-left:32px}.syno-sds-appview .sds-appview-app-item .sds-appview-app-item-title{color:#FFFFFF;font:12px verdana, tahoma, arial, helvetica, sans-serif;text-align:center;text-shadow:0.1em 0.1em 0.1em #000000;padding-top:8px}.syno-sds-appview .ux-float-layout-ct.sds-float-layout-ct-animate .x-box-item{-webkit-transition-property:top,left;-moz-transition-property:top,left;-o-transition-property:top,left;transition-property:top,left;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0.3s;-moz-transition-duration:0.3s;-o-transition-duration:0.3s;transition-duration:0.3s}.syno-sds-appview .on-mouse-out .sds-app-panel,.syno-sds-appview .on-instruction .sds-app-panel{opacity:0.5}.classical.syno-sds-appview{padding-left:22px;position:absolute}.classical.syno-sds-appview .crossbrowser-background{background-color:#F5FAFF;border-bottom-right-radius:3px;border-bottom-left-radius:3px;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=100);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);opacity:1;box-shadow:0 2px 6px rgba(0,0,0,0.5)}.classical.syno-sds-appview:after{background-image:none}.classical.syno-sds-appview .sds-appview-searchfiled{top:0;left:0;margin:12px 20px 12px 16px}.classical.syno-sds-appview .syno-sds-appview-container{padding:0}.classical.syno-sds-appview .sds-app-items-panel{display:block}.classical.syno-sds-appview .sds-app-items-panel.search-result-app-panel{overflow:hidden}.classical.syno-sds-appview .sds-appview-app-item{width:136px;height:100px;padding:0}.classical.syno-sds-appview .sds-appview-app-item img{display:block;opacity:1;width:48px;margin-left:44px}.classical.syno-sds-appview .sds-appview-app-item .sds-appview-app-item-title{color:#505a64;text-shadow:none;padding-top:4px}.classical.syno-sds-appview.x-hide-offsets .sds-appview-app-item,.classical.syno-sds-appview.x-hide-offsets .syno-ux-textfilter-trigger,.classical.syno-sds-appview.x-hide-offsets .vscrollerbar.scrollgeneric{visibility:hidden !important}.sds-search-result{background-image:none;color:#505A64}.sds-search-result.x-layer{border-color:#C8D2DC;background-color:#FFFFFF;padding:4px;box-shadow:0 2px 4px rgba(0,0,0,0.5)}.sds-search-result .x-combo-list-hd{border:none}.sds-search-result .x-combo-list-hd,.sds-search-result .section{height:32px;line-height:32px;background:#FFF;padding:0 0 0 16px;color:#0086E5;font-size:15px;font-weight:normal;cursor:default}.sds-search-result .section{padding-left:8px}.sds-search-result .x-combo-list-inner{background-color:#FFF;padding-left:8px}.sds-search-result .x-combo-list-item{white-space:no-wrap;width:100%;padding:0px;height:32px;line-height:32px}.sds-search-result .x-combo-list-item,.sds-search-result .x-combo-list-item.x-combo-selected{border:none !important}.sds-search-result .x-combo-list-item img{padding:8px}.sds-search-result .x-combo-list-item .topic{padding-left:0}.sds-search-result .x-combo-selected{background:#F5FAFF}.sds-search-result .x-combo-selected:active{background:#E6F5FF}.sds-search-result .loading-indicator{margin-top:0px}.sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-text,.sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-text,.ext-webkit .sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-text{font-size:12px;color:#505A64;background-image:url(/scripts/ext-3/ux/images/Components/icon_search.png);background-position:4px 0px;padding-left:30px;padding-top:0px;height:24px !important;line-height:24px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-text,.sds-window-v5 .syno-textfilter .x-form-field-wrap .synohdpack .syno-textfilter-text,.synohdpack .sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-text,.sds-widget-window .syno-textfilter .x-form-field-wrap .synohdpack .syno-textfilter-text{background-image:url("../img/synohdpack/images/Components/icon_search.png");background-size:24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-text,.sds-window-v5 .syno-textfilter .x-form-field-wrap .synohdpackdebug .syno-textfilter-text,.synohdpackdebug .sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-text,.sds-widget-window .syno-textfilter .x-form-field-wrap .synohdpackdebug .syno-textfilter-text{background-image:url("../img/synohdpack/images/Components/icon_search.png");background-size:24px;outline:1px green dashed}}.sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-text,.sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-text{margin-top:1px}.ext-ie .sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-text,.ext-ie .sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-text{margin-top:1px !important}.sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-text.x-form-empty-field,.sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-text.x-form-empty-field{color:#96A0AA}.sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger,.sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger{background:url(/scripts/ext-3/ux/images/Components/icon_search_clear.png) 0px 0px no-repeat;border:none;width:24px;height:24px;right:0px;margin-top:1px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger,.synohdpack .sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger{background-image:url("../img/synohdpack/images/Components/icon_search_clear.png");background-size:24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger,.synohdpackdebug .sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger{background-image:url("../img/synohdpack/images/Components/icon_search_clear.png");background-size:24px;outline:1px green dashed}}.sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger.x-form-trigger-over,.sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger.x-form-trigger-over{background-position:0 -24px}.sds-window-v5 .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger:active,.sds-widget-window .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger:active{background-position:0 -48px}.sds-desktop-view-animate{position:absolute;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=40);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);opacity:0.4;-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0.15s;-moz-transition-duration:0.15s;-o-transition-duration:0.15s;transition-duration:0.15s}.sds-desktop-view-animate .scale-item{-o-transform:scale(0.95);-moz-transform:scale(0.95);-ms-transform:scale(0.95);-webkit-transform:scale(0.95);transform:scale(0.95);-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden;-webkit-transition-property:top,left,opacity,-webkit-transform;-moz-transition-property:top,left,opacity,-moz-transform;-o-transition-property:top,left,opacity,-o-transform;transition-property:top,left,opacity,transform;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0.2s;-moz-transition-duration:0.2s;-o-transition-duration:0.2s;transition-duration:0.2s}.sds-desktop-view-animate.sds-widgetview .scale-item{-webkit-transition-property:top,left,opacity,-webkit-transform;-moz-transition-property:top,left,opacity,-moz-transform;-o-transition-property:top,left,opacity,-o-transform;transition-property:top,left,opacity,transform;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0.2s;-moz-transition-duration:0.2s;-o-transition-duration:0.2s;transition-duration:0.2s}.sds-desktop-view-animate.sds-desktop-view-show{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=100);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);opacity:1}.sds-desktop-view-animate.sds-desktop-view-show .scale-item{-o-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1)}.sds-desktop-view-animate.no-transition{-webkit-transition-property:none;-moz-transition-property:none;-o-transition-property:none;transition-property:none;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0s;-moz-transition-duration:0s;-o-transition-duration:0s;transition-duration:0s}.sds-desktop-view-animate.no-transition .scale-item{-webkit-transition-property:none;-moz-transition-property:none;-o-transition-property:none;transition-property:none;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0s;-moz-transition-duration:0s;-o-transition-duration:0s;transition-duration:0s}.bounce-effect-fast{-webkit-animation:bounce 400ms ease-out;-moz-animation:bounce 400ms ease-out;-o-animation:bounce 400ms ease-out;animation:bounce 400ms ease-out}.sds-app-widget-instruction{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=0);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);opacity:0;position:absolute;z-index:3;top:0}.sds-app-widget-instruction.show{-webkit-transition-property:opacity, filter;-moz-transition-property:opacity, filter;-o-transition-property:opacity, filter;transition-property:opacity, filter;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0.2s;-moz-transition-duration:0.2s;-o-transition-duration:0.2s;transition-duration:0.2s;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=100);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);opacity:1}.sds-app-widget-instruction .message-arrow{position:absolute;overflow:hidden;width:22px;height:35px}.ext-ie8m .sds-app-widget-instruction .message-arrow{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=75);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=75);opacity:0.75;left:-12px;width:0px;height:0px;border:12px solid transparent;border-right-color:#fff;border-left-width:0px}.sds-app-widget-instruction .message-arrow::after{background:#282d32;background:#282d32;content:'';position:absolute;left:6px;width:16px;height:16px;-webkit-transform-origin:right top;-moz-transform-origin:right top;-ms-transform-origin:right top;-o-transform-origin:right top;transform-origin:right top;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg);box-shadow:0 2px 4px rgba(0,0,0,0.5);border-top:solid 1px white;border-left:solid 1px white}.sds-app-widget-instruction .message-container{visibility:visible;position:absolute;max-width:218px;height:auto;font-size:16px;line-height:22px;color:#FFFFFF;padding:10px 16px;box-shadow:0 1px 4px rgba(0,0,0,0.25);border:solid 1px;border-color:#fff;border-color:rgba(255,255,255,0.75);background:#000;background:rgba(0,0,0,0.75)}body,.ext-el-mask-msg div,.x-tab-strip span.x-tab-strip-text,.x-form-field,.x-form-grow-sizer,.x-form-item,.x-form-invalid-msg,.x-fieldset legend,.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label,.x-grid-group-hd div.x-grid-group-title,.x-grid-empty,.x-tip .x-tip-mc,.x-tip .x-tip-header-text,.x-tip .x-tip-body,.x-window-mc,.x-window-dlg .ext-mb-textarea,.x-small-editor .x-form-field,.ext-webkit .x-small-editor .x-form-field,.x-grid3-hd-row td,.x-grid3-row td,.x-grid3-summary-row td,.x-grid3-topbar,.x-grid3-bottombar,.x-tree-node,.x-date-inner th,.x-date-inner a,.x-date-mp td,.x-date-mp-btns button,.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label,.x-list-header-inner div em,.x-list-body dt em,.x-btn,.x-btn button,.x-dd-drag-ghost,.x-date-middle,.x-date-left,.x-date-right,.x-menu-list-item,.x-combo-list,.x-combo-list-hd,.x-combo-list-small,.x-panel-tl .x-panel-header,.x-panel .x-panel-header,.x-panel-mc,.x-window-tl .x-window-header{font-family:verdana,tahoma,arial,helvetica,sans-serif}.syno-ux-modulelist .x-tree-root-node{width:212px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .x-tree-node-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_general.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .x-tree-node-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_general.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-CMS{background-image:url("../images/module_list_icon/c_icon_CMS.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-CMS{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_CMS.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-CMS{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_CMS.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-backup{background-image:url("../images/module_list_icon/c_icon_backup.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-backup{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_backup.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-backup{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_backup.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-business{background-image:url("../images/module_list_icon/c_icon_business.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-business{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_business.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-business{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_business.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-contact{background-image:url("../images/module_list_icon/c_icon_contact.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-contact{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_contact.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-contact{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_contact.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-directory-service{background-image:url("../images/module_list_icon/c_icon_directory_service.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-directory-service{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_directory_service.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-directory-service{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_directory_service.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-dsm-apps{background-image:url("../images/module_list_icon/c_icon_dsm_apps.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-dsm-apps{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_dsm_apps.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-dsm-apps{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_dsm_apps.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-expansion{background-image:url("../images/module_list_icon/c_icon_expansion.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-expansion{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_expansion.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-expansion{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_expansion.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-external-devices{background-image:url("../images/module_list_icon/c_icon_external_devices.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-external-devices{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_external_devices.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-external-devices{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_external_devices.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-file-services{background-image:url("../images/module_list_icon/c_icon_file_services.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-file-services{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_file_services.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-file-services{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_file_services.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-groups{background-image:url("../images/module_list_icon/c_icon_groups.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-groups{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_groups.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-groups{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_groups.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-hardware-and-power{background-image:url("../images/module_list_icon/c_icon_hardware_and_power.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-hardware-and-power{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hardware_and_power.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-hardware-and-power{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hardware_and_power.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-purchases{background-image:url("../images/module_list_icon/c_icon_purchases.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-purchases{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_purchases.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-purchases{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_purchases.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-syslog{background-image:url("../images/module_list_icon/c_icon_syslog.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-syslog{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_syslog.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-syslog{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_syslog.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-hdd-management{background-image:url("../images/module_list_icon/c_icon_hdd_management.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-hdd-management{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_hdd_management.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-hdd-management{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_hdd_management.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-hot-spare{background-image:url("../images/module_list_icon/c_icon_hot_spare.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-hot-spare{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_hot_spare.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-hot-spare{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_hot_spare.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-info-center{background-image:url("../images/module_list_icon/c_icon_info_center.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-info-center{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_info_center.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-info-center{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_info_center.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-installed{background-image:url("../images/module_list_icon/c_icon_installed.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-installed{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_installed.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-installed{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_installed.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-iscsi-lun{background-image:url("../images/module_list_icon/c_icon_iscsi_lun.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-iscsi-lun{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_iscsi_lun.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-iscsi-lun{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_iscsi_lun.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-iscsi-target{background-image:url("../images/module_list_icon/c_icon_iscsi_target.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-iscsi-target{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_iscsi_target.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-iscsi-target{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_iscsi_target.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-login-style{background-image:url("../images/module_list_icon/c_icon_login_style.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-login-style{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_login_style.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-login-style{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_login_style.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-media-library{background-image:url("../images/module_list_icon/c_icon_media_library.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-media-library{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_media_library.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-media-library{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_media_library.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-network{background-image:url("../images/module_list_icon/c_icon_network.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-network{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_network.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-network{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_network.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-networkmap{background-image:url("../images/module_list_icon/c_icon_networkmap.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-networkmap{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_networkmap.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-networkmap{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_networkmap.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-notifications{background-image:url("../images/module_list_icon/c_icon_notifications.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-notifications{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_notifications.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-notifications{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_notifications.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-overview{background-image:url("../images/module_list_icon/c_icon_overview.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-overview{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_overview.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-overview{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_overview.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-portal{background-image:url("../images/module_list_icon/c_icon_portal.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-portal{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_portal.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-portal{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_portal.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-privilege{background-image:url("../images/module_list_icon/c_icon_privilege.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-privilege{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_privilege.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-privilege{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_privilege.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-public-access{background-image:url("../images/module_list_icon/c_icon_public_access.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-public-access{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_public_access.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-public-access{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_public_access.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-quickconnect{background-image:url("../images/module_list_icon/c_icon_quickconnect.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-quickconnect{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_quickconnect.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-quickconnect{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_quickconnect.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-raid-group{background-image:url("../images/module_list_icon/c_icon_raid_group.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-raid-group{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_raid_group.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-raid-group{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_raid_group.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-recommend{background-image:url("../images/module_list_icon/c_icon_recommend.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-recommend{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_recommend.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-recommend{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_recommend.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-region{background-image:url("../images/module_list_icon/c_icon_region.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-region{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_region.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-region{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_region.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-security{background-image:url("../images/module_list_icon/c_icon_security.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-security{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_security.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-security{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_security.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-shared-folders{background-image:url("../images/module_list_icon/c_icon_shared_folders.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-shared-folders{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_shared_folders.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-shared-folders{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_shared_folders.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-ssd-cache{background-image:url("../images/module_list_icon/c_icon_ssd_cache.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-ssd-cache{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_ssd_cache.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-ssd-cache{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_ssd_cache.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-task-scheduler{background-image:url("../images/module_list_icon/c_icon_task_scheduler.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-task-scheduler{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_task_scheduler.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-task-scheduler{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_task_scheduler.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-terminal-and-SNMP{background-image:url("../images/module_list_icon/c_icon_terminal_and_SNMP.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-terminal-and-SNMP{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_terminal_and_SNMP.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-terminal-and-SNMP{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_terminal_and_SNMP.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-update-and-reset{background-image:url("../images/module_list_icon/c_icon_update_and_reset.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-update-and-reset{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_update_and_reset.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-update-and-reset{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_update_and_reset.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-users{background-image:url("../images/module_list_icon/c_icon_users.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-users{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_users.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-users{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_users.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-utilities{background-image:url("../images/module_list_icon/c_icon_utilities.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-utilities{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_utilities.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-utilities{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_utilities.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-volume{background-image:url("../images/module_list_icon/c_icon_volume.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-volume{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_volume.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-volume{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_volume.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-web-server{background-image:url("../images/module_list_icon/c_icon_web_server.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-web-server{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_web_server.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-web-server{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_web_server.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-wireless{background-image:url("../images/module_list_icon/c_icon_wireless.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-wireless{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_wireless.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-wireless{background-image:url("../img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_wireless.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-performance{background-image:url("../images/module_list_icon/c_icon_performance.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-performance{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_performance.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-performance{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_performance.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-process{background-image:url("../images/module_list_icon/c_icon_process.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-process{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_process.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-process{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_process.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-connect{background-image:url("../images/module_list_icon/c_icon_connect.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-connect{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_connect.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-connect{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_connect.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-speed{background-image:url("../images/module_list_icon/c_icon_speed.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-speed{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_speed.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-speed{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_speed.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf .icon-community{background-image:url("../images/module_list_icon/c_icon_community.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .icon-community{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_community.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .icon-community{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/module_list_icon/c_icon_community.png");background-size:24px 96px;outline:1px green dashed}}.x-tip{box-shadow:0 1px 4px rgba(0,0,0,0.25);border:solid 1px;border-color:#fff;border-color:rgba(255,255,255,0.75);background:#000;background:rgba(0,0,0,0.75)}.x-tip .x-tip-ml,.x-tip .x-tip-mr,.x-tip .x-tip-mc,.x-tip .x-tip-tl,.x-tip .x-tip-tr,.x-tip .x-tip-tc,.x-tip .x-tip-bl,.x-tip .x-tip-br,.x-tip .x-tip-bc{padding:0px;background-image:none;background-color:transparent}.x-tip .x-tip-bwrap{padding:3px 10px}.x-tip .x-tip-body,.x-tip .x-tip-body span,.x-tip .x-tip-body div{font-size:12px !important;color:#FFFFFF !important}.sds-wizard-banner .x-panel-body{background-color:transparent}.ext-ie7 .sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct,.ext-ie7 .sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct,.ext-ie7 .sds-window-v5 .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct,.ext-ie7 .sds-widget-window .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct,.ext-ie8 .sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct,.ext-ie8 .sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct,.ext-ie8 .sds-window-v5 .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct,.ext-ie8 .sds-widget-window .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct,.ext-ie9 .sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct,.ext-ie9 .sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct,.ext-ie9 .sds-window-v5 .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct,.ext-ie9 .sds-widget-window .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct{width:auto !important}.sds-window-v5 .sds-wizard-banner-wrap,.sds-widget-window .sds-wizard-banner-wrap{background-image:url("../images/wizard_bkg_h.png");background-repeat:no-repeat;background-position:top right;background-color:#008def;height:112px !important;display:table}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5 .sds-wizard-banner-wrap,.synohdpack .sds-widget-window .sds-wizard-banner-wrap{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/wizard_bkg_h.png");background-size:414px 112px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5 .sds-wizard-banner-wrap,.synohdpackdebug .sds-widget-window .sds-wizard-banner-wrap{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/wizard_bkg_h.png");background-size:414px 112px;outline:1px green dashed}}.sds-window-v5 .x-panel-body.sds-wizard-banner,.sds-widget-window .x-panel-body.sds-wizard-banner{background-image:none;background-color:transparent;border-bottom:0px;display:table-cell;vertical-align:middle}.sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct,.sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct,.sds-window-v5 .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct,.sds-widget-window .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct{padding-right:20px;padding-left:20px;background-image:none}.sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct,.sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct,.sds-window-v5 .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct,.sds-widget-window .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct{background-image:url("../images/shadow_footbar.png");background-repeat:repeat-x;background-color:transparent;border:0px;padding-top:4px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct,.synohdpack .sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct,.synohdpack .sds-window-v5 .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct,.synohdpack .sds-widget-window .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/shadow_footbar.png");background-size:8px 4px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct,.synohdpackdebug .sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct,.synohdpackdebug .sds-window-v5 .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct,.synohdpackdebug .sds-widget-window .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/shadow_footbar.png");background-size:8px 4px;outline:1px green dashed}}.sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-left,.sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-left,.sds-window-v5 .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-left,.sds-widget-window .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-left{padding:0px 0px 0px 10px}.sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-cell,.sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-cell,.sds-window-v5 .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-cell,.sds-widget-window .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-cell{padding:0}.sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-cell .syno-ux-button,.sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-cell .syno-ux-button,.sds-window-v5 .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-cell .syno-ux-button,.sds-widget-window .x-window-footer.sds-wizard-footer .x-panel-fbar.x-toolbar-layout-ct .x-toolbar-ct .x-toolbar-cell .syno-ux-button{margin:8px 10px 8px 0px}.sds-window-v5 .x-window-footer.sds-wizard-footer-welcome,.sds-widget-window .x-window-footer.sds-wizard-footer-welcome{background-image:url("../images/dsmv5_wizard_bkg_v_01.png");background-position:bottom left;background-repeat:no-repeat}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5 .x-window-footer.sds-wizard-footer-welcome,.synohdpack .sds-widget-window .x-window-footer.sds-wizard-footer-welcome{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/dsmv5_wizard_bkg_v_01.png");background-size:140px 48px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5 .x-window-footer.sds-wizard-footer-welcome,.synohdpackdebug .sds-widget-window .x-window-footer.sds-wizard-footer-welcome{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/dsmv5_wizard_bkg_v_01.png");background-size:140px 48px;outline:1px green dashed}}.sds-window-v5 .x-window-footer.sds-wizard-footer-welcome .x-toolbar-layout-ct,.sds-widget-window .x-window-footer.sds-wizard-footer-welcome .x-toolbar-layout-ct{margin-left:140px}.sds-window-v5 .sds-wizard-banner .wizard-headline,.sds-widget-window .sds-wizard-banner .wizard-headline{font-size:18px;line-height:24px;font-weight:bold;color:#FFFFFF;overflow:hidden;padding-top:0px}.sds-window-v5 .sds-wizard-banner .wizard-description,.sds-widget-window .sds-wizard-banner .wizard-description{font-size:14px;line-height:18px;color:#FFFFFF;overflow:hidden}.sds-window-v5 .sds-wizard-step .sds-wizard-step-bwrap,.sds-widget-window .sds-wizard-step .sds-wizard-step-bwrap{padding:12px 20px 8px 20px}.sds-window-v5 .sds-wizard-step .welcome-headline,.sds-widget-window .sds-wizard-step .welcome-headline{font-size:15px;font-weight:bold;color:#505a64;padding:12px 20px 12px 20px;border-bottom:0px}.sds-window-v5 .sds-wizard-step .welcome-text,.sds-widget-window .sds-wizard-step .welcome-text{color:#505a64;font-size:13px;padding-right:20px;padding-left:20px}.sds-window-v5 .sds-wizard-step .welcome-image,.sds-widget-window .sds-wizard-step .welcome-image{background-image:url("../images/dsmv5_wizard_bkg_v_02.png") !important;background-position:bottom left;background-repeat:no-repeat}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5 .sds-wizard-step .welcome-image,.synohdpack .sds-widget-window .sds-wizard-step .welcome-image{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/dsmv5_wizard_bkg_v_02.png") !important;background-size:140px 366px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5 .sds-wizard-step .welcome-image,.synohdpackdebug .sds-widget-window .sds-wizard-step .welcome-image{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/dsmv5_wizard_bkg_v_02.png") !important;background-size:140px 366px;outline:1px green dashed}}.sds-window-v5 .sds-wizard-step .welcome-image-text,.sds-widget-window .sds-wizard-step .welcome-image-text{position:relative;text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;left:17px;font-size:18px;font-weight:bold;line-height:24px;color:#FFFFFF;background-color:transparent;-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);-webkit-transform-origin:left bottom;-moz-transform-origin:left bottom;-ms-transform-origin:left bottom;-o-transform-origin:left bottom;transform-origin:left bottom;filter:progid:DXImageTransform.Microsoft.Matrix(M11=0.00000000, M12=-1.00000000, M21=1.00000000, M22=0.00000000, SizingMethod='auto expand');-ms-filter:"progid:DXImageTransform.Microsoft.Matrix(M11=0, M12=-1, M21=1, M22=0, SizingMethod='auto expand')"}.sds-wizard-banner{padding-left:20px;padding-right:20px;background:url(../images/wizard-banner.png) repeat top right;background-color:#FAFAFA;border-top:0px;border-right:0px;border-left:0px;border-bottom:1px solid #ddd}.sds-wizard-banner .wizard-headline{font-size:12px;font-weight:bold;color:#222;padding-top:10px}.sds-wizard-banner .wizard-description{font-size:11px}.sds-wizard-step .welcome-headline{font-size:12px;font-weight:bold;color:#222;padding:10px;padding-left:30px;border-bottom:1px solid #ddd}.sds-wizard-step .welcome-image{background:url(../images/wizard_welcome.png) left bottom no-repeat !important}.sds-wizard-step .welcome-text{font-size:12px;padding:10px;padding-left:30px}.sds-wizard-step .welcome-text li{list-style-image:none;list-style-position:inside;list-style-type:square;padding-top:5px}.sds-wizard-step .x-status-loading{background-image:url("../images/components/status_loading.gif");background-repeat:no-repeat;background-position:center center}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-wizard-step .x-status-loading{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/status_loading.gif");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-wizard-step .x-status-loading{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/status_loading.gif");background-size:24px 24px;outline:1px green dashed}}.sds-wizard-step .x-status-success{background-image:url("../images/components/status_success.png");background-repeat:no-repeat;background-position:center center}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-wizard-step .x-status-success{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/status_success.png");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-wizard-step .x-status-success{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/status_success.png");background-size:24px 24px;outline:1px green dashed}}.sds-wizard-step .x-status-fail{background-image:url("../images/components/status_fail.png");background-repeat:no-repeat;background-position:center center}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-wizard-step .x-status-fail{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/status_fail.png");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-wizard-step .x-status-fail{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/status_fail.png");background-size:24px 24px;outline:1px green dashed}}.sds-wizard-step .x-status-warning{background-image:url("../images/components/icon_error.png");background-size:100% 100%;background-repeat:no-repeat;background-position:center center}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-wizard-step .x-status-warning{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/icon_error.png");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-wizard-step .x-status-warning{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/icon_error.png");background-size:24px 24px;outline:1px green dashed}}.syno-sds-image-selector input.image-selector-upload-file{width:1px;height:1px}.ext-firefox3 .image-selector-upload-form form,.ext-ie .syno-sds-image-selector .image-selector-upload-form form{width:140px}.ext-firefox3 input.image-selector-upload-file,.ext-ie .syno-sds-image-selector input.image-selector-upload-file{opacity:0 !important;filter:alpha(opacity=0) !important;width:120px;height:20px;font-size:30px;cursor:pointer;margin-left:10px}.syno-sds-image-selector label.image-selector-fake-upload-button{position:absolute;left:10px;color:blue;width:120px;text-align:center}.syno-sds-image-selector table.x-btn-over button{text-decoration:underline}.syno-sds-image-selector label{color:#505A64}.syno-sds-image-selector .tree_myimage .x-tree-ec-icon.x-tree-elbow,.syno-sds-image-selector .tree_myimage .x-tree-ec-icon.x-tree-elbow-end{display:none}.syno-sds-image-selector .tree_myimage .x-tree-node-icon{margin:6px 8px 0 8px;height:16px}.syno-sds-image-selector .tree_myimage .icon_my_image{background-position:0 0;background-repeat:no-repeat;background-image:url("../images/components/icon_image_selector.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-sds-image-selector .tree_myimage .icon_my_image{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/icon_image_selector.png");background-size:16px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-sds-image-selector .tree_myimage .icon_my_image{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/icon_image_selector.png");background-size:16px 32px;outline:1px green dashed}}.syno-sds-image-selector .tree_myimage .icon_default_image{background-position:0 -16px;background-repeat:no-repeat;background-image:url("../images/components/icon_image_selector.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-sds-image-selector .tree_myimage .icon_default_image{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/icon_image_selector.png");background-size:16px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-sds-image-selector .tree_myimage .icon_default_image{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/components/icon_image_selector.png");background-size:16px 32px;outline:1px green dashed}}.syno-sds-image-selector .tree_filestation .x-tree-node-icon{display:none}.syno-sds-image-selector .x-layout-split{background-position:right 0;background-repeat:repeat-y;background-image:url("../../../scripts/ext-3.4/ux/images/Components/shadow_category.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-sds-image-selector .x-layout-split{background-image:url("../img/synohdpack/images/Components/shadow_category.png");background-size:4px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-sds-image-selector .x-layout-split{background-image:url("../img/synohdpack/images/Components/shadow_category.png");background-size:4px;outline:1px green dashed}}.syno-sds-image-selector .image-selector-upload-form .x-form-item{margin-bottom:0}.syno-sds-image-selector div.thumb-wrap{margin-bottom:4px;margin-right:8px;float:left;height:166px}.syno-sds-image-selector .x-view-selected .thumb{background:#E6F5FF;border:1px solid #A6DAFF}.syno-sds-image-selector .thumb{padding:8px 8px 4px 8px;height:150px;width:120px;border:1px solid;border-color:#fff;border-color:rgba(255,255,255,0);position:relative;display:table-cell;vertical-align:bottom}.syno-sds-image-selector .thumb img{box-shadow:0 1px 3px rgba(0,0,0,0.5);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.5);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.5);max-height:120px;max-width:120px;width:auto;height:auto}.syno-sds-image-selector .thumb .thumb-loading{background-repeat:no-repeat;background-position:center center;background-color:transparent;background-image:url("../../modules/PhotoViewer/images/loading.gif")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-sds-image-selector .thumb .thumb-loading{background-image:url("../img/synohdpack/images/dsm/resources/css/../../modules/PhotoViewer/images/loading.gif");background-size:16px 16px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-sds-image-selector .thumb .thumb-loading{background-image:url("../img/synohdpack/images/dsm/resources/css/../../modules/PhotoViewer/images/loading.gif");background-size:16px 16px;outline:1px green dashed}}.syno-sds-image-selector .thumb .thumb-hover{height:120px;width:120px;display:table-cell;text-align:center;vertical-align:bottom}.syno-sds-image-selector .thumb:hover{background-color:#E6F5FF}.syno-sds-image-selector .thumb span{display:block;overflow:hidden;text-align:center;text-overflow:ellipsis;white-space:nowrap;height:24px;margin-top:4px;line-height:24px;font-size:12px;max-width:120px}.sds-notify-badge-num{background-image:url("../images/dsm5_notification_num.png");width:19px;height:14px;overflow:hidden;cursor:pointer;pointer-events:none}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-notify-badge-num{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/dsm5_notification_num.png");background-size:19px 1400px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-notify-badge-num{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/dsm5_notification_num.png");background-size:19px 1400px;outline:1px green dashed}}.sds-application-notify-badge-num{background-image:url("../images/dsm5_badge_num.png");width:34px;height:24px;overflow:hidden;z-index:3}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-application-notify-badge-num{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/dsm5_badge_num.png");background-size:34px 2400px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-application-notify-badge-num{background-image:url("../img/synohdpack/images/dsm/resources/css/../images/dsm5_badge_num.png");background-size:34px 2400px;outline:1px green dashed}}.sds-notify-badge-num.badge-fix-position{top:15px !important;left:14px !important}.ext-ie9 .sds-notify-badge-num.badge-fix-position,.ext-ie10 .sds-notify-badge-num.badge-fix-position,.ext-ie11 .sds-notify-badge-num.badge-fix-position{top:7px !important;left:6px !important}.bounce-effect{-webkit-animation:bounce 800ms ease-out;-moz-animation:bounce 800ms ease-out;-o-animation:bounce 800ms ease-out;animation:bounce 800ms ease-out}@-webkit-keyframes bounce{0%,5%{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%);opacity:0}15%{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}30%{-webkit-transform:translateY(-80%);-moz-transform:translateY(-80%);-ms-transform:translateY(-80%);-o-transform:translateY(-80%);transform:translateY(-80%)}40%,80%,100%{-webkit-transform:translateY(0%);-moz-transform:translateY(0%);-ms-transform:translateY(0%);-o-transform:translateY(0%);transform:translateY(0%)}60%{-webkit-transform:translateY(-30%);-moz-transform:translateY(-30%);-ms-transform:translateY(-30%);-o-transform:translateY(-30%);transform:translateY(-30%)}90%{-webkit-transform:translateY(-10%);-moz-transform:translateY(-10%);-ms-transform:translateY(-10%);-o-transform:translateY(-10%);transform:translateY(-10%)}100%{opacity:1}}@-o-keyframes bounce{0%,5%{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%);opacity:0}15%{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}30%{-webkit-transform:translateY(-80%);-moz-transform:translateY(-80%);-ms-transform:translateY(-80%);-o-transform:translateY(-80%);transform:translateY(-80%)}40%,80%,100%{-webkit-transform:translateY(0%);-moz-transform:translateY(0%);-ms-transform:translateY(0%);-o-transform:translateY(0%);transform:translateY(0%)}60%{-webkit-transform:translateY(-30%);-moz-transform:translateY(-30%);-ms-transform:translateY(-30%);-o-transform:translateY(-30%);transform:translateY(-30%)}90%{-webkit-transform:translateY(-10%);-moz-transform:translateY(-10%);-ms-transform:translateY(-10%);-o-transform:translateY(-10%);transform:translateY(-10%)}100%{opacity:1}}@-moz-keyframes bounce{0%,5%{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%);opacity:0}15%{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}30%{-webkit-transform:translateY(-80%);-moz-transform:translateY(-80%);-ms-transform:translateY(-80%);-o-transform:translateY(-80%);transform:translateY(-80%)}40%,80%,100%{-webkit-transform:translateY(0%);-moz-transform:translateY(0%);-ms-transform:translateY(0%);-o-transform:translateY(0%);transform:translateY(0%)}60%{-webkit-transform:translateY(-30%);-moz-transform:translateY(-30%);-ms-transform:translateY(-30%);-o-transform:translateY(-30%);transform:translateY(-30%)}90%{-webkit-transform:translateY(-10%);-moz-transform:translateY(-10%);-ms-transform:translateY(-10%);-o-transform:translateY(-10%);transform:translateY(-10%)}100%{opacity:1}}@keyframes bounce{0%,5%{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%);opacity:0}15%{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}30%{-webkit-transform:translateY(-80%);-moz-transform:translateY(-80%);-ms-transform:translateY(-80%);-o-transform:translateY(-80%);transform:translateY(-80%)}40%,80%,100%{-webkit-transform:translateY(0%);-moz-transform:translateY(0%);-ms-transform:translateY(0%);-o-transform:translateY(0%);transform:translateY(0%)}60%{-webkit-transform:translateY(-30%);-moz-transform:translateY(-30%);-ms-transform:translateY(-30%);-o-transform:translateY(-30%);transform:translateY(-30%)}90%{-webkit-transform:translateY(-10%);-moz-transform:translateY(-10%);-ms-transform:translateY(-10%);-o-transform:translateY(-10%);transform:translateY(-10%)}100%{opacity:1}}#sds-weather-info{position:absolute;width:280px;height:330px;padding-left:20px;padding-top:8px;color:#FFFFFF;text-shadow:0px 1px 2px rgba(0,0,0,0.8)}#sds-weather-info .weather-temp{width:56px;height:24px;font-size:16px;font-weight:bold;font-family:"Roboto",verdana,tahoma,arial,helvetica,sans-serif;line-height:24px;padding-top:56px;padding-left:24px;float:left;cursor:pointer}#sds-weather-info .weather-icon{width:200px;height:200px;padding:0px;float:left}#sds-weather-info .weather-icon.thunder{background-image:url("../images/login/weather/login_icon_weather_thunder.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.thunder{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_thunder.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.thunder{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_thunder.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.rain{background-image:url("../images/login/weather/login_icon_weather_rain.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.rain{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_rain.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.rain{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_rain.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.snow{background-image:url("../images/login/weather/login_icon_weather_snow.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.snow{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_snow.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.snow{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_snow.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.fog{background-image:url("../images/login/weather/login_icon_weather_fog.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.fog{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_fog.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.fog{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_fog.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.sun{background-image:url("../images/login/weather/login_icon_weather_sun.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.sun{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_sun.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.sun{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_sun.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.moon{background-image:url("../images/login/weather/login_icon_weather_moon.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.moon{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_moon.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.moon{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_moon.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.sun_clouds{background-image:url("../images/login/weather/login_icon_weather_sun_clouds.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.sun_clouds{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_sun_clouds.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.sun_clouds{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_sun_clouds.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.moon_clouds{background-image:url("../images/login/weather/login_icon_weather_moon_clouds.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.moon_clouds{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_moon_clouds.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.moon_clouds{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_moon_clouds.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.cloudy{background-image:url("../images/login/weather/login_icon_weather_cloudy.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.cloudy{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_cloudy.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.cloudy{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_cloudy.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.tornado{background-image:url("../images/login/weather/login_icon_weather_tornado.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.tornado{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_tornado.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.tornado{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_tornado.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.cold{background-image:url("../images/login/weather/login_icon_weather_cold.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.cold{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_cold.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.cold{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_cold.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.windy{background-image:url("../images/login/weather/login_icon_weather_windy.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.windy{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_windy.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.windy{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_windy.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .weather-icon.hail{background-image:url("../images/login/weather/login_icon_weather_hail.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-weather-info .weather-icon.hail{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_hail.png");background-size:200px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-weather-info .weather-icon.hail{background-image:url("../img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_hail.png");background-size:200px;outline:1px green dashed}}#sds-weather-info .current-time{width:280px;height:80px;text-align:center;font-size:90px;line-height:70px;font-family:"Roboto",verdana,tahoma,arial,helvetica,sans-serif;padding-top:0px;padding-bottom:9px;float:left;border-bottom:solid 1px #FFFFFF;cursor:pointer}#sds-weather-info .current-time .time-tag{font-size:24px;padding-left:10px}#sds-weather-info .current-date{width:280px;height:21px;padding:9px 0px;font-size:15px;font-weight:bold;line-height:21px;font-family:verdana;text-align:center;float:left;border-top:solid 1px #000000}#sds-login{position:absolute;width:100%;height:100%;overflow:hidden;z-index:20000}#sds-login-bgimg{position:absolute;z-index:-1}#sds-login-cuslogo-wrapper{position:absolute;margin:20px 330px;overflow:hidden}#sds-login-background,#sds-steup-otp-background{position:absolute}#edit-otp-dialog,.enforce-wizard-err-message-dialog,.x-tip-invalid{z-index:2147483647 !important}#sds-login-dialog{position:absolute}#sds-login-dialog-form .x-form-text{height:24px;font-size:20px;line-height:20px;border-width:0px;color:#F3F3F3;background-image:none;background-color:transparent}.ext-ie8m .sds-login-light #sds-login-dialog-form .x-form-text{background-color:#FFFFFF;color:#000000}.ext-ie8m .sds-login-dark #sds-login-dialog-form .x-form-text{background-color:#000000;color:#FFFFFF}.sds-login-light #sds-login-dialog-form .x-form-text{text-shadow:0px 1px 1px rgba(0,0,0,0.7)}#sds-login-dialog-form div.x-panel-body{background-color:transparent;border-width:0px;padding:0px}#sds-login-icon{position:absolute;z-index:20001}#sds-login-dialog-form #login_rememberme{position:absolute;top:-1000000px;left:-1000000px}#x-form-el-login_rememberme{padding-top:8px}.sds-login-light #sds-login-dialog-form .syno-ux-checkbox-label{color:#F3F3F3;text-shadow:0px 1px 1px rgba(0,0,0,0.7)}.sds-login-light #sds-login-dialog-form .syno-ux-checkbox-label.syno-ux-cb-disabled{color:#F3F3F3 !important}.sds-login-dark #sds-login-dialog-form .syno-ux-checkbox-label{color:#888787;text-shadow:0px 1px 0px rgba(0,0,0,0.5)}.sds-login-dark #sds-login-dialog-form .syno-ux-checkbox-label.syno-ux-cb-disabled{color:#888787 !important}.sds-login-dark #sds-login-dialog-form .link,.sds-login-light #sds-login-dialog-form .link{font-size:14px;text-decoration:underline;text-align:right;padding-bottom:0px;padding-top:8px}.sds-login-dark #sds-login-dialog-form .link.appicon-ident,.sds-login-light #sds-login-dialog-form .link.appicon-ident{padding-right:52px}.sds-login-dark #sds-login-dialog-form .link:hover,.sds-login-light #sds-login-dialog-form .link:hover{cursor:pointer;color:#50ecff}.sds-login-dark #sds-login-dialog-form .link:active,.sds-login-light #sds-login-dialog-form .link:active{cursor:pointer;color:#00d6f0}.sds-login-dark #sds-login-dialog-form .link{color:#888787}.sds-login-light #sds-login-dialog-form .link{color:#F3F3F3}#sds-login-dialog-form #login-form{min-height:240px}#sds-login-dialog-form .x-form-item{margin:0px}#login-btn{min-width:120px}#login-btn.syno-ux-button.x-btn em button{font-size:20px;line-height:26px;margin-top:6px;padding-left:30px;padding-right:30px}#login-btn.x-btn.syno-ux-button{border-radius:2px;box-shadow:inset 0px 1px 0px rgba(255,255,255,0.3),0px 1px 0px rgba(0,0,0,0.2)}.sds-login-dark #login-btn.x-btn.syno-ux-button{border-color:#0b6fb6;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwODhlOSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzEzN2NjNiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #0088e9), color-stop(100%, #137cc6));background-image:-webkit-linear-gradient(top, #0088e9,#137cc6);background-image:-moz-linear-gradient(top, #0088e9,#137cc6);background-image:-o-linear-gradient(top, #0088e9,#137cc6);background-image:linear-gradient(top, #0088e9,#137cc6)}.sds-login-dark #login-btn.x-btn.syno-ux-button:hover{border-color:#0b5e9a;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwOTBmNyIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzE3ODhkOCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #0090f7), color-stop(100%, #1788d8));background-image:-webkit-linear-gradient(top, #0090f7,#1788d8);background-image:-moz-linear-gradient(top, #0090f7,#1788d8);background-image:-o-linear-gradient(top, #0090f7,#1788d8);background-image:linear-gradient(top, #0090f7,#1788d8)}.sds-login-dark #login-btn.x-btn.syno-ux-button:active{border-color:#0b5e9a;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwN2NkNSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzExNmZiMyIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #007cd5), color-stop(100%, #116fb3));background-image:-webkit-linear-gradient(top, #007cd5,#116fb3);background-image:-moz-linear-gradient(top, #007cd5,#116fb3);background-image:-o-linear-gradient(top, #007cd5,#116fb3);background-image:linear-gradient(top, #007cd5,#116fb3)}#sds-login-dialog #sds-login-bkg-highlight{width:336px;min-height:336px;position:absolute}#sds-login-dialog #sds-login-bkg-highlight .highlight-top{width:336px;height:120px;background-image:url("../img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_top.png");background-size:336px 120px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-login-dialog #sds-login-bkg-highlight .highlight-top{background-image:url("../img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_top.png");background-size:336px 120px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-login-dialog #sds-login-bkg-highlight .highlight-top{background-image:url("../img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_top.png");background-size:336px 120px;outline:1px green dashed}}#sds-login-dialog #sds-login-bkg-highlight .highlight-bottom{width:336px;height:94px;background-image:url("../img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_bottom.png");background-size:336px 94px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack #sds-login-dialog #sds-login-bkg-highlight .highlight-bottom{background-image:url("../img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_bottom.png");background-size:336px 94px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug #sds-login-dialog #sds-login-bkg-highlight .highlight-bottom{background-image:url("../img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_bottom.png");background-size:336px 94px;outline:1px green dashed}}#sds-login-dialog-form{width:567px}.sds-login-light .sds-login-dialog-form-table.x-panel{box-shadow:0px 1px 0px rgba(0,0,0,0.2)}.sds-login-dark .sds-login-dialog-form-table.x-panel{box-shadow:0px 1px 0px rgba(0,0,0,0.5)}.sds-login-light .sds-login-dialog-form-table td{height:58px;border-bottom:solid 1px;border-color:#fff;border-color:rgba(255,255,255,0.6);box-shadow:0px 1px 0px rgba(0,0,0,0.2)}.sds-login-dark .sds-login-dialog-form-table td{height:58px;border-bottom:solid 1px;border-color:#fff;border-color:rgba(255,255,255,0.3);box-shadow:0px 1px 0px rgba(0,0,0,0.5)}.sds-login-dialog-form-table td.prefix{width:200px;background-image:none}.sds-login-dialog-form-table td.username-icon,.sds-login-dialog-form-table td.passwd-icon,.sds-login-dialog-form-table td.otp-icon{width:32px;background-repeat:no-repeat;background-position:10px 13px}.sds-login-dialog-form-table td.username-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/login/icon_user.png");background-size:32px 32px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-login-dialog-form-table td.username-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/login/icon_user.png");background-size:32px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-login-dialog-form-table td.username-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/login/icon_user.png");background-size:32px 32px;outline:1px green dashed}}.sds-login-dialog-form-table td.passwd-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/login/icon_pw.png");background-size:32px 32px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-login-dialog-form-table td.passwd-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/login/icon_pw.png");background-size:32px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-login-dialog-form-table td.passwd-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/login/icon_pw.png");background-size:32px 32px;outline:1px green dashed}}.sds-login-dialog-form-table td.otp-icon{background-image:url(../images/login/icon_phone.png)}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-login-dialog-form-table td.otp-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/login/icon_phone.png");background-size:32px 32px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-login-dialog-form-table td.otp-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/login/icon_phone.png");background-size:32px 32px;outline:1px green dashed}}.sds-login-dialog-form-table td.center{width:240px}#sds-fp-dialog{width:345px;height:333px}#sds-login-dialog{width:336px;min-height:336px;border-radius:3px}.sds-login-light #sds-login-dialog{background-color:#fff;background-color:rgba(255,255,255,0.36);border:solid 1px;border-color:rgba(255,255,255,0.7);box-shadow:0px 2px 4px 1px rgba(0,0,0,0.2)}.sds-login-dark #sds-login-dialog{background-color:#000;background-color:rgba(0,0,0,0.7);border:solid 1px;border-color:#4b4b4b;box-shadow:0px 2px 4px rgba(0,0,0,0.4)}.ext-ie8 #sds-login-dialog,.ext-ie7 #sds-login-dialog{background-color:transparent !important;border:none !important}.ext-ie8 .sds-login-light #sds-login-bkg-highlight,.ext-ie7 .sds-login-light #sds-login-bkg-highlight{background-color:#FFFFFF;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=36);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=36);opacity:0.36;border:solid 1px #FFFFFF}.ext-ie8 .sds-login-dark #sds-login-bkg-highlight,.ext-ie7 .sds-login-dark #sds-login-bkg-highlight{background-color:#000000;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=70);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=70);opacity:0.7;border:solid 1px #4b4b4b}#sds-login-dialog-title{position:absolute;font-weight:bold;line-height:76px;height:76px;width:296px;left:20px;top:1px;color:#F3F3F3;font-size:30px;text-shadow:0px 1px 2px rgba(0,0,0,0.7);overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;white-space:nowrap;text-align:center}.sds-login-light #sds-login-dialog-title{border-bottom:solid 1px;border-color:#fff;border-color:rgba(255,255,255,0.6);box-shadow:0px 1px 0px rgba(0,0,0,0.2)}.sds-login-dark #sds-login-dialog-title{border-bottom:solid 1px;border-color:#fff;border-color:rgba(255,255,255,0.3);box-shadow:0px 1px 0px rgba(0,0,0,0.5)}#sds-login-dialog-status{font-size:14px;padding-top:12px;padding-bottom:0px;line-height:17px}.sds-login-light #sds-login-dialog-status{color:#F3F3F3}.sds-login-dark #sds-login-dialog-status{color:#888787}.sds-login-light #sds-login-dialog-form,.sds-login-dark #sds-login-dialog-form{width:296px;padding:76px 20px 20px 20px}.sds-standalone-main-window .x-window-tl .x-window-header{background-size:24px 24px}.sds-standalone-main-window .x-window-tc .x-panel-icon{height:28px;padding-left:24px !important;padding-top:0;margin-top:3px}.sds-window-v5.sds-standalone-main-window .x-window-tc .x-panel-icon,.sds-standalone-main-window.sds-widget-window .x-window-tc .x-panel-icon{background-position:0 3px}.sds-standalone-main-window .sds-standalone-main-window-header{position:absolute;top:8px;right:4px;height:30px;z-index:2}.sds-window-v5.sds-standalone-main-window .sds-standalone-main-window-header,.sds-standalone-main-window.sds-widget-window .sds-standalone-main-window-header{top:7px}.sds-standalone-main-window .sds-standalone-main-window-header-text{margin-top:7px;margin-left:7px;margin-right:31px;overflow:hidden}.sds-window-v5.sds-standalone-main-window .sds-standalone-main-window-header-text,.sds-standalone-main-window.sds-widget-window .sds-standalone-main-window-header-text{margin-top:3px}.sds-window-v5.sds-standalone-main-window .sds-standalone-main-window-header .sds-standalone-welcome-text,.sds-standalone-main-window.sds-widget-window .sds-standalone-main-window-header .sds-standalone-welcome-text{margin-right:16px}.sds-window-v5.sds-standalone-main-window .sds-standalone-main-window-header .sds-standalone-welcome-text:hover,.sds-standalone-main-window.sds-widget-window .sds-standalone-main-window-header .sds-standalone-welcome-text:hover{color:#0086e5}.sds-window-v5.sds-standalone-main-window .x-window-header-text,.sds-standalone-main-window.sds-widget-window .x-window-header-text{cursor:default;font-size:16px}.sds-standalone-main-window .sds-standalone-main-window-header .sds-standalone-welcome-text{margin-right:14px;font-size:12px;color:#282828}.sds-standalone-main-window .x-window-header-text{cursor:default;font-size:16px}.sds-window.sds-standalone-main-window .x-window-header-text{color:#282828}.sds-standalone-main-window .sds-standalone-logout.syno-ux-button,.sds-standalone-main-window .sds-standalone-help.syno-ux-button{border-color:transparent;background-color:transparent;background-image:none}.sds-standalone-main-window .sds-standalone-logout.syno-ux-button em button,.sds-standalone-main-window .sds-standalone-help.syno-ux-button em button{padding-left:16px;padding-right:7px;margin-left:7px;background-repeat:no-repeat;background-position-y:center;color:#282828}.sds-standalone-main-window .sds-standalone-logout.syno-ux-button.x-btn-over,.sds-standalone-main-window .sds-standalone-logout.syno-ux-button.x-btn-click,.sds-standalone-main-window .sds-standalone-help.syno-ux-button.x-btn-over,.sds-standalone-main-window .sds-standalone-help.syno-ux-button.x-btn-click{border-color:#969a9f;border-width:1px;color:#282828}.sds-standalone-main-window .sds-standalone-logout.syno-ux-button em button.sds-standalone-help-icon,.sds-standalone-main-window .sds-standalone-help.syno-ux-button em button.sds-standalone-help-icon{background-image:url(../images/ico_help.png) !important}.sds-standalone-main-window .sds-standalone-logout.syno-ux-button em button.sds-standalone-logout-icon,.sds-standalone-main-window .sds-standalone-help.syno-ux-button em button.sds-standalone-logout-icon{background-image:url(../images/ico_logout.png) !important}.sds-window-v5.sds-standalone-main-window .sds-standalone-help.syno-ux-button,.sds-standalone-main-window.sds-widget-window .sds-standalone-help.syno-ux-button{margin-right:12px !important;height:24px;width:24px;border:none;background-color:transparent;background-image:none}.sds-window-v5.sds-standalone-main-window .sds-standalone-help.syno-ux-button em button.sds-standalone-help-icon,.sds-standalone-main-window.sds-widget-window .sds-standalone-help.syno-ux-button em button.sds-standalone-help-icon{background-image:url("../images/rt_button.png") !important;background-position:0 -384px;width:auto;background-repeat:no-repeat;padding-left:24px}.sds-window-v5.sds-standalone-main-window .sds-standalone-help.syno-ux-button.x-btn-over em button,.sds-standalone-main-window.sds-widget-window .sds-standalone-help.syno-ux-button.x-btn-over em button{color:#1ca600}.sds-window-v5.sds-standalone-main-window .sds-standalone-help.syno-ux-button.x-btn-over em button.sds-standalone-help-icon,.sds-standalone-main-window.sds-widget-window .sds-standalone-help.syno-ux-button.x-btn-over em button.sds-standalone-help-icon{background-position:0 -408px}.sds-window-v5.sds-standalone-main-window .sds-standalone-help.syno-ux-button.x-btn-click em button,.sds-standalone-main-window.sds-widget-window .sds-standalone-help.syno-ux-button.x-btn-click em button{color:#1ca600}.sds-window-v5.sds-standalone-main-window .sds-standalone-help.syno-ux-button.x-btn-click em button.sds-standalone-help-icon,.sds-standalone-main-window.sds-widget-window .sds-standalone-help.syno-ux-button.x-btn-click em button.sds-standalone-help-icon{background-position:0 -432px}.sds-window-v5.sds-standalone-main-window .x-toolbar-cell .sds-standalone-logout.x-btn,.sds-standalone-main-window.sds-widget-window .x-toolbar-cell .sds-standalone-logout.x-btn{background-image:none;background-color:transparent;border:none;margin-right:0px !important}.sds-window-v5.sds-standalone-main-window .x-toolbar-cell .sds-standalone-logout.x-btn .sds-standalone-logout-icon,.sds-standalone-main-window.sds-widget-window .x-toolbar-cell .sds-standalone-logout.x-btn .sds-standalone-logout-icon{background-image:url("../images/rt_button.png") !important;padding-left:26px;background-position:0 -672px;background-repeat:no-repeat}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .sds-window-v5.sds-standalone-main-window .x-toolbar-cell .sds-standalone-logout.x-btn .sds-standalone-logout-icon,.synohdpack .sds-standalone-main-window.sds-widget-window .x-toolbar-cell .sds-standalone-logout.x-btn .sds-standalone-logout-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/rt_button.png");background-size:"24px" "24px"}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .sds-window-v5.sds-standalone-main-window .x-toolbar-cell .sds-standalone-logout.x-btn .sds-standalone-logout-icon,.synohdpackdebug .sds-standalone-main-window.sds-widget-window .x-toolbar-cell .sds-standalone-logout.x-btn .sds-standalone-logout-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/../images/rt_button.png");background-size:"24px" "24px";outline:1px green dashed}}.sds-window-v5.sds-standalone-main-window .x-toolbar-cell .sds-standalone-logout.x-btn.x-btn-over .sds-standalone-logout-icon,.sds-standalone-main-window.sds-widget-window .x-toolbar-cell .sds-standalone-logout.x-btn.x-btn-over .sds-standalone-logout-icon,.sds-window-v5.sds-standalone-main-window .x-toolbar-cell .sds-standalone-logout.x-btn.x-btn-click .sds-standalone-logout-icon,.sds-standalone-main-window.sds-widget-window .x-toolbar-cell .sds-standalone-logout.x-btn.x-btn-click .sds-standalone-logout-icon{background-position:0 -696px;color:#0086e5}.sds-window-v5.sds-standalone-main-window .x-toolbar-cell .sds-standalone-logout.x-btn.x-item-disabled .sds-standalone-logout-icon,.sds-standalone-main-window.sds-widget-window .x-toolbar-cell .sds-standalone-logout.x-btn.x-item-disabled .sds-standalone-logout-icon{background-position:0 -720px}.sds-window-v5.sds-standalone-main-window .sds-standalone-main-window-header-toolbar em button,.sds-standalone-main-window.sds-widget-window .sds-standalone-main-window-header-toolbar em button{height:24px;line-height:24px}.syno-sds-shortcut-zone-wrapper{position:absolute;overflow:visible;z-index:-1}.syno-sds-shortcut-zone-wrapper.on-instruction{background-color:#fff;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=$ieOpacity)";filter:alpha(opacity=25);filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=25);opacity:0.25;z-index:2 !important}.syno-sds-shortcut-zone-wrapper.on-dropped{z-index:2 !important}.syno-sds-appview.on-mouse-drag .syno-sds-shortcut-zone-wrapper{z-index:2 !important}.syno-sds-shortcut-zone .add-icon{visibility:hidden;position:absolute;width:80px;height:64px;background:url(../images/desktop/add_one.png) no-repeat}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-sds-shortcut-zone .add-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/desktop/add_one.png");background-size:80px 64px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-sds-shortcut-zone .add-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/desktop/add_one.png");background-size:80px 64px;outline:1px green dashed}}.classical .syno-sds-shortcut-zone-wrapper{left:0px}.classical.syno-sds-appview.on-mouse-drag .syno-sds-shortcut-zone-wrapper{z-index:0 !important}.appview-icon-dragging-proxy .sds-application-notify-badge-num{display:none}.appview-icon-dragging-proxy .x-dd-drag-ghost{border:none !important;background-color:transparent !important;opacity:1 !important;filter:none !important}.appview-icon-dragging-proxy .x-dd-drag-ghost .text{visibility:hidden !important}.appview-icon-dragging-proxy .image{white-space:normal}.appview-icon-dragging-proxy.x-dd-drag-proxy{background-color:transparent;border:none;padding:0px;box-shadow:none}.appview-icon-dragging-proxy .x-dd-drop-icon{width:36px;height:36px;top:40px;left:46px;background-position:center}.appview-icon-dragging-proxy.x-dd-drop-ok-add .x-dd-drop-icon{background-image:url(../images/icon_drag_add.png)}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .appview-icon-dragging-proxy.x-dd-drop-ok-add .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/icon_drag_add.png");background-size:36px 36px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .appview-icon-dragging-proxy.x-dd-drop-ok-add .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/icon_drag_add.png");background-size:36px 36px;outline:1px green dashed}}.appview-icon-dragging-proxy.x-dd-drop-nodrop .x-dd-drop-icon{background-image:url(../images/icon_drag_ban.png)}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .appview-icon-dragging-proxy.x-dd-drop-nodrop .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/icon_drag_ban.png");background-size:36px 36px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .appview-icon-dragging-proxy.x-dd-drop-nodrop .x-dd-drop-icon{background-image:url("../img/synohdpack/images/dsm/resources/images/icon_drag_ban.png");background-size:36px 36px;outline:1px green dashed}}.classical.appview-icon-dragging-proxy.x-dd-drop-ok-add .x-dd-drop-icon,.classical.appview-icon-dragging-proxy.x-dd-drop-nodrop .x-dd-drop-icon{width:48px;height:48px;top:16px;left:22px;background-position:center}@font-face{font-family:'Roboto';font-style:normal;font-weight:400;src:local("Roboto Regular"),local("Roboto-Regular"),url(../fonts/roboto.woff) format("woff")}.sds-search-result .x-combo-list-hd,.sds-search-result .section{color:#0086e5}.sds-window-v5.sds-standalone-main-window .sds-standalone-main-window-header .sds-standalone-welcome-text,.sds-standalone-main-window.sds-widget-window .sds-standalone-main-window-header .sds-standalone-welcome-text{margin-right:16px}.sds-window-v5.sds-standalone-main-window .sds-standalone-main-window-header .sds-standalone-welcome-text:hover,.sds-standalone-main-window.sds-widget-window .sds-standalone-main-window-header .sds-standalone-welcome-text:hover{color:#0086e5}.sds-window-v5.sds-standalone-main-window .x-toolbar-cell .sds-standalone-logout.x-btn.x-btn-over .sds-standalone-logout-icon,.sds-standalone-main-window.sds-widget-window .x-toolbar-cell .sds-standalone-logout.x-btn.x-btn-over .sds-standalone-logout-icon,.sds-window-v5.sds-standalone-main-window .x-toolbar-cell .sds-standalone-logout.x-btn.x-btn-click .sds-standalone-logout-icon,.sds-standalone-main-window.sds-widget-window .x-toolbar-cell .sds-standalone-logout.x-btn.x-btn-click .sds-standalone-logout-icon{color:#0086e5}.sds-user-menu .sds-user-menu-options-click .x-menu-item-text,.sds-user-menu .sds-user-menu-restart-click .x-menu-item-text,.sds-user-menu .sds-user-menu-shutdown-click .x-menu-item-text,.sds-user-menu .sds-user-menu-logout-click .x-menu-item-text{color:#0086e5}.sds-overflow-menu .sds-overflow-items-click .x-menu-item-text{color:#0086e5}.sds-tray-msg-window .x-plain-tl .x-plain-header{color:#0086e5}.sds-searchbox .sds-search-result .section{color:#0086e5}.sds-window-v5 .x-window-mc,.sds-widget-window .x-window-mc{background-color:#fff}.sds-window-v5 .x-window-tl,.sds-widget-window .x-window-tl{background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Q4ZWNmYiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #d8ecfb), color-stop(100%, #ffffff));background-image:-webkit-linear-gradient(#d8ecfb,#ffffff);background-image:-moz-linear-gradient(#d8ecfb,#ffffff);background-image:-o-linear-gradient(#d8ecfb,#ffffff);background-image:linear-gradient(#d8ecfb,#ffffff);background-color:#fff;border-top:3px solid #0086e5}.sds-window-v5.deactive-win .x-window-tl,.deactive-win.sds-widget-window .x-window-tl{background-image:linear-gradient(#e6ebf0,#ffffff)}.sds-window-v5 .x-window-header-text,.sds-widget-window .x-window-header-text{color:#0086e5}.sds-window-v5 .x-window-body,.sds-widget-window .x-window-body{background-color:#fff}.sds-window-v5 .x-window-bl,.sds-widget-window .x-window-bl{background-color:#fff}.sds-window-v5 .x-window-tbar .x-toolbar,.sds-widget-window .x-window-tbar .x-toolbar{background-color:#fff}.sds-window-v5 .x-progress-bar,.sds-widget-window .x-progress-bar{background-color:#0086e5}.sds-window-v5 .ext-el-mask,.sds-widget-window .ext-el-mask{background-color:#fff}.sds-window-v5 .ext-el-mask-msg,.sds-widget-window .ext-el-mask-msg{background-color:#fff}.sds-window-v5 .ext-el-mask-msg div,.sds-widget-window .ext-el-mask-msg div{background-color:#fff}.syno-sds-fs-thumbnailsView .thumb-wrap{float:left;padding:0px;margin:0px 16px 8px 16px;-moz-transition-property:margin;-moz-transition-timing-function:ease-out;-moz-transition-duration:218ms;-webkit-transition-property:margin;-webkit-transition-timing-function:ease-out;-webkit-transition-duration:218ms;-o-transition-property:margin;-o-transition-timing-function:ease-out;-o-transition-duration:218ms;transition-timing-function:ease-out;transition-duration:218ms;transition-property:margin}#sds-desktop li.launch-icon .text,#sds-desktop li.launch-icon .text a{text-shadow:0.1em 0.1em 0.1em #000000;filter:Shadow(Color=#000, Direction=135, Strength=1)} diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/css/ext-all.css b/salt/idh/skins/http/opencanary/nasLogin/static/css/ext-all.css new file mode 100644 index 000000000..2fd3718f4 --- /dev/null +++ b/salt/idh/skins/http/opencanary/nasLogin/static/css/ext-all.css @@ -0,0 +1 @@ +html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;}img,body,html{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}ol,ul{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';}.ext-forced-border-box,.ext-forced-border-box *{-moz-box-sizing:border-box;-ms-box-sizing:border-box;-webkit-box-sizing:border-box;}.ext-el-mask{z-index:100;position:absolute;top:0;left:0;-moz-opacity:.5;opacity:.50;filter:alpha(opacity=50);width:100%;height:100%;zoom:1;}.ext-el-mask-msg{z-index:20001;position:absolute;top:0;left:0;border:1px solid;background:repeat-x 0 -16px;padding:2px;}.ext-el-mask-msg div{padding:5px 10px 5px 10px;border:1px solid;cursor:wait;}.ext-shim{position:absolute;visibility:hidden;left:0;top:0;overflow:hidden;}.ext-ie .ext-shim{filter:alpha(opacity=0);}.ext-ie6 .ext-shim{margin-left:5px;margin-top:3px;}.x-mask-loading div{padding:5px 10px 5px 25px;background:no-repeat 5px 5px;line-height:16px;}.x-hidden,.x-hide-offsets{position:absolute!important;left:-10000px;top:-10000px;visibility:hidden;}.x-hide-display{display:none!important;}.x-hide-nosize,.x-hide-nosize *{height:0!important;width:0!important;visibility:hidden!important;border:none!important;zoom:1;}.x-hide-visibility{visibility:hidden!important;}.x-masked{overflow:hidden!important;}.x-masked-relative{position:relative!important;}.x-masked select,.x-masked object,.x-masked embed{visibility:hidden;}.x-layer{visibility:hidden;}.x-unselectable,.x-unselectable *{user-select:none;-o-user-select:none;-ms-user-select:none;-moz-user-select:-moz-none;-webkit-user-select:none;}.x-repaint{zoom:1;background-color:transparent;-moz-outline:0;outline:0;}.x-item-disabled{cursor:default;opacity:.6;-moz-opacity:.6;filter:alpha(opacity=60);}.x-item-disabled *{cursor:default!important;}.x-form-radio-group .x-item-disabled{filter:none;}.x-splitbar-proxy{position:absolute;visibility:hidden;z-index:20001;zoom:1;line-height:1px;font-size:1px;overflow:hidden;}.x-splitbar-h,.x-splitbar-proxy-h{cursor:e-resize;cursor:col-resize;}.x-splitbar-v,.x-splitbar-proxy-v{cursor:s-resize;cursor:row-resize;}.x-color-palette{width:150px;height:92px;cursor:pointer;}.x-color-palette a{border:1px solid;float:left;padding:2px;text-decoration:none;-moz-outline:0 none;outline:0 none;cursor:pointer;}.x-color-palette a:hover,.x-color-palette a.x-color-palette-sel{border:1px solid;}.x-color-palette em{display:block;border:1px solid;}.x-color-palette em span{cursor:pointer;display:block;height:10px;line-height:10px;width:10px;}.x-ie-shadow{display:none;position:absolute;overflow:hidden;left:0;top:0;zoom:1;}.x-shadow{display:none;position:absolute;overflow:hidden;left:0;top:0;}.x-shadow *{overflow:hidden;}.x-shadow *{padding:0;border:0;margin:0;clear:none;zoom:1;}.x-shadow .xstc,.x-shadow .xsbc{height:6px;float:left;}.x-shadow .xstl,.x-shadow .xstr,.x-shadow .xsbl,.x-shadow .xsbr{width:6px;height:6px;float:left;}.x-shadow .xsc{width:100%;}.x-shadow .xsml,.x-shadow .xsmr{width:6px;float:left;height:100%;}.x-shadow .xsmc{float:left;height:100%;background-color:transparent;}.x-shadow .xst,.x-shadow .xsb{height:6px;overflow:hidden;width:100%;}.x-shadow .xsml{background:transparent repeat-y 0 0;}.x-shadow .xsmr{background:transparent repeat-y -6px 0;}.x-shadow .xstl{background:transparent no-repeat 0 0;}.x-shadow .xstc{background:transparent repeat-x 0 -30px;}.x-shadow .xstr{background:transparent repeat-x 0 -18px;}.x-shadow .xsbl{background:transparent no-repeat 0 -12px;}.x-shadow .xsbc{background:transparent repeat-x 0 -36px;}.x-shadow .xsbr{background:transparent repeat-x 0 -6px;}.loading-indicator{background:no-repeat left;padding-left:20px;line-height:16px;margin:3px;}.x-text-resize{position:absolute;left:-1000px;top:-1000px;visibility:hidden;zoom:1;}.x-drag-overlay{width:100%;height:100%;display:none;position:absolute;left:0;top:0;background-image:url(../images/default/s.gif);z-index:20000;}.x-clear{clear:both;height:0;overflow:hidden;line-height:0;font-size:0;}.x-spotlight{z-index:8999;position:absolute;top:0;left:0;-moz-opacity:.5;opacity:.50;filter:alpha(opacity=50);width:0;height:0;zoom:1;}#x-history-frame{position:absolute;top:-1px;left:0;width:1px;height:1px;visibility:hidden;}#x-history-field{position:absolute;top:0;left:-1px;width:1px;height:1px;visibility:hidden;}.x-resizable-handle{position:absolute;z-index:100;font-size:1px;line-height:6px;overflow:hidden;filter:alpha(opacity=0);opacity:0;zoom:1;}.x-resizable-handle-east{width:6px;cursor:e-resize;right:0;top:0;height:100%;}.ext-ie .x-resizable-handle-east{margin-right:-1px;}.x-resizable-handle-south{width:100%;cursor:s-resize;left:0;bottom:0;height:6px;}.ext-ie .x-resizable-handle-south{margin-bottom:-1px;}.x-resizable-handle-west{width:6px;cursor:w-resize;left:0;top:0;height:100%;}.x-resizable-handle-north{width:100%;cursor:n-resize;left:0;top:0;height:6px;}.x-resizable-handle-southeast{width:6px;cursor:se-resize;right:0;bottom:0;height:6px;z-index:101;}.x-resizable-handle-northwest{width:6px;cursor:nw-resize;left:0;top:0;height:6px;z-index:101;}.x-resizable-handle-northeast{width:6px;cursor:ne-resize;right:0;top:0;height:6px;z-index:101;}.x-resizable-handle-southwest{width:6px;cursor:sw-resize;left:0;bottom:0;height:6px;z-index:101;}.x-resizable-over .x-resizable-handle,.x-resizable-pinned .x-resizable-handle{filter:alpha(opacity=100);opacity:1;}.x-resizable-over .x-resizable-handle-east,.x-resizable-pinned .x-resizable-handle-east,.x-resizable-over .x-resizable-handle-west,.x-resizable-pinned .x-resizable-handle-west{background-position:left;}.x-resizable-over .x-resizable-handle-south,.x-resizable-pinned .x-resizable-handle-south,.x-resizable-over .x-resizable-handle-north,.x-resizable-pinned .x-resizable-handle-north{background-position:top;}.x-resizable-over .x-resizable-handle-southeast,.x-resizable-pinned .x-resizable-handle-southeast{background-position:top left;}.x-resizable-over .x-resizable-handle-northwest,.x-resizable-pinned .x-resizable-handle-northwest{background-position:bottom right;}.x-resizable-over .x-resizable-handle-northeast,.x-resizable-pinned .x-resizable-handle-northeast{background-position:bottom left;}.x-resizable-over .x-resizable-handle-southwest,.x-resizable-pinned .x-resizable-handle-southwest{background-position:top right;}.x-resizable-proxy{border:1px dashed;position:absolute;overflow:hidden;display:none;left:0;top:0;z-index:50000;}.x-resizable-overlay{width:100%;height:100%;display:none;position:absolute;left:0;top:0;z-index:200000;-moz-opacity:0;opacity:0;filter:alpha(opacity=0);}.x-tab-panel{overflow:hidden;}.x-tab-panel-header,.x-tab-panel-footer{border:1px solid;overflow:hidden;zoom:1;}.x-tab-panel-header{border:1px solid;padding-bottom:2px;}.x-tab-panel-footer{border:1px solid;padding-top:2px;}.x-tab-strip-wrap{width:100%;overflow:hidden;position:relative;zoom:1;}ul.x-tab-strip{display:block;width:5000px;zoom:1;}ul.x-tab-strip-top{padding-top:1px;background:repeat-x bottom;border-bottom:1px solid;}ul.x-tab-strip-bottom{padding-bottom:1px;background:repeat-x top;border-top:1px solid;border-bottom:0 none;}.x-tab-panel-header-plain .x-tab-strip-top{background:transparent!important;padding-top:0!important;}.x-tab-panel-header-plain{background:transparent!important;border-width:0!important;padding-bottom:0!important;}.x-tab-panel-header-plain .x-tab-strip-spacer,.x-tab-panel-footer-plain .x-tab-strip-spacer{border:1px solid;height:2px;font-size:1px;line-height:1px;}.x-tab-panel-header-plain .x-tab-strip-spacer{border-top:0 none;}.x-tab-panel-footer-plain .x-tab-strip-spacer{border-bottom:0 none;}.x-tab-panel-footer-plain .x-tab-strip-bottom{background:transparent!important;padding-bottom:0!important;}.x-tab-panel-footer-plain{background:transparent!important;border-width:0!important;padding-top:0!important;}.ext-border-box .x-tab-panel-header-plain .x-tab-strip-spacer,.ext-border-box .x-tab-panel-footer-plain .x-tab-strip-spacer{height:3px;}ul.x-tab-strip li{float:left;margin-left:2px;}ul.x-tab-strip li.x-tab-edge{float:left;margin:0!important;padding:0!important;border:0 none!important;font-size:1px!important;line-height:1px!important;overflow:hidden;zoom:1;background:transparent!important;width:1px;}.x-tab-strip a,.x-tab-strip span,.x-tab-strip em{display:block;}.x-tab-strip a{text-decoration:none!important;-moz-outline:0;outline:0;cursor:pointer;}.x-tab-strip-inner{overflow:hidden;text-overflow:ellipsis;}.x-tab-strip span.x-tab-strip-text{white-space:nowrap;cursor:pointer;padding:4px 0;}.x-tab-strip-top .x-tab-with-icon .x-tab-right{padding-left:6px;}.x-tab-strip .x-tab-with-icon span.x-tab-strip-text{padding-left:20px;background-position:0 3px;background-repeat:no-repeat;}.x-tab-strip-active,.x-tab-strip-active a.x-tab-right{cursor:default;}.x-tab-strip-active span.x-tab-strip-text{cursor:default;}.x-tab-strip-disabled .x-tabs-text{cursor:default;}.x-tab-panel-body{overflow:hidden;}.x-tab-panel-bwrap{overflow:hidden;}.ext-ie .x-tab-strip .x-tab-right{position:relative;}.x-tab-strip-top .x-tab-strip-active .x-tab-right{margin-bottom:-1px;}.ext-ie8 .x-tab-strip li{position:relative;}.ext-border-box .ext-ie8 .x-tab-strip-top .x-tab-right,.ext-border-box .ext-ie9 .x-tab-strip-top .x-tab-right{top:1px;}.ext-ie8 .x-tab-strip-top,.ext-ie9 .x-tab-strip-top{padding-top:1px;}.ext-border-box .ext-ie8 .x-tab-strip-top,.ext-border-box .ext-ie9 .x-tab-strip-top{padding-top:0;}.ext-ie8 .x-tab-strip .x-tab-strip-closable a.x-tab-strip-close,.ext-ie9 .x-tab-strip .x-tab-strip-closable a.x-tab-strip-close{top:3px;}.ext-border-box .ext-ie8 .x-tab-strip .x-tab-strip-closable a.x-tab-strip-close,.ext-border-box .ext-ie9 .x-tab-strip .x-tab-strip-closable a.x-tab-strip-close{top:4px;}.ext-ie8 .x-tab-strip-bottom .x-tab-right,.ext-ie9 .x-tab-strip-bottom .x-tab-right{top:0;}.x-tab-strip-top .x-tab-strip-active .x-tab-right span.x-tab-strip-text{padding-bottom:5px;}.x-tab-strip-bottom .x-tab-strip-active .x-tab-right{margin-top:-1px;}.x-tab-strip-bottom .x-tab-strip-active .x-tab-right span.x-tab-strip-text{padding-top:5px;}.x-tab-strip-top .x-tab-right{background:transparent no-repeat 0 -51px;padding-left:10px;}.x-tab-strip-top .x-tab-left{background:transparent no-repeat right -351px;padding-right:10px;}.x-tab-strip-top .x-tab-strip-inner{background:transparent repeat-x 0 -201px;}.x-tab-strip-top .x-tab-strip-over .x-tab-right{background-position:0 -101px;}.x-tab-strip-top .x-tab-strip-over .x-tab-left{background-position:right -401px;}.x-tab-strip-top .x-tab-strip-over .x-tab-strip-inner{background-position:0 -251px;}.x-tab-strip-top .x-tab-strip-active .x-tab-right{background-position:0 0;}.x-tab-strip-top .x-tab-strip-active .x-tab-left{background-position:right -301px;}.x-tab-strip-top .x-tab-strip-active .x-tab-strip-inner{background-position:0 -151px;}.x-tab-strip-bottom .x-tab-right{background:no-repeat bottom right;}.x-tab-strip-bottom .x-tab-left{background:no-repeat bottom left;}.x-tab-strip-bottom .x-tab-strip-active .x-tab-right{background:no-repeat bottom right;}.x-tab-strip-bottom .x-tab-strip-active .x-tab-left{background:no-repeat bottom left;}.x-tab-strip-bottom .x-tab-left{margin-right:3px;padding:0 10px;}.x-tab-strip-bottom .x-tab-right{padding:0;}.x-tab-strip .x-tab-strip-close{display:none;}.x-tab-strip-closable{position:relative;}.x-tab-strip-closable .x-tab-left{padding-right:19px;}.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close{opacity:.6;-moz-opacity:.6;background-repeat:no-repeat;display:block;width:11px;height:11px;position:absolute;top:3px;right:3px;cursor:pointer;z-index:2;}.x-tab-strip .x-tab-strip-active a.x-tab-strip-close{opacity:.8;-moz-opacity:.8;}.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{opacity:1;-moz-opacity:1;}.x-tab-panel-body{border:1px solid;}.x-tab-panel-body-top{border-top:0 none;}.x-tab-panel-body-bottom{border-bottom:0 none;}.x-tab-scroller-left{background:transparent no-repeat -18px 0;border-bottom:1px solid;width:18px;position:absolute;left:0;top:0;z-index:10;cursor:pointer;}.x-tab-scroller-left-over{background-position:0 0;}.x-tab-scroller-left-disabled{background-position:-18px 0;opacity:.5;-moz-opacity:.5;filter:alpha(opacity=50);cursor:default;}.x-tab-scroller-right{background:transparent no-repeat 0 0;border-bottom:1px solid;width:18px;position:absolute;right:0;top:0;z-index:10;cursor:pointer;}.x-tab-scroller-right-over{background-position:-18px 0;}.x-tab-scroller-right-disabled{background-position:0 0;opacity:.5;-moz-opacity:.5;filter:alpha(opacity=50);cursor:default;}.x-tab-scrolling-bottom .x-tab-scroller-left,.x-tab-scrolling-bottom .x-tab-scroller-right{margin-top:1px;}.x-tab-scrolling .x-tab-strip-wrap{margin-left:18px;margin-right:18px;}.x-tab-scrolling{position:relative;}.x-tab-panel-bbar .x-toolbar{border:1px solid;border-top:0 none;overflow:hidden;padding:2px;}.x-tab-panel-tbar .x-toolbar{border:1px solid;border-top:0 none;overflow:hidden;padding:2px;}.x-form-field{margin:0;}.ext-webkit *:focus{outline:none!important;}.x-form-text,textarea.x-form-field{padding:1px 3px;background:repeat-x 0 0;border:1px solid;}textarea.x-form-field{padding:2px 3px;}.x-form-text,.ext-ie .x-form-file{height:22px;line-height:18px;vertical-align:middle;}.ext-ie6 .x-form-text,.ext-ie7 .x-form-text{margin:-1px 0;height:22px;line-height:18px;}.x-quirks .ext-ie9 .x-form-text{height:22px;padding-top:3px;padding-bottom:0;}.x-quirks .ext-ie9 .x-input-wrapper .x-form-text,.x-quirks .ext-ie9 .x-form-field-trigger-wrap .x-form-text{margin-top:-1px;margin-bottom:-1px;}.x-quirks .ext-ie9 .x-input-wrapper .x-form-element{margin-bottom:-1px;}.ext-ie6 .x-form-field-wrap .x-form-file-btn,.ext-ie7 .x-form-field-wrap .x-form-file-btn{top:-1px;}.ext-ie6 textarea.x-form-field,.ext-ie7 textarea.x-form-field{margin:-1px 0;}.ext-strict .x-form-text{height:18px;}.ext-safari.ext-mac textarea.x-form-field{margin-bottom:-2px;}.ext-gecko .x-form-text,.ext-ie8 .x-form-text{padding-top:2px;padding-bottom:0;}.ext-ie6 .x-form-composite .x-form-text.x-box-item,.ext-ie7 .x-form-composite .x-form-text.x-box-item{margin:0!important;}textarea{resize:none;}.x-form-select-one{height:20px;line-height:18px;vertical-align:middle;border:1px solid;}.x-form-check-wrap{line-height:18px;height:auto;}.ext-ie .x-form-check-wrap input{width:15px;height:15px;}.x-form-check-wrap input{vertical-align:bottom;}.x-editor .x-form-check-wrap{padding:3px;}.x-editor .x-form-checkbox{height:13px;}.x-form-check-group-label{border-bottom:1px solid;margin-bottom:5px;padding-left:3px!important;float:none!important;}.x-form-field-wrap .x-form-trigger{width:17px;height:21px;border:0;background:transparent no-repeat 0 0;cursor:pointer;border-bottom:1px solid;position:absolute;top:0;}.x-form-field-wrap .x-form-date-trigger,.x-form-field-wrap .x-form-clear-trigger,.x-form-field-wrap .x-form-search-trigger{cursor:pointer;}.x-form-field-wrap .x-form-twin-triggers .x-form-trigger{position:static;top:auto;vertical-align:top;}.x-form-field-wrap{position:relative;left:0;top:0;text-align:left;zoom:1;white-space:nowrap;}.ext-strict .ext-ie8 .x-toolbar-cell .x-form-field-trigger-wrap .x-form-trigger{right:0;}.x-form-field-wrap .x-form-trigger-over{background-position:-17px 0;}.x-form-field-wrap .x-form-trigger-click{background-position:-34px 0;}.x-trigger-wrap-focus .x-form-trigger{background-position:-51px 0;}.x-trigger-wrap-focus .x-form-trigger-over{background-position:-68px 0;}.x-trigger-wrap-focus .x-form-trigger-click{background-position:-85px 0;}.x-trigger-wrap-focus .x-form-trigger{border-bottom:1px solid;}.x-item-disabled .x-form-trigger-over{background-position:0 0!important;border-bottom:1px solid;}.x-item-disabled .x-form-trigger-click{background-position:0 0!important;border-bottom:1px solid;}.x-trigger-noedit{cursor:pointer;}.x-form-focus,textarea.x-form-focus{border:1px solid;}.x-form-invalid,textarea.x-form-invalid{background:repeat-x bottom;border:1px solid;}.x-form-inner-invalid,textarea.x-form-inner-invalid{background:repeat-x bottom;}.x-editor{visibility:hidden;padding:0;margin:0;}.x-form-grow-sizer{left:-10000px;padding:8px 3px;position:absolute;visibility:hidden;top:-10000px;white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;zoom:1;}.x-form-grow-sizer p{margin:0!important;border:0 none!important;padding:0!important;}.x-form-item{display:block;margin-bottom:4px;zoom:1;}.x-form-item label.x-form-item-label{display:block;float:left;width:100px;padding:3px;padding-left:0;clear:left;z-index:2;position:relative;}.x-form-element{padding-left:105px;position:relative;}.x-form-invalid-msg{padding:2px;padding-left:18px;background:transparent no-repeat 0 2px;line-height:16px;width:200px;}.x-form-label-left label.x-form-item-label{text-align:left;}.x-form-label-right label.x-form-item-label{text-align:right;}.x-form-label-top .x-form-item label.x-form-item-label{width:auto;float:none;clear:none;display:inline;margin-bottom:4px;position:static;}.x-form-label-top .x-form-element{padding-left:0;padding-top:4px;}.x-form-label-top .x-form-item{padding-bottom:4px;}.x-small-editor .x-form-text{height:20px;line-height:16px;vertical-align:middle;}.ext-ie6 .x-small-editor .x-form-text,.ext-ie7 .x-small-editor .x-form-text{margin-top:-1px!important;margin-bottom:-1px!important;height:20px!important;line-height:16px!important;}.ext-strict .x-small-editor .x-form-text{height:16px!important;}.ext-ie6 .x-small-editor .x-form-text,.ext-ie7 .x-small-editor .x-form-text{height:20px;line-height:16px;}.ext-border-box .x-small-editor .x-form-text{height:20px;}.x-small-editor .x-form-select-one{height:20px;line-height:16px;vertical-align:middle;}.x-small-editor .x-form-num-field{text-align:right;}.x-small-editor .x-form-field-wrap .x-form-trigger{height:19px;}.ext-webkit .x-small-editor .x-form-text{padding-top:3px;font-size:100%;}.ext-strict .ext-webkit .x-small-editor .x-form-text{height:14px!important;}.x-form-clear{clear:both;height:0;overflow:hidden;line-height:0;font-size:0;}.x-form-clear-left{clear:left;height:0;overflow:hidden;line-height:0;font-size:0;}.ext-ie6 .x-form-check-wrap input,.ext-border-box .x-form-check-wrap input{margin-top:3px;}.x-form-cb-label{position:relative;margin-left:4px;top:2px;}.ext-ie .x-form-cb-label{top:1px;}.ext-ie6 .x-form-cb-label,.ext-border-box .x-form-cb-label{top:3px;}.x-form-display-field{padding-top:2px;}.ext-gecko .x-form-display-field,.ext-strict .ext-ie7 .x-form-display-field{padding-top:1px;}.ext-ie .x-form-display-field{padding-top:3px;}.ext-strict .ext-ie8 .x-form-display-field{padding-top:0;}.x-form-column{float:left;padding:0;margin:0;width:48%;overflow:hidden;zoom:1;}.x-form .x-form-btns-ct .x-btn{float:right;clear:none;}.x-form .x-form-btns-ct .x-form-btns td{border:0;padding:0;}.x-form .x-form-btns-ct .x-form-btns-right table{float:right;clear:none;}.x-form .x-form-btns-ct .x-form-btns-left table{float:left;clear:none;}.x-form .x-form-btns-ct .x-form-btns-center{text-align:center;}.x-form .x-form-btns-ct .x-form-btns-center table{margin:0 auto;}.x-form .x-form-btns-ct table td.x-form-btn-td{padding:3px;}.x-form .x-form-btns-ct .x-btn-focus .x-btn-left{background-position:0 -147px;}.x-form .x-form-btns-ct .x-btn-focus .x-btn-right{background-position:0 -168px;}.x-form .x-form-btns-ct .x-btn-focus .x-btn-center{background-position:0 -189px;}.x-form .x-form-btns-ct .x-btn-click .x-btn-center{background-position:0 -126px;}.x-form .x-form-btns-ct .x-btn-click .x-btn-right{background-position:0 -84px;}.x-form .x-form-btns-ct .x-btn-click .x-btn-left{background-position:0 -63px;}.x-form-invalid-icon{width:16px;height:18px;visibility:hidden;position:absolute;left:0;top:0;display:block;background:transparent no-repeat 0 2px;}.x-fieldset{border:1px solid;padding:10px;margin-bottom:10px;display:block;}.ext-webkit .x-fieldset-header{padding-top:1px;}.ext-ie .x-fieldset legend{margin-bottom:10px;}.ext-strict .ext-ie9 .x-fieldset legend.x-fieldset-header{padding-top:1px;}.ext-ie .x-fieldset{padding-top:0;padding-bottom:10px;}.x-fieldset legend .x-tool-toggle{margin-right:3px;margin-left:0;float:left!important;}.x-fieldset legend input{margin-right:3px;float:left!important;height:13px;width:13px;}fieldset.x-panel-collapsed{padding-bottom:0!important;border-width:1px 1px 0 1px!important;border-left-color:transparent;border-right-color:transparent;}.ext-ie6 fieldset.x-panel-collapsed{padding-bottom:0!important;border-width:1px 0 0 0!important;margin-left:1px;margin-right:1px;}fieldset.x-panel-collapsed .x-fieldset-bwrap{visibility:hidden;position:absolute;left:-1000px;top:-1000px;}.ext-ie .x-fieldset-bwrap{zoom:1;}.x-fieldset-noborder{border:0 none transparent;}.x-fieldset-noborder legend{margin-left:-3px;}.ext-ie .x-fieldset-noborder legend{position:relative;margin-bottom:23px;}.ext-ie .x-fieldset-noborder legend span{position:absolute;left:16px;}.ext-gecko .x-window-body .x-form-item{-moz-outline:0;outline:0;overflow:auto;}.ext-mac.ext-gecko .x-window-body .x-form-item{overflow:hidden;}.ext-gecko .x-form-item{-moz-outline:0;outline:0;}.x-hide-label label.x-form-item-label{display:none;}.x-hide-label .x-form-element{padding-left:0!important;}.x-form-label-top .x-hide-label label.x-form-item-label{display:none;}.x-fieldset{overflow:hidden;}.x-fieldset-bwrap{overflow:hidden;zoom:1;}.x-fieldset-body{overflow:hidden;}.x-btn{cursor:pointer;white-space:nowrap;}.x-btn button{border:0 none;background-color:transparent;padding-left:3px;padding-right:3px;cursor:pointer;margin:0;overflow:visible;width:auto;-moz-outline:0 none;outline:0 none;}* html .ext-ie .x-btn button{width:1px;}.ext-gecko .x-btn button,.ext-webkit .x-btn button{padding-left:0;padding-right:0;}.ext-gecko .x-btn button::-moz-focus-inner{padding:0;}.ext-ie .x-btn button{padding-top:2px;}.x-btn td{padding:0!important;}.x-btn-text{cursor:pointer;white-space:nowrap;padding:0;}.x-btn-noicon .x-btn-small .x-btn-text{height:16px;}.x-btn-noicon .x-btn-medium .x-btn-text{height:24px;}.x-btn-noicon .x-btn-large .x-btn-text{height:32px;}.x-btn-icon .x-btn-text{background-position:center;background-repeat:no-repeat;}.x-btn-icon .x-btn-small .x-btn-text{height:16px;width:16px;}.x-btn-icon .x-btn-medium .x-btn-text{height:24px;width:24px;}.x-btn-icon .x-btn-large .x-btn-text{height:32px;width:32px;}.x-btn-text-icon .x-btn-icon-small-left .x-btn-text{background-position:0 center;background-repeat:no-repeat;padding-left:18px;height:16px;}.x-btn-text-icon .x-btn-icon-medium-left .x-btn-text{background-position:0 center;background-repeat:no-repeat;padding-left:26px;height:24px;}.x-btn-text-icon .x-btn-icon-large-left .x-btn-text{background-position:0 center;background-repeat:no-repeat;padding-left:34px;height:32px;}.x-btn-text-icon .x-btn-icon-small-top .x-btn-text{background-position:center 0;background-repeat:no-repeat;padding-top:18px;}.x-btn-text-icon .x-btn-icon-medium-top .x-btn-text{background-position:center 0;background-repeat:no-repeat;padding-top:26px;}.x-btn-text-icon .x-btn-icon-large-top .x-btn-text{background-position:center 0;background-repeat:no-repeat;padding-top:34px;}.x-btn-text-icon .x-btn-icon-small-right .x-btn-text{background-position:right center;background-repeat:no-repeat;padding-right:18px;height:16px;}.x-btn-text-icon .x-btn-icon-medium-right .x-btn-text{background-position:right center;background-repeat:no-repeat;padding-right:26px;height:24px;}.x-btn-text-icon .x-btn-icon-large-right .x-btn-text{background-position:right center;background-repeat:no-repeat;padding-right:34px;height:32px;}.x-btn-text-icon .x-btn-icon-small-bottom .x-btn-text{background-position:center bottom;background-repeat:no-repeat;padding-bottom:18px;}.x-btn-text-icon .x-btn-icon-medium-bottom .x-btn-text{background-position:center bottom;background-repeat:no-repeat;padding-bottom:26px;}.x-btn-text-icon .x-btn-icon-large-bottom .x-btn-text{background-position:center bottom;background-repeat:no-repeat;padding-bottom:34px;}.x-btn-tr i,.x-btn-tl i,.x-btn-mr i,.x-btn-ml i,.x-btn-br i,.x-btn-bl i{font-size:1px;line-height:1px;width:3px;display:block;overflow:hidden;}.x-btn-tr i,.x-btn-tl i,.x-btn-br i,.x-btn-bl i{height:3px;}.x-btn-tl{width:3px;height:3px;background:no-repeat 0 0;}.x-btn-tr{width:3px;height:3px;background:no-repeat -3px 0;}.x-btn-tc{height:3px;background:repeat-x 0 -6px;}.x-btn-ml{width:3px;background:no-repeat 0 -24px;}.x-btn-mr{width:3px;background:no-repeat -3px -24px;}.x-btn-mc{background:repeat-x 0 -1096px;vertical-align:middle;text-align:center;padding:0 5px;cursor:pointer;white-space:nowrap;}.ext-strict .ext-ie6 .x-btn-mc,.ext-strict .ext-ie7 .x-btn-mc{height:100%;}.x-btn-bl{width:3px;height:3px;background:no-repeat 0 -3px;}.x-btn-br{width:3px;height:3px;background:no-repeat -3px -3px;}.x-btn-bc{height:3px;background:repeat-x 0 -15px;}.x-btn-over .x-btn-tl{background-position:-6px 0;}.x-btn-over .x-btn-tr{background-position:-9px 0;}.x-btn-over .x-btn-tc{background-position:0 -9px;}.x-btn-over .x-btn-ml{background-position:-6px -24px;}.x-btn-over .x-btn-mr{background-position:-9px -24px;}.x-btn-over .x-btn-mc{background-position:0 -2168px;}.x-btn-over .x-btn-bl{background-position:-6px -3px;}.x-btn-over .x-btn-br{background-position:-9px -3px;}.x-btn-over .x-btn-bc{background-position:0 -18px;}.x-btn-click .x-btn-tl,.x-btn-menu-active .x-btn-tl,.x-btn-pressed .x-btn-tl{background-position:-12px 0;}.x-btn-click .x-btn-tr,.x-btn-menu-active .x-btn-tr,.x-btn-pressed .x-btn-tr{background-position:-15px 0;}.x-btn-click .x-btn-tc,.x-btn-menu-active .x-btn-tc,.x-btn-pressed .x-btn-tc{background-position:0 -12px;}.x-btn-click .x-btn-ml,.x-btn-menu-active .x-btn-ml,.x-btn-pressed .x-btn-ml{background-position:-12px -24px;}.x-btn-click .x-btn-mr,.x-btn-menu-active .x-btn-mr,.x-btn-pressed .x-btn-mr{background-position:-15px -24px;}.x-btn-click .x-btn-mc,.x-btn-menu-active .x-btn-mc,.x-btn-pressed .x-btn-mc{background-position:0 -3240px;}.x-btn-click .x-btn-bl,.x-btn-menu-active .x-btn-bl,.x-btn-pressed .x-btn-bl{background-position:-12px -3px;}.x-btn-click .x-btn-br,.x-btn-menu-active .x-btn-br,.x-btn-pressed .x-btn-br{background-position:-15px -3px;}.x-btn-click .x-btn-bc,.x-btn-menu-active .x-btn-bc,.x-btn-pressed .x-btn-bc{background-position:0 -21px;}.x-btn-disabled *{cursor:default!important;}.x-btn-mc em.x-btn-arrow{display:block;background:transparent no-repeat right center;padding-right:10px;}.x-btn-mc em.x-btn-split{display:block;background:transparent no-repeat right center;padding-right:14px;}.x-btn-mc em.x-btn-arrow-bottom{display:block;background:transparent no-repeat center bottom;padding-bottom:14px;}.x-btn-mc em.x-btn-split-bottom{display:block;background:transparent no-repeat center bottom;padding-bottom:14px;}.x-btn-as-arrow .x-btn-mc em{display:block;background-color:transparent;padding-bottom:14px;}.x-btn-group{padding:1px;}.x-btn-group-header{padding:2px;text-align:center;}.x-btn-group-tc{background:transparent repeat-x 0 0;overflow:hidden;}.x-btn-group-tl{background:transparent no-repeat 0 0;padding-left:3px;zoom:1;}.x-btn-group-tr{background:transparent no-repeat right 0;zoom:1;padding-right:3px;}.x-btn-group-bc{background:transparent repeat-x 0 bottom;zoom:1;}.x-btn-group-bc .x-panel-footer{zoom:1;}.x-btn-group-bl{background:transparent no-repeat 0 bottom;padding-left:3px;zoom:1;}.x-btn-group-br{background:transparent no-repeat right bottom;padding-right:3px;zoom:1;}.x-btn-group-mc{border:0 none;padding:1px 0 0 0;margin:0;}.x-btn-group-mc .x-btn-group-body{background-color:transparent;border:0 none;}.x-btn-group-ml{background:transparent repeat-y 0 0;padding-left:3px;zoom:1;}.x-btn-group-mr{background:transparent repeat-y right 0;padding-right:3px;zoom:1;}.x-btn-group-bc .x-btn-group-footer{padding-bottom:6px;}.x-panel-nofooter .x-btn-group-bc{height:3px;font-size:0;line-height:0;}.x-btn-group-bwrap{overflow:hidden;zoom:1;}.x-btn-group-body{overflow:hidden;zoom:1;}.x-btn-group-notitle .x-btn-group-tc{background:transparent repeat-x 0 0;overflow:hidden;height:2px;}.x-toolbar{border-style:solid;border-width:0 0 1px 0;display:block;padding:2px;background:repeat-x top left;position:relative;left:0;top:0;zoom:1;overflow:hidden;}.x-toolbar-left{width:100%;}.x-toolbar .x-item-disabled .x-btn-icon{opacity:.35;-moz-opacity:.35;filter:alpha(opacity=35);}.x-toolbar td{vertical-align:middle;}.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{white-space:nowrap;}.x-toolbar .x-item-disabled{cursor:default;opacity:.6;-moz-opacity:.6;filter:alpha(opacity=60);}.x-toolbar .x-item-disabled *{cursor:default;}.x-toolbar .x-toolbar-cell{vertical-align:middle;}.x-toolbar .x-btn-tl,.x-toolbar .x-btn-tr,.x-toolbar .x-btn-tc,.x-toolbar .x-btn-ml,.x-toolbar .x-btn-mr,.x-toolbar .x-btn-mc,.x-toolbar .x-btn-bl,.x-toolbar .x-btn-br,.x-toolbar .x-btn-bc{background-position:500px 500px;}.x-toolbar .x-btn-over .x-btn-tl{background-position:-6px 0;}.x-toolbar .x-btn-over .x-btn-tr{background-position:-9px 0;}.x-toolbar .x-btn-over .x-btn-tc{background-position:0 -9px;}.x-toolbar .x-btn-over .x-btn-ml{background-position:-6px -24px;}.x-toolbar .x-btn-over .x-btn-mr{background-position:-9px -24px;}.x-toolbar .x-btn-over .x-btn-mc{background-position:0 -2168px;}.x-toolbar .x-btn-over .x-btn-bl{background-position:-6px -3px;}.x-toolbar .x-btn-over .x-btn-br{background-position:-9px -3px;}.x-toolbar .x-btn-over .x-btn-bc{background-position:0 -18px;}.x-toolbar .x-btn-click .x-btn-tl,.x-toolbar .x-btn-menu-active .x-btn-tl,.x-toolbar .x-btn-pressed .x-btn-tl{background-position:-12px 0;}.x-toolbar .x-btn-click .x-btn-tr,.x-toolbar .x-btn-menu-active .x-btn-tr,.x-toolbar .x-btn-pressed .x-btn-tr{background-position:-15px 0;}.x-toolbar .x-btn-click .x-btn-tc,.x-toolbar .x-btn-menu-active .x-btn-tc,.x-toolbar .x-btn-pressed .x-btn-tc{background-position:0 -12px;}.x-toolbar .x-btn-click .x-btn-ml,.x-toolbar .x-btn-menu-active .x-btn-ml,.x-toolbar .x-btn-pressed .x-btn-ml{background-position:-12px -24px;}.x-toolbar .x-btn-click .x-btn-mr,.x-toolbar .x-btn-menu-active .x-btn-mr,.x-toolbar .x-btn-pressed .x-btn-mr{background-position:-15px -24px;}.x-toolbar .x-btn-click .x-btn-mc,.x-toolbar .x-btn-menu-active .x-btn-mc,.x-toolbar .x-btn-pressed .x-btn-mc{background-position:0 -3240px;}.x-toolbar .x-btn-click .x-btn-bl,.x-toolbar .x-btn-menu-active .x-btn-bl,.x-toolbar .x-btn-pressed .x-btn-bl{background-position:-12px -3px;}.x-toolbar .x-btn-click .x-btn-br,.x-toolbar .x-btn-menu-active .x-btn-br,.x-toolbar .x-btn-pressed .x-btn-br{background-position:-15px -3px;}.x-toolbar .x-btn-click .x-btn-bc,.x-toolbar .x-btn-menu-active .x-btn-bc,.x-toolbar .x-btn-pressed .x-btn-bc{background-position:0 -21px;}.x-toolbar div.xtb-text{padding:2px 2px 0;line-height:16px;display:block;}.x-toolbar .xtb-sep{background-position:center;background-repeat:no-repeat;display:block;font-size:1px;height:16px;width:4px;overflow:hidden;cursor:default;margin:0 2px 0;border:0;}.x-toolbar .xtb-spacer{width:2px;}.x-tbar-page-number{width:30px;height:14px;}.ext-ie .x-tbar-page-number{margin-top:2px;}.x-paging-info{position:absolute;top:5px;right:8px;}.x-toolbar-ct{width:100%;}.x-toolbar-right td{text-align:center;}.x-panel-tbar,.x-panel-bbar,.x-window-tbar,.x-window-bbar,.x-tab-panel-tbar,.x-tab-panel-bbar,.x-plain-tbar,.x-plain-bbar{overflow:hidden;zoom:1;}.x-toolbar-more .x-btn-small .x-btn-text{height:16px;width:12px;}.x-toolbar-more em.x-btn-arrow{display:inline;background-color:transparent;padding-right:0;}.x-toolbar-more .x-btn-mc em.x-btn-arrow{background-image:none;}div.x-toolbar-no-items{color:gray!important;padding:5px 10px!important;}.ext-border-box .x-toolbar-cell .x-form-text{margin-bottom:-1px!important;}.ext-border-box .x-toolbar-cell .x-form-field-wrap .x-form-text{margin:0!important;}.ext-ie .x-toolbar-cell .x-form-field-wrap{height:21px;}.ext-ie .x-toolbar-cell .x-form-text{position:relative;top:-1px;}.ext-strict .ext-ie8 .x-toolbar-cell .x-form-field-trigger-wrap .x-form-text,.ext-strict .ext-ie .x-toolbar-cell .x-form-text{top:0;}.x-toolbar-right td .x-form-field-trigger-wrap{text-align:left;}.x-toolbar-cell .x-form-checkbox,.x-toolbar-cell .x-form-radio{margin-top:5px;}.x-toolbar-cell .x-form-cb-label{vertical-align:bottom;top:1px;}.ext-ie .x-toolbar-cell .x-form-checkbox,.ext-ie .x-toolbar-cell .x-form-radio{margin-top:4px;}.ext-ie .x-toolbar-cell .x-form-cb-label{top:0;}.x-grid3{position:relative;overflow:hidden;}.x-grid-panel .x-panel-body{overflow:hidden!important;}.x-grid-panel .x-panel-mc .x-panel-body{border:1px solid;}.x-grid3 table{table-layout:fixed;}.x-grid3-viewport{overflow:hidden;}.x-grid3-hd-row td,.x-grid3-row td,.x-grid3-summary-row td{-moz-outline:0;outline:0;-moz-user-focus:normal;}.x-grid3-row td,.x-grid3-summary-row td{line-height:13px;vertical-align:top;padding-left:1px;padding-right:1px;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:ignore;}.x-grid3-cell{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:ignore;}.x-grid3-hd-row td{line-height:15px;vertical-align:middle;border-left:1px solid;border-right:1px solid;}.x-grid3-hd-row .x-grid3-marker-hd{padding:3px;}.x-grid3-row .x-grid3-marker{padding:3px;}.x-grid3-cell-inner,.x-grid3-hd-inner{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;padding:3px 3px 3px 5px;white-space:nowrap;}.x-action-col-cell .x-grid3-cell-inner{padding-top:1px;padding-bottom:1px;}.x-action-col-icon{cursor:pointer;}.x-grid3-hd-inner{position:relative;cursor:inherit;padding:4px 3px 4px 5px;}.x-grid3-row-body{white-space:normal;}.x-grid3-body-cell{-moz-outline:0 none;outline:0 none;}.ext-ie .x-grid3-cell-inner,.ext-ie .x-grid3-hd-inner{width:100%;}.ext-strict .x-grid3-cell-inner,.ext-strict .x-grid3-hd-inner{width:auto;}.x-grid-row-loading{background:no-repeat center center;}.x-grid-page{overflow:hidden;}.x-grid3-row{cursor:default;border:1px solid;width:100%;}.x-grid3-row-over{border:1px solid;background:repeat-x left top;}.x-grid3-resize-proxy{width:1px;left:0;cursor:e-resize;cursor:col-resize;position:absolute;top:0;height:100px;overflow:hidden;visibility:hidden;border:0 none;z-index:7;}.x-grid3-resize-marker{width:1px;left:0;position:absolute;top:0;height:100px;overflow:hidden;visibility:hidden;border:0 none;z-index:7;}.x-grid3-focus{position:absolute;left:0;top:0;width:1px;height:1px;line-height:1px;font-size:1px;-moz-outline:0 none;outline:0 none;-moz-user-select:text;-khtml-user-select:text;-webkit-user-select:ignore;}.x-grid3-header{background:repeat-x 0 bottom;cursor:default;zoom:1;padding:1px 0 0 0;}.x-grid3-header-pop{border-left:1px solid;float:right;clear:none;}.x-grid3-header-pop-inner{border-left:1px solid;width:14px;height:19px;background:transparent no-repeat center center;}.ext-ie .x-grid3-header-pop-inner{width:15px;}.ext-strict .x-grid3-header-pop-inner{width:14px;}.x-grid3-header-inner{overflow:hidden;zoom:1;float:left;}.x-grid3-header-offset{padding-left:1px;text-align:left;}td.x-grid3-hd-over,td.sort-desc,td.sort-asc,td.x-grid3-hd-menu-open{border-left:1px solid;border-right:1px solid;}td.x-grid3-hd-over .x-grid3-hd-inner,td.sort-desc .x-grid3-hd-inner,td.sort-asc .x-grid3-hd-inner,td.x-grid3-hd-menu-open .x-grid3-hd-inner{background:repeat-x left bottom;}.x-grid3-sort-icon{background-repeat:no-repeat;display:none;height:4px;width:13px;margin-left:3px;vertical-align:middle;}.sort-asc .x-grid3-sort-icon,.sort-desc .x-grid3-sort-icon{display:inline;}.ext-strict .ext-ie .x-grid3-header-inner,.ext-strict .ext-ie6 .x-grid3-hd{position:relative;}.ext-strict .ext-ie6 .x-grid3-hd-inner{position:static;}.x-grid3-body{zoom:1;}.x-grid3-scroller{overflow:auto;zoom:1;position:relative;}.x-grid3-cell-text,.x-grid3-hd-text{display:block;padding:3px 5px 3px 5px;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:ignore;}.x-grid3-split{background-position:center;background-repeat:no-repeat;cursor:e-resize;cursor:col-resize;display:block;font-size:1px;height:16px;overflow:hidden;position:absolute;top:2px;width:6px;z-index:3;}.x-dd-drag-proxy .x-grid3-hd-inner{background:repeat-x left bottom;width:120px;padding:3px;border:1px solid;overflow:hidden;}.col-move-top,.col-move-bottom{width:9px;height:9px;position:absolute;top:0;line-height:1px;font-size:1px;overflow:hidden;visibility:hidden;z-index:20000;background:transparent no-repeat left top;}.x-grid3-row-selected{border:1px dotted;}.x-grid3-locked td.x-grid3-row-marker,.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker{background:repeat-x 0 bottom!important;vertical-align:middle!important;padding:0;border-top:1px solid;border-bottom:none!important;border-right:1px solid!important;text-align:center;}.x-grid3-locked td.x-grid3-row-marker div,.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div{padding:0 4px;text-align:center;}.x-grid3-dirty-cell{background:transparent no-repeat 0 0;}.x-grid3-topbar,.x-grid3-bottombar{overflow:hidden;display:none;zoom:1;position:relative;}.x-grid3-topbar .x-toolbar{border-right:0 none;}.x-grid3-bottombar .x-toolbar{border-right:0 none;border-bottom:0 none;border-top:1px solid;}.x-props-grid .x-grid3-cell{padding:1px;}.x-props-grid .x-grid3-td-name .x-grid3-cell-inner{background:transparent repeat-y -16px!important;padding-left:12px;}.x-props-grid .x-grid3-body .x-grid3-td-name{padding:1px;padding-right:0;border:0 none;border-right:1px solid;}.x-grid3-col-dd{border:0 none;padding:0;background-color:transparent;}.x-dd-drag-ghost .x-grid3-dd-wrap{padding:1px 3px 3px 1px;}.x-grid3-hd{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:ignore;}.x-grid3-hd-btn{display:none;position:absolute;width:14px;background:no-repeat left center;right:0;top:0;z-index:2;cursor:pointer;}.x-grid3-hd-over .x-grid3-hd-btn,.x-grid3-hd-menu-open .x-grid3-hd-btn{display:block;}a.x-grid3-hd-btn:hover{background-position:-14px center;}.x-grid3-body .x-grid3-td-expander{background:transparent repeat-y right;}.x-grid3-body .x-grid3-td-expander .x-grid3-cell-inner{padding:0!important;height:100%;}.x-grid3-row-expander{width:100%;height:18px;background-position:4px 2px;background-repeat:no-repeat;background-color:transparent;}.x-grid3-row-collapsed .x-grid3-row-expander{background-position:4px 2px;}.x-grid3-row-expanded .x-grid3-row-expander{background-position:-21px 2px;}.x-grid3-row-collapsed .x-grid3-row-body{display:none!important;}.x-grid3-row-expanded .x-grid3-row-body{display:block!important;}.x-grid3-body .x-grid3-td-checker{background:transparent repeat-y right;}.x-grid3-body .x-grid3-td-checker .x-grid3-cell-inner,.x-grid3-header .x-grid3-td-checker .x-grid3-hd-inner{padding:0!important;height:100%;}.x-grid3-row-checker,.x-grid3-hd-checker{width:100%;height:18px;background-position:2px 2px;background-repeat:no-repeat;background-color:transparent;}.x-grid3-row .x-grid3-row-checker{background-position:2px 2px;}.x-grid3-row-selected .x-grid3-row-checker,.x-grid3-hd-checker-on .x-grid3-hd-checker,.x-grid3-row-checked .x-grid3-row-checker{background-position:-23px 2px;}.x-grid3-hd-checker{background-position:2px 1px;}.ext-border-box .x-grid3-hd-checker{background-position:2px 3px;}.x-grid3-hd-checker-on .x-grid3-hd-checker{background-position:-23px 1px;}.ext-border-box .x-grid3-hd-checker-on .x-grid3-hd-checker{background-position:-23px 3px;}.x-grid3-body .x-grid3-td-numberer{background:transparent repeat-y right;}.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner{padding:3px 5px 0 0!important;text-align:right;}.x-grid3-body .x-grid3-td-row-icon{background:transparent repeat-y right;vertical-align:top;text-align:center;}.x-grid3-body .x-grid3-td-row-icon .x-grid3-cell-inner{padding:0!important;background-position:center center;background-repeat:no-repeat;width:16px;height:16px;margin-left:2px;margin-top:3px;}.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander{background:transparent repeat-y right;}.x-grid3-body .x-grid3-check-col-td .x-grid3-cell-inner{padding:1px 0 0 0!important;}.x-grid3-check-col{width:100%;height:16px;background-position:center center;background-repeat:no-repeat;background-color:transparent;}.x-grid3-check-col-on{width:100%;height:16px;background-position:center center;background-repeat:no-repeat;background-color:transparent;}.x-grid-group,.x-grid-group-body,.x-grid-group-hd{zoom:1;}.x-grid-group-hd{border-bottom:2px solid;cursor:pointer;padding-top:6px;}.x-grid-group-hd div.x-grid-group-title{background:transparent no-repeat 3px 3px;padding:4px 4px 4px 17px;}.x-grid-group-collapsed .x-grid-group-body{display:none;}.ext-ie6 .x-grid3 .x-editor .x-form-text,.ext-ie7 .x-grid3 .x-editor .x-form-text{position:relative;top:-1px;}.x-grid-editor .x-form-check-wrap{text-align:center;margin-top:-4px;}.ext-ie .x-props-grid .x-editor .x-form-text{position:static;top:0;}.x-grid-empty{padding:10px;}.ext-ie7 .x-grid-panel .x-panel-bbar{position:relative;}.ext-ie7 .x-grid-panel .x-panel-mc .x-panel-bbar{position:static;}.ext-ie6 .x-grid3-header{position:relative;}.ext-webkit .x-grid-panel .x-panel-bwrap{-webkit-user-select:none;}.ext-webkit .x-tbar-page-number{-webkit-user-select:ignore;}.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell{padding-right:0;border-right:1px solid;}.x-pivotgrid .x-grid3-header-offset table{width:100%;border-collapse:collapse;}.x-pivotgrid .x-grid3-header-offset table td{padding:4px 3px 4px 5px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:11px;line-height:13px;font-family:tahoma;}.x-pivotgrid .x-grid3-row-headers{display:block;float:left;}.x-pivotgrid .x-grid3-row-headers table{height:100%;width:100%;border-collapse:collapse;}.x-pivotgrid .x-grid3-row-headers table td{height:18px;padding:2px 7px 0 0;text-align:right;text-overflow:ellipsis;font-size:11px;font-family:tahoma;}.ext-gecko .x-pivotgrid .x-grid3-row-headers table td{height:21px;}.x-grid3-header-title{top:0;left:0;position:absolute;text-align:center;vertical-align:middle;font-family:tahoma;font-size:11px;padding:auto 1px;display:table-cell;}.x-grid3-header-title span{position:absolute;top:50%;left:0;width:100%;margin-top:-6px;}.x-dd-drag-proxy{position:absolute;left:0;top:0;visibility:hidden;z-index:15000;}.x-dd-drag-ghost{-moz-opacity:.85;opacity:.85;filter:alpha(opacity=85);border:1px solid;padding:3px;padding-left:20px;white-space:nowrap;}.x-dd-drag-repair .x-dd-drag-ghost{-moz-opacity:.4;opacity:.4;filter:alpha(opacity=40);border:0 none;padding:0;background-color:transparent;}.x-dd-drag-repair .x-dd-drop-icon{visibility:hidden;}.x-dd-drop-icon{position:absolute;top:3px;left:3px;display:block;width:16px;height:16px;background-color:transparent;background-position:center;background-repeat:no-repeat;z-index:1;}.x-view-selector{position:absolute;left:0;top:0;width:0;border:1px dotted;opacity:.5;-moz-opacity:.5;filter:alpha(opacity=50);zoom:1;}.ext-strict .ext-ie .x-tree .x-panel-bwrap{position:relative;overflow:hidden;}.x-tree-icon,.x-tree-ec-icon,.x-tree-elbow-line,.x-tree-elbow,.x-tree-elbow-end,.x-tree-elbow-plus,.x-tree-elbow-minus,.x-tree-elbow-end-plus,.x-tree-elbow-end-minus{border:0 none;height:18px;margin:0;padding:0;vertical-align:top;width:16px;background-repeat:no-repeat;}.x-tree-node-collapsed .x-tree-node-icon,.x-tree-node-expanded .x-tree-node-icon,.x-tree-node-leaf .x-tree-node-icon{border:0 none;height:18px;margin:0;padding:0;vertical-align:top;width:16px;background-position:center;background-repeat:no-repeat;}.ext-ie .x-tree-node-indent img,.ext-ie .x-tree-node-icon,.ext-ie .x-tree-ec-icon{vertical-align:middle!important;}.ext-strict .ext-ie8 .x-tree-node-indent img,.ext-strict .ext-ie8 .x-tree-node-icon,.ext-strict .ext-ie8 .x-tree-ec-icon{vertical-align:top!important;}input.x-tree-node-cb{margin-left:1px;height:19px;vertical-align:bottom;}.ext-ie input.x-tree-node-cb{margin-left:0;margin-top:1px;width:16px;height:16px;vertical-align:middle;}.ext-strict .ext-ie8 input.x-tree-node-cb{margin:1px 1px;height:14px;vertical-align:bottom;}.ext-strict .ext-ie8 input.x-tree-node-cb+a{vertical-align:bottom;}.ext-opera input.x-tree-node-cb{height:14px;vertical-align:middle;}.x-tree-noicon .x-tree-node-icon{width:0;height:0;}.x-tree-no-lines .x-tree-elbow{background-color:transparent;}.x-tree-no-lines .x-tree-elbow-end{background-color:transparent;}.x-tree-no-lines .x-tree-elbow-line{background-color:transparent;}.x-tree-arrows .x-tree-elbow{background-color:transparent;}.x-tree-arrows .x-tree-elbow-plus{background:transparent no-repeat 0 0;}.x-tree-arrows .x-tree-elbow-minus{background:transparent no-repeat -16px 0;}.x-tree-arrows .x-tree-elbow-end{background-color:transparent;}.x-tree-arrows .x-tree-elbow-end-plus{background:transparent no-repeat 0 0;}.x-tree-arrows .x-tree-elbow-end-minus{background:transparent no-repeat -16px 0;}.x-tree-arrows .x-tree-elbow-line{background-color:transparent;}.x-tree-arrows .x-tree-ec-over .x-tree-elbow-plus{background-position:-32px 0;}.x-tree-arrows .x-tree-ec-over .x-tree-elbow-minus{background-position:-48px 0;}.x-tree-arrows .x-tree-ec-over .x-tree-elbow-end-plus{background-position:-32px 0;}.x-tree-arrows .x-tree-ec-over .x-tree-elbow-end-minus{background-position:-48px 0;}.x-tree-elbow-plus,.x-tree-elbow-minus,.x-tree-elbow-end-plus,.x-tree-elbow-end-minus{cursor:pointer;}.ext-ie ul.x-tree-node-ct{font-size:0;line-height:0;zoom:1;}.x-tree-node{white-space:nowrap;}.x-tree-node-el{line-height:18px;cursor:pointer;}.x-tree-node a,.x-dd-drag-ghost a{text-decoration:none;-khtml-user-select:none;-moz-user-select:none;-webkit-user-select:ignore;-kthml-user-focus:normal;-moz-user-focus:normal;-moz-outline:0 none;outline:0 none;}.x-tree-node a span,.x-dd-drag-ghost a span{text-decoration:none;padding:1px 3px 1px 2px;}.x-tree-node .x-tree-node-disabled .x-tree-node-icon{-moz-opacity:.5;opacity:.5;filter:alpha(opacity=50);}.x-tree-node .x-tree-node-inline-icon{background-color:transparent;}.x-tree-node a:hover,.x-dd-drag-ghost a:hover{text-decoration:none;}.x-tree-node div.x-tree-drag-insert-below{border-bottom:1px dotted;}.x-tree-node div.x-tree-drag-insert-above{border-top:1px dotted;}.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below{border-bottom:0 none;}.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above{border-top:0 none;}.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a{border-bottom:2px solid;}.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{border-top:2px solid;}.x-tree-node .x-tree-drag-append a span{border:1px dotted;}.x-dd-drag-ghost .x-tree-node-indent,.x-dd-drag-ghost .x-tree-ec-icon{display:none!important;}.x-tree-root-ct{zoom:1;}.x-date-picker{border:1px solid;border-top:0 none;position:relative;}.x-date-picker a{-moz-outline:0 none;outline:0 none;}.x-date-inner,.x-date-inner td,.x-date-inner th{border-collapse:separate;}.x-date-middle,.x-date-left,.x-date-right{background:repeat-x 0 -83px;overflow:hidden;}.x-date-middle .x-btn-tc,.x-date-middle .x-btn-tl,.x-date-middle .x-btn-tr,.x-date-middle .x-btn-mc,.x-date-middle .x-btn-ml,.x-date-middle .x-btn-mr,.x-date-middle .x-btn-bc,.x-date-middle .x-btn-bl,.x-date-middle .x-btn-br{background:transparent!important;vertical-align:middle;}.x-date-middle .x-btn-mc em.x-btn-arrow{background:transparent no-repeat right 0;}.x-date-right,.x-date-left{width:18px;}.x-date-right{text-align:right;}.x-date-middle{padding-top:2px;padding-bottom:2px;width:130px;}.x-date-right a,.x-date-left a{display:block;width:16px;height:16px;background-position:center;background-repeat:no-repeat;cursor:pointer;-moz-opacity:.6;opacity:.6;filter:alpha(opacity=60);}.x-date-right a:hover,.x-date-left a:hover{-moz-opacity:1;opacity:1;filter:alpha(opacity=100);}.x-item-disabled .x-date-right a:hover,.x-item-disabled .x-date-left a:hover{-moz-opacity:.6;opacity:.6;filter:alpha(opacity=60);}.x-date-right a{margin-right:2px;text-decoration:none!important;}.x-date-left a{margin-left:2px;text-decoration:none!important;}table.x-date-inner{width:100%;table-layout:fixed;}.ext-webkit table.x-date-inner{width:175px;}.x-date-inner th{width:25px;}.x-date-inner th{background:repeat-x left top;text-align:right!important;border-bottom:1px solid;cursor:default;padding:0;border-collapse:separate;}.x-date-inner th span{display:block;padding:2px;padding-right:7px;}.x-date-inner td{border:1px solid;text-align:right;padding:0;}.x-date-inner a{padding:2px 5px;display:block;text-decoration:none;text-align:right;zoom:1;}.x-date-inner .x-date-active{cursor:pointer;color:black;}.x-date-inner .x-date-selected a{background:repeat-x left top;border:1px solid;padding:1px 4px;}.x-date-inner .x-date-today a{border:1px solid;padding:1px 4px;}.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a{text-decoration:none!important;}.x-date-bottom{padding:4px;border-top:1px solid;background:repeat-x left top;}.x-date-inner a:hover,.x-date-inner .x-date-disabled a:hover{text-decoration:none!important;}.x-item-disabled .x-date-inner a:hover{background:0;}.x-date-inner .x-date-disabled a{cursor:default;}.x-date-menu .x-menu-item{padding:1px 24px 1px 4px;white-space:nowrap;}.x-date-menu .x-menu-item .x-menu-item-icon{width:10px;height:10px;margin-right:5px;background-position:center -4px!important;}.x-date-mp{position:absolute;left:0;top:0;display:none;}.x-date-mp td{padding:2px;font:normal 11px arial,helvetica,tahoma,sans-serif;}td.x-date-mp-month,td.x-date-mp-year,td.x-date-mp-ybtn{border:0 none;text-align:center;vertical-align:middle;width:25%;}.x-date-mp-ok{margin-right:3px;}.x-date-mp-btns button{text-decoration:none;text-align:center;text-decoration:none!important;border:1px solid;padding:1px 3px 1px;cursor:pointer;}.x-date-mp-btns{background:repeat-x left top;}.x-date-mp-btns td{border-top:1px solid;text-align:center;}td.x-date-mp-month a,td.x-date-mp-year a{display:block;padding:2px 4px;text-decoration:none;text-align:center;}td.x-date-mp-month a:hover,td.x-date-mp-year a:hover{text-decoration:none;cursor:pointer;}td.x-date-mp-sel a{padding:1px 3px;background:repeat-x left top;border:1px solid;}.x-date-mp-ybtn a{overflow:hidden;width:15px;height:15px;cursor:pointer;background:transparent no-repeat;display:block;margin:0 auto;}.x-date-mp-ybtn a.x-date-mp-next{background-position:0 -120px;}.x-date-mp-ybtn a.x-date-mp-next:hover{background-position:-15px -120px;}.x-date-mp-ybtn a.x-date-mp-prev{background-position:0 -105px;}.x-date-mp-ybtn a.x-date-mp-prev:hover{background-position:-15px -105px;}.x-date-mp-ybtn{text-align:center;}td.x-date-mp-sep{border-right:1px solid;}.x-tip{position:absolute;top:0;left:0;visibility:hidden;z-index:20002;border:0 none;}.x-tip .x-tip-close{height:15px;float:right;width:15px;margin:0 0 2px 2px;cursor:pointer;display:none;}.x-tip .x-tip-tc{background:transparent no-repeat 0 -62px;padding-top:3px;overflow:hidden;zoom:1;}.x-tip .x-tip-tl{background:transparent no-repeat 0 0;padding-left:6px;overflow:hidden;zoom:1;}.x-tip .x-tip-tr{background:transparent no-repeat right 0;padding-right:6px;overflow:hidden;zoom:1;}.x-tip .x-tip-bc{background:transparent no-repeat 0 -121px;height:3px;overflow:hidden;}.x-tip .x-tip-bl{background:transparent no-repeat 0 -59px;padding-left:6px;zoom:1;}.x-tip .x-tip-br{background:transparent no-repeat right -59px;padding-right:6px;zoom:1;}.x-tip .x-tip-mc{border:0 none;}.x-tip .x-tip-ml{background:no-repeat 0 -124px;padding-left:6px;zoom:1;}.x-tip .x-tip-mr{background:transparent no-repeat right -124px;padding-right:6px;zoom:1;}.ext-ie .x-tip .x-tip-header,.ext-ie .x-tip .x-tip-tc{font-size:0;line-height:0;}.ext-border-box .x-tip .x-tip-header,.ext-border-box .x-tip .x-tip-tc{line-height:1px;}.x-tip .x-tip-header-text{padding:0;margin:0 0 2px 0;}.x-tip .x-tip-body{margin:0!important;line-height:14px;padding:0;}.x-tip .x-tip-body .loading-indicator{margin:0;}.x-tip-draggable .x-tip-header,.x-tip-draggable .x-tip-header-text{cursor:move;}.x-form-invalid-tip .x-tip-tc{background:repeat-x 0 -12px;padding-top:6px;}.x-form-invalid-tip .x-tip-bc{background:repeat-x 0 -18px;height:6px;}.x-form-invalid-tip .x-tip-bl{background:no-repeat 0 -6px;}.x-form-invalid-tip .x-tip-br{background:no-repeat right -6px;}.x-form-invalid-tip .x-tip-body{padding:2px;}.x-form-invalid-tip .x-tip-body{padding-left:24px;background:transparent no-repeat 2px 2px;}.x-tip-anchor{position:absolute;width:9px;height:10px;overflow:hidden;background:transparent no-repeat 0 0;zoom:1;}.x-tip-anchor-bottom{background-position:-9px 0;}.x-tip-anchor-right{background-position:-18px 0;width:10px;}.x-tip-anchor-left{background-position:-28px 0;width:10px;}.x-menu{z-index:15000;zoom:1;background:repeat-y;}.x-menu-floating{border:1px solid;}.x-menu a{text-decoration:none!important;}.ext-ie .x-menu{zoom:1;overflow:hidden;}.x-menu-list{padding:2px;background-color:transparent;border:0 none;overflow:hidden;overflow-y:hidden;}.ext-strict .ext-ie .x-menu-list{position:relative;}.x-menu li{line-height:100%;}.x-menu li.x-menu-sep-li{font-size:1px;line-height:1px;}.x-menu-list-item{white-space:nowrap;display:block;padding:1px;}.x-menu-item{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:ignore;}.x-menu-item-arrow{background:transparent no-repeat right;}.x-menu-sep{display:block;font-size:1px;line-height:1px;margin:2px 3px;border-bottom:1px solid;overflow:hidden;}.x-menu-focus{position:absolute;left:-1px;top:-1px;width:1px;height:1px;line-height:1px;font-size:1px;-moz-outline:0 none;outline:0 none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:ignore;overflow:hidden;display:block;}a.x-menu-item{cursor:pointer;display:block;line-height:16px;outline-color:-moz-use-text-color;outline-style:none;outline-width:0;padding:3px 21px 3px 27px;position:relative;text-decoration:none;white-space:nowrap;}.x-menu-item-active{background-repeat:repeat-x;background-position:left bottom;border-style:solid;border-width:1px 0;margin:0 1px;padding:0;}.x-menu-item-active a.x-menu-item{border-style:solid;border-width:0 1px;margin:0 -1px;}.x-menu-item-icon{border:0 none;height:16px;padding:0;vertical-align:top;width:16px;position:absolute;left:3px;top:3px;margin:0;background-position:center;}.ext-ie .x-menu-item-icon{left:-24px;}.ext-strict .x-menu-item-icon{left:3px;}.ext-ie6 .x-menu-item-icon{left:-24px;}.ext-ie .x-menu-item-icon{vertical-align:middle;}.x-menu-check-item .x-menu-item-icon{background:transparent no-repeat center;}.x-menu-group-item .x-menu-item-icon{background-color:transparent;}.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{background:transparent no-repeat center;}.x-date-menu .x-menu-list{padding:0;}.x-menu-date-item{padding:0;}.x-menu .x-color-palette,.x-menu .x-date-picker{margin-left:26px;margin-right:4px;}.x-menu .x-date-picker{border:1px solid;margin-top:2px;margin-bottom:2px;}.x-menu-plain .x-color-palette,.x-menu-plain .x-date-picker{margin:0;border:0 none;}.x-date-menu{padding:0!important;}.ext-strict .ext-ie6 .x-menu-sep-li{padding:3px 4px;}.ext-strict .ext-ie6 .x-menu-sep{margin:0;height:1px;}.ext-webkit .x-menu-sep{height:1px;}.ext-ie .x-date-menu{height:199px;}.ext-strict .ext-ie .x-date-menu,.ext-border-box .ext-ie8 .x-date-menu{height:197px;}.ext-strict .ext-ie7 .x-date-menu{height:195px;}.ext-strict .ext-ie8 .x-date-menu{height:auto;}.x-cycle-menu .x-menu-item-checked{border:1px dotted!important;padding:0;}.x-menu .x-menu-scroller{width:100%;background-repeat:no-repeat;background-position:center;height:8px;line-height:8px;cursor:pointer;margin:0;padding:0;}.x-menu .x-menu-scroller-active{height:6px;line-height:6px;}.x-menu-list-item-indent{padding-left:27px;}.x-box-tl{background:transparent no-repeat 0 0;zoom:1;}.x-box-tc{height:8px;background:transparent repeat-x 0 0;overflow:hidden;}.x-box-tr{background:transparent no-repeat right -8px;}.x-box-ml{background:transparent repeat-y 0;padding-left:4px;overflow:hidden;zoom:1;}.x-box-mc{background:repeat-x 0 -16px;padding:4px 10px;}.x-box-mc h3{margin:0 0 4px 0;zoom:1;}.x-box-mr{background:transparent repeat-y right;padding-right:4px;overflow:hidden;}.x-box-bl{background:transparent no-repeat 0 -16px;zoom:1;}.x-box-bc{background:transparent repeat-x 0 -8px;height:8px;overflow:hidden;}.x-box-br{background:transparent no-repeat right -24px;}.x-box-tl,.x-box-bl{padding-left:8px;overflow:hidden;}.x-box-tr,.x-box-br{padding-right:8px;overflow:hidden;}.x-combo-list{border:1px solid;zoom:1;overflow:hidden;}.x-combo-list-inner{overflow:auto;position:relative;zoom:1;overflow-x:hidden;}.x-combo-list-hd{border-bottom:1px solid;padding:3px;}.x-resizable-pinned .x-combo-list-inner{border-bottom:1px solid;}.x-combo-list-item{padding:2px;border:1px solid;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.x-combo-list .x-combo-selected{border:1px dotted!important;cursor:pointer;}.x-combo-list .x-toolbar{border-top:1px solid;border-bottom:0 none;}.x-panel{border-style:solid;border-width:0;}.x-panel-header{overflow:hidden;zoom:1;padding:5px 3px 4px 5px;border:1px solid;line-height:15px;background:transparent repeat-x 0 -1px;}.x-panel-body{border:1px solid;border-top:0 none;overflow:hidden;position:relative;}.x-panel-bbar .x-toolbar,.x-panel-tbar .x-toolbar{border:1px solid;border-top:0 none;overflow:hidden;padding:2px;}.x-panel-tbar-noheader .x-toolbar,.x-panel-mc .x-panel-tbar .x-toolbar{border-top:1px solid;border-bottom:0 none;}.x-panel-body-noheader,.x-panel-mc .x-panel-body{border-top:1px solid;}.x-panel-header{overflow:hidden;zoom:1;}.x-panel-tl .x-panel-header{padding:5px 0 4px 0;border:0 none;background:transparent no-repeat;}.x-panel-tl .x-panel-icon,.x-window-tl .x-panel-icon{padding-left:20px!important;background-repeat:no-repeat;background-position:0 4px;zoom:1;}.x-panel-inline-icon{width:16px;height:16px;background-repeat:no-repeat;background-position:0 0;vertical-align:middle;margin-right:4px;margin-top:-1px;margin-bottom:-1px;}.x-panel-tc{background:transparent repeat-x 0 0;overflow:hidden;}.ext-strict .ext-ie7 .x-panel-tc{overflow:visible;}.x-panel-tl{background:transparent no-repeat 0 0;padding-left:6px;zoom:1;border-bottom:1px solid;}.x-panel-tr{background:transparent no-repeat right 0;zoom:1;padding-right:6px;}.x-panel-bc{background:transparent repeat-x 0 bottom;zoom:1;}.x-panel-bc .x-panel-footer{zoom:1;}.x-panel-bl{background:transparent no-repeat 0 bottom;padding-left:6px;zoom:1;}.x-panel-br{background:transparent no-repeat right bottom;padding-right:6px;zoom:1;}.x-panel-mc{border:0 none;padding:0;margin:0;padding-top:6px;}.x-panel-mc .x-panel-body{background-color:transparent;border:0 none;}.x-panel-ml{background:repeat-y 0 0;padding-left:6px;zoom:1;}.x-panel-mr{background:transparent repeat-y right 0;padding-right:6px;zoom:1;}.x-panel-bc .x-panel-footer{padding-bottom:6px;}.x-panel-nofooter .x-panel-bc,.x-panel-nofooter .x-window-bc{height:6px;font-size:0;line-height:0;}.x-panel-bwrap{overflow:hidden;zoom:1;left:0;top:0;}.x-panel-body{overflow:hidden;zoom:1;}.x-panel-collapsed .x-resizable-handle{display:none;}.ext-gecko .x-panel-animated div{overflow:hidden!important;}.x-plain-body{overflow:hidden;}.x-plain-bbar .x-toolbar{overflow:hidden;padding:2px;}.x-plain-tbar .x-toolbar{overflow:hidden;padding:2px;}.x-plain-bwrap{overflow:hidden;zoom:1;}.x-plain{overflow:hidden;}.x-tool{overflow:hidden;width:15px;height:15px;float:right;cursor:pointer;background:transparent no-repeat;margin-left:2px;}.x-tool-toggle{background-position:0 -60px;}.x-tool-toggle-over{background-position:-15px -60px;}.x-panel-collapsed .x-tool-toggle{background-position:0 -75px;}.x-panel-collapsed .x-tool-toggle-over{background-position:-15px -75px;}.x-tool-close{background-position:0 -0;}.x-tool-close-over{background-position:-15px 0;}.x-tool-minimize{background-position:0 -15px;}.x-tool-minimize-over{background-position:-15px -15px;}.x-tool-maximize{background-position:0 -30px;}.x-tool-maximize-over{background-position:-15px -30px;}.x-tool-restore{background-position:0 -45px;}.x-tool-restore-over{background-position:-15px -45px;}.x-tool-gear{background-position:0 -90px;}.x-tool-gear-over{background-position:-15px -90px;}.x-tool-prev{background-position:0 -105px;}.x-tool-prev-over{background-position:-15px -105px;}.x-tool-next{background-position:0 -120px;}.x-tool-next-over{background-position:-15px -120px;}.x-tool-pin{background-position:0 -135px;}.x-tool-pin-over{background-position:-15px -135px;}.x-tool-unpin{background-position:0 -150px;}.x-tool-unpin-over{background-position:-15px -150px;}.x-tool-right{background-position:0 -165px;}.x-tool-right-over{background-position:-15px -165px;}.x-tool-left{background-position:0 -180px;}.x-tool-left-over{background-position:-15px -180px;}.x-tool-down{background-position:0 -195px;}.x-tool-down-over{background-position:-15px -195px;}.x-tool-up{background-position:0 -210px;}.x-tool-up-over{background-position:-15px -210px;}.x-tool-refresh{background-position:0 -225px;}.x-tool-refresh-over{background-position:-15px -225px;}.x-tool-plus{background-position:0 -240px;}.x-tool-plus-over{background-position:-15px -240px;}.x-tool-minus{background-position:0 -255px;}.x-tool-minus-over{background-position:-15px -255px;}.x-tool-search{background-position:0 -270px;}.x-tool-search-over{background-position:-15px -270px;}.x-tool-save{background-position:0 -285px;}.x-tool-save-over{background-position:-15px -285px;}.x-tool-help{background-position:0 -300px;}.x-tool-help-over{background-position:-15px -300px;}.x-tool-print{background-position:0 -315px;}.x-tool-print-over{background-position:-15px -315px;}.x-tool-expand{background-position:0 -330px;}.x-tool-expand-over{background-position:-15px -330px;}.x-tool-collapse{background-position:0 -345px;}.x-tool-collapse-over{background-position:-15px -345px;}.x-tool-resize{background-position:0 -360px;}.x-tool-resize-over{background-position:-15px -360px;}.x-tool-move{background-position:0 -375px;}.x-tool-move-over{background-position:-15px -375px;}.x-panel-ghost{z-index:12000;overflow:hidden;position:absolute;left:0;top:0;opacity:.65;-moz-opacity:.65;filter:alpha(opacity=65);}.x-panel-ghost ul{margin:0;padding:0;overflow:hidden;font-size:0;line-height:0;border:1px solid;border-top:0 none;display:block;}.x-panel-ghost *{cursor:move!important;}.x-panel-dd-spacer{border:2px dashed;}.x-panel-btns{padding:5px;overflow:hidden;}.x-panel-btns td.x-toolbar-cell{padding:3px;}.x-panel-btns .x-btn-focus .x-btn-left{background-position:0 -147px;}.x-panel-btns .x-btn-focus .x-btn-right{background-position:0 -168px;}.x-panel-btns .x-btn-focus .x-btn-center{background-position:0 -189px;}.x-panel-btns .x-btn-over .x-btn-left{background-position:0 -63px;}.x-panel-btns .x-btn-over .x-btn-right{background-position:0 -84px;}.x-panel-btns .x-btn-over .x-btn-center{background-position:0 -105px;}.x-panel-btns .x-btn-click .x-btn-center{background-position:0 -126px;}.x-panel-btns .x-btn-click .x-btn-right{background-position:0 -84px;}.x-panel-btns .x-btn-click .x-btn-left{background-position:0 -63px;}.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{white-space:nowrap;}.x-panel-reset .x-panel-body html,.x-panel-reset .x-panel-body address,.x-panel-reset .x-panel-body blockquote,.x-panel-reset .x-panel-body body,.x-panel-reset .x-panel-body dd,.x-panel-reset .x-panel-body div,.x-panel-reset .x-panel-body dl,.x-panel-reset .x-panel-body dt,.x-panel-reset .x-panel-body fieldset,.x-panel-reset .x-panel-body form,.x-panel-reset .x-panel-body frame,frameset,.x-panel-reset .x-panel-body h1,.x-panel-reset .x-panel-body h2,.x-panel-reset .x-panel-body h3,.x-panel-reset .x-panel-body h4,.x-panel-reset .x-panel-body h5,.x-panel-reset .x-panel-body h6,.x-panel-reset .x-panel-body noframes,.x-panel-reset .x-panel-body ol,.x-panel-reset .x-panel-body p,.x-panel-reset .x-panel-body ul,.x-panel-reset .x-panel-body center,.x-panel-reset .x-panel-body dir,.x-panel-reset .x-panel-body hr,.x-panel-reset .x-panel-body menu,.x-panel-reset .x-panel-body pre{display:block;}.x-panel-reset .x-panel-body li{display:list-item;}.x-panel-reset .x-panel-body head{display:none;}.x-panel-reset .x-panel-body table{display:table;}.x-panel-reset .x-panel-body tr{display:table-row;}.x-panel-reset .x-panel-body thead{display:table-header-group;}.x-panel-reset .x-panel-body tbody{display:table-row-group;}.x-panel-reset .x-panel-body tfoot{display:table-footer-group;}.x-panel-reset .x-panel-body col{display:table-column;}.x-panel-reset .x-panel-body colgroup{display:table-column-group;}.x-panel-reset .x-panel-body td,.x-panel-reset .x-panel-body th{display:table-cell;}.x-panel-reset .x-panel-body caption{display:table-caption;}.x-panel-reset .x-panel-body th{font-weight:bolder;text-align:center;}.x-panel-reset .x-panel-body caption{text-align:center;}.x-panel-reset .x-panel-body body{margin:8px;}.x-panel-reset .x-panel-body h1{font-size:2em;margin:.67em 0;}.x-panel-reset .x-panel-body h2{font-size:1.5em;margin:.75em 0;}.x-panel-reset .x-panel-body h3{font-size:1.17em;margin:.83em 0;}.x-panel-reset .x-panel-body h4,.x-panel-reset .x-panel-body p,.x-panel-reset .x-panel-body blockquote,.x-panel-reset .x-panel-body ul,.x-panel-reset .x-panel-body fieldset,.x-panel-reset .x-panel-body form,.x-panel-reset .x-panel-body ol,.x-panel-reset .x-panel-body dl,.x-panel-reset .x-panel-body dir,.x-panel-reset .x-panel-body menu{margin:1.12em 0;}.x-panel-reset .x-panel-body h5{font-size:.83em;margin:1.5em 0;}.x-panel-reset .x-panel-body h6{font-size:.75em;margin:1.67em 0;}.x-panel-reset .x-panel-body h1,.x-panel-reset .x-panel-body h2,.x-panel-reset .x-panel-body h3,.x-panel-reset .x-panel-body h4,.x-panel-reset .x-panel-body h5,.x-panel-reset .x-panel-body h6,.x-panel-reset .x-panel-body b,.x-panel-reset .x-panel-body strong{font-weight:bolder;}.x-panel-reset .x-panel-body blockquote{margin-left:40px;margin-right:40px;}.x-panel-reset .x-panel-body i,.x-panel-reset .x-panel-body cite,.x-panel-reset .x-panel-body em,.x-panel-reset .x-panel-body var,.x-panel-reset .x-panel-body address{font-style:italic;}.x-panel-reset .x-panel-body pre,.x-panel-reset .x-panel-body tt,.x-panel-reset .x-panel-body code,.x-panel-reset .x-panel-body kbd,.x-panel-reset .x-panel-body samp{font-family:monospace;}.x-panel-reset .x-panel-body pre{white-space:pre;}.x-panel-reset .x-panel-body button,.x-panel-reset .x-panel-body textarea,.x-panel-reset .x-panel-body input,.x-panel-reset .x-panel-body select{display:inline-block;}.x-panel-reset .x-panel-body big{font-size:1.17em;}.x-panel-reset .x-panel-body small,.x-panel-reset .x-panel-body sub,.x-panel-reset .x-panel-body sup{font-size:.83em;}.x-panel-reset .x-panel-body sub{vertical-align:sub;}.x-panel-reset .x-panel-body sup{vertical-align:super;}.x-panel-reset .x-panel-body table{border-spacing:2px;}.x-panel-reset .x-panel-body thead,.x-panel-reset .x-panel-body tbody,.x-panel-reset .x-panel-body tfoot{vertical-align:middle;}.x-panel-reset .x-panel-body td,.x-panel-reset .x-panel-body th{vertical-align:inherit;}.x-panel-reset .x-panel-body s,.x-panel-reset .x-panel-body strike,.x-panel-reset .x-panel-body del{text-decoration:line-through;}.x-panel-reset .x-panel-body hr{border:1px inset;}.x-panel-reset .x-panel-body ol,.x-panel-reset .x-panel-body ul,.x-panel-reset .x-panel-body dir,.x-panel-reset .x-panel-body menu,.x-panel-reset .x-panel-body dd{margin-left:40px;}.x-panel-reset .x-panel-body ul,.x-panel-reset .x-panel-body menu,.x-panel-reset .x-panel-body dir{list-style-type:disc;}.x-panel-reset .x-panel-body ol{list-style-type:decimal;}.x-panel-reset .x-panel-body ol ul,.x-panel-reset .x-panel-body ul ol,.x-panel-reset .x-panel-body ul ul,.x-panel-reset .x-panel-body ol ol{margin-top:0;margin-bottom:0;}.x-panel-reset .x-panel-body u,.x-panel-reset .x-panel-body ins{text-decoration:underline;}.x-panel-reset .x-panel-body br:before{content:"\A";}.x-panel-reset .x-panel-body :before,.x-panel-reset .x-panel-body :after{white-space:pre-line;}.x-panel-reset .x-panel-body center{text-align:center;}.x-panel-reset .x-panel-body :link,.x-panel-reset .x-panel-body :visited{text-decoration:underline;}.x-panel-reset .x-panel-body :focus{outline:invert dotted thin;}.x-panel-reset .x-panel-body BDO[DIR="ltr"]{direction:ltr;unicode-bidi:bidi-override;}.x-panel-reset .x-panel-body BDO[DIR="rtl"]{direction:rtl;unicode-bidi:bidi-override;}.x-window{zoom:1;}.x-window .x-window-handle{opacity:0;-moz-opacity:0;filter:alpha(opacity=0);}.x-window-proxy{border:1px solid;z-index:12000;overflow:hidden;position:absolute;left:0;top:0;display:none;opacity:.5;-moz-opacity:.5;filter:alpha(opacity=50);}.x-window-header{overflow:hidden;zoom:1;}.x-window-bwrap{z-index:1;position:relative;zoom:1;left:0;top:0;}.x-window-tl .x-window-header{padding:5px 0 4px 0;}.x-window-header-text{cursor:pointer;}.x-window-tc{background:transparent repeat-x 0 0;overflow:hidden;zoom:1;}.x-window-tl{background:transparent no-repeat 0 0;padding-left:6px;zoom:1;z-index:1;position:relative;}.x-window-tr{background:transparent no-repeat right 0;padding-right:6px;}.x-window-bc{background:transparent repeat-x 0 bottom;zoom:1;}.x-window-bc .x-window-footer{padding-bottom:6px;zoom:1;font-size:0;line-height:0;}.x-window-bl{background:transparent no-repeat 0 bottom;padding-left:6px;zoom:1;}.x-window-br{background:transparent no-repeat right bottom;padding-right:6px;zoom:1;}.x-window-mc{border:1px solid;padding:0;margin:0;}.x-window-ml{background:transparent repeat-y 0 0;padding-left:6px;zoom:1;}.x-window-mr{background:transparent repeat-y right 0;padding-right:6px;zoom:1;}.x-window-body{overflow:hidden;}.x-window-bwrap{overflow:hidden;}.x-window-maximized .x-window-bl,.x-window-maximized .x-window-br,.x-window-maximized .x-window-ml,.x-window-maximized .x-window-mr,.x-window-maximized .x-window-tl,.x-window-maximized .x-window-tr{padding:0;}.x-window-maximized .x-window-footer{padding-bottom:0;}.x-window-maximized .x-window-tc{padding-left:3px;padding-right:3px;}.x-window-maximized .x-window-mc{border-left:0 none;border-right:0 none;}.x-window-tbar .x-toolbar,.x-window-bbar .x-toolbar{border-left:0 none;border-right:0 none;}.x-window-bbar .x-toolbar{border-top:1px solid;border-bottom:0 none;}.x-window-draggable,.x-window-draggable .x-window-header-text{cursor:move;}.x-window-maximized .x-window-draggable,.x-window-maximized .x-window-draggable .x-window-header-text{cursor:default;}.x-window-body{background-color:transparent;}.x-panel-ghost .x-window-tl{border-bottom:1px solid;}.x-panel-collapsed .x-window-tl{border-bottom:1px solid;}.x-window-maximized-ct{overflow:hidden;}.x-window-maximized .x-window-handle{display:none;}.x-window-sizing-ghost ul{border:0 none!important;}.x-dlg-focus{-moz-outline:0 none;outline:0 none;width:0;height:0;overflow:hidden;position:absolute;top:0;left:0;}.ext-webkit .x-dlg-focus{width:1px;height:1px;}.x-dlg-mask{z-index:10000;display:none;position:absolute;top:0;left:0;-moz-opacity:.5;opacity:.50;filter:alpha(opacity=50);}body.ext-ie6.x-body-masked select{visibility:hidden;}body.ext-ie6.x-body-masked .x-window select{visibility:visible;}.x-window-plain .x-window-mc{border:1px solid;}.x-window-plain .x-window-body{border:1px solid;background:transparent!important;}.x-html-editor-wrap{border:1px solid;}.x-html-editor-tb .x-btn-text{background:transparent no-repeat;}.x-html-editor-tb .x-edit-bold,.x-menu-item img.x-edit-bold{background-position:0 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-italic,.x-menu-item img.x-edit-italic{background-position:-16px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-underline,.x-menu-item img.x-edit-underline{background-position:-32px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-forecolor,.x-menu-item img.x-edit-forecolor{background-position:-160px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-backcolor,.x-menu-item img.x-edit-backcolor{background-position:-176px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-justifyleft,.x-menu-item img.x-edit-justifyleft{background-position:-112px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-justifycenter,.x-menu-item img.x-edit-justifycenter{background-position:-128px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-justifyright,.x-menu-item img.x-edit-justifyright{background-position:-144px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-insertorderedlist,.x-menu-item img.x-edit-insertorderedlist{background-position:-80px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-insertunorderedlist,.x-menu-item img.x-edit-insertunorderedlist{background-position:-96px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-increasefontsize,.x-menu-item img.x-edit-increasefontsize{background-position:-48px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-decreasefontsize,.x-menu-item img.x-edit-decreasefontsize{background-position:-64px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-sourceedit,.x-menu-item img.x-edit-sourceedit{background-position:-192px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tb .x-edit-createlink,.x-menu-item img.x-edit-createlink{background-position:-208px 0;background-image:url(../images/default/editor/tb-sprite.gif);}.x-html-editor-tip .x-tip-bd .x-tip-bd-inner{padding:5px;padding-bottom:1px;}.x-html-editor-tb .x-toolbar{position:static!important;}.x-panel-noborder .x-panel-body-noborder{border-width:0;}.x-panel-noborder .x-panel-header-noborder{border-width:0 0 1px;border-style:solid;}.x-panel-noborder .x-panel-tbar-noborder .x-toolbar{border-width:0 0 1px;border-style:solid;}.x-panel-noborder .x-panel-bbar-noborder .x-toolbar{border-width:1px 0 0 0;border-style:solid;}.x-window-noborder .x-window-mc{border-width:0;}.x-window-plain .x-window-body-noborder{border-width:0;}.x-tab-panel-noborder .x-tab-panel-body-noborder{border-width:0;}.x-tab-panel-noborder .x-tab-panel-header-noborder{border-width:0 0 1px 0;}.x-tab-panel-noborder .x-tab-panel-footer-noborder{border-width:1px 0 0 0;}.x-tab-panel-bbar-noborder .x-toolbar{border-width:1px 0 0 0;border-style:solid;}.x-tab-panel-tbar-noborder .x-toolbar{border-width:0 0 1px;border-style:solid;}.x-border-layout-ct{position:relative;}.x-border-panel{position:absolute;left:0;top:0;}.x-tool-collapse-south{background-position:0 -195px;}.x-tool-collapse-south-over{background-position:-15px -195px;}.x-tool-collapse-north{background-position:0 -210px;}.x-tool-collapse-north-over{background-position:-15px -210px;}.x-tool-collapse-west{background-position:0 -180px;}.x-tool-collapse-west-over{background-position:-15px -180px;}.x-tool-collapse-east{background-position:0 -165px;}.x-tool-collapse-east-over{background-position:-15px -165px;}.x-tool-expand-south{background-position:0 -210px;}.x-tool-expand-south-over{background-position:-15px -210px;}.x-tool-expand-north{background-position:0 -195px;}.x-tool-expand-north-over{background-position:-15px -195px;}.x-tool-expand-west{background-position:0 -165px;}.x-tool-expand-west-over{background-position:-15px -165px;}.x-tool-expand-east{background-position:0 -180px;}.x-tool-expand-east-over{background-position:-15px -180px;}.x-tool-expand-north,.x-tool-expand-south{float:right;margin:3px;}.x-tool-expand-east,.x-tool-expand-west{float:none;margin:3px 2px;}.x-accordion-hd .x-tool-toggle{background-position:0 -255px;}.x-accordion-hd .x-tool-toggle-over{background-position:-15px -255px;}.x-panel-collapsed .x-accordion-hd .x-tool-toggle{background-position:0 -240px;}.x-panel-collapsed .x-accordion-hd .x-tool-toggle-over{background-position:-15px -240px;}.x-accordion-hd{padding-top:4px;padding-bottom:3px;border-top:0 none;background:transparent repeat-x 0 -9px;}.x-layout-collapsed{position:absolute;left:-10000px;top:-10000px;visibility:hidden;width:20px;height:20px;overflow:hidden;border:1px solid;z-index:20;}.ext-border-box .x-layout-collapsed{width:22px;height:22px;}.x-layout-collapsed-over{cursor:pointer;}.x-layout-collapsed-west .x-layout-collapsed-tools,.x-layout-collapsed-east .x-layout-collapsed-tools{position:absolute;top:0;left:0;width:20px;height:20px;}.x-layout-split{position:absolute;height:5px;width:5px;line-height:1px;font-size:1px;z-index:3;background-color:transparent;}.ext-strict .ext-ie6 .x-layout-split{background-color:#fff!important;filter:alpha(opacity=1);}.x-layout-split-h{background-image:url(../images/default/s.gif);background-position:left;}.x-layout-split-v{background-image:url(../images/default/s.gif);background-position:top;}.x-column-layout-ct{overflow:hidden;zoom:1;}.x-column{float:left;padding:0;margin:0;overflow:hidden;zoom:1;}.x-column-inner{overflow:hidden;zoom:1;}.x-layout-mini{position:absolute;top:0;left:0;display:block;width:5px;height:35px;cursor:pointer;opacity:.5;-moz-opacity:.5;filter:alpha(opacity=50);}.x-layout-mini-over,.x-layout-collapsed-over .x-layout-mini{opacity:1;-moz-opacity:1;filter:none;}.x-layout-split-west .x-layout-mini{top:48%;}.x-layout-split-east .x-layout-mini{top:48%;}.x-layout-split-north .x-layout-mini{left:48%;height:5px;width:35px;}.x-layout-split-south .x-layout-mini{left:48%;height:5px;width:35px;}.x-layout-cmini-west .x-layout-mini{top:48%;}.x-layout-cmini-east .x-layout-mini{top:48%;}.x-layout-cmini-north .x-layout-mini{left:48%;height:5px;width:35px;}.x-layout-cmini-south .x-layout-mini{left:48%;height:5px;width:35px;}.x-layout-cmini-west,.x-layout-cmini-east{border:0 none;width:5px!important;padding:0;background-color:transparent;}.x-layout-cmini-north,.x-layout-cmini-south{border:0 none;height:5px!important;padding:0;background-color:transparent;}.x-viewport,.x-viewport body{margin:0;padding:0;border:0 none;overflow:hidden;height:100%;}.x-abs-layout-item{position:absolute;left:0;top:0;}.ext-ie input.x-abs-layout-item,.ext-ie textarea.x-abs-layout-item{margin:0;}.x-box-layout-ct{overflow:hidden;zoom:1;}.x-box-inner{overflow:hidden;zoom:1;position:relative;left:0;top:0;}.x-box-item{position:absolute;left:0;top:0;}.x-progress-wrap{border:1px solid;overflow:hidden;}.x-progress-inner{height:18px;background:repeat-x;position:relative;}.x-progress-bar{height:18px;float:left;width:0;background:repeat-x left center;border-top:1px solid;border-bottom:1px solid;border-right:1px solid;}.x-progress-text{padding:1px 5px;overflow:hidden;position:absolute;left:0;text-align:center;}.x-progress-text-back{line-height:16px;}.ext-ie .x-progress-text-back{line-height:15px;}.ext-strict .ext-ie7 .x-progress-text-back{width:100%;}.x-list-header{background:repeat-x 0 bottom;cursor:default;zoom:1;height:22px;}.x-list-header-inner div{display:block;float:left;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;}.x-list-header-inner div em{display:block;border-left:1px solid;padding:4px 4px;overflow:hidden;-moz-user-select:none;-khtml-user-select:none;line-height:14px;}.x-list-body{overflow:auto;overflow-x:hidden;overflow-y:auto;zoom:1;float:left;width:100%;}.x-list-body dl{zoom:1;}.x-list-body dt{display:block;float:left;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;zoom:1;}.x-list-body dt em{display:block;padding:3px 4px;overflow:hidden;-moz-user-select:none;-khtml-user-select:none;}.x-list-resizer{border-left:1px solid;border-right:1px solid;position:absolute;left:0;top:0;}.x-list-header-inner em.sort-asc{background:transparent no-repeat center 0;border-style:solid;border-width:0 1px 1px;padding-bottom:3px;}.x-list-header-inner em.sort-desc{background:transparent no-repeat center -23px;border-style:solid;border-width:0 1px 1px;padding-bottom:3px;}.x-slider{zoom:1;}.x-slider-inner{position:relative;left:0;top:0;overflow:visible;zoom:1;}.x-slider-focus{position:absolute;left:0;top:0;width:1px;height:1px;line-height:1px;font-size:1px;-moz-outline:0 none;outline:0 none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:ignore;display:block;overflow:hidden;}.x-slider-horz{padding-left:7px;background:transparent no-repeat 0 -22px;}.x-slider-horz .x-slider-end{padding-right:7px;zoom:1;background:transparent no-repeat right -44px;}.x-slider-horz .x-slider-inner{background:transparent repeat-x 0 0;height:22px;}.x-slider-horz .x-slider-thumb{width:14px;height:15px;position:absolute;left:0;top:3px;background:transparent no-repeat 0 0;}.x-slider-horz .x-slider-thumb-over{background-position:-14px -15px;}.x-slider-horz .x-slider-thumb-drag{background-position:-28px -30px;}.x-slider-vert{padding-top:7px;background:transparent no-repeat -44px 0;width:22px;}.x-slider-vert .x-slider-end{padding-bottom:7px;zoom:1;background:transparent no-repeat -22px bottom;}.x-slider-vert .x-slider-inner{background:transparent repeat-y 0 0;}.x-slider-vert .x-slider-thumb{width:15px;height:14px;position:absolute;left:3px;bottom:0;background:transparent no-repeat 0 0;}.x-slider-vert .x-slider-thumb-over{background-position:-15px -14px;}.x-slider-vert .x-slider-thumb-drag{background-position:-30px -28px;}.x-window-dlg .x-window-body{border:0 none!important;padding:5px 10px;overflow:hidden!important;}.x-window-dlg .x-window-mc{border:0 none!important;}.x-window-dlg .ext-mb-input{margin-top:4px;width:95%;}.x-window-dlg .ext-mb-textarea{margin-top:4px;}.x-window-dlg .x-progress-wrap{margin-top:4px;}.ext-ie .x-window-dlg .x-progress-wrap{margin-top:6px;}.x-window-dlg .x-msg-box-wait{background:transparent no-repeat left;display:block;width:300px;padding-left:18px;line-height:18px;}.x-window-dlg .ext-mb-icon{float:left;width:47px;height:32px;}.x-window-dlg .x-dlg-icon .ext-mb-content{zoom:1;margin-left:47px;}.x-window-dlg .ext-mb-info,.x-window-dlg .ext-mb-warning,.x-window-dlg .ext-mb-question,.x-window-dlg .ext-mb-error{background:transparent no-repeat top left;}.ext-gecko2 .ext-mb-fix-cursor{overflow:auto;}.ext-el-mask{background-color:#ccc;}.ext-el-mask-msg{border-color:#6593cf;background-color:#c3daf9;background-image:url(../images/default/box/tb-blue.gif);}.ext-el-mask-msg div{background-color:#eee;border-color:#a3bad9;color:#222;font:normal 11px tahoma,arial,helvetica,sans-serif;}.x-mask-loading div{background-color:#fbfbfb;background-image:url(../images/default/grid/loading.gif);}.x-item-disabled{color:gray;}.x-item-disabled *{color:gray!important;}.x-splitbar-proxy{background-color:#aaa;}.x-color-palette a{border-color:#fff;}.x-color-palette a:hover,.x-color-palette a.x-color-palette-sel{border-color:#8bb8f3;background-color:#deecfd;}.x-color-palette em{border-color:#aca899;}.x-ie-shadow{background-color:#777;}.x-shadow .xsmc{background-image:url(../images/default/shadow-c.png);}.x-shadow .xsml,.x-shadow .xsmr{background-image:url(../images/default/shadow-lr.png);}.x-shadow .xstl,.x-shadow .xstc,.x-shadow .xstr,.x-shadow .xsbl,.x-shadow .xsbc,.x-shadow .xsbr{background-image:url(../images/default/shadow.png);}.loading-indicator{font-size:11px;background-image:url(../images/default/grid/loading.gif);}.x-spotlight{background-color:#ccc;}.x-tab-panel-header,.x-tab-panel-footer{background-color:#deecfd;border-color:#8db2e3;overflow:hidden;zoom:1;}.x-tab-panel-header,.x-tab-panel-footer{border-color:#8db2e3;}ul.x-tab-strip-top{background-color:#cedff5;background-image:url(../images/default/tabs/tab-strip-bg.gif);border-bottom-color:#8db2e3;}ul.x-tab-strip-bottom{background-color:#cedff5;background-image:url(../images/default/tabs/tab-strip-btm-bg.gif);border-top-color:#8db2e3;}.x-tab-panel-header-plain .x-tab-strip-spacer,.x-tab-panel-footer-plain .x-tab-strip-spacer{border-color:#8db2e3;background-color:#deecfd;}.x-tab-strip span.x-tab-strip-text{font:normal 11px tahoma,arial,helvetica;color:#416aa3;}.x-tab-strip-over span.x-tab-strip-text{color:#15428b;}.x-tab-strip-active span.x-tab-strip-text{color:#15428b;font-weight:bold;}.x-tab-strip-disabled .x-tabs-text{color:#aaa;}.x-tab-strip-top .x-tab-right,.x-tab-strip-top .x-tab-left,.x-tab-strip-top .x-tab-strip-inner{background-image:url(../images/default/tabs/tabs-sprite.gif);}.x-tab-strip-bottom .x-tab-right{background-image:url(../images/default/tabs/tab-btm-inactive-right-bg.gif);}.x-tab-strip-bottom .x-tab-left{background-image:url(../images/default/tabs/tab-btm-inactive-left-bg.gif);}.x-tab-strip-bottom .x-tab-strip-over .x-tab-right{background-image:url(../images/default/tabs/tab-btm-over-right-bg.gif);}.x-tab-strip-bottom .x-tab-strip-over .x-tab-left{background-image:url(../images/default/tabs/tab-btm-over-left-bg.gif);}.x-tab-strip-bottom .x-tab-strip-active .x-tab-right{background-image:url(../images/default/tabs/tab-btm-right-bg.gif);}.x-tab-strip-bottom .x-tab-strip-active .x-tab-left{background-image:url(../images/default/tabs/tab-btm-left-bg.gif);}.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close{background-image:url(../images/default/tabs/tab-close.gif);}.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{background-image:url(../images/default/tabs/tab-close.gif);}.x-tab-panel-body{border-color:#8db2e3;background-color:#fff;}.x-tab-panel-body-top{border-top:0 none;}.x-tab-panel-body-bottom{border-bottom:0 none;}.x-tab-scroller-left{background-image:url(../images/default/tabs/scroll-left.gif);border-bottom-color:#8db2e3;}.x-tab-scroller-left-over{background-position:0 0;}.x-tab-scroller-left-disabled{background-position:-18px 0;opacity:.5;-moz-opacity:.5;filter:alpha(opacity=50);cursor:default;}.x-tab-scroller-right{background-image:url(../images/default/tabs/scroll-right.gif);border-bottom-color:#8db2e3;}.x-tab-panel-bbar .x-toolbar,.x-tab-panel-tbar .x-toolbar{border-color:#99bbe8;}.x-form-field{font:normal 12px tahoma,arial,helvetica,sans-serif;}.x-form-text,textarea.x-form-field{background-color:#fff;background-image:url(../images/default/form/text-bg.gif);border-color:#b5b8c8;}.x-form-select-one{background-color:#fff;border-color:#b5b8c8;}.x-form-check-group-label{border-bottom:1px solid #99bbe8;color:#15428b;}.x-editor .x-form-check-wrap{background-color:#fff;}.x-form-field-wrap .x-form-trigger{background-image:url(../images/default/form/trigger.gif);border-bottom-color:#b5b8c8;}.x-form-field-wrap .x-form-date-trigger{background-image:url(../images/default/form/date-trigger.gif);}.x-form-field-wrap .x-form-clear-trigger{background-image:url(../images/default/form/clear-trigger.gif);}.x-form-field-wrap .x-form-search-trigger{background-image:url(../images/default/form/search-trigger.gif);}.x-trigger-wrap-focus .x-form-trigger{border-bottom-color:#7eadd9;}.x-item-disabled .x-form-trigger-over{border-bottom-color:#b5b8c8;}.x-item-disabled .x-form-trigger-click{border-bottom-color:#b5b8c8;}.x-form-focus,textarea.x-form-focus{border-color:#7eadd9;}.x-form-invalid,textarea.x-form-invalid{background-color:#fff;background-image:url(../images/default/grid/invalid_line.gif);border-color:#c30;}.x-form-invalid.x-form-composite{border:0;background-image:none;}.x-form-invalid.x-form-composite .x-form-invalid{background-color:#fff;background-image:url(../images/default/grid/invalid_line.gif);border-color:#c30;}.x-form-inner-invalid,textarea.x-form-inner-invalid{background-color:#fff;background-image:url(../images/default/grid/invalid_line.gif);}.x-form-grow-sizer{font:normal 12px tahoma,arial,helvetica,sans-serif;}.x-form-item{font:normal 12px tahoma,arial,helvetica,sans-serif;}.x-form-invalid-msg{color:#c0272b;font:normal 11px tahoma,arial,helvetica,sans-serif;background-image:url(../images/default/shared/warning.gif);}.x-form-empty-field{color:gray;}.x-small-editor .x-form-field{font:normal 11px arial,tahoma,helvetica,sans-serif;}.ext-webkit .x-small-editor .x-form-field{font:normal 11px arial,tahoma,helvetica,sans-serif;}.x-form-invalid-icon{background-image:url(../images/default/form/exclamation.gif);}.x-fieldset{border-color:#b5b8c8;}.x-fieldset legend{font:bold 11px tahoma,arial,helvetica,sans-serif;color:#15428b;}.x-btn{font:normal 11px tahoma,verdana,helvetica;}.x-btn button{font:normal 11px arial,tahoma,verdana,helvetica;color:#333;}.x-btn em{font-style:normal;font-weight:normal;}.x-btn-tl,.x-btn-tr,.x-btn-tc,.x-btn-ml,.x-btn-mr,.x-btn-mc,.x-btn-bl,.x-btn-br,.x-btn-bc{background-image:url(../images/default/button/btn.gif);}.x-btn-click .x-btn-text,.x-btn-menu-active .x-btn-text,.x-btn-pressed .x-btn-text{color:#000;}.x-btn-disabled *{color:gray!important;}.x-btn-mc em.x-btn-arrow{background-image:url(../images/default/button/arrow.gif);}.x-btn-mc em.x-btn-split{background-image:url(../images/default/button/s-arrow.gif);}.x-btn-over .x-btn-mc em.x-btn-split,.x-btn-click .x-btn-mc em.x-btn-split,.x-btn-menu-active .x-btn-mc em.x-btn-split,.x-btn-pressed .x-btn-mc em.x-btn-split{background-image:url(../images/default/button/s-arrow-o.gif);}.x-btn-mc em.x-btn-arrow-bottom{background-image:url(../images/default/button/s-arrow-b-noline.gif);}.x-btn-mc em.x-btn-split-bottom{background-image:url(../images/default/button/s-arrow-b.gif);}.x-btn-over .x-btn-mc em.x-btn-split-bottom,.x-btn-click .x-btn-mc em.x-btn-split-bottom,.x-btn-menu-active .x-btn-mc em.x-btn-split-bottom,.x-btn-pressed .x-btn-mc em.x-btn-split-bottom{background-image:url(../images/default/button/s-arrow-bo.gif);}.x-btn-group-header{color:#3e6aaa;}.x-btn-group-tc{background-image:url(../images/default/button/group-tb.gif);}.x-btn-group-tl{background-image:url(../images/default/button/group-cs.gif);}.x-btn-group-tr{background-image:url(../images/default/button/group-cs.gif);}.x-btn-group-bc{background-image:url(../images/default/button/group-tb.gif);}.x-btn-group-bl{background-image:url(../images/default/button/group-cs.gif);}.x-btn-group-br{background-image:url(../images/default/button/group-cs.gif);}.x-btn-group-ml{background-image:url(../images/default/button/group-lr.gif);}.x-btn-group-mr{background-image:url(../images/default/button/group-lr.gif);}.x-btn-group-notitle .x-btn-group-tc{background-image:url(../images/default/button/group-tb.gif);}.x-toolbar{border-color:#a9bfd3;background-color:#d0def0;background-image:url(../images/default/toolbar/bg.gif);}.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{font:normal 11px arial,tahoma,helvetica,sans-serif;}.x-toolbar .x-item-disabled{color:gray;}.x-toolbar .x-item-disabled *{color:gray;}.x-toolbar .x-btn-mc em.x-btn-split{background-image:url(../images/default/button/s-arrow-noline.gif);}.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split,.x-toolbar .x-btn-click .x-btn-mc em.x-btn-split,.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split,.x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split{background-image:url(../images/default/button/s-arrow-o.gif);}.x-toolbar .x-btn-mc em.x-btn-split-bottom{background-image:url(../images/default/button/s-arrow-b-noline.gif);}.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split-bottom,.x-toolbar .x-btn-click .x-btn-mc em.x-btn-split-bottom,.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom,.x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split-bottom{background-image:url(../images/default/button/s-arrow-bo.gif);}.x-toolbar .xtb-sep{background-image:url(../images/default/grid/grid-blue-split.gif);}.x-tbar-page-first{background-image:url(../images/default/grid/page-first.gif)!important;}.x-tbar-loading{background-image:url(../images/default/grid/refresh.gif)!important;}.x-tbar-page-last{background-image:url(../images/default/grid/page-last.gif)!important;}.x-tbar-page-next{background-image:url(../images/default/grid/page-next.gif)!important;}.x-tbar-page-prev{background-image:url(../images/default/grid/page-prev.gif)!important;}.x-item-disabled .x-tbar-loading{background-image:url(../images/default/grid/refresh-disabled.gif)!important;}.x-item-disabled .x-tbar-page-first{background-image:url(../images/default/grid/page-first-disabled.gif)!important;}.x-item-disabled .x-tbar-page-last{background-image:url(../images/default/grid/page-last-disabled.gif)!important;}.x-item-disabled .x-tbar-page-next{background-image:url(../images/default/grid/page-next-disabled.gif)!important;}.x-item-disabled .x-tbar-page-prev{background-image:url(../images/default/grid/page-prev-disabled.gif)!important;}.x-paging-info{color:#444;}.x-toolbar-more-icon{background-image:url(../images/default/toolbar/more.gif)!important;}.x-resizable-handle{background-color:#fff;}.x-resizable-over .x-resizable-handle-east,.x-resizable-pinned .x-resizable-handle-east,.x-resizable-over .x-resizable-handle-west,.x-resizable-pinned .x-resizable-handle-west{background-image:url(../images/default/sizer/e-handle.gif);}.x-resizable-over .x-resizable-handle-south,.x-resizable-pinned .x-resizable-handle-south,.x-resizable-over .x-resizable-handle-north,.x-resizable-pinned .x-resizable-handle-north{background-image:url(../images/default/sizer/s-handle.gif);}.x-resizable-over .x-resizable-handle-north,.x-resizable-pinned .x-resizable-handle-north{background-image:url(../images/default/sizer/s-handle.gif);}.x-resizable-over .x-resizable-handle-southeast,.x-resizable-pinned .x-resizable-handle-southeast{background-image:url(../images/default/sizer/se-handle.gif);}.x-resizable-over .x-resizable-handle-northwest,.x-resizable-pinned .x-resizable-handle-northwest{background-image:url(../images/default/sizer/nw-handle.gif);}.x-resizable-over .x-resizable-handle-northeast,.x-resizable-pinned .x-resizable-handle-northeast{background-image:url(../images/default/sizer/ne-handle.gif);}.x-resizable-over .x-resizable-handle-southwest,.x-resizable-pinned .x-resizable-handle-southwest{background-image:url(../images/default/sizer/sw-handle.gif);}.x-resizable-proxy{border-color:#3b5a82;}.x-resizable-overlay{background-color:#fff;}.x-grid3{background-color:#fff;}.x-grid-panel .x-panel-mc .x-panel-body{border-color:#99bbe8;}.x-grid3-row td,.x-grid3-summary-row td{font:normal 11px/13px arial,tahoma,helvetica,sans-serif;}.x-grid3-hd-row td{font:normal 11px/15px arial,tahoma,helvetica,sans-serif;}.x-grid3-hd-row td{border-left-color:#eee;border-right-color:#d0d0d0;}.x-grid-row-loading{background-color:#fff;background-image:url(../images/default/shared/loading-balls.gif);}.x-grid3-row{border-color:#ededed;border-top-color:#fff;}.x-grid3-row-alt{background-color:#fafafa;}.x-grid3-row-over{border-color:#ddd;background-color:#efefef;background-image:url(../images/default/grid/row-over.gif);}.x-grid3-resize-proxy{background-color:#777;}.x-grid3-resize-marker{background-color:#777;}.x-grid3-header{background-color:#f9f9f9;background-image:url(../images/default/grid/grid3-hrow.gif);}.x-grid3-header-pop{border-left-color:#d0d0d0;}.x-grid3-header-pop-inner{border-left-color:#eee;background-image:url(../images/default/grid/hd-pop.gif);}td.x-grid3-hd-over,td.sort-desc,td.sort-asc,td.x-grid3-hd-menu-open{border-left-color:#aaccf6;border-right-color:#aaccf6;}td.x-grid3-hd-over .x-grid3-hd-inner,td.sort-desc .x-grid3-hd-inner,td.sort-asc .x-grid3-hd-inner,td.x-grid3-hd-menu-open .x-grid3-hd-inner{background-color:#ebf3fd;background-image:url(../images/default/grid/grid3-hrow-over.gif);}.sort-asc .x-grid3-sort-icon{background-image:url(../images/default/grid/sort_asc.gif);}.sort-desc .x-grid3-sort-icon{background-image:url(../images/default/grid/sort_desc.gif);}.x-grid3-cell-text,.x-grid3-hd-text{color:#000;}.x-grid3-split{background-image:url(../images/default/grid/grid-split.gif);}.x-grid3-hd-text{color:#15428b;}.x-dd-drag-proxy .x-grid3-hd-inner{background-color:#ebf3fd;background-image:url(../images/default/grid/grid3-hrow-over.gif);border-color:#aaccf6;}.col-move-top{background-image:url(../images/default/grid/col-move-top.gif);}.col-move-bottom{background-image:url(../images/default/grid/col-move-bottom.gif);}td.grid-hd-group-cell{background:url(../images/default/grid/grid3-hrow.gif) repeat-x bottom;}.x-grid3-row-selected{background-color:#dfe8f6!important;background-image:none;border-color:#a3bae9;}.x-grid3-cell-selected{background-color:#b8cfee!important;color:#000;}.x-grid3-cell-selected span{color:#000!important;}.x-grid3-cell-selected .x-grid3-cell-text{color:#000;}.x-grid3-locked td.x-grid3-row-marker,.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker{background-color:#ebeadb!important;background-image:url(../images/default/grid/grid-hrow.gif)!important;color:#000;border-top-color:#fff;border-right-color:#6fa0df!important;}.x-grid3-locked td.x-grid3-row-marker div,.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div{color:#15428b!important;}.x-grid3-dirty-cell{background-image:url(../images/default/grid/dirty.gif);}.x-grid3-topbar,.x-grid3-bottombar{font:normal 11px arial,tahoma,helvetica,sans-serif;}.x-grid3-bottombar .x-toolbar{border-top-color:#a9bfd3;}.x-props-grid .x-grid3-td-name .x-grid3-cell-inner{background-image:url(../images/default/grid/grid3-special-col-bg.gif)!important;color:#000!important;}.x-props-grid .x-grid3-body .x-grid3-td-name{background-color:#fff!important;border-right-color:#eee;}.xg-hmenu-sort-asc .x-menu-item-icon{background-image:url(../images/default/grid/hmenu-asc.gif);}.xg-hmenu-sort-desc .x-menu-item-icon{background-image:url(../images/default/grid/hmenu-desc.gif);}.xg-hmenu-lock .x-menu-item-icon{background-image:url(../images/default/grid/hmenu-lock.gif);}.xg-hmenu-unlock .x-menu-item-icon{background-image:url(../images/default/grid/hmenu-unlock.gif);}.x-grid3-hd-btn{background-color:#c3daf9;background-image:url(../images/default/grid/grid3-hd-btn.gif);}.x-grid3-body .x-grid3-td-expander{background-image:url(../images/default/grid/grid3-special-col-bg.gif);}.x-grid3-row-expander{background-image:url(../images/default/grid/row-expand-sprite.gif);}.x-grid3-body .x-grid3-td-checker{background-image:url(../images/default/grid/grid3-special-col-bg.gif);}.x-grid3-row-checker,.x-grid3-hd-checker{background-image:url(../images/default/grid/row-check-sprite.gif);}.x-grid3-body .x-grid3-td-numberer{background-image:url(../images/default/grid/grid3-special-col-bg.gif);}.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner{color:#444;}.x-grid3-body .x-grid3-td-row-icon{background-image:url(../images/default/grid/grid3-special-col-bg.gif);}.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander{background-image:url(../images/default/grid/grid3-special-col-sel-bg.gif);}.x-grid3-check-col{background-image:url(../images/default/menu/unchecked.gif);}.x-grid3-check-col-on{background-image:url(../images/default/menu/checked.gif);}.x-grid-group,.x-grid-group-body,.x-grid-group-hd{zoom:1;}.x-grid-group-hd{border-bottom-color:#99bbe8;}.x-grid-group-hd div.x-grid-group-title{background-image:url(../images/default/grid/group-collapse.gif);color:#3764a0;font:bold 11px tahoma,arial,helvetica,sans-serif;}.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title{background-image:url(../images/default/grid/group-expand.gif);}.x-group-by-icon{background-image:url(../images/default/grid/group-by.gif);}.x-cols-icon{background-image:url(../images/default/grid/columns.gif);}.x-show-groups-icon{background-image:url(../images/default/grid/group-by.gif);}.x-grid-empty{color:gray;font:normal 11px tahoma,arial,helvetica,sans-serif;}.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell{border-right-color:#ededed;}.x-grid-with-col-lines .x-grid3-row-selected{border-top-color:#a3bae9;}.x-pivotgrid .x-grid3-header-offset table td{background:url(../images/default/grid/grid3-hrow.gif) repeat-x 50% 100%;border-left:1px solid;border-right:1px solid;border-left-color:#EEE;border-right-color:#d0d0d0;}.x-pivotgrid .x-grid3-row-headers{background-color:#f9f9f9;}.x-pivotgrid .x-grid3-row-headers table td{background:#EEE url(../images/default/grid/grid3-rowheader.gif) repeat-x left top;border-left:1px solid;border-right:1px solid;border-left-color:#EEE;border-right-color:#d0d0d0;border-bottom:1px solid;border-bottom-color:#d0d0d0;height:18px;}.x-dd-drag-ghost{color:#000;font:normal 11px arial,helvetica,sans-serif;border-color:#ddd #bbb #bbb #ddd;background-color:#fff;}.x-dd-drop-nodrop .x-dd-drop-icon{background-image:url(../images/default/dd/drop-no.gif);}.x-dd-drop-ok .x-dd-drop-icon{background-image:url(../images/default/dd/drop-yes.gif);}.x-dd-drop-ok-add .x-dd-drop-icon{background-image:url(../images/default/dd/drop-add.gif);}.x-view-selector{background-color:#c3daf9;border-color:#39b;}.x-tree-node-expanded .x-tree-node-icon{background-image:url(../images/default/tree/folder-open.gif);}.x-tree-node-leaf .x-tree-node-icon{background-image:url(../images/default/tree/leaf.gif);}.x-tree-node-collapsed .x-tree-node-icon{background-image:url(../images/default/tree/folder.gif);}.x-tree-node-loading .x-tree-node-icon{background-image:url(../images/default/tree/loading.gif)!important;}.x-tree-node .x-tree-node-inline-icon{background-image:none;}.x-tree-node-loading a span{font-style:italic;color:#444;}.x-tree-lines .x-tree-elbow{background-image:url(../images/default/tree/elbow.gif);}.x-tree-lines .x-tree-elbow-plus{background-image:url(../images/default/tree/elbow-plus.gif);}.x-tree-lines .x-tree-elbow-minus{background-image:url(../images/default/tree/elbow-minus.gif);}.x-tree-lines .x-tree-elbow-end{background-image:url(../images/default/tree/elbow-end.gif);}.x-tree-lines .x-tree-elbow-end-plus{background-image:url(../images/default/tree/elbow-end-plus.gif);}.x-tree-lines .x-tree-elbow-end-minus{background-image:url(../images/default/tree/elbow-end-minus.gif);}.x-tree-lines .x-tree-elbow-line{background-image:url(../images/default/tree/elbow-line.gif);}.x-tree-no-lines .x-tree-elbow-plus{background-image:url(../images/default/tree/elbow-plus-nl.gif);}.x-tree-no-lines .x-tree-elbow-minus{background-image:url(../images/default/tree/elbow-minus-nl.gif);}.x-tree-no-lines .x-tree-elbow-end-plus{background-image:url(../images/default/tree/elbow-end-plus-nl.gif);}.x-tree-no-lines .x-tree-elbow-end-minus{background-image:url(../images/default/tree/elbow-end-minus-nl.gif);}.x-tree-arrows .x-tree-elbow-plus{background-image:url(../images/default/tree/arrows.gif);}.x-tree-arrows .x-tree-elbow-minus{background-image:url(../images/default/tree/arrows.gif);}.x-tree-arrows .x-tree-elbow-end-plus{background-image:url(../images/default/tree/arrows.gif);}.x-tree-arrows .x-tree-elbow-end-minus{background-image:url(../images/default/tree/arrows.gif);}.x-tree-node{color:#000;font:normal 11px arial,tahoma,helvetica,sans-serif;}.x-tree-node a,.x-dd-drag-ghost a{color:#000;}.x-tree-node a span,.x-dd-drag-ghost a span{color:#000;}.x-tree-node .x-tree-node-disabled a span{color:gray!important;}.x-tree-node div.x-tree-drag-insert-below{border-bottom-color:#36c;}.x-tree-node div.x-tree-drag-insert-above{border-top-color:#36c;}.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a{border-bottom-color:#36c;}.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{border-top-color:#36c;}.x-tree-node .x-tree-drag-append a span{background-color:#ddd;border-color:gray;}.x-tree-node .x-tree-node-over{background-color:#eee;}.x-tree-node .x-tree-selected{background-color:#d9e8fb;}.x-tree-drop-ok-append .x-dd-drop-icon{background-image:url(../images/default/tree/drop-add.gif);}.x-tree-drop-ok-above .x-dd-drop-icon{background-image:url(../images/default/tree/drop-over.gif);}.x-tree-drop-ok-below .x-dd-drop-icon{background-image:url(../images/default/tree/drop-under.gif);}.x-tree-drop-ok-between .x-dd-drop-icon{background-image:url(../images/default/tree/drop-between.gif);}.x-date-picker{border-color:#1b376c;background-color:#fff;}.x-date-middle,.x-date-left,.x-date-right{background-image:url(../images/default/shared/hd-sprite.gif);color:#fff;font:bold 11px "sans serif",tahoma,verdana,helvetica;}.x-date-middle .x-btn .x-btn-text{color:#fff;}.x-date-middle .x-btn-mc em.x-btn-arrow{background-image:url(../images/default/toolbar/btn-arrow-light.gif);}.x-date-right a{background-image:url(../images/default/shared/right-btn.gif);}.x-date-left a{background-image:url(../images/default/shared/left-btn.gif);}.x-date-inner th{background-color:#dfecfb;background-image:url(../images/default/shared/glass-bg.gif);border-bottom-color:#a3bad9;font:normal 10px arial,helvetica,tahoma,sans-serif;color:#233d6d;}.x-date-inner td{border-color:#fff;}.x-date-inner a{font:normal 11px arial,helvetica,tahoma,sans-serif;color:#000;}.x-date-inner .x-date-active{color:#000;}.x-date-inner .x-date-selected a{background-color:#dfecfb;background-image:url(../images/default/shared/glass-bg.gif);border-color:#8db2e3;}.x-date-inner .x-date-today a{border-color:darkred;}.x-date-inner .x-date-selected span{font-weight:bold;}.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a{color:#aaa;}.x-date-bottom{border-top-color:#a3bad9;background-color:#dfecfb;background-image:url(../images/default/shared/glass-bg.gif);}.x-date-inner a:hover,.x-date-inner .x-date-disabled a:hover{color:#000;background-color:#ddecfe;}.x-date-inner .x-date-disabled a{background-color:#eee;color:#bbb;}.x-date-mmenu{background-color:#eee!important;}.x-date-mmenu .x-menu-item{font-size:10px;color:#000;}.x-date-mp{background-color:#fff;}.x-date-mp td{font:normal 11px arial,helvetica,tahoma,sans-serif;}.x-date-mp-btns button{background-color:#083772;color:#fff;border-color:#36c #005 #005 #36c;font:normal 11px arial,helvetica,tahoma,sans-serif;}.x-date-mp-btns{background-color:#dfecfb;background-image:url(../images/default/shared/glass-bg.gif);}.x-date-mp-btns td{border-top-color:#c5d2df;}td.x-date-mp-month a,td.x-date-mp-year a{color:#15428b;}td.x-date-mp-month a:hover,td.x-date-mp-year a:hover{color:#15428b;background-color:#ddecfe;}td.x-date-mp-sel a{background-color:#dfecfb;background-image:url(../images/default/shared/glass-bg.gif);border-color:#8db2e3;}.x-date-mp-ybtn a{background-image:url(../images/default/panel/tool-sprites.gif);}td.x-date-mp-sep{border-right-color:#c5d2df;}.x-tip .x-tip-close{background-image:url(../images/default/qtip/close.gif);}.x-tip .x-tip-tc,.x-tip .x-tip-tl,.x-tip .x-tip-tr,.x-tip .x-tip-bc,.x-tip .x-tip-bl,.x-tip .x-tip-br,.x-tip .x-tip-ml,.x-tip .x-tip-mr{background-image:url(../images/default/qtip/tip-sprite.gif);}.x-tip .x-tip-mc{font:normal 11px tahoma,arial,helvetica,sans-serif;}.x-tip .x-tip-ml{background-color:#fff;}.x-tip .x-tip-header-text{font:bold 11px tahoma,arial,helvetica,sans-serif;color:#444;}.x-tip .x-tip-body{font:normal 11px tahoma,arial,helvetica,sans-serif;color:#444;}.x-form-invalid-tip .x-tip-tc,.x-form-invalid-tip .x-tip-tl,.x-form-invalid-tip .x-tip-tr,.x-form-invalid-tip .x-tip-bc,.x-form-invalid-tip .x-tip-bl,.x-form-invalid-tip .x-tip-br,.x-form-invalid-tip .x-tip-ml,.x-form-invalid-tip .x-tip-mr{background-image:url(../images/default/form/error-tip-corners.gif);}.x-form-invalid-tip .x-tip-body{background-image:url(../images/default/form/exclamation.gif);}.x-tip-anchor{background-image:url(../images/default/qtip/tip-anchor-sprite.gif);}.x-menu{background-color:#f0f0f0;background-image:url(../images/default/menu/menu.gif);}.x-menu-floating{border-color:#718bb7;}.x-menu-nosep{background-image:none;}.x-menu-list-item{font:normal 11px arial,tahoma,sans-serif;}.x-menu-item-arrow{background-image:url(../images/default/menu/menu-parent.gif);}.x-menu-sep{background-color:#e0e0e0;border-bottom-color:#fff;}a.x-menu-item{color:#222;}.x-menu-item-active{background-image:url(../images/default/menu/item-over.gif);background-color:#dbecf4;border-color:#aaccf6;}.x-menu-item-active a.x-menu-item{border-color:#aaccf6;}.x-menu-check-item .x-menu-item-icon{background-image:url(../images/default/menu/unchecked.gif);}.x-menu-item-checked .x-menu-item-icon{background-image:url(../images/default/menu/checked.gif);}.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{background-image:url(../images/default/menu/group-checked.gif);}.x-menu-group-item .x-menu-item-icon{background-image:none;}.x-menu-plain{background-color:#f0f0f0!important;background-image:none;}.x-date-menu,.x-color-menu{background-color:#fff!important;}.x-menu .x-date-picker{border-color:#a3bad9;}.x-cycle-menu .x-menu-item-checked{border-color:#a3bae9!important;background-color:#def8f6;}.x-menu-scroller-top{background-image:url(../images/default/layout/mini-top.gif);}.x-menu-scroller-bottom{background-image:url(../images/default/layout/mini-bottom.gif);}.x-box-tl{background-image:url(../images/default/box/corners.gif);}.x-box-tc{background-image:url(../images/default/box/tb.gif);}.x-box-tr{background-image:url(../images/default/box/corners.gif);}.x-box-ml{background-image:url(../images/default/box/l.gif);}.x-box-mc{background-color:#eee;background-image:url(../images/default/box/tb.gif);font-family:"Myriad Pro","Myriad Web","Tahoma","Helvetica","Arial",sans-serif;color:#393939;font-size:12px;}.x-box-mc h3{font-size:14px;font-weight:bold;}.x-box-mr{background-image:url(../images/default/box/r.gif);}.x-box-bl{background-image:url(../images/default/box/corners.gif);}.x-box-bc{background-image:url(../images/default/box/tb.gif);}.x-box-br{background-image:url(../images/default/box/corners.gif);}.x-box-blue .x-box-bl,.x-box-blue .x-box-br,.x-box-blue .x-box-tl,.x-box-blue .x-box-tr{background-image:url(../images/default/box/corners-blue.gif);}.x-box-blue .x-box-bc,.x-box-blue .x-box-mc,.x-box-blue .x-box-tc{background-image:url(../images/default/box/tb-blue.gif);}.x-box-blue .x-box-mc{background-color:#c3daf9;}.x-box-blue .x-box-mc h3{color:#17385b;}.x-box-blue .x-box-ml{background-image:url(../images/default/box/l-blue.gif);}.x-box-blue .x-box-mr{background-image:url(../images/default/box/r-blue.gif);}.x-combo-list{border-color:#98c0f4;background-color:#ddecfe;font:normal 12px tahoma,arial,helvetica,sans-serif;}.x-combo-list-inner{background-color:#fff;}.x-combo-list-hd{font:bold 11px tahoma,arial,helvetica,sans-serif;color:#15428b;background-image:url(../images/default/layout/panel-title-light-bg.gif);border-bottom-color:#98c0f4;}.x-resizable-pinned .x-combo-list-inner{border-bottom-color:#98c0f4;}.x-combo-list-item{border-color:#fff;}.x-combo-list .x-combo-selected{border-color:#a3bae9!important;background-color:#dfe8f6;}.x-combo-list .x-toolbar{border-top-color:#98c0f4;}.x-combo-list-small{font:normal 11px tahoma,arial,helvetica,sans-serif;}.x-panel{border-color:#99bbe8;}.x-panel-header{color:#15428b;font-weight:bold;font-size:11px;font-family:tahoma,arial,verdana,sans-serif;border-color:#99bbe8;background-image:url(../images/default/panel/white-top-bottom.gif);}.x-panel-body{border-color:#99bbe8;background-color:#fff;}.x-panel-bbar .x-toolbar,.x-panel-tbar .x-toolbar{border-color:#99bbe8;}.x-panel-tbar-noheader .x-toolbar,.x-panel-mc .x-panel-tbar .x-toolbar{border-top-color:#99bbe8;}.x-panel-body-noheader,.x-panel-mc .x-panel-body{border-top-color:#99bbe8;}.x-panel-tl .x-panel-header{color:#15428b;font:bold 11px tahoma,arial,verdana,sans-serif;}.x-panel-tc{background-image:url(../images/default/panel/top-bottom.gif);}.x-panel-tl,.x-panel-tr,.x-panel-bl,.x-panel-br{background-image:url(../images/default/panel/corners-sprite.gif);border-bottom-color:#99bbe8;}.x-panel-bc{background-image:url(../images/default/panel/top-bottom.gif);}.x-panel-mc{font:normal 11px tahoma,arial,helvetica,sans-serif;background-color:#dfe8f6;}.x-panel-ml{background-color:#fff;background-image:url(../images/default/panel/left-right.gif);}.x-panel-mr{background-image:url(../images/default/panel/left-right.gif);}.x-tool{background-image:url(../images/default/panel/tool-sprites.gif);}.x-panel-ghost{background-color:#cbddf3;}.x-panel-ghost ul{border-color:#99bbe8;}.x-panel-dd-spacer{border-color:#99bbe8;}.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{font:normal 11px arial,tahoma,helvetica,sans-serif;}.x-window-proxy{background-color:#c7dffc;border-color:#99bbe8;}.x-window-tl .x-window-header{color:#15428b;font:bold 11px tahoma,arial,verdana,sans-serif;}.x-window-tc{background-image:url(../images/default/window/top-bottom.png);}.x-window-tl{background-image:url(../images/default/window/left-corners.png);}.x-window-tr{background-image:url(../images/default/window/right-corners.png);}.x-window-bc{background-image:url(../images/default/window/top-bottom.png);}.x-window-bl{background-image:url(../images/default/window/left-corners.png);}.x-window-br{background-image:url(../images/default/window/right-corners.png);}.x-window-mc{border-color:#99bbe8;font:normal 11px tahoma,arial,helvetica,sans-serif;background-color:#dfe8f6;}.x-window-ml{background-image:url(../images/default/window/left-right.png);}.x-window-mr{background-image:url(../images/default/window/left-right.png);}.x-window-maximized .x-window-tc{background-color:#fff;}.x-window-bbar .x-toolbar{border-top-color:#99bbe8;}.x-panel-ghost .x-window-tl{border-bottom-color:#99bbe8;}.x-panel-collapsed .x-window-tl{border-bottom-color:#84a0c4;}.x-dlg-mask{background-color:#ccc;}.x-window-plain .x-window-mc{background-color:#ccd9e8;border-color:#a3bae9 #dfe8f6 #dfe8f6 #a3bae9;}.x-window-plain .x-window-body{border-color:#dfe8f6 #a3bae9 #a3bae9 #dfe8f6;}body.x-body-masked .x-window-plain .x-window-mc{background-color:#ccd9e8;}.x-html-editor-wrap{border-color:#a9bfd3;background-color:#fff;}.x-html-editor-tb .x-btn-text{background-image:url(../images/default/editor/tb-sprite.gif);}.x-panel-noborder .x-panel-header-noborder{border-bottom-color:#99bbe8;}.x-panel-noborder .x-panel-tbar-noborder .x-toolbar{border-bottom-color:#99bbe8;}.x-panel-noborder .x-panel-bbar-noborder .x-toolbar{border-top-color:#99bbe8;}.x-tab-panel-bbar-noborder .x-toolbar{border-top-color:#99bbe8;}.x-tab-panel-tbar-noborder .x-toolbar{border-bottom-color:#99bbe8;}.x-border-layout-ct{background-color:#dfe8f6;}.x-accordion-hd{color:#222;font-weight:normal;background-image:url(../images/default/panel/light-hd.gif);}.x-layout-collapsed{background-color:#d2e0f2;border-color:#98c0f4;}.x-layout-collapsed-over{background-color:#d9e8fb;}.x-layout-split-west .x-layout-mini{background-image:url(../images/default/layout/mini-left.gif);}.x-layout-split-east .x-layout-mini{background-image:url(../images/default/layout/mini-right.gif);}.x-layout-split-north .x-layout-mini{background-image:url(../images/default/layout/mini-top.gif);}.x-layout-split-south .x-layout-mini{background-image:url(../images/default/layout/mini-bottom.gif);}.x-layout-cmini-west .x-layout-mini{background-image:url(../images/default/layout/mini-right.gif);}.x-layout-cmini-east .x-layout-mini{background-image:url(../images/default/layout/mini-left.gif);}.x-layout-cmini-north .x-layout-mini{background-image:url(../images/default/layout/mini-bottom.gif);}.x-layout-cmini-south .x-layout-mini{background-image:url(../images/default/layout/mini-top.gif);}.x-progress-wrap{border-color:#6593cf;}.x-progress-inner{background-color:#e0e8f3;background-image:url(../images/default/qtip/bg.gif);}.x-progress-bar{background-color:#9cbfee;background-image:url(../images/default/progress/progress-bg.gif);border-top-color:#d1e4fd;border-bottom-color:#7fa9e4;border-right-color:#7fa9e4;}.x-progress-text{font-size:11px;font-weight:bold;color:#fff;}.x-progress-text-back{color:#396095;}.x-list-header{background-color:#f9f9f9;background-image:url(../images/default/grid/grid3-hrow.gif);}.x-list-header-inner div em{border-left-color:#ddd;font:normal 11px arial,tahoma,helvetica,sans-serif;}.x-list-body dt em{font:normal 11px arial,tahoma,helvetica,sans-serif;}.x-list-over{background-color:#eee;}.x-list-selected{background-color:#dfe8f6;}.x-list-resizer{border-left-color:#555;border-right-color:#555;}.x-list-header-inner em.sort-asc,.x-list-header-inner em.sort-desc{background-image:url(../images/default/grid/sort-hd.gif);border-color:#99bbe8;}.x-slider-horz,.x-slider-horz .x-slider-end,.x-slider-horz .x-slider-inner{background-image:url(../images/default/slider/slider-bg.png);}.x-slider-horz .x-slider-thumb{background-image:url(../images/default/slider/slider-thumb.png);}.x-slider-vert,.x-slider-vert .x-slider-end,.x-slider-vert .x-slider-inner{background-image:url(../images/default/slider/slider-v-bg.png);}.x-slider-vert .x-slider-thumb{background-image:url(../images/default/slider/slider-v-thumb.png);}.x-window-dlg .ext-mb-text,.x-window-dlg .x-window-header-text{font-size:12px;}.x-window-dlg .ext-mb-textarea{font:normal 12px tahoma,arial,helvetica,sans-serif;}.x-window-dlg .x-msg-box-wait{background-image:url(../images/default/grid/loading.gif);}.x-window-dlg .ext-mb-info{background-image:url(../images/default/window/icon-info.gif);}.x-window-dlg .ext-mb-warning{background-image:url(../images/default/window/icon-warning.gif);}.x-window-dlg .ext-mb-question{background-image:url(../images/default/window/icon-question.gif);}.x-window-dlg .ext-mb-error{background-image:url(../images/default/window/icon-error.gif);}.ext-mac.ext-webkit .x-form-check-wrap{padding-left:1px;}.ext-strict .ext-webkit .x-small-editor .x-form-text{padding-top:1px;}.x-window-body{overflow:hidden;position:relative;} diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/css/style.css b/salt/idh/skins/http/opencanary/nasLogin/static/css/style.css new file mode 100644 index 000000000..b6f74eadb --- /dev/null +++ b/salt/idh/skins/http/opencanary/nasLogin/static/css/style.css @@ -0,0 +1 @@ +.syno-backup-repo-cloud-azure_blob{background-image:url("/webman/3rdparty/addon-azure_blob/images/icon.png") !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-backup-repo-cloud-azure_blob{background-image:url("/webman/3rdparty/addon-azure_blob/images/icon@2x.png") !important;background-size:32px 32px !important}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-backup-repo-cloud-azure_blob{background-image:url("/webman/3rdparty/addon-azure_blob/images/icon@2x.png") !important;background-size:32px 32px !important;outline:1px red dashed}}.syno-backup-task-cloud-azure_blob{background-image:url("/webman/3rdparty/addon-azure_blob/images/icon.png") !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-backup-task-cloud-azure_blob{background-image:url("/webman/3rdparty/addon-azure_blob/images/icon@2x.png") !important;background-size:32px 32px !important}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-backup-task-cloud-azure_blob{background-image:url("/webman/3rdparty/addon-azure_blob/images/icon@2x.png") !important;background-size:32px 32px !important;outline:1px red dashed}} diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/css/ux-all.css b/salt/idh/skins/http/opencanary/nasLogin/static/css/ux-all.css new file mode 100644 index 000000000..efd7a572a --- /dev/null +++ b/salt/idh/skins/http/opencanary/nasLogin/static/css/ux-all.css @@ -0,0 +1,11 @@ +.syno-ux-gridpanel div,.syno-ux-editorgridpanel div,.syno-ux-grid-hd-menu li.x-menu-list-item span,.syno-ux-editorgrid-hd-menu li.x-menu-list-item span,.syno-ux-groupcheck-menu li.x-menu-list-item span,.syno-ux-searchfield-menu li.x-menu-list-item span,.syno-ux-menu li.x-menu-list-item span,.syno-ux-schedule-menu li.x-menu-list-item span,.syno-ux-button-menu li.x-menu-list-item span,.syno-ux-textfield,.syno-ux-numberfield,.x-form-item .x-form-item-label.syno-ux-item-label,.syno-ux-triggerfield,.syno-ux-combobox,.syno-ux-colorfield,.syno-ux-schedulefield,.syno-ux-datefield,.syno-ux-timefield,.syno-ux-superboxselect,.syno-ux-checkbox-label,.syno-ux-displayfield.x-form-display-field,.syno-ux-button-grey.x-btn button,.syno-ux-button-grey.x-btn-over.x-btn button,.syno-ux-button-grey:hover.x-btn button,.syno-ux-button-grey.x-btn-click.x-btn button,.syno-ux-button-grey:active.x-btn button,.syno-ux-button-default.x-btn button,.syno-ux-button-default.x-btn-over.x-btn button,.syno-ux-button-default:hover.x-btn button,.syno-ux-button-default.x-btn-click.x-btn button,.syno-ux-button-default:active.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-right.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-left.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-middle.x-btn button,.syno-ux-modulelist .x-tree-node-leaf a span,.syno-ux-modulelist .syno-textfilter .x-form-field-wrap .syno-textfilter-text,.syno-ux-datefield-menu table.x-date-inner tbody tr td span,.syno-ux-datefield-menu .x-date-bottom .x-btn-noicon .x-btn-small button,.syno-ux-datefield-menu .x-date-bottom .x-btn-over.x-btn-noicon .x-btn-small button,.syno-ux-datefield-menu .x-date-bottom .x-btn-click.x-btn-noicon .x-btn-small button,.syno-ux-datefield-menu .x-date-mp tr td a,.syno-ux-datefield-menu .x-date-mp-btns button.x-date-mp-cancel,.syno-ux-datefield-menu .x-date-mp-btns button.x-date-mp-cancel:hover,.syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-text.x-form-text,.syno-ux-tab-panel .x-tab-strip-top li .x-tab-strip-text,.syno-ux-expandable-listview .item-summary .item-title,.syno-ux-treepanel .x-tree-node a span,.syno-ux-superboxselect-item,.syno-ux-combobox-list .x-combo-list-item,.syno-ux-textarea{color:#505a64}.x-item-disabled.x-form-text.syno-ux-textfield,.x-item-disabled.x-form-text.syno-ux-numberfield,.x-item-disabled .x-form-text.syno-ux-triggerfield,.x-item-disabled .x-form-text.syno-ux-combobox,.x-item-disabled .x-form-text.syno-ux-colorfield,.x-item-disabled .x-form-text.syno-ux-schedulefield,.x-item-disabled .x-form-text.syno-ux-datefield,.x-item-disabled .x-form-text.syno-ux-timefield,.x-item-disabled .x-form-text.syno-ux-superboxselect,.syno-ux-displayfield.x-form-display-field.x-item-disabled,.syno-ux-modulelist .syno-textfilter .x-form-field-wrap .syno-textfilter-text.x-form-empty-field,.syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-text.x-form-text.x-form-empty-field,.syno-ux-textfilter .x-form-field-wrap.x-item-disabled,.syno-ux-superboxselect-item.x-item-disabled,.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-disabled span,.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-prevday span,.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-nextday span,.syno-ux-textarea.x-item-disabled.x-form-field{color:#96a0aa}.syno-ux-grid-hd-menu li.x-menu-list-item.x-item-disabled span,.syno-ux-editorgrid-hd-menu li.x-menu-list-item.x-item-disabled span,.syno-ux-groupcheck-menu li.x-menu-list-item.x-item-disabled span,.syno-ux-searchfield-menu li.x-menu-list-item.x-item-disabled span,.syno-ux-menu li.x-menu-list-item.x-item-disabled span,.syno-ux-schedule-menu li.x-menu-list-item.x-item-disabled span,.syno-ux-button-menu li.x-menu-list-item.x-item-disabled span,.syno-ux-cb-disabled.syno-ux-checkbox-label,.syno-ux-button-grey.x-item-disabled.x-btn button,.syno-ux-button-default.x-item-disabled.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-right.x-item-disabled.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-left.x-item-disabled.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-middle.x-item-disabled.x-btn button,.syno-ux-modulelist .x-tree-node-leaf.x-tree-node-disabled a span,.syno-ux-tab-panel .x-tab-strip-top li.x-item-disabled .x-tab-strip-text{color:#96a0aa !important}.syno-ux-displayfield.x-form-display-field .syno-ux-note{color:#00a66e}.x-statusbar .syno-ux-statusbar-success{color:#1ca600}.x-statusbar .syno-ux-statusbar-error{color:#fa4b4b}.syno-ux-grid-mask-info,.x-panel .ext-el-mask-msg.syno-ux-mask-info,.x-panel .ext-el-mask-msg.syno-ux-grid-mask-info{margin:24px;padding:10px 20px 10px 80px;max-width:400px;min-height:48px;border:1px solid #BEC8D2;border-radius:6px;box-shadow:0px 1px 4px rgba(0,0,0,0.25);background-image:url("./images/Components/icon_information.png");background-position:20px 10px;background-repeat:no-repeat;cursor:default}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-grid-mask-info,.synohdpack .x-panel .ext-el-mask-msg.syno-ux-mask-info,.x-panel .synohdpack .ext-el-mask-msg.syno-ux-mask-info,.synohdpack .x-panel .ext-el-mask-msg.syno-ux-grid-mask-info,.x-panel .synohdpack .ext-el-mask-msg.syno-ux-grid-mask-info{background-image:url("../img/synohdpack/./images/Components/icon_information.png");background-size:48px 48px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-grid-mask-info,.synohdpackdebug .x-panel .ext-el-mask-msg.syno-ux-mask-info,.x-panel .synohdpackdebug .ext-el-mask-msg.syno-ux-mask-info,.synohdpackdebug .x-panel .ext-el-mask-msg.syno-ux-grid-mask-info,.x-panel .synohdpackdebug .ext-el-mask-msg.syno-ux-grid-mask-info{background-image:url("../img/synohdpack/./images/Components/icon_information.png");background-size:48px 48px;outline:1px green dashed}}.syno-ux-grid-mask-info div,.x-panel .ext-el-mask-msg.syno-ux-mask-info div,.x-panel .ext-el-mask-msg.syno-ux-grid-mask-info div{padding:0px;height:48px;display:table-cell;vertical-align:middle;word-wrap:break-word;cursor:default;font-size:13px}.syno-ux-grid-mask-info div a,.x-panel .ext-el-mask-msg.syno-ux-mask-info div a,.x-panel .ext-el-mask-msg.syno-ux-grid-mask-info div a{color:#0086e5;font-weight:bold}.syno-ux-gridpanel div,.syno-ux-editorgridpanel div{font-size:12px}.syno-ux-gridpanel .x-panel-ml,.syno-ux-editorgridpanel .x-panel-ml,.syno-ux-gridpanel .x-panel-mr,.syno-ux-editorgridpanel .x-panel-mr{background-image:none;padding:0px}.syno-ux-gridpanel .x-panel-mc,.syno-ux-editorgridpanel .x-panel-mc{padding:0px}.syno-ux-gridpanel .x-panel-tl,.syno-ux-editorgridpanel .x-panel-tl{border:0px}.syno-ux-gridpanel .x-panel-header,.syno-ux-editorgridpanel .x-panel-header{border-bottom:0px dashed transparent !important;margin-bottom:0px !important}.syno-ux-gridpanel .x-panel-tbar .x-toolbar-layout-ct,.syno-ux-editorgridpanel .x-panel-tbar .x-toolbar-layout-ct,.syno-ux-gridpanel .x-panel-tbar-noheader .x-toolbar-layout-ct,.syno-ux-editorgridpanel .x-panel-tbar-noheader .x-toolbar-layout-ct,.syno-ux-gridpanel .x-panel-tbar-noborder .x-toolbar-layout-ct,.syno-ux-editorgridpanel .x-panel-tbar-noborder .x-toolbar-layout-ct{padding:0px 0px 8px 0px;padding-bottom:8px;background-image:none;background-color:transparent;border:0px}.x-grid-panel.syno-ux-gridpanel .x-panel-bwrap,.x-grid-panel.syno-ux-editorgridpanel .x-panel-bwrap{padding-bottom:12px}.x-grid-panel.syno-ux-gridpanel .x-panel-bwrap .x-panel-body,.x-grid-panel.syno-ux-editorgridpanel .x-panel-bwrap .x-panel-body{border:0px}.x-grid-panel.syno-ux-gridpanel .x-panel-bwrap .x-panel-body .x-grid3-scroller,.x-grid-panel.syno-ux-editorgridpanel .x-panel-bwrap .x-panel-body .x-grid3-scroller{padding-right:10px}.x-grid-panel.syno-ux-gridpanel .x-panel-bwrap .x-panel-body .x-grid3,.x-grid-panel.syno-ux-editorgridpanel .x-panel-bwrap .x-panel-body .x-grid3{background-color:transparent;border-top:solid 1px #D7E1EB}.syno-ux-gridpanel .x-grid3-header,.syno-ux-editorgridpanel .x-grid3-header{background-image:none;background-color:transparent;border-bottom:solid 1px #EBF0F5;padding-top:0px;height:26px}.syno-ux-gridpanel .x-grid3-hd,.syno-ux-editorgridpanel .x-grid3-hd{height:26px;border-left:0px;border-right:solid 1px #E1EBF5}.syno-ux-gridpanel .x-grid3-hd .x-grid3-hd-inner,.syno-ux-editorgridpanel .x-grid3-hd .x-grid3-hd-inner{height:26px;line-height:26px;color:#0086e5;background-color:transparent;padding:0 8px}.syno-ux-gridpanel .x-grid3-hd.x-grid3-hd-over .x-grid3-hd-inner,.syno-ux-editorgridpanel .x-grid3-hd.x-grid3-hd-over .x-grid3-hd-inner,.syno-ux-gridpanel .x-grid3-hd.x-grid3-hd-menu-open .x-grid3-hd-inner,.syno-ux-editorgridpanel .x-grid3-hd.x-grid3-hd-menu-open .x-grid3-hd-inner{background-image:none;background-color:transparent}.syno-ux-gridpanel .x-grid3-hd.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-hd-btn,.syno-ux-editorgridpanel .x-grid3-hd.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-hd-btn,.syno-ux-gridpanel .x-grid3-hd.x-grid3-hd-menu-open .x-grid3-hd-inner .x-grid3-hd-btn,.syno-ux-editorgridpanel .x-grid3-hd.x-grid3-hd-menu-open .x-grid3-hd-inner .x-grid3-hd-btn{background-color:transparent;background-image:url("images/Components/trigger.png");background-repeat:no-repeat;background-position:-26px 0px;width:26px;height:26px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-gridpanel .x-grid3-hd.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-hd-btn,.synohdpack .syno-ux-editorgridpanel .x-grid3-hd.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-hd-btn,.synohdpack .syno-ux-gridpanel .x-grid3-hd.x-grid3-hd-menu-open .x-grid3-hd-inner .x-grid3-hd-btn,.synohdpack .syno-ux-editorgridpanel .x-grid3-hd.x-grid3-hd-menu-open .x-grid3-hd-inner .x-grid3-hd-btn{background-image:url("../img/synohdpack/images/Components/trigger.png");background-size:104px 28px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-gridpanel .x-grid3-hd.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-hd-btn,.synohdpackdebug .syno-ux-editorgridpanel .x-grid3-hd.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-hd-btn,.synohdpackdebug .syno-ux-gridpanel .x-grid3-hd.x-grid3-hd-menu-open .x-grid3-hd-inner .x-grid3-hd-btn,.synohdpackdebug .syno-ux-editorgridpanel .x-grid3-hd.x-grid3-hd-menu-open .x-grid3-hd-inner .x-grid3-hd-btn{background-image:url("../img/synohdpack/images/Components/trigger.png");background-size:104px 28px;outline:1px green dashed}}.syno-ux-gridpanel .x-grid3-hd.sort-desc .x-grid3-hd-inner,.syno-ux-editorgridpanel .x-grid3-hd.sort-desc .x-grid3-hd-inner,.syno-ux-gridpanel .x-grid3-hd.sort-asc .x-grid3-hd-inner,.syno-ux-editorgridpanel .x-grid3-hd.sort-asc .x-grid3-hd-inner{background-image:none;background-color:transparent}.syno-ux-gridpanel .x-grid3-hd.sort-desc .x-grid3-hd-inner .x-grid3-sort-icon,.syno-ux-editorgridpanel .x-grid3-hd.sort-desc .x-grid3-hd-inner .x-grid3-sort-icon,.syno-ux-gridpanel .x-grid3-hd.sort-asc .x-grid3-hd-inner .x-grid3-sort-icon,.syno-ux-editorgridpanel .x-grid3-hd.sort-asc .x-grid3-hd-inner .x-grid3-sort-icon{background-color:transparent;background-image:url("images/Components/bt_grid_dropdown.png");background-repeat:no-repeat;margin-left:4px;width:6px;height:26px;vertical-align:top}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-gridpanel .x-grid3-hd.sort-desc .x-grid3-hd-inner .x-grid3-sort-icon,.synohdpack .syno-ux-editorgridpanel .x-grid3-hd.sort-desc .x-grid3-hd-inner .x-grid3-sort-icon,.synohdpack .syno-ux-gridpanel .x-grid3-hd.sort-asc .x-grid3-hd-inner .x-grid3-sort-icon,.synohdpack .syno-ux-editorgridpanel .x-grid3-hd.sort-asc .x-grid3-hd-inner .x-grid3-sort-icon{background-image:url("../img/synohdpack/images/Components/bt_grid_dropdown.png");background-size:6px 168px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-gridpanel .x-grid3-hd.sort-desc .x-grid3-hd-inner .x-grid3-sort-icon,.synohdpackdebug .syno-ux-editorgridpanel .x-grid3-hd.sort-desc .x-grid3-hd-inner .x-grid3-sort-icon,.synohdpackdebug .syno-ux-gridpanel .x-grid3-hd.sort-asc .x-grid3-hd-inner .x-grid3-sort-icon,.synohdpackdebug .syno-ux-editorgridpanel .x-grid3-hd.sort-asc .x-grid3-hd-inner .x-grid3-sort-icon{background-image:url("../img/synohdpack/images/Components/bt_grid_dropdown.png");background-size:6px 168px;outline:1px green dashed}}.syno-ux-gridpanel .x-grid3-hd.sort-desc .x-grid3-hd-inner .x-grid3-sort-icon,.syno-ux-editorgridpanel .x-grid3-hd.sort-desc .x-grid3-hd-inner .x-grid3-sort-icon{background-position:0px 0px}.syno-ux-gridpanel .x-grid3-hd.sort-desc.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-sort-icon,.syno-ux-editorgridpanel .x-grid3-hd.sort-desc.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-sort-icon{background-position:0px -28px}.syno-ux-gridpanel .x-grid3-hd.sort-asc .x-grid3-hd-inner .x-grid3-sort-icon,.syno-ux-editorgridpanel .x-grid3-hd.sort-asc .x-grid3-hd-inner .x-grid3-sort-icon{background-position:0px -84px}.syno-ux-gridpanel .x-grid3-hd.sort-asc.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-sort-icon,.syno-ux-editorgridpanel .x-grid3-hd.sort-asc.x-grid3-hd-over .x-grid3-hd-inner .x-grid3-sort-icon{background-position:0px -112px}.syno-ux-gridpanel .x-grid3-row,.syno-ux-editorgridpanel .x-grid3-row{background-color:transparent;border-bottom:1px solid #EBF0F5;border-width:0 0 1px 0;padding-top:0px}.syno-ux-gridpanel .x-grid3-row.x-grid3-row-over,.syno-ux-editorgridpanel .x-grid3-row.x-grid3-row-over{background-color:#f5faff;border-width:0 0 1px 0}.syno-ux-gridpanel .x-grid3-row.x-grid3-row-selected,.syno-ux-editorgridpanel .x-grid3-row.x-grid3-row-selected{background-color:#e6f5ff !important;border-width:0 0 1px 0}.syno-ux-gridpanel .x-grid3-row .x-grid3-cell,.syno-ux-editorgridpanel .x-grid3-row .x-grid3-cell{height:27px}.syno-ux-gridpanel .x-grid3-row .x-grid3-cell .x-grid3-cell-inner,.syno-ux-editorgridpanel .x-grid3-row .x-grid3-cell .x-grid3-cell-inner{line-height:27px;padding:0 0 0 8px}.syno-ux-gridpanel .x-grid-group .x-grid-group-body .x-grid3-cell-first .x-grid3-cell-inner,.syno-ux-editorgridpanel .x-grid-group .x-grid-group-body .x-grid3-cell-first .x-grid3-cell-inner{padding-left:28px}.syno-ux-gridpanel .x-grid-group .x-grid-group-hd,.syno-ux-editorgridpanel .x-grid-group .x-grid-group-hd{background-image:none;height:27px;border-bottom:1px solid #EBF0F5;padding-top:0px}.syno-ux-gridpanel .x-grid-group .x-grid-group-hd div.x-grid-group-title,.syno-ux-editorgridpanel .x-grid-group .x-grid-group-hd div.x-grid-group-title{background-image:url("./images/Components/category_expand.png");background-position:2px -72px;padding:0 0 0 28px;font-size:12px;color:#6B95B2;height:28px;line-height:28px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-gridpanel .x-grid-group .x-grid-group-hd div.x-grid-group-title,.synohdpack .syno-ux-editorgridpanel .x-grid-group .x-grid-group-hd div.x-grid-group-title{background-image:url("../img/synohdpack/./images/Components/category_expand.png");background-size:24px 144px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-gridpanel .x-grid-group .x-grid-group-hd div.x-grid-group-title,.synohdpackdebug .syno-ux-editorgridpanel .x-grid-group .x-grid-group-hd div.x-grid-group-title{background-image:url("../img/synohdpack/./images/Components/category_expand.png");background-size:24px 144px;outline:1px green dashed}}.syno-ux-gridpanel .x-grid-group .syno-ux-grid-group-hd-over div.x-grid-group-title,.syno-ux-editorgridpanel .x-grid-group .syno-ux-grid-group-hd-over div.x-grid-group-title{color:#5C9DCC;background-position:2px -96px}.syno-ux-gridpanel .x-grid-group .syno-ux-grid-group-hd-click div.x-grid-group-title,.syno-ux-editorgridpanel .x-grid-group .syno-ux-grid-group-hd-click div.x-grid-group-title{color:#5383A6;background-position:2px -120px}.syno-ux-gridpanel .x-grid-group.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title,.syno-ux-editorgridpanel .x-grid-group.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title{background-image:url("./images/Components/category_expand.png");background-position:2px 0px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-gridpanel .x-grid-group.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title,.synohdpack .syno-ux-editorgridpanel .x-grid-group.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title{background-image:url("../img/synohdpack/./images/Components/category_expand.png");background-size:24px 144px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-gridpanel .x-grid-group.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title,.synohdpackdebug .syno-ux-editorgridpanel .x-grid-group.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title{background-image:url("../img/synohdpack/./images/Components/category_expand.png");background-size:24px 144px;outline:1px green dashed}}.syno-ux-gridpanel .x-grid-group.x-grid-group-collapsed .syno-ux-grid-group-hd-over div.x-grid-group-title,.syno-ux-editorgridpanel .x-grid-group.x-grid-group-collapsed .syno-ux-grid-group-hd-over div.x-grid-group-title{background-position:2px -24px}.syno-ux-gridpanel .x-grid-group.x-grid-group-collapsed .syno-ux-grid-group-hd-click div.x-grid-group-title,.syno-ux-editorgridpanel .x-grid-group.x-grid-group-collapsed .syno-ux-grid-group-hd-click div.x-grid-group-title{background-position:2px -48px}.syno-ux-gridpanel .x-grid-group .x-grid-group-body.x-grid3-row-over,.syno-ux-editorgridpanel .x-grid-group .x-grid-group-body.x-grid3-row-over{border:none}.col-move-top{background-image:url("images/Components/col-move-bottom.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .col-move-top{background-image:url("../img/synohdpack/images/Components/col-move-bottom.png");background-size:9px 9px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .col-move-top{background-image:url("../img/synohdpack/images/Components/col-move-bottom.png");background-size:9px 9px;outline:1px green dashed}}.col-move-bottom{background-image:url("images/Components/col-move-bottom.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .col-move-bottom{background-image:url("../img/synohdpack/images/Components/col-move-bottom.png");background-size:9px 9px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .col-move-bottom{background-image:url("../img/synohdpack/images/Components/col-move-bottom.png");background-size:9px 9px;outline:1px green dashed}}.syno-ux-grid-hd-menu,.syno-ux-editorgrid-hd-menu,.syno-ux-groupcheck-menu,.syno-ux-searchfield-menu,.syno-ux-menu,.syno-ux-schedule-menu,.syno-ux-button-menu{background-image:none}.x-layer.syno-ux-grid-hd-menu,.x-layer.syno-ux-editorgrid-hd-menu,.x-layer.syno-ux-groupcheck-menu,.x-layer.syno-ux-searchfield-menu,.x-layer.syno-ux-menu,.x-layer.syno-ux-schedule-menu,.x-layer.syno-ux-button-menu{border-color:#C8D2DC;background-color:#FFFFFF;padding:4px;box-shadow:0 2px 4px rgba(0,0,0,0.5)}.syno-ux-grid-hd-menu ul,.syno-ux-editorgrid-hd-menu ul,.syno-ux-groupcheck-menu ul,.syno-ux-searchfield-menu ul,.syno-ux-menu ul,.syno-ux-schedule-menu ul,.syno-ux-button-menu ul{padding:0px}.syno-ux-grid-hd-menu .x-menu-sep,.syno-ux-editorgrid-hd-menu .x-menu-sep,.syno-ux-groupcheck-menu .x-menu-sep,.syno-ux-searchfield-menu .x-menu-sep,.syno-ux-menu .x-menu-sep,.syno-ux-schedule-menu .x-menu-sep,.syno-ux-button-menu .x-menu-sep{height:1px;background-color:#EBF0F5}.syno-ux-grid-hd-menu li.x-menu-list-item,.syno-ux-editorgrid-hd-menu li.x-menu-list-item,.syno-ux-groupcheck-menu li.x-menu-list-item,.syno-ux-searchfield-menu li.x-menu-list-item,.syno-ux-menu li.x-menu-list-item,.syno-ux-schedule-menu li.x-menu-list-item,.syno-ux-button-menu li.x-menu-list-item{background-image:none;background-color:#FFFFFF;border:none;padding:0px}.syno-ux-grid-hd-menu li.x-menu-list-item span,.syno-ux-editorgrid-hd-menu li.x-menu-list-item span,.syno-ux-groupcheck-menu li.x-menu-list-item span,.syno-ux-searchfield-menu li.x-menu-list-item span,.syno-ux-menu li.x-menu-list-item span,.syno-ux-schedule-menu li.x-menu-list-item span,.syno-ux-button-menu li.x-menu-list-item span{padding-left:4px}.syno-ux-grid-hd-menu li.x-menu-list-item a,.syno-ux-editorgrid-hd-menu li.x-menu-list-item a,.syno-ux-groupcheck-menu li.x-menu-list-item a,.syno-ux-searchfield-menu li.x-menu-list-item a,.syno-ux-menu li.x-menu-list-item a,.syno-ux-schedule-menu li.x-menu-list-item a,.syno-ux-button-menu li.x-menu-list-item a{line-height:28px;height:28px;padding-top:0px;padding-bottom:0px;border:0px;font-size:12px}.syno-ux-grid-hd-menu li.x-menu-list-item a.x-menu-item-arrow,.syno-ux-editorgrid-hd-menu li.x-menu-list-item a.x-menu-item-arrow,.syno-ux-groupcheck-menu li.x-menu-list-item a.x-menu-item-arrow,.syno-ux-searchfield-menu li.x-menu-list-item a.x-menu-item-arrow,.syno-ux-menu li.x-menu-list-item a.x-menu-item-arrow,.syno-ux-schedule-menu li.x-menu-list-item a.x-menu-item-arrow,.syno-ux-button-menu li.x-menu-list-item a.x-menu-item-arrow{background-image:url("./images/Components/dropdown_menu_parent.png");background-position:right 0px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-grid-hd-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpack .syno-ux-editorgrid-hd-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpack .syno-ux-groupcheck-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpack .syno-ux-searchfield-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpack .syno-ux-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpack .syno-ux-schedule-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpack .syno-ux-button-menu li.x-menu-list-item a.x-menu-item-arrow{background-image:url("../img/synohdpack/./images/Components/dropdown_menu_parent.png");background-size:16px 56px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-grid-hd-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpackdebug .syno-ux-editorgrid-hd-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpackdebug .syno-ux-groupcheck-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpackdebug .syno-ux-searchfield-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpackdebug .syno-ux-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpackdebug .syno-ux-schedule-menu li.x-menu-list-item a.x-menu-item-arrow,.synohdpackdebug .syno-ux-button-menu li.x-menu-list-item a.x-menu-item-arrow{background-image:url("../img/synohdpack/./images/Components/dropdown_menu_parent.png");background-size:16px 56px;outline:1px green dashed}}.syno-ux-grid-hd-menu li.x-menu-list-item.x-menu-item-active,.syno-ux-editorgrid-hd-menu li.x-menu-list-item.x-menu-item-active,.syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-active,.syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-active,.syno-ux-menu li.x-menu-list-item.x-menu-item-active,.syno-ux-schedule-menu li.x-menu-list-item.x-menu-item-active,.syno-ux-button-menu li.x-menu-list-item.x-menu-item-active{background-color:#0086e5}.syno-ux-grid-hd-menu li.x-menu-list-item.x-menu-item-active span,.syno-ux-editorgrid-hd-menu li.x-menu-list-item.x-menu-item-active span,.syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-active span,.syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-active span,.syno-ux-menu li.x-menu-list-item.x-menu-item-active span,.syno-ux-schedule-menu li.x-menu-list-item.x-menu-item-active span,.syno-ux-button-menu li.x-menu-list-item.x-menu-item-active span{color:#FFFFFF}.syno-ux-grid-hd-menu li.x-menu-list-item.x-menu-item-active a.x-menu-item-arrow,.syno-ux-editorgrid-hd-menu li.x-menu-list-item.x-menu-item-active a.x-menu-item-arrow,.syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-active a.x-menu-item-arrow,.syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-active a.x-menu-item-arrow,.syno-ux-menu li.x-menu-list-item.x-menu-item-active a.x-menu-item-arrow,.syno-ux-schedule-menu li.x-menu-list-item.x-menu-item-active a.x-menu-item-arrow,.syno-ux-button-menu li.x-menu-list-item.x-menu-item-active a.x-menu-item-arrow{background-position:right -28px}.syno-ux-grid-hd-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.syno-ux-editorgrid-hd-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.syno-ux-groupcheck-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.syno-ux-searchfield-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.syno-ux-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.syno-ux-schedule-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.syno-ux-button-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;background-position:0px 0px;width:22px;height:22px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-grid-hd-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpack .syno-ux-editorgrid-hd-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpack .syno-ux-groupcheck-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpack .syno-ux-searchfield-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpack .syno-ux-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpack .syno-ux-schedule-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpack .syno-ux-button-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-grid-hd-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpackdebug .syno-ux-editorgrid-hd-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpackdebug .syno-ux-groupcheck-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpackdebug .syno-ux-searchfield-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpackdebug .syno-ux-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpackdebug .syno-ux-schedule-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon,.synohdpackdebug .syno-ux-button-menu li.x-menu-list-item .x-menu-check-item .x-menu-item-icon{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;outline:1px green dashed}}.syno-ux-grid-hd-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.syno-ux-editorgrid-hd-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.syno-ux-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.syno-ux-schedule-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.syno-ux-button-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;background-position:0px -66px;width:22px;height:22px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-grid-hd-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpack .syno-ux-editorgrid-hd-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpack .syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpack .syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpack .syno-ux-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpack .syno-ux-schedule-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpack .syno-ux-button-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-grid-hd-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpackdebug .syno-ux-editorgrid-hd-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpackdebug .syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpackdebug .syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpackdebug .syno-ux-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpackdebug .syno-ux-schedule-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon,.synohdpackdebug .syno-ux-button-menu li.x-menu-list-item.x-menu-item-checked .x-menu-item-icon{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;outline:1px green dashed}}.syno-ux-groupcheck-menu li.x-menu-list-item .x-menu-check-item img.x-menu-item-icon,.syno-ux-searchfield-menu li.x-menu-list-item .x-menu-check-item img.x-menu-item-icon{background-image:none}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-groupcheck-menu li.x-menu-list-item .x-menu-check-item img.x-menu-item-icon,.synohdpack .syno-ux-searchfield-menu li.x-menu-list-item .x-menu-check-item img.x-menu-item-icon{background-image:none}}.syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-checked img.x-menu-item-icon,.syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-checked img.x-menu-item-icon{background-image:url("images/Components/dropdown_menu_tick.png");background-position:0px 0px;background-repeat:no-repeat;width:28px;height:28px;left:0px;top:0px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-checked img.x-menu-item-icon,.synohdpack .syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-checked img.x-menu-item-icon{background-image:url("../img/synohdpack/images/Components/dropdown_menu_tick.png");background-size:28px 56px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-checked img.x-menu-item-icon,.synohdpackdebug .syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-checked img.x-menu-item-icon{background-image:url("../img/synohdpack/images/Components/dropdown_menu_tick.png");background-size:28px 56px;outline:1px green dashed}}.syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-checked.x-menu-item-active img.x-menu-item-icon,.syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-checked.x-menu-item-active img.x-menu-item-icon{background-image:url("images/Components/dropdown_menu_tick.png");background-position:0px -28px;background-repeat:no-repeat;width:28px;height:28px;left:0px;top:0px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-checked.x-menu-item-active img.x-menu-item-icon,.synohdpack .syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-checked.x-menu-item-active img.x-menu-item-icon{background-image:url("../img/synohdpack/images/Components/dropdown_menu_tick.png");background-size:28px 56px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-groupcheck-menu li.x-menu-list-item.x-menu-item-checked.x-menu-item-active img.x-menu-item-icon,.synohdpackdebug .syno-ux-searchfield-menu li.x-menu-list-item.x-menu-item-checked.x-menu-item-active img.x-menu-item-icon{background-image:url("../img/synohdpack/images/Components/dropdown_menu_tick.png");background-size:28px 56px;outline:1px green dashed}}.syno-ux-textfield,.ext-strict .x-small-editor .syno-ux-textfield.x-form-text,.syno-ux-numberfield{font-size:12px;background-color:#FFFFFF;box-shadow:inset 0px 1px 0px rgba(80,90,100,0.08);background-image:none;padding-left:8px}.x-form-text.syno-ux-textfield,.ext-strict .x-small-editor .x-form-text.syno-ux-textfield,.x-form-text.syno-ux-numberfield{border-color:#C8D2DC;height:24px}.syno-ux-textfield.syno-ux-textfield-hover,.syno-ux-textfield.syno-ux-numberfield-hover,.syno-ux-textfield-hover.syno-ux-numberfield,.syno-ux-numberfield.syno-ux-numberfield-hover{border-color:#B4BEC8}.x-form-focus.syno-ux-textfield,.ext-strict .x-small-editor .x-form-focus.syno-ux-textfield.x-form-text,.x-form-focus.syno-ux-numberfield{border-color:#0086e5}.x-form-invalid.syno-ux-textfield,.ext-strict .x-small-editor .x-form-invalid.syno-ux-textfield.x-form-text,.x-form-invalid.syno-ux-numberfield{border-color:#FF8C8C;background-color:#FFF0F0;background-image:none}.x-item-disabled.x-form-text.syno-ux-textfield,.ext-strict .x-small-editor .x-item-disabled.x-form-text.syno-ux-textfield,.x-item-disabled.x-form-text.syno-ux-numberfield{border-color:#C8D2DC;background-color:#F6F8FA}.ext-strict .x-small-editor .x-form-text.syno-ux-textfield,.ext-strict .x-small-editor .x-form-text.syno-ux-numberfield{height:24px !important}.x-form-item .x-form-item-label.syno-ux-item-label{font-size:12px;line-height:28px;padding:0px}.syno-ux-triggerfield,.syno-ux-combobox,.syno-ux-colorfield,.syno-ux-schedulefield,.syno-ux-datefield,.syno-ux-timefield,.syno-ux-superboxselect{font-size:12px;background-color:#FFFFFF;box-shadow:inset 0px 1px 0px rgba(80,90,100,0.08);background-image:none;padding-left:8px;border-right:0px}.ext-gecko .syno-ux-triggerfield,.ext-gecko .syno-ux-combobox,.ext-gecko .syno-ux-colorfield,.ext-gecko .syno-ux-schedulefield,.ext-gecko .syno-ux-datefield,.ext-gecko .syno-ux-timefield,.ext-gecko .syno-ux-superboxselect{padding-top:1px;padding-bottom:1px}.syno-ux-triggerfield-readonly.syno-ux-triggerfield,.syno-ux-triggerfield-readonly.syno-ux-combobox,.syno-ux-triggerfield-readonly.syno-ux-colorfield,.syno-ux-triggerfield-readonly.syno-ux-schedulefield,.syno-ux-triggerfield-readonly.syno-ux-datefield,.syno-ux-triggerfield-readonly.syno-ux-timefield,.syno-ux-triggerfield-readonly.syno-ux-superboxselect,.syno-ux-triggerfield-no-trigger.syno-ux-triggerfield,.syno-ux-triggerfield-no-trigger.syno-ux-combobox,.syno-ux-triggerfield-no-trigger.syno-ux-colorfield,.syno-ux-triggerfield-no-trigger.syno-ux-schedulefield,.syno-ux-triggerfield-no-trigger.syno-ux-datefield,.syno-ux-triggerfield-no-trigger.syno-ux-timefield,.syno-ux-triggerfield-no-trigger.syno-ux-superboxselect{border-right:1px solid #C8D2DC}.x-form-text.syno-ux-triggerfield,.x-form-text.syno-ux-combobox,.x-form-text.syno-ux-colorfield,.x-form-text.syno-ux-schedulefield,.x-form-text.syno-ux-datefield,.x-form-text.syno-ux-timefield,.x-form-text.syno-ux-superboxselect{border-color:#C8D2DC;height:24px;line-height:24px}.syno-ux-triggerfield.syno-ux-triggerfield-hover,.syno-ux-triggerfield.syno-ux-combobox-hover,.syno-ux-triggerfield.syno-ux-colorfield-hover,.syno-ux-triggerfield.syno-ux-schedulefield-hover,.syno-ux-triggerfield.syno-ux-datefield-hover,.syno-ux-triggerfield.syno-ux-timefield-hover,.syno-ux-triggerfield-hover.syno-ux-combobox,.syno-ux-triggerfield-hover.syno-ux-colorfield,.syno-ux-triggerfield-hover.syno-ux-schedulefield,.syno-ux-triggerfield-hover.syno-ux-datefield,.syno-ux-triggerfield-hover.syno-ux-timefield,.syno-ux-triggerfield-hover.syno-ux-superboxselect,.syno-ux-combobox.syno-ux-combobox-hover,.syno-ux-combobox.syno-ux-colorfield-hover,.syno-ux-combobox.syno-ux-schedulefield-hover,.syno-ux-combobox.syno-ux-datefield-hover,.syno-ux-combobox.syno-ux-timefield-hover,.syno-ux-combobox-hover.syno-ux-colorfield,.syno-ux-combobox-hover.syno-ux-schedulefield,.syno-ux-combobox-hover.syno-ux-datefield,.syno-ux-combobox-hover.syno-ux-timefield,.syno-ux-combobox-hover.syno-ux-superboxselect,.syno-ux-colorfield.syno-ux-colorfield-hover,.syno-ux-colorfield.syno-ux-schedulefield-hover,.syno-ux-colorfield.syno-ux-datefield-hover,.syno-ux-colorfield.syno-ux-timefield-hover,.syno-ux-colorfield-hover.syno-ux-schedulefield,.syno-ux-colorfield-hover.syno-ux-datefield,.syno-ux-colorfield-hover.syno-ux-timefield,.syno-ux-colorfield-hover.syno-ux-superboxselect,.syno-ux-schedulefield.syno-ux-schedulefield-hover,.syno-ux-schedulefield.syno-ux-datefield-hover,.syno-ux-schedulefield.syno-ux-timefield-hover,.syno-ux-schedulefield-hover.syno-ux-datefield,.syno-ux-schedulefield-hover.syno-ux-timefield,.syno-ux-schedulefield-hover.syno-ux-superboxselect,.syno-ux-datefield.syno-ux-datefield-hover,.syno-ux-datefield.syno-ux-timefield-hover,.syno-ux-datefield-hover.syno-ux-timefield,.syno-ux-datefield-hover.syno-ux-superboxselect,.syno-ux-timefield.syno-ux-timefield-hover,.syno-ux-timefield-hover.syno-ux-superboxselect{border-color:#B4BEC8}.x-form-focus.syno-ux-triggerfield,.x-form-focus.syno-ux-combobox,.x-form-focus.syno-ux-colorfield,.x-form-focus.syno-ux-schedulefield,.x-form-focus.syno-ux-datefield,.x-form-focus.syno-ux-timefield,.x-form-focus.syno-ux-superboxselect{border-color:#0086e5}.x-form-invalid.syno-ux-triggerfield,.x-form-invalid.syno-ux-combobox,.x-form-invalid.syno-ux-colorfield,.x-form-invalid.syno-ux-schedulefield,.x-form-invalid.syno-ux-datefield,.x-form-invalid.syno-ux-timefield,.x-form-invalid.syno-ux-superboxselect{border-color:#FF8C8C;background-color:#FFF0F0;background-image:none}.x-item-disabled .x-form-text.syno-ux-triggerfield,.x-item-disabled .x-form-text.syno-ux-combobox,.x-item-disabled .x-form-text.syno-ux-colorfield,.x-item-disabled .x-form-text.syno-ux-schedulefield,.x-item-disabled .x-form-text.syno-ux-datefield,.x-item-disabled .x-form-text.syno-ux-timefield,.x-item-disabled .x-form-text.syno-ux-superboxselect{border-color:#C8D2DC;background-color:#F6F8FA;background-image:none;border-right:0px}.x-item-disabled .x-form-text.syno-ux-triggerfield-readonly.syno-ux-triggerfield,.x-item-disabled .x-form-text.syno-ux-triggerfield-readonly.syno-ux-combobox,.x-item-disabled .x-form-text.syno-ux-triggerfield-readonly.syno-ux-colorfield,.x-item-disabled .x-form-text.syno-ux-triggerfield-readonly.syno-ux-schedulefield,.x-item-disabled .x-form-text.syno-ux-triggerfield-readonly.syno-ux-datefield,.x-item-disabled .x-form-text.syno-ux-triggerfield-readonly.syno-ux-timefield,.x-item-disabled .x-form-text.syno-ux-triggerfield-readonly.syno-ux-superboxselect,.x-item-disabled .x-form-text.syno-ux-triggerfield-no-trigger.syno-ux-triggerfield,.x-item-disabled .x-form-text.syno-ux-triggerfield-no-trigger.syno-ux-combobox,.x-item-disabled .x-form-text.syno-ux-triggerfield-no-trigger.syno-ux-colorfield,.x-item-disabled .x-form-text.syno-ux-triggerfield-no-trigger.syno-ux-schedulefield,.x-item-disabled .x-form-text.syno-ux-triggerfield-no-trigger.syno-ux-datefield,.x-item-disabled .x-form-text.syno-ux-triggerfield-no-trigger.syno-ux-timefield,.x-item-disabled .x-form-text.syno-ux-triggerfield-no-trigger.syno-ux-superboxselect{border-right:1px solid #C8D2DC}.x-form-field-trigger-wrap .x-form-trigger.syno-ux-triggerfield-trigger,.x-form-field-trigger-wrap .x-form-trigger.syno-ux-combobox-trigger,.x-form-field-trigger-wrap .x-form-trigger.syno-ux-colorfield-trigger,.x-form-field-trigger-wrap .x-form-trigger.syno-ux-schedulefield-trigger,.x-form-field-trigger-wrap .x-form-trigger.syno-ux-datefield-trigger,.x-form-field-trigger-wrap .x-form-trigger.syno-ux-timefield-trigger{background-image:url("images/Components/trigger.png");background-position:0px -1px;background-color:#FFFFFF;border:1px solid #C8D2DC;border-left:0px;width:26px;height:26px;box-shadow:inset 0px 1px 0px rgba(80,90,100,0.08)}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .x-form-field-trigger-wrap .x-form-trigger.syno-ux-triggerfield-trigger,.synohdpack .x-form-field-trigger-wrap .x-form-trigger.syno-ux-combobox-trigger,.synohdpack .x-form-field-trigger-wrap .x-form-trigger.syno-ux-colorfield-trigger,.synohdpack .x-form-field-trigger-wrap .x-form-trigger.syno-ux-schedulefield-trigger,.synohdpack .x-form-field-trigger-wrap .x-form-trigger.syno-ux-datefield-trigger,.synohdpack .x-form-field-trigger-wrap .x-form-trigger.syno-ux-timefield-trigger{background-image:url("../img/synohdpack/images/Components/trigger.png");background-size:104px 28px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .x-form-field-trigger-wrap .x-form-trigger.syno-ux-triggerfield-trigger,.synohdpackdebug .x-form-field-trigger-wrap .x-form-trigger.syno-ux-combobox-trigger,.synohdpackdebug .x-form-field-trigger-wrap .x-form-trigger.syno-ux-colorfield-trigger,.synohdpackdebug .x-form-field-trigger-wrap .x-form-trigger.syno-ux-schedulefield-trigger,.synohdpackdebug .x-form-field-trigger-wrap .x-form-trigger.syno-ux-datefield-trigger,.synohdpackdebug .x-form-field-trigger-wrap .x-form-trigger.syno-ux-timefield-trigger{background-image:url("../img/synohdpack/images/Components/trigger.png");background-size:104px 28px;outline:1px green dashed}}.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-triggerfield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-combobox-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-colorfield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-schedulefield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-datefield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-timefield-trigger{background-position:-26px -1px;border-color:#B4BECB}.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-trigger-invalid.syno-ux-triggerfield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-trigger-invalid.syno-ux-combobox-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-trigger-invalid.syno-ux-colorfield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-trigger-invalid.syno-ux-schedulefield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-trigger-invalid.syno-ux-datefield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-over.syno-ux-trigger-invalid.syno-ux-timefield-trigger{border-color:#FF8C8C;background-color:#FFF0F0}.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-click.syno-ux-triggerfield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-click.syno-ux-combobox-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-click.syno-ux-colorfield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-click.syno-ux-schedulefield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-click.syno-ux-datefield-trigger,.x-form-field-trigger-wrap .x-form-trigger.x-form-trigger-click.syno-ux-timefield-trigger{background-position:-52px -1px}.x-form-field-trigger-wrap .x-form-trigger.syno-ux-trigger-invalid.syno-ux-triggerfield-trigger,.x-form-field-trigger-wrap .x-form-trigger.syno-ux-trigger-invalid.syno-ux-combobox-trigger,.x-form-field-trigger-wrap .x-form-trigger.syno-ux-trigger-invalid.syno-ux-colorfield-trigger,.x-form-field-trigger-wrap .x-form-trigger.syno-ux-trigger-invalid.syno-ux-schedulefield-trigger,.x-form-field-trigger-wrap .x-form-trigger.syno-ux-trigger-invalid.syno-ux-datefield-trigger,.x-form-field-trigger-wrap .x-form-trigger.syno-ux-trigger-invalid.syno-ux-timefield-trigger{border-color:#FF8C8C;background-color:#FFF0F0}.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-triggerfield-trigger,.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-combobox-trigger,.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-colorfield-trigger,.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-schedulefield-trigger,.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-datefield-trigger,.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-timefield-trigger{border-color:#0086e5}.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-trigger-invalid.syno-ux-triggerfield-trigger,.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-trigger-invalid.syno-ux-combobox-trigger,.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-trigger-invalid.syno-ux-colorfield-trigger,.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-trigger-invalid.syno-ux-schedulefield-trigger,.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-trigger-invalid.syno-ux-datefield-trigger,.x-form-field-trigger-wrap.x-trigger-wrap-focus .x-form-trigger.syno-ux-trigger-invalid.syno-ux-timefield-trigger{border-color:#FF8C8C}.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.syno-ux-triggerfield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.syno-ux-combobox-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.syno-ux-colorfield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.syno-ux-schedulefield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.syno-ux-datefield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.syno-ux-timefield-trigger{background-position:-78px -1px;background-color:#F6F8FA;border-color:#C8D2DC}.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-over.syno-ux-triggerfield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-over.syno-ux-combobox-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-over.syno-ux-colorfield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-over.syno-ux-schedulefield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-over.syno-ux-datefield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-over.syno-ux-timefield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-click.syno-ux-triggerfield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-click.syno-ux-combobox-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-click.syno-ux-colorfield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-click.syno-ux-schedulefield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-click.syno-ux-datefield-trigger,.x-form-field-trigger-wrap.x-item-disabled .x-form-trigger.x-form-trigger-click.syno-ux-timefield-trigger{background-position:-78px -1px !important;border-color:#C8D2DC}/*! + * Ext JS Library 3.2.1 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */#images-view .x-panel-body{background:white;font:11px Arial, Helvetica, sans-serif}#images-view .thumb{background:#dddddd;padding:3px}#images-view .thumb img{height:60px;width:80px}#images-view .thumb-wrap{float:left;margin:4px;margin-right:0;padding:5px}#images-view .thumb-wrap span{display:block;overflow:hidden;text-align:center}#images-view .x-view-over{border:1px solid #dddddd;background:#efefef url(../resources/images/default/grid/row-over.gif) repeat-x left top;padding:4px}#images-view .x-view-selected{background:#eff5fb url(images/data-view/selected.gif) no-repeat right bottom;border:1px solid #99bbe8;padding:4px}#images-view .x-view-selected .thumb{background:transparent}#images-view .loading-indicator{font-size:11px;background-image:url("../resources/images/default/grid/loading.gif");background-repeat:no-repeat;background-position:left;padding-left:20px;margin:10px}/*! + * Ext JS Library 3.2.1 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */.x-statusbar .x-status-text{cursor:default}.x-statusbar .x-status-busy{padding-left:25px !important;background:transparent no-repeat 3px 2px}.x-statusbar .x-status-error{padding-left:25px !important;background:transparent no-repeat 3px 2px}.x-statusbar .x-status-valid{padding-left:25px !important;background:transparent no-repeat 3px 2px}.x-statusbar .x-status-busy{background-image:url(images/statusbar/loading.gif)}.x-statusbar .x-status-error{color:#C33;background-image:url(images/statusbar/exclamation.gif)}.x-statusbar .x-status-valid{background-image:url(images/statusbar/accept.png)}.ext-strict .x-form-checkbox,.x-form-radio{margin-right:2px}.ext-strict .ext-ie .x-form-checkbox,.ext-ie .x-form-radio{margin-right:0px}.syno-textfilter .x-form-field-wrap{border:1px solid #B5B8C8;background-color:#FFF}.ext-strict .ext-webkit .syno-textfilter .x-form-field-wrap .syno-textfilter-text,.syno-textfilter .x-form-field-wrap .syno-textfilter-text{font-size:11px;line-height:18px;height:18px !important;padding-left:18px;background-color:transparent;background-image:url(images/TextFilter/search-icon.png);background-position:0 0;background-repeat:no-repeat;border:none}.syno-textfilter .x-form-field-trigger-wrap .syno-textfilter-trigger{height:20px;background-color:transparent;background-image:url(images/TextFilter/search-cancel.png);background-position:0 0;background-repeat:no-repeat;right:0px;border:none}.syno-textfilter .x-form-field-trigger-wrap.x-item-disabled .syno-textfilter-trigger{background-image:url(images/TextFilter/search_icon_cancel.png) !important;background-position:0 -20px !important}.syno-search-field .x-form-field-wrap-right{padding-right:6px;background-image:url(images/TextFilter/search_box.png);background-repeat:no-repeat;height:24px;background-position:right -48px}.syno-search-field .x-form-field-wrap-center{background-image:url(images/TextFilter/search_box.png);background-position:0 -24px;background-repeat:repeat-x;height:24px}.syno-search-field .x-form-field-wrap .syno-textfilter-text{line-height:16px !important;height:16px !important;font-size:12px;background-position:0 0;background-color:transparent;padding-bottom:0 !important}.ext-gecko .syno-search-field .x-form-field-wrap .syno-textfilter-text,.ext-ie9 .syno-search-field .x-form-field-wrap .syno-textfilter-text,.ext-ie8 .syno-search-field .x-form-field-wrap .syno-textfilter-text{padding-top:0 !important}.ext-trident6 .syno-search-field .x-form-field-wrap .syno-textfilter-text{margin-top:2px !important}.syno-search-field .x-form-field-wrap-left{background-image:url(images/TextFilter/search_box.png);background-position:0 0;background-repeat:no-repeat;height:24px !important;border:0;padding-left:6px;background-color:transparent}.syno-search-field .x-form-field-trigger-wrap .syno-textfilter-trigger{top:2px;padding-right:3px}.x-form-field-wrap-center-img{background-image:url(images/TextFilter/search-icon.png);width:16px;height:16px;line-height:16px;display:table-cell;padding-right:2px;background-repeat:no-repeat;background-position:0 2px}.ext-ie9 .x-form-field-wrap-center-img,.ext-ie8 .x-form-field-wrap-center-img{background-position:0 1px}.ext-trident6 .x-form-field-wrap-center-img{background-position:0 2px}.syno-grid-enable-column-checked{height:16px;background-repeat:no-repeat;background-position:center center;background-image:url(images/EnableColumn/checked.gif)}.syno-grid-enable-column-unchecked{height:16px;background-repeat:no-repeat;background-position:center center;background-image:url(images/EnableColumn/unchecked.gif)}.syno-grid-enable-column-grayed{height:16px;background-repeat:no-repeat;background-position:center center;background-image:url(images/EnableColumn/grayed.gif)}.x-checkbox{height:13px;width:13px;background:url(images/TriCheckbox/checkbox.gif) no-repeat -13px 0;vertical-align:bottom}.x-form-focus .x-checkbox,.x-checkbox-over .x-checkbox{background-position:-13px 0}.x-checkbox-down .x-checkbox{background-position:-26px 0}.x-item-disabled .x-checkbox{background-position:-39px 0}.x-checkbox-checked .x-checkbox{background-position:-13px -13px}.x-checkbox-checked .x-form-focus .x-checkbox,.x-checkbox-checked .x-checkbox-over .x-checkbox{background-position:-13px -13px}.x-checkbox-checked .x-checkbox-down .x-checkbox{background-position:-26px -13px}.x-checkbox-checked .x-item-disabled .x-checkbox{background-position:-39px -13px}.ext-ie9.syno-cjk .x-form-check-wrap{line-height:15px}.x-checkbox-grayed .x-checkbox{background-position:-13px -26px}.x-checkbox-grayed .x-form-focus .x-checkbox,.x-checkbox-grayed .x-checkbox-over .x-checkbox{background-position:-13px -26px}.x-checkbox-grayed .x-checkbox-down .x-checkbox{background-position:-26px -26px}.x-checkbox-grayed .x-item-disabled .x-checkbox{background-position:-39px -26px}.ux-cell-value{position:relative;zoom:1}.ux-cell-actions{position:absolute;right:0;top:-2px}.ux-cell-actions-left{left:0;top:-2px}.ux-cell-action{width:16px;height:16px;float:left;cursor:pointer;margin:0 0 0 4px}.ux-cell-actions-left .ux-cell-action{margin:0 4px 0 0}.syno-radiobox .x-form-check-wrap .x-form-radio+label.x-form-cb-label{padding-left:22px;padding-bottom:2px;background-repeat:no-repeat;background-image:url(images/CustRadio/radio_button.png)}.ext-gecko .syno-radiobox .x-form-check-wrap .x-form-radio+label.x-form-cb-label{padding-bottom:1px}.syno-radiobox .x-form-check-wrap.x-item-disabled .x-form-radio+label.x-form-cb-label{background-image:url(images/CustRadio/radio_button.png)}.syno-radiobox .x-form-check-wrap input.x-form-radio{width:0px}.ext-gecko .syno-radiobox .x-form-check-wrap input.x-form-radio,.ext-opera .syno-radiobox .x-form-check-wrap input.x-form-radio,.ext-webkit .syno-radiobox .x-form-check-wrap input.x-form-radio{display:none}.syno-radiobox .x-form-cb-label{margin-left:0px}.syno-radiobox .x-form-check-wrap label{background-position:0px 0px}.syno-radiobox.x-checkbox-over .x-form-check-wrap label{background-position:0px -16px}.syno-radiobox .x-form-check-wrap label.x-checkbox-checked{background-position:0px -32px}.syno-radiobox.x-checkbox-over .x-form-check-wrap label.x-checkbox-checked{background-position:0px -48px}.syno-rounded-menu{background:transparent none;border:0px none}.syno-rounded-menu .x-menu-list{padding:0}.syno-rounded-menu .x-menu-item-active{background-color:#b6def2;background-image:none;border-color:#b6def2}.syno-rounded-menu .x-menu-item-active a.x-menu-item{border-color:#b6def2}.syno-rounded-menu-tl{background:transparent url(images/RoundedMenu/dropdown_menu_bg_a.png) no-repeat 0 0;padding-left:10px;zoom:1;z-index:1;position:relative}.syno-rounded-menu-tc{background:transparent url(images/RoundedMenu/dropdown_menu_bg_a.png) repeat-x 0 -10px;overflow:hidden;zoom:1;height:10px}.syno-rounded-menu-tr{background:transparent url(images/RoundedMenu/dropdown_menu_bg_a.png) no-repeat right -20px;padding-right:10px}.syno-rounded-menu-ml{background:transparent url(images/RoundedMenu/dropdown_menu_bg_bl.png) repeat-y 0 0;padding-left:10px;zoom:1}.syno-rounded-menu-mc{background:transparent url(images/RoundedMenu/dropdown_menu_bg_c.png) repeat 0 0;margin-left:-5px;margin-right:-5px}.syno-rounded-menu-mr{background:transparent url(images/RoundedMenu/dropdown_menu_bg_br.png) repeat-y right 0;padding-right:10px;zoom:1}.syno-rounded-menu-bl{background:transparent url(images/RoundedMenu/dropdown_menu_bg_a.png) no-repeat 0 -30px;padding-left:10px;zoom:1}.syno-rounded-menu-bc{background:transparent url(images/RoundedMenu/dropdown_menu_bg_a.png) repeat-x 0 -40px;zoom:1;height:10px}.syno-rounded-menu-br{background:transparent url(images/RoundedMenu/dropdown_menu_bg_a.png) no-repeat right -50px;padding-right:10px;zoom:1}.syno-rounded-menu-bwrap{background:transparent none;border:0px none}.syno-ux-gridpanel .x-panel-tbar .x-toolbar,.syno-ux-editorgridpanel .x-panel-tbar .x-toolbar,.syno-ux-panel .x-panel-tbar .x-toolbar,.syno-ux-formpanel .x-panel-tbar .x-toolbar,.syno-ux-tab-panel .x-panel-tbar .x-toolbar{border-bottom-color:#D7E1EB;padding:0px 0px 8px 0px}.syno-ux-gridpanel .x-panel-bbar .x-toolbar,.syno-ux-editorgridpanel .x-panel-bbar .x-toolbar,.syno-ux-panel .x-panel-bbar .x-toolbar,.syno-ux-formpanel .x-panel-bbar .x-toolbar,.syno-ux-tab-panel .x-panel-bbar .x-toolbar{border-top-color:#EBF0F5;height:23px}.syno-ux-gridpanel .x-panel-bbar .x-toolbar .xtb-text,.syno-ux-editorgridpanel .x-panel-bbar .x-toolbar .xtb-text,.syno-ux-panel .x-panel-bbar .x-toolbar .xtb-text,.syno-ux-formpanel .x-panel-bbar .x-toolbar .xtb-text,.syno-ux-tab-panel .x-panel-bbar .x-toolbar .xtb-text{line-height:23px;padding-top:0px}.syno-ux-gridpanel .x-panel-ml,.syno-ux-editorgridpanel .x-panel-ml,.syno-ux-panel .x-panel-ml,.syno-ux-formpanel .x-panel-ml,.syno-ux-tab-panel .x-panel-ml,.syno-ux-gridpanel .x-panel-mc,.syno-ux-editorgridpanel .x-panel-mc,.syno-ux-panel .x-panel-mc,.syno-ux-formpanel .x-panel-mc,.syno-ux-tab-panel .x-panel-mc{background-color:transparent}.syno-ux-gridpanel .x-panel-header,.syno-ux-editorgridpanel .x-panel-header,.syno-ux-panel .x-panel-header,.syno-ux-formpanel .x-panel-header,.syno-ux-tab-panel .x-panel-header{background-image:none;border-bottom:1px dashed #D7E1EB;font-size:15px;font-weight:normal;padding:0px 0px 0px 8px}.syno-ux-gridpanel .x-panel-header .x-panel-header-text,.syno-ux-editorgridpanel .x-panel-header .x-panel-header-text,.syno-ux-panel .x-panel-header .x-panel-header-text,.syno-ux-formpanel .x-panel-header .x-panel-header-text,.syno-ux-tab-panel .x-panel-header .x-panel-header-text{color:#0086e5;line-height:28px}.syno-ux-checkbox-icon,.syno-ux-radio-icon{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;background-position:0 0;background-color:transparent;width:22px;height:22px;border:0px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-checkbox-icon,.synohdpack .syno-ux-radio-icon{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-checkbox-icon,.synohdpackdebug .syno-ux-radio-icon{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;outline:1px green dashed}}.ext-ie .x-form-check-wrap .syno-ux-checkbox-icon,.ext-ie .x-form-check-wrap .syno-ux-radio-icon{width:22px;height:22px}.syno-ux-cb-focus.syno-ux-checkbox-icon,.syno-ux-cb-focus.syno-ux-radio-icon,.syno-ux-cb-hover.syno-ux-checkbox-icon,.syno-ux-cb-hover.syno-ux-radio-icon{background-position:0 -22px}.syno-ux-cb-disabled.syno-ux-checkbox-icon,.syno-ux-cb-disabled.syno-ux-radio-icon{background-position:0 -44px}.syno-ux-cb-disabled.syno-ux-cb-checked.syno-ux-checkbox-icon,.syno-ux-cb-disabled.syno-ux-cb-checked.syno-ux-radio-icon{background-position:0 -110px}.syno-ux-cb-disabled.syno-ux-cb-checked.syno-ux-cb-focus.syno-ux-checkbox-icon,.syno-ux-cb-disabled.syno-ux-cb-checked.syno-ux-cb-focus.syno-ux-radio-icon,.syno-ux-cb-disabled.syno-ux-cb-checked.syno-ux-cb-hover.syno-ux-checkbox-icon,.syno-ux-cb-disabled.syno-ux-cb-checked.syno-ux-cb-hover.syno-ux-radio-icon{background-position:0 -110px}.syno-ux-cb-disabled.syno-ux-cb-grayed.syno-ux-checkbox-icon,.syno-ux-cb-disabled.syno-ux-cb-grayed.syno-ux-radio-icon{background-position:0 -176px}.syno-ux-cb-disabled.syno-ux-cb-grayed.syno-ux-cb-grayed.syno-ux-checkbox-icon,.syno-ux-cb-disabled.syno-ux-cb-grayed.syno-ux-cb-grayed.syno-ux-radio-icon{background-position:0 -176px}.syno-ux-cb-checked.syno-ux-checkbox-icon,.syno-ux-cb-checked.syno-ux-radio-icon{background-position:0 -66px}.syno-ux-cb-checked.syno-ux-cb-focus.syno-ux-checkbox-icon,.syno-ux-cb-checked.syno-ux-cb-focus.syno-ux-radio-icon,.syno-ux-cb-checked.syno-ux-cb-hover.syno-ux-checkbox-icon,.syno-ux-cb-checked.syno-ux-cb-hover.syno-ux-radio-icon{background-position:0 -88px}.syno-ux-cb-grayed.syno-ux-checkbox-icon,.syno-ux-cb-grayed.syno-ux-radio-icon{background-position:0 -132px}.syno-ux-cb-grayed.syno-ux-cb-focus.syno-ux-checkbox-icon,.syno-ux-cb-grayed.syno-ux-cb-focus.syno-ux-radio-icon,.syno-ux-cb-grayed.syno-ux-cb-hover.syno-ux-checkbox-icon,.syno-ux-cb-grayed.syno-ux-cb-hover.syno-ux-radio-icon{background-position:0 -154px}.x-form-element .x-form-check-wrap .syno-ux-checkbox-icon,.x-form-element .x-form-check-wrap .syno-ux-radio-icon{position:absolute}.syno-ux-checkbox-label{font-size:12px;line-height:22px !important;padding-left:8px}.x-form-element .x-form-check-wrap .syno-ux-checkbox-label{display:inline-block;padding-left:30px}.syno-ux-fieldset{border:0px;padding:0px;margin-bottom:8px}.syno-ux-fieldset .x-fieldset-bwrap{padding:8px}.syno-ux-fieldset .x-fieldset-header{font-size:15px;font-weight:normal;height:28px;border-bottom:1px dashed #D7E1EB;padding:0}.syno-ux-fieldset .x-fieldset-header .x-fieldset-header-text{line-height:28px}.syno-ux-fieldset legend,.syno-ux-fieldset legend span{cursor:pointer}.syno-ux-fieldset.syno-ux-fieldset-default .x-fieldset-header-text{padding-left:8px}.syno-ux-fieldset.syno-ux-fieldset-default legend,.syno-ux-fieldset.syno-ux-fieldset-default legend span{cursor:default}.syno-ux-fieldset .x-tool.x-tool-toggle{background-image:url("images/Components/fieldset_expand.png");margin-top:2px;background-position:0px -72px;width:24px;height:24px;margin-left:4px;margin-right:4px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-fieldset .x-tool.x-tool-toggle{background-image:url("../img/synohdpack/images/Components/fieldset_expand.png");background-size:24px 288px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-fieldset .x-tool.x-tool-toggle{background-image:url("../img/synohdpack/images/Components/fieldset_expand.png");background-size:24px 288px;outline:1px green dashed}}.syno-ux-fieldset .syno-ux-fieldset-legend-hover{color:#0095FF;border-color:#C3CDD7}.syno-ux-fieldset .syno-ux-fieldset-legend-hover .x-tool.x-tool-toggle{background-position:0px -96px}.syno-ux-fieldset .syno-ux-fieldset-legend-click{color:#0077CC;border-color:#C3CDD7}.syno-ux-fieldset .syno-ux-fieldset-legend-click .x-tool.x-tool-toggle{background-position:0px -120px}.syno-ux-fieldset.x-panel-collapsed .x-tool.x-tool-toggle{background-position:0px 0px}.syno-ux-fieldset.x-panel-collapsed .syno-ux-fieldset-legend-hover .x-tool.x-tool-toggle{background-position:0px -24px}.syno-ux-fieldset.x-panel-collapsed .syno-ux-fieldset-legend-click .x-tool.x-tool-toggle{background-position:0px -48px}.ext-ie .x-fieldset.syno-ux-fieldset{padding-bottom:0px}.ext-ie .x-fieldset.syno-ux-fieldset legend{margin-bottom:0px}.syno-ux-displayfield.x-form-display-field{font-size:12px;padding-top:4px;padding-bottom:4px;line-height:20px}.syno-ux-displayfield.x-form-display-field a{font-weight:bold}.syno-ux-combobox-list.x-layer.x-combo-list{border-color:#C8D2DC;background-color:#FFFFFF;padding:4px;box-shadow:0 2px 4px rgba(0,0,0,0.5)}.syno-ux-combobox-list .x-combo-list-item{height:26px;line-height:26px;background-color:#FFFFFF;font-size:12px;color:#505A64;padding:0px;padding-left:8px}.syno-ux-combobox-list .x-combo-list-item.x-combo-selected{color:#FFFFFF}.syno-ux-combobox-list .x-combo-list-inner{margin-bottom:0px}.syno-ux-combobox-list .syno-ux-pagingtoolbar{border-top:1px solid #EBF0F5;border-bottom:1px solid #D7E1EB;padding:0px}.ext-strict .x-small-editor .x-form-field-wrap .x-form-text.syno-ux-combobox{height:24px !important}.syno-ux-colormenu{background-image:none}.syno-ux-colormenu.x-layer{border-color:#C8D2DC;background-color:#FFFFFF;padding:4px;box-shadow:0 2px 4px rgba(0,0,0,0.5)}.x-form-item .x-form-item-label.syno-ux-item-label{font-size:12px;line-height:28px;padding:0px}.syno-ux-button{height:26px;line-height:26px;border-radius:3px;display:inline-block;text-align:center}.syno-ux-button.x-btn em button{height:26px;font-size:12px;padding-left:14px;padding-right:14px;background-repeat:no-repeat}.syno-ux-button.syno-ux-button-dropdown{padding-right:14px}.syno-ux-button.syno-ux-button-dropdown.syno-ux-button-split{padding-right:6px}.syno-ux-button em{cursor:pointer}.syno-ux-button em.x-btn-arrow{display:block;padding-right:6px;background-image:url("./images/Components/bt_dropdown.png");background-repeat:no-repeat;background-position:top right}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-button em.x-btn-arrow{background-image:url("../img/synohdpack/./images/Components/bt_dropdown.png");background-size:6px 112px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-button em.x-btn-arrow{background-image:url("../img/synohdpack/./images/Components/bt_dropdown.png");background-size:6px 112px;outline:1px green dashed}}.syno-ux-button em.x-btn-arrow button{padding-right:6px}.syno-ux-button em.x-btn-split{display:block;padding-right:12px;background-image:url("./images/Components/bt_dropdown.png");background-repeat:no-repeat;background-position:top right}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-button em.x-btn-split{background-image:url("../img/synohdpack/./images/Components/bt_dropdown.png");background-size:6px 112px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-button em.x-btn-split{background-image:url("../img/synohdpack/./images/Components/bt_dropdown.png");background-size:6px 112px;outline:1px green dashed}}.syno-ux-button em.x-btn-split button{border-right:1px solid #C8D2DC;padding-right:8px}.syno-ux-button.x-item-disabled{cursor:default}.syno-ux-button.x-item-disabled em.x-btn-arrow{background-position-y:-28px}.syno-ux-button.x-item-disabled em.x-btn-split{background-position-y:-28px}.syno-ux-button.syno-ux-button-blue em.x-btn-arrow,.syno-ux-button.syno-ux-button-blue em.x-btn-split,.syno-ux-button.syno-ux-button-red em.x-btn-arrow,.syno-ux-button.syno-ux-button-red em.x-btn-split,.syno-ux-button.syno-ux-button-green em.x-btn-arrow,.syno-ux-button.syno-ux-button-green em.x-btn-split,.syno-ux-button.syno-ux-button-orange em.x-btn-arrow,.syno-ux-button.syno-ux-button-orange em.x-btn-split{background-position-y:-56px}.syno-ux-button.syno-ux-button-blue.x-item-disabled em.x-btn-arrow,.syno-ux-button.syno-ux-button-blue.x-item-disabled em.x-btn-split,.syno-ux-button.syno-ux-button-red.x-item-disabled em.x-btn-arrow,.syno-ux-button.syno-ux-button-red.x-item-disabled em.x-btn-split,.syno-ux-button.syno-ux-button-green.x-item-disabled em.x-btn-arrow,.syno-ux-button.syno-ux-button-green.x-item-disabled em.x-btn-split,.syno-ux-button.syno-ux-button-orange.x-item-disabled em.x-btn-arrow,.syno-ux-button.syno-ux-button-orange.x-item-disabled em.x-btn-split{background-position-y:-84px}.syno-ux-button-blue,.syno-ux-button-red,.syno-ux-button-grey,.syno-ux-button-green,.syno-ux-button-orange{min-width:80px;text-align:center}.syno-ux-button-blue.syno-ux-button-dropdown,.syno-ux-button-blue.syno-ux-button-split,.syno-ux-button-red.syno-ux-button-dropdown,.syno-ux-button-red.syno-ux-button-split,.syno-ux-button-grey.syno-ux-button-dropdown,.syno-ux-button-grey.syno-ux-button-split,.syno-ux-button-green.syno-ux-button-dropdown,.syno-ux-button-green.syno-ux-button-split,.syno-ux-button-orange.syno-ux-button-dropdown,.syno-ux-button-orange.syno-ux-button-split{min-width:0px}.syno-ux-button-grey{border:solid 1px #C8D2DC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ViZjBmNSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #ebf0f5));background-image:-webkit-linear-gradient(#f5faff,#ebf0f5);background-image:-moz-linear-gradient(#f5faff,#ebf0f5);background-image:-o-linear-gradient(#f5faff,#ebf0f5);background-image:linear-gradient(#f5faff,#ebf0f5);background-color:#ebf0f5}.syno-ux-button-grey.x-btn-over,.syno-ux-button-grey:hover{border:solid 1px #B4BEC8;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2U3ZWNmMSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #e7ecf1));background-image:-webkit-linear-gradient(#f5faff,#e7ecf1);background-image:-moz-linear-gradient(#f5faff,#e7ecf1);background-image:-o-linear-gradient(#f5faff,#e7ecf1);background-image:linear-gradient(#f5faff,#e7ecf1);background-color:#e7ecf1}.syno-ux-button-grey.x-btn-click,.syno-ux-button-grey:active{border:solid 1px #B4BEC8;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ViZjBmNSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2UxZTZlYiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ebf0f5), color-stop(100%, #e1e6eb));background-image:-webkit-linear-gradient(#ebf0f5,#e1e6eb);background-image:-moz-linear-gradient(#ebf0f5,#e1e6eb);background-image:-o-linear-gradient(#ebf0f5,#e1e6eb);background-image:linear-gradient(#ebf0f5,#e1e6eb);background-color:#e1e6eb}.syno-ux-button-grey.x-item-disabled{border:solid 1px #C8D2DC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ViZjBmNSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #ebf0f5));background-image:-webkit-linear-gradient(#f5faff,#ebf0f5);background-image:-moz-linear-gradient(#f5faff,#ebf0f5);background-image:-o-linear-gradient(#f5faff,#ebf0f5);background-image:linear-gradient(#f5faff,#ebf0f5);background-color:#ebf0f5}.syno-ux-button-default{border:solid 1px #C8D2DC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2YwZjVmYSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #f0f5fa));background-image:-webkit-linear-gradient(#f5faff,#f0f5fa);background-image:-moz-linear-gradient(#f5faff,#f0f5fa);background-image:-o-linear-gradient(#f5faff,#f0f5fa);background-image:linear-gradient(#f5faff,#f0f5fa);background-color:#f0f5fa;margin-right:6px !important}.syno-ux-button-default.x-btn-over,.syno-ux-button-default:hover{border:solid 1px #B4BEC8;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ViZjBmNSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #ebf0f5));background-image:-webkit-linear-gradient(#f5faff,#ebf0f5);background-image:-moz-linear-gradient(#f5faff,#ebf0f5);background-image:-o-linear-gradient(#f5faff,#ebf0f5);background-image:linear-gradient(#f5faff,#ebf0f5);background-color:#ebf0f5}.syno-ux-button-default.x-btn-click,.syno-ux-button-default:active{border:solid 1px #B4BEC8;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ViZjBmNSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2U2ZWJmMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ebf0f5), color-stop(100%, #e6ebf0));background-image:-webkit-linear-gradient(#ebf0f5,#e6ebf0);background-image:-moz-linear-gradient(#ebf0f5,#e6ebf0);background-image:-o-linear-gradient(#ebf0f5,#e6ebf0);background-image:linear-gradient(#ebf0f5,#e6ebf0);background-color:#e6ebf0}.syno-ux-button-default.x-item-disabled{border:solid 1px #C8D2DC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2YwZjVmYSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #f0f5fa));background-image:-webkit-linear-gradient(#f5faff,#f0f5fa);background-image:-moz-linear-gradient(#f5faff,#f0f5fa);background-image:-o-linear-gradient(#f5faff,#f0f5fa);background-image:linear-gradient(#f5faff,#f0f5fa);background-color:#f0f5fa}.syno-ux-button-blue{border:solid 1px #1687D9;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzMyYWFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzE5OTRlYiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #32aaff), color-stop(100%, #1994eb));background-image:-webkit-linear-gradient(#32aaff,#1994eb);background-image:-moz-linear-gradient(#32aaff,#1994eb);background-image:-o-linear-gradient(#32aaff,#1994eb);background-image:linear-gradient(#32aaff,#1994eb);background-color:#1994EB}.syno-ux-button-blue.x-btn button{color:#FFFFFF}.syno-ux-button-blue.x-btn-over,.syno-ux-button-blue:hover{border:solid 1px #0077CC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzI1YTRmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAyOGFlYiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #25a4ff), color-stop(100%, #028aeb));background-image:-webkit-linear-gradient(#25a4ff,#028aeb);background-image:-moz-linear-gradient(#25a4ff,#028aeb);background-image:-o-linear-gradient(#25a4ff,#028aeb);background-image:linear-gradient(#25a4ff,#028aeb);background-color:#028AEB}.syno-ux-button-blue.x-btn-over.x-btn button,.syno-ux-button-blue:hover.x-btn button{color:#FFFFFF}.syno-ux-button-blue.x-btn-click,.syno-ux-button-blue:active{border:solid 1px #0077CC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzE4OTdmMiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAxODJkZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #1897f2), color-stop(100%, #0182df));background-image:-webkit-linear-gradient(#1897f2,#0182df);background-image:-moz-linear-gradient(#1897f2,#0182df);background-image:-o-linear-gradient(#1897f2,#0182df);background-image:linear-gradient(#1897f2,#0182df);background-color:#0182DF}.syno-ux-button-blue.x-btn-click.x-btn button,.syno-ux-button-blue:active.x-btn button{color:#FFFFFF}.syno-ux-button-blue.x-item-disabled{border:solid 1px #1687D9;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzMyYWFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzE5OTRlYiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #32aaff), color-stop(100%, #1994eb));background-image:-webkit-linear-gradient(#32aaff,#1994eb);background-image:-moz-linear-gradient(#32aaff,#1994eb);background-image:-o-linear-gradient(#32aaff,#1994eb);background-image:linear-gradient(#32aaff,#1994eb);background-color:#1994EB}.syno-ux-button-blue.x-item-disabled.x-btn button{color:#99D4FF !important}.syno-ux-button-blue.syno-ux-button-dropdown.syno-ux-button-split button{border-right-color:#1687D9}.syno-ux-button-blue.syno-ux-button-dropdown.syno-ux-button-split.x-btn-over button{border-right-color:#0077CC}.syno-ux-button-blue.syno-ux-button-dropdown.syno-ux-button-split.x-btn-click button{border-right-color:#0077CC}.syno-ux-button-blue.syno-ux-button-dropdown.syno-ux-button-split.x-item-disabled button{border-right-color:#1687D9}.syno-ux-button-red{border:solid 1px #D14949;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZhNzA3MCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ViNWY1ZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #fa7070), color-stop(100%, #eb5f5f));background-image:-webkit-linear-gradient(#fa7070,#eb5f5f);background-image:-moz-linear-gradient(#fa7070,#eb5f5f);background-image:-o-linear-gradient(#fa7070,#eb5f5f);background-image:linear-gradient(#fa7070,#eb5f5f);background-color:#EB5F5F}.syno-ux-button-red.x-btn button{color:#FFFFFF}.syno-ux-button-red.x-btn-over,.syno-ux-button-red:hover{border:solid 1px #C43B38;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y5Njg2OCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2RmNDg0OCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f96868), color-stop(100%, #df4848));background-image:-webkit-linear-gradient(#f96868,#df4848);background-image:-moz-linear-gradient(#f96868,#df4848);background-image:-o-linear-gradient(#f96868,#df4848);background-image:linear-gradient(#f96868,#df4848);background-color:#DF4848}.syno-ux-button-red.x-btn-over.x-btn button,.syno-ux-button-red:hover.x-btn button{color:#FFFFFF}.syno-ux-button-red.x-btn-click,.syno-ux-button-red:active{border:solid 1px #C43B38;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U4NTY1NiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2Q5NDY0NiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #e85656), color-stop(100%, #d94646));background-image:-webkit-linear-gradient(#e85656,#d94646);background-image:-moz-linear-gradient(#e85656,#d94646);background-image:-o-linear-gradient(#e85656,#d94646);background-image:linear-gradient(#e85656,#d94646);background-color:#D94646}.syno-ux-button-red.x-btn-click.x-btn button,.syno-ux-button-red:active.x-btn button{color:#FFFFFF}.syno-ux-button-red.x-item-disabled{border:solid 1px #D14949;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZhNzA3MCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ViNWY1ZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #fa7070), color-stop(100%, #eb5f5f));background-image:-webkit-linear-gradient(#fa7070,#eb5f5f);background-image:-moz-linear-gradient(#fa7070,#eb5f5f);background-image:-o-linear-gradient(#fa7070,#eb5f5f);background-image:linear-gradient(#fa7070,#eb5f5f);background-color:#EB5F5F}.syno-ux-button-red.x-item-disabled.x-btn button{color:#FFB2B2 !important}.syno-ux-button-red.syno-ux-button-dropdown.syno-ux-button-split button{border-right-color:#D14949}.syno-ux-button-red.syno-ux-button-dropdown.syno-ux-button-split.x-btn-over button{border-right-color:#C43B38}.syno-ux-button-red.syno-ux-button-dropdown.syno-ux-button-split.x-btn-click button{border-right-color:#C43B38}.syno-ux-button-red.syno-ux-button-dropdown.syno-ux-button-split.x-item-disabled button{border-right-color:#D14949}.syno-ux-button-green{border:solid 1px #7db012;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzlhY2YyOSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzg4YmYxNCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #9acf29), color-stop(100%, #88bf14));background-image:-webkit-linear-gradient(#9acf29,#88bf14);background-image:-moz-linear-gradient(#9acf29,#88bf14);background-image:-o-linear-gradient(#9acf29,#88bf14);background-image:linear-gradient(#9acf29,#88bf14);background-color:#88bf14}.syno-ux-button-green.x-btn button{color:#FFFFFF}.syno-ux-button-green.x-btn-over,.syno-ux-button-green:hover{border:solid 1px #63a100;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzg4YzUyNyIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzc4YjcxNCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #88c527), color-stop(100%, #78b714));background-image:-webkit-linear-gradient(#88c527,#78b714);background-image:-moz-linear-gradient(#88c527,#78b714);background-image:-o-linear-gradient(#88c527,#78b714);background-image:linear-gradient(#88c527,#78b714);background-color:#78b714}.syno-ux-button-green.x-btn-over.x-btn button,.syno-ux-button-green:hover.x-btn button{color:#FFFFFF}.syno-ux-button-green.x-btn-click,.syno-ux-button-green:active{border:solid 1px #63a100;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzc2YmIyNSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzY3YWQxMyIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #76bb25), color-stop(100%, #67ad13));background-image:-webkit-linear-gradient(#76bb25,#67ad13);background-image:-moz-linear-gradient(#76bb25,#67ad13);background-image:-o-linear-gradient(#76bb25,#67ad13);background-image:linear-gradient(#76bb25,#67ad13);background-color:#67ad13}.syno-ux-button-green.x-btn-click.x-btn button,.syno-ux-button-green:active.x-btn button{color:#FFFFFF}.syno-ux-button-green.x-item-disabled{border:solid 1px #7db012;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzdkYjAxMiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzg4YmYxNCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #7db012), color-stop(100%, #88bf14));background-image:-webkit-linear-gradient(#7db012,#88bf14);background-image:-moz-linear-gradient(#7db012,#88bf14);background-image:-o-linear-gradient(#7db012,#88bf14);background-image:linear-gradient(#7db012,#88bf14);background-color:#88bf14}.syno-ux-button-green.x-item-disabled.x-btn button{color:#cde894 !important}.syno-ux-button-green.syno-ux-button-dropdown.syno-ux-button-split button{border-right-color:#7db012}.syno-ux-button-green.syno-ux-button-dropdown.syno-ux-button-split.x-btn-over button{border-right-color:#63a100}.syno-ux-button-green.syno-ux-button-dropdown.syno-ux-button-split.x-btn-click button{border-right-color:#63a100}.syno-ux-button-green.syno-ux-button-dropdown.syno-ux-button-split.x-item-disabled button{border-right-color:#7db012}.syno-ux-button-orange{border:solid 1px #ef8202;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZhYTI0NiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2Y0OTgyZCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #faa246), color-stop(100%, #f4982d));background-image:-webkit-linear-gradient(#faa246,#f4982d);background-image:-moz-linear-gradient(#faa246,#f4982d);background-image:-o-linear-gradient(#faa246,#f4982d);background-image:linear-gradient(#faa246,#f4982d);background-color:#faa246}.syno-ux-button-orange.x-btn button{color:#FFFFFF}.syno-ux-button-orange.x-btn-over,.syno-ux-button-orange:hover{border:solid 1px #ea7702;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZhYTI0NiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2VmOGUyYyIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #faa246), color-stop(100%, #ef8e2c));background-image:-webkit-linear-gradient(#faa246,#ef8e2c);background-image:-moz-linear-gradient(#faa246,#ef8e2c);background-image:-o-linear-gradient(#faa246,#ef8e2c);background-image:linear-gradient(#faa246,#ef8e2c);background-color:#faa246}.syno-ux-button-orange.x-btn-over.x-btn button,.syno-ux-button-orange:hover.x-btn button{color:#FFFFFF}.syno-ux-button-orange.x-btn-click,.syno-ux-button-orange:active{border:solid 1px #ea7702;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZhOTk0NiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2VmODQyYyIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #fa9946), color-stop(100%, #ef842c));background-image:-webkit-linear-gradient(#fa9946,#ef842c);background-image:-moz-linear-gradient(#fa9946,#ef842c);background-image:-o-linear-gradient(#fa9946,#ef842c);background-image:linear-gradient(#fa9946,#ef842c);background-color:#fa9946}.syno-ux-button-orange.x-btn-click.x-btn button,.syno-ux-button-orange:active.x-btn button{color:#FFFFFF}.syno-ux-button-orange.x-item-disabled{border:solid 1px #ef8202;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZhYTI0NiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2Y0OTgyZCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #faa246), color-stop(100%, #f4982d));background-image:-webkit-linear-gradient(#faa246,#f4982d);background-image:-moz-linear-gradient(#faa246,#f4982d);background-image:-o-linear-gradient(#faa246,#f4982d);background-image:linear-gradient(#faa246,#f4982d);background-color:#faa246}.syno-ux-button-orange.x-item-disabled.x-btn button{color:#ffe1be !important}.syno-ux-button-orange.syno-ux-button-dropdown.syno-ux-button-split button{border-right-color:#ef8202}.syno-ux-button-orange.syno-ux-button-dropdown.syno-ux-button-split.x-btn-over button{border-right-color:#ea7702}.syno-ux-button-orange.syno-ux-button-dropdown.syno-ux-button-split.x-btn-click button{border-right-color:#ea7702}.syno-ux-button-orange.syno-ux-button-dropdown.syno-ux-button-split.x-item-disabled button{border-right-color:#ef8202}.syno-ux-button.syno-ux-statebuttongroup-right,.syno-ux-button.syno-ux-statebuttongroup-left,.syno-ux-button.syno-ux-statebuttongroup-middle{margin-right:0px !important;border-color:#C8D2DC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2YwZjVmYSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #f0f5fa));background-image:-webkit-linear-gradient(#f5faff,#f0f5fa);background-image:-moz-linear-gradient(#f5faff,#f0f5fa);background-image:-o-linear-gradient(#f5faff,#f0f5fa);background-image:linear-gradient(#f5faff,#f0f5fa);background-color:#C8D2DC}.syno-ux-button.syno-ux-statebuttongroup-right.x-btn em button,.syno-ux-button.syno-ux-statebuttongroup-left.x-btn em button,.syno-ux-button.syno-ux-statebuttongroup-middle.x-btn em button{padding-right:18px;padding-left:18px}.syno-ux-button.syno-ux-statebuttongroup-right.x-btn-over,.syno-ux-button.syno-ux-statebuttongroup-right:hover,.syno-ux-button.syno-ux-statebuttongroup-left.x-btn-over,.syno-ux-button.syno-ux-statebuttongroup-left:hover,.syno-ux-button.syno-ux-statebuttongroup-middle.x-btn-over,.syno-ux-button.syno-ux-statebuttongroup-middle:hover{border-color:#C8D2DC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ViZjBmNSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #ebf0f5));background-image:-webkit-linear-gradient(#f5faff,#ebf0f5);background-image:-moz-linear-gradient(#f5faff,#ebf0f5);background-image:-o-linear-gradient(#f5faff,#ebf0f5);background-image:linear-gradient(#f5faff,#ebf0f5);background-color:#EBF0F5}.syno-ux-button.syno-ux-statebuttongroup-right.x-btn-click,.syno-ux-button.syno-ux-statebuttongroup-right.syno-ux-statebuttongroup-pressed,.syno-ux-button.syno-ux-statebuttongroup-left.x-btn-click,.syno-ux-button.syno-ux-statebuttongroup-left.syno-ux-statebuttongroup-pressed,.syno-ux-button.syno-ux-statebuttongroup-middle.x-btn-click,.syno-ux-button.syno-ux-statebuttongroup-middle.syno-ux-statebuttongroup-pressed{border-color:#0970CB;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzE3OTNlYiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzNiYTZmMyIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #1793eb), color-stop(100%, #3ba6f3));background-image:-webkit-linear-gradient(#1793eb,#3ba6f3);background-image:-moz-linear-gradient(#1793eb,#3ba6f3);background-image:-o-linear-gradient(#1793eb,#3ba6f3);background-image:linear-gradient(#1793eb,#3ba6f3);background-color:#3BA6F3;box-shadow:inset 0px 1px 2px #007bd3}.syno-ux-button.syno-ux-statebuttongroup-right.x-btn-click.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-right.syno-ux-statebuttongroup-pressed.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-left.x-btn-click.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-left.syno-ux-statebuttongroup-pressed.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-middle.x-btn-click.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-middle.syno-ux-statebuttongroup-pressed.x-btn button{color:#FFFFFF;text-shadow:0px 1px 0px rgba(0,0,0,0.15)}.syno-ux-button.syno-ux-statebuttongroup-right.x-item-disabled,.syno-ux-button.syno-ux-statebuttongroup-left.x-item-disabled,.syno-ux-button.syno-ux-statebuttongroup-middle.x-item-disabled{border-color:#C8D2DC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2YwZjVmYSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #f0f5fa));background-image:-webkit-linear-gradient(#f5faff,#f0f5fa);background-image:-moz-linear-gradient(#f5faff,#f0f5fa);background-image:-o-linear-gradient(#f5faff,#f0f5fa);background-image:linear-gradient(#f5faff,#f0f5fa);background-color:#F0F5FA}.syno-ux-button.syno-ux-statebuttongroup-right,.syno-ux-button.syno-ux-statebuttongroup-middle{border-top-left-radius:0px;border-bottom-left-radius:0px}.syno-ux-button.syno-ux-statebuttongroup-left,.syno-ux-button.syno-ux-statebuttongroup-middle{border-right:0px;border-top-right-radius:0px;border-bottom-right-radius:0px}.syno-ux-modulelist{padding-right:6px;background-position:right 0;background-repeat:repeat-y;background-image:url("./images/Components/shadow_category.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist{background-image:url("../img/synohdpack/./images/Components/shadow_category.png");background-size:4px 8px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist{background-image:url("../img/synohdpack/./images/Components/shadow_category.png");background-size:4px 8px;outline:1px green dashed}}.syno-ux-modulelist .x-panel-body{overflow-y:hidden}.syno-ux-modulelist .x-panel-body:before,.syno-ux-modulelist .x-panel-body:after{position:absolute;display:block;height:6px;content:"";width:94%}.syno-ux-modulelist .x-panel-body:before{top:0px;z-index:99;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, rgba(255,255,255,0)));background-image:-webkit-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-moz-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-o-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:linear-gradient(#ffffff,rgba(255,255,255,0))}.syno-ux-modulelist .x-panel-body:after{bottom:0;z-index:99;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(255,255,255,0)), color-stop(100%, #ffffff));background-image:-webkit-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-moz-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-o-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:linear-gradient(rgba(255,255,255,0),#ffffff)}.syno-ux-modulelist.scroll-at-top .x-panel-body:before{display:none}.syno-ux-modulelist.scroll-at-bottom .x-panel-body:after{display:none}.syno-ux-modulelist .x-tree-root-ct{width:auto !important}.syno-ux-modulelist .x-tree-root-node{padding-bottom:8px}.syno-ux-modulelist .x-tree-elbow,.syno-ux-modulelist .x-tree-elbow-end{display:none}.syno-ux-modulelist .x-tree-node,.syno-ux-modulelist .x-tree-node *{cursor:pointer}.syno-ux-modulelist .x-tree-node .x-tree-selected,.syno-ux-modulelist .x-tree-node .x-tree-node-over{background-color:transparent}.syno-ux-modulelist .x-tree-node-icon{width:24px;height:24px;margin:13px 6px 0 8px}.syno-ux-modulelist .syno-modulelist-toggle,.syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-minus,.syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-end-minus,.syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-minus,.syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-end-minus,.syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-plus,.syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-end-plus,.syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-plus,.syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-end-plus{width:24px;height:24px;margin:2px}.syno-ux-modulelist .x-tree-node-collapsed,.syno-ux-modulelist .x-tree-node-expanded{height:27px;margin:4px 0;font-size:12px;font-weight:bold;border-bottom:1px solid #EBF0F5}.syno-ux-modulelist .x-tree-node-collapsed .x-tree-node-icon,.syno-ux-modulelist .x-tree-node-expanded .x-tree-node-icon{display:none}.syno-ux-modulelist .x-tree-node-collapsed a,.syno-ux-modulelist .x-tree-node-expanded a{display:inline-block;width:100%;position:absolute;left:0;color:#6B95B2;overflow:hidden;text-overflow:ellipsis;line-height:27px}.syno-ux-modulelist .x-tree-node-collapsed a span,.syno-ux-modulelist .x-tree-node-expanded a span{color:#6B95B2;margin-left:28px}.syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-minus,.syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-end-minus,.syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-minus,.syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-end-minus{background-image:url("./images/Components/category_expand.png");background-position:0 -72px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-minus,.synohdpack .syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-end-minus,.synohdpack .syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-minus,.synohdpack .syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-end-minus{background-image:url("../img/synohdpack/./images/Components/category_expand.png");background-size:24px 144px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-minus,.synohdpackdebug .syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-end-minus,.synohdpackdebug .syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-minus,.synohdpackdebug .syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-end-minus{background-image:url("../img/synohdpack/./images/Components/category_expand.png");background-size:24px 144px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-plus,.syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-end-plus,.syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-plus,.syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-end-plus{background-image:url("./images/Components/category_expand.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-plus,.synohdpack .syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-end-plus,.synohdpack .syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-plus,.synohdpack .syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-end-plus{background-image:url("../img/synohdpack/./images/Components/category_expand.png");background-size:24px 144px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-plus,.synohdpackdebug .syno-ux-modulelist .x-tree-node-collapsed .x-tree-elbow-end-plus,.synohdpackdebug .syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-plus,.synohdpackdebug .syno-ux-modulelist .x-tree-node-expanded .x-tree-elbow-end-plus{background-image:url("../img/synohdpack/./images/Components/category_expand.png");background-size:24px 144px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-collapsed:hover,.syno-ux-modulelist .x-tree-node-expanded:hover{border-bottom:1px solid #D7E1EB}.syno-ux-modulelist .x-tree-node-collapsed:hover a span,.syno-ux-modulelist .x-tree-node-expanded:hover a span{color:#5C9DCC}.syno-ux-modulelist .x-tree-node-collapsed:hover .x-tree-elbow-minus,.syno-ux-modulelist .x-tree-node-expanded:hover .x-tree-elbow-minus{background-position:0 -96px}.syno-ux-modulelist .x-tree-node-collapsed:hover .x-tree-elbow-plus,.syno-ux-modulelist .x-tree-node-expanded:hover .x-tree-elbow-plus{background-position:0 -24px}.syno-ux-modulelist .x-tree-node-collapsed:active a span,.syno-ux-modulelist .x-tree-node-expanded:active a span{color:#5383A6}.syno-ux-modulelist .x-tree-node-collapsed:active .x-tree-elbow-minus,.syno-ux-modulelist .x-tree-node-expanded:active .x-tree-elbow-minus{background-position:0 -120px}.syno-ux-modulelist .x-tree-node-collapsed:active .x-tree-elbow-plus,.syno-ux-modulelist .x-tree-node-expanded:active .x-tree-elbow-plus{background-position:0 -48px}.syno-ux-modulelist .x-tree-node-leaf{height:50px;font-size:14px}.syno-ux-modulelist .x-tree-node-leaf a{display:inline-block;width:100%;position:absolute;left:0}.syno-ux-modulelist .x-tree-node-leaf a span{padding:0 0 0 38px;display:table-cell;line-height:20px;height:50px;white-space:normal;vertical-align:middle}.syno-ux-modulelist .x-tree-node-leaf .x-tree-node-icon{position:absolute;background-position:0 0;background-image:url("images/Components/c_icon_general.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .x-tree-node-leaf .x-tree-node-icon{background-image:url("../img/synohdpack/images/Components/c_icon_general.png");background-size:24px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .x-tree-node-leaf .x-tree-node-icon{background-image:url("../img/synohdpack/images/Components/c_icon_general.png");background-size:24px 96px;outline:1px green dashed}}.syno-ux-modulelist .x-tree-node-leaf.x-tree-node-over .x-tree-node-icon{background-position:0 -24px}.syno-ux-modulelist .x-tree-node-leaf.x-tree-selected{border-radius:3px}.syno-ux-modulelist .x-tree-node-leaf.x-tree-selected a span{color:#FFFFFF;text-shadow:0 1px 0 rgba(0,0,0,0.15)}.syno-ux-modulelist .x-tree-node-leaf.x-tree-selected .x-tree-node-icon{background-position:0 -48px}.syno-ux-modulelist .x-tree-node-leaf.x-tree-node-disabled .x-tree-node-icon{background-position:0 -72px;opacity:1}.syno-ux-modulelist .x-toolbar{border:none !important;background:none;padding:0 12px}.syno-ux-modulelist .x-panel-bwrap .x-panel-tbar .x-toolbar{padding-bottom:0}.syno-ux-modulelist .syno-textfilter .x-form-field-wrap{border-color:#C8D2DC;background-color:transparent;box-shadow:inset 0px 1px 0px rgba(80,90,100,0.08);background-image:none}.syno-ux-modulelist .syno-textfilter .x-form-field-wrap:hover{border-color:#B4BEC8}.syno-ux-modulelist .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger{width:24px;margin-top:2px;visibility:hidden;background-image:url("./images/Components/icon_search_clear.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger{background-image:url("../img/synohdpack/./images/Components/icon_search_clear.png");background-size:24px 144px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger{background-image:url("../img/synohdpack/./images/Components/icon_search_clear.png");background-size:24px 144px;outline:1px green dashed}}.syno-ux-modulelist .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger:hover{background-position:0 -24px}.syno-ux-modulelist .syno-textfilter .x-form-field-wrap .syno-textfilter-trigger:active{background-position:0 -48px}.syno-ux-modulelist .syno-textfilter .x-form-field-wrap .syno-textfilter-text{font-size:12px;height:24px !important;padding-left:30px;background-position:4px 1px;background-repeat:no-repeat;background-image:url("./images/Components/icon_search.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-modulelist .syno-textfilter .x-form-field-wrap .syno-textfilter-text{background-image:url("../img/synohdpack/./images/Components/icon_search.png");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-modulelist .syno-textfilter .x-form-field-wrap .syno-textfilter-text{background-image:url("../img/synohdpack/./images/Components/icon_search.png");background-size:24px 24px;outline:1px green dashed}}.syno-ux-radio-icon{background-image:url("images/Components/radio_button.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-radio-icon{background-image:url("../img/synohdpack/images/Components/radio_button.png");background-size:22px 132px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-radio-icon{background-image:url("../img/synohdpack/images/Components/radio_button.png");background-size:22px 132px;outline:1px green dashed}}.x-form-field-trigger-wrap.x-form-field-wrap .syno-ux-datefield-trigger.x-form-trigger{background-image:url("images/Components/trigger_date.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .x-form-field-trigger-wrap.x-form-field-wrap .syno-ux-datefield-trigger.x-form-trigger{background-image:url("../img/synohdpack/images/Components/trigger_date.png");background-size:104px 28px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .x-form-field-trigger-wrap.x-form-field-wrap .syno-ux-datefield-trigger.x-form-trigger{background-image:url("../img/synohdpack/images/Components/trigger_date.png");background-size:104px 28px;outline:1px green dashed}}.syno-ux-datefield-menu{border-color:#C8D2DC}.syno-ux-datefield-menu .x-menu-list-item.x-menu-date-item{padding-top:6px;padding-right:6px;padding-left:6px}.syno-ux-datefield-menu .x-date-right,.syno-ux-datefield-menu .x-date-middle,.syno-ux-datefield-menu .x-date-left{background-image:none;height:28px}.syno-ux-datefield-menu .x-date-right a,.syno-ux-datefield-menu .x-date-left a{width:24px;height:24px;background-image:url("images/Components/date_prev_next.png");opacity:1}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-datefield-menu .x-date-right a,.synohdpack .syno-ux-datefield-menu .x-date-left a{background-image:url("../img/synohdpack/images/Components/date_prev_next.png");background-size:24px 192px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-datefield-menu .x-date-right a,.synohdpackdebug .syno-ux-datefield-menu .x-date-left a{background-image:url("../img/synohdpack/images/Components/date_prev_next.png");background-size:24px 192px;outline:1px green dashed}}.syno-ux-datefield-menu .x-date-left a{background-position:0px 0px}.syno-ux-datefield-menu .x-date-right a{background-position:0px -96px}.syno-ux-datefield-menu .x-date-middle{padding:0px}.syno-ux-datefield-menu .x-date-middle .x-btn button{height:28px;font-size:12px}.syno-ux-datefield-menu .x-date-middle .x-btn-mc em.x-btn-arrow{background-image:url("images/Components/date_dropdown.png");background-position:right 0px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-datefield-menu .x-date-middle .x-btn-mc em.x-btn-arrow{background-image:url("../img/synohdpack/images/Components/date_dropdown.png");background-size:6px 112px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-datefield-menu .x-date-middle .x-btn-mc em.x-btn-arrow{background-image:url("../img/synohdpack/images/Components/date_dropdown.png");background-size:6px 112px;outline:1px green dashed}}.syno-ux-datefield-menu .x-date-middle .x-btn-over em.x-btn-arrow{background-position:right -28px}.syno-ux-datefield-menu .x-date-middle .x-btn-click em.x-btn-arrow{background-position:right -56px}.syno-ux-datefield-menu table.x-date-inner{padding-bottom:4px;width:223px}.syno-ux-datefield-menu table.x-date-inner thead th{background-image:none;background-color:white;border:0px}.syno-ux-datefield-menu table.x-date-inner thead th span{height:28px;line-height:28px;padding:0px;margin-bottom:3px;text-align:center;border-bottom:1px solid #D7E1EB}.syno-ux-datefield-menu table.x-date-inner tbody tr td{height:24px;width:32px;border:0px}.syno-ux-datefield-menu table.x-date-inner tbody tr td a{background-color:transparent;border:0px;padding:0px;text-align:center;width:28px;height:24px;line-height:24px;margin-left:2px;margin-right:2px}.syno-ux-datefield-menu table.x-date-inner tbody tr td span{font-size:12px}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-disabled span,.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-prevday span,.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-nextday span{color:#96A0AA}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-disabled a{background-color:transparent}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-selected a span{color:white;font-weight:bold}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-today a{border-bottom:2px solid #FA4B4B;height:22px}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-today a span{color:#FA4B4B;font-weight:bold}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-selected.x-date-active:hover span{color:white}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-today.x-date-active:hover span{color:#FA4B4B}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-today.x-date-selected.x-date-active:hover span{color:white}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-selected.x-date-today a{border:0px;background-color:#FA4B4B;height:24px}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-selected.x-date-today a span{color:white;font-weight:bold}.syno-ux-datefield-menu .x-date-bottom{margin-top:4px;background-image:none;background-color:white;border-top:1px solid #D7E1EB;padding:0px;height:37px}.syno-ux-datefield-menu .x-date-bottom .x-btn-ml,.syno-ux-datefield-menu .x-date-bottom .x-btn-mc,.syno-ux-datefield-menu .x-date-bottom .x-btn-mr{background-image:none}.syno-ux-datefield-menu .x-date-bottom .x-btn-noicon .x-btn-small button{width:70px;height:24px;border-radius:3px;border:solid 1px #C8D2DC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ViZjBmNSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #ebf0f5));background-image:-webkit-linear-gradient(#f5faff,#ebf0f5);background-image:-moz-linear-gradient(#f5faff,#ebf0f5);background-image:-o-linear-gradient(#f5faff,#ebf0f5);background-image:linear-gradient(#f5faff,#ebf0f5);background-color:#EBF0F5}.syno-ux-datefield-menu .x-date-bottom .x-btn-over.x-btn-noicon .x-btn-small button{border:solid 1px #B4BEC8;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2U3ZWNmMSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #e7ecf1));background-image:-webkit-linear-gradient(#f5faff,#e7ecf1);background-image:-moz-linear-gradient(#f5faff,#e7ecf1);background-image:-o-linear-gradient(#f5faff,#e7ecf1);background-image:linear-gradient(#f5faff,#e7ecf1);background-color:#E7ECF1}.syno-ux-datefield-menu .x-date-bottom .x-btn-click.x-btn-noicon .x-btn-small button{border:solid 1px #B4BEC8;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ViZjBmNSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2UxZTZlYiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ebf0f5), color-stop(100%, #e1e6eb));background-image:-webkit-linear-gradient(#ebf0f5,#e1e6eb);background-image:-moz-linear-gradient(#ebf0f5,#e1e6eb);background-image:-o-linear-gradient(#ebf0f5,#e1e6eb);background-image:linear-gradient(#ebf0f5,#e1e6eb);background-color:#E1E6EB}.ext-ie9 .syno-ux-datefield-menu .x-date-picker,.ext-ie8 .syno-ux-datefield-menu .x-date-picker{width:auto !important}.ext-ie9 .syno-ux-datefield-menu .x-date-picker .x-date-mp,.ext-ie8 .syno-ux-datefield-menu .x-date-picker .x-date-mp{width:auto !important}.syno-ux-datefield-menu .x-date-mp tr td a{width:50px;height:24px;line-height:24px;padding:0px;font-size:12px;border:0px}.syno-ux-datefield-menu .x-date-mp tr td.x-date-mp-sel a{color:white;font-weight:bold;background-image:none}.syno-ux-datefield-menu .x-date-mp-year{padding-left:6px;padding-right:0px}.syno-ux-datefield-menu .x-date-mp-month{padding-right:6px;padding-left:0px}.syno-ux-datefield-menu .x-date-mp-ybtn .x-date-mp-prev,.syno-ux-datefield-menu .x-date-mp-ybtn .x-date-mp-next{background-image:url("images/Components/date_prev_next.png");width:24px;height:24px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-datefield-menu .x-date-mp-ybtn .x-date-mp-prev,.synohdpack .syno-ux-datefield-menu .x-date-mp-ybtn .x-date-mp-next{background-image:url("../img/synohdpack/images/Components/date_prev_next.png");background-size:24px 192px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-datefield-menu .x-date-mp-ybtn .x-date-mp-prev,.synohdpackdebug .syno-ux-datefield-menu .x-date-mp-ybtn .x-date-mp-next{background-image:url("../img/synohdpack/images/Components/date_prev_next.png");background-size:24px 192px;outline:1px green dashed}}.syno-ux-datefield-menu .x-date-mp-ybtn .x-date-mp-prev{background-position:0px 0px}.syno-ux-datefield-menu .x-date-mp-ybtn .x-date-mp-prev:hover{background-position:0px -24px}.syno-ux-datefield-menu .x-date-mp-ybtn .x-date-mp-next{background-position:0px -96px}.syno-ux-datefield-menu .x-date-mp-ybtn .x-date-mp-next:hover{background-position:0px -120px}.syno-ux-datefield-menu .x-date-mp-btns{background-image:none;background-color:white}.syno-ux-datefield-menu .x-date-mp-btns td{border-top:1px solid #D7E1EB;padding:0px;height:37px}.syno-ux-datefield-menu .x-date-mp-btns button{width:70px;height:24px;border-radius:3px}.syno-ux-datefield-menu .x-date-mp-btns button.x-date-mp-ok{margin-right:10px;border:solid 1px #1687D9;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzMyYWFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzE5OTRlYiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #32aaff), color-stop(100%, #1994eb));background-image:-webkit-linear-gradient(#32aaff,#1994eb);background-image:-moz-linear-gradient(#32aaff,#1994eb);background-image:-o-linear-gradient(#32aaff,#1994eb);background-image:linear-gradient(#32aaff,#1994eb);background-color:#1994EB;color:#FFFFFF}.syno-ux-datefield-menu .x-date-mp-btns button.x-date-mp-ok:hover{border:solid 1px #0077CC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzI1YTRmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAyOGFlYiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #25a4ff), color-stop(100%, #028aeb));background-image:-webkit-linear-gradient(#25a4ff,#028aeb);background-image:-moz-linear-gradient(#25a4ff,#028aeb);background-image:-o-linear-gradient(#25a4ff,#028aeb);background-image:linear-gradient(#25a4ff,#028aeb);background-color:#028AEB}.syno-ux-datefield-menu .x-date-mp-btns button.x-date-mp-cancel{border:solid 1px #C8D2DC;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ViZjBmNSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #ebf0f5));background-image:-webkit-linear-gradient(#f5faff,#ebf0f5);background-image:-moz-linear-gradient(#f5faff,#ebf0f5);background-image:-o-linear-gradient(#f5faff,#ebf0f5);background-image:linear-gradient(#f5faff,#ebf0f5);background-color:#EBF0F5}.syno-ux-datefield-menu .x-date-mp-btns button.x-date-mp-cancel:hover{border:solid 1px #B4BEC8;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZmFmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2U3ZWNmMSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f5faff), color-stop(100%, #e7ecf1));background-image:-webkit-linear-gradient(#f5faff,#e7ecf1);background-image:-moz-linear-gradient(#f5faff,#e7ecf1);background-image:-o-linear-gradient(#f5faff,#e7ecf1);background-image:linear-gradient(#f5faff,#e7ecf1);background-color:#E7ECF1}.x-form-item .x-form-item-label.syno-ux-item-label{font-size:12px;line-height:28px;padding:0px}.syno-ux-textarea{font-size:12px;color:#505A64;background-color:#FFFFFF;box-shadow:inset 0px 1px 0px rgba(80,90,100,0.08)}.syno-ux-textarea.x-form-field{padding-left:8px;background-image:none;border-color:#C8D2DC;height:24px}.syno-ux-textarea.syno-ux-textarea-hover{border-color:#B4BEC8}.syno-ux-textarea.x-form-invalid{border-color:#FF8C8C;background-color:#FFF0F0;background-image:none}.syno-ux-textarea.x-item-disabled.x-form-field{color:#96A0AA;border-color:#C8D2DC;background-color:#F6F8FA}.x-form-item .x-form-item-label.syno-ux-item-label{font-size:12px;color:#505A64;line-height:28px;padding:0px}.syno-ux-form-fleXcroll-wrap{position:relative;display:inline-block}.syno-ux-form-fleXcroll-wrap .syno-ux-form-fleXcroll-element{position:absolute;right:0px;top:0px;width:10px}.syno-ux-form-fleXcroll-wrap .syno-ux-form-fleXcroll-element .syno-ux-form-fleXcroll-inner-element{width:10px}.syno-ux-textfilter .x-form-field-wrap{border:1px solid #C8D2DC;background-color:#FFFFFF;box-shadow:inset 0px 1px 0px rgba(80,90,100,0.08);background-image:none}.syno-ux-textfilter .x-form-field-wrap div{background-color:transparent}.syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-text.x-form-text{font-size:12px;height:24px !important;padding-left:30px;border:0px;background-position:4px 1px;background-repeat:no-repeat;background-color:transparent;background-image:url("./images/Components/icon_search.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-text.x-form-text{background-image:url("../img/synohdpack/./images/Components/icon_search.png");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-text.x-form-text{background-image:url("../img/synohdpack/./images/Components/icon_search.png");background-size:24px 24px;outline:1px green dashed}}.syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-text.x-form-text.syno-ux-textfilter-filter-icon{background-position:4px 1px;background-repeat:no-repeat;background-image:url("./images/Components/icon_filter.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-text.x-form-text.syno-ux-textfilter-filter-icon{background-image:url("../img/synohdpack/./images/Components/icon_filter.png");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-text.x-form-text.syno-ux-textfilter-filter-icon{background-image:url("../img/synohdpack/./images/Components/icon_filter.png");background-size:24px 24px;outline:1px green dashed}}.syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-trigger{background-position:0px 0px;background-repeat:no-repeat;background-image:url("./images/Components/icon_search_clear.png");border:none;width:24px;height:24px;right:0px;margin-top:1px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-trigger{background-image:url("../img/synohdpack/./images/Components/icon_search_clear.png");background-size:24px 144px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-trigger{background-image:url("../img/synohdpack/./images/Components/icon_search_clear.png");background-size:24px 144px;outline:1px green dashed}}.syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-trigger.x-form-trigger-over{background-position:0px -24px}.syno-ux-textfilter .x-form-field-wrap .syno-ux-textfilter-trigger.x-form-trigger-click{background-position:0px -48px}.syno-ux-textfilter .x-form-field-wrap:hover{border-color:#B4BEC8}.syno-ux-textfilter .x-form-field-wrap.x-form-field-wrap{background-image:none}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-textfilter .x-form-field-wrap.x-form-field-wrap{background-image:none}}.syno-ux-textfilter .x-form-field-wrap.x-form-field-wrap .x-form-field-wrap-center-img{width:34px;height:24px;background-position:0px 1px;background-repeat:no-repeat;background-image:url("images/Components/icon_advanced_search.png");padding-top:1px;padding-bottom:1px;display:table-cell;cursor:pointer}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-textfilter .x-form-field-wrap.x-form-field-wrap .x-form-field-wrap-center-img{background-image:url("../img/synohdpack/images/Components/icon_advanced_search.png");background-size:34px 96px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-textfilter .x-form-field-wrap.x-form-field-wrap .x-form-field-wrap-center-img{background-image:url("../img/synohdpack/images/Components/icon_advanced_search.png");background-size:34px 96px;outline:1px green dashed}}.syno-ux-textfilter .x-form-field-wrap.x-form-field-wrap .x-form-field-wrap-center-img:hover{background-position:0px -23px}.syno-ux-textfilter .x-form-field-wrap.x-item-disabled{border-color:#C8D2DC;background-color:#F6F8FA}.syno-ux-textfilter .x-form-field-wrap.x-item-disabled .x-form-field-wrap-center-img{background-position:0 -71px}.syno-ux-textfilter .x-form-field-wrap.x-item-disabled .x-form-field-wrap-center-img:hover{background-position:0 -71px}.syno-ux-textfilter.syno-ux-searchfield .x-form-field-wrap .syno-ux-textfilter-text.x-form-text{background-image:none;padding-left:0;display:block;vertical-align:inherit}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-textfilter.syno-ux-searchfield .x-form-field-wrap .syno-ux-textfilter-text.x-form-text{background-image:none}}input[type="file"]::-webkit-file-upload-button{cursor:pointer}.syno-ux-filebutton{filter:Alpha(opacity=0);opacity:0;position:absolute !important;padding:0px;border:none;cursor:pointer;z-index:1}.ext-ie .syno-ux-filebutton{font-size:1000px}.syno-ux-filebutton.x-item-disabled{filter:Alpha(opacity=0) !important;opacity:0 !important}.syno-ux-filebutton-btn-wrap{display:inline-block}.syno-ux-filebutton-txt{vertical-align:top}.syno-ux-formpanel .x-panel-body{padding-top:3px;padding-right:10px}.syno-ux-formpanel.syno-ux-formpanel-gradient.syno-ux-formpanel-no-tbar:before{position:absolute;display:block;height:6px;content:"";width:90%;z-index:99;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, rgba(255,255,255,0)));background-image:-webkit-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-moz-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-o-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:linear-gradient(#ffffff,rgba(255,255,255,0))}.syno-ux-formpanel.syno-ux-formpanel-gradient.syno-ux-formpanel-no-tbar.scroll-at-top:before{display:none}.syno-ux-formpanel.syno-ux-formpanel-gradient .x-panel-tbar:after{position:absolute;display:block;height:6px;content:"";width:90%;z-index:99;margin-top:0px;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, rgba(255,255,255,0)));background-image:-webkit-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-moz-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-o-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:linear-gradient(#ffffff,rgba(255,255,255,0))}.syno-ux-formpanel.syno-ux-formpanel-gradient.scroll-at-bottom .x-panel-tbar:after{display:none}.syno-ux-formpanel.syno-ux-formpanel-gradient.syno-ux-formpanel-no-fbar:after{position:absolute;display:block;height:6px;content:"";width:90%;z-index:99;margin-top:-6px;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(255,255,255,0)), color-stop(100%, #ffffff));background-image:-webkit-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-moz-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-o-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:linear-gradient(rgba(255,255,255,0),#ffffff)}.syno-ux-formpanel.syno-ux-formpanel-gradient.syno-ux-formpanel-no-fbar.scroll-at-bottom:after{display:none}.syno-ux-formpanel.syno-ux-formpanel-gradient .x-panel-footer:before{position:absolute;display:block;height:6px;content:"";width:90%;z-index:99;margin-top:-10px;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(255,255,255,0)), color-stop(100%, #ffffff));background-image:-webkit-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-moz-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-o-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:linear-gradient(rgba(255,255,255,0),#ffffff)}.syno-ux-formpanel.syno-ux-formpanel-gradient.scroll-at-bottom .x-panel-footer:before{display:none}.syno-ux-formpanel .x-panel-footer{background-image:url("./images/Components/shadow_footbar.png");background-repeat:repeat-x;padding:4px 0 0 0}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-formpanel .x-panel-footer{background-image:url("../img/synohdpack/./images/Components/shadow_footbar.png");background-size:8px 4px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-formpanel .x-panel-footer{background-image:url("../img/synohdpack/./images/Components/shadow_footbar.png");background-size:8px 4px;outline:1px green dashed}}.syno-ux-formpanel .x-panel-footer .x-toolbar-ct{height:44px}.syno-ux-formpanel .x-panel-tbar .x-toolbar{background-image:none;background-color:transparent;border-bottom:1px solid #D7E1EB}.syno-ux-formpanel .x-panel-btns td.x-toolbar-cell{padding-right:7px;padding-left:0px}.syno-ux-tab-panel .x-tab-strip-top .x-tab-strip-active .x-tab-right span.x-tab-strip-text{padding-bottom:0}.syno-ux-tab-panel .x-tab-strip-top{border:none;background-repeat:repeat-x !important;background-position:0 24px !important;background-size:16px 10px !important;background-image:url("./images/Components/tab_shadow.png") !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-tab-panel .x-tab-strip-top{background-image:url("../img/synohdpack/./images/Components/tab_shadow.png") !important;background-size:16px 10px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-tab-panel .x-tab-strip-top{background-image:url("../img/synohdpack/./images/Components/tab_shadow.png") !important;background-size:16px 10px;outline:1px green dashed}}.syno-ux-tab-panel .x-tab-strip-top .x-tab-left{padding:0}.syno-ux-tab-panel .x-tab-strip-top .x-tab-right{padding:0}.syno-ux-tab-panel .x-tab-strip-top .x-tab-strip-text{height:24px;line-height:24px;padding:0 16px;border-left:1px solid #D7E1EB}.syno-ux-tab-panel .x-tab-strip-top li{height:34px;margin:0}.syno-ux-tab-panel .x-tab-strip-top li.x-tab-strip-over .x-tab-strip-text{color:#78828C}.syno-ux-tab-panel .x-tab-strip-top li.x-tab-strip-active{font-weight:bold;background-image:url("./images/Components/tab_arrow.png");background-repeat:no-repeat;background-position:center 24px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-tab-panel .x-tab-strip-top li.x-tab-strip-active{background-image:url("../img/synohdpack/./images/Components/tab_arrow.png");background-size:16px 10px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-tab-panel .x-tab-strip-top li.x-tab-strip-active{background-image:url("../img/synohdpack/./images/Components/tab_arrow.png");background-size:16px 10px;outline:1px green dashed}}.syno-ux-tab-panel .x-tab-strip-top .x-tab-right,.syno-ux-tab-panel .x-tab-strip-top .x-tab-left,.syno-ux-tab-panel .x-tab-strip-top .x-tab-strip-inner{background-image:none}.syno-ux-tab-panel .x-tab-strip-top .x-tab-strip-closable .x-tab-strip-text{padding:0 30px 0 16px}.syno-ux-tab-panel .x-tab-strip-top .x-tab-strip-closable a.x-tab-strip-close{background-image:url("./images/Components/icon_search_clear.png");margin-top:-3px;width:24px;height:24px;opacity:1;filter:alpha(opacity=100)}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-tab-panel .x-tab-strip-top .x-tab-strip-closable a.x-tab-strip-close{background-image:url("../img/synohdpack/./images/Components/icon_search_clear.png");background-size:24px 144px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-tab-panel .x-tab-strip-top .x-tab-strip-closable a.x-tab-strip-close{background-image:url("../img/synohdpack/./images/Components/icon_search_clear.png");background-size:24px 144px;outline:1px green dashed}}.syno-ux-tab-panel .x-tab-strip-top .x-tab-strip-closable.x-tab-strip-over a.x-tab-strip-close{background-position:0px -24px}.syno-ux-tab-panel .x-tab-strip-spacer{display:none}.syno-ux-tab-panel .x-tab-panel-body{background-color:transparent;border:none}.syno-ux-tab-panel .x-tab-panel-footer{background-image:url("./images/Components/shadow_footbar.png");background-repeat:repeat-x;background-color:transparent;border:0px;padding:4px 0 0 0}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-tab-panel .x-tab-panel-footer{background-image:url("../img/synohdpack/./images/Components/shadow_footbar.png");background-size:8px 4px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-tab-panel .x-tab-panel-footer{background-image:url("../img/synohdpack/./images/Components/shadow_footbar.png");background-size:8px 4px;outline:1px green dashed}}.syno-ux-tab-panel .x-tab-panel-footer .x-toolbar-ct{height:44px}.syno-ux-tab-panel .x-panel-btns td.x-toolbar-cell{padding-right:7px;padding-left:0px}.syno-ux-grid-enable-column-checked{height:22px;margin-top:3px;background-repeat:no-repeat;background-position:center -66px;background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-grid-enable-column-checked{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-grid-enable-column-checked{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;outline:1px green dashed}}.syno-ux-grid-enable-column-checked:hover{background-position:center -88px}.syno-ux-grid-enable-column-unchecked{height:22px;margin-top:3px;background-repeat:no-repeat;background-position:center 0px;background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;)}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-grid-enable-column-unchecked{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-grid-enable-column-unchecked{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;outline:1px green dashed}}.syno-ux-grid-enable-column-unchecked:hover{background-position:center -22px}.syno-ux-grid-enable-column-grayed{height:22px;margin-top:3px;background-repeat:no-repeat;background-position:center -132px;background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-grid-enable-column-grayed{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-grid-enable-column-grayed{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;outline:1px green dashed}}.syno-ux-grid-enable-column-grayed:hover{background-position:center -154px}.syno-ux-checkbox-icon:hover{background-position:0 -22px}.syno-ux-checkbox-icon:hover.syno-ux-cb-checked{background-position:0 -88px}.syno-ux-checkbox-icon:hover.syno-ux-cb-checked.syno-ux-cb-disabled{background-position:0 -110px}.syno-ux-checkbox-icon:hover.syno-ux-cb-disabled{background-position:0 -44px}.syno-ux-grid-enable-column-disabled{height:22px;margin-top:3px;background-repeat:no-repeat;background-position:center -44px;background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-grid-enable-column-disabled{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-grid-enable-column-disabled{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;outline:1px green dashed}}.syno-ux-grid-enable-column-disabled-checked{height:22px;margin-top:3px;background-repeat:no-repeat;background-position:center -110px;background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-grid-enable-column-disabled-checked{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-grid-enable-column-disabled-checked{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;outline:1px green dashed}}.x-panel-noborder .x-panel-bbar-noborder.x-panel-bbar .syno-ux-pagingtoolbar{border-top-color:#EBF0F5;border-bottom:1px solid #D7E1EB;padding:0px;height:26px}.syno-ux-pagingtoolbar{background-color:transparent;background-image:none;line-height:28px}.syno-ux-pagingtoolbar .x-toolbar-right div{padding:2px 8px 2px 2px;font-size:12px;height:24px;line-height:24px}.syno-ux-pagingtoolbar .xtb-sep{height:20px;background-image:none;border-left:1px solid #D7E1EB;width:0px;margin:0px}.syno-ux-pagingtoolbar .x-btn-icon .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .x-btn-mr{width:2px}.syno-ux-pagingtoolbar .x-btn-icon .x-btn-ml i,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-mr i,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .x-btn-ml i,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .x-btn-mr i,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-ml i,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-mr i,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .x-btn-ml i,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .x-btn-mr i{width:2px}.syno-ux-pagingtoolbar .x-btn-icon button,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small button,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled button,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small button{background-image:url("images/Components/bt_pagebar.png") !important;min-width:28px;width:auto;height:28px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-pagingtoolbar .x-btn-icon button,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .x-btn-small button,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled button,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small button{background-image:url("../img/synohdpack/images/Components/bt_pagebar.png") !important;background-size:28px 560px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-pagingtoolbar .x-btn-icon button,.synohdpackdebug .syno-ux-pagingtoolbar .x-btn-icon .x-btn-small button,.synohdpackdebug .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled button,.synohdpackdebug .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small button{background-image:url("../img/synohdpack/images/Components/bt_pagebar.png") !important;background-size:28px 560px;outline:1px green dashed}}.syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn,.syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn-focus,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn-focus,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn-focus,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn-focus{padding:0 3px;background-image:none !important;font-size:12px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn-focus,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn-focus,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn-focus,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn-focus{background-image:none !important}}.syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn .x-btn-mc,.syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn-focus .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn-focus .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn-focus .x-btn-mc,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn .x-btn-mc,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn-focus .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn-focus .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn-focus .x-btn-mc,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn .x-btn-mc,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn-focus .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn-focus .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn-focus .x-btn-mc,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn .x-btn-mc,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn-focus .x-btn-ml,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn-focus .x-btn-mr,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn-focus .x-btn-mc{background-image:none !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn .x-btn-ml,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn .x-btn-mr,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn .x-btn-mc,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn-focus .x-btn-ml,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn-focus .x-btn-mr,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn-focus .x-btn-mc,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn .x-btn-ml,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn .x-btn-mr,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn .x-btn-mc,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn-focus .x-btn-ml,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn-focus .x-btn-mr,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn-focus .x-btn-mc,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn .x-btn-ml,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn .x-btn-mr,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn .x-btn-mc,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn-focus .x-btn-ml,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn-focus .x-btn-mr,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn-focus .x-btn-mc,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn .x-btn-ml,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn .x-btn-mr,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn .x-btn-mc,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn-focus .x-btn-ml,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn-focus .x-btn-mr,.synohdpack .syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn-focus .x-btn-mc{background-image:none !important}}.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .x-tbar-page-first{background-position:0 0}.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .x-tbar-page-prev{background-position:0 -28px}.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .x-tbar-page-next{background-position:0 -56px}.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .x-tbar-page-last{background-position:0 -84px}.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .x-tbar-loading{background-position:0 -112px}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-over .x-btn-small .x-tbar-page-first{background-position:0 -140px}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-over .x-btn-small .x-tbar-page-prev{background-position:0 -168px}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-over .x-btn-small .x-tbar-page-next{background-position:0 -196px}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-over .x-btn-small .x-tbar-page-last{background-position:0 -224px}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-over .x-btn-small .x-tbar-loading{background-position:0 -252px}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-click .x-btn-small .x-tbar-page-first{background-position:0 -280px}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-click .x-btn-small .x-tbar-page-prev{background-position:0 -308px}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-click .x-btn-small .x-tbar-page-next{background-position:0 -336px}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-click .x-btn-small .x-tbar-page-last{background-position:0 -364px}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-click .x-btn-small .x-tbar-loading{background-position:0 -392px}.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .x-tbar-page-first{background-position:0 -420px}.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .x-tbar-page-prev{background-position:0 -448px}.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .x-tbar-page-next{background-position:0 -476px}.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .x-tbar-page-last{background-position:0 -504px}.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .x-tbar-loading{background-position:0 -532px}.syno-ux-toolbar{background-color:transparent;background-image:none}.syno-ux-expandable-listview .item-summary .item-toggle,.syno-ux-expandable-listview .item-summary .item-toggle.item-toggle-expanded,.syno-ux-expandable-listview .item-summary .item-entry,.syno-ux-expandable-listview .item-summary .item-entry.item-toggle-exit,.syno-ux-expandable-listview .item-summary .item-exit{display:inline-block;position:absolute;top:0px;right:0px;width:36px;height:50px}.syno-ux-expandable-listview .item-summary .item-toggle .item-toggle-img,.syno-ux-expandable-listview .item-summary .item-toggle.item-toggle-expanded .item-toggle-img,.syno-ux-expandable-listview .item-summary .item-entry .item-entry-img,.syno-ux-expandable-listview .item-summary .item-entry.item-toggle-exit .item-entry-img,.syno-ux-expandable-listview .item-summary .item-exit .item-exit-img{position:relative;left:6px;top:13px;width:24px;height:24px;background-repeat:no-repeat;background-image:url("images/Components/fieldset_expand.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-expandable-listview .item-summary .item-toggle .item-toggle-img,.syno-ux-expandable-listview .item-summary .item-toggle .synohdpack .item-toggle-img,.synohdpack .syno-ux-expandable-listview .item-summary .item-entry .item-entry-img,.syno-ux-expandable-listview .item-summary .item-entry .synohdpack .item-entry-img,.synohdpack .syno-ux-expandable-listview .item-summary .item-exit .item-exit-img,.syno-ux-expandable-listview .item-summary .item-exit .synohdpack .item-exit-img{background-image:url("../img/synohdpack/images/Components/fieldset_expand.png");background-size:24px 288px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-expandable-listview .item-summary .item-toggle .item-toggle-img,.syno-ux-expandable-listview .item-summary .item-toggle .synohdpackdebug .item-toggle-img,.synohdpackdebug .syno-ux-expandable-listview .item-summary .item-entry .item-entry-img,.syno-ux-expandable-listview .item-summary .item-entry .synohdpackdebug .item-entry-img,.synohdpackdebug .syno-ux-expandable-listview .item-summary .item-exit .item-exit-img,.syno-ux-expandable-listview .item-summary .item-exit .synohdpackdebug .item-exit-img{background-image:url("../img/synohdpack/images/Components/fieldset_expand.png");background-size:24px 288px;outline:1px green dashed}}.syno-ux-expandable-listview .item-wrap{position:relative;padding-left:60px;border-bottom:1px solid #EBF0F5}.syno-ux-expandable-listview .item-wrap.item-over{background-color:#F5FAFF}.syno-ux-expandable-listview .item-wrap.item-selected{background-color:#E6F5FF}.syno-ux-expandable-listview .item-summary{height:50px}.syno-ux-expandable-listview .item-summary .item-icon{display:inline-block;width:32px;height:32px;position:absolute;top:9px;left:12px}.syno-ux-expandable-listview .item-summary .item-toggle .item-toggle-img{background-position:0 0px}.syno-ux-expandable-listview .item-summary .item-toggle:hover{cursor:pointer}.syno-ux-expandable-listview .item-summary .item-toggle:hover .item-toggle-img{background-position:0 -24px}.syno-ux-expandable-listview .item-summary .item-toggle:active .item-toggle-img{background-position:0 -48px}.syno-ux-expandable-listview .item-summary .item-toggle.item-toggle-expanded .item-toggle-img{background-position:0 -72px}.syno-ux-expandable-listview .item-summary .item-toggle.item-toggle-expanded:hover{cursor:pointer}.syno-ux-expandable-listview .item-summary .item-toggle.item-toggle-expanded:hover .item-toggle-img{background-position:0 -96px}.syno-ux-expandable-listview .item-summary .item-toggle.item-toggle-expanded:active .item-toggle-img{background-position:0 -120px}.syno-ux-expandable-listview .item-summary .item-entry .item-entry-img{background-position:0 -144px}.syno-ux-expandable-listview .item-summary .item-entry:hover{cursor:pointer}.syno-ux-expandable-listview .item-summary .item-entry:hover .item-entry-img{background-position:0 -168px}.syno-ux-expandable-listview .item-summary .item-entry:active .item-entry-img{background-position:0 -192px}.syno-ux-expandable-listview .item-summary .item-entry.item-toggle-exit .item-entry-img{background-position:0 -216px}.syno-ux-expandable-listview .item-summary .item-entry.item-toggle-exit:hover{cursor:pointer}.syno-ux-expandable-listview .item-summary .item-entry.item-toggle-exit:hover .item-entry-img{background-position:0 -240px}.syno-ux-expandable-listview .item-summary .item-entry.item-toggle-exit:active .item-entry-img{background-position:0 -264px}.syno-ux-expandable-listview .item-summary .item-exit .item-exit-img{background-position:0 -216px}.syno-ux-expandable-listview .item-summary .item-exit:hover{cursor:pointer}.syno-ux-expandable-listview .item-summary .item-exit:hover .item-exit-img{background-position:0 -240px}.syno-ux-expandable-listview .item-summary .item-exit:active .item-exit-img{background-position:0 -264px}.syno-ux-expandable-listview .item-summary .item-title{font-size:14px;font-weight:bold;line-height:28px}.syno-ux-expandable-listview .item-detail{padding:0 40px 12px 0}.ux-float-layout-ct{position:relative}.ux-float-layout-ct .ux-float-layout-sizer{background:transparent none;border:0 none;padding:0;margin:0;width:0}.ux-float-layout-ct .x-box-item{position:absolute}.ux-float-layout-ct.ux-float-layout-ct-animate .x-box-item{-webkit-transition-property:top,left;-moz-transition-property:top,left;-o-transition-property:top,left;transition-property:top,left;-webkit-transition-timing-function:ease-in;-moz-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:0.3s;-moz-transition-duration:0.3s;-o-transition-duration:0.3s;transition-duration:0.3s}.syno-ux-treepanel{overflow-x:hidden}.syno-ux-treepanel .x-border-panel{background-color:transparent}.syno-ux-treepanel .x-tree-root-ct{width:auto !important;overflow:hidden}.syno-ux-treepanel .x-tree-node-el{display:table;width:100%;line-height:28px;height:28px;overflow:hidden}.syno-ux-treepanel .x-tree-node{text-overflow:ellipsis;white-space:nowrap}.syno-ux-treepanel .x-tree-node a span{font-size:12px;padding-left:2px}.syno-ux-treepanel .x-tree-node .x-tree-node-over{background-color:#E6F5FF;border-radius:3px}.syno-ux-treepanel .x-tree-node .x-tree-node-over .syno-ux-cb-grayed{background-position:0 -154px}.syno-ux-treepanel .x-tree-node .x-tree-node-over .syno-ux-cb-disabled.syno-ux-cb-checked{background-position:0 -110px}.syno-ux-treepanel .x-tree-node .x-tree-selected{border-radius:3px}.syno-ux-treepanel .x-tree-node .x-tree-selected a span{color:#FFFFFF}.syno-ux-treepanel .x-tree-arrows .x-tree-node-indent .x-tree-elbow-line,.syno-ux-treepanel .x-tree-arrows .x-tree-node-indent .x-tree-icon{width:18px}.syno-ux-treepanel .x-tree-arrows .x-tree-elbow-minus,.syno-ux-treepanel .x-tree-arrows .x-tree-elbow-plus,.syno-ux-treepanel .x-tree-arrows .x-tree-elbow-end-minus,.syno-ux-treepanel .x-tree-arrows .x-tree-elbow-end-plus{background-image:url("./images/Components/tree_arrow.png");height:22px;margin-top:6px}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-treepanel .x-tree-arrows .x-tree-elbow-minus,.synohdpack .syno-ux-treepanel .x-tree-arrows .x-tree-elbow-plus,.synohdpack .syno-ux-treepanel .x-tree-arrows .x-tree-elbow-end-minus,.synohdpack .syno-ux-treepanel .x-tree-arrows .x-tree-elbow-end-plus{background-image:url("../img/synohdpack/./images/Components/tree_arrow.png");background-size:64px 16px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-treepanel .x-tree-arrows .x-tree-elbow-minus,.synohdpackdebug .syno-ux-treepanel .x-tree-arrows .x-tree-elbow-plus,.synohdpackdebug .syno-ux-treepanel .x-tree-arrows .x-tree-elbow-end-minus,.synohdpackdebug .syno-ux-treepanel .x-tree-arrows .x-tree-elbow-end-plus{background-image:url("../img/synohdpack/./images/Components/tree_arrow.png");background-size:64px 16px;outline:1px green dashed}}.syno-ux-treepanel .x-tree-arrows .x-tree-ec-over .x-tree-elbow-minus,.syno-ux-treepanel .x-tree-arrows .x-tree-ec-over .x-tree-elbow-end-minus{background-position:0px 0}.syno-ux-treepanel .x-tree-arrows .x-tree-selected .x-tree-elbow-minus,.syno-ux-treepanel .x-tree-arrows .x-tree-selected .x-tree-elbow-end-minus{background-position:-16px 0}.syno-ux-treepanel .x-tree-arrows .x-tree-ec-over .x-tree-elbow-plus,.syno-ux-treepanel .x-tree-arrows .x-tree-ec-over .x-tree-elbow-end-plus{background-position:-32px 0}.syno-ux-treepanel .x-tree-arrows .x-tree-selected .x-tree-elbow-plus,.syno-ux-treepanel .x-tree-arrows .x-tree-selected .x-tree-elbow-end-plus{background-position:-48px 0}.syno-ux-treepanel .x-tree-arrows .x-tree-elbow-minus,.syno-ux-treepanel .x-tree-arrows .x-tree-elbow-end-minus{background-position:0px 0}.syno-ux-treepanel .x-tree-arrows .x-tree-elbow-plus,.syno-ux-treepanel .x-tree-arrows .x-tree-elbow-end-plus{background-position:-32px 0}.syno-ux-treepanel .x-checkbox{margin-top:-3px !important;height:22px;width:22px;background-repeat:no-repeat;background-position:0px 0;background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;);vertical-align:middle;margin-left:4px !important;margin-right:8px !important}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-treepanel .x-checkbox{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-treepanel .x-checkbox{background-image:url("../img/synohdpack/images/Components/checkbox.png");background-size:22px 198px;outline:1px green dashed}}.syno-ux-treepanel .x-checkbox:hover{background-position:0 -22px}.syno-ux-treepanel .x-item-disabled .x-checkbox{background-position:0 -44px}.syno-ux-treepanel .x-checkbox-checked .x-checkbox{background-position:0 -66px}.syno-ux-treepanel .x-checkbox-checked .x-checkbox:hover{background-position:0 -88px}.syno-ux-treepanel .x-item-disabled .x-checkbox-checked .x-checkbox{background-position:0 -110px}.syno-ux-treepanel .x-checkbox-grayed .x-checkbox{background-position:0 -132px}.syno-ux-treepanel .x-checkbox-grayed .x-checkbox:hover{background-position:0 -154px}.syno-ux-treepanel .x-item-disabled .x-checkbox-grayed .x-checkbox{background-position:0 -176px}.syno-ux-treepanel.syno-ux-treepanel-gradient .x-panel-bwrap:before{position:absolute;display:block;height:6px;content:"";width:100%;z-index:99;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, rgba(255,255,255,0)));background-image:-webkit-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-moz-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-o-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:linear-gradient(#ffffff,rgba(255,255,255,0))}.syno-ux-treepanel.syno-ux-treepanel-gradient .x-panel-bwrap:after{position:absolute;display:block;height:6px;content:"";width:100%;z-index:99;margin-top:-6px;background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(255,255,255,0)), color-stop(100%, #ffffff));background-image:-webkit-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-moz-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-o-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:linear-gradient(rgba(255,255,255,0),#ffffff)}.syno-ux-treepanel.syno-ux-treepanel-gradient.scroll-at-top .x-panel-bwrap:before,.syno-ux-treepanel.syno-ux-treepanel-gradient.scroll-at-bottom .x-panel-bwrap:after{display:none}.x-tip-invalid{box-shadow:0 1px 4px rgba(0,0,0,0.25);border:solid 1px;border-color:#FFCCCC;border-color:rgba(255,204,204,0.75);background-color:#FA4B4B;background-color:rgba(250,75,75,0.75)}.x-tip-invalid .x-tip-invalid-ml,.x-tip-invalid .x-tip-invalid-mr,.x-tip-invalid .x-tip-invalid-mc,.x-tip-invalid .x-tip-invalid-tl,.x-tip-invalid .x-tip-invalid-tr,.x-tip-invalid .x-tip-invalid-tc,.x-tip-invalid .x-tip-invalid-bl,.x-tip-invalid .x-tip-invalid-br,.x-tip-invalid .x-tip-invalid-bc{padding:0px;background-image:none;background-color:transparent}.x-tip-invalid .x-tip-invalid-bwrap{padding:3px 10px}.x-tip-invalid .x-tip-invalid-body,.x-tip-invalid .x-tip-invalid-body span,.x-tip-invalid .x-tip-invalid-body div{font-size:12px !important;color:#FFFFFF !important}.ext-gecko .x-window-body .x-form-item{overflow:hidden}.ext-ie .x-toolbar .x-toolbar-cell .x-form-field-wrap{height:auto}.ext-ie .x-toolbar .x-toolbar-cell .x-form-field-wrap .syno-textfilter-text,.ext-ie .x-toolbar .x-toolbar-cell .x-form-field-wrap .syno-ux-textfilter-text{line-height:24px;padding-top:0px;padding-bottom:0px}.selectabletext{-moz-user-select:text;-khtml-user-select:text;-webkit-user-select:text;-ms-user-select:text;user-select:text}input[type=text][readonly].selectabletext,input[type=textarea][readonly].selectabletext,input[type=password][readonly].selectabletext{-moz-user-select:text;-khtml-user-select:text;-webkit-user-select:text;-ms-user-select:text;user-select:text}.x-statusbar .syno-ux-statusbar-loading,.x-statusbar .syno-ux-statusbar-success,.x-statusbar .syno-ux-statusbar-error{display:table-cell;vertical-align:middle;white-space:normal;word-break:break-all;margin-left:2px;height:24px;line-height:12px;font-size:12px;padding-left:30px;padding-right:6px}.x-statusbar .syno-ux-statusbar-loading{background-position:0 0;background-repeat:no-repeat;background-image:url("images/Components/icon_loading.gif")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .x-statusbar .syno-ux-statusbar-loading{background-image:url("../img/synohdpack/images/Components/icon_loading.gif");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .x-statusbar .syno-ux-statusbar-loading{background-image:url("../img/synohdpack/images/Components/icon_loading.gif");background-size:24px 24px;outline:1px green dashed}}.x-statusbar .syno-ux-statusbar-success{background-position:0 0;background-repeat:no-repeat;background-image:url("./images/Components/icon_success.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .x-statusbar .syno-ux-statusbar-success{background-image:url("../img/synohdpack/./images/Components/icon_success.png");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .x-statusbar .syno-ux-statusbar-success{background-image:url("../img/synohdpack/./images/Components/icon_success.png");background-size:24px 24px;outline:1px green dashed}}.x-statusbar .syno-ux-statusbar-error{background-position:0 0;background-repeat:no-repeat;background-image:url("./images/Components/icon_error.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .x-statusbar .syno-ux-statusbar-error{background-image:url("../img/synohdpack/./images/Components/icon_error.png");background-size:24px 24px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .x-statusbar .syno-ux-statusbar-error{background-image:url("../img/synohdpack/./images/Components/icon_error.png");background-size:24px 24px;outline:1px green dashed}}.syno-ux-superboxselect{position:relative;height:auto !important;margin:0px;overflow:hidden;padding:1px 2px 1px 4px;display:block;outline:0px !important;border-right:1px solid #C8D2DC}.x-item-disabled .syno-ux-superboxselect.x-form-focus{border-right:1px solid #C8D2DC}.syno-ux-superboxselect.x-form-invalid{border-right:1px solid #FF8C8C;background-color:#FFF0F0}.x-item-disabled .syno-ux-superboxselect.x-form-text{background-color:#F6F8FA;border-right:1px solid #C8D2DC}.syno-ux-superboxselect input[disabled]{background-color:transparent}.syno-ux-superboxselect ul{overflow:hidden;cursor:text}.syno-ux-superboxselect-display-btns ul{padding-right:50px}.syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns{position:absolute;right:1px;top:0;overflow:hidden;padding:1px}.syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns div{float:left}.syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-clear{width:24px;height:22px;background-repeat:no-repeat;background-attachment:scroll;background-position:0px -1px;background-image:url("./images/Components/icon_search_clear.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-clear{background-image:url("../img/synohdpack/./images/Components/icon_search_clear.png");background-size:24px 144px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-clear{background-image:url("../img/synohdpack/./images/Components/icon_search_clear.png");background-size:24px 144px;outline:1px green dashed}}.syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-clear.syno-ux-superboxselect-btn-over{background-position:0px -25px}.syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-clear.syno-ux-superboxselect-btn-over.syno-ux-superboxselect-btn-click{background-position:0px -49px}.syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-clear.syno-ux-superboxselect-btn-click{background-position:0px -49px}.x-item-disabled .syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-clear{background-position:0px -1px}.syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-expand{width:26px;height:22px;background-repeat:no-repeat;background-attachment:scroll;background-position:0px -3px;background-image:url("images/Components/trigger.png")}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-expand{background-image:url("../img/synohdpack/images/Components/trigger.png");background-size:104px 28px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-expand{background-image:url("../img/synohdpack/images/Components/trigger.png");background-size:104px 28px;outline:1px green dashed}}.syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-expand.syno-ux-superboxselect-btn-over{background-position:-26px -3px}.syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-expand.syno-ux-superboxselect-btn-over.syno-ux-superboxselect-btn-click{background-position:-52px -3px}.syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-expand.syno-ux-superboxselect-btn-click{background-position:-52px -3px}.x-item-disabled .syno-ux-superboxselect-display-btns .syno-ux-superboxselect-btns .syno-ux-superboxselect-btn-expand{background-position:-78px -3px}.syno-ux-superboxselect-btn-hide{display:none}.syno-ux-superboxselect li{float:left;margin:1px 4px 1px 0px;padding:0;line-height:20px}.syno-ux-superboxselect-stacked li{float:none !important}.syno-ux-superboxselect-input input{border:none;outline:0px;margin-top:4px;margin-bottom:4px;background-color:transparent}body.ext-ie .x-superboxselect-input input{background:none;border:none;margin-top:3px}.syno-ux-superboxselect-item{position:relative;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;o-border-radius:2px;khtml-border-radius:2px;border:1px solid #C8D2DC;background-color:#E7F3FE;padding:0px 26px 0px 8px !important;font-size:12px}.syno-ux-superboxselect-item.syno-ux-superboxselect-item-hover{background:#F2F9FF;border:1px solid #B6C4D2}.syno-ux-superboxselect-item.syno-ux-superboxselect-item-focus{border-color:#B6C4D2;background:#E0F0FE}.syno-ux-superboxselect-item-close{background-repeat:no-repeat;background-attachment:scroll;background-position:left 0px;background-image:url("./images/Components/superbox_button_cancel.png");border:none;font-size:1px;height:22px;padding:0;position:absolute;right:0px;top:0px;width:16px;display:block;cursor:pointer;background-color:transparent}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpack .syno-ux-superboxselect-item-close{background-image:url("../img/synohdpack/./images/Components/superbox_button_cancel.png");background-size:8px 88px}}@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-resolution: 144dpi){.synohdpackdebug .syno-ux-superboxselect-item-close{background-image:url("../img/synohdpack/./images/Components/superbox_button_cancel.png");background-size:8px 88px;outline:1px green dashed}}.syno-ux-superboxselect-item-close:hover,.syno-ux-superboxselect-item-close:active{background-position:left -22px}.syno-ux-superboxselect-item-focus .syno-ux-superboxselect-item-close{background-position:left -44px}.x-item-disabled .syno-ux-superboxselect-item-close{background-position:left -66px}.syno-gridtree.syno-ux-treepanel div.x-tree-node-el{display:block}.syno-gridtree .syno-gridtree-col{border:none}.syno-gridtree .syno-gridtree-icons{float:left}.syno-gridtree .syno-gridtree-static .x-tree-ec-icon{display:none}.syno-gridtree .syno-gridtree-static .x-tree-node-el{cursor:default}.syno-gridtree .no-node-icon .x-tree-node-leaf .x-tree-node-icon,.syno-gridtree .no-node-icon .x-tree-node-collapsed .x-tree-node-icon,.syno-gridtree .no-node-icon .x-tree-node-expanded .x-tree-node-icon{display:none}.syno-ux-combobox-list .x-combo-list-item.x-combo-selected{background-color:#0086e5;border:1px solid #0086e5 !important}.syno-ux-datefield-menu .x-date-middle .x-btn button{color:#0086e5}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-selected a{background-color:#0086e5}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-active:hover span{color:#0086e5}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-today a{border-bottom:2px solid #fa4b4b}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-today a span{color:#fa4b4b}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-today.x-date-active:hover span{color:#fa4b4b}.syno-ux-datefield-menu table.x-date-inner tbody tr td.x-date-selected.x-date-today a{background-color:#fa4b4b}.syno-ux-datefield-menu .x-date-mp tr td.x-date-mp-sel a{background-color:#0086e5}.syno-ux-displayfield.x-form-display-field a{color:#0086e5}.syno-ux-expandable-listview .item-wrap.item-over{background-color:#f5faff}.syno-ux-expandable-listview .item-wrap.item-selected{background-color:#e6f5ff}.syno-ux-expandable-listview .item-summary .item-status{color:#0086e5}.syno-ux-fieldset .x-fieldset-header{color:#0086e5}.syno-ux-modulelist .x-panel-body:before{background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, rgba(255,255,255,0)));background-image:-webkit-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-moz-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-o-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:linear-gradient(#ffffff,rgba(255,255,255,0))}.syno-ux-modulelist .x-panel-body:after{background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(255,255,255,0)), color-stop(100%, #ffffff));background-image:-webkit-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-moz-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-o-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:linear-gradient(rgba(255,255,255,0),#ffffff)}.syno-ux-modulelist .x-tree-node-leaf.x-tree-node-over a span{color:#0086e5}.syno-ux-modulelist .x-tree-node-leaf.x-tree-selected{background-color:#0086e5}.syno-ux-modulelist .x-tree-node-leaf.x-tree-selected.x-tree-node-over a span{color:#FFFFFF}.syno-ux-modulelist .syno-textfilter .x-form-field-wrap.x-trigger-wrap-focus{border-color:#0086e5}.syno-ux-pagingtoolbar .x-toolbar-right div{color:#0086e5}.syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn{color:#0086e5}.syno-ux-pagingtoolbar .x-btn-icon .syno-ux-page-btn-focus,.syno-ux-pagingtoolbar .x-btn-icon .x-btn-small .syno-ux-page-btn-focus,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn-focus,.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .x-btn-small .syno-ux-page-btn-focus{background-color:#0086e5;color:white}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-over .syno-ux-page-btn{background-color:#e6f5ff}.syno-ux-pagingtoolbar .x-btn-icon.x-btn-click .syno-ux-page-btn{color:white;background-color:#0086e5}.syno-ux-pagingtoolbar .x-btn-icon.x-item-disabled .syno-ux-page-btn{background-color:transparent}.syno-ux-button.syno-ux-statebuttongroup-right.x-btn-over.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-right:hover.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-left.x-btn-over.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-left:hover.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-middle.x-btn-over.x-btn button,.syno-ux-button.syno-ux-statebuttongroup-middle:hover.x-btn button{color:#0086e5}.x-statusbar .syno-ux-statusbar-loading{color:#0086e5}.syno-ux-superboxselect.x-form-focus{border-right:1px solid #0086e5}.syno-ux-superboxselect.x-form-focus.x-form-invalid{border-right:1px solid #FF8C8C}.syno-ux-tab-panel .x-tab-strip-top li.x-tab-strip-active .x-tab-strip-text{color:#0086e5}.syno-ux-textarea.x-form-focus{border-color:#0086e5}.syno-ux-textfilter .x-form-field-wrap.x-trigger-wrap-focus{border-color:#0086e5}.syno-ux-treepanel .x-tree-node .x-tree-node-over{background-color:#e6f5ff}.syno-ux-treepanel .x-tree-node .x-tree-selected{background-color:#0086e5}.syno-ux-treepanel.syno-ux-treepanel-gradient .x-panel-bwrap:before{background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, rgba(255,255,255,0)));background-image:-webkit-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-moz-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:-o-linear-gradient(#ffffff,rgba(255,255,255,0));background-image:linear-gradient(#ffffff,rgba(255,255,255,0))}.syno-ux-treepanel.syno-ux-treepanel-gradient .x-panel-bwrap:after{background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0icmdiYSgyNTUsMjU1LDI1NSwwKSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');background-size:100%;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(255,255,255,0)), color-stop(100%, #ffffff));background-image:-webkit-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-moz-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:-o-linear-gradient(rgba(255,255,255,0),#ffffff);background-image:linear-gradient(rgba(255,255,255,0),#ffffff)} diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/css/xtheme-gray.css b/salt/idh/skins/http/opencanary/nasLogin/static/css/xtheme-gray.css new file mode 100644 index 000000000..919e73297 --- /dev/null +++ b/salt/idh/skins/http/opencanary/nasLogin/static/css/xtheme-gray.css @@ -0,0 +1,1682 @@ +/*! + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +.ext-el-mask { + background-color: #ccc; +} + +.ext-el-mask-msg { + border-color:#999; + background-color:#ddd; + background-image:url(../images/gray/panel/white-top-bottom.gif); + background-position: 0 -1px; +} +.ext-el-mask-msg div { + background-color: #eee; + border-color:#d0d0d0; + color:#222; + font:normal 11px tahoma, arial, helvetica, sans-serif; +} + +.x-mask-loading div { + background-color:#fbfbfb; + background-image:url(../images/default/grid/loading.gif); +} + +.x-item-disabled { + color: gray; +} + +.x-item-disabled * { + color: gray !important; +} + +.x-splitbar-proxy { + background-color: #aaa; +} + +.x-color-palette a { + border-color:#fff; +} + +.x-color-palette a:hover, .x-color-palette a.x-color-palette-sel { + border-color:#CFCFCF; + background-color: #eaeaea; +} + +/* +.x-color-palette em:hover, .x-color-palette span:hover{ + background-color: #eaeaea; +} +*/ + +.x-color-palette em { + border-color:#aca899; +} + +.x-ie-shadow { + background-color:#777; +} + +.x-shadow .xsmc { + background-image: url(../images/default/shadow-c.png); +} + +.x-shadow .xsml, .x-shadow .xsmr { + background-image: url(../images/default/shadow-lr.png); +} + +.x-shadow .xstl, .x-shadow .xstc, .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbc, .x-shadow .xsbr{ + background-image: url(../images/default/shadow.png); +} + +.loading-indicator { + font-size: 11px; + background-image: url(../images/default/grid/loading.gif); +} + +.x-spotlight { + background-color: #ccc; +}.x-tab-panel-header, .x-tab-panel-footer { + background-color: #eaeaea; + border-color:#d0d0d0; + overflow:hidden; + zoom:1; +} + +.x-tab-panel-header, .x-tab-panel-footer { + border-color:#d0d0d0; +} + +ul.x-tab-strip-top{ + background-color:#dbdbdb; + background-image: url(../images/gray/tabs/tab-strip-bg.gif); + border-bottom-color:#d0d0d0; +} + +ul.x-tab-strip-bottom{ + background-color:#dbdbdb; + background-image: url(../images/gray/tabs/tab-strip-btm-bg.gif); + border-top-color:#d0d0d0; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer, +.x-tab-panel-footer-plain .x-tab-strip-spacer { + border-color:#d0d0d0; + background-color: #eaeaea; +} + +.x-tab-strip span.x-tab-strip-text { + font:normal 11px tahoma,arial,helvetica; + color:#333; +} + +.x-tab-strip-over span.x-tab-strip-text { + color:#111; +} + +.x-tab-strip-active span.x-tab-strip-text { + color:#333; + font-weight:bold; +} + +.x-tab-strip-disabled .x-tabs-text { + color:#aaaaaa; +} + +.x-tab-strip-top .x-tab-right, .x-tab-strip-top .x-tab-left, .x-tab-strip-top .x-tab-strip-inner{ + background-image: url(../images/gray/tabs/tabs-sprite.gif); +} + +.x-tab-strip-bottom .x-tab-right { + background-image: url(../images/gray/tabs/tab-btm-inactive-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-left { + background-image: url(../images/gray/tabs/tab-btm-inactive-left-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-over .x-tab-left { + background-image: url(../images/gray/tabs/tab-btm-over-left-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-over .x-tab-right { + background-image: url(../images/gray/tabs/tab-btm-over-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + background-image: url(../images/gray/tabs/tab-btm-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-left { + background-image: url(../images/gray/tabs/tab-btm-left-bg.gif); +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + background-image:url(../images/gray/tabs/tab-close.gif); +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{ + background-image:url(../images/gray/tabs/tab-close.gif); +} + +.x-tab-panel-body { + border-color:#d0d0d0; + background-color:#fff; +} + +.x-tab-panel-body-top { + border-top: 0 none; +} + +.x-tab-panel-body-bottom { + border-bottom: 0 none; +} + +.x-tab-scroller-left { + background-image:url(../images/gray/tabs/scroll-left.gif); + border-bottom-color:#d0d0d0; +} + +.x-tab-scroller-left-over { + background-position: 0 0; +} + +.x-tab-scroller-left-disabled { + background-position: -18px 0; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); + cursor:default; +} + +.x-tab-scroller-right { + background-image:url(../images/gray/tabs/scroll-right.gif); + border-bottom-color:#d0d0d0; +} + +.x-tab-panel-bbar .x-toolbar, .x-tab-panel-tbar .x-toolbar { + border-color:#d0d0d0; +} +.x-form-field{ + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-text, textarea.x-form-field{ + background-color:#fff; + background-image:url(../images/default/form/text-bg.gif); + border-color:#C1C1C1; +} + +.x-form-select-one { + background-color:#fff; + border-color:#C1C1C1; +} + +.x-form-check-group-label { + border-bottom: 1px solid #d0d0d0; + color: #333; +} + +.x-editor .x-form-check-wrap { + background-color:#fff; +} + +.x-form-field-wrap .x-form-trigger{ + background-image:url(../images/gray/form/trigger.gif); + border-bottom-color:#b5b8c8; +} + +.x-form-field-wrap .x-form-date-trigger{ + background-image: url(../images/gray/form/date-trigger.gif); +} + +.x-form-field-wrap .x-form-clear-trigger{ + background-image: url(../images/gray/form/clear-trigger.gif); +} + +.x-form-field-wrap .x-form-search-trigger{ + background-image: url(../images/gray/form/search-trigger.gif); +} + +.x-trigger-wrap-focus .x-form-trigger{ + border-bottom-color: #777777; +} + +.x-item-disabled .x-form-trigger-over{ + border-bottom-color:#b5b8c8; +} + +.x-item-disabled .x-form-trigger-click{ + border-bottom-color:#b5b8c8; +} + +.x-form-focus, textarea.x-form-focus{ + border-color:#777777; +} + +.x-form-invalid, textarea.x-form-invalid{ + background-color:#fff; + background-image:url(../images/default/grid/invalid_line.gif); + border-color:#c30; +} + +.ext-webkit .x-form-invalid{ + background-color:#fee; + border-color:#ff7870; +} + +.x-form-inner-invalid, textarea.x-form-inner-invalid{ + background-color:#fff; + background-image:url(../images/default/grid/invalid_line.gif); +} + +.x-form-grow-sizer { + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-item { + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-invalid-msg { + color:#c0272b; + font:normal 11px tahoma, arial, helvetica, sans-serif; + background-image:url(../images/default/shared/warning.gif); +} + +.x-form-empty-field { + color:gray; +} + +.x-small-editor .x-form-field { + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.ext-webkit .x-small-editor .x-form-field { + font:normal 12px arial, tahoma, helvetica, sans-serif; +} + +.x-form-invalid-icon { + background-image:url(../images/default/form/exclamation.gif); +} + +.x-fieldset { + border-color:#CCCCCC; +} + +.x-fieldset legend { + font:bold 11px tahoma, arial, helvetica, sans-serif; + color:#777777; +}.x-btn{ + font:normal 11px tahoma, verdana, helvetica; +} + +.x-btn button{ + font:normal 11px arial,tahoma,verdana,helvetica; + color:#333; +} + +.x-btn em { + font-style:normal; + font-weight:normal; +} + +.x-btn-tl, .x-btn-tr, .x-btn-tc, .x-btn-ml, .x-btn-mr, .x-btn-mc, .x-btn-bl, .x-btn-br, .x-btn-bc{ + background-image:url(../images/gray/button/btn.gif); +} + +.x-btn-click .x-btn-text, .x-btn-menu-active .x-btn-text, .x-btn-pressed .x-btn-text{ + color:#000; +} + +.x-btn-disabled *{ + color:gray !important; +} + +.x-btn-mc em.x-btn-arrow { + background-image:url(../images/default/button/arrow.gif); +} + +.x-btn-mc em.x-btn-split { + background-image:url(../images/default/button/s-arrow.gif); +} + +.x-btn-over .x-btn-mc em.x-btn-split, .x-btn-click .x-btn-mc em.x-btn-split, .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-btn-pressed .x-btn-mc em.x-btn-split { + background-image:url(../images/gray/button/s-arrow-o.gif); +} + +.x-btn-mc em.x-btn-arrow-bottom { + background-image:url(../images/default/button/s-arrow-b-noline.gif); +} + +.x-btn-mc em.x-btn-split-bottom { + background-image:url(../images/default/button/s-arrow-b.gif); +} + +.x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-btn-click .x-btn-mc em.x-btn-split-bottom, .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-btn-pressed .x-btn-mc em.x-btn-split-bottom { + background-image:url(../images/gray/button/s-arrow-bo.gif); +} + +.x-btn-group-header { + color: #666; +} + +.x-btn-group-tc { + background-image: url(../images/gray/button/group-tb.gif); +} + +.x-btn-group-tl { + background-image: url(../images/gray/button/group-cs.gif); +} + +.x-btn-group-tr { + background-image: url(../images/gray/button/group-cs.gif); +} + +.x-btn-group-bc { + background-image: url(../images/gray/button/group-tb.gif); +} + +.x-btn-group-bl { + background-image: url(../images/gray/button/group-cs.gif); +} + +.x-btn-group-br { + background-image: url(../images/gray/button/group-cs.gif); +} + +.x-btn-group-ml { + background-image: url(../images/gray/button/group-lr.gif); +} +.x-btn-group-mr { + background-image: url(../images/gray/button/group-lr.gif); +} + +.x-btn-group-notitle .x-btn-group-tc { + background-image: url(../images/gray/button/group-tb.gif); +} +.x-toolbar{ + border-color:#d0d0d0; + background-color:#f0f0f0; + background-image:url(../images/gray/toolbar/bg.gif); +} + +.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{ + font:normal 11px arial,tahoma, helvetica, sans-serif; +} + +.x-toolbar .x-item-disabled { + color:gray; +} + +.x-toolbar .x-item-disabled * { + color:gray; +} + +.x-toolbar .x-btn-mc em.x-btn-split { + background-image:url(../images/default/button/s-arrow-noline.gif); +} + +.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split, .x-toolbar .x-btn-click .x-btn-mc em.x-btn-split, +.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split +{ + background-image:url(../images/gray/button/s-arrow-o.gif); +} + +.x-toolbar .x-btn-mc em.x-btn-split-bottom { + background-image:url(../images/default/button/s-arrow-b-noline.gif); +} + +.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-toolbar .x-btn-click .x-btn-mc em.x-btn-split-bottom, +.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split-bottom +{ + background-image:url(../images/gray/button/s-arrow-bo.gif); +} + +.x-toolbar .xtb-sep { + background-image: url(../images/default/grid/grid-split.gif); +} + +.x-tbar-page-first{ + background-image: url(../images/gray/grid/page-first.gif) !important; +} + +.x-tbar-loading{ + background-image: url(../images/gray/grid/refresh.gif) !important; +} + +.x-tbar-page-last{ + background-image: url(../images/gray/grid/page-last.gif) !important; +} + +.x-tbar-page-next{ + background-image: url(../images/gray/grid/page-next.gif) !important; +} + +.x-tbar-page-prev{ + background-image: url(../images/gray/grid/page-prev.gif) !important; +} + +.x-item-disabled .x-tbar-loading{ + background-image: url(../images/default/grid/loading.gif) !important; +} + +.x-item-disabled .x-tbar-page-first{ + background-image: url(../images/default/grid/page-first-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-last{ + background-image: url(../images/default/grid/page-last-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-next{ + background-image: url(../images/default/grid/page-next-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-prev{ + background-image: url(../images/default/grid/page-prev-disabled.gif) !important; +} + +.x-paging-info { + color:#444; +} + +.x-toolbar-more-icon { + background-image: url(../images/gray/toolbar/more.gif) !important; +} +.x-resizable-handle { + background-color:#fff; +} + +.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east, +.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west +{ + background-image:url(../images/gray/sizer/e-handle.gif); +} + +.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south, +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north +{ + background-image:url(../images/gray/sizer/s-handle.gif); +} + +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north{ + background-image:url(../images/gray/sizer/s-handle.gif); +} +.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{ + background-image:url(../images/gray/sizer/se-handle.gif); +} +.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{ + background-image:url(../images/gray/sizer/nw-handle.gif); +} +.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{ + background-image:url(../images/gray/sizer/ne-handle.gif); +} +.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{ + background-image:url(../images/gray/sizer/sw-handle.gif); +} +.x-resizable-proxy{ + border-color:#565656; +} +.x-resizable-overlay{ + background-color:#fff; +} +.x-grid3 { + background-color:#fff; +} + +.x-grid-panel .x-panel-mc .x-panel-body { + border-color:#d0d0d0; +} + +.x-grid3-row td, .x-grid3-summary-row td{ + font:normal 11px/13px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-hd-row td { + font:normal 11px/15px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-hd-row td { + border-left-color:#eee; + border-right-color:#d0d0d0; +} + +.x-grid-row-loading { + background-color: #fff; + background-image:url(../images/default/shared/loading-balls.gif); +} + +.x-grid3-row { + border-color:#ededed; + border-top-color:#fff; +} + +.x-grid3-row-alt{ + background-color:#fafafa; +} + +.x-grid3-row-over { + border-color:#ddd; + background-color:#efefef; + background-image:url(../images/default/grid/row-over.gif); +} + +.x-grid3-resize-proxy { + background-color:#777; +} + +.x-grid3-resize-marker { + background-color:#777; +} + +.x-grid3-header{ + background-color:#f9f9f9; + background-image:url(../images/gray/grid/grid3-hrow2.gif); +} + +.x-grid3-header-pop { + border-left-color:#d0d0d0; +} + +.x-grid3-header-pop-inner { + border-left-color:#eee; + background-image:url(../images/default/grid/hd-pop.gif); +} + +td.x-grid3-hd-over, td.sort-desc, td.sort-asc, td.x-grid3-hd-menu-open { + border-left-color:#ACACAC; + border-right-color:#ACACAC; +} + +td.x-grid3-hd-over .x-grid3-hd-inner, td.sort-desc .x-grid3-hd-inner, td.sort-asc .x-grid3-hd-inner, td.x-grid3-hd-menu-open .x-grid3-hd-inner { + background-color:#f9f9f9; + background-image:url(../images/gray/grid/grid3-hrow-over2.gif); + +} + +.sort-asc .x-grid3-sort-icon { + background-image: url(../images/gray/grid/sort_asc.gif); +} + +.sort-desc .x-grid3-sort-icon { + background-image: url(../images/gray/grid/sort_desc.gif); +} + +.x-grid3-cell-text, .x-grid3-hd-text { + color:#000; +} + +.x-grid3-split { + background-image: url(../images/default/grid/grid-split.gif); +} + +.x-grid3-hd-text { + color:#333; +} + +.x-dd-drag-proxy .x-grid3-hd-inner{ + background-color:#f9f9f9; + background-image:url(../images/gray/grid/grid3-hrow-over2.gif); + border-color:#ACACAC; +} + +.col-move-top{ + background-image:url(../images/gray/grid/col-move-top.gif); +} + +.col-move-bottom{ + background-image:url(../images/gray/grid/col-move-bottom.gif); +} + +.x-grid3-row-selected { + background-color:#CCCCCC !important; + background-image: none; + border-color:#ACACAC; +} + +.x-grid3-cell-selected{ + background-color: #CBCBCB !important; + color:#000; +} + +.x-grid3-cell-selected span{ + color:#000 !important; +} + +.x-grid3-cell-selected .x-grid3-cell-text{ + color:#000; +} + +.x-grid3-locked td.x-grid3-row-marker, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker{ + background-color:#ebeadb !important; + background-image:url(../images/default/grid/grid-hrow.gif) !important; + color:#000; + border-top-color:#fff; + border-right-color:#6fa0df !important; +} + +.x-grid3-locked td.x-grid3-row-marker div, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div{ + color:#333 !important; +} + +.x-grid3-dirty-cell { + background-image:url(../images/default/grid/dirty.gif); +} + +.x-grid3-topbar, .x-grid3-bottombar{ + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-bottombar .x-toolbar{ + border-top-color:#a9bfd3; +} + +.x-props-grid .x-grid3-td-name .x-grid3-cell-inner{ + background-image:url(../images/default/grid/grid3-special-col-bg.gif) !important; + color:#000 !important; +} + +.x-props-grid .x-grid3-body .x-grid3-td-name{ + background-color:#fff !important; + border-right-color:#eee; +} + +.xg-hmenu-sort-asc .x-menu-item-icon{ + background-image: url(../images/default/grid/hmenu-asc.gif); +} + +.xg-hmenu-sort-desc .x-menu-item-icon{ + background-image: url(../images/default/grid/hmenu-desc.gif); +} + +.xg-hmenu-lock .x-menu-item-icon{ + background-image: url(../images/default/grid/hmenu-lock.gif); +} + +.xg-hmenu-unlock .x-menu-item-icon{ + background-image: url(../images/default/grid/hmenu-unlock.gif); +} + +.x-grid3-hd-btn { + background-color:#f9f9f9; + background-image:url(../images/gray/grid/grid3-hd-btn.gif); +} + +.x-grid3-body .x-grid3-td-expander { + background-image:url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-row-expander { + background-image:url(../images/gray/grid/row-expand-sprite.gif); +} + +.x-grid3-body .x-grid3-td-checker { + background-image: url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-row-checker, .x-grid3-hd-checker { + background-image:url(../images/default/grid/row-check-sprite.gif); +} + +.x-grid3-body .x-grid3-td-numberer { + background-image:url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner { + color:#444; +} + +.x-grid3-body .x-grid3-td-row-icon { + background-image:url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker, +.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander { + background-image:url(../images/gray/grid/grid3-special-col-sel-bg.gif); +} + +.x-grid3-check-col { + background-image:url(../images/default/menu/unchecked.gif); +} + +.x-grid3-check-col-on { + background-image:url(../images/default/menu/checked.gif); +} + +.x-grid-group, .x-grid-group-body, .x-grid-group-hd { + zoom:1; +} + +.x-grid-group-hd { + border-bottom-color:#d0d0d0; +} + +.x-grid-group-hd div.x-grid-group-title { + background-image:url(../images/gray/grid/group-collapse.gif); + color:#5F5F5F; + font:bold 11px tahoma, arial, helvetica, sans-serif; +} + +.x-grid-group-collapsed .x-grid-group-hd div.x-grid-group-title { + background-image:url(../images/gray/grid/group-expand.gif); +} + +.x-group-by-icon { + background-image:url(../images/default/grid/group-by.gif); +} + +.x-cols-icon { + background-image:url(../images/default/grid/columns.gif); +} + +.x-show-groups-icon { + background-image:url(../images/default/grid/group-by.gif); +} + +.x-grid-empty { + color:gray; + font:normal 11px tahoma, arial, helvetica, sans-serif; +} + +.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell { + border-right-color:#ededed; +} + +.x-grid-with-col-lines .x-grid3-row{ + border-top-color:#ededed; +} + +.x-grid-with-col-lines .x-grid3-row-selected { + border-top-color:#B9B9B9; +} +.x-pivotgrid .x-grid3-header-offset table td { + background: url(../images/gray/grid/grid3-hrow2.gif) repeat-x 50% 100%; + border-left: 1px solid; + border-right: 1px solid; + border-left-color: #D0D0D0; + border-right-color: #D0D0D0; +} + +.x-pivotgrid .x-grid3-row-headers { + background-color: #f9f9f9; +} + +.x-pivotgrid .x-grid3-row-headers table td { + background: #EEE url(../images/default/grid/grid3-rowheader.gif) repeat-x left top; + border-left: 1px solid; + border-right: 1px solid; + border-left-color: #EEE; + border-right-color: #D0D0D0; + border-bottom: 1px solid; + border-bottom-color: #D0D0D0; + height: 18px; +} +.x-dd-drag-ghost{ + color:#000; + font: normal 11px arial, helvetica, sans-serif; + border-color: #ddd #bbb #bbb #ddd; + background-color:#fff; +} + +.x-dd-drop-nodrop .x-dd-drop-icon{ + background-image: url(../images/default/dd/drop-no.gif); +} + +.x-dd-drop-ok .x-dd-drop-icon{ + background-image: url(../images/default/dd/drop-yes.gif); +} + +.x-dd-drop-ok-add .x-dd-drop-icon{ + background-image: url(../images/default/dd/drop-add.gif); +} + +.x-view-selector { + background-color:#D6D6D6; + border-color:#888888; +}.x-tree-node-expanded .x-tree-node-icon{ + background-image:url(../images/default/tree/folder-open.gif); +} + +.x-tree-node-leaf .x-tree-node-icon{ + background-image:url(../images/default/tree/leaf.gif); +} + +.x-tree-node-collapsed .x-tree-node-icon{ + background-image:url(../images/default/tree/folder.gif); +} + +.x-tree-node-loading .x-tree-node-icon{ + background-image:url(../images/default/tree/loading.gif) !important; +} + +.x-tree-node .x-tree-node-inline-icon { + background-image: none; +} + +.x-tree-node-loading a span{ + font-style: italic; + color:#444444; +} + +.ext-ie .x-tree-node-el input { + width:15px; + height:15px; +} + +.x-tree-lines .x-tree-elbow{ + background-image:url(../images/default/tree/elbow.gif); +} + +.x-tree-lines .x-tree-elbow-plus{ + background-image:url(../images/default/tree/elbow-plus.gif); +} + +.x-tree-lines .x-tree-elbow-minus{ + background-image:url(../images/default/tree/elbow-minus.gif); +} + +.x-tree-lines .x-tree-elbow-end{ + background-image:url(../images/default/tree/elbow-end.gif); +} + +.x-tree-lines .x-tree-elbow-end-plus{ + background-image:url(../images/gray/tree/elbow-end-plus.gif); +} + +.x-tree-lines .x-tree-elbow-end-minus{ + background-image:url(../images/gray/tree/elbow-end-minus.gif); +} + +.x-tree-lines .x-tree-elbow-line{ + background-image:url(../images/default/tree/elbow-line.gif); +} + +.x-tree-no-lines .x-tree-elbow-plus{ + background-image:url(../images/default/tree/elbow-plus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-minus{ + background-image:url(../images/default/tree/elbow-minus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-end-plus{ + background-image:url(../images/gray/tree/elbow-end-plus-nl.gif); +} + +.x-tree-no-lines .x-tree-elbow-end-minus{ + background-image:url(../images/gray/tree/elbow-end-minus-nl.gif); +} + +.x-tree-arrows .x-tree-elbow-plus{ + background-image:url(../images/gray/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-minus{ + background-image:url(../images/gray/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-end-plus{ + background-image:url(../images/gray/tree/arrows.gif); +} + +.x-tree-arrows .x-tree-elbow-end-minus{ + background-image:url(../images/gray/tree/arrows.gif); +} + +.x-tree-node{ + color:#000; + font: normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-tree-node a, .x-dd-drag-ghost a{ + color:#000; +} + +.x-tree-node a span, .x-dd-drag-ghost a span{ + color:#000; +} + +.x-tree-node .x-tree-node-disabled a span{ + color:gray !important; +} + +.x-tree-node div.x-tree-drag-insert-below{ + border-bottom-color:#36c; +} + +.x-tree-node div.x-tree-drag-insert-above{ + border-top-color:#36c; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-below a{ + border-bottom-color:#36c; +} + +.x-tree-dd-underline .x-tree-node div.x-tree-drag-insert-above a{ + border-top-color:#36c; +} + +.x-tree-node .x-tree-drag-append a span{ + background-color:#ddd; + border-color:gray; +} + +.x-tree-node .x-tree-node-over { + background-color: #eee; +} + +.x-tree-node .x-tree-selected { + background-color: #ddd; +} + +.x-tree-drop-ok-append .x-dd-drop-icon{ + background-image: url(../images/default/tree/drop-add.gif); +} + +.x-tree-drop-ok-above .x-dd-drop-icon{ + background-image: url(../images/default/tree/drop-over.gif); +} + +.x-tree-drop-ok-below .x-dd-drop-icon{ + background-image: url(../images/default/tree/drop-under.gif); +} + +.x-tree-drop-ok-between .x-dd-drop-icon{ + background-image: url(../images/default/tree/drop-between.gif); +} +.x-date-picker { + border-color:#585858; + background-color:#fff; +} + +.x-date-middle,.x-date-left,.x-date-right { + background-image: url(../images/gray/shared/hd-sprite.gif); + color:#fff; + font:bold 11px "sans serif", tahoma, verdana, helvetica; +} + +.x-date-middle .x-btn .x-btn-text { + color:#fff; +} + +.x-date-middle .x-btn-mc em.x-btn-arrow { + background-image:url(../images/gray/toolbar/btn-arrow-light.gif); +} + +.x-date-right a { + background-image: url(../images/gray/shared/right-btn.gif); +} + +.x-date-left a{ + background-image: url(../images/gray/shared/left-btn.gif); +} + +.x-date-inner th { + background-color:#D8D8D8; + background-image: url(../images/gray/panel/white-top-bottom.gif); + border-bottom-color:#AFAFAF; + font:normal 10px arial, helvetica,tahoma,sans-serif; + color:#595959; +} + +.x-date-inner td { + border-color:#fff; +} + +.x-date-inner a { + font:normal 11px arial, helvetica,tahoma,sans-serif; + color:#000; +} + +.x-date-inner .x-date-active{ + color:#000; +} + +.x-date-inner .x-date-selected a{ + background-image: none; + background-color:#D8D8D8; + border-color:#DCDCDC; +} + +.x-date-inner .x-date-today a{ + border-color:darkred; +} + +.x-date-inner .x-date-selected span{ + font-weight:bold; +} + +.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a { + color:#aaa; +} + +.x-date-bottom { + border-top-color:#AFAFAF; + background-color:#D8D8D8; + background:#D8D8D8 url(../images/gray/panel/white-top-bottom.gif) 0 -2px; +} + +.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{ + color:#000; + background-color:#D8D8D8; +} + +.x-date-inner .x-date-disabled a { + background-color:#eee; + color:#bbb; +} + +.x-date-mmenu{ + background-color:#eee !important; +} + +.x-date-mmenu .x-menu-item { + font-size:10px; + color:#000; +} + +.x-date-mp { + background-color:#fff; +} + +.x-date-mp td { + font:normal 11px arial, helvetica,tahoma,sans-serif; +} + +.x-date-mp-btns button { + background-color:#4E565F; + color:#fff; + border-color:#C0C0C0 #434343 #434343 #C0C0C0; + font:normal 11px arial, helvetica,tahoma,sans-serif; +} + +.x-date-mp-btns { + background-color:#D8D8D8; + background:#D8D8D8 url(../images/gray/panel/white-top-bottom.gif) 0 -2px; +} + +.x-date-mp-btns td { + border-top-color:#AFAFAF; +} + +td.x-date-mp-month a,td.x-date-mp-year a { + color: #333; +} + +td.x-date-mp-month a:hover,td.x-date-mp-year a:hover { + color:#333; + background-color:#FDFDFD; +} + +td.x-date-mp-sel a { + background-color:#D8D8D8; + background:#D8D8D8 url(../images/gray/panel/white-top-bottom.gif) 0 -2px; + border-color:#DCDCDC; +} + +.x-date-mp-ybtn a { + background-image:url(../images/gray/panel/tool-sprites.gif); +} + +td.x-date-mp-sep { + border-right-color:#D7D7D7; +}.x-tip .x-tip-close{ + background-image: url(../images/gray/qtip/close.gif); +} + +.x-tip .x-tip-tc, .x-tip .x-tip-tl, .x-tip .x-tip-tr, .x-tip .x-tip-bc, .x-tip .x-tip-bl, .x-tip .x-tip-br, .x-tip .x-tip-ml, .x-tip .x-tip-mr { + background-image: url(../images/gray/qtip/tip-sprite.gif); +} + +.x-tip .x-tip-mc { + font: normal 11px tahoma,arial,helvetica,sans-serif; +} +.x-tip .x-tip-ml { + background-color: #fff; +} + +.x-tip .x-tip-header-text { + font: bold 11px tahoma,arial,helvetica,sans-serif; + color:#444; +} + +.x-tip .x-tip-body { + font: normal 11px tahoma,arial,helvetica,sans-serif; + color:#444; +} + +.x-form-invalid-tip .x-tip-tc, .x-form-invalid-tip .x-tip-tl, .x-form-invalid-tip .x-tip-tr, .x-form-invalid-tip .x-tip-bc, +.x-form-invalid-tip .x-tip-bl, .x-form-invalid-tip .x-tip-br, .x-form-invalid-tip .x-tip-ml, .x-form-invalid-tip .x-tip-mr +{ + background-image: url(../images/default/form/error-tip-corners.gif); +} + +.x-form-invalid-tip .x-tip-body { + background-image:url(../images/default/form/exclamation.gif); +} + +.x-tip-anchor { + background-image:url(../images/gray/qtip/tip-anchor-sprite.gif); +}.x-menu { + background-color:#f0f0f0; + background-image:url(../images/default/menu/menu.gif); +} + +.x-menu-floating{ + border-color:#7D7D7D; +} + +.x-menu-nosep { + background-image:none; +} + +.x-menu-list-item{ + font:normal 11px arial,tahoma,sans-serif; +} + +.x-menu-item-arrow{ + background-image:url(../images/gray/menu/menu-parent.gif); +} + +.x-menu-sep { + background-color:#e0e0e0; + border-bottom-color:#fff; +} + +a.x-menu-item { + color:#222; +} + +.x-menu-item-active { + background-image: url(../images/gray/menu/item-over.gif); + background-color: #f1f1f1; + border-color:#ACACAC; +} + +.x-menu-item-active a.x-menu-item { + border-color:#ACACAC; +} + +.x-menu-check-item .x-menu-item-icon{ + background-image:url(../images/default/menu/unchecked.gif); +} + +.x-menu-item-checked .x-menu-item-icon{ + background-image:url(../images/default/menu/checked.gif); +} + +.x-menu-item-checked .x-menu-group-item .x-menu-item-icon{ + background-image:url(../images/gray/menu/group-checked.gif); +} + +.x-menu-group-item .x-menu-item-icon{ + background-image:none; +} + +.x-menu-plain { + background-color:#fff !important; +} + +.x-menu .x-date-picker{ + border-color:#AFAFAF; +} + +.x-cycle-menu .x-menu-item-checked { + border-color:#B9B9B9 !important; + background-color:#F1F1F1; +} + +.x-menu-scroller-top { + background-image:url(../images/default/layout/mini-top.gif); +} + +.x-menu-scroller-bottom { + background-image:url(../images/default/layout/mini-bottom.gif); +}.x-box-tl { + background-image: url(../images/default/box/corners.gif); +} + +.x-box-tc { + background-image: url(../images/default/box/tb.gif); +} + +.x-box-tr { + background-image: url(../images/default/box/corners.gif); +} + +.x-box-ml { + background-image: url(../images/default/box/l.gif); +} + +.x-box-mc { + background-color: #eee; + background-image: url(../images/default/box/tb.gif); + font-family: "Myriad Pro","Myriad Web","Tahoma","Helvetica","Arial",sans-serif; + color: #393939; + font-size: 12px; +} + +.x-box-mc h3 { + font-size: 14px; + font-weight: bold; +} + +.x-box-mr { + background-image: url(../images/default/box/r.gif); +} + +.x-box-bl { + background-image: url(../images/default/box/corners.gif); +} + +.x-box-bc { + background-image: url(../images/default/box/tb.gif); +} + +.x-box-br { + background-image: url(../images/default/box/corners.gif); +} + +.x-box-blue .x-box-bl, .x-box-blue .x-box-br, .x-box-blue .x-box-tl, .x-box-blue .x-box-tr { + background-image: url(../images/default/box/corners-blue.gif); +} + +.x-box-blue .x-box-bc, .x-box-blue .x-box-mc, .x-box-blue .x-box-tc { + background-image: url(../images/default/box/tb-blue.gif); +} + +.x-box-blue .x-box-mc { + background-color: #c3daf9; +} + +.x-box-blue .x-box-mc h3 { + color: #17385b; +} + +.x-box-blue .x-box-ml { + background-image: url(../images/default/box/l-blue.gif); +} + +.x-box-blue .x-box-mr { + background-image: url(../images/default/box/r-blue.gif); +} +.x-combo-list { + border-color:#ccc; + background-color:#ddd; + font:normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-combo-list-inner { + background-color:#fff; +} + +.x-combo-list-hd { + font:bold 11px tahoma, arial, helvetica, sans-serif; + color:#333; + background-image: url(../images/default/layout/panel-title-light-bg.gif); + border-bottom-color:#BCBCBC; +} + +.x-resizable-pinned .x-combo-list-inner { + border-bottom-color:#BEBEBE; +} + +.x-combo-list-item { + border-color:#fff; +} + +.x-combo-list .x-combo-selected{ + border-color:#777 !important; + background-color:#f0f0f0; +} + +.x-combo-list .x-toolbar { + border-top-color:#BCBCBC; +} + +.x-combo-list-small { + font:normal 11px tahoma, arial, helvetica, sans-serif; +}.x-panel { + border-color: #d0d0d0; +} + +.x-panel-header { + color:#333; + font-weight:bold; + font-size: 11px; + font-family: tahoma,arial,verdana,sans-serif; + border-color:#d0d0d0; + background-image: url(../images/gray/panel/white-top-bottom.gif); +} + +.x-panel-body { + border-color:#d0d0d0; + background-color:#fff; +} + +.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar { + border-color:#d0d0d0; +} + +.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar { + border-top-color:#d0d0d0; +} + +.x-panel-body-noheader, .x-panel-mc .x-panel-body { + border-top-color:#d0d0d0; +} + +.x-panel-tl .x-panel-header { + color:#333; + font:bold 11px tahoma,arial,verdana,sans-serif; +} + +.x-panel-tc { + background-image: url(../images/gray/panel/top-bottom.gif); +} + +.x-panel-tl, .x-panel-tr, .x-panel-bl, .x-panel-br{ + background-image: url(../images/gray/panel/corners-sprite.gif); + border-bottom-color:#d0d0d0; +} + +.x-panel-bc { + background-image: url(../images/gray/panel/top-bottom.gif); +} + +.x-panel-mc { + font: normal 11px tahoma,arial,helvetica,sans-serif; + background-color:#f1f1f1; +} + +.x-panel-ml { + background-color: #fff; + background-image:url(../images/gray/panel/left-right.gif); +} + +.x-panel-mr { + background-image: url(../images/gray/panel/left-right.gif); +} + +.x-tool { + background-image:url(../images/gray/panel/tool-sprites.gif); +} + +.x-panel-ghost { + background-color:#f2f2f2; +} + +.x-panel-ghost ul { + border-color:#d0d0d0; +} + +.x-panel-dd-spacer { + border-color:#d0d0d0; +} + +.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{ + font:normal 11px arial,tahoma, helvetica, sans-serif; +} +.x-window-proxy { + background-color:#fcfcfc; + border-color:#d0d0d0; +} + +.x-window-tl .x-window-header { + color:#555; + font:bold 11px tahoma,arial,verdana,sans-serif; +} + +.x-window-tc { + background-image: url(../images/gray/window/top-bottom.png); +} + +.x-window-tl { + background-image: url(../images/gray/window/left-corners.png); +} + +.x-window-tr { + background-image: url(../images/gray/window/right-corners.png); +} + +.x-window-bc { + background-image: url(../images/gray/window/top-bottom.png); +} + +.x-window-bl { + background-image: url(../images/gray/window/left-corners.png); +} + +.x-window-br { + background-image: url(../images/gray/window/right-corners.png); +} + +.x-window-mc { + border-color:#d0d0d0; + font: normal 11px tahoma,arial,helvetica,sans-serif; + background-color:#e8e8e8; +} + +.x-window-ml { + background-image: url(../images/gray/window/left-right.png); +} + +.x-window-mr { + background-image: url(../images/gray/window/left-right.png); +} + +.x-window-maximized .x-window-tc { + background-color:#fff; +} + +.x-window-bbar .x-toolbar { + border-top-color:#d0d0d0; +} + +.x-panel-ghost .x-window-tl { + border-bottom-color:#d0d0d0; +} + +.x-panel-collapsed .x-window-tl { + border-bottom-color:#d0d0d0; +} + +.x-dlg-mask{ + background-color:#ccc; +} + +.x-window-plain .x-window-mc { + background-color: #E8E8E8; + border-color: #D0D0D0 #EEEEEE #EEEEEE #D0D0D0; +} + +.x-window-plain .x-window-body { + border-color: #EEEEEE #D0D0D0 #D0D0D0 #EEEEEE; +} + +body.x-body-masked .x-window-plain .x-window-mc { + background-color: #E4E4E4; +} +.x-html-editor-wrap { + border-color:#BCBCBC; + background-color:#fff; +} +.x-html-editor-tb .x-btn-text { + background-image:url(../images/default/editor/tb-sprite.gif); +} +.x-panel-noborder .x-panel-header-noborder { + border-bottom-color:#d0d0d0; +} + +.x-panel-noborder .x-panel-tbar-noborder .x-toolbar { + border-bottom-color:#d0d0d0; +} + +.x-panel-noborder .x-panel-bbar-noborder .x-toolbar { + border-top-color:#d0d0d0; +} + +.x-tab-panel-bbar-noborder .x-toolbar { + border-top-color:#d0d0d0; +} + +.x-tab-panel-tbar-noborder .x-toolbar { + border-bottom-color:#d0d0d0; +} + +.x-border-layout-ct { + background-color:#f0f0f0; +} +.x-border-layout-ct { + background-color:#f0f0f0; +} + +.x-accordion-hd { + color:#222; + font-weight:normal; + background-image: url(../images/gray/panel/light-hd.gif); +} + +.x-layout-collapsed{ + background-color:#dfdfdf; + border-color:#d0d0d0; +} + +.x-layout-collapsed-over{ + background-color:#e7e7e7; +} + +.x-layout-split-west .x-layout-mini { + background-image:url(../images/default/layout/mini-left.gif); +} +.x-layout-split-east .x-layout-mini { + background-image:url(../images/default/layout/mini-right.gif); +} +.x-layout-split-north .x-layout-mini { + background-image:url(../images/default/layout/mini-top.gif); +} +.x-layout-split-south .x-layout-mini { + background-image:url(../images/default/layout/mini-bottom.gif); +} + +.x-layout-cmini-west .x-layout-mini { + background-image:url(../images/default/layout/mini-right.gif); +} + +.x-layout-cmini-east .x-layout-mini { + background-image:url(../images/default/layout/mini-left.gif); +} + +.x-layout-cmini-north .x-layout-mini { + background-image:url(../images/default/layout/mini-bottom.gif); +} + +.x-layout-cmini-south .x-layout-mini { + background-image:url(../images/default/layout/mini-top.gif); +} +.x-progress-wrap { + border-color:#8E8E8E; +} + +.x-progress-inner { + background-color:#E7E7E7; + background-image:url(../images/gray/qtip/bg.gif); +} + +.x-progress-bar { + background-color:#BCBCBC; + background-image:url(../images/gray/progress/progress-bg.gif); + border-top-color:#E2E2E2; + border-bottom-color:#A4A4A4; + border-right-color:#A4A4A4; +} + +.x-progress-text { + font-size:11px; + font-weight:bold; + color:#fff; +} + +.x-progress-text-back { + color:#5F5F5F; +} +.x-list-header{ + background-color:#f9f9f9; + background-image:url(../images/gray/grid/grid3-hrow2.gif); +} + +.x-list-header-inner div em { + border-left-color:#ddd; + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-list-body dt em { + font:normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-list-over { + background-color:#eee; +} + +.x-list-selected { + background-color:#f0f0f0; +} + +.x-list-resizer { + border-left-color:#555; + border-right-color:#555; +} + +.x-list-header-inner em.sort-asc, .x-list-header-inner em.sort-desc { + background-image:url(../images/gray/grid/sort-hd.gif); + border-color: #d0d0d0; +} +.x-slider-horz, .x-slider-horz .x-slider-end, .x-slider-horz .x-slider-inner { + background-image:url(../images/default/slider/slider-bg.png); +} + +.x-slider-horz .x-slider-thumb { + background-image:url(../images/gray/slider/slider-thumb.png); +} + +.x-slider-vert, .x-slider-vert .x-slider-end, .x-slider-vert .x-slider-inner { + background-image:url(../images/default/slider/slider-v-bg.png); +} + +.x-slider-vert .x-slider-thumb { + background-image:url(../images/gray/slider/slider-v-thumb.png); +} +.x-window-dlg .ext-mb-text, +.x-window-dlg .x-window-header-text { + font-size:12px; +} + +.x-window-dlg .ext-mb-textarea { + font:normal 12px tahoma,arial,helvetica,sans-serif; +} + +.x-window-dlg .x-msg-box-wait { + background-image:url(../images/default/grid/loading.gif); +} + +.x-window-dlg .ext-mb-info { + background-image:url(../images/gray/window/icon-info.gif); +} + +.x-window-dlg .ext-mb-warning { + background-image:url(../images/gray/window/icon-warning.gif); +} + +.x-window-dlg .ext-mb-question { + background-image:url(../images/gray/window/icon-question.gif); +} + +.x-window-dlg .ext-mb-error { + background-image:url(../images/gray/window/icon-error.gif); +} diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/fonts/roboto.woff b/salt/idh/skins/http/opencanary/nasLogin/static/fonts/roboto.woff new file mode 100644 index 000000000..1440b1be6 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/fonts/roboto.woff differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/02.jpg b/salt/idh/skins/http/opencanary/nasLogin/static/img/02.jpg new file mode 100644 index 000000000..b84b76f92 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/02.jpg differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/favicon.ico b/salt/idh/skins/http/opencanary/nasLogin/static/img/favicon.ico new file mode 100644 index 000000000..cafbf0458 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/favicon.ico differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_16.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_16.png new file mode 100644 index 000000000..f2ae9dae8 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_16.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_32.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_32.png new file mode 100644 index 000000000..b7193aaa0 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_32.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_48.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_48.png new file mode 100644 index 000000000..d8f5388e5 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_48.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_64.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_64.png new file mode 100644 index 000000000..cd79763d8 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_64.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_96.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_96.png new file mode 100644 index 000000000..0fb84d4d3 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_dsm_96.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_tile.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_tile.png new file mode 100644 index 000000000..e3ed42ece Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/icon_tile.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/bt_dropdown.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/bt_dropdown.png new file mode 100644 index 000000000..8b3b0efe7 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/bt_dropdown.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/bt_grid_dropdown.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/bt_grid_dropdown.png new file mode 100644 index 000000000..3d33c8698 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/bt_grid_dropdown.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/bt_pagebar.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/bt_pagebar.png new file mode 100644 index 000000000..b86eccb2f Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/bt_pagebar.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/c_icon_general.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/c_icon_general.png new file mode 100644 index 000000000..ff5e6bb19 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/c_icon_general.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/category_expand.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/category_expand.png new file mode 100644 index 000000000..54bc5dc74 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/category_expand.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/checkbox.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/checkbox.png new file mode 100644 index 000000000..d33494c73 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/checkbox.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/col-move-bottom.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/col-move-bottom.png new file mode 100644 index 000000000..730c355e8 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/col-move-bottom.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/date_dropdown.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/date_dropdown.png new file mode 100644 index 000000000..e8ba17a37 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/date_dropdown.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/date_prev_next.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/date_prev_next.png new file mode 100644 index 000000000..8d0805e86 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/date_prev_next.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/dropdown_menu_parent.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/dropdown_menu_parent.png new file mode 100644 index 000000000..034893ac7 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/dropdown_menu_parent.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/dropdown_menu_tick.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/dropdown_menu_tick.png new file mode 100644 index 000000000..f7818d510 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/dropdown_menu_tick.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/fieldset_expand.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/fieldset_expand.png new file mode 100644 index 000000000..ac42a1736 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/fieldset_expand.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_advanced_search.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_advanced_search.png new file mode 100644 index 000000000..6a2e5c69e Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_advanced_search.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_error.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_error.png new file mode 100644 index 000000000..fe6e9e18a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_error.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_filter.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_filter.png new file mode 100644 index 000000000..dea078087 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_filter.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_information.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_information.png new file mode 100644 index 000000000..ba07815aa Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_information.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_loading.gif b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_loading.gif new file mode 100644 index 000000000..1c073f400 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_loading.gif differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_search.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_search.png new file mode 100644 index 000000000..d5e69e50a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_search.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_search_clear.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_search_clear.png new file mode 100644 index 000000000..b3a7b7486 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_search_clear.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_success.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_success.png new file mode 100644 index 000000000..998025eb2 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/icon_success.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/radio_button.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/radio_button.png new file mode 100644 index 000000000..94ee76f3a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/radio_button.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/shadow_category.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/shadow_category.png new file mode 100644 index 000000000..7d3c08b20 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/shadow_category.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/shadow_footbar.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/shadow_footbar.png new file mode 100644 index 000000000..3f7831369 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/shadow_footbar.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/superbox_button_cancel.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/superbox_button_cancel.png new file mode 100644 index 000000000..9d89ffa35 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/superbox_button_cancel.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/tab_arrow.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/tab_arrow.png new file mode 100644 index 000000000..546739246 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/tab_arrow.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/tab_shadow.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/tab_shadow.png new file mode 100644 index 000000000..32e3fa57c Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/tab_shadow.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/tree_arrow.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/tree_arrow.png new file mode 100644 index 000000000..3ca5234fb Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/tree_arrow.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/trigger.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/trigger.png new file mode 100644 index 000000000..89cc0e4c8 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/trigger.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/trigger_date.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/trigger_date.png new file mode 100644 index 000000000..f96efaa7f Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/Components/trigger_date.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/ExternalDevices/images/tray_icon_device.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/ExternalDevices/images/tray_icon_device.png new file mode 100644 index 000000000..e9a566619 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/ExternalDevices/images/tray_icon_device.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_bgtask.gif b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_bgtask.gif new file mode 100644 index 000000000..d0d9218ff Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_bgtask.gif differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_bgtask.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_bgtask.png new file mode 100644 index 000000000..2db01970b Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_bgtask.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_download.gif b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_download.gif new file mode 100644 index 000000000..de877b8eb Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_download.gif differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_download.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_download.png new file mode 100644 index 000000000..9d7951dbf Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_download.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_upload.gif b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_upload.gif new file mode 100644 index 000000000..cda7be6f0 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_upload.gif differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_upload.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_upload.png new file mode 100644 index 000000000..7f9d2781d Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/FileTaskMonitor/images/tray_icon_upload.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/PollingTask/images/tray_icon_disk_port.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/PollingTask/images/tray_icon_disk_port.png new file mode 100644 index 000000000..b66b079d4 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/PollingTask/images/tray_icon_disk_port.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.gif b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.gif new file mode 100644 index 000000000..72717ba26 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.gif differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.png new file mode 100644 index 000000000..0050b8054 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/modules/ThumbConvertProgress/images/tray_icon_creating_thumbnail.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/bt_bugs.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/bt_bugs.png new file mode 100644 index 000000000..c1f28e6b6 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/bt_bugs.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/bt_dsm_mobile.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/bt_dsm_mobile.png new file mode 100644 index 000000000..befd6ecb4 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/bt_dsm_mobile.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/icon_error.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/icon_error.png new file mode 100644 index 000000000..e33d02828 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/icon_error.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/icon_image_selector.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/icon_image_selector.png new file mode 100644 index 000000000..4ae2f3a71 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/icon_image_selector.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/status_fail.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/status_fail.png new file mode 100644 index 000000000..faaa183a8 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/status_fail.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/status_loading.gif b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/status_loading.gif new file mode 100644 index 000000000..824fde78c Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/status_loading.gif differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/status_success.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/status_success.png new file mode 100644 index 000000000..388c5275e Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/components/status_success.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/add_one.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/add_one.png new file mode 100644 index 000000000..ca1d78cb3 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/add_one.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/icon_app_category.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/icon_app_category.png new file mode 100644 index 000000000..0e613466b Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/icon_app_category.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/spotlight.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/spotlight.png new file mode 100644 index 000000000..ec846e9d1 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/spotlight.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/taskbar_spinner.gif b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/taskbar_spinner.gif new file mode 100644 index 000000000..c28099211 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/desktop/taskbar_spinner.gif differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsm5_badge_num.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsm5_badge_num.png new file mode 100644 index 000000000..b90aa0345 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsm5_badge_num.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsm5_notification_num.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsm5_notification_num.png new file mode 100644 index 000000000..daa7909be Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsm5_notification_num.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsmv5_wizard_bkg_v_01.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsmv5_wizard_bkg_v_01.png new file mode 100644 index 000000000..74fce0530 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsmv5_wizard_bkg_v_01.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsmv5_wizard_bkg_v_02.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsmv5_wizard_bkg_v_02.png new file mode 100644 index 000000000..acfc1b352 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/dsmv5_wizard_bkg_v_02.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/folder.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/folder.png new file mode 100644 index 000000000..5545cbb85 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/folder.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/icon_drag_add.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/icon_drag_add.png new file mode 100644 index 000000000..9fc453da0 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/icon_drag_add.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/icon_drag_ban.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/icon_drag_ban.png new file mode 100644 index 000000000..db8d20c63 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/icon_drag_ban.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/icon_question.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/icon_question.png new file mode 100644 index 000000000..6c0cace9a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/icon_question.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/item_drag_status.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/item_drag_status.png new file mode 100644 index 000000000..0e3e45abd Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/item_drag_status.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/0.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/0.png new file mode 100644 index 000000000..13983c458 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/0.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/1.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/1.png new file mode 100644 index 000000000..7b425ef11 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/1.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/2.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/2.png new file mode 100644 index 000000000..895e68ba5 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/2.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/3.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/3.png new file mode 100644 index 000000000..c81985ab1 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/3.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/4.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/4.png new file mode 100644 index 000000000..5b155a1e9 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/4.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/5dot.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/5dot.png new file mode 100644 index 000000000..a7c8c7c34 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/5dot.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/DSM.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/DSM.png new file mode 100644 index 000000000..60c92f2dc Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/DSM.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/beta.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/beta.png new file mode 100644 index 000000000..84aab8f89 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/beta.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/copyright_2014.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/copyright_2014.png new file mode 100644 index 000000000..6c151700e Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/copyright_2014.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/copyright_2015.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/copyright_2015.png new file mode 100644 index 000000000..0a12707e4 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/copyright_2015.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/synology.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/synology.png new file mode 100644 index 000000000..704aeb1be Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/dark/synology.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/icon_phone.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/icon_phone.png new file mode 100644 index 000000000..05009714a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/icon_phone.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/icon_pw.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/icon_pw.png new file mode 100644 index 000000000..acb35fd3f Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/icon_pw.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/icon_user.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/icon_user.png new file mode 100644 index 000000000..70a4f7091 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/icon_user.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/0.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/0.png new file mode 100644 index 000000000..cc04df60a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/0.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/1.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/1.png new file mode 100644 index 000000000..b600e46d1 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/1.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/2.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/2.png new file mode 100644 index 000000000..e20d1bbec Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/2.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/3.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/3.png new file mode 100644 index 000000000..25e8a7407 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/3.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/4.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/4.png new file mode 100644 index 000000000..485c56560 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/4.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/5dot.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/5dot.png new file mode 100644 index 000000000..5e1af80e8 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/5dot.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/DSM.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/DSM.png new file mode 100644 index 000000000..4834292b5 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/DSM.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/beta.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/beta.png new file mode 100644 index 000000000..52c96e4fb Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/beta.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/copyright_2014.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/copyright_2014.png new file mode 100644 index 000000000..6c151700e Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/copyright_2014.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/copyright_2015.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/copyright_2015.png new file mode 100644 index 000000000..0a12707e4 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/copyright_2015.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/synology.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/synology.png new file mode 100644 index 000000000..61da232c4 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/light/synology.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_bottom.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_bottom.png new file mode 100644 index 000000000..dc1e35bf8 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_bottom.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_top.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_top.png new file mode 100644 index 000000000..2076eec05 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/login_bkg_highlight_top.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_cloudy.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_cloudy.png new file mode 100644 index 000000000..a55e57e7c Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_cloudy.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_cold.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_cold.png new file mode 100644 index 000000000..27a7d8b1d Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_cold.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_fog.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_fog.png new file mode 100644 index 000000000..171f6e374 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_fog.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_hail.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_hail.png new file mode 100644 index 000000000..4ab0372f9 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_hail.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_moon.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_moon.png new file mode 100644 index 000000000..fce03fd79 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_moon.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_moon_clouds.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_moon_clouds.png new file mode 100644 index 000000000..c7999b257 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_moon_clouds.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_rain.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_rain.png new file mode 100644 index 000000000..e2efcfa32 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_rain.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_snow.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_snow.png new file mode 100644 index 000000000..3587ab8c2 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_snow.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_sun.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_sun.png new file mode 100644 index 000000000..e3a53804c Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_sun.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_sun_clouds.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_sun_clouds.png new file mode 100644 index 000000000..1ec55095e Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_sun_clouds.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_thunder.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_thunder.png new file mode 100644 index 000000000..1048e4548 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_thunder.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_tornado.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_tornado.png new file mode 100644 index 000000000..7991621fd Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_tornado.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_windy.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_windy.png new file mode 100644 index 000000000..ca93ce5f3 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/login/weather/login_icon_weather_windy.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_CMS.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_CMS.png new file mode 100644 index 000000000..3903649fd Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_CMS.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_backup.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_backup.png new file mode 100644 index 000000000..5ca546c49 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_backup.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_business.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_business.png new file mode 100644 index 000000000..e2eaede30 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_business.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_community.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_community.png new file mode 100644 index 000000000..75249b172 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_community.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_connect.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_connect.png new file mode 100644 index 000000000..4985683cf Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_connect.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_contact.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_contact.png new file mode 100644 index 000000000..63df0c657 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_contact.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_directory_service.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_directory_service.png new file mode 100644 index 000000000..7c841025a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_directory_service.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_dsm_apps.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_dsm_apps.png new file mode 100644 index 000000000..434ac2671 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_dsm_apps.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_expansion.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_expansion.png new file mode 100644 index 000000000..c13cd5297 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_expansion.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_external_devices.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_external_devices.png new file mode 100644 index 000000000..68e06d6ba Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_external_devices.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_file_services.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_file_services.png new file mode 100644 index 000000000..e59fecdd6 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_file_services.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_general.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_general.png new file mode 100644 index 000000000..ff5e6bb19 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_general.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_groups.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_groups.png new file mode 100644 index 000000000..db5cc8092 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_groups.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hardware_and_power.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hardware_and_power.png new file mode 100644 index 000000000..cbf3c75f1 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hardware_and_power.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hdd_management.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hdd_management.png new file mode 100644 index 000000000..1413da3b5 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hdd_management.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hot_spare.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hot_spare.png new file mode 100644 index 000000000..6e157d45e Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_hot_spare.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_info_center.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_info_center.png new file mode 100644 index 000000000..2138638c5 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_info_center.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_installed.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_installed.png new file mode 100644 index 000000000..76ef52532 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_installed.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_iscsi_lun.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_iscsi_lun.png new file mode 100644 index 000000000..8698a8336 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_iscsi_lun.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_iscsi_target.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_iscsi_target.png new file mode 100644 index 000000000..96c6a5c7c Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_iscsi_target.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_login_style.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_login_style.png new file mode 100644 index 000000000..a1ca3685e Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_login_style.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_media_library.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_media_library.png new file mode 100644 index 000000000..7e1477f60 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_media_library.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_network.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_network.png new file mode 100644 index 000000000..4914a1a4b Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_network.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_networkmap.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_networkmap.png new file mode 100644 index 000000000..85b699cce Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_networkmap.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_notifications.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_notifications.png new file mode 100644 index 000000000..c950dbde7 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_notifications.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_overview.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_overview.png new file mode 100644 index 000000000..d5c822fbd Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_overview.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_performance.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_performance.png new file mode 100644 index 000000000..68ceedf07 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_performance.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_portal.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_portal.png new file mode 100644 index 000000000..1a717dc6b Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_portal.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_privilege.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_privilege.png new file mode 100644 index 000000000..e2fc6c2a8 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_privilege.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_process.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_process.png new file mode 100644 index 000000000..fd1d6061a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_process.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_public_access.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_public_access.png new file mode 100644 index 000000000..4933fe14c Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_public_access.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_purchases.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_purchases.png new file mode 100644 index 000000000..ba6c8e2a1 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_purchases.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_quickconnect.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_quickconnect.png new file mode 100644 index 000000000..c3045a6a6 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_quickconnect.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_raid_group.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_raid_group.png new file mode 100644 index 000000000..e0ab69a9f Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_raid_group.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_recommend.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_recommend.png new file mode 100644 index 000000000..37a41fda2 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_recommend.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_region.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_region.png new file mode 100644 index 000000000..a41231806 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_region.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_security.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_security.png new file mode 100644 index 000000000..027d9811c Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_security.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_shared_folders.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_shared_folders.png new file mode 100644 index 000000000..84d068766 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_shared_folders.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_speed.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_speed.png new file mode 100644 index 000000000..4d3a18c01 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_speed.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_ssd_cache.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_ssd_cache.png new file mode 100644 index 000000000..acd9539c3 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_ssd_cache.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_syslog.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_syslog.png new file mode 100644 index 000000000..612513cff Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_syslog.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_task_scheduler.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_task_scheduler.png new file mode 100644 index 000000000..291c4c71f Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_task_scheduler.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_terminal_and_SNMP.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_terminal_and_SNMP.png new file mode 100644 index 000000000..82b688da0 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_terminal_and_SNMP.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_update_and_reset.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_update_and_reset.png new file mode 100644 index 000000000..33e9b7091 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_update_and_reset.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_users.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_users.png new file mode 100644 index 000000000..5b26404dc Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_users.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_utilities.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_utilities.png new file mode 100644 index 000000000..579bba939 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_utilities.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_volume.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_volume.png new file mode 100644 index 000000000..fad9aa6d0 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_volume.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_web_server.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_web_server.png new file mode 100644 index 000000000..101e5e7b3 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_web_server.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_wireless.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_wireless.png new file mode 100644 index 000000000..7ae063c77 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/module_list_icon/c_icon_wireless.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/rt_button.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/rt_button.png new file mode 100644 index 000000000..3d4f4d68a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/rt_button.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/shadow_footbar.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/shadow_footbar.png new file mode 100644 index 000000000..3f7831369 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/shadow_footbar.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/more_apps.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/more_apps.png new file mode 100644 index 000000000..e533d7c2d Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/more_apps.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/showdesktop.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/showdesktop.png new file mode 100644 index 000000000..7838c6bed Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/showdesktop.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bg.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bg.png new file mode 100644 index 000000000..8d02f577f Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bg.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bt.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bt.png new file mode 100644 index 000000000..8639e527b Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bt.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bt_apps.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bt_apps.png new file mode 100644 index 000000000..7be67834d Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bt_apps.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bt_widgets_shadow.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bt_widgets_shadow.png new file mode 100644 index 000000000..f17628080 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_bt_widgets_shadow.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_shadow.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_shadow.png new file mode 100644 index 000000000..a333532af Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_shadow.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_split.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_split.png new file mode 100644 index 000000000..b731ff8f5 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/taskbar_split.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_notification.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_notification.png new file mode 100644 index 000000000..9db54ed49 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_notification.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_pilot_view.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_pilot_view.png new file mode 100644 index 000000000..5c1672c80 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_pilot_view.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_search.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_search.png new file mode 100644 index 000000000..665d12961 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_search.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_user_menu.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_user_menu.png new file mode 100644 index 000000000..6d7c3f7f3 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_user_menu.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_widget.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_widget.png new file mode 100644 index 000000000..00fcee5bf Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/tray_icon_widget.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_about.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_about.png new file mode 100644 index 000000000..905febfed Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_about.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_logout.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_logout.png new file mode 100644 index 000000000..e848c372a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_logout.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_options.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_options.png new file mode 100644 index 000000000..b979d9e28 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_options.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_restart.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_restart.png new file mode 100644 index 000000000..8a0d37d58 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_restart.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_shutdown.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_shutdown.png new file mode 100644 index 000000000..419280030 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/taskbar/user_menu_shutdown.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/widget_window/widget_rt_button.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/widget_window/widget_rt_button.png new file mode 100644 index 000000000..828bd5e2a Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/widget_window/widget_rt_button.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/wizard_bkg_h.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/wizard_bkg_h.png new file mode 100644 index 000000000..b1d95bc84 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/dsm/resources/images/wizard_bkg_h.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_black_h.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_black_h.png new file mode 100644 index 000000000..33ccb4751 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_black_h.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_black_v.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_black_v.png new file mode 100644 index 000000000..152de2531 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_black_v.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_white_h.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_white_h.png new file mode 100644 index 000000000..f3680b1eb Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_white_h.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_white_v.png b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_white_v.png new file mode 100644 index 000000000..4991e7d54 Binary files /dev/null and b/salt/idh/skins/http/opencanary/nasLogin/static/img/synohdpack/images/scrollbar/scrollbar_white_v.png differ diff --git a/salt/idh/skins/http/opencanary/nasLogin/static/js/misc.js b/salt/idh/skins/http/opencanary/nasLogin/static/js/misc.js new file mode 100644 index 000000000..d602a0e4c --- /dev/null +++ b/salt/idh/skins/http/opencanary/nasLogin/static/js/misc.js @@ -0,0 +1,53 @@ +"use strict"; + +var montharray = new Array(); +montharray[0] = "Jan"; +montharray[1] = "Feb"; +montharray[2] = "Mar"; +montharray[3] = "Apr"; +montharray[4] = "May"; +montharray[5] = "Jun"; +montharray[6] = "Jul"; +montharray[7] = "Aug"; +montharray[8] = "Sep"; +montharray[9] = "Oct"; +montharray[10] = "Nov"; +montharray[11] = "Dec"; + +var dayarray = new Array(); +dayarray[0] = "Sun"; +dayarray[1] = "Mon"; +dayarray[2] = "Tue"; +dayarray[3] = "Wed"; +dayarray[4] = "Thu"; +dayarray[5] = "Fri"; +dayarray[6] = "Sat"; + + +function updateTime() { +var d = new Date(); +var h = d.getHours(); +var m = d.getMinutes(); +m = new String(m); +if (m.length == 1) + m = "0" + m; + +var pms = "AM"; +if (h > 12) +{ +pms = "PM" +h = h % 12; +} + +document.getElementById('ext-comp-1007').innerHTML = h + ":" + m + '' + pms + ''; + +var month = montharray[d.getMonth()]; +var wkday = dayarray[d.getDay()]; +var day = d.getDate(); + +document.getElementById('ext-comp-1008').innerHTML = wkday + ", " + month + " " + day; + +} + +updateTime(); +window.setInterval(updateTime, 2000); diff --git a/salt/idh/soc_idh.yaml b/salt/idh/soc_idh.yaml index 1d6918405..0d8ccb393 100644 --- a/salt/idh/soc_idh.yaml +++ b/salt/idh/soc_idh.yaml @@ -1,6 +1,6 @@ idh: enabled: - description: You can enable or disable IDH. + description: Enables or disables the Intrusion Detection Honeypot (IDH) process. helpLink: idh.html opencanary: config: @@ -80,9 +80,9 @@ idh: http_x_enabled: *serviceOptions http_x_port: *portOptions http_x_skin: &skinOptions - description: + description: HTTP skin advanced: True - helplink: idh.html + helpLink: idh.html http_x_skinlist: &skinlistOptions description: List of skins to use for the service. advanced: True diff --git a/salt/idstools/config.sls b/salt/idstools/config.sls index e162d1139..a44b02807 100644 --- a/salt/idstools/config.sls +++ b/salt/idstools/config.sls @@ -24,15 +24,38 @@ idstools_sbin: - group: 939 - file_mode: 755 -idstools_sbin_jinja: - file.recurse: - - name: /usr/sbin - - source: salt://idstools/tools/sbin_jinja +# If this is used, exclude so-rule-update +#idstools_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://idstools/tools/sbin_jinja +# - user: 934 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +idstools_so-rule-update: + file.managed: + - name: /usr/sbin/so-rule-update + - source: salt://idstools/tools/sbin_jinja/so-rule-update - user: 934 - group: 939 - - file_mode: 755 + - mode: 755 - template: jinja +suricatacustomdirsfile: + file.directory: + - name: /nsm/rules/detect-suricata/custom_file + - user: 939 + - group: 939 + - makedirs: True + +suricatacustomdirsurl: + file.directory: + - name: /nsm/rules/detect-suricata/custom_temp + - user: 939 + - group: 939 + {% else %} {{sls}}_state_not_allowed: diff --git a/salt/idstools/enabled.sls b/salt/idstools/enabled.sls index decc5a5b2..365b38772 100644 --- a/salt/idstools/enabled.sls +++ b/salt/idstools/enabled.sls @@ -39,7 +39,7 @@ so-idstools: {% endif %} - binds: - /opt/so/conf/idstools/etc:/opt/so/idstools/etc:ro - - /opt/so/rules/nids:/opt/so/rules/nids:rw + - /opt/so/rules/nids/suri:/opt/so/rules/nids/suri:rw - /nsm/rules/:/nsm/rules/:rw {% if DOCKER.containers['so-idstools'].custom_bind_mounts %} {% for BIND in DOCKER.containers['so-idstools'].custom_bind_mounts %} @@ -55,6 +55,7 @@ so-idstools: {% endif %} - watch: - file: idstoolsetcsync + - file: idstools_so-rule-update delete_so-idstools_so-status.disabled: file.uncomment: @@ -76,6 +77,7 @@ run_so-rule-update: - require: - docker_container: so-idstools - onchanges: + - file: idstools_so-rule-update - file: idstoolsetcsync - file: synclocalnidsrules - order: last diff --git a/salt/idstools/etc/rulecat.conf b/salt/idstools/etc/rulecat.conf index d6f3d93d8..e4ec611db 100644 --- a/salt/idstools/etc/rulecat.conf +++ b/salt/idstools/etc/rulecat.conf @@ -1,17 +1,23 @@ {%- from 'vars/globals.map.jinja' import GLOBALS -%} -{%- from 'idstools/map.jinja' import IDSTOOLSMERGED -%} ---merged=/opt/so/rules/nids/all.rules ---local=/opt/so/rules/nids/local.rules +{%- from 'soc/merged.map.jinja' import SOCMERGED -%} +--suricata-version=7.0.3 +--merged=/opt/so/rules/nids/suri/all.rules +--output=/nsm/rules/detect-suricata/custom_temp +--local=/opt/so/rules/nids/suri/local.rules {%- if GLOBALS.md_engine == "SURICATA" %} ---local=/opt/so/rules/nids/extraction.rules ---local=/opt/so/rules/nids/filters.rules +--local=/opt/so/rules/nids/suri/extraction.rules +--local=/opt/so/rules/nids/suri/filters.rules {%- endif %} --url=http://{{ GLOBALS.manager }}:7788/suricata/emerging-all.rules --disable=/opt/so/idstools/etc/disable.conf --enable=/opt/so/idstools/etc/enable.conf --modify=/opt/so/idstools/etc/modify.conf -{%- if IDSTOOLSMERGED.config.urls | length > 0 %} -{%- for URL in IDSTOOLSMERGED.config.urls %} ---url={{ URL }} -{%- endfor %} +{%- if SOCMERGED.config.server.modules.suricataengine.customRulesets %} + {%- for ruleset in SOCMERGED.config.server.modules.suricataengine.customRulesets %} + {%- if 'url' in ruleset %} +--url={{ ruleset.url }} + {%- elif 'file' in ruleset %} +--local={{ ruleset.file }} + {%- endif %} + {%- endfor %} {%- endif %} diff --git a/salt/idstools/rules/extraction.rules b/salt/idstools/rules/extraction.rules index bccfc69d6..3ebbd41b1 100644 --- a/salt/idstools/rules/extraction.rules +++ b/salt/idstools/rules/extraction.rules @@ -1,26 +1,26 @@ # Extract all PDF mime type -alert http any any -> any any (msg:"FILE pdf detected"; filemagic:"PDF document"; filestore; sid:1100000; rev:1;) -alert smtp any any -> any any (msg:"FILE pdf detected"; filemagic:"PDF document"; filestore; sid:1100001; rev:1;) -alert nfs any any -> any any (msg:"FILE pdf detected"; filemagic:"PDF document"; filestore; sid:1100002; rev:1;) -alert smb any any -> any any (msg:"FILE pdf detected"; filemagic:"PDF document"; filestore; sid:1100003; rev:1;) +alert http any any -> any any (msg:"FILE pdf detected"; filemagic:"PDF document"; filestore; noalert; sid:1100000; rev:1;) +alert smtp any any -> any any (msg:"FILE pdf detected"; filemagic:"PDF document"; filestore; noalert; sid:1100001; rev:1;) +alert nfs any any -> any any (msg:"FILE pdf detected"; filemagic:"PDF document"; filestore; noalert; sid:1100002; rev:1;) +alert smb any any -> any any (msg:"FILE pdf detected"; filemagic:"PDF document"; filestore; noalert; sid:1100003; rev:1;) # Extract EXE/DLL file types -alert http any any -> any any (msg:"FILE EXE detected"; filemagic:"PE32 executable"; filestore; sid:1100004; rev:1;) -alert smtp any any -> any any (msg:"FILE EXE detected"; filemagic:"PE32 executable"; filestore; sid:1100005; rev:1;) -alert nfs any any -> any any (msg:"FILE EXE detected"; filemagic:"PE32 executable"; filestore; sid:1100006; rev:1;) -alert smb any any -> any any (msg:"FILE EXE detected"; filemagic:"PE32 executable"; filestore; sid:1100007; rev:1;) -alert http any any -> any any (msg:"FILE EXE detected"; filemagic:"MS-DOS executable"; filestore; sid:1100008; rev:1;) -alert smtp any any -> any any (msg:"FILE EXE detected"; filemagic:"MS-DOS executable"; filestore; sid:1100009; rev:1;) -alert nfs any any -> any any (msg:"FILE EXE detected"; filemagic:"MS-DOS executable"; filestore; sid:1100010; rev:1;) -alert smb any any -> any any (msg:"FILE EXE detected"; filemagic:"MS-DOS executable"; filestore; sid:1100011; rev:1;) +alert http any any -> any any (msg:"FILE EXE detected"; filemagic:"PE32 executable"; filestore; noalert; sid:1100004; rev:1;) +alert smtp any any -> any any (msg:"FILE EXE detected"; filemagic:"PE32 executable"; filestore; noalert; sid:1100005; rev:1;) +alert nfs any any -> any any (msg:"FILE EXE detected"; filemagic:"PE32 executable"; filestore; noalert; sid:1100006; rev:1;) +alert smb any any -> any any (msg:"FILE EXE detected"; filemagic:"PE32 executable"; filestore; noalert; sid:1100007; rev:1;) +alert http any any -> any any (msg:"FILE EXE detected"; filemagic:"MS-DOS executable"; filestore; noalert; sid:1100008; rev:1;) +alert smtp any any -> any any (msg:"FILE EXE detected"; filemagic:"MS-DOS executable"; filestore; noalert; sid:1100009; rev:1;) +alert nfs any any -> any any (msg:"FILE EXE detected"; filemagic:"MS-DOS executable"; filestore; noalert; sid:1100010; rev:1;) +alert smb any any -> any any (msg:"FILE EXE detected"; filemagic:"MS-DOS executable"; filestore; noalert; sid:1100011; rev:1;) # Extract all Zip files -alert http any any -> any any (msg:"FILE ZIP detected"; filemagic:"Zip"; filestore; sid:1100012; rev:1;) -alert smtp any any -> any any (msg:"FILE ZIP detected"; filemagic:"Zip"; filestore; sid:1100013; rev:1;) -alert nfs any any -> any any (msg:"FILE ZIP detected"; filemagic:"Zip"; filestore; sid:1100014; rev:1;) -alert smb any any -> any any (msg:"FILE ZIP detected"; filemagic:"Zip"; filestore; sid:1100015; rev:1;) +alert http any any -> any any (msg:"FILE ZIP detected"; filemagic:"Zip"; filestore; noalert; sid:1100012; rev:1;) +alert smtp any any -> any any (msg:"FILE ZIP detected"; filemagic:"Zip"; filestore; noalert; sid:1100013; rev:1;) +alert nfs any any -> any any (msg:"FILE ZIP detected"; filemagic:"Zip"; filestore; noalert; sid:1100014; rev:1;) +alert smb any any -> any any (msg:"FILE ZIP detected"; filemagic:"Zip"; filestore; noalert; sid:1100015; rev:1;) # Extract Word Docs -alert http any any -> any any (msg:"FILE WORDDOC detected"; filemagic:"Composite Document File V2 Document"; filestore; sid:1100016; rev:1;) -alert smtp any any -> any any (msg:"FILE WORDDOC detected"; filemagic:"Composite Document File V2 Document"; filestore; sid:1100017; rev:1;) -alert nfs any any -> any any (msg:"FILE WORDDOC detected"; filemagic:"Composite Document File V2 Document"; filestore; sid:1100018; rev:1;) -alert smb any any -> any any (msg:"FILE WORDDOC detected"; filemagic:"Composite Document File V2 Document"; filestore; sid:1100019; rev:1;) \ No newline at end of file +alert http any any -> any any (msg:"FILE WORDDOC detected"; filemagic:"Composite Document File V2 Document"; filestore; noalert; sid:1100016; rev:1;) +alert smtp any any -> any any (msg:"FILE WORDDOC detected"; filemagic:"Composite Document File V2 Document"; filestore; noalert; sid:1100017; rev:1;) +alert nfs any any -> any any (msg:"FILE WORDDOC detected"; filemagic:"Composite Document File V2 Document"; filestore; noalert; sid:1100018; rev:1;) +alert smb any any -> any any (msg:"FILE WORDDOC detected"; filemagic:"Composite Document File V2 Document"; filestore; noalert; sid:1100019; rev:1;) \ No newline at end of file diff --git a/salt/idstools/soc_idstools.yaml b/salt/idstools/soc_idstools.yaml index 634f68803..4f7a53e91 100644 --- a/salt/idstools/soc_idstools.yaml +++ b/salt/idstools/soc_idstools.yaml @@ -1,50 +1,61 @@ idstools: enabled: - description: You can enable or disable IDSTools. + description: Enables or disables the IDStools process which is used by the Detection system. config: oinkcode: description: Enter your registration code or oinkcode for paid NIDS rulesets. title: Registration Code global: True + forcedType: string helpLink: rules.html ruleset: - description: Defines the ruleset you want to run. Options are ETOPEN or ETPRO. + description: 'Defines the ruleset you want to run. Options are ETOPEN or ETPRO. Once you have changed the ruleset here, you will need to wait for the rule update to take place (every 24 hours), or you can force the update by nagivating to Detections --> Options dropdown menu --> Suricata --> Full Update. WARNING! Changing the ruleset will remove all existing non-overlapping Suricata rules of the previous ruleset and their associated overrides. This removal cannot be undone.' global: True regex: ETPRO\b|ETOPEN\b helpLink: rules.html urls: - description: This is a list of additional rule download locations. + description: This is a list of additional rule download locations. This feature is currently disabled. global: True + multiline: True + forcedType: "[]string" + readonly: True helpLink: rules.html sids: disabled: - description: Contains the list of NIDS rules manually disabled across the grid. To disable a rule, add its Signature ID (SID) to the Current Grid Value box, one entry per line. To disable multiple rules, you can use regular expressions. + description: Contains the list of NIDS rules (or regex patterns) disabled across the grid. This setting is readonly; Use the Detections screen to disable rules. global: True multiline: True forcedType: "[]string" regex: \d*|re:.* helpLink: managing-alerts.html + readonlyUi: True + advanced: true enabled: - description: Contains the list of NIDS rules manually enabled across the grid. To enable a rule, add its Signature ID (SID) to the Current Grid Value box, one entry per line. To enable multiple rules, you can use regular expressions. + description: Contains the list of NIDS rules (or regex patterns) enabled across the grid. This setting is readonly; Use the Detections screen to enable rules. global: True multiline: True forcedType: "[]string" regex: \d*|re:.* helpLink: managing-alerts.html + readonlyUi: True + advanced: true modify: - description: Contains the list of NIDS rules that were modified from their default values. Entries must adhere to the following format - SID "REGEX_SEARCH_TERM" "REGEX_REPLACE_TERM" + description: Contains the list of NIDS rules (SID "REGEX_SEARCH_TERM" "REGEX_REPLACE_TERM"). This setting is readonly; Use the Detections screen to modify rules. global: True multiline: True forcedType: "[]string" helpLink: managing-alerts.html + readonlyUi: True + advanced: true rules: local__rules: - description: Contains the list of custom NIDS rules applied to the grid. To add custom NIDS rules to the grid, enter one rule per line in the Current Grid Value box. + description: Contains the list of custom NIDS rules applied to the grid. This setting is readonly; Use the Detections screen to adjust rules. file: True global: True advanced: True title: Local Rules helpLink: local-rules.html + readonlyUi: True filters__rules: description: If you are using Suricata for metadata, then you can set custom filters for that metadata here. file: True diff --git a/salt/idstools/sync_files.sls b/salt/idstools/sync_files.sls index 64479e937..cdacfaa74 100644 --- a/salt/idstools/sync_files.sls +++ b/salt/idstools/sync_files.sls @@ -21,7 +21,7 @@ idstoolsetcsync: rulesdir: file.directory: - - name: /opt/so/rules/nids + - name: /opt/so/rules/nids/suri - user: 939 - group: 939 - makedirs: True @@ -29,7 +29,7 @@ rulesdir: # Don't show changes because all.rules can be large synclocalnidsrules: file.recurse: - - name: /opt/so/rules/nids/ + - name: /opt/so/rules/nids/suri/ - source: salt://idstools/rules/ - user: 939 - group: 939 diff --git a/salt/idstools/tools/sbin_jinja/so-rule-update b/salt/idstools/tools/sbin_jinja/so-rule-update index db110abc1..9ac09ed15 100755 --- a/salt/idstools/tools/sbin_jinja/so-rule-update +++ b/salt/idstools/tools/sbin_jinja/so-rule-update @@ -11,8 +11,8 @@ if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then {%- set proxy = salt['pillar.get']('manager:proxy') %} {%- set noproxy = salt['pillar.get']('manager:no_proxy', '') %} -# Download the rules from the internet {%- if proxy %} +# Download the rules from the internet export http_proxy={{ proxy }} export https_proxy={{ proxy }} export no_proxy="{{ noproxy }}" @@ -20,14 +20,12 @@ if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then mkdir -p /nsm/rules/suricata chown -R socore:socore /nsm/rules/suricata +{%- if not GLOBALS.airgap %} # Download the rules from the internet -{%- if GLOBALS.airgap != 'True' %} {%- if IDSTOOLSMERGED.config.ruleset == 'ETOPEN' %} - docker exec so-idstools idstools-rulecat -v --suricata-version 6.0 -o /nsm/rules/suricata/ --merged=/nsm/rules/suricata/emerging-all.rules --force + docker exec so-idstools idstools-rulecat -v --suricata-version 7.0.3 -o /nsm/rules/suricata/ --merged=/nsm/rules/suricata/emerging-all.rules --force {%- elif IDSTOOLSMERGED.config.ruleset == 'ETPRO' %} - docker exec so-idstools idstools-rulecat -v --suricata-version 6.0 -o /nsm/rules/suricata/ --merged=/nsm/rules/suricata/emerging-all.rules --force --etpro={{ IDSTOOLSMERGED.config.oinkcode }} -{%- elif IDSTOOLSMERGED.config.ruleset == 'TALOS' %} - docker exec so-idstools idstools-rulecat -v --suricata-version 6.0 -o /nsm/rules/suricata/ --merged=/nsm/rules/suricata/emerging-all.rules --force --url=https://www.snort.org/rules/snortrules-snapshot-2983.tar.gz?oinkcode={{ IDSTOOLSMERGED.config.oinkcode }} + docker exec so-idstools idstools-rulecat -v --suricata-version 7.0.3 -o /nsm/rules/suricata/ --merged=/nsm/rules/suricata/emerging-all.rules --force --etpro={{ IDSTOOLSMERGED.config.oinkcode }} {%- endif %} {%- endif %} diff --git a/salt/influxdb/config.sls b/salt/influxdb/config.sls index 66c681a0d..0f315666a 100644 --- a/salt/influxdb/config.sls +++ b/salt/influxdb/config.sls @@ -85,6 +85,7 @@ influxdb-templates: - clean: True - defaults: INFLUXMERGED: {{ INFLUXMERGED }} + - show_changes: False influxdb_curl_config: file.managed: diff --git a/salt/influxdb/soc_influxdb.yaml b/salt/influxdb/soc_influxdb.yaml index 42566a0a8..846152cf3 100644 --- a/salt/influxdb/soc_influxdb.yaml +++ b/salt/influxdb/soc_influxdb.yaml @@ -1,6 +1,6 @@ influxdb: enabled: - description: You can enable or disable InfluxDB. + description: Enables the grid metrics collection storage system. Security Onion grid health monitoring requires this process to remain enabled. WARNING - Disabling the process is unsupported, and will cause unexpected results. helpLink: influxdb.html config: assets-path: diff --git a/salt/influxdb/templates/alarm_nsm_disk.json b/salt/influxdb/templates/alarm_nsm_disk.json index 691f8c0e8..a3b10f7f3 100644 --- a/salt/influxdb/templates/alarm_nsm_disk.json +++ b/salt/influxdb/templates/alarm_nsm_disk.json @@ -5,10 +5,10 @@ "name": "alarm-nsm-disk" }, "spec": { - "description": "Percent used space on the root partition of at least one node has exceeded the alarm threshold.", + "description": "Percent used space on the nsm partition of at least one node has exceeded the alarm threshold.", "every": "1m0s", "name": "NSM Disk High Usage", - "query": "from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"path\"] == \"/\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> aggregateWindow(every: 1m, fn: max, createEmpty: false)\n |> yield(name: \"max\")", + "query": "from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"path\"] == \"/nsm\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> aggregateWindow(every: 1m, fn: max, createEmpty: false)\n |> yield(name: \"max\")", "status": "active", "statusMessageTemplate": "Check: ${ r._check_name } is: ${ r._level }", "thresholds": [ diff --git a/salt/influxdb/templates/dashboard-security_onion_performance.json b/salt/influxdb/templates/dashboard-security_onion_performance.json index e4f2a6d38..835aedb03 100644 --- a/salt/influxdb/templates/dashboard-security_onion_performance.json +++ b/salt/influxdb/templates/dashboard-security_onion_performance.json @@ -1 +1 @@ -[{"apiVersion":"influxdata.com/v2alpha1","kind":"Dashboard","metadata":{"name":"vivid-wilson-002001"},"spec":{"charts":[{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Uptime","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"uptime\")\n |> hostFilter()\n |> map(fn: (r) => ({r with _value: r._value / (24 * 60 * 60)}))\n |> group(columns: [\"host\"])\n |> last()\n |> lowestMin(n:1)"}],"staticLegend":{},"suffix":" days","width":1},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"},{"id":"z83MTSufTrlrCoEPiBXda","name":"ruby","type":"text","hex":"#BF3D5E","value":1}],"decimalPlaces":0,"height":2,"kind":"Single_Stat","name":"Critical Alarms","queries":[{"query":"from(bucket: \"_monitoring\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"statuses\")\n |> filter(fn: (r) => r[\"_field\"] == \"_message\")\n |> group(columns: [\"_check_id\"])\n |> sort(columns: [\"_time\"])\n |> last()\n |> group()\n |> filter(fn: (r) => r[\"_level\"] == \"crit\")\n |> count()"}],"staticLegend":{},"suffix":" ","width":1,"yPos":2},{"colors":[{"id":"base","name":"rainforest","type":"text","hex":"#4ED8A0"},{"id":"QCTYWuGuHkikYFsZSKMzQ","name":"rainforest","type":"text","hex":"#4ED8A0"},{"id":"QdpMyTRBb0LJ56-P5wfAW","name":"laser","type":"text","hex":"#00C9FF","value":1},{"id":"VQGwCoMrxZyP8asiOW5Cq","name":"tiger","type":"text","hex":"#F48D38","value":2},{"id":"zSO9QkesSIxrU_ntCBx2i","name":"ruby","type":"text","hex":"#BF3D5E","value":3}],"fieldOptions":[{"fieldName":"_time","visible":true},{"displayName":"Alarm","fieldName":"_check_name","visible":true},{"displayName":"Severity","fieldName":"_value","visible":true},{"displayName":"Status","fieldName":"_level","visible":true}],"height":6,"kind":"Table","name":"Alarm Status","queries":[{"query":"from(bucket: \"_monitoring\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"statuses\")\n |> filter(fn: (r) => r[\"_field\"] == \"_message\")\n |> drop(columns: [\"_value\"])\n |> duplicate(column: \"_level\", as: \"_value\")\n |> map(fn: (r) => ({ r with _value: if r._value == \"ok\" then 0 else if r._value == \"info\" then 1 else if r._value == \"warn\" then 2 else 3 }))\n |> group(columns: [\"_check_id\"])\n |> sort(columns: [\"_time\"])\n |> last()\n |> group()\n |> keep(columns: [\"_check_name\",\"_level\",\"_value\"])"}],"staticLegend":{},"tableOptions":{"sortBy":"_check_name","verticalTimeAxis":true},"timeFormat":"YYYY-MM-DD HH:mm:ss","width":3,"yPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"B"}],"colorizeRows":true,"colors":[{"id":"3PVw3hQuZUzyar7Js3mMH","name":"Ectoplasm","type":"scale","hex":"#DA6FF1"},{"id":"O34ux-D8Xq_1-eeWRyYYH","name":"Ectoplasm","type":"scale","hex":"#00717A"},{"id":"P04RoKOHBdLdvfrfFbn0F","name":"Ectoplasm","type":"scale","hex":"#ACFF76"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Elasticsearch Storage Size","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_indices\")\n |> filter(fn: (r) => r[\"_field\"] == \"store_size_in_bytes\")\n |> filter(fn: (r) => r[\"host\"] == r[\"node_name\"])\n |> hostFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"mean\")"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_indices\")\n |> filter(fn: (r) => r[\"_field\"] == \"store_size_in_bytes\")\n |> filter(fn: (r) => r[\"host\"] == r[\"node_name\"])\n |> hostFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":10},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"B"}],"colorizeRows":true,"colors":[{"id":"3PVw3hQuZUzyar7Js3mMH","name":"Ectoplasm","type":"scale","hex":"#DA6FF1"},{"id":"O34ux-D8Xq_1-eeWRyYYH","name":"Ectoplasm","type":"scale","hex":"#00717A"},{"id":"P04RoKOHBdLdvfrfFbn0F","name":"Ectoplasm","type":"scale","hex":"#ACFF76"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"InfluxDB Size","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"influxsize\")\n |> filter(fn: (r) => r[\"_field\"] == \"kbytes\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 1000.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"mean\")"},{"query":"import \"join\"\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"influxsize\")\n |> filter(fn: (r) => r[\"_field\"] == \"kbytes\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 1000.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":14},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":" days"}],"colorizeRows":true,"colors":[{"id":"sW2GqpGAsGB5Adx16jKjp","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"TsdXuXwdI5Npi9S8L4f-i","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"OGL29-SUbJ6FyQb0JzbaD","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"System Uptime","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"uptime\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"host\", \"role\"])\n |> map(fn: (r) => ({r with _value: float(v: r._value) / float(v: 24 * 60 * 60)}))\n |> yield(name: \"last\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"uptime\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"host\", \"role\"])\n |> map(fn: (r) => ({r with _value: float(v: r._value) / float(v: 24 * 60 * 60)}))\n |> yield(name: \"Trend\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":18},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"sW2GqpGAsGB5Adx16jKjp","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"TsdXuXwdI5Npi9S8L4f-i","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"OGL29-SUbJ6FyQb0JzbaD","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"System CPU Usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_idle\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> map(fn: (r) => ({r with _value: r._value * -1.0 + 100.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: true)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_idle\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\",\"host\", \"role\"])\n |> map(fn: (r) => ({r with _value: r._value * -1.0 + 100.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: true)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":22},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"QDwChKZWuQV0BaJcEeSam","name":"Atlantis","type":"scale","hex":"#74D495"},{"id":"ThD0WTqKHltQEVlq9mo6K","name":"Atlantis","type":"scale","hex":"#3F3FBA"},{"id":"FBHYZiwDLKyQK3eRfUD-0","name":"Atlantis","type":"scale","hex":"#FF4D9E"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"System Memory Usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":26},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"b/s"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"heightRatio":0.18482490272373542,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Monitor Interface Traffic - Inbound","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"monint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_recv\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"bytes_recv\"}))"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"monint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_recv\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"Trend\"}))"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.18482490272373542,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":30},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"b/s"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"heightRatio":0.18482490272373542,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Management Interface Traffic - Inbound","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"manint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_recv\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"bytes_recv\"}))"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"manint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_recv\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"Trend\"}))"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.18482490272373542,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":34},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Stenographer Packet Loss","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"stenodrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"stenodrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":3,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":38},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"3PVw3hQuZUzyar7Js3mMH","name":"Ectoplasm","type":"scale","hex":"#DA6FF1"},{"id":"O34ux-D8Xq_1-eeWRyYYH","name":"Ectoplasm","type":"scale","hex":"#00717A"},{"id":"P04RoKOHBdLdvfrfFbn0F","name":"Ectoplasm","type":"scale","hex":"#ACFF76"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Disk Usage /","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> filter(fn: (r) => r[\"path\"] == \"/\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> filter(fn: (r) => r[\"path\"] == \"/\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":42},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"5m Load Average","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"load5\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"width":1,"xPos":1},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"},{"id":"z83MTSufTrlrCoEPiBXda","name":"tiger","type":"text","hex":"#F48D38","value":1}],"decimalPlaces":0,"height":2,"kind":"Single_Stat","name":"Warning Alarms","queries":[{"query":"from(bucket: \"_monitoring\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"statuses\")\n |> filter(fn: (r) => r[\"_field\"] == \"_message\")\n |> group(columns: [\"_check_id\"])\n |> sort(columns: [\"_time\"])\n |> last()\n |> group()\n |> filter(fn: (r) => r[\"_level\"] == \"warn\")\n |> count()"}],"staticLegend":{},"suffix":" ","width":1,"xPos":1,"yPos":2},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"IO Wait","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_iowait\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":"%","width":1,"xPos":2},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"},{"id":"z83MTSufTrlrCoEPiBXda","name":"laser","type":"text","hex":"#00C9FF","value":1}],"decimalPlaces":0,"height":2,"kind":"Single_Stat","name":"Informative Alarms","queries":[{"query":"from(bucket: \"_monitoring\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"statuses\")\n |> filter(fn: (r) => r[\"_field\"] == \"_message\")\n |> group(columns: [\"_check_id\"])\n |> sort(columns: [\"_time\"])\n |> last()\n |> group()\n |> filter(fn: (r) => r[\"_level\"] == \"info\")\n |> count()"}],"staticLegend":{},"suffix":" ","width":1,"xPos":2,"yPos":2},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":0,"height":2,"kind":"Single_Stat","name":"Estimated EPS In","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"logstash_events\")\n |> filter(fn: (r) => r[\"_field\"] == \"in\")\n |> hostFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"width":1,"xPos":3},{"colors":[{"id":"0","name":"viridian","type":"min","hex":"#32B08C"},{"id":"5IArg2lDb8KvnphywgUXa","name":"pineapple","type":"threshold","hex":"#FFB94A","value":70},{"id":"yFhH3mtavjuAZh6cEt5lx","name":"fire","type":"threshold","hex":"#DC4E58","value":80},{"id":"1","name":"ruby","type":"max","hex":"#BF3D5E","value":100}],"decimalPlaces":0,"height":4,"kind":"Gauge","name":"CPU Usage","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_idle\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n: 1)\n |> map(fn: (r) => ({r with _value: r._value * -1.0 + 100.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{},"suffix":"%","tickSuffix":"%","width":3,"xPos":3,"yPos":2},{"colors":[{"id":"0","name":"viridian","type":"min","hex":"#32B08C"},{"id":"kOQLOg2H4FVEE-E1_L8Kq","name":"laser","type":"threshold","hex":"#00C9FF","value":85},{"id":"5IArg2lDb8KvnphywgUXa","name":"tiger","type":"threshold","hex":"#F48D38","value":90},{"id":"yFhH3mtavjuAZh6cEt5lx","name":"ruby","type":"threshold","hex":"#BF3D5E","value":95},{"id":"1","name":"ruby","type":"max","hex":"#BF3D5E","value":100}],"decimalPlaces":0,"height":4,"kind":"Gauge","name":"Root Disk Usage","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"path\"] == \"/\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n: 1)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{},"suffix":"%","tickSuffix":"%","width":3,"xPos":3,"yPos":6},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Suricata Packet Loss","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"suridrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"suridrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":3,"widthRatio":1,"xCol":"_time","xPos":3,"yCol":"_value","yPos":38},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":0,"height":2,"kind":"Single_Stat","name":"Redis Queue","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"redisqueue\")\n |> filter(fn: (r) => r[\"_field\"] == \"unparsed\")\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"width":1,"xPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"xflqbsX-j3iq4ry5QOntK","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#8F8AF4"},{"id":"5H28HcITm6QVfQsXon0vq","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#A51414"},{"id":"25MrINwurNBkQqeKCkMPg","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#F4CF31"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Elasticsearch Document Count","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_indices\")\n |> filter(fn: (r) => r[\"_field\"] == \"docs_count\")\n |> filter(fn: (r) => r[\"host\"] == r[\"node_name\"])\n |> hostFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"mean\")"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_indices\")\n |> filter(fn: (r) => r[\"_field\"] == \"docs_count\")\n |> filter(fn: (r) => r[\"host\"] == r[\"node_name\"])\n |> hostFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":10},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"xflqbsX-j3iq4ry5QOntK","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#8F8AF4"},{"id":"5H28HcITm6QVfQsXon0vq","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#A51414"},{"id":"25MrINwurNBkQqeKCkMPg","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#F4CF31"}],"geom":"line","height":4,"heightRatio":0.301556420233463,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Redis Queue","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"redisqueue\")\n |> filter(fn: (r) => r[\"_field\"] == \"unparsed\")\n |> group(columns: [\"host\", \"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"redisqueue\")\n |> filter(fn: (r) => r[\"_field\"] == \"unparsed\")\n |> group(columns: [\"host\", \"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.301556420233463,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":14},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":" days"}],"colorizeRows":true,"colors":[{"id":"sW2GqpGAsGB5Adx16jKjp","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"TsdXuXwdI5Npi9S8L4f-i","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"OGL29-SUbJ6FyQb0JzbaD","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Container Uptime","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_status\")\n |> filter(fn: (r) => r[\"_field\"] == \"uptime_ns\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> group(columns: [\"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> map(fn: (r) => ({r with _value: float(v: r._value) / float(v: 24 * 60 * 60 * 1000000000)}))\n |> yield(name: \"last\")"},{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_status\")\n |> filter(fn: (r) => r[\"_field\"] == \"uptime_ns\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> group(columns: [\"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> map(fn: (r) => ({r with _value: float(v: r._value) / float(v: 24.0 * 60.0 * 60.0 * 1000000000.0)}))\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":18},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"yT5vTIlaaFChSrQvKLfqf","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"mzzUVSu3ibTph1JmQmDAQ","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"mOcnDo7l8ii6qNLFIB5rs","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Container CPU Usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_cpu\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_percent\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"mean\")"},{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_cpu\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_percent\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":22},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"QDwChKZWuQV0BaJcEeSam","name":"Atlantis","type":"scale","hex":"#74D495"},{"id":"ThD0WTqKHltQEVlq9mo6K","name":"Atlantis","type":"scale","hex":"#3F3FBA"},{"id":"FBHYZiwDLKyQK3eRfUD-0","name":"Atlantis","type":"scale","hex":"#FF4D9E"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Container Memory Usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_percent\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"mean\")"},{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_percent\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":26},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"b"}],"colorizeRows":true,"colors":[{"id":"0ynR6Zs0wuQ3WY0Lz-_KC","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"YiArehCNBwFm9mn8DSXSG","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"DxByY_EQW9Xs2jD5ktkG5","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Container Traffic - Inbound","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_net\")\n |> filter(fn: (r) => r[\"_field\"] == \"rx_bytes\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> map(fn: (r) => ({r with _value: r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"mean\")"},{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_net\")\n |> filter(fn: (r) => r[\"_field\"] == \"rx_bytes\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with _value: r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":30},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"3PVw3hQuZUzyar7Js3mMH","name":"Ectoplasm","type":"scale","hex":"#DA6FF1"},{"id":"O34ux-D8Xq_1-eeWRyYYH","name":"Ectoplasm","type":"scale","hex":"#00717A"},{"id":"P04RoKOHBdLdvfrfFbn0F","name":"Ectoplasm","type":"scale","hex":"#ACFF76"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Disk Usage /nsm","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> filter(fn: (r) => r[\"path\"] == \"/nsm\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> filter(fn: (r) => r[\"path\"] == \"/nsm\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xPos":4,"yPos":42},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Inbound Traffic","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_recv\") \n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> map(fn: (r) => ({r with _value: r._value * 8.0 / (1000.0 * 1000.0)}))\n |> group(columns: [\"host\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> last()\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":" Mb/s","width":1,"xPos":5},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Inbound Drops","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop_in\") \n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> map(fn: (r) => ({r with _value: r._value * 8.0 / (1000.0 * 1000.0)}))\n |> group(columns: [\"host\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> last()\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":" Mb/s","width":1,"xPos":6},{"colors":[{"id":"0","name":"viridian","type":"min","hex":"#32B08C"},{"id":"5IArg2lDb8KvnphywgUXa","name":"pineapple","type":"threshold","hex":"#FFB94A","value":70},{"id":"yFhH3mtavjuAZh6cEt5lx","name":"fire","type":"threshold","hex":"#DC4E58","value":80},{"id":"1","name":"ruby","type":"max","hex":"#BF3D5E","value":100}],"decimalPlaces":0,"height":4,"kind":"Gauge","name":"Memory Usage","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n: 1)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{},"suffix":"%","tickSuffix":"%","width":3,"xPos":6,"yPos":2},{"colors":[{"id":"0","name":"viridian","type":"min","hex":"#32B08C"},{"id":"5IArg2lDb8KvnphywgUXa","name":"laser","type":"threshold","hex":"#00C9FF","value":85},{"id":"yFhH3mtavjuAZh6cEt5lx","name":"tiger","type":"threshold","hex":"#F48D38","value":90},{"id":"H7uprvKmMEh39en6X-ms_","name":"ruby","type":"threshold","hex":"#BF3D5E","value":95},{"id":"1","name":"ruby","type":"max","hex":"#BF3D5E","value":100}],"decimalPlaces":0,"height":4,"kind":"Gauge","name":"NSM Disk Usage","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"path\"] == \"/nsm\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n: 1)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{},"suffix":"%","tickSuffix":"%","width":3,"xPos":6,"yPos":6},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"b/s"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"heightRatio":0.18482490272373542,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Management Interface Traffic - Outbound","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"manint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_sent\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n \n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"bytes_sent\"}))"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"manint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_sent\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n \n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"Trend\"}))"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.18482490272373542,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":34},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Zeek Packet Loss","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekdrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekdrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":3,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":38},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Capture Loss","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekcaptureloss\")\n |> filter(fn: (r) => r[\"_field\"] == \"loss\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":"%","width":1,"xPos":7},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Zeek Loss","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekdrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":"%","width":1,"xPos":8},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"s"}],"colorizeRows":true,"colors":[{"id":"xflqbsX-j3iq4ry5QOntK","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#8F8AF4"},{"id":"5H28HcITm6QVfQsXon0vq","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#A51414"},{"id":"25MrINwurNBkQqeKCkMPg","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#F4CF31"}],"geom":"line","height":4,"heightRatio":0.301556420233463,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Elastic Ingest Time Spent","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_community_id_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"community.id_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_conditional_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"conditional_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_date_index_name_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"date.index.name_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_date_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"date_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_dissect_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"dissect_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_dot_expander_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"dot.expander_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_geoip_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"geoip_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_grok_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"grok_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_json_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"json_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_kv_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"kv_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_lowercase_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"lowercase_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_rename_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"rename_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_script_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"script_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_user_agent_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"user.agent_time\")"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.301556420233463,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":10},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"sW2GqpGAsGB5Adx16jKjp","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"TsdXuXwdI5Npi9S8L4f-i","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"OGL29-SUbJ6FyQb0JzbaD","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"1m Load Average","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"load1\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: true)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"load1\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\",\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: true)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":14,"yTickStep":1},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":" e/s"}],"colorizeRows":true,"colors":[{"id":"xflqbsX-j3iq4ry5QOntK","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#8F8AF4"},{"id":"5H28HcITm6QVfQsXon0vq","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#A51414"},{"id":"25MrINwurNBkQqeKCkMPg","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#F4CF31"}],"geom":"line","height":4,"heightRatio":0.301556420233463,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Logstash EPS","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"logstash_events\")\n |> filter(fn: (r) => r[\"_field\"] == \"in\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"_field\", \"host\", \"pipeline\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"logstash_events\")\n |> filter(fn: (r) => r[\"_field\"] == \"out\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> map(fn: (r) => ({r with _value: -r._value}))\n |> group(columns: [\"_field\", \"host\", \"pipeline\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"logstash_events\")\n |> filter(fn: (r) => r[\"_field\"] == \"in\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"_field\", \"host\", \"pipeline\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"},{"query":"from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"logstash_events\")\n |> filter(fn: (r) => r[\"_field\"] == \"out\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> map(fn: (r) => ({r with _value: -r._value}))\n |> group(columns: [\"_field\", \"host\", \"pipeline\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.301556420233463,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":18},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"UAehjIsi65P8u92M_3sQY","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"_SCP8Npp4NVMx2N4mfuzX","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"BoMPg4R1KDp_UsRORdV3_","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"IO Wait","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_iowait\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_iowait\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":22},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"QDwChKZWuQV0BaJcEeSam","name":"Atlantis","type":"scale","hex":"#74D495"},{"id":"ThD0WTqKHltQEVlq9mo6K","name":"Atlantis","type":"scale","hex":"#3F3FBA"},{"id":"FBHYZiwDLKyQK3eRfUD-0","name":"Atlantis","type":"scale","hex":"#FF4D9E"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Swap Usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"swap\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"swap\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":26},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"b/s"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"heightRatio":0.18482490272373542,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Monitor Interface Drops - Inbound","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"monint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop_in\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"drop_in\"}))"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"monint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop_in\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"Trend\"}))"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.18482490272373542,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":30},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":" days"}],"colorizeRows":true,"colors":[{"id":"3PVw3hQuZUzyar7Js3mMH","name":"Ectoplasm","type":"scale","hex":"#DA6FF1"},{"id":"O34ux-D8Xq_1-eeWRyYYH","name":"Ectoplasm","type":"scale","hex":"#00717A"},{"id":"P04RoKOHBdLdvfrfFbn0F","name":"Ectoplasm","type":"scale","hex":"#ACFF76"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Stenographer PCAP Retention","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"pcapage\")\n |> filter(fn: (r) => r[\"_field\"] == \"seconds\")\n |> map(fn: (r) => ({ r with _value: r._value / (24.0 * 3600.0)}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])"},{"query":"import \"join\"\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"pcapage\")\n |> filter(fn: (r) => r[\"_field\"] == \"seconds\")\n |> map(fn: (r) => ({ r with _value: r._value / (24.0 * 3600.0)}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":42},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Suricata Loss","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"suridrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":"%","width":1,"xPos":9},{"colors":[{"id":"0","name":"viridian","type":"min","hex":"#32B08C"},{"id":"5IArg2lDb8KvnphywgUXa","name":"pineapple","type":"threshold","hex":"#FFB94A","value":50},{"id":"yFhH3mtavjuAZh6cEt5lx","name":"fire","type":"threshold","hex":"#DC4E58","value":70},{"id":"1","name":"ruby","type":"max","hex":"#BF3D5E","value":100}],"decimalPlaces":0,"height":4,"kind":"Gauge","name":"Swap Usage","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"swap\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n: 1)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{},"suffix":"%","tickSuffix":"%","width":3,"xPos":9,"yPos":2},{"colors":[{"id":"base","name":"white","type":"text","hex":"#ffffff"}],"fieldOptions":[{"displayName":"Host","fieldName":"host","visible":true},{"displayName":"Name","fieldName":"container_name","visible":true},{"displayName":"Status","fieldName":"container_status","visible":true},{"displayName":"OOM Killed","fieldName":"_value","visible":true},{"displayName":"_start","fieldName":"_start","visible":true},{"displayName":"_stop","fieldName":"_stop","visible":true},{"displayName":"_time","fieldName":"_time","visible":true},{"displayName":"_field","fieldName":"_field","visible":true},{"displayName":"_measurement","fieldName":"_measurement","visible":true},{"displayName":"engine_host","fieldName":"engine_host","visible":true},{"displayName":"role","fieldName":"role","visible":true},{"displayName":"server_version","fieldName":"server_version","visible":true},{"displayName":"container_image","fieldName":"container_image","visible":true},{"displayName":"container_version","fieldName":"container_version","visible":true},{"displayName":"description","fieldName":"description","visible":true},{"displayName":"maintainer","fieldName":"maintainer","visible":true},{"displayName":"io.k8s.description","fieldName":"io.k8s.description","visible":true},{"displayName":"io.k8s.display-name","fieldName":"io.k8s.display-name","visible":true},{"displayName":"license","fieldName":"license","visible":true},{"displayName":"name","fieldName":"name","visible":true},{"displayName":"org.label-schema.build-date","fieldName":"org.label-schema.build-date","visible":true},{"displayName":"org.label-schema.license","fieldName":"org.label-schema.license","visible":true},{"displayName":"org.label-schema.name","fieldName":"org.label-schema.name","visible":true},{"displayName":"org.label-schema.schema-version","fieldName":"org.label-schema.schema-version","visible":true},{"displayName":"org.label-schema.url","fieldName":"org.label-schema.url","visible":true},{"displayName":"org.label-schema.vcs-ref","fieldName":"org.label-schema.vcs-ref","visible":true},{"displayName":"org.label-schema.vcs-url","fieldName":"org.label-schema.vcs-url","visible":true},{"displayName":"org.label-schema.vendor","fieldName":"org.label-schema.vendor","visible":true},{"displayName":"org.label-schema.version","fieldName":"org.label-schema.version","visible":true},{"displayName":"org.opencontainers.image.created","fieldName":"org.opencontainers.image.created","visible":true},{"displayName":"org.opencontainers.image.licenses","fieldName":"org.opencontainers.image.licenses","visible":true},{"displayName":"org.opencontainers.image.title","fieldName":"org.opencontainers.image.title","visible":true},{"displayName":"org.opencontainers.image.vendor","fieldName":"org.opencontainers.image.vendor","visible":true},{"displayName":"release","fieldName":"release","visible":true},{"displayName":"summary","fieldName":"summary","visible":true},{"displayName":"url","fieldName":"url","visible":true},{"displayName":"vendor","fieldName":"vendor","visible":true},{"displayName":"version","fieldName":"version","visible":true},{"displayName":"org.label-schema.usage","fieldName":"org.label-schema.usage","visible":true},{"displayName":"org.opencontainers.image.documentation","fieldName":"org.opencontainers.image.documentation","visible":true},{"displayName":"org.opencontainers.image.revision","fieldName":"org.opencontainers.image.revision","visible":true},{"displayName":"org.opencontainers.image.source","fieldName":"org.opencontainers.image.source","visible":true},{"displayName":"org.opencontainers.image.url","fieldName":"org.opencontainers.image.url","visible":true},{"displayName":"org.opencontainers.image.version","fieldName":"org.opencontainers.image.version","visible":true},{"displayName":"org.opencontainers.image.description","fieldName":"org.opencontainers.image.description","visible":true}],"height":4,"kind":"Table","name":"Most Recent Container Events","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_status\")\n |> filter(fn: (r) => r[\"_field\"] == \"oomkilled\")\n |> filter(fn: (r) => r[\"container_status\"] != \"running\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"container_name\", \"host\"])\n |> last()\n |> group()\n |> keep(columns: [\"_value\", \"container_name\", \"host\", \"container_status\"])"}],"staticLegend":{},"tableOptions":{"sortBy":"container_name","verticalTimeAxis":true},"timeFormat":"YYYY-MM-DD HH:mm:ss","width":3,"xPos":9,"yPos":6},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Zeek Capture Loss","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekcaptureloss\")\n |> filter(fn: (r) => r[\"_field\"] == \"loss\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekcaptureloss\")\n |> filter(fn: (r) => r[\"_field\"] == \"loss\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":3,"widthRatio":1,"xCol":"_time","xPos":9,"yCol":"_value","yPos":38},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Stenographer Loss","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"stenodrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":"%","width":1,"xPos":10},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"PCAP Retention","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"pcapage\")\n |> filter(fn: (r) => r[\"_field\"] == \"seconds\")\n |> hostFilter()\n |> map(fn: (r) => ({r with _value: r._value / (24.0 * 60.0 * 60.0)}))\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":" days","width":1,"xPos":11}],"description":"Visualize the Security Onion grid performance metrics and alarm statuses.","name":"Security Onion Performance"}}] \ No newline at end of file +[{"apiVersion":"influxdata.com/v2alpha1","kind":"Dashboard","metadata":{"name":"vivid-wilson-002001"},"spec":{"charts":[{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Uptime","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"uptime\")\n |> hostFilter()\n |> map(fn: (r) => ({r with _value: r._value / (24 * 60 * 60)}))\n |> group(columns: [\"host\"])\n |> last()\n |> lowestMin(n:1)"}],"staticLegend":{},"suffix":" days","width":1},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"},{"id":"z83MTSufTrlrCoEPiBXda","name":"ruby","type":"text","hex":"#BF3D5E","value":1}],"decimalPlaces":0,"height":2,"kind":"Single_Stat","name":"Critical Alarms","queries":[{"query":"from(bucket: \"_monitoring\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"statuses\")\n |> filter(fn: (r) => r[\"_field\"] == \"_message\")\n |> group(columns: [\"_check_id\"])\n |> sort(columns: [\"_time\"])\n |> last()\n |> group()\n |> filter(fn: (r) => r[\"_level\"] == \"crit\")\n |> count()"}],"staticLegend":{},"suffix":" ","width":1,"yPos":2},{"colors":[{"id":"base","name":"rainforest","type":"text","hex":"#4ED8A0"},{"id":"QCTYWuGuHkikYFsZSKMzQ","name":"rainforest","type":"text","hex":"#4ED8A0"},{"id":"QdpMyTRBb0LJ56-P5wfAW","name":"laser","type":"text","hex":"#00C9FF","value":1},{"id":"VQGwCoMrxZyP8asiOW5Cq","name":"tiger","type":"text","hex":"#F48D38","value":2},{"id":"zSO9QkesSIxrU_ntCBx2i","name":"ruby","type":"text","hex":"#BF3D5E","value":3}],"fieldOptions":[{"fieldName":"_time","visible":true},{"displayName":"Alarm","fieldName":"_check_name","visible":true},{"displayName":"Severity","fieldName":"_value","visible":true},{"displayName":"Status","fieldName":"_level","visible":true}],"height":6,"kind":"Table","name":"Alarm Status","queries":[{"query":"from(bucket: \"_monitoring\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"statuses\")\n |> filter(fn: (r) => r[\"_field\"] == \"_message\")\n |> drop(columns: [\"_value\"])\n |> duplicate(column: \"_level\", as: \"_value\")\n |> map(fn: (r) => ({ r with _value: if r._value == \"ok\" then 0 else if r._value == \"info\" then 1 else if r._value == \"warn\" then 2 else 3 }))\n |> group(columns: [\"_check_id\"])\n |> sort(columns: [\"_time\"])\n |> last()\n |> group()\n |> keep(columns: [\"_check_name\",\"_level\",\"_value\"])"}],"staticLegend":{},"tableOptions":{"sortBy":"_check_name","verticalTimeAxis":true},"timeFormat":"YYYY-MM-DD HH:mm:ss","width":3,"yPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"B"}],"colorizeRows":true,"colors":[{"id":"3PVw3hQuZUzyar7Js3mMH","name":"Ectoplasm","type":"scale","hex":"#DA6FF1"},{"id":"O34ux-D8Xq_1-eeWRyYYH","name":"Ectoplasm","type":"scale","hex":"#00717A"},{"id":"P04RoKOHBdLdvfrfFbn0F","name":"Ectoplasm","type":"scale","hex":"#ACFF76"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Elasticsearch Storage Size","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_indices\")\n |> filter(fn: (r) => r[\"_field\"] == \"store_size_in_bytes\")\n |> filter(fn: (r) => r[\"host\"] == r[\"node_name\"])\n |> hostFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"mean\")"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_indices\")\n |> filter(fn: (r) => r[\"_field\"] == \"store_size_in_bytes\")\n |> filter(fn: (r) => r[\"host\"] == r[\"node_name\"])\n |> hostFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":10},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"B"}],"colorizeRows":true,"colors":[{"id":"3PVw3hQuZUzyar7Js3mMH","name":"Ectoplasm","type":"scale","hex":"#DA6FF1"},{"id":"O34ux-D8Xq_1-eeWRyYYH","name":"Ectoplasm","type":"scale","hex":"#00717A"},{"id":"P04RoKOHBdLdvfrfFbn0F","name":"Ectoplasm","type":"scale","hex":"#ACFF76"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"InfluxDB Size","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"influxsize\")\n |> filter(fn: (r) => r[\"_field\"] == \"kbytes\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 1000.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"mean\")"},{"query":"import \"join\"\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"influxsize\")\n |> filter(fn: (r) => r[\"_field\"] == \"kbytes\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 1000.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":14},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":" days"}],"colorizeRows":true,"colors":[{"id":"sW2GqpGAsGB5Adx16jKjp","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"TsdXuXwdI5Npi9S8L4f-i","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"OGL29-SUbJ6FyQb0JzbaD","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"System Uptime","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"uptime\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"host\", \"role\"])\n |> map(fn: (r) => ({r with _value: float(v: r._value) / float(v: 24 * 60 * 60)}))\n |> yield(name: \"last\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"uptime\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"host\", \"role\"])\n |> map(fn: (r) => ({r with _value: float(v: r._value) / float(v: 24 * 60 * 60)}))\n |> yield(name: \"Trend\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":18},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"lQ75rvTyd2Lq5pZjzy6LB","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"KLfpRZtiEnU2GxjPtrrzQ","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"1kLynwKxvJ3B5IeJnrBqp","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Kafka EPS","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"controllerHosts = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"kafka_controller\")\n |> filter(fn: (r) => r[\"_field\"] == \"ActiveControllerCount.Value\")\n |> filter(fn: (r) => r[\"_value\"] == 1)\n |> keep(columns: [\"host\"])\n |> distinct(column: \"host\")\n |> map(fn: (r) => ({r with _value: r.host}))\n |> keep(columns: [\"_value\"])\n\ncontrollerHostNames = controllerHosts |> findColumn(fn: (key) => true, column: \"_value\")\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"kafka_topics\")\n |> filter(fn: (r) => r[\"_field\"] == \"MessagesInPerSec.Count\")\n |> filter(fn: (r) => not contains(value: r.host, set: controllerHostNames))\n |> derivative(unit: 1s, nonNegative: true)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"controllerHosts = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"kafka_controller\")\n |> filter(fn: (r) => r[\"_field\"] == \"ActiveControllerCount.Value\")\n |> filter(fn: (r) => r[\"_value\"] == 1)\n |> keep(columns: [\"host\"])\n |> distinct(column: \"host\")\n |> map(fn: (r) => ({r with _value: r.host}))\n |> keep(columns: [\"_value\"])\n\ncontrollerHostNames = controllerHosts |> findColumn(fn: (key) => true, column: \"_value\")\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"kafka_topics\")\n |> filter(fn: (r) => r[\"_field\"] == \"MessagesInPerSec.Count\")\n |> filter(fn: (r) => not contains(value: r.host, set: controllerHostNames))\n |> derivative(unit: 1s, nonNegative: true)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":22},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"sW2GqpGAsGB5Adx16jKjp","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"TsdXuXwdI5Npi9S8L4f-i","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"OGL29-SUbJ6FyQb0JzbaD","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"System CPU Usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_idle\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> map(fn: (r) => ({r with _value: r._value * -1.0 + 100.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: true)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_idle\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\",\"host\", \"role\"])\n |> map(fn: (r) => ({r with _value: r._value * -1.0 + 100.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: true)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":26},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"QDwChKZWuQV0BaJcEeSam","name":"Atlantis","type":"scale","hex":"#74D495"},{"id":"ThD0WTqKHltQEVlq9mo6K","name":"Atlantis","type":"scale","hex":"#3F3FBA"},{"id":"FBHYZiwDLKyQK3eRfUD-0","name":"Atlantis","type":"scale","hex":"#FF4D9E"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"System Memory Usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":30},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"b/s"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"heightRatio":0.18482490272373542,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Monitor Interface Traffic - Inbound","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"monint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_recv\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"bytes_recv\"}))"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"monint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_recv\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"Trend\"}))"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.18482490272373542,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":34},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"b/s"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"heightRatio":0.18482490272373542,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Management Interface Traffic - Inbound","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"manint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_recv\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"bytes_recv\"}))"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"manint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_recv\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"Trend\"}))"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.18482490272373542,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":38},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Stenographer Packet Loss","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"stenodrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"stenodrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":3,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":42},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"3PVw3hQuZUzyar7Js3mMH","name":"Ectoplasm","type":"scale","hex":"#DA6FF1"},{"id":"O34ux-D8Xq_1-eeWRyYYH","name":"Ectoplasm","type":"scale","hex":"#00717A"},{"id":"P04RoKOHBdLdvfrfFbn0F","name":"Ectoplasm","type":"scale","hex":"#ACFF76"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Disk Usage /","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> filter(fn: (r) => r[\"path\"] == \"/\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> filter(fn: (r) => r[\"path\"] == \"/\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":46},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"5m Load Average","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"load5\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"width":1,"xPos":1},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"},{"id":"z83MTSufTrlrCoEPiBXda","name":"tiger","type":"text","hex":"#F48D38","value":1}],"decimalPlaces":0,"height":2,"kind":"Single_Stat","name":"Warning Alarms","queries":[{"query":"from(bucket: \"_monitoring\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"statuses\")\n |> filter(fn: (r) => r[\"_field\"] == \"_message\")\n |> group(columns: [\"_check_id\"])\n |> sort(columns: [\"_time\"])\n |> last()\n |> group()\n |> filter(fn: (r) => r[\"_level\"] == \"warn\")\n |> count()"}],"staticLegend":{},"suffix":" ","width":1,"xPos":1,"yPos":2},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"IO Wait","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_iowait\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":"%","width":1,"xPos":2},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"},{"id":"z83MTSufTrlrCoEPiBXda","name":"laser","type":"text","hex":"#00C9FF","value":1}],"decimalPlaces":0,"height":2,"kind":"Single_Stat","name":"Informative Alarms","queries":[{"query":"from(bucket: \"_monitoring\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"statuses\")\n |> filter(fn: (r) => r[\"_field\"] == \"_message\")\n |> group(columns: [\"_check_id\"])\n |> sort(columns: [\"_time\"])\n |> last()\n |> group()\n |> filter(fn: (r) => r[\"_level\"] == \"info\")\n |> count()"}],"staticLegend":{},"suffix":" ","width":1,"xPos":2,"yPos":2},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":0,"height":2,"kind":"Single_Stat","name":"Estimated EPS In","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"logstash_events\")\n |> filter(fn: (r) => r[\"_field\"] == \"in\")\n |> hostFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"width":1,"xPos":3},{"colors":[{"id":"0","name":"viridian","type":"min","hex":"#32B08C"},{"id":"5IArg2lDb8KvnphywgUXa","name":"pineapple","type":"threshold","hex":"#FFB94A","value":70},{"id":"yFhH3mtavjuAZh6cEt5lx","name":"fire","type":"threshold","hex":"#DC4E58","value":80},{"id":"1","name":"ruby","type":"max","hex":"#BF3D5E","value":100}],"decimalPlaces":0,"height":4,"kind":"Gauge","name":"CPU Usage","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_idle\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n: 1)\n |> map(fn: (r) => ({r with _value: r._value * -1.0 + 100.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{},"suffix":"%","tickSuffix":"%","width":3,"xPos":3,"yPos":2},{"colors":[{"id":"0","name":"viridian","type":"min","hex":"#32B08C"},{"id":"kOQLOg2H4FVEE-E1_L8Kq","name":"laser","type":"threshold","hex":"#00C9FF","value":85},{"id":"5IArg2lDb8KvnphywgUXa","name":"tiger","type":"threshold","hex":"#F48D38","value":90},{"id":"yFhH3mtavjuAZh6cEt5lx","name":"ruby","type":"threshold","hex":"#BF3D5E","value":95},{"id":"1","name":"ruby","type":"max","hex":"#BF3D5E","value":100}],"decimalPlaces":0,"height":4,"kind":"Gauge","name":"Root Disk Usage","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"path\"] == \"/\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n: 1)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{},"suffix":"%","tickSuffix":"%","width":3,"xPos":3,"yPos":6},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Suricata Packet Loss","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"suridrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"suridrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":3,"widthRatio":1,"xCol":"_time","xPos":3,"yCol":"_value","yPos":42},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":0,"height":2,"kind":"Single_Stat","name":"Redis Queue","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"redisqueue\")\n |> filter(fn: (r) => r[\"_field\"] == \"unparsed\")\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"width":1,"xPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"xflqbsX-j3iq4ry5QOntK","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#8F8AF4"},{"id":"5H28HcITm6QVfQsXon0vq","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#A51414"},{"id":"25MrINwurNBkQqeKCkMPg","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#F4CF31"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Elasticsearch Document Count","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_indices\")\n |> filter(fn: (r) => r[\"_field\"] == \"docs_count\")\n |> filter(fn: (r) => r[\"host\"] == r[\"node_name\"])\n |> hostFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"mean\")"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_indices\")\n |> filter(fn: (r) => r[\"_field\"] == \"docs_count\")\n |> filter(fn: (r) => r[\"host\"] == r[\"node_name\"])\n |> hostFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":10},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"xflqbsX-j3iq4ry5QOntK","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#8F8AF4"},{"id":"5H28HcITm6QVfQsXon0vq","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#A51414"},{"id":"25MrINwurNBkQqeKCkMPg","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#F4CF31"}],"geom":"line","height":4,"heightRatio":0.301556420233463,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Redis Queue","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"redisqueue\")\n |> filter(fn: (r) => r[\"_field\"] == \"unparsed\")\n |> group(columns: [\"host\", \"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"redisqueue\")\n |> filter(fn: (r) => r[\"_field\"] == \"unparsed\")\n |> group(columns: [\"host\", \"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.301556420233463,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":14},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":" days"}],"colorizeRows":true,"colors":[{"id":"sW2GqpGAsGB5Adx16jKjp","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"TsdXuXwdI5Npi9S8L4f-i","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"OGL29-SUbJ6FyQb0JzbaD","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Container Uptime","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_status\")\n |> filter(fn: (r) => r[\"_field\"] == \"uptime_ns\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> group(columns: [\"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> map(fn: (r) => ({r with _value: float(v: r._value) / float(v: 24 * 60 * 60 * 1000000000)}))\n |> yield(name: \"last\")"},{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_status\")\n |> filter(fn: (r) => r[\"_field\"] == \"uptime_ns\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> group(columns: [\"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> map(fn: (r) => ({r with _value: float(v: r._value) / float(v: 24.0 * 60.0 * 60.0 * 1000000000.0)}))\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":18},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":0,"height":2,"hoverDimension":"auto","kind":"Single_Stat_Plus_Line","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Kafka Active Controllers","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"kafka_controller\")\n |> filter(fn: (r) => r[\"_field\"] == \"ActiveControllerCount.Value\")\n |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"current\")"},{"query":"from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"kafka_controller\")\n |> filter(fn: (r) => r[\"_field\"] == \"ActiveControllerCount.Value\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":22},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":0,"height":2,"hoverDimension":"auto","kind":"Single_Stat_Plus_Line","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Kafka Active Brokers","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"kafka_controller\")\n |> filter(fn: (r) => r[\"_field\"] == \"ActiveBrokerCount.Value\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"trend\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"kafka_controller\")\n |> filter(fn: (r) => r[\"_field\"] == \"ActiveBrokerCount.Value\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"current\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":24},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"yT5vTIlaaFChSrQvKLfqf","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"mzzUVSu3ibTph1JmQmDAQ","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"mOcnDo7l8ii6qNLFIB5rs","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Container CPU Usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_cpu\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_percent\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"mean\")"},{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_cpu\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_percent\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":26},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"QDwChKZWuQV0BaJcEeSam","name":"Atlantis","type":"scale","hex":"#74D495"},{"id":"ThD0WTqKHltQEVlq9mo6K","name":"Atlantis","type":"scale","hex":"#3F3FBA"},{"id":"FBHYZiwDLKyQK3eRfUD-0","name":"Atlantis","type":"scale","hex":"#FF4D9E"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Container Memory Usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_percent\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"mean\")"},{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_percent\")\n |> filter(fn: (r) => r[\"container_status\"] == \"running\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":30},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"b"}],"colorizeRows":true,"colors":[{"id":"0ynR6Zs0wuQ3WY0Lz-_KC","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"YiArehCNBwFm9mn8DSXSG","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"DxByY_EQW9Xs2jD5ktkG5","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Container Traffic - Inbound","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_net\")\n |> filter(fn: (r) => r[\"_field\"] == \"rx_bytes\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> map(fn: (r) => ({r with _value: r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"mean\")"},{"query":"containerFilter = (tables=<-) =>\n if v.Container != \"(All)\" then\n tables |> filter(fn: (r) => r[\"container_name\"] == v.Container)\n else\n tables\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_net\")\n |> filter(fn: (r) => r[\"_field\"] == \"rx_bytes\")\n |> hostFilter()\n |> roleFilter()\n |> containerFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with _value: r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\", \"container_name\"])\n |> sort(columns: [\"_time\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":4,"yCol":"_value","yPos":34},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"3PVw3hQuZUzyar7Js3mMH","name":"Ectoplasm","type":"scale","hex":"#DA6FF1"},{"id":"O34ux-D8Xq_1-eeWRyYYH","name":"Ectoplasm","type":"scale","hex":"#00717A"},{"id":"P04RoKOHBdLdvfrfFbn0F","name":"Ectoplasm","type":"scale","hex":"#ACFF76"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Disk Usage /nsm","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> filter(fn: (r) => r[\"path\"] == \"/nsm\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> filter(fn: (r) => r[\"path\"] == \"/nsm\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xPos":4,"yPos":46},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Inbound Traffic","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_recv\") \n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> map(fn: (r) => ({r with _value: r._value * 8.0 / (1000.0 * 1000.0)}))\n |> group(columns: [\"host\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> last()\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":" Mb/s","width":1,"xPos":5},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Inbound Drops","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop_in\") \n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> map(fn: (r) => ({r with _value: r._value * 8.0 / (1000.0 * 1000.0)}))\n |> group(columns: [\"host\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> last()\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":" Mb/s","width":1,"xPos":6},{"colors":[{"id":"0","name":"viridian","type":"min","hex":"#32B08C"},{"id":"5IArg2lDb8KvnphywgUXa","name":"pineapple","type":"threshold","hex":"#FFB94A","value":70},{"id":"yFhH3mtavjuAZh6cEt5lx","name":"fire","type":"threshold","hex":"#DC4E58","value":80},{"id":"1","name":"ruby","type":"max","hex":"#BF3D5E","value":100}],"decimalPlaces":0,"height":4,"kind":"Gauge","name":"Memory Usage","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n: 1)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{},"suffix":"%","tickSuffix":"%","width":3,"xPos":6,"yPos":2},{"colors":[{"id":"0","name":"viridian","type":"min","hex":"#32B08C"},{"id":"5IArg2lDb8KvnphywgUXa","name":"laser","type":"threshold","hex":"#00C9FF","value":85},{"id":"yFhH3mtavjuAZh6cEt5lx","name":"tiger","type":"threshold","hex":"#F48D38","value":90},{"id":"H7uprvKmMEh39en6X-ms_","name":"ruby","type":"threshold","hex":"#BF3D5E","value":95},{"id":"1","name":"ruby","type":"max","hex":"#BF3D5E","value":100}],"decimalPlaces":0,"height":4,"kind":"Gauge","name":"NSM Disk Usage","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\")\n |> filter(fn: (r) => r[\"path\"] == \"/nsm\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n: 1)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{},"suffix":"%","tickSuffix":"%","width":3,"xPos":6,"yPos":6},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"b/s"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"heightRatio":0.18482490272373542,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Management Interface Traffic - Outbound","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"manint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_sent\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n \n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"bytes_sent\"}))"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"manint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"bytes_sent\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n \n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"Trend\"}))"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.18482490272373542,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":38},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Zeek Packet Loss","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekdrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekdrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> hostFilter()\n |> roleFilter()\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":3,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":42},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Capture Loss","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekcaptureloss\")\n |> filter(fn: (r) => r[\"_field\"] == \"loss\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":"%","width":1,"xPos":7},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Zeek Loss","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekdrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":"%","width":1,"xPos":8},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"s"}],"colorizeRows":true,"colors":[{"id":"xflqbsX-j3iq4ry5QOntK","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#8F8AF4"},{"id":"5H28HcITm6QVfQsXon0vq","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#A51414"},{"id":"25MrINwurNBkQqeKCkMPg","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#F4CF31"}],"geom":"line","height":4,"heightRatio":0.301556420233463,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Elastic Ingest Time Spent","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_community_id_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"community.id_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_conditional_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"conditional_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_date_index_name_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"date.index.name_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_date_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"date_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_dissect_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"dissect_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_dot_expander_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"dot.expander_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_geoip_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"geoip_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_grok_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"grok_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_json_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"json_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_kv_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"kv_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_lowercase_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"lowercase_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_rename_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"rename_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_script_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"script_time\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"elasticsearch_clusterstats_nodes\")\n |> filter(fn: (r) => r.role == \"standalone\" or r.role == \"eval\" or r.role == \"import\" or r.role == \"managersearch\" or r.role == \"search\" or r.role == \"node\" or r.role == \"heavynode\")\n |> filter(fn: (r) => r[\"_field\"] == \"ingest_processor_stats_user_agent_time_in_millis\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"user.agent_time\")"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.301556420233463,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":10},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"sW2GqpGAsGB5Adx16jKjp","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"TsdXuXwdI5Npi9S8L4f-i","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"OGL29-SUbJ6FyQb0JzbaD","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"1m Load Average","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"load1\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: true)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"system\")\n |> filter(fn: (r) => r[\"_field\"] == \"load1\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\",\"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: true)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":14,"yTickStep":1},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":" e/s"}],"colorizeRows":true,"colors":[{"id":"xflqbsX-j3iq4ry5QOntK","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#8F8AF4"},{"id":"5H28HcITm6QVfQsXon0vq","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#A51414"},{"id":"25MrINwurNBkQqeKCkMPg","name":"Do Androids Dream of Electric Sheep?","type":"scale","hex":"#F4CF31"}],"geom":"line","height":4,"heightRatio":0.301556420233463,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Logstash EPS","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"logstash_events\")\n |> filter(fn: (r) => r[\"_field\"] == \"in\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"_field\", \"host\", \"pipeline\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"logstash_events\")\n |> filter(fn: (r) => r[\"_field\"] == \"out\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> map(fn: (r) => ({r with _value: -r._value}))\n |> group(columns: [\"_field\", \"host\", \"pipeline\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"logstash_events\")\n |> filter(fn: (r) => r[\"_field\"] == \"in\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> group(columns: [\"_field\", \"host\", \"pipeline\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"},{"query":"from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"logstash_events\")\n |> filter(fn: (r) => r[\"_field\"] == \"out\")\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\") \n |> map(fn: (r) => ({r with _value: -r._value}))\n |> group(columns: [\"_field\", \"host\", \"pipeline\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.301556420233463,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":18},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":0,"height":4,"hoverDimension":"auto","kind":"Single_Stat_Plus_Line","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Kafka Under Replicated Partitions","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"kafka_partition\")\n |> filter(fn: (r) => r[\"_field\"] == \"UnderReplicatedPartitions\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"partition\",\"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"kafka_partition\")\n |> filter(fn: (r) => r[\"_field\"] == \"UnderReplicatedPartitions\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"partition\",\"host\", \"role\"])\n |> yield(name: \"trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":22},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"UAehjIsi65P8u92M_3sQY","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"_SCP8Npp4NVMx2N4mfuzX","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"BoMPg4R1KDp_UsRORdV3_","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"IO Wait","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_iowait\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_iowait\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":26},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"QDwChKZWuQV0BaJcEeSam","name":"Atlantis","type":"scale","hex":"#74D495"},{"id":"ThD0WTqKHltQEVlq9mo6K","name":"Atlantis","type":"scale","hex":"#3F3FBA"},{"id":"FBHYZiwDLKyQK3eRfUD-0","name":"Atlantis","type":"scale","hex":"#FF4D9E"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Swap Usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"swap\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"swap\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> roleFilter()\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":30},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"b/s"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"heightRatio":0.18482490272373542,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Monitor Interface Drops - Inbound","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"monint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop_in\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"drop_in\"}))"},{"query":"import \"join\"\n\nhostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nmanints = from(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"node_config\")\n |> hostFilter()\n |> filter(fn: (r) => r[\"_field\"] == \"monint\")\n |> distinct()\n |> group(columns: [\"host\"])\n\ntraffic = from(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"net\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop_in\")\n |> hostFilter()\n |> roleFilter()\n |> derivative(unit: 1s, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n |> map(fn: (r) => ({r with \"_value\": r._value * 8.0}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"host\"])\n\njoin.inner(left: traffic, right: manints,\n on: (l,r) => l.interface == r._value,\n as: (l, r) => ({l with _value: l._value, result: \"Trend\"}))"}],"staticLegend":{"colorizeRows":true,"heightRatio":0.18482490272373542,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":34},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":" days"}],"colorizeRows":true,"colors":[{"id":"3PVw3hQuZUzyar7Js3mMH","name":"Ectoplasm","type":"scale","hex":"#DA6FF1"},{"id":"O34ux-D8Xq_1-eeWRyYYH","name":"Ectoplasm","type":"scale","hex":"#00717A"},{"id":"P04RoKOHBdLdvfrfFbn0F","name":"Ectoplasm","type":"scale","hex":"#ACFF76"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Stenographer PCAP Retention","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"import \"join\"\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"pcapage\")\n |> filter(fn: (r) => r[\"_field\"] == \"seconds\")\n |> map(fn: (r) => ({ r with _value: r._value / (24.0 * 3600.0)}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])"},{"query":"import \"join\"\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"pcapage\")\n |> filter(fn: (r) => r[\"_field\"] == \"seconds\")\n |> map(fn: (r) => ({ r with _value: r._value / (24.0 * 3600.0)}))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> group(columns: [\"_field\",\"host\"])\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":4,"widthRatio":1,"xCol":"_time","xPos":8,"yCol":"_value","yPos":46},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Suricata Loss","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"suridrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":"%","width":1,"xPos":9},{"colors":[{"id":"0","name":"viridian","type":"min","hex":"#32B08C"},{"id":"5IArg2lDb8KvnphywgUXa","name":"pineapple","type":"threshold","hex":"#FFB94A","value":50},{"id":"yFhH3mtavjuAZh6cEt5lx","name":"fire","type":"threshold","hex":"#DC4E58","value":70},{"id":"1","name":"ruby","type":"max","hex":"#BF3D5E","value":100}],"decimalPlaces":0,"height":4,"kind":"Gauge","name":"Swap Usage","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"swap\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n: 1)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{},"suffix":"%","tickSuffix":"%","width":3,"xPos":9,"yPos":2},{"colors":[{"id":"base","name":"white","type":"text","hex":"#ffffff"}],"fieldOptions":[{"displayName":"Host","fieldName":"host","visible":true},{"displayName":"Name","fieldName":"container_name","visible":true},{"displayName":"Status","fieldName":"container_status","visible":true},{"displayName":"OOM Killed","fieldName":"_value","visible":true},{"displayName":"_start","fieldName":"_start","visible":true},{"displayName":"_stop","fieldName":"_stop","visible":true},{"displayName":"_time","fieldName":"_time","visible":true},{"displayName":"_field","fieldName":"_field","visible":true},{"displayName":"_measurement","fieldName":"_measurement","visible":true},{"displayName":"engine_host","fieldName":"engine_host","visible":true},{"displayName":"role","fieldName":"role","visible":true},{"displayName":"server_version","fieldName":"server_version","visible":true},{"displayName":"container_image","fieldName":"container_image","visible":true},{"displayName":"container_version","fieldName":"container_version","visible":true},{"displayName":"description","fieldName":"description","visible":true},{"displayName":"maintainer","fieldName":"maintainer","visible":true},{"displayName":"io.k8s.description","fieldName":"io.k8s.description","visible":true},{"displayName":"io.k8s.display-name","fieldName":"io.k8s.display-name","visible":true},{"displayName":"license","fieldName":"license","visible":true},{"displayName":"name","fieldName":"name","visible":true},{"displayName":"org.label-schema.build-date","fieldName":"org.label-schema.build-date","visible":true},{"displayName":"org.label-schema.license","fieldName":"org.label-schema.license","visible":true},{"displayName":"org.label-schema.name","fieldName":"org.label-schema.name","visible":true},{"displayName":"org.label-schema.schema-version","fieldName":"org.label-schema.schema-version","visible":true},{"displayName":"org.label-schema.url","fieldName":"org.label-schema.url","visible":true},{"displayName":"org.label-schema.vcs-ref","fieldName":"org.label-schema.vcs-ref","visible":true},{"displayName":"org.label-schema.vcs-url","fieldName":"org.label-schema.vcs-url","visible":true},{"displayName":"org.label-schema.vendor","fieldName":"org.label-schema.vendor","visible":true},{"displayName":"org.label-schema.version","fieldName":"org.label-schema.version","visible":true},{"displayName":"org.opencontainers.image.created","fieldName":"org.opencontainers.image.created","visible":true},{"displayName":"org.opencontainers.image.licenses","fieldName":"org.opencontainers.image.licenses","visible":true},{"displayName":"org.opencontainers.image.title","fieldName":"org.opencontainers.image.title","visible":true},{"displayName":"org.opencontainers.image.vendor","fieldName":"org.opencontainers.image.vendor","visible":true},{"displayName":"release","fieldName":"release","visible":true},{"displayName":"summary","fieldName":"summary","visible":true},{"displayName":"url","fieldName":"url","visible":true},{"displayName":"vendor","fieldName":"vendor","visible":true},{"displayName":"version","fieldName":"version","visible":true},{"displayName":"org.label-schema.usage","fieldName":"org.label-schema.usage","visible":true},{"displayName":"org.opencontainers.image.documentation","fieldName":"org.opencontainers.image.documentation","visible":true},{"displayName":"org.opencontainers.image.revision","fieldName":"org.opencontainers.image.revision","visible":true},{"displayName":"org.opencontainers.image.source","fieldName":"org.opencontainers.image.source","visible":true},{"displayName":"org.opencontainers.image.url","fieldName":"org.opencontainers.image.url","visible":true},{"displayName":"org.opencontainers.image.version","fieldName":"org.opencontainers.image.version","visible":true},{"displayName":"org.opencontainers.image.description","fieldName":"org.opencontainers.image.description","visible":true}],"height":4,"kind":"Table","name":"Most Recent Container Events","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"docker_container_status\")\n |> filter(fn: (r) => r[\"_field\"] == \"oomkilled\")\n |> filter(fn: (r) => r[\"container_status\"] != \"running\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"container_name\", \"host\"])\n |> last()\n |> group()\n |> keep(columns: [\"_value\", \"container_name\", \"host\", \"container_status\"])"}],"staticLegend":{},"tableOptions":{"sortBy":"container_name","verticalTimeAxis":true},"timeFormat":"YYYY-MM-DD HH:mm:ss","width":3,"xPos":9,"yPos":6},{"axes":[{"base":"10","name":"x","scale":"linear"},{"name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"TtgHQAXNep94KBgtu48C_","name":"Cthulhu","type":"scale","hex":"#FDC44F"},{"id":"_IuzkORho_8QXTE6vMllv","name":"Cthulhu","type":"scale","hex":"#007C76"},{"id":"bUszW_YI_9oColDbLNQ-d","name":"Cthulhu","type":"scale","hex":"#8983FF"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Zeek Capture Loss","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekcaptureloss\")\n |> filter(fn: (r) => r[\"_field\"] == \"loss\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"},{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nroleFilter = (tables=<-) =>\n if v.Role != \"(All)\" then\n tables |> filter(fn: (r) => r[\"role\"] == v.Role)\n else\n tables\n\nfrom(bucket: \"telegraf/so_long_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"zeekcaptureloss\")\n |> filter(fn: (r) => r[\"_field\"] == \"loss\")\n |> hostFilter()\n |> roleFilter()\n |> group(columns: [\"_field\", \"host\", \"role\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"Trend\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":3,"widthRatio":1,"xCol":"_time","xPos":9,"yCol":"_value","yPos":42},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"Stenographer Loss","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n\nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"stenodrop\")\n |> filter(fn: (r) => r[\"_field\"] == \"drop\")\n |> map(fn: (r) => ({r with _value: r._value * 100.0}))\n |> hostFilter()\n |> group(columns: [\"host\"])\n |> last()\n |> aggregateWindow(every: v.windowPeriod, fn: mean)\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":"%","width":1,"xPos":10},{"colors":[{"id":"base","name":"laser","type":"text","hex":"#00C9FF"}],"decimalPlaces":1,"height":2,"kind":"Single_Stat","name":"PCAP Retention","queries":[{"query":"hostFilter = (tables=<-) =>\n if v.Host != \"(All)\" then\n tables |> filter(fn: (r) => r[\"host\"] == v.Host)\n else\n tables\n \nfrom(bucket: \"telegraf/so_short_term\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"pcapage\")\n |> filter(fn: (r) => r[\"_field\"] == \"seconds\")\n |> hostFilter()\n |> map(fn: (r) => ({r with _value: r._value / (24.0 * 60.0 * 60.0)}))\n |> group(columns: [\"host\"])\n |> last()\n |> highestMax(n:1)"}],"staticLegend":{},"suffix":" days","width":1,"xPos":11}],"description":"Visualize the Security Onion grid performance metrics and alarm statuses.","name":"Security Onion Performance"}}] \ No newline at end of file diff --git a/salt/kafka/ca.sls b/salt/kafka/ca.sls new file mode 100644 index 000000000..f5e78ee2c --- /dev/null +++ b/salt/kafka/ca.sls @@ -0,0 +1,37 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states or sls in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% set KAFKATRUST = salt['pillar.get']('kafka:truststore') %} + +kafkaconfdir: + file.directory: + - name: /opt/so/conf/kafka + - user: 960 + - group: 960 + - makedirs: True + +{% if GLOBALS.is_manager %} +# Manager runs so-kafka-trust to create truststore for Kafka ssl communication +kafka_truststore: + cmd.script: + - source: salt://kafka/tools/sbin_jinja/so-kafka-trust + - template: jinja + - cwd: /opt/so + - defaults: + GLOBALS: {{ GLOBALS }} + KAFKATRUST: {{ KAFKATRUST }} +{% endif %} + +kafkacertz: + file.managed: + - name: /opt/so/conf/kafka/kafka-truststore.jks + - source: salt://kafka/files/kafka-truststore + - user: 960 + - group: 931 + +{% endif %} \ No newline at end of file diff --git a/salt/kafka/config.map.jinja b/salt/kafka/config.map.jinja new file mode 100644 index 000000000..b8e299838 --- /dev/null +++ b/salt/kafka/config.map.jinja @@ -0,0 +1,103 @@ +{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one + or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at + https://securityonion.net/license; you may not use this file except in compliance with the + Elastic License 2.0. #} +{% from 'kafka/map.jinja' import KAFKAMERGED %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +{% set KAFKA_NODES_PILLAR = salt['pillar.get']('kafka:nodes') %} +{% set KAFKA_PASSWORD = salt['pillar.get']('kafka:config:password') %} +{% set KAFKA_TRUSTPASS = salt['pillar.get']('kafka:config:trustpass') %} +{% set KAFKA_EXTERNAL_ACCESS = salt['pillar.get']('kafka:config:external_access:enabled', default=False) %} + +{# Create list of KRaft controllers #} +{% set controllers = [] %} + +{# Check for Kafka nodes with controller in process_x_roles #} +{% for node in KAFKA_NODES_PILLAR %} +{% if 'controller' in KAFKA_NODES_PILLAR[node].role %} +{% do controllers.append(KAFKA_NODES_PILLAR[node].nodeid ~ "@" ~ KAFKA_NODES_PILLAR[node].ip ~ ":9093") %} +{% endif %} +{% endfor %} + +{% set kafka_controller_quorum_voters = ','.join(controllers) %} + +{# By default all Kafka eligible nodes are given the role of broker, except for + grid MANAGER (broker,controller) until overridden through SOC UI #} +{% set node_type = salt['pillar.get']('kafka:nodes:'+ GLOBALS.hostname + ':role') %} + +{# Generate server.properties for 'broker' , 'controller', 'broker,controller' node types + anything above this line is a configuration needed for ALL Kafka nodes #} +{% if node_type == 'broker' %} +{% if KAFKA_EXTERNAL_ACCESS %} +{% do KAFKAMERGED.config.broker.update({'advertised_x_listeners': 'BROKER://'+ GLOBALS.node_ip +':9092' + ',' + 'EXTERNAL_ACCESS://' + GLOBALS.node_ip + ':29092' }) %} +{% do KAFKAMERGED.config.broker.update({'listeners': KAFKAMERGED.config.broker.listeners + ',' + KAFKAMERGED.config.external_access.listeners }) %} +{% do KAFKAMERGED.config.broker.update({'listener_x_security_x_protocol_x_map': KAFKAMERGED.config.broker.listener_x_security_x_protocol_x_map + ',' + KAFKAMERGED.config.external_access.listener_x_security_x_protocol_x_map }) %} +{% do KAFKAMERGED.config.broker.update({'sasl_x_enabled_x_mechanisms': KAFKAMERGED.config.external_access.sasl_x_enabled_x_mechanisms }) %} +{% do KAFKAMERGED.config.broker.update({'sasl_x_mechanism_x_inter_x_broker_x_protocol': KAFKAMERGED.config.external_access.sasl_x_mechanism_x_inter_x_broker_x_protocol }) %} +{% else %} +{% do KAFKAMERGED.config.broker.update({'advertised_x_listeners': 'BROKER://'+ GLOBALS.node_ip +':9092' }) %} +{% endif %} +{% do KAFKAMERGED.config.broker.update({'controller_x_quorum_x_voters': kafka_controller_quorum_voters }) %} +{% do KAFKAMERGED.config.broker.update({'node_x_id': salt['pillar.get']('kafka:nodes:'+ GLOBALS.hostname +':nodeid') }) %} +{% do KAFKAMERGED.config.broker.update({'ssl_x_keystore_x_password': KAFKA_PASSWORD }) %} + +{# Nodes with only the 'broker' role need to have the below settings for communicating with controller nodes #} +{% do KAFKAMERGED.config.broker.update({'controller_x_listener_x_names': KAFKAMERGED.config.controller.controller_x_listener_x_names }) %} +{% do KAFKAMERGED.config.broker.update({ + 'listener_x_security_x_protocol_x_map': KAFKAMERGED.config.broker.listener_x_security_x_protocol_x_map + + ',' + KAFKAMERGED.config.controller.listener_x_security_x_protocol_x_map }) + %} +{% endif %} + +{% if node_type == 'controller' %} +{% do KAFKAMERGED.config.controller.update({'advertised_x_listeners': 'CONTROLLER://' + GLOBALS.node_ip + ':9093'}) %} +{% do KAFKAMERGED.config.controller.update({'controller_x_quorum_x_voters': kafka_controller_quorum_voters }) %} +{% do KAFKAMERGED.config.controller.update({'node_x_id': salt['pillar.get']('kafka:nodes:'+ GLOBALS.hostname +':nodeid') }) %} +{% do KAFKAMERGED.config.controller.update({'ssl_x_keystore_x_password': KAFKA_PASSWORD }) %} + +{% endif %} + +{# Kafka nodes of this type are not recommended for use outside of development / testing. #} +{% if node_type == 'broker,controller' %} +{% if KAFKA_EXTERNAL_ACCESS %} +{% do KAFKAMERGED.config.broker.update({'advertised_x_listeners': 'BROKER://'+ GLOBALS.node_ip +':9092' + ',' + 'CONTROLLER://'+ GLOBALS.node_ip +':9093' + ',' + 'EXTERNAL_ACCESS://' + GLOBALS.node_ip + ':29092' }) %} +{% do KAFKAMERGED.config.broker.update({'listeners': KAFKAMERGED.config.broker.listeners + ',' + KAFKAMERGED.config.external_access.listeners }) %} +{% do KAFKAMERGED.config.broker.update({'listener_x_security_x_protocol_x_map': KAFKAMERGED.config.broker.listener_x_security_x_protocol_x_map + ',' + KAFKAMERGED.config.external_access.listener_x_security_x_protocol_x_map }) %} +{% do KAFKAMERGED.config.broker.update({'sasl_x_enabled_x_mechanisms': KAFKAMERGED.config.external_access.sasl_x_enabled_x_mechanisms }) %} +{% do KAFKAMERGED.config.broker.update({'sasl_x_mechanism_x_inter_x_broker_x_protocol': KAFKAMERGED.config.external_access.sasl_x_mechanism_x_inter_x_broker_x_protocol }) %} +{% else %} +{% do KAFKAMERGED.config.broker.update({'advertised_x_listeners': 'BROKER://'+ GLOBALS.node_ip +':9092' + ',' + 'CONTROLLER://'+ GLOBALS.node_ip +':9093' }) %} +{% endif %} +{% do KAFKAMERGED.config.broker.update({'controller_x_listener_x_names': KAFKAMERGED.config.controller.controller_x_listener_x_names }) %} +{% do KAFKAMERGED.config.broker.update({'controller_x_quorum_x_voters': kafka_controller_quorum_voters }) %} +{% do KAFKAMERGED.config.broker.update({'node_x_id': salt['pillar.get']('kafka:nodes:'+ GLOBALS.hostname +':nodeid') }) %} +{% do KAFKAMERGED.config.broker.update({'process_x_roles': 'broker,controller' }) %} +{% do KAFKAMERGED.config.broker.update({'ssl_x_keystore_x_password': KAFKA_PASSWORD }) %} + +{% do KAFKAMERGED.config.broker.update({ + 'listeners': KAFKAMERGED.config.broker.listeners + ',' + KAFKAMERGED.config.controller.listeners }) + %} + +{% do KAFKAMERGED.config.broker.update({ + 'listener_x_security_x_protocol_x_map': KAFKAMERGED.config.broker.listener_x_security_x_protocol_x_map + + ',' + KAFKAMERGED.config.controller.listener_x_security_x_protocol_x_map }) + %} + +{% endif %} + +{# Truststore config #} +{% do KAFKAMERGED.config.broker.update({'ssl_x_truststore_x_password': KAFKA_TRUSTPASS }) %} +{% do KAFKAMERGED.config.controller.update({'ssl_x_truststore_x_password': KAFKA_TRUSTPASS }) %} +{% do KAFKAMERGED.config.client.update({'ssl_x_truststore_x_password': KAFKA_TRUSTPASS }) %} + +{# Client properties stuff #} +{% do KAFKAMERGED.config.client.update({'ssl_x_keystore_x_password': KAFKA_PASSWORD }) %} + +{% if 'broker' in node_type %} +{% set KAFKACONFIG = KAFKAMERGED.config.broker %} +{% else %} +{% set KAFKACONFIG = KAFKAMERGED.config.controller %} +{% endif %} + +{% set KAFKACLIENT = KAFKAMERGED.config.client %} \ No newline at end of file diff --git a/salt/kafka/config.sls b/salt/kafka/config.sls new file mode 100644 index 000000000..1bedf96a0 --- /dev/null +++ b/salt/kafka/config.sls @@ -0,0 +1,109 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% set KAFKA_EXTERNAL_ACCESS = salt['pillar.get']('kafka:config:external_access:enabled', default=False) %} +{% set KAFKA_EXTERNAL_USERS = salt['pillar.get']('kafka:config:external_access:remote_users', default=None) %} + +kafka_group: + group.present: + - name: kafka + - gid: 960 + +kafka_user: + user.present: + - name: kafka + - uid: 960 + - gid: 960 + - home: /opt/so/conf/kafka + - createhome: False + +kafka_home_dir: + file.absent: + - name: /home/kafka + +kafka_sbin_tools: + file.recurse: + - name: /usr/sbin + - source: salt://kafka/tools/sbin + - user: 960 + - group: 960 + - file_mode: 755 + +kafka_sbin_jinja_tools: + file.recurse: + - name: /usr/sbin + - source: salt://kafka/tools/sbin_jinja + - user: 960 + - group: 960 + - file_mode: 755 + - template: jinja + - defaults: + GLOBALS: {{ GLOBALS }} + +kafka_log_dir: + file.directory: + - name: /opt/so/log/kafka + - user: 960 + - group: 960 + - makedirs: True + +kafka_data_dir: + file.directory: + - name: /nsm/kafka/data + - user: 960 + - group: 960 + - makedirs: True + +{% for sc in ['server', 'client'] %} +kafka_kraft_{{sc}}_properties: + file.managed: + - source: salt://kafka/etc/{{sc}}.properties.jinja + - name: /opt/so/conf/kafka/{{sc}}.properties + - template: jinja + - user: 960 + - group: 960 + - makedirs: True + - show_changes: False +{% endfor %} + +{% if KAFKA_EXTERNAL_ACCESS and KAFKA_EXTERNAL_USERS != None %} +kafka_server_jaas_properties: + file.managed: + - source: salt://kafka/etc/jaas.conf.jinja + - name: /opt/so/conf/kafka/kafka_server_jaas.conf + - template: jinja + - user: 960 + - group: 960 + - show_changes: False +{% else %} +remove_kafka_server_jaas_properties: + file.absent: + - name: /opt/so/conf/kafka/kafka_server_jaas.conf +{% endif %} + +kafka_log4j_properties: + file.managed: + - source: salt://kafka/etc/log4j.properties + - name: /opt/so/conf/kafka/log4j.properties + - user: 960 + - group: 960 + - show_changes: False + +reset_quorum_on_changes: + cmd.run: + - name: rm -f /nsm/kafka/data/__cluster_metadata-0/quorum-state + - onchanges: + - file: /opt/so/conf/kafka/server.properties + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} \ No newline at end of file diff --git a/salt/kafka/defaults.yaml b/salt/kafka/defaults.yaml new file mode 100644 index 000000000..6b97ea84d --- /dev/null +++ b/salt/kafka/defaults.yaml @@ -0,0 +1,71 @@ +kafka: + enabled: False + cluster_id: + controllers: + reset: + logstash: [] + config: + password: + trustpass: + broker: + advertised_x_listeners: + auto_x_create_x_topics_x_enable: true + controller_x_quorum_x_voters: + default_x_replication_x_factor: 1 + inter_x_broker_x_listener_x_name: BROKER + listeners: BROKER://0.0.0.0:9092 + listener_x_security_x_protocol_x_map: BROKER:SSL + log_x_dirs: /nsm/kafka/data + log_x_retention_x_check_x_interval_x_ms: 300000 + log_x_retention_x_hours: 168 + log_x_segment_x_bytes: 1073741824 + node_x_id: + num_x_io_x_threads: 8 + num_x_network_x_threads: 5 + num_x_partitions: 3 + num_x_recovery_x_threads_x_per_x_data_x_dir: 1 + offsets_x_topic_x_replication_x_factor: 1 + process_x_roles: broker + socket_x_receive_x_buffer_x_bytes: 102400 + socket_x_request_x_max_x_bytes: 104857600 + socket_x_send_x_buffer_x_bytes: 102400 + ssl_x_keystore_x_location: /etc/pki/kafka.p12 + ssl_x_keystore_x_type: PKCS12 + ssl_x_keystore_x_password: + ssl_x_truststore_x_location: /etc/pki/kafka-truststore.jks + ssl_x_truststore_x_type: JKS + ssl_x_truststore_x_password: + transaction_x_state_x_log_x_min_x_isr: 1 + transaction_x_state_x_log_x_replication_x_factor: 1 + client: + security_x_protocol: SSL + ssl_x_truststore_x_location: /etc/pki/kafka-truststore.jks + ssl_x_truststore_x_type: JKS + ssl_x_truststore_x_password: + ssl_x_keystore_x_location: /etc/pki/kafka.p12 + ssl_x_keystore_x_type: PKCS12 + ssl_x_keystore_x_password: + controller: + advertsied_x_listeners: + controller_x_listener_x_names: CONTROLLER + controller_x_quorum_x_voters: + listeners: CONTROLLER://0.0.0.0:9093 + listener_x_security_x_protocol_x_map: CONTROLLER:SSL + log_x_dirs: /nsm/kafka/data + log_x_retention_x_check_x_interval_x_ms: 300000 + log_x_retention_x_hours: 168 + log_x_segment_x_bytes: 1073741824 + node_x_id: + process_x_roles: controller + ssl_x_keystore_x_location: /etc/pki/kafka.p12 + ssl_x_keystore_x_type: PKCS12 + ssl_x_keystore_x_password: + ssl_x_truststore_x_location: /etc/pki/kafka-truststore.jks + ssl_x_truststore_x_type: JKS + ssl_x_truststore_x_password: + external_access: + enabled: False + listeners: EXTERNAL_ACCESS://0.0.0.0:29092 + listener_x_security_x_protocol_x_map: EXTERNAL_ACCESS:SASL_SSL + sasl_x_enabled_x_mechanisms: PLAIN + sasl_x_mechanism_x_inter_x_broker_x_protocol: SSL \ No newline at end of file diff --git a/salt/kafka/disabled.sls b/salt/kafka/disabled.sls new file mode 100644 index 000000000..79fd0c261 --- /dev/null +++ b/salt/kafka/disabled.sls @@ -0,0 +1,34 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'kafka/map.jinja' import KAFKAMERGED %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +so-kafka: + docker_container.absent: + - force: True + +so-kafka_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-kafka$ + - onlyif: grep -q '^so-kafka$' /opt/so/conf/so-status/so-status.conf + +{% if GLOBALS.is_manager and KAFKAMERGED.enabled or GLOBALS.pipeline == "KAFKA" %} +ensure_default_pipeline: + cmd.run: + - name: | + /usr/sbin/so-yaml.py replace /opt/so/saltstack/local/pillar/kafka/soc_kafka.sls kafka.enabled False; + /usr/sbin/so-yaml.py replace /opt/so/saltstack/local/pillar/global/soc_global.sls global.pipeline REDIS +{% endif %} + +{# If Kafka has never been manually enabled, the 'Kafka' user does not exist. In this case certs for Kafka should not exist since they'll be owned by uid 960 #} +{% for cert in ['kafka-client.crt','kafka-client.key','kafka.crt','kafka.key','kafka-logstash.crt','kafka-logstash.key','kafka-logstash.p12','kafka.p12','elasticfleet-kafka.p8'] %} +check_kafka_cert_{{cert}}: + file.absent: + - name: /etc/pki/{{cert}} + - onlyif: stat -c %U /etc/pki/{{cert}} | grep -q UNKNOWN + - show_changes: False +{% endfor %} \ No newline at end of file diff --git a/salt/kafka/enabled.sls b/salt/kafka/enabled.sls new file mode 100644 index 000000000..8448bd5aa --- /dev/null +++ b/salt/kafka/enabled.sls @@ -0,0 +1,98 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. +# +# Note: Per the Elastic License 2.0, the second limitation states: +# +# "You may not move, change, disable, or circumvent the license key functionality +# in the software, and you may not remove or obscure any functionality in the +# software that is protected by the license key." + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% set KAFKANODES = salt['pillar.get']('kafka:nodes') %} +{% set KAFKA_EXTERNAL_ACCESS = salt['pillar.get']('kafka:config:external_access:enabled', default=False) %} +{% if 'gmd' in salt['pillar.get']('features', []) %} + +include: + - kafka.ca + - kafka.config + - kafka.ssl + - kafka.storage + - kafka.sostatus + +so-kafka: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-kafka:{{ GLOBALS.so_version }} + - hostname: so-kafka + - name: so-kafka + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-kafka'].ip }} + - user: kafka + - environment: + KAFKA_HEAP_OPTS: -Xmx2G -Xms1G + KAFKA_OPTS: "-javaagent:/opt/jolokia/agents/jolokia-agent-jvm-javaagent.jar=port=8778,host={{ DOCKER.containers['so-kafka'].ip }},policyLocation=file:/opt/jolokia/jolokia.xml {%- if KAFKA_EXTERNAL_ACCESS %} -Djava.security.auth.login.config=/opt/kafka/config/kafka_server_jaas.conf {% endif -%}" + - extra_hosts: + {% for node in KAFKANODES %} + - {{ node }}:{{ KAFKANODES[node].ip }} + {% endfor %} + {% if DOCKER.containers['so-kafka'].extra_hosts %} + {% for XTRAHOST in DOCKER.containers['so-kafka'].extra_hosts %} + - {{ XTRAHOST }} + {% endfor %} + {% endif %} + - port_bindings: + {% for BINDING in DOCKER.containers['so-kafka'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - binds: + - /etc/pki/kafka.p12:/etc/pki/kafka.p12:ro + - /opt/so/conf/kafka/kafka-truststore.jks:/etc/pki/kafka-truststore.jks:ro + - /nsm/kafka/data/:/nsm/kafka/data/:rw + - /opt/so/log/kafka:/opt/kafka/logs/:rw + - /opt/so/conf/kafka/server.properties:/opt/kafka/config/kraft/server.properties:ro + - /opt/so/conf/kafka/client.properties:/opt/kafka/config/kraft/client.properties:ro + - /opt/so/conf/kafka/log4j.properties:/opt/kafka/config/log4j.properties:ro + {% if KAFKA_EXTERNAL_ACCESS %} + - /opt/so/conf/kafka/kafka_server_jaas.conf:/opt/kafka/config/kafka_server_jaas.conf:ro + {% endif %} + - watch: + {% for sc in ['server', 'client'] %} + - file: kafka_kraft_{{sc}}_properties + {% endfor %} + {% if KAFKA_EXTERNAL_ACCESS %} + - file: kafka_server_jaas_properties + {% endif %} + - file: kafkacertz + - require: + - file: kafkacertz + +delete_so-kafka_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-kafka$ + +{% else %} + +{{sls}}_no_license_detected: + test.fail_without_changes: + - name: {{sls}}_no_license_detected + - comment: + - "Kafka for Guaranteed Message Delivery is a feature supported only for customers with a valid license. + Contact Security Onion Solutions, LLC via our website at https://securityonionsolutions.com + for more information about purchasing a license to enable this feature." +include: + - kafka.disabled +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} \ No newline at end of file diff --git a/salt/curator/map.jinja b/salt/kafka/etc/client.properties.jinja similarity index 67% rename from salt/curator/map.jinja rename to salt/kafka/etc/client.properties.jinja index 517209635..501b028bf 100644 --- a/salt/curator/map.jinja +++ b/salt/kafka/etc/client.properties.jinja @@ -3,5 +3,5 @@ https://securityonion.net/license; you may not use this file except in compliance with the Elastic License 2.0. #} -{% import_yaml 'curator/defaults.yaml' as CURATORDEFAULTS %} -{% set CURATORMERGED = salt['pillar.get']('curator', CURATORDEFAULTS.curator, merge=true) %} +{% from 'kafka/config.map.jinja' import KAFKACLIENT -%} +{{ KAFKACLIENT | yaml(False) | replace("_x_", ".") }} \ No newline at end of file diff --git a/salt/kafka/etc/jaas.conf.jinja b/salt/kafka/etc/jaas.conf.jinja new file mode 100644 index 000000000..e12367cd9 --- /dev/null +++ b/salt/kafka/etc/jaas.conf.jinja @@ -0,0 +1,16 @@ +{% set KAFKA_EXTERNAL_USERS = salt['pillar.get']('kafka:config:external_access:remote_users') -%} + +{%- set valid_users = [] -%} + +{%- for item, user in KAFKA_EXTERNAL_USERS.items() -%} +{% if 'password' in user and user.password is not none and user.password.strip() != "" -%} +{% do valid_users.append('user_' ~ user.username ~ '="' ~ user.password ~ '"') -%} +{% endif -%} +{%- endfor -%} + +KafkaServer { + org.apache.kafka.common.security.plain.PlainLoginModule required + {% for user_entry in valid_users -%} + {{ user_entry }}{{ ";" if loop.last }} + {% endfor %} +}; \ No newline at end of file diff --git a/salt/kafka/etc/log4j.properties b/salt/kafka/etc/log4j.properties new file mode 100644 index 000000000..76194c1ee --- /dev/null +++ b/salt/kafka/etc/log4j.properties @@ -0,0 +1,101 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Unspecified loggers and loggers with additivity=true output to server.log and stdout +# Note that INFO only applies to unspecified loggers, the log level of the child logger is used otherwise +log4j.rootLogger=INFO, stdout, kafkaAppender + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%d] %p %m (%c)%n + +log4j.appender.kafkaAppender=org.apache.log4j.RollingFileAppender +log4j.appender.kafkaAppender.File=${kafka.logs.dir}/server.log +log4j.appender.kafkaAppender.MaxFileSize=10MB +log4j.appender.kafkaAppender.MaxBackupIndex=10 +log4j.appender.kafkaAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.kafkaAppender.layout.ConversionPattern=[%d] %p %m (%c)%n + +log4j.appender.stateChangeAppender=org.apache.log4j.RollingFileAppender +log4j.appender.stateChangeAppender.File=${kafka.logs.dir}/state-change.log +log4j.appender.stateChangeAppender.MaxFileSize=10MB +log4j.appender.stateChangeAppender.MaxBackupIndex=10 +log4j.appender.stateChangeAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.stateChangeAppender.layout.ConversionPattern=[%d] %p %m (%c)%n + +log4j.appender.requestAppender=org.apache.log4j.RollingFileAppender +log4j.appender.requestAppender.File=${kafka.logs.dir}/kafka-request.log +log4j.appender.requestAppender.MaxFileSize=10MB +log4j.appender.requestAppender.MaxBackupIndex=10 +log4j.appender.requestAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.requestAppender.layout.ConversionPattern=[%d] %p %m (%c)%n + +log4j.appender.cleanerAppender=org.apache.log4j.RollingFileAppender +log4j.appender.cleanerAppender.File=${kafka.logs.dir}/log-cleaner.log +log4j.appender.cleanerAppender.MaxFileSize=10MB +log4j.appender.cleanerAppender.MaxBackupIndex=10 +log4j.appender.cleanerAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.cleanerAppender.layout.ConversionPattern=[%d] %p %m (%c)%n + +log4j.appender.controllerAppender=org.apache.log4j.RollingFileAppender +log4j.appender.controllerAppender.File=${kafka.logs.dir}/controller.log +log4j.appender.controllerAppender.MaxFileSize=10MB +log4j.appender.controllerAppender.MaxBackupIndex=10 +log4j.appender.controllerAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.controllerAppender.layout.ConversionPattern=[%d] %p %m (%c)%n + +log4j.appender.authorizerAppender=org.apache.log4j.RollingFileAppender +log4j.appender.authorizerAppender.File=${kafka.logs.dir}/kafka-authorizer.log +log4j.appender.authorizerAppender.MaxFileSize=10MB +log4j.appender.authorizerAppender.MaxBackupIndex=10 +log4j.appender.authorizerAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.authorizerAppender.layout.ConversionPattern=[%d] %p %m (%c)%n + +# Change the line below to adjust ZK client logging +log4j.logger.org.apache.zookeeper=INFO + +# Change the two lines below to adjust the general broker logging level (output to server.log and stdout) +log4j.logger.kafka=INFO +log4j.logger.org.apache.kafka=INFO + +# Change to DEBUG or TRACE to enable request logging +log4j.logger.kafka.request.logger=WARN, requestAppender +log4j.additivity.kafka.request.logger=false + +# Uncomment the lines below and change log4j.logger.kafka.network.RequestChannel$ to TRACE for additional output +# related to the handling of requests +#log4j.logger.kafka.network.Processor=TRACE, requestAppender +#log4j.logger.kafka.server.KafkaApis=TRACE, requestAppender +#log4j.additivity.kafka.server.KafkaApis=false +log4j.logger.kafka.network.RequestChannel$=WARN, requestAppender +log4j.additivity.kafka.network.RequestChannel$=false + +# Change the line below to adjust KRaft mode controller logging +log4j.logger.org.apache.kafka.controller=INFO, controllerAppender +log4j.additivity.org.apache.kafka.controller=false + +# Change the line below to adjust ZK mode controller logging +log4j.logger.kafka.controller=TRACE, controllerAppender +log4j.additivity.kafka.controller=false + +log4j.logger.kafka.log.LogCleaner=INFO, cleanerAppender +log4j.additivity.kafka.log.LogCleaner=false + +log4j.logger.state.change.logger=INFO, stateChangeAppender +log4j.additivity.state.change.logger=false + +# Access denials are logged at INFO level, change to DEBUG to also log allowed accesses +log4j.logger.kafka.authorizer.logger=INFO, authorizerAppender +log4j.additivity.kafka.authorizer.logger=false \ No newline at end of file diff --git a/salt/mysql/map.jinja b/salt/kafka/etc/server.properties.jinja similarity index 67% rename from salt/mysql/map.jinja rename to salt/kafka/etc/server.properties.jinja index dd9a6474e..fb0c785cf 100644 --- a/salt/mysql/map.jinja +++ b/salt/kafka/etc/server.properties.jinja @@ -3,5 +3,5 @@ https://securityonion.net/license; you may not use this file except in compliance with the Elastic License 2.0. #} -{% import_yaml 'mysql/defaults.yaml' as MYSQLDEFAULTS with context %} -{% set MYSQLMERGED = salt['pillar.get']('mysql', MYSQLDEFAULTS.mysql, merge=True) %} +{% from 'kafka/config.map.jinja' import KAFKACONFIG -%} +{{ KAFKACONFIG | yaml(False) | replace("_x_", ".") }} diff --git a/salt/kafka/files/managed_node_pillar.jinja b/salt/kafka/files/managed_node_pillar.jinja new file mode 100644 index 000000000..aa4f7e502 --- /dev/null +++ b/salt/kafka/files/managed_node_pillar.jinja @@ -0,0 +1,10 @@ +kafka: + nodes: +{% for node, values in COMBINED_KAFKANODES.items() %} + {{ node }}: + ip: {{ values['ip'] }} + nodeid: {{ values['nodeid'] }} +{%- if values['role'] != none %} + role: {{ values['role'] }} +{%- endif %} +{% endfor %} \ No newline at end of file diff --git a/salt/kafka/init.sls b/salt/kafka/init.sls new file mode 100644 index 000000000..038920cb8 --- /dev/null +++ b/salt/kafka/init.sls @@ -0,0 +1,29 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. +# +# Note: Per the Elastic License 2.0, the second limitation states: +# +# "You may not move, change, disable, or circumvent the license key functionality +# in the software, and you may not remove or obscure any functionality in the +# software that is protected by the license key." + +{% from 'kafka/map.jinja' import KAFKAMERGED %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: +{# Run kafka/nodes.sls before Kafka is enabled, so kafka nodes pillar is setup #} +{% if grains.role in ['so-manager','so-managersearch', 'so-standalone'] %} + - kafka.nodes +{% endif %} +{% if GLOBALS.pipeline == "KAFKA" and KAFKAMERGED.enabled %} +{% if grains.role in ['so-manager', 'so-managersearch', 'so-standalone', 'so-receiver'] %} + - kafka.enabled +{# Searchnodes only run kafka.ssl state when Kafka is enabled #} +{% elif grains.role == "so-searchnode" %} + - kafka.ssl +{% endif %} +{% else %} + - kafka.disabled +{% endif %} diff --git a/salt/kafka/map.jinja b/salt/kafka/map.jinja new file mode 100644 index 000000000..996e5dedf --- /dev/null +++ b/salt/kafka/map.jinja @@ -0,0 +1,10 @@ +{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one + or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at + https://securityonion.net/license; you may not use this file except in compliance with the + Elastic License 2.0. #} + +{# This is only used to determine if Kafka is enabled / disabled. Configuration is found in kafka/config.map.jinja #} +{# kafka/config.map.jinja depends on there being a kafka nodes pillar being populated #} + +{% import_yaml 'kafka/defaults.yaml' as KAFKADEFAULTS %} +{% set KAFKAMERGED = salt['pillar.get']('kafka', KAFKADEFAULTS.kafka, merge=True) %} diff --git a/salt/kafka/nodes.map.jinja b/salt/kafka/nodes.map.jinja new file mode 100644 index 000000000..e162d3f08 --- /dev/null +++ b/salt/kafka/nodes.map.jinja @@ -0,0 +1,88 @@ +{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one + or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at + https://securityonion.net/license; you may not use this file except in compliance with the + Elastic License 2.0. #} + +{# USED TO GENERATE PILLAR/KAFKA/NODES.SLS. #} +{% import_yaml 'kafka/defaults.yaml' as KAFKADEFAULTS %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +{% set process_x_roles = KAFKADEFAULTS.kafka.config.broker.process_x_roles %} + +{% set current_kafkanodes = salt.saltutil.runner( + 'mine.get', + tgt='G@role:so-manager or G@role:so-managersearch or G@role:so-standalone or G@role:so-receiver', + fun='network.ip_addrs', + tgt_type='compound') %} + +{% set STORED_KAFKANODES = salt['pillar.get']('kafka:nodes', default=None) %} +{% set KAFKA_CONTROLLERS_PILLAR = salt['pillar.get']('kafka:controllers', default=None) %} + +{% set existing_ids = [] %} + +{# Check STORED_KAFKANODES for existing kafka nodes and pull their IDs so they are not reused across the grid #} +{% if STORED_KAFKANODES != none %} +{% for node, values in STORED_KAFKANODES.items() %} +{% if values.get('nodeid') %} +{% do existing_ids.append(values['nodeid']) %} +{% endif %} +{% endfor %} +{% endif %} + +{# Create list of possible node ids #} +{% set all_possible_ids = range(1, 2000)|list %} + +{# Create list of available node ids by looping through all_possible_ids and ensuring it isn't in existing_ids #} +{% set available_ids = [] %} +{% for id in all_possible_ids %} +{% if id not in existing_ids %} +{% do available_ids.append(id) %} +{% endif %} +{% endfor %} + +{# Collect kafka eligible nodes and check if they're already in STORED_KAFKANODES to avoid potentially reassigning a nodeid #} +{% set NEW_KAFKANODES = {} %} +{% for minionid, ip in current_kafkanodes.items() %} +{% set hostname = minionid.split('_')[0] %} +{% if not STORED_KAFKANODES or hostname not in STORED_KAFKANODES %} +{% set new_id = available_ids.pop(0) %} +{% do NEW_KAFKANODES.update({hostname: {'nodeid': new_id, 'ip': ip[0], 'role': process_x_roles }}) %} +{% endif %} +{% endfor %} + +{# Combine STORED_KAFKANODES and NEW_KAFKANODES for writing to the pillar/kafka/nodes.sls #} +{% set COMBINED_KAFKANODES = {} %} +{% for node, details in NEW_KAFKANODES.items() %} +{% do COMBINED_KAFKANODES.update({node: details}) %} +{% endfor %} +{% if STORED_KAFKANODES != none %} +{% for node, details in STORED_KAFKANODES.items() %} +{% do COMBINED_KAFKANODES.update({node: details}) %} +{% endfor %} +{% endif %} + +{# Update the process_x_roles value for any host in the kafka_controllers_pillar configured from SOC UI #} +{% set ns = namespace(has_controller=false) %} +{% if KAFKA_CONTROLLERS_PILLAR != none %} +{% set KAFKA_CONTROLLERS_PILLAR_LIST = KAFKA_CONTROLLERS_PILLAR.split(',') %} +{% for hostname in KAFKA_CONTROLLERS_PILLAR_LIST %} +{% if hostname in COMBINED_KAFKANODES %} +{% do COMBINED_KAFKANODES[hostname].update({'role': 'controller'}) %} +{% set ns.has_controller = true %} +{% endif %} +{% endfor %} +{% for hostname in COMBINED_KAFKANODES %} +{% if hostname not in KAFKA_CONTROLLERS_PILLAR_LIST %} +{% do COMBINED_KAFKANODES[hostname].update({'role': 'broker'}) %} +{% endif %} +{% endfor %} +{# If the kafka_controllers_pillar is NOT empty check that atleast one node contains the controller role. + otherwise default to GLOBALS.manager having broker,controller role #} +{% if not ns.has_controller %} +{% do COMBINED_KAFKANODES[GLOBALS.manager].update({'role': 'broker,controller'}) %} +{% endif %} +{# If kafka_controllers_pillar is empty, default to having grid manager as 'broker,controller' + so there is always atleast 1 controller in the cluster #} +{% else %} +{% do COMBINED_KAFKANODES[GLOBALS.manager].update({'role': 'broker,controller'}) %} +{% endif %} \ No newline at end of file diff --git a/salt/kafka/nodes.sls b/salt/kafka/nodes.sls new file mode 100644 index 000000000..90cc931bb --- /dev/null +++ b/salt/kafka/nodes.sls @@ -0,0 +1,18 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'kafka/nodes.map.jinja' import COMBINED_KAFKANODES %} +{% set kafka_cluster_id = salt['pillar.get']('kafka:cluster_id', default=None) %} + +{# Write Kafka pillar, so all grid members have access to nodeid of other kafka nodes and their roles #} +write_kafka_pillar_yaml: + file.managed: + - name: /opt/so/saltstack/local/pillar/kafka/nodes.sls + - mode: 640 + - user: socore + - source: salt://kafka/files/managed_node_pillar.jinja + - template: jinja + - context: + COMBINED_KAFKANODES: {{ COMBINED_KAFKANODES }} diff --git a/salt/mysql/tools/sbin/so-mysql-restart b/salt/kafka/reset.sls old mode 100755 new mode 100644 similarity index 79% rename from salt/mysql/tools/sbin/so-mysql-restart rename to salt/kafka/reset.sls index 8c0583232..8789516cd --- a/salt/mysql/tools/sbin/so-mysql-restart +++ b/salt/kafka/reset.sls @@ -1,12 +1,9 @@ -#!/bin/bash - # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. - - -. /usr/sbin/so-common - -/usr/sbin/so-restart mysql $1 +wipe_kafka_data: + file.absent: + - name: /nsm/kafka/data/ + - force: True \ No newline at end of file diff --git a/salt/kafka/soc_kafka.yaml b/salt/kafka/soc_kafka.yaml new file mode 100644 index 000000000..cb093600f --- /dev/null +++ b/salt/kafka/soc_kafka.yaml @@ -0,0 +1,273 @@ +kafka: + enabled: + description: Set to True to enable Kafka. To avoid grid problems, do not enable Kafka until the related configuration is in place. Requires a valid Security Onion license key. + helpLink: kafka.html + cluster_id: + description: The ID of the Kafka cluster. + readonly: True + advanced: True + sensitive: True + helpLink: kafka.html + controllers: + description: A comma-separated list of hostnames that will act as Kafka controllers. These hosts will be responsible for managing the Kafka cluster. Note that only manager and receiver nodes are eligible to run Kafka. This configuration needs to be set before enabling Kafka. Failure to do so may result in Kafka topics becoming unavailable requiring manual intervention to restore functionality or reset Kafka, either of which can result in data loss. + forcedType: string + helpLink: kafka.html + reset: + description: Disable and reset the Kafka cluster. This will remove all Kafka data including logs that may have not yet been ingested into Elasticsearch and reverts the grid to using REDIS as the global pipeline. This is useful when testing different Kafka configurations such as rearranging Kafka brokers / controllers allowing you to reset the cluster rather than manually fixing any issues arising from attempting to reassign a Kafka broker into a controller. Enter 'YES_RESET_KAFKA' and submit to disable and reset Kafka. Make any configuration changes required and re-enable Kafka when ready. This action CANNOT be reversed. + advanced: True + helpLink: kafka.html + logstash: + description: By default logstash is disabled when Kafka is enabled. This option allows you to specify any hosts you would like to re-enable logstash on alongside Kafka. + forcedType: "[]string" + multiline: True + advanced: True + helpLink: kafka.html + config: + password: + description: The password used for the Kafka certificates. + readonly: True + sensitive: True + helpLink: kafka.html + trustpass: + description: The password used for the Kafka truststore. + readonly: True + sensitive: True + helpLink: kafka.html + broker: + auto_x_create_x_topics_x_enable: + description: Enable the auto creation of topics. + title: auto.create.topics.enable + forcedType: bool + helpLink: kafka.html + default_x_replication_x_factor: + description: The default replication factor for automatically created topics. This value must be less than the amount of brokers in the cluster. Hosts specified in controllers should not be counted towards total broker count. + title: default.replication.factor + forcedType: int + helpLink: kafka.html + inter_x_broker_x_listener_x_name: + description: The name of the listener used for inter-broker communication. + title: inter.broker.listener.name + helpLink: kafka.html + listeners: + description: Set of URIs that is listened on and the listener names in a comma-seperated list. + helpLink: kafka.html + listener_x_security_x_protocol_x_map: + description: Comma-seperated mapping of listener name and security protocols. + title: listener.security.protocol.map + helpLink: kafka.html + log_x_dirs: + description: Where Kafka logs are stored within the Docker container. + title: log.dirs + helpLink: kafka.html + log_x_retention_x_check_x_interval_x_ms: + description: Frequency at which log files are checked if they are qualified for deletion. + title: log.retention.check.interval.ms + helpLink: kafka.html + log_x_retention_x_hours: + description: How long, in hours, a log file is kept. + title: log.retention.hours + forcedType: int + helpLink: kafka.html + log_x_segment_x_bytes: + description: The maximum allowable size for a log file. + title: log.segment.bytes + forcedType: int + helpLink: kafka.html + num_x_io_x_threads: + description: The number of threads used by Kafka. + title: num.io.threads + forcedType: int + helpLink: kafka.html + num_x_network_x_threads: + description: The number of threads used for network communication. + title: num.network.threads + forcedType: int + helpLink: kafka.html + num_x_partitions: + description: The number of log partitions assigned per topic. + title: num.partitions + forcedType: int + helpLink: kafka.html + num_x_recovery_x_threads_x_per_x_data_x_dir: + description: The number of threads used for log recuperation at startup and purging at shutdown. This ammount of threads is used per data directory. + title: num.recovery.threads.per.data.dir + forcedType: int + helpLink: kafka.html + offsets_x_topic_x_replication_x_factor: + description: The offsets topic replication factor. + title: offsets.topic.replication.factor + forcedType: int + helpLink: kafka.html + process_x_roles: + description: The role performed by Kafka brokers. + title: process.roles + readonly: True + helpLink: kafka.html + socket_x_receive_x_buffer_x_bytes: + description: Size, in bytes of the SO_RCVBUF buffer. A value of -1 will use the OS default. + title: socket.receive.buffer.bytes + #forcedType: int - soc needs to allow -1 as an int before we can use this + helpLink: kafka.html + socket_x_request_x_max_x_bytes: + description: The maximum bytes allowed for a request to the socket. + title: socket.request.max.bytes + forcedType: int + helpLink: kafka.html + socket_x_send_x_buffer_x_bytes: + description: Size, in bytes of the SO_SNDBUF buffer. A value of -1 will use the OS default. + title: socket.send.buffer.byte + #forcedType: int - soc needs to allow -1 as an int before we can use this + helpLink: kafka.html + ssl_x_keystore_x_location: + description: The key store file location within the Docker container. + title: ssl.keystore.location + helpLink: kafka.html + ssl_x_keystore_x_password: + description: The key store file password. Invalid for PEM format. + title: ssl.keystore.password + sensitive: True + helpLink: kafka.html + ssl_x_keystore_x_type: + description: The key store file format. + title: ssl.keystore.type + regex: ^(JKS|PKCS12|PEM)$ + helpLink: kafka.html + ssl_x_truststore_x_location: + description: The trust store file location within the Docker container. + title: ssl.truststore.location + helpLink: kafka.html + ssl_x_truststore_x_type: + description: The trust store file format. + title: ssl.truststore.type + helpLink: kafka.html + ssl_x_truststore_x_password: + description: The trust store file password. If null, the trust store file is still use, but integrity checking is disabled. Invalid for PEM format. + title: ssl.truststore.password + sensitive: True + helpLink: kafka.html + transaction_x_state_x_log_x_min_x_isr: + description: Overrides min.insync.replicas for the transaction topic. When a producer configures acks to "all" (or "-1"), this setting determines the minimum number of replicas required to acknowledge a write as successful. Failure to meet this minimum triggers an exception (either NotEnoughReplicas or NotEnoughReplicasAfterAppend). When used in conjunction, min.insync.replicas and acks enable stronger durability guarantees. For instance, creating a topic with a replication factor of 3, setting min.insync.replicas to 2, and using acks of "all" ensures that the producer raises an exception if a majority of replicas fail to receive a write. + title: transaction.state.log.min.isr + forcedType: int + helpLink: kafka.html + transaction_x_state_x_log_x_replication_x_factor: + description: Set the replication factor higher for the transaction topic to ensure availability. Internal topic creation will not proceed until the cluster size satisfies this replication factor prerequisite. + title: transaction.state.log.replication.factor + forcedType: int + helpLink: kafka.html + client: + security_x_protocol: + description: 'Broker communication protocol. Options are: SASL_SSL, PLAINTEXT, SSL, SASL_PLAINTEXT' + title: security.protocol + regex: ^(SASL_SSL|PLAINTEXT|SSL|SASL_PLAINTEXT) + helpLink: kafka.html + ssl_x_keystore_x_location: + description: The key store file location within the Docker container. + title: ssl.keystore.location + helpLink: kafka.html + ssl_x_keystore_x_password: + description: The key store file password. Invalid for PEM format. + title: ssl.keystore.password + sensitive: True + helpLink: kafka.html + ssl_x_keystore_x_type: + description: The key store file format. + title: ssl.keystore.type + regex: ^(JKS|PKCS12|PEM)$ + helpLink: kafka.html + ssl_x_truststore_x_location: + description: The trust store file location within the Docker container. + title: ssl.truststore.location + helpLink: kafka.html + ssl_x_truststore_x_type: + description: The trust store file format. + title: ssl.truststore.type + helpLink: kafka.html + ssl_x_truststore_x_password: + description: The trust store file password. If null, the trust store file is still use, but integrity checking is disabled. Invalid for PEM format. + title: ssl.truststore.password + sensitive: True + helpLink: kafka.html + controller: + controller_x_listener_x_names: + description: Set listeners used by the controller in a comma-seperated list. + title: controller.listener.names + helpLink: kafka.html + listeners: + description: Set of URIs that is listened on and the listener names in a comma-seperated list. + helpLink: kafka.html + listener_x_security_x_protocol_x_map: + description: Comma-seperated mapping of listener name and security protocols. + title: listener.security.protocol.map + helpLink: kafka.html + log_x_dirs: + description: Where Kafka logs are stored within the Docker container. + title: log.dirs + helpLink: kafka.html + log_x_retention_x_check_x_interval_x_ms: + description: Frequency at which log files are checked if they are qualified for deletion. + title: log.retention.check.interval.ms + helpLink: kafka.html + log_x_retention_x_hours: + description: How long, in hours, a log file is kept. + title: log.retention.hours + forcedType: int + helpLink: kafka.html + log_x_segment_x_bytes: + description: The maximum allowable size for a log file. + title: log.segment.bytes + forcedType: int + helpLink: kafka.html + process_x_roles: + description: The role performed by controller node. + title: process.roles + readonly: True + helpLink: kafka.html + external_access: + enabled: + description: Enables or disables access to Kafka topics using user/password authentication. Used for producing / consuming messages via an external client. + forcedType: bool + helpLink: kafka.html + listeners: + description: Set of URIs that is listened on and the listener names in a comma-seperated list. + title: listeners + readonly: True + advanced: True + helpLink: kafka.html + listener_x_security_x_protocol_x_map: + description: External listener name and mapped security protocol. + title: listener.security.protocol.map + readonly: True + advanced: True + helpLink: kafka.html + sasl_x_enabled_x_mechanisms: + description: SASL/PLAIN is a simple username/password authentication mechanism, used with TLS to implement secure authentication. + title: sasl.enabled.mechanisms + readonly: True + advanced: True + helpLink: kafka.html + sasl_x_mechanism_x_inter_x_broker_x_protocol: + description: SASL mechanism used for inter-broker communication + title: sasl.mechanism.inter.broker.protocol + readonly: True + advanced: True + helpLink: kafka.html + remote_users: + user01: &remote_user + username: + description: Username to be used for custom account + forcedType: string + global: True + password: + description: Password to be used for custom account + forcedType: string + global: True + sensitive: True + user02: *remote_user + user03: *remote_user + user04: *remote_user + user05: *remote_user + user06: *remote_user + user07: *remote_user + user08: *remote_user + user09: *remote_user \ No newline at end of file diff --git a/salt/curator/sostatus.sls b/salt/kafka/sostatus.sls similarity index 80% rename from salt/curator/sostatus.sls rename to salt/kafka/sostatus.sls index de6459a6d..37c868a46 100644 --- a/salt/curator/sostatus.sls +++ b/salt/kafka/sostatus.sls @@ -6,11 +6,11 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} -append_so-curator_so-status.conf: +append_so-kafka_so-status.conf: file.append: - name: /opt/so/conf/so-status/so-status.conf - - text: so-curator - - unless: grep -q so-curator /opt/so/conf/so-status/so-status.conf + - text: so-kafka + - unless: grep -q so-kafka /opt/so/conf/so-status/so-status.conf {% else %} @@ -18,4 +18,4 @@ append_so-curator_so-status.conf: test.fail_without_changes: - name: {{sls}}_state_not_allowed -{% endif %} +{% endif %} \ No newline at end of file diff --git a/salt/kafka/ssl.sls b/salt/kafka/ssl.sls new file mode 100644 index 000000000..04b6b4ba7 --- /dev/null +++ b/salt/kafka/ssl.sls @@ -0,0 +1,201 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states or sls in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% set kafka_password = salt['pillar.get']('kafka:config:password') %} + +include: + - ca.dirs + {% set global_ca_server = [] %} + {% set x509dict = salt['mine.get'](GLOBALS.manager | lower~'*', 'x509.get_pem_entries') %} + {% for host in x509dict %} + {% if 'manager' in host.split('_')|last or host.split('_')|last == 'standalone' %} + {% do global_ca_server.append(host) %} + {% endif %} + {% endfor %} + {% set ca_server = global_ca_server[0] %} + +{% if GLOBALS.pipeline == "KAFKA" %} + +{% if GLOBALS.role in ['so-manager', 'so-managersearch', 'so-standalone'] %} +kafka_client_key: + x509.private_key_managed: + - name: /etc/pki/kafka-client.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/kafka-client.key') -%} + - prereq: + - x509: /etc/pki/kafka-client.crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +kafka_client_crt: + x509.certificate_managed: + - name: /etc/pki/kafka-client.crt + - ca_server: {{ ca_server }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - signing_policy: kafka + - private_key: /etc/pki/kafka-client.key + - CN: {{ GLOBALS.hostname }} + - days_remaining: 0 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + +kafka_client_key_perms: + file.managed: + - replace: False + - name: /etc/pki/kafka-client.key + - mode: 640 + - user: 960 + - group: 939 + +kafka_client_crt_perms: + file.managed: + - replace: False + - name: /etc/pki/kafka-client.crt + - mode: 640 + - user: 960 + - group: 939 +{% endif %} + +{% if GLOBALS.role in ['so-manager', 'so-managersearch','so-receiver', 'so-standalone'] %} +kafka_key: + x509.private_key_managed: + - name: /etc/pki/kafka.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/kafka.key') -%} + - prereq: + - x509: /etc/pki/kafka.crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +kafka_crt: + x509.certificate_managed: + - name: /etc/pki/kafka.crt + - ca_server: {{ ca_server }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - signing_policy: kafka + - private_key: /etc/pki/kafka.key + - CN: {{ GLOBALS.hostname }} + - days_remaining: 0 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + cmd.run: + - name: "/usr/bin/openssl pkcs12 -inkey /etc/pki/kafka.key -in /etc/pki/kafka.crt -export -out /etc/pki/kafka.p12 -nodes -passout pass:{{ kafka_password }}" + - onchanges: + - x509: /etc/pki/kafka.key +kafka_key_perms: + file.managed: + - replace: False + - name: /etc/pki/kafka.key + - mode: 640 + - user: 960 + - group: 939 + +kafka_crt_perms: + file.managed: + - replace: False + - name: /etc/pki/kafka.crt + - mode: 640 + - user: 960 + - group: 939 + +kafka_pkcs12_perms: + file.managed: + - replace: False + - name: /etc/pki/kafka.p12 + - mode: 640 + - user: 960 + - group: 939 +{% endif %} + +# Standalone needs kafka-logstash for automated testing. Searchnode/manager search need it for logstash to consume from Kafka. +# Manager will have cert, but be unused until a pipeline is created and logstash enabled. +{% if GLOBALS.role in ['so-standalone', 'so-managersearch', 'so-searchnode', 'so-manager'] %} +kafka_logstash_key: + x509.private_key_managed: + - name: /etc/pki/kafka-logstash.key + - keysize: 4096 + - backup: True + - new: True + {% if salt['file.file_exists']('/etc/pki/kafka-logstash.key') -%} + - prereq: + - x509: /etc/pki/kafka-logstash.crt + {%- endif %} + - retry: + attempts: 5 + interval: 30 + +kafka_logstash_crt: + x509.certificate_managed: + - name: /etc/pki/kafka-logstash.crt + - ca_server: {{ ca_server }} + - subjectAltName: DNS:{{ GLOBALS.hostname }}, IP:{{ GLOBALS.node_ip }} + - signing_policy: kafka + - private_key: /etc/pki/kafka-logstash.key + - CN: {{ GLOBALS.hostname }} + - days_remaining: 0 + - days_valid: 820 + - backup: True + - timeout: 30 + - retry: + attempts: 5 + interval: 30 + cmd.run: + - name: "/usr/bin/openssl pkcs12 -inkey /etc/pki/kafka-logstash.key -in /etc/pki/kafka-logstash.crt -export -out /etc/pki/kafka-logstash.p12 -nodes -passout pass:{{ kafka_password }}" + - onchanges: + - x509: /etc/pki/kafka-logstash.key + +kafka_logstash_key_perms: + file.managed: + - replace: False + - name: /etc/pki/kafka-logstash.key + - mode: 640 + - user: 931 + - group: 939 + +kafka_logstash_crt_perms: + file.managed: + - replace: False + - name: /etc/pki/kafka-logstash.crt + - mode: 640 + - user: 931 + - group: 939 + +kafka_logstash_pkcs12_perms: + file.managed: + - replace: False + - name: /etc/pki/kafka-logstash.p12 + - mode: 640 + - user: 931 + - group: 939 + +{% endif %} +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} \ No newline at end of file diff --git a/salt/kafka/storage.sls b/salt/kafka/storage.sls new file mode 100644 index 000000000..efc36acf6 --- /dev/null +++ b/salt/kafka/storage.sls @@ -0,0 +1,30 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% set kafka_cluster_id = salt['pillar.get']('kafka:cluster_id') %} + +{# Initialize kafka storage if it doesn't already exist. Just looking for meta.properties in /nsm/kafka/data #} +{% if not salt['file.file_exists']('/nsm/kafka/data/meta.properties') %} +kafka_storage_init: + cmd.run: + - name: | + docker run -v /nsm/kafka/data:/nsm/kafka/data -v /opt/so/conf/kafka/server.properties:/opt/kafka/config/kraft/newserver.properties --name so-kafkainit --user root --entrypoint /opt/kafka/bin/kafka-storage.sh {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-kafka:{{ GLOBALS.so_version }} format -t {{ kafka_cluster_id }} -c /opt/kafka/config/kraft/newserver.properties +kafka_rm_kafkainit: + cmd.run: + - name: | + docker rm so-kafkainit +{% endif %} + + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/kafka/tools/sbin/so-kafka-cli b/salt/kafka/tools/sbin/so-kafka-cli new file mode 100644 index 000000000..41993f67f --- /dev/null +++ b/salt/kafka/tools/sbin/so-kafka-cli @@ -0,0 +1,47 @@ +#! /bin/bash +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +if [ -z "$NOROOT" ]; then + # Check for prerequisites + if [ "$(id -u)" -ne 0 ]; then + echo "This script must be run using sudo!" + exit 1 + fi +fi + +function usage() { + echo -e "\nUsage: $0