Commit 7d55a25d authored by Magnus Westergaard's avatar Magnus Westergaard
Browse files

DEICH-5934: Get proximity into monorepo.

parent b66d8b9d
......@@ -411,6 +411,18 @@ services:
org.label-schema.description: "Docker image containing (often more complex, cross-application) jobs intended to be run by cronicle"
no.deichman.label.component-category: "Backend"
sms-proxy:
image: "digibib/proximity:${TAG:-latest}"
profiles:
- "include-build-only-services"
build:
context: proximity
labels:
<<: *common-labels
org.label-schema.name: "proximity"
org.label-schema.description: "Simple HTTPS proxy for debugging purposes"
no.deichman.label.component-category: "Backend"
# zookeeper:
# image: confluentinc/cp-zookeeper:latest
......
......@@ -115,13 +115,13 @@ patch-koha-production:
- /.*\.hotfix(\..*)?/
patch-mailrelay-production:
patch-sms-proxy-production:
extends:
- .production
- .ssh-setup
- .patch-prod
script:
make remote-patch-version CONTAINER=mailrelay TAG=${CI_COMMIT_TAG} ssh_servers="$SSH_SERVERS" ssh_user=$SSH_USER
make remote-patch-version CONTAINER=sms-proxy TAG=${CI_COMMIT_TAG} ssh_servers="$SSH_SERVERS" ssh_user=$SSH_USER
only:
#only creating this job for branches/tags named something.hotfix and optionally something.hotfix.somethingelse
- /.*\.hotfix(\..*)?/
......
......@@ -260,6 +260,17 @@ patch-virtuoso-staging:
- .patch
script:
make remote-patch-version CONTAINER=virtuoso TAG=${CI_COMMIT_TAG} ssh_servers="$SSH_SERVERS" ssh_user=$SSH_USER
only:
#only creating this job for branches/tags named something.hotfix and optionally something.hotfix.somethingelse
- /.*\.hotfix(\..*)?/
patch-sms-proxy-staging:
extends:
- .staging
- .ssh-setup
- .patch
script:
make remote-patch-version CONTAINER=sms-proxy TAG=${CI_COMMIT_TAG} ssh_servers="$SSH_SERVERS" ssh_user=$SSH_USER
only:
#only creating this job for branches/tags named something.hotfix and optionally something.hotfix.somethingelse
- /.*\.hotfix(\..*)?/
\ No newline at end of file
......@@ -214,6 +214,16 @@ deploy-skranke-test:
only:
changes: [ "Makefile", ".gitlab-ci.yml", "gitlab-ci/deploy/test.yml", "gitlab-ci/deploy-jobs.yml", "*.sh", "skranke/**/*"]
deploy-sms-proxy-test:
extends:
- .testdeploy
- .devtest
- .deploy-scp
variables:
APPLICATION_NAME: sms-proxy
only:
changes: [ "Makefile", ".gitlab-ci.yml", "gitlab-ci/deploy/test.yml", "gitlab-ci/deploy-jobs.yml", "*.sh", "proximity/**/*"]
deploy-test-ldap-test:
extends:
- .testdeploy
......@@ -579,3 +589,15 @@ patch-mailchimp-synchonizer-test:
only:
#only creating this job for branches/tags named something.hotfix and optionally something.hotfix.somethingelse
- /.*\.hotfix(\..*)?/
patch-sms-proxy-test:
extends:
- .testdeploy
- .devtest
- .ssh-setup
- .patch
script:
make remote-patch-version CONTAINER=sms-proxy TAG=${CI_COMMIT_TAG} ssh_servers="$SSH_SERVERS" ssh_user=$SSH_USER
only:
#only creating this job for branches/tags named something.hotfix and optionally something.hotfix.somethingelse
- /.*\.hotfix(\..*)?/
......@@ -249,6 +249,17 @@ push-mailrelay-latest:
- master
changes: [ "Makefile", ".gitlab-ci.yml", "*.sh", "mailrelay/**/*", "gitlab-ci/**/*.*"]
push-sms-proxy-latest:
extends:
- .push
when: on_success
variables:
APPLICATION_NAME: sms-proxy
only:
refs:
- master
changes: [ "Makefile", ".gitlab-ci.yml", "*.sh", "proximity/**/*", "gitlab-ci/**/*.*"]
push-test-ldap-latest:
extends:
- .push
......
FROM golang:1.16 as builder
# download deps as separate layer
WORKDIR /go/src/gitlab.deichman.no/digibib/proximity
COPY go.mod .
COPY go.sum .
RUN go mod download
# build
COPY . .
RUN CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -o app
FROM alpine:3.13
COPY --from=builder /go/src/gitlab.deichman.no/digibib/proximity/app /proximity
ARG BUILD_DATE
ARG HEAD_TAG
ARG HISTORY
ARG LATEST_TAG
LABEL no.deichman.label.component-history="${HISTORY}"
ENV BUILD_DATE=${BUILD_DATE} HEAD_TAG=${HEAD_TAG} LATEST_TAG=${LATEST_TAG}
ENTRYPOINT [ "/proximity" ]
# proximity
Simple https proxy for debugging purposes (by mitm relaying)
Usage of proximity:
```
-cert string
A PEM eoncoded certificate file. (default "cert.pem")
-key string
A PEM encoded private key file. (default "key.pem")
-h dump only headers
-l string
local address (default ":9999")
-m int
Interval of metrics logging (default 5)
-no-verify
Do not verify TLS/SSL certificates.
-r string
remote address (default "http://localhost:80")
```
proximity will default to non-tls unless you specify certificate and key
To create a self-signed certificate:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
and answer some questions.
Use flag -no-verify to ignore tls verification errors
\ No newline at end of file
module gitlab.deichman.no/digibib/deichman/proximity
require github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
go 1.16
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
package main
import (
"bytes"
"crypto/tls"
"flag"
"io/ioutil"
"strings"
"regexp"
"log"
"errors"
"net/http"
"net/http/httputil"
"net/url"
"os"
"time"
metrics "github.com/rcrowley/go-metrics"
)
var (
metricsInterval = flag.Int("m", 60, "Interval of metrics logging")
certFile = flag.String("cert", "cert.pem", "A PEM eoncoded certificate file.")
keyFile = flag.String("key", "key.pem", "A PEM encoded private key file.")
localAddr = flag.String("l", ":9999", "local address")
remoteAddr = flag.String("r", "http://localhost:80", "remote address")
verbosity = flag.Int("v", 0, "1: only params, 2: add request and response headers, 3: add request and response body")
noverify = flag.Bool("no-verify", false, "Do not verify TLS/SSL certificates.")
match = flag.String("match", "", "Pattern to match in output")
)
var transport *http.Transport
func main() {
flag.Parse()
log.Printf("Proxying from %v to %v\n\n", *localAddr, *remoteAddr)
go metrics.Log(metrics.DefaultRegistry, time.Duration(*metricsInterval)*time.Second, log.New(os.Stderr, "", 0))
var tlsConfig *tls.Config
if *noverify {
tlsConfig = &tls.Config{InsecureSkipVerify: true}
} else {
// Load client cert
cert, err := tls.LoadX509KeyPair(*certFile, *keyFile)
if err != nil {
log.Printf("failed to load certificate: %s\n", err)
}
tlsConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
}
tlsConfig.BuildNameToCertificate()
}
transport = &http.Transport{ TLSClientConfig: tlsConfig }
http.HandleFunc("/", proxy)
log.Fatal(http.ListenAndServe(*localAddr, nil))
}
func proxy(w http.ResponseWriter, req *http.Request) {
requestsCounter := metrics.GetOrRegisterCounter("numRequests", metrics.DefaultRegistry)
successCounter := metrics.GetOrRegisterCounter("successfulRequests", metrics.DefaultRegistry)
failureCounter := metrics.GetOrRegisterCounter("failedRequests", metrics.DefaultRegistry)
end, err := url.Parse(req.URL.RequestURI())
if err != nil {
log.Printf("failed to parse requested uri '%s': %s\n", req.URL, err)
w.WriteHeader(599)
return
}
// target for proxy
target, err := url.Parse(*remoteAddr)
if err != nil {
log.Printf("failed to parse url: %s\n", err)
w.WriteHeader(599)
return
}
log.Printf("--> %v\n", req.Host)
// copy host + scheme to response
end.Host = target.Host
end.Scheme = target.Scheme
// build destination request, clone body
buf, _ := ioutil.ReadAll(req.Body)
b1 := ioutil.NopCloser(bytes.NewBuffer(buf))
b2 := ioutil.NopCloser(bytes.NewBuffer(buf))
newreq, err := http.NewRequest(req.Method, end.String(), b1)
if err != nil {
log.Printf("failed to create new HTTP request: %s\n", err)
w.WriteHeader(599)
return
}
for header, values := range req.Header {
for _, value := range values {
w.Header().Add(header, value)
}
}
// dump request according to verbosity
requestsCounter.Inc(1)
if *verbosity > 0 {
req.Body = b2 // return original body
log.Println("----- PARAMS ------")
err := req.ParseForm()
if err != nil {
log.Printf("failed to parse HTTP request params/formdata: %s\n", err)
}
for k, v := range req.Form {
val, _ := url.QueryUnescape(v[0])
log.Printf("%s:\t%s\t\n", k, val)
}
if *verbosity > 1 {
if x, err := httputil.DumpRequestOut(newreq, (*verbosity == 3)); err == nil {
log.Println("----- REQUEST ------")
log.Printf("%s", applyMatcher(string(x)))
}
}
req.Body = b2 // return original body
}
// Do real request
client := &http.Client{
Transport: transport,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if len(via) > 10 {
return errors.New("Too many redirects")
}
for header, values := range via[0].Header {
for _, value := range values {
req.Header.Add(header, value)
}
}
if *verbosity >= 1 {
log.Println("----- REDIRECT ------")
if x, err := httputil.DumpRequestOut(req, (*verbosity == 3)); err == nil {
log.Printf("%s", applyMatcher(string(x)))
}
}
return nil
},
}
// build response
var res *http.Response
res, err = client.Do(newreq)
if err != nil {
log.Printf("failed to read response: %s\n", err)
w.WriteHeader(599)
failureCounter.Inc(1)
return
}
defer res.Body.Close()
if res.StatusCode == 200 {
successCounter.Inc(1)
} else {
failureCounter.Inc(1)
}
// Dump response - optionally with body
if *verbosity > 1 {
log.Println("----- RESPONSE ------")
if x, err := httputil.DumpResponse(res, (*verbosity == 3)); err == nil {
log.Print(applyMatcher(string(x)))
}
}
// let response through
var b []byte
b, err = ioutil.ReadAll(res.Body)
if err != nil {
log.Printf("failed to read body: %s\n", err)
w.WriteHeader(599)
return
}
for header, values := range res.Header {
for _, value := range values {
w.Header().Add(header, value)
}
}
w.WriteHeader(res.StatusCode)
w.Write(b)
log.Println("<-- END")
}
func applyMatcher(input string) string {
if input == "" {
return input
}
r, err := regexp.Compile(*match)
if err != nil {
log.Printf("Invalid match regex: %s", err)
return ""
}
matches := r.FindAllString(input, -1)
return strings.Join(matches, "\n")
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment