old_console/console/settings/base.py
2024-11-02 14:12:45 +03:00

473 lines
15 KiB
Python

""" Django settings for console project. """
import os
import sys
from celery.schedules import crontab
from django.utils.translation import gettext_lazy
from console.services.product import load_product_version
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
DEBUG = int(os.environ.get('DEBUG', '0')) > 0
# Program is started under testing framework
TEST_MODE = 'test' in sys.argv or 'pytest' in sys.modules or os.environ.get("TEST_MODE")
# Program is used by developer (human), i.e. loads additional debug software
DEV_MODE = DEBUG and not TEST_MODE
# False to disable access to admin control panel via web
ADMIN_PANEL_ENABLED = DEV_MODE
##################################
### SECURITY ###
##################################
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_CREDENTIALS = True
CORS_EXPOSE_HEADERS = ['Content-Disposition']
ALLOWED_HOSTS = ['*']
######################################
### APPLICATIONS ###
######################################
INSTALLED_APPS = [
'django.forms',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'django_json_widget',
'solo',
'django_celery_beat',
'sequences.apps.SequencesConfig',
'corsheaders',
'django_filters',
'channels',
]
PROJECT_APPS = [
'assets.apps.AssetsConfig',
'license_info.apps.LicenseInfoConfig',
'perms.apps.PermsConfig',
'console.apps.ConsoleConfig',
'core.apps.CoreConfig',
'correlation.apps.CorrelationConfig',
'dashboard.apps.DashboardConfig',
'company.apps.CompanyConfig',
'ncircc.apps.NcirccConfig',
'logstash.apps.LogstashConfig',
'networkmap.apps.NetworkmapConfig',
'users.apps.UsersConfig',
'incident_export.apps.IncidentExportConfig',
'storage.apps.StorageConfig',
'incident.apps.IncidentConfig',
'events.apps.EventsConfig',
'rotation.apps.RotationConfig',
'inputs.apps.InputsConfig',
'devices.apps.DevicesConfig',
'notifications.apps.NotificationsConfig',
]
INSTALLED_APPS += PROJECT_APPS
MIDDLEWARE = [
'core.middleware.LicenseMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'core.middleware.TimezoneMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
########################################
### AUTHENTICATION ###
########################################
AUTHENTICATION_BACKENDS = [
'core.backends.ConsoleAuthBackend.ConsoleAuthSystem',
'django.contrib.auth.backends.ModelBackend',
]
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 8,
}
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
##################################
### DATABASE ###
##################################
if not os.environ['POSTGRES_PORT']:
os.environ['POSTGRES_PORT'] = '5432'
DATABASES = {
'default': {
'ENGINE': "django.db.backends.postgresql", # Project depends on postgre, so no way to change it from env
'NAME': os.environ.get('POSTGRES_DB'),
'USER': os.environ.get('POSTGRES_USER'),
'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
'HOST': os.environ.get('POSTGRES_HOST'),
'PORT': os.environ.get('POSTGRES_PORT'),
}
}
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
#################################
### LOGGING ###
#################################
LOG_PATH = os.environ.get('LOG_PATH', os.path.join(BASE_DIR, 'dockerlogs'))
USER_LOG_FILENAME = os.environ.get('USER_LOG_FILENAME', 'console.log')
MIN_LOG_LEVEL = os.environ.get('MIN_LOG_LEVEL', 'DEBUG')
LOG_MAX_BYTES = int(os.environ.get('LOG_MAX_BYTES', 1024 * 1024 * 5))
LOG_BACKUP_COUNT = int(os.environ.get('LOG_BACKUP_COUNT', 500))
os.makedirs(LOG_PATH, exist_ok=True)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'info_message': {
'format': '%(asctime)s %(levelname)s %(message)s',
},
'debug_format': {
'format': '%(asctime)s %(levelname)s %(filename)s %(funcName)s %(message)s'
}
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': MIN_LOG_LEVEL,
},
'file': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(LOG_PATH, USER_LOG_FILENAME),
'formatter': 'info_message',
'encoding': 'utf-8',
'maxBytes': LOG_MAX_BYTES,
'backupCount': LOG_BACKUP_COUNT,
},
},
'loggers': {
'': {
'handlers': ['file', 'console'],
'level': MIN_LOG_LEVEL,
},
},
}
##############################################
### INTERNATIONALIZATION ###
##############################################
LANGUAGE_CODE = 'en'
LANGUAGES = [
('en', gettext_lazy('English')),
('ru', gettext_lazy('Russian')),
]
INITIAL_DATE_FORMAT = "Y-m-d"
# @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TIME_ZONE = os.environ.get('TIME_ZONE', 'UTC')
# Timezone used for users by default
DEFAULT_CURRENT_TIMEZONE = os.environ.get('DEFAULT_CURRENT_TIMEZONE', 'Europe/Moscow')
USE_I18N = True
USE_L10N = True
USE_TZ = True
LOCALE_PATHS = [
os.path.join(BASE_DIR, 'locale')
]
###############################
### FILES ###
###############################
# Build paths for generated files like static inside the project like this: os.path.join(PUBLIC_DIR, ...)
PUBLIC_DIR = os.environ.get('PUBLIC_DIR', os.path.join(BASE_DIR, 'public'))
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(PUBLIC_DIR, 'static')
MEDIA_ROOT = os.path.join(PUBLIC_DIR, 'media')
REDIS_HOST = os.environ.get('REDIS_HOST', 'redis')
REDIS_PORT = int(os.environ.get('REDIS_PORT', 6379))
REDIS_CACHE_TIMEOUT = 86400
###############################
### CACHE ###
###############################
SOLO_CACHE = 'local'
SOLO_CACHE_TIMEOUT = 60 * 5 # 5 mins
SOLO_CACHE_PREFIX = 'solo'
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
'local': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
'redis': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': f'redis://{REDIS_HOST}:{REDIS_PORT}/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient'
}
}
}
#############################
### DRF ###
#############################
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
'rest_framework.filters.OrderingFilter',
'core.backends.filters.SearchAllFieldsBackend',
),
'DEFAULT_PAGINATION_CLASS': 'core.services.pagination.BasicPagination',
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
}
################################
### CELERY ###
################################
CELERY_BROKER_URL = f'redis://{REDIS_HOST}:{REDIS_PORT}'
CELERY_RESULT_BACKEND = f'redis://{REDIS_HOST}:{REDIS_PORT}'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = TIME_ZONE
CELERY_IMPORTS = ['devices.tasks.firewall', 'devices.tasks.sensor']
""" Single place to setup at which time daily tasks should execute, crontab schedule object"""
DAILY_CRONTAB = crontab(minute='0', hour='1')
""" Single place to setup at which time weekly tasks should execute, crontab schedule object"""
WEEKLY_CRONTAB = crontab(minute='0', hour='1', day_of_week='1')
""" Single place to setup at which time monthly tasks should execute, crontab schedule object"""
MONTHLY_CRONTAB = crontab(minute='0', hour='1', day_of_month='1')
""" Execute every 2 minutes."""
EVERY_2_MINUTE = crontab(minute='*/2')
ROTATE_SIZE_CHECK_CRONTAB = crontab(minute='*/5')
CELERY_BEAT_SCHEDULE = {
'update_statistics': {
'task': 'dashboard.tasks.update_statistics_task',
'schedule': crontab()
},
'expire_users': {
'task': 'console.tasks.expire_users_task',
'schedule': DAILY_CRONTAB
},
'update_auto_network_map_data': {
'task': 'networkmap.tasks.update_auto_network_map_data',
'schedule': crontab()
},
'update_firewall_info_task': {
'task': 'devices.tasks.firewall.update_firewall_info_task',
'schedule': crontab()
},
'update_amount_of_elk_events': {
'task': 'console.tasks.update_amount_of_aggregated_events',
'schedule': crontab()
},
'check_blocked_users': {
'task': 'core.tasks.check_blocked_users',
'schedule': crontab()
},
'update_status_notification': {
'task': 'ncircc.tasks.update_status_notification',
'schedule': crontab(), # todo Уточнить точное время
},
'update_comments': {
'task': 'ncircc.tasks.update_comments',
'schedule': crontab(), # todo Уточнить точное время
},
'ping_sensors': {
'task': 'devices.tasks.sensor.ping_sensors',
'schedule': crontab()
},
'get_disk_usage_task': {
'task': 'core.tasks.get_disk_usage_task',
'schedule': crontab()
},
'reboot_correlator_task': {
'task': 'correlation.tasks.reboot_correlator_task',
'schedule': EVERY_2_MINUTE,
},
}
######################################
### AMC SERVICES ###
######################################
# LICENSE
LICENSE_CLIENT_URL = os.environ.get('LICENSE_CLIENT_URL', 'http://license-client:8050')
LICENSE_CACHE_TIMEOUT = 60 * 60 # 60 minutes
LICENSE_FEATURE_EVENT_PROCESSING = "event_processing"
LICENSE_OPTION_EVENT_SOURCE_COUNT = "event_sources"
# NGINX
NGINX_ENABLED_CONFIG_FILENAME = "armaconsole.nginx"
NGINX_HTTP_CONFIG_FILENAME = "armaconsole_http.nginx"
NGINX_HTTPS_CONFIG_FILENAME = "armaconsole_https.nginx"
NGINX_SITES_AVAILABLE = "/usr/local/armaconsole/nginx"
# CORRELATOR
CORRELATOR_SEVERITY_LEVEL = int(os.environ.get('CORRELATOR_SEVERITY_LEVEL', 6))
CORRELATOR_AUTO_CATEGORY_NAME = os.environ.get('CORRELATOR_AUTO_CATEGORY_NAME', gettext_lazy('Auto'))
CORRELATOR_URL = os.environ.get('CORRELATOR_URL', 'http://correlator:5566')
# VECTOR
LOGSTASH_CONFIG_DIR = os.environ.get('LOGSTASH_CONFIG_DIR', os.path.join(PUBLIC_DIR, 'vector'))
# ELASTICSEARCH
ELASTIC_URL = os.environ.get('ELASTIC_URL', 'http://elasticsearch:9200')
elk_split = ELASTIC_URL.replace('http://', '').split(':')
ELK_HOST = elk_split[0] if len(elk_split) >= 0 else 'elasticsearch'
ELK_PORT = elk_split[1] if len(elk_split) > 0 else 9200
ELK_LOGIN = os.environ.get('ELASTIC_USER', 'elastic')
ELK_PASS = os.environ.get('ELASTIC_PASSWORD', 'changeme')
ELK_MAX_ENTRIES = 100000
ELK_AGGREGATED_INDEX = 'aggregated-*'
ELK_FIREWALL_PRODUCT_NAME = 'Industrial Firerwall' # Yes this is mistake, but it is how now Vector parses IF logs
ELK_ENDPOINT_PRODUCT_NAME = 'Industrial Endpoint'
# RABBITMQ
RABBIT_URL = os.environ.get('RABBIT_URL', 'http://rabbitmq-management:5672')
rabbit_split = RABBIT_URL.replace('http://', '').split(':')
RABBIT_HOST = rabbit_split[0] if len(rabbit_split) >= 0 else 'rabbitmq-management'
RABBIT_PORT = rabbit_split[1] if len(rabbit_split) > 0 else 5672
###############################
### OTHER ###
###############################
# ROUTING
ROOT_URLCONF = 'console.urls'
WSGI_APPLICATION = 'console.wsgi.application'
ASGI_APPLICATION = 'console.asgi.application'
LOGIN_REDIRECT_URL = 'index'
LOGOUT_REDIRECT_URL = 'login'
LOGIN_URL = 'login'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [(REDIS_HOST, REDIS_PORT)],
},
},
}
# TEMPLATES
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# Site info must not contain dynamic data, only static values
SITE_INFO = {
'domain': 'infowatch.ru',
'name': 'InfoWatch ARMA',
'package': 'armaconsole', # Must be a valid deb package name
'version': '1.4.0', # Must be a valid deb package version
'architecture': 'amd64', # Must be a valid deb package architecture
# These values are used in CEF format
'vendor': 'InfoWatch ARMA',
'product': 'ARMAMC'
}
# How many (in percent) keep in table while rotation occurs
# So 0.3 - means 30% of table will stay while rotation
SAVE_DURING_ROTATION = float(os.environ.get('SAVE_DURING_ROTATION', 0.3))
EMAIL_HOST_USER = 'console@arma.com'
EMAIL_HOST = 'localhost'
# GENERATE SELFSIGNED CERTIFICATE
TLS_CERT_DAYS = 365
TLS_CERT_KEY_SIZE = 2048
TLS_CERT_COUNTRY = "RU"
TLS_CERT_STATE = "Moscow"
TLS_CERT_LOCALITY = "Moscow"
TLS_CERT_ORIG_NAME = "ARMA"
TLS_CERT_UNIT_NAME = "Console"
TLS_CERT_COMMON_NAME = "iwarma.ru"
TLS_CERT_FILENAME = "/etc/nginx/ssl/armaconsole/nginx-selfsigned.crt"
TLS_CERT_KEY_FILENAME = "/etc/nginx/ssl/armaconsole/nginx-selfsigned.key"
# TODO: need use
TLS_CERT_DHPARAM_FILENAME = "/etc/nginx/ssl/armaconsole/dhparam.pem"
WEB_UI_PORT = int(os.environ.get('WEB_UI_PORT', 9090))
MAX_UPLOADSIZE = 80 * 1024 * 1024
# NCIRCC
NCIRCC_DOMAIN_NAME = os.environ.get('NCIRCC_DOMAIN_NAME', 'https://test-lk.cert.gov.ru')
NCIRCC_CERT_VERIFY = '/etc/ssl/certs/' if os.path.exists('/etc/ssl/certs/') else False
# Compatible ARMAIF versions
MINIMAL_COMPATIBLE_AIF_VERSION = "3.6"
MINIMAL_VERSION_CORRELATION_RULES = '1.3.4'
# Product version
PRODUCT_VERSION = load_product_version()