Jump to content

[How-To] Emby Server on Windows Server with IIS as Reverse Proxy with Automatic Certificate Renewal


TheITJedi

Recommended Posts

TheITJedi
2 hours ago, mit3gt said:

This is a great guide.  I am having some issues though.  I am following the instructions and I am stuck at the web platform installer.  It appears to have been retired.  Is there a workaround for this?  I am running  Windows Server Essentials 2019.  Any help would be appreciated.  Thanks!

@mit3gtInstallers can be found here: https://www.iis.net/downloads/microsoft/url-rewrite#additionalDownloads 

Link to comment
Share on other sites

  • 1 month later...
KiraCreedeth

Great tutorial! I have been running Emby on W2K19 virtual machine with reverse proxy for 6 months now as in tutorial. Now I wanted to make LAMP WebServer to do some testing and I wondered how I could use reverse proxy from IIS so that I don't have to open more ports. Sorry if this seems obvious question. I am more familiar with Linux servers.

Edited by KiraCreedeth
Link to comment
Share on other sites

KiraCreedeth
5 hours ago, KiraCreedeth said:

Great tutorial! I have been running Emby on W2K19 virtual machine with reverse proxy for 6 months now as in tutorial. Now I wanted to make LAMP WebServer to do some testing and I wondered how I could use reverse proxy from IIS so that I don't have to open more ports. Sorry if this seems obvious question. I am more familiar with Linux servers.

Cannot edit for some reason so I quote myself.

TLDR: VM1 have IIS reverse proxy and Emby, VM2 have LAMP.

What do I need to add to IIS configs so proxy works from VM1 to VM2?

Link to comment
Share on other sites

TheITJedi

@KiraCreedethyoull basically wanna create a new site in IIS. Each site in IIS will need to have its own hostname on the bindings so it will know what site to return based on URL given. Then copy the forward/reverse rules from the Emby reverse proxy to your new site. And change out IP/URL of rewrites to match your LAMP VM. 

  • Thanks 1
Link to comment
Share on other sites

  • 5 months later...
Turbofiero

I had random pauses during playback I could never figure out and got this error in the console

net::ERR_HTTP2_PROTOCOL_ERROR

I finally dug into this and it turns out in C:\Windows\System32\LogFiles\HTTPERR there are logs from http.sys

It had quite a number of lines containing this

2024-01-19 05:02:22 my_client_ip_address%0 6014 my_server_ip_address%0 443 - - - 377 - - - Timer_MinBytesPerSecond - TCP
2024-01-19 05:02:22 my_client_ip_address%0 6014 my_server_ip_address%0 443 - - - 379 - - - Timer_MinBytesPerSecond - TCP
2024-01-19 05:02:27 my_client_ip_address%0 6014 my_server_ip_address%0 443 - - - 381 - - - Timer_MinBytesPerSecond - TCP
2024-01-19 05:02:27 my_client_ip_address%0 6014 my_server_ip_address%0 443 - - - 383 - - - Timer_MinBytesPerSecond - TCP
2024-01-19 05:02:27 my_client_ip_address%0 6014 my_server_ip_address%0 443 - - - 385 - - - Timer_MinBytesPerSecond - TCP
2024-01-19 05:02:27 my_client_ip_address%0 6014 my_server_ip_address%0 443 - - - 387 - - - Timer_MinBytesPerSecond - TCP
2024-01-19 05:02:27 my_client_ip_address%0 6014 my_server_ip_address%0 443 - - - 389 - - - Timer_MinBytesPerSecond - TCP

Heres how to resolve it, go to IIS Manager -> Configuration Editor -> system.applicationHost/webLimits -> minBytesPerSecond set it to 0, or just run this command from an elevated powershell 5.1 prompt 

Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.applicationHost/webLimits" -name "minBytesPerSecond" -value 0


 

Link to comment
Share on other sites

Clackdor

One thing that's been bugging me for quite some time is it seems that websockets aren't being passed through when you put emby in a sub path on iis, which completely breaks remote control.

I have emby reverse proxied at /emby on my site with the virtual directory converted to an application running under its own AppPool. I have the websockets module installed and enabled on the server, and verified it's enabled in the modules under the /emby path.

Any guidance on getting this working?

 

Link to comment
Share on other sites

1 minute ago, Clackdor said:

One thing that's been bugging me for quite some time is it seems that websockets aren't being passed through when you put emby in a sub path on iis, which completely breaks remote control.

I have emby reverse proxied at /emby on my site with the virtual directory converted to an application running under its own AppPool. I have the websockets module installed and enabled on the server, and verified it's enabled in the modules under the /emby path.

Any guidance on getting this working?

 

I would suggest looking at this: 

 

Link to comment
Share on other sites

Turbofiero

@Clackdor web interface works fine under a subpath, just tested this... skip all the extra you did, get rid of the extra app pool and stuff

just make a folder named emby in your application's root directory and drop this web.config in it, should work fine,  if the root config is also proxying to an application then youll need to exclude the emby folder with the conditions of its rewrite rule

 

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <clear />
                <rule name="Redirect to https" stopProcessing="true">
                    <match url=".*" negate="false" />
                    <conditions logicalGrouping="MatchAny" trackAllCaptures="false">
                        <add input="{HTTPS}" pattern="off" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Found" />
                </rule>
                <rule name="Proxy" stopProcessing="false">
                    <match url=".*" />
                    <serverVariables>
                        <set name="HTTP_X_REAL_IP" value="{REMOTE_ADDR}" />
                    </serverVariables>
                    <action type="Rewrite" url="http://127.0.0.1:8096/{R:0}" />
                </rule>
        </rules>
    </rewrite>
  </system.webServer>
</configuration>

 

Link to comment
Share on other sites

Turbofiero

Ooops that doesnt actually work, ill correct this. 

you will need this in your root web.config in order to pass the websocket to emby 

                <rule name="Proxy websocket" stopProcessing="false">
                    <match url="embywebsocket" />
                    <action type="Rewrite" url="http://127.0.0.1:8096/{R:0}" logRewrittenUrl="true" />
                </rule>

 

Edited by Turbofiero
Link to comment
Share on other sites

Clackdor

@TurbofieroI just saw your reply. I actually came to the same resolution with some trial and error. I got it working by adding that rewrite to the root site. It also works if you create another virtual directory/embywebsocket and rewrite that back to emby. After digging in iis logs I found requests going to /embywebsocket even when under a subpath.

My existing configuration already had emby running in a sub path converted to an application so it's not running under the same security context as the default site. While this workaround does work, it kind of defeats the purpose of running emby in its own AppPool.

@Lukeit seems the emby websocket endpoint is only listening for websocket requests at x.x.x.x:8096/embywebsocket and not x.x.x.x:8096/emby/embywebsocket. Can you confirm that's the current behavior?

If so, would it be possible to have emby listen on the subpath and the root of the application, perhaps as a toggle to enable if necessary. Not sure if that would break anything with the current expected behavior regarding websockets, but it couldn't hurt to ask.

That should fix issues people have with websockets with emby running under a sub path behind any reverse proxy without requiring any additional rewrites at the root of the site/proxy.

 

Link to comment
Share on other sites

15 minutes ago, Clackdor said:

@TurbofieroI just saw your reply. I actually came to the same resolution with some trial and error. I got it working by adding that rewrite to the root site. It also works if you create another virtual directory/embywebsocket and rewrite that back to emby. After digging in iis logs I found requests going to /embywebsocket even when under a subpath.

My existing configuration already had emby running in a sub path converted to an application so it's not running under the same security context as the default site. While this workaround does work, it kind of defeats the purpose of running emby in its own AppPool.

@Lukeit seems the emby websocket endpoint is only listening for websocket requests at x.x.x.x:8096/embywebsocket and not x.x.x.x:8096/emby/embywebsocket. Can you confirm that's the current behavior?

If so, would it be possible to have emby listen on the subpath and the root of the application, perhaps as a toggle to enable if necessary. Not sure if that would break anything with the current expected behavior regarding websockets, but it couldn't hurt to ask.

That should fix issues people have with websockets with emby running under a sub path behind any reverse proxy without requiring any additional rewrites at the root of the site/proxy.

 

Hi, no, this isn't true. It should be listening on both. Just tested to confirm.

Link to comment
Share on other sites

Turbofiero

@Lukeyes it does seem to listen on /emby/embywebsocket as well but the web client doesnt attempt this.... the web client goes for domain.tld/embywebsocket

Link to comment
Share on other sites

Clackdor

I'm also seeing the same behavior in emby theatre on windows and Xbox. I intentionally connected them through the reverse proxy and disabled the rewrite rule, no remote control, as soon as I enabled the rule it started working. I'm seeing the same thing when behind nginx too, so it's not something specific with being behind iis. The android client on the other hand works perfectly fine.

Link to comment
Share on other sites

darkassassin07

Putting Emby server in a subfolder/path behind a proxy instead of its own (sub)domain has never been a supported usecase....

 

If you can't tell the application server what path its in, it doesn't know how to tell it's clients what paths to use. Some things can be half-ass patched together with rewrite rules, but stuff almost always gets missed. Especially when not every path is passed to the client by the server, some are just hardcoded paths in the client. Rewrite rules cannot hande these at all.

 

Emby does not have settings to specify a base subpath/url. Only an external domain.

Edited by darkassassin07
  • Facepalm 1
Link to comment
Share on other sites

Clackdor
4 minutes ago, darkassassin07 said:

Putting Emby server in a subfolder/path behind a proxy instead of its own (sub)domain has never been a supported usecase....

 

If you can't tell the application server what path its in, it doesn't know how to tell it's clients what paths to use. Some things can be half-ass patched together with rewrite rules, but stuff almost always gets missed. Especially when not every path is passed to the client by the server, some are just hardcoded paths in the client. Rewrite rules cannot hande these at all.

 

Emby does not have settings to specify a base subpath/url. Only an external domain.

While emby doesn't have a way to specify a custom base URL, it does work if you append /emby to the URL. Even if it's a hard coded base path, it's still there.

I get not being able to specify a custom base as that would definitely break things.

Just a few posts above even @Luke himself confirmed that the websocket endpoint is listening under the /emby subdirectory as well. It just seems that the Web client still calls domain.tld/embywebsocket and never tries domain.tld/emby/embywebsocket.

While I never expect to be able to specify a custom base path, as again that would definitely be a breaking change in a lot of ways, the existence of a hardcoded base path at all means that most of the bits are already there for subpath support behind a reverse proxy. With a few tweaks, it would basically be a fully supported scenario.

Link to comment
Share on other sites

2 hours ago, Clackdor said:

While emby doesn't have a way to specify a custom base URL, it does work if you append /emby to the URL. Even if it's a hard coded base path, it's still there.

I get not being able to specify a custom base as that would definitely break things.

Just a few posts above even @Luke himself confirmed that the websocket endpoint is listening under the /emby subdirectory as well. It just seems that the Web client still calls domain.tld/embywebsocket and never tries domain.tld/emby/embywebsocket.

While I never expect to be able to specify a custom base path, as again that would definitely be a breaking change in a lot of ways, the existence of a hardcoded base path at all means that most of the bits are already there for subpath support behind a reverse proxy. With a few tweaks, it would basically be a fully supported scenario.

There was a reason for doing this a long time ago, and ironically enough, the feedback came from reverse proxy users. @pir8radiodo you recall?

Link to comment
Share on other sites

  • 2 weeks later...
Clackdor

@LukeI know you guys are busy after the 4.8 stable release, but I wanted to report on some things I have discovered after some testing.

I tried putting emby in a subdirectory at domain.tld/media with the same settings as domain.tld/emby.

When in the /media directory I'm seeing iis logs showing requests going to /media/embywebsocket. When in the /emby directory, the requests are going straight to /embywebsocket. 

This was reproducible on all browsers, and even switching from iis to nginx as the reverse proxy. Initially I tested on 4.7.14, but I'm seeing the same behavior under 4.8 stable.

It seems that if /emby is specified in the URL, the websocket requests are bypassing the subdirectory and going straight to the root. Maybe some kind of regex matching issue on the backend? I suspect that because emby isn't aware of a /media subdirectory, but it is aware of a /emby subdirectory.

For the time being I'm still working around this by adding another reverse proxy rule to send requests going to /embywebsocket to the emby backend. 

Ideally it would be nice to have a configurable base path that could be specified in server settings to allow for emby to operate properly in any subdirectory, but I understand if that isn't something you guys want to do at this time.

Regardless can you look into this further? I'd be happy to re-test and send some logs if you'd find that helpful. The workaround works, but it would be nice if if it wasn't necessary.

On a somewhat separate note, I noticed in 4.8 that the displayed external URL is no longer appending the remote port. This actually does allow a path to be specified in the external URL. If emby connect is sending users to the specified external address, then subpaths should theoretically work for connect users without issues, although I haven't tested this as neither myself nor my users use connect. 

I'm loving 4.8 stable so far with no other issues that I've noticed coming from 4.7.14.  It's nice being able to enable x-forwarded-for headers for local networks again so I can see all actual client ip's that are connecting through the reverse proxy.

Thanks for all the hard work you guys do!

 

 

Link to comment
Share on other sites

  • 3 weeks later...
On 2/3/2024 at 12:03 PM, Clackdor said:

@LukeI know you guys are busy after the 4.8 stable release, but I wanted to report on some things I have discovered after some testing.

I tried putting emby in a subdirectory at domain.tld/media with the same settings as domain.tld/emby.

When in the /media directory I'm seeing iis logs showing requests going to /media/embywebsocket. When in the /emby directory, the requests are going straight to /embywebsocket. 

This was reproducible on all browsers, and even switching from iis to nginx as the reverse proxy. Initially I tested on 4.7.14, but I'm seeing the same behavior under 4.8 stable.

It seems that if /emby is specified in the URL, the websocket requests are bypassing the subdirectory and going straight to the root. Maybe some kind of regex matching issue on the backend? I suspect that because emby isn't aware of a /media subdirectory, but it is aware of a /emby subdirectory.

For the time being I'm still working around this by adding another reverse proxy rule to send requests going to /embywebsocket to the emby backend. 

Ideally it would be nice to have a configurable base path that could be specified in server settings to allow for emby to operate properly in any subdirectory, but I understand if that isn't something you guys want to do at this time.

Regardless can you look into this further? I'd be happy to re-test and send some logs if you'd find that helpful. The workaround works, but it would be nice if if it wasn't necessary.

On a somewhat separate note, I noticed in 4.8 that the displayed external URL is no longer appending the remote port. This actually does allow a path to be specified in the external URL. If emby connect is sending users to the specified external address, then subpaths should theoretically work for connect users without issues, although I haven't tested this as neither myself nor my users use connect. 

I'm loving 4.8 stable so far with no other issues that I've noticed coming from 4.7.14.  It's nice being able to enable x-forwarded-for headers for local networks again so I can see all actual client ip's that are connecting through the reverse proxy.

Thanks for all the hard work you guys do!

 

 

Hi, we'll take a look at this. Thanks.

  • Thanks 1
Link to comment
Share on other sites

Turbofiero

Why not just use url rewrite to place the client IP in the X-Real-Ip header? 

 

Or is this ignored for local addresses?

Edited by Turbofiero
Link to comment
Share on other sites

Clackdor
5 minutes ago, Turbofiero said:

Why not just use url rewrite to place the client IP in the X-Real-Ip header? 

 

Or is this ignored for local addresses?

I'm already doing this. Client IP's for local and remote connections are showing up fine. 

The issue with websockets not being passed correctly to emby in a subdirectory affects being able to pause/stop playback and send messages to clients from the admin panel. 

Link to comment
Share on other sites

JGale

@TheITJediThanks for the guide, this is incredibly helpful, not to mention well-done. Appreciate it greatly, next time you're in Canada let me know.

I installed it on Windows 11, and have some notes to add.

  1. NSSM hasn't been updated since 2017, is it still a good option?
  2. Since Server Manager isn't an easy option on non-Server Windows, perhaps add a note to the main post using "Turn Windows Features On and Off".
  3. Role-based server installation wasn't an option, is that a big deal?
  4. With Web Platform Installer being deprecated in 2021, maybe update the original post to have the direct links to the IIS Rewrite module, and the IIS Server Farm module.
  5. Installing Server Farms was a big headache. If the necessary functionality can be added without Server Farms, it'd be easier for the Windows 11 installs.
  6. You could add a note that IISCrypto appears to work just fine in Windows 11, even though it's website only lists Windows Server installs.
  7. What's the best way to use IIS rewrites to redirect www.mywebsite.com to non-www mywebsite.com?

Again, thanks for the install guide, it was very well done, and made my life way easier.

Link to comment
Share on other sites

TheITJedi

@JGale

All of your suggestions are good. I haven’t found an easier option than NSSM. I need to find some time to update the original post, life has been very busy the last few years. I had/have plans to write a PowerShell script to automate most if not all of the configuration and setup. Basically so that the process is packaged up in an easy to use manner for less technical users or people that don’t have a lot of time. Hopefully I can get the time to do that and then update the original post. 

  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...
drashna
On 3/2/2024 at 10:49 AM, TheITJedi said:

@JGale

All of your suggestions are good. I haven’t found an easier option than NSSM. I need to find some time to update the original post, life has been very busy the last few years. I had/have plans to write a PowerShell script to automate most if not all of the configuration and setup. Basically so that the process is packaged up in an easy to use manner for less technical users or people that don’t have a lot of time. Hopefully I can get the time to do that and then update the original post. 

Ran into WinSW recently, and that works well.  It's not super actively developed, but it's not super complicated, either.  Uses .NET, as well.  

<service>
  <id>emby</id>
  <name>Emby Media Server</name>
  <description>This service runs the Emby Media Server.</description>
  <executable>C:\path\to\EmbyServer.exe</executable>
  <arguments>-service</arguments>
  <onfaulture action="restart" />
</service>

It also supports downloading on startup, as well as pre-start commands, too. 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...