Configure an Alternative Linux Web Server for SmarterMail

By default, SmarterMail will install and run the Kestrel web server on Linux. However, it is possible to use an alternate web server for SmarterMail. To do so, you will need to set up a reverse proxy.

Below are instructions for setting up two of the most common web servers on Linux — Nginx and Apache — as reverse proxies along with sample configurations that you can use with minimal fine-tuning. Please note that if you utilize host headers for multiple mail domains, you’ll have to repeat the shown configurations for each domain.  

If Smartermail is already installed

If you’ve already installed SmarterMail and are using Kestrel, you’ll first want to uninstall it using the following command:

sudo ./smartermail_xxxx uninstall

After you’ve uninstalled it, you can re-install. During the installation process, however, you’ll want to decline using the built-in web server. 

If you’ve yet to install Smartermail:

Use the following command to download your desired version of Smartermail:

wget https://downloads.smartertools.com/smartermail/100.0.xxxx/smartermail_ xxxx\&& sudo chmod +x smartermail_xxxx \&& sudo ./smartermail_xxxx install

When asked if you want to use the built-in SmarterMail web-server, select ‘no’.

If your certificate(s) is in .pfx format:

Run the following commands to split each .pfx into a .key/.crt. If you don’t have a wildcard certificate, you’ll need to split 1 certificate per hostname (mail., autodiscover., etc.):

sudo openssl pkcs12 -in _MAIL/AUTODISCOVER.DOMAIN.COM_.pfx -nocerts -out _MAIL/AUTODISCOVER.DOMAIN.COM_.key -nodes -legacy

Replace _MAIL/AUTODISCOVER.DOMAIN.COM_ with the name of the .pfx

sudo openssl pkcs12 –in _MAIL/AUTODISCOVER.DOMAIN.COM_.pfx -clcerts -out _MAIL/AUTODISCOVER.DOMAIN.COM_.crt -legacy

Replace _MAIL/AUTODISCOVER.DOMAIN.COM_ with the name of the .pfx

Your original .pfx certificates will remain intact. You may want to move the .keys and .crts into their own directories for organization. 

Setting up Nginx

  1. Install NGINX, if it isn’t installed already using the following:
    sudo apt install nginx
  2. Create a new config file at /etc/nginx/sites-available/ named after your site and add the following server{...} block per .pfx you have. If you're setting up mail.domain.com and autodiscover.domain.com, you would need to use this block twice, specifying the correct name, .crt path, and .key path for both. If you have a wildcard .pfx, you only need to use the block once and _SERVER_NAME_ should be a single underscore (‘_’).
    1. server { 
      
      	listen 80; 
      	listen 443 ssl; 
      
      	server_name _SERVER_NAME_; # Replace _SERVER_NAME_ with mail.domain.com, autodiscover.domain.com, or ‘_’ as a catch-all 
      	ssl_certificate /PATH/TO/CERTIFICATE; # Replace with path to .crt 
      	ssl_certificate_key /PATH/TO/KEY; # Replace with path to .key
      
      	# Proxy settings 
      	location / { 
      		proxy_pass http://localhost:17017; # Or the appropriate backend server proxy_http_version 1.1;
      		proxy_set_header Connection ""; 
      		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 $scheme; 
      		proxy_set_header X-Forwarded-Host $host;
      		# X-Forwarded-Prefix is not typically used in NGINX and might need custom handling 
      
      		# Proxy settings for WebSockets
      		proxy_http_version 1.1;
      		proxy_set_header Upgrade $http_upgrade;
      		proxy_set_header Connection "Upgrade";
      
      		# Buffer settings 
      		proxy_buffer_size 4096k; 
      		proxy_buffers 8 4096k; 
      		proxy_busy_buffers_size 4096k; 
      
      		# Timeouts 
      		proxy_connect_timeout 1200s; 
      		proxy_send_timeout 1200s; 
      		proxy_read_timeout 1200s; 
      
      		# SSL Offloading 
      		proxy_ssl_server_name on; 
      		proxy_ssl_protocols TLSv1.2 TLSv1.3; 
      	}
      
      	# Error Pages Remove this if you don’t have custom error pages 
      	error_page 500 502 503 504 /custom_50x.html; 
      	location = /custom_50x.html { 
      		root /path/to/your/errors; # Replace with the actual path to your error documents if you have them 
      		internal;
      	} 
      
      	# Logging 
      	access_log /var/log/nginx/access.log; 
      	error_log /var/log/nginx/error.log; 
      }
  3. You will also need to adjust the Nginx configuration file. You will need to add "Upstream" to the file in the HTTP block
    1. sudo nano /etc/nginx/nginx.conf
    2. events {
        worker_connections 768;
        # multi_accept on;
      }
      
      http {
        upstream websocket_backend {
          server 127.0.0.1:17017;
        }
  4. Create a symlink to enable the new site: 
    sudo ln -s /etc/nginx/sites-available/_YOUR_SITE_ /etc/nginx/sites-enabled
  5. Don’t forget to disable the default site if you don’t need it:
    rm /etc/nginx/sites-enabled/default 
  6. Validate Nginx config:
    sudo nginx -t
  7. Start Mail and Nginx services: 
    sudo service smartermail start sudo service nginx start
  8. Enable Nginx to start on boot:
    sudo systemctl enable nginx
  9. Navigate to the following URLs (using your domain and hostnames) to ensure everything is working properly:
    • http://mail.domain.com
    • https://mail.domain.com
    • https://autodiscover.domain.com

Setting up Apache

  1. Install apache
    sudo apt install apache2
  2. Create a new config file at /etc/apache2/sites-available/ named after your site with a .conf extension (e.g. domain.com.conf) and add the following virtual host pair for each .pfx you use. A wildcard certificate will allow you to use just one virtual host pair per root domain, whereas with multiple certificates you’ll need more. For the hostnames ‘mail.’ and ‘autodiscover.’, we’ll need 2 virtual hosts per port. Shown are the 2 virtual hosts for mail.domain.com which can be copied and altered to host autodiscover.domain.com:
  3. <VirtualHost *:80>
     
    ServerName mail.domain.com #Replace with your domain 
    
    ProxyPass / http://localhost:17017/ #Or the appropriate backend server     ProxyPassReverse / http://localhost:17017/ #Or the appropriate backend server 
    
    </VirtualHost> 
    
    <VirtualHost *:443> 
    
    ServerName mail.domain.com #Replace with your domain 
    
    SSLEngine on 
    SSLCertificateFile /path/to/.crt # Replace with path to .crt
    SSLCertificateKeyFile /path/to/.key # Replace with path to .key
    
    ProxyPass / http://localhost:17017/ #Or the appropriate backend server     ProxyPassReverse / http://localhost:17017/ #Or the appropriate backend server 
    
    </VirtualHost> 
  4. Create a symlink to enable the new site:
    sudo ln -s /etc/apache2/sites-available/_YOUR_SITE_ /etc/apache2/sites-enabled
  5. Don’t forget to disable the default site if you don’t need it:
    rm cd /etc/apache2/sites-enabled/000-default.conf
  6. Validate Apache config:
    sudo apache2ctl configtest
  7. Make sure the SSL module is enabled in Apache:
    sudo a2enmod ssl
  8. Start Mail and Apache services: 
    sudo service smartermail start sudo service apache2 start
  9. Enable Apache to start on boot:
    sudo systemctl enable apache2
  10. Navigate to the following URLs (using your domain and hostnames) to ensure everything is working okay:
    • http://mail.domain.com
    • https://mail.domain.com
    • https://autodiscover.domain.com

URL Rewriting

If your root domain (domain.com) doesn’t resolve to your webmail interface, you’ll likely need to setup URL Rewriting to ensure autodiscover requests make it to Smartermail. This article goes into further depth on URL Rewriting: 

https://portal.smartertools.com/kb/a3706/configure-url-rewriting-for-autodiscover-on-linux.aspx

Feedback

smartermail can not get client's real ip address, instead of nginx's LAN IP.
k (9/8/2024 at 11:29 PM)
Hello,

This line: "proxy_set_header X-Real-IP $remote_addr;" is meant to pass along the client's IP to the server. If you have this option in your NGINX config, then this should be working properly

Jorel Haggard (9/10/2024 at 9:18 AM)
and even worse:

Error: Failed to start the transport 'WebSockets': Error: WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.

k (9/10/2024 at 12:00 AM)
Hello,

Can you please start a support ticket detailing this issue?

Jorel Haggard (9/10/2024 at 9:26 AM)