ASP.NET Core修改CentOS的IP地址


最近做的一个产品中有个需求,就是客户使用的时候可以通过Web网页修改服务器的IP地址(客户是普通使用者,没有Linux使用经验,我们的产品作为一台服务器部署到客户机房,客户通过HTTP方式访问使用)。

在Linux中一切皆是文件,修改IP地址同样是只要修改了对应网卡的配置文件后重启网络服务,只要配置正确无IP冲突,即可成功启用新的IP地址。

所以我们实现的思路是访问网卡配置文件,获取当前网卡的配置信息展示(如果有多个网卡就展示多个网卡信息,用tab来切换网卡信息),然后用户可以修改对应的网卡网络信息提交保存,后台通过修改网卡对应的文件内容,即可达到修改网卡IP地址的功能。

当然因为要访问修改网卡配置文件和执行重启网络的命令,对Web的权限有一定的要求,因为客户是内网运行,简单粗暴的使用了root用户来启动Web程序。

以下代码实现了ASP.NET Core修改CentOS的IP地址功能。

前端使用的是LayUI

  1 @model ViewModel.IPVm
2 @{
3     var ipList = Model.IpList;
4 }
5 
6 <div class="layui-bg-gray" style="padding: 30px;">
7     <div class="layui-row layui-col-space15">
8         <div class="layui-col-md6">
9             <div class="layui-card" style="min-height: 280px;">
10                 <div class="layui-card-header">
11                     配置服务器IP
12                 </div>
13                 <div class="layui-card-body">
14                     <div class="layui-tab-item layui-show" id="tbcontent_0" lay-filter="tbcontent_0filter">
15                         @{
16 
17                             if (ipList != null && ipList.Any())
18                             { 
19                                     <ul class="layui-tab-title">
20 
21                                         @{
22                                         for (int i = 0; i < ipList.Count; i++)
23                                         {
24                                             var ip = ipList[i];
25                                             <li>@ip.IpName</li>
26                                         }
27                                     }
28                                     </ul>
29                       
30                                 <div class="layui-tab-content">
31                                     @{
32                                         for (int i = 0; i < ipList.Count; i++)
33                                         {
34                                             var ip = ipList[i];
35                                             var i1 = i;
36                                             <div class="layui-tab-item" id="tbcontent_@i" lay-filter="tbcontent_1filter">
37                                  
38                                                 <div class="layui-form-item layui-form" lay-filter="Ipv4div_@i1">
39                                                     <label for="Ipv4div_@i1" class="layui-form-label" style="width: 100px">IPv4地址:</label>
40                                                     <div class="layui-input-block" style="margin-left: 130px">
41                                                         <input autocomplete="off" type="text" name="Ipv4div_txt_@i1" value="@ip.Ipv4" maxlength="15" placeholder="请填写IPv4的IP地址" class="layui-input" id="Ipv4div_txt_@i1">
42                                                     </div>
43                                                 </div>
44                                                 <div class="layui-form-item layui-form" lay-filter="IpMaskdiv_@i1">
45                                                     <label for="IpMaskdiv_@i1" class="layui-form-label" style="width: 100px">子网掩码:</label>
46                                                     <div class="layui-input-block" style="margin-left: 130px">
47                                                         <input autocomplete="off" type="text" name="IpMaskdiv_txt_@i1" value="@ip.IpMask" maxlength="15" placeholder="请填写IPv4的子网掩码" class="layui-input" id="IpMaskdiv_txt_@i1">
48                                                     </div>
49                                                 </div>
50                                                 <div class="layui-form-item layui-form" lay-filter="IpGetWaydiv_@i1">
51                                                     <label for="IpGetWaydiv_@i1" class="layui-form-label" style="width: 100px">网关地址:</label>
52                                                     <div class="layui-input-block" style="margin-left: 130px">
53                                                         <input autocomplete="off" type="text" name="IpGetWay_txt_@i1" value="@ip.IpGetWay" maxlength="15" placeholder="请填写IPv4的网关地址" class="layui-input" id="IpGetWay_txt_@i1">
54                                                     </div>
55                                                 </div>
56                                                 <div class="layui-form-item layui-form" lay-filter="IpDnsdiv_@i1">
57                                                     <label for="IpDnsdiv_@i1" class="layui-form-label" style="width: 100px">DNS地址:</label>
58                                                     <div class="layui-input-block" style="margin-left: 130px">
59                                                         <input autocomplete="off" type="text" name="IpDnsdiv_txt_@i1" value="@ip.IpDns" maxlength="15" placeholder="请填写IPv4的DNS地址" class="layui-input" id="IpDnsdiv_txt_@i1">
60                                                     </div>
61                                                 </div>
62                                                 <input type="hidden" value="@ip.IpGuid" maxlength="32" name="IpGuid_@i1" id="IpGuid_@i1" />
63                                                 <input type="hidden" value="@ip.IpName" maxlength="32" name="IpName_@i1" id="IpName_@i1" />
64                                                 <button onclick="SaveIpConfig(this);" type="button" class="layui-btn" id="btn_@i" lay-filter="btn_@i filter">提交修改</button>
65                                             </div>
66                                         }
67                                     }
68                                 </div>
69                             }
70                         }
71                     </div>
72                 </div>
73             </div>
74         </div>
75     </div>
76 </div>
77 <script type="text/javascript">
78     var element = layui.element;
79     layui.use('layer');
80  
81     function SaveIpConfig(e) {
82         var btnId = $(e).attr('id');
83         
84         if (btnId == '' || btnId == undefined) return;
85 
86         var id = btnId.split('_');
87 
88         if (id.length != 2) return;
89 
90         var ip = $("#Ipv4div_txt_" + id[1]).val();
91         var mask = $("#IpMaskdiv_txt_" + id[1]).val();
92         var getWay = $("#IpGetWay_txt_" + id[1]).val();
93         var dns = $("#IpDnsdiv_txt_" + id[1]).val();
94         var nid = $("#IpGuid_" + id[1]).val();
95         var ipName = $("#IpName_" + id[1]).val();
96 
97         if ($.trim(ip) == '') {
98             layer.alert('请填写IP地址',
99                 {
100                     title: '错误'
101                 });
102             return;
103         } else {
104             if (!validateIP($.trim(ip))) {
105                 layer.alert('IP地址格式不正确',
106                     {
107                         title: '错误'
108                     });
109                 return;
110             }
111         }
112 
113         if (mask.trim() == '') {
114             layer.alert('请填写子网掩码', {
115                 title: '错误'
116             });
117             return;
118         } else {
119             if (!validateIP($.trim(mask))) {
120                 layer.alert('子网掩码格式不正确',
121                     {
122                         title: '错误'
123                     });
124                 return;
125             }
126         }
127 
128         if ($.trim(getWay) != '' && !validateIP($.trim(getWay))) {
129             layer.alert('网关地址格式不正确', {
130                 title: '错误'
131             });
132             return;
133         }
134 
135         if ($.trim(dns) != '' && !validateIP($.trim(dns))) {
136             layer.alert('DNS格式不正确', {
137                 title: '错误'
138             });
139             return;
140         }
141 
142         layer.confirm('确定要修改服务器IP吗?!',
143             { icon: 3, title: '信息' },
144             function(index) {
145                 layer.close(index);
146                 index = layer.load(0);
147                 $.ajax({
148                     type: 'POST',
149                     url: '/ChangeIp/SaveIpConfig',
150                     data: { ip: ip, mask: mask, getWay: getWay, dns: dns, nid: nid, ipName: ipName},
151                     dataType: "json",
152                     success: function(result) {
153                         if (result != '' && result != 'undefined') {
154                             if (result.code != "200") {
155                                 layer.alert(result.msg,
156                                     {
157                                         title: '错误'
158                                     });
159                                 return;
160                             } else {
161                                 layer.alert('修改成功,请3秒后访问新的IP地址来使用系统。',
162                                     {
163                                         title: '成功'
164                                     });
165                             }
166                         }
167                         else {
168                             layer.alert('返回数据错误。', {
169                                 title: '错误'
170                             });
171                         }
172                     },
173                     complete: function(xhr, ts) {
174                         layer.close(index);
175                     }
176                 });
177                 return false;
178             });
179     }
180     function validateIP(str) {
181         var re = /^(?:(?:2[0-4][0-9]/.)|(?:25[0-5]/.)|(?:1[0-9][0-9]/.)|(?:[1-9][0-9]/.)|(?:[0-9]/.)){3}(?:(?:2[0-4][0-9])|(?:25[0-5])|(?:1[0-9][0-9])|(?:[1-9][0-9])|(?:[0-9]))$/;
182         return re.test(str);
183     }
184 </script>

后台VM实体

 1 namespace ViewModel
2 {
3     public class IPVm
4     { 
3         /// <summary>
4         /// 本地IP地址
5         /// </summary>
6         public List<IpModel> IpList { get; set; }
7     }
8 }

IpModel实体

namespace Model
{
/// <summary>
/// 获取本地IP地址信息
/// </summary>
public class IpModel
{
/// <summary>
/// IP配置文件路径
/// </summary>
public string IpConfigFile { get; set; }
/// <summary>
/// 名称
/// </summary>
public string IpName { get; set; }
/// <summary>
/// 一个随机编号
/// </summary>
public string IpGuid { get; set; }
/// <summary>
/// IPv4的地址
/// </summary>
public string Ipv4 { get; set; }
/// <summary>
/// IPv6的地址
/// </summary>
public string Ipv6 { get; set; }
/// <summary>
/// 子网掩码
/// </summary>
public string IpMask { get; set; }
/// <summary>
/// 网关地址
/// </summary>
public string IpGetWay { get; set; }
/// <summary>
/// DNS地址
/// </summary>
public string IpDns { get; set; }
}
}

后台Controller实现修改IP地址

  1 using Microsoft.AspNetCore.Mvc;
2 using Microsoft.Extensions.Logging;
3 using MidSoft.Sfrz.Model;
4 using System;
5 using System.Collections.Generic;
6 using System.Diagnostics;
7 using System.IO;
8 using System.Linq;
9 using System.Net;
10 using System.Net.NetworkInformation;
11 using System.Threading.Tasks;
12 
13 namespace Controllers
14 {
15     public class ChangeIpController : Controller
16     {
17         private readonly ILogger<CshSjkController> _logger;
18         public ChangeIpController( ILogger<CshSjkController> logger)
19         {
20             _logger = logger;
21         }
22 
23         public IActionResult Index()
24         {
25             #region 获取IP地址
26 
27             var IpList = new List<IpModel>();
28             try
29             {
30                 var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
31                 foreach (var nic in networkInterfaces)
32                 {
33                     if (string.Equals("loopback", nic.Name) || string.Equals("lo", nic.Name)) continue;
34 
35                     var ipModel = new IpModel();
36 
37                     var file = Path.Combine("/", "etc", "sysconfig", "network-scripts", $"ifcfg-{nic.Name}");//这里是网卡的配置文件名称,可能每台服务器的开头不一样,比如我这里的网卡都是ifcfg-开头的文件,记得确认一下
38 
39                     ipModel.IpConfigFile = file;
40 
41                     ipModel.IpDns = "";
42                     ipModel.IpGetWay = "";
43                     ipModel.IpMask = "";
44                     ipModel.Ipv4 = "";
45                     ipModel.Ipv6 = "";
46                     ipModel.IpName = nic.Name;
47                     ipModel.IpGuid = Guid.NewGuid().ToString("D");
48 
49                     if (System.IO.File.Exists(file))
50                     {
51                         var ipDictionary = new Dictionary<string, string>();
52 #if DEBUG
53                         _logger.LogInformation("==========IP============");
54                         _logger.LogInformation($"FilePath={file}");
55 #endif
56 
57                         using (var streamReader = new StreamReader(file))
58                         {
59                             var line = string.Empty;
60                             while ((line = streamReader.ReadLine()) != null)
61                             {
62                                 var split = line.Split('=');
63                                 if (split.Length > 1)
64                                 {
65                                     ipDictionary.Add(split[0], split[1]);
66                                 }
67                             }
68                         }
69 #if DEBUG
70                         _logger.LogInformation($"DicLength:{ipDictionary.Count}");
71                         _logger.LogInformation("==========IPEnd============");
72 #endif
73                         if (ipDictionary.Any())
74                         {
75                             if (ipDictionary.ContainsKey("NAME")) ipModel.IpName = ipDictionary["NAME"].Replace("/"", "");
76                             if (ipDictionary.ContainsKey("UUID")) ipModel.IpGuid = ipDictionary["UUID"].Replace("/"", "");
77                             if (ipDictionary.ContainsKey("IPADDR")) ipModel.Ipv4 = ipDictionary["IPADDR"].Replace("/"", "");
78                             if (ipDictionary.ContainsKey("PREFIX"))
79                             {
80                                 int.TryParse(ipDictionary["PREFIX"].Replace("/"", ""), out var ipMask);
81                                 ipMask = Math.Abs(ipMask);
82                                 if (ipMask == 0 || ipMask > 32)
83                                 {
84                                     ipModel.IpMask = "255.255.255.0";
85                                 }
86                                 else
87                                 {
88                                     var ip = Int2IpMask(ipMask);
89                                     ipModel.IpMask = $"{ip.Item1}.{ip.Item2}.{ip.Item3}.{ip.Item4}";
90                                 }
91 
92                             }
93                             if (ipDictionary.ContainsKey("GATEWAY")) ipModel.IpGetWay = ipDictionary["GATEWAY"].Replace("/"", "");
94                             if (ipDictionary.ContainsKey("DNS1")) ipModel.IpDns = ipDictionary["DNS1"].Replace("/"", "");
95                             if (ipDictionary.ContainsKey("DNS2")) ipModel.IpDns = ipDictionary["DNS2"].Replace("/"", "");
96                         }
97                     }
98 
99 
100                     IpList.Add(ipModel);
101                 }
102             }
103             catch (Exception e)
104             {
105                 _logger.LogError($"加载IP地址配置文件时出错:{e}");
106 
107             }
108 
109             #endregion
110 
111             return View(IpList);
112         }
113 
114         #region 保存服务器网卡IP配置
115         /// <summary>
116         /// 保存服务器网卡IP配置
117         /// </summary>
118         /// <returns></returns>
119         [HttpPost]
120  
121         public async Task<JsonResult> SaveIpConfig()
122         {
123             var ip = Request.Form["ip"];
124             var mask = Request.Form["mask"];
125             var getWay = Request.Form["getWay"];
126             var dns = Request.Form["dns"];
127             var nid = Request.Form["nid"];
128             var ipName = Request.Form["ipName"];
129 
130             if (string.IsNullOrWhiteSpace(ip))
131             {
132                 return new JsonResult(new { code = "300", msg = "请填写IP地址" });
133             }
134             if (!IPAddress.TryParse(ip, out _))
135             {
136                 return new JsonResult(new { code = "300", msg = "IP地址格式不正确" });
137             }
138             if (!IPAddress.TryParse(mask, out _))
139             {
140                 return new JsonResult(new { code = "300", msg = "子网掩码地址格式不正确" });
141             }
142 
143             if (string.IsNullOrEmpty(mask) || mask.ToString().Split('.').Length != 4)
144             {
145                 return null;
146             }
147 
148             var ips = mask.ToString().Split('.');
149             
150             var ipMask = 0;
151             var ip1 = Ip2Mask(ips[0]);
152             var ip2 = Ip2Mask(ips[1]);
153             var ip3 = Ip2Mask(ips[2]);
154             var ip4 = Ip2Mask(ips[3]);
155             if (ip1 == null|| ip2 == null|| ip3 == null|| ip4 == null)
156             {
157                 return new JsonResult(new { code = "300", msg = "子网掩码填写不正确" });
158             }
159 
160             ipMask = (int)ip1 + (int)ip2 + (int)ip3 + (int)ip4;
161 
162             if (ipMask == 0)
163             {
164                 return new JsonResult(new { code = "300", msg = "子网掩码填写不正确" });
165             }
166 
167             if (!string.IsNullOrWhiteSpace(getWay) && !IPAddress.TryParse(ip, out _))
168             {
169                 return new JsonResult(new { code = "300", msg = "网关地址格式不正确" });
170             }
171 
172             if (!string.IsNullOrWhiteSpace(dns) && !IPAddress.TryParse(dns, out _))
173             {
174                 return new JsonResult(new { code = "300", msg = "DNS格式不正确" });
175             }
176 
177             if (string.IsNullOrWhiteSpace(ipName))
178             {
179                 ipName = "enp1s0";
180             }
181             if (string.IsNullOrWhiteSpace(nid))
182             {
183                 nid = Guid.NewGuid().ToString("D");
184             }
185 
186             Task.Run(async () =>
187             {
188 
189                 var file = Path.Combine("/", "etc", "sysconfig", "network-scripts", $"ifcfg-{ipName}");
190                 await Task.Delay(200);
191                 try
192                 {
193                     using (var fileStream = new FileStream(file, FileMode.Create))
194                     {
195                         using (var fileStreamWriter = new StreamWriter(fileStream))
196                         {
197                             await fileStreamWriter.WriteLineAsync(@"TYPE=""Ethernet""");
198                             await fileStreamWriter.WriteLineAsync(@"PROXY_METHOD=""none""");
199                             await fileStreamWriter.WriteLineAsync(@"BROWSER_ONLY=""no""");
200                             await fileStreamWriter.WriteLineAsync(@"BOOTPROTO=""none""");
201                             await fileStreamWriter.WriteLineAsync(@"DEFROUTE=""yes""");
202                             await fileStreamWriter.WriteLineAsync(@"IPV4_FAILURE_FATAL=""no""");
203                             await fileStreamWriter.WriteLineAsync(@"IPV6INIT=""yes""");
204                             await fileStreamWriter.WriteLineAsync(@"IPV6_AUTOCONF=""yes""");
205                             await fileStreamWriter.WriteLineAsync(@"IPV6_DEFROUTE=""yes""");
206                             await fileStreamWriter.WriteLineAsync(@"IPV6_FAILURE_FATAL=""no""");
207                             await fileStreamWriter.WriteLineAsync(@"IPV6_ADDR_GEN_MODE=""stable-privacy""");
208                             await fileStreamWriter.WriteLineAsync($@"NAME=""{ipName}""");
209                             await fileStreamWriter.WriteLineAsync($@"UUID=""{nid}""");
210                             await fileStreamWriter.WriteLineAsync($@"DEVICE=""{ipName}""");
211                             await fileStreamWriter.WriteLineAsync(@"ONBOOT=""yes""");
212                             await fileStreamWriter.WriteLineAsync($@"IPADDR=""{ip}""");
213                             await fileStreamWriter.WriteLineAsync($@"PREFIX=""{ipMask}""");
214                             await fileStreamWriter.WriteLineAsync($@"GATEWAY=""{getWay}""");
215                             await fileStreamWriter.WriteLineAsync($@"DNS1=""{dns}""");
216                             await fileStreamWriter.WriteLineAsync(@"IPV6_PRIVACY=""no""");
217                         }
218                     }
219 
220                     await Process.Start("service", " network restart")?.WaitForExitAsync()!;
221                 }
222                 catch (Exception e)
223                 {
224                     _logger.LogError($"修改服务器IP地址出错:{e}");
225                 }
226 
227             });
228             return new JsonResult(new { code = "200" });
229         }
230 
231         #endregion
232 
233         #region 子网掩码位数转子网掩码IP
234 
235         private Tuple<int, int, int, int> Int2IpMask(int ipLength)
236         {
237             int ip1 = 0, ip2 = 0, ip3 = 0, ip4 = 0;
238             var tmpvar = ipLength;
239             if (tmpvar > 32 || tmpvar < 0)
240             {
241                 return null;
242             }
243 
244             if (tmpvar >= 8)
245             {
246                 ip1 = 255;
247                 tmpvar -= 8;
248             }
249             else
250             {
251                 ip1 = Int2BitMask(tmpvar);
252                 return new Tuple<int, int, int, int>(ip1, 0, 0, 0);
253             }
254             if (tmpvar >= 8)
255             {
256                 ip2 = 255;
257                 tmpvar -= 8;
258             }
259             else
260             {
261                 ip2 = Int2BitMask(tmpvar);
262                 return new Tuple<int, int, int, int>(ip1, ip2, 0, 0);
263             }
264             if (tmpvar >= 8)
265             {
266                 ip3 = 255;
267                 tmpvar -= 8;
268             }
269             else
270             {
271                 ip3 = Int2BitMask(tmpvar);
272                 return new Tuple<int, int, int, int>(ip1, ip2, ip3, 0);
273             }
274             ip4 = Int2BitMask(tmpvar);
275             return new Tuple<int, int, int, int>(ip1, ip2, ip3, ip4);
276         }
277 
278         private int Int2BitMask(int num)
279         {
280             if (num >= 8)
281             {
282                 return (255);
283             }
284             var pianyiliang = 0xff00;
285             while (num > 0)
286             {
287                 pianyiliang = pianyiliang >> 1;
288                 num--;
289             }
290             return (pianyiliang & 0xff);
291         }
292         #endregion
293 
294         #region 子网掩码IP地址转位数
295         private int? Ip2Mask(string ip)
296         {
297             int.TryParse(ip, out var num);
298             if (num == 255)
299             {
300                 return 8;
301             }
302             var pianyiliang = 0xff00;
303             var i = 0;
304             while (i < 8)
305             {
306                 if (num == (pianyiliang & 0xff))
307                 {
308                     return i;
309                 }
310                 pianyiliang >>= 1;
311                 i++;
312             }
313             return null;
314         }
315         #endregion
316     }
317 }

 

原创文章,作者:kirin,如若转载,请注明出处:https://blog.ytso.com/269412.html

(0)
上一篇 2022年6月21日
下一篇 2022年6月21日

相关推荐

发表回复

登录后才能评论