Differences

This shows you the differences between two versions of the page.

Link to this comparison view

file-system-permissies [2019/05/28 10:47]
file-system-permissies [2019/09/21 22:57] (current)
Line 1: Line 1:
 +====== Read-only vs Read-write filesystemen ======
 + 
 +In onze omgeving maken wij onderscheid tussen read-only en read-write
 +filesystemen. Voor de read-only filesystemen geldt dat deze vanaf de
 +web, applicatie en database servers **niet** gewijzigd kunnen worden.
 +Deze filesystemen worden gebruikt om de executeerbare delen en de
 +configuratie van applicaties op te slaan.
  
 +In onze omgeving is het zo dat alle web-app en pages directories op read-only
 +filesystemen liggen. Verder ligt alle configuratie (frontproxy,​ database,
 +applicatieserver) op een read-only filesysteem. De read-write filesystemen
 +worden alleen gebruikt voor logfiles, temp-directories en databases.
 +
 +De reden hiervoor is dat als een site gehacked wordt, het voor de
 +hacker onmogelijk is om b.v. jsp of php files te wijzigen.
 +Concreet houdt dit in dat
 +bij een geslaagde hack poging de applicatie zichzelf niet kan wijzigen
 +(op instigatie van de hacker), en dat het dus bijzonder moeilijk zal
 +zijn om b.v. aan de database inhoud te komen. ​ Overigens is er bij
 +ons nog nooit een geslaagde hackpoging geweest.
 +
 +Dit houdt in dat het voor applicaties dus niet mogelijk is om
 +self-modifying code te gebruiken (bv een jsp die een nieuwe versie van
 +zichzelf neerzet). In het geval van MMBase houdt dit in dat er niet
 +via het web-interface nieuwe delen van MMBase geinstalleerd kunnen worden
 +(want de applicatieserver mag niet schrijven in z'n web-app directory)
 +Zelfs als u bijvoorbeeld "chmod 777" (= unix speak voor world writable)
 +op een jsp bestand zou doen, dan nog is het niet te wijzigen vanaf
 +een applicatieserver. Dit willen we dan ook ten zeerste afraden.
 +
 +De enige plek vanaf waar naar de read-only filesystemen geschreven mag
 +worden is de upload server. Da's ook nodig, anders zouden er b.v. nooit nieuwe
 +jsp bestanden geplaatst kunnen worden.
 +
 +
 +==== Users en Groups namen ====
 +In het web- app- en testcluster is i.h.a. een vrij stricte relatie
 +tussen een usernaam en waar deze voor gebruikt wordt. B.v. een
 +instantie die leeft onder /​e/​XX/​YYYYYY draait bijna altijd onder
 +het userid YYYYYYXX. ​ Voorbeeld: de webserver instantie /e/fp/dmd1a
 +draait onder als user dmd1afp, de postfix instantie /e/ml/dmd2b draait
 +als dmd2bml.
 +
 +Alle user accounts worden gecreeerd volgens het "all accounts are
 +created equal" principe, wat inhoudt dat er nooit intrinsieke rechten
 +aan een account hangen. De rechten volgen pas door het account toe te
 +voegen aan specifieke groepen.
 +Om dit af te dwingen worden accounts altijd gecreeerd met uid=gid (dit
 +is unix terminologie,​ en betekent dat elk account in z'n eigen unieke
 +groep geplaatst wordt). De naam van de groep is gelijk aan de naam van
 +de user. Oftewel, als er een user X is met uid N, dan is z'n
 +primary group-id ook N en de bijbehorende groepsnaam is weer
 +X. Ook aan het uid hangen geen speciale rechten, da's gewoon het
 +eerstvolgende vrije uid boven de 5000.
 +Voorbeeld: de user "​test1afp"​. Deze heeft de volgende entry in
 +/etc/passwd
 +<​code>​
 +test1afp:​x:​5000:​5000:​Test webserver:/​e/​fp/​test1a:/​sbin/​nologin
 +</​code>​
 +Zie hoe het userid gelijk is aan het group-id (5000), dus in /etc/group
 +komt de volgende regel voor:
 +<​code>​
 +test1afp:​x:​5000:​
 +</​code>​
 +
 +Als we nu rechten uit willen delen aan deze user, dan kan dat op basis
 +van group-membership. Typisch voor een webserver is dat deze data moet
 +kunnen wegschrijven en derhalve lid van een data writers ("​dw"​) group
 +moet zijn:
 +<​code>​
 +dwtest:​x:​20000:​test1afp,​test1bfp,​webtoko1
 +</​code>​
 +
 +De groeps-id'​s hebben ook geen speciale betekenis; het eerste vrije uid
 +boven de 20000. In de groeps namen zit wel enige codering, nl in de
 +eerste twee letters:
 +
 +  * rd - Reader
 + De groep voor users die ergens mogen lezen.
 +Dit bestaat om ervoor te zorgen dat ongerelateerde entiteiten niet
 +elkaars spullen mogen lezen. De readers omvat normaal gesproken alle
 +user users die iets met een applicatie te maken hebben: webservers,
 +applicatieservers,​ databases, uploaders en beheerders.
 +  * dw - Data writer
 + De groep voor users die data mogen plaatsen.
 +Dit zijn de uploaders en de processen die zelf data wegschrijven (bv een
 +webserver die ge-upload content ergens weg moet kunnen schrijven)
 +  * cw - Content Writer
 + De groep voor users die content (denk aan php
 +code) mogen plaatsen. Dit zijn normaal gesproken alleen de uploaders.
 +
 +
 +Voorbeeld: stel dat er een applicatie <tt/foo/ is, bestaande uit een
 +paar webservers en een paar uploaders,
 +dan geeft dat aanleiding tot de volgende groepen:
 +<​code>​
 +rdfoo:​x:​20000:​uploader1,​uploader2,​foo1afp,​foo1bfp,​beheerders
 +dwfoo:​x:​20001:​uploader1,​uploader2,​foo1afp,​foo1bfp
 +cwfoo:​x:​20002:​uploader1,​uploader2
 +</​code>​
 +
 +===== File Permissies =====
 +
 +==== Het probleem: afscherming en samen kunnen schrijven ====
 +Er zijn twee problemen die we op willen lossen:
 +
 +  * Afscherming
 +Je wilt niet dat alles voor iedereen leesbaar is.
 +De uploaders van de ene omroep moeten niet de code van een andere omroep
 +kunnen zien.
 +  * Samen schrijven
 +Je wilt dat verschillende users dingen op het filesysteem met elkaar
 +kunnen delen. Bijvoorbeeld meerdeer upload accounts die samen aan de
 +code van 1 applicatie moeten kunnen werken, of meerdere geloadbalancede
 +webservers die elk onder een gesharede /data spulletjes moeten kunnen
 +wegschrijven.
 +Ook wil je vaak dat zowel uploaders als webservers samen onder /data
 +kunnens chrijven.
 +
 +
 +==== Oplossing voor Afscherming:​ Hekjes ====
 +Een hekje is een directory ergens bovenaan in een directory tree die
 +niet world readable is, slechts group readable en dus alleen te passeren
 +voor users die lid zijn van die groep.
 +
 +Voorbeeld:
 +
 +Beschouw de volgende groep:
 +<​code>​
 +readers:​x:​10000:​uploader1,​uploader2,​webserver1,​webserver2,​beheerders
 +</​code>​
 +en deze directory:
 +<​code>​
 +/​d/​netapp/​ro/​00/​ap/​www.website.nl
 +</​code>​
 +
 +Als we die directory nou owner root:​readers,​ mode 750 geven dan is alles
 +wat daaronder ligt niet meer te benaderen voor users die geen lid van de
 +groep "​readers"​ zijn. Onafhankelijk van de permissies daaronder!
 +
 +==== Oplossing voor samen Schrijven: datawriters en contentwriters ====
 +
 +Voor het schrijven roepen we ook 2 groepen in het leven: de datawriters
 +en de contentwriters. Contentwriters zijn iha de users met een upload
 +account, die vanuit de upload server de /pages (e.d.) directory mogen
 +vullen. In de datawriters groep zitten de webservers en de uploaders
 +samen. En dat geeft ze rechten om onder /data te schrijven.
 +
 +Om dit goed te laten werken is het nodig dat zowel datawriters als
 +contentwriters een umask 002 hanteren, zodat wat ze aanmaken default
 +group writable is.
 +
 +En om dat weer veilig te kunnen doen is het nodig dat ALLE users
 +een uniek primary group ID hebben.
 +
 +Dus, voorbeeld:
 +
 +We hebben de users:
 +<​code>​
 +webserver1:​x:​5001:​5001:​Ik ben een webserver:/​var/​empty/​home:/​sbin/​nologin
 +webserver1:​x:​5002:​5002:​Ik ben een webserver:/​var/​empty/​home:/​sbin/​nologin
 +uploader1:​x:​5003:​5003:​Ik ben een uploader:/​home/​omroep/​uploader1:/​bin/​bash
 +uploader2:​x:​5004:​5004:​Ik ben een uploader:/​home/​omroep/​uploader1:/​bin/​bash
 +</​code>​
 +
 +Dan hebben we de groepen:
 +<​code>​
 +readers:​x:​10000:​uploader1,​uploader2,​webserver1,​webserver2,​beheerders
 +contentwriters:​x:​10001:​uploader1,​uploader2
 +datawriters:​x:​10002:​uploader1,​uploader2,​webserver1,​webserver2
 +</​code>​
 +
 +En de permissies onder /​e/​ap/​www.website.nl zouden dan zijn:
 +<​code>​
 +$ cd /​e/​ap/​www.website.nl
 +# ls -Lla .
 +drwxr-x--- ​   2 root     ​readers ​      4.0K Jan 14 23:12 .
 +drwxrwxr-x ​   2 root     ​contenwriters 4.0K Jan 14 23:12 pages
 +drwxrwxr-x ​   2 root     ​datawriters ​  4.0K Jan 14 23:12 data
 +</​code>​
 +
 +
 +
 +==== Granulariteit van readers en content/​data-writers ====
 +
 +=== Readers ===
 +Laten we per omroep 1 readers groep aanmaken.
 +Dat betekent dat als webtoko1 en webtoko2 allebei voor $omroep werken
 +ze elkaars code kunnen lezen en de code die een omroep zelf opgehoest
 +heeft. Maar, dat zou imo geen probleem moeten zijn.
 +
 +=== Content/​Data-writers ===
 +Je wilt niet dat webtoko1 en webtoko2 over elkaars code heen kunnen
 +krassen. Ook wil je een asymmetrische relatie tussen $omroep en
 +$webtoko, nl $omroep mag wel over de code van $webtoko heenkrassen,​ maar
 +niet andersom.
 +Dit is te regelen door per omroep-webtoko combinatie een groepje aan te
 +maken:
 +<​code>​
 +readers:​x:​10000:​omroep,​webtoko1,​webtoko2,​webserver1,​webserver2,​beheerders
 +contentwriters:​x:​10001:​omroep
 +toko1writers:​x:​10002:​omroep,​webtoko1
 +toko2writers:​x:​10003:​omroep,​webtoko2
 +datawriters:​x:​10004::​omroep,​webtoko1,​webtoko2,​webserver1,​webserver2
 +</​code>​
 +
 +Op die manier kan toko1 nog wel over de data van toko2 heenschrijven,​
 +maar dat konden ze toch al, als ze in dezelfde apache instantie draaien.
 +(nl door het apache maar te laten doen)
 +
 +$omroep dreigt wel lid van veel groepen te worden op die manier
 +(net zoveel als dat ze gescheiden webtoko'​s in dienst hebben), dus die
 +moeten wellicht van tijd tot tijd "​newgrp toko1writers"​ intikken om over
 +de code van toko1 heen te kunnen krassen.
 +
 +Als tokoX nou maar 1 account heeft, en niet hoeft te delen met tokoY,
 +dan kan het simpeler opgelost worden; nl tokoX geen lid te maken van
 +enige contentwriter group en de pages directory owner tokoX.
 +Dwz owner tokoX:​contentwriters,​ mode 775.
 +
 +==== Rechten goed houden met php ====
 +Bovenstaande rechtenstructuur is essentieel voor de juiste werking van een website. Wanneer er, bijvoorbeeld door de code van de website, wijzigingen in de rechten worden aangebracht kan hierdoor functionaliteit verloren gaan. Het is daarom belangrijk dat de code van de website de rechten niet veranderd wat helaas in php niet altijd voor de hand liggend is. De basis gedachte achter ons platform is: eea is zo opgezet dat de rechten vanzelf goed komen te staan. Wij zien dus het liefst dat er zo min mogelijk gebruik wordt gemaakt van chown/chmod en consorten. Voorwaarde is wel dat het zgn "​umask"​ goed staat; dat moet op '​002'​ staan.
 +In onze web-, sshd- en ftpservers zorgen wij ervoor dat dat goed staat. In shell accounts adviseren wij om in
 +een '​.profile'​ een 'umask 002' op te nemen. Enige probleem geval zijn cronjobs. Cron draait met een verkeerd umask (022); indien er cronjobjes gebruikt worden die mogelijk files of directories zouden kunnen creeeren dan is het aan te raden om in het desbetreffende commando een umask op te nemen; bijvoorbeeld zoiets:
 +<​code>​
 +*/5 * * * * umask 002; doe_iets.php
 +</​code>​
 +
 +
 +Sommige php functies (b.v. mkdir) willen in sommige gevallen dat er permissies opgegeven worden.
 +De mkdir functie werkt als volgt:
 +<​code>​
 +bool mkdir ( string $pathname [, int $mode = 0777 [, bool $recursive = false [, resource $context ]]] )
 +</​code>​
 +
 +Dat houdt in dat als je recursive een directory aan wilt maken ("​mkdir -p" zeg maar) je opeens verplicht bent om ook permissies op te geven. Gebruik in dat geval de default permissies (hier dus 0777)
 +dat komt omdat de permissies die bij mkdir opgegeven worden, worden ge-bitmasked met je umask en op die manier toch de juiste rechten gebruikt worden.
 +
 +Bepaalde CMS'en hebben extra settings nodig om directory'​s met juiste permissies aan te maken. Bijvoorbeeld **Drupal**; definieer in settings.php:​
 +<code php>
 +
 +$settings['​file_chmod_directory'​] = 02775;
 +</​code>​