BGP の TCP アクセス制限

夢の実現に一歩近づきました。lab試験の挑戦権を得ました。これは私にとって大きな前進です。 CCIE Lab(Design)対策としてCisco-Live:LTRCCIE-3401を勉強しています。この練習問題の難易度分からないけど、まー難しい。 そのうちの一つで簡単な検証をしたのでblogにしてみました。

1.TS Ticket 7: Control Plane Security

f:id:chimay_wh:20211113100113p:plain
f:id:chimay_wh:20211113100139p:plain
f:id:chimay_wh:20211113100154p:plain

解答を見て意味は分かったので検証してみたのですが、ここでどうでもいいこと(結果として良かった!)に引っかかりました。 BGPサーバ(tcp179)をコントロールするにはどうするのだろう。

CCIE勉強会コミュニティに質問したら、いくつかのコントロール方法についてコメントいただけました。以下の2点です。 持つべきものはフォロワーですね!感謝感謝 Thank you • ͙‧⁺o (⁎˃ᴗ˂⁎) o⁺‧ • ͙‧⁺

① Dynamic Peering
② neighbor x.x.x.x transport connection-mode

2.Dynamic Peering

雑に言うと、片側は通常通りにneighborコマンドで定義して、対向はPeeringするアドレスレンジを指定して範囲内のIPでPeeringする技術です。
neighborコマンドのpeer-group optionで、ピアグループを指定する必要があります。(今回はBGPというピアグループ名にしています。)

2.1 検証構成(Dynamic Peering)

f:id:chimay_wh:20211113100743p:plain

R1のBGP-Config(左端の▲クリックすると見えます)

!/// R1 ///
!
router bgp 100
 bgp router-id 10.1.1.1
 bgp log-neighbor-changes
 neighbor BGP peer-group
 neighbor 10.1.2.2 remote-as 200
 neighbor 10.1.2.2 peer-group BGP
end

R2のBGP-Config(左端の▲クリックすると見えます)

!/// R2 ///
!
router bgp 200
 bgp router-id 10.1.1.2
 bgp log-neighbor-changes
 bgp listen range 10.1.2.0/24 peer-group BGP
 neighbor BGP peer-group
 neighbor BGP remote-as 100
end

2.2 パケットキャプチャ(Dynamic Peering)

Wireshark メニュー(Statics > Flow Graph)
range側がTCP/179になりました。 f:id:chimay_wh:20211113100858p:plain

2.3 showコマンド(Dynamic Peering)

R1#sh ip bgp sum
BGP router identifier 10.1.1.1, local AS number 100
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.1.2.2        4          200      19      19        1    0    0 00:14:09        0
R1#
R2#sh ip bgp sum
BGP router identifier 10.1.1.2, local AS number 200
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
*10.1.2.1       4          100      22      22        1    0    0 00:17:07        0
* Dynamically created based on a listen range command
Dynamically created neighbors: 1, Subnet ranges: 1

BGP peergroup BGP listen range group members: 
  10.1.2.0/24 

Total dynamically created neighbors: 1/(100 max), Subnet ranges: 1

R2#
R2#show tcp brief 
TCB       Local Address               Foreign Address             (state)
7F57472C5C48  192.168.2.26.23            192.168.2.4.49321           ESTAB
7F57478DCD00  10.1.2.2.179               10.1.2.1.16909              ESTAB
7F5747A64230  192.168.2.26.646           192.168.2.250.52027         ESTAB

2.4 コマンドリファレンス(bgp listen)

https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/iproute_bgp/command/irg-cr-book/bgp-a1.html#wp3798496750

3.neighbor transport

雑に言うと、積極的にPeeringする定義にするのか、相手からのPeering signalを待つのかという技術です。

オンラインヘルプ

R1(config-router)#neighbor 10.1.2.2 ?
  transport                  Transport options

R1(config-router)#neighbor 10.1.2.2 transport ?
  connection-mode     Specify passive or active connection

R1(config-router)#neighbor 10.1.2.2 transport connection-mode ?
  active   Actively establish the TCP session
  passive  Passively establish the TCP session

R1(config-router)#neighbor 10.1.2.2 transport connection-mode active 
R1(config-router)#

3.1 検証構成(neighbor transport)

検証構成は同じです。R1とR2だけです。

R1のconnection-mode passive(左端の▲クリックすると見えます)

!/// R1 ///
!
router bgp 100
 bgp router-id 10.1.1.1
 bgp log-neighbor-changes
 neighbor 10.1.2.2 remote-as 200
 neighbor 10.1.2.2 transport connection-mode passive
end


R2のconnection-mode active(左端の▲クリックすると見えます)

!/// R2 ///
!
router bgp 200
 bgp router-id 10.1.1.2
 bgp log-neighbor-changes
 neighbor 10.1.2.1 remote-as 100
 neighbor 10.1.2.1 transport connection-mode active
end

3.2 パケットキャプチャ(neighbor transport)

Wireshark メニュー(Statics > Flow Graph)
passive側がTCP/179になりました。 f:id:chimay_wh:20211113103429p:plain

3.3 showコマンド(neighbor transport)

R1#sh ip bgp sum
BGP router identifier 10.1.1.1, local AS number 100
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.1.2.2        4          200      10      10        1    0    0 00:06:20        0
R1#
R2#show ip bgp sum
BGP router identifier 10.1.1.2, local AS number 200
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.1.2.1        4          100      10      10        1    0    0 00:05:48        0
R2#
R2#sh tcp brief | i 179
7F5747899F08  10.1.2.2.46644             10.1.2.1.179                ESTAB
R2#

3.4 コマンドリファレンス(neighbor transport)

https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/iproute_bgp/command/irg-cr-book/bgp-m1.html#wp2116780248

定義の意味は分かったのでここで簡単に実験します。

4.実験1(両サイドpassive)

結果は何となくお察しのとおりでした。

4.1 showコマンド(両サイドpassive)

R1#sh ip bgp summary 
BGP router identifier 10.1.1.1, local AS number 100
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.1.2.2        4          200       0       0        1    0    0 00:05:30 Idle
R1#
R2#sh ip bgp summary 
BGP router identifier 10.1.1.2, local AS number 200
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.1.2.1        4          100       0       0        1    0    0 00:05:42 Idle
R2#

KEEPALIVE Messageすら送信しなくなります。いつまで待ってもestablishにはなりません。

5.実験2(両サイドactive)

passive/activeと聞いてLACPのようなを動作を想像していたので実験結果は意外でした。

5.1 showコマンド(両サイドactive)

R1#sh ip bgp sum
BGP router identifier 10.1.1.1, local AS number 100
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.1.2.2        4          200       0       0        1    0    0 00:08:55 Idle
R1#
R2#sh ip bgp sum
BGP router identifier 10.1.1.2, local AS number 200
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.1.2.1        4          100       0       0        1    0    0 00:03:07 Idle
R2#

5.2 パケットキャプチャ(両サイドactive)

Wireshark メニュー(Statics > Flow Graph)
両passiveと両activeとの違いは明白でした。俺がtcp/179を使う!いや俺もtcp/179使うと双方譲らない戦いが始まりました。キャプチャーは途中で止めています。 f:id:chimay_wh:20211113111331p:plain 実験の結果から”neighbor transport”でpassiveを使う場合は、 逆サイは”neighbor transport”を使わない、若しくはactiveにする必要があることが分かりました。

6.検証 TS Ticket 7: Control Plane Security(XE)

Cisco-liveの構成ではIOS-XRなのですが、csr1000v(IOS-XE)を使って簡易検証します。

6.1 検証構成と意図している内容

アドレスやAS-Num等異なりますが、eBGP Peeringしているという条件は同じなので、Cisco-liveの構成通りにわざわざ変更せずに検証してみます。 (無精者が故の選択は沼にハマりましたが、結果として良かったです。) f:id:chimay_wh:20211114203556p:plain

R1(PE16相当)のConfig(左端の▲クリックすると見えます)

!/// R1 ///
!
router bgp 100
 bgp log-neighbor-changes
 neighbor 10.1.2.2 remote-as 200
end

R2(PE31相当)のConfig(左端の▲クリックすると見えます)

!/// R2 ///
!
router bgp 200
 bgp log-neighbor-changes
 neighbor 10.1.2.1 remote-as 100
end

6.2 showコマンド(TS Ticket 7:XE)

R1#sh ip bgp sum
BGP router identifier 100.1.1.1, local AS number 100
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.1.2.2        4          200       9       9        1    0    0 00:04:42        0
R1#
R1#sh tcp br | i 179
7F5E3A9E8E28  10.1.2.1.179               10.1.2.2.11328              ESTAB
R1#

しかし、このままだと題意を満たさないので、双方にACLを追加します。 それにより、R2(PE31相当)がTCP/179でsessionでsessionを張ることになるはずです。

6.3 ACL適用(TS Ticket 7:XE)

R1
!
ip access-list extended 100
 deny   tcp any any eq bgp
 permit ip any any
R2
!
ip access-list extended 100
 deny   tcp any eq bgp any
 permit ip any any

6.4 ACL適用後(TS Ticket 7:XE)

ACLだけでは意図したとおりにならないので、明示的にaccess-groupに指定したらうまくいきました。 (ACLだけだと出来たり出来なかったり不安定でした。)

R1
!
interface GigabitEthernet1
 ip access-group 100 in
R2
interface GigabitEthernet1
 ip access-group 100 in

6.5 パケットキャプチャ(TS Ticket 7:XE)

Wireshark メニュー(Statics > Flow Graph)
R2(PE31相当)がTCP/179でsessionを張りました。 f:id:chimay_wh:20211114184324p:plain

6.6 show log(TS Ticket 7:XE)

ACLと戦っている様子です。長いですが、最後に10.1.2.100 Up と出てEST ! f:id:chimay_wh:20211114184718p:plain

6.7 showコマンド(TS Ticket 7:XE)

R1#sh ip bgp sum
BGP router identifier 100.1.1.1, local AS number 100
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.1.2.2        4          200      17      17        1    0    0 00:12:38        0
R1#
R1#sh tcp br
TCB       Local Address               Foreign Address             (state)
7F5E3A973460  10.1.2.100.31707           10.1.2.2.179                ESTAB
7F5E3AAA58D8  192.168.2.250.23           192.168.2.4.63844           ESTAB
7F5E335F4C80  192.168.2.250.50857        192.168.2.26.646            ESTAB
R1#

もう一度Cisco-Liveの解説を見て妙なことに気づきました。 IOS-XRだと対向で1対ではなく、個別にsessionを張っているかのような記載になっています。 もう何を信用して良いやら...CML2で確かめることにしました。

7.検証 TS Ticket 7: Control Plane Security(XR)

Cisco-liveの構成と同様IOS-XRを使って簡易検証しました。

7.1 検証構成と意図している内容(XR)

アドレスは異なりますが、Cisco-liveの構成に寄せられるところは寄せて検証しました。 f:id:chimay_wh:20211114203726p:plain

xr9kv1(PE16相当)のConfig(左端の▲クリックすると見えます)

!/// xr9kv1 ///
!
route-policy PASS
  pass
end-policy
!
router bgp 100
 bgp router-id 10.1.1.1
 address-family ipv4 unicast
 !
 neighbor 10.1.2.2
  remote-as 300
  address-family ipv4 unicast
   route-policy PASS in
   route-policy PASS out
  !
 !
!
end

xr9kv2(PE31相当)のConfig(左端の▲クリックすると見えます)

!/// xr9kv2 ///
!
route-policy PASS
  pass
end-policy
!
router bgp 300
 bgp router-id 10.1.1.2
 address-family ipv4 unicast
 !
 neighbor 10.1.2.1
  remote-as 100
  address-family ipv4 unicast
   route-policy PASS in
   route-policy PASS out
  !
 !
!
end

7.2 showコマンド(TS Ticket 7:XR)

RP/0/RP0/CPU0:xr9kv1#sh ip bgp sum
<snip>

Process       RcvTblVer   bRIB/RIB   LabelVer  ImportVer  SendTblVer  StandbyVer
Speaker               2          2          2          2           2           0

Neighbor        Spk    AS MsgRcvd MsgSent   TblVer  InQ OutQ  Up/Down  St/PfxRcd
10.1.2.2          0   300     715     716        2    0    0 00:00:53          0

RP/0/RP0/CPU0:xr9kv1#
RP/0/RP0/CPU0:xr9kv1(config)#do sh tcp br | i EST
Sun Nov 14 10:15:16.245 UTC
0x00007fe7ac014a88 0x60000000      0      0  10.1.1.1:646           10.1.1.2:53251         ESTAB
0x00007fe7ac00fc78 0x60000000      0      0  192.168.2.23:23        192.168.2.4:52594      ESTAB
0x00007fe7d8035e18 0x60000000      0      0  10.1.2.1:32445         10.1.2.2:179           ESTAB
RP/0/RP0/CPU0:xr9kv1(config)#int gigabitEthernet 0/0/0/0
RP/0/RP0/CPU0:xr9kv1(config-if)#shut
RP/0/RP0/CPU0:xr9kv1(config-if)#commit 
Sun Nov 14 10:15:32.550 UTC
RP/0/RP0/CPU0:xr9kv1(config-if)#no shut
RP/0/RP0/CPU0:xr9kv1(config-if)#commit 
Sun Nov 14 10:16:00.490 UTC
RP/0/RP0/CPU0:xr9kv1(config-if)#do sh tcp br | i EST
Sun Nov 14 10:16:15.560 UTC
0x00007fe7ac00fc78 0x60000000      0      0  192.168.2.23:23        192.168.2.4:52594      ESTAB
0x00007fe7ac00b758 0x60000000      0     23  10.1.2.1:179           10.1.2.2:45645         ESTAB
0x00007fe7ac00c198 0x60000000      0      0  10.1.1.1:646           10.1.1.2:31905         ESTAB
RP/0/RP0/CPU0:xr9kv1(config-if)#

しかし、このままだと題意を満たさないケースがあるので、双方にACLを追加します。 それにより、xr9kv2(PE31相当)がTCP/179でsessionでsessionを張ることになるはずです。

7.3 ACL適用(TS Ticket 7:XR)

xr9kv1
!
ipv4 access-list AS300-IN
 10 deny tcp any any eq bgp
 20 permit ipv4 any any
!
xr9kv2
!
ipv4 access-list AS100-IN
 10 deny tcp any eq bgp any
 20 permit ipv4 any any
!

7.4 ACL適用後(TS Ticket 7:XR)

ACLだけでは意図したとおりにならないので、明示的にaccess-groupに指定したらうまくいきました。 (ACLだけだと出来たり出来なかったり不安定でした。)

R1
!
interface GigabitEthernet0/0/0/0
 ipv4 access-group AS300-IN ingress
R2
interface GigabitEthernet0/0/0/0
 ipv4 access-group AS100-IN ingress

7.5 パケットキャプチャ(TS Ticket 7:XR)

Wireshark メニュー(Statics > Flow Graph)
R2(PE31相当)がTCP/179でsessionを張りました。 f:id:chimay_wh:20211114200106p:plain

7.6 show log(TS Ticket 7:XR)

neighbor 10.1.2.1 Up (VRF: default) (AS: 100) と出てEST !

bgp[1078]: %ROUTING-BGP-5-ADJCHANGE : neighbor 10.1.2.1 Down - BGP Notification received, administrative shutdown (VRF: default) (AS: 100) 
bgp[1078]: %ROUTING-BGP-5-NSR_STATE_CHANGE : Changed state to NSR-Ready 
bgp[1078]: %ROUTING-BGP-5-ADJCHANGE : neighbor 10.1.2.1 Up (VRF: default) (AS: 100) 
bgp[1078]: %ROUTING-BGP-5-NSR_STATE_CHANGE : Changed state to Not NSR-Ready

7.7 showコマンド(TS Ticket 7:XR)

RP/0/RP0/CPU0:xr9kv1#show ip bgp sum
<snip>
Process       RcvTblVer   bRIB/RIB   LabelVer  ImportVer  SendTblVer  StandbyVer
Speaker               2          2          2          2           2           0

Neighbor        Spk    AS MsgRcvd MsgSent   TblVer  InQ OutQ  Up/Down  St/PfxRcd
10.1.2.2          0   300     769     780        2    0    0 00:11:08          0

RP/0/RP0/CPU0:xr9kv1#
RP/0/RP0/CPU0:xr9kv1#show tcp brief | i EST
Sun Nov 14 11:02:57.834 UTC
0x00007fe7ac00a7f8 0x60000000      0      0  10.1.1.1:646           10.1.1.2:49725         ESTAB
0x00007fe7d80356f8 0x60000000      0      0  10.1.2.1:46071         10.1.2.2:179           ESTAB
0x00007fe7ac00af38 0x60000000      0      0  192.168.2.23:23        192.168.2.4:53097      ESTAB
RP/0/RP0/CPU0:xr9kv1#

色々と寄り道をしましたが、結果的に運よく全てが繋がり土日で解決まとめるまでできて良かったです。Twitterで頂いたリプによりRFC4271におけるcollisionの存在を知り、リプにあったとおりcollisionも観測できました。Establishが遅い時にルータが何をしているのかが分かりました。 本当にありがとうございました!

Request for Comments: 4271 A Border Gateway Protocol 4 (BGP-4)

6.8. BGP Connection Collision Detection

If a pair of BGP speakers try to establish a BGP connection with each other simultaneously, then two parallel connections well be formed. If the source IP address used by one of these connections is the same as the destination IP address used by the other, and the destination IP address used by the first connection is the same as the source IP address used by the other, connection collision has occurred. In the event of connection collision, one of the connections MUST be closed.

1つのやり方だけでなく他にないか?これを常に意識しようと思います。先入観を捨てるのはなかなか難しい。これは今後の課題です。

最後までお読みいただきありがとうございました!