PIM
Architecture:
- Nginx:
- SSL termination
- Reverse proxy
- Apache:
- Authentication and access control
- WSGI
- Radicale:
- CalDAV and CardDAV server, written in Python
- File storage
Radicale: CalDAV and CardDAV
Create new user:
$ groupadd vcal
$ useradd -g vcal vcal -d /srv/vcal -m
Create web root:
$ mkdir /srv/www/cal-example-com
$ chown vcal:vcal /srv/www/cal-example-com
$ chmod 755 /srv/www/cal-example-com
Create virtual env:
$ su - vcal
$ cd /srv/www/cal-example-com
$ virtualenv --no-site-packages venv
$ source venv/bin/activate
$ pip install --upgrade
$ pip install radicale
Create WSGI file /srv/www/cal-example-com/radicale.wsgi
:
import radicale
import site
site.addsitedir('/srv/www/cal-example-com/venv/lib/python2.6/site-packages')
radicale.log.start()
application = radicale.Application()
Create configuration /etc/radicale/config
:
[acl]
type = None
[storage]
type = filesystem
filesystem_folder = /srv/vcal/collections
[logging]
debug = False
Create configuration /etc/radicale/logging
:
[loggers]
keys = root
[handlers]
keys = file
[formatters]
keys = full
[logger_root]
level = INFO
handlers = file
[handler_file]
class = FileHandler
args = ('/var/log/radicale.log',)
formatter = full
[formatter_full]
format = %(asctime)s - %(levelname)s: %(message)s
create logratate configuration /etc/logrotate.d/radicale
:
/var/log/radicale.log {
weekly
rotate 4
compress
missingok
create 0640 vcal adm
}
TODO: is postrotate required?
Create initial logfile:
$ touch /var/log/radicale.log
$ chown vcal:adm /var/log/radicale.log
Apache WSGI + AuthN
Note: As Apache is only used internally it only listens on localhost on a high port.
$ apt-get install apache2
$ apt-get install libapache2-mod-wsgi
$ a2enmod authnz_ldap
$ a2enmod rewrite
Create /etc/apache2/sites-available/cal-example-com
:
<VirtualHost 127.0.0.1:7080>
ServerName cal.example.com
ErrorLog ${APACHE_LOG_DIR}/cal-example-com.error.log
CustomLog ${APACHE_LOG_DIR}/cal-example-com.access.log combined
WSGIDaemonProcess radicale user=vcal group=vcal threads=1
WSGIScriptAlias / /srv/www/cal-example-com/radicale.wsgi
<Directory /srv/www/cal-example-com>
WSGIProcessGroup radicale
WSGIApplicationGroup %{GLOBAL}
AllowOverride None
Order allow,deny
allow from all
AuthType Basic
AuthName "Authentication"
AuthBasicProvider ldap
AuthLDAPURL ldap://127.0.0.1:389/dc=example,dc=com?uid,mail?one
Require valid-user
RewriteEngine On
RewriteCond %{PATH_INFO} ^/shared/.*
RewriteRule .* - [Last]
RewriteCond %{ENV:AUTHENTICATE_mail}%{PATH_INFO} !^([^/]+/)\1
RewriteRule .* - [Forbidden]
</Directory>
</VirtualHost>
Enable site:
$ a2ensite cal-example.com
$ a2dissite default
Configure /etc/apache2/ports.conf
:
NameVirtualHost 127.0.0.1:7080
Listen 127.0.0.1:7080
<IfModule mod_ssl.c>
Listen 127.0.0.1:7443
</IfModule>
<IfModule mod_gnutls.c>
Listen 127.0.0.1:7443
</IfModule>
Nginx reverse proxy + SSL
server {
listen 443;
server_name cal.example.com;
server_name_in_redirect off;
ssl on;
ssl_certificate /etc/ssl/certs/cal-example-com.pem;
ssl_certificate_key /etc/ssl/private/cal-example-com.pem;
access_log /var/log/nginx/cal-example-com.access.log;
error_log /var/log/nginx/cal-example-com.error.log;
root /srv/www/cal-example-com;
index index.html;
error_page 404 /index.html;
location / {
proxy_pass http://localhost:7080;
}
}
Sources: