Skip to content

Commit

Permalink
Add HTTPS support to Varnish cache using Hitch (#7725)
Browse files Browse the repository at this point in the history
* Add Hitch config and include Hitch in CIAB

* Add license
  • Loading branch information
AbdelrahmanElawady committed Sep 5, 2023
1 parent 618ddf6 commit c571cf3
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 24 deletions.
19 changes: 19 additions & 0 deletions cache-config/t3c-apply/t3c-apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,25 @@ func Main() int {
}
}

if trops.HitchReload {
svcStatus, _, err := util.GetServiceStatus("hitch")
cmd := "start"
running := false
if err != nil {
log.Errorf("not starting 'hitch', error getting 'hitch' run status: %s\n", err)
} else if svcStatus != util.SvcNotRunning {
cmd = "reload"
}
running, err = util.ServiceStart("hitch", cmd)
if err != nil {
log.Errorf("'hitch' was not %sed: %s\n", cmd, err)
} else if running {
log.Infof("service 'hitch' %sed", cmd)
} else {
log.Infoln("service 'hitch' already running")
}
}

// reload sysctl
if trops.SysCtlReload == true {
runSysctl(cfg)
Expand Down
4 changes: 4 additions & 0 deletions cache-config/t3c-apply/torequest/torequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ type RestartData struct {
TeakdRestart bool // a restart of teakd is required
TrafficServerRestart bool // a trafficserver restart is required
RemapConfigReload bool // remap.config should be reloaded
HitchReload bool // hitch should be reloaded
}

type ConfigFile struct {
Expand Down Expand Up @@ -520,6 +521,7 @@ func (r *TrafficOpsReq) replaceCfgFile(cfg *ConfigFile) (*FileRestartData, error
trafficServerRestart := cfg.Name == "plugin.config"
ntpdRestart := cfg.Name == "ntpd.conf"
sysCtlReload := cfg.Name == "sysctl.conf"
hitchReload := cfg.Name == "hitch.conf"

log.Debugf("Reload state after %s: remap.config: %t reload: %t restart: %t ntpd: %t sysctl: %t", cfg.Name, remapConfigReload, trafficCtlReload, trafficServerRestart, ntpdRestart, sysCtlReload)

Expand All @@ -532,6 +534,7 @@ func (r *TrafficOpsReq) replaceCfgFile(cfg *ConfigFile) (*FileRestartData, error
NtpdRestart: ntpdRestart,
TrafficServerRestart: trafficServerRestart,
RemapConfigReload: remapConfigReload,
HitchReload: hitchReload,
},
}, nil
}
Expand Down Expand Up @@ -810,6 +813,7 @@ func (r *TrafficOpsReq) CheckReloadRestart(data []FileRestartData) RestartData {
rd.TeakdRestart = rd.TeakdRestart || changedFile.TeakdRestart
rd.TrafficServerRestart = rd.TrafficServerRestart || changedFile.TrafficServerRestart
rd.RemapConfigReload = rd.RemapConfigReload || changedFile.RemapConfigReload
rd.HitchReload = rd.HitchReload || changedFile.HitchReload
}
return rd
}
Expand Down
29 changes: 28 additions & 1 deletion cache-config/t3c-generate/cfgfile/varnish.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ package cfgfile
*/

import (
"errors"
"path/filepath"

"github.com/apache/trafficcontrol/cache-config/t3c-generate/config"
"github.com/apache/trafficcontrol/cache-config/t3cutil"
"github.com/apache/trafficcontrol/lib/varnishcfg"
Expand All @@ -42,5 +45,29 @@ func GetVarnishConfigs(toData *t3cutil.ConfigData, cfg config.Cfg) ([]t3cutil.AT
LineComment: "//",
Secure: false,
})
return configs, err
txt, hitchWarnings := varnishcfg.GetHitchConfig(toData.DeliveryServices, filepath.Join(cfg.Dir, "ssl/"))
warnings = append(warnings, hitchWarnings...)
logWarnings("Generating hitch configuration files: ", hitchWarnings)

configs = append(configs, t3cutil.ATSConfigFile{
Name: "hitch.conf",
Text: txt,
Path: cfg.Dir,
ContentType: "text/plain; charset=us-ascii",
LineComment: "//",
Secure: false,
})

sslConfigs, err := GetSSLCertsAndKeyFiles(toData)
if err != nil {
return nil, errors.New("getting ssl key and cert config files: " + err.Error())
}
for i := range sslConfigs {
// path changed manually because GetSSLCertsAndKeyFiles hardcodes the directory certs and keys are written to.
// will be removed once GetSSLCertsAndKeyFiles uses proxy.config.ssl.server.cert.path parameter.
sslConfigs[i].Path = filepath.Join(cfg.Dir, "ssl/")
}
configs = append(configs, sslConfigs...)

return configs, nil
}
2 changes: 2 additions & 0 deletions infrastructure/cdn-in-a-box/varnish/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ RUN curl -s https://packagecloud.io/install/repositories/varnishcache/varnish73/

RUN yum install varnish-7.3.0 -y

RUN yum install -y hitch-1.5.2

RUN dnf install -y bind-utils kyotocabinet-libs initscripts iproute net-tools nmap-ncat gettext autoconf automake libtool gcc-c++ cronie glibc-devel openssl-devel git perl && \
dnf install -y jq logrotate findutils && \
dnf clean all
Expand Down
109 changes: 86 additions & 23 deletions infrastructure/cdn-in-a-box/varnish/systemctl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# under the License.

VARNISHD_EXECUTABLE="/usr/sbin/varnishd"
HITCH_EXECUTABLE="/usr/sbin/hitch"

is_varnishd_running() {
pgrep -x "$(basename "$VARNISHD_EXECUTABLE")" >/dev/null
Expand All @@ -28,7 +29,7 @@ start_varnishd() {
echo "varnishd is already running."
else
echo "Starting varnishd..."
"$VARNISHD_EXECUTABLE" -f /opt/cache/etc/varnish/default.vcl
"$VARNISHD_EXECUTABLE" -f /opt/cache/etc/varnish/default.vcl -a :80 -a :6081,PROXY
echo "varnishd is now running."
fi
}
Expand Down Expand Up @@ -67,28 +68,90 @@ restart_varnishd() {
start_varnishd
}

case "$1" in
enable)
exit 0
;;
start)
start_varnishd
;;
stop)
stop_varnishd
;;
restart)
restart_varnishd
;;
status)
if is_varnishd_running; then
exit 0
fi
exit 3
;;
*)
echo "Usage: $0 {start|stop|restart|enable|status}"
is_hitch_running() {
pgrep -x "$(basename "$HITCH_EXECUTABLE")" >/dev/null
}


start_hitch() {
if is_hitch_running; then
echo "hitch is already running."
else
echo "Starting hitch..."
"$HITCH_EXECUTABLE" --config /opt/cache/etc/varnish/hitch.conf --daemon
echo "hitch is now running."
fi

}

reload_hitch() {
if is_hitch_running; then
pkill -HUP "$(basename "$HITCH_EXECUTABLE")"
else
echo "hitch is not running"
exit 1
esac
fi
}

handle_varnish_service() {
case "$1" in
enable)
exit 0
;;
start)
start_varnishd
;;
stop)
stop_varnishd
;;
restart)
restart_varnishd
;;
status)
if is_varnishd_running; then
# t3c-apply looks for this specific string
echo "Active: active"
exit 0
fi
exit 3
;;
*)
echo "Usage: $0 {start|stop|restart|enable|status}"
exit 1
esac
}

handle_hitch_service() {
case "$1" in
enable)
exit 0
;;
start)
start_hitch
;;
reload)
reload_hitch
;;
status)
if is_hitch_running; then
# t3c-apply looks for this specific string
echo "Active: active"
exit 0
fi
exit 3
;;
*)
echo "Usage: $0 {start|stop|restart|reload|enable|status}"
exit 1
esac
}

if [[ $2 == "varnish.service" ]]
then
handle_varnish_service $1
elif [[ $2 == "hitch.service" ]]
then
handle_hitch_service $1
fi

exit 0
61 changes: 61 additions & 0 deletions lib/varnishcfg/hitch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package varnishcfg

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import (
"path/filepath"
"strings"

"github.com/apache/trafficcontrol/lib/go-atscfg"
)

// GetHitchConfig returns Hitch config using TO data
func GetHitchConfig(deliveryServices []atscfg.DeliveryService, sslDir string) (string, []string) {
warnings := make([]string, 0)
lines := []string{
`frontend = {`,
` host = "*"`,
` port = "443"`,
`}`,
`backend = "[127.0.0.1]:6081"`,
`write-proxy-v2 = on`,
// TODO: change root user
`user = "root"`,
}

dses, dsWarns := atscfg.DeliveryServicesToSSLMultiCertDSes(deliveryServices)
warnings = append(warnings, dsWarns...)

dses = atscfg.GetSSLMultiCertDotConfigDeliveryServices(dses)

for dsName, ds := range dses {
cerName, keyName := atscfg.GetSSLMultiCertDotConfigCertAndKeyName(dsName, ds)
lines = append(lines, []string{
`pem-file = {`,
` cert = "` + filepath.Join(sslDir, cerName) + `"`,
` private-key = "` + filepath.Join(sslDir, keyName) + `"`,
`}`,
}...)
}

txt := strings.Join(lines, "\n")
txt += "\n"
return txt, warnings
}
60 changes: 60 additions & 0 deletions lib/varnishcfg/hitch_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package varnishcfg

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import (
"strings"
"testing"

"github.com/apache/trafficcontrol/lib/go-atscfg"
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/lib/go-util"
)

func TestGetHitchConfig(t *testing.T) {
ds1 := &atscfg.DeliveryService{}
ds1.XMLID = util.StrPtr("ds1")
ds1.Protocol = util.IntPtr(1)
ds1Type := tc.DSTypeHTTP
ds1.Type = &ds1Type
ds1.ExampleURLs = []string{"https://ds1.example.org"}
deliveryServices := []atscfg.DeliveryService{*ds1}
txt, warnings := GetHitchConfig(deliveryServices, "/ssl")
expectedTxt := strings.Join([]string{
`frontend = {`,
` host = "*"`,
` port = "443"`,
`}`,
`backend = "[127.0.0.1]:6081"`,
`write-proxy-v2 = on`,
`user = "root"`,
`pem-file = {`,
` cert = "/ssl/ds1_example_org_cert.cer"`,
` private-key = "/ssl/ds1.example.org.key"`,
`}`,
}, "\n")
expectedTxt += "\n"
if len(warnings) != 0 {
t.Errorf("expected no warnings got %v", warnings)
}
if txt != expectedTxt {
t.Errorf("expected: %s got: %s", expectedTxt, txt)
}
}

0 comments on commit c571cf3

Please sign in to comment.