diff --git a/CHANGELOG.md b/CHANGELOG.md index 496bf362..75169db2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,23 @@ # Change Log All notable changes to this project will be documented in this file. +## Wazuh Docker v4.0.0_1.10.1 + +### Added + +- Update to Wazuh version 4.0.0 +- Updating Wazuh cluster key dynamically ([@1stOfHisGame](https://github.com/1stOfHisGame)) [#393](https://github.com/wazuh/wazuh-docker/pull/393) +- Switched to CentOS 7 for base image ([@xr09](https://github.com/xr09)) [#259](https://github.com/wazuh/wazuh-docker/issues/259) +- Using s6-overlay for process management ([@xr09](https://github.com/xr09)) [#274](https://github.com/wazuh/wazuh-docker/issues/274) +- Allow the creation of custom API users ([@xr09](https://github.com/xr09)) [#395](https://github.com/wazuh/wazuh-docker/issues/395) +- OpenDistro support ([@xr09](https://github.com/xr09)) [#373](https://github.com/wazuh/wazuh-docker/pull/373) + + +### Changed + +- Removal of Elastic images + + ## Wazuh Docker v3.13.2_7.9.1 ### Added diff --git a/README.md b/README.md index a53e9aae..77ce2d2a 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,9 @@ In this repository you will find the containers to run: -* wazuh: It runs the Wazuh manager, Wazuh API and Filebeat (for integration with Elastic Stack) -* wazuh-kibana: Provides a web user interface to browse through alerts data. It includes Wazuh plugin for Kibana, that allows you to visualize agents configuration and status. -* wazuh-nginx: Proxies the Kibana container, adding HTTPS (via self-signed SSL certificate) and [Basic authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#Basic_authentication_scheme). -* wazuh-elasticsearch: An Elasticsearch container (working as a single-node cluster) using Elastic Stack Docker images. **Be aware to increase the `vm.max_map_count` setting, as it's detailed in the [Wazuh documentation](https://documentation.wazuh.com/current/docker/wazuh-container.html#increase-max-map-count-on-your-host-linux).** +* wazuh-opendistro: It runs the Wazuh manager, Wazuh API and Filebeat OSS (for integration with ODFE) +* wazuh-kibana-opendistro: Provides a web user interface to browse through alerts data. It includes Wazuh plugin for Kibana, that allows you to visualize agents configuration and status. +* opendistro-for-elasticsearch: An Elasticsearch (ODFE) container (working as a single-node cluster) using ODFE Docker images. **Be aware to increase the `vm.max_map_count` setting, as it's detailed in the [Wazuh documentation](https://documentation.wazuh.com/current/docker/wazuh-container.html#increase-max-map-count-on-your-host-linux).** In addition, a docker-compose file is provided to launch the containers mentioned above. @@ -22,43 +21,145 @@ In addition, a docker-compose file is provided to launch the containers mentione * [Wazuh documentation for Docker](https://documentation.wazuh.com/current/docker/index.html) * [Docker hub](https://hub.docker.com/u/wazuh) + +### Setup SSL certificate and Basic Authentication + +Before starting the environment it is required to provide an SSL certificate (or just generate one self-signed) and setup the basic auth. + +Documentation on how to provide these two can be found at [nginx_conf/README.md](nginx_conf/README.md). + + +## Environment Variables + +Default values are included when available. + +### Wazuh +``` +API_USERNAME="wazuh" # Wazuh API username +API_PASSWORD="wazuh" # Wazuh API password - Must comply with requirements + # (8+ length, uppercase, lowercase, specials chars) + +ELASTICSEARCH_URL=https://elasticsearch:9200 # Elasticsearch URL +ELASTIC_USERNAME=admin # Elasticsearch Username +ELASTIC_PASSWORD=admin # Elasticsearch Password +FILEBEAT_SSL_VERIFICATION_MODE=full # Filebeat SSL Verification mode (full or none) +SSL_CERTIFICATE_AUTHORITIES="" # Path of Filebeat SSL CA +SSL_CERTIFICATE="" # Path of Filebeat SSL Certificate +SSL_KEY="" # Path of Filebeat SSL Key +``` + +### Kibana +``` +PATTERN="wazuh-alerts-*" # Default index pattern to use + +CHECKS_PATTERN=true # Defines which checks must to be consider by the healthcheck +CHECKS_TEMPLATE=true # step once the Wazuh app starts. Values must to be true or false +CHECKS_API=true +CHECKS_SETUP=true + +EXTENSIONS_PCI=true # Enable PCI Extension +EXTENSIONS_GDPR=true # Enable GDPR Extension +EXTENSIONS_HIPAA=true # Enable HIPAA Extension +EXTENSIONS_NIST=true # Enable NIST Extension +EXTENSIONS_TSC=true # Enable TSC Extension +EXTENSIONS_AUDIT=true # Enable Audit Extension +EXTENSIONS_OSCAP=false # Enable OpenSCAP Extension +EXTENSIONS_CISCAT=false # Enable CISCAT Extension +EXTENSIONS_AWS=false # Enable AWS Extension +EXTENSIONS_GCP=false # Enable GCP Extension +EXTENSIONS_VIRUSTOTAL=false # Enable Virustotal Extension +EXTENSIONS_OSQUERY=false # Enable OSQuery Extension +EXTENSIONS_DOCKER=false # Enable Docker Extension + +APP_TIMEOUT=20000 # Defines maximum timeout to be used on the Wazuh app requests + +API_SELECTOR=true Defines if the user is allowed to change the selected API directly from the Wazuh app top menu +IP_SELECTOR=true # Defines if the user is allowed to change the selected index pattern directly from the Wazuh app top menu +IP_IGNORE="[]" # List of index patterns to be ignored + +WAZUH_MONITORING_ENABLED=true # Custom settings to enable/disable wazuh-monitoring indices +WAZUH_MONITORING_FREQUENCY=900 # Custom setting to set the frequency for wazuh-monitoring indices cron task +WAZUH_MONITORING_SHARDS=2 # Configure wazuh-monitoring-* indices shards and replicas +WAZUH_MONITORING_REPLICAS=0 # + +ADMIN_PRIVILEGES=true # App privileges +``` + ## Directory structure - wazuh-docker - ├── docker-compose.yml - ├── kibana - │   ├── config - │   │   ├── entrypoint.sh - │   │   └── kibana.yml - │   └── Dockerfile - ├── LICENSE - ├── nginx - │   ├── config - │   │   └── entrypoint.sh - │   └── Dockerfile - ├── README.md - ├── CHANGELOG.md - ├── VERSION - ├── test.txt - └── wazuh - ├── config - │   ├── data_dirs.env - │   ├── entrypoint.sh - │   ├── filebeat.runit.service - │   ├── filebeat.yml - │   ├── init.bash - │   ├── postfix.runit.service - │   ├── wazuh-api.runit.service - │   └── wazuh.runit.service - └── Dockerfile + ├── CHANGELOG.md + ├── docker-compose.yml + ├── elastic_conf + │   └── elasticsearch.yml + ├── generate-opendistro-certs.yml + ├── kibana-odfe + │   ├── config + │   │   ├── custom_welcome + │   │   │   ├── light_theme.style.css + │   │   │   ├── template.js.hbs + │   │   │   ├── wazuh_logo_circle.svg + │   │   │   └── wazuh_wazuh_bg.svg + │   │   ├── entrypoint.sh + │   │   ├── kibana_settings.sh + │   │   ├── wazuh_app_config.sh + │   │   ├── wazuh.yml + │   │   └── welcome_wazuh.sh + │   └── Dockerfile + ├── LICENSE + ├── production_cluster + │   ├── elastic_opendistro + │   │   ├── elasticsearch-node1.yml + │   │   ├── elasticsearch-node2.yml + │   │   ├── elasticsearch-node3.yml + │   │   └── internal_users.yml + │   ├── kibana_ssl + │   │   └── generate-self-signed-cert.sh + │   ├── nginx + │   │   ├── nginx.conf + │   │   └── ssl + │   │   └── generate-self-signed-cert.sh + │   ├── ssl_certs + │   │   └── certs.yml + │   └── wazuh_cluster + │   ├── wazuh_manager.conf + │   └── wazuh_worker.conf + ├── production-cluster.yml + ├── README.md + ├── VERSION + └── wazuh-odfe + ├── config + │   ├── create_user.py + │   ├── etc + │   │   ├── cont-init.d + │   │   │   ├── 0-wazuh-init + │   │   │   ├── 1-config-filebeat + │   │   │   └── 2-manager + │   │   └── services.d + │   │   └── filebeat + │   │   ├── finish + │   │   └── run + │   ├── filebeat.yml + │   ├── permanent_data.env + │   ├── permanent_data.sh + │   └── wazuh.repo + └── Dockerfile + ## Branches -* `stable` branch on correspond to the latest Wazuh-Docker stable version. +* `4.0` branch on correspond to the latest Wazuh-Docker stable version. * `master` branch contains the latest code, be aware of possible bugs on this branch. * `Wazuh.Version_ElasticStack.Version` (for example 3.13.1_7.8.0) branch. This branch contains the current release referenced in Docker Hub. The container images are installed under the current version of this branch. + +## Compatibility Matrix + +| Wazuh version | ODFE | +|---------------|---------| +| v4.0.0 | 1.10.1 | + + ## Credits and Thank you These Docker containers are based on: diff --git a/VERSION b/VERSION index e3f58770..1cdd9758 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ -WAZUH-DOCKER_VERSION="3.13.2_7.9.1" -REVISION="31320" +WAZUH-DOCKER_VERSION="4.0.0_1.10.1" +REVISION="40000" diff --git a/docker-compose.yml b/docker-compose.yml index 601e84e8..cf47f224 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,28 +1,46 @@ # Wazuh App Copyright (C) 2020 Wazuh Inc. (License GPLv2) -version: '2' +version: '3.7' services: wazuh: - image: wazuh/wazuh:3.13.2_7.9.1 + image: wazuh/wazuh-odfe:4.0.0_1.10.1 hostname: wazuh-manager restart: always ports: - - "1514:1514/udp" + - "1514:1514" - "1515:1515" - "514:514/udp" - "55000:55000" + environment: + - ELASTICSEARCH_URL=https://elasticsearch:9200 + - ELASTIC_USERNAME=admin + - ELASTIC_PASSWORD=admin + - FILEBEAT_SSL_VERIFICATION_MODE=none + volumes: + - ossec_api_configuration:/var/ossec/api/configuration + - ossec_etc:/var/ossec/etc + - ossec_logs:/var/ossec/logs + - ossec_queue:/var/ossec/queue + - ossec_var_multigroups:/var/ossec/var/multigroups + - ossec_integrations:/var/ossec/integrations + - ossec_active_response:/var/ossec/active-response/bin + - ossec_agentless:/var/ossec/agentless + - ossec_wodles:/var/ossec/wodles + - filebeat_etc:/etc/filebeat + - filebeat_var:/var/lib/filebeat elasticsearch: - image: wazuh/wazuh-elasticsearch:3.13.2_7.9.1 + image: amazon/opendistro-for-elasticsearch:1.10.1 hostname: elasticsearch restart: always ports: - "9200:9200" environment: - - "ES_JAVA_OPTS=-Xms1g -Xmx1g" - - ELASTIC_CLUSTER=true - - CLUSTER_NODE_MASTER=true - - CLUSTER_MASTER_NODE_NAME=es01 + - discovery.type=single-node + - cluster.name=wazuh-cluster + - network.host=0.0.0.0 + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + - bootstrap.memory_lock=true ulimits: memlock: soft: -1 @@ -30,29 +48,35 @@ services: nofile: soft: 65536 hard: 65536 - mem_limit: 2g kibana: - image: wazuh/wazuh-kibana:3.13.2_7.9.1 + image: wazuh/wazuh-kibana-odfe:4.0.0_1.10.1 hostname: kibana restart: always + ports: + - 443:5601 + environment: + - ELASTICSEARCH_USERNAME=admin + - ELASTICSEARCH_PASSWORD=admin + - SERVER_SSL_ENABLED=true + - SERVER_SSL_CERTIFICATE=/usr/share/kibana/config/opendistroforelasticsearch.example.org.cert + - SERVER_SSL_KEY=/usr/share/kibana/config/opendistroforelasticsearch.example.org.key + depends_on: - elasticsearch links: - elasticsearch:elasticsearch - wazuh:wazuh - nginx: - image: wazuh/wazuh-nginx:3.13.2_7.9.1 - hostname: nginx - restart: always - environment: - - NGINX_PORT=443 - - NGINX_CREDENTIALS - ports: - - "80:80" - - "443:443" - depends_on: - - kibana - links: - - kibana:kibana +volumes: + ossec_api_configuration: + ossec_etc: + ossec_logs: + ossec_queue: + ossec_var_multigroups: + ossec_integrations: + ossec_active_response: + ossec_agentless: + ossec_wodles: + filebeat_etc: + filebeat_var: diff --git a/elastic_conf/elasticsearch.yml b/elastic_conf/elasticsearch.yml new file mode 100644 index 00000000..a7b1d6a5 --- /dev/null +++ b/elastic_conf/elasticsearch.yml @@ -0,0 +1,3 @@ +cluster.name: wazuh-elastic +network.host: 0.0.0.0 + diff --git a/elasticsearch/Dockerfile b/elasticsearch/Dockerfile deleted file mode 100644 index fb3644b2..00000000 --- a/elasticsearch/Dockerfile +++ /dev/null @@ -1,56 +0,0 @@ -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) -ARG ELASTIC_VERSION=7.9.1 -FROM docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION} -ARG ELASTIC_VERSION -ARG S3_PLUGIN_URL="https://artifacts.elastic.co/downloads/elasticsearch-plugins/repository-s3/repository-s3-${ELASTIC_VERSION}.zip" - -ENV ELASTICSEARCH_URL="http://elasticsearch:9200" - -ENV ALERTS_SHARDS="1" \ - ALERTS_REPLICAS="0" - -ENV API_USER="foo" \ - API_PASS="bar" - -ENV XPACK_ML="true" - -ENV ENABLE_CONFIGURE_S3="false" - -ARG TEMPLATE_VERSION=v3.13.2 - -# Elasticearch cluster configuration environment variables -# If ELASTIC_CLUSTER is set to "true" the following variables will be added to the Elasticsearch configuration -# CLUSTER_INITIAL_MASTER_NODES set to own node by default. -ENV ELASTIC_CLUSTER="false" \ - CLUSTER_NAME="wazuh" \ - CLUSTER_NETWORK_HOST="0.0.0.0" \ - CLUSTER_NODE_MASTER="false" \ - CLUSTER_NODE_DATA="true" \ - CLUSTER_NODE_INGEST="true" \ - CLUSTER_NODE_NAME="wazuh-elasticsearch" \ - CLUSTER_MASTER_NODE_NAME="master-node" \ - CLUSTER_MEMORY_LOCK="true" \ - CLUSTER_DISCOVERY_SERVICE="wazuh-elasticsearch" \ - CLUSTER_NUMBER_OF_MASTERS="2" \ - CLUSTER_MAX_NODES="1" \ - CLUSTER_DELAYED_TIMEOUT="1m" \ - CLUSTER_INITIAL_MASTER_NODES="wazuh-elasticsearch" - -COPY config/entrypoint.sh /entrypoint.sh - -RUN chmod 755 /entrypoint.sh - -COPY --chown=elasticsearch:elasticsearch ./config/load_settings.sh ./ - -RUN chmod +x ./load_settings.sh - -RUN bin/elasticsearch-plugin install --batch $S3_PLUGIN_URL - -COPY config/configure_s3.sh ./config/configure_s3.sh -RUN chmod 755 ./config/configure_s3.sh - -COPY --chown=elasticsearch:elasticsearch ./config/config_cluster.sh ./ -RUN chmod +x ./config_cluster.sh - -ENTRYPOINT ["/entrypoint.sh"] -CMD ["elasticsearch"] diff --git a/elasticsearch/config/config_cluster.sh b/elasticsearch/config/config_cluster.sh deleted file mode 100644 index 04e70263..00000000 --- a/elasticsearch/config/config_cluster.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -elastic_config_file="/usr/share/elasticsearch/config/elasticsearch.yml" - -remove_single_node_conf(){ - if grep -Fq "discovery.type" $1; then - sed -i '/discovery.type\: /d' $1 - fi -} - -remove_cluster_config(){ - sed -i '/# cluster node/,/# end cluster config/d' $1 -} - -# If Elasticsearch cluster is enable, then set up the elasticsearch.yml -if [[ $ELASTIC_CLUSTER == "true" && $CLUSTER_NODE_MASTER != "" && $CLUSTER_NODE_DATA != "" && $CLUSTER_NODE_INGEST != "" && $CLUSTER_MASTER_NODE_NAME != "" ]]; then - # Remove the old configuration - remove_single_node_conf $elastic_config_file - remove_cluster_config $elastic_config_file - -if [[ $CLUSTER_NODE_MASTER == "true" ]]; then -# Add the master configuration -# cluster.initial_master_nodes for bootstrap the cluster -cat > $elastic_config_file << EOF -# cluster node -network.host: $CLUSTER_NETWORK_HOST -node.name: $CLUSTER_MASTER_NODE_NAME -node.master: $CLUSTER_NODE_MASTER -cluster.initial_master_nodes: - - $CLUSTER_MASTER_NODE_NAME -# end cluster config" -EOF - -elif [[ $CLUSTER_NODE_NAME != "" ]];then -# Remove the old configuration -remove_single_node_conf $elastic_config_file -remove_cluster_config $elastic_config_file - -cat > $elastic_config_file << EOF -# cluster node -network.host: $CLUSTER_NETWORK_HOST -node.name: $CLUSTER_NODE_NAME -node.master: false -discovery.seed_hosts: - - $CLUSTER_MASTER_NODE_NAME - - $CLUSTER_NODE_NAME -# end cluster config" -EOF -fi -# If the cluster is disabled, then set a single-node configuration -else - # Remove the old configuration - remove_single_node_conf $elastic_config_file - remove_cluster_config $elastic_config_file - echo "discovery.type: single-node" >> $elastic_config_file -fi \ No newline at end of file diff --git a/elasticsearch/config/configure_s3.sh b/elasticsearch/config/configure_s3.sh deleted file mode 100644 index ffb9cdbc..00000000 --- a/elasticsearch/config/configure_s3.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -set -e - -# Check number of arguments passed to configure_s3.sh. If it is different from 4 or 5, the process will finish with error. -# param 1: number of arguments passed to configure_s3.sh - -function CheckArgs() -{ - if [ $1 != 4 ] && [ $1 != 5 ];then - echo "Use: configure_s3.sh (By default is added to the path and the repository name)" - echo "or use: configure_s3.sh " - exit 1 - - fi -} - -# Create S3 repository from base_path / (if there is no argument, current version is added) -# Repository name would be - (if there is no argument, current version is added) -# param 1: -# param 2: -# param 3: -# param 4: -# param 5: Optional -# output: It will show "acknowledged" if the repository has been successfully created - -function CreateRepo() -{ - - elastic_ip_port="$2" - bucket_name="$3" - path="$4" - repository_name="$5" - - if [ $1 == 5 ];then - version="$6" - else - version=`curl -s $elastic_ip_port | grep number | cut -d"\"" -f4 | cut -c1` - fi - - if ! [[ "$version" =~ ^[0-9]+$ ]];then - echo "Elasticsearch major version must be an integer" - exit 1 - fi - - repository="$repository_name-$version" - s3_path="$path/$version" - - curl -X PUT "$elastic_ip_port/_snapshot/$repository" -H 'Content-Type: application/json' -d' - { - "type": "s3", - "settings": { - "bucket": "'$bucket_name'", - "base_path": "'$s3_path'" - } - } - ' - -} - -# Run functions CheckArgs and CreateRepo -# param 1: number of arguments passed to configure_s3.sh -# param 2: -# param 3: -# param 4: -# param 5: -# param 6: Optional - -function Main() -{ - CheckArgs $1 - - CreateRepo $1 $2 $3 $4 $5 $6 -} - -Main $# $1 $2 $3 $4 $5 \ No newline at end of file diff --git a/elasticsearch/config/entrypoint.sh b/elasticsearch/config/entrypoint.sh deleted file mode 100644 index de743755..00000000 --- a/elasticsearch/config/entrypoint.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -# For more information https://github.com/elastic/elasticsearch-docker/blob/6.8.0/build/elasticsearch/bin/docker-entrypoint.sh - -set -e - -# Files created by Elasticsearch should always be group writable too -umask 0002 - -run_as_other_user_if_needed() { - if [[ "$(id -u)" == "0" ]]; then - # If running as root, drop to specified UID and run command - exec chroot --userspec=1000 / "${@}" - else - # Either we are running in Openshift with random uid and are a member of the root group - # or with a custom --user - exec "${@}" - fi -} - - -#Disabling xpack features - -elasticsearch_config_file="/usr/share/elasticsearch/config/elasticsearch.yml" -if grep -Fq "#xpack features" "$elasticsearch_config_file"; -then - declare -A CONFIG_MAP=( - [xpack.ml.enabled]=$XPACK_ML - ) - for i in "${!CONFIG_MAP[@]}" - do - if [ "${CONFIG_MAP[$i]}" != "" ]; then - sed -i 's/.'"$i"'.*/'"$i"': '"${CONFIG_MAP[$i]}"'/' $elasticsearch_config_file - fi - done -else - echo " -#xpack features -xpack.ml.enabled: $XPACK_ML - " >> $elasticsearch_config_file -fi - -# Run load settings script. - -./config_cluster.sh - -./load_settings.sh & - -# Execute elasticsearch - -run_as_other_user_if_needed /usr/share/elasticsearch/bin/elasticsearch diff --git a/elasticsearch/config/load_settings.sh b/elasticsearch/config/load_settings.sh deleted file mode 100644 index 5aeedb9c..00000000 --- a/elasticsearch/config/load_settings.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -set -e - -el_url=${ELASTICSEARCH_URL} - - -if [[ ${ENABLED_XPACK} != "true" || "x${ELASTICSEARCH_USERNAME}" = "x" || "x${ELASTICSEARCH_PASSWORD}" = "x" ]]; then - auth="" -else - auth="--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" -fi - -until curl ${auth} -XGET $el_url; do - >&2 echo "Elastic is unavailable - sleeping" - sleep 5 -done - ->&2 echo "Elastic is up - executing command" - -if [ $ENABLE_CONFIGURE_S3 ]; then - #Wait for Elasticsearch to be ready to create the repository - sleep 10 - IP_PORT="${ELASTICSEARCH_IP}:${ELASTICSEARCH_PORT}" - - if [ "x$S3_PATH" != "x" ]; then - - if [ "x$S3_ELASTIC_MAJOR" != "x" ]; then - ./config/configure_s3.sh $IP_PORT $S3_BUCKET_NAME $S3_PATH $S3_REPOSITORY_NAME $S3_ELASTIC_MAJOR - - else - ./config/configure_s3.sh $IP_PORT $S3_BUCKET_NAME $S3_PATH $S3_REPOSITORY_NAME - - fi - - fi - -fi - -if [ ${ENABLED_XPACK} = "true" ]; then -curl -XPUT "$el_url/_cluster/settings" ${auth} -H 'Content-Type: application/json' -d' -{ - "persistent": { - "xpack.monitoring.collection.enabled": true - } -} -' -fi - -# Set cluster delayed timeout when node falls -curl -X PUT "$el_url/_all/_settings" -H 'Content-Type: application/json' -d' -{ - "settings": { - "index.unassigned.node_left.delayed_timeout": "'"$CLUSTER_DELAYED_TIMEOUT"'" - } -} -' - - -echo "Elasticsearch is ready." diff --git a/generate-opendistro-certs.yml b/generate-opendistro-certs.yml new file mode 100644 index 00000000..4c83507a --- /dev/null +++ b/generate-opendistro-certs.yml @@ -0,0 +1,10 @@ +# Wazuh App Copyright (C) 2020 Wazuh Inc. (License GPLv2) +version: '3' + +services: + generator: + image: wazuh/opendistro-certs-generator:0.1 + hostname: opendistro-certs-generator + volumes: + - ./production_cluster/ssl_certs/certs.yml:/usr/src/config/myconf.yml + - ./production_cluster/ssl_certs/:/usr/src/certs/out/ diff --git a/kibana/Dockerfile b/kibana-odfe/Dockerfile similarity index 67% rename from kibana/Dockerfile rename to kibana-odfe/Dockerfile index 9aae9632..c88b73b2 100644 --- a/kibana/Dockerfile +++ b/kibana-odfe/Dockerfile @@ -1,12 +1,12 @@ # Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) -FROM docker.elastic.co/kibana/kibana:7.9.1 +FROM amazon/opendistro-for-elasticsearch-kibana:1.10.1 USER kibana ARG ELASTIC_VERSION=7.9.1 -ARG WAZUH_VERSION=3.13.2 +ARG WAZUH_VERSION=4.0.0 ARG WAZUH_APP_VERSION="${WAZUH_VERSION}_${ELASTIC_VERSION}" WORKDIR /usr/share/kibana -RUN ./bin/kibana-plugin install https://packages.wazuh.com/wazuhapp/wazuhapp-${WAZUH_APP_VERSION}.zip +RUN ./bin/kibana-plugin install https://packages.wazuh.com/4.x/ui/kibana/wazuh_kibana-${WAZUH_APP_VERSION}-1.zip WORKDIR / USER root @@ -20,56 +20,41 @@ ENV PATTERN="" \ CHECKS_SETUP="" \ EXTENSIONS_PCI="" \ EXTENSIONS_GDPR="" \ + EXTENSIONS_HIPAA="" \ + EXTENSIONS_NIST="" \ + EXTENSIONS_TSC="" \ EXTENSIONS_AUDIT="" \ EXTENSIONS_OSCAP="" \ EXTENSIONS_CISCAT="" \ EXTENSIONS_AWS="" \ + EXTENSIONS_GCP="" \ EXTENSIONS_VIRUSTOTAL="" \ EXTENSIONS_OSQUERY="" \ + EXTENSIONS_DOCKER="" \ APP_TIMEOUT="" \ - WAZUH_SHARDS="" \ - WAZUH_REPLICAS="" \ - WAZUH_VERSION_SHARDS="" \ - WAZUH_VERSION_REPLICAS="" \ + API_SELECTOR="" \ IP_SELECTOR="" \ IP_IGNORE="" \ - XPACK_RBAC_ENABLED="" \ WAZUH_MONITORING_ENABLED="" \ WAZUH_MONITORING_FREQUENCY="" \ WAZUH_MONITORING_SHARDS="" \ WAZUH_MONITORING_REPLICAS="" \ ADMIN_PRIVILEGES="" -ARG XPACK_CANVAS="true" -ARG XPACK_LOGS="true" -ARG XPACK_INFRA="true" -ARG XPACK_ML="true" -ARG XPACK_DEVTOOLS="true" -ARG XPACK_MONITORING="true" -ARG XPACK_APM="true" - -ARG CHANGE_WELCOME="false" - -COPY --chown=kibana:kibana ./config/wazuh_app_config.sh ./ - -RUN chmod +x ./wazuh_app_config.sh - -COPY --chown=kibana:kibana ./config/kibana_settings.sh ./ - -RUN chmod +x ./kibana_settings.sh - -COPY --chown=kibana:kibana ./config/xpack_config.sh ./ - -RUN chmod +x ./xpack_config.sh - -RUN ./xpack_config.sh - -COPY --chown=kibana:kibana ./config/welcome_wazuh.sh ./ - -RUN chmod +x ./welcome_wazuh.sh - -RUN ./welcome_wazuh.sh USER kibana RUN NODE_OPTIONS="--max-old-space-size=2048" /usr/local/bin/kibana-docker --optimize +COPY ./config/custom_welcome /tmp/custom_welcome +COPY --chown=kibana:kibana ./config/welcome_wazuh.sh ./ +RUN chmod +x ./welcome_wazuh.sh +ARG CHANGE_WELCOME="true" +RUN ./welcome_wazuh.sh + +COPY --chown=kibana:kibana ./config/wazuh.yml /usr/share/kibana/optimize/wazuh/config/wazuh.yml +COPY --chown=kibana:kibana ./config/wazuh_app_config.sh ./ +RUN chmod +x ./wazuh_app_config.sh + +COPY --chown=kibana:kibana ./config/kibana_settings.sh ./ +RUN chmod +x ./kibana_settings.sh + ENTRYPOINT ./entrypoint.sh diff --git a/kibana-odfe/config/custom_welcome/light_theme.style.css b/kibana-odfe/config/custom_welcome/light_theme.style.css new file mode 100644 index 00000000..a1256a82 --- /dev/null +++ b/kibana-odfe/config/custom_welcome/light_theme.style.css @@ -0,0 +1,4349 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +/* @notice + * This product bundles bootstrap@3.3.6 which is available under a + * "MIT" license. + * + * The MIT License (MIT) + * + * Copyright (c) 2011-2015 Twitter, Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +.container { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +.row { + margin-left: -15px; + margin-right: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0%; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0%; + } +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; + font-size: 14px; +} +.table thead { + font-size: 12px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #D3DAE6; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 1px solid #D3DAE6; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #D3DAE6; +} +.table .table { + background-color: #FFF; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; + font-size: 12px; +} +.table-bordered { + border: 1px solid #D3DAE6; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #D3DAE6; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #D3DAE6; +} +.table-hover > tbody > tr:hover { + background-color: #D3DAE6; +} +table col[class*="col-"] { + position: static; + float: none; + display: table-column; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + float: none; + display: table-cell; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #D3DAE6; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #c3ccdd; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #017D73; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #01645c; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #006BB4; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #005c9b; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #F5A700; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #dc9600; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #BD271E; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #a7221b; +} +.table-responsive { + overflow-x: auto; + min-height: 0.01%; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #D3DAE6; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +.form-control { + display: block; + width: 100%; + height: 32px; + padding: 5px 15px; + font-size: 14px; + line-height: 1.42857143; + color: #343741; + background-color: #fafbfd; + background-image: none; + border: 1px solid #D3DAE6; + border-radius: 4px; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #006BB4; + outline: 0; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 107, 180, 0.6); +} +.form-control::-moz-placeholder { + color: #98A2B3; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #98A2B3; +} +.form-control::-webkit-input-placeholder { + color: #98A2B3; +} +.form-control::-ms-expand { + border: 0; + background-color: transparent; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: #D3DAE6; + opacity: 1; +} +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} +textarea.form-control { + height: auto; +} +.form-group:not(:empty) { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + padding-top: 6px; + padding-bottom: 6px; + margin-bottom: 0; + min-height: 34px; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-left: 0; + padding-right: 0; +} +.input-sm { + height: 32px; + padding: 6px 9px; + font-size: 12px; + line-height: 1.5; + border-radius: 4px; +} +select.input-sm { + height: 32px; + line-height: 32px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 32px; + padding: 6px 9px; + font-size: 12px; + line-height: 1.5; + border-radius: 4px; +} +.form-group-sm select.form-control { + height: 32px; + line-height: 32px; +} +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 32px; + min-height: 32px; + padding: 7px 9px; + font-size: 12px; + line-height: 1.5; +} +.input-lg { + height: 62px; + padding: 18px 27px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 4px; +} +select.input-lg { + height: 62px; + line-height: 62px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 62px; + padding: 18px 27px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 4px; +} +.form-group-lg select.form-control { + height: 62px; + line-height: 62px; +} +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 62px; + min-height: 38px; + padding: 19px 27px; + font-size: 18px; + line-height: 1.3333333; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 40px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 32px; + height: 32px; + line-height: 32px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback, +.input-group-lg + .form-control-feedback, +.form-group-lg .form-control + .form-control-feedback { + width: 62px; + height: 62px; + line-height: 62px; +} +.input-sm + .form-control-feedback, +.input-group-sm + .form-control-feedback, +.form-group-sm .form-control + .form-control-feedback { + width: 32px; + height: 32px; + line-height: 32px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #FFF; +} +.has-success .form-control { + border-color: #FFF; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-success .form-control:focus { + border-color: #e6e6e6; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; +} +.has-success .input-group-addon { + color: #FFF; + border-color: #FFF; + background-color: #017D73; +} +.has-success .form-control-feedback { + color: #FFF; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #FFF; +} +.has-warning .form-control { + border-color: #FFF; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-warning .form-control:focus { + border-color: #e6e6e6; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; +} +.has-warning .input-group-addon { + color: #FFF; + border-color: #FFF; + background-color: #F5A700; +} +.has-warning .form-control-feedback { + color: #FFF; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #FFF; +} +.has-error .form-control { + border-color: #FFF; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-error .form-control:focus { + border-color: #e6e6e6; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; +} +.has-error .input-group-addon { + color: #FFF; + border-color: #FFF; + background-color: #BD271E; +} +.has-error .form-control-feedback { + color: #FFF; +} +.has-feedback label ~ .form-control-feedback { + top: 25px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #6d7388; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 6px; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 26px; +} +.form-horizontal .form-group { + margin-left: -15px; + margin-right: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + margin-bottom: 0; + padding-top: 6px; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 19px; + font-size: 18px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 7px; + font-size: 12px; + } +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-muted { + color: #b2bac6; +} +.text-primary { + color: #343741; +} +a.text-primary:hover, +a.text-primary:focus { + color: #1d1f25; +} +.text-success { + color: #FFF; +} +a.text-success:hover, +a.text-success:focus { + color: #e6e6e6; +} +.text-info { + color: #FFF; +} +a.text-info:hover, +a.text-info:focus { + color: #e6e6e6; +} +.text-warning { + color: #FFF; +} +a.text-warning:hover, +a.text-warning:focus { + color: #e6e6e6; +} +.text-danger { + color: #FFF; +} +a.text-danger:hover, +a.text-danger:focus { + color: #e6e6e6; +} +.bg-info { + background-color: #006BB4; +} +a.bg-info:hover, +a.bg-info:focus { + background-color: #004d81; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +@media (min-width: 0) { + .dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +.fade { + opacity: 0; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + transition-property: height, visibility; + transition-duration: 0.35s; + transition-timing-function: ease; +} +/** + * ui/angular-ui-select depends upon these styles. Don't use them in your markup. + * Please use the UI Framework styles instead. + */ +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 5px 15px; + font-size: 14px; + line-height: 1.42857143; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + box-shadow: 0 0 0 1px white, 0 0 0 2px #0079a5; + /* 3 */ +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #FFF; + text-decoration: none; +} +.btn:active, +.btn.active { + outline: 0; + background-image: none; + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + opacity: 0.65; + filter: alpha(opacity=65); + box-shadow: none; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #FFF; + background-color: #006BB4; + border-color: #006BB4; +} +.btn-default:focus, +.btn-default.focus { + color: #FFF; + background-color: #004d81; + border-color: #001f35; +} +.btn-default:hover { + color: #FFF; + background-color: #004d81; + border-color: #004777; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #FFF; + background-color: #004d81; + border-color: #004777; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #FFF; + background-color: #00375d; + border-color: #001f35; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + background-color: #006BB4; + border-color: #006BB4; +} +.btn-default .badge { + color: #006BB4; + background-color: #FFF; +} +.btn-primary { + color: #FFF; + background-color: #006BB4; + border-color: #006BB4; +} +.btn-primary:focus, +.btn-primary.focus { + color: #FFF; + background-color: #004d81; + border-color: #001f35; +} +.btn-primary:hover { + color: #FFF; + background-color: #004d81; + border-color: #004777; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #FFF; + background-color: #004d81; + border-color: #004777; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #FFF; + background-color: #00375d; + border-color: #001f35; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus { + background-color: #006BB4; + border-color: #006BB4; +} +.btn-primary .badge { + color: #006BB4; + background-color: #FFF; +} +.btn-xs { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 4px; +} +.navbar { + position: relative; + min-height: 45px; + margin-bottom: 0px; + border: 1px solid transparent; +} +@media (min-width: 0) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 0) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + overflow-x: visible; + padding-right: 10px; + padding-left: 10px; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 0) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-left: 0; + padding-right: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -10px; + margin-left: -10px; +} +@media (min-width: 0) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1050; +} +@media (min-width: 0) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + padding: 12.5px 10px; + font-size: 18px; + line-height: 20px; + height: 45px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 0) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -10px; + } +} +.navbar-toggle { + position: relative; + float: right; + margin-right: 10px; + padding: 9px 10px; + margin-top: 5.5px; + margin-bottom: 5.5px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 0) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 6.25px -10px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: -1) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 0) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 12.5px; + padding-bottom: 12.5px; + } +} +.navbar-form { + margin-left: -10px; + margin-right: -10px; + padding: 10px 10px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + margin-top: 6.5px; + margin-bottom: 6.5px; +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: -1) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 0) { + .navbar-form { + width: auto; + border: 0; + margin-left: 0; + margin-right: 0; + padding-top: 0; + padding-bottom: 0; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-text { + margin-top: 12.5px; + margin-bottom: 12.5px; +} +@media (min-width: 0) { + .navbar-text { + float: left; + margin-left: 10px; + margin-right: 10px; + } +} +@media (min-width: 0) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -10px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #F5F7FA; + border-color: transparent; +} +.navbar-default .navbar-brand { + color: #69707D; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #69707D; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #69707D; +} +.navbar-default .navbar-nav > li > a { + color: #69707D; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #69707D; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #343741; + background-color: transparent; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #69707D; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #d3dce9; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #d3dce9; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #FFF; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: transparent; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: transparent; + color: #343741; +} +@media (max-width: -1) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #69707D; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #69707D; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #343741; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #69707D; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #69707D; +} +.navbar-default .navbar-link:hover { + color: #69707D; +} +.navbar-inverse { + background-color: #343741; + border-color: #1d1f25; +} +.navbar-inverse .navbar-brand { + color: #FFF; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #FFF; + background-color: #4b4f5d; +} +.navbar-inverse .navbar-text { + color: #FFF; +} +.navbar-inverse .navbar-nav > li > a { + color: #D3DAE6; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #FFF; + background-color: #61677a; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #FFF; + background-color: #69707D; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #b2bac6; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #1d1f25; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #1d1f25; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #FFF; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #24262d; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + background-color: #69707D; + color: #FFF; +} +@media (max-width: -1) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #1d1f25; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #1d1f25; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #D3DAE6; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #FFF; + background-color: #61677a; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #FFF; + background-color: #69707D; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #b2bac6; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #D3DAE6; +} +.navbar-inverse .navbar-link:hover { + color: #FFF; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: none; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.modal-open { + overflow: hidden; +} +.modal { + display: none; + overflow: hidden; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1070; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + transform: translate(0, -25%); + transition: transform 0.3s ease-out; +} +.modal.in .modal-dialog { + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #FFF; + border: 1px solid #98A2B3; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 4px; + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; + outline: 0; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1060; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} +.modal-backdrop.in { + opacity: 0.5; + filter: alpha(opacity=50); +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 20px; + margin-bottom: 20px; + background-color: #b8bec8; + border-radius: 4px; + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} +.progress-bar { + float: left; + width: 0%; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #FFF; + text-align: center; + background-color: #54B399; + transition: width 0.6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #017D73; +} +.progress-striped .progress-bar-success { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #006BB4; +} +.progress-striped .progress-bar-info { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #F5A700; +} +.progress-striped .progress-bar-warning { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #BD271E; +} +.progress-striped .progress-bar-danger { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.list-group { + margin-bottom: 20px; + padding-left: 0; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #FFF; + border: 1px solid #D3DAE6; +} +.list-group-item:first-child { + border-top-right-radius: 4px; + border-top-left-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.list-group-item--noBorder { + border-top: 0; +} +a.list-group-item, +button.list-group-item { + color: #69707D; +} +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: #343741; +} +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + text-decoration: none; + color: #69707D; + background-color: #F5F7FA; +} +button.list-group-item { + width: 100%; + text-align: left; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + background-color: #D3DAE6; + color: #b2bac6; + cursor: not-allowed; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #b2bac6; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #343741; + background-color: #343741; + border-color: #343741; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #969bab; +} +.list-group-item-success { + color: #FFF; + background-color: #017D73; +} +a.list-group-item-success, +button.list-group-item-success { + color: #FFF; +} +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +button.list-group-item-success:hover, +a.list-group-item-success:focus, +button.list-group-item-success:focus { + color: #FFF; + background-color: #01645c; +} +a.list-group-item-success.active, +button.list-group-item-success.active, +a.list-group-item-success.active:hover, +button.list-group-item-success.active:hover, +a.list-group-item-success.active:focus, +button.list-group-item-success.active:focus { + color: #fff; + background-color: #FFF; + border-color: #FFF; +} +.list-group-item-info { + color: #FFF; + background-color: #006BB4; +} +a.list-group-item-info, +button.list-group-item-info { + color: #FFF; +} +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +button.list-group-item-info:hover, +a.list-group-item-info:focus, +button.list-group-item-info:focus { + color: #FFF; + background-color: #005c9b; +} +a.list-group-item-info.active, +button.list-group-item-info.active, +a.list-group-item-info.active:hover, +button.list-group-item-info.active:hover, +a.list-group-item-info.active:focus, +button.list-group-item-info.active:focus { + color: #fff; + background-color: #FFF; + border-color: #FFF; +} +.list-group-item-warning { + color: #FFF; + background-color: #F5A700; +} +a.list-group-item-warning, +button.list-group-item-warning { + color: #FFF; +} +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +button.list-group-item-warning:hover, +a.list-group-item-warning:focus, +button.list-group-item-warning:focus { + color: #FFF; + background-color: #dc9600; +} +a.list-group-item-warning.active, +button.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +button.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus, +button.list-group-item-warning.active:focus { + color: #fff; + background-color: #FFF; + border-color: #FFF; +} +.list-group-item-danger { + color: #FFF; + background-color: #BD271E; +} +a.list-group-item-danger, +button.list-group-item-danger { + color: #FFF; +} +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +button.list-group-item-danger:hover, +a.list-group-item-danger:focus, +button.list-group-item-danger:focus { + color: #FFF; + background-color: #a7221b; +} +a.list-group-item-danger.active, +button.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +button.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus, +button.list-group-item-danger.active:focus { + color: #fff; + background-color: #FFF; + border-color: #FFF; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.nav { + margin-bottom: 0; + padding-left: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #D3DAE6; +} +.nav > li.disabled > a { + color: #b2bac6; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #b2bac6; + text-decoration: none; + background-color: transparent; + cursor: not-allowed; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #D3DAE6; + border-color: #006BB4; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #D3DAE6; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #D3DAE6; + background-color: #FFF; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #343741; + background-color: #FFF; + border: 1px solid #D3DAE6; + border-bottom-color: transparent; + cursor: default; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #FFF; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #FFF; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #FFF; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #FFF; + background-color: #006BB4; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #FFF; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #FFF; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #FFF; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + background-color: #017D73; + border-color: #014a44; + color: #FFF; +} +.alert-success hr { + border-top-color: #00312d; +} +.alert-success .alert-link { + color: #e6e6e6; +} +.alert-info { + background-color: #006BB4; + border-color: #004d81; + color: #FFF; +} +.alert-info hr { + border-top-color: #003e68; +} +.alert-info .alert-link { + color: #e6e6e6; +} +.alert-warning { + background-color: #F5A700; + border-color: #c28400; + color: #FFF; +} +.alert-warning hr { + border-top-color: #a97300; +} +.alert-warning .alert-link { + color: #e6e6e6; +} +.alert-danger { + background-color: #BD271E; + border-color: #911e17; + color: #FFF; +} +.alert-danger hr { + border-top-color: #7b1914; +} +.alert-danger .alert-link { + color: #e6e6e6; +} +.bsTooltip { + position: absolute; + z-index: 1040; + display: block; + font-family: 'Open Sans', Helvetica, Arial, sans-serif; + font-style: normal; + font-weight: normal; + letter-spacing: normal; + line-break: auto; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + font-size: 12px; + opacity: 0; + filter: alpha(opacity=0); +} +.bsTooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.bsTooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.bsTooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.bsTooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.bsTooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.bsTooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 4px; +} +.bsTooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.bsTooltip.top .bsTooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.bsTooltip.top-left .bsTooltip-arrow { + bottom: 0; + right: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.bsTooltip.top-right .bsTooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.bsTooltip.right .bsTooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.bsTooltip.left .bsTooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.bsTooltip.bottom .bsTooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.bsTooltip.bottom-left .bsTooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.bsTooltip.bottom-right .bsTooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + font-size: 14px; + text-align: left; + background-color: #FFF; + border: 1px solid #D3DAE6; + border-radius: 4px; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1); + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #D3DAE6; +} +.dropdown-menu > li > a, +.dropdown-menu > li > button { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #7b7b7b; + white-space: nowrap; +} +.dropdown-menu > li > button { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: none; + border: none; + width: 100%; + text-align: left; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > button:hover, +.dropdown-menu > li > a:focus, +.dropdown-menu > li > button:focus { + text-decoration: none; + color: #FFF; + background-color: #343741; +} +.dropdown-menu > .active > button, +.dropdown-menu > .active > a, +.dropdown-menu > .active > button:hover, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > button:focus, +.dropdown-menu > .active > a:focus { + color: #FFF; + text-decoration: none; + outline: 0; + background-color: #343741; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #98A2B3; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: not-allowed; +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + left: auto; + right: 0; +} +.dropdown-menu-left { + left: 0; + right: auto; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #98A2B3; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px dashed; + border-bottom: 4px solid \9; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +@media (min-width: 0) { + .navbar-right .dropdown-menu { + left: auto; + right: 0; + } + .navbar-right .dropdown-menu-left { + left: 0; + right: auto; + } +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-left: 0; + padding-right: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group .form-control:focus { + z-index: 3; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon { + height: 62px; + padding: 18px 27px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 4px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon { + height: 62px; + line-height: 62px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon { + height: 32px; + padding: 6px 9px; + font-size: 12px; + line-height: 1.5; + border-radius: 4px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon { + height: 32px; + line-height: 32px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon { + height: auto; +} +.input-group-addon, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 5px 15px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #343741; + text-align: center; + background-color: #D3DAE6; + border: 1px solid #D3DAE6; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 6px 9px; + font-size: 12px; + border-radius: 4px; +} +.input-group-addon.input-lg { + padding: 18px 27px; + font-size: 18px; + border-radius: 4px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 5px 15px; + line-height: 1.42857143; + text-decoration: none; + color: #006BB4; + background-color: transparent; + border: 1px solid transparent; + margin-left: -1px; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + z-index: 2; + color: #006BB4; + background-color: rgba(0, 0, 0, 0); + border-color: transparent; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 3; + color: #343741; + background-color: rgba(0, 0, 0, 0); + border-color: transparent; + cursor: default; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #343741; + background-color: rgba(38, 38, 38, 0); + border-color: transparent; + cursor: not-allowed; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 18px 27px; + font-size: 18px; + line-height: 1.3333333; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 6px 9px; + font-size: 12px; + line-height: 1.5; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; +} +.pager { + padding-left: 0; + margin: 20px 0; + list-style: none; + text-align: center; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: transparent; + border: 1px solid transparent; + border-radius: 0; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: rgba(0, 0, 0, 0); +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #FFF; + background-color: transparent; + cursor: not-allowed; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #FFF; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #FFF; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.label-default { + background-color: #006BB4; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #004d81; +} +.label-primary { + background-color: #343741; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #1d1f25; +} +.label-success { + background-color: #017D73; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #014a44; +} +.label-info { + background-color: #006BB4; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #004d81; +} +.label-warning { + background-color: #F5A700; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #c28400; +} +.label-danger { + background-color: #BD271E; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #911e17; +} +.panel { + margin-bottom: 20px; + background-color: #FFF; + border: 1px solid transparent; + border-radius: 4px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.panel-title > .small > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #F5F7FA; + border-top: 1px solid #D3DAE6; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item, +.panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-left: 15px; + padding-right: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #D3DAE6; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + border: 0; + margin-bottom: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #D3DAE6; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #D3DAE6; +} +.panel-default { + border-color: #D3DAE6; +} +.panel-default > .panel-heading { + color: #7b7b7b; + background-color: #F5F7FA; + border-color: #D3DAE6; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #D3DAE6; +} +.panel-default > .panel-heading .badge { + color: #F5F7FA; + background-color: #7b7b7b; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #D3DAE6; +} +.panel-primary { + border-color: #343741; +} +.panel-primary > .panel-heading { + color: #FFF; + background-color: #343741; + border-color: #343741; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #343741; +} +.panel-primary > .panel-heading .badge { + color: #343741; + background-color: #FFF; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #343741; +} +.panel-success { + border-color: #014a44; +} +.panel-success > .panel-heading { + color: #FFF; + background-color: #017D73; + border-color: #014a44; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #014a44; +} +.panel-success > .panel-heading .badge { + color: #017D73; + background-color: #FFF; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #014a44; +} +.panel-info { + border-color: #004d81; +} +.panel-info > .panel-heading { + color: #FFF; + background-color: #006BB4; + border-color: #004d81; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #004d81; +} +.panel-info > .panel-heading .badge { + color: #006BB4; + background-color: #FFF; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #004d81; +} +.panel-warning { + border-color: #c28400; +} +.panel-warning > .panel-heading { + color: #FFF; + background-color: #F5A700; + border-color: #c28400; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #c28400; +} +.panel-warning > .panel-heading .badge { + color: #F5A700; + background-color: #FFF; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #c28400; +} +.panel-danger { + border-color: #911e17; +} +.panel-danger > .panel-heading { + color: #FFF; + background-color: #BD271E; + border-color: #911e17; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #911e17; +} +.panel-danger > .panel-heading .badge { + color: #BD271E; + background-color: #FFF; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #911e17; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + font-family: 'Open Sans', Helvetica, Arial, sans-serif; + font-style: normal; + font-weight: normal; + letter-spacing: normal; + line-break: auto; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + font-size: 14px; + background-color: #FFF; + background-clip: padding-box; + border: 1px solid #D3DAE6; + border-radius: 4px; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1); +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 3px 3px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top > .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #92a3c1; + border-top-color: #d3dae6; + bottom: -11px; +} +.popover.top > .arrow:after { + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #FFF; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #92a3c1; + border-right-color: #d3dae6; +} +.popover.right > .arrow:after { + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #FFF; +} +.popover.bottom > .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #92a3c1; + border-bottom-color: #d3dae6; + top: -11px; +} +.popover.bottom > .arrow:after { + content: " "; + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #FFF; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #92a3c1; + border-left-color: #d3dae6; +} +.popover.left > .arrow:after { + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #FFF; + bottom: -10px; +} +.clearfix:before, +.clearfix:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.modal-header:before, +.modal-header:after, +.modal-footer:before, +.modal-footer:after, +.nav:before, +.nav:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after { + content: " "; + display: table; +} +.clearfix:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.dl-horizontal dd:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.modal-header:after, +.modal-footer:after, +.nav:after, +.pager:after, +.panel-body:after { + clear: both; +} +.center-block { + display: block; + margin-left: auto; + margin-right: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; +} +.affix { + position: fixed; +} +.navbar > .container-fluid > .navbar-nav:not(.pull-right):first-child, +.navbar > .container-fluid > .navbar-form:not(.pull-right):first-child { + margin-left: -15px; + margin-top: 4px; +} +.navbar { + border-width: 0; +} +.navbar-btn-link { + margin: 0; + border-radius: 0; +} +@media (max-width: 768px) { + .navbar-btn-link { + width: 100%; + text-align: left; + } +} +.navbar-default .badge { + background-color: #FFF; + color: #F5F7FA; +} +.navbar-inverse .kbnGlobalNav__logoBrand { + height: 45px; + width: 252px; + background-color: #4b4f5d; +} +.navbar-inverse .kbnGlobalNav__smallLogoBrand { + height: 45px; + width: 45px; + background-color: #4b4f5d; +} +.navbar-inverse .badge { + background-color: #FFF; + color: #4b4f5d; +} +.navbar-brand { + cursor: default; + font-size: 1.8em; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.navbar-nav { + font-size: 12px; +} +.navbar-nav > .active > a { + border-bottom-color: #7b7b7b; + background-color: transparent; +} +.navbar-toggle { + margin-top: 4px; +} +.text-primary, +.text-primary:hover { + color: #343741; +} +.text-success, +.text-success:hover { + color: #017D73; +} +.text-danger, +.text-danger:hover { + color: #BD271E; +} +.text-warning, +.text-warning:hover { + color: #F5A700; +} +.text-info, +.text-info:hover { + color: #006BB4; +} +table .success, +.table .success, +table .warning, +.table .warning, +table .danger, +.table .danger, +table .info, +.table .info { + color: #FFF; +} +table .success a, +.table .success a, +table .warning a, +.table .warning a, +table .danger a, +.table .danger a, +table .info a, +.table .info a { + color: #FFF; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #D3DAE6; +} +.form-control, +input { + border-width: 1px; + box-shadow: none; +} +.form-control:focus, +input:focus { + box-shadow: none; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning .form-control-feedback { + color: #F5A700; +} +.has-warning .form-control, +.has-warning .form-control:focus { + border: 1px solid; + border-color: #F5A700; +} +.has-warning .input-group-addon { + border-color: #F5A700; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error .form-control-feedback { + color: #BD271E; +} +.has-error .form-control, +.has-error .form-control:focus { + border: 1px solid; + border-color: #BD271E; +} +.has-error .input-group-addon { + border-color: #BD271E; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success .form-control-feedback { + color: #017D73; +} +.has-success .form-control, +.has-success .form-control:focus { + border: solid #017D73; +} +.has-success .input-group-addon { + border-color: #017D73; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + border-color: transparent; +} +.pager a, +.pager a:hover { + color: #FFF; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + background-color: rgba(38, 38, 38, 0); +} +.panel { + border-radius: 0; + box-shadow: 0 0 0 rgba(0, 0, 0, 0); +} +.progress { + box-shadow: none; +} +.progress .progress-bar { + font-size: 10px; + line-height: 10px; +} +.well { + box-shadow: none; +} + +/*------------- WAZUH -------------*/ +.wz-login { + background: url(./wazuh_wazuh_bg.svg) !important; + width: 100% !important; + height: 100% !important; + background-size: cover !important; +} + +.login-wrapper { + text-align: center; + width: 430px!important; + top: 55px; + border-radius: 1px; + padding: 1em; +} + +#kibana-body > div > div.app-wrapper.hidden-chrome > div > div.application > div > ul > div.euiText.euiText--medium > div { + text-align: center; + padding-bottom: 10px; + color: #ffffff !important; + font-size: 35px !important; + font-weight: 300; +} + +#kibana-body > div > div.app-wrapper.hidden-chrome > div > div.application > div > ul > div.euiText.euiText--small > div { + text-align: center; + padding-bottom: 15px; + color: #ffffff !important; + font-size: 16px !important; +} + +#kibana-body > div > div.app-wrapper.hidden-chrome > div > div.application > div > ul > form { + padding: 16px; + box-shadow: 0 2px 2px -1px rgba(152, 162, 179, 0.3), 0 1px 5px -2px rgba(152, 162, 179, 0.3); + background-color: #FFF; + border: 1px solid #D3DAE6; + border-radius: 4px; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + margin-top: 32px; +} + +.loginWelcome__logo { + display: inline-block; + width: 80px; + height: 80px; + line-height: 80px; + text-align: center; + background-color: #FFF; + border-radius: 100%; + padding: 16px; + box-shadow: 0 6px 12px -1px rgba(152, 162, 179, 0.2), 0 4px 4px -1px rgba(152, 162, 179, 0.2), 0 2px 2px 0 rgba(152, 162, 179, 0.2); + margin-bottom: 32px; +} + +div.euiFormRow > div.euiFormRow__fieldWrapper > button { + background-color: #00a9e5!important; + border-color: #00a9e5!important; + color: #fff; +} + +.loginWelcome__logo { + background: url(./wazuh_logo_circle.svg) center center no-repeat !important; +} diff --git a/kibana-odfe/config/custom_welcome/template.js.hbs b/kibana-odfe/config/custom_welcome/template.js.hbs new file mode 100644 index 00000000..b3ee1d61 --- /dev/null +++ b/kibana-odfe/config/custom_welcome/template.js.hbs @@ -0,0 +1,112 @@ +var kbnCsp = JSON.parse(document.querySelector('kbn-csp').getAttribute('data')); +window.__kbnStrictCsp__ = kbnCsp.strictCsp; +window.__kbnThemeTag__ = "{{themeTag}}"; +window.__kbnPublicPath__ = {{publicPathMap}}; +window.__kbnBundles__ = {{kbnBundlesLoaderSource}} + +if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) { + var legacyBrowserError = document.getElementById('kbn_legacy_browser_error'); + legacyBrowserError.style.display = 'flex'; +} else { + if (!window.__kbnCspNotEnforced__ && window.console) { + window.console.log("^ A single error about an inline script not firing due to content security policy is expected!"); + } + var loadingMessage = document.getElementById('kbn_loading_message'); + loadingMessage.style.display = 'flex'; + + window.onload = function () { + //WAZUH + var interval = setInterval(() => { + var title = document.querySelector("#kibana-body > div > div.app-wrapper.hidden-chrome > div > div.application > div > ul > div.euiText.euiText--medium > div") + if (!!title) { + clearInterval(interval); + var content = document.querySelector("#kibana-body > div"); + content.classList.add("wz-login") + title.textContent = "Welcome to Wazuh"; + var subtitle = document.querySelector("#kibana-body > div > div.app-wrapper.hidden-chrome > div > div.application > div > ul > div.euiText.euiText--small > div") + subtitle.textContent = "The Open Source Security Platform"; + var logo = document.querySelector("#kibana-body > div > div.app-wrapper.hidden-chrome > div > div.application > div > ul > figure"); + logo.remove(); + var logoContainer = document.querySelector("#kibana-body > div > div.app-wrapper.hidden-chrome > div > div.application > div > ul"); + $(logoContainer).prepend(''); + } + }) + // + + function failure() { + // make subsequent calls to failure() noop + failure = function () {}; + + var err = document.createElement('h1'); + err.style['color'] = 'white'; + err.style['font-family'] = 'monospace'; + err.style['text-align'] = 'center'; + err.style['background'] = '#F44336'; + err.style['padding'] = '25px'; + err.innerText = document.querySelector('[data-error-message]').dataset.errorMessage; + + document.body.innerHTML = err.outerHTML; + } + + var stylesheetTarget = document.querySelector('head meta[name="add-styles-here"]') + function loadStyleSheet(url, cb) { + var dom = document.createElement('link'); + dom.rel = 'stylesheet'; + dom.type = 'text/css'; + dom.href = url; + dom.addEventListener('error', failure); + dom.addEventListener('load', cb); + document.head.insertBefore(dom, stylesheetTarget); + } + + var scriptsTarget = document.querySelector('head meta[name="add-scripts-here"]') + function loadScript(url, cb) { + var dom = document.createElement('script'); + {{!-- NOTE: async = false is used to trigger async-download/ordered-execution as outlined here: https://www.html5rocks.com/en/tutorials/speed/script-loading/ --}} + dom.async = false; + dom.src = url; + dom.addEventListener('error', failure); + dom.addEventListener('load', cb); + document.head.insertBefore(dom, scriptsTarget); + } + + function load(urls, cb) { + var pending = urls.length; + urls.forEach(function (url) { + var innerCb = function () { + pending = pending - 1; + if (pending === 0 && typeof cb === 'function') { + cb(); + } + } + + if (typeof url !== 'string') { + load(url, innerCb); + } else if (url.slice(-4) === '.css') { + loadStyleSheet(url, innerCb); + } else { + loadScript(url, innerCb); + } + }); + } + + load([ + {{#each jsDependencyPaths}} + '{{this}}', + {{/each}} + ], function () { + {{#unless legacyBundlePath}} + __kbnBundles__.get('entry/core/public').__kbnBootstrap__(); + {{/unless}} + + load([ + {{#if legacyBundlePath}} + '{{legacyBundlePath}}', + {{/if}} + {{#each styleSheetPaths}} + '{{this}}', + {{/each}} + ]); + }); + } +} diff --git a/kibana-odfe/config/custom_welcome/wazuh_logo_circle.svg b/kibana-odfe/config/custom_welcome/wazuh_logo_circle.svg new file mode 100644 index 00000000..45a61d74 --- /dev/null +++ b/kibana-odfe/config/custom_welcome/wazuh_logo_circle.svg @@ -0,0 +1 @@ +wazuh_logo_circle \ No newline at end of file diff --git a/kibana-odfe/config/custom_welcome/wazuh_wazuh_bg.svg b/kibana-odfe/config/custom_welcome/wazuh_wazuh_bg.svg new file mode 100644 index 00000000..0c49c5c6 --- /dev/null +++ b/kibana-odfe/config/custom_welcome/wazuh_wazuh_bg.svg @@ -0,0 +1 @@ +wazuh_wazuh_bg \ No newline at end of file diff --git a/kibana/config/entrypoint.sh b/kibana-odfe/config/entrypoint.sh similarity index 58% rename from kibana/config/entrypoint.sh rename to kibana-odfe/config/entrypoint.sh index 1c445e10..f2c017f1 100644 --- a/kibana/config/entrypoint.sh +++ b/kibana-odfe/config/entrypoint.sh @@ -7,16 +7,22 @@ set -e # Waiting for elasticsearch ############################################################################## -if [ "x${ELASTICSEARCH_URL}" = "x" ]; then - el_url="http://elasticsearch:9200" +if [ "x${ELASTICSEARCH_URL}" == "x" ]; then + if [[ ${ENABLED_SECURITY} == "false" ]]; then + export el_url="http://elasticsearch:9200" + else + export el_url="https://elasticsearch:9200" + fi else - el_url="${ELASTICSEARCH_URL}" + export el_url="${ELASTICSEARCH_URL}" fi -if [[ ${ENABLED_XPACK} != "true" || "x${ELASTICSEARCH_USERNAME}" = "x" || "x${ELASTICSEARCH_PASSWORD}" = "x" ]]; then +if [[ ${ENABLED_SECURITY} == "false" || "x${ELASTICSEARCH_USERNAME}" == "x" || "x${ELASTICSEARCH_PASSWORD}" == "x" ]]; then auth="" + # remove security plugin from kibana if elasticsearch is not using it either + /usr/share/kibana/bin/kibana-plugin remove opendistro_security else - auth="--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" + export auth="--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} -k" fi until curl -XGET $el_url ${auth}; do @@ -37,7 +43,7 @@ strlen=0 while [[ $strlen -eq 0 ]] do - template=$(curl $el_url/_cat/templates/wazuh -s) + template=$(curl ${auth} $el_url/_cat/templates/wazuh -s) strlen=${#template} >&2 echo "Wazuh alerts template not loaded - sleeping." sleep 2 @@ -54,4 +60,6 @@ sleep 5 ./kibana_settings.sh & +sleep 2 + /usr/local/bin/kibana-docker diff --git a/kibana/config/kibana_settings.sh b/kibana-odfe/config/kibana_settings.sh similarity index 51% rename from kibana/config/kibana_settings.sh rename to kibana-odfe/config/kibana_settings.sh index cd00fa6c..b0c56e4d 100644 --- a/kibana/config/kibana_settings.sh +++ b/kibana-odfe/config/kibana_settings.sh @@ -1,7 +1,7 @@ #!/bin/bash # Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) -WAZUH_MAJOR=3 +WAZUH_MAJOR=4 ############################################################################## # Wait for the Kibana API to start. It is necessary to do it in this container @@ -17,10 +17,9 @@ WAZUH_MAJOR=3 ############################################################################## # Customize elasticsearch ip ############################################################################## -if [ "$ELASTICSEARCH_KIBANA_IP" != "" ]; then - sed -i "s:#elasticsearch.hosts:elasticsearch.hosts:g" /usr/share/kibana/config/kibana.yml - sed -i 's|http://elasticsearch:9200|'$ELASTICSEARCH_KIBANA_IP'|g' /usr/share/kibana/config/kibana.yml -fi +sed -i "s|elasticsearch.hosts:.*|elasticsearch.hosts: $el_url|g" /usr/share/kibana/config/kibana.yml +# disable multitenancy +sed -i "s|opendistro_security.multitenancy.enabled:.*|opendistro_security.multitenancy.enabled: false|g" /usr/share/kibana/config/kibana.yml # If KIBANA_INDEX was set, then change the default index in kibana.yml configuration file. If there was an index, then delete it and recreate. if [ "$KIBANA_INDEX" != "" ]; then @@ -30,26 +29,7 @@ if [ "$KIBANA_INDEX" != "" ]; then echo "kibana.index: $KIBANA_INDEX" >> /usr/share/kibana/config/kibana.yml fi -# If XPACK_SECURITY_ENABLED was set, then change the xpack.security.enabled option from true (default) to false. -if [ "$XPACK_SECURITY_ENABLED" != "" ]; then - if grep -q 'xpack.security.enabled' /usr/share/kibana/config/kibana.yml; then - sed -i '/xpack.security.enabled/d' /usr/share/kibana/config/kibana.yml - fi - echo "xpack.security.enabled: $XPACK_SECURITY_ENABLED" >> /usr/share/kibana/config/kibana.yml -fi - -if [ "$KIBANA_IP" != "" ]; then - kibana_ip="$KIBANA_IP" -else - kibana_ip="kibana" -fi - -# Add auth headers if required -if [ "$ELASTICSEARCH_USERNAME" != "" ] && [ "$ELASTICSEARCH_PASSWORD" != "" ]; then - curl_auth="-u $ELASTICSEARCH_USERNAME:$ELASTICSEARCH_PASSWORD" -fi - -while [[ "$(curl $curl_auth -XGET -I -s -o /dev/null -w ''%{http_code}'' $kibana_ip:5601/status)" != "200" ]]; do +while [[ "$(curl -XGET -I -s -o /dev/null -w '%{http_code}' -k https://127.0.0.1:5601/app/login)" != "200" ]]; do echo "Waiting for Kibana API. Sleeping 5 seconds" sleep 5 done @@ -69,16 +49,12 @@ EOF sleep 5 # Add the wazuh alerts index as default. -curl -POST "http://$kibana_ip:5601/api/kibana/settings" -H "Content-Type: application/json" -H "kbn-xsrf: true" -d@${default_index} +curl ${auth} -POST -k https://127.0.0.1:5601/api/kibana/settings -H "Content-Type: application/json" -H "kbn-xsrf: true" -d@${default_index} rm -f ${default_index} sleep 5 # Configuring Kibana TimePicker. -curl -POST "http://$kibana_ip:5601/api/kibana/settings" -H "Content-Type: application/json" -H "kbn-xsrf: true" -d \ -'{"changes":{"timepicker:timeDefaults":"{\n \"from\": \"now-24h\",\n \"to\": \"now\",\n \"mode\": \"quick\"}"}}' - -sleep 5 -# Do not ask user to help providing usage statistics to Elastic -curl -POST "http://$kibana_ip:5601/api/telemetry/v2/optIn" -H "Content-Type: application/json" -H "kbn-xsrf: true" -d '{"enabled":false}' +curl ${auth} -POST -k "https://127.0.0.1:5601/api/kibana/settings" -H "Content-Type: application/json" -H "kbn-xsrf: true" -d \ +'{"changes":{"timepicker:timeDefaults":"{\n \"from\": \"now-12h\",\n \"to\": \"now\",\n \"mode\": \"quick\"}"}}' echo "End settings" diff --git a/kibana-odfe/config/wazuh.yml b/kibana-odfe/config/wazuh.yml new file mode 100644 index 00000000..6c52d526 --- /dev/null +++ b/kibana-odfe/config/wazuh.yml @@ -0,0 +1,162 @@ +--- +# +# Wazuh app - App configuration file +# Copyright (C) 2015-2020 Wazuh, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# Find more information about this on the LICENSE file. +# +# ======================== Wazuh app configuration file ======================== +# +# Please check the documentation for more information on configuration options: +# https://documentation.wazuh.com/current/installation-guide/index.html +# +# Also, you can check our repository: +# https://github.com/wazuh/wazuh-kibana-app +# +# ------------------------------- Index patterns ------------------------------- +# +# Default index pattern to use. +#pattern: wazuh-alerts-* +# +# ----------------------------------- Checks ----------------------------------- +# +# Defines which checks must to be consider by the healthcheck +# step once the Wazuh app starts. Values must to be true or false. +#checks.pattern : true +#checks.template: true +#checks.api : true +#checks.setup : true +#checks.metaFields: true +# +# --------------------------------- Extensions --------------------------------- +# +# Defines which extensions should be activated when you add a new API entry. +# You can change them after Wazuh app starts. +# Values must to be true or false. +#extensions.pci : true +#extensions.gdpr : true +#extensions.hipaa : true +#extensions.nist : true +#extensions.tsc : true +#extensions.audit : true +#extensions.oscap : false +#extensions.ciscat : false +#extensions.aws : false +#extensions.gcp : false +#extensions.virustotal: false +#extensions.osquery : false +#extensions.docker : false +# +# ---------------------------------- Time out ---------------------------------- +# +# Defines maximum timeout to be used on the Wazuh app requests. +# It will be ignored if it is bellow 1500. +# It means milliseconds before we consider a request as failed. +# Default: 20000 +#timeout: 20000 +# +# -------------------------------- API selector -------------------------------- +# +# Defines if the user is allowed to change the selected +# API directly from the Wazuh app top menu. +# Default: true +#api.selector: true +# +# --------------------------- Index pattern selector --------------------------- +# +# Defines if the user is allowed to change the selected +# index pattern directly from the Wazuh app top menu. +# Default: true +#ip.selector: true +# +# List of index patterns to be ignored +#ip.ignore: [] +# +# -------------------------------- X-Pack RBAC --------------------------------- +# +# Custom setting to enable/disable built-in X-Pack RBAC security capabilities. +# Default: enabled +#xpack.rbac.enabled: true +# +# ------------------------------ wazuh-monitoring ------------------------------ +# +# Custom setting to enable/disable wazuh-monitoring indices. +# Values: true, false, worker +# If worker is given as value, the app will show the Agents status +# visualization but won't insert data on wazuh-monitoring indices. +# Default: true +#wazuh.monitoring.enabled: true +# +# Custom setting to set the frequency for wazuh-monitoring indices cron task. +# Default: 900 (s) +#wazuh.monitoring.frequency: 900 +# +# Configure wazuh-monitoring-* indices shards and replicas. +#wazuh.monitoring.shards: 2 +#wazuh.monitoring.replicas: 0 +# +# Configure wazuh-monitoring-* indices custom creation interval. +# Values: h (hourly), d (daily), w (weekly), m (monthly) +# Default: d +#wazuh.monitoring.creation: d +# +# Default index pattern to use for Wazuh monitoring +#wazuh.monitoring.pattern: wazuh-monitoring-* +# +# --------------------------------- wazuh-cron ---------------------------------- +# +# Customize the index prefix of predefined jobs +# This change is not retroactive, if you change it new indexes will be created +# cron.prefix: test +# +# ------------------------------ wazuh-statistics ------------------------------- +# +# Custom setting to enable/disable statistics tasks. +#cron.statistics.status: true +# +# Enter the ID of the APIs you want to save data from, leave this empty to run +# the task on all configured APIs +#cron.statistics.apis: [] +# +# Define the frequency of task execution using cron schedule expressions +#cron.statistics.interval: 0 0 * * * * +# +# Define the name of the index in which the documents are to be saved. +#cron.statistics.index.name: statistics +# +# Define the interval in which the index will be created +#cron.statistics.index.creation: w +# +# ------------------------------- App privileges -------------------------------- +#admin: true +# +# ---------------------------- Hide manager alerts ------------------------------ +# Hide the alerts of the manager in all dashboards and discover +#hideManagerAlerts: false +# +# ------------------------------- App logging level ----------------------------- +# Set the logging level for the Wazuh App log files. +# Default value: info +# Allowed values: info, debug +#logs.level: info +# +# -------------------------------- Enrollment DNS ------------------------------- +# Set the variable WAZUH_REGISTRATION_SERVER in agents deployment. +# Default value: '' +#enrollment.dns: '' +# +#-------------------------------- API entries ----------------------------------- +#The following configuration is the default structure to define an API entry. +# +#hosts: +# - : +# url: http(s):// +# port: +# username: +# password: + diff --git a/kibana/config/wazuh_app_config.sh b/kibana-odfe/config/wazuh_app_config.sh similarity index 71% rename from kibana/config/wazuh_app_config.sh rename to kibana-odfe/config/wazuh_app_config.sh index cae2dcef..95f0d895 100644 --- a/kibana/config/wazuh_app_config.sh +++ b/kibana-odfe/config/wazuh_app_config.sh @@ -3,12 +3,10 @@ wazuh_url="${WAZUH_API_URL:-https://wazuh}" wazuh_port="${API_PORT:-55000}" -api_user="${API_USER:-foo}" -api_password="${API_PASS:-bar}" +api_username="${API_USERNAME:-wazuh}" +api_password="${API_PASSWORD:-wazuh}" kibana_config_file="/usr/share/kibana/optimize/wazuh/config/wazuh.yml" -mkdir -p /usr/share/kibana/optimize/wazuh/config/ -touch $kibana_config_file declare -A CONFIG_MAP=( [pattern]=$PATTERN @@ -18,20 +16,21 @@ declare -A CONFIG_MAP=( [checks.setup]=$CHECKS_SETUP [extensions.pci]=$EXTENSIONS_PCI [extensions.gdpr]=$EXTENSIONS_GDPR + [extensions.hipaa]=$EXTENSIONS_HIPAA + [extensions.nist]=$EXTENSIONS_NIST + [extensions.tsc]=$EXTENSIONS_TSC [extensions.audit]=$EXTENSIONS_AUDIT [extensions.oscap]=$EXTENSIONS_OSCAP [extensions.ciscat]=$EXTENSIONS_CISCAT [extensions.aws]=$EXTENSIONS_AWS + [extensions.gcp]=$EXTENSIONS_GCP [extensions.virustotal]=$EXTENSIONS_VIRUSTOTAL [extensions.osquery]=$EXTENSIONS_OSQUERY + [extensions.docker]=$EXTENSIONS_DOCKER [timeout]=$APP_TIMEOUT - [wazuh.shards]=$WAZUH_SHARDS - [wazuh.replicas]=$WAZUH_REPLICAS - [wazuh-version.shards]=$WAZUH_VERSION_SHARDS - [wazuh-version.replicas]=$WAZUH_VERSION_REPLICAS + [api.selector]=$API_SELECTOR [ip.selector]=$IP_SELECTOR [ip.ignore]=$IP_IGNORE - [xpack.rbac.enabled]=$XPACK_RBAC_ENABLED [wazuh.monitoring.enabled]=$WAZUH_MONITORING_ENABLED [wazuh.monitoring.frequency]=$WAZUH_MONITORING_FREQUENCY [wazuh.monitoring.shards]=$WAZUH_MONITORING_SHARDS @@ -46,21 +45,18 @@ do fi done -# remove default API entry (new in 3.11.0_7.5.1) -sed -ie '/- default:/,+4d' $kibana_config_file - -CONFIG_CODE=$(curl -s -o /dev/null -w "%{http_code}" -XGET $el_url/.wazuh/_doc/1513629884013 ${auth}) +CONFIG_CODE=$(curl ${auth} -s -o /dev/null -w "%{http_code}" -XGET $el_url/.wazuh/_doc/1513629884013) grep -q 1513629884013 $kibana_config_file _config_exists=$? if [[ "x$CONFIG_CODE" != "x200" && $_config_exists -ne 0 ]]; then -cat << EOF > $kibana_config_file +cat << EOF >> $kibana_config_file hosts: - 1513629884013: url: $wazuh_url port: $wazuh_port - user: $api_user + username: $api_username password: $api_password EOF else diff --git a/kibana-odfe/config/welcome_wazuh.sh b/kibana-odfe/config/welcome_wazuh.sh new file mode 100644 index 00000000..74ae2eef --- /dev/null +++ b/kibana-odfe/config/welcome_wazuh.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) + +if [[ $CHANGE_WELCOME == "true" ]] +then + echo "Set Wazuh app as the default landing page" + echo "server.defaultRoute: /app/wazuh" >> /usr/share/kibana/config/kibana.yml + + echo "Set custom welcome styles" + cp -f /tmp/custom_welcome/template.js.hbs /usr/share/kibana/src/legacy/ui/ui_render/bootstrap/template.js.hbs + cp -f /tmp/custom_welcome/light_theme.style.css /usr/share/kibana/optimize/bundles/light_theme.style.css + cp -f /tmp/custom_welcome/*svg /usr/share/kibana/optimize/bundles/ +fi + diff --git a/kibana/config/welcome_wazuh.sh b/kibana/config/welcome_wazuh.sh deleted file mode 100644 index 3683c23d..00000000 --- a/kibana/config/welcome_wazuh.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -if [[ $CHANGE_WELCOME == "true" ]] -then - - rm -rf ./optimize/bundles - - kibana_path="/usr/share/kibana" - # Set Wazuh app as the default landing page - echo "Set Wazuh app as the default landing page" - echo "server.defaultRoute: /app/wazuh" >> /usr/share/kibana/config/kibana.yml - - # Redirect Kibana welcome screen to Discover - echo "Redirect Kibana welcome screen to Discover" - sed -i "s:'/app/kibana#/home':'/app/wazuh':g" $kibana_path/src/ui/public/chrome/directives/global_nav/global_nav.html - sed -i "s:'/app/kibana#/home':'/app/wazuh':g" $kibana_path/src/ui/public/chrome/directives/header_global_nav/header_global_nav.js - - # Redirect Kibana welcome screen to Discover - echo "Hide undesired links" - sed -i 's#visible: true#visible: false#g' $kibana_path/node_modules/x-pack/plugins/rollup/public/crud_app/index.js - sed -i 's#visible: true#visible: false#g' $kibana_path/node_modules/x-pack/plugins/license_management/public/management_section.js -fi diff --git a/kibana/config/xpack_config.sh b/kibana/config/xpack_config.sh deleted file mode 100644 index 89ffadfa..00000000 --- a/kibana/config/xpack_config.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -kibana_config_file="/usr/share/kibana/config/kibana.yml" -if grep -Fq "#xpack features" "$kibana_config_file"; -then - declare -A CONFIG_MAP=( - [xpack.apm.ui.enabled]=$XPACK_APM - [xpack.grokdebugger.enabled]=$XPACK_DEVTOOLS - [xpack.searchprofiler.enabled]=$XPACK_DEVTOOLS - [xpack.ml.enabled]=$XPACK_ML - [xpack.canvas.enabled]=$XPACK_CANVAS - [xpack.infra.enabled]=$XPACK_INFRA - [monitoring.enabled]=$XPACK_MONITORING - [console.enabled]=$XPACK_DEVTOOLS - ) - for i in "${!CONFIG_MAP[@]}" - do - if [ "${CONFIG_MAP[$i]}" != "" ]; then - sed -i 's/.'"$i"'.*/'"$i"': '"${CONFIG_MAP[$i]}"'/' $kibana_config_file - fi - done -else - echo " -#xpack features -xpack.apm.ui.enabled: $XPACK_APM -xpack.grokdebugger.enabled: $XPACK_DEVTOOLS -xpack.searchprofiler.enabled: $XPACK_DEVTOOLS -xpack.ml.enabled: $XPACK_ML -xpack.canvas.enabled: $XPACK_CANVAS -xpack.infra.enabled: $XPACK_INFRA -xpack.monitoring.enabled: $XPACK_MONITORING -console.enabled: $XPACK_DEVTOOLS -" >> $kibana_config_file -fi diff --git a/nginx/Dockerfile b/nginx/Dockerfile deleted file mode 100644 index b7e49c75..00000000 --- a/nginx/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) -FROM nginx:latest - -ENV DEBIAN_FRONTEND noninteractive - -RUN apt-get update && apt-get install -y openssl apache2-utils - -COPY config/entrypoint.sh /entrypoint.sh - -RUN chmod 755 /entrypoint.sh - -RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -VOLUME ["/etc/nginx/conf.d"] - -ENV NGINX_NAME="foo" \ - NGINX_PWD="bar" - -ENTRYPOINT [ "/entrypoint.sh" ] diff --git a/nginx/config/entrypoint.sh b/nginx/config/entrypoint.sh deleted file mode 100644 index 2f4dcecc..00000000 --- a/nginx/config/entrypoint.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -set -e - -# Generating certificates. -if [ ! -d /etc/nginx/conf.d/ssl ]; then - echo "Generating SSL certificates" - mkdir -p /etc/nginx/conf.d/ssl/certs /etc/nginx/conf.d/ssl/private - openssl req -x509 -batch -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/conf.d/ssl/private/kibana-access.key -out /etc/nginx/conf.d/ssl/certs/kibana-access.pem >/dev/null -else - echo "SSL certificates already present" -fi - -# Setting users credentials. -# In order to set NGINX_CREDENTIALS, before "docker-compose up -d" run (a or b): -# -# a) export NGINX_CREDENTIALS="user1:pass1;user2:pass2;" or -# export NGINX_CREDENTIALS="user1:pass1;user2:pass2" -# -# b) Set NGINX_CREDENTIALS in docker-compose.yml: -# NGINX_CREDENTIALS=user1:pass1;user2:pass2; or -# NGINX_CREDENTIALS=user1:pass1;user2:pass2 -# -if [ ! -f /etc/nginx/conf.d/kibana.htpasswd ]; then - echo "Setting users credentials" - if [ ! -z "$NGINX_CREDENTIALS" ]; then - IFS=';' read -r -a users <<< "$NGINX_CREDENTIALS" - for index in "${!users[@]}" - do - IFS=':' read -r -a credentials <<< "${users[index]}" - if [ $index -eq 0 ]; then - htpasswd -b -c /etc/nginx/conf.d/kibana.htpasswd ${credentials[0]} ${credentials[1]} >/dev/null - else - htpasswd -b /etc/nginx/conf.d/kibana.htpasswd ${credentials[0]} ${credentials[1]} >/dev/null - fi - done - else - # NGINX_PWD and NGINX_NAME are declared in nginx/Dockerfile - htpasswd -b -c /etc/nginx/conf.d/kibana.htpasswd $NGINX_NAME $NGINX_PWD >/dev/null - fi -else - echo "Kibana credentials already configured" -fi - -if [ "x${NGINX_PORT}" = "x" ]; then - NGINX_PORT=443 -fi - -if [ "x${KIBANA_HOST}" = "x" ]; then - KIBANA_HOST="kibana:5601" -fi - -echo "Configuring NGINX" - - -if [ "${NGINX_PORT}" = "443" ]; then -cat > /etc/nginx/conf.d/default.conf < /etc/nginx/conf.d/default.conf </dev/null 2>&1 && pwd )" +cd $DIR + +if [ -s key.pem ] +then + echo "Certificate already exists" + exit +else + openssl req -x509 -batch -nodes -days 365 -newkey rsa:2048 -keyout key.pem -out cert.pem +fi diff --git a/production_cluster/nginx/nginx.conf b/production_cluster/nginx/nginx.conf new file mode 100644 index 00000000..8cd13ca2 --- /dev/null +++ b/production_cluster/nginx/nginx.conf @@ -0,0 +1,67 @@ +user nginx; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + + keepalive_timeout 65; + + server_tokens off; + gzip on; + + # kibana UI + server { + listen 80; + listen [::]:80; + return 301 https://$host:443$request_uri; + } + + server { + listen 443 default_server ssl http2; + listen [::]:443 ssl http2; + ssl_certificate /etc/nginx/ssl/cert.pem; + ssl_certificate_key /etc/nginx/ssl/key.pem; + location / { + proxy_pass https://kibana:5601/; + proxy_ssl_verify off; + proxy_buffer_size 128k; + proxy_buffers 4 256k; + proxy_busy_buffers_size 256k; + } + } + +} + + + +# load balancer for Wazuh cluster +stream { + upstream mycluster { + hash $remote_addr consistent; + server wazuh-master:1514; + server wazuh-worker:1514; + } + server { + listen 1514; + proxy_pass mycluster; + } +} diff --git a/production_cluster/nginx/ssl/generate-self-signed-cert.sh b/production_cluster/nginx/ssl/generate-self-signed-cert.sh new file mode 100644 index 00000000..e006733f --- /dev/null +++ b/production_cluster/nginx/ssl/generate-self-signed-cert.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +cd $DIR + +if [ -s key.pem ] +then + echo "Certificate already exists" + exit +else + openssl req -x509 -batch -nodes -days 365 -newkey rsa:2048 -keyout key.pem -out cert.pem +fi diff --git a/production_cluster/ssl_certs/certs.yml b/production_cluster/ssl_certs/certs.yml new file mode 100644 index 00000000..f7dad185 --- /dev/null +++ b/production_cluster/ssl_certs/certs.yml @@ -0,0 +1,30 @@ +ca: + root: + dn: CN=root-ca,OU=CA,O=Example\, Inc.,DC=example,DC=com + pkPassword: none + keysize: 2048 + file: root-ca.pem + intermediate: + dn: CN=intermediate,OU=CA,O=Example\, Inc.,DC=example,DC=com + keysize: 2048 + validityDays: 3650 + pkPassword: intermediate-ca-password + file: intermediate-ca.pem + +nodes: + - name: node1 + dn: CN=node1,OU=Ops,O=Example\, Inc.,DC=example,DC=com + dns: + - elasticsearch + - name: node2 + dn: CN=node2,OU=Ops,O=Example\, Inc.,DC=example,DC=com + dns: + - elasticsearch-2 + - name: node3 + dn: CN=node3,OU=Ops,O=Example\, Inc.,DC=example,DC=com + dns: + - elasticsearch-3 + - name: filebeat + dn: CN=filebeat,OU=Ops,O=Example\, Inc.,DC=example,DC=com + dns: + - wazuh diff --git a/production_cluster/wazuh_cluster/wazuh_manager.conf b/production_cluster/wazuh_cluster/wazuh_manager.conf new file mode 100644 index 00000000..740321bb --- /dev/null +++ b/production_cluster/wazuh_cluster/wazuh_manager.conf @@ -0,0 +1,349 @@ + + + yes + yes + no + no + no + smtp.example.wazuh.com + ossecm@example.wazuh.com + recipient@example.wazuh.com + 12 + alerts.log + + + + 3 + 12 + + + + + plain + + + + secure + 1514 + tcp + 131072 + + + + + no + yes + yes + yes + yes + yes + yes + yes + + + 43200 + + /var/ossec/etc/rootcheck/rootkit_files.txt + /var/ossec/etc/rootcheck/rootkit_trojans.txt + + yes + + + + yes + 1800 + 1d + yes + + wodles/java + wodles/ciscat + + + + + yes + yes + /var/log/osquery/osqueryd.results.log + /etc/osquery/osquery.conf + yes + + + + + no + 1h + yes + yes + yes + yes + yes + yes + yes + + + + yes + yes + 12h + yes + + + + no + 5m + 6h + yes + + + + no + trusty + xenial + bionic + focal + 1h + + + + + no + stretch + buster + 1h + + + + + no + 5 + 6 + 7 + 8 + 1h + + + + + yes + 1h + + + + + yes + 2010 + 1h + + + + + + + no + + + 43200 + + yes + + + yes + + + no + + + /etc,/usr/bin,/usr/sbin + /bin,/sbin,/boot + + + /etc/mtab + /etc/hosts.deny + /etc/mail/statistics + /etc/random-seed + /etc/random.seed + /etc/adjtime + /etc/httpd/logs + /etc/utmpx + /etc/wtmpx + /etc/cups/certs + /etc/dumpdates + /etc/svc/volatile + + + .log$|.swp$ + + + /etc/ssl/private.key + + yes + yes + yes + yes + + + 10 + + + 100 + + + + yes + 5m + 1h + 10 + + + + + + 127.0.0.1 + ^localhost.localdomain$ + 4.2.2.1 + 4.2.2.2 + 208.67.220.220 + + + + disable-account + disable-account.sh + user + yes + + + + restart-ossec + restart-ossec.sh + + + + + firewall-drop + firewall-drop.sh + srcip + yes + + + + host-deny + host-deny.sh + srcip + yes + + + + route-null + route-null.sh + srcip + yes + + + + win_route-null + route-null.cmd + srcip + yes + + + + win_route-null-2012 + route-null-2012.cmd + srcip + yes + + + + netsh + netsh.cmd + srcip + yes + + + + netsh-win-2016 + netsh-win-2016.cmd + srcip + yes + + + + + + + command + df -P + 360 + + + + full_command + netstat -tulpn | sed 's/\([[:alnum:]]\+\)\ \+[[:digit:]]\+\ \+[[:digit:]]\+\ \+\(.*\):\([[:digit:]]*\)\ \+\([0-9\.\:\*]\+\).\+\ \([[:digit:]]*\/[[:alnum:]\-]*\).*/\1 \2 == \3 == \4 \5/' | sort -k 4 -g | sed 's/ == \(.*\) ==/:\1/' | sed 1,2d + netstat listening ports + 360 + + + + full_command + last -n 20 + 360 + + + + + ruleset/decoders + ruleset/rules + 0215-policy_rules.xml + etc/lists/audit-keys + etc/lists/amazon/aws-eventnames + etc/lists/security-eventchannel + + + etc/decoders + etc/rules + + + + + no + 1515 + no + yes + 0 + yes + no + yes + HIGH:!ADH:!EXP:!MD5:!RC4:!3DES:!CAMELLIA:@STRENGTH + + no + /var/ossec/etc/sslmanager.cert + /var/ossec/etc/sslmanager.key + no + + + + wazuh + manager + master + c98b6ha9b6169zc5f67rae55ae4z5647 + 1516 + 0.0.0.0 + + wazuh-master + + no + no + + + + + + + syslog + /var/ossec/logs/active-responses.log + + diff --git a/production_cluster/wazuh_cluster/wazuh_worker.conf b/production_cluster/wazuh_cluster/wazuh_worker.conf new file mode 100644 index 00000000..59462183 --- /dev/null +++ b/production_cluster/wazuh_cluster/wazuh_worker.conf @@ -0,0 +1,349 @@ + + + yes + yes + no + no + no + smtp.example.wazuh.com + ossecm@example.wazuh.com + recipient@example.wazuh.com + 12 + alerts.log + + + + 3 + 12 + + + + + plain + + + + secure + 1514 + tcp + 131072 + + + + + no + yes + yes + yes + yes + yes + yes + yes + + + 43200 + + /var/ossec/etc/rootcheck/rootkit_files.txt + /var/ossec/etc/rootcheck/rootkit_trojans.txt + + yes + + + + yes + 1800 + 1d + yes + + wodles/java + wodles/ciscat + + + + + yes + yes + /var/log/osquery/osqueryd.results.log + /etc/osquery/osquery.conf + yes + + + + + no + 1h + yes + yes + yes + yes + yes + yes + yes + + + + yes + yes + 12h + yes + + + + no + 5m + 6h + yes + + + + no + trusty + xenial + bionic + focal + 1h + + + + + no + stretch + buster + 1h + + + + + no + 5 + 6 + 7 + 8 + 1h + + + + + yes + 1h + + + + + yes + 2010 + 1h + + + + + + + no + + + 43200 + + yes + + + yes + + + no + + + /etc,/usr/bin,/usr/sbin + /bin,/sbin,/boot + + + /etc/mtab + /etc/hosts.deny + /etc/mail/statistics + /etc/random-seed + /etc/random.seed + /etc/adjtime + /etc/httpd/logs + /etc/utmpx + /etc/wtmpx + /etc/cups/certs + /etc/dumpdates + /etc/svc/volatile + + + .log$|.swp$ + + + /etc/ssl/private.key + + yes + yes + yes + yes + + + 10 + + + 100 + + + + yes + 5m + 1h + 10 + + + + + + 127.0.0.1 + ^localhost.localdomain$ + 4.2.2.1 + 4.2.2.2 + 208.67.220.220 + + + + disable-account + disable-account.sh + user + yes + + + + restart-ossec + restart-ossec.sh + + + + + firewall-drop + firewall-drop.sh + srcip + yes + + + + host-deny + host-deny.sh + srcip + yes + + + + route-null + route-null.sh + srcip + yes + + + + win_route-null + route-null.cmd + srcip + yes + + + + win_route-null-2012 + route-null-2012.cmd + srcip + yes + + + + netsh + netsh.cmd + srcip + yes + + + + netsh-win-2016 + netsh-win-2016.cmd + srcip + yes + + + + + + + command + df -P + 360 + + + + full_command + netstat -tulpn | sed 's/\([[:alnum:]]\+\)\ \+[[:digit:]]\+\ \+[[:digit:]]\+\ \+\(.*\):\([[:digit:]]*\)\ \+\([0-9\.\:\*]\+\).\+\ \([[:digit:]]*\/[[:alnum:]\-]*\).*/\1 \2 == \3 == \4 \5/' | sort -k 4 -g | sed 's/ == \(.*\) ==/:\1/' | sed 1,2d + netstat listening ports + 360 + + + + full_command + last -n 20 + 360 + + + + + ruleset/decoders + ruleset/rules + 0215-policy_rules.xml + etc/lists/audit-keys + etc/lists/amazon/aws-eventnames + etc/lists/security-eventchannel + + + etc/decoders + etc/rules + + + + + no + 1515 + no + yes + 0 + yes + no + yes + HIGH:!ADH:!EXP:!MD5:!RC4:!3DES:!CAMELLIA:@STRENGTH + + no + /var/ossec/etc/sslmanager.cert + /var/ossec/etc/sslmanager.key + no + + + + wazuh + worker01 + worker + c98b6ha9b6169zc5f67rae55ae4z5647 + 1516 + 0.0.0.0 + + wazuh-master + + no + no + + + + + + + syslog + /var/ossec/logs/active-responses.log + + diff --git a/wazuh-odfe/Dockerfile b/wazuh-odfe/Dockerfile new file mode 100644 index 00000000..0148d8e0 --- /dev/null +++ b/wazuh-odfe/Dockerfile @@ -0,0 +1,51 @@ +# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) +FROM centos:7 + +ARG FILEBEAT_VERSION=7.9.1 +ARG WAZUH_VERSION=4.0.0-1 +ARG TEMPLATE_VERSION="master" +ARG WAZUH_FILEBEAT_MODULE="wazuh-filebeat-0.1.tar.gz" + +# Set repositories. +RUN rpm --import https://packages.wazuh.com/key/GPG-KEY-WAZUH + +COPY config/wazuh.repo /etc/yum.repos.d/wazuh.repo + +RUN yum --enablerepo=updates clean metadata && \ + yum -y install openssl which expect openssh-clients && yum -y install wazuh-manager-${WAZUH_VERSION} -y && \ + sed -i "s/^enabled=1/enabled=0/" /etc/yum.repos.d/wazuh.repo && \ + yum clean all && rm -rf /var/cache/yum + +RUN curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-oss-${FILEBEAT_VERSION}-x86_64.rpm &&\ + rpm -i filebeat-oss-${FILEBEAT_VERSION}-x86_64.rpm && rm -f filebeat-oss-${FILEBEAT_VERSION}-x86_64.rpm + +RUN curl -s https://packages.wazuh.com/4.x/filebeat/${WAZUH_FILEBEAT_MODULE} | tar -xvz -C /usr/share/filebeat/module + +ARG S6_VERSION="v2.1.0.2" +RUN curl --fail --silent -L https://github.com/just-containers/s6-overlay/releases/download/${S6_VERSION}/s6-overlay-amd64.tar.gz \ + -o /tmp/s6-overlay-amd64.tar.gz && \ + tar xzf /tmp/s6-overlay-amd64.tar.gz -C / --exclude="./bin" && \ + tar xzf /tmp/s6-overlay-amd64.tar.gz -C /usr ./bin && \ + rm /tmp/s6-overlay-amd64.tar.gz + +COPY config/filebeat.yml /etc/filebeat/ + +RUN chmod go-w /etc/filebeat/filebeat.yml + +ADD https://raw.githubusercontent.com/wazuh/wazuh/$TEMPLATE_VERSION/extensions/elasticsearch/7.x/wazuh-template.json /etc/filebeat +RUN chmod go-w /etc/filebeat/wazuh-template.json + +COPY config/etc/ /etc/ +COPY --chown=root:ossec config/create_user.py /var/ossec/framework/scripts/create_user.py + +# Prepare permanent data +# Sync calls are due to https://github.com/docker/docker/issues/9547 +COPY config/permanent_data.env config/permanent_data.sh / +RUN chmod 755 /permanent_data.sh && \ + sync && /permanent_data.sh && \ + sync && rm /permanent_data.sh + +# Services ports +EXPOSE 55000/tcp 1514/tcp 1515/tcp 514/udp 1516/tcp + +ENTRYPOINT [ "/init" ] diff --git a/wazuh-odfe/config/create_user.py b/wazuh-odfe/config/create_user.py new file mode 100644 index 00000000..b4b5e813 --- /dev/null +++ b/wazuh-odfe/config/create_user.py @@ -0,0 +1,90 @@ +import logging +import sys +import json +import random +import string +import os + +# Set framework path +sys.path.append(os.path.dirname(sys.argv[0]) + "/../framework") + +USER_FILE_PATH = "/var/ossec/api/configuration/admin.json" + + +try: + from wazuh.security import ( + create_user, + get_users, + get_roles, + set_user_role, + update_user, + ) +except Exception as e: + logging.error("No module 'wazuh' found.") + sys.exit(1) + + +def read_user_file(path=USER_FILE_PATH): + with open(path) as user_file: + data = json.load(user_file) + return data["username"], data["password"] + + +def db_users(): + users_result = get_users() + return {user["username"]: user["id"] for user in users_result.affected_items} + + +def db_roles(): + roles_result = get_roles() + return {role["name"]: role["id"] for role in roles_result.affected_items} + + +if __name__ == "__main__": + if not os.path.exists(USER_FILE_PATH): + # abort if no user file detected + sys.exit(0) + username, password = read_user_file() + initial_users = db_users() + if username not in initial_users: + # create a new user + create_user(username=username, password=password) + users = db_users() + uid = users[username] + roles = db_roles() + rid = roles["administrator"] + set_user_role( + user_id=[ + str(uid), + ], + role_ids=[ + str(rid), + ], + ) + else: + # modify an existing user ("wazuh" or "wazuh-wui") + uid = initial_users[username] + update_user( + user_id=[ + str(uid), + ], + password=password, + ) + # set a random password for all other users + for name, id in initial_users.items(): + if name != username: + random_pass = "".join( + random.choices( + string.ascii_uppercase + + string.ascii_lowercase + + string.digits + + "@$!%*?&-_", + k=16, + ) + ) + update_user( + user_id=[ + str(id), + ], + password=random_pass, + ) diff --git a/wazuh-odfe/config/etc/cont-init.d/0-wazuh-init b/wazuh-odfe/config/etc/cont-init.d/0-wazuh-init new file mode 100644 index 00000000..68538c10 --- /dev/null +++ b/wazuh-odfe/config/etc/cont-init.d/0-wazuh-init @@ -0,0 +1,187 @@ +#!/usr/bin/with-contenv bash +# Wazuh App Copyright (C) 2020 Wazuh Inc. (License GPLv2) + +# Variables +source /permanent_data.env + +WAZUH_INSTALL_PATH=/var/ossec +WAZUH_CONFIG_MOUNT=/wazuh-config-mount +AUTO_ENROLLMENT_ENABLED=${AUTO_ENROLLMENT_ENABLED:-true} + + +############################################################################## +# Aux functions +############################################################################## +print() { + echo -e $1 +} + +error_and_exit() { + echo "Error executing command: '$1'." + echo 'Exiting.' + exit 1 +} + +exec_cmd() { + eval $1 > /dev/null 2>&1 || error_and_exit "$1" +} + +exec_cmd_stdout() { + eval $1 2>&1 || error_and_exit "$1" +} + + +############################################################################## +# This function will attempt to mount every directory in PERMANENT_DATA +# into the respective path. +# If the path is empty means permanent data volume is also empty, so a backup +# will be copied into it. Otherwise it will not be copied because there is +# already data inside the volume for the specified path. +############################################################################## + +mount_permanent_data() { + for permanent_dir in "${PERMANENT_DATA[@]}"; do + # Check if the path is not empty + if find ${permanent_dir} -mindepth 1 | read; then + print "The path ${permanent_dir} is already mounted" + else + print "Installing ${permanent_dir}" + exec_cmd "cp -a ${WAZUH_INSTALL_PATH}/data_tmp/permanent${permanent_dir}/. ${permanent_dir}" + fi + done +} + +############################################################################## +# This function will replace from the permanent data volume every file +# contained in PERMANENT_DATA_EXCP +# Some files as 'internal_options.conf' are saved as permanent data, but +# they must be updated to work properly if wazuh version is changed. +############################################################################## + +apply_exclusion_data() { + for exclusion_file in "${PERMANENT_DATA_EXCP[@]}"; do + if [ -e ${WAZUH_INSTALL_PATH}/data_tmp/exclusion/${exclusion_file} ] + then + DIR=$(dirname "${exclusion_file}") + if [ ! -e ${DIR} ] + then + mkdir -p ${DIR} + fi + + print "Updating ${exclusion_file}" + exec_cmd "cp -p ${WAZUH_INSTALL_PATH}/data_tmp/exclusion/${exclusion_file} ${exclusion_file}" + fi + done +} + +############################################################################## +# This function will delete from the permanent data volume every file +# contained in PERMANENT_DATA_DEL +############################################################################## + +remove_data_files() { + for del_file in "${PERMANENT_DATA_DEL[@]}"; do + if [ -e ${del_file} ] + then + print "Removing ${del_file}" + exec_cmd "rm ${del_file}" + fi + done +} + +############################################################################## +# Create certificates: Manager +############################################################################## + +create_ossec_key_cert() { + print "Creating ossec-authd key and cert" + exec_cmd "openssl genrsa -out ${WAZUH_INSTALL_PATH}/etc/sslmanager.key 4096" + exec_cmd "openssl req -new -x509 -key ${WAZUH_INSTALL_PATH}/etc/sslmanager.key -out ${WAZUH_INSTALL_PATH}/etc/sslmanager.cert -days 3650 -subj /CN=${HOSTNAME}/" +} + +############################################################################## +# Copy all files from $WAZUH_CONFIG_MOUNT to $WAZUH_INSTALL_PATH and respect +# destination files permissions +# +# For example, to mount the file /var/ossec/data/etc/ossec.conf, mount it at +# $WAZUH_CONFIG_MOUNT/etc/ossec.conf in your container and this code will +# replace the ossec.conf file in /var/ossec/data/etc with yours. +############################################################################## + +mount_files() { + if [ -e "$WAZUH_CONFIG_MOUNT" ] + then + print "Identified Wazuh configuration files to mount..." + exec_cmd_stdout "cp --verbose -r $WAZUH_CONFIG_MOUNT/* $WAZUH_INSTALL_PATH" + else + print "No Wazuh configuration files to mount..." + fi +} + + +############################################################################## +# Allow users to set the container hostname as dynamically on +# container start. +# +# To use this: +# 1. Create your own ossec.conf file +# 2. In your ossec.conf file, set to_be_replaced_by_hostname as your node_name +# 3. Mount your custom ossec.conf file at $WAZUH_CONFIG_MOUNT/etc/ossec.conf +############################################################################## + +set_custom_hostname() { + sed -i 's/to_be_replaced_by_hostname<\/node_name>/'"${HOSTNAME}"'<\/node_name>/g' ${WAZUH_INSTALL_PATH}/etc/ossec.conf +} + +############################################################################## +# Allow users to set the container cluster key dynamically on +# container start. +# +# To use this: +# 1. Create your own ossec.conf file +# 2. In your ossec.conf file, set to_be_replaced_by_cluster_key as your key +# 3. Mount your custom ossec.conf file at $WAZUH_CONFIG_MOUNT/etc/ossec.conf +############################################################################## + +set_custom_cluster_key() { + sed -i 's/to_be_replaced_by_cluster_key<\/key>/'"${WAZUH_CLUSTER_KEY}"'<\/key>/g' ${WAZUH_INSTALL_PATH}/etc/ossec.conf +} + +############################################################################## +# Main function +############################################################################## + +main() { + # Mount permanent data (i.e. ossec.conf) + mount_permanent_data + + # Restore files stored in permanent data that are not permanent (i.e. internal_options.conf) + apply_exclusion_data + + # Remove some files in permanent_data (i.e. .template.db) + remove_data_files + + # Generate ossec-authd certs if AUTO_ENROLLMENT_ENABLED is true and does not exist + if [ $AUTO_ENROLLMENT_ENABLED == true ] + then + if [ ! -e ${WAZUH_INSTALL_PATH}/etc/sslmanager.key ] + then + create_ossec_key_cert + fi + fi + + # Mount selected files (WAZUH_CONFIG_MOUNT) to container + mount_files + + # Allow setting custom hostname + set_custom_hostname + + # Allow setting custom cluster key + set_custom_cluster_key + + # Delete temporary data folder + rm -rf ${WAZUH_INSTALL_PATH}/data_tmp + +} + +main diff --git a/wazuh-odfe/config/etc/cont-init.d/1-config-filebeat b/wazuh-odfe/config/etc/cont-init.d/1-config-filebeat new file mode 100644 index 00000000..ce033aa5 --- /dev/null +++ b/wazuh-odfe/config/etc/cont-init.d/1-config-filebeat @@ -0,0 +1,45 @@ +#!/usr/bin/with-contenv bash +# Wazuh App Copyright (C) 2020 Wazuh Inc. (License GPLv2) + +set -e + +if [ "$ELASTICSEARCH_URL" != "" ]; then + >&2 echo "Customize Elasticsearch ouput IP" + sed -i "s|hosts:.*|hosts: ['$ELASTICSEARCH_URL']|g" /etc/filebeat/filebeat.yml +fi + +# Configure filebeat.yml security settings + +if [ "$ELASTIC_USERNAME" != "" ]; then + >&2 echo "Configuring username." + sed -i "s|#username:.*|username: '$ELASTIC_USERNAME'|g" /etc/filebeat/filebeat.yml +fi + +if [ "$ELASTIC_PASSWORD" != "" ]; then + >&2 echo "Configuring password." + sed -i "s|#password:.*|password: '$ELASTIC_PASSWORD'|g" /etc/filebeat/filebeat.yml +fi + +if [ "$FILEBEAT_SSL_VERIFICATION_MODE" != "" ]; then + >&2 echo "Configuring SSL verification mode." + sed -i "s|#ssl.verification_mode:.*|ssl.verification_mode: $FILEBEAT_SSL_VERIFICATION_MODE|g" /etc/filebeat/filebeat.yml +fi + +if [ "$SSL_CERTIFICATE_AUTHORITIES" != "" ]; then + >&2 echo "Configuring Certificate Authorities." + sed -i "s|#ssl.certificate_authorities:.*|ssl.certificate_authorities: ['$SSL_CERTIFICATE_AUTHORITIES']|g" /etc/filebeat/filebeat.yml +fi + +if [ "$SSL_CERTIFICATE" != "" ]; then + >&2 echo "Configuring SSL Certificate." + sed -i "s|#ssl.certificate:.*|ssl.certificate: '$SSL_CERTIFICATE'|g" /etc/filebeat/filebeat.yml +fi + +if [ "$SSL_KEY" != "" ]; then + >&2 echo "Configuring SSL Key." + sed -i "s|#ssl.key:.*|ssl.key: '$SSL_KEY'|g" /etc/filebeat/filebeat.yml +fi + + +chmod go-w /etc/filebeat/filebeat.yml || true +chown root: /etc/filebeat/filebeat.yml || true diff --git a/wazuh-odfe/config/etc/cont-init.d/2-manager b/wazuh-odfe/config/etc/cont-init.d/2-manager new file mode 100644 index 00000000..4419011a --- /dev/null +++ b/wazuh-odfe/config/etc/cont-init.d/2-manager @@ -0,0 +1,113 @@ +#!/usr/bin/with-contenv bash + +############################################################################## +# Migration sequence +# Detect if there is a mounted volume on /wazuh-migration and copy the data +# to /var/ossec, finally it will create a flag ".migration-completed" inside +# the mounted volume +############################################################################## + +function __colortext() +{ + echo -e " \e[1;$2m$1\e[0m" +} + +function echogreen() +{ + echo $(__colortext "$1" "32") +} + +function echoyellow() +{ + echo $(__colortext "$1" "33") +} + +function echored() +{ + echo $(__colortext "$1" "31") +} + +function_wazuh_migration(){ + if [ -d "/wazuh-migration" ]; then + if [ ! -e /wazuh-migration/.migration-completed ]; then + if [ ! -e /wazuh-migration/global.db ]; then + echoyellow "The volume mounted on /wazuh-migration does not contain all the correct files." + return + fi + + \cp -f /wazuh-migration/data/etc/ossec.conf /var/ossec/etc/ossec.conf + chown root:ossec /var/ossec/etc/ossec.conf + chmod 640 /var/ossec/etc/ossec.conf + + \cp -f /wazuh-migration/data/etc/client.keys /var/ossec/etc/client.keys + chown ossec:ossec /var/ossec/etc/client.keys + chmod 640 /var/ossec/etc/client.keys + + \cp -f /wazuh-migration/data/etc/sslmanager.cert /var/ossec/etc/sslmanager.cert + \cp -f /wazuh-migration/data/etc/sslmanager.key /var/ossec/etc/sslmanager.key + chown root:root /var/ossec/etc/sslmanager.cert /var/ossec/etc/sslmanager.key + chmod 640 /var/ossec/etc/sslmanager.cert /var/ossec/etc/sslmanager.key + + \cp -f /wazuh-migration/data/etc/shared/default/agent.conf /var/ossec/etc/shared/default/agent.conf + chown ossec:ossec /var/ossec/etc/shared/default/agent.conf + chmod 660 /var/ossec/etc/shared/default/agent.conf + + \cp -f /wazuh-migration/data/etc/decoders/* /var/ossec/etc/decoders/ + chown ossec:ossec /var/ossec/etc/decoders/* + chmod 660 /var/ossec/etc/decoders/* + + \cp -f /wazuh-migration/data/etc/rules/* /var/ossec/etc/rules/ + chown ossec:ossec /var/ossec/etc/rules/* + chmod 660 /var/ossec/etc/rules/* + + if [ -e /wazuh-migration/data/agentless/.passlist ]; then + \cp -f /wazuh-migration/data/agentless/.passlist /var/ossec/agentless/.passlist + chown root:ossec /var/ossec/agentless/.passlist + chmod 640 /var/ossec/agentless/.passlist + fi + + \cp -f /wazuh-migration/global.db /var/ossec/queue/db/global.db + chown ossec:ossec /var/ossec/queue/db/global.db + chmod 640 /var/ossec/queue/db/global.db + + # mark volume as migrated + touch /wazuh-migration/.migration-completed + + echogreen "Migration completed succesfully" + else + echoyellow "This volume has already been migrated. You may proceed and remove it from the mount point (/wazuh-migration)" + fi + fi +} + +function_create_custom_user() { + if [[ ! -z $API_USERNAME ]] && [[ ! -z $API_PASSWORD ]]; then + cat << EOF > /var/ossec/api/configuration/admin.json +{ + "username": "$API_USERNAME", + "password": "$API_PASSWORD" +} +EOF + + # create or customize API user + if /var/ossec/framework/python/bin/python3 /var/ossec/framework/scripts/create_user.py; then + # remove json if exit code is 0 + rm /var/ossec/api/configuration/admin.json + else + echored "There was an error configuring the API user" + # terminate container to avoid unpredictable behavior + exec s6-svscanctl -t /var/run/s6/services + exit 1 + fi + fi +} + + +# Migrate data from /wazuh-migration volume +function_wazuh_migration + +# create API custom user +function_create_custom_user + +# Start Wazuh +/var/ossec/bin/ossec-control start diff --git a/wazuh-odfe/config/etc/services.d/filebeat/finish b/wazuh-odfe/config/etc/services.d/filebeat/finish new file mode 100644 index 00000000..8813eb67 --- /dev/null +++ b/wazuh-odfe/config/etc/services.d/filebeat/finish @@ -0,0 +1,6 @@ +#!/usr/bin/env sh +echo >&2 "Filebeat exited. code=${1}" + +# terminate other services to exit from the container +exec s6-svscanctl -t /var/run/s6/services + diff --git a/wazuh-odfe/config/etc/services.d/filebeat/run b/wazuh-odfe/config/etc/services.d/filebeat/run new file mode 100644 index 00000000..706ee5af --- /dev/null +++ b/wazuh-odfe/config/etc/services.d/filebeat/run @@ -0,0 +1,4 @@ +#!/usr/bin/with-contenv sh +echo >&2 "starting Filebeat" + +exec /usr/share/filebeat/bin/filebeat -e -c /etc/filebeat/filebeat.yml -path.home /usr/share/filebeat -path.config /etc/filebeat -path.data /var/lib/filebeat -path.logs /var/log/filebeat diff --git a/wazuh/config/filebeat.yml b/wazuh-odfe/config/filebeat.yml similarity index 64% rename from wazuh/config/filebeat.yml rename to wazuh-odfe/config/filebeat.yml index 46600662..8a627bf9 100644 --- a/wazuh/config/filebeat.yml +++ b/wazuh-odfe/config/filebeat.yml @@ -1,3 +1,4 @@ + # Wazuh - Filebeat configuration file filebeat.modules: - module: wazuh @@ -11,5 +12,11 @@ setup.template.json.path: '/etc/filebeat/wazuh-template.json' setup.template.json.name: 'wazuh' setup.template.overwrite: true setup.ilm.enabled: false - -output.elasticsearch.hosts: ['http://elasticsearch:9200'] \ No newline at end of file +output.elasticsearch: + hosts: ['https://elasticsearch:9200'] + #username: + #password: + #ssl.verification_mode: + #ssl.certificate_authorities: + #ssl.certificate: + #ssl.key: diff --git a/wazuh-odfe/config/permanent_data.env b/wazuh-odfe/config/permanent_data.env new file mode 100644 index 00000000..9c2556d8 --- /dev/null +++ b/wazuh-odfe/config/permanent_data.env @@ -0,0 +1,67 @@ +# Permanent data mounted in volumes +i=0 +PERMANENT_DATA[((i++))]="/var/ossec/api/configuration" +PERMANENT_DATA[((i++))]="/var/ossec/etc" +PERMANENT_DATA[((i++))]="/var/ossec/logs" +PERMANENT_DATA[((i++))]="/var/ossec/queue" +PERMANENT_DATA[((i++))]="/var/ossec/agentless" +PERMANENT_DATA[((i++))]="/var/ossec/var/multigroups" +PERMANENT_DATA[((i++))]="/var/ossec/integrations" +PERMANENT_DATA[((i++))]="/var/ossec/active-response/bin" +PERMANENT_DATA[((i++))]="/var/ossec/wodles" +PERMANENT_DATA[((i++))]="/etc/filebeat" +export PERMANENT_DATA + +# Files mounted in a volume that should not be permanent +i=0 +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/etc/internal_options.conf" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/integrations/pagerduty" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/integrations/slack" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/integrations/slack.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/integrations/virustotal" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/integrations/virustotal.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/default-firewall-drop.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/disable-account.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/firewalld-drop.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/firewall-drop.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/host-deny.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/ip-customblock.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/ipfw_mac.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/ipfw.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/kaspersky.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/kaspersky.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/npf.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/ossec-slack.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/ossec-tweeter.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/pf.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/restart-ossec.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/restart.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/route-null.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/sshlogin.exp" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/ssh_pixconfig_diff" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/ssh_asa-fwsmconfig_diff" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/ssh_integrity_check_bsd" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/main.exp" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/su.exp" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/ssh_integrity_check_linux" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/register_host.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/ssh_generic_diff" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/ssh_foundry_diff" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/ssh_nopass.exp" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/agentless/ssh.exp" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/aws/aws-s3" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/aws/aws-s3.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/azure/azure-logs" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/azure/azure-logs.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/docker/DockerListener" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/docker/DockerListener.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/gcloud/gcloud" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/gcloud/gcloud.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/gcloud/integration.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/gcloud/tools.py" +export PERMANENT_DATA_EXCP + +# Files mounted in a volume that should be deleted +i=0 +PERMANENT_DATA_DEL[((i++))]="/var/ossec/queue/db/.template.db" +export PERMANENT_DATA_DEL diff --git a/wazuh-odfe/config/permanent_data.sh b/wazuh-odfe/config/permanent_data.sh new file mode 100644 index 00000000..7dfaa647 --- /dev/null +++ b/wazuh-odfe/config/permanent_data.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Wazuh App Copyright (C) 2020 Wazuh Inc. (License GPLv2) + +# Variables +source /permanent_data.env + +WAZUH_INSTALL_PATH=/var/ossec +DATA_TMP_PATH=${WAZUH_INSTALL_PATH}/data_tmp +mkdir ${DATA_TMP_PATH} + +# Move exclusion files to EXCLUSION_PATH +EXCLUSION_PATH=${DATA_TMP_PATH}/exclusion +mkdir ${EXCLUSION_PATH} + +for exclusion_file in "${PERMANENT_DATA_EXCP[@]}"; do + # Create the directory for the exclusion file if it does not exist + DIR=$(dirname "${exclusion_file}") + if [ ! -e ${EXCLUSION_PATH}/${DIR} ] + then + mkdir -p ${EXCLUSION_PATH}/${DIR} + fi + + mv ${exclusion_file} ${EXCLUSION_PATH}/${exclusion_file} +done + +# Move permanent files to PERMANENT_PATH +PERMANENT_PATH=${DATA_TMP_PATH}/permanent +mkdir ${PERMANENT_PATH} + +for permanent_dir in "${PERMANENT_DATA[@]}"; do + # Create the directory for the permanent file if it does not exist + DIR=$(dirname "${permanent_dir}") + if [ ! -e ${PERMANENT_PATH}${DIR} ] + then + mkdir -p ${PERMANENT_PATH}${DIR} + fi + + mv ${permanent_dir} ${PERMANENT_PATH}${permanent_dir} + +done diff --git a/wazuh-odfe/config/wazuh.repo b/wazuh-odfe/config/wazuh.repo new file mode 100644 index 00000000..e230d6a9 --- /dev/null +++ b/wazuh-odfe/config/wazuh.repo @@ -0,0 +1,7 @@ +[wazuh_repo] +gpgcheck=1 +gpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH +enabled=1 +name=Wazuh repository +baseurl=https://packages.wazuh.com/4.x/yum/ +protect=1 diff --git a/wazuh/Dockerfile b/wazuh/Dockerfile deleted file mode 100644 index 2a091d86..00000000 --- a/wazuh/Dockerfile +++ /dev/null @@ -1,83 +0,0 @@ -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) -FROM phusion/baseimage:0.10.2 - -ARG FILEBEAT_VERSION=7.9.1 - -ARG WAZUH_VERSION=3.13.2-1 - -ENV API_USER="foo" \ - API_PASS="bar" - -ARG TEMPLATE_VERSION="v3.13.2" - -# Set repositories. -RUN set -x && echo "deb https://packages.wazuh.com/3.x/apt/ stable main" | tee /etc/apt/sources.list.d/wazuh.list && \ - curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | apt-key add - && \ - curl --silent --location https://deb.nodesource.com/setup_10.x | bash - && \ - echo "postfix postfix/mailname string wazuh-manager" | debconf-set-selections && \ - echo "postfix postfix/main_mailer_type string 'Internet Site'" | debconf-set-selections && \ - groupadd -g 1000 ossec && useradd -u 1000 -g 1000 -d /var/ossec ossec - -RUN add-apt-repository universe && apt-get update && apt-get upgrade -y -o Dpkg::Options::="--force-confold" && \ - apt-get --no-install-recommends --no-install-suggests -y install openssl postfix bsd-mailx python-boto python-pip \ - apt-transport-https vim expect nodejs python-cryptography mailutils libsasl2-modules wazuh-manager=${WAZUH_VERSION} \ - wazuh-api=${WAZUH_VERSION} && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && rm -f \ - /var/ossec/logs/alerts/*/*/*.log && rm -f /var/ossec/logs/alerts/*/*/*.json && rm -f \ - /var/ossec/logs/archives/*/*/*.log && rm -f /var/ossec/logs/archives/*/*/*.json && rm -f \ - /var/ossec/logs/firewall/*/*/*.log && rm -f /var/ossec/logs/firewall/*/*/*.json - -# Adding first run script and entrypoint -COPY config/data_dirs.env /data_dirs.env -COPY config/init.bash /init.bash -RUN mkdir /entrypoint-scripts -COPY config/entrypoint.sh /entrypoint.sh -COPY config/00-wazuh.sh /entrypoint-scripts/00-wazuh.sh -COPY config/01-config_filebeat.sh /entrypoint-scripts/01-config_filebeat.sh - -# Sync calls are due to https://github.com/docker/docker/issues/9547 -RUN chmod 755 /init.bash && \ - sync && /init.bash && \ - sync && rm /init.bash && \ - curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-${FILEBEAT_VERSION}-amd64.deb &&\ - dpkg -i filebeat-${FILEBEAT_VERSION}-amd64.deb && rm -f filebeat-${FILEBEAT_VERSION}-amd64.deb && \ - chmod 755 /entrypoint.sh && \ - chmod 755 /entrypoint-scripts/00-wazuh.sh && \ - chmod 755 /entrypoint-scripts/01-config_filebeat.sh - -COPY config/filebeat.yml /etc/filebeat/ -RUN chmod go-w /etc/filebeat/filebeat.yml - -# Setting volumes -VOLUME ["/var/ossec/data"] -VOLUME ["/etc/filebeat"] -VOLUME ["/etc/postfix"] -VOLUME ["/var/lib/filebeat"] - -# Services ports -EXPOSE 55000/tcp 1514/udp 1515/tcp 514/udp 1516/tcp - -# Adding services -RUN mkdir /etc/service/wazuh && \ - mkdir /etc/service/wazuh-api && \ - mkdir /etc/service/postfix && \ - mkdir /etc/service/filebeat - -COPY config/wazuh.runit.service /etc/service/wazuh/run -COPY config/wazuh-api.runit.service /etc/service/wazuh-api/run -COPY config/postfix.runit.service /etc/service/postfix/run -COPY config/filebeat.runit.service /etc/service/filebeat/run - -RUN chmod +x /etc/service/wazuh-api/run && \ - chmod +x /etc/service/wazuh/run && \ - chmod +x /etc/service/postfix/run && \ - chmod +x /etc/service/filebeat/run - - -ADD https://raw.githubusercontent.com/wazuh/wazuh/$TEMPLATE_VERSION/extensions/elasticsearch/7.x/wazuh-template.json /etc/filebeat -RUN chmod go-w /etc/filebeat/wazuh-template.json - -ARG WAZUH_FILEBEAT_MODULE="wazuh-filebeat-0.1.tar.gz" -RUN curl -s https://packages.wazuh.com/3.x/filebeat/${WAZUH_FILEBEAT_MODULE} | tar -xvz -C /usr/share/filebeat/module - -# Run all services -ENTRYPOINT ["/entrypoint.sh"] diff --git a/wazuh/config/00-wazuh.sh b/wazuh/config/00-wazuh.sh deleted file mode 100644 index 2ac30efd..00000000 --- a/wazuh/config/00-wazuh.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -# Wazuh container bootstrap. See the README for information of the environment -# variables expected by this script. - -# Startup the services -source /data_dirs.env - -FIRST_TIME_INSTALLATION=false - -WAZUH_INSTALL_PATH=/var/ossec -DATA_PATH=${WAZUH_INSTALL_PATH}/data - -WAZUH_CONFIG_MOUNT=/wazuh-config-mount - -print() { - echo -e $1 -} - -error_and_exit() { - echo "Error executing command: '$1'." - echo 'Exiting.' - exit 1 -} - -exec_cmd() { - eval $1 > /dev/null 2>&1 || error_and_exit "$1" -} - -exec_cmd_stdout() { - eval $1 2>&1 || error_and_exit "$1" -} - -edit_configuration() { # $1 -> setting, $2 -> value - sed -i "s/^config.$1\s=.*/config.$1 = \"$2\";/g" "${DATA_PATH}/api/configuration/config.js" || error_and_exit "sed (editing configuration)" -} - -for ossecdir in "${DATA_DIRS[@]}"; do - if [ ! -e "${DATA_PATH}/${ossecdir}" ] - then - print "Installing ${ossecdir}" - exec_cmd "mkdir -p $(dirname ${DATA_PATH}/${ossecdir})" - exec_cmd "cp -pr /var/ossec/${ossecdir}-template ${DATA_PATH}/${ossecdir}" - FIRST_TIME_INSTALLATION=true - fi -done - -if [ -e ${WAZUH_INSTALL_PATH}/etc-template ] -then - cp -p /var/ossec/etc-template/internal_options.conf /var/ossec/etc/internal_options.conf -fi - -# copy missing files from queue-template (in case this is an upgrade from previous versions) -for filename in /var/ossec/queue-template/*; do - fname=$(basename $filename) - echo $fname - if test ! -e "/var/ossec/data/queue/$fname"; then - cp -rp "/var/ossec/queue-template/$fname" /var/ossec/data/queue/ - fi -done - -touch ${DATA_PATH}/process_list -chgrp ossec ${DATA_PATH}/process_list -chmod g+rw ${DATA_PATH}/process_list - -AUTO_ENROLLMENT_ENABLED=${AUTO_ENROLLMENT_ENABLED:-true} -API_GENERATE_CERTS=${API_GENERATE_CERTS:-true} - -if [ $FIRST_TIME_INSTALLATION == true ] -then - if [ $AUTO_ENROLLMENT_ENABLED == true ] - then - if [ ! -e ${DATA_PATH}/etc/sslmanager.key ] - then - print "Creating ossec-authd key and cert" - exec_cmd "openssl genrsa -out ${DATA_PATH}/etc/sslmanager.key 4096" - exec_cmd "openssl req -new -x509 -key ${DATA_PATH}/etc/sslmanager.key -out ${DATA_PATH}/etc/sslmanager.cert -days 3650 -subj /CN=${HOSTNAME}/" - fi - fi - if [ $API_GENERATE_CERTS == true ] - then - if [ ! -e ${DATA_PATH}/api/configuration/ssl/server.crt ] - then - print "Enabling Wazuh API HTTPS" - edit_configuration "https" "yes" - print "Create Wazuh API key and cert" - exec_cmd "openssl genrsa -out ${DATA_PATH}/api/configuration/ssl/server.key 4096" - exec_cmd "openssl req -new -x509 -key ${DATA_PATH}/api/configuration/ssl/server.key -out ${DATA_PATH}/api/configuration/ssl/server.crt -days 3650 -subj /CN=${HOSTNAME}/" - fi - fi -fi - -############################################################################## -# Copy all files from $WAZUH_CONFIG_MOUNT to $DATA_PATH and respect -# destination files permissions -# -# For example, to mount the file /var/ossec/data/etc/ossec.conf, mount it at -# $WAZUH_CONFIG_MOUNT/etc/ossec.conf in your container and this code will -# replace the ossec.conf file in /var/ossec/data/etc with yours. -############################################################################## -if [ -e "$WAZUH_CONFIG_MOUNT" ] -then - print "Identified Wazuh configuration files to mount..." - - exec_cmd_stdout "cp --verbose -r $WAZUH_CONFIG_MOUNT/* $DATA_PATH" -else - print "No Wazuh configuration files to mount..." -fi - -function ossec_shutdown(){ - ${WAZUH_INSTALL_PATH}/bin/ossec-control stop; -} - -############################################################################## -# Allow users to set the container hostname as dynamically on -# container start. -# -# To use this: -# 1. Create your own ossec.conf file -# 2. In your ossec.conf file, set to_be_replaced_by_hostname as your node_name -# 3. Mount your custom ossec.conf file at $WAZUH_CONFIG_MOUNT/etc/ossec.conf -############################################################################## -sed -i 's/to_be_replaced_by_hostname<\/node_name>/'"${HOSTNAME}"'<\/node_name>/g' ${WAZUH_INSTALL_PATH}/etc/ossec.conf - -# Setting Wazuh cluster key -sed -i 's/to_be_replaced_by_cluster_key<\/key>/'"${WAZUH_CLUSTER_KEY}"'<\/key>/g' ${WAZUH_INSTALL_PATH}/etc/ossec.conf - -# Trap exit signals and do a proper shutdown -trap "ossec_shutdown; exit" SIGINT SIGTERM - -chmod -R g+rw ${DATA_PATH} -chmod 750 /var/ossec/agentless/* - -############################################################################## -# Interpret any passed arguments (via docker command to this entrypoint) as -# paths or commands, and execute them. -# -# This can be useful for actions that need to be run before the services are -# started, such as "/var/ossec/bin/ossec-control enable agentless". -############################################################################## -for CUSTOM_COMMAND in "$@" -do - echo "Executing command \`${CUSTOM_COMMAND}\`" - exec_cmd_stdout "${CUSTOM_COMMAND}" -done - -############################################################################## -# Change Wazuh API user credentials. -############################################################################## - -pushd /var/ossec/api/configuration/auth/ - -echo "Change Wazuh API user credentials" -change_user="node htpasswd -b -c user $API_USER $API_PASS" -eval $change_user - -popd diff --git a/wazuh/config/01-config_filebeat.sh b/wazuh/config/01-config_filebeat.sh deleted file mode 100644 index 952301e6..00000000 --- a/wazuh/config/01-config_filebeat.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# Wazuh App Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -set -e - -# Modify the output to Elasticsearch if th ELASTICSEARCH_URL is set -if [ "$ELASTICSEARCH_URL" != "" ]; then - >&2 echo "Customize Elasticsearch ouput IP." - sed -i 's|http://elasticsearch:9200|'$ELASTICSEARCH_URL'|g' /etc/filebeat/filebeat.yml -fi diff --git a/wazuh/config/data_dirs.env b/wazuh/config/data_dirs.env deleted file mode 100644 index e6735069..00000000 --- a/wazuh/config/data_dirs.env +++ /dev/null @@ -1,8 +0,0 @@ -i=0 -DATA_DIRS[((i++))]="api/configuration" -DATA_DIRS[((i++))]="etc" -DATA_DIRS[((i++))]="logs" -DATA_DIRS[((i++))]="queue" -DATA_DIRS[((i++))]="agentless" -DATA_DIRS[((i++))]="var/multigroups" -export DATA_DIRS diff --git a/wazuh/config/entrypoint.sh b/wazuh/config/entrypoint.sh deleted file mode 100644 index 11bfe752..00000000 --- a/wazuh/config/entrypoint.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -# It will run every .sh script located in entrypoint-scripts folder in lexicographical order -for script in `ls /entrypoint-scripts/*.sh | sort -n`; do - bash "$script" - -done - -############################################################################## -# Start Wazuh Server. -############################################################################## - -/sbin/my_init diff --git a/wazuh/config/filebeat.runit.service b/wazuh/config/filebeat.runit.service deleted file mode 100644 index fc28c4be..00000000 --- a/wazuh/config/filebeat.runit.service +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) -service filebeat start -tail -f /var/log/filebeat/filebeat diff --git a/wazuh/config/init.bash b/wazuh/config/init.bash deleted file mode 100644 index 293b8c4a..00000000 --- a/wazuh/config/init.bash +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) - -# Initialize the custom data directory layout -source /data_dirs.env - -cd /var/ossec -for ossecdir in "${DATA_DIRS[@]}"; do - mv ${ossecdir} ${ossecdir}-template - ln -s $(realpath --relative-to=$(dirname ${ossecdir}) data)/${ossecdir} ${ossecdir} -done diff --git a/wazuh/config/postfix.runit.service b/wazuh/config/postfix.runit.service deleted file mode 100644 index 2d27102c..00000000 --- a/wazuh/config/postfix.runit.service +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) -service postfix start -tail -f /var/log/mail.log diff --git a/wazuh/config/wazuh-api.runit.service b/wazuh/config/wazuh-api.runit.service deleted file mode 100644 index 27caf5d7..00000000 --- a/wazuh/config/wazuh-api.runit.service +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) -service wazuh-api start -tail -f /var/ossec/data/logs/api.log diff --git a/wazuh/config/wazuh.runit.service b/wazuh/config/wazuh.runit.service deleted file mode 100644 index 50ea9401..00000000 --- a/wazuh/config/wazuh.runit.service +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -# Wazuh Docker Copyright (C) 2020 Wazuh Inc. (License GPLv2) -service wazuh-manager start -tail -f /var/ossec/data/logs/ossec.log