Merge branch 'master' into powerdnsplugin_01

This commit is contained in:
csine-nflx 2020-01-31 16:37:57 -08:00 committed by GitHub
commit fecb5b6252
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 129 additions and 24 deletions

View File

@ -3,7 +3,7 @@ RUN apt-get update
RUN apt-get install -y make software-properties-common curl RUN apt-get install -y make software-properties-common curl
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - RUN curl -sL https://deb.nodesource.com/setup_7.x | bash -
RUN apt-get update RUN apt-get update
RUN apt-get install -y nodejs libldap2-dev libsasl2-dev libldap2-dev libssl-dev RUN apt-get install -y npm libldap2-dev libsasl2-dev libldap2-dev libssl-dev
RUN pip install -U setuptools RUN pip install -U setuptools
RUN pip install coveralls bandit RUN pip install coveralls bandit
WORKDIR /app WORKDIR /app

3
docker/.dockerignore Normal file
View File

@ -0,0 +1,3 @@
*-env
docker-compose.yml
Dockerfile

View File

@ -8,12 +8,6 @@ ENV gid 1337
ENV user lemur ENV user lemur
ENV group lemur ENV group lemur
COPY entrypoint /
COPY src/lemur.conf.py /home/lemur/.lemur/lemur.conf.py
COPY supervisor.conf /
COPY nginx/default.conf /etc/nginx/conf.d/
COPY nginx/default-ssl.conf /etc/nginx/conf.d/
RUN addgroup -S ${group} -g ${gid} && \ RUN addgroup -S ${group} -g ${gid} && \
adduser -D -S ${user} -G ${group} -u ${uid} && \ adduser -D -S ${user} -G ${group} -u ${uid} && \
apk --update add python3 libldap postgresql-client nginx supervisor curl tzdata openssl bash && \ apk --update add python3 libldap postgresql-client nginx supervisor curl tzdata openssl bash && \
@ -40,7 +34,6 @@ RUN addgroup -S ${group} -g ${gid} && \
curl -sSL https://github.com/Netflix/lemur/archive/$VERSION.tar.gz | tar xz -C /opt/lemur --strip-components=1 && \ curl -sSL https://github.com/Netflix/lemur/archive/$VERSION.tar.gz | tar xz -C /opt/lemur --strip-components=1 && \
pip3 install --upgrade pip && \ pip3 install --upgrade pip && \
pip3 install --upgrade setuptools && \ pip3 install --upgrade setuptools && \
chmod +x /entrypoint && \
mkdir -p /run/nginx/ /etc/nginx/ssl/ && \ mkdir -p /run/nginx/ /etc/nginx/ssl/ && \
chown -R $user:$group /opt/lemur/ /home/lemur/.lemur/ chown -R $user:$group /opt/lemur/ /home/lemur/.lemur/
@ -52,6 +45,13 @@ RUN npm install --unsafe-perm && \
node_modules/.bin/gulp package --urlContextPath=$(urlContextPath) && \ node_modules/.bin/gulp package --urlContextPath=$(urlContextPath) && \
apk del build-dependencies apk del build-dependencies
COPY entrypoint /
COPY src/lemur.conf.py /home/lemur/.lemur/lemur.conf.py
COPY supervisor.conf /
COPY nginx/default.conf /etc/nginx/conf.d/
COPY nginx/default-ssl.conf /etc/nginx/conf.d/
RUN chmod +x /entrypoint
WORKDIR / WORKDIR /
HEALTHCHECK --interval=12s --timeout=12s --start-period=30s \ HEALTHCHECK --interval=12s --timeout=12s --start-period=30s \

29
docker/docker-compose.yml Normal file
View File

@ -0,0 +1,29 @@
version: '3'
services:
postgres:
image: "postgres:10"
restart: always
volumes:
- pg_data:/var/lib/postgresql/data
env_file:
- pgsql-env
lemur:
# image: "netlix-lemur:latest"
build: .
depends_on:
- postgres
- redis
env_file:
- lemur-env
- pgsql-env
ports:
- 80:80
- 443:443
redis:
image: "redis:alpine"
volumes:
pg_data: {}

View File

@ -1,4 +1,6 @@
#!/bin/sh #!/bin/bash
set -eo pipefail
if [ -z "${POSTGRES_USER}" ] || [ -z "${POSTGRES_PASSWORD}" ] || [ -z "${POSTGRES_HOST}" ] || [ -z "${POSTGRES_DB}" ];then if [ -z "${POSTGRES_USER}" ] || [ -z "${POSTGRES_PASSWORD}" ] || [ -z "${POSTGRES_HOST}" ] || [ -z "${POSTGRES_DB}" ];then
echo "Database vars not set" echo "Database vars not set"
@ -7,22 +9,23 @@ fi
export POSTGRES_PORT="${POSTGRES_PORT:-5432}" export POSTGRES_PORT="${POSTGRES_PORT:-5432}"
echo 'export SQLALCHEMY_DATABASE_URI="postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB"' >> /etc/profile export LEMUR_ADMIN_PASSWORD="${LEMUR_ADMIN_PASSWORD:-admin}"
export SQLALCHEMY_DATABASE_URI="postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB"
source /etc/profile
PGPASSWORD=$POSTGRES_PASSWORD psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB --command 'select 1;' PGPASSWORD=$POSTGRES_PASSWORD psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB --command 'select 1;'
echo " # Create Postgres trgm extension" echo " # Create Postgres trgm extension"
PGPASSWORD=$POSTGRES_PASSWORD psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB --command 'CREATE EXTENSION pg_trgm;' PGPASSWORD=$POSTGRES_PASSWORD psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB --command 'CREATE EXTENSION IF NOT EXISTS pg_trgm;'
echo " # Done" echo " # Done"
if [ -z "${SKIP_SSL}" ]; then if [ -z "${SKIP_SSL}" ]; then
if [ ! -f /etc/nginx/ssl/server.crt ] && [ ! -f /etc/nginx/ssl/server.key ]; then if [ ! -f /etc/nginx/ssl/server.crt ] && [ ! -f /etc/nginx/ssl/server.key ]; then
openssl req -x509 -newkey rsa:4096 -nodes -keyout /etc/nginx/ssl/server.key -out /etc/nginx/ssl/server.crt -days 365 -subj "/C=US/ST=FAKE/L=FAKE/O=FAKE/OU=FAKE/CN=FAKE" openssl req -x509 -newkey rsa:4096 -nodes -keyout /etc/nginx/ssl/server.key -out /etc/nginx/ssl/server.crt -days 365 -subj "/C=US/ST=FAKE/L=FAKE/O=FAKE/OU=FAKE/CN=FAKE"
fi fi
mv /etc/nginx/conf.d/default-ssl.conf.a /etc/nginx/conf.d/default-ssl.conf [ -f "/etc/nginx/conf.d/default-ssl.conf.a" ] && mv /etc/nginx/conf.d/default-ssl.conf.a /etc/nginx/conf.d/default-ssl.conf
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.a [ -f "/etc/nginx/conf.d/default.conf" ] && mv -f /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.a
fi fi
# if [ ! -f /home/lemur/.lemur/lemur.conf.py ]; then # if [ ! -f /home/lemur/.lemur/lemur.conf.py ]; then
@ -33,7 +36,7 @@ fi
# fi # fi
echo " # Running init" echo " # Running init"
su lemur -c "python3 /opt/lemur/lemur/manage.py init" su lemur -s /bin/bash -c "cd /opt/lemur/lemur; python3 /opt/lemur/lemur/manage.py init -p ${LEMUR_ADMIN_PASSWORD}"
echo " # Done" echo " # Done"
# echo "Creating user" # echo "Creating user"

25
docker/lemur-env Normal file
View File

@ -0,0 +1,25 @@
# SKIP_SSL=1
# LEMUR_TOKEN_SECRET=
# LEMUR_DEFAULT_COUNTRY=
# LEMUR_DEFAULT_STATE=
# LEMUR_DEFAULT_LOCATION=
# LEMUR_DEFAULT_ORGANIZATION=
# LEMUR_DEFAULT_ORGANIZATIONAL_UNIT=
# LEMUR_DEFAULT_ISSUER_PLUGIN=cryptography-issuer
# LEMUR_DEFAULT_AUTHORITY=cryptography
# MAIL_SERVER=mail.example.com
# MAIL_PORT=25
# LEMUR_EMAIL=lemur@example.com
# LEMUR_SECURITY_TEAM_EMAIL=['team@example.com']
# LEMUR_TOKEN_SECRET=
# LEMUR_ENCRYPTION_KEYS=['']
# DEBUG=True
# LDAP_DEBUG=True
# LDAP_AUTH=True
# LDAP_BIND_URI=ldap://example.com
# LDAP_BASE_DN=DC=example,DC=com
# LDAP_EMAIL_DOMAIN=example.com
# LDAP_USE_TLS=False
# LDAP_REQUIRED_GROUP=certificate-management-admins
# LDAP_GROUPS_TO_ROLES={'certificate-management-admins': 'admin', 'Team': 'team@example.com'}
# LDAP_IS_ACTIVE_DIRECTORY=False

View File

@ -9,7 +9,7 @@ server {
} }
server { server {
listen 443; listen 443 ssl;
server_name _; server_name _;
access_log /dev/stdout; access_log /dev/stdout;
error_log /dev/stderr; error_log /dev/stderr;

4
docker/pgsql-env Normal file
View File

@ -0,0 +1,4 @@
POSTGRES_USER=lemur
POSTGRES_PASSWORD=12345
POSTGRES_DB=lemur
POSTGRES_HOST=postgres

View File

@ -1,4 +1,6 @@
import os import os
from ast import literal_eval
_basedir = os.path.abspath(os.path.dirname(__file__)) _basedir = os.path.abspath(os.path.dirname(__file__))
CORS = os.environ.get("CORS") == "True" CORS = os.environ.get("CORS") == "True"
@ -29,3 +31,13 @@ LOG_LEVEL = str(os.environ.get('LOG_LEVEL','DEBUG'))
LOG_FILE = str(os.environ.get('LOG_FILE','/home/lemur/.lemur/lemur.log')) LOG_FILE = str(os.environ.get('LOG_FILE','/home/lemur/.lemur/lemur.log'))
SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI','postgresql://lemur:lemur@localhost:5432/lemur') SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI','postgresql://lemur:lemur@localhost:5432/lemur')
LDAP_DEBUG = os.environ.get('LDAP_DEBUG') == "True"
LDAP_AUTH = os.environ.get('LDAP_AUTH') == "True"
LDAP_IS_ACTIVE_DIRECTORY = os.environ.get('LDAP_IS_ACTIVE_DIRECTORY') == "True"
LDAP_BIND_URI = str(os.environ.get('LDAP_BIND_URI',''))
LDAP_BASE_DN = str(os.environ.get('LDAP_BASE_DN',''))
LDAP_EMAIL_DOMAIN = str(os.environ.get('LDAP_EMAIL_DOMAIN',''))
LDAP_USE_TLS = str(os.environ.get('LDAP_USE_TLS',''))
LDAP_REQUIRED_GROUP = str(os.environ.get('LDAP_REQUIRED_GROUP',''))
LDAP_GROUPS_TO_ROLES = literal_eval(os.environ.get('LDAP_GROUPS_TO_ROLES') or "{}")

View File

@ -180,6 +180,13 @@ Lemur provides a helpful command that will initialize your database for you. It
In addition to creating a new user, Lemur also creates a few default email notifications. These notifications are based on a few configuration options such as ``LEMUR_SECURITY_TEAM_EMAIL``. They basically guarantee that every certificate within Lemur will send one expiration notification to the security team. In addition to creating a new user, Lemur also creates a few default email notifications. These notifications are based on a few configuration options such as ``LEMUR_SECURITY_TEAM_EMAIL``. They basically guarantee that every certificate within Lemur will send one expiration notification to the security team.
Your database installation requires the pg_trgm extension. If you do not have this installed already, you can allow the script to install this for you by adding the SUPERUSER permission to the lemur database user.
.. code-block:: bash
sudo -u postgres -i
psql
postgres=# ALTER USER lemur WITH SUPERUSER
Additional notifications can be created through the UI or API. See :ref:`Creating Notifications <CreatingNotifications>` and :ref:`Command Line Interface <CommandLineInterface>` for details. Additional notifications can be created through the UI or API. See :ref:`Creating Notifications <CreatingNotifications>` and :ref:`Command Line Interface <CommandLineInterface>` for details.
**Make note of the password used as this will be used during first login to the Lemur UI.** **Make note of the password used as this will be used during first login to the Lemur UI.**
@ -189,10 +196,16 @@ Additional notifications can be created through the UI or API. See :ref:`Creati
cd /www/lemur/lemur cd /www/lemur/lemur
lemur init lemur init
.. note:: If you added the SUPERUSER permission to the lemur database user above, it is recommended you revoke that permission now.
.. code-block:: bash
sudo -u postgres -i
psql
postgres=# ALTER USER lemur WITH NOSUPERUSER
.. note:: It is recommended that once the ``lemur`` user is created that you create individual users for every day access. There is currently no way for a user to self enroll for Lemur access, they must have an administrator create an account for them or be enrolled automatically through SSO. This can be done through the CLI or UI. See :ref:`Creating Users <CreatingUsers>` and :ref:`Command Line Interface <CommandLineInterface>` for details. .. note:: It is recommended that once the ``lemur`` user is created that you create individual users for every day access. There is currently no way for a user to self enroll for Lemur access, they must have an administrator create an account for them or be enrolled automatically through SSO. This can be done through the CLI or UI. See :ref:`Creating Users <CreatingUsers>` and :ref:`Command Line Interface <CommandLineInterface>` for details.
Set Up a Reverse Proxy Set Up a Reverse Proxy
--------------------- ---------------------

View File

@ -105,7 +105,7 @@ class LdapPrincipal:
role = role_service.get_by_name(self.ldap_default_role) role = role_service.get_by_name(self.ldap_default_role)
if role: if role:
if not role.third_party: if not role.third_party:
role = role.set_third_party(role.id, third_party_status=True) role = role_service.set_third_party(role.id, third_party_status=True)
roles.add(role) roles.add(role)
# update their 'roles' # update their 'roles'

View File

@ -119,6 +119,9 @@ class CertificateInputSchema(CertificateCreationSchema):
@validates_schema @validates_schema
def validate_authority(self, data): def validate_authority(self, data):
if 'authority' not in data:
raise ValidationError("Missing Authority.")
if isinstance(data["authority"], str): if isinstance(data["authority"], str):
raise ValidationError("Authority not found.") raise ValidationError("Authority not found.")

View File

@ -1,8 +1,10 @@
from flask_script import Manager from flask_script import Manager
import sys
from lemur.constants import SUCCESS_METRIC_STATUS from lemur.constants import SUCCESS_METRIC_STATUS
from lemur.dns_providers.service import get_all_dns_providers, set_domains from lemur.dns_providers.service import get_all_dns_providers, set_domains
from lemur.extensions import metrics from lemur.extensions import metrics, sentry
from lemur.plugins.base import plugins from lemur.plugins.base import plugins
manager = Manager( manager = Manager(
@ -19,13 +21,20 @@ def get_all_zones():
dns_providers = get_all_dns_providers() dns_providers = get_all_dns_providers()
acme_plugin = plugins.get("acme-issuer") acme_plugin = plugins.get("acme-issuer")
function = f"{__name__}.{sys._getframe().f_code.co_name}"
log_data = {
"function": function,
"message": "",
}
for dns_provider in dns_providers: for dns_provider in dns_providers:
try: try:
zones = acme_plugin.get_all_zones(dns_provider) zones = acme_plugin.get_all_zones(dns_provider)
set_domains(dns_provider, zones) set_domains(dns_provider, zones)
except Exception as e: except Exception as e:
print("[+] Error with DNS Provider {}: {}".format(dns_provider.name, e)) print("[+] Error with DNS Provider {}: {}".format(dns_provider.name, e))
set_domains(dns_provider, []) log_data["message"] = f"get all zones failed for {dns_provider} {e}."
sentry.captureException(extra=log_data)
status = SUCCESS_METRIC_STATUS status = SUCCESS_METRIC_STATUS

View File

@ -46,7 +46,7 @@ class ADCSIssuerPlugin(IssuerPlugin):
) )
current_app.logger.info("Requesting CSR: {0}".format(csr)) current_app.logger.info("Requesting CSR: {0}".format(csr))
current_app.logger.info("Issuer options: {0}".format(issuer_options)) current_app.logger.info("Issuer options: {0}".format(issuer_options))
cert, req_id = ( cert = (
ca_server.get_cert(csr, adcs_template, encoding="b64") ca_server.get_cert(csr, adcs_template, encoding="b64")
.decode("utf-8") .decode("utf-8")
.replace("\r\n", "\n") .replace("\r\n", "\n")
@ -54,7 +54,7 @@ class ADCSIssuerPlugin(IssuerPlugin):
chain = ( chain = (
ca_server.get_ca_cert(encoding="b64").decode("utf-8").replace("\r\n", "\n") ca_server.get_ca_cert(encoding="b64").decode("utf-8").replace("\r\n", "\n")
) )
return cert, chain, req_id return cert, chain, None
def revoke_certificate(self, certificate, comments): def revoke_certificate(self, certificate, comments):
raise NotImplementedError("Not implemented\n", self, certificate, comments) raise NotImplementedError("Not implemented\n", self, certificate, comments)

View File

@ -212,7 +212,7 @@ class AWSSourcePlugin(SourcePlugin):
if not regions: if not regions:
regions = ec2.get_regions(account_number=account_number) regions = ec2.get_regions(account_number=account_number)
else: else:
regions = regions.split(",") regions = "".join(regions.split()).split(",")
for region in regions: for region in regions:
elbs = elb.get_all_elbs(account_number=account_number, region=region) elbs = elb.get_all_elbs(account_number=account_number, region=region)

View File

@ -23,7 +23,11 @@ from setuptools import setup, find_packages
from subprocess import check_output from subprocess import check_output
import pip import pip
if tuple(map(int, pip.__version__.split('.'))) >= (10, 0, 0): if tuple(map(int, pip.__version__.split('.'))) >= (19, 3, 0):
from pip._internal.network.session import PipSession
from pip._internal.req import parse_requirements
elif tuple(map(int, pip.__version__.split('.'))) >= (10, 0, 0):
from pip._internal.download import PipSession from pip._internal.download import PipSession
from pip._internal.req import parse_requirements from pip._internal.req import parse_requirements
else: else: