Hosting a C# WebSocket Server on Elastic Beanstalk - c#

I’ve written a WS server from scratch and I’m trying to host it on AWS Elastic Beanstalk service. However, I’ve only figured a way to add it to a web project (that can be hosted on EB) by tacking it on with a thread on startup.cs:
Thread thr = new Thread(() =>
{
var ws = new WebsocketServer();
});
thr.IsBackground = true;
thr.Start();
To my delight and surprise, I was able to successfully test this locally and it works perfectly fine, but when put on EB I am unable to connect to anything (even though I am 99% certain I’m sending requests to the appropriate URL). I’ve tried adding the port I’ve specified but nothing helps.
I’m using a TcpListener initialized like this:
TcpListener server = new TcpListener(IPAddress.Parse(“127.0.0.1”), 443);
server.Start();
And accept clients with a TcpClient like so:
TcpClient client = new TcpClient();
client = server.AcceptTcpClient();
Now based on my experience I assume that the connection is working properly but EB simply does not automatically set it up for public access. Is there any way to do this? Would using the same port as the web app help? (If so, how do I set/see what port it does use?). Since WS is initiated with a HTTP request, is there possibly a way to establish a connection using a Controller method of the format:
[Route("ws")]
[HttpGet]
public async Task<IActionResult> ConnectWS()
{
return await AddClient();
}
I have no Load Balancer set up for the EB environment I'm using.
Lastly, if this is a bad practice or infeasible, is there another AWS service I could use to host the server that’s easy to set up for public connections?
Thank you!

Looking at your code, you need to open up traffic on port 443. Depending on your Elastic Beanstalk configuration ( with load balancer? or without load balancer? update your question with this please ) you are close to getting it to work on AWS.
These high level steps will get you there:
Get a cert. For testing you can install openSSL on your local dev machine and create a self-signed cert. AWS has a guide on how to do this. Note: don't use self-signed certs on your live production system. When your site goes public, obtain a catchy name and a real cert to front your service.
(If no load balancer skip to step 3) Go to Certification Manager in your AWS console. There is a big blue button, Import Certficiate. Click this. Open the server.crt file from step 1 with your favorite text editor and paste the contents in the top box with the label: Certificate body. Then open the privatekey.cer file from step 2 with your favorite text editor and paste the contents in the second box with the label: Certificate private key. Click Review and Import and make sure everything is ok
If you have a load balancer, follow the steps from this AWS guide on how to open up 443 on it.. If you don't have a load balancer and it is just a single instance, its a bit more complicated as you have to do it via configuration files. Follow the steps here: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance.html
Try it out and reply back if you have updates to your question with more config specifics. I think you are close to working it out and getting it running on AWS.

Related

How would I get RabbitMQ to work inside of Kubernetes with Traefik?

I succeeded in getting RabbitMQ to work inside of Kubernetes thanks to this RabbitMQ/Kubernetes tutorial from Medium. And I have already setup traefik similar to this Traefik tutorial from Medium.
The problem is that RabbitMQ is only accessible from the outside and not from inside the cluster. I use C# to access RabbitMQ through this hello world tutorial from RabbitMQ. But the part where I have to enter the url only works outside of the cluster.
The var factory = new ConnectionFactory() { HostName = "localhost" };part is what is restricting me. Because in the next line using(var connection = factory.CreateConnection()) a
RabbitMQ.Client.Exceptions.BrokerUnreachableException
gets thrown. Because the url doesn't work inside of a cluster.
To solve this I would probably have to add RabbitMQ in some way to my traefik solution. That way I could define a path which I could use as the url. The problem is that I don't know how to add RabbitMQ into Traefik since it doesn't only use HTTP. Or perhaps there is even a better way to access RabbitMQ from inside a cluster?
Thank you for your time!

C# How to Access local network (192.168.x.x) within Docker containers

This is my first post here, I've looked across the internet in order to solve this issue but have no idea how to do this, as i am new to docker and not that great at networking (saying kindly).
I need a way to access my host machines internal network IP which has been forwarded to a port that connects to a proxy server. so essentially 192.168.x.xx:5000 => someproxyserver.com
now when setting up the SOCKS5 on my local machine or even in C# it is able to connect and it works.
but this is not the case with docker, again i am complete noob at docker, i have tried many things, but i can't seem to get my docker container to connect to the socks5 server.
I even tried to run the docker container with --network=host but i get an error (no route to host)
Ideally i would not want to use --network host as i have many other containers connecting to a external network.
var settings = new ProxySettings() {
Host = localIp,
Port = port
};
using (var proxyClientHandler = new ProxyClientHandler<Socks5>(settings)) {
using (var httpClient = new HttpClient(proxyClientHandler)) {
var response = await httpClient.GetStringAsync("https://api.ipify.org?format=json");
}
}
this is the C# code which i am using to connect to the SOCKS5 server.
When using --network=host
without --network=host
I managed to make this work somehow, without including any run commands, i believe this was failing due to my firewall blocking access, it was weird as i did allow access to it, however after restarting my computer earlier on, it worked :) so yeah if anyone stumbles across this, just remember to make sure your firewall isn't blocking access to docker

How can i make HttpListener to listen on 443 on mac OS?

I am setting up a simple server based on HttpListener in .net core that needs to run on MacOS. Works great on http, but i need it to run on https (port 443. Tried a custom port but still no success)
On windows, it works with "netsh add iplisten" and binding the cert with "netsh add sslcert". And it works great for both http and https.
On Mac OS however, first thing i found out was to set up an alias for localhost "ifconfig lo0 alias 127.0.0.9 up" so i'm allowed to start the httplistener.
That worked, and whenever i make a HTTP request to 127.0.0.9 i get the response i hard-coded in the browser.
Https still doesn't work. So i tried binding the certificate.
I used openssl to create a certificate => got a .p12 cert self-signed.
Used "httpcfg -add -port 443 -p12 server.p12 -pwd mypassword"
That worked, as i could see 2 files appeared in "~/.config/.mono/httplistener/" called 443.cer and 443.pvk.
However, if i navigate to https://127.0.0.9 i get an error connection reset in the browser.
I have no idea what else to try, and i can't find any answer.
Did anybody tried to do this on Mac OS?
var ipAddress = "127.0.0.9";
var httpListener = new HttpListener();
var httpPrefix = string.Format("http://{0}/", ipAddress);
var httpsPrefix = string.Format("https://{0}/", ipAddress);
httpListener.Prefixes.Add(httpPrefix);
httpListener.Prefixes.Add(httpsPrefix);
httpListener.Start();
WaitForNewRequest(httpListener);
In the "WaitForNewRequest(httpListener)" method i just write a hard-coded "hello world" response and wait for the next request. Nothing complicated.
Thank you!
Ports below 1024 are privileged, you need to run your app as root to open them.
If you need to use 443 in production, I highly recommend using apache or nginx to listen on the SSL port and proxy the traffic to your .net code.

Acessing a WebService (HTTPS) that requires a certificate via WCF in C#

I'm the client machine, and the server I'm trying to access is a program which I'll be providing support to (I'm a new 3rd party program) and I need to send then some data.
They use HTTPS but I couldn't connect with this:
public void StartProcess()
{
BasicHttpsBinding binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
// - They said they don't require credentials
EndpointAddress address = new EndpointAddress("https://www.outsideservice.com/services/C001");
OutsideServiceClient client = new OutsideServiceClient(binding, address);
DataToSend data = new DataToSend();
// - Filling up whatever data I need to send, omitted
try
{
client.StartProcess(data);
}
catch (Exception ex)
{
// ex = Could not establish trust relationship for SSL/TLS secure channel
}
}
They already have other 3rd party programs accessing their servers.
I don't have a very good knowledge on how certificates work (other than the basic reading on MSDN).
After questioning how I can access their servers, I got the reply:
" already access our servers via https, just access the machine, download the certificate and use on your client machine."
After googling around how I do this, I tried to access https://theirURL.com/certsrv from here, but I get Resource Not Found error.
From what I could understand from how certificates work, I must obtain a certificate from them, double click it, install on my machine (or the machine running the code to connect to them) to be able to connect right?
Or is there something that I have to do on my end to be able to connect?
"I must obtain a certificate from them, double click it, install on my machine (or the machine running the code to connect to them) to be able to connect right?"
This is the correct way to do things, however to get things up and running you can use this bit of code:
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
I usually like to wrap this in code that doesn't apply this on a release build so that production actually has to have the certificate installed properly as follows:
#if (!Release)
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
#endif
I believe you should be able to put this anywhere you like, such as the Global.asax.cs or right before the call is made.

Why is RavenDB hijacking my Nancy requests?

From a Winforms application using the same connection code, RavenDB works fine. I'm able to store and retrieve documents with abandon.
When I try to do the same thing in a Nancy application the result is completely unexpected.
Nancy is listening on port 12345, and RavenDB is running in Embedded mode with UseEmbeddedHttpServer enabled and listening on port 8080.
The very first request to http://localhost:12345/ gets a web page response as requested. Any subsequent request to http://localhost:12345/ is redirected to /raven/studio.html. If the first request I make is to /widgets Nancy returns a JSON list of widgets as expected, but any subsequent request returns:
Could not figure out what to do
Your request didn't match anything that Raven knows to do, sorry...
It seems like RavenDB is hijacking the port Nancy is listening on. Any ideas what would cause this behaviour?
When hosted by IIS, the port for RavenDB needs to be set explicitly.
The default value is coming from IIS config, which is why it isn't an issue when running embedded mode from a Winforms application.
(db as EmbeddableDocumentStore).Configuration.Port = 8080;
There's no good reason I can think of that it would do that.
Perhaps you should specify an explicit Raven/Port setting. See these docs.
Or you can do it programatically:
var store = new EmbeddableDocumentStore {UseEmbeddedHttpServer = true};
store.Configuration.Port = 8080;

Categories

Resources