Databasebeveiliging is belangrijk voor elke MySQL-configuratie. Gebruikers vormen de basis van elk systeem. Wat databasesystemen betreft, zie ik ze over het algemeen in twee verschillende groepen:
- Gebruikers van applicaties, services of programma's, in feite klanten of klanten die een service gebruiken.
- Databaseontwikkelaars, -beheerders, analisten, enz... - Degenen die de database-infrastructuur onderhouden, ermee werken of er toezicht op houden.
Hoewel elke gebruiker op een bepaald niveau toegang tot de database nodig heeft, zijn die machtigingen niet allemaal gelijk.
Klanten en klanten hebben bijvoorbeeld toegang nodig tot hun 'gerelateerde gebruikersaccount'-gegevens, maar zelfs dat moet met enige mate van controle worden gecontroleerd. Sommige tabellen en gegevens moeten echter strikt verboden zijn (bijv. systeemtabellen).
Niettemin:
- Analyst heeft 'leestoegang nodig ', om informatie en inzicht te vergaren via het opvragen van tabellen...
- Ontwikkelaars hebben een hele reeks machtigingen en privileges nodig om hun werk uit te voeren...
- DBA's hebben 'root' of soortgelijke privileges nodig om de show uit te voeren...
- Kopers van een dienst moeten hun bestel- en betalingsgeschiedenis kunnen zien...
Je kunt je voorstellen (ik weet dat ik dat doe) hoe moeilijk het is om meerdere gebruikers of groepen gebruikers binnen een database-ecosysteem te beheren.
In oudere versies van MySQL wordt een omgeving met meerdere gebruikers op een enigszins eentonige en repetitieve manier tot stand gebracht.
Toch implementeert versie 8 een uitzonderlijke en krachtige SQL-standaardfunctie - Rollen - die een van de meer overbodige gebieden van het hele proces verlicht:het toewijzen van privileges aan een gebruiker.
Dus, wat is een rol in MySQL?
Je kunt zeker een bezoek brengen aan MySQL in 2018:What's in 8.0 en Other Observations, schreef ik hier voor de blog van Verschillend. Hier noem ik rollen voor een overzicht op hoog niveau. Waar ik ze echter alleen daar heb samengevat, lijkt dit huidige bericht dieper te gaan en zich uitsluitend op rollen te concentreren.
Hier is hoe de online MySQL-documentatie een rol definieert:"Een MySQL-rol is een benoemde verzameling privileges".
Lijkt die definitie alleen al niet nuttig?
Maar hoe?
We zullen zien in de voorbeelden die volgen.
Opmerking maken van de gegeven voorbeelden
De voorbeelden in dit bericht zijn in een persoonlijke 'single-user' ontwikkel- en leerwerkstation/-omgeving, dus zorg ervoor dat en implementeer die best practices die u ten goede komen voor uw specifieke behoeften of vereisten. De getoonde gebruikersnamen en wachtwoorden zijn puur willekeurig en zwak.
Gebruikers en rechten in eerdere versies
In MySQL 5.7 bestaan er geen rollen. Het toewijzen van privileges aan gebruikers gebeurt individueel. Laten we ze niet gebruiken om beter te begrijpen welke rollen bieden. Dat slaat helemaal nergens op, ik weet het. Maar naarmate we verder komen in de post, zal dat wel gebeuren.
Hieronder maken we enkele gebruikers aan:
CREATE USER 'reader_1'@'localhost' IDENTIFIED BY 'some_password';
CREATE USER 'reader_writer'@'localhost' IDENTIFIED BY 'another_password';
CREATE USER 'changer_1'@'localhost' IDENTIFIED BY 'a_password';
Vervolgens krijgen die gebruikers enkele privileges:
GRANT SELECT ON some_db.specific_table TO 'reader_1'@'localhost';
GRANT SELECT, INSERT ON some_db.specific_table TO 'reader_writer'@'localhost';
GRANT UPDATE, DELETE ON some_db.specific_table TO 'changer_1'@'localhost';
Oef, blij dat het voorbij is. Nu terug naar…
En zo heb je een verzoek om nog twee 'alleen-lezen' gebruikers te implementeren...
Terug naar de tekentafel:
CREATE USER 'reader_2'@'localhost' IDENTIFIED BY 'password_2';
CREATE USER 'reader_3'@'localhost' IDENTIFIED BY 'password_3';
Hen ook rechten toewijzen:
GRANT SELECT ON some_db.specific_table TO 'reader_2'@'localhost';
GRANT ALL ON some_db.specific_table TO 'reader_3'@'localhost';
Zie je hoe dit minder productief is, vol herhalingen en foutgevoelig? Maar, nog belangrijker, heb je de fout opgemerkt?
Goed voor je!
Terwijl ik privileges toeken aan deze twee extra gebruikers, heb ik per ongeluk ALLE privileges toegekend aan nieuwe gebruiker reader_3.
Oeps.
Een fout die iedereen zou kunnen maken.
Voer MySQL-rollen in
Met rollen, veel van de bovenstaande systematische privilegetoewijzing en delegatie kunnen enigszins gestroomlijnd zijn .
Het maken van gebruikers blijft in principe hetzelfde, maar het toewijzen van privileges via rollen die verschilt:
mysql> CREATE USER 'reader_1'@'localhost' IDENTIFIED BY 'some_password';
Query OK, 0 rows affected (0.19 sec)
mysql> CREATE USER 'reader_writer'@'localhost' IDENTIFIED BY 'another_password';
Query OK, 0 rows affected (0.22 sec)
mysql> CREATE USER 'changer_1'@'localhost' IDENTIFIED BY 'a_password';
Query OK, 0 rows affected (0.08 sec)
mysql> CREATE USER 'reader_2'@'localhost' IDENTIFIED BY 'password_2';
Query OK, 0 rows affected (0.28 sec)
mysql> CREATE USER 'reader_3'@'localhost' IDENTIFIED BY 'password_3';
Query OK, 0 rows affected (0.12 sec)
Als u de systeemtabel mysql.user opvraagt, kunt u zien dat de nieuw aangemaakte gebruikers bestaan:
(Opmerking:ik heb verschillende gebruikersaccounts in deze leer-/ontwikkelomgeving en heb veel van de uitvoer onderdrukt voor een betere helderheid op het scherm.)
mysql> SELECT User FROM mysql.user;
+------------------+
| User |
+------------------+
| changer_1 |
| mysql.infoschema |
| mysql.session |
| mysql.sys |
| reader_1 |
| reader_2 |
| reader_3 |
| reader_writer |
| root |
| | --multiple rows remaining here...
+------------------+
23 rows in set (0.00 sec)
Ik heb deze willekeurige tabel en voorbeeldgegevens:
mysql> SELECT * FROM name;
+--------+------------+
| f_name | l_name |
+--------+------------+
| Jim | Dandy |
| Johhny | Applesauce |
| Ashley | Zerro |
| Ashton | Zerra |
| Ashmon | Zerro |
+--------+------------+
5 rows in set (0.00 sec)
Laten we nu rollen gebruiken om privileges vast te stellen en toe te wijzen aan de nieuwe gebruikers om de naamtabel te gebruiken.
Maak eerst de rollen aan:
mysql> CREATE ROLE main_read_only;
Query OK, 0 rows affected (0.11 sec)
mysql> CREATE ROLE main_read_write;
Query OK, 0 rows affected (0.11 sec)
mysql> CREATE ROLE main_changer;
Query OK, 0 rows affected (0.14 sec)
Let nogmaals op de tabel mysql.user:
mysql> SELECT User FROM mysql.user;
+------------------+
| User |
+------------------+
| main_changer |
| main_read_only |
| main_read_write |
| changer_1 |
| mysql.infoschema |
| mysql.session |
| mysql.sys |
| reader_1 |
| reader_2 |
| reader_3 |
| reader_writer |
| root |
| |
+------------------+
26 rows in set (0.00 sec)
Op basis van deze output kunnen we vermoeden; dat in wezen rollen in feite gebruikers zelf zijn.
Vervolgens privilegetoewijzing:
mysql> GRANT SELECT ON practice.name TO 'main_read_only';
Query OK, 0 rows affected (0.14 sec)
mysql> GRANT SELECT, INSERT ON practice.name TO 'main_read_write';
Query OK, 0 rows affected (0.07 sec)
mysql> GRANT UPDATE, DELETE ON practice.name TO 'main_changer';
Query OK, 0 rows affected (0.16 sec)
Een kort intermezzo
Wacht even. Kan ik gewoon inloggen en eventuele taken uitvoeren met de rolaccounts zelf? Het zijn tenslotte gebruikers en ze hebben de vereiste rechten.
Laten we proberen in te loggen op de oefendatabase met de rol main_changer:
:~$ mysql -u main_changer -p practice
Enter password:
ERROR 1045 (28000): Access denied for user 'main_changer'@'localhost' (using password: YES
Het simpele feit dat we een wachtwoordprompt te zien krijgen, is een goede indicatie dat we dat niet kunnen (tenminste op dit moment). Zoals je je herinnert, heb ik voor geen van de rollen een wachtwoord ingesteld tijdens het maken ervan.
Wat zegt de kolom authenticatie_string van de mysql.user-systeemtabellen?
mysql> SELECT User, authentication_string, password_expired
-> FROM mysql.user
-> WHERE User IN ('main_read_only', 'root', 'main_read_write', 'main_changer')\G
*************************** 1. row ***************************
User: main_changer
authentication_string:
password_expired: Y
*************************** 2. row ***************************
User: main_read_only
authentication_string:
password_expired: Y
*************************** 3. row ***************************
User: main_read_write
authentication_string:
password_expired: Y
*************************** 4. row ***************************
User: root
authentication_string: ***various_jumbled_mess_here*&&*&*&*##
password_expired: N
4 rows in set (0.00 sec)
Ik heb de rootgebruiker opgenomen in de rolnamen voor de IN() predikaatcontrole om eenvoudig aan te tonen dat het een authenticatie_string heeft, terwijl de rollen dat niet doen.
Deze passage in de CREATE ROLE-documentatie verduidelijkt het mooi:"Een rol wanneer deze is gemaakt, is vergrendeld, heeft geen wachtwoord en krijgt de standaard authenticatie-plug-in toegewezen. (Deze rolkenmerken kunnen later worden gewijzigd met de ALTER USER-instructie, door gebruikers die de global CREATE USER privilege.)"
Terug naar de taak die voor ons ligt, kunnen we nu de rollen aan gebruikers toewijzen op basis van hun benodigde rechtenniveau.
Merk op dat er geen ON-clausule aanwezig is in het commando:
mysql> GRANT 'main_read_only' TO 'reader_1'@'localhost', 'reader_2'@'localhost', 'reader_3'@'localhost';
Query OK, 0 rows affected (0.13 sec)
mysql> GRANT 'main_read_write' TO 'reader_writer'@'localhost';
Query OK, 0 rows affected (0.16 sec)
mysql> GRANT 'main_changer', 'main_read_only' TO 'changer_1'@'localhost';
Query OK, 0 rows affected (0.13 sec)
Het kan minder verwarrend zijn als u een soort van 'naamgevingsconventie . gebruikt ' bij het vaststellen van rolnamen (ik weet niet of MySQL er op dit moment een biedt ... Community?) Als om geen andere reden dan om visueel onderscheid te maken tussen hen en reguliere 'niet-rol'-gebruikers.
Er is nog wat werk te doen
Dat was toch supereenvoudig?
Minder overbodig dan de oude manier van privilegetoewijzing.
Laten we die gebruikers nu aan het werk zetten.
We kunnen de verleende privileges voor een gebruiker zien met de SHOW GRANTS-syntaxis. Dit is wat momenteel is toegewezen aan het reader_1 gebruikersaccount:
mysql> SHOW GRANTS FOR 'reader_1'@'localhost';
+------------------------------------------------------+
| Grants for [email protected] |
+------------------------------------------------------+
| GRANT USAGE ON *.* TO `reader_1`@`localhost` |
| GRANT `main_read_only`@`%` TO `reader_1`@`localhost` |
+------------------------------------------------------+
2 rows in set (0.02 sec)
Hoewel dat een informatieve output oplevert, kunt u 'afstemmen ' de instructie voor nog gedetailleerdere informatie over eventuele exacte privileges die een toegewezen rol biedt door een USING-clausule op te nemen in de SHOW GRANTS-instructie en de naam van de toegewezen rol te noemen:
mysql> SHOW GRANTS FOR 'reader_1'@'localhost' USING 'main_read_only';
+-------------------------------------------------------------+
| Grants for [email protected] |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO `reader_1`@`localhost` |
| GRANT SELECT ON `practice`.`name` TO `reader_1`@`localhost` |
| GRANT `main_read_only`@`%` TO `reader_1`@`localhost` |
+-------------------------------------------------------------+
3 rows in set (0.00 sec)
Na inloggen met reader_1:
mysql> SELECT * FROM practice.name;
ERROR 1142 (42000): SELECT command denied to user 'reader_1'@'localhost' for table 'name'
Wat op aarde? Die gebruiker heeft SELECT-rechten gekregen via de rol main_read_only.
Laten we om dit te onderzoeken 2 nieuwe tabellen in versie 8 bezoeken, specifiek voor rollen.
De tabel mysql.role_edges laat zien welke rollen zijn toegekend aan gebruikers:
mysql> SELECT * FROM mysql.role_edges;
+-----------+-----------------+-----------+---------------+-------------------+
| FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION |
+-----------+-----------------+-----------+---------------+-------------------+
| % | main_changer | localhost | changer_1 | N |
| % | main_read_only | localhost | changer_1 | N |
| % | main_read_only | localhost | reader_1 | N |
| % | main_read_only | localhost | reader_2 | N |
| % | main_read_only | localhost | reader_3 | N |
| % | main_read_write | localhost | reader_writer | N |
+-----------+-----------------+-----------+---------------+-------------------+
6 rows in set (0.00 sec)
Maar ik denk dat de andere aanvullende tabel, mysql.default_roles, ons beter zal helpen de SELECT-problemen voor gebruiker reader_1 op te lossen:
mysql> DESC mysql.default_roles;
+-------------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+----------+------+-----+---------+-------+
| HOST | char(60) | NO | PRI | | |
| USER | char(32) | NO | PRI | | |
| DEFAULT_ROLE_HOST | char(60) | NO | PRI | % | |
| DEFAULT_ROLE_USER | char(32) | NO | PRI | | |
+-------------------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> SELECT * FROM mysql.default_roles;
Empty set (0.00 sec)
Lege resultatenset.
Het blijkt dat om een gebruiker een rol te kunnen gebruiken en uiteindelijk de privileges, de gebruiker een standaardrol moet krijgen.
mysql> SET DEFAULT ROLE main_read_only TO 'reader_1'@'localhost', 'reader_2'@'localhost', 'reader_3'@'localhost';
Query OK, 0 rows affected (0.11 sec)
(Een standaardrol kan worden toegewezen aan meerdere gebruikers in één opdracht zoals hierboven...)
mysql> SET DEFAULT ROLE main_read_only, main_changer TO 'changer_1'@'localhost';
Query OK, 0 rows affected (0.10 sec)
(Een gebruiker kan meerdere standaardrollen hebben gespecificeerd zoals in het geval voor gebruiker changer_1...)
Gebruiker reader_1 is nu ingelogd...
mysql> SELECT CURRENT_USER();
+--------------------+
| CURRENT_USER() |
+--------------------+
| [email protected] |
+--------------------+
1 row in set (0.00 sec)
mysql> SELECT CURRENT_ROLE();
+----------------------+
| CURRENT_ROLE() |
+----------------------+
| `main_read_only`@`%` |
+----------------------+
1 row in set (0.03 sec)
We kunnen de momenteel actieve rol zien en ook dat reader_1 nu SELECT-opdrachten kan geven:
mysql> SELECT * FROM practice.name;
+--------+------------+
| f_name | l_name |
+--------+------------+
| Jim | Dandy |
| Johhny | Applesauce |
| Ashley | Zerro |
| Ashton | Zerra |
| Ashmon | Zerro |
+--------+------------+
5 rows in set (0.00 sec)
Andere verborgen nuances
Er is nog een belangrijk onderdeel van de puzzel we moeten het begrijpen.
Er zijn mogelijk 3 verschillende 'niveaus' of 'varianten' van roltoewijzing:
SET ROLE …;
SET DEFAULT ROLE …;
SET ROLE DEFAULT …;
Ik wijs een extra rol toe aan gebruiker reader_1 en log vervolgens in met die gebruiker (niet weergegeven):
mysql> GRANT 'main_read_write' TO 'reader_1'@'localhost';
Query OK, 0 rows affected (0.17 sec)
Aangezien de rol main_read_write het INSERT-recht heeft, kan gebruiker reader_1 die opdracht nu toch uitvoeren?
mysql> INSERT INTO name(f_name, l_name)
-> VALUES('Josh', 'Otwell');
ERROR 1142 (42000): INSERT command denied to user 'reader_1'@'localhost' for table 'name'
Wat is hier aan de hand?
Dit kan helpen...
mysql> SELECT CURRENT_ROLE();
+----------------------+
| CURRENT_ROLE() |
+----------------------+
| `main_read_only`@`%` |
+----------------------+
1 row in set (0.00 sec)
Bedenk dat we in eerste instantie gebruiker reader_1 hebben ingesteld als standaardrol main_read_only. Dit is waar we een van die verschillende 'niveaus' moeten gebruiken van wat ik losjes noem 'rolinstelling':
mysql> SET ROLE main_read_write;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT CURRENT_ROLE();
+-----------------------+
| CURRENT_ROLE() |
+-----------------------+
| `main_read_write`@`%` |
+-----------------------+
1 row in set (0.00 sec)
Probeer die INSERT nu opnieuw:
mysql> INSERT INTO name(f_name, l_name)
-> VALUES('Josh', 'Otwell');
Query OK, 1 row affected (0.12 sec)
Zodra gebruiker reader_1 zich echter weer afmeldt, is de rol main_read_write niet langer actief wanneer reader_1 weer inlogt. Hoewel gebruiker reader_1 de rol main_read_write heeft, is dit niet de standaard.
Laten we nu het 3e 'niveau' van 'rolinstelling' leren kennen, STEL DE STANDAARD ROL IN.
Stel dat aan gebruiker reader_1 nog geen rollen zijn toegewezen:
mysql> SHOW GRANTS FOR 'reader_1'@'localhost';
+----------------------------------------------+
| Grants for [email protected] |
+----------------------------------------------+
| GRANT USAGE ON *.* TO `reader_1`@`localhost` |
+----------------------------------------------+
1 row in set (0.00 sec)
Laten we deze gebruiker 2 rollen TOEKENNEN:
mysql> GRANT 'main_changer', 'main_read_write' TO 'reader_1'@'localhost';
Query OK, 0 rows affected (0.07 sec)
Wijs een standaardrol toe:
mysql> SET DEFAULT ROLE ‘main_changer’ TO 'reader_1'@'localhost';
Query OK, 0 rows affected (0.17 sec)
Met gebruiker reader_1 ingelogd, is die standaardrol actief:
mysql> SELECT CURRENT_ROLE();
+--------------------+
| CURRENT_ROLE() |
+--------------------+
| `main_changer`@`%` |
+--------------------+
1 row in set (0.00 sec)
Schakel nu over naar de rol main_read_write:
mysql> SET ROLE 'main_read_write';
Query OK, 0 rows affected (0.01 sec)
mysql> SELECT CURRENT_ROLE();
+-----------------------+
| CURRENT_ROLE() |
+-----------------------+
| `main_read_write`@`%` |
+-----------------------+
1 row in set (0.00 sec)
Maar om terug te keren naar de toegewezen standaardrol, gebruik SET ROLE DEFAULT zoals hieronder getoond:
mysql> SET ROLE DEFAULT;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT CURRENT_ROLE();
+--------------------+
| CURRENT_ROLE() |
+--------------------+
| `main_changer`@`%` |
+--------------------+
1 row in set (0.00 sec)
Rollen niet toegekend
Ook al heeft gebruiker changer_1 2 rollen beschikbaar tijdens een sessie:
mysql> SELECT CURRENT_ROLE();
+-----------------------------------------+
| CURRENT_ROLE() |
+-----------------------------------------+
| `main_changer`@`%`,`main_read_only`@`%` |
+-----------------------------------------+
1 row in set (0.00 sec)
Wat gebeurt er als je een gebruiker probeert en een rol instelt die hem niet is toegekend?
mysql> SET ROLE main_read_write;
ERROR 3530 (HY000): `main_read_write`@`%` is not granted to `changer_1`@`localhost`
Afgewezen.
Taketh Away
Geen enkel gebruikersbeheersysteem zou compleet zijn zonder de mogelijkheid om de toegang tot bepaalde bewerkingen te beperken of zelfs te verwijderen, mocht dat nodig zijn.
We hebben de opdracht SQL REVOKE tot onze beschikking om privileges van gebruikers en rollen te verwijderen.
Bedenk dat de rol main_changer deze set privileges heeft, in wezen hebben al die gebruikers die deze rol hebben gekregen dat ook:
mysql> SHOW GRANTS FOR main_changer;
+-----------------------------------------------------------------+
| Grants for [email protected]% |
+-----------------------------------------------------------------+
| GRANT USAGE ON *.* TO `main_changer`@`%` |
| GRANT UPDATE, DELETE ON `practice`.`name` TO `main_changer`@`%` |
+-----------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> REVOKE DELETE ON practice.name FROM 'main_changer';
Query OK, 0 rows affected (0.11 sec)
mysql> SHOW GRANTS FOR main_changer;
+---------------------------------------------------------+
| Grants for [email protected]% |
+---------------------------------------------------------+
| GRANT USAGE ON *.* TO `main_changer`@`%` |
| GRANT UPDATE ON `practice`.`name` TO `main_changer`@`%` |
+---------------------------------------------------------+
2 rows in set (0.00 sec)
Om te weten voor welke gebruikers deze wijziging gevolgen heeft, kunnen we de tabel mysql.role_edges opnieuw bezoeken:
mysql> SELECT * FROM mysql.role_edges WHERE FROM_USER = 'main_changer';
+-----------+--------------+-----------+-----------+-------------------+
| FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION |
+-----------+--------------+-----------+-----------+-------------------+
| % | main_changer | localhost | changer_1 | N |
+-----------+--------------+-----------+-----------+-------------------+
1 row in set (0.00 sec)
En we kunnen zien dat gebruiker changer_1 niet langer het DELETE-recht heeft:
mysql> SHOW GRANTS FOR 'changer_1'@'localhost' USING 'main_changer';
+--------------------------------------------------------------------------+
| Grants for [email protected] |
+--------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `changer_1`@`localhost` |
| GRANT UPDATE ON `practice`.`name` TO `changer_1`@`localhost` |
| GRANT `main_changer`@`%`,`main_read_only`@`%` TO `changer_1`@`localhost` |
+--------------------------------------------------------------------------+
3 rows in set (0.00 sec)
Ten slotte, als we een rol volledig moeten verwijderen, hebben we daarvoor het DROP ROLE-commando:
mysql> DROP ROLE main_read_only;
Query OK, 0 rows affected (0.17 sec)
En bij het opvragen van de tabel mysql.role_edges, rol main_read_only is verwijderd:
mysql> SELECT * FROM mysql.role_edges;
+-----------+-----------------+-----------+---------------+-------------------+
| FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION |
+-----------+-----------------+-----------+---------------+-------------------+
| % | main_changer | localhost | changer_1 | N |
| % | main_read_write | localhost | reader_1 | N |
| % | main_read_write | localhost | reader_writer | N |
+-----------+-----------------+-----------+---------------+-------------------+
3 rows in set (0.00 sec)
(Bonus:deze fantastische YouTube-video was een geweldig leermiddel voor mij over rollen.)
Dit voorbeeld van het maken van gebruikers, het toewijzen van rollen en het instellen is op zijn best rudimentair. Toch hebben rollen hun eigen regels waardoor ze verre van triviaal zijn. Ik hoop dat ik door deze blogpost licht heb geworpen op die gebieden die minder intuïtief zijn dan andere, waardoor lezers het mogelijke gebruik van rollen binnen hun systemen beter kunnen begrijpen.
Bedankt voor het lezen.