diff --git a/Dockerfile.oonith b/Dockerfile.oonith new file mode 100644 index 0000000000..65d78dbef2 --- /dev/null +++ b/Dockerfile.oonith @@ -0,0 +1,27 @@ +# This dockerfile is used to build the oohelperd binary +# To make use of it, see the Makefile located inside of oonith/Makefile. +# +# Note: The Dockerfile needs to reside in the root of the repo, so that we can +# copy files into the docker build context. +FROM golang:1.20.12-bullseye as builder +ARG BRANCH_NAME=master + +WORKDIR /build + +COPY . . + +RUN go run ./internal/cmd/buildtool oohelperd build + +## Image running on the host +FROM golang:1.20.12-bullseye as runner + +WORKDIR /app + +COPY --from=builder /build/CLI/oohelperd-* /app +RUN mv oohelperd-* oohelperd + +# oohelperd service +EXPOSE 80 + +# Run +CMD ["/app/oohelperd", "-api-endpoint", "0.0.0.0:80"] diff --git a/internal/cmd/oohelperd/main.go b/internal/cmd/oohelperd/main.go index fdc225d62f..c62e15aa72 100644 --- a/internal/cmd/oohelperd/main.go +++ b/internal/cmd/oohelperd/main.go @@ -32,9 +32,6 @@ var ( // pprofEndpoint is the endpoint where we serve pprof info. pprofEndpoint = flag.String("pprof-endpoint", "127.0.0.1:6061", "Pprof endpoint") - // prometheusEndpoint is the endpoint where we serve prometheus metrics - prometheusEndpoint = flag.String("prometheus-endpoint", "127.0.0.1:9091", "Prometheus endpoint") - // replace runs the commands to replace a running oohelperd. replace = flag.Bool("replace", false, "Replaces a running oohelperd instance") @@ -49,6 +46,8 @@ var ( // versionFlag indicates we must print the version on stdout versionFlag = flag.Bool("version", false, "Prints version information on the stdout") + + prometheusMetricsPassword = os.Getenv("PROMETHEUS_METRICS_PASSWORD") ) // shutdown calls srv.Shutdown with a reasonably long timeout. The srv.Shutdown @@ -94,6 +93,16 @@ func main() { // add the main oohelperd handler to the mux mux.Handle("/", oohelperd.NewHandler(log.Log, &netxlite.Netx{})) + mux.HandleFunc("/metrics", func(w http.ResponseWriter, req *http.Request) { + user, pass, ok := req.BasicAuth() + if ok && user == "prom" && pass == prometheusMetricsPassword { + promhttp.Handler().ServeHTTP(w, req) + } else { + w.Header().Set("WWW-Authenticate", "Basic realm=metrics") + w.WriteHeader(401) + w.Write([]byte("401 Unauthorized\n")) + } + }) // create a listening server for serving ooniprobe requests srv := &http.Server{Addr: *apiEndpoint, Handler: mux} @@ -108,13 +117,6 @@ func main() { go srv.Serve(listener) log.Infof("serving ooniprobe requests at http://%s/", listener.Addr().String()) - // create another server for serving prometheus metrics - promMux := http.NewServeMux() - promMux.Handle("/metrics", promhttp.Handler()) - promSrv := &http.Server{Addr: *prometheusEndpoint, Handler: promMux} - go promSrv.ListenAndServe() - log.Infof("serving prometheus metrics at http://%s/", *prometheusEndpoint) - // create another server for serving pprof metrics pprofMux := http.NewServeMux() pprofMux.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile)) @@ -136,8 +138,6 @@ func main() { shutdownWg.Add(1) go shutdown(srv, shutdownWg) shutdownWg.Add(1) - go shutdown(promSrv, shutdownWg) - shutdownWg.Add(1) go shutdown(pprofSrv, shutdownWg) shutdownWg.Wait() diff --git a/internal/experiment/tlsmiddlebox/measurer.go b/internal/experiment/tlsmiddlebox/measurer.go index bb670496e7..cda743756b 100644 --- a/internal/experiment/tlsmiddlebox/measurer.go +++ b/internal/experiment/tlsmiddlebox/measurer.go @@ -16,7 +16,7 @@ import ( const ( testName = "tlsmiddlebox" - testVersion = "0.1.1" + testVersion = "0.1.2" ) // Measurer performs the measurement. diff --git a/internal/experiment/tlsmiddlebox/measurer_test.go b/internal/experiment/tlsmiddlebox/measurer_test.go index 8c21e8359c..d0b9925206 100644 --- a/internal/experiment/tlsmiddlebox/measurer_test.go +++ b/internal/experiment/tlsmiddlebox/measurer_test.go @@ -18,7 +18,7 @@ func TestMeasurerExperimentNameVersion(t *testing.T) { if measurer.ExperimentName() != "tlsmiddlebox" { t.Fatal("unexpected ExperimentName") } - if measurer.ExperimentVersion() != "0.1.1" { + if measurer.ExperimentVersion() != "0.1.2" { t.Fatal("unexpected ExperimentVersion") } } diff --git a/internal/experiment/tlsmiddlebox/syscall_unix.go b/internal/experiment/tlsmiddlebox/syscall_unix.go index 9d3533f18b..1562f53807 100644 --- a/internal/experiment/tlsmiddlebox/syscall_unix.go +++ b/internal/experiment/tlsmiddlebox/syscall_unix.go @@ -9,6 +9,7 @@ package tlsmiddlebox import ( "net" "syscall" + "strings" ) // SetTTL sets the IP TTL field for the underlying net.TCPConn @@ -23,7 +24,12 @@ func (c *dialerTTLWrapperConn) SetTTL(ttl int) error { return err } rawErr := rawConn.Control(func(fd uintptr) { - err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TTL, ttl) + isIPv6 := strings.Contains(tcpConn.RemoteAddr().String(), "[") + if isIPv6 { + err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, ttl) + } else { + err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TTL, ttl) + } }) // The syscall err is given a higher priority and returned early if non-nil if err != nil { diff --git a/internal/experiment/tlsmiddlebox/syscall_windows.go b/internal/experiment/tlsmiddlebox/syscall_windows.go index 51ef782374..ba00cdc811 100644 --- a/internal/experiment/tlsmiddlebox/syscall_windows.go +++ b/internal/experiment/tlsmiddlebox/syscall_windows.go @@ -9,6 +9,7 @@ package tlsmiddlebox import ( "net" "syscall" + "strings" ) // SetTTL sets the IP TTL field for the underlying net.TCPConn @@ -23,7 +24,12 @@ func (c *dialerTTLWrapperConn) SetTTL(ttl int) error { return err } rawErr := rawConn.Control(func(fd uintptr) { - err = syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IP, syscall.IP_TTL, ttl) + isIPv6 := strings.Contains(tcpConn.RemoteAddr().String(), "[") + if isIPv6 { + err = syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, ttl) + } else { + err = syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IP, syscall.IP_TTL, ttl) + } }) // The syscall err is given a higher priority and returned early if non-nil if err != nil { diff --git a/oonith/Makefile b/oonith/Makefile new file mode 100644 index 0000000000..ce9c14c397 --- /dev/null +++ b/oonith/Makefile @@ -0,0 +1,59 @@ +SERVICE_NAME ?= oohelperd + +ECS_CONTAINER_NAME ?= oonith-service-$(SERVICE_NAME) +IMAGE_NAME ?= ooni/oonith-$(SERVICE_NAME) +DATE := $(shell python3 -c "import datetime;print(datetime.datetime.now(datetime.timezone.utc).strftime('%Y%m%d'))") +GIT_FULL_SHA ?= $(shell git rev-parse HEAD) +SHORT_SHA := $(shell echo ${GIT_FULL_SHA} | cut -c1-8) +PKG_VERSION := "3.20.1" + +BUILD_LABEL := $(DATE)-$(SHORT_SHA) +VERSION_LABEL = v$(PKG_VERSION) +ENV_LABEL ?= latest + +print-labels: + echo "ECS_CONTAINER_NAME=${ECS_CONTAINER_NAME}" + echo "PKG_VERSION=${PKG_VERSION}" + echo "BUILD_LABEL=${BUILD_LABEL}" + echo "VERSION_LABEL=${VERSION_LABEL}" + echo "ENV_LABEL=${ENV_LABEL}" + +docker-build: + # We need to use tar -czh to resolve the common dir symlink + cd .. && docker build -f Dockerfile.oonith \ + --build-arg BRANCH_NAME=${VERSION_LABEL} \ + -t ${IMAGE_NAME}:${BUILD_LABEL} \ + -t ${IMAGE_NAME}:${VERSION_LABEL} \ + -t ${IMAGE_NAME}:${ENV_LABEL} \ + . + + echo "built image: ${IMAGE_NAME}:${BUILD_LABEL} (${IMAGE_NAME}:${VERSION_LABEL} ${IMAGE_NAME}:${ENV_LABEL})" + +docker-push: + # We need to use tar -czh to resolve the common dir symlink + docker push ${IMAGE_NAME}:${BUILD_LABEL} + docker push ${IMAGE_NAME}:${VERSION_LABEL} + docker push ${IMAGE_NAME}:${ENV_LABEL} + +docker-smoketest: + echo "no smoketest implemented" + +imagedefinitions.json: + echo '[{"name":"${ECS_CONTAINER_NAME}","imageUri":"${IMAGE_NAME}:${BUILD_LABEL}"}]' > imagedefinitions.json + +test: + hatch run test + +test-cov: + hatch run test-cov + +build: + echo "no build implemented" + +clean: + rm -f imagedefinitions.json + +run: + cd .. && go run -tags netgo ./internal/cmd/oohelperd + +.PHONY: init test build clean docker print-labels diff --git a/oonith/buildspec.yml b/oonith/buildspec.yml new file mode 100644 index 0000000000..55faa562b8 --- /dev/null +++ b/oonith/buildspec.yml @@ -0,0 +1,29 @@ +version: 0.2 +env: + variables: + OONI_CODE_PATH: oonith + DOCKERHUB_SECRET_ID: oonidevops/dockerhub/access_token + +phases: + install: + runtime-versions: + python: 3.11 + + pre_build: + commands: + - echo "Logging in to dockerhub" + - DOCKER_SECRET=$(aws secretsmanager get-secret-value --secret-id $DOCKERHUB_SECRET_ID --query SecretString --output text) + - echo $DOCKER_SECRET | docker login --username ooni --password-stdin + + build: + commands: + - export GIT_FULL_SHA=${CODEBUILD_RESOLVED_SOURCE_VERSION} + - cd $OONI_CODE_PATH + - make docker-build + - make docker-smoketest + - make docker-push + - make imagedefinitions.json + - cat imagedefinitions.json | tee ${CODEBUILD_SRC_DIR}/imagedefinitions.json + +artifacts: + files: imagedefinitions.json