Git Product home page Git Product logo

privacyidea-docker's Introduction

Docker

privacyIDEA-docker

Simply deploy and run a privacyIDEA instance in a container environment.

Overview

privacyIDEA is an open solution for strong two-factor authentication like OTP tokens, SMS, smartphones or SSH keys.

This project is a complete build environment under linux to build and run privacyIDEA in a container environment. It uses the official python image and the official privacyIDEA-Project from PyPi. The image uses gunicorn to run the app.

The main goals of this project are to:

  • Give an idea how to run privacyIDEA in a container.
  • Build and run the container image, simple and fast.
  • Deploy different versions and/or stages (e.g. production, staging, devel ...) with the same or different configuration on the same host.
  • Easy deploy a "full-stack" (e.g. privacyIDEA, radius, database and reverse proxy) with docker compose.
  • Keep the container's image simple and slim.
  • Build images with no changes to the original privacyIDEA code and few additional scripts as possible inside the image to run the container.

What this project is not:

  • A fully tested and "production-ready" installation of privacyIDEA for your container environment.
  • A possible way to ignore the privacyIDEA Documentation
  • A guide on how to use docker
  • The "one and only" or "best" method to run privacyIDEA in a container.
  • Finished ;)

Note

The image does not include a reverse proxy or a database backend. Running the default image as a standalone container uses gunicorn and a sqlite database. This is not suitable for a production environment.

A more 'real-world' scenario, which is often used, is described in the Compose a privacyIDEA stack section.

Also check the Security considerations before running the image or stack in a production environment.

While decoupling the privacyIDEA image from dependencies like Nginx, Apache or database vendors, it is possible to run privacyIDEA with your favorite components.

If you prefer another approach or would like to test another solution, take a look at the Khalibre / privacyidea-docker project. This project might be a more suitable solution for your needs.

tl;dr

Clone repository and start a full privacyIDEA stack:

git clone https://github.com/gpappsoft/privacyidea-docker.git
cd privacyidea-docker
make cert secret fullstack

Repository

Directory Description
conf contains pi.cfg and logging.cfg files which is included in the image build process.
secrets contains the secrets for docker compose - this project tries to avoid using env-vars for sensitive data (passwords)
scripts contains custom scripts for the script-handler. Will be mounted into the container when compose a stack. Scripts must be executable (chmod +x)
environment contains different example-environment files for a whole stack via docker compose
ssl contains ssl certificates for the reverse-proxy. Replace it with your own certificate and key file. Use PEM-Format without a passphrase. *.pfx is not supported. Name must be pi.pem and pi.key
templates contains files used for different services (nginx, radius ...)

Images

Sample images from this project can be found here:

registry repository
docker.io docker pull docker.io/gpappsoft/privacyidea-docker:latest
ghcr.io docker pull ghcr.io/gpappsoft/privacyidea-docker:latest

Note

latest tagged image is maybe a pre- or development-release. Please use always a release number (like 3.9.2)

Quickstart

Prerequisites and requirements

  • Installed a container runtime engine (docker / podman).
  • Installed BuildKit, buildx and Compose V2 (docker-compose-v2) components
  • The repository is tested with versions listed in COMPAT.md
  • Podman is partially supported. Please refer to PODMAN.md for more details.

Quick & Dirty

docker pull docker.io/gpappsoft/privacyidea-docker:3.9.2
docker run -d --name privacyidea-docker\
            -e PI_REGISTRY_CLASS=null\
            -e DB_PASSWORD=null\
            -e PI_BOOTSTRAP=true\
            -e PI_PEPPER=null\
            -e PI_SECRET=null\
			-v pi-pilog:/var/log/privacyidea:rw,Z\
			-v pi-piconfig:/etc/privacyidea:rw,Z\
			-p 8080:8080\
			gpappsoft/privacyidea-docker:3.9.2

Web-UI: http://localhost:8080

user/password: admin / admin

Preferred way

To build and run a simple local privacyIDEA container (which can run standalone with sqlite):

git clone https://github.com/gpappsoft/privacyidea-docker.git
cd privacyidea-docker
make cert secret build run
....

Answer the following question with a y:

Warning! Overwrite ALL SECRETS  in ./secrets directory: Are you sure? [y/N] y
Accessing the Web-UI:

Use https://localhost:8080

Default admin username: admin

Default admin password is stored in ./secrets/pi_admin_pass

Build images

You can use Makefile targets to build different images with different privacyIDEA versions.

Build a specific privacyIDEA version

make build PI_VERSION=3.8.1

Push to a registry

Use make push [REGISTRY=<registry>]to tag and push the image1

Example

Push image to local registry on port 50002

make push REGISTRY=localhost:5000

Remove the container:

make clean

You can start the container with the same database (sqlite) and configuration and use make run again without bootstrapping the instance.

Remove the container including volumes:

make distclean

ⓘ This will wipe the whole container including the volumes!

Overview make targets

target optional ARGS description example
build PI_VERSION
IMAGE_NAME
Build an image. Optional: specify the version and image name make build PI_VERSION=3.9.2
push REGISTRY Tag and push the image to the registry. Optional: specify the registry URI. Defaults to localhost:5000 make push REGISTRY=docker.io/gpappsoft/privacyidea-docker
run PORT
TAG
Run a standalone container with gunicorn and sqlite. Optional: specify the prefix tag of the container name and listen port. Defaults to pi and port 8080 make run TAG=prod PORT=8888
secret Generate and overwrite secrets in ./secrets make secret
cert Generate a self-signed certificate for the reverse proxy container in ./ssl. and overwrite the existing one make secret
stack TAG PROFILE Run a whole stack with the environment file environment/application-TAG.env. Default is prod. Possible PROFILE values: stack,fullstack,ldap,radius make stack, make stack TAG=dev PROFILE=fullstack , make stack TAG=prod PROFILE=stack,radius
clean TAG Remove the container and network without removing the named volumes. Optional: change prefix tag of the container name. Defaults to pi make clean TAG=prod
distclean TAG Remove the container, network and named volumes. Optional: change prefix tag of the container name. Defaults to pi make distclean TAG=prod

Important

Using the image as a standalone container is not production ready. For a more like 'production ready' instance, please refer to the next section.

Compose a privacyIDEA stack

By using docker compose you can easily deploy a customized privacyIDEA instance, including Nginx as a reverse-proxy and MariaDB as a database backend.

With the use of different environment files for different full-stacks, you can deploy and run multiple stacks at the same time on different ports.

graph TD;
  a2("--env-file=environment/application-dev.env");
  w4(https://localhost:8444);
  w5(RADIUS  2812);
  w6(LDAP 2389);
  subgraph s3 [ ];
       r2(RADIUS);
       n5(NGINX);
       n6(LDAP);
       n7(privacyIDEA);
       n8(MariaDB);
  st2[stack 2];
  end;
  
  a1("--env-file=environment/application-prod.env");
  w1(https://localhost:8443);
  w2(RADIUS 1812);
  w3(LDAP 1389);
  subgraph s1 [ ];
       r1(RADIUS);
       n1(NGINX);
       n2(LDAP);
       n3(privacyIDEA);
       n4(MariaDB);
  st1[Stack 1];
  end;
  
  a1~~~w1;
  a1~~~w2;
  a1~~~w3;

  a2~~~w4;
  a2~~~w5;
  a2~~~w6;

  w1<-- API / WebUI -->n1<-- reverse proxy -->n3(privacyIDEA)<-->n4
  w2<-- radius auth -->r1<-- privacyIDEA Radius -->n3
  w3<-- for clients -->n2<-- resolver -->n3

  w4<-- API / WebUI -->n5<-- reverse proxy -->n7(privacyIDEA)<-->n8
  w5<-- radius auth -->r2<-- privacyIDEA Radius -->n7
  w6<-- for clients -->n6<-- resolver -->n7

  classDef plain font-size:12px,fill:#ddd,stroke:#fff,stroke-width:4px,color:#000;
  classDef heading font-size:12px,fill:#9db668,stroke:#fff,stroke-width:1px,color:#fff;
  classDef title font-size:16px,color:#000,background-color:#9db668,stroke:#ffff;
  classDef docker fill:#265a88,stroke:#fff,stroke-width:2px,color:#fff;
  classDef second fill:#dba614,stroke:#fff,stroke-width:2px,color:#fff;
  classDef tags fill:#dba614,stroke:#fff,stroke-width:2px,color:#fff;
  classDef cluster fill:#fff,stroke:#888,stroke-width:2px,color:#265a88;
  class w1,w2,w3,w4,w5,w6 plain;
  class r1,n2,r2,n6 second;
  class n1,n3,n4,n5,n6,n7,n8,r2,t1 docker;
  class s1,s2,s3,s4 title;
  class a1,a2,st1,st2 heading;

Find example .env files in the environment directory.

Note

The optional RADIUS and LDAP container is only available with PROFILE=fullstack|ldap|radius. See examples below.


Examples:

Note

The docker-compose.yaml, used in this example, always use images from external registries. Change docker-compose.yaml to use your own images.

Run a stack with project the name prod and environment variables files from environment/application-prod.env

  $ make cert secret  #run only once to generate certificate and secrets
  $ PI_BOOTSTRAP=true docker compose --env-file=environment/application-prod.env -p prod up

Or simple run a maketarget.

This example will start a stack including privacyIDEA, reverse_proxy and mariadb container:

make cert secret stack

This example will start a full stack including privacyIDEA, reverse_proxy, mariadb, ldap and radius. Project tag is prod

make cert secret stack PROFILE=fullstack TAG=prod

Note

The ldap have sample users. The resolvers and realm are already configured in privacyIDEA when stack is ready.

Shutdown the stack with the project name prod and remove all resources (container,networks, etc.) except the volumes.

docker compose -p prod down 

You can start the stack in the background with console detached using the -d parameter.

  $ PI_BOOTSTRAP=true docker compose --env-file=environment/application-prod.env -p prod up -d

Full example including build with maketargets:

make cert secret build push stack PI_VERSION=3.9.2 TAG=pidev

Now you can deploy additional containers like OpenLDAP for user realms or Owncloud as a client to test 2FA authentication.

Have fun!

Important

  • Volumes will not be deleted.
  • Currently same secrets from ./secrets/ are used for every stack. Future releases will change this behavior.
  • Delete the /etc/privacyidea/BOOTSTRAP file *inside the privacyIDEA container if you want to bootstrap again. This will not delete an existing database!
  • Compose takes some additional time (~1 minute) because of health-checks.

Environment Variables

privacyIDEA

Variable Default Description
ENVIRONMENT environment/application-prod.env Used to set the correct environment file (env_file) in the docker compose, which is used by the container. Use a relative filename here.
PI_VERSION 3.9.2 Set the used image version
PI_BOOTSTRAP false Set to true to create database tables on the first start of the container. If you need to re-run, then you have to delete the /etc/privacyidea/BOOTSTRAP file inside the container.
PI_UPDATE false Set to true to run the database schema upgrade script in case of a new privacyIDEA version.
PI_PASSWORD admin Don't use this in productive environments. Use secrets with docker compose / docker swarm instead. See Security considerations for more information.
PI_ADMIN admin login name of the initial administrator
PI_PORT 8080 Port used by gunicorn. Don't use this directly in productive environments. Use a reverse proxy..
PI_LOGLEVEL INFO Log level in uppercase (DEBUG, INFO, WARNING, ect.). docker log is always INFO level because of security. See conf/logging.cfg for more details
SUPERUSER_REALM "admin,helpdesk" Admin realms, which can be used for policies in privacyIDEA. Comma separated list. See the privacyIDEA documentation for more information.
PI_SQLALCHEMY_ENGINE_OPTIONS False Set pool_pre_ping option. Set to True for DB clusters (like Galera).
PI_PEPPER /run/secrets/pi_pepper Used for PI_PEPPER in pi.cfg. The filename, including the path, to the file inside the container, with the secret. Use make secrets to generate new secret file. See Security considerations for more information.
SECRET_KEY /run/secrets/pi_secret Used for SECRET_KEY in pi.cfg. The filename, including the path, to the file inside the container, with the secret. Use make secrets to generate new secret file. See Security considerations for more information.

DB connection parameters

Variable Description
DB_HOST Database host
DB_PORT Database port
DB_NAME Database name
DB_USER Database user
DB_PASSWORD The filename, including the path, to the file inside the container, with the database password.
DB_API Database driver (e.g. mysql+pymysql)
DB_EXTRA_PARAM Extra parameter (e.g. "?charset=utf8"). Will be appended to the SQLAlchemy URI (see pi.cfg)

Reverse proxy parameters (for compose/stack)

Variable Default Description
PROXY_PORT 8443 Exposed HTTPS port
PROXY_SERVERNAME localhost Set the reverse-proxy server name. Should be the common name used in the certificate.

RADIUS parameters (for compose/fullstack)

Variable Default Description
RADIUS_PORT 1812 Exposed (external) radius port tcp/udp
RADIUS_PORT 1813 Additional exposed (external) radius port udp

LDAP parameters (for compose/fullstack)

Variable Default Description
LDAP_PORT 1389 Exposed (external) ldap port

Secrets used by docker compose located in secrets/

Filename Default Description
db_password superSecret The database password
pi_admin_pass admin The password for the initial admin
pi_pepper superSecret The PI_PEPPER secret for pi.cfg
pi_secret superSecret The SECRET_KEY secret for pi.cfg

Other values (for compose/fullstack)

  • Openldap admin user: cn=admin,dc=example,dc=org with password openldap
  • Password for ldap user always givenName in lowercase (e.g. Sandra Bullock = sandra)
  • Additional user helpdesk with password helpdesk and admin with password admin available in ldap

Security considerations

Secrets

The current concept of using secrets with files in docker-compose.yaml is a first approach to reducing the risk of using secrets with environment variables. This may change in future versions.

Different stacks always use the same secrets.

Known Bugs

  • unkown

Frequently Asked Questions

Why are not all pi.cfg parameters available as environment variables?

  • I only included the most essential and often-used parameters. You can add more variables to the conf/pi.conf file and build your own image.

Why not include the scripts for the script-handler in the image?

  • The image should only contain a bare privacyIDEA without custom data. You can add them to the Dockerfile file and build your own image.

How can I rotate the audit log?

  • Simply use a cron job on the host system with docker exec and the pi-manage command:
docker exec -it pi-privacyidea-1 pi-manage audit rotate_audit --age 90

How can i access the logs?

  • Use docker log or use the logfile:
docker logs pi-privacyidea-1 
docker exec -it pi-privacyidea-1 cat /var/log/privacyidea/privacyidea.log

How can I update the container to a new privacyIDEA version?

  • Build a new image, make a push and pull. Re-create the container with PI_UPDATE=true. This will run the schema update script to update the database.

Can I import a privacyIDEA database dump into the database container from the stack?

  • Yes, by providing the sql dump to the db container. Please refer to the "Initializing the database contents" section from the official MariaDB docker documentation.

Help! make build does not work, how can i fix it?

DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
curl -SL https://github.com/docker/buildx/releases/download/v0.12.0/buildx-v0.12.0.linux-amd64 -o $DOCKER_CONFIG/cli-plugins/docker-buildx
chmod +x $DOCKER_CONFIG/cli-plugins/docker-{buildx,compose}

Help! Stack is not starting because of an error like permission denied. How can I fix it?

Check selinux and change the permissions like:

chcon -R -t container_file_t PATHTOHOSTDIR

PATHTOHOSTDIR should point to the privacyidea-docker folder.

Help! Error response from daemon: invalid mount config for type "bind": bind source path does not exist: ..., how can I fix it?

Check if the required certificates (pi.key / pi.pem) exists in ssl/

Help! make pushdoes not work with my local registry, how can I fix it?

  • Maybe you try to use ssl: Use the insecure option in your /etc/containers/registries.conf:
    [[registry]]
    prefix="localhost"
    location="localhost:5000"
    insecure=true
    

How can I create a backup of my data?

  • The pi-manage backup command is not working. You have to dump the database manually. For the example stack, use the db container:
docker exec -it pi-db-1 mariadb-dump -u pi -psuperSecret pi
  • enckey/config, certificates and logs stored in the named volumes *_piconfig *_pilog

Roadmap

Customization and scripts

Support for customization comming soon.

Radius

A first release of a Freeradius image with the privacyIDEA-RADIUS plugin is in progress.

Any feedback are welcome!

Disclaimer

This project is my private project doing in my free time. This project is not from the NetKnights company. The project uses the open-source version of privacyIDEA. There is no official support from NetKnights for this project.

Footnotes

  1. If you push to external registries, you may have to login first.

  2. You can run your own local registry with:
    docker run -d -p 5000:5000 --name registry registry:2.7

privacyidea-docker's People

Contributors

gpappsoft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

pablo-knight

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.