diff --git a/v3.html b/v3.html index f0c9f5dc..0c23e279 100644 --- a/v3.html +++ b/v3.html @@ -596,6 +596,19 @@ Caddy:
<If "%{HTTPS} =~ /on/"> RequestHeader set X-Forwarded-Proto "https" </If> +Example lighttpd configuration:
+server.modules += ( "mod_proxy" , "mod_setenv", "mod_rewrite" )
+
+$HTTP["url"] =~ "^/radicale/" {
+ proxy.server = ( "" => (( "host" => "127.0.0.1", "port" => "5232" )) )
+ proxy.header = ( "map-urlpath" => ( "/radicale/" => "/" ))
+
+ setenv.add-request-header = (
+ "X-Script-Name" => "/radicale",
+ "Script-Name" => "/radicale",
+ )
+ url.rewrite-once = ( "^/radicale/radicale/(.*)" => "/radicale/$1" )
+}
Be reminded that Radicale's default configuration enforces limits on the maximum number of parallel connections, the maximum file size and the rate of incorrect authentication attempts. Connections are @@ -617,33 +630,33 @@ and disables HTTP authentication.
auth_basic_user_file /etc/nginx/htpasswd; }Example Apache configuration:
-RewriteEngine On
- ^/radicale$ /radicale/ [R,L]
- RewriteRule
-<Location "/radicale/">
-AuthType Basic
- "Radicale - Password Required"
- AuthName "/etc/radicale/htpasswd"
- AuthUserFile valid-user
- Require
- http://localhost:5232/ retry=0
- ProxyPass http://localhost:5232/
- ProxyPassReverse set X-Script-Name /radicale
- RequestHeader set X-Remote-User expr=%{REMOTE_USER}
- RequestHeader</Location>
Example Apache .htaccess configuration:
- disabled
- DirectoryIndexRewriteEngine On
- ^(.*)$ http://localhost:5232/$1 [P,L]
- RewriteRule
-AuthType Basic
- "Radicale - Password Required"
- AuthName "/etc/radicale/htpasswd"
- AuthUserFile valid-user
+ RequireRewriteEngine On
+ ^/radicale$ /radicale/ [R,L]
+ RewriteRule
+<Location "/radicale/">
+AuthType Basic
+ "Radicale - Password Required"
+ AuthName "/etc/radicale/htpasswd"
+ AuthUserFile valid-user
Require
-# Set to directory of .htaccess file:
- set X-Script-Name /radicale
- RequestHeader set X-Remote-User expr=%{REMOTE_USER} RequestHeader
+ http://localhost:5232/ retry=0
+ ProxyPass http://localhost:5232/
+ ProxyPassReverse set X-Script-Name /radicale
+ RequestHeader set X-Remote-User expr=%{REMOTE_USER}
+ RequestHeader</Location>
Example Apache .htaccess configuration:
+ disabled
+ DirectoryIndexRewriteEngine On
+ ^(.*)$ http://localhost:5232/$1 [P,L]
+ RewriteRule
+AuthType Basic
+ "Radicale - Password Required"
+ AuthName "/etc/radicale/htpasswd"
+ AuthUserFile valid-user
+ Require
+# Set to directory of .htaccess file:
+ set X-Script-Name /radicale
+ RequestHeader set X-Remote-User expr=%{REMOTE_USER} RequestHeader
Security: Untrusted clients should not be able to access the Radicale server directly. Otherwise, they can authenticate as @@ -658,16 +671,16 @@ generate a certificate for Radicale and a certificate for the reverse proxy. The following commands generate self-signed certificates. You will be asked to enter additional information about the certificate, the values don't matter and you can keep the defaults.
-+openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem \ --nodes -days 9999 - openssl req -x509 -newkey rsa:4096 -keyout client_key.pem -out client_cert.pem \ --nodes -days 9999
openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem \ +-nodes -days 9999 + openssl req -x509 -newkey rsa:4096 -keyout client_key.pem -out client_cert.pem \ +-nodes -days 9999
Use the following configuration for Radicale:
-+[server] -ssl = True -certificate = /path/to/server_cert.pem -key = /path/to/server_key.pem -certificate_authority = /path/to/client_cert.pem
[server] +ssl = True +certificate = /path/to/server_cert.pem +key = /path/to/server_key.pem +certificate_authority = /path/to/client_cert.pem
Example nginx configuration:
location /radicale/ { proxy_pass https://localhost:5232/; @@ -686,15 +699,15 @@ values don't matter and you can keep the defaults. environment variable, otherwise no configuration file is loaded and the default configuration is used.
Example uWSGI configuration:
-+[uwsgi] -http-socket = 127.0.0.1:5232 -processes = 8 -plugin = python3 -module = radicale -env = RADICALE_CONFIG=/etc/radicale/config
[uwsgi] +http-socket = 127.0.0.1:5232 +processes = 8 +plugin = python3 +module = radicale +env = RADICALE_CONFIG=/etc/radicale/config
Example Gunicorn configuration:
-+gunicorn --bind '127.0.0.1:5232' --env 'RADICALE_CONFIG=/etc/radicale/config' \ ---workers 8 radicale
gunicorn --bind '127.0.0.1:5232' --env 'RADICALE_CONFIG=/etc/radicale/config' \ +--workers 8 radicale
Manage user accounts with the WSGI server ¶
Set the configuration option
.Radicale.tmp-*type
in the @@ -717,9 +730,18 @@ content:The configuration option
-hook
in thestorage
section must be set to the following command:+git add -A && (git diff --cached --quiet || git commit -m "Changes by "%(user)s)
git add -A && (git diff --cached --quiet || git commit -m "Changes by "%(user)s)
The command gets executed after every change to the storage and commits the changes into the git repository.
+For the hook to not cause errors either git user +details need to be set and match the owner of the collections directory +or the repository needs to be marked as safe.
+When using the systemd unit file from the Running as a service section this +cannot be done via a
+.gitconfig
file in +the users home directory, as Radicale won't have read permissions!In
+/var/lib/radicale/collections/.git
run:git config user.name "radicale" +git config user.email "radicale@example.com"
@@ -729,17 +751,17 @@ commits the changes into the git repository. Radicale can be configured with a configuration file or with command line arguments.
An example configuration file looks like:
-+[server] -# Bind all addresses -hosts = 0.0.0.0:5232, [::]:5232 - -[auth] -type = htpasswd -htpasswd_filename = ~/.config/radicale/users -htpasswd_encryption = md5 - -[storage] -filesystem_folder = ~/.var/lib/radicale/collections
[server] +# Bind all addresses +hosts = 0.0.0.0:5232, [::]:5232 + +[auth] +type = htpasswd +htpasswd_filename = ~/.config/radicale/users +htpasswd_encryption = md5 + +[storage] +filesystem_folder = ~/.var/lib/radicale/collections
Radicale tries to load configuration files from
/etc/radicale/config
and~/.config/radicale/config
. Custom paths can be specified @@ -750,9 +772,9 @@ configuration files can be separated by:
(resp. optional.The same example configuration via command line arguments looks like:
-+python3 -m radicale --server-hosts 0.0.0.0:5232,[::]:5232 \ ---auth-type htpasswd --auth-htpasswd-filename ~/.config/radicale/users \ - --auth-htpasswd-encryption md5
python3 -m radicale --server-hosts 0.0.0.0:5232,[::]:5232 \ +--auth-type htpasswd --auth-htpasswd-filename ~/.config/radicale/users \ + --auth-htpasswd-encryption md5
Add the argument
@@ -964,7 +986,7 @@ books and calendars.--config ""
to stop Radicale from loading the default configuration files. Runpython3 -m radicale --help
for more information.In this section additional HTTP headers that are sent to clients can be specified.
An example to relax the same-origin policy:
-+Access-Control-Allow-Origin = *
Access-Control-Allow-Origin = *
@@ -1034,47 +1056,47 @@ documentation of InfCloud has more details on this. calendars and address books. Use Radicale's web interface or a client with support for it (e.g. DAVx⁵). To create a new calendar run something like:
-+$ curl -u user -X MKCOL 'http://localhost:5232/user/calendar' --data \ -'<?xml version="1.0" encoding="UTF-8" ?> -<create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/"> - <set> - <prop> - <resourcetype> - <collection /> - <C:calendar /> - </resourcetype> - <C:supported-calendar-component-set> - <C:comp name="VEVENT" /> - <C:comp name="VJOURNAL" /> - <C:comp name="VTODO" /> - </C:supported-calendar-component-set> - <displayname>Calendar</displayname> - <C:calendar-description>Example calendar</C:calendar-description> - <I:calendar-color>#ff0000ff</I:calendar-color> - </prop> - </set> -</create>'
$ curl -u user -X MKCOL 'http://localhost:5232/user/calendar' --data \ +'<?xml version="1.0" encoding="UTF-8" ?> +<create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/"> + <set> + <prop> + <resourcetype> + <collection /> + <C:calendar /> + </resourcetype> + <C:supported-calendar-component-set> + <C:comp name="VEVENT" /> + <C:comp name="VJOURNAL" /> + <C:comp name="VTODO" /> + </C:supported-calendar-component-set> + <displayname>Calendar</displayname> + <C:calendar-description>Example calendar</C:calendar-description> + <I:calendar-color>#ff0000ff</I:calendar-color> + </prop> + </set> +</create>'
To create a new address book run something like:
-+$ curl -u user -X MKCOL 'http://localhost:5232/user/addressbook' --data \ -'<?xml version="1.0" encoding="UTF-8" ?> -<create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav"> - <set> - <prop> - <resourcetype> - <collection /> - <CR:addressbook /> - </resourcetype> - <displayname>Address book</displayname> - <CR:addressbook-description>Example address book</CR:addressbook-description> - </prop> - </set> -</create>'
$ curl -u user -X MKCOL 'http://localhost:5232/user/addressbook' --data \ +'<?xml version="1.0" encoding="UTF-8" ?> +<create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav"> + <set> + <prop> + <resourcetype> + <collection /> + <CR:addressbook /> + </resourcetype> + <displayname>Address book</displayname> + <CR:addressbook-description>Example address book</CR:addressbook-description> + </prop> + </set> +</create>'
The collection
/USERNAME
will be created automatically, when the user authenticates to Radicale for the first time. Clients with automatic discovery of collections will only show calendars and address books that are direct children of the path/USERNAME/
.Delete the collections by running something like:
-+curl -u user -X DELETE 'http://localhost:5232/user/calendar'
curl -u user -X DELETE 'http://localhost:5232/user/calendar'
@@ -1089,24 +1111,24 @@ to calendars and address books outside the home directory of users collections and will not show them to the user. This is only useful if you access calendars and address books directly via URL. An example rights file:
-+# Allow reading root collection for authenticated users -[root] -user: .+ -collection: -permissions: r - -# Allow reading and writing principal collection (same as username) -[principal] -user: .+ -collection: {user} -permissions: RW - -# Allow reading and writing calendars and address books that are direct -# children of the principal collection -[calendars] -user: .+ -collection: {user}/[^/]+ -permissions: rw
# Allow reading root collection for authenticated users +[root] +user: .+ +collection: +permissions: r + +# Allow reading and writing principal collection (same as username) +[principal] +user: .+ +collection: {user} +permissions: RW + +# Allow reading and writing calendars and address books that are direct +# children of the principal collection +[calendars] +user: .+ +collection: {user}/[^/]+ +permissions: rw
The titles of the sections are ignored (but must be unique). The keys
user
andcollection
contain regular expressions, that are matched against the username and the path of the @@ -1185,10 +1207,10 @@ system. The storage is locked with exclusive access while theLinux shell scripts ¶
Use the flock utility.
-+# Exclusive -$ flock --exclusive /path/to/storage/.Radicale.lock COMMAND -# Shared -$ flock --shared /path/to/storage/.Radicale.lock COMMAND
# Exclusive +$ flock --exclusive /path/to/storage/.Radicale.lock COMMAND +# Shared +$ flock --shared /path/to/storage/.Radicale.lock COMMAND
Linux and MacOS ¶
@@ -1213,11 +1235,11 @@ folder in the file system storage (e.g. clients that the collection is a calendar, you have to create the file.Radicale.props
with the following content in the folder: -+{"tag": "VCALENDAR"}
{"tag": "VCALENDAR"}
The calendar is now available at the URL path
-/user/calendar
. For address books the file must contain:+{"tag": "VADDRESSBOOK"}
{"tag": "VADDRESSBOOK"}
Calendar and address book collections must not have any child collections. Clients with automatic discovery of collections will only show calendars and address books that are direct children of the path @@ -1348,49 +1370,49 @@ password.
modules is Distutils. For a minimal setup create the filesetup.py
with the following content in an empty folder: -+#!/usr/bin/env python3 - -from distutils.core import setup - -="radicale_static_password_auth", - setup(name=["radicale_static_password_auth"]) packages
#!/usr/bin/env python3 + +from distutils.core import setup + +="radicale_static_password_auth", + setup(name=["radicale_static_password_auth"]) packages
In the same folder create the sub-folder
radicale_static_password_auth
. The folder must have the same name as specified inpackages
above.Create the file
-__init__.py
in theradicale_static_password_auth
folder with the following content:+from radicale.auth import BaseAuth -from radicale.log import logger - -= {"auth": { - PLUGIN_CONFIG_SCHEMA "password": {"value": "", "type": str}}} - - -class Auth(BaseAuth): -def __init__(self, configuration): - super().__init__(configuration.copy(PLUGIN_CONFIG_SCHEMA)) - -def login(self, login, password): - # Get password from configuration option - = self.configuration.get("auth", "password") - static_password # Check authentication - "Login attempt by %r with password %r", - logger.info( - login, password)if password == static_password: - return login - return ""
from radicale.auth import BaseAuth +from radicale.log import logger + += {"auth": { + PLUGIN_CONFIG_SCHEMA "password": {"value": "", "type": str}}} + + +class Auth(BaseAuth): +def __init__(self, configuration): + super().__init__(configuration.copy(PLUGIN_CONFIG_SCHEMA)) + +def login(self, login, password): + # Get password from configuration option + = self.configuration.get("auth", "password") + static_password # Check authentication + "Login attempt by %r with password %r", + logger.info( + login, password)if password == static_password: + return login + return ""
Install the python module by running the following command in the same folder as
-setup.py
:+python3 -m pip install .
python3 -m pip install .
To make use this great creation in Radicale, set the configuration option
-type
in theauth
section toradicale_static_password_auth
:+[auth] -type = radicale_static_password_auth -password = secret
[auth] +type = radicale_static_password_auth +password = secret
You can uninstall the module with:
-+python3 -m pip uninstall radicale_static_password_auth
python3 -m pip uninstall radicale_static_password_auth
Authentication plugins ¶
@@ -1454,14 +1476,14 @@ you want to add new features, fix bugs or update the documentation.PyPI ¶
Radicale is available on PyPI. To install, just type as superuser:
-+python3 -m pip install --upgrade radicale
python3 -m pip install --upgrade radicale
Git Repository ¶
If you want the development version of Radicale, take a look at the git repository on GitHub, or install it directly with:
-+python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
You can also download the content of the repository as an archive.