How to access multiples resources on same server

Hello Team,

Still discovering Ziti secrets! :slight_smile: After succeeding access to one http web site using the overlay, I tried to access other resources on the same server: in my case an https server. As it did not work, I tried with http protocol but again, it's not working. Here are the cli settings I entered. Can someone tell me where I make a mistake?

export http_server="192.168.1.10"

#1. Create an identity for the HTTP client and assign an attribute "http-clients". We'll use this attribute when authorizing the clients to access the HTTP service
ziti edge create identity pcv-el -a 'http-clients' -o pcv-el.jwt

#2. Create an identity for the HTTP server if you are not using an edge-router with the tunneling option enabled
ziti edge create identity myserver -o myserver.jwt

export http_server_id="HeSG1bSG4o" -> server ID

#3. Create an intercept.v1 config.
ziti edge create config http1.intercept.v1 intercept.v1 '{"protocols":["tcp"],"addresses":["site1.mydomain.eu"], "portRanges":[{"low":80, "high":80}]}'
ziti edge create config http2.intercept.v1 intercept.v1 '{"protocols":["tcp"],"addresses":["site2.mydomain.eu"], "portRanges":[{"low":80, "high":80}]}'

#4. Create a host.v1 config.
ziti edge create config http1.host.v1 host.v1 '{"protocol":"tcp", "address":"'"${http_server}"'", "port":80}'
ziti edge create config http2.host.v1 host.v1 '{"protocol":"tcp", "address":"'"${http_server}"'", "port":80}'

I tried using only one host config because server and port is the same for both sites but it failed too. That's why I create two host configs.

#5. Create a service to associate the two configs created previously into a service.
ziti edge create service http1.svc --configs http1.intercept.v1,http1.host.v1
ziti edge create service http2.svc --configs http2.intercept.v1,http2.host.v1

#6. Create a service-policy to authorize "HTTP Clients" to "dial" the service representing the HTTP server.
ziti edge create service-policy http1.policy.dial Dial --service-roles "@http1.svc" --identity-roles '#http-clients'
ziti edge create service-policy http2.policy.dial Dial --service-roles "@http2.svc" --identity-roles '#http-clients'

#7. Create a service-policy to authorize the "HTTP Server" to "bind" the service representing the HTTP server.
ziti edge create service-policy http1.policy.bind Bind --service-roles '@http1.svc' --identity-roles "@${http_server_id}"
ziti edge create service-policy http2.policy.bind Bind --service-roles '@http2.svc' --identity-roles "@${http_server_id}"

Thanks.

1 Like

Could you tell us what didn't work? I assume you mean the client-side tunneler didn't accept traffic?

When it seems like "things aren't working", here's what I do for tunneler-based services:

  • look at the client side tunneler do i see the service in the tunneler?
  • look at the client side tunneler logs, do i see traffic being intercepted for the service I want to have intercepted?
  • look at the far/server side tunneller logs, did it tell me that it's binding the service I expect

Do you know what part is failing here?

1 Like

The HTTPS server wouldn't work because you only have port 80 in the host and intercept configs. Why it wouldn't work when you went back to HTTP is a bit of a mystery.

You could put both sites into a list of the addresses, rather than two different configs, and then only have one pair of intercept/host. When you say it failed when you tried, what exactly happened? The parser doesn't like a space after the comma between addresses, if I recall correctly, so it could have been that.

1 Like

Hi Michael,

For https, of course I created a service with port 443 and it did not work, that's why I tried with http but then it's still working for the first site and I got http error 500 for the second site.

I did not know that it was possible to put multiple addresses in the same config... I'll try ASAP and tell you. Actually, it's not clear in my head how to manage configs, services and policies in the best manner.

Thanks.

1 Like

It seems to be a DNS issue. Here is what I see in a Wireshark capture on the server:

Here is the refuse packet detail:

After a new try, I see this on the client side:
[2024-03-19T10:50:00.932Z] INFO tunnel-cbs:ziti_dns.c:500 format_resp() found record[100.64.0.10] for query[1:winpreprod.vigicloud.eu]

and nothing in the logs on the WEB server side.

Please can you tell me if below behavior is correct:
On the client side, with policy enabled: pinging the web servers return a 100.64 IP address. With policy disabled, public address is returned.
On the server side, with policy enabled, pinging the web server fails. With policy disabled, public address is returned.

1 Like

What is the value of ${http_server} when you create the host.v1 configs? This address is usually a local IP (or hostname that resolves to a local IP) on the server host. Using 127.0.0.1 here is very common, since this lets you expose your server to the OpenZiti tunneler but not over the LAN or WAN. The host.v1 address should definitely not be the IP or hostname of an intercepted OpenZiti service. The addresses in the intercept.v1 configuration will only be meaningful on hosts that are running tunnelers with identities that have Dial access to the service.

Going back to your original question - accessing multiple resources - I think port forwarding is what you're looking for. Here's an example of port forwarding for ports 80 and 443:

ziti edge create config http1.intercept.v1 intercept.v1 '{
  "protocols":["tcp"],
  "addresses":["site1.mydomain.eu"],
  "portRanges":[{"low":80, "high":80}, {"low":443, "high":443}]
}'

ziti edge create config http1.host.v1 host.v1 '{
  "protocol":"tcp",
  "address":"127.0.0.1",
  "forwardPort":true,
  "allowedPortRanges": [{"low":80, "high":80}, {"low":443, "high":443}]
}'
1 Like

Good morning,

http_server value is the private IP of the web server. I won't use 127.0.0.1 because the server must also be accessible through the underlay.

Thanks for the config examples, I'll work on them ASAP. But do you think there is a DNS issue? What do you think about the ping results I noticed at the end of my previous post?

The results on the client side are what I'd expect. This is assuming you are enabling the Dial policy on the client side.

It isn't clear to me which policies are being manipulated, but I would not expect the hostnames in the intercept.v1 to be resolved by the tunneler on the server host unless perhaps you're enabling the 'Dial' policy for the server (which you wouldn't want to do). Taking a step back,I'm confused as to why you'd want the hostname to resolve on the server side? This is the server side after all, and you are using a private IP for the host.v1 address. When/how are the intercept hostnames used on the server?

Well, I agree: pinging the server hostname from the server is useless. I just did this test because I found DNS errors in the Wireshark capture.

But what you wrote regarding the dial policy on the server side is very interesting because of my plan for Ziti usage. Let me explain it in a few words.

We will have multiple endpoints with apps connected to Internet with a SIM card and a central server with multiple web services. The endpoints can access the server easily but we also need the server to access the endpoints when needed, from time to time. These endpoints are behind SIM cards thus it's impossible to initiate a session from the server to any endpoint because its public IP is shared among multiple SIM cards. A tunnel session must be established by the endpoints so, basically, I was looking for a peer to peer solution. That's how I found Openziti. :slight_smile:

Of course, the Zero trust network security is very interesting but, after reading your answer, I'm a bit in trouble. If the endpoints and the server connect to the Ziti infrastructure, can you confirm that the server will be able to reach any endpoint with its identity through the overlay using the underlay connection initiated by the endpoint? This is the main reason why I'm working on Ziti currently. As per my understanding, Ziti makes the job but I would like to be sure before spending days and days on it...

Thank you for your feed-back :slight_smile:

Ahh, ok if you want to access services in both directions then it would make sense to give Dial permission to the tunneler that's on the server. I didn't understand that detail and thought we were only talking about connections from one host to another. So the "server" is actually a server and a client. We can do that.

What services are running on the hosts that I've been thinking of as the client so far? Is it also http[s]? If so, we do have a trick called "addressable terminators" that makes this sort of thing easier. Basically it lets you use a single OpenZiti service (with a single intercept.v1 and host.v1 configuration) to connect to different specific identities that are hosting a service based on the name of the identity. So for example you'd name your identities as the hostnames that are in your intercept.v1 addresses and you change the intercept.v1 and host.v1 configurations a little to tell the tunnelers to connect to (or present) a specific identity. It's come up in other threads here - give this thread a skim for an overview: How can I create a service for ssh and add identities with the least amount of policies/configs/etc? - #2 by scareything). We can talk about addressable terminators if it seems like it would be useful to you, but first I'd like to get back to the dns issue that I misunderstood.

So, which operating system and version is the tunneler running on where the DNS lookup is failing? The tunneler tries to set itself up as a DNS server in the host's resolver configuration, so we'll want to look at the resolver setup while the tunneler is running (and the policies are set appropriately)

For now I have not installed mutual dial and bind as I'm not able to make a simple solution work! But I certainly will succeed with your nice help. :slight_smile: On the other hand, I have an important question regarding my plan: once an endpoint is up and has registered its identity on the controller, do you confirm that it will be possible to send requests to it even though its IP address is unknown? This is what happens when we use VPN clients that maintain a permanent tunnel with the VPN server and then it's easy to send requests through this tunnel from the VPN server side. Do you confirm that it's possible to do the same with OpenZiti? I guess this is exactly what OpenZiti is made for but the documentation pinpoints the added security and does not insist on this peer to peer feature.

Regarding the DNS, the WEB server is a Windows 10 machine (testing lab) with tunneler app 2.1.16.0. Same version on the Windows client and 2.39 (508) on a Mac client. Ziti version is v0.32.2.

Yes, the tunnelers can be reached even though their IP isn't known. All OpenZiti applications including the tunnelers maintain a connection with edge routers at all times, and if the connection is severed they dilligently attempt to reconnect until successful.

Going back to the DNS refused responses that you saw. I'll assume the service configurations are still as they were in your initial message to this thread. Just a quick recap to make sure my understanding is accurate:

  • You were able to access the web server (using the dns name "site1.mydomain.eu") from the tunneler that's running the pcv-el identity via the "http1.svc" service. So far, so good.
  • You were not able to use the "http2.svc" service, which I believe is intended to provide http[s] connections from the web server host to the pcv-el "client".

You mentioned that you enabled policies:

But it wasn't clear to me which policies (and for which identities) you were enabling. My hunch is that you didn't grant Dial permission for the http2.svc service to the myserver identity. This would have meant that the tunneler wasn't trying to intercept the "site2.mydomain.eu" hostname, and that would explain why the DNS server returned a refused response.

So I'd like to share what I would do if I had two identities that needed to access http[s] from each other (and without using the addressable terminator trick, which I do recommend we get to next as it simplifies the setup quite a bit especially as you start adding identities to the setup). Without addressable terminators, we'll create a separate service for each identity. Note that both identities are effectively acting as a client and a server, so each identity needs Dial permission to one service and Bind permission to the other.

  1. Create an identities for each site.

    ziti edge create identity site1 -a site2-clients -o site1.jwt
    
    ziti edge create identity site2 -a site1-clients -o site2.jwt
    
  2. Create the service that provides access to site1.

    ziti edge create config site1.intercept.v1 intercept.v1 '{"protocols":["tcp"],"addresses" ["site1.mydomain.eu"], "portRanges":[{"low":80, "high":80},{"low":443, "high":443}]}'
    
    ziti edge create config site1.host.v1 host.v1 '{"protocol":"tcp","address":"'"${http_server}"'","forwardPort":true, "allowedPortRanges": [{"low":80, "high":80}, {"low":443, "high":443}]}'
    
    ziti edge create service site1.svc --configs site1.intercept.v1,site1.host.v1
    
  3. Create the service that provides access to site2.

    ziti edge create config site2.intercept.v1 intercept.v1 '{"protocols":["tcp"],"addresses" ["site2.mydomain.eu"], "portRanges":[{"low":80, "high":80},{"low":443, "high":443}]}'
    
    ziti edge create config site2.host.v1 host.v1 '{"protocol":"tcp","address":"'"${http_server}"'","forwardPort":true, "allowedPortRanges": [{"low":80, "high":80}, {"low":443, "high":443}]}'
    
    ziti edge create service site2.svc --configs site2.intercept.v1,site2.host.v1
    
  4. Create service policies to authorize clients to the site1 and site2 services.

    ziti edge create service-policy site1.policy.dial Dial --service-roles "@site1.svc" --identity-roles '#site1-clients'
    
    ziti edge create service-policy site2.policy.dial Dial --service-roles "@site2.svc" --identity-roles '#site2-clients'
    
    
  5. Create service policies to authorize the site1 and site2 identities to "bind" their respective services.

    ziti edge create service-policy site1.policy.bind Bind --service-roles '@site1.svc' --identity-roles "@site1"
    
    ziti edge create service-policy site2.policy.bind Bind --service-roles '@site2.svc' --identity-roles "@site2"
    

So basically we think of this as a service and an identity for each site. I'm not sure if all of the sites have their http server at the same private IP. If they do you could share a single host.v1 config between all of the services, but that simplification is minor compared to the benefits of using addressable terminators.

Great! I guess I should change http_server value between point 2 and point 3?

Wow, actually, I don't know the IP address of one site as it is dynamic... So I don't see how I can create the host.v1 configs.

Is the http server running on the same host as the tunneler, or is it on the lan?

If the http server is local, is it binding to that specific IP, or does it bind to all local addresses (0.0.0.0)? If it is local and binding to all addresses, you can use 127.0.0.1 in the host.v1 config.

If the http server is on another host, can you provision a hostname to it and use that as the host.v1 address?

Well, I'm becoming lost! Maybe I can explain further the target organisation I expect to build and you certainly will be able to tell me if it's possible or not with Ziti (and I hope it is!).

The goal is to provide video surveillance systems to customers. So there are 4 types of components:

  1. A central server in the Cloud managed by us with a fqdn and an fixed public IP, protected by a firewall.
  2. Network video recorders (NVR) belonging to customers and that could be anywhere, mainly behind dynamic IP address and for some of them behind a SIM card.
  3. Customers using an app on their PC or smartphone or tablet to access their NVR locally or through Internet
  4. Us, owner and manager of the central server

Which services do we need?

  1. customers access their NVR to see real-time or recorded videos, alarms and so on
  2. NVR access the central server for supervision purpose
  3. central server access NVR for updates, data collection and so on
  4. we access the central server for management and also the NVR when support is needed

Only the central server has a fixed IP and a fqdn.

We built a solution with OpenVPN which worked fine but needs to launch a VPN client for the customers and this is not good. That's why I was searching for a P2P solution (maybe it's not the right word), a solution able to make all these data communications possible inside what I name "technical tunnels" permanently maintained.

I was thinking that a NVR could mount a tunnel with an edge router, keep it up with keep-alive packets and then, the fabric has the knowledge of the real IPaddress of this NVR and then can forward traffic requests from and to this NVR. But, at this stage, I really don't know if Ziti is suitable for my project.

Ok, are these customer NVRs the ones that we don't know how to address in the host.v1 configuration? I suppose the OpenVPN solution solves this problem by letting the customers enter the IP or hostname for their NVR (because they probably know it, and can reach it through the VPN)?

You are right, we will need to put an IP address (or hostname) in the host.v1 configuration in order for the OpenZiti solution to work. If you are thinking about running the tunnelers on the same hosts as the NVRs then I have a strong hunch that using 127.0.0.1 in the host.v1 will work.

Do you know how the NVRs are configured as far as accepting incoming connections are concerned? They must be configured to listen for requests on an IP address and port. Very often, servers (such as this NVR) are configured to listen on the so-called IPv4 wildcard address "0.0.0.0". This means that instead of configuring the server to accept connections on a specific IP like 192.168.1.10, configuring it to listen at 0.0.0.0 means that connections can arrive on any IP that is local to the host the NVR is running on. It would make a lot of sense to configure the NVRs with 0.0.0.0, since otherwise you would need to custom configure each one for the host and network that it is going to run on.

So, if the NVRs are listening on 0.0.0.0, and the tunnelers will be running on the same host as the NVR, then the tunnelers will be able to connect to the NVRs at 127.0.0.1 no matter what other IPs that host may have assigned to it.

For the tests I'm doing, I use tunneling apps you provide. For our project, we plan to use SDK to add Ziti features to the central server, the NVR software and the client app. :slight_smile: so yes, to asnwer your question, "the tunnelers run on the same hosts as the NVRs".

Regarding the NVR configuration, we can do whatever we need as we develop the software. We just have to take care of security but if everything goes through Ziti, it should not be a problem.

Could you kindly show me the commands to test what i presented with the central server, one NVR and one client, only for http for example, using the tunnelers for now?

Sure.

It's really the same setup that I recently shared here, but we'll use 127.0.0.1 for ${http_server}. I named the identities and services "site1" and "site2" in that example, but you could just as well name one of them "central" and the other "site1" if that makes more sense.

Okay, got it. Thanks a lot Shawn. I have installed a 4G router and i will install a fake NVR behind and test the communications with a client and the central server. Of course, I will let you know the result. Thanks again for your precious help. :slight_smile:

1 Like