C# Detect Localhost Port Usage - networking

In advance, thank you for your advice.
I am currently working on a program which uses Putty to create a SSH connection with a server that uses local port forwarding to enable a client, running my software, to access the service behind the SSH server via localhost.
IE: client:20100 -> Internet -> Remote SSH server exposed via router/firewall -> Local Intranet -> Intranet Web POP3 Server:110.
Cmd Line: "putty -ssh -2 -P 22 -C -L 20100:intranteIP:110 -pw sshpassword sshusername#sshserver"
Client would use putty to create a SSH connection with the SSH server specifying in the connection string that it would like to tie port 110 of the Intranet POP3 Server to port 20100 on the client system. Therefore the client would be able to open up a mail client to localhost:20100 and interact with the Internal POP3 server over the SSH tunnel. The above is a general description. I already know what I am trying to do will work without a problem so am not looking for debate on the above.
The question is this...How can I ensure the local port (I cannot use dynamic ports, so it must be static) on localhost is not being used or listened to by any other application?
I am currently executing this code in my C# app:
private bool checkPort(int port)
{
try
{
//Create a socket on the current IPv4 address
Socket TestSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Create an IP end point
IPEndPoint localIP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
// Bind that port
TestSocket.Bind(localIP);
// Cleanup
TestSocket.Close();
return false;
}
catch (Exception e)
{
// Exception occurred. Port is already bound.
return true;
}
}
I am currently calling this function starting with a specific port in a for loop to get the 'false' return at the first available port. The first port I try is actually being listened to by uTorrent. The above code does not catch this and my connection fails.
What is the best method to ensure a port is truly free? I do understand some other program may grab the port during/after I have tested it. I just need to find something that will ensure it is not currently in use AT ALL when the test is executed.
If there is a way to truly reserve the localhost port during the test, I would love to hear about it.

Here's the answer how to check if local port is free.
I would recommend this way:
bool IsBusy(int port)
{
IPGlobalProperties ipGP = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] endpoints = ipGP.GetActiveTcpListeners();
if ( endpoints == null || endpoints.Length == 0 ) return false;
for(int i = 0; i < endpoints.Length; i++)
if ( endpoints[i].Port == port )
return true;
return false;
}

Related

How to connect to remote SFTP server from OpenShift .NET Core POD using SSH.NET

I have a .NET Core 2.2 service running in OpenShift. My service uses SSH.NET to connect to my remote SFTP Server running outside the OpenShift cloud. The SFTP server is configured to provide only SFTP on port 22.
According to SSH.NET, the code to connect to an SFTP server is:
var connectionInfo = new ConnectionInfo("10.1.2.3",
"guest",
new PasswordAuthenticationMethod("guest", "pwd"),
new PrivateKeyAuthenticationMethod("rsa.key"));
using (var client = new SftpClient(connectionInfo))
{
client.Connect();
}
This code works fine when used inside my intranet.
To access a remote resource in OpenShift I have created an egress router that provides a fix IP. All firewalls have been configured to allow accees from OpenShift to my SFTP Server.
My question:
What value shall I use for first parameter in the ConnectionInfo class above? The IP address "10.1.2.3" of my remote server will not work from inside OpenShift because outbound traffic must strictly go through the egress router service.
Note:
I can already access the remote server via HTTPS using an http client access from my POD using URL like this: https://x-myservice-egress.y-myproject-infra-test:4433.
In the ConenctionInfo class I must provide the egress router name and a mapping port, e.g. projectName-egress-xyz:2201. The 2201 is a mapping ID not a physical port, it maps to my real SFTP server host machine IP and port 22.
The code below worked!
var connectionInfo = new ConnectionInfo("projectName-egress-xyz:2201",
"guest",
new PasswordAuthenticationMethod("guest", "pwd"),
new PrivateKeyAuthenticationMethod("rsa.key"));
using (var client = new SftpClient(connectionInfo))
{
client.Connect();
}
Replace it with egress router name and source port mapped to destination port that you defined in your egress configuration.
Ex egress-xyz:source-port

ASP.NET Core: How to get remote IP address?

I try to get remote (client) IP addres:
var ip = httpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress
But it works only for local requests (it will return ::1 value)
When I load page from remote machine the value is null. I investigated there is no IHttpConnectionFeature in the Features collection in this case.
Why? And how to get remote ip address correctly?
I know that this post is old but I came here looking for the same question and finnaly I did this:
On project.json add dependency:
"Microsoft.AspNetCore.HttpOverrides": "1.0.0"
On Startup.cs, in the Configure method add:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto
});
And, of course:
using Microsoft.AspNetCore.HttpOverrides;
Then, I got the ip like this:
Request.HttpContext.Connection.RemoteIpAddress
In my case, when debugging in VS I got always IpV6 localhost, but when deployed on an IIS I got always the remote IP.
Some useful links:
How do I get client IP address in ASP.NET CORE? and RemoteIpAddress is always null
The ::1 may be because:
Connections termination at IIS, which then forwards to Kestrel, the v.next web server, so connections to the web server are indeed from localhost.
(https://stackoverflow.com/a/35442401/5326387)
Just try this:
var ipAddress = HttpContext.Connection.RemoteIpAddress;
And if you have another computer in same LAN, try to connect with this pc but use user ip instead of localhost. Otherwise you will get always ::1 result.

Socket.Connect to SMTP to verify email always returns with smtp connection timeout

I've written a tool that validates emails, mostly copied from various examples on the subject around on the internet (user Don Worthley compiled a decent collection of code samples here https://delicious.com/dworthley/email.validation). Unfortunately after creating the socket and the IPEndPoint from the email to verify's hostname IP and port, my code always fails to connect to the socket due to timeout.
Here is the pertinent code (fails at s.Connect(endPt) due to timeout):
private bool smtpCheckEmail(string email)
{
try
{
string[] host = (email.Split('#'));
string hostname = host[1];
IPHostEntry IPhst = Dns.GetHostEntry(hostname);
IPEndPoint endPt = new IPEndPoint(IPhst.AddressList[0], 25);
using (Socket s = new Socket(endPt.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
try
{
s.Connect(endPt);
}
catch
{
s.Close();
return false;
}
From my research others have reported success with similar code so it might be an issue with my server host. The MVC project is on a GoDaddy VPS with Windows 7 and standard firewall/MSSE as protection (I've tested with both disabled with same timeout result).
I've verified I can telnet to my own host and run through the various HELO, Mail from etc commands but it also times out if I try to connect to smtp for other hosts.
Maybe it's an ISP issue?
I've also tried installing EmailVerify for .NET trial but run into the same problem where any validation at or above SMTP check times out.
Would be great to get some suggestions of what might be the problem and how to troubleshoot it.
Edit: After doing some comparison testing with one of my Azure VPS it looks like it is likely to be server related, "telnet 74.125.206.108 smtp" (gmail's smtp host IP) through command line connects on the Azure box but not on the GoDaddy one my project is on.
I also notice that when my code pulls the IP from the host name (Dns.GetHostEntry(hostname)), in this gmail example it returns 216.58.216.37 which matches what I get if a run nslookup in cmd for gmail.com, however the IP for smtp that I can telnet to is for gmail is 74.125.206.108 which matches the nslookup record for smtp.gmail.com. Could my code be grabbing the wrong IP addresses in many cases here?
Turned out to be a limitation of GoDaddy VPS. Transferred code to an Azure hosted project and it worked great.

JavaDB(Derby) - Connection refused using Network Server Controller in LAN

I'm new to java networking. My scenario here is 2 client computers are connecting to a server hosted in LAN. So I use NetworkServerControl API to start the host:
private static void startServer(){
try{
NetworkServerControl nsc = new NetworkServerControl(InetAddress.getByName("localhost"), 1527);
nsc.start(null);
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Start network error : " + e.getMessage());
}
My questions are:
1) Is localhost accessible by computers in LAN?
- If yes, I tried to use ij to connect derby database in the server but it wrote connection refused. Anything I missed out?
ij: CONNECT 'jdbc:derby://localhost:1527/c:/app_db/' user 'xxx' password 'xxx';
- If no, what is the common approach should be used? Please guide me the right track.
Thanks.
To access your Derby database from other machines on the network, you need to change "localhost" to a different value. You can give the DNS name of your machine, or the public IP address of your machine.
Note that you have to make this change both on the Derby server and on each of the client URLs.
You should be able to use netstat -a to confirm the effects of your changes on the server.

How to host a TcpClient/listener online (I want to host my chat server online)

I have a chat server that i create for my window phone app. Right now it working on my local computer, how do i make it online so everyone can connect to it.
Chat server:
TcpListener chatServer = new TcpListener(4296);
Chat client:
TcpClient client = new TcpClient("127.0.0.1", 4296);
How do i forward the port so i can host it online!
In order for the world to see it you need to host it somewhere with a public IP address. You will then use this IP address in the client connection:
Chat client: TcpClient client = new TcpClient("xxx.xxx.xxx.xxx", 4296);
Depending on your platform you could use Google App Engine or Amazon Web Services to quickly deploy your application.
That depends on your router/gateway. Check your router's documentation for more information how to forward ports.
Basically If you want to deploy your app online you need your own Domain(you get your own IP to host), you can use Cloud Server to deploy(these is a good option, since you can deploy for free but storage is limited in free edition), Or else you can Host on your Routers IP Address.
If you are using first two option then these is a python script to start a listener service on given IP and port.
Here:
import socket
import sys
HOST ='' # Symbolic name, meaning all available interfaces
PORT = 8000 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
s.close()
These is just a sample, you can put all of Your code from Your PC to Cloud and edit the changes in IP.
And if you want your router to listen to the client then you have to go to the routers login page, for most of the router it is 192.168.51.1, go here and login as administrator, Then you should go to firewall configuration over there you will find an option of custom server, then click on it and then there configure the ip address, port,etc to host.
I prefer you to watch these full video to understand properly: Here Video
In these video he is hosting for exploitation purpose you can host to do any other activity.
Thank You.

Resources