private static void RenameOldCert(MikroTikConnection con, CertificateDto[] cert, LetsEncryptCert newCert) { // Может быть несколько сертификатор с одинаковым common-name. var newCertes = con.Command("/certificate print") .Query("fingerprint", newCert.Thumbprint) .Proplist(".id,name,invalid-after") .ToArray <CertificateDto>(); foreach (var mtNewCert in newCertes) { string newName = "new_" + mtNewCert.Name; while (CertExists(con, newName)) { newName = "new_" + newName; } con.Command("/certificate set") .Attribute("numbers", mtNewCert.Id) .Attribute("name", newName) .Send(); } RenameOldMtCerts(con, cert); }
private static void PingHostAsync(MikroTikConnection con, string host, int intervalSec, CancellationToken cancellationToken) { var listener = con.Command("/ping") .Attribute("address", "SERV.LAN") .Attribute("interval", intervalSec.ToString()) .Proplist("time") .Listen(); while (!listener.IsComplete) { MikroTikResponseFrameDictionary result; try { result = listener.ListenNext(); if (cancellationToken.IsCancellationRequested) { listener.Cancel(); } } catch (MikroApiCommandInterruptedException) { // Операция прервана по запросу Cancel return; } catch (Exception) { // Обрыв соединения. return; } Console.WriteLine(result); } }
private static void AddWarning(MikroTikConnection con, string message) { Log.Information("Оставляем сообщение в логах микротика."); con.Command("/log warning") .Attribute("message", message) .Send(); }
private static void RemoveFile(MikroTikConnection con, string fileName) { Log.Information($"Удаляем файл '{fileName}' из микротика."); var res = con.Command("/file remove") .Attribute("numbers", fileName) .Send(); }
private static string MtGetFileId(MikroTikConnection con, string fileName) { string fileId = con.Command("/file print") .Query("name", fileName) .Proplist(".id") .ScalarOrDefault(); return(fileId); }
private static bool TryImport(MikroTikConnection con, string fileName) { int filesImported = con.Command("/certificate import") .Attribute("file-name", fileName) .Attribute("passphrase", "") .Scalar <int>("files-imported"); return(filesImported > 0); }
private static bool CertExists(MikroTikConnection con, string mtName) { var newCertes = con.Command("/certificate print") .Query("name", mtName) .Proplist(".id,name") .ToArray <CertificateDto>(); return(newCertes.Length > 0); }
private void CheckWanInterface(MikroTikConnection con) { Log.Information($"Проверяем что в микротике есть интерфейс '{Config.WanIface}'."); string ifaceId = con.Command("/interface print") .Query("name", Config.WanIface) .Proplist(".id") .ScalarOrDefault <string>(); if (ifaceId == null) { throw new LetsEncryptMikroTikException($"В Микротике не найден интерфейс '{Config.WanIface}'"); } }
public async Task TestCancelListenerAsync() { using (var con = new MikroTikConnection()) { await con.ConnectAsync(Login, Password, Address, Port); var listener = con.Command("/ping") .Attribute("address", "SERV.LAN") .Proplist("time") .Listen(); var task = listener.CancelAsync(); bool success = task.Wait(3000); Assert.True(success); } }
private static void RenameOldMtCerts(MikroTikConnection con, CertificateDto[] cert) { foreach (CertificateDto c in cert) { if (!c.Name.StartsWith("old_", StringComparison.Ordinal)) { string newOldName = "old_" + c.Name; while (CertExists(con, newOldName)) { newOldName = "old_" + newOldName; } con.Command("/certificate set") .Attribute("numbers", c.Id) .Attribute("name", newOldName) .Send(); } } }
private void RestoreFtp(MikroTikConnection con, bool enabledChanged, bool allowedChanged, string allowedAddresses) { if (enabledChanged || allowedChanged) { var com = con.Command("/ip service set") .Attribute("numbers", "ftp"); if (enabledChanged) { Log.Information("Выключаем FTP в микротике."); com.Attribute("disabled", "true"); } if (allowedChanged) { Log.Information($"Убираем IP {Config.ThisMachineIp} из разрешённых для FTP в микротике."); com.Attribute("address", allowedAddresses); } com.Send(); } }
private static bool TryGetExpiredAfter(MikroTikConnection con, string commonName, out TimeSpan expires, out CertificateDto[] certes) { Log.Information($"Запрашиваем у микротика информацию о сертификате с Common-Name: '{commonName}'."); // Может быть несколько сертификатор с одинаковым common-name. certes = con.Command("/certificate print") .Query("common-name", commonName) .Proplist(".id,name,invalid-after") .ToArray <CertificateDto>(); DateTime?invalidAfter = certes.Select(x => new { Cert = x, InvalidAfter = (DateTime?)DateTime.Parse(x.InvalidAfter, CultureInfo.InvariantCulture) }) .DefaultIfEmpty() .Min(x => x?.InvalidAfter); if (invalidAfter != null) { expires = invalidAfter.Value - DateTime.Now; return(true); } expires = default; return(false); }
private static async Task Main() { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // Support localized comments. MikroTikConnection.DefaultEncoding = Encoding.GetEncoding("windows-1251"); // RUS using (var con = new MikroTikConnection(Encoding.GetEncoding("windows-1251"))) { con.Connect("api_dbg", "debug_password", "10.0.0.1"); var leases = con.Command("/ip dhcp-server lease print") .Query("disabled", "false") // filter .Proplist("address", "mac-address", "host-name", "status") .Send(); con.Quit(1000); } //// Отправляет запрос без получения результата. //var listener = con.Command("/ping") // .Attribute("address", "SERV.LAN") // .Attribute("interval", "1") // .Attribute("count", "4") // .Proplist("time") // .Listen(); //// сервер будет присылать результат каждую секунду. //while (!listener.IsComplete) //{ // MikroTikResponseFrame result; // try // { // result = listener.ListenNext(); // } // catch (MikroTikDoneException) // { // break; // } // Console.WriteLine(result); // listener.Cancel(true); //} //var logListener = con.Command("/log listen") // .Listen(); //while (!logListener.IsComplete) //{ // try // { // logListener.ListenNext(); // } // catch (TimeoutException) // { // } // var entry = logListener.ListenNext(); // Console.WriteLine(entry); //} //// Вытащить активные сессии юзера. //var activeSessionsResult = con.Command("/ip hotspot active print") // .Proplist(".id") // .Query("user", "2515") // .Send(); //string[] activeSessions = activeSessionsResult.ScalarArray(".id"); //Thread.Sleep(-1); //resultPrint.Scalar(""); //resultPrint.ScalarList(); //resultPrint.ScalarOrDefault(); //var sw = Stopwatch.StartNew(); //for (int i = 0; i < 500_000; i++) //{ // resultPrint.ToArray(new { }); // resultPrint.ScalarList<int>(); // var row = resultPrint.ToList<InterfaceDto>(); //} //sw.Stop(); //Trace.WriteLine(sw.Elapsed); //Console.WriteLine("OK"); //Thread.Sleep(-1); // Команда выполняется 20 сек. //var task = con.Command("/delay") // .Attribute("delay-time", "20") // .Send(); // Tell router we are done. //con.Quit(1000); }
private string MtAllowPortFilter(int dstPort, int publicPort) { Log.Information($"Создаём правило разрешающее соединения на {publicPort} порт в фаерволе микротика."); string id = _mtCon.Command("/ip firewall filter add") .Attribute("chain", "forward") .Attribute("dst-address", _thisMachineIp.ToString()) .Attribute("protocol", "tcp") .Attribute("dst-port", $"{dstPort}") .Attribute("in-interface", _config.WanIface) .Attribute("action", "accept") .Attribute("disabled", "true") .Attribute("comment", "Let's Encrypt challenge") .Scalar <string>(); Log.Information("Получаем список всех статичных правил фаервола микротика."); // Список всех правил. string[] ids = _mtCon.Command("/ip firewall filter print") .Query("dynamic", "false") .Proplist(".id") .ScalarArray <string>(); // Передвинуть правило в самое начало. if (ids.Length > 1) { Log.Information("Перемещаем наше правило фаервола в самое начало."); _mtCon.Command("/ip firewall filter move") .Attribute("numbers", id) // что переместить. .Attribute("destination", ids[0]) // перед чем. .Send(); } Log.Information("Включаем правило фаервола."); // Включить правило. _mtCon.Command("/ip firewall filter set") .Attribute(".id", id) .Attribute("disabled", "false") .Send(); return(id); }
//private void RemoveExisted(MikroTikConnection con, string commonName) //{ // Log.Information($"Запрашиваем у микротика сертификат с Common-Name: '{commonName}'."); // // Может быть несколько сертификатор с одинаковым common-name. // string[] invalidAfterRaw = con.Command("/certificate print") // .Query("common-name", commonName) // .Proplist(".id") // .ScalarArray<string>(); // if (invalidAfterRaw.Length > 0) // { // Log.Information($"Удаляем существующий сертификат из микротика."); // foreach (string id in invalidAfterRaw) // { // con.Command("/certificate remove") // .Attribute(".id", id) // .Send(); // } // } //} private void EnableFtp(MikroTikConnection con, out int ftpPort, out bool enabledChanged, out bool allowedChanged, out string allowedAddresses) { var ftpService = con.Command("/ip service print") .Query("name", "ftp") .Proplist("disabled,port,address") .Single <IpService>(); ftpPort = ftpService.Port; allowedAddresses = ftpService.Address; bool connectionAllowed = true; if (ftpService.Addresses != null) { connectionAllowed = ftpService.Addresses.Any(x => { if (string.IsNullOrEmpty(x)) { return(true); } string[] parts = x.Split('/'); var ipAddress = IPAddress.Parse(parts[0]); int netMask = int.Parse(parts[1], CultureInfo.InvariantCulture); return(IsInRange(Config.ThisMachineIp, ipAddress, netMask)); }); } if (ftpService.Disabled || !connectionAllowed) { if (ftpService.Disabled) { enabledChanged = true; Log.Warning("В микротике выключен FTP. Временно включаем его."); } else { enabledChanged = false; } string address = ftpService.Address; if (!connectionAllowed) { allowedChanged = true; Log.Warning($"В микротике доступ к FTP с адреса {Config.ThisMachineIp} не разрешён. Временно разрешаем."); address += $",{Config.ThisMachineIp}/32"; } else { allowedChanged = true; } con.Command("/ip service set") .Attribute("numbers", "ftp") .Attribute("disabled", "false") .Attribute("address", address) .Send(); } else { allowedChanged = false; enabledChanged = false; } }