Добавление правила брандмауэра приложения в частные и публичные сети через Win7 FirewallAPI

Немного предыстории: По сути, я хотел бы добавить правило доступа к брандмауэру программы как для частных, так и для публичных сетей.

Я использовал это - "netsh firewall add allowprogram program= "Path.." name=AppName ENABLE scope=ALL profile=CURRENT"

Но теперь я бы хотел немного автоматизировать процесс с помощью COM-объекта. Нашел этот блестящий кусок кода - http://web.archive.org/web/20070707110141/http://www.dot.net.nz/Default.aspx?tabid=42&mid=404&ctl=Details&ItemID=8

И после реализации класса я пытался использовать - FirewallHelper.Instance.GrantAuthorization(@"Path... ","AppName ",NET_FW_SCOPE_.NET_FW_SCOPE_ALL,NET_FW_IP_VERSION_.NET_FW_IP_VERSION_ANY);

Проблема, с которой я сталкиваюсь, заключается в том, что метод GrantAuthorization добавляет только правило для общедоступной ИЛИ частной сети, тогда как моя старая команда netsh будет иметь 2 правила для - 1 для каждой сети.

Команды, на самом деле, кажутся очень похожими, так что для меня это немного странно.

Итак... как добавить оба сетевых правила?

Shaun

5 ответов

Мой ответ от ответа Дэвида, но более подробно. И исправить проблему с настройкой Localports. Вам нужно установить протокол перед настройкой Localports. Более подробно ниже:

Во-первых, вам нужно импортировать ссылку FirewallAPI.dll. Это в "C:\Windows\System32\FirewallAPI.dll" тогда:

using NetFwTypeLib;

и вставьте код в ваш:

        Type tNetFwPolicy2 = Type.GetTypeFromProgID("HNetCfg.FwPolicy2");
        INetFwPolicy2 fwPolicy2 = (INetFwPolicy2)Activator.CreateInstance(tNetFwPolicy2);
        var currentProfiles = fwPolicy2.CurrentProfileTypes;

        // Let's create a new rule
        INetFwRule2 inboundRule = (INetFwRule2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
        inboundRule.Enabled = true;
        //Allow through firewall
        inboundRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;
        //Using protocol TCP
        inboundRule.Protocol = 6; // TCP
        //Port 81
        inboundRule.LocalPorts = "81";
        //Name of rule
        inboundRule.Name = "MyRule";
        // ...//
        inboundRule.Profiles = currentProfiles;

        // Now add the rule
        INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
        firewallPolicy.Rules.Add(inboundRule);

Я думаю, что вам лучше всего поговорить с брандмауэром Windows с расширенной безопасностью API.

Быстрый Google для "C# INetFwRule2" покажет вам многочисленные примеры того, как зарегистрировать или обновить правило брандмауэра.

Чтобы добавить как к публичной, так и к частной политике, я использовал что-то вроде

Type tNetFwPolicy2 = Type.GetTypeFromProgID("HNetCfg.FwPolicy2");
INetFwPolicy2 fwPolicy2 = (INetFwPolicy2)Activator.CreateInstance(tNetFwPolicy2);
var currentProfiles = fwPolicy2.CurrentProfileTypes;

// Let's create a new rule

INetFwRule2 inboundRule = (INetFwRule2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
inboundRule.Enabled = true;
inboundRule.LocalPorts = "1234";
inboundRule.Protocol = 6; // TCP
// ...
inboundRule.Profiles = currentProfiles;

// Now add the rule

INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
firewallPolicy.Rules.Add(inboundRule);

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

Сначала импортируйте ссылку FirewallAPI.dll, расположенную в "C:\Windows\System32\FirewallAPI.dll", затем добавьте директиву using

using NetFwTypeLib;

В inboundRule.Profiles Кажется, свойство классифицируется как набор флагов со следующими значениями (тип свойства - int, поэтому я сделал перечисление):

public enum FirewallProfiles
{
    Domain = 1,
    Private = 2,
    Public = 4
}

Итак, с помощью этого кода мы можем изменить профили на следующие:

// Create a new rule
INetFwRule2 inboundRule = (INetFwRule2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwRule"));
// Enable the rule
inboundRule.Enabled = true;
// Allow through firewall
inboundRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;
// Using protocol TCP
inboundRule.Protocol = 6; // TCP
// Set port number
inboundRule.LocalPorts = "1234";
// Name of rule
inboundRule.Name = "Name Of Firewall Rule";
// Set profiles
inboundRule.Profiles = (int)(FirewallProfiles.Private | FirewallProfiles.Public);

// Add the rule
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
firewallPolicy.Rules.Add(inboundRule);

Или вы могли бы изменить inboundRule.Profiles в значение типа int.

Два примечания:

1: Если вы не запускаете этот код с правами администратора,

firewallPolicty.Rules.Add(inboundRule);

вызовет исключение.

2: inboundRule.Profiles должен быть между значениями 1 и 7. В противном случае будет выдано исключение

На всякий случай, если вы, ребята, хотите исходящее правило:

inboundRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT;

Мы можем сделать это с помощью команд, используя стандартныйProcessбежатьcmd.exe. netshКоманда сначала проверяет наличие правила брандмауэра и, если оно не существует, создает его, в противном случае оно обновляется.

Я предпочитаю не удалять правило, поскольку это приведет к прерыванию подключенных служб при проверке правила.

      static void SetFirewallException(string ruleName, string exePath)
{

    string script = $@"netsh advfirewall firewall show rule name=""{ruleName}"" > nul & if errorlevel 1 (netsh advfirewall firewall add rule name=""{ruleName}"" dir=in action=allow program=""{exePath}"" enable=yes) else (netsh advfirewall firewall set rule name=""{ruleName}"" new program=""{exePath}"")";

    Process process = new Process();
    process.StartInfo.FileName = "cmd.exe";
    process.StartInfo.Arguments = "/c " + script;
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.CreateNoWindow = true;
    process.Start();
    process.WaitForExit();
}
Другие вопросы по тегам