initial commit
This commit is contained in:
177
docs/Makefile
Normal file
177
docs/Makefile
Normal file
@ -0,0 +1,177 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# User-friendly check for sphinx-build
|
||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
||||
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
|
||||
endif
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " xml to make Docutils-native XML files"
|
||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/lemur.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/lemur.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/lemur"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/lemur"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
xml:
|
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
pseudoxml:
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
540
docs/administration/index.rst
Normal file
540
docs/administration/index.rst
Normal file
@ -0,0 +1,540 @@
|
||||
Configuration
|
||||
=============
|
||||
|
||||
.. warning::
|
||||
There are many secrets that Lemur uses that must be protected. All of these options are set via the Lemur configruation
|
||||
file. It is highly advised that you do not store your secrets in this file! Lemur provides functions
|
||||
that allow you to encrypt files at rest and decrypt them when it's time for deployment. See :ref:`Credential Management <CredentialManagement>`
|
||||
for more information.
|
||||
|
||||
Basic Configuration
|
||||
-------------------
|
||||
|
||||
.. data:: LOG_LEVEL
|
||||
:noindex:
|
||||
|
||||
::
|
||||
|
||||
LOG_LEVEL = "DEBUG"
|
||||
|
||||
.. data:: LOG_FILE
|
||||
:noindex:
|
||||
|
||||
::
|
||||
|
||||
LOG_FILE = "/logs/lemur/lemur-test.log"
|
||||
|
||||
|
||||
.. data:: debug
|
||||
:noindex:
|
||||
|
||||
Sets the flask debug flag to true (if supported by the webserver)
|
||||
|
||||
::
|
||||
|
||||
debug = False
|
||||
|
||||
|
||||
.. warning::
|
||||
This should never be used in a production environment as it exposes Lemur to
|
||||
remote code execution through the debug console.
|
||||
|
||||
|
||||
.. data:: CORS
|
||||
:noindex:
|
||||
|
||||
Allows for cross domain requests, this is most commonly used for development but could
|
||||
be use in production if you decided to host the webUI on a different domain than the server.
|
||||
|
||||
Use this cautiously, if you're not sure. Set it to `False`
|
||||
|
||||
::
|
||||
|
||||
CORS = False
|
||||
|
||||
|
||||
.. data:: SQLACHEMY_DATABASE_URI
|
||||
:noindex:
|
||||
|
||||
If you have ever used sqlalchemy before this is the standard connection string used. Lemur uses a postgres database and the connection string would look something like:
|
||||
|
||||
::
|
||||
|
||||
SQLALCHEMY_DATABASE_URI = 'postgresql://<user>:<password>@<hostname>:5432/lemur'
|
||||
|
||||
|
||||
.. data:: LEMUR_MAIL
|
||||
:noindex:
|
||||
|
||||
Lemur mail service
|
||||
|
||||
::
|
||||
|
||||
LEMUR_MAIL = 'lemur.example.com'
|
||||
|
||||
|
||||
.. data:: LEMUR_SECURITY_TEAM_EMAIL
|
||||
:noindex:
|
||||
|
||||
This is an email or list of emails that should be notified when a certificate is expiring. It is also the contact email address for any discovered certificate.
|
||||
|
||||
::
|
||||
|
||||
LEMUR_SECURITY_TEAM_EMAIL = ['security@example.com']
|
||||
|
||||
|
||||
.. data:: LEMUR_RESTRICTED_DOMAINS
|
||||
:noindex:
|
||||
|
||||
This allows the administrator to mark a subset of domains or domains matching a particular regex as
|
||||
*restricted*. This means that only an administrator is allows to issue the domains in question.
|
||||
|
||||
.. data:: LEMUR_TOKEN_SECRET
|
||||
:noindex:
|
||||
|
||||
The TOKEN_SECRET is the secret used to create JWT tokens that are given out to users. This should be securely generated and be kept private.
|
||||
|
||||
See `SECRET_KEY` for methods on secure secret generation.
|
||||
|
||||
::
|
||||
|
||||
LEMUR_TOKEN_SECRET = 'supersecret'
|
||||
|
||||
An example of how you might generate a random string:
|
||||
|
||||
>>> import random
|
||||
>>> secret_key = ''.join(random.choice(string.ascii_uppercase) for x in range(6))
|
||||
>>> secret_key = secret_key + ''.join(random.choice("~!@#$%^&*()_+") for x in range(6))
|
||||
>>> secret_key = secret_key + ''.join(random.choice(string.ascii_lowercase) for x in range(6))
|
||||
>>> secret_key = secret_key + ''.join(random.choice(string.digits) for x in range(6))
|
||||
|
||||
|
||||
.. data:: LEMUR_ENCRYPTION_KEY
|
||||
:noindex:
|
||||
|
||||
The LEMUR_ENCRYPTION_KEY is used to encrypt data at rest within Lemur's database. Without this key Lemur will refuse
|
||||
to start.
|
||||
|
||||
See `LEMUR_TOKEN_SECRET` for methods of secure secret generation.
|
||||
|
||||
::
|
||||
|
||||
LEMUR_ENCRYPTION_KEY = 'supersupersecret'
|
||||
|
||||
|
||||
Authority Options
|
||||
-----------------
|
||||
|
||||
Authorities will each have their own configuration options. There are currently two plugins bundled with Lemur,
|
||||
Verisign/Symantec and CloudCA
|
||||
|
||||
.. data:: VERISIGN_URL
|
||||
:noindex:
|
||||
|
||||
This is the url for the verisign API
|
||||
|
||||
|
||||
.. data:: VERISIGN_PEM_PATH
|
||||
:noindex:
|
||||
|
||||
This is the path to the mutual SSL certificate used for communicating with Verisign
|
||||
|
||||
|
||||
.. data:: CLOUDCA_URL
|
||||
:noindex:
|
||||
|
||||
This is the URL for CLoudCA API
|
||||
|
||||
|
||||
.. data:: CLOUDCA_PEM_PATH
|
||||
:noindex:
|
||||
|
||||
This is the path to the mutual SSL Certificate use for communicating with CLOUDCA
|
||||
|
||||
.. data:: CLOUDCA_BUNDLE
|
||||
:noindex:
|
||||
|
||||
This is the path to the CLOUDCA certificate bundle
|
||||
|
||||
Authentication
|
||||
--------------
|
||||
Lemur currently supports Basic Authentication and Ping OAuth2, additional flows can be added relatively easily
|
||||
If you are not using PING you do not need to configure any of these options
|
||||
|
||||
.. data:: PING_SECRET
|
||||
:noindex:
|
||||
|
||||
::
|
||||
|
||||
PING_SECRET = 'somethingsecret'
|
||||
|
||||
.. data:: PING_ACCESS_TOKEN_URL
|
||||
:noindex:
|
||||
|
||||
::
|
||||
|
||||
PING_ACCESS_TOKEN_URL = "https://<yourpingserver>/as/token.oauth2"
|
||||
|
||||
|
||||
.. data:: PING_USER_API_URL
|
||||
:noindex:
|
||||
|
||||
::
|
||||
|
||||
PING_USER_API_URL = "https://<yourpingserver>/idp/userinfo.openid"
|
||||
|
||||
.. data:: PING_JWKS_URL
|
||||
:noindex:
|
||||
|
||||
::
|
||||
|
||||
PING_JWKS_URL = "https://<yourpingserver>/pf/JWKS"
|
||||
|
||||
|
||||
Notifications
|
||||
=============
|
||||
|
||||
Lemur currently has very basic support for notifications. Notifications are send to the certificate creator, owner and
|
||||
security team as specified by the `SECURITY_TEAM_EMAIL` configuration parameter.
|
||||
|
||||
The template for all of these notifications lives under lemur/template/event.html and can be easily modified to fit your
|
||||
needs.
|
||||
|
||||
Certificates marked as in-active will **not** be notified of upcoming expiration. This enables a user to essentially
|
||||
silence the expiration. If a certificate is active and is expiring the above will be notified at 30, 15, 5, 2 days
|
||||
respectively. Lemur will not attempt to notify about certificate that have already expired.
|
||||
|
||||
|
||||
AWS Configuration
|
||||
=================
|
||||
|
||||
In order for Lemur to manage it's own account and other accounts we must ensure it has the correct AWS permissions.
|
||||
|
||||
.. note:: AWS usage is completely optional. Lemur can upload, find and manage SSL certificates in AWS. But is not required to do so.
|
||||
|
||||
AWS Configuration Options
|
||||
-------------------------
|
||||
|
||||
.. data:: AWS_ACCOUNT_MAPPINGS
|
||||
:noindex:
|
||||
|
||||
Lemur maintains it's own internal table of AWS accounts with their alias and account numbers, this variable is used during setup to bootstrap
|
||||
your particular enviroment.
|
||||
|
||||
Defaults to ``{}``.
|
||||
|
||||
::
|
||||
|
||||
AWS_ACCOUNT_MAPPINGS = {
|
||||
'awsaccountalias': 111111111111
|
||||
}
|
||||
|
||||
|
||||
Setting up IAM roles
|
||||
--------------------
|
||||
|
||||
Lemur uses boto heavily to talk to all the AWS resources it manages. By default it uses the on-instance credentials to make the necessary calls.
|
||||
|
||||
In order to limit the permissions we will create a new two IAM roles for Lemur. You can name them whatever you would like but for example sake we will be calling them LemurInstanceProfile and Lemur.
|
||||
|
||||
Lemur uses to STS to talk to different accounts. For managing one account this isn't necessary but we will still use it so that we can easily add new accounts.
|
||||
|
||||
LemurInstanceProfile is the IAM role you will launch your instance with. It actually has almost no rights. In fact it should really only be able to use STS to assume role to the Lemur role.
|
||||
|
||||
Here is are example polices for the LemurInstanceProfile:
|
||||
|
||||
SES-SendEmail
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"ses:SendEmail"
|
||||
],
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
STS-AssumeRole
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action":
|
||||
"sts:AssumeRole",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
Next we will create the the Lemur IAM role. Lemur
|
||||
|
||||
Here is an example policy for Lemur:
|
||||
|
||||
IAM-ServerCertificate
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"iam:ListServerCertificates",
|
||||
"iam:UpdateServerCertificate",
|
||||
"iam:GetServerCertificate",
|
||||
"iam:UploadServerCertificate"
|
||||
],
|
||||
"Resource": [
|
||||
"*"
|
||||
],
|
||||
"Effect": "Allow",
|
||||
"Sid": "Stmt1404836868000"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"elasticloadbalancing:DescribeInstanceHealth",
|
||||
"elasticloadbalancing:DescribeLoadBalancerAttributes",
|
||||
"elasticloadbalancing:DescribeLoadBalancerPolicyTypes",
|
||||
"elasticloadbalancing:DescribeLoadBalancerPolicies",
|
||||
"elasticloadbalancing:DescribeLoadBalancers",
|
||||
"elasticloadbalancing:DeleteLoadBalancerListeners",
|
||||
"elasticloadbalancing:CreateLoadBalancerListeners"
|
||||
],
|
||||
"Resource": [
|
||||
"*"
|
||||
],
|
||||
"Effect": "Allow",
|
||||
"Sid": "Stmt1404841912000"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
Setting up STS access
|
||||
---------------------
|
||||
Once we have setup our accounts we need to ensure that we create a trust relationship so that LemurInstanceProfile can assume the Lemur role.
|
||||
|
||||
In the AWS console select the Lemur IAM role and select the Trust Relationships tab and click Edit Trust Relationship
|
||||
|
||||
Below is an example policy:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": [
|
||||
"arn:aws:iam::<awsaccountnumber>:role/LemurInstanceProfile",
|
||||
]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
Adding N+1 accounts
|
||||
-------------------
|
||||
|
||||
To add another account we go to the new account and create a new Lemur IAM role with the same policy as above.
|
||||
|
||||
Then we would go to the account that Lemur is running is and edit the trust relationship policy.
|
||||
|
||||
An example policy:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": [
|
||||
"arn:aws:iam::<awsaccountnumber>:role/LemurInstanceProfile",
|
||||
"arn:aws:iam::<awsaccountnumber1>:role/LemurInstanceProfile",
|
||||
]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Setting up SES
|
||||
--------------
|
||||
|
||||
Lemur has built in support for sending it's certificate notifications via Amazon's simple email service (SES). To force
|
||||
Lemur to use SES ensure you are the running as the IAM role defined above and that you have followed the steps outlined
|
||||
in Amazon's documentation `Setting up Amazon SES <http://docs.aws.amazon.com/ses/latest/DeveloperGuide/setting-up-ses.html>`_
|
||||
|
||||
The configuration::
|
||||
|
||||
LEMUR_MAIL = 'lemur.example.com'
|
||||
|
||||
Will be sender of all notifications, so ensure that it is verified with AWS.
|
||||
|
||||
SES if the default notification gateway and will be used unless SMTP settings are configured in the application configuration
|
||||
settings.
|
||||
|
||||
Upgrading Lemur
|
||||
===============
|
||||
|
||||
Lemur provides an easy way to upgrade between versions. Simply download the newest
|
||||
version of Lemur from pypi and then apply any schema cahnges with the following command.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ lemur db upgrade
|
||||
|
||||
.. note:: Internally, this uses `Alembic <https://alembic.readthedocs.org/en/latest/>`_ to manage database migrations.
|
||||
|
||||
.. _CommandLineInterface:
|
||||
|
||||
Command Line Interface
|
||||
======================
|
||||
|
||||
Lemur installs a command line script under the name ``lemur``. This will allow you to
|
||||
perform most required operations that are unachievable within the web UI.
|
||||
|
||||
If you're using a non-standard configuration location, you'll need to prefix every command with
|
||||
--config (excluding create_config, which is a special case). For example::
|
||||
|
||||
lemur --config=/etc/lemur.conf.py help
|
||||
|
||||
For a list of commands, you can also use ``lemur help``, or ``lemur [command] --help``
|
||||
for help on a specific command.
|
||||
|
||||
.. note:: The script is powered by a library called `Flask-Script <https://github.com/smurfix/flask-script>`_
|
||||
|
||||
Builtin Commands
|
||||
----------------
|
||||
|
||||
All commands default to `~/.lemur/lemur.conf.py` if a configuration is not specified.
|
||||
|
||||
.. data:: create_config
|
||||
|
||||
Creates a default configuration file for Lemur.
|
||||
|
||||
Path defaults to ``~/.lemur/lemur.config.py``
|
||||
|
||||
::
|
||||
|
||||
lemur create_config .
|
||||
|
||||
.. note::
|
||||
This command is a special case and does not depend on the configuration file
|
||||
being set.
|
||||
|
||||
|
||||
.. data:: init
|
||||
|
||||
Initializes the configuration file for Lemur.
|
||||
|
||||
::
|
||||
|
||||
lemur -c /etc/lemur.conf.py init
|
||||
|
||||
|
||||
.. data:: start
|
||||
|
||||
Starts a Lemur service. You can also pass any flag that Gunicorn uses to specify the webserver configuration.
|
||||
|
||||
::
|
||||
|
||||
lemur start -w 6 -b 127.0.0.1:8080
|
||||
|
||||
|
||||
.. data:: db upgrade
|
||||
|
||||
Performs any needed database migrations.
|
||||
|
||||
::
|
||||
|
||||
lemur db upgrade
|
||||
|
||||
|
||||
.. data:: create_user
|
||||
|
||||
Creates new users within Lemur.
|
||||
|
||||
::
|
||||
|
||||
lemur create_user -u jim -e jim@example.com
|
||||
|
||||
|
||||
.. data:: create_role
|
||||
|
||||
Creates new roles within Lemur.
|
||||
|
||||
::
|
||||
|
||||
lemur create_role -n example -d "a new role"
|
||||
|
||||
|
||||
.. data:: check_revoked
|
||||
|
||||
Traverses every certificate that Lemur is aware of and attempts to understand it's validity.
|
||||
It utilizes both OCSP and CRL. If Lemur is unable to come to a conclusion about a certificates
|
||||
validity it's status is marked 'unknown'
|
||||
|
||||
|
||||
.. data:: sync
|
||||
|
||||
Sync attempts to discover certificates in the environment that were not created by Lemur. There
|
||||
|
||||
::
|
||||
|
||||
lemur sync --all
|
||||
|
||||
|
||||
Identity and Access Management
|
||||
==============================
|
||||
|
||||
Lemur uses a Role Based Access Control (RBAC) mechanism to control which users have access to which resources. When a
|
||||
user is first created in Lemur the can be assigned one or more roles. These roles are typically dynamically created
|
||||
depending on a external identity provider (Google, LDAP, etc.,) or are hardcoded within Lemur and associated with special
|
||||
meaning.
|
||||
|
||||
Within Lemur there are three main permissions: AdminPermission, CreatorPermission, OwnerPermission. Sub-permissions such
|
||||
as ViewPrivateKeyPermission are compositions of these three main Permissions.
|
||||
|
||||
Lets take a look at how these permissions used:
|
||||
|
||||
Each `Authority` has a set of roles associated with it. If a user is also associated with the same roles
|
||||
that the `Authority` is associated with it Lemur allows that user to user/view/update that `Authority`.
|
||||
|
||||
This RBAC is also used when determining which users can access which certificate private key. Lemur's current permission
|
||||
structure is setup such that if the user is a `Creator` or `Owner` of a given certificate they are allow to view that
|
||||
private key.
|
||||
|
||||
These permissions are applied to the user upon login and refreshed on every request.
|
||||
|
||||
.. seealso::
|
||||
`Flask-Principal <https://pythonhosted.org/Flask-Principal>`_
|
||||
|
||||
|
2
docs/changelog.rst
Normal file
2
docs/changelog.rst
Normal file
@ -0,0 +1,2 @@
|
||||
Change Log
|
||||
==========
|
262
docs/conf.py
Normal file
262
docs/conf.py
Normal file
@ -0,0 +1,262 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# security_monkey documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sat Jun 7 18:43:48 2014.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinxcontrib.autohttp.flask',
|
||||
'sphinx.ext.todo',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'lemur'
|
||||
copyright = u'2015, Kevin Glisson'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.1.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'alabaster'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'lemurdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'lemur.tex', u'Lemur Documentation',
|
||||
u'Kevin Glisson', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'Lemur', u'Lemur Documentation',
|
||||
[u'Kevin Glisson'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'Lemur', u'Lemur Documentation',
|
||||
u'Kevin Glisson', 'Lemur', 'SSL Certificate Management',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
197
docs/developer/index.rst
Normal file
197
docs/developer/index.rst
Normal file
@ -0,0 +1,197 @@
|
||||
Contributing
|
||||
============
|
||||
|
||||
Want to contribute back to Lemur? This page describes the general development flow,
|
||||
our philosophy, the test suite, and issue tracking.
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
If you're looking to help document Lemur, you can get set up with Sphinx, our documentation tool,
|
||||
but first you will want to make sure you have a few things on your local system:
|
||||
|
||||
* python-dev (if you're on OS X, you already have this)
|
||||
* pip
|
||||
* virtualenvwrapper
|
||||
|
||||
Once you've got all that, the rest is simple:
|
||||
|
||||
::
|
||||
|
||||
# If you have a fork, you'll want to clone it instead
|
||||
git clone git://github.com/netflix/lemur.git
|
||||
|
||||
# Create a python virtualenv
|
||||
mkvirtualenv lemur
|
||||
|
||||
# Make the magic happen
|
||||
make dev-docs
|
||||
|
||||
Running ``make dev-docs`` will install the basic requirements to get Sphinx running.
|
||||
|
||||
|
||||
Building Documentation
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Inside the ``docs`` directory, you can run ``make`` to build the documentation.
|
||||
See ``make help`` for available options and the `Sphinx Documentation <http://sphinx-doc.org/contents.html>`_ for more information.
|
||||
|
||||
|
||||
Developing Against HEAD
|
||||
-----------------------
|
||||
|
||||
We try to make it easy to get up and running in a development environment using a git checkout
|
||||
of Lemur. You'll want to make sure you have a few things on your local system first:
|
||||
|
||||
* python-dev (if you're on OS X, you already have this)
|
||||
* pip
|
||||
* virtualenv (ideally virtualenvwrapper)
|
||||
* node.js (for npm and building css/javascript)
|
||||
* (Optional) Potgresql
|
||||
|
||||
Once you've got all that, the rest is simple:
|
||||
|
||||
::
|
||||
|
||||
# If you have a fork, you'll want to clone it instead
|
||||
git clone git://github.com/lemur/lemur.git
|
||||
|
||||
# Create a python virtualenv
|
||||
mkvirtualenv lemur
|
||||
|
||||
# Make the magic happen
|
||||
make
|
||||
|
||||
Running ``make`` will do several things, including:
|
||||
|
||||
* Setting up any submodules (including Bootstrap)
|
||||
* Installing Python requirements
|
||||
* Installing NPM requirements
|
||||
|
||||
.. note::
|
||||
You will want to store your virtualenv out of the ``lemur`` directory you cloned above,
|
||||
otherwise ``make`` will fail.
|
||||
|
||||
Create a default Lemur configuration just as if this were a production instance:
|
||||
|
||||
::
|
||||
|
||||
lemur init
|
||||
|
||||
You'll likely want to make some changes to the default configuration (we recommend developing against Postgres, for example). Once done, migrate your database using the following command:
|
||||
|
||||
::
|
||||
|
||||
lemur upgrade
|
||||
|
||||
|
||||
.. note:: The ``upgrade`` shortcut is simply a shorcut to Alembic's upgrade command.
|
||||
|
||||
|
||||
Coding Standards
|
||||
----------------
|
||||
|
||||
Lemur follows the guidelines laid out in `pep8 <http://www.python.org/dev/peps/pep-0008/>`_ with a little bit
|
||||
of flexibility on things like line length. We always give way for the `Zen of Python <http://www.python.org/dev/peps/pep-0020/>`_. We also use strict mode for JavaScript, enforced by jshint.
|
||||
|
||||
You can run all linters with ``make lint``, or respectively ``lint-python`` or ``lint-js``.
|
||||
|
||||
Spacing
|
||||
~~~~~~~
|
||||
|
||||
Python:
|
||||
4 Spaces
|
||||
|
||||
JavaScript:
|
||||
2 Spaces
|
||||
|
||||
CSS:
|
||||
2 Spaces
|
||||
|
||||
HTML:
|
||||
2 Spaces
|
||||
|
||||
|
||||
Running the Test Suite
|
||||
----------------------
|
||||
|
||||
The test suite consists of multiple parts, testing both the Python and JavaScript components in Lemur. If you've setup your environment correctly, you can run the entire suite with the following command:
|
||||
|
||||
::
|
||||
|
||||
make test
|
||||
|
||||
If you only need to run the Python tests, you can do so with ``make test-python``, as well as ``test-js`` for the JavaScript tests.
|
||||
|
||||
|
||||
You'll notice that the test suite is structured based on where the code lives, and strongly encourages using the mock library to drive more accurate individual tests.
|
||||
|
||||
.. note:: We use py.test for the Python test suite, and a combination of phantomjs and jasmine for the JavaScript tests.
|
||||
|
||||
|
||||
Static Media
|
||||
------------
|
||||
|
||||
Lemur uses a library that compiles it's static media assets (LESS and JS files) automatically. If you're developing using
|
||||
runserver you'll see changes happen not only in the original files, but also the minified or processed versions of the file.
|
||||
|
||||
If you've made changes and need to compile them by hand for any reason, you can do so by running:
|
||||
|
||||
::
|
||||
|
||||
lemur compilestatic
|
||||
|
||||
The minified and processed files should be committed alongside the unprocessed changes.
|
||||
|
||||
Developing with Flask
|
||||
----------------------
|
||||
|
||||
Because Lemur is just Flask, you can use all of the standard Flask functionality. The only difference is you'll be accessing commands that would normally go through manage.py using the ``lemur`` CLI helper instead.
|
||||
|
||||
For example, you probably don't want to use ``lemur start`` for development, as it doesn't support anything like
|
||||
automatic reloading on code changes. For that you'd want to use the standard builtin ``runserver`` command:
|
||||
|
||||
::
|
||||
|
||||
lemur runserver
|
||||
|
||||
|
||||
DDL (Schema Changes)
|
||||
--------------------
|
||||
|
||||
Schema changes should always introduce the new schema in a commit, and then introduce code relying on that schema in a followup commit. This also means that new columns must be NULLable.
|
||||
|
||||
Removing columns and tables requires a slightly more painful flow, and should resemble the follow multi-commit flow:
|
||||
|
||||
- Remove all references to the column or table (but dont remove the Model itself)
|
||||
- Remove the model code
|
||||
- Remove the table or column
|
||||
|
||||
|
||||
Contributing Back Code
|
||||
----------------------
|
||||
|
||||
All patches should be sent as a pull request on GitHub, include tests, and documentation where needed. If you're fixing a bug or making a large change the patch **must** include test coverage.
|
||||
|
||||
Uncertain about how to write tests? Take a look at some existing tests that are similar to the code you're changing, and go from there.
|
||||
|
||||
You can see a list of open pull requests (pending changes) by visiting https://github.com/netflix/lemur/pulls
|
||||
|
||||
|
||||
Plugins
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
plugins/index
|
||||
|
||||
Internals
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
internals/lemur
|
||||
|
20
docs/developer/internals/lemur.accounts.rst
Normal file
20
docs/developer/internals/lemur.accounts.rst
Normal file
@ -0,0 +1,20 @@
|
||||
accounts Package
|
||||
================
|
||||
|
||||
:mod:`models` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.accounts.models
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`service` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.accounts.service
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
11
docs/developer/internals/lemur.analyze.rst
Normal file
11
docs/developer/internals/lemur.analyze.rst
Normal file
@ -0,0 +1,11 @@
|
||||
analyze Package
|
||||
===============
|
||||
|
||||
:mod:`service` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.analyze.service
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
20
docs/developer/internals/lemur.auth.rst
Normal file
20
docs/developer/internals/lemur.auth.rst
Normal file
@ -0,0 +1,20 @@
|
||||
auth Package
|
||||
============
|
||||
|
||||
:mod:`permissions` Module
|
||||
-------------------------
|
||||
|
||||
.. automodule:: lemur.auth.permissions
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`service` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.auth.service
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
20
docs/developer/internals/lemur.authorities.rst
Normal file
20
docs/developer/internals/lemur.authorities.rst
Normal file
@ -0,0 +1,20 @@
|
||||
authorities Package
|
||||
===================
|
||||
|
||||
:mod:`models` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.authorities.models
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`service` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.authorities.service
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
43
docs/developer/internals/lemur.certificates.rst
Normal file
43
docs/developer/internals/lemur.certificates.rst
Normal file
@ -0,0 +1,43 @@
|
||||
certificates Package
|
||||
====================
|
||||
|
||||
:mod:`exceptions` Module
|
||||
------------------------
|
||||
|
||||
.. automodule:: lemur.certificates.exceptions
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`models` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.certificates.models
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`service` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.certificates.service
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`sync` Module
|
||||
------------------
|
||||
|
||||
.. automodule:: lemur.certificates.sync
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`verify` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.certificates.verify
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
34
docs/developer/internals/lemur.common.rst
Normal file
34
docs/developer/internals/lemur.common.rst
Normal file
@ -0,0 +1,34 @@
|
||||
common Package
|
||||
==============
|
||||
|
||||
:mod:`crypto` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.common.crypto
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`health` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.common.health
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`utils` Module
|
||||
-------------------
|
||||
|
||||
.. automodule:: lemur.common.utils
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Subpackages
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
|
||||
lemur.common.services
|
||||
|
35
docs/developer/internals/lemur.common.services.aws.rst
Normal file
35
docs/developer/internals/lemur.common.services.aws.rst
Normal file
@ -0,0 +1,35 @@
|
||||
aws Package
|
||||
===========
|
||||
|
||||
:mod:`elb` Module
|
||||
-----------------
|
||||
|
||||
.. automodule:: lemur.common.services.aws.elb
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`iam` Module
|
||||
-----------------
|
||||
|
||||
.. automodule:: lemur.common.services.aws.iam
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`ses` Module
|
||||
-----------------
|
||||
|
||||
.. automodule:: lemur.common.services.aws.ses
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`sts` Module
|
||||
-----------------
|
||||
|
||||
.. automodule:: lemur.common.services.aws.sts
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
@ -0,0 +1,19 @@
|
||||
cloudca Package
|
||||
===============
|
||||
|
||||
:mod:`cloudca` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.common.services.issuers.plugins.cloudca.cloudca
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`constants` Module
|
||||
-----------------------
|
||||
|
||||
.. automodule:: lemur.common.services.issuers.plugins.cloudca.constants
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
@ -0,0 +1,11 @@
|
||||
plugins Package
|
||||
===============
|
||||
|
||||
Subpackages
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
|
||||
lemur.common.services.issuers.plugins.cloudca
|
||||
lemur.common.services.issuers.plugins.verisign
|
||||
|
@ -0,0 +1,19 @@
|
||||
verisign Package
|
||||
================
|
||||
|
||||
:mod:`constants` Module
|
||||
-----------------------
|
||||
|
||||
.. automodule:: lemur.common.services.issuers.plugins.verisign.constants
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`verisign` Module
|
||||
----------------------
|
||||
|
||||
.. automodule:: lemur.common.services.issuers.plugins.verisign.verisign
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
26
docs/developer/internals/lemur.common.services.issuers.rst
Normal file
26
docs/developer/internals/lemur.common.services.issuers.rst
Normal file
@ -0,0 +1,26 @@
|
||||
issuers Package
|
||||
===============
|
||||
|
||||
:mod:`issuer` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.common.services.issuers.issuer
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`manager` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.common.services.issuers.manager
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Subpackages
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
|
||||
lemur.common.services.issuers.plugins
|
||||
|
11
docs/developer/internals/lemur.common.services.rst
Normal file
11
docs/developer/internals/lemur.common.services.rst
Normal file
@ -0,0 +1,11 @@
|
||||
services Package
|
||||
================
|
||||
|
||||
Subpackages
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
|
||||
lemur.common.services.aws
|
||||
lemur.common.services.issuers
|
||||
|
19
docs/developer/internals/lemur.domains.rst
Normal file
19
docs/developer/internals/lemur.domains.rst
Normal file
@ -0,0 +1,19 @@
|
||||
domains Package
|
||||
===============
|
||||
|
||||
:mod:`models` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.domains.models
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`service` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.domains.service
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
35
docs/developer/internals/lemur.elbs.rst
Normal file
35
docs/developer/internals/lemur.elbs.rst
Normal file
@ -0,0 +1,35 @@
|
||||
elbs Package
|
||||
============
|
||||
|
||||
:mod:`models` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.elbs.models
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`service` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.elbs.service
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`sync` Module
|
||||
------------------
|
||||
|
||||
.. automodule:: lemur.elbs.sync
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`views` Module
|
||||
-------------------
|
||||
|
||||
.. automodule:: lemur.elbs.views
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
27
docs/developer/internals/lemur.listeners.rst
Normal file
27
docs/developer/internals/lemur.listeners.rst
Normal file
@ -0,0 +1,27 @@
|
||||
listeners Package
|
||||
=================
|
||||
|
||||
:mod:`models` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.listeners.models
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`service` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.listeners.service
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`views` Module
|
||||
-------------------
|
||||
|
||||
.. automodule:: lemur.listeners.views
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
20
docs/developer/internals/lemur.roles.rst
Normal file
20
docs/developer/internals/lemur.roles.rst
Normal file
@ -0,0 +1,20 @@
|
||||
roles Package
|
||||
=============
|
||||
|
||||
:mod:`models` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.roles.models
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`service` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.roles.service
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
87
docs/developer/internals/lemur.rst
Normal file
87
docs/developer/internals/lemur.rst
Normal file
@ -0,0 +1,87 @@
|
||||
:mod:`constants` Module
|
||||
-----------------------
|
||||
|
||||
.. automodule:: lemur.constants
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`database` Module
|
||||
----------------------
|
||||
|
||||
.. automodule:: lemur.database
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`decorators` Module
|
||||
------------------------
|
||||
|
||||
.. automodule:: lemur.decorators
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`exceptions` Module
|
||||
------------------------
|
||||
|
||||
.. automodule:: lemur.exceptions
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`extensions` Module
|
||||
------------------------
|
||||
|
||||
.. automodule:: lemur.extensions
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`factory` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.factory
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`manage` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.manage
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`models` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.models
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`notifications` Module
|
||||
---------------------------
|
||||
|
||||
.. automodule:: lemur.notifications
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Subpackages
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
|
||||
lemur.accounts
|
||||
lemur.auth
|
||||
lemur.authorities
|
||||
lemur.certificates
|
||||
lemur.common
|
||||
lemur.domains
|
||||
lemur.roles
|
||||
lemur.status
|
||||
lemur.users
|
||||
|
11
docs/developer/internals/lemur.status.rst
Normal file
11
docs/developer/internals/lemur.status.rst
Normal file
@ -0,0 +1,11 @@
|
||||
status Package
|
||||
==============
|
||||
|
||||
:mod:`views` Module
|
||||
-------------------
|
||||
|
||||
.. automodule:: lemur.status.views
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
19
docs/developer/internals/lemur.users.rst
Normal file
19
docs/developer/internals/lemur.users.rst
Normal file
@ -0,0 +1,19 @@
|
||||
users Package
|
||||
=============
|
||||
|
||||
:mod:`models` Module
|
||||
--------------------
|
||||
|
||||
.. automodule:: lemur.users.models
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
:mod:`service` Module
|
||||
---------------------
|
||||
|
||||
.. automodule:: lemur.users.service
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
151
docs/developer/plugins/index.rst
Normal file
151
docs/developer/plugins/index.rst
Normal file
@ -0,0 +1,151 @@
|
||||
Writing a Plugin
|
||||
================
|
||||
|
||||
**The plugin interface is a work in progress.**
|
||||
|
||||
Several interfaces exist for extending Lemur:
|
||||
|
||||
* Issuers (lemur.issuers)
|
||||
|
||||
Structure
|
||||
---------
|
||||
|
||||
A plugins layout generally looks like the following::
|
||||
|
||||
setup.py
|
||||
lemur_pluginname/
|
||||
lemur_pluginname/__init__.py
|
||||
lemur_pluginname/plugin.py
|
||||
|
||||
The ``__init__.py`` file should contain no plugin logic, and at most, a VERSION = 'x.x.x' line. For example,
|
||||
if you want to pull the version using pkg_resources (which is what we recommend), your file might contain::
|
||||
|
||||
try:
|
||||
VERSION = __import__('pkg_resources') \
|
||||
.get_distribution(__name__).version
|
||||
except Exception, e:
|
||||
VERSION = 'unknown'
|
||||
|
||||
Inside of ``plugin.py``, you'll declare your Plugin class::
|
||||
|
||||
import lemur_pluginname
|
||||
from lemur.common.services.issuers.plugins import Issuer
|
||||
|
||||
class PluginName(Plugin):
|
||||
title = 'Plugin Name'
|
||||
slug = 'pluginname'
|
||||
description = 'My awesome plugin!'
|
||||
version = lemur_pluginname.VERSION
|
||||
|
||||
author = 'Your Name'
|
||||
author_url = 'https://github.com/yourname/lemur_pluginname'
|
||||
|
||||
def widget(self, request, group, **kwargs):
|
||||
return "<p>Absolutely useless widget</p>"
|
||||
|
||||
And you'll register it via ``entry_points`` in your ``setup.py``::
|
||||
|
||||
setup(
|
||||
# ...
|
||||
entry_points={
|
||||
'lemur.plugins': [
|
||||
'pluginname = lemur_pluginname.issuers:PluginName'
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
That's it! Users will be able to install your plugin via ``pip install <package name>`` and configure it
|
||||
via the web interface based on the hooks you enabled.
|
||||
|
||||
|
||||
Permissions
|
||||
===========
|
||||
|
||||
As described in the plugin interface, Lemur provides a suite of permissions.
|
||||
|
||||
In most cases, a admin (that is, if User.is_admin is ``True``), will be granted implicit permissions
|
||||
on everything.
|
||||
|
||||
This page attempts to describe those permissions, and the contextual objects along with them.
|
||||
|
||||
.. data:: add_project
|
||||
|
||||
Controls whether a user can create a new project.
|
||||
|
||||
::
|
||||
|
||||
>>> has_perm('add_project', user)
|
||||
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
Lemur provides a basic py.test-based testing framework for extensions.
|
||||
|
||||
In a simple project, you'll need to do a few things to get it working:
|
||||
|
||||
setup.py
|
||||
--------
|
||||
|
||||
Augment your setup.py to ensure at least the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
setup(
|
||||
# ...
|
||||
install_requires=[
|
||||
'lemur',
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
conftest.py
|
||||
-----------
|
||||
|
||||
The ``conftest.py`` file is our main entry-point for py.test. We need to configure it to load the Lemur pytest configuration:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
pytest_plugins = [
|
||||
'lemur.utils.pytest'
|
||||
]
|
||||
|
||||
|
||||
Test Cases
|
||||
----------
|
||||
|
||||
You can now inherit from Lemur's core test classes. These are Django-based and ensure the database and other basic utilities are in a clean state:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# test_myextension.py
|
||||
from __future__ import absolute_import
|
||||
|
||||
from lemur.testutils import TestCase
|
||||
|
||||
class MyExtensionTest(TestCase):
|
||||
def test_simple(self):
|
||||
assert 1 != 2
|
||||
|
||||
|
||||
Running Tests
|
||||
-------------
|
||||
|
||||
Running tests follows the py.test standard. As long as your test files and methods are named appropriately (``test_filename.py`` and ``test_function()``) you can simply call out to py.test:
|
||||
|
||||
::
|
||||
|
||||
$ py.test -v
|
||||
============================== test session starts ==============================
|
||||
platform darwin -- Python 2.7.9 -- py-1.4.26 -- pytest-2.6.4/python2.7
|
||||
plugins: django
|
||||
collected 1 items
|
||||
|
||||
tests/test_myextension.py::MyExtensionTest::test_simple PASSED
|
||||
|
||||
=========================== 1 passed in 0.35 seconds ============================
|
||||
|
||||
|
60
docs/developer/rest.rst
Normal file
60
docs/developer/rest.rst
Normal file
@ -0,0 +1,60 @@
|
||||
Lemur's front end is entirely API driven. Any action that you can accomplish via the UI can also be accomplished by the
|
||||
UI. The following is documents and provides examples on how to make requests to the Lemur API.
|
||||
|
||||
Authentication
|
||||
--------------
|
||||
|
||||
.. automodule:: lemur.auth.views
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Accounts
|
||||
--------
|
||||
|
||||
.. automodule:: lemur.accounts.views
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Users
|
||||
-----
|
||||
|
||||
.. automodule:: lemur.users.views
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Roles
|
||||
-----
|
||||
|
||||
.. automodule:: lemur.roles.views
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Certificates
|
||||
------------
|
||||
|
||||
.. automodule:: lemur.certificates.views
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Authorities
|
||||
-----------
|
||||
|
||||
.. automodule:: lemur.authorities.views
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Domains
|
||||
-------
|
||||
|
||||
.. automodule:: lemur.domains.views
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
30
docs/faq.rst
Normal file
30
docs/faq.rst
Normal file
@ -0,0 +1,30 @@
|
||||
Frequently Asked Questions
|
||||
==========================
|
||||
|
||||
Common Problems
|
||||
---------------
|
||||
|
||||
In my startup logs I see *'Aborting... Lemur cannot locate db encryption key, is ENCRYPTION_KEY set?'*
|
||||
You likely have not correctly configured **ENCRYPTION_KEY**. See
|
||||
:doc:`administration/configuration` for more information.
|
||||
|
||||
|
||||
How do I
|
||||
--------
|
||||
|
||||
... script the Lemur installation to bootstrap things like roles and users?
|
||||
Lemur is a simple Flask (Python) application that runs using a utility
|
||||
runner. A script that creates a project and default user might look something
|
||||
like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Bootstrap the Flask environment
|
||||
from flask import current_app
|
||||
|
||||
from lemur.users.service import create as create_user
|
||||
from lemur.roles.service import create as create_role
|
||||
from lemur.accounts.service import create as create_account
|
||||
|
||||
role = create_role('aRole', 'this is a new role')
|
||||
create_user('admin', 'password', 'lemur@nobody', True, [role]
|
10
docs/guide/index.rst
Normal file
10
docs/guide/index.rst
Normal file
@ -0,0 +1,10 @@
|
||||
Creating Certificates
|
||||
=====================
|
||||
|
||||
|
||||
Creating Users
|
||||
==============
|
||||
|
||||
|
||||
Creating Roles
|
||||
==============
|
67
docs/index.rst
Normal file
67
docs/index.rst
Normal file
@ -0,0 +1,67 @@
|
||||
Lemur
|
||||
=====
|
||||
|
||||
Lemur is a SSL management service. It attempts to help track and create certificates. By removing common issues with
|
||||
CSR creation it gives normal developers 'sane' SSL defaults and helps security teams push SSL usage throughout an organization.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
quickstart/index
|
||||
production/index
|
||||
|
||||
User Guide
|
||||
----------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
guide/index
|
||||
|
||||
Administration
|
||||
--------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
administration/index
|
||||
plugins/index
|
||||
|
||||
Developers
|
||||
----------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
developer/index
|
||||
|
||||
|
||||
REST API
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
developer/rest
|
||||
|
||||
FAQ
|
||||
----
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
faq
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
changelog
|
||||
license/index
|
||||
|
||||
|
20
docs/license/index.rst
Normal file
20
docs/license/index.rst
Normal file
@ -0,0 +1,20 @@
|
||||
License
|
||||
=======
|
||||
|
||||
Lemur is licensed under a three clause APACHE License.
|
||||
|
||||
The full license text can be found below (:ref:`lemur-license`).
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
Lemur was originally written and is maintained by Kevin Glisson.
|
||||
|
||||
A list of additional contributors can be seen on `GitHub <https://github.com/netflix/lemur/contributors>`_.
|
||||
|
||||
.. _lemur-license:
|
||||
|
||||
Lemur License
|
||||
-------------
|
||||
|
||||
.. include:: ../../LICENSE
|
20
docs/plugins/index.rst
Normal file
20
docs/plugins/index.rst
Normal file
@ -0,0 +1,20 @@
|
||||
Plugins
|
||||
=======
|
||||
|
||||
There are several interfaces currently available to extend Lemur. These are a work in
|
||||
progress and the API is not frozen.
|
||||
|
||||
Bundled Plugins
|
||||
---------------
|
||||
|
||||
Lemur includes several plugins by default. Including extensive support for AWS, VeriSign/Symantec and CloudCA services.
|
||||
|
||||
3rd Party Extensions
|
||||
--------------------
|
||||
|
||||
The following extensions are available and maintained by members of the Lemur community:
|
||||
|
||||
Have an extension that should be listed here? Submit a `pull request <https://github.com/netflix/lemur>`_ and we'll
|
||||
get it added.
|
||||
|
||||
Want to create your own extension? See :doc:`../developer/plugins/index` to get started.
|
277
docs/production/index.rst
Normal file
277
docs/production/index.rst
Normal file
@ -0,0 +1,277 @@
|
||||
Production
|
||||
**********
|
||||
|
||||
There are several steps needed to make Lemur production ready. Here we focus on making Lemur more reliable and secure.
|
||||
|
||||
Basics
|
||||
======
|
||||
|
||||
Because of the sensitivity of the information stored and maintain by Lemur it is important that you follow standard host hardening practices:
|
||||
|
||||
- Run Lemur with a limited user
|
||||
- Disabled any unneeded service
|
||||
- Enable remote logging
|
||||
|
||||
.. _CredentialManagement:
|
||||
|
||||
Credential Management
|
||||
---------------------
|
||||
|
||||
Lemur often contains credentials such as mutual SSL keys that are used to communicate with third party resources and for encrypting stored secrets. Lemur comes with the ability
|
||||
to automatically encrypt these keys such that your keys not be in clear text.
|
||||
|
||||
The keys are located within lemur/keys and broken down by environment
|
||||
|
||||
To utilize this ability use the following commands:
|
||||
|
||||
``lemur lock``
|
||||
|
||||
and
|
||||
|
||||
``lemur unlock``
|
||||
|
||||
If you choose to use this feature ensure that the KEY are decrypted before Lemur starts as it will have trouble communicating with the database otherwise.
|
||||
|
||||
SSL
|
||||
====
|
||||
|
||||
Nginx
|
||||
-----
|
||||
|
||||
Nginx is a very popular choice to serve a Python project:
|
||||
|
||||
- It's fast.
|
||||
- It's lightweight.
|
||||
- Configuration files are simple.
|
||||
|
||||
Nginx doesn't run any Python process, it only serves requests from outside to
|
||||
the Python server.
|
||||
|
||||
Therefor there are two steps:
|
||||
|
||||
- Run the Python process.
|
||||
- Run Nginx.
|
||||
|
||||
You will benefit from having:
|
||||
|
||||
- the possibility to have several projects listening to the port 80;
|
||||
- your web site processes won't run with admin rights, even if --user doesn't
|
||||
work on your OS;
|
||||
- the ability to manage a Python process without touching Nginx or the other
|
||||
processes. It's very handy for updates.
|
||||
|
||||
|
||||
You must create a Nginx configuration file for Lemur. On GNU/Linux, they usually
|
||||
go into /etc/nginx/conf.d/. Name it lemur.conf.
|
||||
|
||||
The minimal configuration file to run the site is::
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name www.yourwebsite.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
}
|
||||
}
|
||||
|
||||
`proxy_pass` just passes the external request to the Python process.
|
||||
The port much match the one used by the 0bin process of course.
|
||||
|
||||
You can make some adjustments to get a better user experience::
|
||||
|
||||
server_tokens off;
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443;
|
||||
access_log /var/log/nginx/log/lemur.access.log;
|
||||
error_log /var/log/nginx/log/lemur.error.log;
|
||||
|
||||
location /api {
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location / {
|
||||
root /apps/lemur/lemur/static/dist;
|
||||
index index.html;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
This makes Nginx serve the favicon and static files which is is much better at than python.
|
||||
|
||||
It is highly recommended that you deploy SSL when deploying Lemur. This may be obvious given Lemur's purpose but the
|
||||
sensitive nature of Lemur and what it controls makes this essential. This is a sample config for Lemur that also terminates SSL::
|
||||
|
||||
server_tokens off;
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443;
|
||||
access_log /var/log/nginx/log/lemur.access.log;
|
||||
error_log /var/log/nginx/log/lemur.error.log;
|
||||
|
||||
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
|
||||
ssl_certificate /path/to/signed_cert_plus_intermediates;
|
||||
ssl_certificate_key /path/to/private_key;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:SSL:50m;
|
||||
|
||||
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
|
||||
ssl_dhparam /path/to/dhparam.pem;
|
||||
|
||||
# modern configuration. tweak to your needs.
|
||||
ssl_protocols TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
|
||||
add_header Strict-Transport-Security max-age=15768000;
|
||||
|
||||
# OCSP Stapling ---
|
||||
# fetch OCSP records from URL in ssl_certificate and cache them
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
|
||||
## verify chain of trust of OCSP response using Root CA and Intermediate certs
|
||||
ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;
|
||||
|
||||
resolver <IP DNS resolver>;
|
||||
|
||||
location /api {
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location / {
|
||||
root /apps/lemur/lemur/static/dist;
|
||||
index index.html;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Apache
|
||||
------
|
||||
|
||||
An example apache config::
|
||||
|
||||
<VirtualHost *:443>
|
||||
...
|
||||
SSLEngine on
|
||||
SSLCertificateFile /path/to/signed_certificate
|
||||
SSLCertificateChainFile /path/to/intermediate_certificate
|
||||
SSLCertificateKeyFile /path/to/private/key
|
||||
SSLCACertificateFile /path/to/all_ca_certs
|
||||
|
||||
# intermediate configuration, tweak to your needs
|
||||
SSLProtocol all -SSLv2 -SSLv3
|
||||
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
|
||||
SSLHonorCipherOrder on
|
||||
|
||||
# HSTS (mod_headers is required) (15768000 seconds = 6 months)
|
||||
Header always set Strict-Transport-Security "max-age=15768000"
|
||||
...
|
||||
</VirtualHost>
|
||||
|
||||
Also included in the configurations above are several best practices when it comes to deploying SSL. Things like enabling
|
||||
HSTS, disabling vulnerable ciphers are all good ideas when it comes to deploying Lemur into a production environment.
|
||||
|
||||
.. seealso::
|
||||
`Mozilla SSL Configuration Generator <https://mozilla.github.io/server-side-tls/ssl-config-generator/>`_
|
||||
|
||||
.. _UsingSupervisor:
|
||||
|
||||
Supervisor
|
||||
==========
|
||||
|
||||
Supervisor is a very nice way to manage you Python processes. We won't cover
|
||||
the setup (which is just apt-get install supervisor or pip install supervisor
|
||||
most of the time), but here is a quick overview on how to use it.
|
||||
|
||||
Create a configuration file named supervisor.ini::
|
||||
|
||||
[unix_http_server]
|
||||
file=/tmp/supervisor.sock;
|
||||
|
||||
[supervisorctl]
|
||||
serverurl=unix:///tmp/supervisor.sock;
|
||||
|
||||
[rpcinterface:supervisor]
|
||||
supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface
|
||||
|
||||
[supervisord]
|
||||
logfile=/tmp/lemur.log
|
||||
logfile_maxbytes=50MB
|
||||
logfile_backups=2
|
||||
loglevel=trace
|
||||
pidfile=/tmp/supervisord.pid
|
||||
nodaemon=false
|
||||
minfds=1024
|
||||
minprocs=200
|
||||
user=lemur
|
||||
|
||||
[program:lemur]
|
||||
command=python /path/to/lemur/manage.py manage.py start
|
||||
|
||||
directory=/path/to/lemur/
|
||||
environment=PYTHONPATH='/path/to/lemur/'
|
||||
user=lemur
|
||||
autostart=true
|
||||
autorestart=true
|
||||
|
||||
The 4 first entries are just boiler plate to get you started, you can copy
|
||||
them verbatim.
|
||||
|
||||
The last one define one (you can have many) process supervisor should manage.
|
||||
|
||||
It means it will run the command::
|
||||
|
||||
python manage.py start
|
||||
|
||||
|
||||
In the directory, with the environment and the user you defined.
|
||||
|
||||
This command will be ran as a daemon, in the background.
|
||||
|
||||
`autostart` and `autorestart` just make it fire and forget: the site will always be
|
||||
running, even it crashes temporarily or if you restart the machine.
|
||||
|
||||
The first time you run supervisor, pass it the configuration file::
|
||||
|
||||
supervisord -c /path/to/supervisor.ini
|
||||
|
||||
Then you can manage the process by running::
|
||||
|
||||
supervisorctl -c /path/to/supervisor.ini
|
||||
|
||||
It will start a shell from were you can start/stop/restart the service
|
||||
|
||||
You can read all errors that might occurs from /tmp/lemur.log.
|
237
docs/quickstart/index.rst
Normal file
237
docs/quickstart/index.rst
Normal file
@ -0,0 +1,237 @@
|
||||
Quickstart
|
||||
**********
|
||||
|
||||
This guide will step you through setting up a Python-based virtualenv, installing the required packages, and configuring the basic web service.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
Some basic prerequisites which you'll need in order to run Lemur:
|
||||
|
||||
* A UNIX-based operating system. We test on Ubuntu, develop on OS X
|
||||
* Python 2.7
|
||||
* PostgreSQL
|
||||
* Ngnix
|
||||
|
||||
.. note:: Lemur was built with in AWS in mind. This means that things such as databases (RDS), mail (SES), and SSL (ELB),
|
||||
are largely handled for us. Lemur does **not** require AWS to function. Our guides and documentation try to be
|
||||
be as generic as possible and are not intended to document every step of launching Lemur into a given environment.
|
||||
|
||||
Setting up an Environment
|
||||
-------------------------
|
||||
|
||||
The first thing you'll need is the Python ``virtualenv`` package. You probably already
|
||||
have this, but if not, you can install it with::
|
||||
|
||||
pip install -U virtualenv
|
||||
|
||||
Once that's done, choose a location for the environment, and create it with the ``virtualenv``
|
||||
command. For our guide, we're going to choose ``/www/lemur/``::
|
||||
|
||||
virtualenv /www/lemur/
|
||||
|
||||
Finally, activate your virtualenv::
|
||||
|
||||
source /www/lemur/bin/activate
|
||||
|
||||
.. note:: Activating the environment adjusts your PATH, so that things like pip now
|
||||
install into the virtualenv by default.
|
||||
|
||||
|
||||
Installing Lemur
|
||||
----------------
|
||||
|
||||
Once you've got the environment setup, you can install Lemur and all its dependencies with
|
||||
the same command you used to grab virtualenv::
|
||||
|
||||
pip install -U lemur
|
||||
|
||||
Once everything is installed, you should be able to execute the Lemur CLI, via ``lemur``, and get something
|
||||
like the following:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ lemur
|
||||
usage: lemur [--config=/path/to/settings.py] [command] [options]
|
||||
|
||||
|
||||
Installing from Source
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you're installing the Lemur source (e.g. from git), you'll also need to install **npm**.
|
||||
|
||||
Once your system is prepared, symlink your source into the virtualenv:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ python setup.py develop
|
||||
|
||||
.. Note:: This command will install npm dependencies as well as compile static assets.
|
||||
|
||||
|
||||
Creating a configuration
|
||||
------------------------
|
||||
|
||||
Before we run Lemur we must create a valid configuration file for it.
|
||||
|
||||
The Lemur cli comes with a simple command to get you up and running quickly.
|
||||
|
||||
Simply run:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ lemur create_config
|
||||
|
||||
.. Note:: This command will create a default configuration under `~/.lemur/lemur.conf.py` you
|
||||
can specify this location by passing the `config_path` parameter to the `create_config` command.
|
||||
|
||||
You can specify `-c` or `--config` to any Lemur command to specify the current environment
|
||||
you are working in. Lemur will also look under the environmental variable `LEMUR_CONF` should
|
||||
that be easier to setup in your environment.
|
||||
|
||||
Once created you will need to update the configuration file with information about your environment,
|
||||
such as which database to talk to, where keys are stores etc..
|
||||
|
||||
Initializing Lemur
|
||||
------------------
|
||||
|
||||
Lemur provides a helpful command that will initialize your database for you. It creates a default user (lemur) that is
|
||||
used by Lemur to help associate certificates that do not currently have an owner. This is most commonly the case when
|
||||
Lemur has discovered certificates from a third party resource. This is also a default user that can be used to
|
||||
administer Lemur.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ lemur init
|
||||
|
||||
.. 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::
|
||||
This assumes you have already created a postgres database and have specified the right postgres URI in the
|
||||
lemur configuration. See the `Postgres Documentation <http://www.postgresql.org/docs/9.0/static/tutorial-createdb.html>`_
|
||||
for details.
|
||||
|
||||
|
||||
Starting the Web Service
|
||||
------------------------
|
||||
|
||||
Lemur provides a built-in webserver (powered by gunicorn and eventlet) to get you off the ground quickly.
|
||||
|
||||
To start the webserver, you simply use ``lemur start``. If you opted to use an alternative configuration path
|
||||
you can pass that via the --config option.
|
||||
|
||||
::
|
||||
|
||||
# Lemur's server runs on port 5000 by default. Make sure your client reflects
|
||||
# the correct host and port!
|
||||
lemur --config=/etc/lemur.conf.py start
|
||||
|
||||
You should now be able to test the web service by visiting `http://localhost:5000/`.
|
||||
|
||||
Setup a Reverse Proxy
|
||||
---------------------
|
||||
|
||||
By default, Lemur runs on port 5000. Even if you change this, under normal conditions you won't be able to bind to
|
||||
port 80. To get around this (and to avoid running Lemur as a privileged user, which you shouldn't), we recommend
|
||||
you setup a simple web proxy.
|
||||
|
||||
Proxying with Nginx
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You'll use the builtin HttpProxyModule within Nginx to handle proxying::
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:5000;
|
||||
proxy_redirect off;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
See :doc:`../production/index` for more details on using Nginx.
|
||||
|
||||
Proxying with Apache
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Apache requires the use of mod_proxy for forwarding requests::
|
||||
|
||||
ProxyPass / http://localhost:5000/
|
||||
ProxyPassReverse / http://localhost:5000/
|
||||
ProxyPreserveHost On
|
||||
RequestHeader set X-Forwarded-Proto "https" env=HTTPS
|
||||
|
||||
You will need to enable ``headers``, ``proxy``, and ``proxy_http`` apache modules to use these settings.
|
||||
|
||||
See :doc:`../production/index` for more details on using Apache.
|
||||
|
||||
|
||||
Running Lemur as a Service
|
||||
---------------------------
|
||||
|
||||
We recommend using whatever software you are most familiar with for managing Lemur processes. One option is
|
||||
`Supervisor <http://supervisord.org/>`_.
|
||||
|
||||
Configure ``supervisord``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Configuring Supervisor couldn't be more simple. Just point it to the ``lemur`` executable in your virtualenv's bin/
|
||||
folder and you're good to go.
|
||||
|
||||
::
|
||||
|
||||
[program:lemur-web]
|
||||
directory=/www/lemur/
|
||||
command=/www/lemur/bin/lemur start
|
||||
autostart=true
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
stdout_logfile syslog
|
||||
stderr_logfile syslog
|
||||
|
||||
See :ref:`Using Supervisor <UsingSupervisor>` for more details on using Supervisor.
|
||||
|
||||
Syncing
|
||||
-------
|
||||
|
||||
Lemur uses periodic sync tasks to make sure it is up-to-date with it's environment. As always things can change outside
|
||||
of Lemur, but we do our best to reconcile those changes.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ crontab -e
|
||||
* 3 * * * lemur sync
|
||||
* 3 * * * lemur check_revoked
|
||||
|
||||
Additional Utilities
|
||||
--------------------
|
||||
|
||||
If you're familiar with Python you'll quickly find yourself at home, and even more so if you've used Flask. The
|
||||
``lemur`` command is just a simple wrapper around Flask's ``manage.py``, which means you get all of the
|
||||
power and flexibility that goes with it.
|
||||
|
||||
Some of those which you'll likely find useful are:
|
||||
|
||||
lock
|
||||
~~~~
|
||||
|
||||
Encrypts sensitive key material - This is most useful for storing encrypted secrets in source code.
|
||||
|
||||
unlock
|
||||
~~~~~~
|
||||
|
||||
Decrypts sensitive key material - Used to decrypt the secrets stored in source during deployment.
|
||||
|
||||
|
||||
What's Next?
|
||||
------------
|
||||
|
||||
The above gets you going, but for production there are several different security considerations to take into account,
|
||||
remember Lemur is handling sensitive data and security is imperative.
|
||||
|
||||
See :doc:`../production/index` for more details on how to configure Lemur for production.
|
||||
|
Reference in New Issue
Block a user