RE:NODE

VDS12 წუთის საკითხავი

პირველი საათი ახალ VDS-ზე: მოწყობის ჩეკლისტი

რა გააკეთო ახალ VDS-ზე: განახლებები, sudo მომხმარებელი, SSH გასაღებები, default-deny firewall, დრო, swap და ავტომატური უსაფრთხოების განახლებები სწორი თანმიმდევრობით.

1 მკითხველი

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

ქვემოთ მოცემული თანმიმდევრობა მნიშვნელოვანია. განახლებები კონფიგურაციამდეა, რადგან პაკეტები, რომლებსაც აპირებ დააკონფიგურირო, სწორედ ის პაკეტებია, რომლებიც იცვლება. მომხმარებელი SSH-ის ჩაკეტვამდეა, რადგან root-ის გარეთ დატოვება სხვა შესასვლელის გაჩენამდე სერვერის პირველ დღეს დაკარგვის კლასიკური გზაა. Firewall SSH-ის შემდეგაა, რადგან default-deny წესი 22 პორტის გამონაკლისის გარეშე სესიასაც და საუბარსაც ამთავრებს.

ბრძანებები Debian-ისა და Ubuntu-სთვისაა, რაც VDS იმიჯების უმეტესობაა. RHEL-ის ოჯახის სისტემებზე apt-ის ნაცვლად dnf, sudo-ს ნაცვლად wheel და ufw-ს ნაცვლად firewalld ჩასვი; ფორმა არ იცვლება.

პირველი შესვლა და რა შეამოწმო#

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

bash
$ ssh root@203.0.113.10The authenticity of host '203.0.113.10' can't be established.ED25519 key fingerprint is SHA256:5xM8n...Are you sure you want to continue connecting (yes/no/[fingerprint])?

შემდეგ ორი წუთი დახარჯე იმის გასარკვევად, რა გაქვს სინამდვილეში. ეს ღირს რამის დაყენებამდე, რადგან ეს ერთადერთი დროა, როცა მანქანა ცნობილ მდგომარეობაშია:

bash
$ cat /etc/os-release          # distribution and version$ uname -r                     # kernel$ lscpu | head -20             # cores, model, virtualisation flags$ free -h                      # memory, and whether swap exists$ df -h /                      # disk, and how much the image used$ ip -brief address            # addresses, v4 and v6$ ss -ltnp                     # what is already listening$ systemd-detect-virt          # kvm, lxc, none

ss -ltnp საინტერესოა. სუფთა იმიჯი ჩვეულებრივ მხოლოდ sshd-ს აჩვენებს და ზოგჯერ DHCP კლიენტს ან localhost-ზე მოსმენად საფოსტო გადამცემ აგენტს. ყველაფერი დანარჩენი, რაც 0.0.0.0-ზე უსმენს, ის რამეა, რაც არ მოგითხოვია და უნდა გამოიძიო. systemd-detect-virt გეუბნება, სრულ ვირტუალიზაციაზე ხარ თუ kernel-ს იზიარებ, რაც წყვეტს, შესაძლებელია თუ არა შემდგომი ნაბიჯებიდან ზოგი - VPS, VDS თუ dedicated სერვერი განმარტავს, რატომ არის ეს განსხვავება მნიშვნელოვანი მარკეტინგზე მეტად.

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

განაახლე ყველაფერი, შემდეგ reboot#

იმიჯი არის სნეპშოტი იმ მომენტიდან, როცა აშენდა, რაც თვეების წინ შეიძლება იყოს. ყველაფრის წინ:

bash
$ apt update$ apt full-upgrade -y$ apt autoremove --purge -y

full-upgrade და არა upgrade, რადგან upgrade პაკეტების წაშლაზე უარს ამბობს და ამიტომ ჩუმად ტოვებს განახლებებს, რომლებსაც dependency-ის ცვლილება სჭირდება. ახალ იმიჯზე ეს განსხვავება ჩვეულებრივ kernel-ია.

შემდეგ შეამოწმე, სჭირდება თუ არა reboot, და გააკეთე ახლა და არა შემდეგ უხერხულ მომენტში:

bash
$ [ -f /var/run/reboot-required ] && cat /var/run/reboot-required$ reboot

Kernel-ის განახლება არაფერს აკეთებს, სანამ მანქანა ახალზე არ გადაიტვირთება. ახალი VDS, რომელზეც არაფერი მუშაობს, ყველაზე იაფი reboot-ია, რომელიც ოდესმე გექნება, ამიტომ გააკეთე. ისევ შედი და uname -r-ით დარწმუნდი, რომ ვერსია შეიცვალა.

მომხმარებელი, რომელიც root არ არის#

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

bash
$ adduser deploy$ usermod -aG sudo deploy

adduser ინტერაქტიული Debian-ის wrapper-ია: ის ქმნის home დირექტორიას, აყენებს shell-ს და პაროლს ითხოვს. მიეცი მას ნამდვილი პაროლი, თუნდაც გასაღებებით შესვლას აპირებდე, რადგან sudo მას მოგთხოვს.

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

bash
$ rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy/$ chmod 700 /home/deploy/.ssh$ chmod 600 /home/deploy/.ssh/authorized_keys

ეს უფლებები დეკორაცია არ არის. sshd უარს ამბობს authorized_keys ფაილის გამოყენებაზე, რომელიც მფლობელის გარდა ვინმესთვის ჩაწერადია, და ამას კლიენტის თვალსაზრისით ჩუმად აკეთებს, რაც „ისევ პაროლს მთხოვს“ საიდუმლოს წარმოქმნის.

გახსენი მეორე ტერმინალი და გამოსცადე, სანამ სხვა რამეს შეცვლი:

bash
$ ssh deploy@203.0.113.10$ sudo -v

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

SSH გასაღებები და წინა კარის დაკეტვა#

თუ გასაღებების წყვილი ჯერ არ გაქვს, შექმენი შენს მანქანაზე და არა სერვერზე:

bash
$ ssh-keygen -t ed25519 -C "deploy@laptop"$ ssh-copy-id deploy@203.0.113.10

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

შემდეგ გამორთე ორი რამ, რაც სერვერს გამოსაცნობს ხდის. თანამედროვე Debian-სა და Ubuntu-ზე /etc/ssh/sshd_config იწყება ხაზით Include /etc/ssh/sshd_config.d/*.conf და ეს დეტალი თითქმის ყველას ებმევა: sshd იყენებს პირველ მნიშვნელობას, რომელსაც გასაღებისთვის მიიღებს, ამიტომ ყველაფერი იმ დირექტორიაში მის ქვემოთ მდებარე მთავარ ფაილს ჯობნის. Cloud იმიჯები ხშირად იქ ფაილს აყოლებენ, რომელიც პაროლით ავთენტიფიკაციას უკან რთავს.

bash
$ ls -la /etc/ssh/sshd_config.d/$ grep -r PasswordAuthentication /etc/ssh/sshd_config /etc/ssh/sshd_config.d/

დაწერე საკუთარი ფაილი, სახელად ისე, რომ ყველაფერზე ადრე დალაგდეს, რაც უკვე იქ არის:

/etc/ssh/sshd_config.d/10-hardening.conf
PermitRootLogin noPasswordAuthentication noKbdInteractiveAuthentication noPubkeyAuthentication yesAuthenticationMethods publickeyMaxAuthTries 3LoginGraceTime 20AllowUsers deploy

Restart-მდე შეამოწმე სინტაქსი, რადგან გატეხილი config ფაილი ნიშნავს, რომ sshd აღარ ბრუნდება:

bash
$ sshd -t && systemctl restart ssh

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

SSH გასაღებები და hardening დანარჩენს სათანადოდ განიხილავს: აგენტები, jump ჰოსტები, გასაღებზე შეზღუდვები და რა გააკეთო, როცა საკუთარ თავს მაინც ჩაკეტავ.

Firewall: default deny#

Default deny შემომავალზე, allow გამავალზე, შემდეგ გახსენი ზუსტად ის, რაც გჭირდება. Ubuntu-ზე ეს ufw-ია და ბრძანებების თანმიმდევრობას უზარმაზარი მნიშვნელობა აქვს:

bash
$ ufw default deny incoming$ ufw default allow outgoing$ ufw allow OpenSSH$ ufw enable$ ufw status numbered

ufw allow OpenSSH ufw enable-მდე, ყოველთვის. default-deny პოლიტიკის ჩართვა SSH წესის გარეშე მაშინვე გაგთიშავს და უკან გზა მხოლოდ შენი პროვაიდერის კონსოლია. ufw გაფრთხილებს, ხოლო გაფრთხილებაზე გადაბიჯება ადვილია.

შემდეგ სერვისები, რომელსაც ნამდვილად გაუშვებ:

bash
$ ufw allow 80/tcp$ ufw allow 443/tcp$ ufw allow 27015:27020/udp      # a range for game servers$ ufw allow from 10.0.0.0/24 to any port 5432 proto tcp

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

ერთი ხაფანგი: Docker პორტებს საკუთარი iptables წესების ჩაწერით აქვეყნებს და ეს წესები ufw-ის წესებს მთლიანად უვლის გვერდს. კონტეინერი, რომელიც -p 5432:5432-ით გაეშვა, ინტერნეტისთვის ღიაა, თუნდაც ufw status მოწესრიგებულად გამოიყურებოდეს. ან bind-ი publish-ისას localhost-ზე გააკეთე -p 127.0.0.1:5432:5432-ით, ან დაამატე შენი წესები DOCKER-USER chain-ში. Docker VDS-ზე ამას კონტექსტში განიხილავს.

დრო, hostname და პატარა პარამეტრები#

არასწორი საათები არასწორ ლოგებს, ჩავარდნილ TLS handshake-ებს და ვადაგასულ token-ებს იწვევს და ისინი უხილავია, სანამ არ გახდება.

bash
$ timedatectl set-timezone Etc/UTC$ timedatectl set-ntp true$ timedatectl

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

მანქანას მიეცი სახელი, რომელსაც აზრი აქვს, განსაკუთრებით თუ მეორეც იქნება:

bash
$ hostnamectl set-hostname web-01

დაამატე ეს სახელი /etc/hosts-ში 127.0.1.1-ის გვერდით, თორემ sudo ყოველ ბრძანებაზე ერთი წამით შეჩერდება, სანამ hostname-ის გადაწყვეტას ცდილობს და ვერ ახერხებს.

კიდევ ორი პატარა რამ, რაც აქ ყოფნისას ღირს გაკეთება. დააყენე locale (update-locale LANG=en_GB.UTF-8), რომ სკრიპტირებული ინსტრუმენტები locale გაფრთხილებებს აღარ ბეჭდავდეს, და შეზღუდე journal, რომ ლოგებმა დისკი ვერ შეავსონ:

/etc/systemd/journald.conf
[Journal]SystemMaxUse=500MSystemMaxFileSize=50M

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

ავტომატური უსაფრთხოების განახლებები#

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

bash
$ apt install unattended-upgrades$ dpkg-reconfigure --priority=low unattended-upgrades

ეს წერს /etc/apt/apt.conf.d/20auto-upgrades-ს. შემდეგ გახსენი /etc/apt/apt.conf.d/50unattended-upgrades და გადაწყვიტე ორი რამ: შეუძლია თუ არა მანქანას თავად გადატვირთვა და როდის.

/etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Automatic-Reboot "true";Unattended-Upgrade::Automatic-Reboot-WithUsers "false";Unattended-Upgrade::Automatic-Reboot-Time "04:00";Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

ავტომატური reboot-ები სწორია web სერვერისთვის და არასწორი თამაშის სერვერისთვის, სადაც დილის ოთხ საათზე ხალხი თამაშობს. თუ მათ გამორთავ, kernel-ის განახლებების შემდეგ reboot-ის საქმე შენზე გადადის, და შესამოწმებელი არის /var/run/reboot-required. შეამოწმე, რომ მთელი ეს ამბავი მუშაობს და არა დაუშვა:

bash
$ unattended-upgrade --dry-run --debug$ cat /var/log/unattended-upgrades/unattended-upgrades.log

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

Swap და მეხსიერების ჭერი#

პატარა VDS იმიჯების უმეტესობა swap-ის გარეშე მოდის. მის გარეშე მეხსიერების პიკი არ ანელებს, ის რაღაცას კლავს: kernel-ის out-of-memory killer ირჩევს ყველაზე დიდ პროცესს, რომელიც ჩვეულებრივ ზუსტად ის არის, რისთვისაც სერვერს უშვებ.

მოკრძალებული swap ფაილი დაზღვევაა და არა დამატებითი მეხსიერება. ორი გიგაბაიტი საკმარისზე მეტია 8 GB მანქანაზე.

bash
$ fallocate -l 2G /swapfile || dd if=/dev/zero of=/swapfile bs=1M count=2048$ chmod 600 /swapfile$ mkswap /swapfile$ swapon /swapfile$ swapon --show

გადატვირთვას რომ გადაურჩეს, დაამატე ერთი ხაზი /etc/fstab-ში:

/etc/fstab
/swapfile none swap sw 0 0

შემდეგ შეამცირე kernel-ის სურვილი, გამოიყენოს, რომ ის უსაფრთხოების ბადედ დარჩეს და ნორმალურ მდგომარეობად არ იქცეს:

bash
$ echo 'vm.swappiness=10' > /etc/sysctl.d/99-swap.conf$ sysctl --system

fallocate ზოგ ფაილურ სისტემაზე ვარდება, სწორედ ამიტომ არის dd fallback. და თუ სერვერი ნორმალური მუშაობისას ნამდვილად swap-ს იყენებს, swap გამოსწორება არ არის - მანქანა ძალიან პატარაა, ან რაღაც გაჟონავს. Linux swap და OOM killer მტკიცებულებების კითხვას გვასწავლის, ხოლო CPU თუ RAM გეიმ სერვერებისთვის - რომელი გაკლია სინამდვილეში.

რა შეიძლება დაელოდოს მეორე საათს#

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

შემდეგირატომ
Backup ან snapshot, ახლავე გადაღებულისუფთა საბაზისო ხაზი არაფერი ღირს და მოგვიანებით ბევრს ღირს
fail2banგანმეორებითი ჩავარდნები თავდამსხმელს ფასს ადებს
Reverse proxy და TLSყველაფერს, რაც HTTP-ს ემსახურება, nginx და სერთიფიკატი უნდა
systemd unit-ები შენი სერვისებისთვისRestart ჩავარდნისას, start ჩატვირთვისას, ლოგები ერთ ადგილას
მონიტორინგიდისკი, მეხსიერება და პასუხობს თუ არა ის ისევ
Docker ან Composeმხოლოდ თუ დატვირთვა ნამდვილად რამდენიმე სერვისია

fail2ban, systemd სერვისები შენი აპებისთვის და nginx როგორც reverse proxy თითოეული მათგანს სათანადოდ განიხილავს. თუ გეგმა ერთ მანქანაზე რამდენიმე გეიმ სერვერია, რამდენიმე გეიმ სერვერი ერთ VDS-ზე პორტებს, მომხმარებლებსა და პროცესების ზედამხედველობას მანამ განიხილავს, სანამ მათთან არეულობაში ჩაიძირები.

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

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

FAQ#

რომელი დისტრიბუცია ავირჩიო?

ის long-term-support გამოშვება, რომელიც უკვე იცი. Ubuntu LTS-სა და Debian stable-ს წლების განმავლობაში უსაფრთხოების განახლებები აქვს, მათზე დაწერილი ზუსტი დოკუმენტაცია ყველაზე მეტია და ინსტალაციის ინსტრუქციების უმეტესობა მათ ვარაუდობს. უფრო ახალი, მოკლევადიანი გამოშვება გაძლევს პაკეტების ვერსიებს, რომლებიც ალბათ არ გჭირდება, ცვლილების სანაცვლოდ - განახლება ყოველ ცხრა თვეში.

მართლა მჭირდება არა-root მომხმარებელი, თუ მანქანას მხოლოდ მე ვიყენებ?

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

ღირს თუ არა SSH პორტის შეცვლა?

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

უნდა დავაყენო თუ არა fail2ban მაშინვე?

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

რამდენი swap დავამატო?

საკმარისი პიკის შესაწოვად და არა იმდენი, რომ პრობლემა დამალოს. ერთი-ორი გიგაბაიტი 8 GB ან მეტი მეხსიერების მქონე მანქანაზე და დაბალი vm.swappiness. სერვერები, რომლებსაც მეხსიერების პროპორციული swap სჭირდებათ, გაცილებით პატარა მანქანებისა და hibernation-ის ეპოქის წესია.

რა არის ერთი ნაბიჯი, რომელსაც ხალხი ტოვებს და ნანობს?

მეორე შესვლის გამოცდა პირველი სესიის დახურვამდე. ყოველი ჩაკეტვის ისტორია იწყება იმით, რომ ვიღაც config ცვლილების შემდეგ sshd-ს გადატვირთავს, ტერმინალს დახურავს და აღმოაჩენს, რომ AllowUsers-ში შეცდომა იყო. სამუშაო სესია ღია დატოვე, სანამ ახალი სესია წარმატებით არ გაიხსნება.


კომენტარები

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

0/2000