How to setup NGINX reverse proxy for Microsoft Exchange

Introduction on NGINX

NGINX is a modern fast webserver which also can be used as an reverse proxy server. A proxy server is a go‑between or intermediary server that forwards requests for content from multiple clients to different servers across the Internet. A reverse proxy server is a type of proxy server that sits behind the firewall in a private network and directs client requests to the appropriate backend server. The reverse proxy server can also do TLS offloading. In this guide we will setup the TLS offloading with Let’s Encrypt.

Using a reverse proxy server with Microsoft Exchange has some challenges to overcome to get everything functional.

Installing Nginx

For this guide we will be using Ubuntu 20.04 with the Nginx version available in the apt repositories.

First install Nginx and required modules then enable it:

# Install Nginx
sudo apt install -y nginx

# Enable Nginx
sudo systemctl enable nginx

# Headers more - Required for Microsoft Exchange
sudo apt-get install -y libnginx-mod-http-headers-more-filter

Install Certbot and python module for Nginx:

# Install certbot and python module
sudo apt install -y certbot python3-certbot-nginx

Unlink the default site:

# Unlink the default site
unlink /etc/nginx/sites-enabled/default

Configure Nginx reverse proxy for Microsoft Exchange

Create the Nginx server block configuration:

sudo nano /etc/nginx/sites-available/mail.domain.tld.conf

Paste in the following info to be able to create an Let’s Encrypt certificate via Certbot:

server {
    listen 80;
    listen [::]:80;
    server_name $mail.domain.tld;

    location / {
        proxy_pass https://$exchange_server;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Enable the configuration:

# Link the conf
sudo ln -s /etc/nginx/sites-available/mail.domain.tld.conf /etc/nginx/sites-enabled/mail.domain.tld.conf

# Reload Nginx
sudo systemctl reload nginx

Run certbot to create the Let’s Encrypt certificate:

# Run certbot
sudo certbot

# Select the mail.domain.tld in the certbot menu
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: mail.domain.tld

# Follow the cerbot configuration and let certbot manage the Nginx configuration.

After running certbot to create the certificate via Let’s Encrypt we can paste in the following info and edit the domain names and server locations:

server {
        if ($host = $mail.domain.tld) {
        return 301 https://$host$request_uri;
        } # managed by Certbot

        listen 80;
        listen [::]:80;

        server_name $mail.domain.tld;
        return 404; # managed by Certbot

        ssl_verify_client       off;

}
server {

        listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
        listen 443 ssl http2; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/$mail.domain.tld/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/$mail.domain.tld/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

        server_name $mail.domain.tld;

        ssl_verify_client       off;

        location /                              { proxy_pass https://$exchange_server; }
        location /owa                           { proxy_pass https://$exchange_server/owa; }
        location /exchange                      { proxy_pass https://$exchange_server/exchange; }
        location /ews                           { proxy_pass https://$exchange_server/ews; }
        location /mapi                          { proxy_pass https://$exchange_server/mapi; }
        location /rpc                           { proxy_pass https://$exchange_server/rpc; }
        location /oab                           { proxy_pass https://$exchange_server/oab; }
        location /autodiscover                  { proxy_pass https://$exchange_server/autodiscover; }
        location /Microsoft-Server-ActiveSync   { proxy_pass https://$exchange_server/Microsoft-Server-ActiveSync; }
        location /ecp                           { proxy_pass https://$exchange_server/ecp; }

        proxy_pass_request_headers on;
        proxy_pass_header Date;
        proxy_pass_header Server;

        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 https;
        more_set_input_headers 'Authorization: $http_authorization';
        proxy_set_header Accept-Encoding "";
        more_set_headers -s 401 'WWW-Authenticate: Basic realm="$mail.domain.tld"';

        proxy_read_timeout 3600;

        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;

        access_log /var/log/nginx/$mail.domain.tld-access.log;
        error_log /var/log/nginx/$mail.domain.tld-error.log;

}

Verify the Nginx configuration and reload Nginx.

# Verify Nginx configuration
sudo nginx -t

# Reload Nginx configuration
sudo systemctl reload nginx

Conclusion

The Nginx reverse proxy is now ready to proxy your Microsoft Exchange Server traffic with TLS offloading via a Let’s Encrypt certificate. Including a working ActiveSync configuration so that all mail clients can connect to your Microsoft Exchange server including Outlook clients.

2 comments

Leave a Reply

Your email address will not be published.