Certbot on Apache server behind a Nginx reverse proxy


#1

Hello,

I have a backend web server (apache) and a frontend web server (nginx) which i use as a reverse proxy.
They are on different networks. My websites that i want the certs for are on the backend apache server and i configured my vhosts there. When i start certbot on the apache server it cant get the certs because my domains are pointing to the frontend nginx server. My question is: what is the easiest way for me to get certificates for my sites?
Thanks in advance for your kind answers :slight_smile:

My current nginx conf:

server {
listen 80;
server_name xxxx.info www.xxx.info

location / {
    proxy_pass http://xx.xx.xx.xx:8080;
    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;
}

}


#2

Hi @Anonimni,

Do you have a way to update your DNS records via an API? There is a DNS challenge method where the client changes requested items in your DNS zone instead of making requested changes to the web server. This can be useful when obtaining a certificate on a machine other than the web server where the certificate will be deployed.


#3

Yes i have access to my DNS settings, would you be so kind and tell me what do i need to change? Thanks in advance!


#4

What connection(s) do you want to encrypt using the certificates?

Client -> nginx
nginx -> apache

or both?


#5

You could use one of the bash clients like

which offer more mature support for authentication via DNS changes. @J0s3f’s question is also a good one to answer before starting.


#6

Thanks for the advice guys! I want to encrypt the connection between client and nginx reversy proxy server.
I looked at the links you gave me and i think https://github.com/Neilpang/acme.sh is the right one for me. Did i understand this correctly, i just install the acme shell script on my nginx server and skip to step 7 in the readme file, request dns verification and add the txt commands to my domain? Do i have to make the domain cert first or can i simply go to step 7? Thanks in advance!


#7

Hi @Anonimni, the point of acme.sh and most clients like it is to make the certificate for you… so you should be able to do something like step 7 without making a certificate first. If it works, it should save the certificate in your working directory so that you can then install it in your web server configuration.


#8

I’ll also point out that Let’s Encrypt certificates have to be renewed every 90 days. Different clients have different approaches to helping you renew (whether automatically or manually). If you’re editing the DNS records yourself to perform the authentication, you probably won’t be able to renew automatically, because the DNS records that Let’s Encrypt wants to be added to the DNS zone will be different every time the certificate is renewed. You would have to re-run your client and perform this process every 90 days.

Some of the DNS providers have an API that lets you change DNS records from the command line somehow, which can then be combined with a Let’s Encrypt client to automate this process more.


#9

I installed the acme script and when i try the dns cert as described in step 7, i get the error:
[Mon Feb 13 21:24:48 UTC 2017] Getting domain auth token for each domain
[Mon Feb 13 21:24:48 UTC 2017] Verifying:mydomain.info
[Mon Feb 13 21:24:51 UTC 2017] mydomain.info:Challenge error: {“type”:“urn:acme:error:malformed”,“detail”:“Unable to update challenge :: Response does not complete challenge”,“status”: 400}
[Mon Feb 13 21:24:51 UTC 2017] Please check log file for more details: /root/.acme.sh/acme.sh.log

Here is a part of my acme.sh.log:

[Mon Feb 13 21:26:50 UTC 2017] timeout
[Mon Feb 13 21:26:50 UTC 2017] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header '
[Mon Feb 13 21:26:51 UTC 2017] ret=‘0’
[Mon Feb 13 21:26:51 UTC 2017] POST
[Mon Feb 13 21:26:51 UTC 2017] url=‘https://acme-v01.api.letsencrypt.org/acme/challenge/R1sQihohQdhomvCXHEZAixZCjRpfjpdJjD8HV6HA_94/644980775
[Mon Feb 13 21:26:51 UTC 2017] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header '
[Mon Feb 13 21:26:52 UTC 2017] _ret=‘0’
[Mon Feb 13 21:26:52 UTC 2017] code=‘400’
[Mon Feb 13 21:26:52 UTC 2017] mydomain.info:Challenge error: {“type”:“urn:acme:error:malformed”,“detail”:“Unable to update challenge :: Response does not complete challenge”,“status”: 400}
[Mon Feb 13 21:26:52 UTC 2017] Skip for removelevel:
[Mon Feb 13 21:26:52 UTC 2017] pid
[Mon Feb 13 21:26:52 UTC 2017] _clearupdns
[Mon Feb 13 21:26:52 UTC 2017] Dns not added, skip.
[Mon Feb 13 21:26:52 UTC 2017] _on_issue_err
[Mon Feb 13 21:26:52 UTC 2017] Please check log file for more details: /root/.acme.sh/acme.sh.log

What am i doing wrong? I addes the TXT values to my domain as the script has requested.


#10

Do you think you could post what TXT record it asked you to add and we can take a look at it in the DNS to see if we agree that it matches?


#11

[Mon Feb 13 21:16:26 UTC 2017] Add the following TXT record:
[Mon Feb 13 21:16:26 UTC 2017] Domain: ‘_acme-challenge.amacert.info’
[Mon Feb 13 21:16:26 UTC 2017] TXT value: ‘A2umUnov7uw45honHtPH7hp3qCasCtxWP3J9J66Qh_s’
[Mon Feb 13 21:16:26 UTC 2017] Please be aware that you prepend _acme-challenge. before your domain
[Mon Feb 13 21:16:26 UTC 2017] so the resulting subdomain will be: _acme-challenge.amacert.info
[Mon Feb 13 21:16:26 UTC 2017] Add the following TXT record:
[Mon Feb 13 21:16:26 UTC 2017] Domain: ‘_acme-challenge.www.amacert.info’
[Mon Feb 13 21:16:26 UTC 2017] TXT value: 'D94wFWa9WXAzi94oRBH1oa5PtTqx1eh2z1T9_x50nL4’
Here it is, thanks for the fast answer.

EDIT:
Here is how it looks in my dns settings:


#12

Hi @Anonimni, I don’t see the TXT record successfully added to your DNS. Do you have some indication or confirmation or lookup result that makes you sure that you’ve added it successfully?


#13

Here is how my dns settings look:


#14

Apparently in that screenshot… but I still don’t see it in the public DNS! Are you sure that your other DNS settings are correct and the place you’re editing it is really going to control your DNS server? Is there some kind of delay before your edits take effect?


#15

My domain is registered at namecheap.com , i am using their default dns servers, and i made the changes in the namecheap control panel, there should be no delay. I will wait some more and try again. How can i check if it is updated? With normal domain whois i see only contact info and such: http://whois.domaintools.com/amacert.info


#16

It probably updated now because when i try again i am getting a different error now:

[Mon Feb 13 22:08:40 UTC 2017] Renew: ‘amacert.info
[Mon Feb 13 22:08:40 UTC 2017] Multi domain=‘DNS:www.amacert.info’
[Mon Feb 13 22:08:40 UTC 2017] Getting domain auth token for each domain
[Mon Feb 13 22:08:40 UTC 2017] Verifying:amacert.info
[Mon Feb 13 22:08:41 UTC 2017] Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 7
[Mon Feb 13 22:08:41 UTC 2017] Can not connect to https://acme-v01.api.letsencrypt.org/directory to get nonce.
[Mon Feb 13 22:08:41 UTC 2017] amacert.info:Can not get challenge:
[Mon Feb 13 22:08:41 UTC 2017] Please check log file for more details: /root/.acme.sh/acme.sh.log

EDIT:

Still getting the first error, it seems that the second error was a fluke.


#17

You have DNS records for _acme-challenge.amacert.info.amacert.info. and _acme-challenge.www.amacert.info.amacert.info..

It looks like Namecheap’s DNS manager implicitly adds “.amacert.info.” onto the end.

You need to rename the DNS records to “_acme-challenge” and “_acme-challenge.www”, or delete and recreate them with those names.


#18

Good catch, @mnordhoff!


#19

Thanks for the help! Can you please tell me how i can check the current dns settings of my domain?


#20

The DNS settings look good to me now. :slight_smile:

Next time you run the ACME client, it may give you a new set of challenges and you may have to edit the DNS record values, but at least everything’s been straightened out.

I don’t know. There are a lot of ways. I used the dig command on a Linux system.

dig _acme-challenge.amacert.info txt
dig _acme-challenge.amacert.info.amacert.info txt
dig _acme-challenge.www.amacert.info txt
dig _acme-challenge.www.amacert.info.amacert.info txt

dig amacert.info ns

dig +norecurse _acme-challenge.amacert.info txt @dns1.registrar-servers.com.
dig +norecurse _acme-challenge.amacert.info txt @dns2.registrar-servers.com.