ट्रिगर्स का उपयोग किए बिना SQL सर्वर में क्वेरी फायरिंग करने वाले क्लाइंट की पहचान का पता लगाएं?


11

मैं वर्तमान में डेटा परिवर्तन पर नज़र रखने के लिए चेंज डेटा कैप्चर (सीडीसी) का उपयोग कर रहा हूं , और मैं उस परिवर्तन को बनाने वाले क्वेरी को सबमिट करने वाले क्लाइंट के होस्ट नाम और आईपी पते को ट्रैक करना चाहता हूं। यदि एक ही उपयोगकर्ता नाम के माध्यम से 5 अलग-अलग क्लाइंट लॉग इन होते हैं, तो किसी को ट्रैकिंग ट्रैकिंग का सामना करना पड़ता है जिसमें से 5 ने क्वेरी को निकाल दिया। अन्य विशिष्ट समाधान जो मुझे मिले उनमें निम्नलिखित कमांड के साथ सीडीसी तालिका को बदलना शामिल है:

ALTER TABLE cdc.schema_table_CT 
ADD HostName nvarchar(50) NULL DEFAULT(HOST_NAME())

हालाँकि, यह उस सर्वर का होस्ट-नाम लौटाता है जिस पर क्वेरी को निकाल दिया गया था, न कि क्वेरी को आग लगाने वाले क्लाइंट का होस्ट-नाम।

क्या इस समस्या का कोई रास्ता है? कुछ ऐसा जो क्लाइंट के होस्ट-नाम या आईपी पते (या किसी अन्य प्रकार की विशिष्ट पहचान) को लॉग करने में मदद करेगा। मैं ट्रिगर्स का उपयोग नहीं करना चाहता, क्योंकि यह सिस्टम को धीमा कर देता है, सीडीसी भी सिस्टम टेबल उत्पन्न करता है, इसलिए उस पर ट्रिगर होना स्पष्ट रूप से संभव नहीं है।

जवाबों:


4

मुझे सीडीसी के बारे में निश्चित नहीं है, लेकिन यदि लॉगिन है view server state permissionतो आप कुछ जानकारी प्राप्त करने के लिए डीएमवी का उपयोग कर सकते हैं।

यह यहाँ ऑनलाइन पुस्तकों में दिया गया है । मैंने उन स्तंभों को जोड़ने के लिए क्वेरी बदल दी है जो आपको देंगे IP address:

SELECT 
    c.session_id, c.net_transport, c.encrypt_option, c.auth_scheme,
    s.host_name, s.program_name, s.client_interface_name,
    c.local_net_address, c.client_net_address, s.login_name, s.nt_domain, 
    s.nt_user_name, s.original_login_name, c.connect_time, s.login_time 
FROM sys.dm_exec_connections AS c
JOIN sys.dm_exec_sessions AS s
    ON c.session_id = s.session_id
WHERE c.session_id = SPID;  --session ID you want to track

4

जब आप कहते हैं, "ट्रिगर्स का उपयोग किए बिना", तो क्या आपका मतलब किसी भी ट्रिगर या केवल पंक्ति-दर-पंक्ति ट्रिगर्स टेबल पर है?

मैं पूछता हूं क्योंकि आप फ़ंक्शन के विवेकपूर्ण उपयोग के साथ जो आप चाहते हैं वह प्राप्त करने में सक्षम हो सकते हैं CONTEXT_INFO(), लेकिन आपको यह सुनिश्चित करने की आवश्यकता होगी कि SET CONTEXT_INFOआपके ऑपरेशन होने से पहले इसे सही ढंग से कहा गया था।

ऐसा करने के लिए एक स्थान सर्वर-स्तरीय लॉगऑन ट्रिगर हो सकता है (जैसे डेटाबेस / ऑब्जेक्ट-स्तरीय ट्रिगर नहीं), जैसे:

USE master
GO
CREATE TRIGGER tr_audit_login
ON ALL SERVER 
WITH EXECUTE AS 'sa'
AFTER LOGON
AS BEGIN
    BEGIN TRY

        DECLARE @eventdata XML = EVENTDATA();

        IF @eventdata IS NOT NULL BEGIN
            DECLARE @spid INT;
            DECLARE @client_host VARCHAR(64);
            SET @client_host    = @eventdata.value('(/EVENT_INSTANCE/ClientHost)[1]',   'VARCHAR(64)');
            SET @spid           = @eventdata.value('(/EVENT_INSTANCE/SPID)[1]',         'INT');

            -- pack the required data into the context data binary
            -- (spid is just an example of packing multiple data items in a single field: you would probably use @@SPID at the point of use, instead)
            DECLARE @context_data VARBINARY(128);
            SET @context_data = CONVERT(VARBINARY(4),  @spid)
                              + CONVERT(VARBINARY(64), @client_host);

            -- persist the spid and host into session-level memory
            SET CONTEXT_INFO @context_data;             
        END

    END TRY
    BEGIN CATCH
        /* do better error handling here...
         * logon trigger can lock all users out of server, so i am just swallowing everything
         */
        DECLARE @msg NVARCHAR(4000) = ERROR_MESSAGE();
        RAISERROR('%s', 10, 1, @msg) WITH LOG;
    END CATCH
END

आप संदर्भ (संग्रह की गति के लिए) को संग्रहीत करने के लिए अपनी तालिका में डिफ़ॉल्ट बाधा जोड़ सकते हैं:

ALTER TABLE cdc.schema_table_CT 
ADD ContextInfo varbinary(128) NULL DEFAULT(CONTEXT_INFO())

आपके पास एक बार, आप उस ContextInfoकॉलम को थोड़ा टुकड़ा-और-पासा के साथ क्वेरी कर सकते हैं :

SELECT *
    ,spid = CONVERT(INT, SUBSTRING(ContextInfo, 1, 4))
    ,client = CONVERT(VARCHAR(64), SUBSTRING(ContextInfo, 5, 64))
FROM cdc.schema_table_CT

तकनीकी रूप से, आप ऐसा कर सकते हैं SUBSTRINGऔर CONVERTअपने डिफ़ॉल्ट बाधा के हिस्से के रूप में सामान कर सकते हैं , और बस क्लाइंट आईपी को वहां स्टोर कर सकते हैं, लेकिन यह पूरे संदर्भ को स्टोर करने के लिए तेज हो सकता है (जैसा कि यह हर पर किया जाता है INSERT), और केवल मानों को एक में निकालें SELECTजब आपको उनकी आवश्यकता हो

मैं अपने सभी को लपेटने के लिए इच्छुक हो सकता हूं SUBSTRINGऔर CONVERTएकल-पंक्ति इनलाइन तालिका-मूल्यवान फ़ंक्शन में कॉल कर सकता हूं , जो मुझे CROSS APPLYआवश्यक होगा । यह एक ही स्थान पर अनपैकिंग तर्क रखता है:

CREATE FUNCTION fn_context (
    @context_info VARBINARY(128)
)
RETURNS TABLE
AS RETURN (
    SELECT
         spid = CONVERT(INT, SUBSTRING(@context_info, 1, 4))
        ,client = CONVERT(VARCHAR(64), SUBSTRING(@context_info, 5, 64))
)
GO

SELECT * 
FROM cdc.schema_table_CT s
CROSS APPLY dbo.fn_context(s.ContextInfo) c

ध्यान दें कि CONTEXT_INFOकेवल एक 128-बाइट है VARBINARY। यदि आपको 128 बाइट में फिट होने से अधिक डेटा की आवश्यकता है, तो मैं उस सभी डेटा को रखने के लिए एक तालिका बनाऊंगा, लॉगऑन ट्रिगर में उस 'सत्र' के लिए पंक्ति के रूप में डालें और CONTEXT_INFOउस तालिका के सरोगेट कुंजी मान पर सेट करें

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

यह अच्छा होगा यदि यह एक डिफ़ॉल्ट के बजाय एक निरंतर गणना वाला स्तंभ हो सकता है, लेकिन CONTEXT_INFO()फ़ंक्शन गैर-नियतात्मक है, इसलिए यह एक नो-गो है (आप कुछ FUNCTIONआस-पास के कुछ चालबाजी का उपयोग करने में सक्षम हो सकते हैं VIEW, लेकिन मैं नहीं करूंगा )।

यह उस उपयोगकर्ता के लिए भी तुच्छ है, जिसके पास SET CONTEXT_INFOखुद को बुलाने और अपने दिन को गड़बड़ करने के लिए पर्याप्त उपयोग है (जैसे नकली मान, या विशेष रूप से तैयार किए गए इंजेक्शन के साथ), इसलिए संदेह और देखभाल के साथ सामग्री का इलाज करें, इसे प्रदर्शित करने से पहले एनकोड करें, और अपवादों को संभालें। कुंआ।

Hostname के लिए, मुझे लगता है कि ClientHostतत्व EVENTDATA()आपको IP पता (या एक <local machine>संकेतक) देता है। जब आप तकनीकी रूप से CLR का उपयोग रिवर्स-डीएनएस लुक्स को होस्टनाम में करने के लिए कर सकते हैं, तो ये हर करने के लिए बहुत धीमे होते हैं INSERT, इसलिए मैं ऐसा नहीं करने की सलाह दूंगा।

यदि आपके पास एक होस्टनाम होना है, तो आप अपने स्थानीय डीएचसीपी सर्वर या डीएनएस ज़ोन फ़ाइल से मौजूदा पट्टों के साथ एक आउट-ऑफ-बैंड प्रक्रिया के रूप में और उसके LEFT JOINलिए समय-समय पर एक अलग तालिका को पॉप्युलेट करने के लिए SQL एजेंट नौकरी का उपयोग करना चाह सकते हैं । भविष्य के प्रश्नों (या FUNCTIONबिंदु-समय के लिए एक डिफ़ॉल्ट बाधा के लिए एक मूल्य प्रदान करने के लिए स्केलर में लपेटें )।

फिर से, आपको ध्यान देना चाहिए कि यदि आवेदन में किसी भी प्रकार का सार्वजनिक-सामना करने वाला घटक है, तो आईपी पते और होस्टनाम अविश्वसनीय हैं (जैसे NAT के कारण)। यहां तक ​​कि अगर यह सार्वजनिक-सामना नहीं कर रहा है, तो अधिकांश आईपी / होस्टनाम मानचित्रों के लिए एक निश्चित समय-आधारित घटक है, जिसे आपको कारक करना पड़ सकता है।

अंत में, अपने लॉगिन ट्रिगर को लागू करने से पहले, यह आपके सर्वर के समर्पित व्यवस्थापक कनेक्शन को चालू करने योग्य हो सकता है। यदि लॉगिन ट्रिगर किसी भी तरह से टूट जाता है, तो यह सभी उपयोगकर्ताओं को (sysadmin खातों सहित) लॉग इन करने से रोक सकता है:

USE master
GO
-- you may want to do this, so you have a back-out if the login trigger breaks login
EXEC sp_configure 'remote admin connections', 1 
GO
RECONFIGURE
GO

यदि आप लॉक आउट हो जाते हैं, तो लॉगिन ट्रिगर को गिराने या निष्क्रिय करने के लिए DAC का उपयोग किया जा सकता है:

C:\> sqlcmd -S localhost -d master -A
1> DISABLE TRIGGER tr_audit_login ON ALL SERVER
2> GO

3

कृपया कनेक्ट बग पर एक नज़र डालें : नीचे से प्रासंगिक स्निपेट है

यह बर्ताव डिज़ाइन के चलते है। सीडीसी को एक बदलाव के बारे में निम्नलिखित जानकारी को उजागर करने के लिए डिज़ाइन किया गया है: अपडेट किए गए कॉलम, संचालन का प्रकार और लेनदेन की जानकारी। इसे ऑडिट समाधान के रूप में तैयार नहीं किया गया है। यह वृद्धिशील डेटा लोड के माध्यम से कुशल एक्सट्रैक्ट ट्रांसफर और लोड सॉल्यूशंस (ETL) को सक्षम करने के लिए बनाया गया है, जो कुल ETF समय को कम करने के लिए महत्वपूर्ण है। इसका मुख्य लक्ष्य "जो बदल गया है" को उजागर नहीं किया गया है, कौन, कब ... इसके लिए मैं SQL ऑडिट सुविधा की सिफारिश करता हूं।

चूंकि अब सीडीसी को ऑडिट समाधान में बदलने की कोई योजना नहीं है।

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