I need example showing how to setup application that on one port listens for public traffic, and on another listens only to private traffic. I have REST API that should be public on 8080 and gRPC that should pe private on 8081.
Please help.
I need example showing how to setup application that on one port listens for public traffic, and on another listens only to private traffic. I have REST API that should be public on 8080 and gRPC that should pe private on 8081.
Please help.
Hi… All (or almost all) LiteFS applications are examples of that, since they serve HTTP publicly but use port 20202 for internal DB replication traffic.
(Indeed, you would create a gigantic security hole if you did allow external access to the latter,
.)
https://fly.io/docs/litefs/getting-started-fly/
That’s maybe more involved than what you were looking for, though.
In general, the main points are…
:: (IPv6).[http_service] or [[services]] declaration.You can use fly services list to verify the list of things that are being exposed to the public.
Hope this helps!
Aside: You unfortunately cannot make this distinction with .flycast addresses—only with .internal.
†Unless your .internal addresses only need to be used for Machines that are already known to be awake for other reasons, e.g., because they’ve signed up as replication subscribers.
I dug up a simpler example, actually, although still maybe not ideal…
The fly.toml:
app = "qua-melon"
primary_region = "ewr"
swap_size_mb = 512
[[services]]
protocol = "tcp"
internal_port = 8080
[[services.ports]]
handlers = ["tls"] # would be ["tls", "http"] for HTTPS.
port = 4321
# note: port 8081 is intentionally *not* mentioned anywhere.
The super-unoptimized Dockerfile:
FROM debian:bullseye-slim
RUN apt-get update -y && \
apt-get install -y --no-install-recommends racket procps iproute2
WORKDIR /app
COPY b.rkt b.rkt
CMD ["racket", "/app/b.rkt"]
And the barebones server itself (b.rkt):
#lang racket/base
(require racket/tcp)
(define (serve port msg)
(define l (tcp-listen port))
(eprintf "listening on ~v...\n" port)
(let again ()
(define-values (in out) (tcp-accept l))
(write-string msg out)
(close-output-port out)
(close-input-port in)
(again)))
(void (thread (λ () (serve 8081 "hello internal.\n"))))
(serve 8080 "hello world.\n")
Note that this uses plain TCP instead of HTTP, and the public service is wrapped in SSL, thus allowing a freebie shared IPv4 address to be used—since I am a cheapskatecost optimization expert.
Test the public one via…
$ socat STDIO OPENSSL:qua-melon.fly.dev:4321,no-sni=0 # note `OPENSSL:` with SNI.
hello world.
But from inside the internal network…
$ fly ssh console
# apt-get update
# apt-get install --no-install-recommends socat
# socat STDIO TCP6:qua-melon.internal:8081 # no SSL.
hello internal.
And to verify…
$ fly services list
PROTOCOL PORTS HANDLERS
TCP 4321 => 8080 [TLS]
Only port 8080 is mentioned, as intended. That’s the only one that the public Internet can get through to.
(Note: some output columns elided.)
Don’t cite port 8081 in any [http_service] or [[services]] declaration.
that is exactly what I needed!
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.