EQVPS
პანელიდაწყება

როგორ შევამოწმოთ ღია პორტები VPS-ზე: რა უსმენს, რას ხედავს ინტერნეტი და Docker-ის სიურპრიზი

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

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

1. რა უსმენს

ბრძანებაა ss. ასოები ნიშნავს: TCP, UDP, მოსმენის სოკეტები, პორტების ნომრები და პროცესის სახელი:

sudo ss -tulpn

ახალ სერვერზე ის ექვს ხაზს ბეჭდავს:

Netid State  Local Address:Port  Process
udp   UNCONN    127.0.0.54:53    systemd-resolve
udp   UNCONN 127.0.0.53%lo:53    systemd-resolve
tcp   LISTEN    127.0.0.54:53    systemd-resolve
tcp   LISTEN 127.0.0.53%lo:53    systemd-resolve
tcp   LISTEN       0.0.0.0:22    sshd
tcp   LISTEN          [::]:22    sshd

მთავარი სვეტია Local Address. ის გეუბნებათ, ვის შეუძლია დაკავშირება:

მისამართივინ მიწვდება
127.0.0.1:… ან 127.0.0.53მხოლოდ ამ სერვერზე მყოფი პროგრამები
0.0.0.0:…ყველა IPv4-ით, თუ ფაირვოლი არ ბლოკავს
[::]:…ყველა IPv6-ით (ჩვეულებრივ IPv4-ითაც)
10.0.0.5:… (კონკრეტული მისამართი)ყველა, ვინც ამ მისამართს მიწვდება

ანუ ახალი სერვერი გარეთ ზუსტად ერთ რამეს აჩენს: SSH-ს 22-ე პორტზე, IPv4-ითა და IPv6-ით. DNS რეზოლვერი 127.0.0.53-ზე პირადია.

რომ მხოლოდ ის ნახოთ, რისი დანახვაც ინტერნეტს შეუძლია, გაფილტრეთ loopback მისამართები:

sudo ss -tlnp | awk 'NR>1 && $4 !~ /^(127\.|\[::1\])/ {print $4, $6}'

გაუშვით ეს ყოველი ინსტალაციის შემდეგ. დავაყენეთ nginx, Docker და ერთი პატარა Python აპლიკაცია, და სია 2 ხაზიდან 10-მდე გაიზარდა, მათ შორის docker-proxy 0.0.0.0:8081-ზე და containerd-ის სოკეტი შემთხვევით localhost პორტზე.

2. რომელმა პროცესმა დაიკავა პორტი

როცა პორტი დაკავებულია და გინდათ გაიგოთ, ვის მიერ:

sudo lsof -i :80 -P -n
sudo fuser 80/tcp
sudo ss -tlnp 'sport = :80'

lsof ყველაზე ადვილად იკითხება. nginx-ისთვის მან აჩვენა ერთი მთავარი პროცესი root-ით და worker www-data-თი, ორივე *:80-ზე, IPv4-ისა და IPv6-ისთვის. fuser მხოლოდ PID-ებს ბეჭდავს — სკრიპტებში მოსახერხებელია. თუ პორტის გათავისუფლება გჭირდებათ, გააჩერეთ სერვისი და არა PID-ის მოკვლა, თორემ systemd მას ხელახლა გაუშვებს: sudo systemctl stop nginx.

3. რას ხედავს ინტერნეტი

ss სერვერის თვალით აჩვენებს. ინტერნეტის ხედვა შეიძლება განსხვავდებოდეს: შუაში ფაირვოლი დგას ან სერვისი 127.0.0.1-ზეა მიბმული. რეალური სურათის სანახავად დაასკანერეთ სერვერი სხვა მანქანიდან — ლეპტოპიდან ან მეორე სერვერიდან. ხელსაწყოა nmap (apt install nmap, Windows-სა და macOS-ზე კი ინსტალერი nmap.org-იდან).

nmap your-server-ip
nmap -p- your-server-ip
nmap -p 22,80,443,3306 your-server-ip

პირველი ფორმა ამოწმებს 1000 ყველაზე გავრცელებულ პორტს, მეორე — ყველა 65 535-ს, მესამე — სიას. ჩვენს ახალ სერვერზე, ყოველგვარ ფაირვოლამდე:

Not shown: 999 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
Nmap done: 1 IP address (1 host up) scanned in 6.83 seconds

65 535 პორტის სრულ სკანირებას 8,9 წამი დასჭირდა და იგივე ერთადერთი პორტი იპოვა. დახურული პორტები მაშინვე reset-ით პასუხობენ, ამიტომ მათი სკანირება სწრაფია.

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

  • open: პროგრამამ კავშირი მიიღო. ეს თქვენი თავდასხმის ზედაპირია.
  • closed: სერვერმა უპასუხა, რომ აქ არაფერი უსმენს. უსაფრთხოა, მაგრამ ადასტურებს, რომ სერვერი არსებობს და რა არ მუშაობს მასზე.
  • filtered: პასუხი არ არის. ფაირვოლმა პაკეტი გადააგდო. სკანერმა არ იცის, დგას თუ არა მის უკან სერვისი.

ერთი პორტისთვის არაფრის დაყენების გარეშე nc -zv სერვერის-ip 443 გიპასუხებთ succeeded ან refused, ხოლო filtered პორტზე ტაიმაუტამდე ელოდება. UDP-სთვის nmap-ს დაუმატეთ -sU და მოემზადეთ ლოდინისთვის; ჩვენს სერვერზე სამი გავრცელებული UDP პორტი — 53, 123 და 161 — closed იყო.

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

4. დახურეთ ზედმეტი

სამი გზა — საუკეთესოდან ყველაზე ფართომდე.

მიაბით localhost-ს. თუ სერვისს მხოლოდ სერვერზე მყოფი პროგრამები იყენებენ, მოუსმინოს 127.0.0.1-ს. პატარა ვებაპლიკაცია გავუშვით --bind 127.0.0.1 8080-ით: ss-მა ის 127.0.0.1:8080-ზე აჩვენა, nmap-მა კი გარედან 8080/tcp closed დააბრუნა. მონაცემთა ბაზებისთვის ეს სწორი ნაგულისხმევია: Redis, MySQL და PostgreSQL Ubuntu-ზე თავიდანვე localhost-ს უსმენენ, და ჩვენი სახელმძღვანელოები Redis-სა და MySQL-ისთვის ასე ტოვებს.

გააჩერეთ სერვისი. sudo systemctl disable --now სახელი მსმენელს სამუდამოდ აშორებს. ss-ით შეამოწმეთ, რომ გაქრა.

ჩართეთ ფაირვოლი. ჯერ დაუშვით SSH, შემდეგ ის, რასაც აწვდით, შემდეგ ჩართეთ:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw enable
sudo ufw status verbose

გარედან სკანირება მთლიანად შეიცვალა:

Not shown: 997 filtered tcp ports (no-response)
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
8081/tcp open  blackice-icecap
Nmap done: 1 IP address (1 host up) scanned in 10.18 seconds

ყოველი დაუშვებელი პორტი closed-იდან filtered-ში გადავიდა, ხოლო 65 535 პორტის სრულ სკანირებას ახლა 8,9-ის ნაცვლად 110 წამი დასჭირდა. სკანერისთვის მეტი დრო თითო პორტზე, თქვენს სერვერზე ნაკლები ინფორმაცია. ჩვენი UFW-ის სახელმძღვანელო განიხილავს სიხშირის შეზღუდვას, ერთი IP-ის დაშვებას და IPv6-ს.

მაგრამ შეხედეთ მესამე ხაზს.

5. Docker-ის სიურპრიზი

პორტი 8081 ღია დარჩა ჩართული ფაირვოლის დროს და ისე, რომ მის დამშვებ წესს არ ვქონდით. ეს პორტი ეკუთვნის კონტეინერს, რომელიც docker run -p 8081:80 nginx:alpine-ით გავუშვით. Docker ბირთვის ფაირვოლში საკუთარ წესებს ამატებს და ისინი ufw-ის წესებზე ადრე მოწმდება. წესი, რომელიც მან ჩვენს სერვერზე ჩაწერა:

-A DOCKER ! -i docker0 -p tcp --dport 8081 -j DNAT --to-destination 172.17.0.2:80

8081 პორტზე მისული ნებისმიერი პაკეტი კონტეინერში გადამისამართდება, სანამ ufw სიტყვას იტყვის. ასე იქცევა ყოველი კონტეინერი -p-ით ან ports:-ის ჩანაწერით, და ss ამას პატიოსნად აჩვენებს როგორც docker-proxy 0.0.0.0:8081-ზე.

გამოსწორება — პორტის გამოქვეყნება მხოლოდ localhost-ზე:

docker rm -f web
docker run -d --name web -p 127.0.0.1:8081:80 nginx:alpine

Compose-ში ports:-ში ჩაწერეთ "127.0.0.1:8081:80". ცვლილების შემდეგ ss-მა აჩვენა 127.0.0.1:8081, Docker-ის წესს დაემატა -d 127.0.0.1/32, ხოლო გარედან სკანირებამ 8081/tcp filtered დააბრუნა. საჯარო მხარისთვის წინ დააყენეთ nginx როგორც reverse proxy HTTPS-ით, რომ სერვერზე ღია იყოს მხოლოდ 22, 80 და 443 პორტები.

შემოწმების სია ყოველი ცვლილების შემდეგ

  1. sudo ss -tulpn: 0.0.0.0-ის ან [::]-ის შემცველი ყოველი ხაზი ის არის, რისი გახსნაც გინდოდათ?
  2. nmap სერვერის-ip ლეპტოპიდან: ემთხვევა ღია პორტები?
  3. მონაცემთა ბაზა, ქეში ან ადმინ-პანელი საჯარო მისამართზე: დღესვე გადაიტანეთ 127.0.0.1-ზე ან ფაირვოლის უკან.
  4. Docker-ის ყოველი ports: ჩანაწერი: იწყება 127.0.0.1:-ით, თუ ის საჯარო ვებპორტი არ არის?
  5. SSH ყველასთვის ღიაა: დაამატეთ fail2ban ან შესვლა მხოლოდ გასაღებით.

Windows Server-ზე იგივე შემოწმებაა Get-NetTCPConnection -State Listen, ხოლო წესები Windows-ის ფაირვოლშია. ყოველ Linux ტარიფს, Nano-დან $3-ად დაწყებული, აქვს ვერსია საკუთარი IPv4 მისამართით, და იქ ის, რასაც ss-ში ხედავთ, მთელი სამყარო ხედავს — გარდა იმისა, რასაც თქვენი ფაირვოლი აჩერებს.

ხდკ

რომელი პორტებია ღია ახალ VPS-ზე?

ჩვენს Ubuntu 24.04 იმიჯზე — ერთი: SSH 22-ე პორტზე. მის გარდა უსმენს მხოლოდ ლოკალური DNS რეზოლვერი 127.0.0.53-სა და 127.0.0.54-ზე, რომელსაც ინტერნეტიდან ვერ მიწვდებით. სხვა მანქანიდან ყველა 65 535 TCP პორტის სკანირებამ ზუსტად ერთი ღია პორტი იპოვა.

რით განსხვავდება closed პორტი filtered-ისგან?

Closed ნიშნავს, რომ სერვერმა უპასუხა: აქ არაფერი უსმენს, და სკანერი ამას მაშინვე იგებს. Filtered ნიშნავს, რომ პასუხი საერთოდ არ არის — ასე იქცევა ფაირვოლი, რომელიც პაკეტებს აგდებს. ორივე შეჭრას აჩერებს, მაგრამ filtered ასევე მალავს, რა სერვისები არსებობს, და ჩვენს სერვერზე სრულ სკანირებას დაახლოებით თორმეტჯერ ანელებს.

რატომ აჩვენებს ss პორტს, რომელსაც nmap closed-ად აფასებს?

სერვისი მხოლოდ 127.0.0.1-ს, loopback მისამართს უსმენს. თავად სერვერზე მყოფ პროგრამებს შეუძლიათ დაკავშირება, გარედან — არავის. ss-ის გამოტანაში შეხედეთ Local Address სვეტს: 127.0.0.1:8080 პირადია, 0.0.0.0:8080 ან [::]:8080 ინტერნეტიდან ხელმისაწვდომია, თუ ფაირვოლი ნებას რთავს.

ufw ჩავრთე, რატომ არის Docker-ის პორტი ისევ ღია?

Docker საკუთარ ფაირვოლის წესებს წერს და ისინი ufw-ის წესებზე ადრე მოწმდება. -p 8081:80-ით გაშვებული კონტეინერი ჩვენს სერვერზე გარედან ხელმისაწვდომი იყო ჩართული ufw-ის დროს და 8081-ისთვის წესის გარეშე. გამოაქვეყნეთ localhost-ზე: -p 127.0.0.1:8081:80, ხოლო საჯარო მხარისთვის წინ დააყენეთ nginx ან Caddy.

როგორ შევამოწმო პორტი ჩემი კომპიუტერიდან?

ერთი პორტისთვის — nc -zv სერვერის-ip 443, ათასი ყველაზე გავრცელებულისთვის დააყენეთ nmap და გაუშვით nmap სერვერის-ip. NAT ტარიფზე ინტერნეტიდან მხოლოდ თქვენი გადამისამართებული SSH პორტი პასუხობს; დანარჩენი განზრახ მიუწვდომელია.

კომენტარები

ჯერ არ არის კომენტარები. იყავით პირველი.

დატოვეთ კომენტარი

კომენტარები მოდერირდება გამოჩენამდე.