윈도우 방화벽 해제


Intro

 네트워크를 사용하는 윈도우 프로그램을 하다보면, 방화벽이 문제가 되는 경우가 있습니다. 물론 방화벽에서 프로세스의 네트워크 사용에 대해서 Notify 하고, 설정을 유도하는 창이 뜨긴 합니다만, 그렇지 않은 경우도 있고 잘 아시다시피 사용자는 꼼꼼하지 않습니다. 무턱대고 취소를 누르는 경우도 있고 여간 귀찮은게 아닙니다. 하여 프로그램 설치 및 실행시 자동으로 윈도우 방화벽에 해당 프로그램을 예외로 등록할 수 있다면 매우 편할 것입니다.


Content

윈도우 방화벽에 등록을 하기 전에 짚고 넘어가야 할 것이 있습니다. 바로 윈도우 방화벽이 다 같은 것이 아니라는 점입니다. 윈도우 방화벽은 'Firewall' 과 'Advanced Firewall' 로 나뉩니다. Windows Server 2008 과 Vista 부터가 'Advanced Firewall' 이며, 그 이전을 'Firewall' 이라고 합니다.

 윈도우 방화벽을 해제하는 방법에는 크게 두가지가 있습니다. 하나는 COM(NetFwTypeLib) 을 이용한 것이고, 또 하나는 프롬프트 명령을 이용한 방법입니다.
 두 방벙에 대해서 장단점이 있겠지요. 개인적으로는 후자를 선호합니다. 전자의 경우에는 세부적이 설정을 하기 위해서는 코드가 질어지는 단점이 있습니다. 또한 Vista 이전 버젼의 사용자가 'Advanced Firewall' 설정을 하기 위해서는 Vista 이상의 COM 이 필요합니다. 즉 빌드하기 귀찮아 진다는 것이죠.


Code

 1. COM 이용하기
  - Microsoft Visual Studio 에서 COM객체를 참조 추가를 해 주어야 합니다.


경로에 dll 이름을 보면 'FirewallAPI.dll' 이라고 되어 있네요.

 - 이제 아래와 같이 사용하면 됩니다.


 public static INetFwMgr WinFirewallManager() {
    Type type = Type.GetTypeFromCLSID(new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}"));
    return Activator.CreateInstance(type) as INetFwMgr;
}

public bool AuthorizeProgram(string title, string path, NET_FW_SCOPE_ scope, NET_FW_IP_VERSION_ ipver) {
    Type type = Type.GetTypeFromProgID("HNetCfg.FwAuthorizedApplication");
    INetFwAuthorizedApplication authapp = Activator.CreateInstance(type) as INetFwAuthorizedApplication;
    authapp.Name = title;
    authapp.ProcessImageFileName = path;
    authapp.Scope = scope;
    authapp.IpVersion = ipver;
    authapp.Enabled = true;

    INetFwMgr mgr = WinFirewallManager();
    try {
        mgr.LocalPolicy.CurrentProfile.AuthorizedApplications.Add(authapp);
    } catch (Exception ex) {
        System.Diagnostics.Trace.Write(ex.Message);
        return false;
    }

    return true;
}




'CrystalCube.exe' 라는 프로그램을 방화벽에 예외 등록할 경우 다음과 같이 호출해 주면 됩니다.



  AuthorizeProgram("CrystalCube",
 @"C:\ProgramFiles\Crystal\CrystalCube.exe",
 NET_FW_SCOPE_.NET_FW_SCOPE_ALL,
 NET_FW_IP_VERSION_.NET_FW_IP_VERSION_ANY);


자세한 방법은 MSDN 을 참고하시기 바랍니다.
http://msdn.microsoft.com/en-us/library/aa366418%28VS.85%29.aspx



2. 프롬프트 명령어 이용하기
 - 제가 선호하는 방법입니다. 가장 깔끔한 방법이 아닐까 싶네요. 윈도우에서 제공하는 netsh 명령을 사용하는 것입니다.

 우선 코드를 보면 다음과 같습니다.



 public static class Firewall
{
    private static readonly string FirewallCmd = "netsh firewall add allowedprogram \"{1}\" \"{0}\" ENABLE";
    private static readonly string AdvanceFirewallCmd = "netsh advfirewall firewall add rule name=\"{0}\" dir=in action=allow program=\"{1}\" enable=yes";
    private static readonly int VistaMajorVersion = 6; 

    public static bool AuthorizeProgram(string name, string programFullPath) {
        try {
            // OS version check
            string strFormat = Firewall.FirewallCmd;
            if (System.Environment.OSVersion.Version.Major >= Firewall.VistaMajorVersion) {
                strFormat = Firewall.AdvanceFirewallCmd;
            }

            // Start to register
            string command = String.Format(strFormat, name, programFullPath);
            System.Console.WriteLine(command);

            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.CreateNoWindow = true;
            startInfo.FileName = "cmd.exe";
            startInfo.UseShellExecute = false;
            startInfo.RedirectStandardInput = true;
            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardError = true;

            Process process = new Process();
            process.EnableRaisingEvents = false;
            process.StartInfo = startInfo;
            process.Start();
            process.StandardInput.Write(command + Environment.NewLine);
            process.StandardInput.Close();

            string result = process.StandardOutput.ReadToEnd();
            string error = process.StandardError.ReadToEnd();

            process.WaitForExit();
            process.Close();
        } catch {
            return false;
        }

        return true;
    }
}



 감이 오시나요?

[Win XP]

netsh firewall add allowedprogram C:\MyApp\MyApp.exe "My Application" ENABLE


[Vista or Win7]

netsh advfirewall firewall add rule name="My Application" dir=in action=allow program=C:\MyApp\MyApp.exe" enable=yes



이런 명령을 .NET 을 이용해서 내부적으로 호출하는 방식입니다. 장점은 복잡하게 코드를 구현 할 필요가 없고, 윈도우 버젼이나 기타 상태에 대한 예외를 개발자가 고려할 필요가 없다라는 것입니다. netsh 내부적으로 알아서 잘~ 처리해 주니까요.

사실 Windows 7 의 방화벽 설정을 보면 다음과 같이 매우 설정사항이 많습니다.


Profile / Enable / Action / Port 등등 너무나 많습니다. 이들 설정에 대해서는 아래 MSDN 을 참고하시면 되겠습니다.

http://support.microsoft.com/kb/947709

Command 에서 필요한 인자값들만 변경해서 사용하시면 되겠죠?


반대로 삭제하는 명령은 아래와 같습니다.

[Win XP]

netsh firewall delete allowedprogram C:\MyApp\MyApp.exe

[Vista or Win7]

netsh advfirewall firewall delete rule name="My Application" programC:\MyApp\MyApp.exe"




Result

 윈도우 방화벽이라는게 여간 귀찮은 것이 아닙니다. 만약 윈도우의 설정과 관련해서 변경해야 할 것이 있다면 무조건 코드레벨에서 방법을 찾지 않으셨으면 합니다. 잘 찾아보면 더 쉽고 완벽한 방법들이 많이 있거든요. 그럼 오늘의 포스팅은 여기서 마치도록 하겠습니다~


  • 초보자 2012.08.27 21:52

    제가 여기저기 헤매면서 찾고 있던 것을 한 번에 알려주셨네요.
    무조건적으로 코드단의 정보를 찾고 있었지만, 더 쉬운 방법도 있다는 것을 이제 알았습니다.
    정말 감사합니다.

  • 김기원 2012.12.13 11:13

    좋은 정보 감사합니다.
    Netsh를 컴멘드에서는 했었는데 폼이 안난다고 해서 찾아봤는데
    그게 가장 좋은 방법이네요. ^^
    퍼갈께요...

  • 감사합니다 2013.02.11 00:19

    좋은 정보 감사합니다~ 퍼갈께요

  • 감사합니다 2013.02.11 00:19

    좋은 정보 감사합니다~ 퍼갈께요

  • 바람돌이 2014.06.25 14:46

    유용하게 잘 쓰겠습니다.

  • 바람돌이2 2014.06.30 09:29

    netsh advfirewall firewall show rule name="rule" || netsh advfirewall firewall add rule name="rule" dir=in action=allow

    이런 아이디어가 있네요.. 역시 똑똑한 분들이 많으시네요..