howto

Samstag, 26. August 2006

HOWTO_ Asterisk 1.2 als SIP-Proxy für Sipgate, QSC IPfonie und dus.net

Neulich erinnerte ich mich daran, dass ich Monat für Monat ungenutzte Freiminuten bei QSC IPfonie privat, dem kostenlosen VoIP-Anschluss, welcher bei meinem Q-DSL Internetanschluss inklusive ist, verfallen lasse.

Bei VoIP bin ich recht früh eingestiegen, d.h. zu dem Zeitpunkt, als in Deutschland die erste Hardware dafür nicht mehr preislich weit im dreistelligen Bereich lag. Daher nenne ich ein Grandstream Budge-Tone 101 mein Eigen.
Dieses unterstützt aber nur einen Account, und komplett von Sipgate zu QSC möchte ich auch nicht wechseln, dagegen sprechen einfach zu viele Gründe: Rufnummer, Anrufhistorie, Adressbuch, und und und.

Dann erinnerte ich mich an die Software-Telefonanlage Asterisk und einen Einführungsartikel in der c't. Und so fing ich langsam an, mich zu erkundigen, was Asterisk im SIP-Bereich leistet und ob es für meine Zwecke dienlich sein kann.

Offensichtlich ist dies der Fall, was sollte sonst dieser Artikel. Also, folgende Eckdaten beschreiben meine Installation:
  • Läuft auf einem Debian GNU/Linux Server
  • Verwendet ausschließlich SIP
  • Ist bei den drei Providern Sipgate, QSC sowie dus.net registriert
  • Annahme von Anrufen von allen Providern
  • ausgehende Anrufe über alle Provider
  • einfaches LCR (Least Cost Routing), welches ausgehende Anrufe
    • ins Festnetz in der Nebenzeit über QSC,
    • ins Festnetz in der Hauptzeit über dus.net und
    • alle anderen Anrufe über sipgate leitet.
  • Direkte Wahl eines Anbieters über eine führende Ziffer
    • 3 für dus.net
    • 4 für QSC IPfonie
    • 7 für Sipgate
Alles lässt sich über 2 Konfigurationsdateien regeln, welche ich im Folgenden kurz erkläre.

sip.conf:
;
; SIP Configuration for Asterisk
;
; Syntax for specifying a SIP device in extensions.conf is
; SIP/devicename where devicename is defined in a section below.
;
; You may also use
; SIP/username@domain to call any SIP user on the Internet
; (Don't forget to enable DNS SRV records if you want to use this)
;
; If you define a SIP proxy as a peer below, you may call
; SIP/proxyhostname/user or SIP/user@proxyhostname
; where the proxyhostname is defined in a section below
;
; Useful CLI commands to check peers/users:
;   sip show peers              Show all SIP peers (including friends)
;   sip show users              Show all SIP users (including friends)
;   sip show registry           Show status of hosts we register with
;
;   sip debug                   Show all SIP messages
;
;   reload chan_sip.so          Reload configuration file
;                               Active SIP peers will not be reconfigured
;

[general]
context=from-sip                ; Default context for incoming calls

;recordhistory=yes              ; Record SIP history by default (see sip history / sip no history)
;realm=qsc.de                   ; Realm for digest authentication
                                ; defaults to "asterisk"
                                ; Realms MUST be globally unique according to RFC 3261
                                ; Set this to your host name or domain name
port=5060                       ; UDP Port to bind to (SIP standard port is 5060)
bindaddr=0.0.0.0                ; IP address to bind to (0.0.0.0 binds to all)
srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
                                ; Note: Asterisk only uses the first host
                                ; in SRV records
                                ; Disabling DNS SRV lookups disables the
                                ; ability to place SIP calls based on domain
                                ; names to some other SIP users on the Internet
;pedantic=yes                   ; Enable slow, pedantic checking for Pingtel
                                ; and multiline formatted headers for strict
                                ; SIP compatibility (defaults to "no")
;tos=184                        ; Set IP QoS to either a keyword or numeric val
;tos=lowdelay                   ; lowdelay,throughput,reliability,mincost,none
;maxexpirey=3600                ; Max length of incoming registration we allow
;defaultexpirey=120             ; Default length of incoming/outoing registration
;notifymimetype=text/plain      ; Allow overriding of mime type in MWI NOTIFY
;videosupport=yes               ; Turn on support for SIP video

disallow=all                    ; First disallow all codecs
; use "show translation" for installed codecs
;allow=gsm
;allow=g726
;allow=adpcm
;allow=slin
;allow=lpc10
allow=alaw
allow=ulaw                      ; Allow codecs in order of preference
;allow=ilbc                     ; Note: codec order is respected only in [general]
;musicclass=default             ; Sets the default music on hold class for all SIP calls
                                ; This may also be set for individual users/peers
;language=en                    ; Default language setting for all users/peers
                                ; This may also be set for individual users/peers
;relaxdtmf=yes                  ; Relax dtmf handling
;rtptimeout=60                  ; Terminate call if 60 seconds of no RTP activity
                                ; when we're not on hold
;rtpholdtimeout=300             ; Terminate call if 300 seconds of no RTP activity
                                ; when we're on hold (must be > rtptimeout)
;trustrpid = no                 ; If Remote-Party-ID should be trusted
;progressinband=no              ; If we should generate in-band ringing always
useragent=Asterisk 1.2          ; Allows you to change the user agent string
nat=yes                         ; NAT settings
                                ; yes = Always ignore info and assume NAT
                                ; no = Use NAT mode only according to RFC3581
                                ; never = Never attempt NAT mode or RFC3581 support
                                ; route = Assume NAT, don't send rport (work around more UNIDEN bugs)
;promiscredir = no      ; If yes, allows 302 or REDIR to non-local SIP address
;                       ; Note that promiscredir when redirects are made to the
;                       ; local system will cause loops since SIP is incapable
;                       ; of performing a "hairpin" call.
;
; Examples:
;externip = 83.236.156.2        ; Address that we're going to put in outbound SIP messages
                                ; if we're behind a NAT

                                ; The externip and localnet is used
                                ; when registering and communicating with other proxies
                                ; that we're registered with
                                ; You may add multiple local networks.  A reasonable set of defaults
                                ; are:
;localnet=10.0.0.10
;localnet=192.168.0.0/255.255.0.0; All RFC 1918 addresses are local networks
;localnet=10.0.0.0/255.255.255.0        ; Also RFC1918
;localnet=172.16.0.0/12         ; Another RFC1918 with CIDR notation


register => 030123456789:MYPASSWD@sip.qsc.de/030123456789       ; Register 030123456789 @ QSC
register => SIP-ID:SIP-PWD@sipgate.de/SIP-ID                 ; Register SIP-ID @ sipgate
register => Auth-ID:Kennwort@voip.dus.net/Auth-ID     ; Register AuthID @ dus.net


; ##### SIP PROVIDERS #####
[qsc]
type=peer
context=qsc-incoming
insecure=very
username=030123456789
secret=MYPASSWD
fromuser=030123456789
host=sip.qsc.de
dtmfmode=rfc2833
canredirect=no


[sipgate]
type=peer
context=sip-incoming
insecure=very
username=SIP-ID
secret=SIP-PWD
fromuser=SIP-ID
fromdomain=sipgate.de
host=sipgate.de
qualify=no
dtmfmode=info
canredirect=no


[dus]
type=peer
context=dus-incoming
insecure=very
username=Auth-ID
secret=Kennwort
fromuser=Auth-ID
host=proxy.dus.net
dtmfmode=rfc2833
canredirect=no
language=de


; ##### SIP CLIENTS #####
[client01]
; ~~~ Grandstream Budge-Tone 101 ~~~
type=friend
context=intern-client01
username=client01
secret=password01
host=dynamic
dtmfmode=info


[client02]
type=friend
context=intern-client02
username=client02
secret=password02
host=dynamic
dtmfmode=info
Ja, was bedeutet das jetzt alles? [name] bezeichnet einen sogenannten Kontext, für den die folgenden Zuweisungen der Art Variable=Wert gelten.

Die Kontexte [qsc], [sipgate] und [dus] sind meine drei VoIP-Anbieter. Die Daten sind eigentlich selbsterklärend. Zusätzlich benötigt jeder Anbieter noch eine Registrierung, bei der sich Asterisk als SIP-Client anmeldet. Dies wird durch die Befehle register => AUTH[:PWD]@HOST[:PORT]/AUTH vorgenommen. Für QSC müssen 030123456789 durch die eigene QSC-Rufnummer und MYPASSWD durch das vergebene Passwort, für sipgate SIP-ID durch die Sipgate-ID und SIP-PWD durch das SIP-Passwort, für dus.net Auth-ID und Kennwort durch die entsprechenden Daten ersetzt werden.

[client01] und [client02] konfigurieren zwei locale SIP-Clients, in meinem Falle das Grandstream Budge-Tone 101 sowie ein weiterer, welchen ich mit X-Lite zum Testen verwende.

Wichtig sind hier (eigentlich) nur noch die vergebenen Kontexte context=. Diese werde in der Datei extensions.conf ausgeführt, und bei einem von einem hier festgelegten Kontexte ausgeführten Anruf angesprungen. Kommt also ein Anruf auf die Sipgate-Rufnummer, so wird der Kontext sip-incoming angesprungen.


extensions.conf:
;
; The "General" category is for certain variables.  All other categories
; are interpreted as extension contexts
;
[general]

static=yes
writeprotect=no
autofallthrough=yes
;clearglobalvars=no
;priorityjumping=no

;
[globals]

USERNAME=cypressor                  ; display name for  caller ID in outgoing calls

QSCUSERID=030123456789                          ; caller ID number for QSC calls
QSCPREFIX=4                                     ; 4-GHI (Ipfonie)
DUSUSERID=Auth-ID                               ; caller ID number for dus.net calls
DUSPREFIX=3                                     ; 3-DEF (Dus.net)
SIPUSERID=SIP-ID                                ; caller ID number for sipgate calls
SIPPREFIX=7                                     ; 7-PQRS (Sipgate)

DEFAULTCONTEXT=sipgate-out                      ; default outgoing context for all calls
                                                ; that could not be routed

PHONE1=SIP/client01                             ; identification of phone no. 1
PHONE1NAME=(local) Grandstream BT101            ; display name, will be set if phone does not provide a name itself
PHONE1NUMBER=101                                ; extension number of phone no. 1

PHONE2=SIP/client02
PHONE2NAME=(local) Phone 2
PHONE2NUMBER=102



; #############################################
; #####  CALLS MADE FROM INTERNAL PHONES  #####
[intern-client01]
exten => _X.,1,NoOp(${CALLERID})
exten => _X.,2,GotoIf($["${CALLERIDNAME}" != ""]?3:5)
exten => _X.,3,SetCallerID("${CALLERIDNAME}" <${PHONE1NUMBER}>)
exten => _X.,4,Goto(6)
exten => _X.,5,SetCallerID("${PHONE1NAME}" <${PHONE1NUMBER}>)
exten => _X.,6,Goto(intern,${EXTEN},1)
include => intern

[intern-client02]
exten => _X.,1,NoOp(${CALLERID})
exten => _X.,2,GotoIf($["${CALLERIDNAME}" != ""]?3:5)
exten => _X.,3,SetCallerID("${CALLERIDNAME}" <${PHONE2NUMBER}>)
exten => _X.,4,Goto(6)
exten => _X.,5,SetCallerID("${PHONE2NAME}" <${PHONE2NUMBER}>)
exten => _X.,6,Goto(intern,${EXTEN},1)
include => intern

[intern]
; check with exceptions
include => out-exceptions
; try to route calls with available providers
include => out-route
; unrouteable extension, try default
include => default-out
; no outgoing extension available, try local
include => local
; nothing found yet? playback error
exten => i,1,Playback(invalid)
exten => i,2,Hangup



; #############################################
; ##### CALLS GOING OUT TO SIP-PROVIDERS  #####
[out-exceptions]
; exceptional extensions for outgoing calls
; especially numbers not beginning with 0 to prevent them
; from being routed to another (not-default) provider
include => out-mailbox
exten => 110,1,GoSub(sipgate-out,${EXTEN},1)

[out-mailbox]
; external mailboxes
; sipgate
exten => 50000,1,GoSub(sipgate-out,${EXTEN},1)

[out-route]
; route outgoing (external) calls to provider
; use the first number 2-9 to choose provider
; try numbers beginning with 1 in local context
exten => _1.,1,GoSub(local,${EXTEN},1)
exten => _${DUSPREFIX}.,1,GoSub(dus-out,${EXTEN:1},1)
exten => _${QSCPREFIX}.,1,GoSub(qsc-out,${EXTEN:1},1)
exten => _${SIPPREFIX}.,1,GoSub(sipgate-out,${EXTEN:1},1)
; weekend, always Off-Peak
exten => _0[2-9]X.,1,GoSubIf($["${IFTIME(*|sat-sun|*|*?true)}" != ""]?qsc-out,${EXTEN},1)
 ; mo-fr, Off-Peak is 18-9h
exten => _0[2-9]X.,2,GoSubIf($["${IFTIME(18:00-8:50|mon-fri|*|*?true)}" != ""]?qsc-out,${EXTEN},1)
; On-Peak, use dus.net
exten => _0[2-9]X.,3,GoSub(dus-out,${EXTEN},1)
; 01802/01804 not supported by sipgate
exten => _0180[2,4].,1,GoSub(dus-out,${EXTEN},1)

[default-out]
; include default for outgoing calls
include => ${DEFAULTCONTEXT}

[qsc-out]
exten => _X.,1,SetCallerID("${USERNAME}" <${QSCUSERID}>|a)
exten => _X.,2,Dial(SIP/${EXTEN}@qsc,90,tr)
exten => _X.,3,Hangup
; Return
exten => i,1,Return

[dus-out]
exten => _X.,1,SetCallerID("${USERNAME}" <${DUSUSERID}>)
exten => _X.,2,Dial(SIP/${EXTEN}@dus,60)
exten => _X.,3,Hangup
; Return
exten => i,1,Return

[sipgate-out]
exten => _X.,1,SetCallerID("${USERNAME}" <${SIPUSERID}>)
exten => _X.,2,Dial(SIP/${EXTEN}@sipgate,30,trg)
exten => _X.,3,Hangup
; Return
exten => i,1,Return


; #############################################
; ##### LOCAL CALLS TO OTHER PHONES #####
[local]
; Phone 1
exten => ${PHONE1NUMBER},1,Dial(${PHONE1},60)
exten => ${PHONE1NUMBER},2,Hangup
; Phone 2
exten => ${PHONE2NUMBER},1,Dial(${PHONE2},60)
exten => ${PHONE2NUMBER},2,Hangup
; Return
exten => i,1,Return

; #############################################
; ##### INCOMING CALLS ON ASTERISK #####
[from-sip]
exten => s,1,NoOp(Incoming asterisk call\, no extension)
exten => s,2,NoOp(Setting pseudo extension 00 to call)
exten => s,3,NoOp(${STRFTIME(,,%H)})
exten => s,4,GoTo(00,1)
include => ring-all


; #############################################
; ##### INCOMING CALLS FROM SIP-PROVIDERS #####
[qsc-incoming]
include => ring-all

[sip-incoming]
include => ring-all

[dus-incoming]
include => ring-all


; #############################################
; ##### CALLS TO ALL PHONES #####
[ring-all]
exten => _X.,1,NoOp(Call on line ${EXTEN} from ${CALLERID}.)
exten => _X.,2,DIAL(${PHONE1}&${PHONE2}, 90)
exten => _X.,3,Hangup
Diese Datei ist etwas komplexer. Eine Extension bezeichnet eigentlich nur eine Nummer, welche angerufen wird. Ausgehend von dem Kontext, von dem aus eine Rufnummer gewählt wird, wird nun nach passenden Extensions gesucht und die entsprechenden Kommandos ausgeführt.
exten => <EXTEN>,<PRIO>,<COMMAND>
<EXTEN> war wie gesagt eine Nummer. <PRIO> ist die Priorität. Dabei wird mit 1 angefangen und mit jedem Kommando um eins hochgezählt. <COMMAND> ist ein Kommando, welches mit diversen Parametern versehen irgendeine Aktion ausführt. Zu kompliziert? Ein Beispiel:
[intern-client01]
exten => 100,1,NoOp
exten => 100,2,Answer
exten => 100,3,Wait(5)
exten => 100,4,Playback(invalid)
exten => 100,5,Hangup
Wählt der erste Client ([client01] in sip.conf) die Rufnummer 100, wird die erste definierte Extension mit der Priorität 1 angesprungen und das Kommando NoOp (No Operation) ausgeführt. Das macht - nichts. Anschließend wird die Priorität um eins erhöht, ist also 2. Dazu passt die zweite Extension. So weit dürfte die Sache mit der Priorität also klar sein. Kann ich also kurz die meist verwendeten Kommandos erklären.
NoOp		macht nichts
Hangup		legt auf, beendet also die Verbindung bzw weist einen Anruf ab
Dial		wählt einen anderen Anschluss an
Goto		springt zu einem Ziel
GoSub		geht in eine Unterroutine
Return		kehrt aus einer Unterroutine zurück
GotoIf		springt zu einem Ziel, wenn die Bedingung erfüllt ist
GoSubIf		geht in die Unterroutine, wenn die Bedingung erfüllt ist
SetCallerID	setzt Displayname und Nummer des Anrufers
In Klammern stehen dabei jeweils die benötigten Parameter - oder eben auch keine.

So, was ist nun ${EXTEN} und ähnliches? Ganz offensichtlich Variablen, die von Asterisk automatisch gesetzt werden. Einen Überblick gibt es unter http://www.voip-info.org/wiki/view/Asterisk+variables. Diese werden beim Auswerten der Extensions automatisch ersetzt durch ihren Wert. ${EXTEN} liefert übrigens die aktuelle Extension, ${EXTEN:1} schneidet das erste Zeichen ab, ${EXTEN:0:3} liefert nur die ersten drei Zeichen.

Ah, und warum ist eigentlich bei mir (fast) keine Extension eine richtige Nummer? Nun ja, irgendwie muss man ja doch mit Wildcards arbeiten. Einfache Ausdrücke leitet man dabei mit _ ein. Neben normalen Zahlen gibt es die folgenden Wildcards
  • X Eine Zahl zwischen 0 und 9
  • N Eine Zahl zwischen 2 und 9
  • Z Eine Zahl zwischen 1 und 9
  • . beliebig viele Zeichen und Zahlen
  • [125-8] Eine Zahl aus 1,2,5,6,7,8
So, jetzt versuche ich mal einen Weg durch den ganzen Dschungel zu erklären. Gehen wir also davon aus, dass mein Telefon als [client01] bei Asterisk angemeldet ist. Es sei Mittwoch, 13 Uhr und ich rufe die Festnetznummer 030-18 44 00 1 an.
In sip.conf ist nun als Kontext intern-client01 definiert. Diesen springen wir nun in der extensions.conf an und suchen nach der ersten zur Rufnummer passenden Extension - die Priorität ist eins.
[intern-client01]
exten => _X.,1,NoOp(${CALLERID})
exten => _X.,2,GotoIf($["${CALLERIDNAME}" != ""]?3:5)
exten => _X.,3,SetCallerID("${CALLERIDNAME}" <${PHONE1NUMBER}>)
exten => _X.,4,Goto(6)
exten => _X.,5,SetCallerID("${PHONE1NAME}" <${PHONE1NUMBER}>)
exten => _X.,6,Goto(intern,${EXTEN},1)
include => intern
Ah, _X. passt zu uns, denn die angerufene Nummer ist fängt mit einer Zahl zwischen 0 und 9 an. NoOp macht nichts,
exten => _X.,2,GotoIf($["${CALLERIDNAME}" != ""]?3:5)
setzt die Priorität auf 3, wenn ${CALLERIDNAME}, also der vom Telefon gelieferte Display Name, nicht leer ist, ansonsten auf 5. Gehen wir mal davon aus, dass mein Telefon einen Namen liefert, wir springen also zu
exten => _X.,3,SetCallerID("${CALLERIDNAME}" <${PHONE1NUMBER}>)
und setzen die Anrufer-ID. Die folgende Zeile springt zum Goto, welches uns wiederum in den Kontext intern katapultiert und die Priorität wieder auf eins zurücksetzt.
[intern]
; check with exceptions
include => out-exceptions
; try to route calls with available providers
include => out-route
; unrouteable extension, try default
include => default-out
; no outgoing extension available, try local
include => local
; nothing found yet? playback error
exten => i,1,Playback(invalid)
exten => i,2,Hangup
Oh, aber was macht include? Naja, es inkludiert den benannten Kontext in den aktuellen, tut also so, also ob der Inhalt des inkludierten Kontextes im aktuellen stehen würde.
Ich nehme einfach mal vorne weg, dass die out-exceptions bei unserer Rufnummer nicht zutreffen und wandere in den Routingteil.
[out-route]
; route outgoing (external) calls to provider
; use the first number 2-9 to choose provider
; try numbers beginning with 1 in local context
exten => _1.,1,GoSub(local,${EXTEN},1)
exten => _${DUSPREFIX}.,1,GoSub(dus-out,${EXTEN:1},1)
exten => _${QSCPREFIX}.,1,GoSub(qsc-out,${EXTEN:1},1)
exten => _${SIPPREFIX}.,1,GoSub(sipgate-out,${EXTEN:1},1)
; weekend, always Off-Peak
exten => _0[2-9]X.,1,GoSubIf($["${IFTIME(*|sat-sun|*|*?true)}" != ""]?qsc-out,${EXTEN},1)
 ; mo-fr, Off-Peak is 18-9h
exten => _0[2-9]X.,2,GoSubIf($["${IFTIME(18:00-8:50|mon-fri|*|*?true)}" != ""]?qsc-out,${EXTEN},1)
; On-Peak, use dus.net
exten => _0[2-9]X.,3,GoSub(dus-out,${EXTEN},1)
; 01802/01804 not supported by sipgate
exten => _0180[2,4].,1,GoSub(dus-out,${EXTEN},1)
Da wird's schon besser. Die drei Prefixe checken auf die Verwendung einer Durchwahlnummer, um direkt über den gewählten Anbieter zu telefonieren. Da unsere Nummer aber mit 0 anfängt, treffen diese schon mal nicht zu, und wir wenden uns
; weekend, always Off-Peak
exten => _0[2-9]X.,1,GoSubIf($["${IFTIME(*|sat-sun|*|*?true)}" != ""]?qsc-out,${EXTEN},1)
zu. Die Extension _0[2-9]X. trifft auf alle Festnetzrufnummern zu. GoSubIf überprüft die Bedingung und springt bei Erfüllung in die Subroutine - den Kontext [qsc-out]. Die Bedingung ist ein Ausdruck, diese werden in der Art
$[expr1 operator expr2]
formuliert; siehe auch http://www.voip-info.org/wiki/view/Asterisk+Expressions. Im Ausdruck wird die Funktion IfTime aufgerufen, welche bei Zutreffen der Zeitangabe *|sat-sun|*|* den String true zurückliefert, andernfalls einen Leerstring. Die Zeitangabe trifft für alle Tage zwischen Samstag und Sonntag, jeweils inklusive, zu; also fürs Wochenende. Heute sei jedoch Mittwoch, damit müssen wir also weitermachen. Mehr zur Zeitangabe gibt es unter http://www.voip-info.org/wiki/view/Asterisk+cmd+GotoIfTime.
So viel sei gesagt, auch die nächste Extension trifft nicht zu, erst wieder
; On-Peak, use dus.net
exten => _0[2-9]X.,3,GoSub(dus-out,${EXTEN},1)
und diese geht sofort in den Kontext
[dus-out]
exten => _X.,1,SetCallerID("${USERNAME}" <${DUSUSERID}>)
exten => _X.,2,Dial(SIP/${EXTEN}@dus,60)
exten => _X.,3,Hangup
; Return
exten => i,1,Return
Ich setze die von dus.net erwartete Caller-ID
SetCallerID("${USERNAME}" <${DUSUSERID}>)
und rufe über den Kontext dus in sip.conf die Nummer ${EXTEN}, welche ja die zu Beginn gewählte 030 - 18 44 00 1 ist:
Dial(SIP/${EXTEN}@dus,60)
Dial lässt es hier 60 Sekunden lang klingeln, dann wird automatisch aufgelegt.

Konnte keine passende Extension im aktuellen Kontext gefunden werden, so wird automatisch die Extension auf i für Invalid gesetzt, und mittels Return landen wir wieder im aufrufenden Kontext, in diesem Falle wäre das out-route. Da jedoch kein Fehler auftrat, hatten wir hier unser Telefonat und sind fertig.

Damit sollte jetzt sowohl die Konfiguration im Groben als auch die Vorgehensweise bei einem Anruf verstanden sein. Hoffe ich :)

Freitag, 25. August 2006

HOWTO_ Asterisk 1.2 unter Debian "Sarge" 3.1 installieren

Diese Anleitung beschäftigt sich mit der Installation des aktuellen PBX Asterisk 1.2.11 auf Debian GNU/Linux "Sarge" 3.1 (stable).
Um nicht auf meinem Produktivserver herumspielen zu müssen, installierte ich kurzerhand das aktuelle Debian 3.1r3 in einer virtuellen Maschine in VirtualPC 2004 SP1. Da im stable-Zweig des Debian-Package-Repositories leider nur eine veraltete Version von Asterisk vorhanden ist, welche nicht mit QSC IPfonie privat zusammenarbeitet, kompilierte ich das ganze kurzerhand selbst. Dies war in wenigen Minuten abgehandelt.
Doch nun kam der Schock, als ich das ganze ebenso auf meinem Produktivsystem machen wollte - denn die zur Kompilierung benötigen Packages ließen sich nicht installieren. Ich hatte nämlich bereits Software aus dem testing-Zweig installiert und mir damit Packages eingehandelt, welche sich nicht mehr mit den äußerst empfindlichen libc-Packages vereinbaren ließen.
Genauso wenig konnte ich auch den halbwegs aktuellen Asterisk 1.2.10 aus testing verwenden, denn die diversen Inkompatibilitäten hätten gleich noch den MySQL 4.1 Server mit deinstalliert.
Nach vielem Herumprobieren fand ich nun doch einen Weg, wie der Asterisk ohne große Klimmzüge auf meinen Server findet.

Teil 1: Pinnen

In /etc/apt/sources.list muss mindestens ein testing Zweig hinzugefügt werden. Am einfachsten kopiert man sich dazu einen der vorhandenen stable-Server und schreibt diesen auf testing um:
# Stable server
deb http://ftp.uni-koeln.de/debian/ stable main

# testing server
deb http://ftp.uni-koeln.de/debian/ testing main

# unstable server
deb http://ftp.uni-koeln.de/debian/ unstable main

Nun müssen, damit das System nicht vollkommen durcheinander gerät, noch die Prioritäten der einzelnen Zweige eingestellt werden. Sofern nicht vorhanden, legt man mit touch /etc/apt/prefences die entsprechende Datei an und schreibt folgende Zeilen hinein.
Package: *
Pin: release a=stable
Pin-Priority: 700

Package: *
Pin: release a=testing
Pin-Priority: 650

Package: *
Pin: release a=unstable
Pin-Priority: 600
Man beachte die absteigenden Prioritäten.

Teil 2: Software installieren

Um Asterisk kompilieren zu können, muss erst einmal eine Menge Software installiert werden. Auf einem "frischen" System wird das mit dem folgenden Kommando erledigt.
# apt-get -t testing install termcap-compat libnewt-dev \
libncurses5-dev openssl libssl-dev zlib1g-dev gcc make

Jetzt noch Asterisk herunterladen und dann kann es losgehen.
# cd ~
# wget http://ftp.digium.com/pub/asterisk/asterisk-1.2-current.tar.gz
# tar -xzf asterisk-1.2-current.tar.gz


Teil 3: Asterisk compilieren

# cd ~/asterisk-1.2.11
# make clean; make install; make samples
Mehr gibt es nicht dazu :).

Teil 4: Startupscript anlegen

In /etc/init.d erzeugt man noch mit touch /etc/init.d/asterisk ein Startupscript, in welches der folgende Inhalt eingetragen wird.
#!/bin/sh -e
#
# asterisk              This init.d script is used to start asterisk.
#                       It basically just calls asterisk.

ENV="env -i LANG=C PATH=/usr/local/bin:/usr/bin:/bin"


set -e
if [ -x /usr/sbin/asterisk ] ; then
        HAVE_ASTERISK=1
else
        exit 0
fi

ASTERISK="$ENV /usr/sbin/asterisk"
PIDFILE="/var/run/asterisk.pid"

asterisk_start() {
        if [ -e "$PIDFILE" ]
        then
                echo " ... Already running"
                exit 1
        fi

        $ASTERISK
}

asterisk_stop() {
        if [ -e "$PIDFILE" ]
        then
                PID=`cat $PIDFILE 2>/dev/nul`

                $ASTERISK -rx "stop now"

                CNT=0
                while [ 1 ]
                do
                        CNT=$(expr $CNT + 1)

                        [ ! -d /proc/$PID ] && break

                        if [ $CNT -gt 60 ]
                        then
                                echo " ... failed!"
                                echo "Asterisk failed to honor the stop command, please investigate the situation by hand."
                                exit 1
                        fi

                        sleep 1
                done
        else
                echo -n " ... no pidfile found! not running?"
        fi
}

case $1 in
        start)
                echo -n "Starting PBX: Asterisk"
                asterisk_start
                echo "."
        ;;
        stop)
                echo -n "Stopping PBX: Asterisk"
                asterisk_stop
                echo "."
        ;;
        reload)
                echo -n "Reloading PBX config..."
                $ASTERISK -rx "restart gracefully"
                echo "done."
        ;;
        restart | force-reload)
                echo -n "Forcing reload of PBX: Asterisk"
                asterisk_stop
                asterisk_start
                echo "."
        ;;
        *)
                echo "Usage: /etc/init.d/asterisk start|stop|restart|reload|force-reload"
        ;;
esac
Jetzt muss nur noch dieses Script beim Hoch- und Herunterfahren des System ausgeführt werden:
# update-rc.d asterisk defaults 99 00


Teil 5: Starten und verbinden

Mit /etc/init.d/asterisk start wird der Service gestartet, verbinden kann man über asterisk -r.
Die Konfigurationsdateien liegen unter /etc/asterisk.

Sonntag, 21. Mai 2006

HOWTO_ SSL-Verschlüsselung mit dem Apache httpd

  1. Schlüssel erstellen

    In einem Verzeichnis der Wahl erstellt man mit
    openssl req -new > new.cert.csr
    einen privaten Schlüssel und die Zertifikationsanforderung. Der Common Name (CM) muss dabei dem hostname des Servers entsprechen, etwa fs-design.homelinux.org.
  2. Passwort entfernen

    Mittels
    openssl rsa -in privkey.pem -out new.cert.key
    entfernt man aus dem privaten Schlüssel das Passwort.
  3. Zertifikat für Schlüssel erstellen

    openssl x509 -in new.cert.csr -out new.cert.crt -req -signkey new.cert.key -days 365
    erstellt ein Zertifikat, das 365 Tage, also ein Jahr lang, gültig ist.
  4. Zertifikat zum Apache kopieren

    mkdir /etc/apache2/conf/ssl.key
    mkdir /etc/apache2/conf/ssl.crt
    cp new.cert.key /etc/apache2/conf/ssl.key/server.key
    cp new.cert.crt /etc/apache2/conf/ssl.crt/server.crt
  5. mod_ssl konfigurieren

    Die Datei /etc/apache2/conf/ssl.conf mit dem Editor der Wahl öffnen und die Zeilen mit <IfDefine> und </IfDefine> auskommentieren. Den VirtualHost auf * setzen. Eine leere Datei für den Sessioncache anlegen mit touch /var/log/apache2/ssl_scache.
  6. Server neu starten

    Den httpd mit apache2ctl graceful neu starten, nun sollte er unter dem Port 443 SSL-verschlüsselt erreichbar sein.

HOWTO_ Apache2 mit PHP4 und GD kompilieren

Aus alten Zeiten stammt noch diese Anleitung, die ich bereits mehrmals erfolgreich ausgeführt habe. Inzwischen ist aber mein Server komplett per apt eingerichtet worden, ich habe keinen Compiler mehr benötigt.
  1. Apache2

    Anleitung laut http://www.php.net/manual/en/install.apache2.php.
    Apache httpd herunterladen und entpacken.
    #> cd apache2
    #> ./configure \
    --prefix=/etc/apache2/
    --enable-so
    #> make && make install
    In der /etc/apache2/conf/httpd.conf für User und Group einen existierenden Benutzer und dessen Gruppe, zb nobody und nogroup eintragen.
  2. PHP4 mit GD-Library

    Freetype 2, und zlib herunterladen, kompilieren und installieren ohne besondere Parameter.
    libpng herunterladen, aus scripts die makefile.linux nach ../makefile kopieren, und mit make && make install kompilieren und installieren.
    jpeg-6b downloaden und mit make kompilieren.
    #> mkdir /usr/local/man/man1
    #> cp libjpeg.* /usr/lib/
    #> cp j*.h /usr/local/
    #> make install
    GD Graphics Library herunterladen und kompilieren.
    #> cp gd.h /usr/local/lib
    #> make install
    PHP4 herunterladen und entpacken.
    #> ./configure \
    --prefix=/etc/php4 \
    --with-apx2=/etc/apache2/bin/apxs \
    --with-zlib \
    --enable-bcmath \
    --with-bz2 \
    --enable-exif \
    --enable-ftp \
    --with-gd=/usr/local/lib \
    --with-jpeg-dir

Samstag, 20. Mai 2006

HOWTO_ VPN auf niedrigster Ebene mittels VDE

  1. Einleitung

    Parallel zu OpenVPN beschäftigte ich mich auch mit einer anderen VPN-Technik, nachdem mich ein Artikel in der c't 22/05 neugierig gemacht hatte.
  2. Server unter Debian Sarge 3.1

    Während VDE zwar im stable-Zweig von Debian enthalten ist, sind es die für die komplette Funktion benötigten Pakete bridge-utils und uml_utilities nicht. Um das System nicht durcheinander zu bringen, indem ich stable und unstable mische, füge ich einen extra Servereintrag in die Datei /etc/apt/sources.list hinzu, der nach der Installation wieder auskommentiert wird. Sämtliche großen Mirrors stehen zur Wahl, momentan läuft aber folgender Eintrag gut:
    # unstable mirror
    deb http://ftp.uni-koeln.de/debian/ unstable main
    Nach einem apt-get update können nun die benötigten Pakete installiert werden:
    #> apt-get install vde bridge-utils uml_utilities
    Nun kann der unstable-Mirror in der Serverliste wieder auskommentiert werden, ein apt-get update bringt die Paketliste wieder auf den aktuellen "stable" Stand.
    Im Folgenden wird ein TAP-Device angelegt, und mit einer entsprechenden IP-Adresse hochgefahren.
    #> tunctl -t 1
    #> vde_switch -tap tap1 -daemon
    #> ifup tap1 192.168.1.1 up
  3. Client unter Mac OS X

    Für den Mac verwende ich VDE2, die Quelldateien können von der Projektseite bei Sourceforge heruntergeladen werden. Für die Kompilierung müssen die XCode-Tools mit GCC installiert sein.
    Die Sources werden entpackt, kompiliert und installiert.
    #> tar -xjf vde-2.0.2.tar.bz2
    #> cd vde-2.0.2
    #> ./configure
    #> make
    #> sudo make install
    Anschließend wird auch unter OS X ein TAP-Device benötig. Da ich im Zuge von OpenVPN tunnelblick installiert hatte, war für mich keine Arbeit mehr nötig. Manuell können die TUN/TAP-Treiber von http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ heruntergeladen werden. Das bei mir vorhandene Device ist tap0.
    #> vde_switch --tap tap0 --daemon
    Jetzt muss nur noch die Verbindung zum Server hergestellt werden. VDE tunnelt die Ethernetpakete über SSH, prinzipiell ist aber auch telnet möglich. Hier wird also jetzt der virtuelle Netzwerkstecker eingeklickt und anschließend die "Karte" hochgefahren.
    #> sudo dpipe vde_plug = ssh <USER>@<SERVER> vde_plug
    #> ifconfig tap0 192.168.1.2 up
    Und schon sind die beiden Rechner über das (virtuelle) Netzwerk 192.168.1.0/24 verbunden.
  4. Fazit

    Einrichtung geht wirklich problemlos. Allerdings gibt es meines Wissens bisher keine GUI (stört das jemanden?). Riesiger Vorteil gegenüber einem "herkömmlichen" VPN ist natürlich, dass Ethernetpakete getunnelt werden, das also hier wirklich auf der alleruntersten Ebene stattfindet. Da spielt es auch gar keine Rolle, welche Protokolle darauf aufsetzen, laut Autor des c't-Artikels war sogar eine stabile PPPoE-Verbindung zu einem DSL-Modem möglich.
    Einen Geschwindigkeitsvorteil gegenüber OpenVPN konnte ich aber nicht bemerken, zumindest nicht, was Pings oder Websurfen angeht. Und: Von einer offenen TCP/IP-Verbindung zwischen Server und Client sind beide Systeme abhängig!
  5. VDE tunneln

    Um die Verbindung zwischen Client und Server herzustellen, benötigt VDE einen Tunnel. Das Einfachste ist sicherlich SSH, da hier auch gleich die sonst nicht vorhandene Verschlüsselung mit eingebaut wird. Damit kommt man natürlich nicht durch jede Firewall, und erst recht nicht durch jeden Proxy! Es gilt also für SSH das Gleiche wie für OpenVPN. Es funktioniert auch genau so.

Dienstag, 9. Mai 2006

HOWTO_ Create an SWT Carbon Application with Eclipse under Mac OS X

It took quite some hours until I was able to get a simple "Hello World" SWT Application running under Mac OS X. Finally, it was all about copying and including the right libraries.

System

Copy the following files out of Eclipse's plugins directory to /System/Library/Frameworks/JavaVM.framework/Versions/1.4/Libraries or /System/Library/Frameworks/JavaVM.framework/Versions/1.5/Libraries, depending on which Java version your are using.
  • libswt-carbon-3139.jnilib
  • libswt-pi-carbon-3139.jnilib
  • libswt-webkit-carbon-3139.jnilib

Eclipse

Create a new Java project in Eclipse and add the following external Jars to the project's build path. You will also find them in the plugin folder of your Eclipse installation.
  • org.eclipse.swt_3.1.0.jar
  • org.eclipse.swt.carbon.macosx.ppc_3.1.1.jar
  • org.eclipse.jface_3.1.1.jar
  • org.eclipse.jface.text_3.1.1.jar
  • org.eclipse.core.runtime_3.1.1.jar
The versions of the libraries might differ to the Eclipse version you are using. But as all of them are being shipped with Eclipse, it is all a thing of having the right libraries in the right directory :).

Samstag, 22. April 2006

HOWTO_ OpenVPN mit HTTPTunnel durch Proxyserver bugsieren

Im ersten Teil ging es um die Einrichtung von OpenVPN-Server und Client. Nun ist allerdings der Zugriff auf das WWW aus vielen größeren Netzwerken durch Proxy-Server kontrolliert und beschränkt. Es gibt doch einige Mechanismen, wie sich eine VPN-Verbindung darüber aufbauen lässt.
  1. Tunneln per CONNECT

    Etliche Proxyserver erlauben auch Verbindungen zu HTTPS-Servern. Dabei hat der Proxy allerdings keinen Zugriff auf die aufgebaute Verbindung (wir erinnern uns: Verschlüsselung) und leitet die Daten einfach nur durch. Prinzipiell weiß er nicht einmal, dass am Ende eine SSL-Verbindung aufgebaut wurde, denn initial wird lediglich eine unverschlüsselte TCP/IP-Verbindung verwendet.
    Dieser Mechanismus ist im OpenVPN-Client bereits eingebaut und kann einfach in der Konfigurationsdatei eingestellt werden.
    http-proxy [proxy server] [proxy port #]

    Standardmäßig werden HTTPS-Verbindungen zum Port 443 aufgebaut, und daher beschränken Proxyadministratoren auch gerne das CONNECT-Kommando auf diesen Port. In meinem Falle "sitzt" da zu Hause aber bereits ein Webserver, so dass ich auf diese Methode leider nicht zurückgreifen kann. Mit ein wenig Herumprobieren ließe sich eventuell der Port mittels iptables sharen.
  2. HTTPTunnel

    Was aber erlaubt wird, sind unverschlüsselte, les- und cachebare HTTP-Verbindungen. Wer wirklich Pech hat, darf auch diese nur zu einem Port 80 aufbauen und - genau - da sitzt eben oft auch ein Webserver. Glücklicherweise wird der Port 8080 oftmals auch freigeschaltet, und über den lasse ich nun HTTPTunnel laufen. Tipps dazu habe ich aus diesem Artikel.
    1. Setup Server (Debian Sarge 3.1 "stable")
      Nach apt-get install httptunnel wird mit touch /etc/init.d/httptunnelein kleines Startupscript angelegt und mit folgendem Inhalt gefüllt:
      #!/bin/bash

      # Startup-script für HTTPTunnel
      # Tunnelendpunkt auf Port 8080 wird auf
      # 1194 (OpenVPN-Server) weitergeleitet
      echo Starting HTTPTunnel for OpenVPN
      hts --forward-port localhost:1194 8080
      Automatisch bei Systemstart laden:
      chmod +x /etc/init.d/httptunnel
      update-rc.d httptunnel defaults 98

      Damit ist der Tunnel eingerichtet, aber zwei Anpassungen für OpenVPN sind in der /etc/openvpn/server.conf noch vorzunehmen:
      # HTTP-Tunnelling funktioniert nur mit TCP-Paketen!
      proto tcp
      ;proto udp

      # Mit tun funktioniert das NAT-Routing auf dem VPN-Server nicht
      dev tap
      ;dev tun
      Nach einem Neustart sind die Änderungen übernommen:
      /etc/init.d/openvpn stop
      /etc/init.d/openvpn start
    2. Setup Client (Max OS X)
      Hier ist ein bisschen mehr Arbeit nötig. Auf jeden Fall müssen die aktuellen XCode-Tools installiert werden, da sonst die GCC nicht vorhanden ist.
      Die Sources müssen heruntergeladen und entpackt werden, aktuell ist 3.0.5. Nun in das Verzeichnis wechseln und mit
      ./configure
      make
      sudo make install
      sudo ./install-sh hts /usr/local/bin
      sudo ./install-sh htc /usr/local/bin
      kompilieren und installieren. Der Tunnelclient ist nun einsatzbereit:
      htc --forward-port 8080 --proxy <PROXY>[:<PORT>] [--proxy-authorization <USER>:<PASS>] <VPN_HOSTNAME>:8080

      Damit auch der VPN-Client über den HTTPTunnel geht, müssen ihm diese Änderungen über die Konfiguration bekannt gemacht werden. In den Utilities mit einem Doppelklick Tunnelblick starten, auf das Icon klicken, Details... auswählen und auf Edit Configuration klicken.
      # TAP statt TUN verwenden
      ;dev tun
      dev tap

      # HTTP verwendet TCP und nicht UDP
      ;proto udp
      proto tcp

      # Tunnel wird lokal geöffnet
      ;remote myserver.dyndns.org 1149
      remote localhost 8080
      Abspeichern und fertig ist.
    Damit lässt sich nun aus fast jedem Netzwerk heraustunneln. Die Pinglaufzeit ist mit rund 60ms akzeptabel, die Geschwindigkeit ist durch das zweifache Tunneln allerdings deutlich herabgesetzt, bei umfangreichen Webseiten dauert das Laden schon mal bis zu 5 Sekunden. Dazu muss ich allerdings sagen, dass mein Homeserver mit 1536/1024 kbps angebunden ist, letztendlich ist der Upstream der Flaschenhals. Wer nur 16 Kbyte (=128kbps) hat, wird auch nicht groß über ISDN-Geschwindigkeit hinauskommen können.
    Bei dem von mir verwendeten Proxy bricht leider die Verbindung nach kurzer Zeit immer wieder ab, eine runde halbe Minute später beendet sich dann auch der HTTPTunnel-Client und muss neu gestartet werden. Eventuell lässt sich dies aber noch über die verschiedenen Parameter (htc --help) optimieren.
    Last but not least fehlt noch ein elegantes (automatisches?) Startupscript für den HTTPTunnel-Client. Wenn ich mal wieder nichts zu tun habe...

HOWTO_ OpenVPN-Server unter Debian 3.1 "Sarge" und Mac OS X als Client

Im ersten Teil beschreibe ich, wie man innerhalb von wenigen Minuten unter Debian Sarge (der aktuellen "stable release") den OpenVPN-Server einrichtet und als Client einen Mac OS X-Rechner damit verbindet. Im zweiten Teil werde ich einige Tipps geben, wie man auch hinter einem Proxy-Server "nach Hause" kommt.
  1. Server (Debian Sarge 3.1 "stable)

    1. Installation
      Einfacher geht es nicht: apt-get install openvpn.
    2. Schlüssel und Zertifikate
      Hat so funktioniert, wie im offiziellen Quick-HOWTO beschrieben.
      Zuerst müssen die Installationsscripte in das vorgesehende Verzeichnis kopiert werden:
      cp -r /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn/
      Um nicht später bei der Erstellung der Zertifikate alles per Hand mehrfach eingeben zu müssen, werden in der Datei /etc/openvpn/easy-rsa/vars ein paar Variablen gesetzt:
      export KEY_COUNTRY=DE
      export KEY_PROVINCE=NA
      export KEY_CITY="<Stadt>"
      export KEY_ORG="<Organisation>"
      export KEY_EMAIL="<Mailadresse>"

      Das erste Zertifikat ist das er zertifizierenden Stelle, bei Common-Name ist ein beliebiger Name einzutragen, das Passwort ist nicht zu belegen.
      . ./vars; ./clean-all; ./build-ca
      Nun erstellt ./build-key-server server das Serverzertifikat, bei Common-Name ist server einzutragen, alle Nachfragen nach Zertifizierungen sind mit Y zu bejahen.

      Für jeden Client, der später zum Server connecten darf, muss nun ebenfalls ein Zertifikat und ein Schlüssel erstellt werden, dabei muss der Common-Name mit dem jeweils angegebenen Clientnamen des Kommandozeilenaufrufs (im Beispiel client1) übereinstimmen.
      ./build-key client1

      Die Diffie-Hellman-Parameter werden mit ./build-dh erstellt. Die folgende Tabelle zeigt, welche Dateien auf welchem Rechner benötigt werden:
      Datei Rechner Zweck
      ca.crt Serv+Cl Root CA Zertifikat
      ca.key Signierung Root CA Schlüssel
      dh{n}.pem Server Diffie Hellman Param.
      server.crt Server Server Zertifikat
      server.key Server Server Schlüssel
      client1.crt Client1 Client1 Zertifikat
      client1.key Client1 Client1 Schlüssel
      Alle Schlüssel (*.key) sind dabei geheim und sollten nicht öffentlich zugänglich sein. Die für den Betrieb von OpenVPN benötigten Dateien server.key, server.crt, ca.crt und dh{n}.pem sind nach /etc/openvpn zu kopieren.
    3. Konfiguration
      Die Vorlagen aus /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz nach /etc/openvpn kopieren und entpacken. Drei Änderungen sind vorzunehmen:
      # Ändert auf Clients den default Gateway auf
      # den VPN-Server um, so dass SÄMTLICHER
      # traffic über das VPN geleitet wird
      # (ausser für das jeweils lokale Netzwerk).
      push "redirect-gateway def1“

      # Aktivieren der Kompression, da
      # mehrfaches Tunnel massiv die
      # Geschwindigkeit drückt.
      comp-lzo

      # Standardwert ist nobody, doch diese
      # Gruppe existiert auf Debian Sarge nicht
      group nogroup
      Nach einem Neustart des OpenVPN-Servers wird die Konfiguration übernommen:
      /etc/init.d/openvpn stop
      /etc/init.d/openvpn start
    4. NAT-Routing
      Jetzt wird zwar sämtlicher Traffic von den Clients auf den Server geleitet, kommt von dort aber nicht mehr weiter. Daher muss hier noch etwas Arbeit geleistet werden, die Langfassung beschrieb T.J. Nelson.
      touch /etc/init.d/iptables.openvpn.sh legt eine neue Datei fürs Routing an. Folgende Zeilen sind in die Datei einzutragen:
      #!/bin/bash
      # get rid of previous iptables entries
      iptables -F
      iptables -F -t nat
      iptables -X
      
      iptables -t nat -A POSTROUTING -o eth0  -j SNAT --to 192.168.0.2
      iptables -A FORWARD  -j ACCEPT
      #iptables -L -t nat     (list all rules)
      
      # activate ip forwarding
      echo 1 > /proc/sys/net/ipv4/ip_forward
      Nun noch einmalig händisch starten
      chmod +x /scripts/iptables.ovpn.sh
      /etc/init.d/iptables.openvpn.sh
      und automatisch beim Systemstart ausführen lassen:
      update-rc.d iptbl.ovpn defaults 98
  2. Client (Max OS X)

    Die Hauptarbeit ist bereits getan, nach wenigen Schritten sollte sich nun der erste Client verbinden lassen. Der fertig geschnürte OpenVPN-Client Tunnelblick muss in der Version 3 heruntergeladen und alle enthaltenen Programme mit Doppelklick auf Tunnelblick-Complete.mpkg installiert werden.

    Nachdem die Schlüssel und Zertifkate client1.crt, client1.key und ca.crt (etwa per SCP) vom Server nach /Users/USERNAME/Library/openvpn/ gewandert sind, startet man Tunnelblick mit einem Doppelklick (zu finden unter Utilities). Ein Klick auf das Symbol öffnet das spartanische Menü, Details... öffnet den Log Output, bei dem sich ein Button Edit Configuration findet. Hier sind nur wenige Änderungen vorzunehmen:
    # Serveradresse angeben
    remote HOST PORT
    
    # Zertifikat und Schlüssel
    cert client1.crt
    key client1.key
    
    # Kompression
    comp-lzo
    Abspeichern und ein Klick auf Connect oder openvpn (Disconnected im Menü sollte erfolgreich Zugang zum Server gewähren.

Freitag, 21. April 2006

HOWTO_ Chiba 2.0.0 RC1 unter Apache Tomcat 4.1.31

Nachdem ich mich nun einen ganzen Tag lag mit Tomcat- und Java-(De)Installationen herumgeärgert habe, schreibe ich jetzt mal hier alle Schritte auf, die nötig waren.
  1. System und Software

  2. Installation von Java

    Angeblich ist Chiba zwar auch mit Java 2 SE v.5.0 lauffähig, bei mir jedoch machte es damit Probleme. Daher auf jeden Fall die 1.4er Version installieren, und zwar das SDK. Tomcat benötigt zum Kompilieren von Chiba nämlich den javac Compiler. Das Installationsverzeichnis ist egal.
  3. Installation von Tomcat

    Laut Chiba-Webseite ist die 4er Version von Tomcat erste Wahl. Der 5.0er wollte bei mir gar nicht laufen, 5.5 erkannte zwar Chiba, lud aber die Beispiele nicht. Angeblich funktioniert Chiba dennoch....
    Das Installationscript von Tomcat 4.1 erkennt den Pfad zum JDK einwandfrei, ich hatte jedoch kein Java 5.0 JDK nebenher installiert, was bei so einer Parallelinstallation dann abläuft, kann ich nicht sagen. Start- und Stopscripte werden automatisch im Startmenü eingerichtet, alternativ lässt sich Tomcat auch als NT-Service installieren.
    [Update] Tomcat 5.5 funktioniert, wenn bei der Installation auf das Verzeichnis der Java 1.4 RE verwiesen wurde und zusätzlich das Kompatibilitätsupdate "compat" installiert wird (einfach extrahieren).
  4. Installation von Chiba

    WAR-Datei herunterladen, und nach ${CATALINA.HOME}/webapps kopieren, wobei ${CATALINA.HOME} auf das Rootverzeichnis der Tomcat-Installation weist.
    Zu diesem Zeitpunkt dürfte sich die Indexseite von Chiba bereits über die URL http://127.0.0.1:8080/chiba-web-2.0.0rc1/ aufrufen lassen - der Port ließ sich bei der Tomcat-Installation einstellen. Ein Klick auf eines der Beispielscripte dürfte jedoch gnadenlos in einer von mehreren Exceptions enden:
    javax.servlet.ServletException: Servlet execution threw an exception
    javax.xml.transform.TransformerException: javax.xml.transform.TransformerException: java.lang.RuntimeException: dependant file 'C:\Programme\Apache Group\Tomcat 4.1\ui.xsl' does not exist!
    Darum ist jetzt noch der folgende, weniger nachvollziehbare Schritt notwenig.
  5. Fehlende Packages installieren

    Das Verzeichnis ${CATALINA.HOME}/common/endorsed in ${CATALINA.HOME}/common/endorsed.bak umbenennen. Von http://www.apache.org/dyn/closer.cgi/xml/xalan-j die Datei xalan-j_2_7_0-bin.zip herunterladen und die vier enthaltenen jar-Dateien nach ${CATALINA.HOME}/common/endorsed extrahieren.
  6. Installation überprüfen

    Die URL http://127.0.0.1:8080/chiba-web-2.0.0rc1/ im Browser aufrufen und bei einer der aufgelisteten XHTML-Dateien die Scripted HTML Version anklicken. Jetzt sollte alles prima laufen.
[Update] Nach etlichen Stunden und vielen Nerven habe ich jetzt auch eine ach-so-simple Lösung für Chiba unter Mac OS X 10.4 "Tiger" zu bieten.
Bei der Tomcat-Version sollte zu der "LE" gegriffen werden, zu finden unter browse download area. Sicherheitshalber benutzte ich die gezippte Version, obwohl tar und gnutar beide die tar.gz-Dateien korrekt entpackten, wenn sie auch mit einer Fehlermeldung abschlossen.
Anschließend entpackt man das Archiv und setzt ein paar Rechte.
sudo sh
cp /path/to/downloads/jakarta-tomcat-4.1.31-LE-jdk14.tar.gz /usr/local/
cd /usr/local
gnutar -xzf jakarta-tomcat-4.3.31-LE-jdk14.tar.gz
rm jakarta-tomcat-4.3.31-LE-jdk14.tar.gz
ln -s jakarta-tomcat-4.3.31 tomcat
chown -R <USERNAME>: tomcat/
chmod u+x tomcat/bin/*.sh
touch ~/start-tomcat legt das Startscript an:
#!/bin/sh
export CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.4/Home
$CATALINA_HOME/bin/startup.sh
Ganz ähnlich wird für das Stopscript (touch ~/stop-tomcat) verfahren:
#!/bin/sh
export CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.4/Home
$CATALINA_HOME/bin/shutdown.sh
Jetzt muss nur noch die WAR-Datei von Chiba nach /usr/local/tomcat/webapps/ kopiert werden und ein Reboot durchgeführt werden. Warum der Reboot? Ich weiss es nicht, aber ohne diesen funktioniert Tomcat nicht richtig und prodziert nur Sonderzeichenmüll à la à@ú3ý¸uþ, Firefox, Camino & Co. luden gar die Antwortseiten als Binärdatei herunter. Inhalt: Die soeben genannten Sonderzeichen. Nur Safari did as expected, Chiba warf eine Exception, dass keine gültige HTTP-Verbindung aufgebaut wurde. Jeder Boot tut gut, und das bei Apple...
[Update 2] Ich vermute, dass ich zu dem Zeitpunkt noch httptunnel auf dem entsprechenden Port hatte laufen lassen. Aber dass a) zwei TCP/IP-Anwendungen einen Port belegen können und b) Safari sich automatisch die Richtige auswählt, übersteigt meine Vorstellungskraft.

Reflog

Informationstechnische Howtos, Hinweise und Merkwürdiges

Batchlib v1.0 2008-03-29

Aktuelle Beiträge

HOWTO_ O2 DSL Surf &...
Der O2 DSL Surf & Phone-Router ist für die alleinige...
cypressor - 12. Feb, 19:57
Uptweak Windows XP Home...
There are a lot of annoying limitations in Windows...
cypressor - 9. Okt, 19:30
BATCHLIB_ Batchlib package...
Download Batchlib package v1.0 (5 KB zip file) What...
cypressor - 29. Mär, 19:10
BATCHLIB_ Batchlib library...
The batchlib library string.cmd is part of the batchlib...
cypressor - 29. Mär, 18:10

Homepage Ticker

Links

Status

Online seit 6579 Tagen
Zuletzt aktualisiert: 28. Jun, 11:32
RSS XML 1.0 Button-Get-Firefox

batch
batchlib
howto
tech
video
Profil
Abmelden
Weblog abonnieren