When should I use ServiceFabricIntegrationOptions.UseUniqueServiceUrl - c#

This seems to say that is is always necessary otherwise you may resolve an incorrect service -- as there is no guarantee that services won't move around etc...
The default asp.net core service template uses
UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
Is there a reason for this? When is it okay to not use the ServiceFabricIntegration middleware?
E: I see these are actually a flags enum. So likely you should always use UseUniqueServiceUrl https://github.com/Azure/service-fabric-aspnetcore/blob/develop/src/Microsoft.ServiceFabric.AspNetCore/WebHostBuilderServiceFabricExtension.cs

Respectfully, I don't think you have read the docs well enough. It is well explained here:
Services that use a dynamically-assigned port should make use of this middleware.
Services that use a fixed unique port do not have this problem in a cooperative environment. A fixed unique port is typically used for externally-facing services that need a well-known port for client applications to connect to. For example, most Internet-facing web applications will use port 80 or 443 for web browser connections. In this case, the unique identifier should not be enabled.
So summarized: when using Kestrel or WebListener you can choose to use a dynamic port or a fixed port. See the sections Use WebListener/Kestrel with a static port and Use WebListener/Kestrel with a dynamic port in the mentioned link. When you opt to use a dynamic port use ServiceFabricIntegrationOptions.UseUniqueServiceUrl, otherwise use ServiceFabricIntegrationOptions.None as the parameter for the middleware.
Now, as of the why you need this unique service url middleware in case of a dynamic port, there is a scenario that describes the possible problem:
If services use dynamically-assigned application ports, a service replica may coincidentally use the same IP:port endpoint of another service that was previously on the same physical or virtual machine. This can cause a client to mistakely connect to the wrong service. This can happen if the following sequence of events occur:
Service A listens on 10.0.0.1:30000 over HTTP.
Client resolves Service A and gets address 10.0.0.1:30000
Service A moves to a different node.
Service B is placed on 10.0.0.1 and coincidentally uses the same port 30000.
Client attempts to connect to service A with cached address 10.0.0.1:30000.
Client is now successfully connected to service B not realizing it is connected to the wrong service.
This can cause bugs at random times that can be difficult to diagnose

Related

Switching Client and Server roles on gRPC in .NET Apps?

So I'm starting with the simple Greeter service from the VS2022 sample project template "ASP.NET Core gRPC Service", targeting .NET7, running on Windows. Name this side "A".
I was able to write a second console app (also .NET7) that connects as a gRPC client to that service, invoke the SayHello() rpc successfully and retrieve the expected response message. Name this side "B". So far, so good.
My scenario, however, is a bit different: I want the client B to connect to the server A and authenticate with the server (which is not part of the sample so far but I assume this will work fine as well). Then, the server A shall start acting as a gRPC client and the console-app-client B shall act as a gRPC server, i.e. I want them to switch roles (or establish another role if you like). The challenge is that I want the two parties to re-use the same TCP HTTP/2 connection that has already been established. So I'm looking for a way to create new instances of gRPC client/servers at runtime and provide them with the existing TCP connection. The reason why I need to do it this way are limitations coming from network security (the initial connection can only come B to A). I'm aware that by using streams I can make my server A send messages to B, but I'd prefer to have the full client/server support.
I saw a few discussions around the same question but the presented approaches are using GO as a language and it's hard for me to understand whether and how I can do the same in .NET7.
Possible? Thanks!

IIS Website Application doesnt work anything but port 80

I wrote a WCF service in visual studio 2017. I then added this service to IIS (not the express version but the full fledge IIS). It is added as an application under the default created website. I can access my service end-point without any issues at http://localhost/<websitename>/MyService.svc/test/123. /test/123 is just a simple GET endpoint.
The default website is already configured for port 80.
However, when I changed the port from 80 to say, 1234, it does not work. It merely returns me "Service Unavailable. HTTP Error 503." when I hit the /test/123 endpoint.
I have already executed the console command to add the port to ACL netsh http add urlacl url=http://+:1234/ user=everyone.
Does anyone know how can I get another port (non 80) to work?
Edit:
I am aware that there is an answer How to run WCF service on a specific port which explains how to bind to another port. However, the accepted answer uses the net.tcp protocol. I would like to use the HTTP protocol.
Is there any way to do it with HTTP protocol? If it cannot be done, then I guess ill have to redesign and swap over to net.tcp protocol.
I am extremely new to .NET development and WCF, so hopefully somebody with experience can point me in the right direction.
As it turns out, the problem had nothing to do with the so-called linked answer.
Prior to running my WCF service in IIS, I was trying to deploy it as a WAS and then Console application. In my process of getting those 2 implementations to work, I had to execute the command netsh http add urlacl url=http://+:1234/ user=everyone so that the port could be accessed.
By sheer luck, i stumbled upon this link:
https://serverfault.com/questions/666976/service-unavailable-if-i-try-to-access-iis-website-via-ip-address-works-fine-vi
Although it didnt have an accepted answer, the comments held the answer. My problem was caused exactly because I executed the netsh command. What happens is that the command causes that ip/port to be reserved, and thus, IIS cannot attach to the ip/port and therefore the Service Unavailable error. I assumed that if the WAS and Console version needed that command to be executed, then the IIS version needed it as well.
As for letting an IIS WCF Service be available on any other port, the process is super simple. Within IIS itself (Execute "inetmgr" in Run to launch), in the default or custom website you created, edit the binding and change the HTTP port to whatever port that you want. After that, its done. You should be able to access your application/website from that port via HTTP.
Eg:
http://localhost:<some port>/<websitename>/MyService.svc/test/123
My WCF Service config was a standard config that allowed for HTTP access.
If you would like to access it from another computer or from the internet, then you will need to configure your router to port forward your selected port (if needed) and ensure that your firewall allows data flow for that port.
Many "thanks" to the downvoters who assume this was some duplicate. Your "help" contributed in finding a solution to the problem.

Owin hostname-based sites using Service Fabric

I'm having trouble hosting multiple websites on different sub-domains using Service Fabric and OWIN.
Let's say I have four HTTP(S) servers on my Service Fabric cloud. Each of them are running on a different port. So at some point of their initialization, they will respectively call:
Microsoft.Owin.Hosting.WebApp.Start("http://+:80/", UnsecureStartup);
Microsoft.Owin.Hosting.WebApp.Start("https://+:443/", MainStartup);
Microsoft.Owin.Hosting.WebApp.Start("https://+:4431/", ApiStartup);
Microsoft.Owin.Hosting.WebApp.Start("https://+:4432/", ExtrasStartup);
This all works fine. All requests are successfully fulfilled. All four ports serve the startups they've been assigned in their respective stateless services, and the HTTPS ones make use of the same certificate as set from ServiceManifest.xml in proper Service Fabric fashion. Here's a similar single-server setup.
We always planned to use sub-domains instead of different ports. Now we have our domain and we're trying to do the following:
Microsoft.Owin.Hosting.WebApp.Start("http://example.com:80/", UnsecureStartup);
Microsoft.Owin.Hosting.WebApp.Start("https://example.com:443/", MainStartup);
Microsoft.Owin.Hosting.WebApp.Start("https://api.example.com:443/", ApiStartup);
Microsoft.Owin.Hosting.WebApp.Start("https://extras.example.com:443/", ExtrasStartup);
The code above does run. All four stateless services start and go green in Service Fabric Explorer. Yet, every single request (both to http:80 and to https:445) is met with the same response:
Service Unavailable
HTTP Error 503. The service is unavailable.
Why does Service Fabric allow us to have multiple Owin servers, even on the same port, if it's not possible for me to select one based on hostname? Does anyone have any idea of how we can make this work?
Any help is greatly appreciated.
In my understanding, hostnames does not work very well with SF.
You have the following options as I see it:
1) You use different ports on your internal services and put a WAF in front of your SF Cluster and let that one handle SSL offloading, URL routing and NATing to your internal ports. This way you will only need 1 public IP.
2) You add more public IPs and let your public load balancing handle it. You will need 3 IP addresses for this, but since the first 5 IPs are free in azure, this wont cost you anything extra.
You probobly want to go with option 1 as it gives you easier certificate managing, better security and more flexibility but at the cost of $.

how should I host my service such that other computers can consume myAppService using Internet

I have created a WCF service called MyAppService.
Now, I don't want to host that service on any servers. I would like to host it in my Computer. I know how to host a WCF service in Console/Windows App, as a Windows Service and in IIS.
But I have a problem to host this service in my computer. I mean in short that I want my Computer to Work as server and other computers should be able to consume myAppService from my computer via internet.
So, I would like to ask what is the best hosting option for me and how should I host my service such that other computers can consume myAppService using Internet. 1 more question : If the above problem is solved, then can I use netTcpBinding or I have to use some HttpBinding?
I'm still not 100% certain that I am answering the right question, but I'll give it a shot.
I believe what you are asking is: given that you are hosting a service in IIS on your personal computer, how do you allow others access to it? If my interpretation is incorrect, then please accept my apology in advance.
Note: I'm assuming IPv4 in this answer. IPv6 may be an option, but this answer would not apply.
There are two steps in the solution, and there are a few obstacles that you may or may not be able to overcome.
Get the client's web traffic to your public IP address.
Route incoming traffic to your computer.
Step 1
You can determine your public IP address in many ways, one of which is to ask Google: https://www.google.com/#q=what+is+my+ip
Obstacles are as follows:
Your IP address may change from time to time. The solution is to use a dynamic DNS service such as http://dyn.com/dns/, http://www.thatip.com/, or any of several alternatives that can be found online. These services will provide a URL that routes to your public IP, and they will provide a way to keep your public IP up-to-date so that name resoslution generally works. Keep in mind that DNS does not reliably change in realtime, however, so you should expect some downtime if and when your IP address changes.
Your ISP may block incoming traffic. Whether and how you can get around this is specific to your IP. Specifically, it is common for ISPs to block incoming port 20, 22, 23, 25, 80, and 443. You may be able to work around port blocking by choosing a non-standard port for your service. (This may not affect your WCF and IIS configuration as detailed in step 2.)
Particularly if you are using any kind of shared apartment connection, you may find that you do not have your own public IP address. If that is the case, then there is nothing you can do. If your router's WAN address (or computer's IP addres, if you're not using a router) is something in the 192.168.* or 10.* ranges, then it's time to look into server options.
Step 2
Once a client request has routed through the public internet to your public IP address, it needs to be routed to your computer.
The easiest, though least common these days, scenario is if your computer is directly connected to your cable/DSL modem. In this case, traffic that routes to your public IP is handled by your computer. This is the scenario where your WCF and IIS configuration needs to be listening on the actual port used by the client. For example, if your ISP is blocking port 80, then maybe you could configure your service to listen on port 34323, and that is the port that the client needs to request in the service call.
The most common scenario is that you have a router attached to your cable/DSL modem. In this case, you need to get into the administration control panel on your router and forward a port. For example, if your computer is configured to listen to port 80 for incoming service requests, then you can forward a port (for example, 34323) to port 80 on your local machine. How to forward the port differs by router. You should be able to find it by poking around or by doing an internet search.
The obstacle here is that your local IP address may change. You can overcome this by setting it to a static address outside of your router's DHCP assignment range or by setting up a DHCP reservation within your router. Either way will work. I suggest searching the internet for setting up a static IP or poking around in your router administration settings for DHCP reservations.
If you get all of your settings correct, and if there are no obstacles outside of your control, then a client on the internet can access your WCF service.
Edit:
I missed talking about local Windows firewall concerns. I could go into that, but allow me to link to this how-to guide that covers it pretty well. (Remember, a WCF service is conceptually similar to a website from a hosting standpoint, so much of this applies.) http://www.pcstats.com/articleview.cfm?articleID=1774

Writing a proxy to listen for information traveling from client to service

I need to write an application that acts as a proxy between a client and a service. All I want to do is read the data that is traveling in both directions from client to service and vice versa. In essence I want this proxy to be able to be just plugged in without the need to reconfigure port settings in either the client or the service. Is this possible? Is there any specific library I could use in the C# .Net framework that will help?
EDIT: The service is on a remote machine.
EDIT: Example: Lets assume that the client is communicating to the service via port 1234 and the service is communicating to the client via port 5678. I want the application to listen and read the data traveling through these ports without actually reconfiguring either the client or the service. Is that possible?
If you are to read/listen/capture the data then it does not need to be a proxy. I would recommend WinPcap library (http://www.winpcap.org/). Although it's a C/C++ library, I don't think it's hard for a C#/.NET application to make use of it.
If you wanna redirect the ongoing connection as soon as your proxy program is up, the short answer is hard, really hard and impossible. As far as I've known, once the connection between 2 ends is established, no way you can change it (unless you have access to the router and modify its NAT on the fly, like a load balancer...). If you just want to read & not to modify the traffic data, use WinPcap or any packet sniffer. Either of these solutions are quite expensive to implement in term of money and technical work :)
Because you didn't give us what you actual wanna do, I assume that you don't need that "much" complexity. Here a solution just in case you meet the following prerequisites:
The client connects to the service via a domain name, not an absolute IP and vice versa. This is important because we are going to change the DNS in the host file to "fake" the end-point servers to our proxy server address.
You have access rights (administrator) to the client machine & the service machine to make any change.
Then what you should do next is to:
Change the IP of the hostname of your service server on your client machine to the IP of the proxy server. This just changes the result of the OS DNS resolver. Do the reversing way for the service server.
Drop & re-establish connections between 2 client machine & service server. Now, each connection is properly "proxied" via your proxy server.
Ha, quite intricate but it works I think... Hoping someone has better solutions for this situation and I'm looking forward to hearing that.

Categories

Resources