Home / Community / Blog

Konfiguracja postfix'a

Odkomentowałem linię:

mailbox_transport = lmtp:unix:/var/lib/imap/socket/lmtp

w pliku /etc/postfix/main.cf.

Automatyczne zakładanie skrzynek pocztowych

Domyślnie wymagane jest ręczne założenie skrzynki dla każdego użytkownika. Gdy korzystamy z LDAP może być to niewdzięczne zajęcie. Chciałem, żeby się zakładały automatycznie.

Zgodnie z zaleceniami z sieci dopisałem:

autocreatequota: 20480
unixhierarchysep: yes
quotawarn: 90
autocreateinboxfolders: Drafts|Sent|Trash
autosubscribeinboxfolders: Drafts|Sent|Trash
lmtp_over_quota_perm_failure: 1

do pliku /etc/imapd.conf.
Ta automatyzacja działa tylko gdy użytkownik zaloguje się do serwera POP3 lub IMAP. Dopóki się choć raz nie zaloguje to serwer nie przyjmuje poczty!

Przydało by się zakładanie skrzynki odbywało się gdy serwer postfix autoryzował odbiorcę. Na szczęście CurierIMAP z CentOS ma nałożoną łatę Autocreate INBOX patch for Cyrus. Po ustawieniu:

createonpost: yes

w pliku /etc/imapd.conf skrzynka będzie zakładana gdy przyjdzie pierwsza wiadomość.

Te dwie opcje działają jednocześnie - skrzynka jest zakładana przy pierwszej wiadomości lub przy pierwszym zalogowaniu się.

Konwersja mailbox do maildir

To nie jest takie proste. Wcześniejsze wiadomości z pliku mbox można zaimportować do Thunderbird'a za pomocą dodatku ImportExportTools, jeżeli konto jest zdefiniowane jako IMAP to wiadomości powinny trafić na serwer, ale tego nie testowałem.

Jak już postawiłem usługę katalogową, to chciałem użyć jej do autoryzacji do repozytoriów SVN do których był dostęp przez Apache.

W sumie jest to proste:

<IfModule mod_dav.c>
    <Location /svn>
        DAV svn
        SVNParentPath /var/lib/svn/repositories
        SVNListParentPath on
        AuthType Basic
        AuthName "Dostep do repozytorium"
        AuthBasicProvider ldap
        AuthLDAPURL "ldap://localhost/dc=jaqb,dc=gda,dc=pl" NONE
        AuthLDAPBindDN "cn=Manager,dc=jaqb,dc=gda,dc=pl"
        AuthLDAPBindPassword jakiesmocnehaslo
        AuthLDAPGroupAttribute memberUid
        AuthLDAPGroupAttributeIsDN off
        Require ldap-group cn=svnowcy,ou=groups,dc=jaqb,dc=gda,dc=pl
    </Location>
</IfModule>

kluczowe są dwa wpisy:

AuthLDAPGroupAttribut memberUid
AuthLDAPGroupAttributeIsDN off

bez tego Apache zakładał, że użytkownicy są wpisani jako member lub uniquemember i na dodatek jako np.:

uid=jaqb,ou=People,dc=jaqb,dc=gda,dc=pl

a domyślnie LAM zakłada jako np.: jaqb w memberUid.

Redmine ma możliwość integracji z usługami katalogowymi. Chciałem mojego połączyć z OpenLDAP który postawiłem.

Po zalogowaniu się na konto administratora w zakładce Administration jest LDAP authentication. Tam wybrałem New authentication mode i wpisałem:

     Name: mój zajefajny serwerek
     Host: localhost
     Port: 389
  Account: cn=Manager,dc=jaqb,dc=gda,dc=pl
  Base DN: ou=users,dc=jaqb,dc=gda,dc=pl

nie jest zaznaczone LDAPS, ale musi być zaznaczone On-the-fly user creation - to oznacza, że jak użytkownik z OpenLDAP loguje się po raz pierwszy w Redmine to zostanie mu automatycznie założone konto (w Redmine). Jeżeli to nie jest zaznaczone, to musielibyśmy najpierw takiemu delikwentowi założyć konto w Redmine i wskazać, że ma się autoryzować przez OpenLDAP.

Dalej w Attributes wpisałem:

     Login: uid
First name: givenName
 Last name: sn
      Mail: mail

.

Po zatwierdzeniu pokazała się tabelka w której widać było nowo utworzone połączenie. Można je teraz przetestować. Jeżeli wszystko jest OK zastanawiamy się, czemu Users jest 0 skoro w bazie OpenLDAP jest ich kilka setek (no w każdym razie przeważnie więcej niż 1). Otóż ta liczba to liczba użytkowników z autoryzowanych w Redmine przez dane połączenie, więc na początek 0 jest OK.

Teraz można się wylogować z konta administratora. Zalogować na użytkownika z OpenLDAP. Ucieszyć, że działa. Wylogować. Zalogować jeszcze raz na administratora i przekonać, że Users się zmieniło.

Pakiety

Zaczynamy od instalacji pakietów:

yum install openldap-servers openldap-clients

od razu można ustawić, żeby serwer (slapd) się włączał automatycznie:

chkconfig --add slapd
chkconfig slapd on

na razie go nie włączam.

Jedna ważna uwaga. W pakiecie openldap jest używany plik /etc/openldap/ldap.conf, ale niektóre pakiety (np.: kiedyś nss_ldap, a obecnie pam_ldap) używają pliku /etc/ldap.conf lub /etc/pam_ldap.conf. Dwa różne plik z konfiguracją powodują problemy, dlatego zwykle kasuję plik /etc/ldap.conf i w jego miejsce tworzę link symboliczny o takiej samej nazwie wskazujący na /etc/openldap/ldap.conf:

rm /etc/ldap.conf
rm /etc/pam_ldap.conf
ln -s /etc/openldap/ldap.conf /etc/ldap.conf
ln -s /etc/openldap/ldap.conf /etc/pam_ldap.conf

Skopiowałem domyślną konfigurację bazy i ustawiłem uprawnienia:

cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
chown -R ldap:ldap /var/lib/ldap

Dostosowałem wartości olcSuffix i olcRootDN w pliku

/etc/openldap/slapd.d/cn=config/olcDatabase={2}bdb.ldif

u mnie wyglądają tak:

olcSuffix: dc=jaqb,dc=gda,dc=pl
olcRootDN: cn=Manager,dc=jaqb,dc=gda,dc=pl

Wygenerowałem skrót hasła (haslo) poleceniem slappasswd:

slappasswd -u
New password:
Re-enter new password:
{SSHA}B6+pPk3uabUwf034GKcToi3a75A44Jws

i ustawiłem je w konfiguracji jakże oczywistą komendą:

echo "olcRootPW: {SSHA}B6+pPk3uabUwf034GKcToi3a75A44Jws" >> \
/etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif

od razu ustawiłem, żeby akceptował połączenia szyfrowane zmieniłem wartość SLAPD_LDAPS w pliku /etc/sysconfig/ldap na yes:

SLAPD_LDAPS=yes

i uruchomiłem serwer

/etc/init.d/slapd start

Otworzyłem port dla połączeń szyfrowanych:

iptables -I INPUT -p tcp --dport 636 -j ACCEPT

Teraz już można podłączyć się do serwera za pomocą polecenia:

ldapsearch -H ldaps:// localhost -D "cn=Manager,dc=jaqb,dc=gda,dc=pl" -W

nic tam nie ma bo baza jest pusta a na dodatek certyfikat może być nie pasujący, ale można się podłączyć.

GUI

Ściągnąłem i zainstalowałem obsługę LDAP w PHP i LDAP Account Manager'a:

yum install php-ldap
wget "http://downloads.sourceforge.net/project/lam/LAM/3.9/ldap-account-manager-3.9-0.fedora.1.noarch.rpm?r=&ts=1355006390&use_mirror=netcologne"
rpm -i ldap-account-manager-3.9-0.fedora.1.noarch.rpm

(jest już dostępna wersja 4.0.RC1).

W przypadku SElinux'a trzeba zmienić kontekst pliku lam.conf (i kilku innych potrzebnych później):

setenforce Permissive
chcon -t httpd_t /var/lib/ldap-account-manager/config/lam.conf
chcon -t httpd_t /var/lib/ldap-account-manager/config/config.cfg
chcon -t httpd_t /var/lib/ldap-account-manager/config/profiles/default.user
setenforce Enforcing

lub od razu dla całego katalogu:

setenforce Permissive
chcon -R -t httpd_t /var/lib/ldap-account-manager/config
setenforce Enforcing

Teraz można się zalogować do LAM przez adres:

http://adres.ip.kompuerta.lub.nazwa/lam

Najpierw wypadałoby zmienić domyślne hasło. W tym celu w prawym górnym rogu kliknąć LAM configuration. i wejść w Edit general settings. Domyślne hasło to lam. Nowe hasło ustawić w ramce Change master password.

Teraz należy dostosować konfigurację. Znowu w prawym górnym rogu kliknąć LAM configuration. Tam trzeba wejść w Edit server profiles, zmienić w zakładce General settings: Tree suffix - w zależności od domeny i w ramce Security settings hasło i List of valid users - tam wpisałem

cn=Manager,dc=jaqb,dc=gda,dc=pl

a w zakładce Account types: LDAP suffix dla każdego z typów kont. U mnie wygląda to tak

ou=users,dc=jaqb,dc=gda,dc=pl
ou=groups,dc=jaqb,dc=gda,dc=pl
ou=machines,dc=jaqb,dc=gda,dc=pl
dc=jaqb,dc=gda,dc=pl

dla odpowiednio Users, Groups, Hosts i Samba domains.

Teraz można się zalogować wpisując ustawione wcześniej hasło. Przy pierwszym logowaniu baza jest pusta, więc LAM wyświetli komunikat podobny do tego:

The following suffixes are missing in LDAP. LAM can create them for you.
ou=users,dc=jaqb,dc=gda,dc=pl
ou=groups,dc=jaqb,dc=gda,dc=pl
ou=machines,dc=jaqb,dc=gda,dc=pl
dc=jaqb,dc=gda,dc=pl

kliknięcie Create jest równoznaczne zaimportowaniu pliku init.ldiff o zawartości:

# jaqb.gda.pl
dn: dc=jaqb,dc=gda,dc=pl
objectClass: organization
objectClass: dcObject
dc: jaqb
o: jaqb

# users, jaqb.gda.pl
dn: ou=users,dc=jaqb,dc=gda,dc=pl
objectClass: organizationalUnit
ou: users

# groups, jaqb.gda.pl
dn: ou=groups,dc=jaqb,dc=gda,dc=pl
objectClass: organizationalUnit
ou: groups

# machines, jaqb.gda.pl
dn: ou=machines,dc=jaqb,dc=gda,dc=pl
objectClass: organizationalUnit
ou: machines

pliku poleceniem

ldapadd -H ldap://localhost -D "cn=Manager,dc=jaqb,dc=gda,dc=pl" -W -f init.ldiff

Zakładanie użytkowników

Chciałem, żeby użytkownicy byli rozróżniani po uid'zie, więc zmieniłem w Tools, Profile editor domyślny profil (default) dla użytkowników RDN identifier na uid i przy okazji zmieniłem domyślną powłokę (Login shell) na /bin/false.

Najpierw trzeba założyć grupę - nazwałem ją wszyscy.

Potem wystarczy wypełnić wymagane pola, oznaczone gwiazdką. Tak naprawdę wystarczy nazwisko (Last name), resztę uzupełni LAM jak przejdziemy na zakładkę Unix. LAM przyjmuje konwencję nazwy użytkownika jako pierwsza litera imienia i nazwisko, dla Jana Kowalskiego będzie to jkowalski.

Teraz wystarczy skonfigurować inne usługi by korzystały z usługi katalogowej.

Przy okazji innych poszukiwań wpadłem na plone jako gotowa paczka w repozytorium EPEL i podobno on wspiera wielojęzyczność za pomocą pakietu LinguaPlone.

Ja zacząłem od ściągnięcia źródeł Redmine w bieżącej wersji i czytania opisu instalacji na CentOS.

Ruby

Wbrew temu co napisali zainstalowałem ruby z paczki (wersja prawie ta sama 1.8.7.358 a 1.8.7.352):

yum install ruby

doinstalowały się zależności: compat-readline5 i ruby-libs.

Następny etap to instalacja rubygems w wersji 1.4.2. W paczce jest 1.3.7, ale dokumentacja ostrzega tylko przed wersją 1.5, no to instaluję

yum install rubygems

doinstalowały się zależności: ruby-irb i ruby-rdoc.

Teraz zaczyna się magia. Instaluję jakieś cuda nie wiadomo gdzie i jak. Łatwiej by było z pakietów, ale przykład nie chce się zainstalować - brakuje libev.

gem install passenger

oczywiście błąd:

mkmf.rb can't find header files for ruby at /usr/lib/ruby/ruby.h

pewnie brakuje ruby-devel, i make , i gcc. Zainstalowałem:

yum install ruby-devel make

teraz już poszło - nie wymagało gcc-c++.

Teraz powinno być

passenger-install-apache2-module

ale kreator grzecznie informuje, że pakiety devel są potrzebne, więc instaluję:

yum install gcc-c++ curl-devel openssl-devel zlib-devel \
                      httpd-devel apr-devel apr-util-devel

instalacja pakietów i instalacja (kompilacja) modułu chwilę trwa. Kreator pokazuje co trzeba dodać do konfiguracji serwera apache:

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-3.0.18/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-3.0.18
PassengerRuby /usr/bin/ruby

i jak podłączyć przykładową aplikację w ruby:

Suppose you have a Rails application in /somewhere. Add a virtual host to your
Apache configuration file and set its DocumentRoot to /somewhere/public:

   <VirtualHost *:80>
      ServerName www.yourhost.com
      # !!! Be sure to point DocumentRoot to 'public'!
      DocumentRoot /somewhere/public    
      <Directory /somewhere/public>
         # This relaxes Apache security settings.
         AllowOverride all
         # MultiViews must be turned off.
         Options -MultiViews
      </Directory>
   </VirtualHost>

And that's it! You may also want to check the Users Guide for security and optimization tips, troubleshooting and other useful information:
/usr/lib/ruby/gems/1.8/gems/passenger-3.0.18/doc/Users guide Apache.html

Instalacja i wstępna konfiguracja

Teraz ściągnąłem jak kazali:

wget http://rubyforge.org/frs/download.php/75910/redmine-1.3.2.tar.gz

, na wszelki wypadek najświeższą wersję też:

wget http://rubyforge.org/frs/download.php/76589/redmine-2.1.4.tar.gz

i dalej wg. HOWTO rozpakowałem do /var/www:

cd /var/www
tar -xzf ~/redmine-1.3.2.tar.gz
ln -s redmine-1.3.2 redmine

i zrobiłem link, żeby był w standardowej ścieżce i łatwo było zrobić aktualizację.

Założyłem bazę i użytkownika:

create database redmine character set utf8;
create user 'redmine'@'localhost' identified by 'jakieshaslo';
grant all privileges on redmine.* to 'redmine'@'localhost';

Teraz dalej (oczywiście zamiast nano używam mcedit):

cd /var/www/redmine/config
cp database.yml.example database.yml
mcedit database.yml

zmieniłem tylko hasło w części production (i to spowodowało błąd później, najlepiej od razu ustawić też nazwę użytkownika).

Znowu magia:

cd /var/www/redmine
gem install bundler

potem wpisałem do nowego pliku /var/www/redmine/Gemfile:

# file: /var/www/redmine/Gemfile
source "http://rubygems.org"
gem "rake", "0.8.3"
gem "rack", "1.1.0"
gem "i18n", "0.4.2"
gem "rubytree", "0.5.2", :require => "tree"
gem "RedCloth", "~>4.2.3", :require => "redcloth" # for CodeRay
gem "mysql"
gem "coderay", "~>0.9.7"

i uruchomiłem:

bundle install

ale zwraca błąd:

Gem::InstallError: hoe requires RubyGems version >= 1.4. Try 'gem update --system' to update RubyGems itself.
An error occurred while installing hoe (3.3.1), and Bundler cannot continue.
Make sure that `gem install hoe -v '3.3.1'` succeeds before bundling.

no to zgodnie z sugestią uruchomiłem

gem update --system

chwile to trwało. Teraz wysypał się na:

Installing mysql (2.9.0) with native extensions

no to doinstalowałem

yum install mysql-devel

i teraz poszło.

Konfiguracja właściwego Redmine'a

W pliku

/var/www/redmine/config/environment.rb

odkomentowałem linię

ENV['RAILS_ENV'] ||= 'production'

Magia (już się zaczynam przyzwyczajać):.

RAILS_ENV=production bundle exec rake generate_session_store

i jeszcze raz

RAILS_ENV=production bundle exec rake db:migrate

tym razem pokazało błąd

rake aborted!
Access denied for user 'root'@'localhost' (using password: YES)

(See full trace by running task with --trace)

jak się okazało to błąd połączenia do bazy MySQL, poprawiłem nazwę użytkownika w pliku

config/database.yml

, bo przecież wcześniej zmieniłem tylko hasło ;-).

Pominąłem ładowanie domyślnych danych, bo było opcjonalne, ale i tak je załadowałem przy pierwszym zalogowaniu się. Można uruchomić:

RAILS_ENV=production bundle exec rake redmine:load_default_data

Testowe uruchomienie.

Domyślnie wbudowany serwer działa na porcie 3000. Trzeba go otworzyć na firewall'u:

iptables -I INPUT -p tcp --dport 3000 -j ACCEPT

Sam serwer uruchamia się tak:

cd /var/www/redmine
ruby script/server webrick -e production

można się zalogować domyślnym użytkownikiem admin z hasłem admin.

Konfiguracja Apache.

Pozamieniałem nazwy skryptów CGI jak kazali:

cd /var/www/redmine/public
cp dispatch.cgi.example dispatch.cgi
cp dispatch.fcgi.example dispatch.fcgi
cp dispatch.rb.example dispatch.rb

nadal nic nie działa.

Teraz wg. HowTo configure Apache to run Redmine. Najpierw włączyłem obsługę wielu domen dopisując

NameVirtualHost *:80

w pliku /etc/httpd/conf/httpd.conf. Utworzyłem plik /etc/httpd/conf.d/redmine.conf z zawartością:

<VirtualHost *:80>
    ServerName redmine.mojadomena.pl
    ServerAdmin ja@mojadomena.pl
    DocumentRoot /var/www/redmine/public/
    ErrorLog logs/redmine_error_log
   RailsEnv production

  <Directory /var/www/redmine/public/>
        Options Indexes ExecCGI FollowSymLinks
        Order allow,deny
        Allow from all
        AllowOverride all
    </Directory>
</VirtualHost>

skopiowałem pliki jak kazali (niepotrzebnie):

cd /var/www/redmine/public
cp htaccess.fcgi.example .htaccess

i już było lepiej bo pojawił się w przeglądarce komunikat błędu

Application error

Rails application failed to start properly

a w logu było

Rails Error: Unable to access log file. Please ensure that \
/var/www/redmine-1.3.2/log/production.log exists and is \
chmod 0666. The log level has been raised to WARN and \
the output directed to STDERR until the problem is fixed.

no to zmieniłem uprawnienia do plików

cd /var/www
chown -R apache:apache redmine-1.3.2/

jak widać zmieniam na katalogu gdzie są pliki, a nie na linku symbolicznym.

Potem wycofałem się z uruchamiania przez FastCGI, nie po to instalowałem passenger'a - musiałem skasować plik .htaccess:

cd /var/www/redmine
rm public/.htaccess

ale zamiast aplikacji wyświetlała mi się zawartość katalogu. Wskazówkę znalazłem w logach apache'a:

ERROR: Cannot create directory '/var/log/passenger-analytics': Permission denied (13)

rozwiązanie było proste:

mkdir /var/log/passenger-analytics

W końcu działa!

Zamiast puenty

Sprawdziłem magiczne instalatory:

which gem
yum provides /usr/bin/gem

plik gem jest w pakiecie rubygems (rubygems-1.3.7-1.el6.noarch) i instaluje pakiety w

/usr/lib/ruby/gems/1.8/gems

teraz już nie jest tak magicznie.

Na popularnym portalu aukcyjnym można znaleźć "DCF77 RECEIVER Arduino" oparty na MAS6180B1 który realizuje radiową część zegarka synchronizowanego sygnałem DCF77 (to znaczy, że sygnał trzeba jeszcze zdekodować).

Kiedyś chciałem budować coś wymagającego synchronizacji czasu...

Just my blog...

Mon Tue Wed Thu Fri Sat Sun
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31