Why is my Azure public IP not showing up in Dns.GetHostAddresses? - c#

I'm trying to set up a custom server on an Azure VM. I've assigned it a public IP address, which I'm able to reach and get into the server via Remote Desktop, so that part's working just fine.
But when I try to bind to the public IP address using the websocket-sharp library, it fails, saying "the host part isn't a local host name."
I've tracked this down to this file, where the following code block executes, and ends up returning false:
var host = System.Net.Dns.GetHostName ();
var addrs = System.Net.Dns.GetHostAddresses (host);
foreach (var addr in addrs) {
if (address.Equals (addr))
return true;
}
return false;
With a bit of debugging, I've determined that Dns.GetHostAddresses is showing internal IPs only, but not the external IP address. I've configured the IP address in Azure and attached it to the server, and I've turned on IP forwarding in the networking configuration and rebooted the VM, but the server still doesn't recognize its own external IP.
What am I missing?

What am I missing?
You could test Dns.GetHostAddresses with the local machine hostname, it also just could get the internal ip, it is not related to Azure VM.
If we want to get the public Ip of Azure VM with host name, we could use the Azure SDK to do that.
I also do a sample demo to get the public IP. Before that we need to registry Azure AD and assign corrosponding role to registried App. About how to registry Azure AD and create creditial file, you could refer to another SO thread and this link.
var subscriptiondId = "subscription Id";
var credentials = SdkContext.AzureCredentialsFactory.FromFile(#"path of creditial file");
var resouceGroup = "resouce group";
var hostName = "host name";
NetworkManagementClient networkManagement = new NetworkManagementClient(credentials) { SubscriptionId = subscriptiondId };
ComputeManagementClient computeManagement =
new ComputeManagementClient(credentials) {SubscriptionId = subscriptiondId};
var nic = computeManagement.VirtualMachines.GetAsync(resouceGroup, hostName).Result.NetworkProfile.NetworkInterfaces
.FirstOrDefault();
var networkIntefaceName = nic?.Id.Split('/').Last();
var ipConfiguration = networkManagement.NetworkInterfaces.GetAsync(resouceGroup, networkIntefaceName).Result.IpConfigurations.FirstOrDefault();
var publicIpAddressId = ipConfiguration?.PublicIPAddress.Id;
var ip = networkManagement.PublicIPAddresses.GetAsync(resouceGroup, publicIpAddressId?.Split('/').Last()

Related

How to get client machine name during login. C# MVC

I tried this link in stackoverflow but not getting the client's name.
clientHostName = clientIpAddress = string.Empty;
try
{
clientIpAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(clientIpAddress))
{
clientIpAddress = Request.ServerVariables["REMOTE_ADDR"];
}
System.Net.IPAddress myIP = System.Net.IPAddress.Parse(clientIpAddress);
System.Net.IPHostEntry GetIPHost = System.Net.Dns.GetHostEntry(myIP);
clientHostName = GetIPHost.HostName; // Working in dev environment. Moving to QA env this is returning null
}
catch { }
Take a look at blowdarts answer in the post you linked. It is not possible to get the machine name of remote machines this way. If you are in control of the client application you may try to make the client explicitly send it's machine name instead.

How to get client ipaddress and device name who logs in to my website using c#

I have searched and read almost every article related to my search about how to get client ipaddress and machine name but all the codes return only server ip and name. I've tried these codes also given below, it gives my PC ip on localhost but on the server, it gives server ip and name :
string stringHostName = Dns.GetHostName();
IPHostEntry ipHostEntries = Dns.GetHostEntry(stringHostName);
and also used this method :
public string GetUserIPAddress()
{
System.Web.HttpContext context = System.Web.HttpContext.Current;
string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDER_FOR"];
if (!string.IsNullOrEmpty(ipAddress))
{
string[] addresses = ipAddress.Split(',');
if (addresses.Length != 0)
{
return addresses[0];
}enter code here
}
return context.Request.ServerVariables["REMOTE_ADDR"];
}
It gives ::1 on localhost but on the server it gives server ip only.
Kindly help me if there any way possible to get client ipaddress and machine name using C#.

Check service status remotely

I need to grab the service status (running, stopped) remotely using the credentials of the user running my executable(winform).
Would WMI be the best method?
I need this query to work on windows(7,2003,2008,2012).Can someone point me in the right direction.
if (RemoteOSversion.Contains("Windows 7"))
{
var Windows7Query = xdoc.Elements("OS").Elements("Windows7");
foreach (var myServices in Windows7Query)
{
var ServicesQuery = myServices.Elements("Services");
foreach (var ServiceName in ServicesQuery)
{
var ServiceOutput = ServiceName.Value;
}
}
}
ServiceOutput is the service name. I need to check if this service is running/stopped remotely using the same credentials of the user running my exe
It's REALLY straightforward with WMI
var sc = new ServiceController(ServiceName, MachineName);
string result = sc.Status.ToString();
Yes, use WMI.
WMI has a query language called WQL, which is similar to to SQL. You can execute these in C# using the System.Management classes.
To work with WMI you need to add a reference to the System.Management assembly. Then you can set up a connection (i.e. ManagementScope) to the WMI Provider as follows:
ConnectionOptions options = new ConnectionOptions();
// If we are connecting to a remote host and want to
// connect as a different user, we need to set some options
//options.Username =
//options.Password =
//options.Authority =
//options.EnablePrivileges =
// If we are connecting to a remote host, we need to specify the hostname:
//string providerPath = #"\\Hostname\root\CIMv2";
string providerPath = #"root\CIMv2";
ManagementScope scope = new ManagementScope(providerPath, options);
scope.Connect();
You can read more about WMI at Microsoft Docs and work around at working-with-windows-services-using-csharp-and-wmi.

Programmatically access to TFS 2010 from outside the domain

I'm trying to access my TFS server programmatically from outside the domain where the server is installed. A basic test program would look like this :
class Program
{
static void Main(string[] args)
{
Uri tfsUri = new Uri("<serverUri>");
TfsConfigurationServer _ConfigurationServer = TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
CatalogNode projectCollectionCatalog = _ConfigurationServer.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None)[0]; // actual connection tries to happen here
}
}
Another version, with credentials forced :
class Program
{
static void Main(string[] args)
{
Uri tfsUri = new Uri("<serverURI>");
TfsConfigurationServer _ConfigurationServer = new TfsConfigurationServer(tfsUri, new NetworkCredential("<DifferentKindOfUsernames>", "<Password>"));
CatalogNode projectCollectionCatalog = _ConfigurationServer.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None)[0];
}
}
Another version with a mix of both previous version :
public class ConnectByImplementingCredentialsProvider : ICredentialsProvider
{
public ICredentials GetCredentials(Uri uri, ICredentials iCredentials)
{
return new NetworkCredential("<DifferentKindOfUsernames>", "<Password>", "<DomainOrNot>");
}
public void NotifyCredentialsAuthenticated(Uri uri)
{
throw new ApplicationException("Unable to authenticate");
}
}
class Program
{
static void Main(string[] args)
{
string _myUri = #"<serverUri>";
ConnectByImplementingCredentialsProvider connect = new ConnectByImplementingCredentialsProvider();
ICredentials iCred = new NetworkCredential("<DifferentKindOfUsernames>", "<Password>", "<DomainOrNot>");
connect.GetCredentials(new Uri(_myUri), iCred);
TfsConfigurationServer configurationServer =
TfsConfigurationServerFactory.GetConfigurationServer(new Uri(_myUri), connect);
configurationServer.EnsureAuthenticated();
}
}
And a version with an active directory Impersonator :
class Program
{
static void Main(string[] args)
{
using (new Impersonator("<DifferentKindOfUsernames>", "<DomainOrNot>", "<Password>"))
{
Uri tfsUri = new Uri("<serverUri>");
TfsConfigurationServer _ConfigurationServer = TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
CatalogNode projectCollectionCatalog = _ConfigurationServer.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None)[0]; // actual connection tries to happen here
}
}
}
serverURI being in the form of http://<servername>:8080/tfs or http://<serverip>:8080/tfs (both tested, with hosts file up to date) which is what is set as Notification URL on the TFS Server. This program works inside the domain.
DifferentKindOfUsernames being anything from 'DOMAIN\Username', 'LocallyDuplicatedUsername', 'LOCALMACHINE\Username' with the appropriate password, password being the same in the domain and on the machine.
This simple access won't work outside of the domain , and I have this error :
TF30063: You are not authorized to access <serverUri>
translated in a web context (using the same process in an asp.net website), it is a 401 error :
The remote server returned an error: (401) Unauthorized.
even if (things tested so far) :
I have a mapping between the local user/password who runs the program on the domain outsider machine and an active directory account who has admin access to TFS(even with impersonation rights on TFS activated) .
I add a BackConnectionNames registry key with the domain outsider machine name and ip like described here.
I disable the loopback check like described here.
I use an Active Directory Impersonator with different combination of user / domain or machine name. Active Directory Impersonator being described here.
I added the TFS Server IP to the local internet zone (tried trusted site as well) in the domain outsider server IE security options like described here.
I have tested the access to the serverURI from a browser. The uri works and I have access to the TFS Collection if I give the credentials with DomainName\User + Password. I tested this before any of the modifications I described before. I wonder what could be the difference between the programmatic access and the browser access besides all the things I have tested so far.
You're not passing credentials to build the connection. This means that you're using your currently logged in credentials from the host outside of the domain. I'm not an expert on Windows Authentication, but I think that this can, in certain circumstances, work transparently (if the username and password are identical) but it appears to depend on the NTLM version being used, the client and server operating systems, trust relationships and security zones, the IIS configuration and perhaps the phase of the moon.
In other words, you probably want to pass the credentials to the connection:
TfsConfigurationServer _ConfigurationServer = new TfsConfigurationServer(uri, new NetworkCredential("username", "password", "DOMAIN"));
Note that it's strongly recommended to enable SSL/TLS if you're connecting to your server over an untrusted (public) network.
(I corrected this to use the three-arg constructor for NetworkCredential -- my mistake. As you note, if you put DOMAIN\username in the username argument to NetworkCredential, it will treat it as \DOMAIN\username instead of DOMAIN\username. This, I suppose, it why nobody lets me write C# code.)

How to get the server IP Address (in C# / asp.net)?

Is there a 1 line method to get the IP Address of the server?
Thanks
Request.ServerVariables["LOCAL_ADDR"];
From the docs:
Returns the server address on which the request came in. This is important on computers where there can be multiple IP addresses bound to the computer, and you want to find out which address the request used.
This is distinct from the Remote addresses which relate to the client machine.
From searching the net I found following code: (I couldn't find a single line method there)
string myHost = System.Net.Dns.GetHostName();
// Show the hostname
MessageBox.Show(myHost);
// Get the IP from the host name
string myIP = System.Net.Dns.GetHostEntry(myHost).AddressList[index].ToString();
// Show the IP
MessageBox.Show(myIP);
-> where index is the index of your ip address host (ie. network connection).
Code from: http://www.geekpedia.com/tutorial149_Get-the-IP-address-in-a-Windows-application.html
As other(s) have posted, System.Net.Dns.GetHostEntry is the way to go. When you access the AddressList property, you'll want to take the AddressFamily property into account, as it could return both IPv4 AND IPv6 results.
This method will return your machine public IP address when run this code on your PC and when you deploy your application on server will return Server IP address.
public static string Getpublicip()
{
try
{
string externalIP = "";
var request = (HttpWebRequest)WebRequest.Create("http://icanhazip.com.ipaddress.com/");
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
externalIP = new WebClient().DownloadString("http://icanhazip.com");
return externalIP;
}
catch (Exception e)
{
return "null";
}
}

Categories