@@ -, +, @@ - generates letsencrypt certificates - sets up a https-only website - redirects http to https - sets the path where letsencrypt-auto lives - default value /usr/bin, but there is no Debian package yet - build a debian package with patch applied - checkout letsencrypt on the machine where you are testing the package git clone https://github.com/letsencrypt/letsencrypt - use apache mod_ssl sudo a2enmod ssl - make sure the machine is accessible on 80 (needed for letsencrypt) and 443 from the internet - install koha with your new package - Put your (existing) domain options in /etc/koha/koha-sites.conf - use koha-create with the new options: sudo koha-create --create-db --force-https --letsencrypt /home/mirko/letsencrypt - wait until setup is finished, check that you got a working OPAC and staff client with certificates make sure to use https:// to open both sites - check that http redirects to https --- debian/docs/koha-create.xml | 17 +++++++ debian/scripts/koha-create | 59 ++++++++++++++++++++-- debian/scripts/koha-foreach | 2 + debian/scripts/koha-functions.sh | 11 ++++ debian/scripts/koha-list | 81 ++++++++++++++++++++++-------- debian/templates/apache-site-https.conf.in | 68 +++++++++++++++++++++++++ 6 files changed, 215 insertions(+), 23 deletions(-) create mode 100644 debian/templates/apache-site-https.conf.in --- a/debian/docs/koha-create.xml +++ a/debian/docs/koha-create.xml @@ -40,6 +40,8 @@ port directory + + directory | instancename @@ -177,6 +179,21 @@ + + + Set up a https-only website + + + + + + + Specify the where letsencrypt-auto lives + It defaults to /usr/bin. + + + + , Print usage information. --- a/debian/scripts/koha-create +++ a/debian/scripts/koha-create @@ -71,6 +71,8 @@ Options: conjunction with --defaultsql and --populate-db. --upload-path dir Set a user defined upload_path. It defaults to /var/lib/koha//uploads + --force-https Set up a https-only site with letsencrypt certificates + --letsencrypt Path to the letsencrypt folder --help,-h Show this help. Note: the instance name cannot be longer that 11 chars. @@ -192,6 +194,20 @@ EOM die fi + # Check that mod_ssl is installed and enabled. + if [ "$USE_HTTPS" = "yes" ]; then + if ! /usr/sbin/apachectl -M 2> /dev/null | grep -q 'ssl_module'; then + cat 1>&2 < #https$:\1443>:" "/etc/apache2/sites-available/$name.conf" + # enable redirect from http to https on port 80 + sed -i "s:^\s*#\(.*\)#nohttps$:\1:" "/etc/apache2/sites-available/$name.conf" + # make koha-list --letsencrypt aware of this instance # could be done by checking apache conf instead + touch /var/lib/koha/$name/letsencrypt.enabled + # restart apache with working certs + service apache2 restart +} + # Set defaults and read config file, if it exists. DOMAIN="" OPACPORT="80" @@ -354,6 +387,9 @@ END_BIBLIOS_RETRIEVAL_INFO="" START_AUTHORITIES_RETRIEVAL_INFO="" END_AUTHORITIES_RETRIEVAL_INFO="" +APACHE_CONFIGFILE="" +LETSENCRYPT_PATH="/usr/bin/" + if [ -e /etc/koha/koha-sites.conf ] then . /etc/koha/koha-sites.conf @@ -361,7 +397,7 @@ fi [ $# -ge 1 ] && [ $# -le 16 ] || ( usage ; die "Error: wrong parameters" ) -TEMP=`getopt -o chrpm:l:d:f:b:a: -l create-db,request-db,populate-db,use-db,use-memcached,enable-sru,sru-port:,help,marcflavor:,auth-idx:,biblio-idx:,zebralang:,defaultsql:,configfile:,passwdfile:,database:,adminuser:,memcached-servers:,memcached-prefix:,upload-path:, \ +TEMP=`getopt -o chrpm:l:d:f:b:a: -l create-db,request-db,populate-db,use-db,use-memcached,enable-sru,sru-port:,help,marcflavor:,auth-idx:,biblio-idx:,zebralang:,defaultsql:,configfile:,passwdfile:,database:,adminuser:,memcached-servers:,memcached-prefix:,upload-path:,force-https,letsencrypt:, \ -n "$0" -- "$@"` # Note the quotes around `$TEMP': they are essential! @@ -378,7 +414,6 @@ CLO_MEMCACHED_SERVERS="" CLO_MEMCACHED_PREFIX="" CLO_UPLOAD_PATH="" - while true ; do case "$1" in -c|--create-db) @@ -419,6 +454,10 @@ while true ; do SRU_SERVER_PORT="$2" ; shift 2 ;; --upload-path) CLO_UPLOAD_PATH="$2" ; shift 2 ;; + --force-https) + USE_HTTPS="yes" ; shift ;; + --letsencrypt) + LETSENCRYPT_PATH="$2" ; shift 2 ;; -h|--help) usage ; exit 0 ;; --) @@ -514,6 +553,10 @@ check_apache_config opacdomain="$OPACPREFIX$name$OPACSUFFIX$DOMAIN" intradomain="$INTRAPREFIX$name$INTRASUFFIX$DOMAIN" +# Check if letsencrypt path is valid, die otherwise +if [ ! -e "$LETSENCRYPT_PATH/letsencrypt-auto" ]; then + die "Cannot find letsencrypt-auto in $LETSENCRYPT_PATH" +fi if [ -f $PASSWDFILE ] && [ `cat $PASSWDFILE | grep "^$name:"` ] then @@ -598,8 +641,13 @@ FLUSH PRIVILEGES; eof fi #` + if [ "$USE_HTTPS" = "yes" ]; then + APACHE_CONFIGFILE="apache-site-https.conf.in" + else + APACHE_CONFIGFILE="apache-site.conf.in" + fi # Generate and install Apache site-available file and log dir. - generate_config_file apache-site.conf.in \ + generate_config_file $APACHE_CONFIGFILE \ "/etc/apache2/sites-available/$name.conf" mkdir "/var/log/koha/$name" chown "$username:$username" "/var/log/koha/$name" @@ -708,6 +756,11 @@ then # Start Indexer daemon koha-indexer --start "$name" fi + + if [ "$USE_HTTPS" = "yes" ]; then + # Get letsencrypt certificates + letsencrypt_instance + fi fi --- a/debian/scripts/koha-foreach +++ a/debian/scripts/koha-foreach @@ -30,6 +30,8 @@ do --nosip) listopts="$listopts --nosip";; --plack) listopts="$listopts --plack";; --noplack) listopts="$listopts --noplack";; + --letsencrypt) listopts="$listopts --letsencrypt" ;; +--noletsencrypt) listopts="$listopts --noletsencrypt" ;; *) break;; esac shift --- a/debian/scripts/koha-functions.sh +++ a/debian/scripts/koha-functions.sh @@ -84,6 +84,17 @@ is_email_enabled() fi } +is_letsencrypt_enabled() +{ + local instancename=$1 + + if [ -e /var/lib/koha/$instancename/letsencrypt.enabled ]; then + return 0 + else + return 1 + fi +} + is_sip_enabled() { local instancename=$1 --- a/debian/scripts/koha-list +++ a/debian/scripts/koha-list @@ -36,24 +36,27 @@ show_instances() for instance in $( get_instances ); do case $show in "all") - if instance_filter_email $instance $show_email && \ - instance_filter_plack $instance $show_plack && \ - instance_filter_sip $instance $show_sip; then + if instance_filter_email $instance $show_email && \ + instance_filter_letsencrypt $instance $show_letsencrypt && \ + instance_filter_plack $instance $show_plack && \ + instance_filter_sip $instance $show_sip; then echo $instance fi ;; "enabled") if is_enabled $instance; then - if instance_filter_email $instance $show_email && \ - instance_filter_plack $instance $show_plack && \ - instance_filter_sip $instance $show_sip; then + if instance_filter_email $instance $show_email && \ + instance_filter_letsencrypt $instance $show_letsencrypt && \ + instance_filter_plack $instance $show_plack && \ + instance_filter_sip $instance $show_sip; then echo $instance fi fi ;; "disabled") if ! is_enabled $instance; then - if instance_filter_email $instance $show_email && \ - instance_filter_plack $instance $show_plack && \ - instance_filter_sip $instance $show_sip; then + if instance_filter_email $instance $show_email && \ + instance_filter_letsencrypt $instance $show_letsencrypt && \ + instance_filter_plack $instance $show_plack && \ + instance_filter_sip $instance $show_sip; then echo $instance fi fi ;; @@ -106,6 +109,28 @@ instance_filter_plack() return 1 } +instance_filter_letsencrypt() +{ + local instancename=$1 + local show_letsencrypt=$2; + + case $show_letsencrypt in + "all") + return 0 ;; + "enabled") + if is_letsencrypt_enabled $instancename; then + return 0 + fi ;; + "disabled") + if ! is_letsencrypt_enabled $instancename; then + return 0 + fi ;; + esac + + # Didn't match any criteria + return 1 +} + instance_filter_email() { local instancename=$1 @@ -150,6 +175,17 @@ set_show_email() fi } +set_show_letsencrypt() +{ + local letsencrypt_param=$1 + + if [ "$show_letsencrypt" = "all" ]; then + show_letsencrypt=$letsencrypt_param + else + die "Error: --letsencrypt and --noletsencrypt are mutually exclusive." + fi +} + set_show_plack() { local plack_param=$1 @@ -190,6 +226,8 @@ Options: --nosip Show instances with SIP disabled --plack Show instances with Plack enabled --noplack Show instances with Plack disabled + --letsencrypt Show instances with letsencrypt enabled + --noletsencrypt Show instances with letsencrypt disabled --help | -h Show this help The filtering options can be combined, and you probably want to do this @@ -201,23 +239,26 @@ show="all" show_email="all" show_sip="all" show_plack="all" +show_letsencrypt="all" -args=$(getopt -l help,enabled,disabled,email,noemail,sip,nosip,plack,noplack -o h -n $0 -- "$@") +args=$(getopt -l help,enabled,disabled,email,noemail,sip,nosip,plack,noplack,letsencrypt,noletsencrypt -o h -n $0 -- "$@") set -- $args while [ ! -z "$1" ] do case "$1" in - -h|--help) usage; exit;; - --email) set_show_email "enabled" ;; - --noemail) set_show_email "disabled" ;; - --sip) set_show_sip "enabled" ;; - --nosip) set_show_sip "disabled" ;; - --plack) set_show_plack "enabled" ;; - --noplack) set_show_plack "disabled" ;; - --enabled) set_show "enabled" ;; - --disabled) set_show "disabled" ;; - *) break;; + -h|--help) usage; exit;; + --email) set_show_email "enabled" ;; + --noemail) set_show_email "disabled" ;; + --sip) set_show_sip "enabled" ;; + --nosip) set_show_sip "disabled" ;; + --plack) set_show_plack "enabled" ;; + --noplack) set_show_plack "disabled" ;; + --letsencrypt) set_show_letsencrypt "enabled" ;; +--noletsencrypt) set_show_letsencrypt "disabled" ;; + --enabled) set_show "enabled" ;; + --disabled) set_show "disabled" ;; + *) break;; esac shift done --- a/debian/templates/apache-site-https.conf.in +++ a/debian/templates/apache-site-https.conf.in @@ -0,0 +1,68 @@ +# Koha instance __KOHASITE__ Apache config. + +# redirect http to https +# #nohttps +# RewriteEngine On #nohttps +# RewriteCond %{HTTPS} !=on #nohttps +# RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L] #nohttps +# #nohttps + +# OPAC + #https +# SSLEngine on +# SSLProtocol +TLSv1.2 +TLSv1.1 +TLSv1 +# SSLCompression off +# SSLHonorCipherOrder on +# SSLCipherSuite "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-SA- +# SSLCertificateKeyFile /etc/letsencrypt/live/__OPACSERVER__/privkey.pem +# SSLCertificateFile /etc/letsencrypt/live/__OPACSERVER__/cert.pem +# SSLCertificateChainFile /etc/letsencrypt/live/__OPACSERVER__/chain.pem + + = 2.4> + Define instance "__KOHASITE__" + + Include /etc/koha/apache-shared.conf +# Include /etc/koha/apache-shared-disable.conf +# Include /etc/koha/apache-shared-opac-plack.conf + Include /etc/koha/apache-shared-opac.conf + + ServerName __OPACSERVER__ + SetEnv KOHA_CONF "/etc/koha/sites/__KOHASITE__/koha-conf.xml" + SetEnv MEMCACHED_SERVERS "__MEMCACHED_SERVERS__" + SetEnv MEMCACHED_NAMESPACE "__MEMCACHED_NAMESPACE__" + AssignUserID __UNIXUSER__ __UNIXGROUP__ + + ErrorLog /var/log/koha/__KOHASITE__/opac-error.log +# TransferLog /var/log/koha/__KOHASITE__/opac-access.log +# RewriteLog /var/log/koha/__KOHASITE__/opac-rewrite.log + + +# Intranet + #https +# SSLEngine on +# SSLProtocol +TLSv1.2 +TLSv1.1 +TLSv1 +# SSLCompression off +# SSLHonorCipherOrder on +# SSLCipherSuite "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES +# SSLCertificateKeyFile /etc/letsencrypt/live/__OPACSERVER__/privkey.pem +# SSLCertificateFile /etc/letsencrypt/live/__OPACSERVER__/cert.pem +# SSLCertificateChainFile /etc/letsencrypt/live/__OPACSERVER__/chain.pem + + = 2.4> + Define instance "__KOHASITE__" + + Include /etc/koha/apache-shared.conf +# Include /etc/koha/apache-shared-disable.conf +# Include /etc/koha/apache-shared-intranet-plack.conf + Include /etc/koha/apache-shared-intranet.conf + + ServerName __INTRASERVER__ + SetEnv KOHA_CONF "/etc/koha/sites/__KOHASITE__/koha-conf.xml" + SetEnv MEMCACHED_SERVERS "__MEMCACHED_SERVERS__" + SetEnv MEMCACHED_NAMESPACE "__MEMCACHED_NAMESPACE__" + AssignUserID __UNIXUSER__ __UNIXGROUP__ + + ErrorLog /var/log/koha/__KOHASITE__/intranet-error.log +# TransferLog /var/log/koha/__KOHASITE__/intranet-access.log +# RewriteLog /var/log/koha/__KOHASITE__/intranet-rewrite.log + --