-
-
Save polds/d5110ecc1077247e65c60e07475c5f82 to your computer and use it in GitHub Desktop.
Tailscale attempt at HTTP from CloudRun / GKE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# From https://tailscale.com/kb/1108/cloudrun/ | |
FROM golang:1.16.2-alpine3.13 as builder | |
WORKDIR /app | |
COPY . ./ | |
RUN go build \ | |
-a \ | |
-ldflags "-s -w -extldflags 'static'" \ | |
-installsuffix cgo \ | |
-tags netgo \ | |
-o /bin/app \ | |
cmd/fetch-headers/*.go | |
FROM alpine:latest as tailscale | |
WORKDIR /app | |
COPY . ./ | |
ENV TSFILE=tailscale_1.12.3_amd64.tgz | |
RUN wget https://pkgs.tailscale.com/stable/${TSFILE} && \ | |
tar xzf ${TSFILE} --strip-components=1 | |
COPY . ./ | |
FROM alpine | |
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/* | |
# Copy binary to production image | |
COPY --from=builder /bin/app /bin/app | |
COPY --from=tailscale /app/tailscaled /app/tailscaled | |
COPY --from=tailscale /app/tailscale /app/tailscale | |
COPY build/package/nginx-tailscale/start.sh /app/start.sh | |
RUN mkdir -p /var/run/tailscale /var/cache/tailscale /var/lib/tailscale | |
EXPOSE 80 | |
# Run on container startup. | |
RUN chmod +x /app/start.sh | |
CMD ["/app/start.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fetch Headers attempts to fetch the headers of a service routed through Tailscale. | |
package main | |
import ( | |
"context" | |
"fmt" | |
"log" | |
"net/http" | |
"os" | |
"strings" | |
"time" | |
) | |
var client = http.DefaultClient | |
func main() { | |
log.Print("starting server...") | |
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { | |
w.Write([]byte("ok")) | |
}) | |
http.HandleFunc("/", handler) | |
port := os.Getenv("PORT") | |
if port == "" { | |
port = "80" | |
log.Printf("defaulting to port %s", port) | |
} | |
log.Printf("listening on port %s", port) | |
if err := http.ListenAndServe(":"+port, nil); err != nil { | |
log.Fatal(err) | |
} | |
} | |
func handler(w http.ResponseWriter, r *http.Request) { | |
ctx, cancel := context.WithCancel(r.Context()) | |
defer cancel() | |
fmt.Fprintf(w, "fetching over ipv4...\n\n") | |
hdrFetch(ctx, w, "http://100.99.71.121:5000") | |
fmt.Fprintf(w, "fetching over ipv6...\n\n") | |
hdrFetch(ctx, w, "http://[fd7a:115c:a1e0:ab12:4843:cd96:6263:4779]:5000") | |
if err := ctx.Err(); err != nil { | |
fmt.Fprintf(w, "context error: %v\n", err) | |
} | |
} | |
func hdrFetch(ctx context.Context, w http.ResponseWriter, addr string) { | |
ctx, cancel := context.WithTimeout(ctx, 30*time.Second) | |
defer cancel() | |
req, err := http.NewRequestWithContext(ctx, http.MethodGet, addr, nil) | |
if err != nil { | |
fmt.Fprintf(w, "unable to create new request: %v\n", err) | |
return | |
} | |
res, err := client.Do(req) | |
if err != nil { | |
fmt.Fprintf(w, "unable to issue http request: %v\n", err) | |
return | |
} | |
defer res.Body.Close() | |
var sb strings.Builder | |
for k, v := range res.Header { | |
fmt.Fprintf(&sb, "%s => %q\n", k, v) | |
} | |
fmt.Fprintln(w, sb.String()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment