RE:NODE

ბაზები13 წუთის საკითხავი

MySQL-ის მომხმარებლები და უფლებები: CREATE USER, GRANT და role-ები

როგორ მუშაობს MySQL 8.4-ის ანგარიშები: მომხმარებელი და host pattern, CREATE USER, GRANT და REVOKE, role-ები, პაროლის პოლიტიკა და მინიმალური უფლებების სქემა აპლიკაციისთვის.

0 მკითხველი

MySQL-ის ანგარიში მომხმარებლის სახელი არ არის. ის მომხმარებლის სახელი და host pattern-ია ერთად - 'app'@'%' და 'app'@'localhost' ორი სხვადასხვა ანგარიშია, საკუთარი პაროლებითა და საკუთარი უფლებებით. როგორც კი ამას ჩასწვდები, MySQL-ის უფლებების სისტემის უმეტესი ნაწილი მარტივია: ანგარიშს CREATE USER-ით ქმნი, GRANT-ით აძლევ უფლებებს გლობალურ, ბაზის, ცხრილის ან სვეტის დონეზე, უფლებების ხშირ ნაკრებებს role-ებად აჯგუფებ და შედეგს SHOW GRANTS-ით ამოწმებ. ჩვევა, რომელიც ღირს გამოიმუშაო, არის ყოველი აპლიკაციისთვის საკუთარი ანგარიშის მიცემა უფლებებით მის საკუთარ ბაზაზე და მეტი არაფერი, ხოლო root-ის შენახვა ადმინისტრირებისთვის.

ეს გზამკვლევი MySQL 8.4 LTS-ს ფარავს. მისი უმეტესი ნაწილი 8.0-შიც იგივეა; განსხვავებები მონიშნულია იქ, სადაც მნიშვნელოვანია. თუ MySQL 5.7-იდან მოდიხარ, ორი ცვლილება, რომელიც ძველ სკრიპტებს ამტვრევს, ისაა, რომ GRANT აღარ ქმნის მომხმარებლებს და რომ ნაგულისხმევი პაროლის plugin არის caching_sha2_password.

ანგარიში არის მომხმარებელი პლუს ჰოსტი#

ყოველი ანგარიში mysql.user-ში ინახება User და Host სვეტებით. როცა კლიენტი უკავშირდება, MySQL უყურებს მისამართს, საიდანაც მოვიდა, და სახელს, რომელიც მისცა, და ირჩევს ერთადერთ ყველაზე კონკრეტულ შესაბამის ხაზს. უფლებები ამ ხაზიდან მოდის და სხვა არსაიდან.

sql
SELECT user, host, plugin, account_locked, password_last_changedFROM mysql.userORDER BY user, host;
Host მნიშვნელობაემთხვევაშენიშვნა
localhostUnix socket კავშირებს სერვერზეარა TCP-ს 127.0.0.1-ზე, თუ სახელის გადაწყვეტა მას ასე არ ასახავს
127.0.0.1TCP-ს იმავე მანქანიდან
203.0.113.50ზუსტად ამ მისამართსყველაზე კონკრეტული ფორმა
198.51.100.%ნებისმიერ მისამართს, რომელიც 198.51.100.-ით იწყება% ნებისმიერი სტრიქონია, _ ნებისმიერი ერთი სიმბოლო
198.51.100.0/24იგივეს, CIDR ფორმითCIDR ჩანაწერს 8.0.23 ან უფრო ახალი სჭირდება
%.example.netჰოსტებს, რომელთა reverse DNS example.net-ით მთავრდებამომუშავე reverse DNS სჭირდება; მოერიდე
%ყველგანჩვეული არჩევანი, როცა კლიენტის მისამართი ფიქსირებული არ არის

დამთხვევა ხაზებს ჯერ ჰოსტის კონკრეტულობით ალაგებს - ლიტერალური მისამართები და სახელები pattern-ებამდე, pattern-ები შიშველ %-მდე - და მხოლოდ შემდეგ მომხმარებლის სახელით. ეს კლასიკურ ხაფანგს ქმნის: ზოგიერთ ძველ ინსტალაციას ანონიმური ანგარიში ''@'localhost' მოჰყვება. მომხმარებელი, რომელიც localhost-იდან app-ად უკავშირდება, ანონიმურ ხაზს 'app'@'%'-მდე ემთხვევა, რადგან ჰოსტი უფრო კონკრეტულია, და შემდეგ არცერთი იმ უფლებიდან არ აქვს, რომელიც მიეცა. SELECT CURRENT_USER(); შესვლის შემდეგ გეუბნება, რომელ ხაზს დაემთხვიე სინამდვილეში. თუ ის @localhost-ს აჩვენებს ცარიელი მომხმარებლით, ანონიმური ანგარიში წაშალე.

როცა კლიენტის მისამართი იცვლება - სახლის ინტერნეტი, ლეპტოპი, აპლიკაციის პლატფორმა ფიქსირებული გამავალი მისამართის გარეშე - % პრაქტიკული არჩევანია, და ანგარიშს პაროლი და TLS იცავს. როცა ფიქსირებული მისამართი გაქვს, მისი გამოყენება იაფი დამატებითი ფენაა.

მომხმარებლების შექმნა#

sql
CREATE USER 'app'@'%'  IDENTIFIED BY 'a-long-generated-password'  REQUIRE SSL  PASSWORD EXPIRE NEVER;

ანგარიში ნაგულისხმევი ავთენტიკაციის plugin-ით, caching_sha2_password-ით იქმნება. MySQL 8.4-ში ნაგულისხმევს authentication_policy ადგენს; ძველი default_authentication_plugin ცვლადი ამოღებულია. mysql_native_password არსებობს, მაგრამ გამორთულია, თუ სერვერი mysql_native_password=ON-ით არ ჩაირთო, ამიტომ IDENTIFIED WITH mysql_native_password სტანდარტულ 8.4 სერვერზე ვარდება.

MySQL-ს შეუძლია პაროლი შენთვის დააგენერიროს და ერთხელ დაბეჭდოს:

sql
CREATE USER 'report'@'%' IDENTIFIED BY RANDOM PASSWORD;
code
+--------+------+----------------------+-------------+| user   | host | generated password   | auth_factor |+--------+------+----------------------+-------------+| report | %    | 7Ba(Xr;lWk.Vx4Tq,Z%3 |           1 |+--------+------+----------------------+-------------+

სიგრძე generated_random_password_length-იდან მოდის (ნაგულისხმევად 20). მაშინვე დააკოპირე; ის არსად ინახება ისე, რომ უკან წაიკითხო.

სხვა პუნქტები, რომლებიც ღირს იცოდე:

  • IF NOT EXISTS ბრძანებას უსაფრთხოს ხდის provisioning სკრიპტში ხელახლა გასაშვებად.
  • REQUIRE SSL ამ ანგარიშისთვის დაუშიფრავ კავშირებს უარყოფს. REQUIRE X509 კლიენტის სერტიფიკატს ითხოვს.
  • WITH MAX_USER_CONNECTIONS 20 ანგარიშის ერთდროულ session-ებს ზღუდავს, რაც ერთ გაკონტროლებიდან გამოსულ სერვისს უშლის ხელს, max_connections-ის ქვეშ ყველა სლოტი დაიკავოს.
  • ACCOUNT LOCK ანგარიშს გამორთულს ქმნის, რაც სასარგებლოა definer ანგარიშისთვის, რომელიც view-ებსა და routine-ებს ფლობს, მაგრამ არასოდეს უნდა შევიდეს.
  • COMMENT 'billing service' mysql.user-ში შენიშვნას ინახავს (8.0.21 და უფრო ახალი), რისიც ორ წელიწადში გაგიხარდება.

არსებული ანგარიშის შესაცვლელად გამოიყენე ALTER USER; სახელის გადასარქმევად RENAME USER 'app'@'%' TO 'shop'@'%'; წასაშლელად DROP USER IF EXISTS 'app'@'%'. მომხმარებლის წაშლა მის მიერ შექმნილ ობიექტებს არ შლის, მაგრამ view-ები და routine-ები, რომელთა DEFINER ეს მომხმარებელი იყო, მუშაობას წყვეტენ, სანამ definer ისევ არ იარსებებს.

GRANT და REVOKE#

უფლებები გარკვეულ დონეზე გაიცემა და დონე ON პუნქტია:

sql
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app'@'%';          -- databaseGRANT SELECT ON appdb.orders TO 'report'@'%';                          -- tableGRANT SELECT (id, email, created_at) ON appdb.users TO 'support'@'%';  -- columnsGRANT EXECUTE ON PROCEDURE appdb.close_month TO 'cron'@'%';            -- routineGRANT PROCESS ON *.* TO 'monitor'@'%';                                 -- global

MySQL 8.0-დან GRANT ზუსტად ერთ რამეს აკეთებს. 5.7-ის ჩვევა GRANT ALL ON db.* TO 'u'@'%' IDENTIFIED BY 'pw' - მომხმარებლის შექმნა და პაროლის დაყენება ერთბაშად - ახლა სინტაქსური შეცდომაა. ჯერ მომხმარებელი შექმენი, შემდეგ უფლებები მიეცი.

REVOKE GRANT-ის სარკისებურია და იგივე დონე უნდა დაასახელოს. SELECT ON appdb.orders-ის ჩამორთმევა ვინმესთვის, ვისაც SELECT ON appdb.* აქვს, არაფერს აკეთებს, რადგან მას ცხრილის დონის grant არასოდეს ჰქონია, რომ ჩამოერთვას. თუ გჭირდება „ყველაფერი ამ ბაზაში ერთი ცხრილის გარდა“, უფლებები ცხრილ-ცხრილ მიეცი, ან ჩართე partial_revokes (ნაგულისხმევად გამორთული), რომელიც გლობალური grant-იდან ბაზის გამოკლების საშუალებას გაძლევს - და მხოლოდ გლობალურიდან.

უფლებები, რომლებიც აპლიკაციას სინამდვილეში სჭირდება

უფლებასაჭიროააპლიკაცია გაშვებისასMigration-ები
SELECT, INSERT, UPDATE, DELETEხაზების წაკითხვა და ჩაწერაკიკი
CREATE, ALTER, DROP, INDEXსქემის შეცვლაარაკი
REFERENCESforeign key-ების შექმნაარაკი
CREATE TEMPORARY TABLESsession-ის დროებითი ცხრილებიზოგჯერზოგჯერ
LOCK TABLESცხრილების ცხადი lock-ებიიშვიათადზოგჯერ
CREATE VIEW, SHOW VIEWView-ებიარათუ view-ებს იყენებ
CREATE ROUTINE, ALTER ROUTINE, EXECUTEStored procedure-ებიმხოლოდ EXECUTEთუ იყენებ
TRIGGER, EVENTTrigger-ები, დაგეგმილი event-ებიარათუ იყენებ

framework-ების უმეტესობა migration-ებს იმავე მონაცემებით უშვებს, რითაც აპლიკაციას, ამიტომ აპლიკაციას საბოლოოდ ALL PRIVILEGES ON appdb.* აქვს. პატარა პროექტისთვის ეს მისაღებია - ის მაინც ერთ ბაზაშია ჩაკეტილი - მაგრამ უფრო ძლიერი სქემა ორი ანგარიშია: app ოთხი მონაცემთა უფლებით და app_migrate სქემის უფლებებით, რომელსაც მხოლოდ deploy-ის ნაბიჯი იყენებს. მაშინ აპლიკაციის გავლით SQL injection-ს DROP TABLE არ შეუძლია.

რა არასოდეს უნდა ჰქონდეს აპლიკაციას: არაფერი ON *.*, GRANT OPTION, FILE (კითხულობს და წერს ფაილებს სერვერის დისკზე), SUPER ან მისი დინამიკური შემცვლელები, PROCESS (ხედავს ყოველი session-ის query-ებს, სხვა აპლიკაციებისაც), CREATE USER ან SHUTDOWN.

დინამიკური უფლებები

MySQL 8-მა ძველი ყოვლისმომცველი SUPER დინამიკურ უფლებებად დაყო, ისეთი სახელებით, როგორიცაა SYSTEM_VARIABLES_ADMIN (გლობალური ცვლადების შეცვლა), CONNECTION_ADMIN (სხვა მომხმარებლების session-ების მოკვლა, max_connections-ის მიღმა დაკავშირება), BINLOG_ADMIN, BACKUP_ADMIN და REPLICATION_SLAVE_ADMIN. MySQL 8.4-მა დაამატა FLUSH_PRIVILEGES, OPTIMIZE_LOCAL_TABLE, TRANSACTION_GTID_TAG, და SET_ANY_DEFINER ALLOW_NONEXISTENT_DEFINER-თან ერთად ამოღებული SET_USER_ID-ის ნაცვლად. ისინი ისევე გაიცემა, როგორც ნებისმიერი სხვა უფლება, ყოველთვის გლობალურ დონეზე:

sql
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'dba'@'%';

SUPER ჯერ კიდევ არსებობს, მაგრამ მოძველებულად არის გამოცხადებული. თუ ძველი ხელსაწყო მას დაჟინებით ითხოვს, გაარკვიე, რომელი დინამიკური უფლება სჭირდება მას სინამდვილეში.

შემოწმება, რისი გაკეთება შეუძლია ანგარიშს#

sql
SHOW GRANTS FOR 'app'@'%';
code
+------------------------------------------------------------------------+| Grants for app@%                                                       |+------------------------------------------------------------------------+| GRANT USAGE ON *.* TO `app`@`%`                                        || GRANT SELECT, INSERT, UPDATE, DELETE ON `appdb`.* TO `app`@`%`         |+------------------------------------------------------------------------+

USAGE ნიშნავს „უფლებების გარეშე“ - ეს ის ხაზია, რომელიც ყველა ანგარიშს აქვს, და ასე ჩანს ანგარიში, რომელსაც არაფერი მიეცა. SHOW GRANTS FOR-ის გარეშე შენს საკუთარ მიმდინარე session-ს აჩვენებს, აქტიური role-ების ჩათვლით. SHOW CREATE USER 'app'@'%' ანგარიშის განსაზღვრებას ბეჭდავს (plugin, TLS მოთხოვნა, ლიმიტები, lock-ის მდგომარეობა) პაროლით hash-ის სახით, და სწორედ ასე აკოპირებ ანგარიშებს სერვერებს შორის - ეს MySQL-ის ახალ ჰოსტზე გადატანის თემაა.

უფრო ფართო ხედვისთვის information_schema-ს ცხრილები USER_PRIVILEGES, SCHEMA_PRIVILEGES, TABLE_PRIVILEGES და COLUMN_PRIVILEGES grant-ებს დონეების მიხედვით ჩამოთვლის, ხოლო mysql.db ბაზის დონისას პირდაპირ ინახავს.

Role-ები#

Role არის უფლებების დასახელებული ნაკრები, რომელიც ანგარიშებს შეიძლება მიეცეს. Role-ები MySQL 8.0-ში გამოჩნდა და შიგნით ჩვეულებრივი ანგარიშებია (ისინი mysql.user-ში ჩანს, დაბლოკილი და პაროლის გარეშე), რის გამოც მათ სახელებსაც ჰოსტის ნაწილი აქვს; ნაგულისხმევად ის %-ია.

sql
CREATE ROLE 'appdb_read', 'appdb_write', 'appdb_ddl';GRANT SELECT ON appdb.* TO 'appdb_read';GRANT INSERT, UPDATE, DELETE ON appdb.* TO 'appdb_write';GRANT CREATE, ALTER, DROP, INDEX, REFERENCES ON appdb.* TO 'appdb_ddl';GRANT 'appdb_read', 'appdb_write' TO 'app'@'%';GRANT 'appdb_read' TO 'report'@'%';GRANT 'appdb_read', 'appdb_write', 'appdb_ddl' TO 'app_migrate'@'%';SET DEFAULT ROLE ALL TO 'app'@'%', 'report'@'%', 'app_migrate'@'%';

ბოლო ხაზი ისაა, რომელიც ყველას ავიწყდება. მიცემული role session-ში აქტიური არ არის, სანამ არ გააქტიურდება, ან session-ის შიგნით SET ROLE-ით, ან ნაგულისხმევ role-ად ყოფნით. გამოტოვე SET DEFAULT ROLE და ანგარიში მხოლოდ USAGE-ით შევა, ყოველი query „command denied“-ით ჩავარდება, ხოლო SHOW GRANTS FOR 'app'@'%' შეცდომაში შემყვანად role-ს მიცემულად აჩვენებს. ალტერნატივაა სერვერის მასშტაბით activate_all_roles_on_login=ON, რომელიც ნაგულისხმევად გამორთულია.

sql
-- What would this account be able to do with its roles active?SHOW GRANTS FOR 'app'@'%' USING 'appdb_read', 'appdb_write';-- Which roles are active in my session right now?SELECT CURRENT_ROLE();

Role-ები მაშინ ამართლებს, როცა ერთნაირი საჭიროებების მქონე რამდენიმე ანგარიში ან ერთნაირი სქემის რამდენიმე ბაზაა. ერთი აპლიკაციისა და ერთი ბაზისთვის ჩვეულებრივი grant-ები სავსებით კარგია.

პაროლები, როტაცია და დაბლოკვა#

MySQL 8-ს აქვს ის პოლიტიკები, რასაც ელი, დაყენებადი თითო ანგარიშზე ან სერვერის ნაგულისხმევად:

sql
ALTER USER 'support'@'%'  PASSWORD EXPIRE INTERVAL 180 DAY  PASSWORD HISTORY 5  FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1;

FAILED_LOGIN_ATTEMPTS PASSWORD_LOCK_TIME-თან ერთად (დღეებში ან UNBOUNDED) ანგარიშს ზედიზედ წარუმატებლობების შემდეგ დროებით ბლოკავს, ხელმისაწვდომია 8.0.19-დან. ეს ადამიანების ანგარიშებზე გონივრული დაცვაა. აპლიკაციის ანგარიშზე დაყენებამდე კარგად დაფიქრდი: არასწორად კონფიგურირებული deploy, რომელიც არასწორ პაროლს ურტყამს, სწორად კონფიგურირებულ ინსტანციებსაც დაბლოკავდა.

ვადის გასვლა ადამიანებს უხდება და სერვისებისთვის ტკივილია. ვადაგასული პაროლი კლიენტს მხოლოდ sandbox რეჟიმში უშვებს, სადაც პაროლის შეცვლის გარდა ვერაფერს გააკეთებს, და driver-ების უმეტესობა ამას დილის სამ საათზე გაუგებარი შეცდომის სახით ამოაგდებს. სერვისის ანგარიშებისთვის როტაცია საკუთარი განრიგით გააკეთე PASSWORD EXPIRE NEVER-ით.

როტაცია გათიშვის გარეშე ორმაგ პაროლებს იყენებს, ხელმისაწვდომია 8.0.14-დან:

sql
-- 1. Add a new password; the old one keeps workingALTER USER 'app'@'%' IDENTIFIED BY 'new-password' RETAIN CURRENT PASSWORD;-- 2. Roll the new password out to every instance of the app-- 3. Retire the old oneALTER USER 'app'@'%' DISCARD OLD PASSWORD;

პაროლის სიძლიერის წესები validate_password კომპონენტიდან მოდის, რომელსაც ზოგი პაკეტი აყენებს, ზოგი კი არა. SHOW VARIABLES LIKE 'validate_password%'; არაფერს აბრუნებს, თუ ის არ არის. გენერირებული პაროლები მას უმეტესწილად უმნიშვნელოს ხდის.

მინიმალური უფლებების სქემა ტიპური აპლიკაციისთვის#

ყველაფერს ერთად თავს მოვუყრით ვებ აპლიკაციისთვის ღამის backup ამოცანით და მხოლოდ წაკითხვის ანალიტიკის ხელსაწყოთი:

ანგარიშიუფლებებივინ იყენებს
rootყველაფერიშენ, მხოლოდ ადმინისტრირებისთვის
appSELECT, INSERT, UPDATE, DELETE appdb-ზეგაშვებული აპლიკაცია
app_migrateსქემის ცვლილებები appdb-ზეdeploy-ის ნაბიჯი
backupSELECT, SHOW VIEW, TRIGGER, LOCK TABLES, EVENT appdb-ზეmysqldump
reportSELECT appdb-ზე, MAX_USER_CONNECTIONS 3ანალიტიკის ხელსაწყო

backup ანგარიშის სია ის არის, რაც mysqldump-ს სჭირდება ერთი ბაზის თანმიმდევრული dump-ისთვის --single-transaction --no-tablespaces-ით; tablespace-ის ინფორმაციის dump-ს გლობალური PROCESS უფლება სჭირდება, რასაც --no-tablespaces თავიდან იცილებს.

RE:NODE-ზე MySQL სერვერს სამი გენერირებული მონაცემი მოჰყვება: root პაროლი, აპლიკაციის ბაზა და მისთვის აპლიკაციის მომხმარებელი. ეს ცხრილის პირველ ორ ხაზს თავიდანვე ფარავს. root-ით დანარჩენს ერთ წუთში შექმნი ზემოთ მოცემული ბრძანებებით, ხოლო ნებისმიერი, ვისაც პანელში სერვერზე subuser-ად დაამატებ, პანელის უფლებებს იღებს, რომლებიც ბაზის ანგარიშებისგან განცალკევებულია - პანელის მხარეს subuser-ები და მინიმალური უფლებები ფარავს.

Definer-ები, view-ები და stored routine-ები#

View-ები, stored procedure-ები, ფუნქციები, trigger-ები და event-ები ნაგულისხმევად თავიანთი DEFINER-ის უფლებებით მუშაობს (SQL SECURITY DEFINER). ორი შედეგი:

  • View საშუალებას აძლევს ვინმეს, მისი გავლით წაიკითხოს, მაშინაც კი, თუ ქვემდებარე ცხრილზე უფლებები არ აქვს, რაც სასარგებლოა ანგარიშგების ანგარიშისთვის სვეტების უსაფრთხო ქვესიმრავლის გამოსაჩენად.
  • როცა ბაზას სხვა სერვერზე გადაიტან, ყოველი ობიექტი ისევ თავის თავდაპირველ definer-ს ასახელებს, ხშირად root@localhost-ს. თუ ეს ანგარიში ახალ სერვერზე არ არსებობს, ობიექტები „The user specified as a definer does not exist“-ით ვარდება.

ობიექტის შექმნას საკუთარი თავისგან განსხვავებული definer-ით 8.4-ში SET_ANY_DEFINER სჭირდება (8.0-ში SET_USER_ID ან SUPER), ხოლო ისეთის შექმნას, რომლის definer არ არსებობს, ALLOW_NONEXISTENT_DEFINER-იც სჭირდება. ჰოსტინგის აპლიკაციის მომხმარებელს ეს არ ექნება, და ამიტომაც ჩვეულებრივი მომხმარებლით აღდგენილი dump-ები ხშირად definer პუნქტებზე ვარდება - გამოსავალია მათი ამოშლა ან გადაწერა იმპორტამდე, ან იმპორტი root-ით. SQL SECURITY INVOKER პრობლემას გვერდს უვლის routine-ებისთვის, რომლებიც გამომძახებლის უფლებებით უნდა მუშაობდეს.

უფლებების შეცდომები და რას ნიშნავს ისინი#

შეცდომის კოდები კონკრეტულია და თითოეული სხვადასხვა გამოსავალზე მიუთითებს.

code
ERROR 1142 (42000): SELECT command denied to user 'app'@'198.51.100.7' for table 'invoices'

ანგარიში დაემთხვა და შევიდა, მაგრამ ამ ცხრილზე SELECT არ აქვს. შეამოწმე SHOW GRANTS შეტყობინებაში დასახელებული ანგარიშისთვის - და არა იმისთვის, რომელსაც გგონია რომ იყენებ - და შეამოწმე, აქტიურია თუ არა role, რომელსაც ეს უფლება აქვს.

code
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER,SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN privilege(s) for this operation

ბრძანებას გლობალური ან დინამიკური უფლება სჭირდება. ხშირი გამომწვევებია dump, რომელიც @@GLOBAL.GTID_PURGED-ს აყენებს, SET GLOBAL იმპორტის სკრიპტში, ან DEFINER პუნქტი, რომელიც სხვას ასახელებს. შეტყობინება ჩამოთვლის უფლებებს, რომლებიც დააკმაყოფილებდა; ჩვეულებრივ სწორი გამოსავალია ბრძანების ამოღება სკრიპტიდან და არა უფლების მიცემა.

code
ERROR 1396 (HY000): Operation CREATE USER failed for 'app'@'%'

ანგარიში უკვე არსებობს (ან, DROP USER-ის შემთხვევაში, არ არსებობს). სკრიპტებში, რომლებიც შეიძლება ორჯერ გაეშვას, გამოიყენე IF NOT EXISTS და IF EXISTS.

code
ERROR 1410 (42000): You are not allowed to create a user with GRANT

5.7-ის სტილის GRANT ... IDENTIFIED BY 8.x სერვერზე, ან GRANT ანგარიშზე, რომელიც ჯერ არ არსებობს. ჯერ CREATE USER გაუშვი.

code
ERROR 1045 (28000): Access denied for user 'app'@'203.0.113.9' (using password: YES)

ავთენტიკაცია ჩავარდა: არასწორი პაროლი, ან არ არსებობს ანგარიში, რომლის host pattern-იც ამ მისამართს ემთხვევა. თუ ანგარიში mysql_native_password-ს იყენებს 8.4 სერვერზე, სადაც ეს plugin გამორთულია, შესვლა აქაც ვარდება. MySQL-ის დისტანციური კავშირები კავშირის მხარის მიზეზებს დეტალურად ფარავს.

FAQ#

მჭირდება FLUSH PRIVILEGES GRANT-ის შემდეგ?

არა. CREATE USER, GRANT, REVOKE, ALTER USER და DROP USER მეხსიერებაში არსებულ უფლებების ქეშს მაშინვე აახლებს. FLUSH PRIVILEGES მხოლოდ grant ცხრილების პირდაპირი რედაქტირების შემდეგაა საჭირო, რაც არ უნდა გააკეთო. ზიანს არ აყენებს, მაგრამ მისი არსებობა სკრიპტში ნიშანია, რომ სკრიპტი სადღაც ძველი წყაროდან არის გადმოწერილი.

რატომ აქვს ჩემს მომხმარებელს წვდომა ერთი მანქანიდან და არა მეორიდან?

იმიტომ, რომ ანგარიში მომხმარებელი და host pattern-ია, და მეორე მანქანის მისამართი მას არ ემთხვევა. შეცდომის შეტყობინება აჩვენებს მისამართს, რომელიც MySQL-მა დაინახა - 'app'@'198.51.100.7' - ამიტომ შეადარე ის SELECT user, host FROM mysql.user-ს. შექმენი ანგარიში ამ ჰოსტისთვის ან გამოიყენე %.

როგორ მივცე მომხმარებელს წვდომა ყველა ბაზაზე, რომლის სახელიც პრეფიქსით იწყება?

ისტორიულად wildcard-იანი ბაზის grant-ით, ბაზის სახელის client\_% backtick-ებში ჩასმით და ქვედა ტირის escape-ით, რომ თავად wildcard არ იყოს. MySQL 8.2-მა wildcard-ები ბაზის grant-ებში მოძველებულად გამოაცხადა და მოსალოდნელია, რომ მომავალ ვერსიაში ლიტერალებად იქცევა. სანაცვლოდ თითო ბაზაზე მიეცი უფლებები; ასე ისედაც უფრო ცხადია.

უნდა იყენებდეს ჩემი აპლიკაცია root-ს?

არა. root-ს შეუძლია ყველა ბაზის წაკითხვა, სერვერის პარამეტრების შეცვლა, მომხმარებლების შექმნა და ნებისმიერი რამის წაშლა. თუ აპლიკაცია გატეხეს, root ცუდ დღეს სრულ დანაკარგად აქცევს. გამოიყენე ანგარიში უფლებებით აპლიკაციის საკუთარ ბაზაზე და root მოვლისთვის შეინახე.

რა განსხვავებაა role-სა და მომხმარებელს შორის MySQL-ში?

შიგნით ძალიან მცირე: role დაბლოკილ ანგარიშად ინახება პაროლის გარეშე. განსხვავება გამოყენებაშია. Role-ები ანგარიშებს ეძლევა და უნდა გააქტიურდეს (ნაგულისხმევი role-ით ან SET ROLE-ით), სანამ მათი უფლებები იმოქმედებს. ანგარიშები კი შედიან.

შემიძლია ვნახო, რა უფლებებს იძლევა role?

კი: SHOW GRANTS FOR 'appdb_read'; role-ის საკუთარ უფლებებს ჩამოთვლის, ხოლო SHOW GRANTS FOR 'app'@'%' USING 'appdb_read'; აჩვენებს, რას იღებს ანგარიში ამ role-ის აქტიურობისას. ანგარიშების გამაგრებაზე მეტი ბაზის უსაფრთხოების საკონტროლო სიაშია.


კომენტარები

სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.

0/2000