프로그램적으로 윈도우 방화벽 설정하기

.

오랜만에~ 정말 오래간만에 포스팅을 합니다. :)

그동안 회사를 이직하고, 결혼도 하고 하느라 정신이 없다는 핑계로 블로그 운영에 많이 소홀했네요.


재밌는 일도 많고(IT 적으로), 다양한것들을 해 보았는데.

블로깅할 시간이 없었어요~ ㅎ.



모쪼록, 방화벽 관련해서 포스팅을 하려고 합니다.

이전에 한번 netsh 을 통한 방화벽 설정 글을 올린적이 있었는데

(http://crystalcube.co.kr/entry/%EC%9C%88%EB%8F%84%EC%9A%B0-%EB%B0%A9%ED%99%94%EB%B2%BD-%ED%95%B4%EC%A0%9C%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95#recentTrackback)


이번엔 코드레벨에서 COM 개체를 이용하여 처리하는 방법입니다.

코드는 .NET 이고, XP 이후 버젼부터 동작 가능합니다.



    [방화벽 설정]


public static class FirewallAPI
{
    private static INetFwPolicy2 _firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
        
    //public enum FirewallAction
    //{
    //    Block = 0,
    //    Allow = 1,
    //    Max = 2
    //}


    //public enum FirewallDirection
    //{
    //    In = 1,
    //    Out = 2,
    //    Max = 3
    //}

    public enum Protocol
    {
        Tcp = 6,
        Udp = 0x11,
        Any = 0x100
    }



    public static bool AddInboudRule(string name, string programFullPath) {
        if (IsInboundRuleExist(name, programFullPath) == true) { return true; }

        INetFwRule newRule = (INetFwRule)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
        newRule.Name = name;
        newRule.ApplicationName = programFullPath;
        newRule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_ANY;
        newRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN;
        newRule.Enabled = true;
        newRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;

        _firewallPolicy.Rules.Add(newRule);

        return IsInboundRuleExist(name, programFullPath);
    }



    private static bool IsInboundRuleExist(string name, string programFullPath)
    {
        return _firewallPolicy.Rules.Cast<INetFwRule>().Any(rule => rule.Name == name && rule.ApplicationName == programFullPath);
    }



    private static bool IsInboundRuleExist(string name, Protocol protocol, int port)
    {
        return _firewallPolicy.Rules.Cast<INetFwRule>().Any(r => r.Name == name && r.Protocol == (int)protocol && r.LocalPorts == port.ToString());
    }

    private static bool IsInboundRuleExist(string name, Protocol protocol) {
        return _firewallPolicy.Rules.Cast<INetFwRule>().Any(r => r.Name == name && r.Protocol == (int)protocol);
    }



    public static bool AddInboudRule(string name, Protocol protocol, int port)
    {
        if (IsInboundRuleExist(name, protocol, port) == true) { return true; }

        INetFwRule newRule = (INetFwRule)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
        newRule.Name = name;
        newRule.Protocol = (int) protocol;
        newRule.LocalPorts = port.ToString();
        newRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN;
        newRule.Enabled = true;
        newRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;

        _firewallPolicy.Rules.Add(newRule);

        return IsInboundRuleExist(name, protocol, port);
    }



    public static bool RemoveInboundRule(string name, Protocol protocol, int port)
    {
        if (IsInboundRuleExist(name, protocol, port) == false) { return true; }

        INetFwRule rule = _firewallPolicy.Rules.Cast<INetFwRule>().FirstOrDefault(r => r.Name == name && r.Protocol == (int) protocol && r.LocalPorts.Contains(port.ToString()));
        if (rule != null) { _firewallPolicy.Rules.Remove(name); }
            
        return IsInboundRuleExist(name, protocol, port) == false;
    }


    public static bool RemoveInboundRule(string name, Protocol protocol) {
        if (IsInboundRuleExist(name, protocol) == false) { return true; }

        INetFwRule rule = _firewallPolicy.Rules.Cast<INetFwRule>().FirstOrDefault(r => r.Name == name && r.Protocol == (int)protocol);
        if (rule != null) { _firewallPolicy.Rules.Remove(name); }

        return IsInboundRuleExist(name, protocol) == false;
    }
}





먼저 코드를 작성하려면, 언급했듯이 COM 인터페이스를 추가해 주어야 합니다.

어셈블리 파일명은 NetFwTypeLib 이고, 프로젝트 참조추가 해 주어야 합니다.



당연히 COM 카테고리에서 찾아봐야 겠지요 ^-^


그리고 코드 상단에서 using 해 주어야 합니다.



    [NetFwTypeLib]


using NetFwTypeLib;





샘플코드에서는 인바운드(Inbound) 규칙에 대해서 설정하는 것을 다루었습니다.

Outbound 도 어렵지 않게 하실 수 있을거라고 생각합니다.


'Inbound / Outbound', 'TCP,UDP,...' 등의 값들은 모두 NetFwTypeLib 안에 enum 으로 정의되어 있으니 참고하시면 됩니다.

코드상에서 제가 enum 으로 다시 정의한 것들은, 샘플코드를 쓰는 쪽에서 NetFwTypeLib 를 별도로 Import 하지 않아도 되게 하려고.. 한 것입니다.


모쪼록, 많은 도움 되셨길 바랍니다. :)

'Microsoft > C#' 카테고리의 다른 글

#warning, #error, #line 지시자  (0) 2014.05.08
인증서(certification) 만들기  (1) 2014.04.09
키보드 마우스 글로벌 후킹  (1) 2012.06.15
MessageQueue 구현하기  (3) 2011.05.08
JSON 과 AJAX 그리고 C#  (0) 2011.04.25