Rose debug info
---------------

Notes about IT

Позднее Ctrl + ↑

Что делать, если БД в состоянии Suspend?

Случилось, что после вынужденного выключения сервера БД одна из баз свалилась в состояние Suspend. Конечно лучше делать бекапы, но не было их на тестовом сервере. Вот скрипт, который можно и в GUI проделать, который мне помог восстановить базу:

EXEC sp_resetstatus [DB];
ALTER DATABASE [DB]SET EMERGENCY
DBCC checkdb([DB])
ALTER DATABASE [DB]SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DBCC CheckDB ([DB], REPAIR_ALLOW_DATA_LOSS)
ALTER DATABASE [DB]SET MULTI_USER

Вместо [DB] вставить свою БД.

2014   sql   windows

Утилизация RAM Metafile в Windows 2008 R2

Как часто вы видели в Диспетчере задач (Task Manager) 100% загрузку RAM, хотя суммарно по процессам там было не более 30%?
На скриншотах ниже показана не 100% загрузка, но ощутить неприятный момент дадут.

Хорошо, что у нас уже есть инструменты Windows Sysinternals, а конкретно RAMMap. Качаем, запускаем (не требует установки) и видим следующую картину:

Некие Metafiles отъедают львиную долю оперативки и, если посчитать, именно этот объем мы не увидим в Диспетчере задач.
Погуглив на тему Metafiles я нашел описание:

Metafile is part of the system cache and consists of NTFS metadata. NTFS metadata includes the MFT as well as the other various NTFS metadata files… In the MFT each file attribute record takes 1KB and each file has at least one attribute record. Add to this the other NTFS metadata files and you can see why the Metafile category can grow quite large on servers with lots of files

Что же, основным содержание одного из дисков являются jpg-файлы (>1.8Tb). Поиск по фразам «how to clean / reduce METAfIle size» выдал решение в виде установки Dynamic Cache Service. В первый раз я не установил данную службу, поэтому не могу сказать при ее работоспособность, но говорят, что под Windows Server 2008 R2 Web edition она не работает.
Что же делать, если нужно срочно освободить RAM или служба Dynamic Cache Service не приводит к желаемому результату? Открываем RAMMap, меню Empty — Empty System Wokring Set

После этого вы увидите пропавшие гигабайты.

2014   windows

Поиск цепочек блокировок на SQL Server с помощью процедуры sp_locks

Введение

Параллелизм в отношении БД можно определить как число пользователей, способных работать с данной БД, не мешая и не пересекаясь друг с другом. Чем больше число одновременно работающих пользователей, тем выше параллелизм.

SQL Server блокирует данные для обеспечения их целостности. Это необходимо в любой БД, где данные подвергаются изменениям. Чтобы подчеркнуть это, скажу, что если БД находится в состоянии READ_ONLY, SQL Server не создает блокировок считываемых данных, поскольку они не могут быть изменены и, следовательно, защищать данные не нужно. Поэтому SQL Server только помечает объекты, к которым происходит обращение, блокировкой Intense Share (IS), чтобы исключить выполнение таких DDL-выражений, как удаление таблицы, из которой производится чтение.

Блокировки данных существуют в любой среде, где модифицируются данные (то есть БД находится в состоянии READ_WRITE, в противоположность предыдущему примеру), и это совершенно нормально. SQL Server удерживает необходимые блокировки для защиты целостности данных и освобождает данные, как только отпадает необходимость в блокировке.

Краткосрочные блокировки не оказывают негативного воздействия, они — часть нормальной работы SQL Ser­ver. Проблемы возникают, когда продолжительность блокировок становится большой, то есть в несколько секунд, и в этом случае в игру вступает sp_locks.

sp_locks

sp_locks — это полезное средство, помогающее в поиске и устранении проблем в сценариях с блокировками и параллелизмом.

Листинг 1. Процедура sp_locks.

USE [master];
SET QUOTED_IDENTIFIER ON; SET ANSI_NULLS ON;

IF  EXISTS (SELECT * FROM sys.objects 
              WHERE object_id = OBJECT_ID(N'[dbo].[sp_Locks]') 
                AND type IN (N'P', N'PC')
)
  DROP PROCEDURE dbo.sp_Locks;
GO
  
  
CREATE PROCEDURE dbo.sp_Locks
(
   @Mode int = 2,
   @Wait_Duration_ms int = 1000 /* 1 seconds */
)
/*
  19/04/2008 Yaniv Etrogi
  http://www.sqlserverutilities.com  
*/
AS
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

--EXEC sp_Locks @Mode = 3, @Wait_Duration_ms = 1000

/* return the one result set */
IF @Mode = 1
BEGIN;
  SELECT
      t.blocking_session_id           AS blocking,
      t.session_id                    AS blocked,
      p2.[program_name]               AS program_blocking,
      p1.[program_name]               AS program_blocked,
      DB_NAME(l.resource_database_id) AS [database],
      p2.[hostname]                   AS host_blocking,
      p1.[hostname]                   AS host_blocked,
      t.wait_duration_ms,
      l.request_mode,
      l.resource_type,
      t.wait_type,
      (SELECT SUBSTRING(st.text, (r.statement_start_offset/2) + 1, 
              ((CASE r.statement_end_offset 
                  WHEN -1 THEN DATALENGTH(st.text) 
                  ELSE r.statement_end_offset END
                - r.statement_start_offset) /2 ) + 1)
        FROM sys.dm_exec_requests AS r 
          CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS st 
        WHERE r.session_id = l.request_session_id) AS statement_blocked,
      CASE WHEN t.blocking_session_id > 0 THEN 
        (SELECT st.text 
          FROM sys.sysprocesses AS p 
            CROSS APPLY sys.dm_exec_sql_text(p.sql_handle) AS st
          WHERE p.spid = t.blocking_session_id)
      ELSE NULL END AS statement_blocking
       --,t.resource_description AS blocking_resource_description
       --,l.resource_associated_entity_id
    FROM sys.dm_os_waiting_tasks AS t
      INNER JOIN sys.dm_tran_locks AS l 
        ON t.resource_address = l.lock_owner_address
      INNER JOIN sys.sysprocesses p1 ON p1.spid = t.session_id
      INNER JOIN sys.sysprocesses p2 ON p2.spid = t.blocking_session_id
    WHERE t.session_id > 50 AND t.wait_duration_ms > @Wait_Duration_ms;
END;

/* return the first two result sets */
IF @Mode = 2
BEGIN;
SELECT 
    spid,
    [status],
    CONVERT(CHAR(3), blocked) AS blocked,
    loginame,
    SUBSTRING([program_name] ,1,25) AS program,
    SUBSTRING(DB_NAME(p.dbid),1,10) AS [database],
    SUBSTRING(hostname, 1, 12) AS host,
    cmd,
    waittype,
    t.[text]
  FROM sys.sysprocesses p
    CROSS APPLY sys.dm_exec_sql_text (p.sql_handle) t
  WHERE spid IN (SELECT blocked FROM sys.sysprocesses WHERE blocked <> 0) 
    AND blocked = 0;

SELECT
    t.blocking_session_id            AS blocking,
    t.session_id                     AS blocked,
    p2.[program_name]                AS program_blocking,
    p1.[program_name]                AS program_blocked,
    DB_NAME(l.resource_database_id)  AS [database],
    p2.[hostname]                    AS host_blocking,
    p1.[hostname]                    AS host_blocked,
    t.wait_duration_ms,
    l.request_mode,
    l.resource_type,
    t.wait_type,
    (SELECT SUBSTRING(st.text, (r.statement_start_offset / 2) + 1, 
              ((CASE r.statement_end_offset 
                  WHEN -1 THEN DATALENGTH(st.text)
                  ELSE r.statement_end_offset END
                - r.statement_start_offset) / 2) + 1
            )
      FROM sys.dm_exec_requests AS r
        CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS st 
      WHERE r.session_id = l.request_session_id) AS statement_blocked,
    CASE WHEN t.blocking_session_id > 0 THEN 
          (SELECT st.text 
            FROM sys.sysprocesses AS p 
              CROSS APPLY sys.dm_exec_sql_text(p.sql_handle) AS st 
            WHERE p.spid = t.blocking_session_id) ELSE NULL 
         END AS statement_blocking
  FROM sys.dm_os_waiting_tasks AS t
    INNER JOIN sys.dm_tran_locks AS l
      ON t.resource_address = l.lock_owner_address
    INNER JOIN sys.sysprocesses p1 ON p1.spid = t.session_id
    INNER JOIN sys.sysprocesses p2 ON p2.spid = t.blocking_session_id
  WHERE t.session_id > 50 AND t.wait_duration_ms > @Wait_Duration_ms;
END;


/* return all three result sets */
IF @Mode = 3
BEGIN;
SELECT 
    spid,
    [status],
    CONVERT(CHAR(3), blocked) AS blocked,
    loginame,
    SUBSTRING([program_name], 1, 25)   AS program,
    SUBSTRING(DB_NAME(p.dbid), 1, 10)  AS [database],
    SUBSTRING(hostname, 1, 12)         AS host,
    cmd,
    waittype,
    t.[text]
  FROM sys.sysprocesses p
  CROSS APPLY sys.dm_exec_sql_text (p.sql_handle) t
  WHERE spid IN (SELECT blocked FROM sys.sysprocesses WHERE blocked <> 0)
    AND blocked = 0;

  
SELECT
    t.blocking_session_id                AS blocking,
    t.session_id                        AS blocked,
    SUBSTRING(p2.[program_name], 1, 25)  AS program_blocking,
    SUBSTRING(p1.[program_name], 1, 25)  AS program_blocked,
    DB_NAME(l.resource_database_id)      AS [database],
    p2.[hostname]                        AS host_blocking,
    p1.[hostname]                        AS host_blocked,
    t.wait_duration_ms,
    l.request_mode,
    l.resource_type,
    t.wait_type,
    (SELECT SUBSTRING(st.text, (r.statement_start_offset/2) + 1, 
            ((CASE r.statement_end_offset WHEN -1 THEN DATALENGTH(st.text)
              ELSE r.statement_end_offset 
              END - r.statement_start_offset) / 2) + 1) 
      FROM sys.dm_exec_requests AS r 
        CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS st 
      WHERE r.session_id = l.request_session_id) AS statement_blocked,
    CASE WHEN t.blocking_session_id > 0 THEN 
           (SELECT st.text 
              FROM sys.sysprocesses AS p 
                CROSS APPLY sys.dm_exec_sql_text(p.sql_handle) AS st 
              WHERE p.spid = t.blocking_session_id) ELSE NULL 
         END AS statement_blocking
    --,t.resource_description        AS blocking_resource_description
    --,l.resource_associated_entity_id
  FROM sys.dm_os_waiting_tasks AS t
    INNER JOIN sys.dm_tran_locks AS l 
      ON t.resource_address = l.lock_owner_address
    INNER JOIN sys.sysprocesses p1 ON p1.spid = t.session_id
    INNER JOIN sys.sysprocesses p2 ON p2.spid = t.blocking_session_id
  WHERE t.session_id > 50 AND t.wait_duration_ms > @Wait_Duration_ms;

SELECT DISTINCT
    r.session_id             AS spid,
    r.percent_complete       AS [percent],
    r.open_transaction_count AS open_trans,
    r.[status],
    r.reads,
    r.logical_reads,
    r.writes,
    s.cpu,
    DB_NAME(r.database_id)   AS [db_name],
    s.[hostname],
    s.[program_name],
  --s.loginame,
  --s.login_time,
    r.start_time,
  --r.wait_type,
    r.wait_time,
    r.last_wait_type,
    r.blocking_session_id    AS blocking,
    r.command,
    (SELECT SUBSTRING(text, statement_start_offset / 2 + 1,
            (CASE WHEN statement_end_offset = -1 THEN
                    LEN(CONVERT(NVARCHAR(MAX),text)) * 2 
                  ELSE statement_end_offset 
                  END - statement_start_offset) / 2)
      FROM sys.dm_exec_sql_text(r.sql_handle)) AS [statement],
    t.[text]
    --,query_plan 
  FROM sys.dm_exec_requests r
    INNER JOIN sys.sysprocesses s ON s.spid = r.session_id
    CROSS APPLY sys.dm_exec_sql_text (r.sql_handle) t
    --CROSS APPLY sys.dm_exec_query_plan (r.plan_handle) 
  WHERE r.session_id > 50 AND r.session_id <> @@spid
    AND s.[program_name] NOT LIKE 'SQL Server Profiler%'
    --AND db_name(r.database_id) NOT LIKE N'distribution'
    --AND r.wait_type IN ('SQLTRACE_LOCK', 'IO_COMPLETION', 'TRACEWRITE')
  ORDER BY s.CPU DESC;
END;
GO

В отличие от хранимой процедуры sp_helpindex2, выбирающей информацию, связанную с контекстом текущей БД, sp_locks выбирает информацию уровня сервера, и поэтому она не должна быть помечена как системная хранимая процедура. Однако использование префикса sp_ позволяется воспользоваться тем, что SQL Server сперва ищет все объекты с таким префиксом в БД master. Это дает возможность вызвать процедуру из любой БД, не используя имя из трех частей (например, database.schema.object), что удобно.

Процедура возвращает до трех наборов результатов, что регулируется входным параметром @Mode.

Первый набор результатов возвращает информацию о Lead Blocker-процессе, если таковой существует, и нужен в ситуациях наличия высокой активности блокировок, приводящей к появлению цепочек блокировок.

Цепочка блокировок — это ситуация, когда есть много процессов, блокирующих другие процессы, которые, в свою очередь, блокируют данные или другие процессы. Во многих случаях это требует ручного вмешательства для разрешения конфликта, обычно это вмешательство принимает форму команды, завершающей исполнение процесса, выступающего в роли Lead Blocker.

Lead Blocker — это кличка для процесса, являющегося главной причиной, инициатором, с которого начинается цепочка блокировок — то есть этот процесс блокирует другой процесс, который, в свою очередь, будучи заблокированным, не может снять наложенные им блокировки, и тем самым сам становится блокирующим процессом. Это может продолжаться и продолжаться, вовлекая другие процессы, и порождая цепочки блокировок.

В таком сценарии страдает параллелизм работы с БД, и это, конечно, отражается на времени отклика приложений. Так что на момент, когда вы узнаете о наличии такой ситуации, вы, конечно, хотите как можно быстрее справиться с ней, чтобы минимизировать ее влияние на систему.

Этот набор результатов чаще всего содержит одну строку, но в сценарии эскалации блокировок вы можете увидеть и несколько строк (что означает, что имеется несколько блокирующих процессов и несколько цепочек блокировок).

На рисунке 1, где показано исполнение тестового сценария, блокирующим является процесс, выдавший команду UPDATE (spid 218). Этот процесс блокирует первый процесс, (spid 193), выдающий команду SELECT (/* connection 1 */), и любой последующий SELECT блокируется этим первым выражением SELECT.

Завершение подключения, выдавшего команду UPDATE, позволит всем блокированным (ожидающим) процессам продолжить работу и разрушит цепочку блокировок.

Заметьте, что если прервать любой другой процесс, сценарий эскалации блокировок не будет прерван и цепочка блокировок сохранится.

Второй набор результатов содержит информацию о блокирующих и блокированных процессах, обращаясь к трем ключевым DMV: sys.dm_os_waiting_tasks, sys.dm_­tran_locks и sys.sysprocesses.

Мы выполняем запрос sys.dm_os_waiting_tasks, поскольку именно это нас и интересует — задачи (процессы), находящиеся в состоянии ожидания, в данном случае — ожидающие возможности получить блокировку ресурсов. Приятно то, что это DMV можно соединить с sys.dm_tran_locks по колонке resource_address, которая содержит адрес в памяти ресурса, которого ожидает задача, а с другой стороны условия объединения имеется колонка lock_owner_address из sys.dm_tran_locks, являющаяся адресом в памяти внутренней структуры данных, используемой для отслеживания запросов на блокировки модулем LOCK_MANAGER SQL Server-а.

Эти два DMV дают ценную информацию о блокировках. Далее мы добавляем sys.sysprocesses, чтобы получить информацию более высокого уровня, о блокировках программ и хостов. Чтобы получить информацию о блокирующих и заблокированных процессах, мы дважды выполняем соединение с sys.sysprocesses — один экземпляр для блокирующих, а другой — для заблокированных процессов.

Это достигается соединением одного экземпляра sys.sysprocesses как p1 с sys.dm_os_waiting_tasks по колонке session_id, и второго экземпляра как p2 по колонке blocking_session_id из sys.dm_os_waiting_tasks.

Входной параметр @Wait_Duration_ms позволяет ограничить число выводимых строк теми процессами, чье время ожидание превышает число (время в миллисекундах), указанное в этом параметре. Это очень полезно, поскольку обычно вас не интересуют краткосрочные (в 2-3 секунды) ожидания (блокировки), не оказывающие отрицательного влияния на систему.

Третий набор результатов содержит информацию из sys.dm_exec_requests об активно исполняемых процессах. Этот набор результатов может быть полезным, когда нет активных блокировок, и первые два набора не содержат никаких строк, но вам все-таки нужно увидеть, что исполняется в данное время на сервере.

Листинг 2. Использование sp_lock

-- Возвратить только второй набор результатов
EXEC sp_Locks @Mode = 1, @Wait_Duration_ms = 1000;
-- Возвратить первый и второй наборы результатов
EXEC sp_Locks @Mode = 2, @Wait_Duration_ms = 1000;
-- Возвратить все три набора результатов
EXEC sp_Locks @Mode = 3, @Wait_Duration_ms = 1000;

Помещение информации о блокировках в таблицу

Чтобы сохранить информацию о блокировках в таблицу, используйте скрипт Capture_blocking_info.sql, который использует выражение INSERT…EXEC с sp_locks в @Mode = 2.

Листинг 3. Скрипт Capture_blocking_info.sql

/*

  Сохранение информации о блокировках в таблицу
  
  19/04/2008 Yaniv Etrogi   
  http://www.sqlserverutilities.com  

*/    
USE [tempdb];
SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON;


IF  EXISTS (
  SELECT * 
    FROM sys.objects 
    WHERE object_id = OBJECT_ID(N'[dbo].[Blocks]') 
    AND type in (N'U'))
  DROP TABLE [dbo].[Blocks];
GO

CREATE TABLE [dbo].[Blocks](
  [Id] [int] identity(1,1) NOT NULL CONSTRAINT 
  [PK_Blocks] PRIMARY KEY NONCLUSTERED ([Id]),
  [InsertTime] datetime CONSTRAINT 
  [DF_Blocks_InsertTime] DEFAULT (getdate()) NOT NULL,
  [blocking] smallint NULL,
  [blocked] smallint NULL,
  [program_blocking] varchar(128) NULL,
  [program_blocked] varchar(128) NULL,
  [database] varchar(128) NULL,
  [host_blocking] varchar(128) NOT NULL,
  [host_blocked] varchar(128) NOT NULL,
  [wait_duration_ms] bigint NULL,
  [request_mode] varchar(60) NOT NULL,
  [resource_type] varchar(60) NOT NULL,
  [wait_type] varchar(60) NULL,
  [statement_blocked] varchar(max) NULL,
  [statement_blocking] varchar(max) NULL );
GO

CREATE CLUSTERED INDEX IXC_Blocks_InsertTime ON dbo.Blocks (InsertTime);

-- Бесконечный цикл до ручного прекращения исполнения 
-- или изменения условия WHEN
SET NOCOUNT ON;
DECLARE @i int; SELECT @i = 0;

WHILE (@i < 1000000)
BEGIN;
INSERT INTO [dbo].[Blocks]
           ([blocking],
            [blocked],
            [program_blocking],
            [program_blocked],
            [database],
            [host_blocking],
            [host_blocked],
            [wait_duration_ms],
            [request_mode],
            [resource_type],
            [wait_type],
            [statement_blocked],
            [statement_blocking])
EXEC sp_Locks @Wait_Duration_ms = 1000, @Mode = 1;

SELECT @i = @i + 1;
IF @i % 100 = 0 PRINT @i;  --print every 100 iterations 
WAITFOR DELAY '00:00:10';  --10 seconds sleep
END;

-- Выборка полученных данных о блокировках.
SET NOCOUNT ON; 
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT TOP 100
       [Id],
       [InsertTime], 
       [blocking],
       [blocked],
       LEFT([program_blocking], 20) AS [program_blocking],
       LEFT([program_blocked], 20)  AS [program_blocked],
       [database],
       [host_blocking],
       [host_blocked],
       [wait_duration_ms],
       [request_mode],
       [resource_type],
       [wait_type],
       [statement_blocked],
       [statement_blocking]
FROM  [dbo].[Blocks]
ORDER BY [InsertTime] DESC;

Внутри блокировок

Чтобы получить представление о блокирующих и заблокированных процессах, возвращаемых sp_locks, можно использовать следующий скрипт, детализирующий причины блокировки.

Я использую его при поиске и воспроизведении сценария блокировки. Фильтрация по spid позволяет мне видеть только нужные мне данные и получить картину выделенных ресурсов и состояния их блокировок.

SET NOCOUNT ON; 
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
SELECT --TOP 100
  l.request_session_id AS spid,
  DB_NAME(l.resource_database_id) AS [database],
  CASE WHEN l.resource_type = 'OBJECT' 
    THEN OBJECT_NAME(l.resource_associated_entity_id, l.resource_database_id)
  WHEN l.resource_associated_entity_id = 0 
    THEN 'NA' 
    ELSE OBJECT_NAME(p.object_id, l.resource_database_id) END AS [object],
      p.index_id,
      l.resource_type        AS [resource],
      l.resource_description AS [description],
      l.request_mode         AS [mode],
      l.request_status       AS [status],
      l.resource_associated_entity_id
FROM sys.dm_tran_locks l 
LEFT JOIN sys.partitions p ON p.hobt_id = l.resource_associated_entity_id
WHERE resource_type NOT LIKE 'DATABASE'
--AND l.request_session_id = @@SPID -- <---- edit spid here
--AND DB_NAME(l.resource_database_id) NOT LIKE 'distribution'

При исполнении скрипта для тестового сценария при фильтрации по имени БД я вижу все вовлеченные процессы. Это четко показывает, что блокирующий процесс, spid 218, удерживает эксклюзивную (Х) блокировку ключа индекса (кластерного индекса в данном случае), и что это блокировка обновляемой строки. Эксклюзивная блокировка строки должна быть также помечена на уровне страницы, что и делается с помощью Intense Exclusive (IX) блокировки. Можно видеть, что это страница 154 в файле данных с номером 1. IX-блокировка страницы должна быть распространена до уровня таблицы, что и делается с помощью IX-блокировки этого объекта.

Листинг 4. Тестовый сценарий

USE [master];
SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON;

IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'TEST')
  CREATE DATABASE TEST;
GO

USE [TEST];
IF EXISTS (
  SELECT * FROM sys.objects 
    WHERE object_id = OBJECT_ID(N'[dbo].[T1]') 
    AND type in (N'U'))
  DROP TABLE [dbo].[T1];
GO

USE [TEST];
IF EXISTS (
  SELECT * FROM sys.objects 
    WHERE object_id = OBJECT_ID(N'[dbo].[T1]') 
    AND type in (N'U'))
  DROP TABLE [dbo].[T1];
GO

CREATE TABLE [dbo].[T1]
(
  [c1] [int] IDENTITY(1,1) NOT NULL,
  [c2] [int] NOT NULL, PRIMARY KEY CLUSTERED([c1] ) 
);


INSERT T1 (c2) VALUES (10);
INSERT T1 (c2) VALUES (20);
INSERT T1 (c2) VALUES (30);
INSERT T1 (c2) VALUES (40);
INSERT T1 (c2) VALUES (50);
INSERT T1 (c2) VALUES (60);
/* Blocker */
-- Выполняет UPDATE и оставляет транзакцию открытой, так что эксклюзивная (X) 
-- блокировка, получаемая процессом, не освобождается. 
USE [TEST];
BEGIN TRAN; UPDATE T1 SET c2 = 100 WHERE c1 = 5;
--ROLLBACK

/* Blocked */
USE [TEST]; SELECT * FROM TEST..T1 /* connection 1 */ ;
USE [TEST]; SELECT * FROM TEST..T1 /* connection 2 */ ;
USE [TEST]; SELECT * FROM TEST..T1 /* connection 3 */ ;
USE [TEST]; SELECT * FROM TEST..T1 /* connection 4 */ ;
USE [TEST]; SELECT * FROM TEST..T1 /* connection 5 */ ;

Все остальные процессы, пытающиеся читать данные, имеют статус WAIT и ожидают освобождения ресурса, заблокированного выражением UPDATE.

Права

DMV (Dynamic Management Views) и DMF (Dynamic Management Function), используемые хранимой процедурой, требуют, чтобы вызывающая их сторона имела права VIEW SERVER STATE и, конечно, право на запуск процедур из БД master (EXECUTE).

/*
USE [master];
GRANT VIEW SERVER STATE TO Paul;
GRANT EXECUTE ON sp_locks TO Paul;
*/

(c) www.k-press.ru

2014   sql   windows

Экспорт и импорт сайтов и пулов приложений из/в IIS

When using multiple IIS server in a Load Balanced Environment it will be alot of work to create all your website twice with the same settings on each webserver. Therefor it is possible to export and import your configuration from one webserver to the other. This will also be usefull when your upgrading from IIS 7 (Windows Server 2008) to IIS 7.5 (Windows Server 2008 R2).

When you create a website in IIS 7 or 7.5 a unique application pool will also be created and used by this website, that’s why you need to import these application pools first on the second webserver before importing the website(s).

To Export the Application Pools on IIS 7:

%windir%\system32\inetsrv\appcmd list apppool /config /xml > c:\apppools.xml

This will export all the application pools on your webserver, therefor you need to edit the apppools.xml and remove the application that you do not need to import for example:

  • DefaultAppPool
  • Classic .NET AppPool
  • SecurityTokenServiceApplicationPool

And other apppools that already exist on the second webserver, appcmd doesn’t skip already existing apppools, it just quit’s and doesn’t import any.

To import the Application Pools:

%windir%\system32\inetsrv\appcmd add apppool /in < c:\apppools.xml

All the AppPools in the xml will be created on your second webserver.

To Export all your website:

%windir%\system32\inetsrv\appcmd list site /config /xml > c:\sites.xml

This will export all the websites on your webserver, therefor you need to edit the sites.xml and remove the websites that you do not need to import for example:

  • Default Website

And all other websites that already exist on the second webserver.

To Import the website:

%windir%\system32\inetsrv\appcmd add site /in < c:\sites.xml

It’s also possible to export a single website or application pool all you need to do is add the name of the Application Pool or Website to the command line:

To export/import a single application pool:

%windir%\system32\inetsrv\appcmd list apppool “MyAppPool” /config /xml > c:\myapppool.xml

Import:

%windir%\system32\inetsrv\appcmd add apppool /in < c:\myapppool.xml

To export/import a single website:

%windir%\system32\inetsrv\appcmd list site “MyWebsite” /config /xml > c:\mywebsite.xml

Import:

%windir%\system32\inetsrv\appcmd add site /in < c:\mywebsite.xml

(c) microsoftpro.nl

2014   iis   web   windows

Два провайдера и распределение по каналам

После добавления в нашу тестовую конфигурацию второго провайдера появилась проблема ответа определенных сервисов по нужному каналу, если обращаться к ним из вне через NAT.

На пример веб сервер, выведенный через NAT на IP адрес первого провайдера получает запрос, а вот вероятность того, что ответ пойдет по нужному каналу уже не 100%. Какой же он после этого веб сервер?

Решить эту проблему нам поможет механизм маркировки пакетов.

Таблица MANGLE предназначена для операций по классификации и маркировке пакетов и соединений, а также модификации заголовков пакетов. В частности нас интересует цепочка PREROUTING, которая позволяет маркировать пакет до маршрутизации.

Попробуем разобраться с веб сервером.

Допустим у нас настроен NAT 80 порта с внешнего IP 192.168.1.116 (ISP1, первый провайдер) на 80 порт веб сервера в локальной сети и необходимо гарантировать, что все ответы, которые буду идти от веб сервера попадали на шлюз первого провайдера.

Вот правило для таблицы NAT.

[mkt@MikroTik] > ip firewall nat add chain=dstnat dst-address=192.168.1.116
protocol=tcp dst-port=80 action=dst-nat to-addresses=192.168.0.2 to-ports=80
comment="NAT 80 port from ISP1 to local web server"

[mkt@MikroTik] > ip firewall nat print
Flags: X - disabled, I - invalid, D - dynamic
0   chain=srcnat action=masquerade out-interface=!LOCAL

1   ;;; NAT 80 port from ISP1 to local web server
chain=dstnat action=dst-nat to-addresses=192.168.0.2 to-ports=80
protocol=tcp dst-address=192.168.1.116 dst-port=80

Первым шагом создадим правило в таблице MANGLE.

[mkt@MikroTik] > ip firewall mangle add chain=prerouting  src-address=192.168.0.2
protocol=tcp src-port=80 action=mark-routing new-routing-mark=to-isp1

[mkt@MikroTik] > ip firewall mangle print
Flags: X - disabled, I - invalid, D - dynamic
0   chain=prerouting action=add-src-to-address-list protocol=tcp
address-list=test_list address-list-timeout=0s dst-port=23

1   chain=prerouting action=mark-routing new-routing-mark=to-isp1
passthrough=yes protocol=tcp src-address=192.168.0.2 src-port=80

Пакеты с локального адреса 192.168.0.2 с 80 порта буду маркироваться как to-isp1.

Вторым шагом добавим правило в таблицу маршрутизации.

[mkt@MikroTik] > ip route add gateway=192.168.1.249 routing-mark=to-isp1

[mkt@MikroTik] > ip route print      
Flags: X - disabled, A - active, D - dynamic,
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme,
B - blackhole, U - unreachable, P - prohibit
#      DST-ADDRESS        PREF-SRC        GATEWAY            DISTANCE
0 A S  0.0.0.0/0                          192.168.1.249 r... 1
1 A S  0.0.0.0/0                          192.168.1.249 r... 1
                                        192.168.1.249 r...
                                        192.168.222.1 r...
2 ADC  192.168.0.0/24     192.168.0.1     LOCAL              0
3 ADC  192.168.1.0/24     192.168.1.116   ISP1               0
4 ADC  192.168.222.0/24   192.168.222.100 ISP2               0

Все что приходит с маркером to-isp1 отправляется на шлюз первого провайдера.

Теперь усложним ситуацию, допустим второй провайдер предоставят на выгодных условиях большую локальную сеть по всему городу и через эту сеть объединены все 10 филиалов вашей фирмы. Все филиалы и офис пользуются тем же сайтом, но какой смысл ходить на него через первого провайдера, когда можно настроить доступ к нему практически локально.

В первую очередь добавляем правило в таблицу NAT, по которому все запросы, пришедшие на внешний IP адрес, который предоставляет 2-ой провайдер, на 80 порт будут переадресовываться на 80 порт локального веб сервера.

[mkt@MikroTik] > ip firewall nat add chain=dstnat dst-address=192.168.222.100
protocol=tcp dst-port=80 action=dst-nat to-addresses=192.168.0.2 to-ports=80
comment="NAT 80 port from ISP2 to local web server"

[mkt@MikroTik] > ip firewall nat print
Flags: X - disabled, I - invalid, D - dynamic
0   chain=srcnat action=masquerade out-interface=!LOCAL

1   ;;; NAT 80 port from ISP1 to local web server
chain=dstnat action=dst-nat to-addresses=192.168.0.2 to-ports=80
protocol=tcp dst-address=192.168.1.116 dst-port=80

2   ;;; NAT 80 port from ISP2 to local web server
chain=dstnat action=dst-nat to-addresses=192.168.0.2 to-ports=80
protocol=tcp dst-address=192.168.222.100 dst-port=80

Следующим шагом добавим в таблицу MANGLE еще одно правило:

[mkt@MikroTik] > ip firewall mangle add chain=prerouting src-address=192.168.0.2
protocol=tcp src-port=80 dst-address=192.168.222.0/24 action=mark-routing
new-routing-mark=to-isp2

[mkt@MikroTik] > ip firewall mangle print
Flags: X - disabled, I - invalid, D - dynamic
0   chain=prerouting action=add-src-to-address-list protocol=tcp
address-list=test_list address-list-timeout=0s dst-port=23

1   chain=prerouting action=mark-routing new-routing-mark=to-isp2
passthrough=yes protocol=tcp src-address=192.168.0.2
dst-address=192.168.222.0/24 src-port=80

2   chain=prerouting action=mark-routing new-routing-mark=to-isp1
passthrough=yes protocol=tcp src-address=192.168.0.2 src-port=80

Пакеты с локального адреса 192.168.0.2 с 80 порта буду маркироваться как to-isp2 если они предназначены для подсети второго провайдера.

Ну и в заключении правило в таблице маршрутизации:

[mkt@MikroTik] > ip route add gateway=192.168.222.1 routing-mark=to-isp2
                                                              
[mkt@MikroTik] > ip route print      
Flags: X - disabled, A - active, D - dynamic,
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme,
B - blackhole, U - unreachable, P - prohibit
#      DST-ADDRESS        PREF-SRC        GATEWAY            DISTANCE
0 A S  0.0.0.0/0                          192.168.1.249 r... 1
1 A S  0.0.0.0/0                          192.168.222.1 r... 1
2 A S  0.0.0.0/0                          192.168.1.249 r... 1
                                        192.168.1.249 r...
                                        192.168.222.1 r...
3 ADC  192.168.0.0/24     192.168.0.1     LOCAL              0
4 ADC  192.168.1.0/24     192.168.1.116   ISP1               0
5 ADC  192.168.222.0/24   192.168.222.100 ISP2               0

Теперь на запросы, пришедшие со стороны первого провайдера, ответ пойдет на шлюз первого провайдера, а на запросы со стороны второго провайдера и из подсети второго провайдера ответ пойдет на шлюз второго провайдера.

(c) slagovskiy.blogspot.ru

2014   mikrotik   network

Два провайдера и балансировка нагрузки

В последнее время ситуация, когда доступны несколько провайдеров не нова, MikroTik Router OS позволяет настроить доступ сразу по нескольким сетевым интерфейсам, а так же настроить балансировку нагрузки в зависимости от ограничений, которые выставляет провайдер.

Первым шагом настроим дополнительный интерфейс.
Инициализируем сам интерфейс.

[mkt@MikroTik] /interface> print
Flags: D - dynamic, X - disabled, R - running, S - slave
#     NAME                      TYPE             MTU
0  R  ether1                    ether            1500
1  R  ether2                    ether            1500
2  X  ether3                    ether            1500

[mkt@MikroTik] /interface> enable 2

[mkt@MikroTik] /interface> print
Flags: D - dynamic, X - disabled, R - running, S - slave
#     NAME                      TYPE             MTU
0  R  ether1                    ether            1500
1  R  ether2                    ether            1500
2  R  ether3                    ether            1500

Для удобства все же пора дать более понятные имена интерфейсам.

[mkt@MikroTik] /interface> set ether1 name="ISP1"

[mkt@MikroTik] /interface> set ether2 name="LOCAL"

[mkt@MikroTik] /interface> set ether3 name="ISP2"

[mkt@MikroTik] /interface> print
Flags: D - dynamic, X - disabled, R - running, S - slave
#     NAME                       TYPE             MTU
0  R  ISP1                       ether            1500
1  R  LOCAL                      ether            1500
2  R  ISP2                       ether            1500

Теперь назначим IP адрес новому интерфейсу.

[mkt@MikroTik] > ip address add address=192.168.222.100/24 interface=ISP2

[mkt@MikroTik] > ip address print
Flags: X - disabled, I - invalid, D - dynamic
#   ADDRESS            NETWORK         BROADCAST       INTERFACE
0   192.168.1.116/24   192.168.1.0     192.168.1.255   ISP1
1   192.168.0.1/24     192.168.0.0     192.168.0.255   LOCAL
2   192.168.222.100/24 192.168.222.0   192.168.222.255 ISP2

Настало время изменить маршрутизацию по умолчанию. Для начала допустим, что оба провайдера предоставляют одинаковую скорость доступа к сети Internet, значит настроим балансировку (это когда для исходящих соединений каналы чередуются), так что бы запросы распеределялись равномерно, т. е. 50/50. Прежде всего удалим старый шлюз по умолчанию.

[mkt@MikroTik] > ip route print
Flags: X - disabled, A - active, D - dynamic,
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme,
B - blackhole, U - unreachable, P - prohibit
#      DST-ADDRESS        PREF-SRC        GATEWAY            DISTANCE
0 A S  0.0.0.0/0                          192.168.1.249 r... 1
1 ADC  192.168.0.0/24     192.168.0.1     LOCAL              0
2 ADC  192.168.1.0/24     192.168.1.116   ISP1               0
3 ADC  192.168.222.0/24   192.168.222.100 ISP2               0

[mkt@MikroTik] > ip route remove 0

[mkt@MikroTik] > ip route print
Flags: X - disabled, A - active, D - dynamic,
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme,
B - blackhole, U - unreachable, P - prohibit
#      DST-ADDRESS        PREF-SRC        GATEWAY            DISTANCE
0 ADC  192.168.0.0/24     192.168.0.1     LOCAL              0
1 ADC  192.168.1.0/24     192.168.1.116   ISP1               0
2 ADC  192.168.222.0/24   192.168.222.100 ISP2               0

И добавим новый, точнее новые.

[mkt@MikroTik] > ip route add dst-address=0.0.0.0/0
gateway=192.168.1.249,192.168.222.1

[mkt@MikroTik] > ip route print                                    
Flags: X - disabled, A - active, D - dynamic,
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme,
B - blackhole, U - unreachable, P - prohibit
#      DST-ADDRESS        PREF-SRC        GATEWAY            DISTANCE
0 A S  0.0.0.0/0                          192.168.1.249 r... 1
                                       192.168.222.1 r...
1 ADC  192.168.0.0/24     192.168.0.1     LOCAL              0
2 ADC  192.168.1.0/24     192.168.1.116   ISP1               0
3 ADC  192.168.222.0/24   192.168.222.100 ISP2               0

Предположим, что у первого провайдера скорость доступа в два раза выше чем у второго, тогда 2/3 исходящих запросов надо направить на первого, а оставшиеся 1/3 на второго.

[mkt@MikroTik] > ip route add dst-address=0.0.0.0/0
gateway=192.168.1.249,192.168.1.249,192.168.222.1

[mkt@MikroTik] > ip route print                                    
Flags: X - disabled, A - active, D - dynamic,
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme,
B - blackhole, U - unreachable, P - prohibit
#      DST-ADDRESS        PREF-SRC        GATEWAY            DISTANCE
0 A S  0.0.0.0/0                          192.168.222.1 r... 1
                                       192.168.1.249 r...
                                       192.168.1.249 r...
1 ADC  192.168.0.0/24     192.168.0.1     LOCAL              0
2 ADC  192.168.1.0/24     192.168.1.116   ISP1               0
3 ADC  192.168.222.0/24   192.168.222.100 ISP2               0

Это простейший вариант настройки, при котором получаем выход в интернет с балансировкой нагрузки, но у такого подхода есть ряд недостатков, на пример не будет работать доступ через на NAT к локальному серверу (сервисы web, smtp, pop, которые были настроены ранее), но не такая большая проблема, но об этом в следующий раз.

(c) slagovskiy.blogspot.ru

2014   mikrotik   network

Настройка Firewall на Mikrotik

Межсетевой экран, брендмауэр или Firewall выполняет фильтрацию пакетов являясь таким образом инструментом обеспечивающим безопасность и управление потоками данных, проходящими через маршрутизатор. Вместе с трансляцией сетевых адресов NAT файервол служит инструментом предотвращения несанкционированного проникновения в сеть компании. Возможно и наоборот применением фильтрации пакетов совместно с транспарентными Proxy серверами и NAT добиться запрета на использование определённых ресурсов и внешних сетей. Полезно Firewall использовать для ограничения доступа к заведомо незащищенным службам. Он может служить препятствием для внедрения ложных данных с помощью уязвимых служб злоумышленником. Также через него возможен контроль доступа к узлам сети, регистрирование попыток доступа как извне, так и из внутренней сети. Можно регламентировать порядок доступа к сети, осуществлять уведомление о подозрительной деятельности, попытках зондирования или атаки на узлы сети или сам экран.

Файервол Mikrotik RouterOS обладает мощными функциями и включает следующие возможности:
1 Фильтрация пакетов;
2 Фильтрация p2p протоколов
3 Классификация трафика по:
3.1 исходный MAC-адрес;
3.2 IP-адрес (сеть или список) и тип адреса (бродкаст, локальный, мультикаст, юникаст);
3.3 Порт или список портов;
3.4 IP-протокол;
3.5 Опции протокола (ICMP тип и другие коды, TCP флаги, IP опции и MSS);
3.6 Интерфейс, откуда получен пакет или куда он назначается;
3.7 Внутренний поток или маркированное подключение;
3.8 Байт ToS (DSCP);
3.9 Содержимое пакета;
3.10 Скорость получения пакетов и количество последовательностей;
3.11 Размер пакета;
3.12 Время получения пакета.

Основные принципы фильтрации

Оперирование файерволом осуществляется посредством правил. Правило определяет выражение, которое говорит роутеру что делать с индивидуальным IP-пакетом. Каждое правило состоит из двух частей: первое описывает параметры, по которым должны классифицироваться приходящие пакеты, второе отвечает за действие над пакетом. Правила, для лучшего управления, организованы в цепочки.
Устройство фильтра по-умолчанию имеет три цепочки: input, forward и output, которые отвечают за приходяший, перемещаемый внутри роутера и исходящий трафик соответственно. Пользователь может добавить новые цепочки, если это будет нужно.
Под эти цепочки трафик по-умолчанию не попадает. Для этого используется метод action=jump с параметром jump-target в одной из предустановленных цепочек.

Цепочки фильтра

Как говорилось раньше, правила фильтрации в файерволе сгруппированы в цепочки. Это позволяет пакету попавшему под некий критерий в одной цепочке переходить к следующему правилу и следующим цепочкам. К примеру пакетам с определённого адреса и порта нужно применить много правил. Конечно, эти правила можно перечислить в цепочке forward, однако правильнее будет создать для них отдельную цепочку, перебросить туда попавшие под условие пакеты и выполнить над ними нужные нам действия: /ip firewall filter add src-address=1.1.1.2/32 jump-target=«mychain». Это правило создаст новую цепочку mychain, в которую попадут все пакеты с адресом источника 1.1.1.2/32.

Три предустановленных цепочки, которые не могут быть удалены:
Input — применимо к пакетам, приходящим на маршрутизатор, у которых адрес получателя такой же, как и у интерфейса, на который этот пакет поступил. Пакеты, проходящие через маршрутизатор не попадают под действие правил цепочки input.
Forward — применимо к пакетам, проходящим через маршрутизатор;
Output — применимо к пакетам созданным маршратизатором, которые покидают его через один из интерфейсов. Пакеты, проходящие через маршрутизатор не попадают под действие цепочки output.
При попадании пакета в одну из цепочек, правила применяются от верхего к нижнему. Если пакет попадает под критерий одного из правил, над ним выполняется указанное в правиле действие и этот пакет не попадает больше под действие других правил из этой цепочки (исключение составляет только действие passthrough). Если пакет не попадает под действие ни одного из правил цепочки, к нему по умолчанию применяется действие Accept.

Описание параметров

action (accept | add-dst-to-address-list | add-src-to-address-list | drop | jump | log | passthrough | reject | return | tarpit; default: accept) — применяемое действие, если пакет совпал с правилом
accept — принять пакет. Не подразумевает каких-либо действий. Если пакет был принят, к нему больше не применяется никаких действий в цепочке.
add-dst-to-address-list — добавить адрес назначения пакета в address list , указанный в параметре address-list
add-src-to-address-list — добавить адрес источника пакета в address list , указанный в параметре address-list
drop — разрушить пакет (без посылки сообщения ICMP reject)
jump — перепрыгнуть в цепочку, указанную в параметре jump-target
log — каждое совпадение с этим действием добавит в системный лог сообщение
passthrough — игнорировать это правило и перейти к следующему
reject —отбросить этот пакет и постать сообщение ICMP reject
return — вернуть пакет в цепочку, из которой он был переброшен
tarpit — захватить и удерживать входящие TCP подключения (отвечать SYN/ACK на входящий TCP SYN пакет)
address-list (name) — указывает имя списка адресов, в которых хранятся IP-адреса из действий action=add-dst-to-address-list или action=add-src-to-address-list. Эти списки могут быть похже использованы в других правилах.
address-list-timeout (time; default: 00:00:00) — интервал времени, через который адреса будут удалены из списка, указанного в параметре address-list . Используется в сочетании с действиями add-dst-to-address-list или add-src-to-address-list .00:00:00 — означает оставить адреса в списке навсегда.
chain (forward | input | output | name) — указывает цепочку, в которую следует поместить правило. Разные типы трафика проходят через разные цепочки, поэтому будьте в курсе своего выбора, указывая то или иное значение этого параметра. Если указанное значение цепочки не совпадает ни с одним из уже существующих, система создаст новое правило с указанным именем.
comment (text) — комментарий описывает правило. В скриптах комментарии обычно служат для идентификации правил.
connection-bytes (integer-integer) — применять правило, если количество переданных байт через подключение превысило указанное значение. 0 — не ограничено, пример: connection-bytes=2000000-0 сработает в том случае, если количество данных, переданных через открытое подключение превысило 2MB;
connection-limit (integer,netmask) — ограничивает количество доступных подключений на адрес или блок адресов;
connection-mark (name) —пакеты, попавшие под действие правил в mangle и названные в соответствии с параметром connection mark
connection-state (established | invalid | new | related) — интерпретация состояния подключения посредством анализа данных из connection tracking .
established — пакет, принадлежащийa уже установленному подключению. К примеру ответ от маршрутизатора.
invalid — пакет, который не может быть идентифицирован по какой-либо причине. К примеру это может быть переполнение памяти и ICMP ошибки. К таким пакетам нужно применять действие DROP
new — пакет, начинающий создание TCP подключения
related — запрошенный пакет, который не принадлежит уже установленным подключениям. К примеру ICMP ошибки, или пакет, начинающий передачу данных по протоколу FTP( /ip firewall service-port)
connection-type (ftp | gre | h323 | irc | mms | pptp | quake3 | tftp) — определение типа подключения, базирующееся на использовании данных из connection tracking. Конфигурирование производится в /ip firewall service-port
content (text) — содержимое текстового пакета
dst-address (IP address/netmask | IP address-IP address) — указывает диапазон адресов, у которых IP-адрес назначения совпадает с параметром. При неправильном введении пары address/netmask система сама подстроит эти параметры. К примеру:1.1.1.1/24 будет заменено на 1.1.1.0/24
dst-address-list (name) — совпадение адреса назначения пакета с определенными ранее значениями в address list
dst-address-type (unicast | local | broadcast | multicast) — совпадение типа адреса назначения пакета с заданным предустановленным значением:
unicast — IP-адреса, используемые ля передачи от одной точки к другой. В таком типе пакетов существует только один отправитель и один получатель
local — совпадеине с адресами, назначенными сетевым интерфейсам маршрутизатора
broadcast — IP-пакет, посылаемый сразу всем членам подсети
multicast — этот тип пакета используется для передачи данных от одного отправителя многим получателям в сети.
dst-limit (integer/time{0,1},integer,dst-address | dst-port | src-address{+},time{0,1}) — ограничивает скорость пакетов в секунду (packet per second (pps)) на IP-адрес или порт.
В результате работы правила каждый IP-адрес или порт назначения получает свой лимит.
Параметр имеет следующие опции:
Count — среднее количество пакетов в секунду (packets per second (pps))за время Time
Time — интервал времени, за который производится подсчёт среднего количества пакетов
Burst — количество пакетов в пике
Mode — классификатор для ограничения скорости пакетов
Expire — указывает интервал, через который записанные IP адреса /порты будут удалены
dst-port (integer: 0..65535-integer: 0..65535{*}) — интервал портов назначения
hotspot (multiple choice: from-client | auth | local-dst | http) — сравнивает пакеты полученные от клиентов с различными хот-спотами. все значения могут быть отклонены/инвертированы
from-client — true, если пакеты получены от Hot-Spot клиента
auth — true, если пакеты получены от авторизированного Hot-Spot клиента
local-dst — true, если пакет имеет локальный адрес назначения
hotspot — true, если TCP пакет от клиента и назначается на 80 порт прозрачного прокси сервера или клиент имеет адрес прокси сконфигурированный и аналогичный адресу:порту пакета
icmp-options (integer:integer) — совпадение полей ICMP Type:Code
in-interface (name) — интерфейс, с которого пакет поступил в маршратизатор
ipv4-options (any | loose-source-routing | no-record-route | no-router-alert | no-source-routing | no-timestamp | none | record-route | router-alert | strict-source-routing | timestamp) — совпадение параметров заголовка ipv4
any — совпадает по крайней мере один пакет с установленной ipv4 опцией
loose-source-routing — пакеты с опцией loose source routing. Эта опция используется для направления интернет дейтаграм основаных на информации поставляемой источником
no-record-route — пакеты с опцией no record route. Эта опция используется для направления интернет дейтаграм основаных на информации поставляемой источником
no-router-alert — совпадение пакетов с опцией no router alter
no-source-routing — совпадение пакетов с опцией no source routing
no-timestamp — совпадение пакетов с опцией with no timestamp
record-route — совпадение пакетов с опцией record route
router-alert — совпадение пакетов с опцией router alter
strict-source-routing — совпадение пакетов с опцией strict source routing
timestamp — совпадение пакетов со штампом времени
jump-target (forward | input | output | name) — имя целевой цепочки куда должен быть отправлен пакет при использовании action=jump.
limit (integer/time{0,1},integer) — ограничивает поток пакетов. Используется для уменьшения количества сообщений в логах
Count — максимальное среднее количество пакетов, указанное в пакетах в секунду (PPS Packet Per Second) за время в опции Time
Time — указывает интервал времени за который будет производиться подсчёт среднего количества пакетов
Burst — количество пакетов при пике
log-prefix (text) — все сообщения, записываемые в лог, будут иметь этот префикс. Используется вместе с опцией action=log
nth (integer,integer: 0..15,integer{0,1}) — совпадение каждого n-ного пакета, попавшего в правило. Всего доступно 16 счётчиков
Every — совпадение каждого Every+1th пакета. К примеру, если Every=1 тогда под действие правила попадёт каждый второй пакет
Counter — указывает какой счётчик будет использоваться. Счётчик увеличивается на 1 с каждым новым правилом где указанна опция nth
Packet -совпадает с номером данного пакета. Значение по очевидным причинам должно быть между нулем и Every. Если опиция используется для данного счетчика, тогда должно быть по крайней мере Every+1 правило с этой опцией, охватывающее все значения между 0 и Every включительно out-interface (name) — интерфейс, через который пакеты будут покидать маршрутизатор
p2p (all-p2p | bit-torrent | blubster | direct-connect | edonkey | fasttrack | gnutella | soulseek | warez | winmx) — совпадение пакетов протоколов peer-to-peer (P2P)
packet-mark (text) — цепочка пакетов, промаркированная в разделе mangle файервола
packet-size (integer: 0..65535-integer: 0..65535{0,1}) — размер пакета в байтах
Min — указывает нижний предел диапазона размера пакета
Max — указывает верхний предел диапазона размера пакета

phys-in-interface (name) — физический интерфейс, указанный в качестве порта моста, по которому пакет поступил в маршрутизатор
phys-out-interface (name) — физический интерфейс, указанный в качестве порта моста, по которому пакет выйдет из маршрутизатора
protocol (ddp | egp | encap | ggp | gre | hmp | icmp | idrp-cmtp | igmp | ipencap | ipip | ipsec-ah | ipsec-esp | iso-tp4 | ospf | pup | rdp | rspf | st | tcp | udp | vmtp | xns-idp | xtp | integer) — совпадение IP протокола. Указывается имя протокола или его номер. Вы должны указать эту опцию, чтобы получить доступ к специфическим параметрам для каждого протокола.
psd (integer,time,integer,integer) — попытка определения сканирования TCP и UDP портов. Необходимо назначить меньшее значение портам с высокими номерами для того, чтобы уменьшить количество ложных срабатываний. К примеру, при использовании пассивного режима FTP.
WeightThreshold — полный вес последних TCP/UDP пакетов с различными портами назначения, поступающими с одного хоста, которые распознанные как один из методов сканирования
DelayThreshold — задержка между пакетами с разными портами назначения, поступающие с одного хоста и распознанные как возможная последовательность сканирования
LowPortWeight — вес пакетов при сканировании привилегированных портов (<=1024)
HighPortWeight — вес пакетов на непривилегированные порты назначения
random (integer: 1..99) — совпадение пакетов с заданным уровнем случайности
reject-with (icmp-admin-prohibited | icmp-echo-reply | icmp-host-prohibited | icmp-host-unreachable | icmp-net-prohibited | icmp-network-unreachable | icmp-port-unreachable | icmp-protocol-unreachable | tcp-reset | integer) — указывает причину по которой был отброшен пакет в action=reject
routing-mark (name) — совпадение пакетов, обозначенных в цепочке mangle параметром routing mark
src-address (IP address/netmask | IP address-IP address) — указывает диапазон адресов IP пакетов поступивших извне. Замечание: консоль конвертирует неправильно набранные IP значения address/netmask в правильный сетевой адрес. К примеру:1.1.1.1/24 будет конвертирован в 1.1.1.0/24
src-address-list (name) — совпадение адреса источника с списком IP-адресов в предустановленном пользователе address list
src-address-type (unicast | local | broadcast | multicast) — совпадение типа IP-адреса:
unicast — IP адрес используется для передачи данных между двумя узлами, где только один отправитель и один получатель
local — совпадение адреса, назначенного одному из интерфейсов маршрутизатора
broadcast — IP пакет был отправлен из одной точки всем получателям и IP подсети
multicast — этот типа IP адресации ответственен за передачу между одной или несколькими точками одной или набору других точек
src-mac-address (MAC address) — MAC адрес источника
src-port (integer: 0..65535-integer: 0..65535{*}) — диапазон портов источника
tcp-flags (ack | cwr | ece | fin | psh | rst | syn | urg) — tcp флаги
ack — запрос данных
cwr — принимающее окно уменьшено
ece — ECN-флаг echo (explicit congestion notification)
fin — закрытие подключения
psh — функция push
rst — разорвать подключение
syn — новое подключение
urg — urgent data
tcp-mss (integer: 0..65535) — совпадение значения TCP MSS IP пакета
time (time-time,sat | fri | thu | wed | tue | mon | sun{+}) — позволяет создать фильтр, базирующийся на времени получения пакета или дате. Для локально созданных пакетов дате отправки
tos (max-reliability | max-throughput | min-cost | min-delay | normal) — совпадение с полем «тип сервиса» Type of Service (ToS) в IP загаловке
max-reliability — максимальная надёжность (ToS=4)
max-throughput — максимальная пропускная способность (ToS=8)
min-cost — минимальная стоимость (ToS=2)
min-delay — минимальная задержка (ToS=16)
normal — нормальное обслуживание (ToS=0)

Правила NAT применяются первыми, и это нужно помнить при создании правил файервола, так как оригинальные пакеты могли быть модифицированы в NAT.

Примеры применения

Защита вашего маршрутизатора RouterOS

Для защиты вашего маршрутизатора сменить пароль администратора недостаточно и нужно воспользоваться фильтрацией пакетов. Все пакеты с адресом назначения маршрутизатора попадают во входную цепочку файервола INPUT. Заметьте, что попавшие в цепочку INPUT пакеты не будут проходить через маршрутизатор.

/ip firewall filter
add chain=input connection-state=invalid action=drop comment="Drop Invalid connections"
add chain=input connection-state=established action=accept comment="Allow Established connections"
add chain=input protocol=udp action=accept comment="Allow UDP"
add chain=input protocol=icmp action=accept comment="Allow ICMP"
add chain=input src-address=192.168.0.0/24 action=accept comment="Allow access to router from known network"
add chain=input action=drop comment="Drop anything else"

Для защиты сети проверяется весь трафик проходящий через маршрутизатор и блокировать нежелательные пакеты:

/ip firewall filter
add chain=forward protocol=tcp connection-state=invalid action=drop comment="drop invalid connections"
add chain=forward connection-state=established action=accept comment="allow already established connections"
add chain=forward connection-state=related action=accept comment="allow related connections"

Блокировать IP адреса, названные «bogons»:

add chain=forward src-address=0.0.0.0/8 action=drop
add chain=forward dst-address=0.0.0.0/8 action=drop
add chain=forward src-address=127.0.0.0/8 action=drop
add chain=forward dst-address=127.0.0.0/8 action=drop
add chain=forward src-address=224.0.0.0/3 action=drop
add chain=forward dst-address=224.0.0.0/3 action=drop

Перебросить их в другую цепочку:

add chain=forward protocol=tcp action=jump jump-target=tcp
add chain=forward protocol=udp action=jump jump-target=udp
add chain=forward protocol=icmp action=jump jump-target=icmp

Создать цепочку tcp и запретить некоторые tcp порты:

add chain=tcp protocol=tcp dst-port=69 action=drop comment="deny TFTP"
add chain=tcp protocol=tcp dst-port=111 action=drop comment="deny RPC portmapper"
add chain=tcp protocol=tcp dst-port=135 action=drop comment="deny RPC portmapper"
add chain=tcp protocol=tcp dst-port=137-139 action=drop comment="deny NBT"
add chain=tcp protocol=tcp dst-port=445 action=drop comment="deny cifs"
add chain=tcp protocol=tcp dst-port=2049 action=drop comment="deny NFS"
add chain=tcp protocol=tcp dst-port=12345-12346 action=drop comment="deny NetBus"
add chain=tcp protocol=tcp dst-port=20034 action=drop comment="deny NetBus"
add chain=tcp protocol=tcp dst-port=3133 action=drop comment="deny BackOriffice"
add chain=tcp protocol=tcp dst-port=67-68 action=drop comment="deny DHCP"

Запретить udp порты в цепочке udp:

add chain=udp protocol=udp dst-port=69 action=drop comment="deny TFTP"
add chain=udp protocol=udp dst-port=111 action=drop comment="deny PRC portmapper"
add chain=udp protocol=udp dst-port=135 action=drop comment="deny PRC portmapper"
add chain=udp protocol=udp dst-port=137-139 action=drop comment="deny NBT"
add chain=udp protocol=udp dst-port=2049 action=drop comment="deny NFS"
add chain=udp protocol=udp dst-port=3133 action=drop comment="deny BackOriffice"

Разрешить только необходимые коды icmp в цепочке с именем icmp:

add chain=icmp protocol=icmp icmp-options=0:0 action=accept comment="drop invalid connections"
add chain=icmp protocol=icmp icmp-options=3:0 action=accept comment="allow established connections"
add chain=icmp protocol=icmp icmp-options=3:1 action=accept comment="allow already established connections"
add chain=icmp protocol=icmp icmp-options=4:0 action=accept comment="allow source quench"
add chain=icmp protocol=icmp icmp-options=8:0 action=accept comment="allow echo request"
add chain=icmp protocol=icmp icmp-options=11:0 action=accept comment="allow time exceed"
add chain=icmp protocol=icmp icmp-options=12:0 action=accept comment="allow parameter bad"
add chain=icmp action=drop comment="deny all other types"

(c) netflow.by

2014   mikrotik   network

Nginx как прокси для Apache2

Имеем сервер под Linux Debian

# uname -a
Linux server 2.6.18-6-686 #1 SMP Mon Oct 13 16:13:09 UTC 2008 i686 GNU/Linux
# nginx -V
nginx version: nginx/1.1.17
# apache2 -V
Server version: Apache/2.2.9 (Debian)

Конфигурация Nginx

# cat /usr/local/nginx/conf/sites-enabled/blog.a-zazell.ru
server {

listen 93.190.18.10:80;
server_name blog.a-zazell.ru ;

root /var/www/a-zazell.ru/blog/wp;
index index.php;

access_log  /var/log/nginx/blog.a-zazell.ru_access.log;
error_log  /var/log/nginx/blog.a-zazell.ru_error.log;
# Все проксируем без кэширования на Apache2
location / {
    proxy_pass http://127.0.0.1:8888/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_redirect     off;
    client_max_body_size       10m;
    proxy_cache off;
}
# Статику отдает Nginx
location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt)$ {
    #log_not_found off;
}
# Если нет иконки, не надо мусорить в Лог
location = /favicon.ico {log_not_found off;access_log off;}
# Смотреть файлы с точки НЕЛЬЗЯ
location ~ /\. {deny all;access_log off;log_not_found off;}
# Роботам в Лог не сорить
location = /robots.txt { access_log off; log_not_found off; }

}
# Переносим Всех, кто зашел на http://a-zazell.ru в блог
server {
listen 93.190.18.10:80;
server_name www.a-zazell.ru a-zazell.ru;
return 301 http://blog.a-zazell.ru;
}

Конфигурация Apache2

# cat /etc/apache2/sites-enabled/blog.a-zazell.ru
<VirtualHost *:8888>

ServerName blog.a-zazell.ru
ServerAdmin mail@a-zazell.ru
DocumentRoot /ftp/httpd/a-zazell.ru/blog/wp

ErrorLog /var/log/apache2/blog.a-zazell.ru_error.log
TransferLog /var/log/apache2/blog.a-zazell.ru_access.log

RewriteEngine On
<Directory /var/www/a-zazell.ru/blog/wp/>
 Options -Indexes FollowSymLinks Includes ExecCGI
 AllowOverride All
 order deny,allow
 allow from all
</Directory>
</VirtualHost>

Вышеописанной конфигурации вполне достаточно. Еще не забудьте добавить в Apache2 модуль rpaf (libapache2-mod-rpaf).

(c) blog.a-zazell.ru

2014   nix   web

Что нужно не забыть при передаче роли PDC эмулятора

Проблема
Иногда возникает абсолютно жизненная ситуация — роли хозяина операций.
Сервер может переезжать на новую платформу, апгрейдится, или просто сломаться.
Здесь часто упускается довольно важная деталь- при передаче роли PDC эмулятора (чьей одной из многих забот является контроль точного времени в домене) автоматически не изменяется параметр реестра, отвечающий за эту настройку.
//(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\Parameters\Type)

Сценарий
Таким образом, представим ситуацию- у Вас имеется один лес, один домен и два сервера, являющихся контроллерами домена.
Отказывает один из контроллеров (PDC), и эта роль вручную передается второму контроллеру.
Что произойдет в этом случае? Параметр реестра, объявляющий сервер надежным источником точного времени, не «переедет» на нового владельца, и синхронизация времени нарушится.
Исправление

  1. На «старом» PDC Emulator, выполните:
w32tm /config /syncfromflags:domhier /reliable:no /update

net stop w32time
net start w32time
  1. Передайте роль PDC Emulator на новый контроллер домена.
  2. На «новом» PDC Emulator, выполните:
w32tm /config /manualpeerlist:PEERS /syncfromflags:manual /reliable:yes /update

где PEERS будут серверами-источниками точного времени,параметр может принимать значение DNS имени либо IP адреса.
Если источников больше одного, между ними необходимо ввести пробел, и также не забудьте про кавычки: «time.domain.com time1.domain.com».

(c) social.technet.microsoft.com

2014   ad   windows

Передача или принудительное назначение (захват) ролей FSMO другому контроллеру домена используя модуль AD-Powershell

Перемещение FSMO ролей с помощью AD PowerShell имеет следующие преимущества:

  • Не требуется подключение к будущим владельцам роли,
  • Только захват роли FSMO (если текущий владелец недоступен) потребует ввода дополнительных параметров, вы должны будете использовать дополнительный параметр -force,
  • Перенос или захват FSMO ролей не требует обязательного подключения к текущему или будущему владельцу роли.Вы можете выполнять камандлеты модуля AD-Powershell на клиенте Windows 7 или  рядовом сервере Windows Server 2008 R2 (с установленным пакетом RSAT).

Передача ролей другому владельцу осуществляется с помощью командлета Move-ADDirectoryServerOperationMasterRole

Перенос всех ролей:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole SchemaMaster,RIDMaster,InfrastructureMaster,DomainNamingMaster,PDCEmulator

Захват всех ролей:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole SchemaMaster,RIDMaster,InfrastructureMaster,DomainNamingMaster,PDCEmulator -Force

В примере имя целевого Контроллера Домена DC1:
Используем следующую команду для передачи всех ролей дркгому контроллеру домена:

Move-ADDirectoryServerOperationMasterRole -Identity "DC1" -OperationMasterRole SchemaMaster,RIDMaster,InfrastructureMaster,DomainNamingMaster,PDCEmulator

Используем следующую команду для захвата всех ролей другим контроллером домена:

Move-ADDirectoryServerOperationMasterRole -Identity "DC1" -OperationMasterRole SchemaMaster,RIDMaster,InfrastructureMaster,DomainNamingMaster,PDCEmulator -Force

Вместо ввода Имен FSMO, можно использованы Цифровые сокращения.

0 - PDCEmulator
1 - RIDMaster
2 - InfrastructureMaster
3 - SchemaMaster
4 - DomainNamingMaster

Передача всех ролей:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 0,1,2,3,4

Захват всех ролей:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 0,1,2,3,4 -Force

В примере имя целевого Контроллера Домена DC1:
Используем следующую команду для передачи всех ролей другому контроллеру домена:

Move-ADDirectoryServerOperationMasterRole -Identity "DC1" -OperationMasterRole 0,1,2,3,4

Используем следующую команду для захвата всех ролей другим контроллером домена:

Move-ADDirectoryServerOperationMasterRole -Identity "DC1" -OperationMasterRole 0,1,2,3,4 -Force

Передача или захват роли Domain Naming Master

Передача роли:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole DomainNamingMaster

или

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 4

Захват роли:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole DomainNamingMaster -Force

или

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 4 -Force

Передача или захват роли Schema Master

Передача роли:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole SchemaMaster

или

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 3

Захват роли:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole SchemaMaster -Force

или

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 3 -Force

Передача или захват роли Infrastructure Master

Передача роли:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole InfrastructureMaster

или

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 2

Захват роли:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole InfrastructureMaster -Force

или

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 2 -Force

Передача или захват роли RID Master

Передача роли:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole RIDMaster

или

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 1

Захват роли:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole RIDMaster -Force

или

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 1 -Force

Передача или захват роли PDC Emulator

Передача роли:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole PDCEmulator

или

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 0

Захват роли:

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole PDCEmulator -Force

или

Move-ADDirectoryServerOperationMasterRole -Identity "Target-DC" -OperationMasterRole 0 -Force

Дополнительная информация

Вы также можете просмотреть текущего владельца роли FSMO используя следующие командлеты AD-Powershell:

Get-ADForest | select SchemaMaster,DomainNamingMaster
Get-ADDomain | select PDCEmulator,RIDMaster,InfrastructureMaster

Ссылки

Move-ADDirectoryServerOperationMasterRole
Active Directory Administration with Windows PowerShell
How To Revert Back or downgrade Windows Server 2008 R2 Forest and Domain functional Level
AD-Powershell for Active Directory Administrators

(с) social.technet.microsoft.com

2014   ad   windows
Ранее Ctrl + ↓