[GH-ISSUE #2037] Exchange Server with Nginx Proxy Manager #1472

Open
opened 2026-02-26 07:31:12 +03:00 by kerem · 29 comments
Owner

Originally created by @azaloum90 on GitHub (May 4, 2022).
Original GitHub issue: https://github.com/NginxProxyManager/nginx-proxy-manager/issues/2037

I have some settings that will supposedly work, but I am unsure how to enter these into NPM. Any ideas?

http://blog.manton.im/2016/04/configure-nginx-with-exchange-2010-2013.html

server {
  listen 192.168.0.1:443 ssl;
  server_name owa.myserver.com;
  ssl_certificate /etc/nginx/ssl/cert.pem;
  ssl_certificate_key /etc/nginx/ssl/key.key;
  access_log  /var/log/nginx/mydomain.access.log  combined;
  error_log  /var/log/nginx/mydomain.error.log;
  client_max_body_size 3G;
  proxy_request_buffering off;
  ssl_session_timeout     5m;
  tcp_nodelay on;
    proxy_http_version      1.1;
    proxy_read_timeout      360;
    proxy_pass_header       Date;
    proxy_pass_header       Server;
    proxy_pass_header      Authorization;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_pass_request_headers on;
    more_set_input_headers 'Authorization: $http_authorization';
    proxy_set_header Accept-Encoding "";
    more_set_headers -s 401 'WWW-Authenticate: Basic realm="fqdnofyourexchangeserver"';
    proxy_buffering off;
    proxy_set_header Connection "Keep-Alive";
  location / {
  return 301 https://owa.myserver.com/owa;
  }
  location ~* ^/owa { proxy_pass https://fqdnofyourexchangeserver; }
  location ~* ^/Microsoft-Server-ActiveSync { proxy_pass https://fqdnofyourexchangeserver; }
  location ~* ^/ecp { proxy_pass https://fqdnofyourexchangeserver; }
  location ~* ^/rpc { proxy_pass https://fqdnofyourexchangeserver; }
}
# redirect all http traffic to https
server {
  listen 80;
  server_name owa.myserver.com;
  return 301 https://$host$request_uri;
}
Originally created by @azaloum90 on GitHub (May 4, 2022). Original GitHub issue: https://github.com/NginxProxyManager/nginx-proxy-manager/issues/2037 I have some settings that will supposedly work, but I am unsure how to enter these into NPM. Any ideas? http://blog.manton.im/2016/04/configure-nginx-with-exchange-2010-2013.html ``` server { listen 192.168.0.1:443 ssl; server_name owa.myserver.com; ssl_certificate /etc/nginx/ssl/cert.pem; ssl_certificate_key /etc/nginx/ssl/key.key; access_log /var/log/nginx/mydomain.access.log combined; error_log /var/log/nginx/mydomain.error.log; client_max_body_size 3G; proxy_request_buffering off; ssl_session_timeout 5m; tcp_nodelay on; proxy_http_version 1.1; proxy_read_timeout 360; proxy_pass_header Date; proxy_pass_header Server; proxy_pass_header Authorization; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass_request_headers on; more_set_input_headers 'Authorization: $http_authorization'; proxy_set_header Accept-Encoding ""; more_set_headers -s 401 'WWW-Authenticate: Basic realm="fqdnofyourexchangeserver"'; proxy_buffering off; proxy_set_header Connection "Keep-Alive"; location / { return 301 https://owa.myserver.com/owa; } location ~* ^/owa { proxy_pass https://fqdnofyourexchangeserver; } location ~* ^/Microsoft-Server-ActiveSync { proxy_pass https://fqdnofyourexchangeserver; } location ~* ^/ecp { proxy_pass https://fqdnofyourexchangeserver; } location ~* ^/rpc { proxy_pass https://fqdnofyourexchangeserver; } } # redirect all http traffic to https server { listen 80; server_name owa.myserver.com; return 301 https://$host$request_uri; } ```
Author
Owner

@mirotrex commented on GitHub (Nov 23, 2022):

Are there any Updates on this issue? @jc21

<!-- gh-comment-id:1324765075 --> @mirotrex commented on GitHub (Nov 23, 2022): Are there any Updates on this issue? @jc21
Author
Owner

@azaloum90 commented on GitHub (Nov 23, 2022):

Are there any Updates on this issue? @jc21

I got nothing back from anyone... Nobody seems to know how to implement it. I gave up and went back to Microsoft Web Application Proxy

<!-- gh-comment-id:1325543381 --> @azaloum90 commented on GitHub (Nov 23, 2022): > Are there any Updates on this issue? @jc21 I got nothing back from anyone... Nobody seems to know how to implement it. I gave up and went back to Microsoft Web Application Proxy
Author
Owner

@ichilver commented on GitHub (Jun 9, 2023):

I tried adding the below in the NPM advanced tab, and also for each of the locations you mentioned above.

/
/owa
/ecp
/rpc
/Microsoft-Server-ActiveSync
/mapi
client_max_body_size   3G;
tcp_nodelay   on;

proxy_request_buffering off;
proxy_buffering off;

proxy_http_version     1.1;
proxy_read_timeout     3600;

proxy_pass_request_headers on;
proxy_pass_header Date;
proxy_pass_header Server;
proxy_pass_header Authorization;

proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Accept-Encoding "";

more_set_input_headers 'Authorization: $http_authorization';
more_set_headers -s 401 'WWW-Authenticate: Basic realm="exchange-server.mydomain.com"';

However when I go to https://exchange-server.mydomain.com/owa I get an error 'HTTP Error 400. The request has an invalid header name.'

I connected to the container and went to the logs in /data/logs but I can't see which header its complaining about.

However if you took out the line proxy_set_header Host $host; it works

Well!!! Works to a point.

  • I have OWA webaccess working.
  • I have ECP working, although I soon redirected that as I don't want the ECP publicly accessible
  • I even seem to have ActiveSync working as I am running Nine from Android App store and that connects too.

What I can't get working is outlook from outside on the Internet when the Exchange IIS server only has "Windows Auth" enabled. If I enable "Basic Auth" it gets a bit further but still doesn't works.

I can see it does the autodiscover stuff ok and then redirects to https://exchange-server.mydomain.com/mapi and asks for a username and password.

I tried domain\username and username@mydomain.com and neither work.
I tried setting the Realm to exchange-server.mydomain.com and exchange-server.msad.mydomain.com

I am missing something for passing the correct type of authentication, but what???
I need to support the "Windows Auth" on the IIS server, but how do I that from NPM?

Any ideas?

Has anyone got MS Exchange working behind a NPM for OWA, ActiveSync and Outlook?

<!-- gh-comment-id:1584298163 --> @ichilver commented on GitHub (Jun 9, 2023): I tried adding the below in the NPM advanced tab, and also for each of the locations you mentioned above. ``` / /owa /ecp /rpc /Microsoft-Server-ActiveSync /mapi ``` ``` client_max_body_size 3G; tcp_nodelay on; proxy_request_buffering off; proxy_buffering off; proxy_http_version 1.1; proxy_read_timeout 3600; proxy_pass_request_headers on; proxy_pass_header Date; proxy_pass_header Server; proxy_pass_header Authorization; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection "Keep-Alive"; proxy_set_header Accept-Encoding ""; more_set_input_headers 'Authorization: $http_authorization'; more_set_headers -s 401 'WWW-Authenticate: Basic realm="exchange-server.mydomain.com"'; ``` However when I go to https://exchange-server.mydomain.com/owa I get an error 'HTTP Error 400. The request has an invalid header name.' I connected to the container and went to the logs in /data/logs but I can't see which header its complaining about. However if you took out the line `proxy_set_header Host $host;` it works Well!!! Works to a point. * I have OWA webaccess working. * I have ECP working, although I soon redirected that as I don't want the ECP publicly accessible * I even seem to have ActiveSync working as I am running Nine from Android App store and that connects too. What I can't get working is outlook from outside on the Internet when the Exchange IIS server only has "Windows Auth" enabled. If I enable "Basic Auth" it gets a bit further but still doesn't works. I can see it does the autodiscover stuff ok and then redirects to https://exchange-server.mydomain.com/mapi and asks for a username and password. I tried domain\username and username@mydomain.com and neither work. I tried setting the Realm to `exchange-server.mydomain.com` and `exchange-server.msad.mydomain.com` I am missing something for passing the correct type of authentication, but what??? I need to support the "Windows Auth" on the IIS server, but how do I that from NPM? Any ideas? Has anyone got MS Exchange working behind a NPM for OWA, ActiveSync and Outlook?
Author
Owner

@azaloum90 commented on GitHub (Jun 9, 2023):

I tried adding the below in the NPM advanced tab, and also for each of the locations you mentioned above.

/
/owa
/ecp
/rpc
/Microsoft-Server-ActiveSync
/mapi
client_max_body_size   3G;
tcp_nodelay   on;

proxy_request_buffering off;
proxy_buffering off;

proxy_http_version     1.1;
proxy_read_timeout     3600;

proxy_pass_request_headers on;
proxy_pass_header Date;
proxy_pass_header Server;
proxy_pass_header Authorization;

proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Accept-Encoding "";

more_set_input_headers 'Authorization: $http_authorization';
more_set_headers -s 401 'WWW-Authenticate: Basic realm="exchange-server.mydomain.com"';

However when I go to https://exchange-server.mydomain.com/owa I get an error 'HTTP Error 400. The request has an invalid header name.'

I connected to the container and went to the logs in /data/logs but I can't see which header its complaining about.

However if you took out the line proxy_set_header Host $host; it works

Well!!! Works to a point.

  • I have OWA webaccess working.
  • I have ECP working, although I soon redirected that as I don't want the ECP publicly accessible
  • I even seem to have ActiveSync working as I am running Nine from Android App store and that connects too.

What I can't get working is outlook from outside on the Internet when the Exchange IIS server only has "Windows Auth" enabled. If I enable "Basic Auth" it gets a bit further but still doesn't works.

I can see it does the autodiscover stuff ok and then redirects to https://exchange-server.mydomain.com/mapi and asks for a username and password.

I tried domain\username and username@mydomain.com and neither work. I tried setting the Realm to exchange-server.mydomain.com and exchange-server.msad.mydomain.com

I am missing something for passing the correct type of authentication, but what??? I need to support the "Windows Auth" on the IIS server, but how do I that from NPM?

Any ideas?

Has anyone got MS Exchange working behind a NPM for OWA, ActiveSync and Outlook?

You for so much further than I ever did! I'm intrigued as to what else gets in the way of allowing this. I believe the mechanism that needs to function is "Forms Authentication", but not sure what that needs from an http reverse proxy perspective.

Wish MS had more info, I don't think they'll ever consider this a "supported" configuration so I can't ask.

Only other thing I can think of is running Wireshark from my existing Web Application Proxy and doing some pakcey captures

<!-- gh-comment-id:1584547909 --> @azaloum90 commented on GitHub (Jun 9, 2023): > I tried adding the below in the NPM advanced tab, and also for each of the locations you mentioned above. > > ``` > / > /owa > /ecp > /rpc > /Microsoft-Server-ActiveSync > /mapi > ``` > > ``` > client_max_body_size 3G; > tcp_nodelay on; > > proxy_request_buffering off; > proxy_buffering off; > > proxy_http_version 1.1; > proxy_read_timeout 3600; > > proxy_pass_request_headers on; > proxy_pass_header Date; > proxy_pass_header Server; > proxy_pass_header Authorization; > > proxy_set_header Host $host; > proxy_set_header X-Forwarded-Proto https; > proxy_set_header X-Real-IP $remote_addr; > proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; > proxy_set_header Connection "Keep-Alive"; > proxy_set_header Accept-Encoding ""; > > more_set_input_headers 'Authorization: $http_authorization'; > more_set_headers -s 401 'WWW-Authenticate: Basic realm="exchange-server.mydomain.com"'; > ``` > > However when I go to https://exchange-server.mydomain.com/owa I get an error 'HTTP Error 400. The request has an invalid header name.' > > I connected to the container and went to the logs in /data/logs but I can't see which header its complaining about. > > However if you took out the line `proxy_set_header Host $host;` it works > > Well!!! Works to a point. > > * I have OWA webaccess working. > * I have ECP working, although I soon redirected that as I don't want the ECP publicly accessible > * I even seem to have ActiveSync working as I am running Nine from Android App store and that connects too. > > What I can't get working is outlook from outside on the Internet when the Exchange IIS server only has "Windows Auth" enabled. If I enable "Basic Auth" it gets a bit further but still doesn't works. > > I can see it does the autodiscover stuff ok and then redirects to https://exchange-server.mydomain.com/mapi and asks for a username and password. > > I tried domain\username and [username@mydomain.com](mailto:username@mydomain.com) and neither work. I tried setting the Realm to `exchange-server.mydomain.com` and `exchange-server.msad.mydomain.com` > > I am missing something for passing the correct type of authentication, but what??? I need to support the "Windows Auth" on the IIS server, but how do I that from NPM? > > Any ideas? > > Has anyone got MS Exchange working behind a NPM for OWA, ActiveSync and Outlook? You for so much further than I ever did! I'm intrigued as to what else gets in the way of allowing this. I believe the mechanism that needs to function is "Forms Authentication", but not sure what that needs from an http reverse proxy perspective. Wish MS had more info, I don't think they'll ever consider this a "supported" configuration so I can't ask. Only other thing I can think of is running Wireshark from my existing Web Application Proxy and doing some pakcey captures
Author
Owner

@ichilver commented on GitHub (Jun 9, 2023):

@azaloum90 I think I got all the stuff working for HTTP GET requests and stuff requiring Basic Auth.

What I can't get working is the NTLM auth on /autodiscover and /mapi

I am either missing something in the NPM settings or its just not possible to proxy NTLM auth. Something in the back of my mind is thinking this isn't possible because technically NPM is acting as "a man in the middle". IDK.

<!-- gh-comment-id:1584622935 --> @ichilver commented on GitHub (Jun 9, 2023): @azaloum90 I think I got all the stuff working for HTTP GET requests and stuff requiring Basic Auth. What I can't get working is the NTLM auth on /autodiscover and /mapi I am either missing something in the NPM settings or its just not possible to proxy NTLM auth. Something in the back of my mind is thinking this isn't possible because technically NPM is acting as "a man in the middle". IDK. <Scratching head>
Author
Owner

@azaloum90 commented on GitHub (Jun 9, 2023):

@azaloum90 I think I got all the stuff working for HTTP GET requests and stuff requiring Basic Auth.

What I can't get working is the NTLM auth on /autodiscover and /mapi

I am either missing something in the NPM settings or its just not possible to proxy NTLM auth. Something in the back of my mind is thinking this isn't possible because technically NPM is acting as "a man in the middle". IDK.

It's definitely possible because MAPI authentication works fine with Microsoft Web Application Proxy (that's actually a Microsoft-supported configuration, though you are supposed to pass it through ADFS for authentication which I do not). Brings me back to "what's missing in the packets", so I think I'd have to look at the packets traversing:

From Microsoft Web App Proxy
To Exchange

And then compare that with packets traversing:

From NPM
To Exchange

Unfortunately my NPM setup has been turned off for over a year now, but I suppose I could grab some packet captures from my Web App Proxy to Exchange servers and then compare with yours?

<!-- gh-comment-id:1584834480 --> @azaloum90 commented on GitHub (Jun 9, 2023): > @azaloum90 I think I got all the stuff working for HTTP GET requests and stuff requiring Basic Auth. > > What I can't get working is the NTLM auth on /autodiscover and /mapi > > I am either missing something in the NPM settings or its just not possible to proxy NTLM auth. Something in the back of my mind is thinking this isn't possible because technically NPM is acting as "a man in the middle". IDK. It's definitely possible because MAPI authentication works fine with Microsoft Web Application Proxy (that's actually a Microsoft-supported configuration, though you are supposed to pass it through ADFS for authentication which I do not). Brings me back to "what's missing in the packets", so I think I'd have to look at the packets traversing: From Microsoft Web App Proxy To Exchange And then compare that with packets traversing: From NPM To Exchange Unfortunately my NPM setup has been turned off for over a year now, but I suppose I could grab some packet captures from my Web App Proxy to Exchange servers and then compare with yours?
Author
Owner

@ilya-maltsev commented on GitHub (Jul 27, 2023):

Hi,
try to check that basic authentication enabled for MAPI on Exchange:
https://learn.microsoft.com/en-us/exchange/clients/mapi-over-http/configure-mapi-over-http?view=exchserver-2019
After exec that command:
Set-MapiVirtualDirectory -Identity "<exchange_host>\mapi (Default Web Site)" -ExternalURL https://<mail.domain.com>/mapi -IISAuthenticationMethods NTLM, OAuth , Basic
in our case, all works fine

<!-- gh-comment-id:1652941134 --> @ilya-maltsev commented on GitHub (Jul 27, 2023): Hi, try to check that basic authentication enabled for MAPI on Exchange: https://learn.microsoft.com/en-us/exchange/clients/mapi-over-http/configure-mapi-over-http?view=exchserver-2019 After exec that command: `Set-MapiVirtualDirectory -Identity "<exchange_host>\mapi (Default Web Site)" -ExternalURL https://<mail.domain.com>/mapi -IISAuthenticationMethods NTLM, OAuth , Basic` in our case, all works fine
Author
Owner

@azaloum90 commented on GitHub (Jan 24, 2024):

Hi, try to check that basic authentication enabled for MAPI on Exchange: https://learn.microsoft.com/en-us/exchange/clients/mapi-over-http/configure-mapi-over-http?view=exchserver-2019 After exec that command: Set-MapiVirtualDirectory -Identity "<exchange_host>\mapi (Default Web Site)" -ExternalURL https://<mail.domain.com>/mapi -IISAuthenticationMethods NTLM, OAuth , Basic in our case, all works fine

Hey, could you by chance show me some screenshots of how you have the configuration entered into NPM? The entry points are rather confusing and I am curious as to what your configuration is.

<!-- gh-comment-id:1907208704 --> @azaloum90 commented on GitHub (Jan 24, 2024): > Hi, try to check that basic authentication enabled for MAPI on Exchange: https://learn.microsoft.com/en-us/exchange/clients/mapi-over-http/configure-mapi-over-http?view=exchserver-2019 After exec that command: `Set-MapiVirtualDirectory -Identity "<exchange_host>\mapi (Default Web Site)" -ExternalURL https://<mail.domain.com>/mapi -IISAuthenticationMethods NTLM, OAuth , Basic` in our case, all works fine Hey, could you by chance show me some screenshots of how you have the configuration entered into NPM? The entry points are rather confusing and I am curious as to what your configuration is.
Author
Owner

@ilya-maltsev commented on GitHub (Jan 24, 2024):

@azaloum90
that command must be directly executed on Windows Server with installed Exchange via Powershell

<!-- gh-comment-id:1907923296 --> @ilya-maltsev commented on GitHub (Jan 24, 2024): @azaloum90 that command must be directly executed on Windows Server with installed Exchange via Powershell
Author
Owner

@azaloum90 commented on GitHub (Jan 24, 2024):

@azaloum90 that command must be directly executed on Windows Server with installed Exchange via Powershell

Hey,

I'm aware of that piece, I'm just curious how you have the rest of the configuration entered into NPM?

<!-- gh-comment-id:1908357291 --> @azaloum90 commented on GitHub (Jan 24, 2024): > @azaloum90 that command must be directly executed on Windows Server with installed Exchange via Powershell Hey, I'm aware of that piece, I'm just curious how you have the rest of the configuration entered into NPM?
Author
Owner

@ilya-maltsev commented on GitHub (Jan 24, 2024):

@azaloum90 Look at magic lines

http {

map $status $forceBasicOutlook{         #magic_line
        401    'Basic realm=$host';     #magic_line
}                                       #magic_line

}

server {
...
    keepalive_timeout 3h;
    proxy_read_timeout 3h;

    proxy_pass_header       Date;
    proxy_pass_header       Server;
    proxy_pass_header       Authorization;

    proxy_hide_header WWW-Authenticate;                      #magic_line
    add_header WWW-Authenticate $forceBasicOutlook always;   #magic_line

    proxy_buffering off;
    proxy_http_version 1.1;
    proxy_request_buffering off;
    proxy_set_header Connection "Keep-Alive";

...
}
<!-- gh-comment-id:1908397189 --> @ilya-maltsev commented on GitHub (Jan 24, 2024): @azaloum90 Look at magic lines ``` http { map $status $forceBasicOutlook{ #magic_line 401 'Basic realm=$host'; #magic_line } #magic_line } server { ... keepalive_timeout 3h; proxy_read_timeout 3h; proxy_pass_header Date; proxy_pass_header Server; proxy_pass_header Authorization; proxy_hide_header WWW-Authenticate; #magic_line add_header WWW-Authenticate $forceBasicOutlook always; #magic_line proxy_buffering off; proxy_http_version 1.1; proxy_request_buffering off; proxy_set_header Connection "Keep-Alive"; ... }
Author
Owner

@azaloum90 commented on GitHub (Jan 29, 2024):

@azaloum90 Look at magic lines

http {

map $status $forceBasicOutlook{         #magic_line
        401    'Basic realm=$host';     #magic_line
}                                       #magic_line

}

server {
...
    keepalive_timeout 3h;
    proxy_read_timeout 3h;

    proxy_pass_header       Date;
    proxy_pass_header       Server;
    proxy_pass_header       Authorization;

    proxy_hide_header WWW-Authenticate;                      #magic_line
    add_header WWW-Authenticate $forceBasicOutlook always;   #magic_line

    proxy_buffering off;
    proxy_http_version 1.1;
    proxy_request_buffering off;
    proxy_set_header Connection "Keep-Alive";

...
}

Thanks for this. How many entries for your mail server? just a mail.domain.com entry?

<!-- gh-comment-id:1913923575 --> @azaloum90 commented on GitHub (Jan 29, 2024): > @azaloum90 Look at magic lines > > ``` > http { > > map $status $forceBasicOutlook{ #magic_line > 401 'Basic realm=$host'; #magic_line > } #magic_line > > } > > server { > ... > keepalive_timeout 3h; > proxy_read_timeout 3h; > > proxy_pass_header Date; > proxy_pass_header Server; > proxy_pass_header Authorization; > > proxy_hide_header WWW-Authenticate; #magic_line > add_header WWW-Authenticate $forceBasicOutlook always; #magic_line > > proxy_buffering off; > proxy_http_version 1.1; > proxy_request_buffering off; > proxy_set_header Connection "Keep-Alive"; > > ... > } > ``` Thanks for this. How many entries for your mail server? just a mail.domain.com entry?
Author
Owner

@vtornik commented on GitHub (Feb 6, 2024):

@azaloum90 Look at magic lines

http {

map $status $forceBasicOutlook{         #magic_line
        401    'Basic realm=$host';     #magic_line
}                                       #magic_line

}

server {
...
    keepalive_timeout 3h;
    proxy_read_timeout 3h;

    proxy_pass_header       Date;
    proxy_pass_header       Server;
    proxy_pass_header       Authorization;

    proxy_hide_header WWW-Authenticate;                      #magic_line
    add_header WWW-Authenticate $forceBasicOutlook always;   #magic_line

    proxy_buffering off;
    proxy_http_version 1.1;
    proxy_request_buffering off;
    proxy_set_header Connection "Keep-Alive";

...
}

Thanks for this. Could you tell me how to perform this configuration in the Nginx proxy manager interface? How and in which tab should this be specified?
1-npm-details
2-npm-custom location
3-npm-Advanced

<!-- gh-comment-id:1930085033 --> @vtornik commented on GitHub (Feb 6, 2024): > @azaloum90 Look at magic lines > > ``` > http { > > map $status $forceBasicOutlook{ #magic_line > 401 'Basic realm=$host'; #magic_line > } #magic_line > > } > > server { > ... > keepalive_timeout 3h; > proxy_read_timeout 3h; > > proxy_pass_header Date; > proxy_pass_header Server; > proxy_pass_header Authorization; > > proxy_hide_header WWW-Authenticate; #magic_line > add_header WWW-Authenticate $forceBasicOutlook always; #magic_line > > proxy_buffering off; > proxy_http_version 1.1; > proxy_request_buffering off; > proxy_set_header Connection "Keep-Alive"; > > ... > } > ``` Thanks for this. Could you tell me how to perform this configuration in the Nginx proxy manager interface? How and in which tab should this be specified? ![1-npm-details](https://github.com/NginxProxyManager/nginx-proxy-manager/assets/6999120/4d794ade-d290-4e2f-a278-6e31738432d4) ![2-npm-custom location](https://github.com/NginxProxyManager/nginx-proxy-manager/assets/6999120/e044cd0b-b39c-4ffa-825b-2a7dbaa765f7) ![3-npm-Advanced](https://github.com/NginxProxyManager/nginx-proxy-manager/assets/6999120/8cae2aa0-e7d6-42a9-9d3e-cd7ef0e09331)
Author
Owner

@azaloum90 commented on GitHub (Feb 6, 2024):

@azaloum90 Look at magic lines

http {

map $status $forceBasicOutlook{         #magic_line
        401    'Basic realm=$host';     #magic_line
}                                       #magic_line

}

server {
...
    keepalive_timeout 3h;
    proxy_read_timeout 3h;

    proxy_pass_header       Date;
    proxy_pass_header       Server;
    proxy_pass_header       Authorization;

    proxy_hide_header WWW-Authenticate;                      #magic_line
    add_header WWW-Authenticate $forceBasicOutlook always;   #magic_line

    proxy_buffering off;
    proxy_http_version 1.1;
    proxy_request_buffering off;
    proxy_set_header Connection "Keep-Alive";

...
}

Thanks for this. Could you tell me how to perform this configuration in the Nginx proxy manager interface? How and in which tab should this be specified? 1-npm-details 2-npm-custom location 3-npm-Advanced

I am wondering the same... @ilya-maltsev if you know please let us know.

<!-- gh-comment-id:1930286826 --> @azaloum90 commented on GitHub (Feb 6, 2024): > > @azaloum90 Look at magic lines > > ``` > > http { > > > > map $status $forceBasicOutlook{ #magic_line > > 401 'Basic realm=$host'; #magic_line > > } #magic_line > > > > } > > > > server { > > ... > > keepalive_timeout 3h; > > proxy_read_timeout 3h; > > > > proxy_pass_header Date; > > proxy_pass_header Server; > > proxy_pass_header Authorization; > > > > proxy_hide_header WWW-Authenticate; #magic_line > > add_header WWW-Authenticate $forceBasicOutlook always; #magic_line > > > > proxy_buffering off; > > proxy_http_version 1.1; > > proxy_request_buffering off; > > proxy_set_header Connection "Keep-Alive"; > > > > ... > > } > > ``` > > Thanks for this. Could you tell me how to perform this configuration in the Nginx proxy manager interface? How and in which tab should this be specified? ![1-npm-details](https://private-user-images.githubusercontent.com/6999120/302689161-4d794ade-d290-4e2f-a278-6e31738432d4.PNG?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDcyMzc3MDYsIm5iZiI6MTcwNzIzNzQwNiwicGF0aCI6Ii82OTk5MTIwLzMwMjY4OTE2MS00ZDc5NGFkZS1kMjkwLTRlMmYtYTI3OC02ZTMxNzM4NDMyZDQuUE5HP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDIwNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDAyMDZUMTYzNjQ2WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ZTEzNGE1MTkzYzA0N2M3ZmJjN2NkMmRhNDI2MTExNDg1ZmRhNmM1ZjA4Y2FjZjg0MjMxOWJhYzlmNjAwODM3NyZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.VONQtiFA7sWdJwffcwHWvrlT_9gzsjYtZlR1xP7FQOw) ![2-npm-custom location](https://private-user-images.githubusercontent.com/6999120/302689172-e044cd0b-b39c-4ffa-825b-2a7dbaa765f7.PNG?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDcyMzc3MDYsIm5iZiI6MTcwNzIzNzQwNiwicGF0aCI6Ii82OTk5MTIwLzMwMjY4OTE3Mi1lMDQ0Y2QwYi1iMzljLTRmZmEtODI1Yi0yYTdkYmFhNzY1ZjcuUE5HP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDIwNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDAyMDZUMTYzNjQ2WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9YTdkYTZlZWM0Y2IxZmY2MjJhMmQ3MDFjM2ZkY2YwNzE5NDczZDViMWUzMzkxZmI2NWMyMTdjNjdiZGJlNGNmMCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.m1fmKjAESURRzuy2yf25YlyGQw7LE4aTz2P1bb-vUwE) ![3-npm-Advanced](https://private-user-images.githubusercontent.com/6999120/302689173-8cae2aa0-e7d6-42a9-9d3e-cd7ef0e09331.PNG?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDcyMzc3MDYsIm5iZiI6MTcwNzIzNzQwNiwicGF0aCI6Ii82OTk5MTIwLzMwMjY4OTE3My04Y2FlMmFhMC1lN2Q2LTQyYTktOWQzZS1jZDdlZjBlMDkzMzEuUE5HP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDIwNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDAyMDZUMTYzNjQ2WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9OGU3MzRkNzE3YjQ0NDY4NjI1YWFkM2Q5MmUzMzA3ZTUyMWQxMjVkYTk3NzhlZGQ4MThmN2M1YTc2NzIzMWNiOCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.O9V4ZGEPz0tJuefh_maWChOyNFwravHaKsPX0YnmVFE) I am wondering the same... @ilya-maltsev if you know please let us know.
Author
Owner
<!-- gh-comment-id:1930353089 --> @ilya-maltsev commented on GitHub (Feb 6, 2024): https://develop.nginxproxymanager.com/advanced-config/#custom-nginx-configurations
Author
Owner

@azaloum90 commented on GitHub (Feb 6, 2024):

https://develop.nginxproxymanager.com/advanced-config/#custom-nginx-configurations

Given this info, is it safe to assume that the info should go into this screenshot?
3-npm-Advanced

<!-- gh-comment-id:1930457992 --> @azaloum90 commented on GitHub (Feb 6, 2024): > https://develop.nginxproxymanager.com/advanced-config/#custom-nginx-configurations Given this info, is it safe to assume that the info should go into this screenshot? ![3-npm-Advanced](https://private-user-images.githubusercontent.com/6999120/302689173-8cae2aa0-e7d6-42a9-9d3e-cd7ef0e09331.PNG?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDcyNDE2NjIsIm5iZiI6MTcwNzI0MTM2MiwicGF0aCI6Ii82OTk5MTIwLzMwMjY4OTE3My04Y2FlMmFhMC1lN2Q2LTQyYTktOWQzZS1jZDdlZjBlMDkzMzEuUE5HP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDIwNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDAyMDZUMTc0MjQyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MzM3YThlYWVmYjQ1YmE5YWZjNmViNGJiN2VlMGUwZGUyMmNjZDA0NWNlYjdhNDdkNTNmMjVjMGY0YTZiMGIyNiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.MBlncNpI9RNTGJ88AdUtYnlgy6UIOGU82iHCeMOzSq8)
Author
Owner

@vtornik commented on GitHub (Feb 6, 2024):

https://develop.nginxproxymanager.com/advanced-config/#custom-nginx-configurations

Thank you. Do I understand correctly that I have to create
a /data/nginx/custom/http_top.conf file
with this content:

map $status $forceBasicOutlook{ #magic_line
401 'Basic realm=$host'; #magic_line
} #magic_line

and
the /data/nginx/custom/server_proxy.conf file
with the contents:

keepalive_timeout 3h;
proxy_read_timeout 3h;

proxy_pass_header       Date;
proxy_pass_header       Server;
proxy_pass_header       Authorization;

proxy_hide_header WWW-Authenticate;                      #magic_line
add_header WWW-Authenticate $forceBasicOutlook always;   #magic_line

proxy_buffering off;
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_set_header Connection "Keep-Alive";
<!-- gh-comment-id:1930925784 --> @vtornik commented on GitHub (Feb 6, 2024): > https://develop.nginxproxymanager.com/advanced-config/#custom-nginx-configurations Thank you. Do I understand correctly that I have to create a /data/nginx/custom/http_top.conf file with this content: map $status $forceBasicOutlook{ #magic_line 401 'Basic realm=$host'; #magic_line } #magic_line and the /data/nginx/custom/server_proxy.conf file with the contents: keepalive_timeout 3h; proxy_read_timeout 3h; proxy_pass_header Date; proxy_pass_header Server; proxy_pass_header Authorization; proxy_hide_header WWW-Authenticate; #magic_line add_header WWW-Authenticate $forceBasicOutlook always; #magic_line proxy_buffering off; proxy_http_version 1.1; proxy_request_buffering off; proxy_set_header Connection "Keep-Alive";
Author
Owner

@azaloum90 commented on GitHub (Apr 22, 2024):

@azaloum90 Look at magic lines

http {

map $status $forceBasicOutlook{         #magic_line
        401    'Basic realm=$host';     #magic_line
}                                       #magic_line

}

server {
...
    keepalive_timeout 3h;
    proxy_read_timeout 3h;

    proxy_pass_header       Date;
    proxy_pass_header       Server;
    proxy_pass_header       Authorization;

    proxy_hide_header WWW-Authenticate;                      #magic_line
    add_header WWW-Authenticate $forceBasicOutlook always;   #magic_line

    proxy_buffering off;
    proxy_http_version 1.1;
    proxy_request_buffering off;
    proxy_set_header Connection "Keep-Alive";

...
}

@ilya-maltsev ,

Would you be able to post your entire configuration, as well as perhaps with screenshots as to where these configurations are entered (obviously with domain names redacted)? Though your info was helpful, I am unable to make this work with a variety of configurations -- NPM is reporting that my host is offline, likely due to the configuration being mis-scripted.

Any help is greatly appreciated!

Adam

<!-- gh-comment-id:2068459972 --> @azaloum90 commented on GitHub (Apr 22, 2024): > @azaloum90 Look at magic lines > > ``` > http { > > map $status $forceBasicOutlook{ #magic_line > 401 'Basic realm=$host'; #magic_line > } #magic_line > > } > > server { > ... > keepalive_timeout 3h; > proxy_read_timeout 3h; > > proxy_pass_header Date; > proxy_pass_header Server; > proxy_pass_header Authorization; > > proxy_hide_header WWW-Authenticate; #magic_line > add_header WWW-Authenticate $forceBasicOutlook always; #magic_line > > proxy_buffering off; > proxy_http_version 1.1; > proxy_request_buffering off; > proxy_set_header Connection "Keep-Alive"; > > ... > } > ``` @ilya-maltsev , Would you be able to post your entire configuration, as well as perhaps with screenshots as to where these configurations are entered (obviously with domain names redacted)? Though your info was helpful, I am unable to make this work with a variety of configurations -- NPM is reporting that my host is offline, likely due to the configuration being mis-scripted. Any help is greatly appreciated! Adam
Author
Owner

@ilya-maltsev commented on GitHub (Apr 22, 2024):

@azaloum90
Did you look at https://develop.nginxproxymanager.com/advanced-config/#custom-nginx-configurations
?
Advanced configuration must be did through config files of nginx, not through web-ui of NPM...

If you are a more advanced user, you might be itching for extra Nginx customizability.

NPM has the ability to include different custom configuration snippets in different places.

You can add your custom configuration snippet files at /data/nginx/custom as follow:

Unfortunately I can't show my config files of nginx...

<!-- gh-comment-id:2070264620 --> @ilya-maltsev commented on GitHub (Apr 22, 2024): @azaloum90 Did you look at https://develop.nginxproxymanager.com/advanced-config/#custom-nginx-configurations ? Advanced configuration must be did through config files of nginx, not through web-ui of NPM... ``` If you are a more advanced user, you might be itching for extra Nginx customizability. NPM has the ability to include different custom configuration snippets in different places. You can add your custom configuration snippet files at /data/nginx/custom as follow: ``` Unfortunately I can't show my config files of nginx...
Author
Owner

@tarocjsu commented on GitHub (May 6, 2024):

Useless discussion....

<!-- gh-comment-id:2095145110 --> @tarocjsu commented on GitHub (May 6, 2024): Useless discussion....
Author
Owner

@github-actions[bot] commented on GitHub (Nov 26, 2024):

Issue is now considered stale. If you want to keep it open, please comment 👍

<!-- gh-comment-id:2499460309 --> @github-actions[bot] commented on GitHub (Nov 26, 2024): Issue is now considered stale. If you want to keep it open, please comment :+1:
Author
Owner
<!-- gh-comment-id:3273677561 --> @TrentSteenholdt commented on GitHub (Sep 10, 2025): https://blog.cortanadesign.com.au/2025/09/10/how_to_get_exchange_2019_working_behind_nginx_proxy_manager
Author
Owner

@azaloum90 commented on GitHub (Sep 12, 2025):

https://blog.cortanadesign.com.au/2025/09/10/how_to_get_exchange_2019_working_behind_nginx_proxy_manager

Wow, this is incredible, thank you!

I tried to use your compose file and am getting an error message that either a login is required, or that the docker repository does not exist (clearly not the case). Am I doing something wrong here?

Image Image
<!-- gh-comment-id:3286795142 --> @azaloum90 commented on GitHub (Sep 12, 2025): > https://blog.cortanadesign.com.au/2025/09/10/how_to_get_exchange_2019_working_behind_nginx_proxy_manager Wow, this is incredible, thank you! I tried to use your compose file and am getting an error message that either a login is required, or that the docker repository does not exist (clearly not the case). Am I doing something wrong here? <img width="414" height="408" alt="Image" src="https://github.com/user-attachments/assets/5c6899ab-39a3-4f4b-95dd-504c31e3c54a" /> <img width="304" height="247" alt="Image" src="https://github.com/user-attachments/assets/80a282f2-600a-4d50-92b5-7788f68000ed" />
Author
Owner

@TrentSteenholdt commented on GitHub (Sep 17, 2025):

https://blog.cortanadesign.com.au/2025/09/10/how_to_get_exchange_2019_working_behind_nginx_proxy_manager

Wow, this is incredible, thank you!

I tried to use your compose file and am getting an error message that either a login is required, or that the docker repository does not exist (clearly not the case). Am I doing something wrong here?

Image Image

https://hub.docker.com/r/greetoz/npm-ntlm I wouldn't trust your shortened image name for pulling the right one :-)

<!-- gh-comment-id:3302518936 --> @TrentSteenholdt commented on GitHub (Sep 17, 2025): > > https://blog.cortanadesign.com.au/2025/09/10/how_to_get_exchange_2019_working_behind_nginx_proxy_manager > > Wow, this is incredible, thank you! > > I tried to use your compose file and am getting an error message that either a login is required, or that the docker repository does not exist (clearly not the case). Am I doing something wrong here? > > <img alt="Image" width="414" height="408" src="https://private-user-images.githubusercontent.com/8965127/489016839-5c6899ab-39a3-4f4b-95dd-504c31e3c54a.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTgxMDc5MjMsIm5iZiI6MTc1ODEwNzYyMywicGF0aCI6Ii84OTY1MTI3LzQ4OTAxNjgzOS01YzY4OTlhYi0zOWEzLTRmNGItOTVkZC01MDRjMzFlM2M1NGEucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDkxNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA5MTdUMTExMzQzWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9OGNkZDFiYTBmYWMyYmVjY2U4ZjUwZGI0MWI5MjkxMDA1NTljMjBhNmYyMGZmMGJjYmEyZmQyMjc2YTI4ZWEwYiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.sZYSRryC1Hbv9f8iSLgtg9qWuc5VCTLl3wxyjbRaxqo"> <img alt="Image" width="304" height="247" src="https://private-user-images.githubusercontent.com/8965127/489016738-80a282f2-600a-4d50-92b5-7788f68000ed.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTgxMDc5MjMsIm5iZiI6MTc1ODEwNzYyMywicGF0aCI6Ii84OTY1MTI3LzQ4OTAxNjczOC04MGEyODJmMi02MDBhLTRkNTAtOTJiNS03Nzg4ZjY4MDAwZWQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDkxNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA5MTdUMTExMzQzWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9N2FkNWM0ZjU4MDIyYzc4NGFjODA0NzMwNzYxZGNkMGQ5Yjk3NmQzY2E0NWI0ZTA3Mjc1ZDk2MGJmMjczMTI0OCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.8AOVXW1f8jKjQqO6rq4bsbcgWGke85lHXQLx8vKF4Q8"> https://hub.docker.com/r/greetoz/npm-ntlm I wouldn't trust your shortened image name for pulling the right one :-)
Author
Owner

@azaloum90 commented on GitHub (Sep 17, 2025):

The only way I was able to get this to work was removing the ":latest" from the command, after which it pulled as expected.

Still having some issues with the config, might have to message you separately for that one :)

Get Outlook for Androidhttps://aka.ms/AAb9ysg


From: Trent Steenholdt @.>
Sent: Wednesday, September 17, 2025 7:18:09 AM
To: NginxProxyManager/nginx-proxy-manager @.
>
Cc: azaloum90 @.>; Mention @.>
Subject: Re: [NginxProxyManager/nginx-proxy-manager] Exchange Server with Nginx Proxy Manager (Issue #2037)

[https://avatars.githubusercontent.com/u/47766435?s=20&v=4]TrentSteenholdt left a comment (NginxProxyManager/nginx-proxy-manager#2037)https://github.com/NginxProxyManager/nginx-proxy-manager/issues/2037#issuecomment-3302518936

https://blog.cortanadesign.com.au/2025/09/10/how_to_get_exchange_2019_working_behind_nginx_proxy_manager

Wow, this is incredible, thank you!

I tried to use your compose file and am getting an error message that either a login is required, or that the docker repository does not exist (clearly not the case). Am I doing something wrong here?

[Image]https://private-user-images.githubusercontent.com/8965127/489016839-5c6899ab-39a3-4f4b-95dd-504c31e3c54a.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTgxMDc5MjMsIm5iZiI6MTc1ODEwNzYyMywicGF0aCI6Ii84OTY1MTI3LzQ4OTAxNjgzOS01YzY4OTlhYi0zOWEzLTRmNGItOTVkZC01MDRjMzFlM2M1NGEucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDkxNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA5MTdUMTExMzQzWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9OGNkZDFiYTBmYWMyYmVjY2U4ZjUwZGI0MWI5MjkxMDA1NTljMjBhNmYyMGZmMGJjYmEyZmQyMjc2YTI4ZWEwYiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.sZYSRryC1Hbv9f8iSLgtg9qWuc5VCTLl3wxyjbRaxqo [Image] https://private-user-images.githubusercontent.com/8965127/489016738-80a282f2-600a-4d50-92b5-7788f68000ed.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTgxMDc5MjMsIm5iZiI6MTc1ODEwNzYyMywicGF0aCI6Ii84OTY1MTI3LzQ4OTAxNjczOC04MGEyODJmMi02MDBhLTRkNTAtOTJiNS03Nzg4ZjY4MDAwZWQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDkxNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA5MTdUMTExMzQzWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9N2FkNWM0ZjU4MDIyYzc4NGFjODA0NzMwNzYxZGNkMGQ5Yjk3NmQzY2E0NWI0ZTA3Mjc1ZDk2MGJmMjczMTI0OCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.8AOVXW1f8jKjQqO6rq4bsbcgWGke85lHXQLx8vKF4Q8

https://hub.docker.com/r/greetoz/npm-ntlm I wouldn't trust your shortened image name for pulling the right one :-)


Reply to this email directly, view it on GitHubhttps://github.com/NginxProxyManager/nginx-proxy-manager/issues/2037#issuecomment-3302518936, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACEMYBZDEUJ2LEGWCHDSAUL3TE7PDAVCNFSM6AAAAABSPKDKJ2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTGMBSGUYTQOJTGY.
You are receiving this because you were mentioned.Message ID: @.***>

<!-- gh-comment-id:3302681240 --> @azaloum90 commented on GitHub (Sep 17, 2025): The only way I was able to get this to work was removing the ":latest" from the command, after which it pulled as expected. Still having some issues with the config, might have to message you separately for that one :) Get Outlook for Android<https://aka.ms/AAb9ysg> ________________________________ From: Trent Steenholdt ***@***.***> Sent: Wednesday, September 17, 2025 7:18:09 AM To: NginxProxyManager/nginx-proxy-manager ***@***.***> Cc: azaloum90 ***@***.***>; Mention ***@***.***> Subject: Re: [NginxProxyManager/nginx-proxy-manager] Exchange Server with Nginx Proxy Manager (Issue #2037) [https://avatars.githubusercontent.com/u/47766435?s=20&v=4]TrentSteenholdt left a comment (NginxProxyManager/nginx-proxy-manager#2037)<https://github.com/NginxProxyManager/nginx-proxy-manager/issues/2037#issuecomment-3302518936> https://blog.cortanadesign.com.au/2025/09/10/how_to_get_exchange_2019_working_behind_nginx_proxy_manager Wow, this is incredible, thank you! I tried to use your compose file and am getting an error message that either a login is required, or that the docker repository does not exist (clearly not the case). Am I doing something wrong here? [Image]<https://private-user-images.githubusercontent.com/8965127/489016839-5c6899ab-39a3-4f4b-95dd-504c31e3c54a.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTgxMDc5MjMsIm5iZiI6MTc1ODEwNzYyMywicGF0aCI6Ii84OTY1MTI3LzQ4OTAxNjgzOS01YzY4OTlhYi0zOWEzLTRmNGItOTVkZC01MDRjMzFlM2M1NGEucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDkxNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA5MTdUMTExMzQzWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9OGNkZDFiYTBmYWMyYmVjY2U4ZjUwZGI0MWI5MjkxMDA1NTljMjBhNmYyMGZmMGJjYmEyZmQyMjc2YTI4ZWEwYiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.sZYSRryC1Hbv9f8iSLgtg9qWuc5VCTLl3wxyjbRaxqo> [Image] <https://private-user-images.githubusercontent.com/8965127/489016738-80a282f2-600a-4d50-92b5-7788f68000ed.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTgxMDc5MjMsIm5iZiI6MTc1ODEwNzYyMywicGF0aCI6Ii84OTY1MTI3LzQ4OTAxNjczOC04MGEyODJmMi02MDBhLTRkNTAtOTJiNS03Nzg4ZjY4MDAwZWQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDkxNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA5MTdUMTExMzQzWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9N2FkNWM0ZjU4MDIyYzc4NGFjODA0NzMwNzYxZGNkMGQ5Yjk3NmQzY2E0NWI0ZTA3Mjc1ZDk2MGJmMjczMTI0OCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.8AOVXW1f8jKjQqO6rq4bsbcgWGke85lHXQLx8vKF4Q8> https://hub.docker.com/r/greetoz/npm-ntlm I wouldn't trust your shortened image name for pulling the right one :-) — Reply to this email directly, view it on GitHub<https://github.com/NginxProxyManager/nginx-proxy-manager/issues/2037#issuecomment-3302518936>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ACEMYBZDEUJ2LEGWCHDSAUL3TE7PDAVCNFSM6AAAAABSPKDKJ2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTGMBSGUYTQOJTGY>. You are receiving this because you were mentioned.Message ID: ***@***.***>
Author
Owner

@azaloum90 commented on GitHub (Oct 14, 2025):

The only way I was able to get this to work was removing the ":latest" from the command, after which it pulled as expected.

Still having some issues with the config, might have to message you separately for that one :)

Get Outlook for Androidhttps://aka.ms/AAb9ysg

Hi!

So I got to "Defining the NTLM Upstream" part of your guide using this YAML config:

`services:
app:
image: 'docker.io/greetoz/npm-ntlm:latest'
labels:
- "com.centurylinklabs.watchtower.enable=true"
restart: unless-stopped
ports:
# These ports are in format :
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Add any other Stream port you want to expose
- '32400:32400' # Plex

# Uncomment the next line if you uncomment anything in the section
# environment:
  # Uncomment this if you want to change the location of
  # the SQLite DB file within the container
  # DB_SQLITE_FILE: "/data/database.sqlite"

  # Uncomment this if IPv6 is not enabled on your host
  # DISABLE_IPV6: 'true'

volumes:
  - /mnt/docker/npm/data:/data
  - /mnt/docker/npm/letsencrypt:/etc/letsencrypt

`

I am getting this error in the logs:

nginx: [emerg] unknown directive "ntlm" in /data/nginx/custom/http_top.conf:4

Basic searches show that this means it can't seem to utilize the NTLM module within the container.

Is there something that I am missing?

<!-- gh-comment-id:3400011817 --> @azaloum90 commented on GitHub (Oct 14, 2025): > The only way I was able to get this to work was removing the ":latest" from the command, after which it pulled as expected. > > Still having some issues with the config, might have to message you separately for that one :) > > Get Outlook for Android<https://aka.ms/AAb9ysg> > […](#) Hi! So I got to "Defining the NTLM Upstream" part of your guide using this YAML config: `services: app: image: 'docker.io/greetoz/npm-ntlm:latest' labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped ports: # These ports are in format <host-port>:<container-port> - '80:80' # Public HTTP Port - '443:443' # Public HTTPS Port - '81:81' # Admin Web Port # Add any other Stream port you want to expose - '32400:32400' # Plex # Uncomment the next line if you uncomment anything in the section # environment: # Uncomment this if you want to change the location of # the SQLite DB file within the container # DB_SQLITE_FILE: "/data/database.sqlite" # Uncomment this if IPv6 is not enabled on your host # DISABLE_IPV6: 'true' volumes: - /mnt/docker/npm/data:/data - /mnt/docker/npm/letsencrypt:/etc/letsencrypt ` I am getting this error in the logs: > nginx: [emerg] unknown directive "ntlm" in /data/nginx/custom/http_top.conf:4 Basic searches show that this means it can't seem to utilize the NTLM module within the container. Is there something that I am missing?
Author
Owner

@trentsteenholdt-synergyau commented on GitHub (Oct 14, 2025):

The only way I was able to get this to work was removing the ":latest" from the command, after which it pulled as expected.
Still having some issues with the config, might have to message you separately for that one :)
Get Outlook for Androidhttps://aka.ms/AAb9ysg

Hi!

So I got to "Defining the NTLM Upstream" part of your guide using this YAML config:

`services: app: image: 'docker.io/greetoz/npm-ntlm:latest' labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped ports: # These ports are in format : - '80:80' # Public HTTP Port - '443:443' # Public HTTPS Port - '81:81' # Admin Web Port # Add any other Stream port you want to expose - '32400:32400' # Plex

# Uncomment the next line if you uncomment anything in the section
# environment:
  # Uncomment this if you want to change the location of
  # the SQLite DB file within the container
  # DB_SQLITE_FILE: "/data/database.sqlite"

  # Uncomment this if IPv6 is not enabled on your host
  # DISABLE_IPV6: 'true'

volumes:
  - /mnt/docker/npm/data:/data
  - /mnt/docker/npm/letsencrypt:/etc/letsencrypt

`

I am getting this error in the logs:

nginx: [emerg] unknown directive "ntlm" in /data/nginx/custom/http_top.conf:4

Basic searches show that this means it can't seem to utilize the NTLM module within the container.

Is there something that I am missing?

Asking the real basic question, but are you sure your docker image has been composed with the right image? E.g. docker-compose up -d

Also it could just be the formatting, but make sure your compose file is formatted exactly with the right indents etc.

Here is mine


version: "3"
services:
  app:
    image: 'greetoz/npm-ntlm:latest'
    restart: unless-stopped
    ports:
      # These ports are in format <host-port>:<container-port>
      - '80:80' # Public HTTP Port
      - '443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
      # Add any other Stream port you want to expose
      # - '21:21' # FTP

    # Uncomment the next line if you uncomment anything in the section
    # environment:
      # Uncomment this if you want to change the location of
      # the SQLite DB file within the container
      # DB_SQLITE_FILE: "/data/database.sqlite"

      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'

    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
      - ./nginx-mods/20-dynamic-mods.conf:/etc/nginx/modules/20-dynamic-mods.conf:ro

Might be the missing piece is the dynamic-mods reference.


/opt/nginxproxymanager/nginx-mods
root@cortana-rp01:/opt/nginxproxymanager/nginx-mods# cat 20-dynamic-mods.conf
load_module /usr/lib/nginx/modules/ngx_http_upstream_ntlm_module.so;
load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;
# load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so;
root@cortana-rp01:/opt/nginxproxymanager/nginx-mods#
<!-- gh-comment-id:3400026803 --> @trentsteenholdt-synergyau commented on GitHub (Oct 14, 2025): > > The only way I was able to get this to work was removing the ":latest" from the command, after which it pulled as expected. > > Still having some issues with the config, might have to message you separately for that one :) > > Get Outlook for Androidhttps://aka.ms/AAb9ysg > > […](#) > > Hi! > > So I got to "Defining the NTLM Upstream" part of your guide using this YAML config: > > `services: app: image: 'docker.io/greetoz/npm-ntlm:latest' labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped ports: # These ports are in format : - '80:80' # Public HTTP Port - '443:443' # Public HTTPS Port - '81:81' # Admin Web Port # Add any other Stream port you want to expose - '32400:32400' # Plex > > ``` > # Uncomment the next line if you uncomment anything in the section > # environment: > # Uncomment this if you want to change the location of > # the SQLite DB file within the container > # DB_SQLITE_FILE: "/data/database.sqlite" > > # Uncomment this if IPv6 is not enabled on your host > # DISABLE_IPV6: 'true' > > volumes: > - /mnt/docker/npm/data:/data > - /mnt/docker/npm/letsencrypt:/etc/letsencrypt > ``` > > ` > > I am getting this error in the logs: > > > nginx: [emerg] unknown directive "ntlm" in /data/nginx/custom/http_top.conf:4 > > Basic searches show that this means it can't seem to utilize the NTLM module within the container. > > Is there something that I am missing? Asking the real basic question, but are you sure your docker image has been composed with the right image? E.g. `docker-compose up -d` Also it could just be the formatting, but make sure your compose file is formatted exactly with the right indents etc. Here is mine ```yaml version: "3" services: app: image: 'greetoz/npm-ntlm:latest' restart: unless-stopped ports: # These ports are in format <host-port>:<container-port> - '80:80' # Public HTTP Port - '443:443' # Public HTTPS Port - '81:81' # Admin Web Port # Add any other Stream port you want to expose # - '21:21' # FTP # Uncomment the next line if you uncomment anything in the section # environment: # Uncomment this if you want to change the location of # the SQLite DB file within the container # DB_SQLITE_FILE: "/data/database.sqlite" # Uncomment this if IPv6 is not enabled on your host # DISABLE_IPV6: 'true' volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt - ./nginx-mods/20-dynamic-mods.conf:/etc/nginx/modules/20-dynamic-mods.conf:ro ``` Might be the missing piece is the dynamic-mods reference. ```bash /opt/nginxproxymanager/nginx-mods root@cortana-rp01:/opt/nginxproxymanager/nginx-mods# cat 20-dynamic-mods.conf load_module /usr/lib/nginx/modules/ngx_http_upstream_ntlm_module.so; load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so; # load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so; root@cortana-rp01:/opt/nginxproxymanager/nginx-mods# ```
Author
Owner

@azaloum90 commented on GitHub (Oct 25, 2025):

The only way I was able to get this to work was removing the ":latest" from the command, after which it pulled as expected.
Still having some issues with the config, might have to message you separately for that one :)
Get Outlook for Androidhttps://aka.ms/AAb9ysg

Hi!
So I got to "Defining the NTLM Upstream" part of your guide using this YAML config:
`services: app: image: 'docker.io/greetoz/npm-ntlm:latest' labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped ports: # These ports are in format : - '80:80' # Public HTTP Port - '443:443' # Public HTTPS Port - '81:81' # Admin Web Port # Add any other Stream port you want to expose - '32400:32400' # Plex

# Uncomment the next line if you uncomment anything in the section
# environment:
  # Uncomment this if you want to change the location of
  # the SQLite DB file within the container
  # DB_SQLITE_FILE: "/data/database.sqlite"

  # Uncomment this if IPv6 is not enabled on your host
  # DISABLE_IPV6: 'true'

volumes:
  - /mnt/docker/npm/data:/data
  - /mnt/docker/npm/letsencrypt:/etc/letsencrypt

`
I am getting this error in the logs:

nginx: [emerg] unknown directive "ntlm" in /data/nginx/custom/http_top.conf:4

Basic searches show that this means it can't seem to utilize the NTLM module within the container.
Is there something that I am missing?

Asking the real basic question, but are you sure your docker image has been composed with the right image? E.g. docker-compose up -d

Also it could just be the formatting, but make sure your compose file is formatted exactly with the right indents etc.

Here is mine

version: "3"
services:
app:
image: 'greetoz/npm-ntlm:latest'
restart: unless-stopped
ports:
# These ports are in format :
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP

# Uncomment the next line if you uncomment anything in the section
# environment:
  # Uncomment this if you want to change the location of
  # the SQLite DB file within the container
  # DB_SQLITE_FILE: "/data/database.sqlite"

  # Uncomment this if IPv6 is not enabled on your host
  # DISABLE_IPV6: 'true'

volumes:
  - ./data:/data
  - ./letsencrypt:/etc/letsencrypt
  - ./nginx-mods/20-dynamic-mods.conf:/etc/nginx/modules/20-dynamic-mods.conf:ro

Might be the missing piece is the dynamic-mods reference.

/opt/nginxproxymanager/nginx-mods
root@cortana-rp01:/opt/nginxproxymanager/nginx-mods# cat 20-dynamic-mods.conf
load_module /usr/lib/nginx/modules/ngx_http_upstream_ntlm_module.so;
load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;

load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so;

root@cortana-rp01:/opt/nginxproxymanager/nginx-mods#

Confirmed, the lack of the "20-dynamic-mods.conf" configuration file with the information you provided on the host as you noted is what caused the error below. Once I added that to the Docker configuration, all was functional:

nginx: [emerg] unknown directive "ntlm" in /data/nginx/custom/http_top.conf:4

Other item I did not realize was that your Nginx Configuration for use in the NPM Web portal requires actual FQDNs, not just ip address. The box I am using is destined to be on a DMZ network, so there is no available DNS server that has the FQDN's availabile. I set up DNSMasq via another docker container on the same system and all "host not found" errors disappeared, and NPM now shows the Exchange .

At this point in time, the only thing I have not yet done is utilize an Azure Tenant for the Entra ID App Registration / connectivity into my domain. Have you had any luck getting this to work without that component? I am using an Exchange ActiveSync Mail Client (eMClient Mail application) and it just keeps kicking back "Unauthorized" when I try to utilize NPM for connectivity,

<!-- gh-comment-id:3447847775 --> @azaloum90 commented on GitHub (Oct 25, 2025): > > > The only way I was able to get this to work was removing the ":latest" from the command, after which it pulled as expected. > > > Still having some issues with the config, might have to message you separately for that one :) > > > Get Outlook for Androidhttps://aka.ms/AAb9ysg > > > […](#) > > > > > > Hi! > > So I got to "Defining the NTLM Upstream" part of your guide using this YAML config: > > `services: app: image: 'docker.io/greetoz/npm-ntlm:latest' labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped ports: # These ports are in format : - '80:80' # Public HTTP Port - '443:443' # Public HTTPS Port - '81:81' # Admin Web Port # Add any other Stream port you want to expose - '32400:32400' # Plex > > ``` > > # Uncomment the next line if you uncomment anything in the section > > # environment: > > # Uncomment this if you want to change the location of > > # the SQLite DB file within the container > > # DB_SQLITE_FILE: "/data/database.sqlite" > > > > # Uncomment this if IPv6 is not enabled on your host > > # DISABLE_IPV6: 'true' > > > > volumes: > > - /mnt/docker/npm/data:/data > > - /mnt/docker/npm/letsencrypt:/etc/letsencrypt > > ``` > > > > > > > > > > > > > > > > > > > > > > > > ` > > I am getting this error in the logs: > > > nginx: [emerg] unknown directive "ntlm" in /data/nginx/custom/http_top.conf:4 > > > > > > Basic searches show that this means it can't seem to utilize the NTLM module within the container. > > Is there something that I am missing? > > Asking the real basic question, but are you sure your docker image has been composed with the right image? E.g. `docker-compose up -d` > > Also it could just be the formatting, but make sure your compose file is formatted exactly with the right indents etc. > > Here is mine > > version: "3" > services: > app: > image: 'greetoz/npm-ntlm:latest' > restart: unless-stopped > ports: > # These ports are in format <host-port>:<container-port> > - '80:80' # Public HTTP Port > - '443:443' # Public HTTPS Port > - '81:81' # Admin Web Port > # Add any other Stream port you want to expose > # - '21:21' # FTP > > # Uncomment the next line if you uncomment anything in the section > # environment: > # Uncomment this if you want to change the location of > # the SQLite DB file within the container > # DB_SQLITE_FILE: "/data/database.sqlite" > > # Uncomment this if IPv6 is not enabled on your host > # DISABLE_IPV6: 'true' > > volumes: > - ./data:/data > - ./letsencrypt:/etc/letsencrypt > - ./nginx-mods/20-dynamic-mods.conf:/etc/nginx/modules/20-dynamic-mods.conf:ro > Might be the missing piece is the dynamic-mods reference. > > /opt/nginxproxymanager/nginx-mods > root@cortana-rp01:/opt/nginxproxymanager/nginx-mods# cat 20-dynamic-mods.conf > load_module /usr/lib/nginx/modules/ngx_http_upstream_ntlm_module.so; > load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so; > # load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so; > root@cortana-rp01:/opt/nginxproxymanager/nginx-mods# Confirmed, the lack of the "20-dynamic-mods.conf" configuration file with the information you provided on the host as you noted is what caused the error below. Once I added that to the Docker configuration, all was functional: `nginx: [emerg] unknown directive "ntlm" in /data/nginx/custom/http_top.conf:4` Other item I did not realize was that your Nginx Configuration for use in the NPM Web portal requires actual FQDNs, not just ip address. The box I am using is destined to be on a DMZ network, so there is no available DNS server that has the FQDN's availabile. I set up DNSMasq via another docker container on the same system and all "host not found" errors disappeared, and NPM now shows the Exchange . At this point in time, the only thing I have not yet done is utilize an Azure Tenant for the Entra ID App Registration / connectivity into my domain. Have you had any luck getting this to work *without* that component? I am using an Exchange ActiveSync Mail Client (eMClient Mail application) and it just keeps kicking back "Unauthorized" when I try to utilize NPM for connectivity,
Author
Owner

@azaloum90 commented on GitHub (Nov 8, 2025):

The only way I was able to get this to work was removing the ":latest" from the command, after which it pulled as expected.
Still having some issues with the config, might have to message you separately for that one :)
Get Outlook for Androidhttps://aka.ms/AAb9ysg

Hi!
So I got to "Defining the NTLM Upstream" part of your guide using this YAML config:
`services: app: image: 'docker.io/greetoz/npm-ntlm:latest' labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped ports: # These ports are in format : - '80:80' # Public HTTP Port - '443:443' # Public HTTPS Port - '81:81' # Admin Web Port # Add any other Stream port you want to expose - '32400:32400' # Plex

# Uncomment the next line if you uncomment anything in the section
# environment:
  # Uncomment this if you want to change the location of
  # the SQLite DB file within the container
  # DB_SQLITE_FILE: "/data/database.sqlite"

  # Uncomment this if IPv6 is not enabled on your host
  # DISABLE_IPV6: 'true'

volumes:
  - /mnt/docker/npm/data:/data
  - /mnt/docker/npm/letsencrypt:/etc/letsencrypt

`
I am getting this error in the logs:

nginx: [emerg] unknown directive "ntlm" in /data/nginx/custom/http_top.conf:4

Basic searches show that this means it can't seem to utilize the NTLM module within the container.
Is there something that I am missing?

Asking the real basic question, but are you sure your docker image has been composed with the right image? E.g. docker-compose up -d

Also it could just be the formatting, but make sure your compose file is formatted exactly with the right indents etc.

Here is mine

version: "3"
services:
app:
image: 'greetoz/npm-ntlm:latest'
restart: unless-stopped
ports:
# These ports are in format :
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP

# Uncomment the next line if you uncomment anything in the section
# environment:
  # Uncomment this if you want to change the location of
  # the SQLite DB file within the container
  # DB_SQLITE_FILE: "/data/database.sqlite"

  # Uncomment this if IPv6 is not enabled on your host
  # DISABLE_IPV6: 'true'

volumes:
  - ./data:/data
  - ./letsencrypt:/etc/letsencrypt
  - ./nginx-mods/20-dynamic-mods.conf:/etc/nginx/modules/20-dynamic-mods.conf:ro

Might be the missing piece is the dynamic-mods reference.

/opt/nginxproxymanager/nginx-mods
root@cortana-rp01:/opt/nginxproxymanager/nginx-mods# cat 20-dynamic-mods.conf
load_module /usr/lib/nginx/modules/ngx_http_upstream_ntlm_module.so;
load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;

load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so;

root@cortana-rp01:/opt/nginxproxymanager/nginx-mods#

Just wanted to reach out one last time. Have you had any issues with the OAB throwing errors for connectivty? I have done the entire config you noted except for the HMA piece, and everything works flawlessly -- mobile clients, outlook, 3rd party mail clients ----- EXCEPT when trying to download the Offline Address Book, then both Outlook and the 3rd party mail clients throw errors. Outlook prompts for credentials regularly because of this. I've worked around it for now by using a 3rd party mail client where I can disable download of the OAB, but I am wondering what else can be added to the /OAB portion of the config to prevent this issue.

Feel free to email me at myusername @ gee-mayle.c0m

Thanks!
Adam

<!-- gh-comment-id:3506722560 --> @azaloum90 commented on GitHub (Nov 8, 2025): > > > The only way I was able to get this to work was removing the ":latest" from the command, after which it pulled as expected. > > > Still having some issues with the config, might have to message you separately for that one :) > > > Get Outlook for Androidhttps://aka.ms/AAb9ysg > > > […](#) > > > > > > Hi! > > So I got to "Defining the NTLM Upstream" part of your guide using this YAML config: > > `services: app: image: 'docker.io/greetoz/npm-ntlm:latest' labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped ports: # These ports are in format : - '80:80' # Public HTTP Port - '443:443' # Public HTTPS Port - '81:81' # Admin Web Port # Add any other Stream port you want to expose - '32400:32400' # Plex > > ``` > > # Uncomment the next line if you uncomment anything in the section > > # environment: > > # Uncomment this if you want to change the location of > > # the SQLite DB file within the container > > # DB_SQLITE_FILE: "/data/database.sqlite" > > > > # Uncomment this if IPv6 is not enabled on your host > > # DISABLE_IPV6: 'true' > > > > volumes: > > - /mnt/docker/npm/data:/data > > - /mnt/docker/npm/letsencrypt:/etc/letsencrypt > > ``` > > > > > > > > > > > > > > > > > > > > > > > > ` > > I am getting this error in the logs: > > > nginx: [emerg] unknown directive "ntlm" in /data/nginx/custom/http_top.conf:4 > > > > > > Basic searches show that this means it can't seem to utilize the NTLM module within the container. > > Is there something that I am missing? > > Asking the real basic question, but are you sure your docker image has been composed with the right image? E.g. `docker-compose up -d` > > Also it could just be the formatting, but make sure your compose file is formatted exactly with the right indents etc. > > Here is mine > > version: "3" > services: > app: > image: 'greetoz/npm-ntlm:latest' > restart: unless-stopped > ports: > # These ports are in format <host-port>:<container-port> > - '80:80' # Public HTTP Port > - '443:443' # Public HTTPS Port > - '81:81' # Admin Web Port > # Add any other Stream port you want to expose > # - '21:21' # FTP > > # Uncomment the next line if you uncomment anything in the section > # environment: > # Uncomment this if you want to change the location of > # the SQLite DB file within the container > # DB_SQLITE_FILE: "/data/database.sqlite" > > # Uncomment this if IPv6 is not enabled on your host > # DISABLE_IPV6: 'true' > > volumes: > - ./data:/data > - ./letsencrypt:/etc/letsencrypt > - ./nginx-mods/20-dynamic-mods.conf:/etc/nginx/modules/20-dynamic-mods.conf:ro > Might be the missing piece is the dynamic-mods reference. > > /opt/nginxproxymanager/nginx-mods > root@cortana-rp01:/opt/nginxproxymanager/nginx-mods# cat 20-dynamic-mods.conf > load_module /usr/lib/nginx/modules/ngx_http_upstream_ntlm_module.so; > load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so; > # load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so; > root@cortana-rp01:/opt/nginxproxymanager/nginx-mods# Just wanted to reach out one last time. Have you had any issues with the OAB throwing errors for connectivty? I have done the entire config you noted except for the HMA piece, and everything works flawlessly -- mobile clients, outlook, 3rd party mail clients ----- EXCEPT when trying to download the Offline Address Book, then both Outlook and the 3rd party mail clients throw errors. Outlook prompts for credentials regularly because of this. I've worked around it for now by using a 3rd party mail client where I can disable download of the OAB, but I am wondering what else can be added to the /OAB portion of the config to prevent this issue. Feel free to email me at myusername @ gee-mayle.c0m Thanks! Adam
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/nginx-proxy-manager-NginxProxyManager#1472
No description provided.