कैसे एक खुला PostgreSQL बंदरगाह को सुरक्षित करने के लिए


29

तो, यह स्थिति है। ऐसा लगता है कि हमें दुनिया के लिए एक खुला टीसीपी पोर्ट 5432 होना चाहिए, जहां एक ग्राहक के पास अपने पोस्टग्रेक्यूएल डेटाबेस तक पहुंच हो।

स्पष्ट कारणों के लिए, हम केवल "नहीं" नहीं कह सकते, केवल अंतिम-अंतिम उपाय के रूप में।

सबसे बड़ी मुसीबतें क्या हैं? मैं अपने बुनियादी ढांचे की रक्षा कैसे कर सकता हूं?

वैसे भी: इसे दुनिया के लिए क्यों नहीं खोला जाना चाहिए ? मुझे लगता है, शायद यह कुछ 20 साल पुराने, सुरक्षित एफ़टीपी सर्वर की तुलना में अधिक सुरक्षित है।

पीएस वीपीएन ठीक नहीं है। कुछ एन्क्रिप्शन शायद (यदि मैं उसे एक JDBC कनेक्शन URL दे सकता हूं जो काम करता है )।


4
SSH सुरंग एक विकल्प नहीं हैं? यह कैसे-कैसे लेख वास्तव में एक उदाहरण के रूप में PostgreSQL का उपयोग करता है । आप ग्राहक को पूर्व-कॉन्फ़िगर किए गए SSH क्लाइंट के साथ कनेक्ट करने में आसान बनाने के लिए प्रदान कर सकते हैं।
लूसिफ़ेर सैम

@LuciferSam सं। Db का उपयोग लगभग 100 कंपनी मशीनों पर इन-हाउस विकसित जावा एप्लिकेशन द्वारा किया जाएगा। उन्हें कॉन्फ़िगर करने का हमारा एकमात्र तरीका उनके स्थानीय प्रशासन को jdbc कनेक्शन url देना है, कोई भी अन्य बहुत-बहुत समस्याग्रस्त है।

@milkman ऐप क्या करता है? शायद इसके बजाय एक RESTful सर्वर को क्वेरी कर सकता है? जाहिर है, एसक्यूएल को
रीस्ट पास

@ tedder42 यह सीएमएस के उपयोगकर्ताओं के डेटाबेस में हेरफेर करता है, जिसे हमारे द्वारा भी होस्ट किया जाता है। हमें इसका स्रोत बदलने की अनुमति नहीं है।

जवाबों:


41

SSL की आवश्यकता है, SELinux चालू रखें, लॉग की निगरानी करें, और एक वर्तमान PostgreSQL संस्करण का उपयोग करें

सर्वर साइड

SSL की आवश्यकता है

में postgresql.confसेट ssl=onहै और आप अपने keyfile और certfile उचित रूप से स्थापित किया है (डॉक्स और में टिप्पणियों को देखने के लिए सुनिश्चित करें postgresql.conf)।

यदि आप इसे क्लाइंट पर विशेष सेटअप के बिना ग्राहकों द्वारा विश्वसनीय होना चाहते हैं, तो आपको CA से एक प्रमाण पत्र खरीदने की आवश्यकता हो सकती है।

में pg_hba.confकी तरह कुछ का उपयोग करें:

hostssl theuser thedatabase 1.2.3.4/32 md5

... संभवतः उपयोगकर्ता और / या डेटाबेस के लिए "सभी" के साथ, और संभवतः एक व्यापक स्रोत आईपी एड्रेस फिल्टर के साथ।

उन उपयोगकर्ताओं को सीमित करें जो लॉग इन कर सकते हैं, दूरस्थ सुपरयुसर लॉगिन को अस्वीकार कर सकते हैं

यदि संभव हो तो उपयोगकर्ताओं के लिए "सभी" की अनुमति न दें; यदि आप इसके लिए आवश्यकता से बच सकते हैं तो आप दूरस्थ रूप से सुपरयुसर लॉगिन की अनुमति नहीं देना चाहते हैं।

उपयोगकर्ताओं के अधिकार सीमित करें

उस उपयोगकर्ता के अधिकारों को प्रतिबंधित करें जो लॉग इन कर सकते हैं। उन्हें CREATEDBया CREATEUSERअधिकार न दें ।

REVOKECONNECTसे सही PUBLICअपने सभी डेटाबेस पर, फिर इसे वापस केवल उन / भूमिकाओं कि डेटाबेस का उपयोग करने के लिए सक्षम होना चाहिए करने के लिए दे। (समूह उपयोगकर्ताओं को भूमिकाओं में और भूमिकाओं के अधिकार प्रदान करते हैं, बजाय सीधे व्यक्तिगत उपयोगकर्ताओं को)।

सुनिश्चित करें कि रिमोट एक्सेस वाले उपयोगकर्ता केवल उन DBs से कनेक्ट कर सकते हैं जिनकी उन्हें आवश्यकता है, और केवल स्कीमा, टेबल और कॉलम के अधिकार हैं जिनके भीतर उन्हें वास्तव में आवश्यकता है। यह स्थानीय उपयोगकर्ताओं के लिए भी अच्छा अभ्यास है, यह सिर्फ समझदार सुरक्षा है।

क्लाइंट सेटअप

PgJDBC में, पैरामीटर पास करेंssl=true :

JDBC ड्राइवर को SSL कनेक्शन आज़माने और स्थापित करने के लिए आपको कनेक्शन URL पैरामीटर ssl = true जोड़ना होगा।

... और क्लाइंट सर्टिफिकेट में सर्वर सर्टिफिकेट स्थापित करें, या एक सर्टिफिकेट सर्टिफिकेट का उपयोग करें, जो कि जावा के बिल्ट-इन ट्रस्टस्टोर्स में से एक के द्वारा भरोसा किया जाता है यदि आप नहीं चाहते कि उपयोगकर्ता को सर्टिफिकेट स्थापित करना पड़े।

जारी कार्रवाई

अब सुनिश्चित करें कि आप PostgreSQL को अपडेट रखें । PostgreSQL में केवल कुछ पूर्व-सुरक्षा सुरक्षा छेद हैं, लेकिन यह शून्य से अधिक है, इसलिए अद्यतित रहें। आप वैसे भी, Bugfixes अच्छी चीजें हैं होना चाहिए।

अगर आपके पास कभी पता नहीं है कि बड़े नेटब्लॉक / क्षेत्र हैं तो फायरवॉल जोड़ें।

लॉग कनेक्शन और डिस्कनेक्ट (देखें postgresql.conf)। यदि व्यावहारिक हो तो लॉग इन करें। यदि कोई प्रैक्टिकल डिटेक्शन सिस्टम या फेल 2 एबन या इसके समान सामने है तो प्रैक्टिकल चलाएं। Post2es के साथ विफलता के लिए, यहाँ एक सुविधाजनक तरीका है

लॉग फ़ाइलों की निगरानी करें।

बोनस व्यामोह

सोचने के लिए अतिरिक्त कदम ...

क्लाइंट सर्टिफिकेट चाहिए

यदि आप चाहते हैं, तो आप यह भी उपयोग pg_hba.confकरने के लिए उपयोग कर सकते हैं कि क्लाइंट सर्वर द्वारा विश्वसनीय X.509 क्लाइंट प्रमाणपत्र प्रस्तुत करता है। यह सर्वर प्रमाण के रूप में एक ही सीए का उपयोग करने की आवश्यकता नहीं है, आप एक homebrew ओपनएसएल सीए के साथ ऐसा कर सकते हैं। एक JDBC उपयोगकर्ता को अपने जावा कीस्टोर में क्लाइंट सर्टिफिकेट आयात करने की आवश्यकता होती है keytoolऔर संभवत: जावा को उनके कीस्टॉर पर इंगित करने के लिए कुछ JSSE सिस्टम गुण कॉन्फ़िगर करते हैं, इसलिए यह पूरी तरह से पारदर्शी नहीं है।

उदाहरण को छोड़ें

यदि आप वास्तव में पागल होना चाहते हैं, तो क्लाइंट के लिए एक अलग कंटेनर / वीएम में, या कम से कम एक अलग उपयोगकर्ता खाते के तहत, केवल डेटाबेस (ओं) के साथ उन्हें चलाने की आवश्यकता है।

इस तरह अगर वे PostgreSQL उदाहरण से समझौता करते हैं तो उन्हें आगे नहीं मिलेगा।

SELinux का प्रयोग करें

मुझे यह कहना नहीं चाहिए, लेकिन ...

SELinux सपोर्ट वाली मशीन को RHEL 6 या 7 की तरह चलाएं, और SELinux को बंद न करें या इसे परमिशन मोड पर सेट न करें । इसे लागू करने की विधि में रखें।

एक गैर-डिफ़ॉल्ट पोर्ट का उपयोग करें

केवल अस्पष्टता से सुरक्षा मूर्खता है। एक बार जब आप समझदार सामान कर लेते हैं तो थोड़ी अस्पष्टता का उपयोग करने वाली सुरक्षा संभवतः चोट नहीं पहुंचाएगी।

स्वचालित हमलावरों के लिए जीवन को थोड़ा कठिन बनाने के लिए एक गैर-डिफ़ॉल्ट पोर्ट पर पीजी चलाएं।

सामने एक छद्म रखो

आप कनेक्शन पूल और प्रॉक्सी के रूप में कार्य करते हुए PostgreSQL के सामने PgBouncer या PgPool-II भी चला सकते हैं। इस तरह से आप प्रॉक्सी को एसएसएल को हैंडल कर सकते हैं, न कि असली डेटाबेस होस्ट को। प्रॉक्सी एक अलग वीएम या मशीन पर हो सकती है।

कनेक्शन पूलिंग प्रॉक्सी का उपयोग आमतौर पर वैसे भी PostgreSQL के साथ एक अच्छा विचार है, जब तक कि क्लाइंट ऐप में पहले से ही एक अंतर्निहित पूल नहीं है। अधिकांश जावा एप्लिकेशन सर्वर, रेल, आदि में अंतर्निहित पूलिंग है। फिर भी, सर्वर साइड पूलिंग प्रॉक्सी सबसे अधिक हानिरहित है।


3
यदि क्लाइंट के पास एक स्थिर $ IP है, तो केवल फ़ायरवॉल के माध्यम से $ पोर्ट की अनुमति दें।
user9517

आपका बहुत बहुत धन्यवाद! Pgjdbc के पास यह परम है, लेकिन मैं उसे केवल jdbc कनेक्शन url दे सकता हूं, और मुझे यकीन नहीं है कि यह उसके java एप्लिकेशन (मालिकाना, अप्राप्य) के साथ काम करेगा। ठीक है, नहीं तो मैं एक नया सवाल पूछूंगा। धन्यवाद आपका विस्तृत जवाब!

1
@lesto असल में, मुझे लगता है कि वीपीएन को बड़े पैमाने पर उजागर करने से हमले की सतह केवल एक प्रतिबंधित सेवा की तुलना में बढ़ जाती है। लोग यह भूल जाते हैं कि वीपीएन तब रिमोट मशीन (एस) पर किसी भी मैलवेयर के लिए सभी परिधि सुरक्षा के माध्यम से पंच करने के लिए और नेटवर्क की हिम्मत पाने के लिए एक हमला चैनल बन जाता है। मैं केवल उन्हें स्वीकार्य मानता हूं यदि वे एक डीएमजेड से जुड़ते हैं जो उन्हें इंटरनेट होस्ट के रूप में विषाक्त होने के रूप में व्यवहार करता है।
क्रेग रिंगर

1
@ क्रेगिंगर, मैं बाकी सुरक्षा को हटाने के लिए नहीं कह रहा हूं, लेकिन वीपीएन में सेवा को
प्रोत्साहित

1
@lesto ज़रूर, सहमत, एक वीपीएन एक उपयोगी अतिरिक्त परत हो सकता है अगर इसे जादू सुरक्षा सॉस के रूप में नहीं माना जाता है जैसे कि बहुत से दुर्भाग्य से।
क्रेग रिंगर

2

क्रेग्स प्रभावशाली कार्य योजना का एक सरल विस्तार:

हो सकता है कि उपयोगकर्ता नेटवर्क प्रदाताओं के केवल एक रिश्तेदार सेट का उपयोग कर रहा हो (उदाहरण के लिए, चलते समय उसका मोबिल नेटवर्क प्रदाता, घर से उसका केबल नेटवर्क और कार्यस्थल से कार्यस्थल आउटगोइंग आईपी)।

अधिकांश नेटवर्क प्रदाता के पास कई आईपी हैं, लेकिन वास्तव में कई सबनेट नहीं हैं। तो, आप एक iptables फ़िल्टर दे सकते हैं, जो आपके ग्राहक द्वारा उपयोग किए जाने वाले नेटवर्क सेगमेंट तक पोस्टग्रेज़ल एक्सेस को सीमित करता है। इसने नेट के बेतरतीब ढंग से चयनित मुसीबत स्रोतों की हमले की संभावनाओं को बहुत कम कर दिया।

एक साधारण समर्थन परिदृश्य:

  1. आपका ग्राहक आपको कॉल करता है, "मैं लॉगिन नहीं कर सकता"
  2. आपको एक tcpdump -i eth0 -p tcp port 5432कमांड से पता चलता है कि वह कहां से आ रहा है।
  3. एक साथ whois 1.2.3.4आप आईपी इस आईपी पते के द्वारा प्रयोग किया जाता मिल सकता है। उदाहरण के लिए, यह हो सकता है 1.2.3.0/24
  4. एक iptables -A INPUT -s 1.2.3.0/24 -p tcp --dport 5432 -j ACCEPT(या कुछ समान) के साथ आप अपने नए सबनेट के साथ tcp कनेक्शन की अनुमति देते हैं।

एक बहुत ही अच्छी पर्ल स्क्रिप्ट है जिसका नाम uifस्थायी और सहज ज्ञान युक्त डिसेबल iptables प्रदान कर सकता है। ("Uif iptables" के लिए Google)।


1
दिलचस्प विचार है, लेकिन यह थोड़ा नाजुक लगता है।
nishantjr

@nishantjr बेशक यह एक स्टैंडअलोन समाधान नहीं है, केवल चीजों को बेहतर बनाने की संभावना है।
पीटर कहते हैं मोनिका

एक अधिक व्यावहारिक दृष्टिकोण व्यक्तिगत ISPs और / या देशों के लिए श्वेतसूची में हो सकता है, यह देखने के तरीकों के लिए जैसे कि stackoverflow.com/questions/16617607/…
जोसिप रोडिन

1

यहाँ HOWTO के आधार पर PostgreSQL के लिए एक बहुत ही सरल Fail2ban विन्यास ऊपर जुड़ा हुआ है लेकिन वास्तव में Ubuntu पैकेज के साथ काम करने के लिए ठीक है, एक और त्रुटि स्थिति को पकड़ता है और इसे जल्दी बनाने के लिए विभिन्न डीबग संदेशों को छोड़ देता है:

/etc/fail2ban/filter.d/local-postgresql.conf:

[Definition]

failregex = <HOST>\(\d+\) FATAL:  password authentication failed for .+$
            <HOST>\(\d+\) FATAL:  no pg_hba.conf entry for host .+$

ignoreregex = duration:

/etc/fail2ban/jail.d/local-postgresql.conf:

[local-postgresql]
enabled  = true
filter   = local-postgresql
action   = iptables[name=PostgreSQL, port=5432, protocol=tcp]
           sendmail-whois[name=PostgreSQL, dest=root@localhost]
logpath  = /var/log/postgresql/postgresql-9.3-main.log
maxretry = 3

1

Fail2ban एक शक्तिशाली उपकरण है, लेकिन इस बात पर भरोसा न करें कि एक फिल्टर भी काम करेगा। असफल फ़िल्टर टूल का उपयोग करके किसी भी फ़िल्टर का परीक्षण करें , और किसी भी उद्धरण से बचने के लिए याद रखें (यानी "व्यवस्थापक" \ "admin \" होगा)। एक उदाहरण के रूप में, मेरे /etc/log/postgresql/postgresql-9.3-main.log से निम्न फ़िल्टर विफलता रेखा का परीक्षण मेरे लिए काम नहीं आया।

fail2ban-regex '2016-09-20 14:30:09 PDT FATAL:  password authentication failed for user "admin"' '<HOST>\(\d+\) FATAL:  password authentication failed for .+$'

ऊपर वाले ने मुझे दिया

विफलता: 0 कुल

मुझे लॉग प्रारूप से मेल करने के लिए असफलता अद्यतन करना पड़ा।

fail2ban-regex '2016-09-20 14:30:09 PDT FATAL:  password authentication failed for user "admin"' 'FATAL:  password authentication failed for user \"<HOST>\"'

इससे मुझे सकारात्मक परिणाम मिला।

विफलता: 1 कुल

फेल 2बन-रेगेक्स टेस्ट को पूरी लॉग फाइलों पर भी लागू किया जा सकता है।

fail2ban-regex /var/log/postgresql/postgresql-9.3-main.log /etc/fail2ban/filter.d/postgresql.local

उपरोक्त ने मुझे अपडेट किए गए विफलता के साथ निम्नलिखित सकारात्मक परिणाम दिए।

असफलता: 169 कुल

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.