Fully proxy an internal IP via a Netbird client? (Similar to Tailscale `TS_DEST_IP`)

Hey ๐Ÿ‘‹ Does anyone know if Netbird supports a similar function to TS_DEST_IP in Tailscale (docs)? I'm looking to maybe switch, but that's a feature I'm using and I find it useful as I can expose an internal resource with a Netbird IP address without installing Netbird directly on it.
Tailscale
Using Tailscale with Docker ยท Tailscale Docs
Connect your container to Tailscale using Tailscale's official Docker image.
Solution:
This seems to work, but I'm a bit scared it might break down, either because Netbird will do some things to the iptables periodically, or because a future update of Netbird might break it. ```yaml - image: netbirdio/netbird:latest name: netbird...
Jump to solution
22 Replies
jeevis
jeevisโ€ข3mo ago
So just to confirm
jeevis
jeevisโ€ข3mo ago
Simplifying the IP schemes a bit just as an example, but you mean a setup like this? Where someone goes to the website at 12.34.56.78, and that VPS redirects it to the 192.168.0.5x server that is there? What type of traffic is it?
No description
Fading
FadingOPโ€ข3mo ago
If I understand this right diagram right, the "VPN Gateway" machine would be working as a router to forward traffic for e.g. the 192.168.0.0/24 CIDR? I.e. if I'm in the Netbird VPN, and I want to access Website 1, I need to dial 192.168.0.50
jeevis
jeevisโ€ข3mo ago
A Router is just a "Computer that routes traffic between interfaces". Windows/Linux/BSD can all do it, so it would just need to be a VM, not an entire router.
Fading
FadingOPโ€ข3mo ago
If I got that right, it's not quite what I'm looking for
jeevis
jeevisโ€ข3mo ago
but it could be a router
Fading
FadingOPโ€ข3mo ago
Ok I meant a "routing peer" as per the Netbird docs
jeevis
jeevisโ€ข3mo ago
Yes, you would tell the public VPS that the traffic at 192.168.0.0/24 is accessible through the VM at netbird address 100.x.x.1 So anything going to that VPS(or wherever you want that machine, could be your computer) can access the 192.168.x.x network
Fading
FadingOPโ€ข3mo ago
What I have with Tailscale at the moment is that there is a Tailscale client running for each thing that I want to expose, and it forwards traffic for exactly one IP. The benefit of that that I want to replicate in Netbird is that you mask the internal IP with a Tailscale IP
Fading
FadingOPโ€ข3mo ago
No description
Fading
FadingOPโ€ข3mo ago
Maybe this clarifies that ^ (The current setup is sed /Netbird/Tailscale/g)
jeevis
jeevisโ€ข3mo ago
So NAT When something hits 100.x.x.2, NAT to internal Address (hostname of the k8s container)
Fading
FadingOPโ€ข3mo ago
Yes!
jeevis
jeevisโ€ข3mo ago
Im hoping someone with k8s experience will have a look, but I would just run a single sidecar that goes to a reverse proxy, and have the reverse proxy be what directs the traffic to the correct site(unless you need them segregated because they are different clients or whatever) Then you can point all your DNS at a single IP(the proxy), and it should redirect to the correct site. if not that, then i think you would have to do NAT on the sidecar itself, which im not sure about how to go doing.
jeevis
jeevisโ€ข3mo ago
And i think(but am not sure) it would add the route/network?
Fading
FadingOPโ€ข3mo ago
Yes, that's how I understand the Netbird operator works. I'd very much like to keep the cluster CIDR "hidden", we have a couple of clusters and it's not entirely impossible two services on two different clusters end up having the same IP. Assigning distinct CIDRs for each cluster is possible, but an in my mind a solution that comes with way too much headache (esp. since changing the CIDR after the fact is not possible and you need to recreate the cluster). Thanks for your help so far ๐Ÿ™‚ I think I just found the feature I was looking for. It's called "setup keys" and it's supported by the Netbird operator
Fading
FadingOPโ€ข3mo ago
But can also be manually configured without the operator:
apiVersion: v1
kind: Secret
metadata:
name: test
namespace: default
stringData:
SETUP_KEY: REDACTED
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- image: netbirdio/netbird:latest
name: netbird
env:
- name: NB_SETUP_KEY
valueFrom:
secretKeyRef:
name: test
key: SETUP_KEY
- name: NB_MANAGEMENT_URL
value: https://netbird.example.com
securityContext:
capabilities:
add:
- NET_ADMIN
- image: nginx
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
protocol: TCP
apiVersion: v1
kind: Secret
metadata:
name: test
namespace: default
stringData:
SETUP_KEY: REDACTED
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- image: netbirdio/netbird:latest
name: netbird
env:
- name: NB_SETUP_KEY
valueFrom:
secretKeyRef:
name: test
key: SETUP_KEY
- name: NB_MANAGEMENT_URL
value: https://netbird.example.com
securityContext:
capabilities:
add:
- NET_ADMIN
- image: nginx
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
protocol: TCP
As far as I can tell it doesn't allow specifying a destination other than the localhost, so it's not quite equivalent to TS_DEST_IP, and I suppose it is more akin to having a normal Netbird client installed in the Pod. That gets me almost there, unfortunately I do have a similar use case where I can't simply inject a sidecar container Oh and I realized, I'd much rather be exposing a Kubernetes service than an individual Pod this way ๐Ÿค”
Solution
Fading
Fadingโ€ข3mo ago
This seems to work, but I'm a bit scared it might break down, either because Netbird will do some things to the iptables periodically, or because a future update of Netbird might break it.
- image: netbirdio/netbird:latest
name: netbird
command:
- /bin/sh
- -c
- |
set -e

iptables -t nat -I PREROUTING 1 -i wt0 -p tcp -j DNAT --to-destination ${NB_DEST_IP}
iptables -A FORWARD -i wt0 -o eth0 -p tcp -d ${NB_DEST_IP} -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

/usr/local/bin/netbird up
env:
- name: NB_DEST_IP
value: 10.43.124.158
- name: NB_SETUP_KEY
valueFrom:
secretKeyRef:
name: test
key: SETUP_KEY
- name: NB_MANAGEMENT_URL
value: https://netbird.example.com
- image: netbirdio/netbird:latest
name: netbird
command:
- /bin/sh
- -c
- |
set -e

iptables -t nat -I PREROUTING 1 -i wt0 -p tcp -j DNAT --to-destination ${NB_DEST_IP}
iptables -A FORWARD -i wt0 -o eth0 -p tcp -d ${NB_DEST_IP} -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

/usr/local/bin/netbird up
env:
- name: NB_DEST_IP
value: 10.43.124.158
- name: NB_SETUP_KEY
valueFrom:
secretKeyRef:
name: test
key: SETUP_KEY
- name: NB_MANAGEMENT_URL
value: https://netbird.example.com
jeevis
jeevisโ€ข3mo ago
does netbird touch the firewall? i think it just does routes and DNS if systemd-resolved
Fading
FadingOPโ€ข3mo ago
There are Netbird-specific chains in iptables, in the container at least

Did you find this page helpful?