Le manuel du parfait plombier NSX-T (maj continue)

03/06/2020: Dumper vos règles firewall en place sur chaque interface de vos VM.

Cela fait quelques mois que je poste régulièrement des billets sur mes découvertes et mon apprentissage de la production sur « NSX-T ». Durant tout ce temps, je me suis construit petit à petit une liste de tips & tricks pour pouvoir être plus efficace et aller plus vite à l’essentiel dans différentes circonstances. Après le billet « du parfait plombier des snapshots vSphere » et le billet « du parfait plombier VSAN », il est temps d’inaugurer le manuel « du parfait plombier NSX-T » !

Trace ethernet en ligne de commande sur un ESXi

Ce n’est pas spécialement lié à NSX-T et cette fonction est parfaitement utilisable sur un ESXi quel qu’il soit, mais elle est très utile quand on veut pister un flux problématique depuis ou vers une VM donnée. ESXi met à votre disposition des outils très puissants, vous allez voir. Le seul pré-requis : ça ne marche qu’avec des VM connectées via des DVswitchs, mais je pense que ça ne dérangera personne en 2019 ^^.

Tout d’abord, récupérez le numéro du port virtuel que vous souhaitez tracer : pour se faire, sous cli utilisez cette commande :

[root@chronos:~] net-stats -l
PortNum          Type SubType SwitchName       MACAddress         ClientName
33558533            4       0 DvsPortset-0     54:b2:03:8d:65:45  vmnic0
33558535            3       0 DvsPortset-0     54:b2:03:8d:65:46  vmk0
33558542            5       7 DvsPortset-0     00:50:56:a7:4a:d4  exo.eth0
33558543            5       7 DvsPortset-0     00:50:56:a7:22:2c  exo.eth3
33558544            5       7 DvsPortset-0     00:50:56:a7:aa:08  exo.eth1
33558545            5       7 DvsPortset-0     00:50:56:a7:de:c3  exo.eth2
33558546            5       9 DvsPortset-0     00:0c:29:5f:49:f1  titan.eth0
33558548            4       0 DvsPortset-0     54:b2:03:8d:65:46  vmnic1
33558558            5       9 DvsPortset-0     00:50:56:a5:5e:af  log.vlab.eth0
33558559            5       9 DvsPortset-0     00:50:56:a5:c5:bf  edge.eth1
33558560            5       9 DvsPortset-0     00:50:56:a5:08:19  edge.eth0
33558561            5       9 DvsPortset-0     00:0c:29:4f:7d:3a  vcenter.vlab.eth0
33558562            5       9 DvsPortset-0     00:50:56:85:0b:68  vpnchu.eth0
[root@chronos:~]

Vous obtenez ici la liste exhaustive ports dvSwitch que l’ESXi exploite actuellement : ceux des VM s’exécutant actuellement sur la machine. Sur des grosses productions cela peut représenter des dizianes, voire des centaines de ports. Un petit « grep le_nom_de_ma_vm » derrière la commande vous permettra d’aller droit au but.

Ensuite, pour le port cible, utilisez cette ligne de commande :

[root@chronos:~] pktcap-uw --switchport 33558562 --dir 2 -o - | tcpdump-uw -enr -
The switch port id is 0x02001022.
pktcap: The output file is -.
pktcap: No server port specifed, select 62906 as the port.
pktcap: Local CID 2.
pktcap: Listen on port 62906.
pktcap: Accept...
reading from file -, link-type EN10MB (Ethernet)
pktcap: Vsock connection from port 1032 cid 2.
21:51:51.607466 00:50:56:ba:e3:48 > 01:00:5e:7f:ff:fa, ethertype IPv4 (0x0800), length 143: 172.16.16.7.51483 > 239.255.255.250.1900: UDP, length 101
21:51:51.607518 00:50:56:ba:e3:48 > 01:00:5e:7f:ff:fa, ethertype IPv4 (0x0800), length 143: 172.16.16.7.51483 > 239.255.255.250.1900: UDP, length 101
21:51:51.677905 70:ee:50:05:4c:ea > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 172.16.16.254 tell 172.16.16.151, length 46
21:51:51.677935 70:ee:50:05:4c:ea > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 172.16.16.254 tell 172.16.16.151, length 46
21:51:51.733048 00:11:32:85:4c:41 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 172.16.16.43 tell 172.16.16.50, length 46
21:51:51.733076 00:11:32:85:4c:41 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 172.16.16.43 tell 172.16.16.50, length 46
21:51:51.812814 00:50:56:85:0b:68 > 00:50:56:a7:4a:d4, ethertype IPv4 (0x0800), length 118: 172.16.16.27.50397 > 80.82.234.188.4500: UDP-encap: ESP(spi=0x05af6f44,seq=0xa), length 76
(...)
21:51:57.087427 00:50:56:ba:e3:48 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 63: 172.16.16.7.49652 > 172.16.16.255.32414: UDP, length 21
21:51:57.087528 00:50:56:ba:e3:48 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 63: 172.16.16.7.59333 > 172.16.16.255.32412: UDP, length 21
21:51:57.087539 00:50:56:ba:e3:48 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 63: 172.16.16.7.59333 > 172.16.16.255.32412: UDP, length 21
21:51:57.235970 f4:5c:89:b4:63:f7 > 01:00:5e:7f:ff:fa, ethertype IPv4 (0x0800), length 217: 172.16.16.28.58719 > 239.255.255.250.1900: UDP, length 175
21:51:57.235985 f4:5c:89:b4:63:f7 > 01:00:5e:7f:ff:fa, ethertype IPv4 (0x0800), length 217: 172.16.16.28.58719 > 239.255.255.250.1900: UDP, length 175
tcpdump-uw: pcap_loop: error reading dump file: Interrupted system call
pktcap: Join with dump thread failed.
pktcap: Destroying session 4.
pktcap:
pktcap: Dumped 26 packet to file -, dropped 0 packets.
pktcap: Done.
[root@chronos:~]

C’est une combinaison de pktcap-uw, qui permet tout simplement de dumper le contenu du flux ethernet du port ciblé. Ce flux est ensuite envoyé à la commande, beaucoup plus classique, tcpdump-uw, un clone du bon vieux tcpdump. L’option « –dir 2 » dans la commande pktcap-uw indique qu’on souhaite les flux in et out. Je vous laisse découvrir ces deux commande, les possibilités sont énormes pour analyser en temps réel l’activité d’une VM sans la perturber le moins du monde, ni a forcieri, d’installer un traceur à la wireshark dessus !

Trace en ligne de commande d’un port de logical router sur vos edges nodes

Une fois connecté en admin sur la edge cible (si vous êtes en actif/actif, vous devez faire des traces combinées sur les deux edge nodes), récupérez d’abord la liste de vos routeurs (DR, SR) :

edge> get logical-routers
Logical Router
UUID                                   VRF    LR-ID  Name                              Type                        Ports
736a80e3-23f6-5a2d-81d6-bbefb2786666   0      0                                        TUNNEL                      3
1645f252-f64c-4551-9470-97dffcc6bc2a   1      2      SR-tier0                          SERVICE_ROUTER_TIER0        5
65075e33-1b3b-4bee-b1f5-c739515765ea   2      4      SR-tier1                          SERVICE_ROUTER_TIER1        5
bd8c3fb0-6116-495f-8f75-5fbf727fec8c   3      1      DR-tier0                          DISTRIBUTED_ROUTER_TIER0    4
e3449431-7951-46fc-906e-804798252c52   4      3      DR-tier1                          DISTRIBUTED_ROUTER_TIER1    5
edge>

Une fois récupéré l’UUID du routeur, vous devez lister et récupérer l’UUID de l’interface du routeur que vous voulez tracer :

edge> get logical-router 1645f252-f64c-4551-9470-97dffcc6bc2a  interfaces
Logical Router
UUID                                   VRF    LR-ID  Name                              Type
bd8c3fb0-6116-495f-8f75-5fbf727fec8c   3      1      DR-tier0                          DISTRIBUTED_ROUTER_TIER0
Interfaces (IPv6 DAD Status A-Assigned, D-Duplicate, T-Tentative)
    Interface     : ce53f97a-9534-4036-a09d-a7008d7ac1f2
    Ifuid         : 283
    Name          : tier0-tier1-t0_lrp
    Internal name : downlink-283
    Mode          : lif
    IP/Mask       : 100.64.80.0/31;fc29:26d9:3e6:7000::1/64(NA);fe80::50:56ff:fe56:4452/64(NA)
(...)
    Interface     : d4a1c96c-11b4-5ac2-94f4-e83d23e7e95c
    Ifuid         : 281
    Mode          : blackhole

Logical Router
UUID                                   VRF    LR-ID  Name                              Type
1645f252-f64c-4551-9470-97dffcc6bc2a   1      2      SR-tier0                          SERVICE_ROUTER_TIER0
Interfaces (IPv6 DAD Status A-Assigned, D-Duplicate, T-Tentative)
    Interface     : 54c2533b-bca4-5226-b0d9-83329b17c967
    Ifuid         : 271
(...)
    Interface     : fc352090-55f6-42e9-807c-3c88788a639e
    Ifuid         : 270
    Name          : uplink
    Internal name : uplink-270
    Mode          : lif
    IP/Mask       : 192.168.1.254/24
    MAC           : 00:50:56:a5:c5:bf
    LS port       : 91da4245-0e59-49a1-a32b-50741d81e559
    Urpf-mode     : STRICT_MODE
    DAD-mode      : LOOSE
    RA-mode       : SLAAC_DNS_TRHOUGH_RA(M=0, O=0)
    Admin         : up
    Op_state      : up
    MTU           : 1500

edge>

Pour notre exemple, on va prendre la dernière du SR-tier0, en fait l’uplink vers l’exterieur du monde joyeux de NSX-T. Pour tracer l’activité de l’interface en question :

edge> start capture interface fc352090-55f6-42e9-807c-3c88788a639e expression host 10.10.1.1
22:18:43.138405 00:50:56:a7:22:2c > 00:50:56:a5:c5:bf, ethertype IPv4 (0x0800), length 78: 172.16.16.3.54596 > 10.10.1.1.22: Flags [S], seq 3519720696, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 325339733 ecr 0,sackOK,eol], length 0
AFBWpcW/AFBWpyIsCABFAABAAABAAD8GdJqsEBADCgoBAdVEABbRyqz4AAAAALAC//++BgAAAgQFtAEDAwYBAQgKE2RKVQAAAAAEAgAA

22:18:43.138332 00:50:56:a5:c5:bf > 00:50:56:a7:22:2c, ethertype IPv4 (0x0800), length 74: 10.10.1.1.22 > 172.16.16.3.54596: Flags [S.], seq 1106438837, ack 3519720697, win 28960, options [mss 1460,sackOK,TS val 3261765426 ecr 325339733,nop,wscale 7], length 0
AFBWpyIsAFBWpcW/CABFAAA8AABAAD4GdZ4KCgEBrBAQAwAW1URB8uq10cqs+aAScSDXkwAAAgQFtAQCCArCapcyE2RKVQEDAwc=

(...)

22:18:44.796406 00:50:56:a5:c5:bf > 00:50:56:a7:22:2c, ethertype IPv4 (0x0800), length 66: 10.10.1.1.22 > 172.16.16.3.54596: Flags [F.], seq 4422, ack 3415, win 315, options [nop,nop,TS val 3261767085 ecr 325341344], length 0
AFBWpyIsAFBWpcW/CABFEAA01kZAAD4Gn08KCgEBrBAQAwAW1URB8vv70cq6T4ARATtK4wAAAQEICsJqna0TZFCg

22:18:44.796412 00:50:56:a7:22:2c > 00:50:56:a5:c5:bf, ethertype IPv4 (0x0800), length 66: 172.16.16.3.54596 > 10.10.1.1.22: Flags [.], ack 4423, win 2048, options [nop,nop,TS val 325341352 ecr 3261767085], length 0
AFBWpcW/AFBWpyIsCABFSAA0AABAAD8GdF6sEBADCgoBAdVEABbRyrpPQfL7/IAQCABEFgAAAQEIChNkUKjCap2t

^C
85 packets captured
85 packets received by filter
0 packets dropped by kernel

edge>

Vous noterez l’expression qui permet ici le dump à un host en particulier, tout comme tcpdump. Les possibilités sont presques infinies, aussi je vous recommande de piocher à loisir dans la doc « NSX-T Command line Reference », à consulter ici pour la 2.5.

Tracer l’activité du distributed firewall NSX-T sur ESXi

Vous le savez sans doute, pour chaque règle de micro-segmentation, vous pouvez cocher l’option de « logging ». Cette option permet d’activer la trace de chaque activité de la règle en question sur chacun des transport nodes (ESXi) de votre plateforme. Une fois fait, dès que la règle est matchée sur un VM donnée, la décision du DFW est logguée dans le fichier /var/log/dfwpktlogs.log de l’ESXi où la VM s’exécute. Il vous suffit donc de consulter ce fichier pour voir ce qui s’est passé. Voici un petit exemple :

[root@nested-esx2:~] tail -f /var/log/dfwpktlogs.log
2019-12-14T22:29:29.367Z a3c10b92 INET6 match DROP 1027 IN 76 ICMP fe80::ffff:ffff:ffff:ffff->ff02::1
2019-12-14T22:29:35.562Z a3c10b92 INET match DROP 1027 OUT 76 UDP 10.10.2.1/34847->37.187.101.179/123
2019-12-14T22:29:45.479Z a3c10b92 INET TERM 1030 OUT UDP 10.10.2.1/51060->192.168.1.1/53 2/2 134/732
2019-12-14T22:29:45.812Z a3c10b92 INET match DROP 1027 OUT 76 UDP 10.10.2.1/49266->194.57.169.1/123
2019-12-14T22:29:56.062Z a3c10b92 INET match DROP 1027 OUT 76 UDP 10.10.2.1/50722->92.243.6.5/123
2019-12-14T22:30:25.487Z a3c10b92 INET TERM 1030 OUT UDP 10.10.2.1/60116->192.168.1.1/53 2/2 134/464
2019-12-14T22:30:38.294Z a3c10b92 INET match PASS 1029 IN 64 TCP 172.16.16.3/56827->10.10.2.1/22 S
2019-12-14T22:31:00.494Z a3c10b92 INET TERM 1029 IN TCP FIN 172.16.16.3/56827->10.10.2.1/22 46/36 5781/6177
2019-12-14T22:31:34.367Z a3c10b92 INET match DROP 1027 IN 36 PROTO 2 0.0.0.0->224.0.0.1
2019-12-14T22:31:34.367Z a3c10b92 INET6 match DROP 1027 IN 76 ICMP fe80::ffff:ffff:ffff:ffff->ff02::1
[root@nested-esx2:~]

Le numéro après le INET/INET6 match [decision] correspond au numéro de la règle (à retrouver dans l’interface web). Vous avez aussi des indications du type TERM (fermeture de la session statefull) voir RDR qui indique une « redirection », SNAT ou DNAT. Bref, une mine d’or pour vérifier que les règles implantés sont bonne. Bon, honnêtement, si vous avec beaucoup de machine, je vous conseille fortement au moins un aggrégateur de log pour vos machines (et les appliances NSX-T au passage), voire un VMware Log Insight, si vous avez des licences adaptées.

Visualiser la liste des règles firewall NSX appliquée sur une vmnic d’une machine virtuelle

Toujours très utile pour voir si par hasard, la nouvelle règle que vous venez d’implanter sur NSX-T est bien en place au bon endroit et fait le job correctement, il existe un groupe de deux commandes vous permettant de lister l’ensemble des règles appliquées à une vmnic donnée.

D’abord identifiez l’identifiant de la vmnic à regarder. Pour cela, placez vous sur l’ESXi où tourne la VM cible, comme toujours puis utilisez la commande summarize-dvfilter :

[root@cronos:~] summarize-dvfilter | grep -A 2 eon-10.10.1.100
world 2141337 vmm0:eon-10.10.1.100 vcUuid:'50 3c 29 0b 19 51 bf e0-8c da 33 db 43 63 37 d9'
 port 67108871 eon-10.10.1.100.eth0
  vNic slot 2
   name: nic-2141337-eth0-vmware-sfw.2
[root@cronos:~]

Si la VM dispose de plusieurs interfaces, évidemment, vous aurez plusieurs réponses. Repérez à chaque fois l’identifant suivant le champ « name: ». Ici dans notre exemple, on va utiliser l’ID « nic-2141337-eth0-vmware-sfw.2 » dans la deuxième commande, vsipioctl :

[root@cronos:~] vsipioctl getrules -f nic-2141337-eth0-vmware-sfw.2
ruleset mainrs {
  # generation number: 0
  # realization time : 2020-06-01T17:12:39
  # FILTER rules
  rule 4109 at 1 inout protocol udp from addrset 39747e9a-afe6-4707-990f-0f7b9e5660af to addrset rdst4109 port {53, 123} accept;
  rule 4109 at 2 inout protocol tcp from addrset 39747e9a-afe6-4707-990f-0f7b9e5660af to addrset rdst4109 port 53 accept;
  rule 2 at 3 inout protocol any from any to any drop;
  # IDP rules
  rule 3075 at 1 inout protocol any from any to any with ids profile 9c8b0080-08ea-4ddd-8d60-d9e75e1ac946 idp_detect;
}
ruleset mainrs_L2 {
  # generation number: 0
  # realization time : 2020-06-01T17:12:39
  # FILTER rules
  rule 1 at 1 inout ethertype any stateless from any to any accept;
}
[root@cronos:~]

La commande est très intéressante car elle vous renvoie des tonnes d’informations, comme la date de génération des règles (pour voir justement si votre nouvelle implantation a impacté ce ruleset. Ensuite, vous avez l’ensemble des règles L2 (Ethernet) et L3 (IP). Enfin vous y retrouvez, comme pour les logs firewall, les numéro de règles mais aussi leur portée et leur effet exact. Accessoirement, depuis NSX-T 3.0 vous avez aussi les fameuses règles IDS/IPS.

Je vous laisse découvrir tout ce qu’on peut récupérer à l’aide de cette commande magique vsipioctl. Essayez, par exemple vsipioctl getfwconfig, vsipioctl getspoofguard ou encore vsipioctl getfilterstat …

A suivre … :)