Owncloud .htaccess preventing cert renewal

Hi everyone, I’ve got an OwnCloud VPS box setup with Let’s Encrypt and a successfully created certificate. Following instructions from my VPS provider, I’ve created a cron job that automatically renews my certificate on a periodic basis. However, between registering the cert and the next renewal job running, I installed OwnCloud as a secure dropbox alternative. Trouble is, I’m fairly confident that something in the .htaccess file is preventing the renewal from working by rewriting the call to .well-known\acme-challenge:

> Automatic Let's Encrypt renewal for domain.net was attempted and failed.
> This certificate expires on 2016-06-17 11:46:00 -0400 EDT.

> Failed to get renewed certificate from Let's Encrypt: The Let's Encrypt HTTP challenge failed: acme error 'urn:acme:error:unauthorized': Invalid response from http://domain.net/.well-known/acme-challenge/p9e6A_0Z1l4edZzJaCv5VufRo8eBh3fapugv7c5USpg: "<!DOCTYPE html>
> <!--[if lte IE 8]><html class="ng-csp ie ie8 lte9 lte8" data-placeholder-focus="false" lang="en" ><![endif]-->
> <"

> Please contact your web host for more information on how to fix this issue.

And here’s the snippet from my .htaccess that I think is causing the issue … I’m just now sure how to update this to allow a call to this directory but without compromising the rest of my OwnCloud setup. Any takers?

> <IfModule mod_rewrite.c>
>   RewriteEngine on
>   RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
>   RewriteRule ^\.well-known/host-meta /public.php?service=host-meta [QSA,L]
>   RewriteRule ^\.well-known/host-meta\.json /public.php?service=host-meta-json [QSA,L]
>   RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L]
>   RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L]
>   RewriteRule ^remote/(.*) remote.php [QSA,L]
>   RewriteRule ^(build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
>   RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.*
>   RewriteRule ^(\.|autotest|occ|issue|indie|db_|console).* - [R=404,L]

>   # Rewrite rules for `front_controller_active`
>   Options -MultiViews
>   RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]
>   RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]
>   RewriteCond %{REQUEST_FILENAME} !\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$
>   RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$
>   RewriteCond %{REQUEST_FILENAME} !/remote.php
>   RewriteCond %{REQUEST_FILENAME} !/public.php
>   RewriteCond %{REQUEST_FILENAME} !/cron.php
>   RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php
>   RewriteCond %{REQUEST_FILENAME} !/status.php
>   RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php
>   RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php
>   RewriteCond %{REQUEST_FILENAME} !/updater/
>   RewriteCond %{REQUEST_FILENAME} !/ocs-provider/
>   RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.*
> </IfModule>
1 Like

Are you sure it’s due to the .htaccess ? I suspect it isn’t.

If you place a file ( for example ‘test’ ) within .well-known/acme-challenge on your owncloud, with just a text file and contents “success”. If you then try and go to your domain/.well-known/acme-challenge/test from location elsewhere on the internet ( so it isn’t on your local network, or on a whitelisted IP address ) do you get “success” or what do you get ?

I actually get the file opening up in the browser and it displays the contents.

I tried HTTPS:

I also tried HTTP (which forwarded me to the HTTPS URL):

Both times, the success.txt rendered in the browser.

In that case the issue isn’t your .htaccess file :wink:

Can you provide a little more detail of the issue you were seeing ? and if you use the test/staging server (always best for testing) can you get a cert ? or do you get the same issue ?

Do you recognize the page part of which comes back with an error? By the look of “ng-csp” in it, it’s probably something made with Angular.js :slight_smile: If you know which page comes back, it might be easier to understand what is happening (for example which rewrite rule might have been triggered).

Also it helps a lot to raise the log level of rewrites when you have quite a few and see how exactly particular request gets processed.

It’s definitely just forwarding me back to the login page for my Owncloud.org software (installed in the root of my website). Here’s the index.php page that contains that “ng-csp” suspect snippet:

<!DOCTYPE html>
<!--[if lte IE 8]><html class="**ng-csp** ie ie8 lte9 lte8" data-placeholder-focus="false" lang="en" ><![endif]-->
<!--[if IE 9]><html class="ng-csp ie ie9 lte9" data-placeholder-focus="false" lang="en" ><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html class="ng-csp" data-placeholder-focus="false" lang="en" ><!--<![endif]-->

@serverco, here’s the latest from my renewal log, which is weird because it isn’t saying anything about the failure in the email …

mhaddy@ubuntu-tor1:~$ sudo tail -n200 /var/log/letsencrypt/letsencrypt.log
2016-06-06 06:31:03,458:DEBUG:certbot.main:Root logging level set at 30
2016-06-06 06:31:03,458:INFO:certbot.main:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2016-06-06 06:31:03,458:DEBUG:certbot.main:certbot version: 0.8.0
2016-06-06 06:31:03,458:DEBUG:certbot.main:Arguments: []
2016-06-06 06:31:03,458:DEBUG:certbot.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#apache,PluginEntryPoint#webroot,PluginEntryPoint#null,PluginEntryPoint#manual,PluginEntryPoint#standalone)
2016-06-06 06:31:03,512:DEBUG:certbot.plugins.selection:Requested authenticator <certbot.cli._Default object at 0x7ff26f90e2d0> and installer <certbot.cli._Default object at 0x7ff26f90e2d0>
2016-06-06 06:31:03,513:DEBUG:certbot.cli:Default Detector is Namespace(account=<certbot.cli._Default object at 0x7ff26f903650>, agree_dev_preview=None, allow_subset_of_names=<certbot.cli._Default object at 0x7ff26f903410>, apache=<certbot.cli._Default object at 0x7ff26f90e3d0>, apache_challenge_location=<certbot.cli._Default object at 0x7ff26f905b10>, apache_ctl=<certbot.cli._Default object at 0x7ff26f905310>, apache_dismod=<certbot.cli._Default object at 0x7ff26f909550>, apache_enmod=<certbot.cli._Default object at 0x7ff26f909750>, apache_handle_modules=<certbot.cli._Default object at 0x7ff26f905810>, apache_handle_sites=<certbot.cli._Default object at 0x7ff26f905510>, apache_init_script=<certbot.cli._Default object at 0x7ff26f905150>, apache_le_vhost_ext=<certbot.cli._Default object at 0x7ff26f909210>, apache_server_root=<certbot.cli._Default object at 0x7ff26f905fd0>, apache_vhost_root=<certbot.cli._Default object at 0x7ff26f905e50>, authenticator=<certbot.cli._Default object at 0x7ff26f90e2d0>, break_my_certs=<certbot.cli._Default object at 0x7ff26f903f50>, cert_path=<certbot.cli._Default object at 0x7ff26f909790>, chain_path=<certbot.cli._Default object at 0x7ff26f909a90>, checkpoints=<certbot.cli._Default object at 0x7ff26f909290>, config_dir=<certbot.cli._Default object at 0x7ff26f909b90>, config_file=None, configurator=<certbot.cli._Default object at 0x7ff26f90e2d0>, csr=<certbot.cli._Default object at 0x7ff26f909190>, debug=<certbot.cli._Default object at 0x7ff26f903b50>, dialog_mode=<certbot.cli._Default object at 0x7ff270572c90>, domains=<certbot.cli._Default object at 0x7ff270572f10>, dry_run=<certbot.cli._Default object at 0x7ff270572310>, duplicate=<certbot.cli._Default object at 0x7ff26f903750>, email=<certbot.cli._Default object at 0x7ff270572e10>, expand=<certbot.cli._Default object at 0x7ff26f903150>, fullchain_path=<certbot.cli._Default object at 0x7ff26f909990>, func=<function renew at 0x7ff270b03140>, hsts=<certbot.cli._Default object at 0x7ff26f905490>, http01_port=<certbot.cli._Default object at 0x7ff26f903e50>, ifaces=<certbot.cli._Default object at 0x7ff26f909590>, init=<certbot.cli._Default object at 0x7ff26f909390>, installer=<certbot.cli._Default object at 0x7ff26f90e2d0>, key_path=<certbot.cli._Default object at 0x7ff26f909890>, logs_dir=<certbot.cli._Default object at 0x7ff26f909d90>, manual=<certbot.cli._Default object at 0x7ff26f909b10>, manual_public_ip_logging_ok=<certbot.cli._Default object at 0x7ff26f903910>, manual_test_mode=<certbot.cli._Default object at 0x7ff26f903b10>, must_staple=<certbot.cli._Default object at 0x7ff26f905190>, nginx=<certbot.cli._Default object at 0x7ff26f909f10>, no_self_upgrade=<certbot.cli._Default object at 0x7ff26f903950>, no_verify_ssl=<certbot.cli._Default object at 0x7ff26f903c50>, noninteractive_mode=<certbot.cli._Default object at 0x7ff270572b50>, num=<certbot.cli._Default object at 0x7ff26f905f50>, os_packages_only=<certbot.cli._Default object at 0x7ff26f903850>, post_hook=<certbot.cli._Default object at 0x7ff26f905c90>, pre_hook=<certbot.cli._Default object at 0x7ff26f905b90>, prepare=<certbot.cli._Default object at 0x7ff26f909490>, quiet=<certbot.cli._Default object at 0x7ff26f903a50>, redirect=<certbot.cli._Default object at 0x7ff26f905290>, register_unsafely_without_email=<certbot.cli._Default object at 0x7ff270572150>, reinstall=<certbot.cli._Default object at 0x7ff26f903050>, renew_by_default=<certbot.cli._Default object at 0x7ff26f903310>, renew_hook=<certbot.cli._Default object at 0x7ff26f905d90>, rsa_key_size=<certbot.cli._Default object at 0x7ff26f905090>, server=<certbot.cli._Default object at 0x7ff26f909e90>, staging=<certbot.cli._Default object at 0x7ff26f909f90>, standalone=<certbot.cli._Default object at 0x7ff26f909d10>, standalone_supported_challenges=<certbot.cli._Default object at 0x7ff26f903f10>, staple=<certbot.cli._Default object at 0x7ff26f905890>, strict_permissions=<certbot.cli._Default object at 0x7ff26f905a90>, text_mode=<certbot.cli._Default object at 0x7ff270572a90>, tls_sni_01_port=<certbot.cli._Default object at 0x7ff26f903d50>, tos=<certbot.cli._Default object at 0x7ff26f903550>, uir=<certbot.cli._Default object at 0x7ff26f905690>, update_registration=<certbot.cli._Default object at 0x7ff270572d10>, user_agent=<certbot.cli._Default object at 0x7ff26f909090>, verb='renew', verbose_count=<certbot.cli._Default object at 0x7ff270565e10>, webroot=<certbot.cli._Default object at 0x7ff26f909910>, webroot_map=<certbot.cli._Default object at 0x7ff26f903d10>, webroot_path=<certbot.cli._Default object at 0x7ff26f909710>, work_dir=<certbot.cli._Default object at 0x7ff26f909c90>)
2016-06-06 06:31:03,528:INFO:certbot.renewal:Cert not yet due for renewal
2016-06-06 06:31:03,534:INFO:certbot.renewal:Cert not yet due for renewal
2016-06-06 06:31:03,536:DEBUG:certbot.renewal:no renewal failures

From that log everything looks OK.

in /etc/letsencrypt/live/yourdomain what’s the date of the latest cert ? and is that the one you are actually using ?

Hmmm my cert.pem in /etc/letsencrypt/live/yourdomain has a date of May 22 when I do ls -la, and this matches the certificate details I see in my browser:

In your original post you say

Yet in the post recent post it expires on "August 20 2016"

Are these exactly the same domain ? since the one you have isn't due to expire, so you wouldn't expect it to renew yet anyway.

Yup, exactly the same domains. Now I’m trying to figure out what job is sending me those emails because I know I had a few challenges in setting this up in the beginning (wanting just domain.net, then www.domain.net, then othersub.domain.net, etc.) so this may be a remnant not cleaned up from that trial and error.

When I sudo crontab -e, here’s what I had created to check for renewals weekly:

#update SSL certs for let's encrypt, every mon @ 2:30 AM
30 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log

And here’s the latest from that log so again, nothing to worry about here:

Processing /etc/letsencrypt/renewal/domain.net.conf

Processing /etc/letsencrypt/renewal/domain.net-0001.conf

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/domain.net/fullchain.pem (skipped)
  /etc/letsencrypt/live/domain.net-0001/fullchain.pem (skipped)
No renewals were attempted.

Does this have something to do with how I’ve setup my virtual hosts?

mhaddy@ubuntu-tor1:~$ ls -la /etc/apache2/sites-enabled/
total 12
drwxr-xr-x 2 root root 4096 May 22 21:22 .
drwxr-xr-x 8 root root 4096 May 22 21:30 ..
lrwxrwxrwx 1 root root   36 Apr  9 10:32 domain.net.conf -> ../sites-available/domain.net.conf
lrwxrwxrwx 1 root root   53 May  8 08:13 domain.net-le-ssl.conf -> /etc/apache2/sites-available/domain.net-le-ssl.conf
lrwxrwxrwx 1 root root   43 May  8 15:30 sub.domain.net.conf -> ../sites-available/sub.domain.net.conf
lrwxrwxrwx 1 root root   60 May 22 21:22 sub.domain.net-le-ssl.conf -> /etc/apache2/sites-available/sub.domain.net-le-ssl.conf

I’m not sure if I need both *-le-ssl.conf and the other *.conf file for the domain and subdomain, respectively, but LE automatically created the *-le-ssl.conf files when I ran the configuration scripts.

It shouldn’t have anything to do with your virtual hosts - no.

It looks more as if you have another cron or something running somewhere that is sending you the “error” emails - whereas your “main LE cron” is working correctly.

Can you get any clues from the headers in the email ( server / account it comes from ) and timestamp - that you can then check in your logs (mail and cron ) for the source.

Checking the headers was a good idea – turns out I had a Let’s Encrypt certificate installed on my shared hosting still setup from before I setup my cloud VPS. I removed that certificate and let’s see if I still get the notifications!

Thank you so much for helping me step through this with some logic and lots of patience.


Just checking in - still no email, so I think I got it! Thanks once again.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.