Firewall : Is inbound required for getting response while Outbound rule already there? - asp.net

I developed one MVC web application which have Web APIs and hosted in Amazon Instance and one windows application for calling those APIs for getting response from that server.
Both Web and Windows applications are developed in asp.net framework 4.5 using c# language.
Windows application is installed in more than 200 client's system which are highly secure servers it selves with all Inbound ports blocked in Firewall.
I am using HttpWebRequest with BindIPEndPoint for calling Web APIs using configured TCP port range [default 7777-7786].
API calls working fine from Windows Application if there are Allow Inbound and Outbound firewall Rules.
But the problem is clients are not allowing me any Inbound Firewall rules, they only allowing Outbound Firewall rules for those port range And Windows application is not working with blocked inbound rules for those port range.
Is it must I need to open Inbound Rule in Firewall for those port range for calling/getting request/response to/from APIs ? If no need of Inbound Firewall rule then please explain Why ?
Below is the API call which use one static TCP port in my Windows Application :
try
{
string address = RevWatchURL;
address = address + "api/GetRevGuardLatestPatch";
HttpWebRequest httpWebRequest = WebRequest.Create(address) as HttpWebRequest;
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
httpWebRequest.Timeout = 300000;
httpWebRequest.ServicePoint.BindIPEndPointDelegate =
new BindIPEndPoint(CommonValues.BindIPEndPointCallbackRGPatch);
string enRevGuardUniqueId =
Encryption.EncryptionTechnique(Convert.ToString(UniqueId), null, null);
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"UniqueId\":\"" + enRevGuardUniqueId + "\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
try
{
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
returnVal = streamReader.ReadToEnd();
streamReader.Close();
httpResponse.Close();
}
}
catch (WebException ex)
{
}
finally
{
httpWebRequest.Abort();
}
Obj = JsonConvert.DeserializeObject<CommonValues.RevGuardPatchClass>(returnVal);
}
catch (Exception ex)
{
MessageBox.Show("Error", "API", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
BindIPEndPoint Method:
public static IPEndPoint BindIPEndPointCallbackRGPatch(ServicePoint servicePoint,
IPEndPoint remoteEndPoint, int retryCount)
{
return new IPEndPoint(IPAddress.Any, 7777);
}

Related

Unable to Connect to Rabbit MQ

I am using amazon service and created rabbitmq broker now from the DOT NET code i am trying to connect to this broker.
var factory = new ConnectionFactory
{
Uri = new Uri("amqps://it:Password#hostname:5671")
};
var connection = factory.CreateConnection();
I am struggle here to get connection getting below error :
None of the specified endpoints were reachable
at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
Update:
It seems your client wants to connect using TLS/SSL (your uri specifies the protocol "amqps" and the port 5671).
Try enabling TLS/SSL:
var factory = new ConnectionFactory {
UserName = userName,
Password = password,
VirtualHost = "/",
HostName = hostName,
Port = port,
Ssl = new SslOption
{ Enabled = true, // <--------
ServerName = hostName }
};
The (JVM based) guide shows how to configure the connection factory. It sets the credentials on the factory, not in the URI:
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername(username); // <----------
factory.setPassword(password); // <----------
//Replace the URL with your information
factory.setHost("b-c8352341-ec91-4a78-ad9c-a43f23d325bb.mq.us-west-2.amazonaws.com");
factory.setPort(5671);
// Allows client to establish a connection over TLS
factory.useSslProtocol()
// Create a connection
Connection conn = factory.newConnection();
(This needs to be translated to the corresponding .NET code)

Unable able to communicate between two services

I have created two Web API in Asp.net Core one is Wrapper Service to be deployed on DMZ Server and other is core service which have access to our DB Non DMZ. The problem i am facing is that i am unable to communicate between two services.
Both are running on local machine through dockers. When i try to hit core service running on url: https://localhost:56788/Rewards thorugh HttpClient/WebRequest i got message
No connection could be made because the target machine actively refused it.
DMZ Controller Logic
[Route("[controller]")]
[ApiController]
public class RewardsController : ControllerBase
{
[HttpGet]
public string Get()
{
string response = string.Empty;
//using (var client = new HttpClient())
//{
// client.BaseAddress = new Uri("http://localhost:5000/");
// //HTTP GET
// var responseTask = client.GetAsync("Rewards");
// responseTask.Wait();
// var result = responseTask.Result;
// if (result.IsSuccessStatusCode)
// {
// response = result.ToString();
// }
// else //web api sent error response
// {
// //log response status here..
// response = "Error";
// }
//}
string sURL = "https://localhost:56788/Rewards";
WebRequest wrPostURL = WebRequest.Create(sURL);
wrPostURL.Method = "GET";
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
using (HttpWebResponse webresponse = wrPostURL.GetResponse() as HttpWebResponse)
{
Encoding enc = System.Text.Encoding.GetEncoding("utf-8");
StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream(), enc);
var jsonResponse = loResponseStream.ReadToEnd();
loResponseStream.Close();
webresponse.Close();
}
return response;
}
}
NON-DMZ Controller Logic
[Route("[controller]")]
[ApiController]
public class RewardsController : ControllerBase
{
[HttpGet]
public string Get()
{
return "Hello";
}
}
Update
This problem is due to dockers. When i deploy both APIs to IIS then it will work fine but i have to do it with Dockers
The problem occurs due to the fact that i was calling localhost to communicate with other API running on another container. When we call localhost the first container start looking for the service that is running on same container. By using VM/Local Machine IP instead of localhost the problem can be avoided.

A connection attempt failed because the connected party did not properly -- Using HttpClient

I am receiving connection attempt failed to my web api service when I called the service from asp.net mvc application. If I call the service from a browser or from MVC application hosted on another server, it works.
It also works if I host the application in test server or development server.
It doesn't work only when I host the application on that server and call the service from the mvc app.
Any suggestion. Is something on the hosted server is blocking the connection.
using (var client = new HttpClient())
{
string baseUrlFromConfig = ConfigurationManager.AppSettings["webServiceUrl"];
client.BaseAddress = new Uri(baseUrlFromConfig);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Uri myUri = new Uri(baseUrlFromConfig + "api/account/ConfirmEmail?e=" + e + "&code=" + code, UriKind.Absolute);
var response = client.GetAsync(myUri).Result;
if (response.IsSuccessStatusCode)
{
string responseString = response.Content.ReadAsStringAsync().Result;
}
}

Configure Azure web role to start app domain on launch

Azure has a fantastic ability to roll updates so that the entire system is not offline all at once. However, when Azure updates my web roles, the AppDomains are understandably recycled. Sometimes the ASP.NET startup code can take over a minute to finish initializing, and that's only once a user hits the new server.
Can I get Azure to start the AppDomain for the site and wait for it to come up before moving on to the next server? Perhaps using some magic in the OnStart method of WebRole?
See Azure Autoscale Restarts Running Instances which includes the following code:
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
IPHostEntry ipEntry = Dns.GetHostEntry(Dns.GetHostName());
string ip = null;
foreach (IPAddress ipaddress in ipEntry.AddressList)
{
if (ipaddress.AddressFamily.ToString() == "InterNetwork")
{
ip = ipaddress.ToString();
}
}
string urlToPing = "http://" + ip;
HttpWebRequest req = HttpWebRequest.Create(urlToPing) as HttpWebRequest;
WebResponse resp = req.GetResponse();
return base.OnStart();
}
}

confusion about Certificates

I have WCF REST web service hosted by IIS, it works on HTTPS, I generate Certificate on IIS and assign Https to a port
I generate cer through IE browser. I create a test application and regardless Add a client certificate or not or even add a wrong certificate the connection take place and a I get correct response. I am wondering how the message was decrypted if there is no certificate sent.
Either the destination is not secured or I misunderstand the whole thing.
also
The error I have from the callback "CheckValidationResult()" is either
CertCN_NO_MATCH = 0x800B010F
or
"Unknown Certificate Problem" , the certificateProblem (parameter of CheckValidationResult) is 0 for this case
What is CertCN_NO_MATCH eror, what is CN?
See code below.
ServicePointManager.CertificatePolicy = new CertPolicy();
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(String.Format("https://{0}/uri", ip));
//request.ClientCertificates.Add(new X509Certificate("D:\\ThePubKey.cer"));
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
using (StreamWriter stream = new StreamWriter(request.GetRequestStream()))
{
stream.Write("RequestType=CheckStatus&ReportType=Fulfillment&ReportID=5");
}
using (StreamReader stream = new StreamReader(request.GetResponse().GetResponseStream()))
{
Response.ContentType = "text/xml";
Response.Output.Write(stream.ReadToEnd());
Response.End();
}
class CertPolicy : ICertificatePolicy
{
public enum CertificateProblem : uint
{
CertEXPIRED = 0x800B0101,
CertVALIDITYPERIODNESTING = 0x800B0102,
CertROLE = 0x800B0103,
CertPATHLENCONST = 0x800B0104,
CertCRITICAL = 0x800B0105,
CertPURPOSE = 0x800B0106,
CertISSUERCHAINING = 0x800B0107,
CertMALFORMED = 0x800B0108,
CertUNTRUSTEDROOT = 0x800B0109,
CertCHAINING = 0x800B010A,
CertREVOKED = 0x800B010C,
CertUNTRUSTEDTESTROOT = 0x800B010D,
CertREVOCATION_FAILURE = 0x800B010E,
CertCN_NO_MATCH = 0x800B010F,
CertWRONG_USAGE = 0x800B0110,
CertUNTRUSTEDCA = 0x800B0112
}
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
{
// You can do your own certificate checking.
// You can obtain the error values from WinError.h.
// Return true so that any certificate will work with this sample.
String error = "";
using (StringWriter writer = new StringWriter())
{
writer.WriteLine("Certificate Problem with accessing " + request.RequestUri);
writer.Write("Problem code 0x{0:X8},", (int)certificateProblem);
writer.WriteLine(GetProblemMessage((CertificateProblem)certificateProblem));
error = writer.ToString();
}
return true;
}
private String GetProblemMessage(CertificateProblem Problem)
{
String ProblemMessage = "";
CertificateProblem problemList = new CertificateProblem();
String ProblemCodeName = Enum.GetName(problemList.GetType(), Problem);
if (ProblemCodeName != null)
ProblemMessage = ProblemMessage + "-Certificateproblem:" +
ProblemCodeName;
else
ProblemMessage = "Unknown Certificate Problem";
return ProblemMessage;
}
}
I've just replied to this similar question (in Java).
CN is the "Common Name". It ought to be the hostname of the server to which you're connecting (unless it's in the subject alternative name). I guess from your code sample that you're using the IP address directly. In this case, the CN should be that IP address (it tends to be better to use a hostname rather than an IP address). See RFC 2818 (sec 3.1) for the specifications.
Note that the CN or subject alternative name is from the point of view of the client, so if you connect to https://some.example.com/, then the name in the cert should be some.example.com, if you connect to https://localhost/, then the name in the cert should be localhost, even if some.example.com and localhost may be the same server effectively.
(I guess that by default, IIS might generate a certificate for the external name, but you'd have to look at the certificate to know; this should be visible in the certificate properties somewhere.)

Resources