Understanding BT Smart hub 2 and my IPv6 addresses

As part of some work trying to get IPV6 to connect, I spent too much time understanding the various IP addresses in my configuration. By accident I found the magic incantation that allowed my z/OS on zD&T to talk to the outside internet.

Under the covers the BT Smart Hub 2 has a router called Arcadyan_ae. You will see this in a Wireshark trace. My IP addresses start with 2A00:23C5:… This belongs to BT. I’ve replace the address with BT:a:b:c .

This Blog post is referred to in Connecting a zPDT z/OS to the internet to using IPV6 and explains the various IPv6 addresses

My BT Smart Hub 2

You can display configuration information from the Smart Hub by using a web browser and address 192.168.1.254.

The Smart Hub IPv6 information.

This is password protected in the Advanced Settings.

There is a section IPv6 WAN details, this was not of interest.
The section IPv6 LAN details has

  • Link local address: fe80::6a2:22ff:feae:2871/64

For my Linux Server

the information in the BT Hub was

  • Device Name: Colins Server
  • Device Icon: None
  • Connection Status: Connected
  • IP address: 192.168.1.25 I think this came from my z/OS system running on the server!
  • MAC address: CC:64…:C5
  • Connection Type: Wireless
  • Address assignment: DHCP
  • Always using this address: YES
  • IPv6 Addressing:
    • GUA(Temporary): BT:a:b:c:2f3d:acdb Assigned by device
    • GUA (Permanent) :BT:a:b:c:7cd3:8993 Assigned by device
    • Link local address:fe80::…:8c80:37a4 Assigned by device

The IPv4 address (192.168.1.25) varied from day to day. During the day, it tended to be the same value. I could not find what caused it to change.

On my Linux server

The command ip addr gave

wlxcc641aee92c5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
link/ether cc:64:1a...:c5 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.25/24 brd 192.168.1.255 scope global dynamic noprefixroute wlxcc641aee92c5
...
inet6 BT:a:b:c:7cd3:8993/64 scope global temporary dynamic
...
inet6 BT:a:b:c:2f3d:acdb/64 scope global dynamic mngtmpaddr noprefixroute
...
inet6 fe80::...:8c80:37a4 /64 scope link noprefixroute
...

Where

  • the GUA (Permanent) is the same as the address with scope global temporary dynamic
  • the GUA (Temporary) is the same as the address with scope global dynamic mngtmpaddr noprefixroute
  • the Link local address is the same as the address with scope link noprefixroute. The word link gives it away.

Configure z/OS TCPIP Interface

I configured the interface like

 INTERFACE WIRE6 
DEFINE IPAQENET6
CHPIDTYPE OSD
IPADDR 2001:DB7:8::1
PORTNAME PORTB

INTERFACE WIRE6
ADDADDR BT:a:b:c::1
START WIRE6

This interface has addresses 2001:DB7:8::1 and BT:a:b:c::1. The value BT:a:b:c is the same as the high part of the Smart Hub’s Global unicast address: BT:a:b:c:6a2:22ff:feae:2871. The value BT:a:b:cuniquely identifies my Smart Hub2 router. Any device in the subarea below this router, must have the same top part. I picked address 1(::1).

The TSO NETSTAT HOME command gave

IntfName:   WIRE6 
Address: 2001:db7:8::1
Type: Global
Flags:
Address: BT:a:b:c::1
Type: Global
Flags:
Address: fe80::cc64:1a02:ee:92c5
Type: Link_Local
Flags: Autoconfigured

With the two addresses I configured, and an internally generated link local address.

The TSO NETSTAT ND gave

Query Neighbor cache for fe80::6a2:22ff:feae:2871 
IntfName: WIRE6 IntfType: IPAQENET6
LinkLayerAddr: 04A222AE2871 State: Reachable
Type: Router AdvDfltRtr: Yes

Where fe80::6a2:22ff:feae:2871 is the IPv6 address of the router – see the top of this blog post.

Routing

My routing table did not need an IPv6 default entry because TCPIP can deduce it.

BEGINRoutes 
; Destination SubnetMask FirstHop LinkName Size
ROUTE 10.0.0.0 255.0.0.0 = TAP0 MTU 1492

ROUTE DEFAULT 192.168.1.254 WIRE MTU 1492

ENDRoutes

TSO NETSTAT ROUTE gave me

IPv6 Destinations 
DestIP: Default
Gw: fe80::6a2:22ff:feae:2871
Intf: WIRE6 Refcnt: 0000000000
Flgs: UGD MTU: 1492
MTU: 65535
DestIP: 2001:db7:8::1/128
Gw: ::
Intf: WIRE6 Refcnt: 0000000000
Flgs: UH MTU: 1492
DestIP: BT:a:b:c::/64
Gw: ::
Intf: WIRE6 Refcnt: 0000000000
Flgs: UD MTU: 1492
DestIP: aBT:a:b:c::1/128
Gw: ::
Intf: WIRE6 Refcnt: 0000000000
Flgs: UH MTU: 1492
DestIP: fe80::cc64:1a02:ee:92c5/128
Gw: ::
Intf: WIRE6 Refcnt: 0000000000
Flgs: UH MTU: 1492

DestIP: ::1/128
Gw: ::
Intf: LOOPBACK6 Refcnt: 0000000000
Flgs: UH

Where the Default is the value in TSO NETSTAT ND, and is the IP address of the Smart Hub2 – see above.

PING

When I did a TCPIP PING to an IPv6 address,

  • the source was BT:a:b:c::1
  • the destination was 2a04:abcd::81

The first ping

The first ping had the following flows

  1. Ping the address
  2. The router does not know where the originating IP address came from, so it asks all devices connected to it – Does anyone have this IP address?
  3. Z/OS replies to the router saying “I’ve got that address”
  4. The router says “Here is some data for you

In more technically

  1. From BT:a:b:c::1 ping destination 2a04:abcd::81
  2. (From the router) Source Address: fe80::6a2:22ff:feae:2871 to all devices on the subnet (ff02::1:ff00:1) Neighbour Solicitation for BT:a:b:c::1
  3. (From z/OS) Source Address: fe80::cc64:1a03:ee:92c5 to the router (fe80::6a2:22ff:feae:2871) Neighbour Advertisement BT:a:b:c::1
  4. From 2a04:abcd::81 to BT:a:b:c :1 ping response


The second ping request went directly to z/OS because the BT Hub had learned where the IP address was.

Connecting a zPDT z/OS to the internet to using IPV6

I needed to get my ZD&T machine connected to the internet so it could download some files as part of an install. Note, this allows my z/OS to contact the internet, externals machines cannot contact my machine.

I blogged

It took a while to get it working. It is based on scenario 4 of the zD&T documentation.

The configuration uses the wireless connection from my Linux server.

You need to know/configure the address of various end points. Some addresses are configured by the systems, some addresses you need to configure.

Before you start

You need to know what the IP address of your z/OS image is

I used the GUA permanent address

   INTERFACE WIRE6 
DEFINE IPAQENET6
CHPIDTYPE OSD

IPADDR 2001:DB7:8::1
PORTNAME PORTB

INTERFACE WIRE6
ADDADDR BT:a:b:c:B8CE:404B:3360:3644
START WIRE6

What’s my TCP configuration on Linux?

The command ip addr gave (displaying only the IP V6 entries)

1: lo: <LOOPBACK,UP,LOWER_UP> ...    
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: eno1:...
...
inet6 fe80::2d8:61ff:fee9:312a/64 scope link ...
3: wlxcc641aee92c5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...

inet6 BT:a:b:c:8b43:7ce6:34d1:c0fe/64 scope global temporary dynamic ...

inet6 BT:a:b:c:9824:30b:2f3d:acdb/64 scope global dynamic mngtmpaddr noprefixroute ...
inet6 fe80::7bfc:5da1:8c80:37a4/64 scope link noprefixroute ...
4: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc ...
link/ether ...
...
inet6 fe80::48f6:deff:fef4:c8d4/64 scope link valid_lft forever preferred_lft forever

Where

  • lo is the loop back address.
  • eno1 is the connection over an Ethernet cable to my laptop
  • wlxcc641aee92c5 is the wireless connection to my router and the outside world. The IP address of the Linux server end is BT:a:b:c… . This value is used in the z/OS configuration.
  • tap0 is the tunnel interface to z/OS from the base linux machine. It has address fe80::48f6:deff:fef4:c8d4 This address is internal to the subnet.

I think these end point addresses were all generated for me.

My devmap

The devmap file contains the definitions of the emulated devices. For the OSA I had

[manager]  # tap0 define network adapter (OSA) for communication with Linux
name awsosa 0009 --path=A0 --pathtype=OSD --tunnel_intf=y # QDIO mode
device 400 osa osa --unitadd=0
device 401 osa osa --unitadd=1
device 402 osa osa --unitadd=2

name awsosa 0010 --path=F1 --pathtype=OSD --interface=wlxcc641aee92c5
device 404 osa osa --unitadd=0
device 405 osa osa --unitadd=1
device 406 osa osa --unitadd=2
device 407 osa osa --unitadd=3
device 408 osa osa --unitadd=4
device 409 osa osa --unitadd=5

Where the –interface is the same name as my wireless interface (see above).

Find_io

The find_io command gives the network configuration known by the emulation code.

FIND_IO for "colin@colin-ThinkCentre-M920s" 
Interface Current MAC IPv4 IPv6
Path Name State Addr Addr Address
---- ---------------- ----------- ---- ------ --------------
F0 eno1 UP,RUNNING 00... 10.... fe80::2d8:61ff:fee9:312a%eno1
F1 wlxcc641aee92c5 UP,RUNNING cc... 192.... BT:a:b:c:8b43:7ce6:34d1:c0fe

We have the same information as the ip addr command

The OSAs

In the devmap file the OSAs were defined as starting at 400 and 404. They each use 3 “wires”. One for reading, one for writing, and one for data (addresses 400, 401 and 402).

[manager]  # tap0 define network adapter (OSA) for communication with Linux
name awsosa 0009 --path=A0 --pathtype=OSD --tunnel_intf=y # QDIO mode
device 400 osa osa --unitadd=0
device 401 osa osa --unitadd=1
device 402 osa osa --unitadd=2
device 403 osa osa --unitadd=3


name awsosa 0010 --path=F1 --pathtype=OSD --interface=wlxcc641aee92c5
device 404 osa osa --unitadd=0
device 405 osa osa --unitadd=1
device 406 osa osa --unitadd=2
device 407 osa osa --unitadd=3
device 408 osa osa --unitadd=4
device 409 osa osa --unitadd=5
device 40a osa osa --unitadd=6

Where wlxcc641aee92c5 is the name of the wireless interface on Linux.

In the z/OS file ADCD.Z31B.VTAMLST(OSATRL2) is

OSATRL1 VBUILD TYPE=TRL                                                 
OSATRL1E TRLE LNCTL=MPC,READ=(0400),WRITE=(0401),DATAPATH=(0402), X
PORTNAME=PORTA, X
MPCLEVEL=QDIO
OSATRL2E TRLE LNCTL=MPC,READ=(0404),WRITE=(0405),DATAPATH=(0406,407), X
PORTNAME=PORTB, X
MPCLEVEL=QDIO

Where we have the same addresses 400 and 404.
You refer to these definitions using PORTA and PORTB.

PORTB uses data paths 0406 for the TCPIP IPv4 inerface, and 0407 for the IPv6 Interface.

You can use the VTAM command D NET,TRL to display the status of them

          d net,trl                                         
STC05323 IST097I DISPLAY ACCEPTED
STC05323 IST350I DISPLAY TYPE = TRL
------------------------------------------------------------
TRL MAJOR NODE = ISTTRL
TRLE = IUTIQDIO STATUS = NEVAC CONTROL = MPC
TRLE = IUTSAMEH STATUS = NEVAC CONTROL = MPC
2 TRLE(S) DISPLAYED
------------------------------------------------------------
TRL MAJOR NODE = OSATRL2
TRLE = OSATRL1E STATUS = ACTIV CONTROL = MPC
TRLE = OSATRL2E STATUS = ACTIV CONTROL = MPC

Define the TCP/IP interfaces

Current levels of TCP define interfaces with the “INTERFACE” statement. DEVICE and LINK statements are deprecated.

My wireless definitions ar

                                                
INTERFACE WIRE
DEFINE IPAQENET
CHPIDTYPE OSD
IPADDR 192.168.1.61
PORTNAME PORTB
START WIRE

INTERFACE WIRE6
DEFINE IPAQENET6
CHPIDTYPE OSD
IPADDR BT:a:b:c::2
PORTNAME PORTB
; INTERFACE WIRE6
; ADDADDR BT:a:b:c::1

START WIRE6

This defines both IPv4 and IPv6 interfaces, both using the same port PORTB

The interfaces are started

I chose these two addresses myself. These address show up in the NETSTAT HOME command.

After it has started

The TSO NETSTAT HOME command gave

Home address list: 
LinkName: LOOPBACK
Address: 127.0.0.1
Flags:
IntfName: TAP0
Address: 10.1.1.2
Flags: Primary
IntfName: WIRE
Address: 192.168.1.61
Flags:
IntfName: WIRE6
Address: BT:a:b:c::2
Type: Global
Flags:
Address: fe80::cc64:1a02:ee:92c5
Type: Link_Local
Flags: Autoconfigured
IntfName: LOOPBACK6
Address: ::1
Type: Loopback
Flags:

Where we see the interfaces and their IP addresses.

Define the TCP Routes

I created COLIN.TCPPARMS(S5ROUTE) with content

BEGINRoutes 
; Destination SubnetMask FirstHop LinkName Size
ROUTE 10.0.0.0 255.0.0.0 10.1.1.1 TAP0 MTU 1492
; Default to the internet
ROUTE DEFAULT 192.168.1.254 WIRE MTU 1492
;ROUTE DEFAULT6 fe80::6a2:22ff:feae:2871 WIRE6 MTU 5000
ENDRoutes

Note there is no DEFAULT6 entry – TCPIP works this out for itself. If you have more than one IPv6 interface you should uncomment the DEFAULT6 statement to ensure the traffic goes the right way.

I used the TCPIP console command v tcpip,,obey,COLIN.TCPPARMS(S5ROUTE) to activate the routing table. If you get it wrong, edit the member, save the changes, and issue the command again.

The TSO NETSTAT ROUTE command gave me

IPv4 Destinations 
Destination Gateway Flags Refcnt Interface
----------- ------- ----- ------ ---------
Default 192.168.1.254 UGS 0000000000 WIRE
10.0.0.0/8 0.0.0.0 US 0000000000 TAP0
10.1.1.2/32 0.0.0.0 UH 0000000000 TAP0
127.0.0.1/32 0.0.0.0 UH 0000000000 LOOPBACK
192.168.1.61/32 0.0.0.0 UH 0000000000 WIRE
IPv6 Destinations
DestIP: Default
Gw: fe80::6a2:22ff:feae:2871
Intf: WIRE6 Refcnt: 0000000000
Flgs: UGD MTU: 1492
DestIP: ::1/128
Gw: ::
Intf: LOOPBACK6 Refcnt: 0000000000
Flgs: UH MTU: 65535
DestIP: BT:a:b:c::/64
Gw: ::
Intf: WIRE6 Refcnt: 0000000000
Flgs: UD MTU: 1492
DestIP: BT:a:b:c::2/128
Intf: WIRE6 Refcnt: 0000000000
Flgs: UH MTU: 1492
DestIP: fe80::cc64:1a02:ee:92c5/128
Gw: ::
Intf: WIRE6 Refcnt: 0000000000
Flgs: UH MTU: 1492

Where fe80::6a2:22ff:feae:2871 is from the BT Hub IPv6 LAN details: Link local address:.

The command TSO NETSTAT ND gives the neighbour discovery. This gave me

Query Neighbor cache for fe80::6a2:22ff:feae:2871 
IntfName: WIRE6 IntfType: IPAQENET6
LinkLayerAddr: 04A222AE2871 State: Reachable
Type: Router AdvDfltRtr: Yes

Which shows what IPv6 neighbours have been discovered.

And finally – test it

I could use the TSO PING command to ping a server the internet. Check you can ping the address from Linux before you try it from z/OS, because some servers do not respond to ping requests.

Doing a wireshark trace of a successful ping showed the originator IP address was BT:a:b:c::2, the home address of interface WIRE6 in TCPIP on my z/OS image.

Connecting a zPDT z/OS to the internet using IPv4

I needed to get my ZD&T machine connected to the internet so it could download some files as part of an install. Note, while this allows my z/OS to contact the internet, externals machines cannot contact my machine.

As a follow-on to this Blog post I wrote Connecting a zPDT z/OS to the internet to using IPV6 which extends this post.

As usual there are many strands to this, so I wrote Understanding BT home hub and my IPv6 addresses to cover some of the background knowledge.

It took a while to get it working. It is based on scenario 4 of the zD&T documentation.

The configuration uses the wireless connection from my Linux server.

You need to know/configure the address of various end points. Some addresses are configured by the systems, some addresses you need to configure.

What’s my TCP configuration on Linux?

The command ip addr gave (displaying only the IP V4 entries)

1: lo: <...> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever

2: eno1: <...> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:...
altname enp0s31f6
inet 10.1.0.3/24 brd 10.1.0.255 scope global eno1
valid_lft forever preferred_lft forever

3: wlxcc641aee92c5: <...> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether cc:...
inet 192.168.1.139/24 brd 192.168.1.255 scope global dynamic noprefixroute wlxcc641aee92c5
valid_lft 80179sec preferred_lft 80179sec
noprefixroute
valid_lft 263sec preferred_lft 83sec
inet6 fe80::7bfc:5da1:8c80:37a4/64 scope link noprefixroute
valid_lft forever preferred_lft forever
5: tap0: <...> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
link/ether 46:...
inet 10.1.1.1/24 brd 10.1.1.255 scope global tap0
valid_lft forever preferred_lft forever

Where

  • lo is the loop back address.
  • eno1 is the connection over an Ethernet cable to my laptop with the address (on this linux machine) 10.1.0.3. The address of the other end of the Ethernet, on my laptop, is 10.1.0.2
  • wlxcc641aee92c5 is the wireless connection to my router and the outside world. The IP address of the Linux server end is 192.168.1.139.
  • tap0 is the tunnel interface to z/OS from the base linux machine. It has address 10.1.1.1

I think these end point addresses were all generated for me.

Linux Settings

I believe that you need some Linux settings. Having repeated the scenario, it works even when the values described where set to 0, so the guidance in this section may not be relevant.

sysctl net.ipv4.ip_forward

to display the value. It needs to be 1. You can set it using

sudo sysctl -w net.ipv4.ip_forward=1
#sudo sysctl -w net.ipv6.conf.all.forwarding=1

You can do commands like

sysctl -a |grep v4
sysctl -a |grep v6

My devmap

The devmap file contains the definitions of the emulated devices. For the OSA I had

[manager]  # tap0 define network adapter (OSA) for communication with Linux
name awsosa 0009 --path=A0 --pathtype=OSD --tunnel_intf=y # QDIO mode
device 400 osa osa --unitadd=0
device 401 osa osa --unitadd=1
device 402 osa osa --unitadd=2

name awsosa 0010 --path=F1 --pathtype=OSD --interface=wlxcc641aee92c5
device 404 osa osa --unitadd=0
device 405 osa osa --unitadd=1
device 406 osa osa --unitadd=2
device 407 osa osa --unitadd=3
device 408 osa osa --unitadd=4
device 409 osa osa --unitadd=5

Where the –interface is the same name as my wireless interface (see above).

When I used IPv6 as well as IPv4, there were two TCPIP Interface on the same OSA. I need address 406 and 407 for one interface, and 408 and 409 for the other interface. The TCPIP documentation does not say this.

Find_io

The find_io command gives the network configuration known by the emulation code.

FIND_IO for "colin@colin-ThinkCentre-M920s" 

Interface Current MAC IPv4 IPv6
Path Name State Addr Address Address
------ ---------------- ---------------- ---- ------------- --------------
F0 eno1 UP, RUNNING 00:.. 10.1.0.3 fe80::...%eno1
F1 wlxcc641aee92c5 UP, RUNNING cc:.. 192.168.1.139 2a00:...
A0 tap0 UP, RUNNING 46:.. 10.1.1.1 fe80::...@tap0
...

End of FIND_IO

This is the same information as the ip addr command

The OSAs

In the devmap file the OSAs were defined as starting at 400 and 404. One for reading, one for writing, and several for data.

In the z/OS VTAM file ADCD.Z31B.VTAMLST(OSATRL2) (below) defines two OSAs.

The first is for my Ethernet. This has one TCPIP Interface, and so paths 402 and 403 for the data.

The second is for the wireless connection. This has two TCPIP interfaces one for IPV4 and one for IPv6. One uses path (406,407), the other uses(408,409). These addresses must match the devmap definitions.

OSATRL1 VBUILD TYPE=TRL                                                 
OSATRL1E TRLE LNCTL=MPC,READ=(0400),WRITE=(0401),DATAPATH=(0402), X
PORTNAME=PORTA, X
MPCLEVEL=QDIO
OSATRL2E TRLE LNCTL=MPC,READ=(0404),WRITE=(0405),DATAPATH=(0406,407), X
PORTNAME=PORTB, X
MPCLEVEL=QDIO


You refer to these definitions using PORTA and PORTB in the TCPIP interfaces

You can use the VTAM command D NET,TRL to display the status of them

          d net,trl                                         
STC05323 IST097I DISPLAY ACCEPTED
STC05323 IST350I DISPLAY TYPE = TRL
------------------------------------------------------------
TRL MAJOR NODE = ISTTRL
TRLE = IUTIQDIO STATUS = NEVAC CONTROL = MPC
TRLE = IUTSAMEH STATUS = NEVAC CONTROL = MPC
2 TRLE(S) DISPLAYED
------------------------------------------------------------
TRL MAJOR NODE = OSATRL2
TRLE = OSATRL1E STATUS = ACTIV CONTROL = MPC
TRLE = OSATRL2E STATUS = ACTIV CONTROL = MPC

Define the TCP/IP interfaces

Current levels of TCP define interfaces with the “INTERFACE” statement. DEVICE and LINK statements are deprecated.

My definitions for IPv4 are

 INTERFACE TAP0 
DEFINE IPAQENET
CHPIDTYPE OSD
IPADDR 10.1.1.2
PORTNAME PORTA
START TAP0

INTERFACE WIRE
DEFINE IPAQENET
CHPIDTYPE OSD
IPADDR 192.168.1.61
PRIROUTER
PORTNAME PORTB
START WIRE

This defines an interface TAP0 using the PORTA definitions above, and gives the z/OS end of the connection the address 10.1.1.2. From my laptop I can ping 10.1.1.2, it gets routed to the Linux server, and into z/OS.

The interface is started

Another interface WIRE is defined using PORTB and the z/OS end of the connection is 192.168.1.61

I chose these two addresses myself. These address show up in the NETSTAT HOME command.

After it has started

The TSO NETSTAT HOME command gave

MVS TCP/IP NETSTAT CS 3.1     
Home address list:
LinkName: LOOPBACK
Address: 127.0.0.1
Flags:
IntfName: TAP0
Address: 10.1.1.2
Flags: Primary
IntfName: WIRE
Address: 192.168.1.61
Flags:

Where we see the interfaces and their IP addresses.

Define the TCP Routes

I created COLIN.TCPPARMS(S5ROUTE) with content

BEGINRoutes 
; Destination SubnetMask FirstHop LinkName Size
ROUTE 10.0.0.0 255.0.0.0 10.1.1.1 TAP0 MTU 1492
ROUTE 192.168.1.0 255.255.255.0 = WIRE MTU 1492
ROUTE DEFAULT 192.168.1.254 WIRE MTU 1492
ENDRoutes

This says for the destination IP address if it is

  • anything beginning with 10. (from the subnet mask 255.0.0.0) send it over interface TAP0. The command ip addr shows tap0 with inet 10.1.1.1/24 brd 10.1.1.255
  • anything with address 192.168.1.something (from the subnet mask 255.255.255.0) sent it over interface WIRE (note: in this case this definition is redundant because of the default below).
  • anything else, send it down the DEFAULT definition over interface WIRE. The IP address of my wireless router is 192.168.1.254. Initially I had a different address – the address in the find_io. After several pings which timed out, ping worked. It is better to specify the address of the router/hub.

I used the TCPIP console command v tcpip,,obey,COLIN.TCPPARMS(S5ROUTE) to activate the routing table. If you get it wrong, edit the member, save the changes, and issue the command again.

The TSO NETSTAT ROUTE command gave me

IPv4 Destinations 
Destination Gateway Flags Refcnt Interface
----------- ------- ----- ------ ---------
Default 192.168.1.254 UGS 0000000000 WIRE
10.0.0.0/8 0.0.0.0 US 0000000000 TAP0
10.1.1.2/32 0.0.0.0 UH 0000000000 TAP0
127.0.0.1/32 0.0.0.0 UH 0000000000 LOOPBACK
192.168.1.61/32 0.0.0.0 UH 0000000000 WIRE

And finally – test it

I could use the TSO PING command to ping a server the internet. Check you can ping the address from Linux before you try it from z/OS, because some servers do not respond to ping requests.

Useful commands

On Linux

  • ip addr
  • ip route

On z/OS

VTAM operator commands
  • D NET,TRL
  • d net,trl,trle=OSATRL2E This gives information such as which OSA data ports are being used, by with TCPIP interfaces.
  • D NET,ID=…
  • D NET,ID=…,E
  • V NET,ACT,ID=….
  • V NET,INACT,ID=….
TCPIP operator commands
  • v tcpip,,obey,… for example COLIN.TCPPARMS(S5ROUTE)

TSO commands

  • TSO NETSTAT HOME
  • TSO NETSTAT ROUTE
  • TSO PING x.x.x.x
  • TSO TRACERTE x.x.x.x

Some problems I experienced

A ping did not get a response back

A wireshark trace of the wireless interface showed the ping request had an originator IP address of 10.1.1.2. This was caused by having the wrong routing table

MVS TCP/IP NETSTAT CS 3.1       TCPIP Name: TCPIP           17:10:28 
IPv4 Destinations
Destination Gateway Flags Refcnt Interface
----------- ------- ----- ------ ---------
Default 10.1.1.1 UGS 0000000000 TAP0
10.0.0.0/8 0.0.0.0 US 0000000000 TAP0
10.1.0.0/24 10.1.1.1 UGS 0000000000 TAP0
10.1.1.2/32 0.0.0.0 UH 0000000000 TAP0
127.0.0.1/32 0.0.0.0 UH 0000000000 LOOPBACK
192.168.1.61/32 0.0.0.0 UH 0000000000 WIRE

The default routing was via TAP0

The NETSTAT HOME gave

 MVS TCP/IP NETSTAT CS 3.1       TCPIP Name: TCPIP       
Home address list:
LinkName: LOOPBACK
Address: 127.0.0.1
Flags:
IntfName: TAP0
Address: 10.1.1.2
Flags: Primary
IntfName: WIRE
Address: 192.168.1.61
Flags:

So the IP address of the TAP0 interface was 10.1.1.2, and this was used as the originating end point.

Any nodes on the route to the destination do not know where 10.1.12 is located …. 10.*.*.* it is usually an address on the local machine, and so you get no response back.

With the address 192.168.1.xx the wireless router converts it to the router’s own address, and so the intermediate nodes on the journey can use the hub’s IP address, and the reply gets back to the wireless router.

Ping failed – nothing in wireshark

  INTERFACE WIRE 
DEFINE IPAQENET
CHPIDTYPE OSD
IPADDR 192.168.1.60
PRIROUTER
VLANID 2
PORTNAME PORTB

I had VLANID 2 … when I removed this statement it worked.

Sessions failed to start

When I started TCPIP I got the message

EZZ4336I ERROR DURING ACTIVATION OF INTERFACE WIRE – CODE 8010002A DIAGNOSTIC CODE 02

Using the command D U,,,400,8 showed

UNIT TYPE STATUS        VOLSER     VOLSTATE      SS  
0400 OSA A-BSY 0
0401 OSA A 0
0402 OSA A-BSY 0
0403 OSA O 0
0404 OSA OFFLINE 0
0405 OSA OFFLINE 0
0406 OSA OFFLINE 0
0407 OSA OFFLINE 0

This shows the second OSA was not available (it was offline). I found I had misconfigured the OSA with addresses (404, 405, and 406) in my devmap.

Not for humans but for search engines – Comms server

Below are messages I’ve experienced and my solutions

IST1578I DEVICE INOP DETECTED FOR … BY ISTTSCMA CODE = 104

and

EZZ4338I ERROR REPORTED ON INTERFACE … – CODE 80100040
DIAGNOSTIC CODE 03

I was trying to get IPV4 and IPV6 interfaces to work with one OSA.

With

OSATRL1 VBUILD TYPE=TRL 
OSATRL2E TRLE LNCTL=MPC,READ=(0404),WRITE=(0405),DATAPATH=(0406,407), X
PORTNAME=PORTB, X
PORTNUM=1, X
MPCLEVEL=QDIO

it produced the above messages

with

OSATRL1 VBUILD TYPE=TRL 
OSATRL2E TRLE LNCTL=MPC,READ=(0404),WRITE=(0405),DATAPATH=(0406,408), X
PORTNAME=PORTB, X
PORTNUM=1, X
MPCLEVEL=QDIO

so with two paths 406 and 408, instead of 406 and 407, it worked!

My zD&T devmap had

name awsosa 0010 --path=F1 --pathtype=OSD  --interface=wlxcc641aee92c5 
device 404 osa osa --unitadd=0
device 405 osa osa --unitadd=1
device 406 osa osa --unitadd=2
device 407 osa osa --unitadd=3
device 408 osa osa --unitadd=4
device 409 osa osa --unitadd=5
device 40a osa osa --unitadd=6

Where wlxcc641aee92c5 is my Linux wireless interface.
find_io gave me

         Interface         Current    MAC         IPv4          IPv6           
Path Name State Address Address Address
------ ---------------- ---------- ---------- ----------- --------------
...
F1 wlxcc641aee92c5 UP, RUNNING cc:64:... 192.168.1.61 2a00:23c5:...

EZZ4203I Z/OS UNIX – TCP/IP CONNECTION ERROR FOR TCPIP-BPX4SOC, 00000003, FFFFFFFF, 00000070 ,112B00B6

This had the wrong definition in BPXPRMxx see https://www.ibm.com/support/pages/apar/II12338. I had entries for TYPE(CINET) when I needed only INET

Using the z/OS DNS on ADCD

This came out of a question. It is another of the little questions that get much bigger.

Background to Domain Name System(DNS)

DNS allows you to get an IP address from a string such as “WWW.MY.COM”.

You can have some files on your local system which provide this mapping, or you can exploit DNS Servers in the big internet.

Some people configure their system so it tries the internet first, and if that fails, uses local files.

You can do reverse DNS lookup, mapping an IP address to a string. For example you want to allow access from sites in WWW.MYFRIEND.COM. When a connection is started, you get the IP address, and can then do a reverse DNS lookup to get a name, which you can check in your “allow” list.

DNS commands for the end user

You can use the “old” tso command NSLOOKUP http://www.ibm.com, or the “new” command dig http://www.ibm.com. Neither of which seemed to give me any output!

The NSLOOKUP and DIG commands send their output to SYSOUT. In my TSO system, SYSOUT has been configured to JES. If I use SDSF, and display the output of my TSO userid, there is a SYSOUT, with the output in it!

NSLOOKUP

The NSLOOKUP command

NSLOOKUP http://www.my.com

NSLOOKUP http://www.my.com this.dns.site

NSLOOKUP 10.1.1.2

Tracing a DNS request

This does not provide much useful information! It does not tell you what happened, or what failed. It is described here.

Starting and stopping the DNS

This is not obvious. At IPL the ADCD.Z24C.PARMLIB(BPXPRM00) member has

RESOLVER_PROC(RESOLVER)

the resolver procedure must be in a data set that is specified by the IEFPDSI DD card specification of the MSTJCLxx PARMLIB member.

If you use D A,L it does not show up.

D A,RESOLVER gives you the normal output.

When I issued

P RESOLVER
S RESOLVER

It used the RESOLVER procedure from USER.Z24C.PROCLIB, the normal concatenation.

Displaying and changing the configuration.

You can display some of the current resolver configuration using

f resolver,display

The output is like

EZZ9298I RESOLVERSETUP - USER.Z24C.TCPPARMS(GBLRESOL)                   
EZZ9298I DEFAULTTCPIPDATA - USER.Z24C.TCPPARMS(GBLTDATA)                
EZZ9298I GLOBALTCPIPDATA - /etc/resolv.conf                             
EZZ9298I DEFAULTIPNODES - ADCD.Z24C.TCPPARMS(ZPDTIPN1)                  
EZZ9298I GLOBALIPNODES - /etc/hosts                                     
EZZ9304I COMMONSEARCH                                                   
EZZ9304I CACHE                                                          
EZZ9298I CACHESIZE - 200M                                               
EZZ9298I MAXTTL - 2147483647                                            
EZZ9298I MAXNEGTTL - 2147483647                                         
EZZ9304I NOCACHEREORDER                                                 
EZZ9298I UNRESPONSIVETHRESHOLD - 25                                     

The only way I could display all of the resolver configuration was to get a resolver trace!

//IBMRESO JOB 1,MSGCLASS=H 
//S1  EXEC PGM=IKJEFT01,REGION=0M 
//SYSPRINT DD SYSOUT=* 
//SYSTSPRT DD SYSOUT=* 
//SYSTCPT DD SYSOUT=* 
//SYSPRINT DD SYSOUT=* 
//SYSTSIN DD * 
NSLOOKUP 99.99.99.99 
/* 

This gave me in //SYSTCPT

Resolver Trace Initialization Complete -> 2023/02/26 18:01:56.725504                      
res_init Parse error on line 1: /etc/resolv.conf

res_init Resolver values:
Setup file warning messages = No
CTRACE TRACERES option = No
Global Tcp/Ip Dataset = /etc/resolv.conf
Default Tcp/Ip Dataset = USER.Z24C.TCPPARMS(GBLTDATA)
Local Tcp/Ip Dataset = None
Translation Table = TCPIP.STANDARD.TCPXLBIN
UserId/JobName = IBMUSER
Caller API = TCP/IP C Sockets
Caller Mode = EBCDIC
System Name = S0W1 (from VMCF)
UnresponsiveThreshold = 25
(D) DataSetPrefix = TCPIP
(D) HostName = S0W1
(D) TcpIpJobName = TCPIP
(*) DomainOrigin = None
(*) NameServer(s) = None
(*) NsPortAddr = 53 (*) ResolverTimeout = 5
(*) ResolveVia = UDP (*) ResolverUdpRetries = 1
(*) Options NDots = 1
(D) Trace Resolver (*) SockNoTestStor
(D) AlwaysWto = NO (D) MessageCase = MIXED
(*) LookUp = DNS LOCAL
(*) Cache
(*) NoCacheReorder
res_init Succeeded
res_init Started: 2023/02/26 18:01:56.794280
res_init Ended: 2023/02/26 18:01:56.794305

This is documented here.

The source of the value is

  • (*) Default value
  • (A) Modified by application
  • (D) Default file (not used if the local file is found)
  • (E) Environment variable
  • (G) Global file
  • (L) Local file

This means the “LookUp = DNS LOCAL ” value came from the default value.

The resolver JCL in USER.Z24C.PROCLIB had

//SETUP DISP=SHR,DSN=USER.Z24C.TCPPARMS(GBLRESOL)

When I changed this member to have LOOKUP LOCAL DSN, and used the F RESOLVER,REFRESH command, this changed the value.

Sample hosts file

The sample host file in TCPIP.SEZAINST(HOSTS) has

; The format of this file is documented in RFC 952, "DoD Internet 
; Host Table Specification". 
; 
; The format for entries is: 
; 
; NET : ADDR : NETNAME : 
; GATEWAY : ADDR, ALT-ADDR : HOSTNM : CPUTYPE : OPSYS : PROTOCOLS : 
; HOST : ADDR, ALT-ADDR : HOSTNM, NICKNM : CPUTYPE : OPSYS : PROTOCOLS : 
; 
; Where: 
;   ADDR, ALT-ADDR = IP address in decimal, e.g., 26.0.0.73 
;   HOSTNM, NICKNM = the fully qualified host name and any nicknames 
;   CPUTYPE = machine type (PDP-11/70, VAX-11/780, IBM-3090, C/30, etc.) 
;   OPSYS = operating system (UNIX, TOPS20, TENEX, VM/SP, etc.) 
;   PROTOCOLS = transport/service (TCP/TELNET,TCP/FTP, etc.) 
;   : (colon) = field delimiter 
;   :: (2 colons) = null field 
; *** CPUTYPE, OPSYS, and PROTOCOLS are optional fields. 
; 
;   MAKESITE does not allow continuation lines, as described in 
;   note 2 of the section "GRAMMATICAL HOST TABLE SPECIFICATION" 
;   in RFC 952.  Entries should be specified on a single line of 
;   up to a maximum of 512 characters per line. 
HOST : 129.34.128.245, 129.34.128.246 : YORKTOWN, WATSON :::: 
; 
NET  : 9.67.43.0 : RALEIGH.IBM.COM : 
; 
GATEWAY : 129.34.0.0 : YORKTOWN-GATEWAY :::: 

Unix application trace

Enable the trace by issuing the Unix command

export RESOLVER_TRACE=~/trace

Run the command

pip install mfpandas      

gave

-[33mWARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x500B209580>: 
Failed to establish a new connection:
[Errno 1] EDC9501I The name does not resolve for the supplied parameters.')': /simple/mfpandas/-[0m-[33m

Look at the trace file

oedit trace

gave

GetAddrInfo Started: 2025/11/25 15:58:36.890589 
GetAddrinfo Invoked with following inputs:
Host Name: pypi.org
Service Name: 443
Hints parameter supplied with settings:
ai_family = 0, ai_flags = 0x00000000
ai_protocol = 0, ai_socktype = 1
No NameServers specified, no DNS activity
GetAddrInfo Opening Socket for IOCTLs
BPX1SOC: RetVal = 0, RC = 0, Reason = 0x00000000, Type=IPv4
BPX1IOC: RetVal = 0, RC = 0, Reason = 0x00000000
GetAddrInfo Opened Socket 0x00000005
GetAddrInfo Only IPv4 Interfaces Exist
GetAddrInfo Searching Local Tables for IPv6 Address
Global IpNodes Dataset = ADCD.Z31B.TCPPARMS(ZPDTIPN1)
Default IpNodes Dataset = ADCD.Z31B.TCPPARMS(ZPDTIPN1)
Search order = CommonSearch
BPX1ENV Get _BPXK_AUTOCVT: RetVal = 0, RC = 0, Reason = 0x00000000
_BPXK_AUTOCVT current value is ON
BPX1ENV Set _BPXK_AUTOCVT: RetVal = 0, RC = 0, Reason = 0x00000000
_BPXK_AUTOCVT set to OFF
Parse error on line 22: ADCD.Z31B.TCPPARMS(ZPDTIPN1)
SITETABLE from globalipnodes ADCD.Z31B.TCPPARMS(ZPDTIPN1)
- Lookup for pypi.org
GetAddrInfo Searching Local Tables for IPv4 Address
- Lookup for pypi.org
GetAddrInfo Searching Local Tables for IPv6 Address
- Lookup for pypi.org.DAL-EBIS.IHOST.COM
GetAddrInfo Searching Local Tables for IPv4 Address
- Lookup for pypi.org.DAL-EBIS.IHOST.COM
GetAddrInfo Closing IOCTL Socket 0x00000005
BPX1CLO: RetVal = 0, RC = 0, Reason = 0x00000000
GetAddrInfo Failed: RetVal = -1, RC = 1, Reason = 0x78AE1004
GetAddrInfo Ended: 2025/11/25 15:58:36.904995

EDIT       /etc/hosts
Command ===>
****** ******************************************************* Top
==MSG> -Warning- The UNDO command is not available until you chang
==MSG> your edit profile using the command RECOVERY ON.
000001 # BEGIN ANSIBLE MANAGED BLOCK
000002 #72.26.1.2 s0w1.dal-ebis.ihost.com S0W1
000003 127.0.0.1 localhost
000004 # END ANSIBLE MANAGED BLOCK
000005 #IPAddress Hostname alias
000006 151.101.128.223 pypi.org pip

Why can’t I connect to a z/OS port?

I’ve found couple of those little problems which took me a day to resolve – but which are obvious when you understand the problem.

The problems

I was trying to connect the Health Center in Eclipse to the Health agent in Liberty on z/OS.

The first problem was the health center agent on z/OS could not connect to the port. This was due to bad TCPIP configuration

The second problem was I could not connect to it from Eclipse. I had configured the port to be on the local rather than external interface.

My setup

In my jvm.options I had

-Xhealthcenter:level=off,readonly=off,jmx=on,port=1972

Problem 1: The health center agent on z/OS could not connect to the port

In the Liberty startup output I received (after about a timeout of about a minute)

SEVERE: Health Center agent failed to start. java.io.IOException: Cannot bind to URL [rmi://S0W1:1972/jmxrmi]: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host:

Where my system is called S0W1.

It is trying to connect to system S0W1 port 1972, and failing.

TSO PING S0W1 gave

 CS 3.1: Pinging host S0W1.DAL-EBIS.IHOST.COM (172.26.1.2)
Ping #1 timed out

This was a surprise to me – I was expecting it to be my local z/OS machine…. I do not have an interface with address 172.26.1.2. This explains why it timed out.

In my ADCD.Z31B.TCPPARMS(GBLTDATA) I had

S0W1:   HOSTNAME   S0W1 
;
;
; NOTE - Use either DOMAINORIGIN/DOMAIN or SEARCH to specify your domain
; origin value
;
; DOMAINORIGIN or DOMAIN statement
; ================================
; DOMAINORIGIN or DOMAIN specifies the domain origin that will be
; appended to host names passed to the resolver. If a host name
; ends with a dot, then the domain origin will not be appended to the
; host name.
;
DOMAINORIGIN DAL-EBIS.IHOST.COM

Because S0W1 did not end with a dot – TCPIP put the DOMAINORIGIN on the end.

ADCD.Z31B.TCPPARMS(ZPDTIPN1)

had

172.26.1.2 S0W1.DAL-EBIS.IHOST.COM S0W1      
127.0.0.1 LOCALHOST

Which says for S0W1…. use IP address 172.26.1.2.

I changed this to

S0W1:   HOSTNAME   S0W1.
   127.0.0.1       S0W1        
127.0.0.1 LOCALHOST

With these changes, I restarted TCPIP, and told the resolver to use the updated configuration.

F RESOLVER,REFRESH,SETUP=ADCD.Z31b.TCPPARMS(GBLRESOL)

I then got

INFO: Health Center agent started on port 1972.

So my first success. However…

Problem 2 : I could not connect Eclipse to the port

… once I had managed to get get the server to connect to the port. When the server issues a TCPIP binds to a port, you need to specify the IP address and port. I had configured the hostname S0W1 as the local interface (127.0.0.1). When I tried to connect from Eclipse, I was trying to connect to port 1972 on interface 10.1.1.2 – which had not been configured!

The Liberty output had

WARNING: RMI TCP Accept-1972: accept loop for erverSocket[addr=0.0.0.0/0.0.0.0, localport=1972] throws java.io.IOException: EDC5122I Input/output error. (errno2=0x12B804B9)

I changed ADCD.Z31B.TCPPARMS(ZPDTIPN1) to have

10.1.1.2 S0W1
127.0.0.1 LOCALHOST

so the name S0W1 is associated with interface 10.1.1.2. I started restart TCPIP and the resolver and it manage to connect. It only took a day to resolve these problems.

Not for humans – AT-TLS and security messages

EZD1287I TTLS Error RC: 6 Initial Handshake

6 Key label is not found

My server certificate was in the keyring, but it had expired. I renewed it, and got past this.

EZD1287I TTLS 403 No certificate received from partner.

403 No certificate received from partner.

In my curl request I did not have –cert ./colinpaice.pem:password –key ./colinpaice.key.pem, when the server expected a certificate (gpmserve had CLIENT_CERT(ACCEPT)).

My z/OS had HandshakeRole ServerWithClientAuth, but the client did not provide a certificate.

EZD1287I TTLS Error RC: 428 Initial Handshake

The private key cannot be obtained from the certificate.

The server userid needs access to the keyring. If the private key belongs to the server’s userid, then the server’s userid needs read access to the keyring. If the private key belongs to a different userid, the server’s userid needs update access to the keyring. See here for more information.

EZD1287I TTLS Error RC: 435 Initial Handshake

435 Certification authority is unknown.

I got this having replaced the CA certificate. Deleting a certificate removes it from any keyring. When you recreate the CA, you need to add it to every keyring it was in. Before deleting a certificate it is worth listing it to see where it is used. I added it to my keyring and it worked!

EZD1287I TTLS Error RC: 510 No acceptable key labels found

510 No acceptable key labels found

My server certificate was in the keyring, but it did not have the capabilities to support the handshake. For example client only supported RSA, but server was ECC.

pthread_security_np, pthread_security_app_np

This function call can be used to map a certificate to a userid.

I got

ESRCH (143): The user ID provided as input is not defined to the security product or does not have an OMVS segment defined.

errno2 0be8044c. Code 044c is JRNoCertforUser, There is no userid defined for this certificate. Action: Ensure the userid is known to the SAF service.


You also get this message if the mapping from certificate to userid is missing. For example

RACDCERT DELMAP(LABEL('IBMUSER1Label))ID(IBMUSER)
RACDCERT MAP ID(IBMUSER) -
WITHLABEL('IBMUSER1Label') -
SDNFILTER('CN=colinpaice.O=cpwebuser.C=GB')
RACDCERT LISTMAP ID(IBMUSER)
SETROPTS RACLIST(DIGTNMAP, DIGTCRIT) REFRESH

R_ticketserv (IRRSPK00): Parse or extract 8, 16, 28

I was using the service to generate a pass token, and got SAF 8 RACF 16 RS 28.

Unable to generate PassTicket. Verify that the secured signon (PassTicket) function and
application ID is configured properly by referring to Using PassTickets in z/OS Security Server RACF Security Administrator’s Guide.

Action

I needed to define

RALTER  PTKTDATA MYAPPL  SSIGNON(KEYMASKED(7E4304D681920260)) - 
APPLDATA('NO REPLAY PROTECTION')

Where MYAPPL is the application name.

R_ticketserv (IRRSPK00): Parse or extract 8, 8, 16

With userid = “ADCBD” and APPL = ” MVSS0W1″ I got SAF 0 RACF 0 RS 0.

With userid = “ADCBD” and APPL = ” TSOS0W1″ I got SAF 8 RACF 8 RS 16. Not authorized to use this service.
I used

RDEFINE PTKTDATA   IRRPTAUTH.TSOS0W1.*  UACC(NONE) 

and it worked

EZD1287I TTLS Error RC: 467 Initial Handshake

Running from Python – a request worked. Running from Chrome gave me the above message.
I solved it by making the connection TLS 1.3 ON and TLS 1.2 OFF

The doc (Cryptographic Services System Secure Sockets Layer Programming)

says

467 Signature algorithm not in signature algorithm pairs list.
Explanation
A signature algorithm that is used to sign a local or peer certificate is not included in the signature algorithm pairs list or the certificate signature algorithm pairs list. The server certificate chain must use signature algorithms included in the signature algorithm pairs or the certificate signature algorithm pairs that are presented by the client during the TLS handshake. The client certificate chain must use signature algorithms included in the signature algorithm pairs or the certificate signature algorithm pairs that are presented by the server during the TLS handshake. If remote partner specifies the signature algorithm pairs and the certificate signature algorithm pairs, the specified certificate signature algorithm pairs take precedence over the signature algorithm pairs. For TLS V1.2 handshakes, the GSK_TLS_CERT_SIG_ALG_PAIRS setting is only used on the client
side to indicate the signature algorithms that the client supports in the server’s certificate chain.
User response
Ensure that the signatures of the local and peer certificates in the certificate chain use signature algorithms that are present in the signature algorithm pairs list or the certificate signature algorithm pairs list that is presented by the session partner. If the certificate chain is correct, configure the client or server or both to specify all necessary signature algorithms pairs in the GSK_TLS_SIG_ALG_PAIRS or SK_TLS_CERT_SIG_ALG_PAIRS
settings to allow use of the certificate chain. If GSK_TLS_CERT_SIG_ALG_PAIRS is specified, it takes precedence while checking the signature algorithms used in the certificate chain.

Zowe: Planning: How do I protect what Zowe users can do on z/OS?

As part of my planning for Zowe, I wanted to know how I could control what Zowe users can do on z/OS. I could not find any definitions for security profiles, so how do I do it?

It took a few days thinking about this to realise I was looking a the problem the wrong way. The correct way of looking at it, is that Zowe is a transport system for getting requests from a user’s work station to z/OS. This is similar to a 3270 emulator connection to z/OS. You control what the userid can do, and do not try to control what the 3270 emulator can do.

When a userid logs on to TSO through a 3270 emulator, z/OS knows the userid of the address space, and can control access to what resources the userid can access.

When a userid logs on to Zowe there are two paths that can be taken:

  • Zowe can create a TSO address space for the userid, using the CEA facilities. The z/OS® CEA TSO/E address space manager provides services to programmatically start and manage TSO/E address spaces and provides a communications mechanism for use between the caller and the programs running in these managed address spaces.
  • A thread within Zowe can use the pthread_security and change the userid of that thread. It can use your certificate, or a userid and password to validate the user. At the end of the request it resets the userid back.

From a permissions perspective, it does not matter if request came into a TSO address space or as a result of the pthread_security request. The userid is extracted and normal SAF processing is used to manage access to a resource.

But…

Your system may have IPSEC rules which police traffic into and out of TCP/IP on z/OS, for example allow traffic from these external IP address during 0900 to 1700 Monday to Friday, and deny access at any other time.

You might need to have similar rules for connectivity through Zowe. There are several ports used by Zowe and z/OSMF. You need to review what controls you need for these ports to stop unwanted traffic from accessing your system.

How do you get into the well protected castle? – you tunnel

Before I retired, if I wanted access to the corporate systems, I would start up a tool (vpn/dialer) which set up an encrypted session to the corporate front end, and tunnel through this to get to the back end. It was transparent and was like being directly attached.

How do you set up your castle to allow authorised people in – but deny access to unauthorised access?

If you logon directly to a back-end server from a cafe or other public WiFi, your credentials etc may be in the clear. You need to use “a secure app” such as banking app, or provide a vpn or tunnel to access your system to encrypt the traffic.

I’ve been logging on to someone else’s system and most of the useful connections to this are disabled. I could access via 3270 but could not use FTP etc.

I was trying to debug a TLS problem and found suspicious evidence in the trace. A connection was being made to the TLS port on my server, and failing because it did not speak TLS. Someone had clearly found the IP address of my system, and was trying all ports to get in!

How do you protect the system and keep unwanted people out – but allow authorised people to connect. You need to do both of…

Secure tunnelling

You could use TLS to protect the conversation between client and server, but this means you have allowed the connection to get through TCP/IP and to your application before checking to see if the connection is permitted.

Port forwarding or tunnelling controls access to your system at the outer edge of your system, logically within TCP/IP, before it gets to your application. It is well described here.

I used the SSH command

ssh -N -L 9876:12.23.34.45:8765 colin@23.34.45.56 -p 2222

If I used address https://localhost:9876 in my web browser, I am connected to 12.23.34.45:8765 through system 23.34.45.56 .

Where

  • -N says port forwarding
  • my local port 9876 is linked to 12.23.34.45 port 8765
  • via IP address 23.34.45.56. Think of this as the guard house.
  • colin is the userid. You get prompted for your password.
  • use port 2222 at the guard house. Think of multiple entrances to the guard house. “General public” “special guest” “people who work here”. The port says go to the “special guest” door. The first time, you have to successfully logon with your userid and password to get your details recorded as a valid visitor to the site. You are given a token which is saved for next time you want access (think of it as a visitor badge).

What is IPSEC?

IPSEC is part of Communications Server on z/OS. It provides

  • IP filtering to control which packets can enter the system
  • IP filtering to control which packets can leave the system

You can filter on

  • packet information – allow a ping, but not FTP
  • network attributes – only allow from a list of IP address
  • time – at certain times of day. For example a normal working day – so if someone is trying to access this system at two o’clock in the morning, this would be worth investigating.

You can

  • allow
  • deny
  • log

You need to be careful setting the rules up – if you want to allow traffic in from 1.2.3.4, then you need to allow traffic out to address 1.2.3.4

My rule

I would set up an input rule like

For input port 8765 deny all access, all packet types, all hours of the day.

Using the tunnel needs a little care

The browser validates the certificate sent from the server. If there ALTNAME, the client(browser) should check that the IP address specified in the ALTNAME matches the IP address used in the original URL, and your connection has not been high jacked.

In my browser I used https://127.0.0.1:9876, where 9876 was specified in the ssl command above. The certificate at the server had ALTNAME with IP address of 127.0.0.1, and so this was considered valid. The IP ALTNAME IP adddress is usually the IP address of the server (or one of them if there are more than one) so you may get messages saying an insecure certificate is being used. You can accept this, or configure your browser to ignore these checks (which is not a good idea)

Thanks

Thanks to Lionel Dyck and Randy Rackov for their help in this blog post.

How to get a file from z/OS to a different z/OS without using FTP

I have a userid on a z/OS production system, which does not support FTP. To run my tests, I needed to get some files on to this system. Getting the files there was a challange.

The 3270 emulator has support for transferring files. It uses the IND$FILE TSO command to send data packaged as 3270 datastream As far as I can tell, this only works with data sets, not Unix files.

Creating a portable file from a data set.

You can package a data set into a FB Lrecl 80 dataset using the TSO XMIT (TRANSMIT) command.

Create a portable dataset from a Unix file.

On my home system I created a PAX dataset from a file in a Unix directory.

Use cd to get into the directory you want to package. If you specify a file name like /tmp/mypackage, the unpax will store the output in /tmp/mypackage which may not be where you want to store the data.

If you use relative directories such as ‘.’ it will unpax into a relative directory. I used the cd command to get into my working directory

pax -W "seqparms='space=(cyl,(10,10))'" -wzvf  "//'COLIN.ZOWE.PAX'" -x os390  myfile

You need both the single and double quotes around the data set name.

This created a data set with record format FB, and Lrecl 80.

A 360 MB file became a 426 CYL data set.

If you run out of space ( B37-04 abend). Delete the dataset before you reissue the pax command, otherwise the space parameters on the pax command are ignored; and increase the amount of space in the pax command.

I FTPed this down to my Linux machine in binary mode.

Send the file to the remote z/OS over 3270 emulator

Because FTP was not available I had to use the TSO facility IND$FILE. One of the options from the “file” menu was “File Transfer”.

You fill in details of the local file name, the remote data set name, and data set attributes.

In theory you need to be in TSO option 6 – where you can enter TSO commands, but when I tried this I kept getting “input field too small”. I had to exit ISPF and get into native TSO before the command worked.

The transfer rate is very slow. It sends one block at a time, and waits for the acknowledgement. With TCP/IP you can send multiple blocks before waiting for the ack, and use big blocks. For a 300MB file, I achieved 47KB per second with a 16000 block size – so not very high.

With IND$FILE, pick the biggest block size you can. I think it supports a maximum size of 32767. I got 86 KB/second with a 32767 block size with DFT mode.

For a dataset packaged with TSO XMIT

Use the TSO command RECEIVE INDSN(…) to restore the data set.

Un PAX the file to recreate it

On the production system, I use went into Unix, and used the cd command to get to the destination directory.

pax -ppx -rf  "//'COLIN.ZOWE.PAX'"