ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C# .NET] Windows 방화벽 등록하기
    Desktop App/C#.Net 2022. 3. 3. 23:16

    TCP 통신 기능이 있는 닷넷 프레임워크 앱들은 실행하면 아래와 같은 창이 뜨고,

    허용 시 윈도우 방화벽에 자동으로 등록이 된다.

     

     

    이 때 네트워크 프로필과 다른 옵션을 선택하거나 엑세스를 허용하지 않은 경우,

    또는 무언가 알 수 없는 오류로 위 창조차 보이지 않고 방화벽에 등록이 되지 않는 경우가 생긴다.

     

    해당 문제로 고객사측 앱 사용에 문제가 있어 방화벽에 앱을 자동으로 등록해줄 수 있도록 해주었다.

     

    테스트하기 위해 간단한 프로젝트를 생성했다.

     

    참조 우클릭 -> 참조 추가

     

    COM 항목에서 NetFw라고 검색하면 위와 같이 NetFwTypeLib 라이브러리가 나온다.

    체크하여 참조해준다.

     

    테스트만 하고 끝낼 것이 아니라 배포용 앱에도 추가해야 하기 때문에 따로 클래스를 만들어 주었다.

    using System;
    using System.Linq;
    using NetFwTypeLib;
    
    namespace FirewallTest
    {
        public static class Firewall
        {
            public enum Protocol
            {
                TCPUDP = 0x100,
                TCP = 6,
                UDP = 0x11
            }
            public enum Direction
            {
                INBOUND = 1,
                OUTBOUND = 2,
                MAX = 3
            }
    
            public enum Action
            {
                BLOCK = 0,
                ALLOW = 1,
                MAX = 2
            }
    
            private static INetFwPolicy2 policy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
    
            public static bool Find(string name, string path)
            {
                return policy.Rules.Cast<INetFwRule>().Any(rule => rule.Name == name && rule.ApplicationName == path);
            }
            public static bool Find(string name, Protocol protocol)
            {
                return policy.Rules.Cast<INetFwRule>().Any(r => r.Name == name && r.Protocol == (int)protocol);
            }
    
            /// <summary>
            /// Add Firewall Rule
            /// </summary>
            /// <param name="name">Rule Name</param>
            /// <param name="path">Program Full Path</param>
            /// <param name="direction">Direction</param>
            /// <param name="action">Action</param>
            /// <returns>If added, will returns true. Elif Removed, will returns false.</returns>
            public static bool Add(string name, string path, Direction direction, Action action)
            {
                if (Find(name, path)) return true;
    
                INetFwRule rule = (INetFwRule)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
    
                rule.Name = name;
                rule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_ANY;
                rule.Direction = (NET_FW_RULE_DIRECTION_)direction;
                rule.Enabled = true;
                rule.Action = (NET_FW_ACTION_)action;
                
                policy.Rules.Add(rule);
    
                return Find(name, path);
            }
            /// <summary>
            /// Add Firewall Rule
            /// </summary>
            /// <param name="name">Rule Name</param>
            /// <param name="protocol">Protocol Type</param>
            /// <param name="direction">Direction</param>
            /// <param name="action">Action</param>
            /// <returns>If added, will returns true. Elif Removed, will returns false.</returns>
            public static bool Add(string name, Protocol protocol, Direction direction, Action action)
            {
                if (Find(name, protocol)) return true;
    
                INetFwRule rule = (INetFwRule)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
    
                rule.Name = name;
                rule.Protocol = (int)protocol;
                rule.Direction = (NET_FW_RULE_DIRECTION_)direction;
                rule.Enabled = true;
                rule.Action = (NET_FW_ACTION_)action;
    
                policy.Rules.Add(rule);
    
                return Find(name, protocol);
            }
    
            /// <summary>
            /// Remove Firewall Rule
            /// </summary>
            /// <param name="name">Rule Name</param>
            /// <param name="protocol">Protocol Type</param>
            /// <returns>If Removed or Not exist, will returns true. Elif It didn't Removed, will returns false.</returns>
            public static bool Remove(string name, Protocol protocol)
            {
                if (!Find(name, protocol)) return true;
    
                INetFwRule rule = policy.Rules.Cast<INetFwRule>().FirstOrDefault(r => r.Name == name && r.Protocol == (int)protocol);
    
                if (rule != null) policy.Rules.Remove(name);
    
                return !Find(name, protocol);
            }
        }
    }

     

     

    테스트해보기 위해 아래 코드를 버튼에 넣고 시험해 보았다.

    Firewall.Add(Application.ProductName, Application.ExecutablePath, Firewall.Direction.INBOUND, Firewall.Action.ALLOW);
    Firewall.Add(Application.ProductName + "2", Firewall.Protocol.TCP, Firewall.Direction.INBOUND, Firewall.Action.ALLOW);
    
    Firewall.Remove(Application.ProductName, Firewall.Protocol.TCPUDP);

     

     

    적용 전

     

    적용 후

     

     

    삭제 후

     

     

    특정 프로토콜만 허용

     

     

    특정 포트만 허용하는 메서드도 넣으려고 했으나, 무슨 이유에서인지 ArgumentException이 뜨며 적용되지 않는다.

     

     

    댓글 0

Designed by Tistory.