How to use letsencrypt on basic webhosting without ssh access?

First, can you confirm that your web host allows you to upload your own certificate and private key? If not, you won’t be able to use the certificate you issue.

If so, I would recommend using manual mode (-a manual) instead of standalone. This will give you instructions about uploading a certain file to a location on your web server for validation.


Will it be possible to just add one’s personal IP-address as an A-record for their domain and instruct LE client to use this IP for verification?

Domain validation for a certificate from any CA is about whether you control the domain. So, if the personal IP-address is publicly accessible and so is the web server you put behind it, sure. But most personal IP addresses end at a router that NATs a bunch of computers behind it, so rigging up a web server will just end in confusing connection rejection errors.

We don’t recommend folks try that because if they don’t have enough control over their domain’s host to do any of the usual Let’s Encrypt workflows, it’s unlikely they have the network or the experience to rig up a secure web server on their personal IP.


indeed… it’s quite cheap to get a SSH accessible VPS server these days. You can get a VPS server as little as US$15/yr ! Money saved on commercial SSL certs can be put towards a VPS server heh :slight_smile:

@eva2000 where do you get that?
15$ per YEAR? are you sure?

sure i have over 90+ VPS servers a many are 128MB OpenVZ based VPS at US$15/yr from reliable My ECC 256bit SSL certificate test site is on a 128MB VPS from them at US$15/yr :slight_smile: Next step up if you need more disk space is at US$3.5/month or US$3.15m paid yearly = US$37.80/yr and that excludes their 10% discount code :slight_smile:

My Centmin Mod install guide for RamNode on their KVM offerings when CentOS 7 templates were not available yet (they are now) (of course centos 7 won’t run on 128MB VPS needs min 768-1024MB VPS).

Hi thanks
I tried it, the following instruction pop out
Content-Type header MUST be set to text/plain.

If you don’t have HTTP server configured, you can run the following
command on the target server (as root):

mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf “%s” v2gQJ8W4y0xU8u8mLWGxc2UU1SLRMLb6yEpGZ5il0vg.XZAqYPdlQ2QevySPFlFG4rPvOsAkdavRrg9p2IjLqWA > .well-known/acme-challenge/v2gQJ8W4y0xU8u8mLWGxc2UU1SLRMLb6yEpGZ5il0vg

run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c
“import BaseHTTPServer, SimpleHTTPServer;
SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map = {’’: ‘text/plain’};
s = BaseHTTPServer.HTTPServer((’’, 80), SimpleHTTPServer.SimpleHTTPRequestHandler);

So I created the file locally and transfer it via ftp to my web hosting (my webhosting supports https via web interface by inserting the pem certificate), In the root of my server I created the folder .well-known inside the other folder a copied the given file to it.
After I should run the python script on my local PC or the server somehow? do i have to insert somewhere my domain name? I would be glad for further instructions, thank you. For classic webhosting it would be great to have 1 year validity of certificates, so the admin do not have to do it every 3 monts…

thank you


You can try I’ve used the site before and it is very simple to understand. Just a few copy and paste commands and you have a cert. You will have to do this every 3 months though if you choose this option.

thanks I tried this
everything was going OK until step 4 where I have to put file on my server, I did it

but the following error occured (I tried twice)

Error: Domain challenge failed. Please start back at Step 1. {“type”:“http-01”,“status”:“invalid”,“error”:{“type”:“urn:acme:error:unauthorized”,“detail”:“Error parsing key authorization file: Invalid key authorization: malformed key thumbprint”},“uri”:“",“token”:“MTNMYtRu1L8QTp61rpneTZAnnuGUz3vGKrVsza35Kbw”,“keyAuthorization”:“MTNMYtRu1L8QTp61rpneTZAnnuGUz3vGKrVsza35Kbw.EaRywCnunC06bg1y4bTCGzhHYaHqf2KmUfpbx6PwkGI”,“validationRecord”:[{“url”:“”,“hostname”:“”,“port”:“80”,“addressesResolved”:[“”],“addressUsed”:"”}]}

can you give a hint what to do? Did I put the file there in a wrong way? should I change permissions of the file?

you maybe could try looking at the mime type and setting it to text/plain, pretty easy htaccess, but dont have it in memory atm.

I am only basic linux user, could you be please more specific, what should I try to do? thank you

try to search for “text/plain” and/or “htaccess” and somewhere I have a text which has to go into a file called .htaccess (yes with the dot) and that must be in the acme-challenge folder

@fogelton As far as I can see, your Content-Type is correct:

curl -i
HTTP/1.1 200 OK
Date: Tue, 01 Dec 2015 10:44:33 GMT
Server: Apache
Last-Modified: Tue, 01 Dec 2015 08:03:46 GMT
ETag: "c80871-59-525d198da0617"
Accept-Ranges: bytes
Content-Length: 89
Cache-Control: max-age=600
Expires: Tue, 01 Dec 2015 10:54:33 GMT
Content-Type: text/plain  <- this is the correct  Content-Type, no need to change it

<- here you have a new line

But your challenge file contains a new line after the challenge text. It’s suppossed that this new line issue with challenge file was already solved but just in case, you should try to create the challenge file with another editor, or create it using the suggested command by letsencrypt printf "%s" whatever > .well-known/acme-challenge/whatever and upload it to your web server using ftp (or the method you should use to upload files to your web server).

Note: Keep in mind that every time you execute the letsencrypt command the challenge file changes and you need to create the right file and upload it to your web server.


I checked in gedit and there was no new line, I also tried curl -i and the result is without the new line you report, weird.
I did the procedure again, I put there a new file
curl -i
HTTP/1.1 200 OK
Date: Wed, 02 Dec 2015 10:41:30 GMT
Server: Apache
Last-Modified: Wed, 02 Dec 2015 10:22:41 GMT
ETag: "c80ef2-59-525e7a77d50f5"
Accept-Ranges: bytes
Content-Length: 89
Cache-Control: max-age=600
Expires: Wed, 02 Dec 2015 10:51:30 GMT
Content-Type: text/plain


and the same error occured
Error: Domain challenge failed. Please start back at Step 1.

Any ideas please

@fogelton Sorry but I’m still viewing a Carriage Return in your challenge file. I just used curl -i and piped it to cat -A that will show the hidden characters (return carriages, end of line, etc.) and you will see the difference between your server and mine:

curl -i | cat -A
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    89  100    89    0     0   1389      0 --:--:-- --:--:-- --:--:--  1412
HTTP/1.1 200 OK^M$
Date: Wed, 02 Dec 2015 10:56:18 GMT^M$
Server: Apache^M$
Last-Modified: Wed, 02 Dec 2015 10:22:41 GMT^M$
ETag: "c80ef2-59-525e7a77d50f5"^M$
Accept-Ranges: bytes^M$
Content-Length: 89^M$
Cache-Control: max-age=600^M$
Expires: Wed, 02 Dec 2015 11:06:18 GMT^M$
Content-Type: text/plain^M$

As you can see there is a ^M in your last line and should be only a $ (end of line). This is the same test used with my server (in the last line there is no ^M):

curl -i | cat -A
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    88  100    88    0     0   1885      0 --:--:-- --:--:-- --:--:--  1913
HTTP/1.1 200 OK^M$
Date: Wed, 02 Dec 2015 10:56:25 GMT^M$
Server: Apache/2.4.10 (Debian)^M$
Strict-Transport-Security: max-age=17280000^M$
Last-Modified: Wed, 02 Dec 2015 10:54:51 GMT^M$
ETag: "58-525e81a9037b2"^M$
Accept-Ranges: bytes^M$
Content-Length: 88^M$

1.- First, try to update letsencrypt using git pull inside the dir you have located letsencrypt-auto command because it is suppossed that this problem was already solved…

2.- Again, create the challenge file using printf or echo -n and upload that file to your server because your editor is adding a carriage return.

3.- I think that letsencrypt is in maintenance till General Availability (tomorrow, 3rd December at 6 PM GMT) so even if you get to upload the right file, it could not work because of this maintenance*.

  • Edit: The right link to the scheduled maintenance is this and the schedule maintenance is:
    December 2, 2015 3:00PM - 5:00PM MST
    December 2, 2015 10:00PM - 12:00AM UTC


thanks, I will try tomorrow

@fogelon Check my edited post, the actual scheduled maintenance window is:

December 2, 2015 3:00PM - 5:00PM MST
December 2, 2015 10:00PM - 12:00AM UTC

So you could try to generate the certificates today (outside those maintenance windows of course) :wink:

thanks I just tried, It works :slight_smile: thank you for patience and help

@fogelton Glad you get it working :wink: Anyway, just for the records, do you uploaded a new file without the new line, updated your letsencrypt client, both of them?

I did both of them, I created the file with printf and pipe instead of echo and pipe and I updated the client