Den Schulen Freiheiten bei der Geräteauswahl geben?

Die idea­le Ausgangssituation

Es gibt ein Medi­en­zen­trum eines Land­krei­ses. Es beschäf­tigt zwei Tech­ni­ker und einen Sys­tem­ad­mi­nis­tra­tor, um fol­gen­des für die Schu­len in Trä­ger­schaft des Land­krei­ses zu leisten:

  • Ent­wick­lung von Infra­struk­tur an Schu­len (Inter­net­zu­gang, Ver­net­zung, WLAN, Präsentationstechnik)
  • Koor­di­na­ti­on mit dem Hoch­bau­amt des Land­krei­ses, z.B. bei Elektroinstallationsarbeiten)
  • War­tung und tech­ni­scher Support
  • Aus­schrei­bung und Beschaf­fung von Endgeräten
  • Abwick­lung von Garantiefällen
  • ver­läss­li­che Ver­tre­tungs­re­ge­lun­gen bei Aus­fall von Supportmitarbetenden
  • usw.

Zusätz­lich sind zwei Medi­en­päd­ago­gen am Medi­en­zen­trum ange­dockt, zwei Mit­ar­bei­ter küm­mern sich um Medi­en­ver­leih und Gerä­te­aus­lei­he (Licht­tech­nik, Beschal­lung, Film- oder Foto­aus­rüs­tung, Geo­caching­ge­rä­te, iPad-Kof­fer u.v.m.) und das Medi­en­zen­trum beschäf­tigt dar­über­hin­aus noch eine Bun­des­frei­wil­li­gen­dienst­leis­te­rin sowie einen Jahrespraktikanten.

Das Medi­en­zen­trum betreut nur die Land­kreis­schu­len auch tech­nisch, ansons­ten aber alle Schu­len und außer­schu­li­sche Bil­dungs­trä­ger mit Bera­tung und kos­ten­lo­ser Geräteausleihe.

Sol­che Medi­en­zen­tren gibt es, nicht vie­le, aber es gibt sie. Ob sie wirk­lich will, muss man ent­schei­den, wenn man hier weiterliest.

Die oft anzu­tref­fen­de Vergangenheit

In der Ver­gan­gen­heit haben Schu­len mit ihren Haus­halts­mit­teln Anschaf­fun­gen und bau­li­che Maß­nah­men im Bereich der IT-Tech­nik allein gestal­tet. Dazu konn­ten sie teil­wei­se Titel­grup­pen im Haus­halt rela­tiv frei ver­schie­ben. Dabei sind Net­ze und Gerä­te­parks ent­stan­den, die weit­ge­hend undo­ku­men­tiert vor sich hin­wer­keln. Tech­ni­scher Sup­port wur­de von exter­nen Dienst­leis­tern auf Stun­den­ba­sis über­nom­men, die meist meh­re­re Stun­den damit ver­bracht haben, zunächst zu ver­ste­hen, wie bestimm­te Din­ge vor Ort über­haupt funk­tio­nie­ren, bevor sie hel­fend aktiv wer­den konn­ten. Wenn der Tech­nik­papst­leh­rer vor Ort aus­fiel, fiel das Netz mit ihm aus.

Der Ent­wick­lungs­stand ein­zel­ner Schu­len ist dabei sehr unter­schied­lich und nicht zuletzt auch davon abhän­gig, wie ver­netzt und ein­fluss­reich Schul­lei­tun­gen in der Regi­on posi­tio­niert sind. Der eine kann Dritt­mit­tel in fast unbe­grenz­ter Höhe ein­wer­ben, der ande­re hat immer noch einen PC-Raum mit WindowsXP.

Die Her­aus­for­de­run­gen in einer sol­chen Struktur

  1. Wenn man bei Pro­ble­men schnell inter­ve­nie­ren will, kann das in der Flä­che nur funk­tio­nie­ren, wenn ich einen Groß­teil der Auf­ga­ben per Fern­war­tung erle­di­gen kann.
  2. Wenn man vor Ort Pro­ble­me lösen muss, ist eine gute Doku­men­ta­ti­on und weit­ge­hen­de Stan­dar­di­sie­rung unerlässlich.
  3. Man braucht z.B. im Bereich von WLAN- oder MDM-Sys­te­men zwin­gend man­dan­ten­fä­hi­ge Lösun­gen, d.h. bestimm­te Din­ge muss die jewei­li­ge Schu­le selbst für sich ent­schei­den dür­fen und ande­re Din­ge müs­sen zen­tral steu­er­bar sein, weil ich ansons­ten als Dienst­leis­ter im Extrem­fall n (=Anzahl der Schu­len) ver­schie­de­ne Sys­te­me bedie­nen kön­nen muss.
  4. Auch bei Platt­for­men macht es durch­aus Sinn, ein­heit­li­che Lösun­gen zu ver­wen­den, da LuL und SuS dann z.B. beim Schul­wech­sel ihre gewohn­te Umge­bung in ihrer gewohn­ten Kon­fi­gu­ra­ti­on vorfinden.
  5. Schu­len ver­lie­ren bei die­sem Anspruch aber zwangs­läu­fig Auto­no­mie im Bereich ihrer Finanz­pla­nun­gen, die bis­her immer bestan­den hat. Infra­struk­tur kann nicht ein­fach so beschafft wer­den, wenn gleich­zei­tig der Anspruch besteht, dass der Trä­ger sie ver­läss­lich war­ten soll.
  6. Die auto­di­dak­ti­schen  „Tech­nik­päps­te“ vor Ort ver­lie­ren an Ein­fluss und Anerkennung.
  7. Die Gna­de der Tech­ni­schen Betreu­ung ergießt sich auf alle Schu­len glei­cher­ma­ßen. Dabei ver­lie­ren die bis­her star­ken Sys­te­me, aber es gewin­nen die bis­her ver­nach­läs­sig­ten Schulen.

Die letz­ten drei Punk­te machen in sol­chen Struk­tu­ren übri­gens gefühlt 98% der Arbeits­zeit aus.

Jetzt ergibt sich ein her­aus­for­dern­der Spa­gat: Einer­seits brau­chen Schu­len spe­zi­ell bei der Aus­wahl von End­ge­rä­ten natür­lich päd­ago­gi­schen Hand­lungs­spiel­raum, ande­rer­seits muss die tech­ni­sche Betreu­ung die­ser Gerä­te leist­bar sein.

Extrem­bei­spie­le (lei­der rea­le aus der Beratungspraxis):

  • Eine Schu­le kauft nach päd­ago­gi­scher Bera­tung bei Media­markt 50 iPads und for­dert vom Trä­ger einen Klausurmodus.
  • Eine Schu­le möch­te auf BYOD-Gerä­ten arbei­ten und for­dert vom Trä­ger, dass die­ser alle Schü­ler­ge­rä­te in die Schul­do­mä­ne einbindet.
  • Eine Schu­le beschafft ein Pro­gramm zur Lern­stands­er­he­bung und ver­langt vom Trä­ger die Anbin­dung an das AD der Schule.
  • Eine Schu­le nimmt 50 gespen­de­te PCs an und ver­langt vom Trä­ger Hard­ware­sup­port dafür

Es darf nicht dazu kom­men, dass eine Schu­le auto­nom eine Ent­schei­dung trifft, die an ande­rer Stel­le unleist­ba­re Arbeit­pro­zes­se erzeugt. Es darf auch nicht dazu kom­men, dass der Trä­ger ein­sei­ti­ge Vor­ga­ben im Bereich der Aus­stat­tung macht. Das pas­siert aber immer genau da, wo es kein Gegen­ge­wicht in Form von medi­en­päd­ago­gi­schen Blick­win­keln gibt. Des­we­gen ist für mich eine Bera­tung hin­sicht­lich der Anschaf­fung von End­ge­rä­ten ohne Umfeld­ana­ly­se („Mal im Schul­amt Kaf­fee trin­ken“, „Infra­struk­tur ana­ly­sie­ren“, „Stake­hol­der erfra­gen“) immer kri­tisch zu sehen.

Der Ide­al­fall ist für mich ein part­ner­schaft­li­cher Umgang mit­ein­an­der, bei dem ein Part­ner den ande­ren mit­denkt und einbezieht.

Wenn der Trä­ger aus der Rol­le des „Beschaf­fers“ und „Pflicht­er­fül­lers“ und die Schu­le im Gegen­zug aus der Rol­le des „Bitt­stel­lers“ her­aus­kommt, sind nach mei­ner Erfah­rung viel mehr Din­ge möglich.

Lei­der sind die­se Rol­len­bil­der in so man­cher Regi­on ziem­lich ver­här­tet. Und lei­der bringt ein sol­ches Ver­hält­nis natür­lich auch Auto­no­mie­ein­bu­ßen mit sich – vor allem bei Schu­len, die bis­her sehr gut auf­ge­stellt waren.

Etwas zu aktu­el­len Ten­den­zen bei Endgeräten

Ich hal­te momen­tan iPads aus tech­ni­scher und War­tungs­sicht für abso­lut alter­na­tiv­los. Das Preis-/Leis­tungs­ver­hält­nis stimmt, es gibt sehr brauch­ba­re MDM-Lösun­gen dafür, die Ein­satz­mög­lich­kei­ten im Unter­richt (z.B. als mobi­le Doku­men­ten­ka­me­ra) sind viel­fäl­tig. Es hat für mich einen pri­mär tech­ni­schen Grund, war­um sich die­se Lösung momen­tan stark ver­brei­tet. Es wird noch etwas dau­ern, bis von ande­ren Her­stel­lern ver­gleich­ba­re und glei­cher­ma­ßen bezahl­ba­re Ange­bo­te kommen.

Die aus mei­ner Sicht Zemen­tie­rung des klas­si­schen Unter­richts­mo­dells z.B. in der Class­room-App fin­de ich schwie­rig. Ich lese bis­her wenig aus der iPa­ded-Ecke zum The­ma „Modi­fi­ca­ti­on“ oder „Rede­fi­ni­ti­on“. Viel­leicht sehe ich das auch nicht – auf Table­te­vents kommt das in Pro­gramm­hef­ten neben viel „Knöpf­chen­kun­de“ aber all­mäh­lich. Ich weiß auch nicht, wie es mit der Daten­schutz­fra­ge bei 1:1‑Geräten jetzt genau aus­schaut – bei schul­ei­ge­nen Gerä­ten scheint das brauch­bar gelöst zu sein. Der Ansatz, dem Nut­zer mög­lichst viel bei der Bedie­nung abzu­neh­men, ist nicht so mei­ner mit Blick auf die Not­wen­dig­keit infor­ma­ti­scher Grund­kom­pe­ten­zen in der Zukunft.

Kei­ne Rol­le wer­den iPads wei­ter­hin in tech­ni­schen Berei­chen oder im Kon­text von Berufs­ori­en­tie­rung spie­len, also über­all, wo es um Fach­an­wen­dun­gen geht. Da ist im gra­phi­schen und audio­vi­su­el­len Bereich wei­ter­hin Apple mit sei­nen iMacs sehr stark, ansons­ten wird wohl Micro­soft noch ein wenig das Feld besetzen.

Per­sön­lich blei­be ich Linux­er. Ohne zwei offe­ne Ter­mi­nal­sit­zun­gen bin ich nicht glück­lich. Die Zukunft sehe ich in ser­ver­ba­sier­ten Anwen­dun­gen („Web-Apps“), die gerä­te­un­ab­hän­gig genutzt wer­den kön­nen und auf frei­er Soft­ware basie­ren. Zusätz­lich wer­den Vir­tua­li­sie­rung bzw. vir­tu­el­le Desk­tops gera­de auch im Kon­text von Prü­fun­gen eine gewal­ti­ge Rol­le spielen.

 

 

Medienbildung und Informatik

Fol­gen­de Auf­ga­ben haben Pro­gram­mier­an­fän­ger von mir nach ca. vier Ein­hei­ten Python bekom­men. Das Bei­spiel zeigt – fin­de ich – ganz gut, dass Medi­en­kom­pe­tenz und Infor­ma­tik sich sehr gut ergän­zen kön­nen, teil­wei­se viel­leicht sogar ein­an­der bedin­gen. Das Pro­blem der Pass­wort­län­ge und dem Pass­wort­auf­bau wird hier bewusst nicht ange­spro­chen, weil das pro­gram­mier­tech­nisch etwas anspruchs­vol­ler ist. Das kommt dann in der Folgestunde.
Wei­ter­hin ist natür­lich auch das sha-2-Ver­schlüs­se­lungs­ver­fah­ren moder­ne­ren Ent­wick­lun­gen wie z.B. pbkdf2 weit unter­le­gen, aber auch pro­gram­mier­tech­nisch wesent­lich beherrsch­ba­rer. sha512 ist schon ganz ok, auch wenn heu­ti­ge Gra­fik­kar­ten ca. 200 Mil­lio­nen Schlüs­sel pro Sekun­de berechnen.

Kryptografie

Immer wie­der hörst du davon, dass bei gro­ßen Anbie­tern Daten­bank­in­hal­te gestoh­len wer­den. In dem Arti­kel steht aller­dings nichts davon, dass Pass­wör­ter gestoh­len wer­den, son­dern Hash­es. Heu­te wirst du ler­nen, dass du jetzt schon ganz ein­fach viel bes­ser sein kannst als Lin­ke­dIn und das mit nur ganz weni­gen Code­zei­len in Python.

Um alles mög­lichst gut zu ver­ste­hen, musst du auf jeden Fall die bei­den oben ver­link­ten Arti­kel lesen oder wenigs­tens überfliegen.

Aufgabe 1:

Nimm eines dei­ner Pass­wör­ter und las­se fol­gen­des Pro­gramm lau­fen (z.B. auf https://try.jupyter.org ).

1
2
3
4
5
6
7
# wir weisen Python an, Kryptografiefunktionen zu laden
import hashlib
# wir fragen nach einem Passwort
crypted_phrase = input()
# Und geben den Hash des Passworts als MD5-Hash aus
print("Hash is:")
print(hashlib.md5(crypted_phrase.encode('utf-8')).hexdigest())

Nimm jetzt den Hash und kopie­re ihn auf die­se Sei­te. Nach Ein­ga­be der Sicher­heits­ab­fra­ge (reCaptcha) kannst du schau­en, ob der Hash dei­nes Pass­worts bereits bekannt ist (Wenn du das Ver­fah­ren mit dem Pass­wort „12345678“ durch­führst, wirst du sehen, dass das „geknackt“ wird.

Wie­der­ho­le das Ver­fah­ren mit einem dei­ner Pass­wör­ter und fol­gen­dem Pro­gramm (mit „12345678“ klappt es! – auch mit dei­nem Passwort?):

1
2
3
4
5
6
7
# wir weisen Python an, Kryptografiefunktionen zu laden
import hashlib
# wir fragen nach einem Passwort
crypted_phrase = input()
# Und geben den Hash des Passworts als MD5-Hash aus
print("Hash is:")
print(hashlib.sha512(crypted_phrase.encode('utf-8')).hexdigest())

Wenn dein Pass­wort auch im zwei­ten Fall „geknackt“ wur­de, hast du ein Pro­blem, wenn du Opfer eines Daten­bank­dieb­stahls wirst. Auch dein Anbie­ter wird nur Hash­es in einer Daten­bank speichern.

Infor­mie­re dich jetzt über den Unter­schied zwi­schen dem md5- und dem sha512-Ver­schlüs­se­lungs­ver­fah­ren. Python kann fol­gen­de Ver­fah­ren „von Natur aus“: md5, sha1, sha224, sha256, sha384, sha512.

Aufgabe 2:

Das Pro­blem ist schon lan­ge gelöst – mit nur weni­gen Code­zei­len mehr. Infor­mie­re dich über den Begriff „Salt“ in Ver­bin­dung mit Hashes.

1
2
3
4
5
6
import hashlib
# Statt "somestring" kannst bzw. solltest du möglichst wirres Zeug hier reinschreiben
salt = "somestring"
crypted_phrase = input()
salted_password = crypted_phrase + salt
print(hashlib.md5(salted_password.encode('utf-8')).hexdigest())

Wenn du jetzt ver­suchst, den Hash cra­cken zu las­sen, klappt das nicht mehr, weil ein soge­nann­test „salt“ (Salz) zum Pass­wort hin­zu­ge­fügt wird. Bei unse­rem Pro­gramm ver­wen­det jedes Pass­wort jedoch den glei­chen Salt.

Auch dafür gibt es eine Lösung:

1
2
3
4
5
6
import hashlib, uuid
# Python schreibt nun für dich wirres Zeug hier hinein
salt = uuid.uuid4().hex
crypted_phrase = input()
salted_password = crypted_phrase + salt
print(hashlib.md5(salted_password.encode('utf-8')).hexdigest())

Hät­ten Lin­ke­dIn und ande­re die Benut­zer­pass­wör­ter mit einem siche­ren Algo­rith­mus (z.B. sha512) gehasht und mit einem Salt ver­se­hen, wäre der Dieb­stahl der Daten­ban­ken nicht so ein gro­ßes Pro­blem, da es sehr lan­ge dau­ern wür­de, die Pass­wör­ter aus den Hash­es zu errechnen.

In der Pra­xis spei­chert man die Salts im Klar­text zusam­men mit den Hash­es, meist durch ein Trenn­zei­chen abge­setzt. Du kannst ja ein­mal über­le­gen, war­um das kein Pro­blem darstellt.

Aufgabe 3:

Schrei­be fol­gen­de Programme

  1. Es wird zwei­mal ein Pass­wort abge­fragt und dazu ein Hash berech­net. Stim­men bei­de Hash­es (und damit die Pass­wör­ter) über­ein, soll das Pro­gramm die Aus­ga­be „Access granted!“ machen, ansons­ten „Access denied!“ ausgeben.
  2. Ein Pro­gramm fragt nach einem „Masterpasswort“ (pass­word) und einem Domain­na­men (salt). Es berech­net dar­aus einen Hash, den man als Pass­wort für die betref­fen­de Web­sei­te benut­zen kann – wenn man immer das rich­ti­ge Mas­ter­pass­wort und den glei­chen Domain­na­men ein­gibt – qua­si ein ganz ein­fa­cher Passwortmanager!

Über Owncloud mit Quellen syncen, die eigentlich nicht syncen können

Die Mög­lich­keit, Ord­ner und Datei­en über meh­re­re Gerä­te zu syn­chro­ni­sie­ren, möch­te ich nicht mehr mis­sen. Egal ob ich auf der Arbeit, zu Hau­se oder unter­wegs bin – über­all habe ich den glei­chen Datenbestand.

Wenn ich ver­schie­de­ne Diens­te im Netz nut­ze, brau­che ich meist für jeden eine eige­ne App bzw. ein eige­nes Pro­gramm. Eini­ge Diens­te schei­nen auf den ers­ten Blick gar kei­ne Syn­chro­ni­sa­ti­on zu erlau­ben (z.B. der FTP-Zugang für den Web­space). Dafür gibt es eine Lösung über Own­cloud. Own­cloud kann näm­lich schon sehr lan­ge exter­ne Daten­quel­len einbinden.

Dazu muss man sich zunächst ein­mal bei Own­cloud als Admi­nis­tra­tor ein­log­gen und unter Apps auf das +-Zei­chen klicken.

owncloud01Danach akti­viert man unter „not enab­led“ das Plug­in „Exter­nal Storage“.

owncloud02Anschlie­ßend muss man in den Admin­be­reich gehen

owncloud03… und allen Nut­zern erlau­ben, das Plug­in zu nutzen:

owncloud05Dabei sind die unter­schied­lichs­ten Pro­to­kol­le mög­lich, z.B. auch ande­re Own­cloud­sys­te­me. Man kann auch glo­ba­le Ord­ner defi­nie­ren, die allen oder nur eini­gen Nut­zern der Own­cloud-Instanz zur Ver­fü­gung ste­hen. Anschlie­ßend kann sich jeder Nut­zer unter dem Men­u­punkt „Per­so­nal“ eige­ne Daten­quel­len definieren:

owncloud06Natür­lich kann ich auch nur ein­zel­ne Ord­ner der exter­nen Quel­le synchronisieren:

owncloud07Own­cloud ver­hält sich gegen­über den exter­nen Quel­len wie ein nor­ma­ler Cli­ent, d.h. es wer­den kei­ne Daten auf dem Own­cloud­ser­ver gespei­chert – er stellt ledig­lich die Schnitt­stel­le zu ande­ren Diens­ten hier.

Der Trick ist, dass ich für alle die­se Diens­te dann nur noch eine App auf dem Tablet, dem Smart­phone oder dem Rech­ner benö­ti­ge, um mit ganz unter­schied­li­chen Quel­len Datei­en und Daten aus­zu­tau­schen, auch wenn die­se offi­zi­ell über­haupt kei­ne Syn­chro­ni­sa­ti­ons­funk­ti­on unter­stüt­zen. Die­se Diens­te erschei­nen in der Own­cloud-App ein­fach unter dem Namen, den ich für den Ord­ner ver­ge­ben habe.

Eine Syn­chro­ni­sa­ti­ons­app für IServ, mei­nen Lan­des­ser­ver, Goog­le, jeden belie­bi­gen Web­space usw. – reiz­voll – oder?

OpenLDAP automatisch installieren und einrichten

Ich habe heu­te ein Script geschrie­ben, wel­ches OpenLDAP auf Debi­an­sys­te­men auto­ma­tisch instal­lie­ren und auch gleich für ppo­li­cy kon­fi­gu­rie­ren kann. Wer sowas schon­mal von Hand gemacht hat, weiß um die Schwie­rig­kei­ten. Es soll­te auf den meis­ten Debi­an­de­ri­va­ten funk­tio­nie­ren (ent­wi­ckelt habe ich auf stretch), ist aber leicht anpass­bar, da ich alle Ein­zel­schrit­te in Funk­tio­nen gepackt habe.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/bin/bash
 
# globals
LDAPDB="mdb"
PASSWORD="test1234"
HOSTNAME=`hostname`
DOMAIN=`echo  $HOSTNAME | awk -v FS="." '{print $1}'`
TLD=`echo  $HOSTNAME | awk -v FS="." '{print $2}'`
PPOLICY_FILE="/etc/ldap/schema/ppolicy.ldif"
LOGFILE="debug.txt"
 
# basesetup()
# Installs slapd (openLDAP) unattended
# using debconf
 
basesetup() {
 
	PASS=$1
        HOST=$2
	DBTYPE=$3
 
	echo "Building LDAP-Roottree ...\n"
 
	export DEBIAN_FRONTEND=noninteractive
	echo -e " \
		slapd    slapd/internal/generated_adminpw    password   $PASS
		slapd    slapd/password2    password    $PASS
		slapd    slapd/internal/adminpw    password   $PASS
		slapd    slapd/password1    password    $PASS
		slapd	 slapd/backend: string	$DBTYPE
		slapd	 slapd/domain	string	$HOST
	" | debconf-set-selections
 
	apt-get install -y slapd ldap-utils
 
}
 
make_index() {
 
	echo "Adding index ...\n"
 
        echo -e " \
dn: olcDatabase={1}$LDAPDB,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: mail,givenName eq,subinitial
        " | ldapmodify -Y EXTERNAL -H ldapi:///
 
}
 
# configure_policy()
# installs: 	ppolicy-scheme
# 		ppolicy-module
# 		overlay
# 		ppolicycontext
# 		defaultpolicy
 
configure_policy() {
 
        echo "Setting temporary ACLs ..."
 
        echo -e " \
dn: olcDatabase={1}$LDAPDB,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write by * none
        " | ldapmodify -Y EXTERNAL -H ldapi:///
 
	echo "Adding ppolicy-scheme ..."
 
	ldapadd -Q -Y EXTERNAL -H ldapi:/// -f $PPOLICY_FILE
 
        echo "Activating ppolicy-module ..."
 
        echo -e " \
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: ppolicy.la
        " | ldapmodify -Y EXTERNAL -H ldapi:///
 
	/etc/init.d/slapd restart
 
        echo "Generating ppolicy-context ..."
 
        echo -e " \
dn: ou=policies,dc=$DOMAIN,dc=$TLD
objectClass: organizationalUnit
objectClass: top
ou: policies
        " | ldapadd -Q -Y EXTERNAL -H ldapi:///
 
        echo "Setting default policy ..."
 
        echo -e " \
dn: cn=default,ou=policies,dc=$DOMAIN,dc=$TLD
objectClass: top
objectClass: person
objectClass: pwdPolicy
cn: default
sn: default
pwdAllowUserChange: TRUE
# this don't work though documentation says it should
# pwdAttribute: userPassword
# So we use OID for workaround
pwdAttribute: 2.5.4.35
pwdInhistory: 3
pwdLockout: TRUE
pwdLockoutDuration: 1800
pwdMaxAge: 0
pwdMaxFailure: 3
pwdMinLength: 6
pwdMustChange: TRUE
pwdSafeModify: TRUE
# comment for syntax reason (trailing TAB here leads to syntax error when importing)
        " | ldapadd -Q -Y EXTERNAL -H ldapi:///
 
        echo "Generating overlay ..."
 
        echo -e " \
dn: olcOverlay=ppolicy,olcDatabase={1}$LDAPDB,cn=config
objectClass: olcOverlayConfig
objectClass: olcPPolicyConfig
olcOverlay: ppolicy
olcPPolicyDefault: cn=default,ou=policies,dc=$DOMAIN,dc=$TLD
olcPPolicyHashCleartext: FALSE
olcPPolicyUseLockout: FALSE
olcPPolicyForwardUpdates: FALSE
# comment for syntax reason (trailing TAB here leads to syntax error when importing)
        " | ldapadd -Q -Y EXTERNAL -H ldapi:///
 
}
 
# configure_tls()
# does:
#	generating of cert-authority
#	generating of certs for slapd
#	configuring of slapd for using tls
 
configure_tls() {
 
	echo
 
}
 
# toggle_acl()
# sets ACL back to save values after install
 
toggle_acl() {
 
	echo
 
}
 
# debug_output()
# dumps to file:
#	debconf values for slapd
#	complete Root-DN
#	complete cn=config
 
debug_output() {
 
	debconf-show slapd > $LOGFILE
	slapcat >> $LOGFILE
	ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config >> $LOGFILE
 
}
 
 
# cleanldap()
# Removes all of openLDAP
 
cleanldap() {
 
	apt-get remove -y slapd ldap-utils --purge
 
}
 
# main
 
basesetup $PASSWORD $HOSTNAME $LDAPDB
make_index
configure_policy
debug_output
cleanldap

Eigent­lich muss man oben nur ein ande­res Pass­wort set­zen und am Ende das „cle­anldap“ aus­kom­men­tie­ren. Da das Gan­ze noch „Work in Pro­gress“ ist, feh­len noch eini­ge Funktionen:

  1. Kon­fi­gu­ra­ti­on für TLS
  2. Inte­gra­ti­on des freeradius-Schemas
  3. Ver­nünf­ti­ge ACLs nach Abschluss der Instal­la­ti­on setzen

Ja, ich ste­he in die­sem Jahr ziem­lich auf LDAP …

Lustige Portweiterleitungen

Unse­re Schul­home­page besitzt einen eige­nen Log­in­be­reich, für den wir ger­ne auch die Nutzername/Passwortwortkombination nut­zen woll­ten wie für den Schul­ser­ver. Meh­re­re unter­schied­li­che Zugän­ge sind in der Regel nut­zer­un­freund­lich und wer­den kaum akzeptiert.

Das ver­wen­de­te Joom­la! hat zum Glück eine Rei­he von Authen­ti­fi­zie­rungs­plug­ins, unter ande­rem LDAP, POP3, IMAP oder Kebe­ros. Am ein­fachs­ten geht es über IMAP, d.h. Joom­la! ver­sucht sich mit den Nut­zer­da­ten bei Mail­ser­ver des Schul­ser­vers ein­zu­log­gen und wenn das klappt, legt es einen neu­en Benut­zer­ac­count an, den es zukünf­tig immer extern authen­ti­fi­ziert. Dum­mer­wei­se klapp­te das bei uns nur über eine unver­schlüs­sel­te Ver­bin­dung zuver­läs­sig – also kei­ne sinn­vol­le Option.

Glück­li­cher­wei­se läuft unser Joom­la! auf einem VSer­ver, auf den wir Shell­zu­griff haben. Mit einem linux­ty­pi­schen Ein­zei­ler kann man den Mail­ser­ver­port durch einen ver­schlüs­sel­ten Kanal auf den VSer­ver tun­neln – bei uns:

ssh ‑R 1143:localhost:143 unprivileged@vserver.xy ‑N ‑T

Das sorgt dafür, das der unver­schlüs­sel­te Mail­ser­ver­port 143 auf dem VSer­ver unter der Port­num­mer 1143 erreich­bar ist.

Nor­ma­ler­wei­se wür­de nach die­sem Kom­man­do das Pass­wort des Benut­zer „unpri­vi­le­ged“ (der Nut­zer soll­te mög­lichst wenig Rech­te auf dem Ziel­ser­ver haben, wes­halb die Port­num­mer auch grö­ßer als 1024 sein muss) erfragt wer­den. Damit das nicht geschieht, ver­wen­den wir die Authen­ti­fi­zie­rung per Public-Key.

Unser Schul­ser­ver ist nur per VDSL an das Inter­net ange­bun­den und wird ein­mal täg­lich pro­vi­der­sei­tig vom Netz getrennt. Damit wür­de unser Tun­nel zusam­men­bre­chen. Damit das erkannt wird, läuft fol­gen­des Script per cron­job alle fünf Minuten:

#!/bin/bash
COUNT=‚ps aux | grep unpri­vi­le­ged | wc ‑l‚
if [ $COUNT ‑ge 2 ]; then
exit 0
else
ssh ‑R 1143:localhost:143 unprivileged@vserver.xy ‑N ‑T
fi

Die Varia­ble COUNT ent­hält die Aus­ga­be der Befehls­pi­pe zwi­schen den Back­ticks ‚. Wenn der Tun­nel offen ist, ent­hält die Aus­ga­be zwei Zei­len (den eigent­li­chen Tun­nel­pro­zess und den Such­pro­zess nach „unpri­vi­le­ged“). Wenn das so ist, tut das Script nichts, wenn nicht, star­tet es den Tun­nel ein­fach neu. Das Script muss mit Root­rech­ten lau­fen, da ein Port unter­halb von 1024 lokal ver­wen­det wird.

Auf die­se Wei­se kann man im Prin­zip jeden Dienst lokal auf einen VSer­ver wei­ter­lei­ten, z.B. auf den LDAP der Mus­ter­lö­sung aus Baden-Würt­tem­berg und muss dann kei­ne Klar­text­pass­wör­ter mehr durch die Gegend schicken.

1 2 3 4 5 6 24