Did Android require any special policies to work?

I’m not sure what the issue is, but I can’t seem to get to the fabric on my android. The identity is endless, the service is started, no access to the dial services I have access to.

It shows two services. What isn’t working for you? If you expand the identity, what do you see?

You can use the ziti cli and policy advisor for more details. You’d do something like:

ziti edge policy-advisor identities -q | grep clint

which will show you something like:

OKAY : clint (1) -> brozac (1) Common Routers: (1/1) Dial: Y Bind: N

If you run that for your identity, can you post back here what it shows you? (obviously grep’ing for pixel or jp, not clint)

I confirmed that I have the proper dial rights. I can resolve the hosts, but can’t ssh or https. I have no problem with that service on my laptop tethered to my phone.

$ zpa identities | grep pixel
OKAY : pixel.jp (1) -> pve (1) Common Routers: (1/1) Dial: Y Bind: N
OKAY : pixel.jp (1) -> ssh (1) Common Routers: (1/1) Dial: Y Bind: N

I checked and the packet tunnel logs are blank on the android app. The application logs aren’t much help.

The router that offloads the traffic, does it show any logs that might be related? When you click ‘feedback’ from the UI, your log is totally empty???

Here are my logs, minus the keys.

$ ll
Permissions Size User Date Modified Name
.rw-rw-r--@  170 jp   16 Aug 11:28  app.info
.rw-rw-r--@  577 jp   16 Aug 11:28  D7iRVTThT
.rw-rw-r--@ 1.6k jp   16 Aug 11:28  keystore.info
.rw-rw-r--@  61k jp   16 Aug 11:28  logcat
.rw-rw-r--@  21k jp   16 Aug 11:28  thread_dump.txt
.rw-rw-r--@   66 jp   16 Aug 11:28  ziti_dns.info
.rw-rw-r--@  225 jp   16 Aug 11:28  ziti_mobile.info
$ cat D7iRVTThT 
id:         D7iRVTThT
controller: https://ziti.jptech.services:8441
status:     Active

=== Services ===
name: ssh id: 5PTrC1jpZkVtrrP8wat5fH permissions: Dial intercept: [TCP]:[DomainName(name=*.jp)]:[22]
name: pve id: 2JHCtuH6CtG9G1Gd4DcCbv permissions: Dial intercept: [TCP]:[DomainName(name=*.jp)]:[8006-8007]

=== Available Edge Routers[1] ===
EdgeRouter(name=ziti.jptech.services, hostname=, supportedProtocols={tls=tls://ziti.jptech.services:8442}, urls=null)
=== Channels[1] ===
ER: tls://ziti.jptech.services:8442 status: Connected(latency=102)
=== Connections[0] ===
$ cat app.info 
Device:          Pixel 7 (Google)
Android Version: 13
Android-SDK:     33
Ziti Version:    0.23.11(ffbf119)
App:             org.openziti.mobile
App Version:     v0.7.10
$ tail logcat 
08-16 11:28:20.058  5323 13378 V Channel[tls://ziti.jptech.services:8442]: [2023-08-16 11:28:20.057] got m = ct: ResultType, seq: 4, repTo: 33, connId: null, body 0 bytes
08-16 11:28:20.061  5323  5586 V tlschannel.impl.TlsChannelImpl: [2023-08-16 11:28:20.061] engine.unwrap() result [status=BUFFER_UNDERFLOW,handshakeStatus=NOT_HANDSHAKING,bytesProduced=0,bytesConsumed=0]. engine status: NOT_HANDSHAKING; inEncrypted BufferHolder{name='inEncrypted', allocator=tlschannel.TrackingAllocator@adbea5e, plainData=false, maxSize=17408, opportunisticDispose=true, buffer=java.nio.HeapByteBuffer[pos=0 lim=0 cap=4096], lastSize=4096}; inPlain: ByteBufferSet[[java.nio.HeapByteBuffer[pos=0 lim=20 cap=20]]:0:1]
08-16 11:28:20.061  5323  8101 V Channel[tls://ziti.jptech.services:8442]: [2023-08-16 11:28:20.061] latency[Channel[tls://ziti.jptech.services:8442]] is now 95
08-16 11:28:20.062  5323  5586 V tlschannel.impl.TlsChannelImpl: [2023-08-16 11:28:20.062] Reading from channel
08-16 11:28:20.064  5323  7948 D Channel[tls://ziti.jptech.services:8442]: [2023-08-16 11:28:20.064] transitioned to Connected(latency=102)
08-16 11:28:20.064  5323  5586 V tlschannel.impl.TlsChannelImpl: [2023-08-16 11:28:20.064] Read from channel; response: 0, buffer: java.nio.HeapByteBuffer[pos=0 lim=4096 cap=4096]
08-16 11:28:33.610  5323 13723 D routing : 0 active connections

logcat ERROR:
$ tail thread_dump.txt 
  kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:731)
  kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)

Thread: Thread[ConnectivityThread,5,main]
  android.os.MessageQueue.nativePollOnce(Native Method)
  android.os.MessageQueue.next(MessageQueue.java:335)
  android.os.Looper.loopOnce(Looper.java:161)
  android.os.Looper.loop(Looper.java:288)
  android.os.HandlerThread.run(HandlerThread.java:67)
$ cat !$
cat ziti_dns.info
pve1.jp -> pve1.jp/100.64.1.2 [*.jp]

== Wildcard Domains ==
*.jp
 cat ziti_mobile.info 
ZitiVPNService: running
supervisor:  SupervisorJobImpl{Active}@f4f011a
monitor:     StandaloneCoroutine{Active}@b15944b
tunnelState: stop
tunnelUptime:not running

=== Routing ===
CIDRBlock(ip=/100.64.0.0, bits=10) (default)

Ah, I bet I know what’s going on. I am thinking you are using the $dst_host variable and I’m thinking the Android tunneler doesn’t support that. Is that the case maybe?

So far, yes, using $dst_host everywhere. Any hosted service that will appear more than once I am trying to make it so there aren’t duplicates.

Are you trying to use addressible terminators?

Season 2 Idk GIF by Star Wars

I haven't gotten far enough into the docs to understand what an addressable terminator is. I haven't created a terminator manually, the services I have created have instantiated the terminators, so far as I know. This is how I created the SSH and Proxmox services.

Are you actually using $dst_host? Or $dst_hostname? The variables mentioned in support domain substitutions · Issue #540 · openziti/ziti-tunnel-sdk-c · GitHub, including $dst_host have not yet been implemented in any of the tunnelers.

This probably warrants a longer explanation and I don't know if have it documented anywhere (@scareything or @TheLumberjack can point to the right place). But the short explanation goes like this -- when you specify host_cfg.listenOptions.identity and intercept_cfg.dialOptions.identity you actually compel tunneler to bind or dial an addressible terminator.

For Android ZME this feature is not implemented yet

My mistake, it is $dst_host.

ziti edge create config "${NAME}".cfg.intercept.v1 intercept.v1 '{
   "addresses": ["*.jp"],
    "protocols": ["tcp"],
    "portRanges": [ {"low":'"${PORT}"',"high":'"${PORT}"'} ],
    "dialOptions": { "identity": "$dst_hostname" }
  }'

So I can't use this 'catch-all' ssh service with android, yet. Understood.

In your opinion, is my quest for 'don't repeat yourself' reusable service/policy/config going to cause further issues later on? Is it a better practice to make a one-to-one service/policy/config for each host I want to bind and dial to?

I believe this is appropriate in the where you have a fleet of machines you have to administer via SSH (or other means). You can add/remove new endpoints and, also, access without touching services or policies. This is the exact use case we had in mind when we developed this feature

1 Like