Outils pour utilisateurs

Outils du site


reseau:bgp:ebgp

Table des matières

eBGP (A METTRE A JOUR)

Tout l’eBGP se fait sur nominoe.
Implémentation utilisée : bird 1.5.0_1

La configuration pour l’IPv4 se fait dans /usr/local/etc/bird.conf et la configuration pour l’IPv6 se fait dans /usr/local/etc/bird6.conf.

IPv4

Il faut commencer par les options de base, router-id, politique de gestion des routes, routes statiques, ce que l’on journalise, etc.

# Configure logging
log syslog { warning, error, fatal, bug };

# Turn on global debugging of all protocols
# debug protocols all;


# Override router ID and store ASN
router id 89.234.186.1;
define myasn = 204092;


#####################
# GENERAL PROTOCOLS #
#####################
# This pseudo-protocol watches all interface up/down events.
protocol device
{
    # Scan interfaces every 5 seconds
    scan time 5;
}

# test by glucas - 2016-09-13 for ibgp VPN nh
# get ibgp nh
protocol direct
{
    # Restrict network interfaces we work on
    interface "em1";
}

# This pseudo-protocol performs synchronization between BIRD's routing tables and the kernel.
protocol kernel
{
    # Don't remove routes on BIRD shutdown
    persist;

    import none;

    # Export to the kernel.
    # FreeBSD doesn't support "krt_prefsrc" :'(
    export all;
}


# Static routes
# Used to announce our IP allocations and drop traffic for non-allocated IPs
# (if we don't have a more specific route). Without it, traffic for our allocations go out of our AS.
protocol static static_grifon_allocations
{
    import all;

    route 89.234.186.0/24 unreachable;
}

Ensuite, on définit les filtres d’entrée. Notons que nous utilisons des templates afin de factoriser le code dans les fonctions de filtrage. Nous avons un filtre spécifique pour le VPN afin de s’assurer que ce ne soit que des /32 IPv4 qui soient annoncés (pas de route de par défaut ou du /27 réservé aux VPNs), et qu’ils soient bien dans le /25 normalement utilisable.

###############
# BGP FILTERS #
###############
function check_import(int peeras; ip nexthop)
  prefix set martians;
  int set reserved_asn;
  prefix set our_prefixes;
{
    martians = [ 10.0.0.0/8+, 100.64.0.0/10+,
        127.0.0.0/8+, 169.254.0.0/16+, 172.16.0.0/12+,
        192.0.0.0/24+, 192.0.2.0/24+, 192.168.0.0/16+,
        198.18.0.0/15+, 198.51.100.0/24+, 203.0.113.0/24+,
        224.0.0.0/4+, 240.0.0.0/4+, 255.255.255.255/32 ];

    reserved_asn = [ 0, 64297..131071, 4200000000..4294967294, 4294967295 ];

    our_prefixes = [ 89.234.186.0/24+, 149.6.72.96/29+, 89.234.141.142/31+, 
                89.234.186.13/32, 89.234.186.14/32 ];

    # Avoid too short and too long prefixes
    if (net.len < 8) || (net.len > 24) then return false;

    # Avoid 0.0.0.0/X (default route + 0.0.0.0/8)
    if net.ip = 0.0.0.0 then return false;

    # Avoid reserved networks
    if net ~ martians then return false;

    # Remove our prefixes. Only us can announce them
    # Remove also our interconnection prefixes. We are directly connected.
    if net ~ our_prefixes then return false;

    # Check that the next AS is our neighbour's.
    # Same for next-hop
    if bgp_path.first != peeras then return false;
    if bgp_next_hop != nexthop then return false;

    # AS_PATH too long (max seen in real life = 54)
    if bgp_path.len > 64 then return false;

    # Don't accept if path contains a reserved AS
    # Disabled because it removes legit prefixes
    # if bgp_path ~ reserved_asn then return false;

    return true;
}

function check_vpn_import() {
	if ! (net.len = 32 ) then return false;
	if ! (net ~ [ 89.234.186.0/25+ ]) then return false;

	else return true;
}

filter bgp_filter_cogent_in
{
    if (check_import(174, 149.6.72.97)) then
    {
        # Here we can set localpref or remove a prefix, for example

        accept;
    }
    else
    {
        reject "Prefix filtered IN Cogent";
    }
}

filter bgp_filter_arn_hwhost1_in
{
    if (check_import(60630, 89.234.141.142)) then
    {
        # Here we can set localpref or remove a prefix, for example

        accept;
    }
    else
    {
        reject "Prefix filtered IN ARN hwhost1";
    }
}

filter bgp_filter_arn_hwhost2_in
{
    if (check_import(60630, 89.234.186.13)) then
    {
        # Here we can set localpref or remove a prefix, for example

        accept;
    }
    else
    {
        reject "Prefix filtered IN ARN hwhost2";
    }
}

# For VPN
filter ibgp_filter_vpn_in {
    if (check_vpn_import()) then accept;
    else reject "Prefix filtered for iBGP VPN";
}

Puis les filtres de sortie. Nous remarquons que c’est ici que l’on définit l’AS prepending afin d’influer (un peu) sur le choix des routes. L’AS prepending ne fonctionne pas forcément car il est de poids plus faible que le localpref, donc si un autre AS favorise interoute par rapport à cogent, il passera par interoute même si l’AS path est plus long.

# For ARN
filter bgp_filter_backup_upstream_out
{
    # Export only our IP allocations
    if (proto = "static_grifon_allocations") then
    {
        # Here you can set community or do AS-prepending

        # AS-prepending
        bgp_path.prepend(204092);
        bgp_path.prepend(204092);

        accept;
    }
    else
    {
        reject "Prefix filtered OUT backup upstream";
    }
}

Pour finir, on définit nos peers BGP. Attention, il faut impérativement avoir définit les filtres avant.
Chaque peer est sous la même forme : « protocol bgp $peer { options; } ». Si vous ne nommez pas vos peers ($peer), il va y avoir des conflits entre eux.

##################
# eBGP NEIGHBORS #
#   UPSTREAMS    #
##################
template bgp UPSTREAM
{
    local as myasn;

    # Be able to see filtered routes with "sh route filtered" command
    import keep filtered;

    # Protect ourselves from massive routes leaks
    receive limit 620000 action block;

    # Announce only our IP allocations
    export where proto = "static_grifon_allocations";
    export limit 1 action disable;
}

template bgp BACKUP_UPSTREAM from UPSTREAM
{
    # Do AS-prepending here
    export filter bgp_filter_backup_upstream_out;

    # We forward traffic to ARN when we have no other choice.
    # BIRD preference is like Cisco weight.
    # With several routers, we will need to use local_pref instead.
    preference 50;
}

protocol bgp bgp_cogent from UPSTREAM
{
    description "Cogent";

    neighbor 149.6.72.97 as 174;

    # Local address we use to establish the BGP session
    source address 149.6.72.98;

    # We cannot use TCP-MD5 auth because we use a poorly designed OS ;)
    # password=''

    # Accept all routes from Cogent except bogons and other bad stuff
    import filter bgp_filter_cogent_in;
}

protocol bgp bgp_arn_hwhost1 from BACKUP_UPSTREAM
{
    description "ARN-hwhost1";

    neighbor 89.234.141.142 as 60630;
    source address 89.234.141.143;

    import filter bgp_filter_arn_hwhost1_in;
}

protocol bgp bgp_arn_hwhost2 from BACKUP_UPSTREAM
{
    description "ARN-hwhost2";

    neighbor 89.234.186.13 as 60630;
    source address 89.234.186.14;

    import filter bgp_filter_arn_hwhost2_in;
}

Nous avons un peer spécifique pour le VPN où nous présisons un adresse source sidd

IPv6

Le schéma de la conf est le même qu’en IPv4.
On commence par les options de base, router-id, politique de gestion des routes, routes statiques, ce que l’on journalise, etc.

# Configure logging
log syslog { warning, error, fatal, bug };

# Turn on global debugging of all protocos
# debug protocols all;


# Override router ID
router id 89.234.186.1;


# This pseudo-protocol watches all interface up/down events.
protocol device {
    scan time 5;            # Scan interfaces every 5 seconds
}


# This pseudo-protocol performs synchronization between BIRD's routing tables and the kernel.
protocol kernel 
{
    persist;                # Don't remove routes on bird shutdown

    import none;

    # Export to kernel. This host must use that IP as source IP to initiate connections with the world
    export filter {
            # pas supporté FreeBSD
            # krt_prefsrc = 2a00:5881:8100::131;
            accept;
    };
}


# Static routes
protocol static static_grifon_allocations 
{
    import all;

    route 2a00:5884::/32 unreachable;
}

Ensuite, on définit les filtres d’entrée :

###############
# BGP FILTERS #
###############
function check_import(int peeras; ip nexthop)
  prefix set martians;
  int set reserved_asn;
  prefix set our_prefixes;
{
    # 2001::/23 contains for example 2001:4:112::/48, belonging to AS112
    # so we mustn't filter more specific
    # 3FFE::/16 et 5F00::/8 = formerly 6bone (IPv6 tests)
    martians = [ ::1/128, ::/128, ::ffff:0:0/96+, 100::/64+,
    2001:db8::/32+, 2001::/23, 2001:2::/48+,
    2001:10::/28+, 2002::/17+, fc00::/7, fe80::/10, ff00::/8+,
    3FFE::/16+, 5F00::/8+ ];

    reserved_asn = [ 0, 64297..131071, 4200000000..4294967294, 4294967295 ];

    our_prefixes = [ 2a00:5884::/32+, 2001:978:2:4e::5:0/112+, 2001:470:11:cf::/64+,
        2a00:5881:8100:ff00::/112+, 2a00:5884:ff::/112+ ];

    # Avoid too short and too long prefixes
    if (net.len < 16) || (net.len > 48) then return false;

    # Remove default route
    if net = ::/0 then return false;

    # Avoid reserved networks
    if net ~ martians then return false;

    # Avoid bogons. IANA didn't allocate outside of 2000::/3
    # but there are already announces there
    if ! (net.ip ~ 2000::/3) then return false;

    # Remove our prefixes. Only us can announce them
    # Remove our interconnection prefixes. We are directly connected
    if net ~ our_prefixes then return false;

    # Check that the next AS is our neighbour's.
    # Same for next-hop
    if bgp_path.first != peeras then return false;
    if bgp_next_hop != nexthop then return false;

    # AS_PATH too long (max seen in real life = 54)
    if bgp_path.len > 64 then return false;

    # Don't accept if path contains a reserved AS
    # Disabled because it removes legit prefixes
    # if bgp_path ~ reserved_asn then return false;

    return true;
}

filter bgp_filter_cogent_in
{
    if (check_import(174, 2001:978:2:4e::5:1)) then
    {
        # Here you can set localpref or remove a prefix, for example

        accept;
    }
    else
    {
        reject "Prefix filtered IN Cogent";
    }
}

filter bgp_filter_hurricane_electric_in
{
    if (check_import(6939, 2001:470:11:cf::1)) then
    {
        # Here you can set localpref or remove a prefix, for example

        accept;
    }
    else
    {
        reject "Prefix filtered IN HE";
    }
}

filter bgp_filter_arn_hwhost1_in
{
    if (check_import(60630, 2a00:5881:8100:ff00::142)) then
    {
        # Here you can set localpref or remove a prefix, for example

        accept;
    }
    else
    {
        reject "Prefix filtered IN ARN hwhost1";
    }
}

filter bgp_filter_arn_hwhost2_in
{
    if (check_import(60630, 2a00:5884:ff::13)) then
    {
        # Here you can set localpref or remove a prefix, for example

        accept;
    }
    else
    {
        reject "Prefix filtered IN ARN hwhost2";
    }
}

# For HE and AND
filter bgp_filter_backup_upstream_out
{
    # Export only our IP allocations
    if (proto = "static_grifon_allocations") then
    {
        # Here you can set community or do AS-prepending

        # AS-prepending
        bgp_path.prepend(204092);
        bgp_path.prepend(204092);
        
        accept;
    }
    else
    {
        reject "Prefix filtered OUT backup upstream";
    }
} 

Et pour finir, nos peers BGP.

##################
# eBGP NEIGHBORS #
#   UPSTREAMS    #
##################
template bgp UPSTREAM
{
    local as myasn;

    # Be able to see filtered routes with "sh route filtered" command
    import keep filtered;

    # Protect ourselves from massive routes leaks
    receive limit 50000 action block;

    # Announce only our IP allocations
    export where proto = "static_grifon_allocations";
    export limit 1 action disable;
}

template bgp BACKUP_UPSTREAM from UPSTREAM
{
    # AS-prepending + export only ARN's IP allocations
    export filter bgp_filter_backup_upstream_out;

    # We forward traffic to ARN when we have no other choice.
    # BIRD preference is like Cisco weight.
    # With several routers, we will need to use local_pref instead.
    preference 50;
}

protocol bgp bgp_cogent from UPSTREAM
{
    description "Cogent";

    neighbor 2001:978:2:4e::5:1 as 174;

    # Local address we use to establish the BGP session
    source address 2001:978:2:4e::5:2;

    # We cannot use TCP-MD5 auth because we use a poorly designed OS ;)
    # password=''

    # Accept all routes from Cogent except bogons and other bad stuff
    import filter bgp_filter_cogent_in;
}

protocol bgp bgp_hurricane_electric from BACKUP_UPSTREAM
{
    description "Hurricane_Electric";

    neighbor 2001:470:11:cf::1 as 6939;
    source address 2001:470:11:cf::2;

    import filter bgp_filter_hurricane_electric_in;
}

protocol bgp bgp_arn_hwhost1 from BACKUP_UPSTREAM
{
    description "ARN-hwhost1";

    neighbor 2a00:5881:8100:ff00::142 as 60630;
    source address 2a00:5881:8100:ff00::143;

    import filter bgp_filter_arn_hwhost1_in;
}

protocol bgp bgp_arn_hwhost2 from BACKUP_UPSTREAM
{
    description "ARN-hwhost2";

    neighbor 2a00:5884:ff::13 as 60630;
    source address 2a00:5884:ff::14;

    import filter bgp_filter_arn_hwhost2_in;
}
reseau/bgp/ebgp.txt · Dernière modification : 2019/09/01 17:05 de 127.0.0.1