settings.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. """
  2. Django settings for desecapi project.
  3. For more information on this file, see
  4. https://docs.djangoproject.com/en/1.7/topics/settings/
  5. For the full list of settings and their values, see
  6. https://docs.djangoproject.com/en/1.7/ref/settings/
  7. """
  8. # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
  9. import os
  10. from datetime import timedelta
  11. from django.conf.global_settings import PASSWORD_HASHERS as DEFAULT_PASSWORD_HASHERS
  12. BASE_DIR = os.path.dirname(os.path.dirname(__file__))
  13. # Quick-start development settings - unsuitable for production
  14. # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
  15. # SECURITY WARNING: keep the secret key used in production secret!
  16. SECRET_KEY = os.environ['DESECSTACK_API_SECRETKEY']
  17. # SECURITY WARNING: don't run with debug turned on in production!
  18. DEBUG = False
  19. if os.environ.get('DESECSTACK_API_DEBUG', "").upper() == "TRUE":
  20. DEBUG = True
  21. ALLOWED_HOSTS = [
  22. 'api',
  23. 'desec.%s' % os.environ['DESECSTACK_DOMAIN'],
  24. 'update.dedyn.%s' % os.environ['DESECSTACK_DOMAIN'],
  25. 'update6.dedyn.%s' % os.environ['DESECSTACK_DOMAIN'],
  26. ]
  27. # Application definition
  28. INSTALLED_APPS = (
  29. 'django.contrib.auth',
  30. 'django.contrib.contenttypes',
  31. 'rest_framework',
  32. 'desecapi.apps.AppConfig',
  33. 'corsheaders',
  34. 'django_prometheus',
  35. )
  36. MIDDLEWARE = (
  37. 'django_prometheus.middleware.PrometheusBeforeMiddleware',
  38. 'corsheaders.middleware.CorsMiddleware',
  39. 'django.middleware.common.CommonMiddleware',
  40. 'django.middleware.csrf.CsrfViewMiddleware',
  41. 'django_prometheus.middleware.PrometheusAfterMiddleware',
  42. )
  43. ROOT_URLCONF = 'api.urls'
  44. WSGI_APPLICATION = 'desecapi.wsgi.application'
  45. DATABASES = {
  46. 'default': {
  47. 'ENGINE': 'django_prometheus.db.backends.postgresql',
  48. 'NAME': 'desec',
  49. 'USER': 'desec',
  50. 'PASSWORD': os.environ['DESECSTACK_DBAPI_PASSWORD_desec'],
  51. 'HOST': 'dbapi',
  52. },
  53. }
  54. CACHES = {
  55. 'default': {
  56. # TODO 'BACKEND': 'django_prometheus.cache.backends.memcached.PyLibMCCache' not supported
  57. 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
  58. 'LOCATION': 'memcached:11211',
  59. }
  60. }
  61. # This is necessary because the default is America/Chicago
  62. TIME_ZONE = 'UTC'
  63. USE_TZ = True
  64. REST_FRAMEWORK = {
  65. 'DEFAULT_RENDERER_CLASSES': (
  66. 'rest_framework.renderers.JSONRenderer',
  67. ),
  68. 'DEFAULT_PARSER_CLASSES': (
  69. 'rest_framework.parsers.JSONParser',
  70. ),
  71. 'DEFAULT_AUTHENTICATION_CLASSES': (
  72. 'desecapi.authentication.TokenAuthentication',
  73. ),
  74. 'DEFAULT_PAGINATION_CLASS': 'desecapi.pagination.LinkHeaderCursorPagination',
  75. 'PAGE_SIZE': 500,
  76. 'TEST_REQUEST_DEFAULT_FORMAT': 'json',
  77. 'EXCEPTION_HANDLER': 'desecapi.exception_handlers.exception_handler',
  78. 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning',
  79. 'ALLOWED_VERSIONS': ['v1', 'v2'],
  80. 'DEFAULT_THROTTLE_CLASSES': [
  81. 'desecapi.throttling.ScopedRatesThrottle',
  82. 'rest_framework.throttling.UserRateThrottle',
  83. ],
  84. 'DEFAULT_THROTTLE_RATES': {
  85. # ScopedRatesThrottle
  86. 'account_management_active': ['3/min'], # things with side effect, e.g. sending mail or zone creation on signup
  87. 'account_management_passive': ['10/min'], # things like GET'ing v/* or auth/* URLs, or creating/deleting tokens
  88. 'dyndns': ['1/min'], # dynDNS updates; anything above 1/min is a client misconfiguration
  89. 'dns_api_read': ['10/s', '50/min'], # DNS API requests that do not involve pdns
  90. 'dns_api_write': ['6/s', '50/min', '200/h'], # DNS API requests that do involve pdns
  91. # UserRateThrottle
  92. 'user': '1000/d', # hard limit on requests by a) an authenticated user, b) an unauthenticated IP address
  93. },
  94. 'NUM_PROXIES': 0, # Do not use X-Forwarded-For header when determining IP for throttling
  95. }
  96. PASSWORD_HASHER_TOKEN = 'desecapi.authentication.TokenHasher'
  97. PASSWORD_HASHERS = DEFAULT_PASSWORD_HASHERS + [PASSWORD_HASHER_TOKEN]
  98. # CORS
  99. # No need to add Authorization to CORS_ALLOW_HEADERS (included by default)
  100. CORS_ORIGIN_ALLOW_ALL = True
  101. TEMPLATES = [
  102. {
  103. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  104. 'DIRS': [],
  105. 'APP_DIRS': True,
  106. 'OPTIONS': {
  107. 'context_processors': [
  108. 'django.template.context_processors.debug',
  109. 'django.template.context_processors.request',
  110. 'django.contrib.auth.context_processors.auth',
  111. 'django.contrib.messages.context_processors.messages',
  112. ],
  113. },
  114. },
  115. ]
  116. # How and where to send mail
  117. EMAIL_BACKEND = 'desecapi.mail_backends.MultiLaneEmailBackend'
  118. EMAIL_HOST = os.environ['DESECSTACK_API_EMAIL_HOST']
  119. EMAIL_HOST_USER = os.environ['DESECSTACK_API_EMAIL_HOST_USER']
  120. EMAIL_HOST_PASSWORD = os.environ['DESECSTACK_API_EMAIL_HOST_PASSWORD']
  121. EMAIL_PORT = os.environ['DESECSTACK_API_EMAIL_PORT']
  122. EMAIL_USE_TLS = True
  123. DEFAULT_FROM_EMAIL = 'deSEC <support@desec.io>'
  124. ADMINS = [(address.split("@")[0], address) for address in os.environ['DESECSTACK_API_ADMIN'].split()]
  125. DESECSTACK_DOMAIN = os.environ['DESECSTACK_DOMAIN']
  126. # default NS records
  127. DEFAULT_NS = [name + '.' for name in os.environ['DESECSTACK_NS'].strip().split()]
  128. DEFAULT_NS_TTL = os.environ['DESECSTACK_NSLORD_DEFAULT_TTL']
  129. # Public Suffix settings
  130. PSL_RESOLVER = os.environ.get('DESECSTACK_API_PSL_RESOLVER')
  131. LOCAL_PUBLIC_SUFFIXES = {'dedyn.%s' % os.environ['DESECSTACK_DOMAIN']}
  132. # PowerDNS-related
  133. NSLORD_PDNS_API = 'http://nslord:8081/api/v1/servers/localhost'
  134. NSLORD_PDNS_API_TOKEN = os.environ['DESECSTACK_NSLORD_APIKEY']
  135. NSMASTER_PDNS_API = 'http://nsmaster:8081/api/v1/servers/localhost'
  136. NSMASTER_PDNS_API_TOKEN = os.environ['DESECSTACK_NSMASTER_APIKEY']
  137. CATALOG_ZONE = 'catalog.internal'
  138. # Celery
  139. CELERY_BROKER_URL = 'amqp://rabbitmq'
  140. CELERY_EMAIL_MESSAGE_EXTRA_ATTRIBUTES = [] # required because djcelery_email.utils accesses it
  141. CELERY_TASK_TIME_LIMIT = 30
  142. TASK_CONFIG = { # The first entry is the default queue
  143. 'email_slow_lane': {'rate_limit': '3/m'},
  144. 'email_fast_lane': {'rate_limit': '1/s'},
  145. 'email_immediate_lane': {'rate_limit': None},
  146. }
  147. # pdns accepts request payloads of this size.
  148. # This will hopefully soon be configurable: https://github.com/PowerDNS/pdns/pull/7550
  149. PDNS_MAX_BODY_SIZE = 16 * 1024 * 1024
  150. # SEPA direct debit settings
  151. SEPA = {
  152. 'CREDITOR_ID': os.environ['DESECSTACK_API_SEPA_CREDITOR_ID'],
  153. 'CREDITOR_NAME': os.environ['DESECSTACK_API_SEPA_CREDITOR_NAME'],
  154. }
  155. # user management
  156. AUTH_PASSWORD_VALIDATORS = [
  157. {
  158. 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
  159. 'OPTIONS': {'min_length': 8}
  160. },
  161. ]
  162. MINIMUM_TTL_DEFAULT = int(os.environ['DESECSTACK_MINIMUM_TTL_DEFAULT'])
  163. AUTH_USER_MODEL = 'desecapi.User'
  164. LIMIT_USER_DOMAIN_COUNT_DEFAULT = 5
  165. USER_ACTIVATION_REQUIRED = True
  166. VALIDITY_PERIOD_VERIFICATION_SIGNATURE = timedelta(hours=int(os.environ.get('DESECSTACK_API_AUTHACTION_VALIDITY', '0')))
  167. # CAPTCHA
  168. CAPTCHA_VALIDITY_PERIOD = timedelta(hours=24)
  169. # Watchdog
  170. WATCHDOG_SLAVES = os.environ.get('DESECSTACK_WATCHDOG_SLAVES', '').split()
  171. WATCHDOG_WINDOW_SEC = 600
  172. # Prometheus (see https://github.com/korfuri/django-prometheus/blob/master/documentation/exports.md)
  173. # TODO Switch to PROMETHEUS_METRICS_EXPORT_PORT_RANGE instead of this workaround, which currently necessary to due
  174. # https://github.com/korfuri/django-prometheus/issues/215
  175. try:
  176. import uwsgi
  177. except ImportError:
  178. pass # not running in uwsgi, e.g. management command
  179. else:
  180. import prometheus_client
  181. prometheus_client.values.ValueClass = prometheus_client.values.MultiProcessValue(
  182. process_identifier=uwsgi.worker_id)
  183. if DEBUG and not EMAIL_HOST:
  184. EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
  185. if os.environ.get('DESECSTACK_E2E_TEST', "").upper() == "TRUE":
  186. DEBUG = True
  187. LIMIT_USER_DOMAIN_COUNT_DEFAULT = 5000
  188. USER_ACTIVATION_REQUIRED = False
  189. EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
  190. REST_FRAMEWORK['DEFAULT_THROTTLE_CLASSES'] = []