Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure Compojure Ring and https

I'm using Clojure (ring and compojure) to build a web app and I don't know where to start with https. I have a registration and login that will need to be secured, then once they're authenticated they'll need to stay in https.

I can't seem to find a good tutorial on setting up https in general or for a clojure app specifically.

I found this answer: How do you enable https and http->https redirects in ring / compojure

Does that mean I can write my compojure app as if there's no https and have nginx sit in front and take care of all that for me?

like image 378
user3866249 Avatar asked Jul 22 '14 20:07

user3866249


People also ask

What is clojure ring?

Ring is a Clojure web applications library inspired by Python's WSGI and Ruby's Rack. By abstracting the details of HTTP into a simple, unified API, Ring allows web applications to be constructed of modular components that can be shared among a variety of applications, web servers, and web frameworks.

What is ring middleware?

In Ring, middleware refers to simple functions that wrap the main handler and adjusts some aspects of it in some way.

What is Compojure?

Compojure is a small routing library for Ring that allows web applications to be composed of small, independent parts.


2 Answers

Yes, the standard procedure is to have nginx act as a reverse proxy in front of the ring based webapp. This is considered secure and it's easier to maintain because it's more standard. Every clojure based site I know about does it this way.

like image 159
Arthur Ulfeldt Avatar answered Oct 05 '22 02:10

Arthur Ulfeldt


The reverse proxy approach does seem to be the most common option. However, as an 'experiment' I looked into using just ring, jetty compojure etc with https. It isn't that hard.

  1. First you need to use keytool to generate a self signed certificate and install that into a new keystore. The keytool docs a pretty good and can walk you through this process. Note that if you use a self signed cert, you will need to add an exception rule with most browsers to say that you trust that certificate.

  2. Copy the keystore file created into the root of your project tree

  3. Update the jetty config parameters to specify ssl, ssl-port, keystore file and keystore password.

  4. Add the ring/ring-defaults package to your project.clj

  5. Add the wrap-defaults middleware with the secure-site-defaults configuration option to force https connections i.e. redirect http connections to https.

This is not the setup I would recommend for production use, but I found it simpler than also having to configure ngix when doing development etc. The hardest part was working through the keytool process. However, just following the docs and examples gives you enough provided you don't allow yoruself to be overwhelmed by all the options - just keep it simple.

Something like

keytool -genkeypair \
        -keystore $SSL_DIR/$KS_NAME \
        -keypass $PASSWORD \
        -storepass $PASSWORD \
        -keyalg RSA -keysize 2048 \
        -alias root \
        -ext bc:c \
        -dname "$ROOT_CN"

echo "CA Key"
keytool -genkeypair \
        -keystore $SSL_DIR/$KS_NAME \
        -alias ca \
        -ext bc:c \
        -keypass $PASSWORD \
        -keyalg RSA -keysize 2048 \
        -storepass $PASSWORD \
        -dname "$CA_CN"

echo "Server Key"
keytool -genkeypair \
        -keystore $SSL_DIR/$KS_NAME \
        -alias server \
        -keypass $PASSWORD \
        -storepass $PASSWORD \
        -keyalg RSA -keysize 2048 \
        -dname "$SERVER_CN"

echo "Root Cert"
keytool -keystore $SSL_DIR/$KS_NAME \
        -storepass $PASSWORD \
        -alias root \
        -exportcert \
        -rfc > $SSL_DIR/root.pem

echo "CA Cert"
keytool -storepass $PASSWORD \
        -keystore $SSL_DIR/$KS_NAME \
        -certreq \
        -alias ca | keytool -storepass $PASSWORD \
                            -keystore $SSL_DIR/$KS_NAME \
                            -gencert \
                            -alias root \
                            -ext BC=0 \
                            -rfc > $SSL_DIR/ca.pem

echo "Import CA cert"
keytool -keystore $SSL_DIR/$KS_NAME \
        -storepass $PASSWORD \
        -importcert \
        -alias ca \
        -file $SSL_DIR/ca.pem

echo "Server Cert"
keytool -storepass $PASSWORD \
        -keystore $SSL_DIR/$KS_NAME \
        -certreq \
        -alias server | keytool -storepass $PASSWORD \
                                -keystore $SSL_DIR/$KS_NAME \
                                -gencert \
                                -alias ca \
                                -rfc > $SSL_DIR/server.pem



echo "Import Server Cert"
cat $SSL_DIR/root.pem $SSL_DIR/ca.pem $SSL_DIR/server.pem | \
    keytool -keystore $SSL_DIR/$KS_NAME \
            -storepass $PASSWORD \
            -keypass $PASSWORD \
            -importcert \
            -alias server
like image 39
Tim X Avatar answered Oct 05 '22 03:10

Tim X