Skip to content

Instantly share code, notes, and snippets.

@mxvin
Created October 11, 2020 18:18
Show Gist options
  • Save mxvin/89005fa45d2fac04b15d4f9fe09c8bfa to your computer and use it in GitHub Desktop.
Save mxvin/89005fa45d2fac04b15d4f9fe09c8bfa to your computer and use it in GitHub Desktop.
Cutting down Mailu nginx server -- removing nginx from mailu
Cutting down Mailu - Dockerized Mail Server https://github.com/Mailu/Mailu
I like Mailu, with docker, deploying mail server is just easy and simple. Very Low overhead and low memory usage (Without using any fancy addons like ClamAV antivirus, fetchmail, webDav, etc... Only Postfix, Dovecot, and Their manager app)
Some tip to cutting down Mailu nginx server -- removing nginx from mailu -- I feel that running two nginx on one server is kinda useless. Oh Why, I said :)
Assuming you have running/configuring mailu via docker-compose.yml that you get from setup.mailu.io
Steps/Tip
1. You need to extract nginx.conf and proxy.conf from the running 'front' container. run `` docker-compose exec cat /etc/nginx/nginx.conf > nginx.conf `` && `` docker-compose exec cat /etc/nginx/proxy.conf > proxy.conf ``-- save that coz u need that later + save your time
2. You can start do `` docker-compose down `` -- then delete 'front' entry on docker-compose.yml. It's okay also to delete some 'depends_on' options that linked to 'front'. Remove things accordingly as you want, and left the core things : 'redis', 'admin', 'imap', 'smtp', 'antispam'(yeah you may want remove that aswell if you want).
3. If you choose to use webmail client like roundcube on config (now it's just running) you may want to remove that as well. For efficiency sake, its better to install webmail client manually to nginx
4. on 'admin' services, remove 'ports' options as you don't need that later. just forward all things directly to container IPs
5. Add these line to mailu.env
HOST_FRONT=admin
HOST_WEBMAIL=admin
this env is also described on https://mailu.io/1.7/configuration.html
HOST_FRONT is needed by 'smtp' services, and HOST_WEBMAIL is needed by 'admin' services. Because we deleted these services, we need to satisfy the script `` system.get_host_address_from_environment() `` that inside every container service.
If these line still make container not starting up normally (said unhealthy, or still on starting state -- see this via `` docker container ls ``) see the logs via `` docker-compose logs ``
6. now you can start configuring your local nginx.
Nginx steps:
1. Make sure your nginx binary supporting mail. check that by issuing command `` nginx -V | grep mail ``. You need these flags: "--with-mail" and "--with-mail_ssl_module"
2. Edit /etc/nginx/nginx.conf -- then add `` include conf.d/mail.conf `` at the very bottom of config (outside http scoop)
3. Start editing /etc/nginx/conf.d/mail.conf -- you can adopt the portion of extracted nginx.conf from 'front' (1st step above) to this file
edit these file accordingly. I recommended to remove everything but left only the mail { } directive
4. Edit 'auth_http' option to 'http://{docker admin services IP} /internal/auth/email'
X. **tip** : find out every container ips by running cmd `` docker network ls `` and after finding your docker net `` docker network inspect <docker net id> ``
5. Include/replace current ssl config to yours accordingly
6. Mail proxy finish. Now next to admin app proxy-ing chore
7. Add a new vhost config (may on 'sites-enabled' folder for debian-based distro) -- name the vhost mailu.conf
8. now adopt the portion of http { } directive from extracted nginx.conf from 'front' (1st step above)
edit accordingly, you need to adjust some variable like IP of $admin and $antispam. To find out these ips, see tip above.
------ remove everything and left the location directive of /admin/ui , /admin/antispam, /internal , and some redirection to https if you want that. You also need the extracted proxy.conf and place that anywhere you want - remember to edit the 'include' path to the proxy.conf
99. Last, You may want to save some of your server storage. Go ahead and remove 'front', and any docker image that you don't need. Just run `` docker image ls `` and run `` docker image rm <image id> `` to remove unused images from your system
That's it! Now you have a very light, high-performance - easy to configure mail server! Powered by Mailu - With only one nginx :)
** It's possible to edit the docker-compose.yml at the first place. But, you need that generated nginx.conf that have been adjusted to the current environment you pick from setup **
# Basic configuration
user nginx;
worker_processes auto;
error_log /dev/stderr info;
pid /var/run/nginx.pid;
load_module "modules/ngx_mail_module.so";
events {
worker_connections 1024;
}
http {
# Standard HTTP configuration with slight hardening
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
sendfile on;
keepalive_timeout 65;
server_tokens off;
absolute_redirect off;
resolver 127.0.0.11 valid=30s;
# Header maps
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
# Disable the main http server when on kubernetes (port 80 and 443)
# Main HTTP server
server {
# Favicon stuff
root /static;
# Variables for proxifying
set $admin 192.168.xxx.xxx; # match this to related container ips
set $antispam 192.168.xxx.xxx:11334; # match this to related container ips
# Always listen over HTTP
listen 80;
listen [::]:80;
# Only enable HTTPS if TLS is enabled with no error
listen 443 ssl http2;
listen [::]:443 ssl http2;
include /etc/nginx/tls.conf;
ssl_session_cache shared:SSLHTTP:50m;
add_header Strict-Transport-Security 'max-age=31536000';
if ($proxy_x_forwarded_proto = http) {
return 301 https://$host$request_uri;
}
add_header X-Frame-Options 'SAMEORIGIN';
add_header X-Content-Type-Options 'nosniff';
add_header X-Permitted-Cross-Domain-Policies 'none';
add_header X-XSS-Protection '1; mode=block';
add_header Referrer-Policy 'same-origin';
# In any case, enable the proxy for certbot if the flavor is letsencrypt
# If TLS is failing, prevent access to anything except certbot
include /overrides/*.conf;
# Actual logic
location / {
try_files $uri /roundcube;
}
location /admin {
return 301 /admin/ui;
}
location ~ /admin/(ui|static) {
rewrite ^/admin/(.*) /$1 break;
include /etc/nginx/proxy.conf;
proxy_set_header X-Forwarded-Prefix /admin;
proxy_pass http://$admin;
}
location /admin/antispam {
rewrite ^/admin/antispam/(.*) /$1 break;
auth_request /internal/auth/admin;
proxy_set_header X-Real-IP "";
proxy_set_header X-Forwarded-For "";
proxy_pass http://$antispam;
}
location /internal {
internal;
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_pass http://$admin;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
location /health {
return 204;
}
}
# Forwarding authentication server
server {
# Variables for proxifying
set $admin 192.168.xxx.xxx;
listen 127.0.0.1:8000;
location / {
proxy_pass http://$admin/internal$request_uri;
}
}
}
mail {
server_name <HOSTNAME>;
auth_http http://<DOCKER admin IPs>/internal/auth/email;
proxy_pass_error_message on;
resolver 127.0.0.11 valid=30s;
include /etc/nginx/tls.conf;
ssl_session_cache shared:SSLMAIL:50m;
# Default SMTP server for the webmail (no encryption, but authentication)
server {
listen 10025;
protocol smtp;
smtp_auth plain;
}
# Default IMAP server for the webmail (no encryption, but authentication)
server {
listen 10143;
protocol imap;
smtp_auth plain;
}
# SMTP is always enabled, to avoid losing emails when TLS is failing
server {
listen 25;
listen [::]:25;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EE CDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES 256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256- SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES 256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GC M-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES -CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
starttls on;
protocol smtp;
smtp_auth none;
}
# All other protocols are disabled if TLS is failing
server {
listen 143;
listen [::]:143;
starttls only;
protocol imap;
imap_auth plain;
}
server {
listen 110;
listen [::]:110;
starttls only;
protocol pop3;
pop3_auth plain;
}
server {
listen 587;
listen [::]:587;
starttls only;
protocol smtp;
smtp_auth plain;
}
server {
listen 465 ssl;
listen [::]:465 ssl;
protocol smtp;
smtp_auth plain login;
}
server {
listen 993 ssl;
listen [::]:993 ssl;
protocol imap;
imap_auth plain;
}
server {
listen 995 ssl;
listen [::]:995 ssl;
protocol pop3;
pop3_auth plain;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment