Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix/security monkey v0.7.0 #50

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions security_monkey/0.7.0/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
boto.cfg
docker-compose.yml
secmonkey.env
*.example
security_monkey-nginx
2 changes: 2 additions & 0 deletions security_monkey/0.7.0/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
boto.cfg
secmonkey.env
39 changes: 39 additions & 0 deletions security_monkey/0.7.0/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2014 Netflix, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

FROM ubuntu:14.04
MAINTAINER Netflix Open Source Development <[email protected]>

ENV SECURITY_MONKEY_VERSION=v0.7.0 \
SECURITY_MONKEY_SETTINGS=/usr/local/src/security_monkey/env-config/config-deploy.py

RUN apt-get update &&\
apt-get -y -q install python-software-properties software-properties-common postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3 curl &&\
apt-get install -y python-pip python-dev python-psycopg2 libffi-dev libpq-dev libyaml-dev libxml2-dev libxmlsec1-dev git sudo swig python-m2crypto &&\
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR 188 ( Netflix/security_monkey#188 ) should have removed the requirement for m2crypto.

apt-get clean autoclean autoremove && rm -rf /var/lib/apt/lists/*

RUN cd /usr/local/src &&\
git clone --branch $SECURITY_MONKEY_VERSION https://github.com/Netflix/security_monkey.git

WORKDIR /usr/local/src/security_monkey
RUN python setup.py install &&\
/bin/mkdir -pv /var/log/security_monkey &&\
touch /var/log/security_monkey/security_monkey-deploy.log /var/log/security_monkey/securitymonkey.log

COPY config-deploy.py /usr/local/src/security_monkey/env-config/
ADD api-start.sh api-init.sh scheduler-start.sh /usr/local/src/security_monkey/scripts/

EXPOSE 5000

ENTRYPOINT ["/usr/local/src/security_monkey/scripts/api-start.sh"]
15 changes: 15 additions & 0 deletions security_monkey/0.7.0/api-init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

sudo -u ${SECURITY_MONKEY_POSTGRES_USER:-postgres} psql\
-h ${SECURITY_MONKEY_POSTGRES_HOST:-postgres} -p ${SECURITY_MONKEY_POSTGRES_PORT:-5432}\
--command "ALTER USER ${SECURITY_MONKEY_POSTGRES_USER:-postgres} with PASSWORD '${SECURITY_MONKEY_POSTGRES_PASSWORD:-securitymonkeypassword}';"

sudo -u ${SECURITY_MONKEY_POSTGRES_USER:-postgres} createdb\
-h ${SECURITY_MONKEY_POSTGRES_HOST:-postgres} -p ${SECURITY_MONKEY_POSTGRES_PORT:-5432}\
-O ${SECURITY_MONKEY_POSTGRES_USER:-postgres} ${SECURITY_MONKEY_POSTGRES_DATABASE:-secmonkey}

mkdir -p /var/log/security_monkey/
touch "/var/log/security_monkey/security_monkey-deploy.log"

cd /usr/local/src/security_monkey/
exec python manage.py db upgrade
4 changes: 4 additions & 0 deletions security_monkey/0.7.0/api-start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

cd /usr/local/src/security_monkey/
exec python manage.py run_api_server -b 0.0.0.0:${SECURITY_MONKEY_API_PORT:-5000}
4 changes: 4 additions & 0 deletions security_monkey/0.7.0/boto.cfg.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[Credentials]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY

305 changes: 305 additions & 0 deletions security_monkey/0.7.0/config-deploy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
# Copyright 2014 Netflix, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Insert any config items here.
# This will be fed into Flask/SQLAlchemy inside security_monkey/__init__.py

import os

# Setting default settings
sm_config = {
'fqdn': 'ec2-XX-XXX-XXX-XXX.compute-1.amazonaws.com',
'postgres': {
'database': 'secmonkey',
'host': 'localhost',
'password': 'securitymonkeypassword',
'port': '5432',
'user': 'postgres'
},
'api': {
'port': 5000
},
'email': {
'security-team-email': [],
'smtp': False,
'ses-region': 'us-east-1',
'default-sender': '[email protected]',
'server': 'smtp.example.com',
'username': 'username',
'password': 'password'
}
}

if 'SECURITY_MONKEY_POSTGRES_HOST' in os.environ:
sm_config['postgres']['host'] = os.environ.get('SECURITY_MONKEY_POSTGRES_HOST')

if 'SECURITY_MONKEY_POSTGRES_USER' in os.environ:
sm_config['postgres']['user'] = os.environ.get('SECURITY_MONKEY_POSTGRES_USER')

if 'SECURITY_MONKEY_POSTGRES_PASSWORD' in os.environ:
sm_config['postgres']['password'] = os.environ.get('SECURITY_MONKEY_POSTGRES_PASSWORD')

if 'SECURITY_MONKEY_POSTGRES_DATABASE' in os.environ:
sm_config['postgres']['database'] = os.environ.get('SECURITY_MONKEY_POSTGRES_DATABASE')

if 'SECURITY_MONKEY_POSTGRES_PORT' in os.environ:
sm_config['postgres']['port'] = os.environ.get('SECURITY_MONKEY_POSTGRES_PORT')

if 'SECURITY_MONKEY_API_PORT' in os.environ:
sm_config['api']['port'] = os.environ.get('SECURITY_MONKEY_API_PORT')

if 'SECURITY_MONKEY_FQDN' in os.environ:
sm_config['fqdn'] = os.environ.get('SECURITY_MONKEY_FQDN')

if 'SECURITY_MONKEY_SECURITY_TEAM_EMAIL' in os.environ:
sm_config['email']['security-team-email'] = os.environ.get('SECURITY_MONKEY_SECURITY_TEAM_EMAIL')

if 'SECURITY_MONKEY_SMTP' in os.environ:
# Must change String from environment variable into Boolean
if os.environ.get('SECURITY_MONKEY_SMTP') == 'True':
sm_config['email']['smtp'] = True

if 'SECURITY_MONKEY_SES_REGION' in os.environ:
sm_config['email']['ses-region'] = os.environ.get('SECURITY_MONKEY_SES_REGION')

if 'SECURITY_MONKEY_EMAIL_DEFAULT_SENDER' in os.environ:
sm_config['email']['default-sender'] = os.environ.get('SECURITY_MONKEY_EMAIL_DEFAULT_SENDER')

if 'SECURITY_MONKEY_EMAIL_SERVER' in os.environ:
sm_config['email']['server'] = os.environ.get('SECURITY_MONKEY_EMAIL_SERVER')

if 'SECURITY_MONKEY_EMAIL_USERNAME' in os.environ:
sm_config['email']['username'] = os.environ.get('SECURITY_MONKEY_EMAIL_USERNAME')

if 'SECURITY_MONKEY_EMAIL_PASSWORD' in os.environ:
sm_config['email']['password'] = os.environ.get('SECURITY_MONKEY_EMAIL_PASSWORD')

LOG_CFG = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '%(asctime)s %(levelname)s: %(message)s '
'[in %(pathname)s:%(lineno)d]'
}
},
'handlers': {
'file': {
'class': 'logging.handlers.RotatingFileHandler',
'level': 'DEBUG',
'formatter': 'standard',
'filename': '/var/log/security_monkey/securitymonkey.log',
'maxBytes': 10485760,
'backupCount': 100,
'encoding': 'utf8'
},
'console': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'standard',
'stream': 'ext://sys.stdout'
}
},
'loggers': {
'security_monkey': {
'handlers': ['file', 'console'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably don't want to use file in docker.

Logging should go to stdout, iirc.

'level': 'DEBUG'
},
'apscheduler': {
'handlers': ['file', 'console'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably don't want to use file in docker.

Logging should go to stdout, iirc.

'level': 'INFO'
}
}
}

SQLALCHEMY_DATABASE_URI = 'postgresql://%s:%s@%s:%s/%s' % (
sm_config['postgres']['user'],
sm_config['postgres']['password'],
sm_config['postgres']['host'],
sm_config['postgres']['port'],
sm_config['postgres']['database']
)

# print sm_config['postgres']
# print SQLALCHEMY_DATABASE_URI

SQLALCHEMY_POOL_SIZE = 50
SQLALCHEMY_MAX_OVERFLOW = 15
ENVIRONMENT = 'ec2'
USE_ROUTE53 = False
FQDN = sm_config['fqdn']
API_PORT = sm_config['api']['port']
WEB_PORT = '443'
WEB_PATH = '/static/ui.html'
FRONTED_BY_NGINX = True
NGINX_PORT = '443'
BASE_URL = 'https://{}/'.format(FQDN)

SECRET_KEY = '<INSERT_RANDOM_STRING_HERE>'

MAIL_DEFAULT_SENDER = sm_config['email']['default-sender']
SECURITY_REGISTERABLE = True
SECURITY_CONFIRMABLE = False
SECURITY_RECOVERABLE = False
SECURITY_PASSWORD_HASH = 'bcrypt'
SECURITY_PASSWORD_SALT = '<INSERT_RANDOM_STRING_HERE>'
SECURITY_TRACKABLE = True

SECURITY_POST_LOGIN_VIEW = BASE_URL
SECURITY_POST_REGISTER_VIEW = BASE_URL
SECURITY_POST_CONFIRM_VIEW = BASE_URL
SECURITY_POST_RESET_VIEW = BASE_URL
SECURITY_POST_CHANGE_VIEW = BASE_URL

# This address gets all change notifications (i.e. '[email protected]')
SECURITY_TEAM_EMAIL = sm_config['email']['security-team-email']

# These are only required if using SMTP instead of SES
EMAILS_USE_SMTP = sm_config['email']['smtp'] # Otherwise, Use SES
SES_REGION = sm_config['email']['ses-region']
MAIL_SERVER = sm_config['email']['server']
MAIL_PORT = 465
MAIL_USE_SSL = True
MAIL_USERNAME = sm_config['email']['username']
MAIL_PASSWORD = sm_config['email']['password']

WTF_CSRF_ENABLED = True
WTF_CSRF_SSL_STRICT = True # Checks Referer Header. Set to False for API access.
WTF_CSRF_METHODS = ['DELETE', 'POST', 'PUT', 'PATCH']

# "NONE", "SUMMARY", or "FULL"
SECURITYGROUP_INSTANCE_DETAIL = 'FULL'

# Threads used by the scheduler.
# You will likely need at least one core thread for every account being monitored.
CORE_THREADS = 25
MAX_THREADS = 30

# SSO SETTINGS:
ACTIVE_PROVIDERS = [] # "ping", "google" or "onelogin"

PING_NAME = '' # Use to override the Ping name in the UI.
PING_REDIRECT_URI = "{BASE}api/1/auth/ping".format(BASE=BASE_URL)
PING_CLIENT_ID = '' # Provided by your administrator
PING_AUTH_ENDPOINT = '' # Often something ending in authorization.oauth2
PING_ACCESS_TOKEN_URL = '' # Often something ending in token.oauth2
PING_USER_API_URL = '' # Often something ending in idp/userinfo.openid
PING_JWKS_URL = '' # Often something ending in JWKS
PING_SECRET = '' # Provided by your administrator

GOOGLE_CLIENT_ID = ''
GOOGLE_AUTH_ENDPOINT = ''
GOOGLE_SECRET = ''

ONELOGIN_APP_ID = '<APP_ID>' # OneLogin App ID provider by your administrator
ONELOGIN_EMAIL_FIELD = 'User.email' # SAML attribute used to provide email address
ONELOGIN_DEFAULT_ROLE = 'View' # Default RBAC when user doesn't already exist
ONELOGIN_HTTPS = True # If using HTTPS strict mode will check the requests are HTTPS
ONELOGIN_SETTINGS = {
# If strict is True, then the Python Toolkit will reject unsigned
# or unencrypted messages if it expects them to be signed or encrypted.
# Also it will reject the messages if the SAML standard is not strictly
# followed. Destination, NameId, Conditions ... are validated too.
"strict": True,

# Enable debug mode (outputs errors).
"debug": True,

# Service Provider Data that we are deploying.
"sp": {
# Identifier of the SP entity (must be a URI)
"entityId": "{BASE}metadata/".format(BASE=BASE_URL),
# Specifies info about where and how the <AuthnResponse> message MUST be
# returned to the requester, in this case our SP.
"assertionConsumerService": {
# URL Location where the <Response> from the IdP will be returned
"url": "{BASE}api/1/auth/onelogin?acs".format(BASE=BASE_URL),
# SAML protocol binding to be used when returning the <Response>
# message. OneLogin Toolkit supports this endpoint for the
# HTTP-POST binding only.
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
},
# If you need to specify requested attributes, set a
# attributeConsumingService. nameFormat, attributeValue and
# friendlyName can be omitted
#"attributeConsumingService": {
# "ServiceName": "SP test",
# "serviceDescription": "Test Service",
# "requestedAttributes": [
# {
# "name": "",
# "isRequired": False,
# "nameFormat": "",
# "friendlyName": "",
# "attributeValue": ""
# }
# ]
#},
# Specifies info about where and how the <Logout Response> message MUST be
# returned to the requester, in this case our SP.
"singleLogoutService": {
# URL Location where the <Response> from the IdP will be returned
"url": "{BASE}api/1/auth/onelogin?sls".format(BASE=BASE_URL),
# SAML protocol binding to be used when returning the <Response>
# message. OneLogin Toolkit supports the HTTP-Redirect binding
# only for this endpoint.
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
},
# Specifies the constraints on the name identifier to be used to
# represent the requested subject.
# Take a look on src/onelogin/saml2/constants.py to see the NameIdFormat that are supported.
"NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
# Usually x509cert and privateKey of the SP are provided by files placed at
# the certs folder. But we can also provide them with the following parameters
"x509cert": "",
"privateKey": ""
},

# Identity Provider Data that we want connected with our SP.
"idp": {
# Identifier of the IdP entity (must be a URI)
"entityId": "https://app.onelogin.com/saml/metadata/{APP_ID}".format(APP_ID=ONELOGIN_APP_ID),
# SSO endpoint info of the IdP. (Authentication Request protocol)
"singleSignOnService": {
# URL Target of the IdP where the Authentication Request Message
# will be sent.
"url": "https://app.onelogin.com/trust/saml2/http-post/sso/{APP_ID}".format(APP_ID=ONELOGIN_APP_ID),
# SAML protocol binding to be used when returning the <Response>
# message. OneLogin Toolkit supports the HTTP-Redirect binding
# only for this endpoint.
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
},
# SLO endpoint info of the IdP.
"singleLogoutService": {
# URL Location of the IdP where SLO Request will be sent.
"url": "https://app.onelogin.com/trust/saml2/http-redirect/slo/{APP_ID}".format(APP_ID=ONELOGIN_APP_ID),
# SAML protocol binding to be used when returning the <Response>
# message. OneLogin Toolkit supports the HTTP-Redirect binding
# only for this endpoint.
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
},
# Public x509 certificate of the IdP
"x509cert": "<ONELOGIN_APP_CERT>"
}
}

from datetime import timedelta
PERMANENT_SESSION_LIFETIME=timedelta(minutes=60)
SESSION_REFRESH_EACH_REQUEST=True
SESSION_COOKIE_SECURE=True
SESSION_COOKIE_HTTPONLY=True
PREFERRED_URL_SCHEME='https'

REMEMBER_COOKIE_DURATION=timedelta(minutes=60) # Can make longer if you want remember_me to be useful.
REMEMBER_COOKIE_SECURE=True
REMEMBER_COOKIE_HTTPONLY=True
Loading