rockstor / rockstor-core

Linux/BTRFS based Network Attached Storage(NAS)
http://rockstor.com/docs/contribute_section.html
GNU General Public License v3.0
552 stars 137 forks source link

LetsEncrypt support :) #987

Open roweryan opened 8 years ago

roweryan commented 8 years ago

Because it's coming, soon :)

iFloris commented 8 years ago

Would be pretty cool and save some money

dizzi90 commented 8 years ago

letsencrypt is out and works well. Ought to be integrated. Shouldn't be too hard.

schakrava commented 8 years ago

Sounds good. Can one of you clearly document this feature request please? Documenting implementation steps would also be very useful.

phillxnet commented 8 years ago

Linking to a forum thread on the same issue:- http://forum.rockstor.com/t/idea-get-certificate-from-lets-encrypt/927/1

henfri commented 8 years ago

Hello,

I think, this explains well, what needs to be done: https://digitz.org/blog/lets-encrypt-ssl-centos-7-setup/

Install git

yum install git

Install EPEL repo if not present

yum install epel-release

Now let us clone the github repository of Let's encrypt

cd /root/ git clone https://github.com/letsencrypt/letsencrypt

cd letsencrypt

Run the auto installer

./letsencrypt-auto certonly

(possibly, this is needed before: yum install gcc libffi-devel python-devel openssl-devel)

The Server must be reachable from the internet before (I presume port 80)

redecs commented 8 years ago

AFAIK Lets Encrypt needs to check ownership for the server before issuing the certificate so the web server running on the NAS appliance should be accessible from the internet, but this is really not recommend (that why VPNs exist).

henfri commented 8 years ago

Lets encrypt can start and provide an own web server for this purpose and stop it after retreival.

henfri commented 8 years ago

apache.

Standalone¶

To obtain a cert using a “standalone” webserver, you can use the standalone plugin by including certonly and --standalone on the command line. This plugin needs to bind to port 80 or 443 in order to perform domain validation, so you may need to stop your existing webserver. To control which port the plugin uses, include one of the options shown below on the command line.

--standalone-supported-challenges http-01 to use port 80 --standalone-supported-challenges tls-sni-01 to use port 443

henfri commented 8 years ago

Hello,

I did some research now and I would propose one of these two approaches:

A) Use the existing nginx Server

The Server needs to be reachable from the Internet for the time of the letsencrypt certificate retreival. Letsencrypt puts a file into the webroot of the nginx Server that is then checked by the letsencrypt service to confirm that one has control over the server If there are concerns, the alternative is:

B) Stop the existing nginx Server and using the Builtin Server of the letsencrypt application, then start the ngingx Server again.

The Drawback is, that the Web-Interface is not visible during this and this would not be very appealing to the user.

Both variants could be offered, as they are very similar.

Needed User-Input:

Here's the code:

#for upnpc:
if upnp; then
  yum install wget
  wget ftp://195.220.108.108/linux/sourceforge/k/ke/kenzy/special/C7/x86_64/miniupnpc-1.9-7.el7.centos.x86_64.rpm
  rpm -Uvh miniupnpc-1.9-7.el7.centos.x86_64.rpm
fi

# Install git
yum install git

# Install EPEL repo if not present 
yum install epel-release

# Now let us clone the github repository of Let's encrypt
cd /root/
git clone https://github.com/letsencrypt/letsencrypt

cd letsencrypt

if A; then
   stop ngix
fi

if upnp; then
  # The Server must be reachable from the internet before (I presume port 80)
  upnpc -a $IP_LAN 80 80 TCP
  # Make sure that the port is closed again, even if the script fails
  at now + 10 minutes "upnpc -d  80 TCP"
fi

# Run letsencrypt
if A; then
   ./letsencrypt-auto certonly --webroot -w /path/to/ngix/webroot -d $DomainName --agree-tos --email $MailAdress
start nginx
fi

if B; then
 ./letsencrypt-auto certonly --standalone-supported-challenges http-01 -d $DomainName --agree-tos --email $MailAdress
fi

#Now the certificates need to be installed in Rockstor

What do you think?

Greetings, Hendrik

henfri commented 8 years ago

No opinions?

schakrava commented 8 years ago

I haven't had a chance to try this out myself yet, but have you implemented this on your Rockstor instance manually?

henfri commented 8 years ago

Hello,

yes, with some limitations: a) opening the port with upnpc does not work yet (might be my router though) EDIT: Works now. b) could not stop nginx. Had to kill it.

But before going further, I'd like to hear your opinions. There is hardly any point working on this at all if there is little interest. Or if you don't think we should automate the port-forwarding, or if you want the webroot-option exclusively, we can ommit part of the script below. But in general it runs.

Here a slightly modified script:


#!/bin/bash

upnpc=true
A=true  #A: Use existing webxervers webroot
webroot=/path/to/webroot
B=false #B: stop nginx and run own webserver
DomainName=my.domain
MailAddress=hendrik@my.domain

#for upnpc:
if [ "$upnpc" = true ]; then
  yum install wget
  wget ftp://195.220.108.108/linux/sourceforge/k/ke/kenzy/special/C7/x86_64/miniupnpc-1.9-7.el7.centos.x86_64.rpm
  rpm -Uvh miniupnpc-1.9-7.el7.centos.x86_64.rpm
fi

# Install git
yum install git

# Install EPEL repo if not present 
yum install epel-release

# Now let us clone the github repository of Let's encrypt
cd /root/
git clone https://github.com/letsencrypt/letsencrypt

cd letsencrypt

if [ "$upnpc" = true ]; then
  # The Server must be reachable from the internet before (I presume port 80)
  upnpc -r  80 TCP
  # Make sure that the port is closed again, even if the script fails
  at now + 10 minutes "upnpc -d  80 TCP"
fi

# Run letsencrypt
if [ "$A" = true ]; then
   ./letsencrypt-auto certonly --webroot -w $webroot -d $DomainName --agree-tos --email $MailAddress
fi

if [ "$B" = true ]; then
  service ngix stop
 ./letsencrypt-auto certonly --standalone-supported-challenges http-01 -d $DomainName --agree-tos --email $MailAddress
 service nginx start
fi

#Now the certificates need to be installed in Rockstor
henfri commented 8 years ago

Status-update:

I am quite sure, that with with my previous Rockstor-Installation I had letsencrypt running. But with my new Installation, I get an outdated python version-error:

Error: Package: tkinter-2.7.5-34.el7.x86_64 (base) Requires: python = 2.7.5-34.el7 Installed: python-2.7.5-18.el7_1.1.x86_64 (@anaconda/3) python = 2.7.5-18.el7_1.1 Error: Package: python-tools-2.7.5-34.el7.x86_64 (base) Requires: python = 2.7.5-34.el7 Installed: python-2.7.5-18.el7_1.1.x86_64 (@anaconda/3) python = 2.7.5-18.el7_1.1 You could try using --skip-broken to work around the problem You could try running: rpm -Va --nofiles --nodigest Loaded plugins: changelog, fastestmirror Loading mirror speeds from cached hostfile

The upnpc-part is working though; I think that this could be a stable feature - unique to NAS-OSes as far as I know.

Greetings, Hendrik

phillxnet commented 8 years ago

@henfri This looks like you have the 2.7.5-18 python installed with is correct for Rockstor but at one point when upstream CentOS upgraded python to 2.7.5-34 Rockstor had to downgrade it back to the 18 version as there were incompatibilities introduced due to back-ports included in the 34 version. You could make sure you rely on the -18 variant of tkinter and python-tools and that will hopefully sort out those incompatibility messages.

henfri commented 8 years ago

Hello Philip,

understood. I wonder though, wheather it wouldn't be better to fix the incompatibilities, as now Rockstor is cut off from further updates. Anyway, thanks for your suggestion. I did this now:

yum install tcl tk tix

wget ftp://bo.mirror.garr.it/1/slc/centos/7.1.1503/updates/x86_64/Packages/tkinter-2.7.5-18.el7_1.1.x86_64.rpm
wget ftp://bo.mirror.garr.it/1/slc/centos/7.1.1503/updates/x86_64/Packages/python-tools-2.7.5-18.el7_1.1.x86_64.rpm

rpm -i tkinter-2.7.5-18.el7_1.1.x86_64.rpm python-tools-2.7.5-18.el7_1.1.x86_64.rpm

I still get the same message though:

Error: Package: tkinter-2.7.5-34.el7.x86_64 (base)
           Requires: python = 2.7.5-34.el7
           Installed: python-2.7.5-18.el7_1.1.x86_64 (@anaconda/3)
               python = 2.7.5-18.el7_1.1
Error: Package: python-tools-2.7.5-34.el7.x86_64 (base)
           Requires: python = 2.7.5-34.el7
           Installed: python-2.7.5-18.el7_1.1.x86_64 (@anaconda/3)
               python = 2.7.5-18.el7_1.1
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest
Loaded plugins: changelog, fastestmirror

I suggest we stop here, don't you think? Let's first decide -whether there is interest including this in rockstor -which of the approaches (A, B above) we should go -to patch the letsencrypt client or update python on rockstor

Conceptually, this will work.

(For reference: https://community.letsencrypt.org/t/missing-old-python-version-on-centos/9415/4)

By the way: On which CentOS version does Rockstor build up from?

Greetings, Hendrik

JohnnyCalavera commented 8 years ago

But before going further, I'd like to hear your opinions. There is hardly any point working on this at all if there is little interest. @henfri

I'm definitely interested in an automated process. Updated my 4-bay synology servers to DSM 6.0 beta 2 because of the let's encrypt feature and don't wanna miss this on my 12-bay rockstor build.

sfranzen commented 8 years ago

Definitely also interested in a better solution than the default self-signed certificate. I concur with @henfri that it is best to avoid deviating from upstream.

sitic commented 7 years ago

Updated tutorial:

Rockstor doesn't use port 80, so there is no need to stop the rockstor service. Create a port forwarding or use UPnP if your router supports it:

yum install epel-release
yum install certbot
yum install miniupnpc     # optional, for UPnP  port forwarding
upnpc -r 80 TCP
certbot certonly --standalone --standalone-supported-challenges http-01 -d example1.com -d rockstor.example2.com
upnpc -d 80 TCP

The certificates should now be in /etc/letsencrypt/live. They are only valid for 90 days, to renew them automatically create a cron job (e.g. in /etc/cron.monthly) or systemd timer to run

 certbot renew --pre-hook "upnpc -r 80 TCP" --post-hook "upnpc -d 80 TCP"
 rsync -arL /etc/letsencrypt/live/ /mnt2/letsencrypt

regularly. The rsync copies the cert to a share which I've created so that I can share it with docker containers. For the rockstor webservice itself:

mv /opt/rockstor/certs/rockstor.cert /opt/rockstor/certs/rockstor.cert.bak
mv /opt/rockstor/certs/rockstor.key /opt/rockstor/certs/rockstor.key.bak
ln -s /etc/letsencrypt/live/YOURDOMAIN/fullchain.pem  /opt/rockstor/certs/rockstor.cert
ln -s /etc/letsencrypt/live/YOURDOMAIN/privkey.pem /opt/rockstor/certs/rockstor.key

Letsencrypt works quite well with dyndns providers, so there is no need to buy a domain.

MFlyer commented 7 years ago

Hi all, I read this issue many times and here my final question: everyone requesting LetsEncrypt support to remotely access Rockstor / Rockstor Rock-ons with a real certificate?

MFlyer commented 7 years ago

Hi all @henfri - @sitic - @sfranzen how do you think to use a TLD cert on a local machine without exposing it to the web?? Let me explain. Just had a Letsencrypt cert exposing my Rockstor dev env via Watchguard Firewall+dyndns (.hopto.org) and installed newly generated certs on nginx. Certs are ok, nginx went up without issues, and probably this can be nicely coded over Rockstor too, but now my question: from my class C lan (192.168..*) I can only connect to Rockstor machine via ip add, hostname or hostname.mydomain.local, so our new LetsEncrypt cert obviously return errors (ex. on Chrome "There are issues with the site's certificate chain (net::ERR_CERT_COMMON_NAME_INVALID)." <- cert address not equal to actual server name)

Starting from this, do you want LetsEncrypt to expose Rockstor machine over the web?? Are you plannig a "dns hack" to have a valid cert? (done it faking my domain dns adding a route to my_host_name.hopto.org and got all green https, but personally I don't like this - check attached image)

To @schakrava / @phillxnet : we can have LetsEncrypt over Rockstor but this will require user to expose Rockstor over internet (don't like it) and mess with domain dns / hosts file adding fake infos (don't like it again)

dns

doenietzomoeilijk commented 6 years ago

I'd like to see LE encryption happening as well, and I'd like it to be in the standard UI somewhere. We'd need to figure out a way to get this to a user-friendly and secure point - at some point you'll have to open up your NAS to the world for a short period, but as discussed that's a matter of shortly opening port 80 until the cert is done. As for user interface etc, we could always take a peek at how other systems manage it; I know Synology DSM has LE support, and they don't just aim at power users.

I do think there'd have to be some clearly defined scenarios, though: either you can and want to (temporarily, at least) open up a port to the world, or you want to use DNS magic and jump hosts and whatnot, at which point you'd be on your own as there's simply too many variables and options there. From my point of view, the workflow that @sitic described seems reasonable.

To answer @MFlyer 's question specifically: yes, I want to be able to reach my Rockstor install from outside, over SSL.

daniel-illi commented 6 years ago

If you don't like to open the port 80 to the world, it is also possible to do the validation with a dns entry.

I'm using this letsencrypt client which supports the api of many dns providers: https://github.com/Neilpang/acme.sh#9-automatic-dns-api-integration

This works like a charm without the need of complicated webserver configurations.

vesper1978 commented 6 years ago

Any update on getting Let's Encrypt support added? I think it's a very important feature to have added since security is a huge focus these days and having a valid SSL certificate out of the box or with an update would be a major selling point to use Rockstor for a lot of people.

phillxnet commented 5 years ago

Just had another quick look at this issue, relating to the later comment as we now have certbot: I'm in agreement with @doenietzomoeilijk that @sitic 's approach is the neatest most suitable. Verifying via custom dns records is really reaching for integration into Rocsktor don't think we should go that way, as per @MFlyer's comment on the same.

@daniel-illi Agreed an open port 80 seems like asking for unwanted attention, even if it's just a redirect / rewrite. But if we, as per @sitic 's guide, use pre and post hocks within certbot then we can minimise this open port 80 state for the duration of the certificate generation / consequent renewal only which would be only around a few seconds a month anyway.

I had thought the "--standalone" option was deprecated but it looks like I was thinking of: "The --standalone-supported-challenges option has been deprecated since certbot version 0.9.0." form: https://certbot.eff.org/docs/using.html#standalone

It would be best for this to happen completely outside of Rockstor's own configuration as the more closely we stick to certbot's built-ins the better. With a simply initial kick-off from the Rockstor Web-UI and then leave certbot to it's game.

Prior to dropping the ball on the "--standalone" option I had success via the "certonly --webroot" approach which writes file data challenge info to the webserver root):

certbot certonly --webroot --webroot-path /opt/rockstor -d example.com

but it requires a tone of messing around with our nginx config via /opt/rockstor/etc/nginx/nginx.conf:

               location /.well-known  {
                       root /opt/rockstor/;
               }

and a backward step by reverting our prior port 80 redirect / rewrite:

       server {
               listen 80 default_server;
               server_name "~^(?<myhost>.+)$";
               rewrite ^ https://$myhost/$request_uri? permanent;
       }

Which is way too messy.

So lets concentrate on the --standalone approach, especially since we have now gone to the trouble of freeing up port 80 anyway, unless of course it is used by a Rock-on which would need special treatment of sorts.