TheITJedi 37 Posted March 1, 2021 Posted March 1, 2021 (edited) Hey, Hoping someone can help me with this. I use IIS/AAR to reverse proxy Emby to be publicly accessible and handle SSL offload. I have had everything working beautifully for quite sometime with one small exception. The client IPs in the Admin Dashboard all show ::1 regardless of where the user signs in from (tested using cellular and my little brothers computer in another state). I have verified that X-Forwarded-For and the client's IP are showing correctly in the logs for IIS however they do not display in the dashboard. My stack is: Windows Server 2019 IIS 10 AAR 3 Flow is: Internet -> IIS -> Emby My Web.Config looks like: <?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <clear></clear> <rule name="Redirect to https" enabled="true" patternSyntax="Wildcard" stopProcessing="true"> <match url="*" negate="false" /> <conditions logicalGrouping="MatchAny"> <add input="{HTTPS}" pattern="off" /> </conditions> <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Found" /> </rule> <rule name="Proxy to Emby" stopProcessing="true"> <match url="(.*)" /> <serverVariables> <set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" /> <set name="HTTP_ACCEPT_ENCODING" value="" /> </serverVariables> <action type="Rewrite" url="http://localhost:8096/{R:1}" /> </rule> </rules> <outboundRules> <rule name="Add Strict-Transport-Security when HTTPS" enabled="true"> <match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" /> <conditions> <add input="{HTTPS}" pattern="on" /> </conditions> <action type="Rewrite" value="max-age=31536000; includeSubDomains; preload" /> </rule> <rule name="Proxy to Emby" preCondition="ResponseIsHtml1" enabled="true"> <match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^http(s)?://http://localhost:8096/(.*)" /> <action type="Rewrite" value="http{R:1}://publicurl.mydomain.com/{R:2}" /> </rule> <rule name="Restore-AcceptEncoding" preCondition="NeedsRestoringAcceptEncoding"> <match serverVariable="HTTP_ACCEPT_ENCODING" pattern="^(.*)" /> <action type="Rewrite" value="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" /> </rule> <preConditions> <preCondition name="ResponseIsHtml1"> <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/(.+)" /> </preCondition> <preCondition name="NeedsRestoringAcceptEncoding"> <add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".+" /> </preCondition> </preConditions> </outboundRules> </rewrite> <caching enabled="false" enableKernelCache="false" /> <httpProtocol> <customHeaders> <add name="X-Frame-Options" value="SAMEORIGIN" /> <add name="X-Xss-Protection" value="1; mode=block" /> <add name="X-Content-Type-Options" value="nosniff" /> <add name="Referrer-Policy" value="same-origin" /> <add name="Feature-Policy" value="sync-xhr 'self'" /> <add name="Cache-Control" value="no-cache" /> </customHeaders> </httpProtocol> </system.webServer> </configuration> As I said, feature-wise everything works fantastic, it does appear that the bit-rate limiting for external streams does not apply due to this either. Thanks in advance! Edited March 2, 2021 by itjedi42 Additonal Information
Abobader 3243 Posted March 1, 2021 Posted March 1, 2021 Hello itjedi42, Please wait for someone from staff support or our members to reply to you. It's recommended to provide more info, as it explain in this thread: Thank you. Emby Team
TheITJedi 37 Posted March 1, 2021 Author Posted March 1, 2021 @Abobader, I dont know that its a bug. Do you happen to know what headers Emby looks at to get the client IP address? I would assume it would consume the X-Forwarded-For header and be able to use that, however it does not appear to.
TheITJedi 37 Posted March 1, 2021 Author Posted March 1, 2021 @Abobader It looks very much like Emby just doesnt care about X-Forwarded-For and only cares about what the connection IP address is.
TheITJedi 37 Posted March 1, 2021 Author Posted March 1, 2021 (edited) 7 hours ago, PenkethBoy said: ::1 = to localhost yes, im aware. trying to determine why Emby won't read the X-Forwarded-For header and use it rather than reporting localhost/ip of reverse proxy. HTTP_X_FORWARDED_FOR/X-Forwarded-For is being set and I can read it fine with other code behind the reverse proxy, however depending on if the reverse proxy rule is "localhost" or 10.0.1.5, Emby will show either ::1 or 10.0.1.5 for all connections. I have a couple other things set up on my server using similar reverse proxy configurations and they successfully consume the correct IP address from X-Forwarded-For. At this point I am curious as to the exact mechanism that Emby is using to determine the client's IP and why it doesnt appear to observe the industry standard X-Forwarded-For/HTTP_X_FORWARDED_FOR headers/variables. Edited March 1, 2021 by itjedi42 Additional Information
Happy2Play 9153 Posted March 1, 2021 Posted March 1, 2021 @pir8radiodo you have some insight on this.
pir8radio 1302 Posted March 2, 2021 Posted March 2, 2021 (edited) 13 hours ago, itjedi42 said: yes, im aware. trying to determine why Emby won't read the X-Forwarded-For header and use it rather than reporting localhost/ip of reverse proxy. HTTP_X_FORWARDED_FOR/X-Forwarded-For is being set and I can read it fine with other code behind the reverse proxy, however depending on if the reverse proxy rule is "localhost" or 10.0.1.5, Emby will show either ::1 or 10.0.1.5 for all connections. I have a couple other things set up on my server using similar reverse proxy configurations and they successfully consume the correct IP address from X-Forwarded-For. At this point I am curious as to the exact mechanism that Emby is using to determine the client's IP and why it doesnt appear to observe the industry standard X-Forwarded-For/HTTP_X_FORWARDED_FOR headers/variables. 6 hours ago, Happy2Play said: @pir8radiodo you have some insight on this. I'll have to find the post, luke said something about a change to x-forwarded for (been months now).... I'll have to find that post, i could be imagining this conversation. Try and set x-real-ip either by mapping it to x-forwarded-for or just passing it.. send an IP to emby via x-real-ip and see what you get.. Im doing both, and I don't have time tonight to test which one emby is actually abiding by. Emby USED to list all of the proxy IP's for every connecting user like 10.x.x.1, 11.x.x.2 in one line, but that stopped a long time ago, when i think emby started ignoring x-forwarded-for, either that or emby only "looks" at the first or last IP in that string, which could be the wrong IP. Edited March 2, 2021 by pir8radio
TheITJedi 37 Posted March 2, 2021 Author Posted March 2, 2021 (edited) 11 hours ago, pir8radio said: I'll have to find the post, luke said something about a change to x-forwarded for (been months now).... I'll have to find that post, i could be imagining this conversation. Try and set x-real-ip either by mapping it to x-forwarded-for or just passing it.. send an IP to emby via x-real-ip and see what you get.. Im doing both, and I don't have time tonight to test which one emby is actually abiding by. Emby USED to list all of the proxy IP's for every connecting user like 10.x.x.1, 11.x.x.2 in one line, but that stopped a long time ago, when i think emby started ignoring x-forwarded-for, either that or emby only "looks" at the first or last IP in that string, which could be the wrong IP. I am now passing: - X-Forwarded-For - X-Real-IP - X-Client-IP Still only getting IP of reverse proxy in Emby rather than actual user's IP. Seriously... is there not a dev for the project that can tell me exactly what headers it wants and will honor? I can not be the first person to be using IIS for a reverse proxy. @Luke Edited March 2, 2021 by itjedi42
Luke 38863 Posted March 2, 2021 Posted March 2, 2021 There's a lot of people here using a reverse proxy. I Would suggest checking out @pir8radio 's nginx configuration.
TheITJedi 37 Posted March 2, 2021 Author Posted March 2, 2021 @Luke nginx is not an option in my environment. I just want to know what header Emby will actually read the original client's IP from so it will display in activity and be able to differentiate between external and internal clients. None of these are acknowledged by Emby: - X-Original-Host - X-Forwarded-For - X-Real-IP - X-Client-IP
Luke 38863 Posted March 2, 2021 Posted March 2, 2021 3 minutes ago, itjedi42 said: @Luke nginx is not an option in my environment. I just want to know what header Emby will actually read the original client's IP from so it will display in activity and be able to differentiate between external and internal clients. None of these are acknowledged by Emby: - X-Original-Host - X-Forwarded-For - X-Real-IP - X-Client-IP I understand, but you can still look at how he configured it and translate that to the reverse proxy software that you're using.
Solution TheITJedi 37 Posted March 2, 2021 Author Solution Posted March 2, 2021 (edited) @Luke Thanks, I was able to find the answer. For anyone wondering, it appears that if the X-Real-IP is populated from X-Forwarded-For it won't work. X-Real-IP needs to be populated as such: <set name="HTTP_X_REAL_IP" value="{REMOTE_ADDR}" /> Here is the working copy of my Web.Config for any other IIS users. (just change IP for backend host and my.public.url to match your public url.) Supports: SSL offload, forced HTTPS, remote control, and is fully transparent to Emby. <?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <clear></clear> <rule name="Redirect to https" enabled="true" patternSyntax="Wildcard" stopProcessing="true"> <match url="*" negate="false" /> <conditions logicalGrouping="MatchAny"> <add input="{HTTPS}" pattern="off" /> </conditions> <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Found" /> </rule> <rule name="Proxy to Emby" stopProcessing="false"> <match url="(.*)" /> <serverVariables> <set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" /> <set name="HTTP_ACCEPT_ENCODING" value="" /> <set name="HTTP_X_REAL_IP" value="{REMOTE_ADDR}" /> </serverVariables> <action type="Rewrite" url="http://10.0.1.5:8096/{R:1}" logRewrittenUrl="true" /> <conditions> <add input="/{R:1}" pattern=".well-known" negate="true" /> </conditions> </rule> </rules> <outboundRules> <rule name="Add Strict-Transport-Security when HTTPS" enabled="true"> <match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" /> <conditions> <add input="{HTTPS}" pattern="on" /> </conditions> <action type="Rewrite" value="max-age=31536000; includeSubDomains; preload" /> </rule> <rule name="Proxy to Emby" preCondition="ResponseIsHtml1" enabled="true"> <match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^http(s)?://http://localhost:8096/(.*)" /> <action type="Rewrite" value="http{R:1}://my.public.url/{R:2}" /> </rule> <rule name="Restore-AcceptEncoding" preCondition="NeedsRestoringAcceptEncoding"> <match serverVariable="HTTP_ACCEPT_ENCODING" pattern="^(.*)" /> <action type="Rewrite" value="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" /> </rule> <preConditions> <preCondition name="ResponseIsHtml1"> <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/(.+)" /> </preCondition> <preCondition name="NeedsRestoringAcceptEncoding"> <add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".+" /> </preCondition> </preConditions> </outboundRules> </rewrite> <caching enabled="false" enableKernelCache="false" /> <httpProtocol> <customHeaders> <add name="X-Frame-Options" value="SAMEORIGIN" /> <add name="X-Xss-Protection" value="1; mode=block" /> <add name="X-Content-Type-Options" value="nosniff" /> <add name="Referrer-Policy" value="same-origin" /> <add name="Feature-Policy" value="sync-xhr 'self'" /> <add name="Cache-Control" value="no-cache" /> </customHeaders> </httpProtocol> </system.webServer> </configuration> Edited March 2, 2021 by itjedi42
pir8radio 1302 Posted March 2, 2021 Posted March 2, 2021 4 hours ago, TheITJedi said: @Luke Thanks, I was able to find the answer. For anyone wondering, it appears that if the X-Real-IP is populated from X-Forwarded-For it won't work. X-Real-IP needs to be populated as such: <set name="HTTP_X_REAL_IP" value="{REMOTE_ADDR}" /> Here is the working copy of my Web.Config for any other IIS users. (just change IP for backend host and my.public.url to match your public url.) Supports: SSL offload, forced HTTPS, remote control, and is fully transparent to Emby. I started out with IIS as a reverse proxy, but had all kinds of issues, I think those posts are listed in the forum here somewhere.. Glad you found the answer, It might be that real_IP cant handle the multiple addresses found in an x_forwarded_for string. @Luke the emby web server used to grab the "X_Forwarded_For" IP address and pass it on to emby... What one is the internal webserver "looking" at these days? I used to see multiple IP's listed in my emby dashboard which would tell me what hops the user took to get to me (through cloudflare) these days i only see ONE ip listed in my dashboard and its usually the client only ip. Just curious if you know off the top of your head?
Luke 38863 Posted March 2, 2021 Posted March 2, 2021 First we check x-forwarded-for, then if we don't get anything from there we move on to x-real-ip. both can handle multiple ip's being specified, comma delimited, in which case, the last one is used. 1
benwallner 2 Posted June 23, 2022 Posted June 23, 2022 On 02/03/2021 at 23:39, Luke said: First we check x-forwarded-for, then if we don't get anything from there we move on to x-real-ip. both can handle multiple ip's being specified, comma delimited, in which case, the last one is used. Can this behavior be changed? According to the MDN Web Docs the first IP should be used https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
Luke 38863 Posted June 27, 2022 Posted June 27, 2022 On 6/23/2022 at 3:56 AM, benwallner said: Can this behavior be changed? According to the MDN Web Docs the first IP should be used https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For Hi @benwallner that's what we do for X-Forwarded-For. It's only for X-Real-IP that we use the last value.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now