public AuthorizedKeysModule() { Post["/ak/create"] = x => { string remoteUser = Request.Form.RemoteUser; string user = Request.Form.User; string key = Request.Form.Key; var model = new AuthorizedKeyModel { RemoteUser = remoteUser, User = user, KeyValue = key }; var authorizedKeysConfiguration = new AuthorizedKeysConfiguration(); authorizedKeysConfiguration.AddKey(model); var home = user == "root" ? "/root/.ssh" : $"/home/{user}/.ssh"; var authorizedKeysPath = $"{home}/authorized_keys"; if (!File.Exists(authorizedKeysPath)) { File.Create(authorizedKeysPath); } var line = $"{key} {remoteUser}"; File.AppendAllLines(authorizedKeysPath, new List <string> { line }); var bash = new Bash(); bash.Execute($"chmod 600 {authorizedKeysPath}", false); bash.Execute($"chown {user}:{user} {authorizedKeysPath}", false); return(HttpStatusCode.OK); }; Get["/ak/introduce"] = x => { var remoteHost = Request.Query.Host; var remoteUser = $"{Environment.UserName}@{Environment.MachineName}"; Console.WriteLine(remoteUser); string user = Request.Query.User; string key = Request.Query.Key; var dict = new Dictionary <string, string> { { "RemoteUser", remoteUser }, { "User", user }, { "Key", key } }; var r = new ApiConsumer().Post($"http://{remoteHost}/ak/create", dict); return(r); }; Post["/ak/introduce"] = x => { var remoteHost = Request.Form.Host; var remoteUser = $"{Environment.UserName}@{Environment.MachineName}"; Console.WriteLine(remoteUser); string user = Request.Form.User; string key = Request.Form.Key; var dict = new Dictionary <string, string> { { "RemoteUser", remoteUser }, { "User", user }, { "Key", key } }; var r = new ApiConsumer().Post($"http://{remoteHost}/ak/create", dict); return(r); }; }
public void AddKey(AuthorizedKeyModel model) { var zones = _serviceModel.Keys; zones.Add(model); _serviceModel.Keys = zones; Save(_serviceModel); }
public AssetClusterModule() { Get["/cluster"] = x => { var syncedMachines = ClusterConfiguration.GetNodes(); var config = ClusterConfiguration.GetClusterInfo(); foreach (var node in syncedMachines) { var services = _api.Get <List <RssdpServiceModel> >(node.ModelUrl + "device/services"); node.Services = services; } var importPortMapping = syncedMachines .Select(_ => _.Services) .Merge() .Select(_ => _.Name) .ToHashSet() .Select(_ => new Cluster.PortMapping { ServiceName = _, ServicePort = "", VirtualPort = "" }) .ToList() ; var existingPortMapping = config.PortMapping.ToList(); foreach (var i in importPortMapping) { if (existingPortMapping.FirstOrDefault(_ => _.ServiceName == i.ServiceName) == null) { existingPortMapping.Add(i); } } config.PortMapping = existingPortMapping.ToList(); var model = new PageAssetClusterModel { Info = config, ClusterNodes = syncedMachines.OrderBy(_ => _.Hostname).ThenBy(_ => _.PublicIp).ToList(), NetworkAdapters = IPv4.GetAllLocalDescription().ToList() }; return(JsonConvert.SerializeObject(model)); }; Post["/cluster/save"] = x => { string config = Request.Form.Config; string ip = Request.Form.Ip; var model = JsonConvert.DeserializeObject <List <NodeModel> >(config); var model2 = JsonConvert.DeserializeObject <Cluster.Configuration>(ip); ClusterConfiguration.SaveNodes(model); ClusterConfiguration.SaveConfiguration(model2); new Do().ClusterChanges(); DeployClusterConfiguration(); return(HttpStatusCode.OK); }; Post["Accept Configuration", "/cluster/accept"] = x => { string file = Request.Form.File; string content = Request.Form.Content; if (string.IsNullOrEmpty(file)) { return(HttpStatusCode.BadRequest); } if (string.IsNullOrEmpty(content)) { return(HttpStatusCode.BadRequest); } ConsoleLogger.Log($"[cluster] received config for file: {file}"); DirectoryWatcherCluster.Stop(); try { FileWithAcl.WriteAllText(file, content, "644", "root", "wheel"); } catch (Exception) { ConsoleLogger.Warn(""); DirectoryWatcherCluster.Start(); return(HttpStatusCode.InternalServerError); } DirectoryWatcherCluster.Start(); var dict = Dicts.DirsAndServices; if (dict.ContainsKey(file)) { ConsoleLogger.Log("[cluster] restart service bind to config file"); var services = dict[file]; foreach (var svc in services) { Systemctl.Enable(svc); Systemctl.Restart(svc); } } ConsoleLogger.Log("[cluster] apply changes after new config"); new Do().HostChanges(); new Do().NetworkChanges(); DeployClusterConfiguration(); return(HttpStatusCode.OK); }; #region [ Handshake + cluster init ] Post["/asset/handshake/start", true] = async(x, ct) => { string conf = Request.Form.HostJson; var remoteNode = JsonConvert.DeserializeObject <NodeModel>(conf); if (remoteNode == null) { return(HttpStatusCode.InternalServerError); } const string pathToPrivateKey = "/root/.ssh/id_rsa"; const string pathToPublicKey = "/root/.ssh/id_rsa.pub"; if (!File.Exists(pathToPublicKey)) { var k = Bash.Execute($"ssh-keygen -t rsa -N '' -f {pathToPrivateKey}"); ConsoleLogger.Log(k); } var key = File.ReadAllText(pathToPublicKey); if (string.IsNullOrEmpty(key)) { return(HttpStatusCode.InternalServerError); } var dict = new Dictionary <string, string> { { "ApplePie", key } }; var r = new ApiConsumer().Post($"{remoteNode.ModelUrl}asset/handshake", dict); if (r != HttpStatusCode.OK) { return(HttpStatusCode.InternalServerError); } //ho fatto l'handshake, quindi il nodo richiesto è pronto per essere integrato nel cluster //1. controllo la configurazione var clusterConfiguration = ClusterConfiguration.GetClusterInfo(); if (string.IsNullOrEmpty(clusterConfiguration.Guid)) { clusterConfiguration.Guid = Guid.NewGuid().ToString(); } if (string.IsNullOrEmpty(clusterConfiguration.Priority)) { clusterConfiguration.Priority = "100"; } if (string.IsNullOrEmpty(clusterConfiguration.NetworkInterface)) { clusterConfiguration.NetworkInterface = ""; } if (string.IsNullOrEmpty(clusterConfiguration.VirtualIpAddress)) { clusterConfiguration.VirtualIpAddress = ""; } //2. salvo la configurazione ClusterConfiguration.SaveConfiguration(clusterConfiguration); //3. controllo i nodi presenti nella configurazione var clusterNodes = ClusterConfiguration.GetNodes(); var iplocals = IPv4.GetAllLocalAddress().ToList(); var disc = await ServiceDiscovery.Rssdp.Discover(); //4. per prima cosa controllo l'host locale var localNode = disc.FirstOrDefault(_ => iplocals.Contains(_.PublicIp)); //5. se non c'è lo aggiungo if (clusterNodes.FirstOrDefault(_ => _.MachineUid == localNode.MachineUid && _.PublicIp == localNode.PublicIp) == null) { clusterNodes.Add(localNode); } //7. se non c'è lo aggiungo if (clusterNodes.FirstOrDefault(_ => _.MachineUid == remoteNode.MachineUid && _.PublicIp == remoteNode.PublicIp) == null) { clusterNodes.Add(remoteNode); } //8. salvo la configurazione dei nodi ClusterConfiguration.SaveNodes(clusterNodes); //9. riavvio/avvio il servizio di cluster new Do().ClusterChanges(); DeployClusterConfiguration(); return(HttpStatusCode.OK); }; Post["/asset/handshake"] = x => { string apple = Request.Form.ApplePie; var info = apple.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); if (info.Length < 2) { return(HttpStatusCode.InternalServerError); } var key = info[0]; var remoteUser = info[1]; const string user = "******"; var model = new AuthorizedKeyModel { RemoteUser = remoteUser, User = user, KeyValue = key }; var authorizedKeysConfiguration = new AuthorizedKeysConfiguration(); authorizedKeysConfiguration.AddKey(model); try { DirectoryWithAcl.CreateDirectory("/root/.ssh"); const string authorizedKeysPath = "/root/.ssh/authorized_keys"; if (File.Exists(authorizedKeysPath)) { var f = File.ReadAllText(authorizedKeysPath); if (!f.Contains(apple)) { FileWithAcl.AppendAllLines(authorizedKeysPath, new List <string> { apple }, "644", "root", "wheel"); } } else { FileWithAcl.WriteAllLines(authorizedKeysPath, new List <string> { apple }, "644", "root", "wheel"); } Bash.Execute($"chmod 600 {authorizedKeysPath}", false); Bash.Execute($"chown {user}:{user} {authorizedKeysPath}", false); return(HttpStatusCode.OK); } catch (Exception ex) { ConsoleLogger.Log(ex); return(HttpStatusCode.InternalServerError); } }; Post["/cluster/deploy"] = x => { var clusterConfiguration = Request.Form.Cluster; Cluster.DeployConf model = Newtonsoft.Json.JsonConvert.DeserializeObject <Cluster.DeployConf>(clusterConfiguration); ClusterConfiguration.SaveConfiguration(model.Configuration); ClusterConfiguration.SaveNodes(model.Nodes); new Do().ClusterChanges(); return(HttpStatusCode.OK); }; //Post["/asset/wol"] = x => { // string mac = Request.Form.MacAddress; // CommandLauncher.Launch("wol", new Dictionary<string, string> { { "$mac", mac } }); // return HttpStatusCode.OK; //}; //Get["/asset/nmasp/{ip}"] = x => { // string ip = x.ip; // var result = CommandLauncher.Launch("nmap-ip-fast", new Dictionary<string, string> { { "$ip", ip } }).Where(_ => !_.Contains("MAC Address")).Skip(5).Reverse().Skip(1).Reverse(); // var list = new List<NmapScanStatus>(); // foreach(var r in result) { // var a = r.SplitToList(" ").ToArray(); // var mo = new NmapScanStatus { // Protocol = a[0], // Status = a[1], // Type = a[2] // }; // list.Add(mo); // } // list = list.OrderBy(_ => _.Protocol).ToList(); // return JsonConvert.SerializeObject(list); //}; #endregion }
public AssetDiscoveryModule() { Get["/discovery"] = x => { var avahiBrowse = new AvahiBrowse(); avahiBrowse.DiscoverService("antd"); var localServices = avahiBrowse.Locals; var launcher = new CommandLauncher(); var list = new List <AvahiServiceViewModel>(); var kh = new SshKnownHosts(); foreach (var ls in localServices) { var arr = ls.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries); var mo = new AvahiServiceViewModel { HostName = arr[0].Trim(), Ip = arr[1].Trim(), Port = arr[2].Trim(), MacAddress = "" }; launcher.Launch("ping-c", new Dictionary <string, string> { { "$ip", arr[1].Trim() } }); var result = launcher.Launch("arp", new Dictionary <string, string> { { "$ip", arr[1].Trim() } }).ToList(); if (result.Any()) { var mac = result.LastOrDefault().Print(3, " "); mo.MacAddress = mac; } mo.IsKnown = kh.Hosts.Contains(arr[1].Trim()); list.Add(mo); } var model = new PageAssetDiscoveryModel { AntdAvahiServices = list }; return(JsonConvert.SerializeObject(model)); }; Post["/asset/handshake/start"] = x => { var hostIp = Request.Form.Host; var hostPort = Request.Form.Port; const string pathToPrivateKey = "/root/.ssh/id_rsa"; const string pathToPublicKey = "/root/.ssh/id_rsa.pub"; if (!File.Exists(pathToPublicKey)) { var bash = new Bash(); var k = bash.Execute($"ssh-keygen -t rsa -N '' -f {pathToPrivateKey}"); ConsoleLogger.Log(k); } var key = File.ReadAllText(pathToPublicKey); if (string.IsNullOrEmpty(key)) { return(HttpStatusCode.InternalServerError); } var dict = new Dictionary <string, string> { { "ApplePie", key } }; var r = new ApiConsumer().Post($"http://{hostIp}:{hostPort}/asset/handshake", dict); var kh = new SshKnownHosts(); kh.Add(hostIp); return(r); }; Post["/asset/handshake"] = x => { string apple = Request.Form.ApplePie; var info = apple.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); if (info.Length < 2) { return(HttpStatusCode.InternalServerError); } var key = info[0]; var remoteUser = info[1]; const string user = "******"; var model = new AuthorizedKeyModel { RemoteUser = remoteUser, User = user, KeyValue = key }; var authorizedKeysConfiguration = new AuthorizedKeysConfiguration(); authorizedKeysConfiguration.AddKey(model); try { Directory.CreateDirectory("/root/.ssh"); const string authorizedKeysPath = "/root/.ssh/authorized_keys"; if (File.Exists(authorizedKeysPath)) { var f = File.ReadAllText(authorizedKeysPath); if (!f.Contains(apple)) { File.AppendAllLines(authorizedKeysPath, new List <string> { apple }); } } else { File.WriteAllLines(authorizedKeysPath, new List <string> { apple }); } var bash = new Bash(); bash.Execute($"chmod 600 {authorizedKeysPath}", false); bash.Execute($"chown {user}:{user} {authorizedKeysPath}", false); return(HttpStatusCode.OK); } catch (Exception ex) { ConsoleLogger.Log(ex); return(HttpStatusCode.InternalServerError); } }; Post["/asset/wol"] = x => { string mac = Request.Form.MacAddress; var launcher = new CommandLauncher(); launcher.Launch("wol", new Dictionary <string, string> { { "$mac", mac } }); return(HttpStatusCode.OK); }; Get["/asset/nmap/{ip}"] = x => { string ip = x.ip; var launcher = new CommandLauncher(); var result = launcher.Launch("nmap-ip-fast", new Dictionary <string, string> { { "$ip", ip } }).Where(_ => !_.Contains("MAC Address")).Skip(5).Reverse().Skip(1).Reverse(); var list = new List <NmapScanStatus>(); foreach (var r in result) { var a = r.SplitToList(" ").ToArray(); var mo = new NmapScanStatus { Protocol = a[0], Status = a[1], Type = a[2] }; list.Add(mo); } list = list.OrderBy(_ => _.Protocol).ToList(); return(JsonConvert.SerializeObject(list)); }; }