Mając doświadczenie z paroma podobnymi systemami, postanowiłem wrócić do sprawdzonego rozwiązania – Trac do obsługi rozmaitych programistycznych projektów, którymi próbuję bawić się od czasu do czasu. Bardzo zależało mi na prostocie i powszechności wybranego oprogramowania. Trac oba te warunki spełnia.

Chciałem, żeby Trac dobrze współpracował z serwerem Nginx, który obsługuje ruch WWW na neumanny.net. Zależało mi, żeby do autoryzacji nie włączać kolejnego mechanizmu, a użyć tego, co już miałem [1]. Wybór był prosty (może trochę za prosty) – skorzystanie z PAM (Pluggable Authentication Modules), włączonych do Nginx za pomocą rozszerzenia Auth PAM.

Konfiguracja Nginx

Nginx skompiowany jest więc u mnie z takimi (między innymi) opcjami:

$ emerge -pv nginx

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R    ] www-servers/nginx-1.4.4  NGINX_MODULES_HTTP="auth_pam fastcgi proxy"

Fragment pliku konfiguracyjnego, dotyczący serwera z Trac-em przygotowałem bazując na przykładowej konfiguracji z oficjalnej dokumentacji Trac. Wygląda on tak:

http {

    upstream code_neumanny_net {
        server  127.0.0.1:9080;
    }

    server {
        listen 80;
        server_name code.neumanny.net;
        return 301 https://code.neumanny.net$request_uri;
    }

    server {
        listen 443 ssl;
        keepalive_timeout 70;
        server_name code.neumanny.net;

        ssl on;
        ssl_certificate /etc/ssl/local/certs/wwwsan-cert-rsa.pem;
        ssl_certificate_key /etc/ssl/local/private/wwwsan-key-rsa.pem;

        access_log /srv/www/code.neumanny.net/logs/access.log main;
        error_log /srv/www/code.neumanny.net/logs/error.log info;

        root /srv/www/code.neumanny.net;

        location ~ ^/favicon.ico$ {
            root /srv/www/code.neumanny.net/static;
            log_not_found off;
            access_log off;
            expires max;
        }
        location = /robots.txt {
            root /srv/www/code.neumanny.net/static;
            allow all;
            log_not_found off;
            access_log off;
        }
        location / {
            index index.html;
        }
        if ($uri ~ ^/(.*)) {
            set $path_info /$1;
        }
        location /hpgp/chrome/ {
            alias /srv/trac/hpgp/htdocs/;
        }
        location /hpgp/ {
            auth_pam "hPGP Developer Zone";
            auth_pam_service_name "nginx";

            fastcgi_pass code_neumanny_net;

            fastcgi_param SCRIPT_NAME        "";
            fastcgi_param PATH_INFO          $path_info;
            fastcgi_param REQUEST_METHOD     $request_method;
            fastcgi_param SERVER_NAME        $server_name;
            fastcgi_param SERVER_PORT        $server_port;
            fastcgi_param SERVER_PROTOCOL    $server_protocol;
            fastcgi_param QUERY_STRING       $query_string;
            fastcgi_param AUTH_USER          $remote_user;
            fastcgi_param REMOTE_USER        $remote_user;
            fastcgi_param REMOTE_ADDR        $remote_addr;
            fastcgi_param CONTENT_TYPE       $content_type;
            fastcgi_param CONTENT_LENGTH     $content_length;
            }
    }
}

Z kolei plik konfiguracyjny PAM, w którym zdefiniowane są opcje dostępu (/etc/pam.d/nginx) wygląda tak:

auth     required  pam_listfile.so onerr=fail item=user sense=allow file=/etc/security/nginx.allowed
auth     required  pam_unix.so try_first_pass likeauth nullok
auth     optional  pam_permit.so
account  required  pam_unix.so
account  optional  pam_permit.so

W widocznym w konfiguracji pliku /etc/security/nginx.allowed znajduje się lista użytkowników uprawnionych do logowania do tego serwisu.

Należy ponadto pamiętać, że aby moduł Auth PAM zadziałał, należy umożliwić użytkownikowi, z którego uprawnieniami uruchomiony jest serwer Nginx, odczyt pliku /etc/shadow.

Konfiguracja Trac

Poniżej opcje, z którymi skompilowany jest Trac:

$ emerge -pv trac

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R    ] www-apps/trac-1.0.1  USE="fastcgi i18n" 0 kB

I jeszcze zawartość /etc/conf.d/tracd:

export PYTHONPATH=/usr/lib64/python2.7/site-packages:/usr/local/lib64/python2.7/site-packages
export PYTHON_EGG_CACHE=/var/lib/trac/egg-cache/
TRACD_PORT="9080"
TRACD_OPTS="--hostname localhost --protocol=fcgi --env-parent-dir /srv/trac/"

W efekcie proces tracd działa z następującymi parametrami:

/usr/bin/python2.7 /usr/bin/tracd -p 9080 --hostname localhost --protocol=fcgi \
        --env-parent-dir /srv/trac/

Działanie

Przy takiej konfiguracji jak powyżej, dostęp do serwisu tracd jest ograniczony dla niektórych użytkowników, którzy mają konto (zwykłe unixowe) na serwerze. Ponadto dostęp do statycznych elementów Trac zapewniony jest bezpośrednio z poziomu serwera Nginx.

[1]Tak, jestem chyba zwolennikiem zasady znanej jako „Brzytwa Ockhama”.