Open cctomato opened 7 months ago
Hello and thanks for the insightful question!
Eventually it will help to know exactly which ziti tunnel client you are using (ziti-edge-tunnel? ziti-router with tunneler enabled?) and your current service configurations, but I can start by explaining the features that make it possible to project source IP.
Are you aware of the sourceIp
field in the intercept configuration? This is certainly the first step in controlling the source IP that is used when the tunneler client on the Linux server connects to the device. Here's an example intercept configuration that sets sourceIp
:
ziti edge create config myservice.intercept intercept.v1 '{ "addresses": [ "192.168.3.20" ], "protocols": [ "udp" ], "portRanges": [ { "low": 5000, "high": 6000 } ], "sourceIp": "$tunneler_id.name" }'
You can put any IP address[:port] in sourceIp
, but usually you'll want to use the following variables so you don't need a separate service and intercept configuration for each client:
variable | description |
---|---|
tunneler_id.name | the name of the openziti identity that the intercepting tunneler is using. this obviously must be a dotted-decimal IP address for the feature to work. |
src_ip / src_port | the actual source IP and/or port of the UDP or TCP client that got intercepted. this variable is really only useful if the intercepting tunneler is acting as a gateway for other hosts on a LAN. if connections are being intercepted from processes that are running on the same host as the intercepting tunneler, which I assume is your situation based on your diagram, then $src_ip will end up being the IP address that is assigned to the tun interface if ziti-edge-tunnel is the client ("100.64.0.1" by default) or the destination IP of the intercepted connection if you're using ziti-router or ziti-tunnel to intercept the connections. |
dst_ip / dst_port | the destination ip and/or port of the intercepted connection |
You'll also need to whitelist any IPs that you want to project from the ziti tunnel client on the server. For this, the host.v1
configuration type supports an allowedSourceAddresses
field. You can use a list of IPs and/or CIDRs for this:
ziti edge create config myservice.host host.v1 '{"address": "127.0.0.1", "protocol":"udp", "forwardPort":true, "allowedPortRanges":[{"low":5000,"high":6000}], "allowedSourceAddresses":["192.168.2.0/24"]}'
There are some caveats:
ziti-edge-tunnel
on the server-side if you are using source IPs and want the return path to use that source IP. This is due to very technical reasons that are summarized in https://github.com/openziti/ziti-tunnel-sdk-c/issues/443. So you must use either an edge router (with tunneler features enabled), or ziti-edge-tunnel
with zfw integration on the server-side.allowedSourceAddresses
field to the lo
interface. ziti-edge-tunnel
expect that you will manage the local addresses manually.@scareything Thank you for your answer!
The requesters is a PC with Ziti's Windows client application(desktop-edge-win) installed. And the Ubuntu Linux Server installed with ziti-edge-tunnel.
create identity
# for Requester 192.168.2.2
ziti edge create identity user requester001 -o 001.jwt
# for Requester 192.168.2.3
ziti edge create identity user requester002 -o 002.jwt
# for Requester 192.168.2.4
ziti edge create identity user requester003 -o 003.jwt
# for Linux Server 192.168.3.10
ziti edge create identity user ubuntu001 -o ubuntu001.jwt
# add addtribute
ziti edge update identity requester001 -a requesters
ziti edge update identity requester002 -a requesters
ziti edge update identity requester003 -a requesters
ziti edge update identity ubuntu -a devices
intercept config
ziti edge create config device-intercept-config intercept.v1 '{"protocols": ["udp"], "addresses": ["192.168.3.20"], "portRanges": [{"low": 5000, "high": 5000}]}'
hostv1 config
ziti edge create config device-host-config host.v1 '{"forwardAddress": "true", "allowedAddresses": ["192.168.3.20"] ,"forwardPort":"true", "allowedPortRanges":[{"low":5000,"high":5000}],"forwardProtocol": "true","allowedProtocols":["udp"]}'
service config
ziti edge create service device-connect -c device-intercept-config,device-host-config
bind polices
ziti edge create service-policy device-bind Bind --identity-roles "#devices" --service-roles '@device-connect' --semantic 'AnyOf'
dial polices
ziti edge create service-policy device-dial Dial --identity-roles "#requesters" --service-roles '@device-connect' --semantic 'AnyOf'
After completing the above settings, All requester can send a udp request to 192.168.3.20:5000 through its 3000 port, and the device's 5000 port can also receive this udp request. Now this device needs to send data to the requester 3000 port. The program on the device only knows that the source IP of the udp request is 192.168.3.10. Therefore, the device will send a udp request to 192.168.3.10:3000, the Linux Severs's 3000 port can get the udp request.
It is obvious that the requester's 3000 port will not receive this udp request.
Because there are multiple requesters, I don't know how to forward the udp requests received on the Linux server to the original requester's 3000 port.
Ok, so your service configurations will need to use the source address fields that I described in my previous message for the source IP to be used at the Linux server. You'll also need to name your identities as literal IP addresses for the "$tunneler_id.name" variable to work. Finally, you must use an edge router to do the tunneling on the Linux server.
If your requesting applications are setting their source port 3000 then the device will be able to return traffic through that port.
I have a usage scenario for device discovery where the requester and device communicate using the UDP protocol.
As shown in the figure, the requester(192.168.2.x) sends a udp request to the device(192.168.3.20), and the device needs to reply to the message through the udp request. However, the device does not know which requester sent the request.
It can only obtain the ip address of the Linux server(192.168.3.10)
So the device cannot return data to the requester.
I want to know how to obtain the source IP address of the requester (192.168.2. x). Or is it necessary to establish a service configuration from the device to the requester for communication.
Please help me! Thanks!