आईपी सेट पुनरीक्षित
पहले से ही आईपी सेट का उल्लेख करने वाला एक उत्तर है। हालाँकि, यह इसमें एक आयामी है कि यह क्लासिक नियमों पर प्रदर्शन लाभ पर केंद्रित है और यह तथ्य कि आईपी सेट समस्या को कम करता है एक व्यक्ति के बहुत सारे आईपी पते के साथ होता है जिसे आसानी से सीआईडीआर नोटेशन में सबनेट के रूप में व्यक्त नहीं किया जा सकता है।
नीचे उपयोग संकेतन
क्योंकि ipsetमैं द्वारा पढ़ी ipset restoreऔर लिखी गई संकेतन का उपयोग करूँगा ipset save।
iptables(और ip6tables) नियमों के अनुरूप मैं द्वारा पढ़ी iptables-restoreऔर लिखी गई अधिसूचना का उपयोग करूंगा iptables-save। यह एक छोटी संकेतन के लिए बनाता है और यह मुझे संभावित IPv4- केवल (उपसर्ग -4) या IPv6- केवल (उपसर्ग -6) नियमों को उजागर करने की अनुमति देता है।
कुछ उदाहरणों में हम पैकेट प्रवाह को दूसरी श्रृंखला में बदल देंगे। उस बिंदु पर श्रृंखला का अस्तित्व माना जाता है, इसलिए श्रृंखला बनाने के लिए लाइनों का उत्पादन नहीं किया जाता है (और न ही तालिका का नाम या कमांड- COMMITअंत में उल्लेख किया गया है)।
उन्नत IP सेट
IP सेट अन्य उत्तर में वर्णित की तुलना में बहुत अधिक कर सकता है और आपको यहां इस संक्षिप्त प्रविष्टि ipset(8)के साथ-साथ निश्चित रूप से IP सेट प्रलेखन ( ) भी पढ़ना चाहिए iptables-extensions(8)।
उदाहरण के लिए मैं मुख्य रूप से तीन सेट प्रकार पर ध्यान केंद्रित करेंगे: hash:ip, hash:netऔर list:set, लेकिन वहाँ की तुलना में अधिक हैं और वे सभी वैध उपयोगों की सूची है।
उदाहरण के लिए आप केवल आईपी पते ही नहीं बल्कि पोर्ट नंबर से भी मेल खा सकते हैं ।
के रूप में iptables-saveऔर के साथ आईपी सेट को सहेजना और पुनर्स्थापित करनाiptables-restore
आप बल्क में IP सेट घोषणाएँ बना सकते हैं और उन्हें पाइपिंग द्वारा आयात कर सकते हैं ipset restore। यदि आप पहले से मौजूद प्रविष्टियों के खिलाफ अपने कमांड को अधिक लचीला बनाना चाहते हैं, तो उपयोग करें ipset -exist restore।
यदि आपके नियम एक फाइल में हैं जिसे default.setआप उपयोग करेंगे:
ipset -exist restore < default.set
उस तरह की फ़ाइल में प्रविष्टियाँ createसेट करने के लिए और addउनमें प्रविष्टियाँ हो सकती हैं। लेकिन आम तौर पर कमांड लाइन से अधिकांश कमांड फाइलों में एक संबंधित संस्करण है। उदाहरण (DNS सर्वर का एक सेट बनाना):
create dns4 hash:ip family inet
create dns6 hash:ip family inet6
# Google DNS servers
add dns4 8.8.8.8
add dns4 8.8.4.4
add dns6 2001:4860:4860::8888
add dns6 2001:4860:4860::8844
यहाँ एक सेट IPv4 ( dns4) और एक IPv6 ( dns6) के लिए बनाया गया है।
आईपी सेट पर टाइमआउट
आईपी सेट में टाइमआउट एक सेट प्रति डिफ़ॉल्ट और प्रति प्रविष्टि के रूप में भी सेट किया जा सकता है। यह उन परिदृश्यों के लिए बहुत उपयोगी है, जहां आप किसी को अस्थायी रूप से ब्लॉक करना चाहते हैं (जैसे पोर्ट-स्कैनिंग के लिए या अपने SSB सर्वर को भंग करने का प्रयास करना)।
यह काम इस प्रकार है (आईपी सेट के निर्माण के दौरान डिफ़ॉल्ट):
create ssh_loggedon4 hash:ip family inet timeout 5400
create ssh_loggedon6 hash:ip family inet6 timeout 5400
create ssh_dynblock4 hash:ip family inet timeout 1800
create ssh_dynblock6 hash:ip family inet6 timeout 1800
हम नीचे दिए गए इन विशेष सेटों और औचित्य पर वापस लौट आएंगे क्योंकि वे जिस तरह से सेट हैं, उसी तरह से हैं।
यदि आप किसी विशेष आईपी पते के लिए अपना समय निर्धारित करना चाहते हैं, तो आप बस कह सकते हैं:
add ssh_dynblock4 1.2.3.4 timeout 7200
(सेट) डिफ़ॉल्ट आधे घंटे के बजाय दो घंटे के लिए आईपी 1.2.3.4 को ब्लॉक करने के लिए।
यदि आप ipset save ssh_dynblock4थोड़ी देर के बाद उस के साथ देखने के लिए थे , तो आप कुछ लाइनों के साथ देखेंगे:
create ssh_dynblock4 hash:ip family inet hashsize 1024 maxelem 65536 timeout 1800
add ssh_dynblock4 1.2.3.4 timeout 6954
समयबाह्य कैविएट
- टाइमआउट किसी भी सेट पर एक सुविधा है। यदि सेट टाइमआउट समर्थन के साथ नहीं बनाया गया था, तो आपको एक त्रुटि (जैसे
Kernel error received: Unknown error -1) प्राप्त होगी ।
- सेकंड में टाइमआउट दिया जाता है। उदाहरण के लिए, मिनट से लेकर सेकंड तक बैश अंकगणितीय अभिव्यक्तियों का उपयोग करें। उदाहरण के लिए:
sudo ipset add ssh_dynblock4 1.2.3.4 timeout $((120*60))
यह देखना कि किसी दिए गए आईपी सेट में कोई प्रविष्टि मौजूद है या नहीं
आपकी स्क्रिप्ट्स के अंदर यह देखना उपयोगी हो सकता है कि क्या एक प्रविष्टि पहले से मौजूद है। यह प्राप्त किया जा सकता है ipset testजिसके साथ शून्य मौजूद है यदि प्रविष्टि मौजूद है और गैर-शून्य अन्यथा। तो सामान्य जांच को एक स्क्रिप्ट में लागू किया जा सकता है:
if ipset test dns4 8.8.8.8; then
echo "Google DNS is in the set"
fi
हालाँकि, कई मामलों में आप -existस्विच का उपयोग करना चाहेंगे ipsetताकि यह निर्देश दिया जा सके कि यह मौजूदा प्रविष्टियों के बारे में शिकायत न करें।
iptablesनियमों से IP सेट करना
यह, मेरी राय में, आईपी सेट के हत्यारे सुविधाओं में से एक है। न केवल आप एक आईपी सेट की प्रविष्टियों के खिलाफ मैच कर सकते हैं, आप एक मौजूदा आईपी सेट में नई प्रविष्टियां भी जोड़ सकते हैं।
इस प्रश्न के उत्तर में उदाहरण के लिए आपके पास:
-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP
-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT
... एसएसएच (टीसीपी पोर्ट 22) के लिए दर-सीमा कनेक्शन के प्रयासों के इरादे से। प्रयुक्त मॉड्यूल recentहाल के कनेक्शन प्रयासों का ट्रैक रखता है। stateमॉड्यूल के बजाय , मैं conntrackमॉड्यूल को पसंद करता हूं , हालांकि।
# Say on your input chain of the filter table you have
-A INPUT -i eth+ -p tcp --dport ssh -j SSH
# Then inside the SSH chain you can
# 1. create an entry in the recent list on new connections
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
# 2. check whether 3 connection attempts were made within 2 minutes
# and if so add or update an entry in the ssh_dynblock4 IP set
-4 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock4 src --exist
-6 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock6 src --exist
# 3. last but not least reject the packets if the source IP is in our
# IP set
-4 -A SSH -m set --match-set ssh_dynblock4 src -j REJECT
-6 -A SSH -m set --match-set ssh_dynblock6 src -j REJECT
इस मामले में मैं SSHश्रृंखला के प्रवाह को इस तरह से पुनर्निर्देशित कर रहा हूं कि मुझे -p tcp --dport sshहर एक नियम के लिए खुद को दोहराना नहीं है ।
दोहराना:
-m setबनाता है iptablesके बारे में पता है कि हम से स्विच का उपयोग कर रहे setमॉड्यूल (जो आईपी सेट संभालती है)
--match-set ssh_dynblock4 srcनामित सेट के खिलाफ स्रोत ( ) पते iptablesसे मिलान करने के लिए कहता है ( )
srcssh_dynblock4
- यह
sudo ipset test ssh_dynblock4 $IP(जहां $IPपैकेट के लिए स्रोत आईपी पता है) से मेल खाती है
-j SET --add-set ssh_dynblock4 src --existआईपी सेट में पैकेट से स्रोत ( src) पते को जोड़ता या अपडेट करता है ssh_dynblock4। यदि कोई प्रविष्टि मौजूद है ( --exist) तो वह बस अपडेट हो जाएगी।
- यह
sudo ipset -exist add ssh_dynblock4 $IP(जहां $IPपैकेट के लिए स्रोत आईपी पता है) से मेल खाती है
यदि आप इसके बजाय लक्ष्य / गंतव्य पते का मिलान करना चाहते हैं, तो आप dstइसके बजाय उपयोग करेंगे src। अधिक विकल्पों के लिए मैनुअल से परामर्श करें।
सेट के सेट
आईपी सेट में अन्य सेट हो सकते हैं। अब यदि आप इस लेख को यहाँ तक फॉलो करते हैं तो आपको आश्चर्य होगा कि क्या सेट्स को संयोजित करना संभव है। और निश्चित ही यह है। ऊपर से IP सेट के लिए हम दो संयुक्त सेट बना सकते हैं ssh_dynblockऔर ssh_loggedonक्रमशः IPv4-only और IPv6- केवल सेट शामिल करने के लिए:
create ssh_loggedon4 hash:ip family inet timeout 5400
create ssh_loggedon6 hash:ip family inet6 timeout 5400
create ssh_dynblock4 hash:ip family inet timeout 1800
create ssh_dynblock6 hash:ip family inet6 timeout 1800
# Sets of sets
create ssh_loggedon list:set
create ssh_dynblock list:set
# Populate the sets of sets
add ssh_loggedon ssh_loggedon4
add ssh_loggedon ssh_loggedon6
add ssh_dynblock ssh_dynblock4
add ssh_dynblock ssh_dynblock6
और अगला सवाल जो आपके दिमाग में उठना चाहिए वह यह है कि क्या यह हमें आईपी संस्करण-एग्रोस्टिक फैशन में आईपी सेटों के मिलान और हेरफेर करने की अनुमति देता है ।
और उस का जवाब एक शानदार है: हाँ! (अफसोस, यह स्पष्ट नहीं था कि पिछली बार मैंने जाँच की थी)
नतीजतन पिछले अनुभाग के नियमों को पढ़ने के लिए फिर से लिखा जा सकता है:
-A INPUT -i eth+ -p tcp --dport ssh -j SSH
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
-A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist
-A SSH -m set --match-set ssh_dynblock src -j REJECT
जो बहुत अधिक संक्षिप्त है। और हां, यह कोशिश की जाती है और परीक्षण की जाती है और एक आकर्षण की तरह काम करती है।
यह सब एक साथ रखना: SSH जानवर बल रक्षा
मेरे सर्वर पर मेरे पास एक स्क्रिप्ट है cronजो एक नौकरी के रूप में चलती है जो होस्ट नामों का एक गुच्छा लेती है और उन आईपी पते को हल करती है, फिर इसे "विश्वसनीय होस्ट" के लिए आईपी सेट में खिलाती है। यह विचार है कि विश्वसनीय होस्ट सर्वर में लॉग इन करने के लिए अधिक प्रयास करते हैं और जरूरी नहीं कि किसी अन्य के रूप में लंबे समय तक अवरुद्ध हो।
इसके विपरीत, मेरे पास पूरे देश के विश्वसनीय एसएस (यानी नियमों के आदेश) के (संभावित) अपवाद के साथ, मेरे एसएसएच सर्वर से जुड़ने से अवरुद्ध है।
हालाँकि, इसे पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है। यहां मैं एक साफ समाधान जोड़ना चाहूंगा जो सेट में निहित सेट का उपयोग करेगा ssh_loggedonताकि बाद के कनेक्शन के प्रयासों को अन्य पैकेटों के समान जांच के माध्यम से सौंप दिया जा सके।
निम्नलिखित नियमों को देखने के लिए 90 मिनट के डिफ़ॉल्ट समय ssh_loggedonऔर 30 मिनट के लिए याद रखना महत्वपूर्ण है:ssh_dynblockiptables
-A INPUT -i eth+ -p tcp --dport ssh -j SSH
-A SSH -m set --match-set ssh_loggedon src -j ACCEPT
-A SSH -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit
-A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist
-A SSH -m set --match-set ssh_dynblock src -j REJECT
अब तक आपको अपने आप से पूछना चाहिए कि ssh_loggedonउप-सेटों में कनेक्टिंग आईपी पता कैसे समाप्त होता है । तो पढ़िए ...
बोनस: SSH लॉगऑन के दौरान आपके द्वारा लॉग इन किया गया IP जोड़ना
यदि आपने sshrcदोस्तों के साथ प्रयोग किया है , तो आपको इसकी कमियों का पता चल जाएगा। लेकिन पीएएम बचाव के लिए आता है। एक मॉड्यूल नाम pam_exec.soहमें एक बिंदु पर SSH लॉगऑन के दौरान एक स्क्रिप्ट को लागू करने की अनुमति देता है जहां हम जानते हैं कि उपयोगकर्ता में प्रवेश किया गया है।
में /etc/pam.d/sshdनीचे pam_envऔर pam_selinuxप्रविष्टियों निम्नलिखित पंक्ति जोड़ें:
session optional pam_exec.so stdout /path/to/your/script
और सुनिश्चित करें कि स्क्रिप्ट का आपका संस्करण ( /path/to/your/scriptऊपर) मौजूद है और निष्पादन योग्य है।
पीएएम पर्यावरण चर का उपयोग करता है जो यह बताता है कि क्या चल रहा है, इसलिए आप इस तरह की एक सरल स्क्रिप्ट का उपयोग कर सकते हैं:
#!/bin/bash
# When called via pam_exec.so ...
SETNAME=ssh_loggedon
if [[ "$PAM_TYPE" == "open_session" ]] && [[ -n "$PAM_RHOST" ]]; then
[[ "x$PAM_RHOST" != "x${PAM_RHOST//:/}" ]] && SETNAME="${SETNAME}6" || SETNAME="${SETNAME}4"
ipset -exist add $SETNAME "$PAM_RHOST"
fi
दुर्भाग्य से ipsetउपयोगिता नेटफिल्टर के बिल्ट-इन स्मार्टस में नहीं लगती है। इसलिए हमें अपनी प्रविष्टि जोड़ते समय IPv4 और IPv6 IP सेट के बीच अंतर करने की आवश्यकता है। अन्यथा ipsetमान लेंगे कि हम आईपी के बजाय सेट के सेट में एक और सेट जोड़ना चाहते हैं । और निश्चित रूप से यह संभावना नहीं है कि एक आईपी के नाम पर एक सेट होगा :)
तो हम :आईपी पते की जांच करते हैं और 6ऐसे मामले में सेट नाम के लिए संलग्न करते हैं और 4अन्यथा।
समाप्त।