Hi all,
I've tried to do some research on this already, but without much luck.
So
I'm hoping others may be able to assist.
I'm trying to use Nginx as a Reverse Proxy back to an Exchange 2007
environment.
- Nginx is terminating to HTTPS / SSL connection for the Client
- Nginx is then proxying to the Exchange environment over HTTP
As other have found, this appears to be working find for all Exchange
Services, with the exception of 'Outlook Anywhere', which is also known
as
Outlook RCP/HTTP(S).
To better define the problem, an Exchange Client Access Server hosts the
following Virtual Directories (or services) is IIS7:
/Autodiscover - For devices to automatically configure their
connection
setting
/owa - "Outlook Web Access" - Basically webmail
/OAB - "Offline Address Book" - Where clients can download
copies off the offline address book
/EWS - "Exchange Web Services" - Good question as to what
this
is!
/Public - "Public Folders" - Conenction point for Public
Folder
access
/Microsoft-Server-ActiveSync - Used with devices for ActiveSync
/Rpc - "Outlook Anywhere" - Outlook connecting using
RPC/HTTP(S) - This is the problematic one.
(plus a few legacy and admin services)
So, I have everything working through Nginx, with the exception
RPC/HTTP(S).
Initially I was seeing this error:
10.110.2.15 - username [27/Feb/2013:17:24:31 +0000] "RPC_IN_DATA
/rpc/rpcproxy.dll?EX-SERVER-2008.servers.null.org:6002 HTTP/1.1" 413 198
"-"
"MSRPC" "-"
After a bit of reading, this was resolved with the following directive:
http {
client_max_body_size 0;
}
(Yes, I know 0=unlimited and that may not be appropriate, but I'm still
testing!)
So now all that I'm left with is trying to resolve this error:
10.110.2.15 - username [28/Feb/2013:07:39:27 +0000] "RPC_OUT_DATA
/rpc/rpcproxy.dll?EX-SERVER-2008.servers.null.or:6004 HTTP/1.1" 405 172
"-"
"MSRPC" "-"
10.110.2.15 - username [28/Feb/2013:07:39:27 +0000] "RPC_IN_DATA
/rpc/rpcproxy.dll?EX-SERVER-2008.servers.null.org:6004 HTTP/1.1" 405 172
"-"
"MSRPC" "-"
With my very limited knowledge Error 405 is "Method Not Allowed".
I've seen various solutions which suggest changing the 'error_page 405'
directive to different things. Such as:
location / {
error_page 405 = @app;
try_files $uri @app;
}
location @app {
proxy_pass http://app_servers;
}
But these don't seem to solve the issue.
So my questions are:
1. How can I allow this Method, if that is the issue?
2. If what I'm doing is fundamentally not possible, please just let me
know!
For Reference:
I'm running Nginx v1.2.7 from the nginx Repo on Centos 6.3
My main Nginx Config looks like this (Some of the names and IPs have
been
changed to protect the innocent):
upstream exchange_all {
ip_hash;
server 10.1.1.1 max_fails=1 fail_timeout=10s;
server 10.1.1.2 max_fails=1 fail_timeout=10s;
# Do NOT Remove - this is needed for auth to work
keepalive 32;
}
server {
listen 10.2.1.1;
return 301 https://webmail.null.com$request_uri;
}
server {
listen 10.2.1.1:443 ;
ssl on;
ssl_certificate /etc/ssl/webmail.aeltc.com.crt;
ssl_certificate_key /etc/ssl/ae-lb02-key.pem;
ssl_session_cache shared:SSL:60m;
ssl_session_timeout 60m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
proxy_redirect off;
proxy_buffering off;
proxy_read_timeout 3600;
proxy_pass_header Date;
proxy_pass_header Server;
proxy_set_header Connection "";
proxy_set_header Accept-Encoding "";
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_set_header X-Forwarded-Proto off;
add_header Front-End-Https on;
proxy_http_version 1.1;
location ~*/Autodiscover {
proxy_pass http://exchange_all;
}
location ~*/owa {
proxy_pass http://exchange_all;
}
location ~*/OAB {
proxy_pass http://exchange_all;
}
# location ~*/rpc/ {
location ~*/rpc/rpcproxy\.dll\? {
proxy_pass http://exchange_all;
}
location ~*/EWS {
proxy_pass http://exchange_all;
}
location ~*/Public {
proxy_pass http://exchange_all;
}
location ~*/Microsoft-Server-ActiveSync {
proxy_pass http://exchange_all;
}
location ~*/$ {
return 301 https://webmail.null.com/owa;
}
}
Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,236709,236709#msg-236709
on 2013-02-28 09:33
on 2013-02-28 13:26
Hello! On Thu, Feb 28, 2013 at 03:33:06AM -0500, gmor wrote: [...] > 1. How can I allow this Method, if that is the issue? > 2. If what I'm doing is fundamentally not possible, please just let me > know! The 405 error, at least if returned by nginx, means that module which used to handle the request doesn't understand the request method used. E.g. static module will only handle GET and HEAD, and will return 405 to anything else as it doesn't know how to handle other methods. Proxy module, in contrast, just proxies the request and don't care which method was used. So first of all I would suggest you to make sure requests are handled in a location with proxy_pass properly configured. A simple way to do this would be to just throw away all funny regexp locations you wrote in your config, and start with a simple location / { proxy_pass http://backend; } to handle all requests. Using debug log might be also helpful, see http://nginx.org/en/debugging_log.html. (Note: I'm not sure this will work at all, I've never tried. I would rather suppose it won't work, as RPC likely tries to establish in/out data streams. I wouldn't expect a stream from a client to a backend to work as nginx will insist on reading a request body before it will be passed to the backend.) [...] > upstream exchange_all { > ip_hash; > server 10.1.1.1 max_fails=1 fail_timeout=10s; > server 10.1.1.2 max_fails=1 fail_timeout=10s; > > # Do NOT Remove - this is needed for auth to work > keepalive 32; Just a side note: This is wrong - there is no guarantee that the same upstream server connection will used for requests from a particular client. While with keepalive Integrated Windows Authentication might appear to work, it in fact doesn't. You should switch to Basic authentication instead. See http://en.wikipedia.org/wiki/Integrated_Windows_Au... for more details. [...] -- Maxim Dounin http://nginx.org/en/donation.html
on 2013-02-28 15:16
Hi, Thanks for the quick response. I've done what you suggested with the following results: >A >simple way to do this would be to just throw away all funny >regexp locations you wrote in your config, and start with a simple >location / { >proxy_pass http://backend; >} Absolutely happy to. Now I'm seeing slightly different behaviour. No more 405 errors, the Outlook client just hangs now, eventually reporting 'Server not Available' In the debug log, I'm now seeing the following: 2013/02/28 13:56:55 [info] 3150#0: *1 client prematurely closed connection, client: 10.110.2.15, server: , request: "RPC_IN_DATA /rpc/rpcproxy.dll?EX-SERVER-2008.servers.null.org:6002 HTTP/1.1", host: "webmail.null.com" 2013/02/28 13:56:55 [info] 3150#0: *2 client prematurely closed connection, so upstream connection is closed too (104: Connection reset by peer) while reading upstream, client: 10.110.2.15, server: , request: "RPC_OUT_DATA /rpc/rpcproxy.dll?EX-SERVER-2008.servers.null.org:6002 HTTP/1.1", upstream: "http://10.1.1.2:80/rpc/rpcproxy.dll?EX-MBX-2008.se..., host: "webmail.null.com" Which is me eventually cancelling the Outlook connection. This is evident from tailing the debug log - Nothing during the connection; but these events which the connection attempt is cancelled. So... Good news, Error 405 doesn't seem to be the cause of my issues, it would appear that my location directives were wrong in some way. Bad news, Outlook Anywhere still isn't working. If anyone has any other suggestions, please let me know. Thanks, Graham. Posted at Nginx Forum: http://forum.nginx.org/read.php?2,236709,236722#msg-236722
on 2013-02-28 16:20
Hello! On Thu, Feb 28, 2013 at 09:15:52AM -0500, gmor wrote: > >proxy_pass http://backend; > client: 10.110.2.15, server: , request: "RPC_IN_DATA > from tailing the debug log - Nothing during the connection; but these events > which the connection attempt is cancelled. This what I've talked about - RPC client tries to establish data stream, presumably by faking big request body, but fails because nginx actually waits for the body before passing the request to an upstream server. -- Maxim Dounin http://nginx.org/en/donation.html
on 2013-03-04 10:06
Hi, Thanks for the explanation. It absolutely makes sense now that you've clarified how Nginx works. Following on from this, I've now chosen to use HAProxy for this particular Exchange / Outlook Anywhere use-case. This supports the 'streaming' model of Outlook Anywhere, by simply passing the data to the backend, without waiting for the complete body (with the 'option http-no-delay' directive - http://cbonte.github.com/haproxy-dconv/configurati...). I hope to be able to find a case for using Nginx in the future as it still looks like a great product. Thanks again for the support, Graham Posted at Nginx Forum: http://forum.nginx.org/read.php?2,236709,236892#msg-236892
on 2013-04-18 12:53
So, anyone know, will be this feature in future betas or releases? (I tryed to use haproxy, but it don't work :( can you please share your config? ) Posted at Nginx Forum: http://forum.nginx.org/read.php?2,236709,238473#msg-238473
on 2013-04-18 13:08
Hi, Happy to share my config. This is based on HAProxy Version 1.5-Dev17. It's by no means perfect, but's working for us at the moment: global # Default Maximum Number of Connections. Used to set ulimit -n maxconn 20000 # Run as a Daemon Service in the Background daemon # Define the Number of Processor Cores - Not Essential #nbproc 2 # Allows Turning Off of Kernel TCP Splicing - Not Essential #nosplice # Logging Setting. Local to Local Syslog and Control from There log 127.0.0.1 daemon log-send-hostname log-tag haproxy # Define a UNIX Socket so that you can Admin the Service interactively stats socket /usr/local/sbin/haproxy-socket level admin defaults # Do Not Log Connections with No Requests option dontlognull # Force Clients to try and Reconnect to an Alternative Server if one is Down option redispatch # Ensure that Streaming HTTP Works Correctly - Vital for Outlook Anywhere option http-no-delay # Enable Continuous Stats for Long Running Connections option contstats # Log All HTTP Date option httplog # Log Request and Responses as Fast as Possible option logasap # Set Logging to the Setting in Global log global # Define the Method of Load Balancing - source = Source IP Hash balance source # Client Inactivity Timeout #timeout client 900s timeout client 3600s # Server Inactivity Timeout #timeout server 900s timeout server 3600s # Maximum Time a Request is Queued on the Load Balancer timeout queue 30s # Other Timeouts - Need Investigating timeout connect 5s timeout http-keep-alive 1s timeout http-request 15s timeout tarpit 1m # Define the Default Server Checking Behaviour - 10 seconds, 3 Missed Checks is Failure, 2 Successful Check Brings Server Back default-server inter 10s fall 3 rise 2 userlist stats-auth # User / Password for Admin Access to Stats Page group stats-admin users admin user admin password [Remvoed] # User / Password for Monitor Access to Stats Page group stats-readonly users monitor user monitor password [Removed] listen stats # Define the Mode mode http # Bind to an IP Address/Port bind 10.2.1.1:8080 # Define ACLs to be Used in the Stats Authentication Process acl AUTH-readonly http_auth_group(stats-auth) stats-readonly acl AUTH-admin http_auth_group(stats-auth) stats-admin acl net-allowed src 10.3.1.8/29 10.4.1.8/29 # Enable Various Stats Features stats enable stats show-desc Load Balancer for Exchange stats uri / stats refresh 10s # Enable Stats Auth stats http-request auth unless AUTH-admin OR AUTH-readonly stats admin if AUTH-admin # Block Access Unless in the Allow Network Range block unless net-allowed frontend ft_exchange # Define the Mode mode http # Define the Maximum Number of Connections for the Frontend maxconn 8000 # Bind to an IP Address/Port, Select SSL and specific the Certificate # The Ciphers option for SSL can be Added: ciphers bind 10.2.1.1:443 ssl crt /etc/ssl/crt.domain.com.pem ciphers TLSv1+SSLv3+HIGH:!aNULL:!eNULL # Define a List of Accepted ACLs for Future use acl all-exchange path_beg -i /autodiscover /owa /oab /ews /public /microsoft-server-activesync /rpc acl root url_len 1 acl autodiscover path_beg -i /autodiscover acl owa path_beg -i /owa acl oab path_beg -i /oab acl ews path_beg -i /ews acl public path_beg -i /public acl activesync path_beg -i /microsoft-server-activesync acl outlook-anywhere path_beg -i /rpc # Block All Request Except Those to Exchange Virtual Directories block unless all-exchange OR root # Redirect is the URL is a Single Character, which can only mean / redirect location /owa if root # Capture the User-Agent Header, so that it is Added to the Log capture request header User-Agent len 50 capture request header Content-Length len 120 capture response header Content-Length len 120 # Define Which Set of Backend Servers to Use default_backend bk_exchange_all backend bk_exchange_all # Define the Mode mode http # Define the Overal Maximum Number of Connections for the Backend fullconn 8000 # Define the Backend Servers server exchange01 10.1.1.1:80 check server exchange02 10.1.1.2:80 check (IP addresses and names have been changed to protect to innocent). Posted at Nginx Forum: http://forum.nginx.org/read.php?2,236709,238474#msg-238474
on 2013-04-18 13:47
Thank you, I'll try to modify it, because don't work for me too :) Apr 18 15:39:21 localhost haproxy[32134]: 217.118.93.107:25372 [18/Apr/2013:15:39:21.100] ft_exchange~ ft_exchange/<NOSRV> 129/-1/-1/-1/+129 302 +101 - - PR-- 0/0/0/0/0 0/0"GET / HTTP/1.1" By the way, are you use haproxy only for exchange? your backends use http? not https? gmor Wrote: ------------------------------------------------------- > Hi, > > bind 10.2.1.1:443 ssl crt /etc/ssl/crt.domain.com.pem ciphers > TLSv1+SSLv3+HIGH:!aNULL:!eNULL > > backend bk_exchange_all > > # Define the Backend Servers > server exchange01 10.1.1.1:80 check > server exchange02 10.1.1.2:80 check > Posted at Nginx Forum: http://forum.nginx.org/read.php?2,236709,238475#msg-238475
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.