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 }

 

posted @ 2022-06-21 10:24  踏平扶桑  阅读(214)  评论(0编辑  收藏  举报