static int SslCertListCollector(ConsoleService c, string cmdName, string str) { ConsoleParam[] args = { new ConsoleParam("[dnsZonesDir]", ConsoleService.Prompt, "dnsZonesDir: ", ConsoleService.EvalNotEmpty, null), new ConsoleParam("OUT", ConsoleService.Prompt, "outDir: ", ConsoleService.EvalNotEmpty, null), new ConsoleParam("HASH"), }; ConsoleParamValueList vl = c.ParseCommandList(cmdName, str, args); string dirZonesDir = vl.DefaultParam.StrValue; string outDir = vl["OUT"].StrValue; string hashliststr = vl["HASH"].StrValue; string[] hashlist = hashliststr._Split(StringSplitOptions.RemoveEmptyEntries, ";", "/", ",", ":", " "); var dirList = Lfs.EnumDirectory(dirZonesDir, false); if (dirList.Where(x => x.IsFile && (IgnoreCaseTrim)Lfs.PathParser.GetExtension(x.Name) == ".dns").Any() == false) { // 指定されたディレクトリに *.dns ファイルが 1 つもない場合は子ディレクトリ名をソートして一番大きいものを選択する dirZonesDir = dirList.OrderByDescending(x => x.Name).Where(x => x.IsDirectory).Select(x => x.FullPath).First(); } Con.WriteLine($"Target directory: '{dirZonesDir}'"); // 1. DNS ゾーンファイルを入力してユニークな FQDN レコードの一覧を生成する DnsFlattenUtil flat = new DnsFlattenUtil(); foreach (FileSystemEntity ent in Lfs.EnumDirectory(dirZonesDir, true)) { if (ent.IsFile) { string fn = ent.FullPath; fn._Print(); flat.InputZoneFile(Lfs.PathParser.GetFileNameWithoutExtension(fn), Lfs.ReadDataFromFile(fn).Span); } } // 2. FQDN の一覧を入力して FQDN と IP アドレスのペアの一覧を生成する DnsIpPairGeneratorUtil pairGenerator = new DnsIpPairGeneratorUtil(100, flat.FqdnSet); List <SniHostnameIpAddressPair> list = pairGenerator.ExecuteAsync()._GetResult().ToList(); // 3. FQDN と IP アドレスのペアの一覧を入力して SSL 証明書一覧を出力する SslCertCollectorUtil col = new SslCertCollectorUtil(1000, list); IReadOnlyList <SslCertCollectorItem> ret = col.ExecuteAsync()._GetResult(); if (hashlist.Length >= 1) { List <SslCertCollectorItem> filtered = new List <SslCertCollectorItem>(); ret.Where(x => hashlist.Where(y => y._IsSameHex(x.CertHashSha1)).Any())._DoForEach(x => filtered.Add(x)); ret = filtered; } ret = ret.OrderBy(x => x.FriendName._NonNullTrim()._Split(StringSplitOptions.RemoveEmptyEntries, ".").Reverse()._Combine("."), StrComparer.IgnoreCaseTrimComparer).ToList(); // 結果表示 Con.WriteLine($"Results: {ret.Count} endpoints"); // 結果保存 string csv = ret._ObjectArrayToCsv(withHeader: true); XmlAndXsd xmlData = Util.GenerateXmlAndXsd(ret); string dir = outDir; Lfs.WriteDataToFile(Lfs.PathParser.Combine(dir, xmlData.XmlFileName), xmlData.XmlData, flags: FileFlags.AutoCreateDirectory); Lfs.WriteDataToFile(Lfs.PathParser.Combine(dir, xmlData.XsdFileName), xmlData.XsdData, flags: FileFlags.AutoCreateDirectory); Lfs.WriteStringToFile(Lfs.PathParser.Combine(dir, "csv.csv"), csv, flags: FileFlags.AutoCreateDirectory, writeBom: true); return(0); }
public static CactiTask LoadFromFile(string filename) => LoadFromData(Lfs.ReadDataFromFile(filename).Span);
static int SslCertChecker(ConsoleService c, string cmdName, string str) { ConsoleParam[] args = { new ConsoleParam("[dnsZonesDir]", ConsoleService.Prompt, "dnsZonesDir: ", ConsoleService.EvalNotEmpty, null), }; ConsoleParamValueList vl = c.ParseCommandList(cmdName, str, args); string dirZonesDir = vl.DefaultParam.StrValue;//@"C:\Users\yagi\Desktop\dnstest";// var dirList = Lfs.EnumDirectory(dirZonesDir, false); if (dirList.Where(x => x.IsFile && (IgnoreCaseTrim)Lfs.PathParser.GetExtension(x.Name) == ".dns").Any() == false) { // 指定されたディレクトリに *.dns ファイルが 1 つもない場合は子ディレクトリ名をソートして一番大きいものを選択する dirZonesDir = dirList.OrderByDescending(x => x.Name).Where(x => x.IsDirectory).Select(x => x.FullPath).First(); } //Con.WriteLine($"Target directory: '{dirZonesDir}'"); // 1. DNS ゾーンファイルを入力してユニークな FQDN レコードの一覧を生成する DnsFlattenUtil flat = new DnsFlattenUtil(); foreach (FileSystemEntity ent in Lfs.EnumDirectory(dirZonesDir, true)) { if (ent.IsFile) { string fn = ent.FullPath; //fn._Print(); flat.InputZoneFile(Lfs.PathParser.GetFileNameWithoutExtension(fn), Lfs.ReadDataFromFile(fn).Span); } } // 2. FQDN の一覧を入力して FQDN と IP アドレスのペアの一覧を生成する DnsIpPairGeneratorUtil pairGenerator = new DnsIpPairGeneratorUtil(100, flat.FqdnSet); List <SniHostnameIpAddressPair> list = pairGenerator.ExecuteAsync()._GetResult().ToList(); List <int> ports_FastDebug = new(); ports_FastDebug.Add(443); // 3. FQDN と IP アドレスのペアの一覧を入力して SSL 証明書一覧を出力する SslCertCollectorUtil col = new SslCertCollectorUtil(1000, list, new SslCertCollectorUtilSettings { //TryCount = 1, //PotentialHttpsPorts = portsTmp, DoNotIgnoreLetsEncrypt = true, Silent = true, }); long startTick = Time.Tick64; IReadOnlyList <SslCertCollectorItem> ret = col.ExecuteAsync()._GetResult(); long endTick = Time.Tick64; DateTimeOffset now = DtOffsetNow; DateTimeOffset threshold2 = now.AddDays(20); // 証明書が古くなっていれば警告を出す // IP アドレスごとに整理 SortedDictionary <string, List <SslCertCollectorItem> > dictSoon = new SortedDictionary <string, List <SslCertCollectorItem> >(StrComparer.IpAddressStrComparer); SortedDictionary <string, List <SslCertCollectorItem> > dictExpired = new SortedDictionary <string, List <SslCertCollectorItem> >(StrComparer.IpAddressStrComparer); foreach (var item in ret.Where(x => x.IpAddress._IsFilled())) { var span = item.CertNotAfter - item.CertNotBefore; // もともと有効期限が 約 3 年間よりも長い証明書が登録されている場合は、意図的に登録されているオレオレ証明書であるので、更新対象としてマークしない if (span < Consts.Numbers.MaxCertExpireSpanTargetForUpdate) { // 古いかどうか確認 if (item.CertNotAfter < threshold2) { if (item.CertNotAfter < now) { // すでに有効期限超過 var o = dictExpired._GetOrNew(item.IpAddress !, () => new List <SslCertCollectorItem>()); o.Add(item); } else { // 有効期限 間もなく var o = dictSoon._GetOrNew(item.IpAddress !, () => new List <SslCertCollectorItem>()); o.Add(item); } } } } dictSoon.Values._DoForEach(x => x._DoSortBy(x => x.OrderBy(x => x.FriendName, StrComparer.FqdnReverseStrComparer).OrderBy(x => x.SniHostName, StrComparer.FqdnReverseStrComparer).OrderBy(x => x.Port))); int soonHosts = dictSoon.Count(); int expiredHosts = dictExpired.Count(); Con.WriteLine(); Con.WriteLine("----"); if (soonHosts >= 1) { Con.WriteLine($"Result: WARNING: Total {soonHosts} host's SSL certificates are expiring soon. Please check!", flags: LogFlags.Heading); } else { Con.WriteLine($"Result: OK: No host's SSL certificates are expiring soon. Good.", flags: LogFlags.Heading); } Con.WriteLine("", flags: LogFlags.Heading); if (expiredHosts >= 1) { Con.WriteLine($"Result: Info: Total {expiredHosts} host's SSL certificates are already expired.", flags: LogFlags.Heading); } else { Con.WriteLine($"Result: Info: No host's SSL certificates are already expired.", flags: LogFlags.Heading); } Con.WriteLine("", flags: LogFlags.Heading); Con.WriteLine($" Total SniHostnameIpAddressPairs: {list.Count._ToString3()}", flags: LogFlags.Heading); Con.WriteLine($" Total SslCertCollectorItems: {ret.Count._ToString3()}", flags: LogFlags.Heading); Con.WriteLine($" Took time: {(endTick - startTick)._ToTimeSpanMSecs()._ToTsStr()}", flags: LogFlags.Heading); Con.WriteLine(); if (soonHosts >= 1) { CoresLib.Report_SimpleResult += $" (WARN! Expiring Soon: {soonHosts} hosts)"; Con.WriteLine(); Con.WriteLine("=========== WARN: Expiring Soon Hosts Summary ==========="); int index = 0; foreach (var host in dictSoon) { string ip = host.Key; string fqdns = host.Value.Select(x => x.FriendName).Distinct(StrCmpi)._OrderByValue(StrComparer.FqdnReverseStrComparer)._Combine(", "); index++; Con.WriteLine($"Host #{index}/{dictSoon.Count}: IP = '{ip}', FQDNs = '{fqdns}'"); } Con.WriteLine(); } if (expiredHosts >= 1) { Con.WriteLine(); Con.WriteLine("=========== INFO: Already Expired Hosts Summary ==========="); int index = 0; foreach (var host in dictExpired) { string ip = host.Key; string fqdns = host.Value.Select(x => x.FriendName).Distinct(StrCmpi)._OrderByValue(StrComparer.FqdnReverseStrComparer)._Combine(", "); index++; Con.WriteLine($"Host #{index}/{dictExpired.Count}: IP = '{ip}', FQDNs = '{fqdns}'"); } Con.WriteLine(); } if (soonHosts >= 1) { string printStr = dictSoon._ObjectToJson(); Con.WriteLine(); Con.WriteLine("=========== WARN: Expiring Soon Certificates Details ==========="); Con.WriteLine(printStr); Con.WriteLine(); } if (expiredHosts >= 1) { string printStr = dictExpired._ObjectToJson(); Con.WriteLine(); Con.WriteLine("=========== INFO: Already Expired Certificates Details ==========="); Con.WriteLine(printStr); Con.WriteLine(); } return(0); }