C#在日常运维中的应用:操作Windows防火墙

8 篇文章 1 订阅
2 篇文章 0 订阅

前言

由于疫情的持续肆虐,出行成了大问题。为了尽量减少风险,外地的办公室是能不过去就不过去。一般问题远程就解决了,但碰到系统因故障需重装的情况就比较麻烦,外地的同事并不是IT专业的,在电话指导+Word文档指引下安装完系统,后续仍有一些重复的操作如开启远程桌面、设置默认账号密码及变更防火墙设置(以放开远程桌面连接)等,虽亦可以写份Word文档说明操作步骤,但总感觉这些操作可以通过程序来实现,同时考虑到在远程桌面开通后,仍有一些标准的安全设置需要重复设置,遂用C#写了两个小工具来自动化这些操作。其中主要用到以下这些功能,分享一下。

在此前,我们已通过另一个Console小工具配合Powershell脚本开通了远程桌面,接下来我们可以通过C#来进行防火墙的基本设置。主要通过WindowsFirewallHelper(参考https://github.com/falahati/WindowsFirewallHelper)来操作Windows防火墙。

/// <summary>
/// 建立自定义程序规则
/// </summary>
/// <param name="newAppRuleName ">规则名称</param>
/// <param name="appExeFileName">程序可执行文件完整路径及名称</param>
private void CreateApplicationRule(string newAppRuleName, string appExeFileName)
{
	var rule = FirewallManager.Instance.Rules.Where(r =>
	r.Direction == FirewallDirection.Outbound && //搜索出站规则
	r.Name.Equals(newAppRuleName)
	).FirstOrDefault();

	if (rule == null) // 指定的规则不存在
	{
		try
		{
			rule = FirewallManager.Instance.CreateApplicationRule(
				FirewallProfiles.Domain | FirewallProfiles.Private | FirewallProfiles.Public, // 生效的配置文件
				newAppRuleName,
				FirewallAction.Block, // 阻止
				appExeFileName,
				FirewallProtocol.TCP //协议
				);

			rule.Direction = FirewallDirection.Outbound; //方向:出站

			FirewallManager.Instance.Rules.Add(rule);

			// todo: 输出成功建立规则信息
		}
		catch (Exception ex)
		{
			// todo: 输出错误信息
		}
	}
	else
	{
		// todo: 输出规则已存在信息			
	}
}

/// <summary>
/// 建立自定义端口规则
/// </summary>
/// <param name="newPortRuleName">规则名称</param>
/// <param name="portNumber">端口:例如3389</param>
/// <param name="firewallAction">动作:FirewallAction.Allow 或 FirewallAction.Block</param>
/// <param name="firewallDirection">方向:FirewallDirection.Inbound 或 FirewallDirection.Outbound</param>
private void CreatePortRule(string newPortRuleName, ushort portNumber, FirewallAction firewallAction, FirewallDirection firewallDirection)
{
	//搜索规则
	var rule = FirewallManager.Instance.Rules.Where(r =>
	r.Direction == firewallDirection && 
	r.Name.Equals(newPortRuleName)
	).FirstOrDefault();

	if (rule == null) // 指定的规则不存在
	{
		try
		{
			rule = FirewallManager.Instance.CreatePortRule(
				FirewallProfiles.Domain | FirewallProfiles.Private | FirewallProfiles.Public, // 生效的配置文件
				newPortRuleName,
				firewallAction, // 运作:允许或阻止
				portNumber,
				FirewallProtocol.TCP //协议
				);

			rule.Direction = firewallDirection; //方向

			FirewallManager.Instance.Rules.Add(rule);

			// todo: 输出成功建立规则信息
		}
		catch (Exception ex)
		{
			// todo: 输出错误信息
		}
	}
	else
	{
		// todo: 输出规则已存在信息			
	}
}

// 定义允许的IP地址列表
private	IAddress[] TargetIPAddress = new IAddress[]
{
	SingleIP.Parse("192.168.11.248"),
	SingleIP.Parse("192.168.10.248")
};

/// <summary>
/// 更新自定义规则
/// </summary>
/// <param name="targetRuleName">规则名称</param>
/// <param name="firewallDirection">入站或出站规则</param>
/// <param name="allowedIPAddress">允许的IP地址</param>
private void UpdateRule(string targetRuleName, FirewallDirection firewallDirection, IAddress[] allowedIPAddress)
{
	// 搜索目标规则
	var rule = FirewallManager.Instance.Rules.Where(r =>
	r.Direction == firewallDirection &&
	r.Name.Equals(targetRuleName)
	).FirstOrDefault();

	if (rule != null)
	{
		try
		{
			rule.RemoteAddresses = allowedIPAddress;
			// todo: 输出成功更新信息
		}
		catch (Exception ex)
		{
			// todo: 输出出错信息
		}
	}
	else
	{
		// todo: 输出规则不存在信息
	}
}

/// <summary>
/// 删除(入站或出站)规则
/// https://github.com/falahati/WindowsFirewallHelper 使用的是 SingleOrDefault
/// 但是,如碰巧有两条同名规则时会报提示:Sequence Contains More Than One Matching Element 
/// </summary>
/// <param name="targetRuleName">规则名称</param>
private void RemoveRule(string targetRuleName)
{
	var rule2Remove = FirewallManager.Instance.Rules.FirstOrDefault (r => r.Name == targetRuleName); 

	if (rule2Remove!= null)
	{
		try
		{
			FirewallManager.Instance.Rules.Remove(rule2Remove);
			// todo: 输出成功删除信息
		}
		catch (Exception ex)
		{
			// todo: 输出出错信息
		}
	}
	else
	{
		// todo: 输出规则不存在信息
	}
}

/*
* 禁用或启用规则
* WindowsFirewallHelper并没有提供禁用或启用规则的方法(或许是没有找到?),只能通过迂回的方式(运行advfirewall firewall set 命令)以达到目的。
*/

/// <summary>
/// 修改规则
/// </summary>
/// <param name="targetRuleName">规则名称</param>
/// <param name="actionFlag">bool: True or False</param>
private void ModifyRule(string targetRuleName, bool actionFlag)
{
	string cmd = "/C netsh advfirewall firewall set rule name=\"" + targetRuleName + "\" new enable=" + (actionFlag ? "yes" : "no");
	RunCMD(cmd);
}

/// <summary>
/// 运行命令行程序
/// </summary>
/// <param name="argument">命令行参数</param>
private static void RunCMD(string argument)
{
	Process process = new Process();
	ProcessStartInfo startInfo = new ProcessStartInfo();
	startInfo.WindowStyle = ProcessWindowStyle.Hidden; // 隐藏运行时窗口
	startInfo.FileName = @"C:\Windows\System32\cmd.exe";
	startInfo.Arguments = argument;
	process.StartInfo = startInfo;
	process.Start();			
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值