Subversion ჰოსტის შეზღუდვა VPN მომხმარებლებზე Apache 2.4-ით
ServerName ვირტუალურ ჰოსტს ირჩევს და არ ზღუდავს, ვინ უკავშირდება. მოითხოვეთ VPN დიაპაზონი და საცავის ნამდვილი მომხმარებელი, შემდეგ დაამტკიცეთ ორივე უარი.
Subversion-ის ვირტუალური ჰოსტის VPN მისამართზე მიმართვა ცვლის იმას, რომელი საიტი პასუხობს მოთხოვნას და არა იმას, ვის აქვს მისი გაგზავნის უფლება. წვდომის შემოწმება მოგვიანებით ხდება, URL-ს შესაბამისი განყოფილების წესების მიხედვით, და ჰოსტის სახელი ამ გადაწყვეტილებაში არასდროს შედის. თუ ServerName თქვენი ერთადერთი ცვლილება იყო, საცავი ზუსტად ისეა ხელმისაწვდომი, როგორც გუშინ. კონფიგურაციაში ორ განსხვავებულ კითხვას უნდა გაეცეს პასუხი: რომელმა სოკეტმა მიიღო კავშირი და რომელი იდენტობა ატარებდა მოთხოვნას.
რას განსაზღვრავს ServerName სინამდვილეში
სახელზე დაფუძნებული ვირტუალური ჰოსტინგი Host-ის თავსართს ადარებს ServerName და ServerAlias ჩანაწერებს, ირჩევს ერთ ჰოსტს და აძლევს მას მოთხოვნის დამუშავების უფლებას. თვით კავშირი ადრე მიიღო Listen სოკეტმა, რომელიც სერვერს ეკუთვნის და არა ჰოსტს. ამიტომ კერძოდ მოჩვენებული სახელი დაცვას არ იძლევა: ნებისმიერ კლიენტს, რომელიც სოკეტს მიაღწევს, შეუძლია გაგზავნოს ეს Host თავსართი. სახელი მარშრუტიზაციის გასაღებია, ხოლო მარშრუტიზაციის გასაღებებს გამომძახებელი ირჩევს.
შეგიძლიათ იხილოთ დაშენება გამოცნობის გარეშე. apachectl -S ბეჭდავს თითოეულ ჰოსტს, მის პორტს და სახელებს და აღნიშნავს, რომელია ნაგულისხმევი მისამართისთვის.
RequireAll არის კონტეინერი, რომელიც ორივე შემოწმებას სავალდებულოს ხდის
Apache 2.4 ერთი განყოფილების Require დირექტივებს იმპლიციტურ RequireAny-ში ახვევს, ამიტომ ორი შიშველი დირექტივა ნიშნავს, რომ რომელიმე მათგანი საკმარისია. დაამატეთ კონტეინერი და მნიშვნელობა შებრუნდება:
<Location /svn/repo>
AuthType Basic
AuthName "Subversion"
AuthBasicProvider file
AuthUserFile /etc/apache2/svn.htpasswd
<RequireAll>
Require ip 10.8.0.0/24
Require valid-user
</RequireAll>
</Location>RequireAll ითხოვს ორივე პირობას: წყაროს მისამართს გვირაბის დიაპაზონში და მომხმარებელს, რომელსაც საცავი იღებს. სწორედ ამას უნდა ნიშნავდეს მხოლოდ-VPN Subversion URL-ისთვის. mod_authz_core-ის ცნობარი აღწერს კონტეინერის წესებს. დატოვეთ ბლოკი საცავის არსებული Location-ის შიგნით და დატოვეთ უკვე მომუშავე DAV დირექტივები ადგილზე, რადგან ეს ფრაგმენტი არც AuthType-ს ცვლის, არც პაროლის ფაილს, არც ბილიკის დონის ავტორიზაციას.
წყაროს შემოწმება mod_authz_host-იდან მოდის, ამიტომ სანამ სხვა რამეს გამართავთ, დაადასტურეთ, რომ ის ჩატვირთულია: apachectl -M | grep authz_host.
მისამართი, რომელსაც Apache აფასებს, სოკეტის მისამართია
Require ip ადარებს იმ მისამართს, რომელიც Apache-მ კავშირისთვის ჩაწერა, და ეს ყოველთვის არ არის ის მისამართი, რომელიც კლიენტს ჰგონია, რომ აქვს.
როცა VPN თავის მისამართებს თარგმანის გარეშე მარშრუტავს, Apache გვირაბის მისამართს ხედავს და 10.8.0.0/24 ემთხვევა. როცა კარიბჭე თარგმნის, Apache კარიბჭეს ხედავს და წესი ჩუმად არაფერს ემთხვევა; იგივე ხდება ჰოსტის წინ TLS-ის დამამთავრებელი ბალანსირების უკან. ამ შემთხვევისთვის არსებობს mod_remoteip. RemoteIPHeader X-Forwarded-For ბალანსირებისთვის განკუთვნილ RemoteIPTrustedProxy-თან ერთად ცვლის ჩაწერილ მისამართს და მხოლოდ მაშინ აქვს დიაპაზონს რასთან შესადარებელი.
თვითნებური გადამისამართების თავსართის ნდობა უარესია, ვიდრე წესის საერთოდ არ ქონა. ნებისმიერ კლიენტს შეუძლია გაგზავნოს X-Forwarded-For 10.8.0.9-ით და დააკმაყოფილოს დიაპაზონის შემოწმება, რომელიც არასდროს ყოფილა მიმაგრებული სანდო ნაბიჯს.
შრეებად დააწყვეთ მსმენელი და საცავის პოლიტიკა
მიბმა ცალკე კონტროლია და ხშირად უფრო მარტივი. Listen 10.8.0.1:443 განსაზღვრავს, რომელი სოკეტები არსებობს, და მოთხოვნა ვერ აირჩევს ჰოსტს იმ სოკეტზე, რომელიც არასდროს გახსნილა. ფასი გაშვების რიგია: თუ Apache-ის გაშვებისას გვირაბის ინტერფეისი გამორთულია, მიბმა ვერ ხერხდება და სერვისი არ ადის. დააწყვილეთ იგი ერთეულების რიგთან ან მიამაგრეთ მისამართზე, რომელიც გვირაბისგან დამოუკიდებლად არსებობს.
ბილიკის ნებართვები რჩება AuthzSVNAccessFile-ში. საიტისთვის მოქმედი ანგარიში არ არის იგივე ნებართვა, რაც პროექტის ბილიკზე ჩაწერის წვდომა, და ქსელის წესი ამას არ ცვლის.
ყურადღება მიაქციეთ განყოფილებების გაერთიანებას, როცა ბლოკი ჩართულ ფაილშია. Apache აერთიანებს ავტორიზაციის კონტეინერებს ჩადგმულ განყოფილებებში და ყველაზე კონკრეტულ შესაბამის განყოფილებას შეუძლია მოთხოვნის ჩანაცვლება და არა დამატება, ამიტომ /svn-ზე არსებულმა წესმა შეიძლება ვერ მიაღწიოს /svn/repo/trunk-ს, როცა უფრო ვიწრო განყოფილება განსაზღვრავს საკუთარს.
სანამ დასრულებულად გამოაცხადებთ, დაამტკიცეთ ორივე უარი
შეამოწმეთ ოთხი მოთხოვნა და არა ერთი. VPN-ის შიგნით მოქმედი ანგარიშით უნდა მიიღოთ საცავის სია. VPN-ის შიგნით არასწორი პაროლით უნდა მიიღოთ 401 და არა სია. VPN-ის გარედან მოქმედი მონაცემებით უნდა მიიღოთ 403, და იგივე საჯარო მოთხოვნა ალტერნატიულ ჰოსტის სახელზე ისევე უნდა ჩავარდეს.
თითო შემთხვევაზე ერთი ბრძანება საკმარისია: curl -sI -u user:pass https://svn.example.com/svn/repo/, შემდეგ წაიკითხეთ სტატუსის სტრიქონი. გაიმეორეთ მომუშავე შემთხვევა ნამდვილი კლიენტითაც, რადგან svn info ავარჯიშებს იმ DAV მეთოდებს, რომლებსაც commit-ები და განახლებები გამოიყენებენ.
თუ ოთხი შედეგიდან რომელიმე არ ემთხვევა თქვენს მიერ განზრახ პოლიტიკას, კონფიგურაცია დასრულებული არ არის და ჰოსტის სახელის შეცვლა ამას არ შეცვლის.