Why does WebRTC/TURNS not work for every client? - webrtc

We previously configured our clients to use a TURN server at turn:ourTurn.com:443. A customer with very strict network rules could not use our WebRTC services, but when updating the ICE server to turns:ourTurnserver.com:443?transport=tcp (note the added S in turns vs turn and TCP as transport protocol) it resolved their issue.
Unfortunately, this made our service unavailable to many other customers (no idea why, we expected the 'strictest' config with TURNS/TLS to work all the time). So we implemented the 'gold standard' implementation where the clients use a list of ICE servers, i.e.
[stun:ourTurnserver.com:443, turn:ourTurnserver.com:443?transport=udp, turn:ourTurnserver.com:443?transport=tcp, turns:ourTurnserver.com:443?transport=tcp]
Now our service works again for all users, EXCEPT those behind the very strict firewall.
Note that the new configuration (list of ICE servers) includes the TURNS address, which made the config work for the strict firewall in the first place.
Any ideas what is going on?

Related

How do we get WebRTC to work with a VPN (have tried TURN solution)

Our WebRTC app works in every environment until one user turns on a VPN.
The error we're getting is a failed ICE candidate.
We have tried leveraging TURNs along with STUNs, both public and private, still no success.
Any ideas?
Is your TURN server accessiable over TCP? In your ICE Servers list you should have two entries turn:turn-server.com?protocol=tcp and turns:turn-server.com?protocol=tcp. If you don't specify the protocol it will use UDP.
VPNs cause a few different issues with WebRTC. If it is connectivity there isn't much you can do. I have seen a few VPNs that by default have a very low MTU, it may be configurable.

Multiple stun/turn servers on Kurento/elasticRTC

Is it possible (or any hack) to configure multiple stun/turn servers on the WebRtcEndpoint.conf.ini or through our signaling servers? So that if one stun fails it falls back to another? If the feature is not available what would be the closest solution?
I am not sure if I am looking into the right location - I've seen that WebRtcEndpoint has methods for- getStunServerPort()/getStunServerAddress(). So a possible client side configuration?
Reason - We've been using kurento media server (6.0) and elasticRTC 6.5 (For the future development) on an AWS vpc. It was working fine by using one of the publicly available STUN servers. Suddenly it stopped working and we figured out the STUN server was not working anymore. So we switched to Google stun and it started working normally
I would suggest, instead of using a globally configured IP in WebRtcEndpoint.conf.ini, to use the methods that you mention in the WebRtcEndpoint. That way, you can use a CNAME and resolve the IP every now and then. You might have a separate scheduled task that checks the STUN server to see if it's still available, and then refresh it when it is no longer valid.

Taking a server from development to production

I have created a service (WCF) that acts as a backend for a DB. For now it does basic operations such as INSERT, SELECT etc. I have run it locally and now it is time to expose her to the internet and enter 'production'. Is there a best practice to doing so? Bear in mind this service will be hosted on a PC as a Windows Service (not IIS). This is the first time I am putting a Windows Service into production so I am hazy on the details but I think this is the main idea:
On the service: Check for 'rookie' errors such as SQL Injection. Set maximum message sizes to ones marginally higher than the largest message that should be transmitted by my service. Also upgrade self signed X.509 certificate to one issued by a CA. (Where does one store this certificate? Locally on the PC?)
On the PC: Fully patched software (OS etc) and windows firewall with a specific set of rules that allows traffic only on the ports being used (I suppose the safest way to do this is to use the windows tool Allow a program or feature through Windows Firewall ?). Furthermore an updated antivirus running.
On the Network: For the network router, port forward the respective ports being used (the base address is declared as http://localhost:8080 so I guess port 80 for HTTP and 443 for HTTPS? I am using message level Security.)
General precautions: Full message logging on the service to analyze traffic and potential attackers. Also run a Network intrusion detection system such as Snort so that I can sleep a bit better at night.
Am I missing anything obvious? Also should I be hosting in IIS, on security exchange someone said that I would be vulnerable to HTTP attacks if I did not put the code behind a web server. However I have not read this anywhere else

Publically exposing a WCF service which is behind firewall

Enviroment
Consider the following production environment setup for a web application:
End user --Internet--> web server in DMZ --Firewall--> WCF hosted on app server --> DB Server
Constraint:
Also consider that we cannot change anything from the infrastructure point of view. For example, open ports, change any firewall setting etc.
Problem:
We want to expose the WCF, which is hosted on the app server, to external clients. We are trying to solve this as follows:
End user --Internet--> Router WCF in DMZ --Firewall--> WCF hosted on app server --> DB Server
Please note that we cannot establish a db connection from the DMZ environment where the WCF needs to be hosted so that the external clients can consume it. We have developed a "Router WCF" which passes through all messages to the internal WCF and vice-versa.
This solution adds an unnecessary overhead of serializing and de-serializing data. There must a better and proper way of doing this. We are looking forward to the community for guidance. Thank you.
In DMZ the bibliography tells you: always create an intermediate layer. This means another machine on the internet will be the point of connection and it will proxy the connection back to WCF.
The machine is the web server you seem to mention, that is stupid, has no data, and (to be a proper DMZ) has a firewall between it and all the machines (WCF and the others) it serves that permits only IP:PORTS used on such machines.
In this scenario, usually Apache on the public web server with a URL-rewrite rule (i.e if it is /x/y send it to servera.internal.com:9900 - if it is /x/z send it to serverb.internal.com:9901 etc...) is enough, but there are plenty of solutions of course.
It seems you are doing exactly this, why do you say it is not the proper solution?
DMZs could seem a bit dated as protection mechanism (I agree) but you have to think when servers like your WCF machine had dozens of ports opened, and you wanted to lower the risk of random ports on web-facing machines, a giant attack surface. Nowadays everything can work with couple of ports opened, so it can seem "silly" to do all of this just to forward a TCP port. But it is still valuable as (for example) if servers behind the web server in DMZ do not have internet access, even when WCF is compromised, the attacker cannot use its own reverse shell to deploy what it is nowadays called an APT (yesterday backdoor). The attacker "won't see" his own machine from WCF as the DMZ provides the connection to the external world.

wsDualHttpBinding ClientBaseAddress & firewalls

I'm planning on using a wsDualHttpBinding for a WCF service with callbacks. The clients will be a windows form application communicating to the service over the internet. Obviously I have no control over the firewall on the client side, so I'm wondering what is the proper way to set the ClientBaseAddress on the client side?
Right now in my intiial testing I'm running the service and client on the same pc and i am setting the binding as follows
Dim binding As System.ServiceModel.WSDualHttpBinding = Struct.Endpoint.Binding
binding.ClientBaseAddress = New Uri("http://localhost:6667")
But I have a feeling this won't work when deploying over the internet because "localhost" won't translate to the machine address (much less worrying about NAT translation) and that port might be blocked by the clients firewall.
What is the proper way to handle the base address for callbacks to a remote client?
some one tell me if i do not specify ClientBaseAddress then WCF infratructure creates a default client base address at port 80 which is used for the incoming connections from the service. Since port 80 is usually open to firewalls, things should just work.
so just tell me when win form wcf client apps will run then how can i open my custom port like "6667" and also guide me what library or what approach i should use as a result response should come from client side router
to pc and firewall will not block anything. please discuss this issue with real life scenario how people handle this kind of situation in real life. thanks
The proper way is to use TCP transport instead of HTTP transport. Duplex communication over HTTP requires two HTTP connections - one opened from client to server (that's OK) and second opened from server to client. This can work only in scenarios where you have full control over both ends. There is simply too many complications which cannot be avoided just by guessing what address to use like:
Local Windows or third party firewall has to be configured
Permission for application to run - listening on HTTP is not allowed by default unless UAC is turned off or application is running as admin. You must allow listening on the port through netsh or httpcfg (windows XP and 2003) - that again requires admin permissions.
Port can be already used by another application. In case of 80 it can be used by any local web server - for example IIS.
Private networks and network devices - if your client machine is behind the NAT the port forwarding must be configured but what if you have two machines running your application on the same private network? You cannot forward from the same incoming port to two machines.
All these issues can be avoided mostly only when you have control over whole infrastructure. That is the reason why HTTP duplex communication is useful mostly for intranet scenarios and why for example Silverlight offers another implementation where the second connection is not created and Silverlight client instead polls server continuously to check if there is any callback available.
TCP transport requires only single connection from client to server because TCP protocol is natively duplex so the server can call back the client through the same connection. When you deploy a public service you usually have control over infrastructure on the server side so you can make necessary changes in configuration to make it work.
I think this also answers your previous question.