I det forrige indlæg om MySQL-sikkerhed har vi dækket en række muligheder, der kan bruges til at gøre dine MySQL-forekomster mere sikre. De inkluderede:
- Generelle MySQL-sikkerhedsforanstaltninger;
- Styring af adgang i MySQL;
- Oprettelse, ændring og sletning af brugere i MySQL;
- Tildeling og tilbagekaldelse af privilegier til og fra brugere i MySQL;
- Tjekker, hvilke privilegier der er tildelt brugere i MySQL.
I dette indlæg vil vi dykke ned i resten af mulighederne, herunder:
- Kontokategorier i MySQL;
- Roller i MySQL;
- Reserverede konti i MySQL;
- Adgangskodeadministration i MySQL;
- Kontolåsning i MySQL;
- Sikkerhedsplugins, der tilbydes af MySQL;
- Sikring af MySQL-sikkerhedskopier.
Husk på, at vi endnu en gang ikke dækker absolut alt, hvad du behøver at vide, men vi vil forsøge at give gode udgangspunkter for at lave din egen research.
Kontokategorier i MySQL
Kontokategorier blev introduceret i MySQL 8 - specifikt i MySQL 8.0.16. Her er kernen i det:
- Der er to separate kontokategorier:almindelige brugere og systembrugere;
- En almindelig bruger er en bruger uden SYSTEM_USER-privilegiet - en systembruger er en bruger med SYSTEM_USER-privilegiet;
- En almindelig bruger kan ændre almindelige konti - en sådan bruger kan ikke ændre systemkonti;
- En systembruger kan ændre både systemkonti og almindelige konti;
- Almindelige konti kan ændres af både almindelige brugere og systembrugere;
- Systemkonti kan kun ændres af systembrugere.
For at gøre brug af kontokategorier i MySQL sikkerhedsmæssigt skal du huske på, at SYSTEM_USER-privilegiet påvirker ting som kontomanipulation og dræbning af sessioner og udsagn i dem - dette koncept i MySQL tillader begrænsning af visse ændringer til visse konti, hvilket gør MySQL mere sikkert. Kontokategorier kan også bruges til at beskytte systemkonti mod manipulation af almindelige konti:for at gøre det, giv ikke mysql-skemaændringsprivilegier til almindelige konti.
For at give en konto SYSTEM_USER-privilegier skal du bruge følgende forespørgsel på en oprettet konto:
GRANT SYSTEM_USER ON *.* TO system_user;
Roller i MySQL
I MySQL er roller samlinger af privilegier. Når du tildeler en brugerkonto en rolle i MySQL, giver du alle de privilegier, der er knyttet til denne rolle. Roller kan oprettes ved hjælp af CREATE ROLE-sætningen:
CREATE ROLE ‘role_1’, ‘role_2’;
Rollenavne består af en brugerdel og en værtsdel - brugerdelen må ikke være tom, og værtsdelen er som standard "%", hvis den ikke er angivet.
Når roller oprettes, bør du tildele privilegier til dem. Privilegier kan tildeles ved hjælp af GRANT-sætningen:
- GIV ALLE PÅ demo_database.* TIL ‘demo_user’; ville give alle privilegier til en bruger kaldet demo_user på en database kaldet demo_database;
- GIV INDSÆT, VÆLG, OPDATER, SLET PÅ database.* TIL ‘demo_bruger’; ville give INSERT, SELECT, UPDATE og DELETE privilegier til en bruger kaldet demo_user på en database kaldet demo_database;
- GIV VALG PÅ demo_database.* TIL ‘demo_user’; ville give SELECT-rettigheder til en bruger kaldet demo_user på en database kaldet demo_database.
For at tildele en rolle til en individuel bruger, skal du bruge denne syntaks:
GRANT ‘role_name’ TO ‘user_name’@’localhost’;
For at tildele flere roller til en individuel bruger, skal du bruge denne syntaks:
GRANT ‘role_1’, ‘role_2’ TO ‘user_name’@’localhost’;
For at tildele roller til flere brugere på samme tid, skal du bruge denne syntaks:
GRANT ‘role_name’ TO ‘user1’@’localhost’, ‘user2’@’localhost’;
Roller kan være nyttige til at forhindre sikkerhedshændelser, fordi hvis en angriber kender adgangskoden til en ikke særlig privilegeret bruger og fejlagtigt antager, at brugeren er meget "kraftfuld" rollemæssigt, kan din applikation (og din database) være meget godt reddet.
Reserverede konti i MySQL
Når der er tale om reserverede konti, skal du huske på, at MySQL opretter konti under initialiseringen af databiblioteket. Der er et par konti, der bør betragtes som reserveret i MySQL:
- 'root'@'localhost' - denne konto er en superbrugerkonto, og den har gudlignende privilegier på tværs af alle MySQL-databaser (den kan udføre enhver handling på tværs af enhver MySQL-database). Det er værd at bemærke, at root-brugeren også kan omdøbes for at undgå at afsløre en meget privilegeret konto. For at omdøbe kontoen skal du køre følgende forespørgsel:
RENAME USER ‘root’@’localhost’ TO ‘username’@’localhost’;
- Sørg for at udstede en FLUSH PRIVILEGES; erklæring efter omdøbning af kontoen for at ændringerne træder i kraft.
- ‘mysql.sys’@’localhost’ - denne konto er en systembruger, der bruges som definerer for visning, procedurer og funktioner i sys-skemaet. Tilføjet i MySQL 5.7.9 for at undgå problemer, der kan opstå, hvis root-kontoen omdøbes.
- ‘mysql.session’@’localhost’ – denne konto bruges internt af plugins til at få adgang til serveren.
I dette tilfælde kan du ikke gøre ret meget sikkerhedsmæssigt, men husk på, at root-kontoen har gudlignende privilegier, hvilket betyder, at den kan udføre enhver handling på tværs af enhver MySQL-database og udvise forsigtighed når det besluttes, hvem der skal give rettighederne til at få adgang til kontoen. Husk også, hvad de andre MySQL-konti bruges til.
Adgangskodeadministration i MySQL
MySQL understøtter også adgangskodestyringsfunktioner. Nogle af dem omfatter:
- Evnen til periodisk at udløbe adgangskoder;
- Evnen til at undgå genbrug af adgangskode;
- Evnen til at generere adgangskoder;
- Evnen til at kontrollere, om adgangskoden i brug er stærk;
- Evnen til midlertidigt at låse brugere ude efter for mange mislykkede loginforsøg.
Nu vil vi se nærmere på disse muligheder.
For at udløbe en adgangskode manuelt, skal du bruge ALTER USER-sætningen som sådan:
ALTER USER ‘user’@’localhost’ PASSWORD EXPIRE;
For at indstille en global politik skal du ændre my.cnf-filen, så den inkluderer parameteren default_password_lifetime. Parameteren kan defineres under [mysqld]-sektionen (følgende eksempel indstiller adgangskodens levetid til 3 måneder (90 dage)):
default_password_lifetime=90
Hvis du vil have adgangskoderne til aldrig at udløbe, skal du indstille parameteren default_password_litetime til 0.
Du kan også indstille adgangskodeudløb for specifikke brugere. Hvis du vil indstille intervallet for udløb af adgangskode for en bruger kaldet demo_user, kan du bruge følgende eksempel:
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE INTERVAL 90 DAY;
Sådan deaktiverer du adgangskodeudløb:
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE NEVER;
For at nulstille den globale politik for udløb af adgangskode:
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE DEFAULT;
Restriktioner for genbrug af adgangskoder tillader ikke, at adgangskoder genbruges - for at gøre brug af denne funktion skal du bruge variablerne password_history og password_reuse_interval. Du kan enten indsætte disse variabler i my.cnf ved at se på eksemplet nedenfor eller indstille dem under kørsel ved at tilføje SET PERSIST foran udsagn nedenfor.
For at forbyde genbrug af nogen af de 5 tidligere brugte adgangskoder nyere end 365 dage, skal du bruge:
password_history=5
password_reuse_interval=365
For at kræve mindst 5 adgangskodeændringer før genbrug tillades:
ALTER USER ‘demo_user’@’localhost’ PASSWORD HISTORY 5;
Det samme kan gøres, når du opretter en bruger - udskift ALTER USER med CREATE USER.
For at generere en tilfældig adgangskode, når du opretter en bruger, skal du køre:
CREATE USER [email protected] IDENTIFIED BY RANDOM PASSWORD;
Sådan ændrer du adgangskoden for en bruger til en tilfældigt genereret:
SET PASSWORD FOR [email protected] TO RANDOM;
Din tilfældige adgangskode vil blive vist nedenunder.
Husk, at de tilfældige standardadgangskoder har en længde på 20 tegn. Længden kan styres af variablen generated_random_password_length, som har et interval fra 5 til 255.
For at kontrollere, om en brugt adgangskode er stærk, kan du bruge variablen VALIDATE_PASSWORD_STRENGTH - funktionen viser et tal fra 0 til 100, hvor 0 er det svageste og 100 er det stærkeste:
VÆLG VALIDATE_PASSWORD_STRENGTH('adgangskode');
Kontolåsning i MySQL
MySQL 8.0.19 introducerede også muligheden for midlertidigt at låse brugerkonti. Dette kan opnås ved hjælp af variablerne FAILED_LOGIN_ATTEMPTS og PASSWORD_LOCK_TIME.
For at aktivere kontolåsning, når du opretter en bruger, skal du køre:
CREATE USER ‘demo_user’@’localhost’ IDENTIFIED BY ‘password’ FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 5;
Værdien efter FAILED_LOGIN_ATTEMPTS angiver efter hvor mange mislykkede forsøg kontoen er låst, værdien efter PASSWORD_LOCK_TIME angiver kontolåsetiden i dage. Det er også muligt at angive en værdi, som ikke slutter, før kontoen er låst op ved at angive PASSWORD_LOCK_TIME som UNBOUNDED.
Sikkerhedsplugins udbydes af MySQL
MySQL tilbyder også et par plugins, der yderligere kan forbedre sikkerhedsfunktionerne. MySQL tilbyder:
- Godkendelsesplugins;
- Forbindelseskontrol-plugins;
- Adgangskodevalideringsplugins;
- Revisionsplugins;
- Firewall-plugins;
Disse plugins kan bruges til en række ting sikkerhedsmæssigt:
Godkendelsesplugins
Godkendelsesplugins kan tillade brugere at vælge mellem flere pluggbare godkendelsesmetoder, der er tilgængelige i MySQL. De kan bruges sammen med CREATE USER eller ALTER USER sætninger. Her er et eksempel:
CREATE USER ‘user_1’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘password’;
Denne forespørgsel ville implementere godkendelse ved hjælp af den oprindelige adgangskode-hash-metode.
Connection-Control Plugins
Forbindelseskontrol-plugins kan introducere en stigende forsinkelse i serversvar på forbindelsesforsøg, hvis forbindelsesforsøgene overstiger et vist antal - de er i stand til at stoppe potentielle brute-force-angreb. Dette plugin-bibliotek blev introduceret til MySQL i version 5.7.17, og det kan føjes til MySQL enten via my.cnf eller ved at indlæse plugins på serveren under kørsel.
For at tilføje plugins til my.cnf , tilføj følgende linje under [mysqld]:
plugin-load-add=connection_control.so
Når du har ændret filen, skal du gemme dine ændringer og genstarte MySQL.
For at indlæse plugins til serveren under kørsel, skal du køre:
INSTALL PLUGIN CONNECTION_CONTROL SONAME ‘connection_control.so’;
INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME ‘connection_control.so’;
Juster .so-suffikset efter behov. Hvis du har udført alt korrekt, bør CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS-tabellen indeholde alle de mislykkede forsøg på at oprette forbindelse.
Adgangskodevalideringsplugins
Adgangskodevalideringsplugins kan tillade brugere at bruge stærkere adgangskoder, hvis de bruges korrekt. Adgangskodevalideringsplugin'et kan installeres via my.cnf eller ved at indlæse pluginnet på serveren under kørsel. For at installere pluginnet via my.cnf skal du tilføje følgende linje under [mysqld], og genstart derefter serveren:
plugin-load-add=validate_password.so
Kør følgende sætning for at indlæse plugin'et under kørsel:
INSTALL PLUGIN validate_password SONAME ‘validate_password.so’;
Føj validate-password=FORCE_PLUS_PERMANENT til my.cnf for at indlæse pluginnet under runtime og forhindre det i at blive fjernet.
For at forhindre serveren i at køre, hvis pluginnet ikke er initialiseret, skal du bruge --validate-password-indstillingen med værdien FORCE eller FORCE_PLUS_PERMANENT.
Politik for adgangskodestyrke kan også ændres:For at gøre det skal du ændre værdien for validate_password_policy til LOW, MEDIUM eller STRONG. Værdien af LOW kontrollerer kun adgangskodelængden, MEDIUM-politikken tilføjer nogle betingelser, og STRONG-politikken tilføjer betingelsen om, at adgangskodeunderstrenge, der består af 4 eller flere tegn, ikke må matche ord i en ordbogsfil, der kan specificeres ved at ændre variablen validate_password_dictionary_file.
Nøglering-plugins
Nøglering-plugins kan gøre det muligt for serverkomponenter og plugins at opbevare følsomme oplysninger sikkert til genfinding. For at indlæse pluginnet i MySQL skal du tilføje følgende under [mysqld]:
early-plugin-load=keyring_file.so
For at angive nøgleringhvælvingsfilen skal du tilføje følgende (variablen keyring_vault_config skal pege på konfigurationsfilen):
loose-keyring_vault_config=”/var/lib/mysql_keyring/keyring_vault.conf”
Nøgleringfilen skal indeholde vault_url-variablen, som definerer vault-serveradressen, secret_mount_point-variablen, som definerer monteringspunktets navn, hvor nøgleringsboksen gemmer nøglerne, og et token, som skal defineres af vault-serveren. Valgfrit kan vault_ca-variablen også defineres (den skal pege på CA-certifikatet, der bruges til at signere boksens certifikater).
Genstart serveren for at ændringerne træder i kraft;
Revisionsplugins
Revisionsplugins kan aktivere overvågning, logning og blokering af aktivitet udført på MySQL-servere. For at installere MySQL Enterprise Audit skal du køre et script, der er placeret i delebiblioteket for din MySQL-instans (undgå at indsætte adgangskoden til din MySQL-instans i terminalen - brug my.cnf):
mysql < /path/to/audit_log_filter_linux_install.sql
Du kan også forhindre pluginnet i at blive fjernet under kørsel - tilføj følgende i [mysqld]-sektionen:
audit_log=FORCE_PLUS_PERMANENT
Genstart serveren for at anvende ændringerne. Bemærk, at den regelbaserede logning som standard ikke logger hændelser, der kan revideres, så for at få den til at logge alt, skal du oprette et filter:
SELECT audit_log_filter_set_filter(‘log_filter’, ‘{ “filter”: { “log”: true } }’);
Tildel den derefter til en konto:
SELECT audit_log_filter_set_user(‘%’, ‘log_filter’);
Bemærk, at revisionsplugins kun er tilgængelige i MySQL Enterprise Edition;
Firewall-plugins
Firewall-plugins kan gøre det muligt for brugere at tillade eller nægte udførelse af specifikke SQL-sætninger baseret på specifikke mønstre. MySQL Enterprise Firewall blev introduceret i MySQL 5.6.24 - den er i stand til at beskytte data ved at overvåge, advare og blokere uautoriseret aktivitet:den er i stand til at blokere SQL-injektionsangreb, overvåge trusler og blokere mistænkelig trafik samt at opdage indtrængen i databasen. Firewallen er også i stand til at logge blokerede udsagn - de kan inspiceres, og en realtidsoptælling af godkendte og afviste udsagn kan også observeres.
For at installere MySQL Enterprise Firewall skal du blot aktivere den, når du installerer MySQL Server på Windows, den kan også installeres, deaktiveres eller afinstalleres ved hjælp af MySQL Workbench 6.3.4. Firewallen kan også installeres manuelt ved at køre et script i share-mappen på din MySQL-installation. For at aktivere firewallen skal du tilføje følgende linje under [mysqld] og genstarte serveren:
mysql_firewall_mode=ON
Firewallen kan også aktiveres under kørsel:
SET GLOBAL mysql_firewall_mode = ON;
Alternativt for at bevare firewallen (hvilket betyder, at firewallen ikke skal genaktiveres ved hver efterfølgende servergenstart):
SET PERSIST mysql_firewall_mode = ON;
Giv derefter et FIREWALL_ADMIN-privilegium til enhver konto, der administrerer firewallen, og FIREWALL_USER-privilegiet til enhver konto, der kun skal have adgang til sine egne firewall-regler. Tildel også EXECUTE-privilegiet til de lagrede procedurer for firewallen i mysql-databasen. For at firewallen kan fungere, skal du registrere profiler med den, derefter træne firewallen til at kende de tilladte sætninger, som databasen kan udføre, og bagefter fortælle firewallen om at matche indgående sætninger mod den indstillede hvidliste. Hver profil har en driftstilstand - OFF, RECORDING, PROTECTING eller DETECTING. FRA deaktiverer profilen, OPTAGELSE træner firewallen, PROTECTING tillader eller afviser udførelse af sætningen, og DETECTING registrerer (men blokerer ikke) indtrængensforsøg. Regler for en specificeret profil kan nulstilles ved at indstille dens værdi til NULSTIL. FRA vil deaktivere profilen. For at indstille tilstanden skal du bruge følgende forespørgsel, hvor navn er profilnavnet og FRA er driftstilstanden:
CALL mysql.sp_set_firewall_mode(name, ‘OFF’);
Firewall-pluginnet er også kun tilgængeligt i MySQL Enterprise Edition.
Sikring af MySQL-sikkerhedskopier
For så vidt angår MySQL-sikkerhedskopier, har du et par muligheder.
- Hvis du bruger mysqldump, kan du gemme dit brugernavn og din adgangskode i my.cnf og påberåbe mysqldump sådan (følgende kommando vil dumpe alle databaser i en fil /home/backup.sql):
$ mysqldump --defaults-extra-file=/var/lib/my.cnf --single-transaction --all-databases > /home/backup.sql
- Ved at gemme dit brugernavn og din adgangskode inde i my.cnf, skriver du ikke din adgangskode inde i terminalen - sådan en metode til at tage backup er mere sikker, fordi mens dumpet kører, kan kommandoen ses via ps axen kommando.
-
Du kan også overveje at bruge mysqldump-secure, som er et POSIX-kompatibelt wrapper-script, som er i stand til at komprimere og kryptere sikkerhedskopier med stærk sikkerhed i tankerne .
-
Sikkerhedskopier kan krypteres ved at bruge OpenSSL - tag blot din sikkerhedskopi, og krypter den derefter med følgende kommando:
$ openssl enc -aes-256-cbc -salt -in backup.tar.gz -out backup.tar.gz.enc -k password
Kommandoen ovenfor vil oprette en ny krypteret fil backup.tar.gz.enc i den aktuelle mappe. Filen vil blive krypteret med den adgangskode, du valgte (erstat adgangskoden med den ønskede adgangskode). Filen kan dekrypteres senere ved at køre følgende kommando:
$ openssl aes-256-cbc -d -in backup.tar.gz.enc -out backup.tar.gz -k password
Erstat adgangskoden med din adgangskode.
-
mysqldump har en anden mulighed for at kryptere dine sikkerhedskopier (følgende eksempel komprimerer dem også med gzip):
$ mysqldump --all-databases --single-transaction --triggers --routines | gzip | openssl enc -aes-256-cbc -k password > backup.xb.enc
Erstat adgangskoden med den ønskede adgangskode.
-
Du kan også kryptere dine sikkerhedskopier ved hjælp af mariabackup eller xtrabackup. Her er et eksempel fra MariaDB-dokumentationen:
$ mariabackup --user=root --backup --stream=xbstream | openssl enc -aes-256-cbc -k password > backup.xb.enc
Erstat adgangskoden med din ønskede adgangskode.
-
Sikkerhedskopier kan også krypteres ved hjælp af ClusterControl - hvis krypteringsindstillingen er aktiveret for en bestemt sikkerhedskopi, vil ClusterControl kryptere sikkerhedskopien ved hjælp af AES-256 CBC (kryptering sker på backup-noden). Hvis sikkerhedskopien er gemt på en controller-node, streames backupfilerne i et krypteret format ved hjælp af socat eller netcat. Hvis komprimering er aktiveret, vil ClusterControl først komprimere sikkerhedskopien, derefter - kryptere den. Krypteringsnøglen genereres automatisk, hvis den ikke eksisterer, og gemmes derefter i CMON-konfigurationen i indstillingen backup_encryption_key. Husk, at denne nøgle er kodet og skal afkodes først. For at gøre det skal du køre følgende kommando:
$ cat /etc/cmon.d/cmon_ClusterID.cnf | grep ^backup_encryption_key | cut -d"'" -f2 | base64 -d > keyfile.key
Kommandoen vil læse backup_encryption_key og afkode dens værdi til et binært output. Nøglefilen kan bruges til at dekryptere sikkerhedskopien sådan:
$ cat backup.aes256 | openssl enc -d -aes-256-cbc -pass file:/path/to/keyfile.key > backup_file.xbstream.gz
For flere eksempler, se ClusterControl-dokumentationen.
Konklusion
I disse indlæg om MySQL-sikkerhed dækkede vi nogle sikkerhedsforanstaltninger, som kan være til gavn, hvis du føler behov for at stramme sikkerheden på dine MySQL-instanser. Selvom vi ikke dækkede absolut alt, føler vi, at disse punkter kan være et godt udgangspunkt, når du skal stramme sikkerheden på din MySQL-installation. Tag fra disse indlæg, hvad du vil, lav din egen research, og anvend de sikkerhedsforanstaltninger, der er mest anvendelige i din situation.