> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tangoanalytics.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy an on-premise Locatee Cisco IOS XE Gateway

# Prerequisites

## Supported devices

* Managed Cisco WLCs, starting from **Cisco 9800-series**, running IOS XE **17.6 or higher**
* **NETCONF-YANG** must be configured for telemetry to work, even if NETCONF is not used. For more information on configuring **NETCONF-YANG**, see the [NETCONF Protocol](https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/1610/b_1610_programmability_cg/configuring_yang_datamodel.html) module.

## On-Premise Server

This guide assumes the prior completion of steps outlined in [Deploy an on-premise gateway](https://docs.locatee.ch/docs/on-premise-gateway)

# Installation

## Create a Locatee Gateway API token

1. Open Locatee Analytics
2. Go to **Admin > Data Sources > Gateways**
3. Create a new **On-Prem** type gateway

4) Copy the generated token and note the gateway's unique ID:

![](https://files.readme.io/30c7521-Locatee_Admin.png)

## Configure Locatee IOS XE Gateway

1. Modify existing compose YAML configuration located at `/opt/locatee/gateway/gateway.yaml` to include iOS XE Gateway:

```yaml YAML theme={null}
# ... previous content  
  ios-xe-gateway-prod:
    image: artifact.ch.locatee.com/molten-unison-255209/locatee-on-prem-repo/ciscoiosxe:stable
    container_name: ios-xe-gateway-prod
    restart: always
    environment:
      # Please provide Locatee IOS XE Gateway ID
      LOCATEE_CISCOIOSXE_GATEWAYID:
      # Please provide Locatee IOS XE API URL
      LOCATEE_CISCOIOSXE_API_BASEURL:
      # Please provide Locatee IOS XE API TOKEN
      LOCATEE_CISCOIOSXE_API_TOKEN:
      # short form name of the Locatee environment, for example `customer-prod`
      LOCATEE_CUSTOMER_NAME:
      # Path to logging credentials
      GOOGLE_APPLICATION_CREDENTIALS: /opt/locatee/logging.json
      FEATURE_GATE_ANONYMIZATION_ENABLED: 'false'
      GRPC_SERVER_SECURITY_ENABLED: 'false'
    ports:
      - "8140:8140"
    volumes:
      - /opt/locatee/gateway/logging.json:/opt/locatee/logging.json
    logging:
      driver: json-file
      options:
        max-size: 10M
```

4. Restart existing gateways:

```Text Shell theme={null}
docker-compose -f /opt/locatee/gateway/gateway.yaml down
docker-compose -f /opt/locatee/gateway/gateway.yaml up -d
```

5. Monitor IOS XE Gateway logs for any errors:

```shell theme={null}
docker logs ios-xe-gateway-prod -f
```

## Configure IOS XE WLC

### Preliminary checks

1. Check HTTP server status:

```shell theme={null}
show ip http server secure status

### Expected Output
# HTTP secure server status: Enabled HTTP secure server port: 443 
```

If you don't get expected output, execute the following to start HTTP Server:

```shell theme={null}
ip http secure-server 
```

2. Check NETCONF-YANG status:

```shell theme={null}
show platform software yang-management process

### Expected Output
#confd            : Running 
#nesd             : Running 
#syncfd           : Running
```

If you don't get expected output, execute the following to enable NETCONF-YANG:

```shell theme={null}
netconf-yang
```

### Enable Telemetry subscriptions

1. Configure the controller for wireless client readouts:

```shell theme={null}
# Enable Wireless Client Probing
wireless probe filter

# Use the default RSSI averaging algorithm for processing wireless probes
location algorithm rssi-average

# Expire RSSI probes after 300 seconds
location expiry client 300

# disable that APs hold back RSSI measurements) 
location notify-threshold client 0

# Configures the Half-Life time for the rssi-averaging algorithm to calculate a stable RSSI value for the clients
location rssi-half-life client ENM_HALF_LIFE_TIME_180

# Include also LAA mac addresses in probe results, otherwise associated LAA clients will not get RSSI measurements reported
wireless probe locally-administered-mac
```

2. Create telemetry receiver pointing to the IP:PORT of Locatee IOS XE Gateway:

```shell theme={null}
telemetry receiver protocol locatee-gw-receiver
 host ip-address LOCATEE_GATEWAY_SERVER_IP 8140
 protocol grpc-tcp
```

3. Confirm that the receiver has been successfully created. The output should include the information about the receiver:

```shell theme={null}
show telemetry receiver name locatee-gw-receiver

### Expected Output
# Name: locatee-gw-receiver
# Profile:
# State: Valid
```

4. Configure the IOS XE telemetry subscriptions:

```shell theme={null}
no telemetry ietf subscription 1231
telemetry ietf subscription 1231
 encoding encode-kvgpb
 filter xpath /wireless-client-oper:client-oper-data/common-oper-data
 stream yang-push
 update-policy periodic 12000
 receiver name locatee-gw-receiver

no telemetry ietf subscription 1232
telemetry ietf subscription 1232
 encoding encode-kvgpb
 filter xpath /wireless-client-oper:client-oper-data/dot11-oper-data
 stream yang-push
 update-policy periodic 12000
 receiver name locatee-gw-receiver

no telemetry ietf subscription 1233
telemetry ietf subscription 1233
 encoding encode-kvgpb
 filter xpath /wireless-client-oper:client-oper-data/policy-data
 stream yang-push
 update-policy periodic 12000
 receiver name locatee-gw-receiver

no telemetry ietf subscription 1234
telemetry ietf subscription 1234
 encoding encode-kvgpb
 filter xpath /wireless-client-oper:client-oper-data/dc-info
 stream yang-push
 update-policy periodic 12000
 receiver name locatee-gw-receiver

no telemetry ietf subscription 1240
telemetry ietf subscription 1240
 encoding encode-kvgpb
 filter xpath /wireless-location-oper:location-oper-data/location-rssi-measurements
 stream yang-push
 update-policy periodic 12000
 receiver name locatee-gw-receiver
```

4. Check receiver connection status. The output should include connection with IP address of Locatee Gateway with `Active` State:

```shell theme={null}
show telemetry internal connection

### Expected Output
# Telemetry connections
# 
# ** LOCATEE_GATEWAY_SERVER_IP		8140		**		**		Active
```

5. Check subscription status. The output should include each subscription id configured in previous step with receiver in `Connected` state:

```shell theme={null}
show telemetry ietf subscription all detail

### Expected Output
# Telemetry subscription detail:
# Subscription ID: 1231
# Type: Configured
# ...
# Named receivers:
# ...
# locatee-gw-receiver		**		**		Connected
# Similar output for other subscriptions
```

### Troubleshooting Telemetry subscriptions

#### Receiver connection isn't `Active` or subscription status isn't `Connected`

Please check the output of the following command:

```shell theme={null}
show platform software trace message mdt-pubd chassis active R0
```

## Enable mTLS between Gateway & WLC (Optional)

### Certificate Requirements

Communication between Cisco WLC IOS XE & Locatee gateway can be encrypted using mutual certificate authentication, which requires two sets of certificates. Both certificates should be signed by same CA.

* **Server Certificate & Private Key** (for Locatee Gateway), further referred as `server.crt` & `server.key`
* **Client Certificate**(for WLC), further referred as `client.crt`

In the absence of separate CA which can issue those certificates, it's possible to use self-signed certificates  generated using openssl. Start by generating root CA & Server Certificate & Private Key:

```shell theme={null}
# Create CA Cert & Key
openssl req -x509 -newkey rsa:4096 -keyout root-ca.key -out root-ca.crt -sha256 -days 3650 -nodes
# Create Server Cert CSR & Key
openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -sha256 -nodes
# Sign Server CSR using CA to create Cert
openssl x509 -req -days 3650 -in server.csr -CA root-ca.crt -CAkey root-ca.key -CAcreateserial -out server.crt
```

### Configure Locatee IOS XE Gateway with TLS

1. Create a new directory `/opt/locatee/gateway/certificates` and copy server certificate, server key, root CA certificate (if CA is present) and client certificate there:

```text Text theme={null}
/opt/locatee/gateway/certificates/server.crt
/opt/locatee/gateway/certificates/server.key
/opt/locatee/gateway/certificates/root-ca.crt
```

2. Modify existing compose YAML configuration located at `/opt/locatee/gateway/gateway.yaml` to include mTLS settings:

```yaml YAML theme={null}
# ... previous content  
  ios-xe-gateway-prod:
    image: artifact.ch.locatee.com/molten-unison-255209/locatee-on-prem-repo/ciscoiosxe:stable
    container_name: ios-xe-gateway-prod
    restart: always
    environment:
      # Please provide Locatee IOS XE Gateway ID
      LOCATEE_CISCOIOSXE_GATEWAYID:
      # Please provide Locatee IOS XE API URL
      LOCATEE_CISCOIOSXE_API_BASEURL:
      # Please provide Locatee IOS XE API TOKEN
      LOCATEE_CISCOIOSXE_API_TOKEN:
      # short form name of the Locatee environment, for example `customer-prod`
      LOCATEE_CUSTOMER_NAME:
      # Path to logging credentials
      GOOGLE_APPLICATION_CREDENTIALS: /opt/locatee/logging.json
      FEATURE_GATE_ANONYMIZATION_ENABLED: 'false'
      # Use TLS for grpc-server.
      GRPC_SERVER_SECURITY_ENABLED: 'true'
      # Force the client to authenticate itself using a x509 certificate
      GRPC_SERVER_SECURITY_CLIENTAUTH: 'REQUIRE'
      # Please provide path to server cert file e.g. file:/certificates/server.crt
      GRPC_SERVER_SECURITY_CERTIFICATECHAIN: 'file:/certificates/server.crt'
      # Please provide path to server private key cert file e.g. file:/certificates/server.key
      GRPC_SERVER_SECURITY_PRIVATEKEY: 'file:/certificates/server.key'
      # Please provide path to CA cert file e.g. file:/certificates/root-ca.crt 
      GRPC_SERVER_SECURITY_TRUSTCERTCOLLECTION: 'file:/certificates/root-ca.crt'
    ports:
      - "8140:8140"
    volumes:
      - /opt/locatee/gateway/logging.json:/opt/locatee/logging.json
      - /opt/locatee/gateway/certificates:/certificates:ro
    logging:
      driver: json-file
      options:
        max-size: 10M
```

3. Restart existing gateways

```shell Shell theme={null}
docker-compose -f /opt/locatee/gateway/gateway.yaml down
docker-compose -f /opt/locatee/gateway/gateway.yaml up -d
```

4. Monitor IOS XE Gateway logs for any errors:

```shell theme={null}
docker logs ios-xe-gateway-prod -f
```

### Configure IOS XE WLC with TLS

1. Configure the IOS XE trust point:

```shell theme={null}
crypto pki trustpoint locatee-gw
  enrollment terminal
  chain-validation stop
  revocation-check none
exit
crypto pki authenticate locatee-gw
	<< paste contents of root-ca.crt
quit
```

2. Create CSR request:

```shell theme={null}
crypto pki enroll locatee-gw
```

3. Copy the output of CSR into a separate file called `client.csr` under `/opt/locatee/gateway/certificates`
4. Sign Client CSR using CA to create cert

```shell theme={null}
openssl x509 -req -days 3650 -in client.csr -CA root-ca.crt -CAkey root-ca.key -CAcreateserial -out client.crt
```

5. Import Client Certificate back to Cisco IOS XE:

```shell theme={null}
crypto pki import locatee-gw certificate
	<< paste contents of client.crt
quit
```

6. Create telemetry receiver pointing to the IP:PORT of Locatee IOS XE Server Gateway using gRPC TLS Profile:

```shell theme={null}
telemetry receiver protocol locatee-gw-receiver-tls
 host ip-address LOCATEE_GATEWAY_IP 8140
 protocol grpc-tls profile locatee-gw
```

7. Reconfigure IOS XE telemetry subscriptions to use receiver with TLS profile:

```shell theme={null}
no telemetry ietf subscription 1231
telemetry ietf subscription 1231
 encoding encode-kvgpb
 filter xpath /wireless-client-oper:client-oper-data/common-oper-data
 stream yang-push
 update-policy periodic 12000
 receiver name locatee-gw-receiver-tls

no telemetry ietf subscription 1232
telemetry ietf subscription 1232
 encoding encode-kvgpb
 filter xpath /wireless-client-oper:client-oper-data/dot11-oper-data
 stream yang-push
 update-policy periodic 12000
 receiver name locatee-gw-receiver-tls

no telemetry ietf subscription 1233
telemetry ietf subscription 1233
 encoding encode-kvgpb
 filter xpath /wireless-client-oper:client-oper-data/policy-data
 stream yang-push
 update-policy periodic 12000
 receiver name locatee-gw-receiver-tls

no telemetry ietf subscription 1234
telemetry ietf subscription 1234
 encoding encode-kvgpb
 filter xpath /wireless-client-oper:client-oper-data/dc-info
 stream yang-push
 update-policy periodic 12000
 receiver name locatee-gw-receiver-tls

no telemetry ietf subscription 1240
telemetry ietf subscription 1240
 encoding encode-kvgpb
 filter xpath /wireless-location-oper:location-oper-data/location-rssi-measurements
 stream yang-push
 update-policy periodic 12000
 receiver name locatee-gw-receiver-tls
```

8. Check receiver connection status. The output should include connection with IP address of Locatee Gateway with `Active` State:

```shell theme={null}
show telemetry internal connection

### Expected Output
# Telemetry connections
# 
# ** LOCATEE_GATEWAY_SERVER_IP		8140		**		**		Active
```

5. Check subscription status. The output should include each subscription id configured in previous step with TLS receiver in `Connected` state:

```shell theme={null}
show telemetry ietf subscription all detail

### Expected Output
# Telemetry subscription detail:
# Subscription ID: 1231
# Type: Configured
# ...
# Named receivers:
# ...
# locatee-gw-receiver-tls		**		**		Connected
# Similar output for other subscriptions
```
