diff --git a/README.md b/README.md index 62f31fbbdb89ad4080cb985756c8bfbf7b6a64ed..f4f09c72be47850f95b75477ff48996bb85de998 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,32 @@ - run `vagrant plugin install vagrant-hostsupdater` to install ## Get started: +- Put a TLS certificate (self-signed is fine, but make sure you have [public, intermediate, and private all concatenated into one .pem file](https://www.digitalocean.com/community/tutorials/how-to-implement-ssl-termination-with-haproxy-on-ubuntu-14-04)) in /data/per-user/coreos.dev/combined.pem on the host system. +- Test it with `openssl s_server -cert /data/per-user/coreos.dev/combined.pem -www` ```bash vagrant up ``` -Wait for the provisioning to finish (~40mins), and go to your browser: http://coreos.dev +Wait for the provisioning to finish (~40mins), and go to your browser: https://coreos.dev + +### If you want to add another wordpress instance apart from coreos.dev: +- For e.g. example.dev, put a cert for it in /data/per-user/example.dev/combined.pem on +the host system. +- Test it with `openssl s_server -cert /data/per-user/example.dev/combined.pem -www` + +```bash +vagrant ssh +sudo sh /data/infrastructure/scripts/approve-user.sh example.dev wordpress +``` +Check https://example.dev in your bowser! + +### Cleaning up + +To clean up stuff from previous runs of your VM, you can do: -### If you want to add another wordpress instance: ```bash vagrant ssh -sudo sh /data/infrastructure/scripts/adduser.sh example.dev wordpress +rm -rf /etc/systemd/system/multi-user.wants/* ``` -Check http://example.dev in your bowser! +and then restart the VM with `vagrant reload`. diff --git a/Vagrantfile b/Vagrantfile index 0cf87287ba51bd98c0090d0e1d3d6de1b09e80ca..8d2a497ce647729290136d042ee88ed2ace4a710 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -34,9 +34,10 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| core.vm.hostname = HOSTNAME core.vm.network :private_network, ip: "#{BASE_IP_ADDR}.#{i+1}" config.vm.synced_folder ".", "/data/infrastructure" + config.vm.synced_folder "/data/per-user", "/data/per-user" core.vm.provision :file, source: "./config/user-data", destination: "/var/lib/coreos-vagrant/vagrantfile-user-data" core.vm.provision :shell, path: "./scripts/setup.sh" - core.vm.provision :shell, path: "./scripts/adduser.sh", args: [HOSTNAME, "wordpress"] + core.vm.provision :shell, path: "./scripts/approve-user.sh", args: [HOSTNAME, "nginx"] end end end diff --git a/scripts/adduser.sh b/scripts/adduser.sh deleted file mode 100644 index d0f147513bc98db3deeb17e661899a1f0e13c5ae..0000000000000000000000000000000000000000 --- a/scripts/adduser.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -eux - -# Start service for new site (and create the user) -systemctl enable $2@$1.service -systemctl start $2@$1.service - -sleep 10 - -# Configure new site in HAproxy -IP=`docker inspect --format '{{.NetworkSettings.IPAddress}}' $2-$1` - -echo IP address of new container \'$2-$1\' is \'$IP\' -sed s/%HOSTNAME%/$1/g /data/infrastructure/templates/haproxy-frontend.part | sed s/%IP%/$IP/g >> /data/server-wide/haproxy/frontends.part -sed s/%HOSTNAME%/$1/g /data/infrastructure/templates/haproxy-backend.part | sed s/%IP%/$IP/g >> /data/server-wide/haproxy/backends.part -cat /data/server-wide/haproxy/haproxy-main.part /data/server-wide/haproxy/frontends.part /data/server-wide/haproxy/backends.part > /data/server-wide/haproxy/haproxy.cfg -systemctl reload haproxy.service diff --git a/scripts/approve-user.sh b/scripts/approve-user.sh new file mode 100644 index 0000000000000000000000000000000000000000..ec441d25c1722e6ae47999cc90143b7dd2c743f0 --- /dev/null +++ b/scripts/approve-user.sh @@ -0,0 +1,31 @@ +#!/bin/bash -eux + +# Start service for new site (and create the user) +systemctl enable $2@$1.service +systemctl start $2@$1.service + +sleep 10 + +# Configure new site in HAproxy +IP=`docker inspect --format '{{.NetworkSettings.IPAddress}}' $2-$1` + +echo IP address of new container \'$2-$1\' is \'$IP\' + +if [ -f /data/per-user/$1/combined.pem ]; then + echo Importing cert from /data/per-user/$1/combined.pem + echo TODO: enforce validity check at this point! + echo Please run scripts/check-cert.sh $1 to make sure it\'s OK + mkdir -p /data/server-wide/haproxy/approved-certs + cp /data/per-user/$1/combined.pem /data/server-wide/haproxy/approved-certs/$1.pem + echo /haproxy-override/approved-certs/$1.pem $1 >> /data/server-wide/haproxy/certs/list.txt + sed s/%HOSTNAME%/$1/g /data/infrastructure/templates/haproxy-cert.part >> /data/server-wide/haproxy/certs.part +else + echo WARNING: TLS cert /data/per-user/$1/combined.pem not found! Not enabling SNI for this domain. +fi + +sed s/%HOSTNAME%/$1/g /data/infrastructure/templates/haproxy-frontend.part >> /data/server-wide/haproxy/frontends.part + +sed s/%HOSTNAME%/$1/g /data/infrastructure/templates/haproxy-backend.part | sed s/%IP%/$IP/g >> /data/server-wide/haproxy/backends.part + +cat /data/server-wide/haproxy/haproxy-1.part /data/server-wide/haproxy/certs.part /data/server-wide/haproxy/haproxy-2.part /data/server-wide/haproxy/frontends.part /data/server-wide/haproxy/backends.part > /data/server-wide/haproxy/haproxy.cfg +systemctl reload haproxy.service diff --git a/scripts/check-cert.sh b/scripts/check-cert.sh new file mode 100644 index 0000000000000000000000000000000000000000..035de4788fb4e21a3655b1e296e23d51a7b21738 --- /dev/null +++ b/scripts/check-cert.sh @@ -0,0 +1,37 @@ +if [ -f /data/per-user/$1/tls.cert ]; then +if [ -f /data/per-user/$1/tls.key ]; then +if [ -f /data/per-user/$1/chain.pem ]; then + echo head -5 /data/per-user/$1/tls.cert: + head -5 /data/per-user/$1/tls.cert + echo head -5 /data/per-user/$1/chain.pem: + head -5 /data/per-user/$1/chain.pem + echo head -5 /data/per-user/$1/tls.key: + head -5 /data/per-user/$1/tls.key + + echo Some information about: /data/per-user/$1/tls.cert: + openssl x509 -text -in /data/per-user/$1/tls.cert + + echo Some information about: /data/per-user/$1/chain.pem: + openssl x509 -text -in /data/per-user/$1/chain.pem + + echo Some information about: /data/per-user/$1/tls.key: + openssl rsa -text -in /data/per-user/$1/tls.key + + if [ -f /data/per-user/$1/combined.pem ]; then + echo combined.pem exists! Please make sure it\'s tls.cert + chain.pem + tls.key \(in that order\) + else + echo Generating /data/per-user/$1/combined.pem: + cat /data/per-user/$1/tls.cert /data/per-user/$1/chain.pem /data/per-user/$1/tls.key > /data/per-user/$1/combined.pem + fi + + echo Running a test server on port 4433 on this server now \(please use your browser to check\): + openssl s_server -cert /data/per-user/$1/combined.pem -www +else + echo Files /data/per-user/$1/{tls.cert,tls.key,chain.pem} not found +fi +else + echo Files /data/per-user/$1/{tls.cert,tls.key,chain.pem} not found +fi +else + echo Files /data/per-user/$1/{tls.cert,tls.key,chain.pem} not found +fi diff --git a/scripts/setup.sh b/scripts/setup.sh index ed268765ea0ac90b356c710c909db1602fbf1ddf..973b5c49e96cdff751daad730f5c7ce8d835ebf4 100644 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -12,8 +12,12 @@ docker pull tutum/nginx # Configure and start HAproxy docker pull dockerfile/haproxy mkdir -p /data/server-wide/haproxy -cp /data/infrastructure/templates/haproxy-main.part /data/server-wide/haproxy/haproxy-main.part -rm /data/server-wide/haproxy/frontends.part -rm /data/server-wide/haproxy/backends.part +cp /data/infrastructure/templates/haproxy-*.part /data/server-wide/haproxy/ +rm /data/server-wide/haproxy/*.part +#rm /etc/systemd/system/multi-user.target.wants/* +touch /data/server-wide/haproxy/certs.part +touch /data/server-wide/haproxy/frontends.part +touch /data/server-wide/haproxy/backends.part +cp /data/infrastructure/templates/haproxy-*.part /data/server-wide/haproxy/ systemctl enable haproxy.service systemctl start haproxy.service diff --git a/templates/haproxy-main.part b/templates/haproxy-1.part similarity index 61% rename from templates/haproxy-main.part rename to templates/haproxy-1.part index b8de0ca624a148caf1da6f1b15d67f44cbd99d29..9493145a2261fa5c05f26888b4705f044c010210 100644 --- a/templates/haproxy-main.part +++ b/templates/haproxy-1.part @@ -15,5 +15,9 @@ defaults timeout client 50000 timeout server 50000 -frontend http-in - bind *:80 +frontend https-in +mode http + bind *:443 ssl crt-list /haproxy-override/certs/list.txt crt /haproxy-override/approved-certs/coreos.dev/combined.pem + reqadd X-Forwarded-Proto:\ https + + diff --git a/templates/haproxy-2.part b/templates/haproxy-2.part new file mode 100644 index 0000000000000000000000000000000000000000..45f44d9b6a82908ef7747c8924ee680a1928b758 --- /dev/null +++ b/templates/haproxy-2.part @@ -0,0 +1,6 @@ + + +default_backend coreos.dev + +frontend http-in + bind *:80 diff --git a/templates/haproxy-cert.part b/templates/haproxy-cert.part new file mode 100644 index 0000000000000000000000000000000000000000..b2516294e590f2511b3b996d4c7aff6c424fa2a5 --- /dev/null +++ b/templates/haproxy-cert.part @@ -0,0 +1,4 @@ + +# %HOSTNAME%: + acl is_%HOSTNAME% req_ssl_sni -i %HOSTNAME% + use_backend %HOSTNAME% if is_%HOSTNAME% diff --git a/unit-files/haproxy.service b/unit-files/haproxy.service index de7e400e80a1ba51b1fbd56b51abf64d582ba7d9..96dc328c86db1a706e5f3c00c096c199483650f2 100644 --- a/unit-files/haproxy.service +++ b/unit-files/haproxy.service @@ -11,6 +11,7 @@ ExecStartPre=-/usr/bin/docker rm %p ExecStart=/usr/bin/docker run\ --name %p\ -p 80:80\ +-p 443:443\ -v /data/server-wide/%p:/haproxy-override\ dockerfile/haproxy ExecReload=/usr/bin/docker restart %p