Open BLineBrian opened 3 weeks ago
Granted I haven't set up a proxy for media before, but are you trying to proxy UDP or TCP traffic? I'd assume TCP would be easier to set up (though be warned that media over TCP is a major downgrade, it's the fallback for a reason).
hundred IP ranges
Where is this coming from? It should just be 99.77.128.0/18
. Also, if it's helpful, you can get away with just allowlisting one regions URLs, e.g.
turns:ice.m1.ue1.app.chime.aws
for us-east-1, if you explicitly place your meetings there.
Ideally we'd like to proxy UDP for the reasons you mentioned, but TCP isn't in the end of the world. If clients want the best performance then they should open the required port ranges for Chime.
Where is this coming from? It should just be 99.77.128.0/18
The documentation indicates that all IPs for route53, cloudfront, and ec2 must be whitelisted. It does look like the media-specific endpoints (ice...chime.aws
for TURN, signal...chime.aws
for signaling) are in that 99.77.128.0/18
subnet.
But the UI sdk also uses a static assets endpoint (static.sdkassets.chime.aws
) and an event data endpoint (data.svc...chime.aws
), which are both cloudfront IPs. That's a pretty big list of subnets to whitelist. I does not look like the UI requires EC2 IPs, which was the most egregious one.
Also, if it's helpful, you can get away with just allowlisting one regions URLs, e.g.
Any chance it's possible to get a complete list of these URLs? IT teams don't like wildcards, but are more amenable to lists of addresses.
I did actually end up getting the ice/TURN proxying working for video conferencing. The only real problem left is that the urlRewriter
function doesn't catch all addresses. The static.sdkassets.chime.aws
in particular does not seem to have a built-in way to run through a proxy. We will fork the sdk and make a change to support that. If it works well, we will open a PR back to this repo.
Because TCP and UDP don't really support hostnames, there's no magic way to make this proxy work. The plan is to use the URL rewriter to map Chime ice URIs to ports on our proxy server. We'll have to continue to update that mapping when we discover new URLs (it'd be great to get a list somehow!).
For example, we would URL rewrite:
ice.m1.ue1.app.chime.aws:3478 -> our-proxy.example.com:8000
ice.m3.ue1.app.chime.aws:3478 -> our-proxy.example.com:8001
Then those endpoints would forward to the original URLs based on a hardcoded list.
I was able to get UDP forwarding working with openresty, with a config like this:
stream {
upstream turn_backend1 {
server ice.m1.ue1.app.chime.aws:3478;
}
server {
listen 8000 udp;
proxy_pass turn_backend1;
ssl_preread on;
}
upstream turn_backend2 {
server ice.m3.ue1.app.chime.aws:3478;
}
server {
listen 8001 udp;
proxy_pass turn_backend2;
ssl_preread on;
}
}
I'm pretty certain it's possible to get TCP forwarding working with openresty but I haven't had a chance yet. I got that working in haproxy though, with a config like this:
listen turn1
mode tcp
bind 0.0.0.0:8000
server turn ice.m1.ue1.app.chime.aws:443
listen turn2
mode tcp
bind 0.0.0.0:8001
server turn2 ice.m3.ue1.app.chime.aws:443
And the URL rewriter is setup on the client side like this:
const meetingSessionConfiguration = new MeetingSessionConfiguration(JoinInfo.Meeting, JoinInfo.Attendee);
meetingSessionConfiguration.urls.urlRewriter = (uri) => {
if (uri?.match(/\.*signal.*?aws/gi)) {
const wsUri = uri.replace('wss', 'https');
return (
'wss://signal-proxy.example.com/' + // replace with your domain, use wss if you have ssl
'?url=' +
encodeURIComponent(wsUri)
);
} else if (uri?.match(/turn:*/)) {
if (uri === 'turn:ice.m1.ue1.app.chime.aws:3478?transport=udp') {
return 'turn:ice-proxy.example.com:8000?transport=udp';
} else if (uri === 'turn:ice.m3.ue1.app.chime.aws:3478?transport=udp') {
return 'turn:ice-proxy.example.com:8001?transport=udp';
} else if (uri === 'turns:ice.m3.ue1.app.chime.aws:443?transport=tcp') {
return 'turn:ice-proxy.example.com:8000?transport=tcp';
} else if (uri === 'turns:ice.m1.ue1.app.chime.aws:443?transport=tcp') {
return 'turn:ice-proxy.example.com:8001?transport=tcp';
} else {
throw new Error(`Unknown ice server: ${uri}`);
}
}
return uri;
};
That code is junk but you get the picture. Hope that helps somebody.
I'm going to leave this issue open since the documentation good be better, and it's possible there's a better, built-in way to handle things. If I open a PR for url rewrite updates I'll link it here.
Thanks for the response, i think this would probably help others in the future. May be a bit of time until this can make it into documentation since we'd probably need to set up our own working example :P.
As for the URLs it is just
signal.m1.ue1.app.chime.aws
ice.m1.ue1.app.chime.aws
Where ue1
can be replaced by the Meeting regions short hand, and m1 replaced by m1, m2, m3.
What are you trying to do?
We'd like to route all web meeting networking between the browser SDK and chime through a proxy. There are a handful of reasons one could want to do something like this, but in our case we are looking to limit the number of domains and IPs required by our application. Our users are often on sensitive networks that require an IT team to explicitly allow every outbound IP, hostname, and port. Chime requires over a hundred IP ranges to be opened, or open the wildcard
*.chime.aws
(which is equally problematic in this case).How can the documentation be improved to help your use case?
The documentation very briefly mentions proxying and suggests using url rewriting to do it. As written, it says clearly that media can be proxied (over TCP), and implies that everything can be proxied. It's not clear to me if that's actually possible. Forwarding all of the necessary data is not trivial and there are no examples.
In our minimal case, which is to have a web conference and record it - without any filters or other magic - we would want the following to be proxied:
turns:ice.m1.ue1.app.chime.aws?transport=tcp
. These URLs are passed to the pluggableurlRewriter
which implies this should be possible. We tried to proxy these a handful of different ways (generally inspired by work others have done proxying CoTURN, which I think is analogous) and were not able to get it working.signal.m1.ue1.app.chime.aws
. We were able to get this working using the urlRewriter, with an approach similar to the one here: https://github.com/aws/amazon-chime-sdk-js/issues/951https://static.sdkassets.chime.aws
. These URLs are not passed to the pluggableurlRewriter
so I don't see any obvious way to do this without editing source code.10.3.X.X
IP, which I assume is hole punching behavior that I don't completely understand. Maybe this works itself out if we proxy the turn listener, I'm not sure.More documentation on exactly what is possible with proxying, and more information on how to do it, would be very valuable.
Has anyone had success with any of the above?
What documentation have you looked at so far?
Github FAQs, API docs, and source code. See above.