VyOS - Setting up BGP

Hello, I'm Baptiste, a Network and System Engineer working for a service provider. I've embarked on a journey to deploy BGP for fun in my personal infrastructure. This post marks the beginning of many to come, as I plan to use this blog as an archive to document my project. If, along the way, I can assist others, that's even better!

English is not my primary language, so please bear with me and feel free to reach out with any guidance or questions. :)

This post assumes that you have already set up your VyOS with the following minimum requirements:
1.One interface designated as the WAN connection.
2.One interface dedicated to your IPv4 prefix.
3.An Autonomous System Number (ASN).
4.A BGP tunnel ready for connection or a prepared BGP session peer.
5.Basic familiarity with VyOS and proficiency in using the Command Line Interface (CLI)."

My setup :

  • Proxmox as hypervisor.
  • VM with 4 cores, 8GB of RAM, 32GB of disk space.
  • My WAN is one on my ISP's attributed IPv4.
  • VyOS Version 1.5 (commands are different between last version !)
  • I'm using BGP-Tunnel as my peer with GRE Tunnel.

Step 1 : GRE Tunnel /w BGPTunnel.com

In my current setup, I am utilizing BGPTunnel.com as my primary peer. However, in the future, my datacenter housing provider will enable me to establish an eBGP session directly with them. This future enhancement will replace BGPTunnel.com as my BGP peer.

Note 20.02.2024 : BGP Session established with VTX.

To create the tunnel with BGPTunnel.com follow as procede :

  1. Create an account on their website and link your ASN.
  2. Once they verified your ASN, click on the "Tunnels" tab.
  3. To create a new tunnel, select the type 'GRE' and choose the server location that is closest to you. Enter your WAN IPv4 address, ensuring this IP is reachable by a ping. Finally, click on "Create Tunnel" to complete the process..
  4. Now click on "config" and then enter these commande into VyOs
configuration
set interfaces tunnel tun0 encapsulation "gre"
set interfaces tunnel tun0 source-address <Your WAN IP>
set interfaces tunnel tun0 remote <Remote IP of the Tunnel>
set interfaces tunnel tun0 address <Your attributed local address, should be a /30>

  1. Now that the tunnel is created, you should be able to ping the other end of the tunnel (Your attributed local address minus 1).
  2. Now click on the "BGP Sessions" tab and then "New BGP Session".
  3. Select your ASN, then your tunnel and click on "Create new BGP Session".
  4. The peering partner is now ready.

Step 2 : BGP Setup

Now that you have someone to peer to we need to configure our router to export your prefix, in this example I'm using my own IPv4 prefix and ASN.

If your provider can provide full BGP table, like mine, the route map will be different, so be aware of the risk.

First we need to put one of your address on the interface that will be used with your prefix, this IP need to be on one of the prefix you are exporting.

set interfaces ethernet eth1 address <IP Address>

Enter these commands to configure BGP on your router :

set protocols bgp system-as <Your ASN>
set protocols bgp neighbor <Peer Gateway> remote-as <Remote ASN>
set protocols bgp neighbor <Peer Gateway> update-source <Your Peer Address>
set protocols bgp address-family ipv4-unicast network <Your IPv4 prefix>
set protocols bgp neighbor <Peer Gateway> interface source-interface <Your tunnel interface>
set protocols bgp parameters router-id <The IP of your prefix's interface>

Now that we have setup the base parameter for BGP we need to make some policy to only export/import our prefix.
To do that enter these commands :

#Create a permitted prefix list
set policy prefix-list <Prefix-Rule-Name>-OUT rule <Prefix Rule ID> action 'permit'
set policy prefix-list <Prefix-Rule-Name>-OUT rule <Prefix Rule ID> prefix <Your prefix>

#Create a permited route map with your prefix.
set policy route-map <Route-Map-Name>-IN rule <Map Rule ID> action 'permit'
set policy route-map <Route-Map-Name>-OUT rule <Map Rule ID> match ip address prefix-list <Prefix-List-Name>-OUT

#Deny everything else (99 is a random ID number, should be higher than your other rules)
set policy route-map <Route-Map-Name>-OUT rule 99 action 'deny'

#Set the Route map you just created on the BGP config.
set protocols bgp neighbor <Peer Gateway> address-family ipv4-unicast route-map import <Route-Map-Name>-INT
set protocols bgp neighbor <Peer Gateway> address-family ipv4-unicast route-map export <Route-Map-Name>-OUT

#Create a default gateway policy route for the interfaces that contain the prefix, if you are provided with full BGP table, create static route only for the neighbor's IP.
set policy route <Policy-Route-Name> rule <Route Rule ID> destination address 0.0.0.0/0
set policy route <Policy-Route-Name> rule <Route Rule ID> set table 100
set protocols static table <Route Table Rule ID> route 0.0.0.0/0 next-hop <Peer Gateway>
set policy route <Policy-Route-Name> interface eth1

#Commit and save your change !
commit
save

Now everything should be working, to verify the BGP status enter the command :

show bgp neighbors <Peer Gateway>

Search for "BGP state" and it should be established !
image-1.png

Step 3 : Test, End & Configuration

To ensure that your prefix is correctly exported, you have multiple options. The simplest one is to ping the IP address associated with your interface's prefix. If the ping is successful, everything is functioning as expected; otherwise, there might be a configuration issue.

Alternatively, you can set up another virtual machine (VM) on the same LAN as your prefix's interface. Configure an IP for this VM and attempt to ping 1.1.1.1. If the ping is successful, you can further verify the routing by checking your own IP. To do this, enter:

curl ifconfig.me

If the response is the IP of the VM interface, you've done everything correctly !

If nothing is working, you will find bellow my entire config !

interfaces {
    ethernet eth0 {
        address 212.147.79.246/29
        hw-id bc:24:11:4f:03:79
    }
    ethernet eth1 {
        address 82.115.209.1/24
        hw-id bc:24:11:fe:a7:52
    }
    loopback lo {
    }
    tunnel tun0 {
        address 10.249.4.10/30
        encapsulation gre
        remote 154.57.85.10
        source-address 212.147.79.246
    }
}
nat {
}
policy {
    prefix-list AS215825-OUT {
        rule 10 {
            action permit
            prefix 82.115.209.0/24
        }
    }
    route-map AS215825-IN {
        rule 10 {
            action permit
        }
    }
    route-map AS215825-OUT {
        rule 10 {
            action permit
            match {
                ip {
                    address {
                        prefix-list AS215825-OUT
                    }
                }
            }
        }
        rule 20 {
            action deny
        }
    }
}
protocols {
    bgp {
        address-family {
            ipv4-unicast {
                network 82.115.209.0/24 {
                }
                redistribute {
                    connected {
                    }
                }
            }
        }
        neighbor 10.249.4.9 {
            address-family {
                ipv4-unicast {
                    route-map {
                        export AS215825-OUT
                        import AS215825-IN
                    }
                }
            }
            interface {
                source-interface tun0
            }
            remote-as 209533
            update-source 10.249.4.10
        }
        parameters {
            router-id 82.115.209.1
        }
        system-as 215825
    }
    static {
        route 0.0.0.0/0 {
            next-hop 212.147.79.241 {
                distance 2
            }
        }
        table 100 {
            route 0.0.0.0/0 {
                next-hop 10.249.4.9 {
                }
            }
        }
    }
}

If you have any questions, don't hesitate to contact me !
By email : baptiste(at)baptiste.it
On Twitter : @Verttigo_