RE:NODE

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

Valkey-ის უსაფრთხოება: პაროლები, ACL მომხმარებლები და ღიაობა

დაიცავი Valkey სერვერი: requirepass, ACL მომხმარებლები key-ებისა და ბრძანებების ლიმიტით, საშიში ბრძანებები, protected mode, TLS და რატომ აქცევს ღია პორტი სერვერს მაინერად.

0 მკითხველი

ავთენტიფიკაციის გარეშე Valkey, რომელიც ინტერნეტიდან მისაწვდომია, მონაცემების გაჟონვა კი არა, დისტანციური shell-ია. ბრძანებების ნაკრები კლიენტს საშუალებას აძლევს შეცვალოს, სად წერს სერვერი snapshot ფაილს და რა ჰქვია მას, და ეს საკმარისია, რომ მანქანაზე SSH key ან cron ფაილი ჩააგდოს იმ მომხმარებლის სახელით, რომლითაც Valkey მუშაობს. ავტომატური სკანერები ღია ინსტანციებს წუთებში პოულობენ, და რასაც ისინი ტოვებენ, ჩვეულებრივ კრიპტოვალუტის მაინერია. ქვემოთ მოცემული გამაგრების ყოველი ნაბიჯი სწორედ ამ ერთი ფაქტის გამო არსებობს.

დაცვა, მნიშვნელობის მიხედვით: არასოდეს გახსნა ის ავთენტიფიკაციის გარეშე; გამოიყენე გრძელი შემთხვევითი პაროლი; ყოველ აპლიკაციას მიეცი საკუთარი ACL მომხმარებელი მხოლოდ იმ key-ებითა და ბრძანებებით, რომლებიც მას სჭირდება; ადმინისტრაციული და დამანგრეველი ბრძანებები აპლიკაციის მონაცემებისგან შორს დაიჭირე; და იცოდე, რომ პროტოკოლი უბრალო ტექსტია, თუ TLS არ არის მორგებული. ეს პოსტი თითოეულს გადის რეალური კონფიგურაციითა და ბრძანებებით.

რატომ ტყდება ღია ინსტანციები#

შეტევა ძველი და მარტივია, და მისი ფორმის ცოდნა დაცვის ზომებს ხსნის.

  1. ინტერნეტის სკანირება პორტ 6379-ზე (და სხვა გავრცელებულ პორტებზე), რომელიც Redis პროტოკოლით პასუხობს.
  2. INFO-ს გაგზავნა. თუ პასუხობს NOAUTH-ის გარეშე, ინსტანცია ღიაა.
  3. CONFIG SET dir-ისა და CONFIG SET dbfilename-ის გამოყენება, რომ snapshot-ის გამოტანა მგრძნობიარე გზაზე მიმართოს - /root/.ssh/ და authorized_keys, ან cron დირექტორია.
  4. key-ის ჩაწერა, რომლის მნიშვნელობა SSH public key-ს ან cron ხაზს შეიცავს, SAVE-ის გაშვება, და snapshot ფაილში უკვე გამოსაყენებელი payload დევს.
  5. შესვლა, ან cron-ის მოლოდინი, და მაინერის დაყენება.

ვარიანტები MODULE LOAD-ით მავნე მოდულს ტვირთავენ, ან REPLICAOF-ით რეპლიკაციას ბოროტად იყენებენ, რომ მოდული თავდამსხმელის სერვერიდან ჩამოქაჩონ. ყველა მათგანს ორი რამ სჭირდება: კავშირი ავთენტიფიკაციის გარეშე და ადმინისტრაციული ბრძანებების გაშვების უფლება. ერთ-ერთი მოაშორე და შეტევა ჩავარდება.

თანამედროვე Valkey ამის ნაწილს ნაგულისხმევად უკვე ხურავს. enable-protected-configs, enable-debug-command და enable-module-command სამივე ნაგულისხმევად no-ზეა, რაც კრძალავს მგრძნობიარე გზების, მაგალითად dir-ის, შეცვლას მუშაობის დროს და კლიენტებისგან MODULE LOAD-ს ბლოკავს. ეს ნამდვილი გაუმჯობესებაა რამდენიმე წლის წინანდელ სერვერებთან შედარებით, და მაინც არ არის მიზეზი ინსტანცია ღია დატოვო: თავად მონაცემების წაკითხვა, ჩაწერა და წაშლა ყველას შეუძლია, ვინც დაუკავშირდება.

Protected mode და binding#

ორი პარამეტრი წყვეტს, ვის შეუძლია საერთოდ დაკავშირება.

valkey.conf
bind 127.0.0.1 -::1protected-mode yesport 6379

bind ჩამოთვლის ინტერფეისებს, რომლებზეც Valkey უსმენს. მანქანაზე, სადაც ის მხოლოდ ლოკალურ პროცესებს სჭირდება, loopback სწორი პასუხია და რისკის უმეტესობას პირდაპირ აქრობს. წინ მდგარი - -::1-ში ნიშნავს "ნუ ჩავარდები გაშვებისას, თუ ეს მისამართი მიუწვდომელია".

protected-mode yes დამცავი ბადეა: თუ პაროლი დაყენებული არ არის და bind ნაგულისხმევიდან არ შეცვლილა, სერვერი loopback-ის გარდა ყველაფრიდან კავშირს უარყოფს და კლიენტს მიზეზს ეუბნება. ის არ იცავს ინსტანციას, რომელიც განზრახ საჯარო მისამართზეა მიბმული პაროლის გარეშე - სერვერი ვარაუდობს, რომ ეს შენი გააზრებული არჩევანია.

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

RE:NODE-ზე Valkey გეგმა იქმნება ამ სერვერისთვის გენერირებული პაროლით და მისაწვდომია გეგმის საკუთარ host-სა და პორტზე; ბაზის გეგმებს წინ proxy სლოტი არ აქვს. ინსტანცია ავთენტიფიკაციის გარეშე მდგომარეობაში არასოდეს იყიდება, რაც კლასიკურ შეცდომას აქრობს. შენი საქმე რჩება პაროლის იმ ადგილებისგან შორს დაჭერა, სადაც არ უნდა მოხვდეს, და ამ პოსტის დანარჩენი ნაწილი.

პაროლები: requirepass და AUTH#

უმარტივესი ავთენტიფიკაცია ერთი საერთო პაროლია:

valkey.conf
requirepass 9fK2pQ7x-a-long-random-string-from-a-generator

კლიენტები შემდეგ ავთენტიფიცირდებიან AUTH <password>-ით ნებისმიერ სხვა ბრძანებამდე, ან პაროლს კავშირის URL-ში სვამენ: redis://:password@host:port/0. შიგნით requirepass ჩაშენებული default ACL მომხმარებლის პაროლს აყენებს, ამიტომ AUTH default <password>-იც მუშაობს.

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

bash
$ openssl rand -base64 32

თუ ის URL-ში მოხვდება, მოერიდე ან percent-encode გაუკეთე @-ს, /-ს, :-ს და #-ს, რომლებიც ბევრ კლიენტში URL-ის დამუშავებას ტეხავს - ან გამოიყენე openssl rand -hex 32, რომელიც მხოლოდ უსაფრთხო სიმბოლოებს აწარმოებს.

შეინახე ის იქ, სადაც შენი სხვა საიდუმლოებებია: environment ცვლადებში ან secrets store-ში, არასოდეს repository-ში commit-ით და არასოდეს support ჩატში ან issue tracker-ში ჩასმული. Environment ცვლადები და საიდუმლოებები განიხილავს, სად უნდა ცხოვრობდნენ ისინი, ხოლო ბაზის უსაფრთხოების checklist Valkey-ზეც ისევე ვრცელდება, როგორც ნებისმიერ SQL სერვერზე.

ერთი საერთო პაროლის როტაცია ნიშნავს მის შეცვლას სერვერზე და ყველა კლიენტში ერთდროულად, რაც მოუხერხებელია. ACL მომხმარებლები ამასაც წყვეტს.

საიდან ჟონავს პაროლები პრაქტიკაში

პაროლს იშვიათად იპარავენ Valkey-დან. ის მის გარშემოდან ჟონავს:

  • Log-ები. გაშვებისას დაბეჭდილი კავშირის URL ("connecting to redis://:hunter2@...") log ფაილებში, log აგრეგატორებსა და screenshot-ებში ხვდება. დაწერე host და პორტი log-ში, არასოდეს URL.
  • შეცდომის ანგარიშები. Exception tracker-ები ნაგულისხმევად იჭერენ environment ცვლადებს და კონფიგურაციის ობიექტებს. გაწმინდე ის ცვლადი, რომელიც URL-ს ინახავს.
  • კლიენტის მხარის bundle-ები. Front-end build-მა, რომელიც environment ცვლადებს კითხულობს, შეიძლება ჩაშენოს ისეთი, რომელიც მხოლოდ სერვერისთვის იყო განკუთვნილი. Valkey-ის მონაცემები ბრაუზერამდე არასოდეს უნდა მივიდეს.
  • გაზიარებული ეკრანები და ticket-ები. ჩასმული .env ფაილი გამოქვეყნებული პაროლია.
  • გუნდის ყოფილი წევრები. ერთი საერთო პაროლი, რომელიც ყველამ იცის, ვინც ოდესმე პროექტზე მუშაობდა, ისეთი პაროლია, რომელსაც ერთ ადამიანს ვერ ჩამოართმევ.

ეს ბოლო ყველაზე ძლიერი არგუმენტია აპლიკაციაზე ცალკე ACL მომხმარებლებისა და როტაციისთვის, როგორც რუტინისა და არა საგანგებო ზომისა. როცა ვინმე მიდის, როტაცია გააკეთე.

ACL მომხმარებლები: თითო აპლიკაციაზე ერთი#

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

code
ACL SETUSER shop on >s3cr3t-shop-password ~shop:* &shop:* +@all -@dangerousACL SETUSER reports on >s3cr3t-report-password ~shop:* resetchannels -@all +@read +pingACL SETUSER default off

პირველი ხაზის წაკითხვა მარცხნიდან მარჯვნივ:

წესიმნიშვნელობა
onმომხმარებელი ჩართულია
>passwordამატებს პაროლს (მომხმარებელს შეიძლება რამდენიმე ჰქონდეს)
~shop:*წვდომა მხოლოდ shop:*-ის შესაბამის key-ებზე
&shop:*შეუძლია shop:*-ის შესაბამისი pub/sub არხების გამოყენება
+@allუშვებს ბრძანებების ყველა კატეგორიას...
-@dangerous...შემდეგ შლის საშიშ კატეგორიას

წესები თანმიმდევრობით მოქმედებს, ამიტომ +@all -@dangerous ნიშნავს "ყველაფერი საშიში ბრძანებების გარდა". მეორე მომხმარებელი მხოლოდ კითხულობს და არხები საერთოდ არ აქვს. მესამე ხაზი default მომხმარებელს თიშავს, რაც ნიშნავს, რომ მომხმარებლის დასახელების გარეშე ვერავინ დაუკავშირდება - ეს მხოლოდ მას შემდეგ გააკეთე, რაც დარწმუნდები, რომ ყველა კლიენტი მომხმარებლის სახელით ავთენტიფიცირდება.

კლიენტები ავთენტიფიცირდებიან AUTH shop <password>-ით, ან URL-ში მომხმარებლის სახელით: redis://shop:password@host:port/0. მიმდინარე კლიენტ ბიბლიოთეკების უმეტესობა ამას უჭერს მხარს; ძალიან ძველებს, რომლებიც მხოლოდ AUTH <password>-ს აგზავნიან, მხოლოდ default მომხმარებლის გამოყენება შეუძლიათ.

სასარგებლო შემოწმების ბრძანებები:

code
ACL WHOAMIACL LISTACL GETUSER shopACL CAT dangerousACL DRYRUN shop FLUSHALLACL LOG 10

ACL DRYRUN ამოწმებს, დაეშვებოდა თუ არა მომხმარებელს ბრძანება, მისი გაშვების გარეშე. ACL LOG ბოლო უარყოფებსა და წარუმატებელ ავთენტიფიკაციებს იწერს, რაც debug-ის ხელსაწყოცაა და ადრეული გაფრთხილებაც, რომ ვინმე პაროლებს არჩევს.

ACL SETUSER-ით შექმნილი მომხმარებლები მეხსიერებაში ცხოვრობენ. რესტარტს რომ გადაურჩნენ, უნდა შეინახონ: ან ACL ფაილში, რომელიც aclfile-ით არის მორგებული და ACL SAVE-ით ჩაიწერება, ან valkey.conf-ში user ხაზებად, CONFIG REWRITE-ით შენახული. ამ ნაბიჯის დავიწყება ნიშნავს, რომ გულდასმით აწყობილი უფლებები შემდეგ რესტარტზე ქრება.

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

საშიში ბრძანებები#

@dangerous კატეგორია იმ ბრძანებების ნაკრებია, რომელთა გაშვებაც აპლიკაციის საქმე არ არის. რამდენიმე ყველაზე მნიშვნელოვანი:

ბრძანებარისკი
FLUSHALL, FLUSHDBშლის ყველაფერს, მყისვე
CONFIGკითხულობს და ცვლის სერვერის პარამეტრებს
KEYSმთელ keyspace-ს ერთი ბლოკირებადი გამოძახებით გადის
DEBUGშეუძლია სერვერის დავარდნა ან გაჭედვა
SHUTDOWNაჩერებს სერვერს
MODULEტვირთავს native კოდს
REPLICAOF, SLAVEOFსერვერს თავდამსხმელის სერვერის რეპლიკად აქცევს
SAVEბლოკირებადი snapshot
MONITORყველა კლიენტის ყველა ბრძანებას აგზავნის ნაკადად, პაროლების ჩათვლით
CLIENT ქვებრძანებებიჩამოთვლის და კლავს სხვა კავშირებს

ბრძანებების გამორთვის ძველი მეთოდი კონფიგურაციის ფაილში rename-command იყო, რომელიც FLUSHALL-ს ცარიელ სტრიქონად ან შემთხვევით სახელად არქმევდა. ის ჯერ კიდევ მუშაობს, მაგრამ ყველა მომხმარებლისთვის ყველაფერი-ან-არაფერია და ტეხავს ხელსაწყოებს, რომლებიც ბრძანების არსებობას ელიან. ACL-ები უკეთესი ხელსაწყოა: აპლიკაციის მომხმარებელს უბრალოდ არ შეუძლია FLUSHALL-ის გაშვება, ადმინისტრატორ მომხმარებელს კი ისევ შეუძლია.

KEYS ცალკე ხსენებას იმსახურებს, რადგან ის საშიშია შემთხვევით და არა ბოროტი განზრახვით. დეველოპერის debug ხაზი, რომელიც KEYS *-ს უშვებს production ინსტანციაზე მილიონობით key-ით, მას წამებით ყინავს. გამოიყენე SCAN MATCH შაბლონით და KEYS აპლიკაციის მომხმარებლებს მოაშორე.

დაშიფვრა გადაცემისას#

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

Valkey TLS-ს უჭერს მხარს, თუ მასთან ერთად არის აწყობილი; ის tls-port-ით, tls-cert-file-ით, tls-key-file-ით და tls-ca-cert-file-ით ირგება, კლიენტები კი rediss:// სქემით უკავშირდებიან (ორი s). გვთავაზობს თუ არა კონკრეტული ჰოსტინგის ინსტანცია TLS-ს თავის პორტზე, ამ სერვისის თვისებაა, ამიტომ შეამოწმე, სანამ ივარაუდებ - თუ გეგმა მხოლოდ host-სა და პორტს ჩამოთვლის, ივარაუდე უბრალო TCP. სადაც TLS მიუწვდომელია:

  • აპლიკაცია და Valkey ერთ ლოკაციაზე დაიჭირე, რომ ტრაფიკმა საჯარო ინტერნეტი საჭიროზე მეტად არ გადაკვეთოს.
  • Valkey-ში ნუ შეინახავ მონაცემებს, რომელთა წაკითხვა გადაცემისას სერიოზული ინციდენტი იქნებოდა: ბარათის ნომრები, დაუშიფრავი პირადი ჩანაწერები, ხანგრძლივი საიდუმლოებები.
  • პაროლის როტაცია გააკეთე, თუ ოდესმე აპლიკაციასა და სერვერს შორის გზაში ეჭვი შეგეპარება.

არასოდეს დააყენო Valkey HTTP reverse proxy-ის უკან იმ იმედით, რომ ის დაშიფვრას დაამატებს. პროტოკოლი HTTP არ არის; ვებ proxy მას ვერ გაატარებს, ხოლო TCP დონის TLS terminator წინ მხოლოდ ამ terminator-მდე მონაკვეთს იცავს.

მონიტორინგი, როტაცია და ინციდენტზე რეაგირება#

უსაფრთხოება ისიც არის, რომ შეამჩნიო, როცა რამე არასწორად ხდება.

  • უყურე `ACL LOG`-ს განმეორებითი ავთენტიფიკაციის შეცდომებისთვის. უცნობი მისამართიდან მოსული ტალღა ნიშნავს, რომ ვიღაც პაროლს არჩევს.
  • უყურე `INFO clients`-ს, თუ connected_clients ბევრად აღემატება იმას, რასაც შენი აპლიკაცია ხსნის. მოულოდნელი კავშირები გამოძიებად ღირს.
  • უყურე `INFO keyspace`-ს და მეხსიერებას. keyspace, რომელიც უცებ ცარიელდება, ან ივსება უცნობი key-ებით, სახელად backup1, backup2 უცნაური მნიშვნელობებით, ზემოთ აღწერილი შეტევის ნიშანია.
  • პაროლების როტაცია გააკეთე ACL-ის რამდენიმე პაროლის მხარდაჭერით: ახალი პაროლი მომხმარებელს დაუმატე, ყველა კლიენტზე გაავრცელე, შემდეგ ძველი <oldpassword-ით წაშალე. არც downtime, არც ერთდროული გადართვის დღე.

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

Checklist#

  1. ავთენტიფიკაცია ჩართულია: 32 ან მეტი შემთხვევითი სიმბოლოს პაროლი, ან ACL მომხმარებლები.
  2. პორტი მისაწვდომია მხოლოდ იმისთვის, ვისაც სჭირდება: loopback ერთ მანქანაზე, firewall-ის allow-list იქ, სადაც მას აკონტროლებ.
  3. თითო აპლიკაციას საკუთარი ACL მომხმარებელი აქვს, შეზღუდული თავისი key პრეფიქსით და @dangerous-ის გარეშე, იქ, სადაც მომხმარებლების შექმნა შეგიძლია.
  4. default მომხმარებელი გამორთულია ან ძლიერი პაროლი აქვს.
  5. ACL ცვლილებები ACL ფაილში ან კონფიგურაციაში ინახება, რომ რესტარტს გადაურჩეს.
  6. პაროლები environment ცვლადებში ან secrets store-შია და არა კოდში.
  7. TLS გამოიყენება, სადაც შემოთავაზებულია; სადაც არა, მგრძნობიარე მონაცემები Valkey-ს გარეთ რჩება.
  8. ACL LOG-ს, კლიენტების რაოდენობასა და მეხსიერებას თვალი ედევნება.
  9. არსებობს როტაციის გეგმა, რომელსაც downtime არ სჭირდება.

FAQ#

საკმარისია თუ არა requirepass თავისთავად?

ერთი აპლიკაციისთვის გრძელი შემთხვევითი პაროლით და პორტით, რომელიც საჭიროზე ფართოდ არ არის გახსნილი, ეს გონივრული საბაზისო დონეა. ACL მომხმარებლები მინიმალურ პრივილეგიასა და უმტკივნეულო როტაციას ამატებენ, და მათი მნიშვნელობა იზრდება, რაც მეტი აპლიკაცია იზიარებს ერთ ინსტანციას.

შემიძლია Valkey დავმალო პორტის შეცვლით?

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

რატომ ამბობს ჩემი კლიენტი NOAUTH-ს მომხმარებლის სახელის დაყენების შემდეგ?

კლიენტი აგზავნის AUTH <password>-ს მომხმარებლის სახელის გარეშე, ამიტომ სერვერი მას default მომხმარებელზე ცდის. ჩასვი მომხმარებლის სახელი URL-ში ან კლიენტის username პარამეტრში და შეამოწმე, უჭერს თუ არა ბიბლიოთეკის ვერსია მხარს ACL ავთენტიფიკაციას.

ინახება თუ არა ACL პაროლები უბრალო ტექსტად?

არა. Valkey ACL პაროლების SHA-256 hash-ებს ინახავს, და ACL GETUSER hash-ებს აჩვენებს და არა პაროლებს. პაროლი მაინც უბრალო ტექსტად კვეთს ქსელს, თუ TLS არ გამოიყენება.

უნდა გამოიყენონ cache-მა და სესიების საცავმა სხვადასხვა მომხმარებელი?

დიახ, თუ ისინი სხვადასხვა აპლიკაციაა ან ნდობის სხვადასხვა დონე აქვთ. ცალკე მომხმარებლები ცალკე key პრეფიქსებით ნიშნავს, რომ ერთში არსებული ბაგი ან გატეხვა მეორის მონაცემებს ვერ წაიკითხავს და ვერ წაშლის.


კომენტარები

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

0/2000