===== BGP Route Injector ===== ==== Latest Update ==== If you are interested in FlowSpec (RFC 5575), there is now full support for it on trunk. svn co http://svn.exa.org.uk/bgp/trunk bgp Make sure your trunk version up-to-date. Bug reports are welcome :) What is FlowSpec ? * http://uknof.org/uknof15/Mangin-NakedBGP.pdf * http://www.terena.org/activities/tf-ngn/tf-ngn17/uze-flowspec.pdf * http://www.nanog.net/meetings/nanog38/presentations/labovitz-bgp-flowspec.pdf * http://resources.nznog.org/2006/Friday-240306/DavidLambert-BGPFlowSpecificationUpdate/Lambert.ppt ==== What is it ? ==== A BGP speaker which can inject routes with arbitrary next-hops into your network. I use it to : * source ASN112 servers * source some ipv4 routes * **source some ipv6 routes** (using both IPv4 and IPv6 TCP connections) * **redirect traffic flows** from my customers to a mail sink hole when they spam * **mitigate DDOS** ==== Where can I get it ? ==== The code is stored in our SVN repository: \\ [[http://svn.exa.org.uk/bgp/trunk|http://svn.exa.org.uk/bgp/trunk]] \\ [[http://fisheye.exa.org.uk/browse/BGP/trunk|Fisheye browsing]] The latest stable version information is available at http://svn.exa.org.uk/bgp/branches/stable Currently it is version 1.0 Get it with cd /opt svn co http://svn.exa.org.uk/bgp/branches/1.0 bgp There is no tarball, the only way to download the code is through SVN. ==== How do you configure it ? ==== You can copy and edit one of the sample configuration file provided in the etc/bgp folder, then provide the name of the configuration file as an argument to the program. However, the folder lib/bgp must be the in Python include PATH for the program to run. env PYTHONPATH=/opt/bgp/lib /opt/bgp/daemon/bgpd /opt/bgp/etc/bgp/as112.txt We are using [[http://cr.yp.to/daemontools.html|deamontools]] to run and restart the application on kill/crash (we never saw it crash - touching wood). Some supervise scripts are provided in the repository service folder (but the configuration file name). As the application does not bind to port 179, or program the local routing table, it does not need any escalated privileges and will happily run as "nobody". The configuration file is very juniper like : IPv4 example neighbor 192.168.127.128 { description "a quagga test peer"; router-id 192.168.127.1; local-address 192.168.127.1; local-as 65000; peer-as 65534; graceful-restart; static { route 10.0.1.0/24 { next-hop 10.0.255.254; } route 10.0.2.0/24 { next-hop 10.0.255.254; community 30740:30740; } route 10.0.3.0/24 { next-hop 10.0.255.254; community [ 30740:30740 30740:0 ]; } route 10.0.4.0/24 { next-hop 10.0.255.254; local-preference 200; } route 10.0.5.0/24 next-hop 10.0.255.254 local-preference 200; route 10.0.6.0/24 next-hop 10.0.255.254 community 30740:30740; route 10.0.7.0/24 next-hop 10.0.255.254 local-preference 200 community 30740:30740; route 10.0.8.0/24 next-hop 10.0.255.254 community 30740:30740 local-preference 200; route 10.0.7.0/24 next-hop 10.0.255.254 local-preference 200 community [30740:0 30740:30740]; route 10.0.8.0/24 next-hop 10.0.255.254 community [30740:0 30740:30740] local-preference 200; route 10.0.5.0/24 next-hop 192.0.2.92 local-preference 10 community [ 0x87654321 ]; } } IPv6 example neighbor 2a02:b80::2 { description "a quagga test peer"; router-id 192.168.127.1; local-address 2a02:b80::1; local-as 65000; peer-as 65534; hold-time 180; graceful-restart 1200; static { route 1.2.3.4/32 next-hop 5.6.7.8; route 2A02:B80:0:1::1/64 next-hop 2A02:B80:0:2::1 community [30740:0 30740:30740] local-preference 200; } } FlowSpec (RFC 5575) Example neighbor 192.168.127.128 { description "a juniper router"; router-id 192.168.127.1; local-address 192.168.127.1; local-as 65000; peer-as 65534; flow { route optional-name-of-the-route { match { source 10.0.0.1/32; destination 192.168.0.1/32; port =80 =8080; destination-port >8080&<8088 =3128; # destination-port [ 8080 3128 ]; source-port >1024; protocol [ udp tcp ]; # protocol [ 4 6 ]; # protocol tcp; # packet-length >200&<300 >400&<500; # fragment not-a-fragment; # fragment [ first-fragment last-fragment ]; # icmp-type [ unreachable echo-request echo-reply ]; # icmp-code [ host-unreachable network-unreachable ]; # tcp-flags [ urgent rst ]; # dscp [ 10 20 ]; # dscp >10&<20; } then { # bytes/seconds rate-limit 9600; # discard; # redirect 65500:12345; # redirect 1.2.3.4:5678; } } } } It is possible to send a SIGHUP signal the program to have it send the right updates (peer setup and tear down, announcement and withdrawal) to sync the remote RIB to a new configuration file. ==== An example of FlowSpec setup ==== neighbor 82.219.123.221 { [....] flow { route { match { source 10.0.0.1/32; destination 192.168.0.1/32; port =80; destination-port =3128 >8080&<8088; source-port >1024; protocol tcp; } then { discard; } } } } thomas@router> show configuration protocols bgp local-as 30740; group flow { type external; multihop; local-preference 100; local-address 82.219.123.221; import no-export; export deny-all; peer-as 65500; neighbor 82.219.131.242 { traceoptions { file bgp; flag all; } family inet { unicast; flow { no-validate everything; } } family inet6 { unicast; } } } thomas@router> show configuration policy-options policy-statement everything then accept; thomas@router> show route table inetflow.0 extensive inetflow.0: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden) 192.168.0.1,10.0.0.1,proto=6,port=80,dstport=3128,>8080&<8088,srcport>1024/256 (1 entry, 0 announced) *BGP Preference: 170/-101 Next hop type: Fictitious Next-hop reference count: 1 State: Peer AS: 65500 Age: 1:13 Task: BGP_65500_30740.82.219.131.242+32319 AS path: 65500 I Communities: no-export traffic-rate:0:0 Localpref: 100 Router ID: 82.219.131.242 ==== Tell me more about the code ==== It is written in Python 2.x for version 2.5 or later. \\ No tests have been performed to check if it works with version 3.0. The Python specificities of 2.5/2.6 have been removed from the code and 2.4 will now let you setup bgp adjacencies. The code only relies on the standard library and has no external dependencies. ==== Anticipated Users FAQ ==== Q: Where do I report bugs - ask for help ?? \\ A: ... contact me: **thomas . mangin AT exa - networks . co . uk** Q: Where is the documentation ? \\ A: Here and in the code .. really do you need more ?? Q: Is this code supported ? \\ A: YES - Should you find any bug, please report it. Q: Does it work on Linux,MACOSX, Windows ? \\ A: Linux: yes, it is our deployment environment \\ A: MACOS: yes, it is developed on MAC OSX 10.6 \\ A: Windows: It should, but I have never tried. Let me know your experience. Q: I keep seeing "Received Notification (3,10) from peer UPDATE message error: Invalid Network Field." in the logs \\ A: You are most likely trying to send IPv6 route(s) to a router which is not ready to accept them \\ A: This is caused as we send the route(s) even if the router did not announce the protocol \\ A: To fix it under junos type "set family inet6 unicast" under your bgp group or peer Q: I am trying to connect to my router and it is not working \\ A: Did you enable multi-hop BGP on your router ? Q: I am trying to send some IPv6 routes to my router but the connection never stays up \\ A: You may need to enable family inet6 for this peer. \\ A: juniper: set protocol bgp group neighbor family inet6 unicast \\ A: Do not forget to explicitly enable IPv4 as well if you are planning to send both v6 and v4 routes \\ A: juniper: set protocol bgp group neighbor family inet unicast Q: All seems fine but my route is not added to the routing table \\ A: You may need to allow for non-directly connected next-hop \\ A: juniper: set protocol bgp group neighbor accept-remote-nexthop Q: I see I can specify the as-path (as-sequence) sent to the peer. Do you prepend the router ASN to peers ? \\ A: EBGP: we will add the router ASN automatically, to create loops. \\ A: IBGP: it is used "as it". Q: Can I connect using a IPv6 connection ? \\ A: Yes Q: Can you maintain more than one BGP session? \\ A: Yes, you can define more than one neighbor in the configuration file \\ A: Or have multiple instance running (like one instance per peer) Q: Are you planning to add more features ? (support for vpnv4, etc.) \\ A: I will only really code new features for my own use, but feel free to ask or send me patches. Q: Why did you implement Graceful Restart ? \\ A: My use case are machines announcing service IPs without lower MED/Local Prefence backup machines ready to take the over in case of problems. The BGP IPs are then still routed during reboots and in case of very high load for example it will not render the service IP unreacheable if some keepalive are missed. \\ A: If no graceful-restart time is set, the waiting time is set to be the same as the hold-time. As servers often take much longer than the default 180 seconds to reboots, we recommend that you set the graceful-restart timer to a much higher value. Q: I would like to inject routes in the network but my server is behind a NATing firewall, will it work ? \\ A: NAT is not a good idea but: Yes, it will work. \\ A: Set your local-address as your machine LAN IP and the router-id as the firewall public IP. Q: As the code is single threaded, can a blocking network IO with one peer cause issues with another ? \\ A: We are using select to only read data when available on the socket but as we are not using a dedicated thread for keepalive, it could happen. \\ A: Should Disk IO be very slow on configuration reload, we may be not be able sending KEEPALIVE in time, this is why the default run script renice positively the program. A: If it be a concern, run one instance of the program per peer. Q: As you have no separate thread for keepalives, how many peers do you think one instance can manage comfortably? \\ A: it will really depend on the number of routes exchanged, and many other parameters, but under normal use (even thousand of routes) you should never encounter an issue. \\ A: if unsure, just drop me a mail. ==== Anticipated Coders FAQ ==== Q: I am a Ruby coder and I hate Python \\ A: use ByteMark [[https://projects.bytemark.co.uk/projects/bgpfeeder|BGPFeeder]] a very similar application hg clone http://src.bytemark.co.uk/bgpfeeder Q: I am a Perl coder and I hate Python \\ A: Use [[http://code.google.com/p/bgpsimple|bgpsimple]] svn checkout http://bgpsimple.googlecode.com/svn/trunk/ bgpsimple-read-only Q: But there is [[https://code.launchpad.net/pybgp| already one in Python]] ! \\ A: I am not sure if this project existed when I started or not but I clearly missed it ! (and it does not support the MultiProtocol Extensions for IPv6 but instead for ipv4 and vpnv4/mpls which was not good for me :p) bzr branch lp:pybgp