forked from Github-Mirrors/canaille
doc: split installation page
This commit is contained in:
parent
6dac4a1ca8
commit
c362f0256f
5 changed files with 182 additions and 168 deletions
|
@ -1,11 +1,12 @@
|
||||||
Backends
|
Backends
|
||||||
#############
|
#############
|
||||||
|
|
||||||
|
Canaille can read and save data in different databases.
|
||||||
|
This page presents the different database backends and their specificities:
|
||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
:local:
|
:local:
|
||||||
|
|
||||||
Canaille can read and save data in different databases:
|
|
||||||
|
|
||||||
Memory
|
Memory
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|
10
doc/conf.py
10
doc/conf.py
|
@ -27,6 +27,7 @@ sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
|
||||||
|
|
||||||
extensions = [
|
extensions = [
|
||||||
"sphinx.ext.autodoc",
|
"sphinx.ext.autodoc",
|
||||||
|
"sphinx.ext.autosectionlabel",
|
||||||
"sphinx.ext.doctest",
|
"sphinx.ext.doctest",
|
||||||
"sphinx.ext.graphviz",
|
"sphinx.ext.graphviz",
|
||||||
"sphinx.ext.intersphinx",
|
"sphinx.ext.intersphinx",
|
||||||
|
@ -52,6 +53,10 @@ todo_include_todos = False
|
||||||
|
|
||||||
intersphinx_mapping = {
|
intersphinx_mapping = {
|
||||||
"python": ("https://docs.python.org/3", None),
|
"python": ("https://docs.python.org/3", None),
|
||||||
|
"authlib": ("https://docs.authlib.org/en/latest", None),
|
||||||
|
"flask": ("https://flask.palletsprojects.com", None),
|
||||||
|
"flask-babel": ("https://python-babel.github.io/flask-babel", None),
|
||||||
|
"flask-wtf": ("https://flask-wtf.readthedocs.io", None),
|
||||||
}
|
}
|
||||||
|
|
||||||
issues_uri = "https://gitlab.com/yaal/canaille/-/issues/{issue}"
|
issues_uri = "https://gitlab.com/yaal/canaille/-/issues/{issue}"
|
||||||
|
@ -94,3 +99,8 @@ texinfo_documents = [
|
||||||
"Miscellaneous",
|
"Miscellaneous",
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# -- Options for autosectionlabel -----------------------------------------
|
||||||
|
|
||||||
|
autosectionlabel_prefix_document = True
|
||||||
|
autosectionlabel_maxdepth = 2
|
||||||
|
|
165
doc/deployment.rst
Normal file
165
doc/deployment.rst
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
Deployment
|
||||||
|
##########
|
||||||
|
|
||||||
|
Application service
|
||||||
|
===================
|
||||||
|
|
||||||
|
After having finished Canaille installation you have to run it in a WSGI application server.
|
||||||
|
Here are some WSGI server configuration examples you can pick. Do not forget to update the paths.
|
||||||
|
|
||||||
|
gunicorn
|
||||||
|
--------
|
||||||
|
|
||||||
|
TBD
|
||||||
|
|
||||||
|
uwsgi
|
||||||
|
-----
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[uwsgi]
|
||||||
|
virtualenv=/opt/canaille/env
|
||||||
|
socket=/etc/canaille/uwsgi.sock
|
||||||
|
plugin=python3
|
||||||
|
module=canaille:create_app()
|
||||||
|
lazy-apps=true
|
||||||
|
master=true
|
||||||
|
processes=1
|
||||||
|
threads=10
|
||||||
|
need-app=true
|
||||||
|
thunder-lock=true
|
||||||
|
touch-chain-reload=/etc/canaille/uwsgi-reload.fifo
|
||||||
|
enable-threads=true
|
||||||
|
reload-on-rss=1024
|
||||||
|
worker-reload-mercy=600
|
||||||
|
buffer-size=65535
|
||||||
|
disable-write-exception = true
|
||||||
|
env = CONFIG=/etc/canaille/config.toml
|
||||||
|
|
||||||
|
Webserver
|
||||||
|
=========
|
||||||
|
|
||||||
|
Now you have to plug your WSGI application server to your webserver so it is accessible on the internet.
|
||||||
|
Here are some webserver configuration examples you can pick:
|
||||||
|
|
||||||
|
Nginx
|
||||||
|
-----
|
||||||
|
|
||||||
|
.. code-block:: nginx
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name auth.mydomain.tld;
|
||||||
|
return 301 https://$server_name$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
server_name auth.mydomain.tld;
|
||||||
|
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/moncompte.nubla.fr/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/moncompte.nubla.fr/privkey.pem;
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
|
||||||
|
ssl_session_tickets off;
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
ssl_stapling on;
|
||||||
|
ssl_stapling_verify on;
|
||||||
|
|
||||||
|
index index.html index.php;
|
||||||
|
charset utf-8;
|
||||||
|
client_max_body_size 10M;
|
||||||
|
|
||||||
|
access_log /opt/canaille/logs/nginx.access.log;
|
||||||
|
error_log /opt/canaille/logs/nginx.error.log;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_comp_level 4;
|
||||||
|
gzip_min_length 256;
|
||||||
|
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
||||||
|
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
||||||
|
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header Referrer-Policy "same-origin" always;
|
||||||
|
|
||||||
|
location /static {
|
||||||
|
root /opt/canaille/src/canaille;
|
||||||
|
|
||||||
|
location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|woff2|svg)$ {
|
||||||
|
access_log off;
|
||||||
|
expires 30d;
|
||||||
|
add_header Cache-Control public;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
include uwsgi_params;
|
||||||
|
uwsgi_pass unix:/etc/canaille/uwsgi.sock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Apache
|
||||||
|
------
|
||||||
|
|
||||||
|
TBD
|
||||||
|
|
||||||
|
Recurrent jobs
|
||||||
|
==============
|
||||||
|
|
||||||
|
You might want to clean up your database to avoid it growing too much. You can regularly delete
|
||||||
|
expired tokens and authorization codes with:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
env CONFIG="$CANAILLE_CONF_DIR/config.toml" FLASK_APP=canaille "$CANAILLE_INSTALL_DIR/env/bin/canaille" clean
|
||||||
|
|
||||||
|
|
||||||
|
Webfinger
|
||||||
|
=========
|
||||||
|
|
||||||
|
You may want to configure a `WebFinger`_ endpoint on your main website to allow the automatic discovery of your Canaille installation based on the account name of one of your users. For instance, suppose your domain is ``mydomain.tld`` and your Canaille domain is ``auth.mydomain.tld`` and there is a user ``john.doe``. A third-party application could require to authenticate the user and ask them for a user account. The user would give their account ``john.doe@mydomain.tld``, then the application would perform a WebFinger request at ``https://mydomain.tld/.well-known/webfinger`` and the response would contain the address of the authentication server ``https://auth.mydomain.tld``. With this information the third party application can redirect the user to the Canaille authentication page.
|
||||||
|
|
||||||
|
The difficulty here is that the WebFinger endpoint must be hosted at the top-level domain (i.e. ``mydomain.tld``) while the authentication server might be hosted on a sublevel (i.e. ``auth.mydomain.tld``). Canaille provides a WebFinger endpoint, but if it is not hosted at the top-level domain, a web redirection is required on the ``/.well-known/webfinger`` path.
|
||||||
|
|
||||||
|
Nginx
|
||||||
|
-----
|
||||||
|
|
||||||
|
.. code-block:: nginx
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443;
|
||||||
|
server_name mydomain.tld;
|
||||||
|
rewrite ^/.well-known/webfinger https://auth.mydomain.tld/.well-known/webfinger permanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
Apache
|
||||||
|
------
|
||||||
|
|
||||||
|
.. code-block:: apache
|
||||||
|
|
||||||
|
<VirtualHost *:443>
|
||||||
|
ServerName mydomain.tld
|
||||||
|
RewriteEngine on
|
||||||
|
RewriteRule "^/.well-know/webfinger" "https://auth.mydomain.tld/.well-known/webfinger" [R,L]
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
|
Create your first user
|
||||||
|
======================
|
||||||
|
|
||||||
|
Once canaille is installed, you have several ways to populate the database. The obvious one is by adding
|
||||||
|
directly users and group into your LDAP directory. You might also want to temporarily enable then
|
||||||
|
``ENABLE_REGISTRATION`` configuration parameter to allow you to create your first users. Then, if you
|
||||||
|
have configured your ACLs properly then you will be able to manage users and groups through the Canaille
|
||||||
|
interface.
|
||||||
|
|
||||||
|
.. _WebFinger: https://www.rfc-editor.org/rfc/rfc7033.html
|
|
@ -35,6 +35,7 @@ Table of contents
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
install
|
install
|
||||||
|
deployment
|
||||||
backends
|
backends
|
||||||
configuration
|
configuration
|
||||||
troubleshooting
|
troubleshooting
|
||||||
|
|
169
doc/install.rst
169
doc/install.rst
|
@ -45,10 +45,10 @@ Choose a path where to store your configuration file. You can pass any configura
|
||||||
sudo mkdir --parents "$CANAILLE_CONF_DIR"
|
sudo mkdir --parents "$CANAILLE_CONF_DIR"
|
||||||
sudo cp $CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/config.sample.toml "$CANAILLE_CONF_DIR/config.toml"
|
sudo cp $CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/config.sample.toml "$CANAILLE_CONF_DIR/config.toml"
|
||||||
|
|
||||||
You should then edit your configuration file to adapt the values to your needs.
|
You should then edit your configuration file to adapt the values to your needs. Look at the configuration details in the :doc:`configuration` page.
|
||||||
|
|
||||||
Installation
|
Install and check
|
||||||
============
|
=================
|
||||||
|
|
||||||
Automatic schemas installation
|
Automatic schemas installation
|
||||||
------------------------------
|
------------------------------
|
||||||
|
@ -112,166 +112,3 @@ After a manual installation, you can check your configuration file with the foll
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
env CONFIG="$CANAILLE_CONF_DIR/config.toml" "$CANAILLE_INSTALL_DIR/env/bin/canaille" check
|
env CONFIG="$CANAILLE_CONF_DIR/config.toml" "$CANAILLE_INSTALL_DIR/env/bin/canaille" check
|
||||||
|
|
||||||
Application service
|
|
||||||
===================
|
|
||||||
|
|
||||||
Finally you have to run canaille in a WSGI application server.
|
|
||||||
Here are some WSGI server configuration examples you can pick. Do not forget to update the paths.
|
|
||||||
|
|
||||||
gunicorn
|
|
||||||
--------
|
|
||||||
|
|
||||||
TBD
|
|
||||||
|
|
||||||
uwsgi
|
|
||||||
-----
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[uwsgi]
|
|
||||||
virtualenv=/opt/canaille/env
|
|
||||||
socket=/etc/canaille/uwsgi.sock
|
|
||||||
plugin=python3
|
|
||||||
module=canaille:create_app()
|
|
||||||
lazy-apps=true
|
|
||||||
master=true
|
|
||||||
processes=1
|
|
||||||
threads=10
|
|
||||||
need-app=true
|
|
||||||
thunder-lock=true
|
|
||||||
touch-chain-reload=/etc/canaille/uwsgi-reload.fifo
|
|
||||||
enable-threads=true
|
|
||||||
reload-on-rss=1024
|
|
||||||
worker-reload-mercy=600
|
|
||||||
buffer-size=65535
|
|
||||||
disable-write-exception = true
|
|
||||||
env = CONFIG=/etc/canaille/config.toml
|
|
||||||
|
|
||||||
Webserver
|
|
||||||
=========
|
|
||||||
|
|
||||||
Now you have to plug your WSGI application server to your webserver so it is accessible on the internet.
|
|
||||||
Here are some webserver configuration examples you can pick:
|
|
||||||
|
|
||||||
Nginx
|
|
||||||
-----
|
|
||||||
|
|
||||||
.. code-block:: nginx
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
listen [::]:80;
|
|
||||||
server_name auth.mydomain.tld;
|
|
||||||
return 301 https://$server_name$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
server_name auth.mydomain.tld;
|
|
||||||
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/moncompte.nubla.fr/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/moncompte.nubla.fr/privkey.pem;
|
|
||||||
ssl_session_timeout 1d;
|
|
||||||
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
|
|
||||||
ssl_session_tickets off;
|
|
||||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
|
||||||
ssl_prefer_server_ciphers off;
|
|
||||||
ssl_stapling on;
|
|
||||||
ssl_stapling_verify on;
|
|
||||||
|
|
||||||
index index.html index.php;
|
|
||||||
charset utf-8;
|
|
||||||
client_max_body_size 10M;
|
|
||||||
|
|
||||||
access_log /opt/canaille/logs/nginx.access.log;
|
|
||||||
error_log /opt/canaille/logs/nginx.error.log;
|
|
||||||
|
|
||||||
gzip on;
|
|
||||||
gzip_vary on;
|
|
||||||
gzip_comp_level 4;
|
|
||||||
gzip_min_length 256;
|
|
||||||
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
|
||||||
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
|
||||||
|
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
|
||||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
||||||
add_header X-XSS-Protection "1; mode=block" always;
|
|
||||||
add_header X-Content-Type-Options "nosniff" always;
|
|
||||||
add_header Referrer-Policy "same-origin" always;
|
|
||||||
|
|
||||||
location /static {
|
|
||||||
root /opt/canaille/src/canaille;
|
|
||||||
|
|
||||||
location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|woff2|svg)$ {
|
|
||||||
access_log off;
|
|
||||||
expires 30d;
|
|
||||||
add_header Cache-Control public;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
include uwsgi_params;
|
|
||||||
uwsgi_pass unix:/etc/canaille/uwsgi.sock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Apache
|
|
||||||
------
|
|
||||||
|
|
||||||
TBD
|
|
||||||
|
|
||||||
Recurrent jobs
|
|
||||||
==============
|
|
||||||
|
|
||||||
You might want to clean up your database to avoid it growing too much. You can regularly delete
|
|
||||||
expired tokens and authorization codes with:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
env CONFIG="$CANAILLE_CONF_DIR/config.toml" FLASK_APP=canaille "$CANAILLE_INSTALL_DIR/env/bin/canaille" clean
|
|
||||||
|
|
||||||
|
|
||||||
Webfinger
|
|
||||||
=========
|
|
||||||
|
|
||||||
You may want to configure a `WebFinger`_ endpoint on your main website to allow the automatic discovery of your Canaille installation based on the account name of one of your users. For instance, suppose your domain is ``mydomain.tld`` and your Canaille domain is ``auth.mydomain.tld`` and there is a user ``john.doe``. A third-party application could require to authenticate the user and ask them for a user account. The user would give their account ``john.doe@mydomain.tld``, then the application would perform a WebFinger request at ``https://mydomain.tld/.well-known/webfinger`` and the response would contain the address of the authentication server ``https://auth.mydomain.tld``. With this information the third party application can redirect the user to the Canaille authentication page.
|
|
||||||
|
|
||||||
The difficulty here is that the WebFinger endpoint must be hosted at the top-level domain (i.e. ``mydomain.tld``) while the authentication server might be hosted on a sublevel (i.e. ``auth.mydomain.tld``). Canaille provides a WebFinger endpoint, but if it is not hosted at the top-level domain, a web redirection is required on the ``/.well-known/webfinger`` path.
|
|
||||||
|
|
||||||
Nginx
|
|
||||||
-----
|
|
||||||
|
|
||||||
.. code-block:: nginx
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 443;
|
|
||||||
server_name mydomain.tld;
|
|
||||||
rewrite ^/.well-known/webfinger https://auth.mydomain.tld/.well-known/webfinger permanent;
|
|
||||||
}
|
|
||||||
|
|
||||||
Apache
|
|
||||||
------
|
|
||||||
|
|
||||||
.. code-block:: apache
|
|
||||||
|
|
||||||
<VirtualHost *:443>
|
|
||||||
ServerName mydomain.tld
|
|
||||||
RewriteEngine on
|
|
||||||
RewriteRule "^/.well-know/webfinger" "https://auth.mydomain.tld/.well-known/webfinger" [R,L]
|
|
||||||
</VirtualHost>
|
|
||||||
|
|
||||||
Create your first user
|
|
||||||
======================
|
|
||||||
|
|
||||||
Once canaille is installed, you have several ways to populate the database. The obvious one is by adding
|
|
||||||
directly users and group into your LDAP directory. You might also want to temporarily enable then
|
|
||||||
``ENABLE_REGISTRATION`` configuration parameter to allow you to create your first users. Then, if you
|
|
||||||
have configured your ACLs properly then you will be able to manage users and groups through the Canaille
|
|
||||||
interface.
|
|
||||||
|
|
||||||
.. _WebFinger: https://www.rfc-editor.org/rfc/rfc7033.html
|
|
||||||
|
|
Loading…
Reference in a new issue