From b5282d11cfe3db4dd323f0f025d7072a3ee130fe Mon Sep 17 00:00:00 2001 From: Marius Pedersen <57487101+mapemapemape@users.noreply.github.com> Date: Tue, 5 Nov 2024 11:46:47 +0100 Subject: [PATCH 1/4] Fix a IPv6 address parsing error --- client/nivlheim_client | 2 +- client/windows/nivlheim_client.ps1 | 2 +- debian/changelog | 6 ++++++ server/service/postArchive.go | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/client/nivlheim_client b/client/nivlheim_client index 3fc39d2..c89ed90 100755 --- a/client/nivlheim_client +++ b/client/nivlheim_client @@ -67,7 +67,7 @@ my $NAME = 'nivlheim_client'; my $AUTHOR = 'Øyvind Hagberg'; my $CONTACT = 'oyvind.hagberg@usit.uio.no'; my $RIGHTS = 'USIT/IT-DRIFT/GD/GID, University of Oslo, Norway'; -my $VERSION = '2.7.25'; +my $VERSION = '2.7.26'; # Usage text my $USAGE = <<"END_USAGE"; diff --git a/client/windows/nivlheim_client.ps1 b/client/windows/nivlheim_client.ps1 index cbfc7db..198310c 100644 --- a/client/windows/nivlheim_client.ps1 +++ b/client/windows/nivlheim_client.ps1 @@ -31,7 +31,7 @@ param( [bool]$nosleep = $false ) -Set-Variable version -option Constant -value "2.7.25" +Set-Variable version -option Constant -value "2.7.26" Set-Variable useragent -option Constant -value "NivlheimPowershellClient/$version" Set-PSDebug -strict Set-StrictMode -version "Latest" # http://technet.microsoft.com/en-us/library/hh849692.aspx diff --git a/debian/changelog b/debian/changelog index c522535..c1707f5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +nivlheim (2.7.26-1) buster; urgency=low + + * Fixed a bug when clients post files from a IPv6 address + + -- Marius Pedersen <57487101+mapemapemape@users.noreply.github.com> + nivlheim (2.7.25-1) buster; urgency=low * Changes in the server code (cgi scripts rewritten in Go) diff --git a/server/service/postArchive.go b/server/service/postArchive.go index 6198302..440eeed 100644 --- a/server/service/postArchive.go +++ b/server/service/postArchive.go @@ -26,7 +26,7 @@ type apiMethodPostArchive struct { const MAX_UPLOAD_SIZE = 1024 * 1024 * 10 func (vars *apiMethodPostArchive) ServeHTTP(w http.ResponseWriter, req *http.Request) { - ipAddr := strings.SplitN(req.Header.Get("X-Forwarded-For"), ":", 2)[0] // host:port + ipAddr := req.Header.Get("X-Forwarded-For") log.Printf("post from %s\n", ipAddr) contentType := req.Header.Get("Content-Type") From 0adf68ba261b95e530cb1693bc21e85512653459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Hagberg?= Date: Tue, 5 Nov 2024 13:08:42 +0100 Subject: [PATCH 2/4] Fix VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0c3a15b..112ebb3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.7.25 +2.7.26 From 17a02cbb0ce7529bed9bc78b30e99fa5da7b9a89 Mon Sep 17 00:00:00 2001 From: Marius Pedersen <57487101+mapemapemape@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:49:55 +0100 Subject: [PATCH 3/4] Fix a couple of bugs --- server/service/cert.go | 2 +- server/service/ping.go | 204 ++++++++++++++++++++--------------------- 2 files changed, 103 insertions(+), 103 deletions(-) diff --git a/server/service/cert.go b/server/service/cert.go index 577a76a..60d6cb8 100644 --- a/server/service/cert.go +++ b/server/service/cert.go @@ -45,7 +45,7 @@ type generalNames struct { } func (vars *apiMethodReqCert) ServeHTTP(w http.ResponseWriter, req *http.Request) { - ipAddr := strings.SplitN(req.Header.Get("X-Forwarded-For"), ":", 2)[0] // host:port + ipAddr := req.Header.Get("X-Forwarded-For") log.Printf("Request for new certificate from %s", ipAddr) trustedByCFE := false diff --git a/server/service/ping.go b/server/service/ping.go index 6f19550..dd4283f 100644 --- a/server/service/ping.go +++ b/server/service/ping.go @@ -1,115 +1,115 @@ package main import ( - "database/sql" - "log" - "net/http" - "strconv" - "regexp" - "os" + "database/sql" + "log" + "net/http" + "os" + "regexp" + "strconv" ) type apiMethodSecurePing struct { - db *sql.DB + db *sql.DB } func apiPing(w http.ResponseWriter, req *http.Request) { - w.Header().Set("Content-Type", "text/plain") - w.Write([]byte("pong")) + w.Header().Set("Content-Type", "text/plain") + w.Write([]byte("pong")) } func (vars *apiMethodSecurePing) ServeHTTP(w http.ResponseWriter, req *http.Request) { - var err error - var left int64 - - // If the client cert will expire soon, politely ask it to renew - left, err = strconv.ParseInt(req.Header.Get("Cert-Client-V-Remain"), 10, 64) - if err != nil { - http.Error(w, "Unable to get certificate time remaining", http.StatusInternalServerError) - return - } - if (left < 30) { - http.Error(w, "Your certificate is about to expire, please renew it.", http.StatusBadRequest) - return - } - - // If the client cert was signed by a different CA than the one that's currently active, - // politely ask it to renew - cIssuer := req.Header.Get("Cert-Client-I-DN") - ca, err := os.ReadFile("/var/www/nivlheim/CA/nivlheimca.crt") - if err != nil { - log.Println(err.Error()) - http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) - return - } - - cacert := getCert(ca) - if cacert == nil { - http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) - return - } - caIssuer := cacert.Subject.ToRDNSequence() - - if cIssuer != caIssuer.String() { - http.Error(w, "The server has a new CA certificate, please renew your certificate.", http.StatusBadRequest) - return - } - - // Compute the client cert fingerprint - pemContent := req.Header.Get("Cert-Client-Cert") - - // pem.Decode needs the header and footer to be on their own lines - match := regexp.MustCompile("(?s)(-{5}BEGIN CERTIFICATE-{5})(.*)(-{5}END CERTIFICATE-{5})") - pemContent2 := match.ReplaceAll([]byte(pemContent), []byte("$1\n$2\n$3")) - - cert := getCert(pemContent2) - if cert == nil { - http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) - return - } - - fingerprint := getCertFPString(cert) - - // Check revoked status - var revoked bool - err = vars.db.QueryRow("SELECT revoked FROM certificates WHERE fingerprint=$1", fingerprint).Scan(&revoked) - if err != nil { - if err == sql.ErrNoRows { - log.Printf("Could not find certificate in database when checking revocation status. Fingerprint: %s", fingerprint) - http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) - return - } else { - log.Println(err.Error()) - http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) - return - } - } - if revoked { - http.Error(w, "Your certificate has been revoked.", http.StatusForbidden) - return - } - - // Check if the machine has been renamed (compare commonname with the current hostname) - dn := req.Header.Get("Cert-Client-S-DN") - match = regexp.MustCompile("CN=(.*?),.*$") - cn := match.ReplaceAll([]byte(dn), []byte("$1")) - var hostname string - - err = vars.db.QueryRow("SELECT hostname FROM hostinfo WHERE certfp=$1", fingerprint).Scan(&hostname) - if err != nil { - if err == sql.ErrNoRows { - log.Printf("Could not find certificate in database when checking hostname. Fingerprint: %s", fingerprint) - } else { - log.Println(err.Error()) - http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) - return - } - } - if len(hostname) > 0 && hostname != string(cn) { - http.Error(w, "Please renew your certificate.", http.StatusForbidden) - return - } - - w.Header().Set("Content-Type", "text/plain") - w.Write([]byte("pong")) + var err error + var left int64 + + // If the client cert will expire soon, politely ask it to renew + left, err = strconv.ParseInt(req.Header.Get("Cert-Client-V-Remain"), 10, 64) + if err != nil { + http.Error(w, "Unable to get certificate time remaining", http.StatusInternalServerError) + return + } + if left < 30 { + http.Error(w, "Your certificate is about to expire, please renew it.", http.StatusBadRequest) + return + } + + // If the client cert was signed by a different CA than the one that's currently active, + // politely ask it to renew + cIssuer := req.Header.Get("Cert-Client-I-DN") + ca, err := os.ReadFile("/var/www/nivlheim/CA/nivlheimca.crt") + if err != nil { + log.Println(err.Error()) + http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) + return + } + + cacert := getCert(ca) + if cacert == nil { + http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) + return + } + caIssuer := cacert.Subject.ToRDNSequence() + + if cIssuer != caIssuer.String() { + http.Error(w, "The server has a new CA certificate, please renew your certificate.", http.StatusBadRequest) + return + } + + // Compute the client cert fingerprint + pemContent := req.Header.Get("Cert-Client-Cert") + + // pem.Decode needs the header and footer to be on their own lines + match := regexp.MustCompile("(?s)(-{5}BEGIN CERTIFICATE-{5})(.*)(-{5}END CERTIFICATE-{5})") + pemContent2 := match.ReplaceAll([]byte(pemContent), []byte("$1\n$2\n$3")) + + cert := getCert(pemContent2) + if cert == nil { + http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) + return + } + + fingerprint := getCertFPString(cert) + + // Check revoked status + var revoked bool + err = vars.db.QueryRow("SELECT revoked FROM certificates WHERE fingerprint=$1", fingerprint).Scan(&revoked) + if err != nil { + if err == sql.ErrNoRows { + log.Printf("Could not find certificate in database when checking revocation status. Fingerprint: %s", fingerprint) + http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) + return + } else { + log.Println(err.Error()) + http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) + return + } + } + if revoked { + http.Error(w, "Your certificate has been revoked.", http.StatusForbidden) + return + } + + // Check if the machine has been renamed (compare commonname with the current hostname) + dn := req.Header.Get("Cert-Client-S-DN") + match = regexp.MustCompile("CN=(.*?),.*$") + cn := match.ReplaceAll([]byte(dn), []byte("$1")) + var hostname sql.NullString + + err = vars.db.QueryRow("SELECT hostname FROM hostinfo WHERE certfp=$1", fingerprint).Scan(&hostname) + if err != nil { + if err == sql.ErrNoRows { + log.Printf("Could not find certificate in database when checking hostname. Fingerprint: %s", fingerprint) + } else { + log.Println(err.Error()) + http.Error(w, "The server encountered an error. Please try again later.", http.StatusInternalServerError) + return + } + } + if len(hostname.String) > 0 && hostname.String != string(cn) { + http.Error(w, "Please renew your certificate.", http.StatusForbidden) + return + } + + w.Header().Set("Content-Type", "text/plain") + w.Write([]byte("pong")) } From 06bebefd1708fd381a31d89f8f70f6976affc147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Hagberg?= Date: Thu, 7 Nov 2024 17:18:17 +0100 Subject: [PATCH 4/4] Move to Alpine to fix the strange httpd error This commit does the following: - Use Alpine 3.18 as a base for building container images - Modify the Apache config files to match what comes with Alpine - The PID file is now in /var/run/apache2 - Remove deprecated statements from docker-compose.yml and Dockerfile(s) - Had to make a small change to cert.go. Don't know why. Worked before? --- ci/docker/Dockerfile | 22 ++-- ci/docker/api_Dockerfile | 9 +- ci/docker/docker-compose.yml | 1 - server/client_CA_cert.sh | 4 +- server/entrypoint.sh | 2 +- server/httpd.conf | 216 ++++++++++++++++++++++++++++------- server/httpd_ssl.conf | 5 + server/service/cert.go | 17 ++- 8 files changed, 210 insertions(+), 66 deletions(-) diff --git a/ci/docker/Dockerfile b/ci/docker/Dockerfile index 603f9e4..4eddbe2 100644 --- a/ci/docker/Dockerfile +++ b/ci/docker/Dockerfile @@ -1,21 +1,23 @@ -FROM fedora:latest +FROM alpine:3.18 EXPOSE 80 443 -LABEL no.uio.contact=usit-gid@usit.uio.no +LABEL no.uio.contact=usit-dia@usit.uio.no LABEL description="Web server for Nivlheim" ARG BRANCH="" -RUN dnf install -y httpd mod_ssl procps-ng \ - unzip file bind-utils npm \ - && dnf install -y --releasever=39 openssl \ - && dnf clean all \ - && rm -rf /var/cache/yum \ - && npm install -g handlebars +RUN apk update && apk upgrade \ + && apk add apache2 apache2-ssl apache2-utils apache2-proxy procps-ng unzip file bind-tools npm bash curl \ + && apk add openssl1.1-compat && rm /usr/bin/openssl && ln /usr/bin/openssl1.1 /usr/bin/openssl \ + && rm -rf /var/cache/apk/* +RUN npm install -g handlebars # config COPY server/openssl_ca.conf /etc/nivlheim/ COPY server/client_CA_cert.sh /usr/bin/ -COPY server/httpd_ssl.conf /etc/httpd/conf.d/ssl.conf -COPY server/httpd.conf /etc/httpd/conf/httpd.conf +COPY server/httpd_ssl.conf /etc/apache2/conf.d/ssl.conf +COPY server/httpd.conf /etc/apache2/httpd.conf + +# before moving to Alping we used this log directory so let's continue with that +RUN mkdir /var/log/httpd # copy the static web content COPY server/website /var/www/html/ diff --git a/ci/docker/api_Dockerfile b/ci/docker/api_Dockerfile index fdafe38..c453358 100644 --- a/ci/docker/api_Dockerfile +++ b/ci/docker/api_Dockerfile @@ -11,19 +11,18 @@ COPY server/service/*.go ./ COPY server/service/database ./database COPY server/service/utility ./utility -RUN go build -o /nivlheim -ldflags "-X main.version=${version:-UNDEFINED}" +RUN CGO_ENABLED=0 go build -o /nivlheim -ldflags "-X main.version=${version:-UNDEFINED}" ## Deploy -FROM ubuntu:latest -MAINTAINER iti-dia@usit.uio.no -LABEL no.uio.contact=usit-gid@usit.uio.no +FROM alpine:3.18 +LABEL no.uio.contact=usit-dia@usit.uio.no LABEL description="Main Nivlheim server exposing API" EXPOSE 4040 WORKDIR / -RUN apt-get update -qq && apt-get install -yqq ca-certificates +RUN apk --no-cache add ca-certificates COPY --from=build /nivlheim /nivlheim COPY server/server.conf /etc/nivlheim/server.conf diff --git a/ci/docker/docker-compose.yml b/ci/docker/docker-compose.yml index 0f77d36..6a6ed7d 100644 --- a/ci/docker/docker-compose.yml +++ b/ci/docker/docker-compose.yml @@ -1,4 +1,3 @@ -version: "3.9" services: nivlheimweb: container_name: docker-nivlheimweb-1 diff --git a/server/client_CA_cert.sh b/server/client_CA_cert.sh index 58b32d0..769b0a5 100755 --- a/server/client_CA_cert.sh +++ b/server/client_CA_cert.sh @@ -97,8 +97,8 @@ if [[ $ACTIVATE -eq 1 ]]; then mv new_nivlheimca.csr nivlheimca.csr mv new_nivlheimca.crt nivlheimca.crt # signal httpd to gracefully restart, if it is running - if [[ -f /var/run/httpd/httpd.pid ]]; then - kill -usr1 `cat /var/run/httpd/httpd.pid` + if [[ -f /var/run/apache2/httpd.pid ]]; then + kill -usr1 `cat /var/run/apache2/httpd.pid` fi else echo "There's no new CA certificate to activate" diff --git a/server/entrypoint.sh b/server/entrypoint.sh index a822cac..9c16269 100755 --- a/server/entrypoint.sh +++ b/server/entrypoint.sh @@ -56,7 +56,7 @@ fi function sigterm() { echo "Received SIGTERM" - kill -term `cat /var/run/httpd/httpd.pid` + kill -term `cat /var/run/apache2/httpd.pid` } trap sigterm SIGTERM diff --git a/server/httpd.conf b/server/httpd.conf index 785dac5..edbdfbe 100644 --- a/server/httpd.conf +++ b/server/httpd.conf @@ -6,9 +6,6 @@ # # for a discussion of each configuration directive. # -# See the httpd.conf(5) man page for more information on this configuration, -# and httpd.service(8) on using and configuring the httpd service. -# # Do NOT simply read the instructions in here without understanding # what they do. They're here only as hints or reminders. If you are unsure # consult the online docs. You have been warned. @@ -16,10 +13,20 @@ # Configuration and logfile names: If the filenames you specify for many # of the server's control files begin with "/" (or "drive:/" for Win32), the # server will use that explicit path. If the filenames do *not* begin -# with "/", the value of ServerRoot is prepended -- so 'log/access_log' -# with ServerRoot set to '/www' will be interpreted by the -# server as '/www/log/access_log', where as '/log/access_log' will be -# interpreted as '/log/access_log'. +# with "/", the value of ServerRoot is prepended -- so "logs/access_log" +# with ServerRoot set to "/usr/local/apache2" will be interpreted by the +# server as "/usr/local/apache2/logs/access_log", whereas "/logs/access_log" +# will be interpreted as '/logs/access_log'. + +# +# ServerTokens +# This directive configures what you return as the Server HTTP response +# Header. The default is 'Full' which sends information about the OS-Type +# and compiled in modules. +# Set to one of: Full | OS | Minor | Minimal | Major | Prod +# where Full conveys the most information, and Prod the least. +# +ServerTokens OS # # ServerRoot: The top of the directory tree under which the server's @@ -31,17 +38,25 @@ # same ServerRoot for multiple httpd daemons, you will need to change at # least PidFile. # -ServerRoot "/etc/httpd" +ServerRoot /var/www + +# +# Mutex: Allows you to set the mutex mechanism and mutex file directory +# for individual mutexes, or change the global defaults +# +# Uncomment and change the directory if mutexes are file-based and the default +# mutex file directory is not on a local disk or is not appropriate for some +# other reason. +# +# Mutex default:/run/apache2 # # Listen: Allows you to bind Apache to specific IP addresses and/or # ports, instead of the default. See also the # directive. # -# Change this to Listen on a specific IP address, but note that if -# httpd.service is enabled to run at boot time, the address may not be -# available when the service starts. See the httpd.service(8) man -# page for more information. +# Change this to Listen on specific IP addresses as shown below to +# prevent Apache from glomming onto all bound IP addresses. # #Listen 12.34.56.78:80 Listen 8080 @@ -58,8 +73,102 @@ Listen 8080 # Example: # LoadModule foo_module modules/mod_foo.so # -Include conf.modules.d/*.conf +#LoadModule mpm_event_module modules/mod_mpm_event.so +LoadModule mpm_prefork_module modules/mod_mpm_prefork.so +#LoadModule mpm_worker_module modules/mod_mpm_worker.so +LoadModule authn_file_module modules/mod_authn_file.so +#LoadModule authn_dbm_module modules/mod_authn_dbm.so +#LoadModule authn_anon_module modules/mod_authn_anon.so +#LoadModule authn_dbd_module modules/mod_authn_dbd.so +#LoadModule authn_socache_module modules/mod_authn_socache.so +LoadModule authn_core_module modules/mod_authn_core.so +LoadModule authz_host_module modules/mod_authz_host.so +LoadModule authz_groupfile_module modules/mod_authz_groupfile.so +LoadModule authz_user_module modules/mod_authz_user.so +#LoadModule authz_dbm_module modules/mod_authz_dbm.so +#LoadModule authz_owner_module modules/mod_authz_owner.so +#LoadModule authz_dbd_module modules/mod_authz_dbd.so +LoadModule authz_core_module modules/mod_authz_core.so +LoadModule access_compat_module modules/mod_access_compat.so +LoadModule auth_basic_module modules/mod_auth_basic.so +#LoadModule auth_form_module modules/mod_auth_form.so +#LoadModule auth_digest_module modules/mod_auth_digest.so +#LoadModule allowmethods_module modules/mod_allowmethods.so +#LoadModule file_cache_module modules/mod_file_cache.so +#LoadModule cache_module modules/mod_cache.so +#LoadModule cache_disk_module modules/mod_cache_disk.so +#LoadModule cache_socache_module modules/mod_cache_socache.so +#LoadModule socache_shmcb_module modules/mod_socache_shmcb.so +#LoadModule socache_dbm_module modules/mod_socache_dbm.so +#LoadModule socache_memcache_module modules/mod_socache_memcache.so +#LoadModule socache_redis_module modules/mod_socache_redis.so +#LoadModule watchdog_module modules/mod_watchdog.so +#LoadModule macro_module modules/mod_macro.so +#LoadModule dbd_module modules/mod_dbd.so +#LoadModule dumpio_module modules/mod_dumpio.so +#LoadModule echo_module modules/mod_echo.so +#LoadModule buffer_module modules/mod_buffer.so +#LoadModule data_module modules/mod_data.so +#LoadModule ratelimit_module modules/mod_ratelimit.so +LoadModule reqtimeout_module modules/mod_reqtimeout.so +#LoadModule ext_filter_module modules/mod_ext_filter.so +#LoadModule request_module modules/mod_request.so +#LoadModule include_module modules/mod_include.so +LoadModule filter_module modules/mod_filter.so +#LoadModule reflector_module modules/mod_reflector.so +#LoadModule substitute_module modules/mod_substitute.so +#LoadModule sed_module modules/mod_sed.so +#LoadModule charset_lite_module modules/mod_charset_lite.so +#LoadModule deflate_module modules/mod_deflate.so +#LoadModule brotli_module modules/mod_brotli.so +LoadModule mime_module modules/mod_mime.so +LoadModule log_config_module modules/mod_log_config.so +#LoadModule log_debug_module modules/mod_log_debug.so +#LoadModule log_forensic_module modules/mod_log_forensic.so +#LoadModule logio_module modules/mod_logio.so +LoadModule env_module modules/mod_env.so +#LoadModule mime_magic_module modules/mod_mime_magic.so +#LoadModule expires_module modules/mod_expires.so +LoadModule headers_module modules/mod_headers.so +#LoadModule usertrack_module modules/mod_usertrack.so +#LoadModule unique_id_module modules/mod_unique_id.so +LoadModule setenvif_module modules/mod_setenvif.so +LoadModule version_module modules/mod_version.so +#LoadModule remoteip_module modules/mod_remoteip.so +#LoadModule session_module modules/mod_session.so +#LoadModule session_cookie_module modules/mod_session_cookie.so +#LoadModule session_crypto_module modules/mod_session_crypto.so +#LoadModule session_dbd_module modules/mod_session_dbd.so +#LoadModule slotmem_shm_module modules/mod_slotmem_shm.so +#LoadModule slotmem_plain_module modules/mod_slotmem_plain.so +#LoadModule dialup_module modules/mod_dialup.so +#LoadModule http2_module modules/mod_http2.so +LoadModule unixd_module modules/mod_unixd.so +#LoadModule heartbeat_module modules/mod_heartbeat.so +#LoadModule heartmonitor_module modules/mod_heartmonitor.so +LoadModule status_module modules/mod_status.so +LoadModule autoindex_module modules/mod_autoindex.so +#LoadModule asis_module modules/mod_asis.so +#LoadModule info_module modules/mod_info.so +#LoadModule suexec_module modules/mod_suexec.so + + #LoadModule cgid_module modules/mod_cgid.so + + + #LoadModule cgi_module modules/mod_cgi.so + +#LoadModule vhost_alias_module modules/mod_vhost_alias.so +#LoadModule negotiation_module modules/mod_negotiation.so +LoadModule dir_module modules/mod_dir.so +#LoadModule actions_module modules/mod_actions.so +#LoadModule speling_module modules/mod_speling.so +#LoadModule userdir_module modules/mod_userdir.so +LoadModule alias_module modules/mod_alias.so +#LoadModule rewrite_module modules/mod_rewrite.so + +LoadModule negotiation_module modules/mod_negotiation.so + # # If you wish httpd to run as a different user or group, you must run # httpd as root initially and it will switch. @@ -71,6 +180,8 @@ Include conf.modules.d/*.conf User apache Group apache + + # 'Main' server configuration # # The directives in this section set up the values used by the 'main' @@ -101,6 +212,16 @@ TraceEnable off # ServerAdmin root@localhost +# +# Optionally add a line containing the server version and virtual host +# name to server-generated pages (internal error documents, FTP directory +# listings, mod_status and mod_info output etc., but not CGI generated +# documents or custom error documents). +# Set to "EMail" to also include a mailto: link to the ServerAdmin. +# Set to one of: On | Off | EMail +# +ServerSignature On + # # ServerName gives the name and port that the server uses to identify itself. # This can often be determined automatically, but we recommend you specify @@ -132,19 +253,8 @@ ServerAdmin root@localhost # documents. By default, all requests are taken from this directory, but # symbolic links and aliases may be used to point to other locations. # -DocumentRoot "/var/www/html" - -# -# Relax access to content within /var/www. -# - - AllowOverride None - # Allow open access: - Require all granted - - -# Further relax access to the default document root: - +DocumentRoot "/var/www/localhost/htdocs" + # # Possible values for the Options directive are "None", "All", # or any combination of: @@ -162,7 +272,7 @@ DocumentRoot "/var/www/html" # # AllowOverride controls what directives may be placed in .htaccess files. # It can be "All", "None", or any combination of the keywords: - # Options FileInfo AuthConfig Limit + # AllowOverride FileInfo AuthConfig Limit # AllowOverride None @@ -224,7 +334,7 @@ LogLevel warn # define per- access logfiles, transactions will be # logged therein and *not* in this file. # - #CustomLog "logs/access_log" common + #CustomLog logs/access.log common # # If you prefer a logfile with access, agent, and referer information @@ -260,26 +370,43 @@ LogLevel warn # client. The same rules about trailing "/" apply to ScriptAlias # directives as to Alias. # - ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" + ScriptAlias /cgi-bin/ "/var/www/localhost/cgi-bin/" + + # + # ScriptSock: On threaded servers, designate the path to the UNIX + # socket used to communicate with the CGI daemon of mod_cgid. + # + #Scriptsock cgisock + + # -# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased +# "/var/www/localhost/cgi-bin" should be changed to whatever your ScriptAliased # CGI directory exists, if you have that configured. # - + AllowOverride None Options None Require all granted + + # + # Avoid passing HTTP_PROXY environment to CGI's on this or any proxied + # backend servers which have lingering "httpoxy" defects. + # 'Proxy' request header is undefined by the IETF, not listed by IANA + # + RequestHeader unset Proxy early + + # # TypesConfig points to the file containing the list of mappings from # filename extension to MIME-type. # - TypesConfig /etc/mime.types + TypesConfig /etc/apache2/mime.types # # AddType allows you to add to or override the MIME configuration @@ -318,8 +445,8 @@ LogLevel warn # To parse .shtml files for server-side includes (SSI): # (You will also need to add "Includes" to the "Options" directive.) # - AddType text/html .shtml - AddOutputFilter INCLUDES .shtml + #AddType text/html .shtml + #AddOutputFilter INCLUDES .shtml # @@ -331,13 +458,14 @@ LogLevel warn # AddDefaultCharset UTF-8 - + # # The mod_mime_magic module allows the server to use various hints from the # contents of the file itself to determine its type. The MIMEMagicFile # directive tells the module where the hint definitions are located. # - MIMEMagicFile conf/magic + + MIMEMagicFile /etc/apache2/magic # @@ -351,6 +479,13 @@ AddDefaultCharset UTF-8 #ErrorDocument 402 http://www.example.com/subscription_info.html # +# +# MaxRanges: Maximum number of Ranges in a request before +# returning the entire resource, or one of the special +# values 'default', 'none' or 'unlimited'. +# Default setting is to accept 200 Ranges. +#MaxRanges unlimited + # # EnableMMAP and EnableSendfile: On systems that support it, # memory-mapping or the sendfile syscall may be used to deliver @@ -358,12 +493,11 @@ AddDefaultCharset UTF-8 # be turned off when serving from networked-mounted # filesystems or if support for these functions is otherwise # broken on your system. -# Defaults if commented: EnableMMAP On, EnableSendfile Off +# Defaults: EnableMMAP On, EnableSendfile Off # #EnableMMAP off -EnableSendfile on +#EnableSendfile on -# Supplemental configuration +# Load config files from the config directory "/etc/apache2/conf.d". # -# Load config files in the "/etc/httpd/conf.d" directory, if any. -IncludeOptional conf.d/*.conf +IncludeOptional /etc/apache2/conf.d/*.conf diff --git a/server/httpd_ssl.conf b/server/httpd_ssl.conf index 2d7ccb3..15744b6 100644 --- a/server/httpd_ssl.conf +++ b/server/httpd_ssl.conf @@ -1,3 +1,8 @@ +LoadModule ssl_module modules/mod_ssl.so +LoadModule socache_shmcb_module modules/mod_socache_shmcb.so +SSLRandomSeed startup file:/dev/urandom 512 +SSLRandomSeed connect builtin + # Listen to the standard HTTPS port Listen 443 https diff --git a/server/service/cert.go b/server/service/cert.go index 60d6cb8..a8beb4c 100644 --- a/server/service/cert.go +++ b/server/service/cert.go @@ -184,7 +184,7 @@ func (vars *apiMethodReqCert) ServeHTTP(w http.ResponseWriter, req *http.Request caCRT := getCACRT(config.ConfDir + "/" + config.CACertFile) caKey, err := getCAKey(config.ConfDir + "/" + config.CAKeyFile) if err != nil { - log.Println("Failed to get CA key") + log.Printf("Failed to get CA key: %s", err.Error()) http.Error(w, "Failed to get CA key", http.StatusInternalServerError) return } @@ -197,7 +197,7 @@ func (vars *apiMethodReqCert) ServeHTTP(w http.ResponseWriter, req *http.Request } clientDER, err := x509.ParseCertificate(clientCRT) if err != nil { - log.Println("Failed to parse client certificate") + log.Printf("Failed to parse client certificate: %s", err.Error()) http.Error(w, "Failed to parse client certificate", http.StatusInternalServerError) return } @@ -311,7 +311,7 @@ func (vars *apiMethodRenewCert) ServeHTTP(w http.ResponseWriter, req *http.Reque caCRT := getCACRT(config.ConfDir + "/" + config.CACertFile) caKey, err := getCAKey(config.ConfDir + "/" + config.CAKeyFile) if err != nil { - log.Println("Failed to get CA key") + log.Printf("Failed to get CA key: %s", err.Error()) http.Error(w, "Failed to get CA key", http.StatusInternalServerError) return } @@ -323,7 +323,7 @@ func (vars *apiMethodRenewCert) ServeHTTP(w http.ResponseWriter, req *http.Reque } clientDER, err := x509.ParseCertificate(clientCRT) if err != nil { - log.Println("Failed to parse client certificate") + log.Printf("Failed to parse client certificate: %s", err.Error()) http.Error(w, "Failed to parse client certificate", http.StatusInternalServerError) return } @@ -506,11 +506,16 @@ func getCAKey(fileName string) (*rsa.PrivateKey, error) { func getKey(key []byte) (*rsa.PrivateKey, error) { block, _ := pem.Decode(key) if block == nil { - fmt.Println("failed to decode key") + return nil, errors.New("failed to decode key") } parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { - fmt.Println("failed to parse key") + // Try another method + parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + fmt.Println("failed to parse key") + return nil, err + } } return parsedKey.(*rsa.PrivateKey), nil }