Hello All!
I’ve compiled nginx with new nginx-acme module (added to a for ACME2.0 support)
and i can’t get it to generate certificates. Log show this error:
*140 cannot load certificate “/etc/nginx/”: PEM_read_bio_X509_AUX() failed
My nginx config states the path:
nginx-acme issuer (Let’s Encrypt)
acme_issuer letsencrypt {
uri https://acme-v02.api.letsencrypt.org/directory;
contact mailto:admin@mydomain.com;
state_path /var/cache/nginx/acme-letsencrypt;
accept_terms_of_service;
}
acme_shared_zone zone=ngx_acme_shared:1M;
I have checked permissions.
But it still trying to write to /etc/nginx
i’m using nginx 1.28 on Ubuntu 24.04
Thank you
Hi @dialbat!
Can you share your entire (sanitized) config? Your error seems to be more likely due to when/how it’s loading the certificate than the certificate not being generated. If it was the latter you would be running into an issue such as this one.
That log message is normal if the site is accessed before the certificate is generated and applied to the site. So it should only happen the first time while nginx is waiting for letsencrypt to verify ownership.
1 Like
I understand that, but its not the first time message, unfortunately.
just figured out how to add code.
My logic in nginx config, if that matters: Internet → Xeams (anti spam) → Exchange server.
I’m certifying access to OWA, SMTP and MAPI over HTTP.
Domains are coming from mail-server_names.conf
mydomain@xeamslinux:~$ sudo nginx -T
[sudo] password for mydomain:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:
user www-data;
worker_processes auto;
pid /var/run/nginx.pid;
error_log /var/log/nginx/error.log debug;
events { worker_connections 1024; }
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Access log must be in http/server/location (not global)
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server_tokens off;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 valid=300s ipv6=off;
resolver_timeout 5s;
# nginx-acme issuer (Let’s Encrypt)
acme_issuer letsencrypt {
uri https://acme-v02.api.letsencrypt.org/directory;
contact mailto:admin@mydomain.com;
state_path /var/cache/nginx/acme-letsencrypt;
accept_terms_of_service;
}
acme_shared_zone zone=ngx_acme_shared:1M;
# Upstreams
upstream exchange_https { server 10.0.20.10:443; keepalive 64; ntlm; }
upstream xeams_https { server 10.0.30.20:5272; keepalive 32; }
# host → backend map (include so you only edit one file)
map $host $backend_upstream { include /etc/nginx/snippets/backend-map.conf; }
# Common proxy headers/options
include /etc/nginx/snippets/common-proxy.conf;
include /etc/nginx/conf.d/*.conf;
}
# configuration file /etc/nginx/mime.types:
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/avif avif;
image/png png;
image/svg+xml svg svgz;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/webp webp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
font/woff woff;
font/woff2 woff2;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.apple.mpegurl m3u8;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/vnd.ms-excel xls;
application/vnd.ms-fontobject eot;
application/vnd.ms-powerpoint ppt;
application/vnd.oasis.opendocument.graphics odg;
application/vnd.oasis.opendocument.presentation odp;
application/vnd.oasis.opendocument.spreadsheet ods;
application/vnd.oasis.opendocument.text odt;
application/vnd.openxmlformats-officedocument.presentationml.presentation
pptx;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
xlsx;
application/vnd.openxmlformats-officedocument.wordprocessingml.document
docx;
application/vnd.wap.wmlc wmlc;
application/wasm wasm;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/xspf+xml xspf;
application/zip zip;
application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream iso img;
application/octet-stream msi msp msm;
audio/midi mid midi kar;
audio/mpeg mp3;
audio/ogg ogg;
audio/x-m4a m4a;
audio/x-realaudio ra;
video/3gpp 3gpp 3gp;
video/mp2t ts;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
}
# configuration file /etc/nginx/snippets/backend-map.conf:
# Default all mail/autodiscover hosts to Exchange
default https://exchange_https;
# (Optional explicit) Xeams UI host
xeams.mydomain.com https://xeams_https;
# configuration file /etc/nginx/snippets/common-proxy.conf:
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 https;
proxy_read_timeout 3600;
client_max_body_size 100m;
# configuration file /etc/nginx/conf.d/exchange-http.conf:
server {
listen 80;
include /etc/nginx/snippets/mail-server_names.conf;
# ACME HTTP-01 handled internally by module
# location /.well-known/acme-challenge/ { }
location / { return 404; }
# Redirect any other HTTP to HTTPS
# location / { return 301 https://$host$request_uri; }
}
# configuration file /etc/nginx/snippets/mail-server_names.conf:
server_name
mail.mydomain.com autodiscover.mydomain.com
# Optional extras
xeams.mydomain.com;
# configuration file /etc/nginx/conf.d/exchange-https.conf:
server {
listen 443 ssl default_server;
server_name _;
ssl_reject_handshake on; # No cert needed; aborts TLS handshake early
return 444; # Optional: drop the connection
}
server {
listen 443 ssl;
http2 on;
include /etc/nginx/snippets/mail-server_names.conf;
# Ask module to issue/renew SAN cert for *these* names
acme_certificate letsencrypt;
# Use module-provided vars as live cert/key
ssl_certificate $acme_certificate;
ssl_certificate_key $acme_certificate_key;
ssl_certificate_cache max=2;
# HSTS (enable after certs are working)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# --- Exchange endpoints (NTLM-friendly) ---
location ~* ^/(owa|ecp)(/.*)?$ { proxy_pass https://exchange_https; }
location ~* ^/mapi(/.*)?$ { proxy_pass https://exchange_https; }
location ~* ^/ews(/.*)?$ { proxy_pass https://exchange_https; }
location ~* ^/Microsoft-Server-ActiveSync(/.*)?$ { proxy_pass https://exchange_https; }
location ~* ^/oab(/.*)?$ { proxy_pass https://exchange_https; }
location ~* ^/autodiscover/(autodiscover\.xml|.*)$ { proxy_pass https://exchange_https; }
# Xeams UI (optional)
location /xeams/ { proxy_pass https://xeams_https; }
# Fallback (routes via map)
location / {
proxy_pass $backend_upstream;
include /etc/nginx/snippets/common-proxy.conf;
}
}
mydomain@xeamslinux:~$
1 Like
Only things I see is, mailto: shouldn’t be there.
Second, make sure that /var/cache/nginx/acme-letsencrypt directory is writable by nginx. For me the account.key is written by root, but the certs themselfs are written as the user nginx is running as, in this case www-data
1 Like
mydomain@xeamslinux:~$ sudo -u www-data sh -c 'echo ok > /var/cache/nginx/acme-letsencrypt/.permcheck && rm /var/cache/nginx/acme-letsencrypt/.permcheck' && echo "write: OK"
write: OK
and everything checks out.
Maybe i’m missing some basic step.
- Configure nginx
2.Start nginx
3.ports 80 and 443 open
- try accessing url from outside
- certificate should be generated.
am i correct?
1 Like
Hello guys,
not sure how, but now its working 
thank you for your imput!
1 Like