diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..9b9c2b0 --- /dev/null +++ b/README.txt @@ -0,0 +1,54 @@ +59811:666 => /24 = only send to Voxility + /32 = announce to RTBH on ixs/upstreams/UTRS +65535:666 => COMMUNITY-AS59811-BLACKHOLE + +59811:6500x => originated from site + | + x => 0 = all + 1 = TN2 + 2 = LD5 + 3 = MA1 + 4 = PUE + +650xy:zzzzz + |||| + x => 0 = all + | | 1 = TN2 + | | 2 = LD5 + | | 3 = MA1 + | | 4 = PUE + | | + y => 0 = no-announce + | 1 = prepend 1 + | 2 = prepend 2 + | 3 = prepend 3 + | 9 = no-export + | + zzzzz => 0 = any peer/upstream/downstream + 1299 = Arelion + 2914 = NTT + 3223 = Voxility (NB see also 59811:666) + 6762 = TISparkle + 65511 = Tampnet (would be 200781) + + 65521 = LON1 + 65522 = LON2 + 65523 = LINX Manchester + 65524 = LINX Scotland + 65525 = LONAP + + + +LOCAL PREFERENCES + +100 => transit (de-pref) +200 => transit +300 => transit (up-pref) + +400 => peering (de-pref) +500 => peering +600 => peering (up-pref) + +700 => downstream (de-pref) +800 => downstream +900 => downstream (up-pref) diff --git a/includes/junos-macros.j2 b/includes/junos-macros.j2 index 96b6fc7..cb2619e 100644 --- a/includes/junos-macros.j2 +++ b/includes/junos-macros.j2 @@ -8,7 +8,7 @@ {%- endif %} {%- endmacro %} -{%- macro interface_addresses(device, interface, interface_context, mtu=False) %} +{%- macro interface_addresses(device, interface, interface_context, interface_tags, mtu=False) %} family inet { {%- if mtu and interface.mtu %} mtu {{ interface.mtu }}; @@ -17,8 +17,12 @@ address {{ address.address }}{% if address.address == device.primary_ip4.address %}{ primary; preferred; - }{% endif %} + }{% else %};{% endif %} {%- endif %}{%- endfor %} + + filter { + input control-plane-protection-IPv4; + } } family inet6 { {%- if mtu and interface.mtu %} @@ -28,8 +32,12 @@ address {{ address.address }}{% if address.address == device.primary_ip6.address %}{ primary; preferred; - }{% endif %} + }{% else %};{% endif %} {%- endif %}{%- endfor %} + + filter { + input control-plane-protection-IPv6; + } } {%- set tags = interface.tags|tags_to_map %} {%- if 'core-isis-link' in tags %} diff --git a/includes/junos-v21-core-router/chassis.j2 b/includes/junos-v21-core-router/chassis.j2 index eaceb3b..7bfbf6e 100644 --- a/includes/junos-v21-core-router/chassis.j2 +++ b/includes/junos-v21-core-router/chassis.j2 @@ -3,7 +3,7 @@ {%- if interface.type.value == 'lag' %}{%- do lag_interfaces.append(interface) %}{%- endif %} {%- endfor %} -chassis { +{{ "chassis"|progress }} { maximum-ecmp 16; redundancy { routing-engine 0 master; diff --git a/includes/junos-v21-core-router/firewall.j2 b/includes/junos-v21-core-router/firewall.j2 new file mode 100644 index 0000000..3056417 --- /dev/null +++ b/includes/junos-v21-core-router/firewall.j2 @@ -0,0 +1,212 @@ +{{ "firewall"|progress }} { + + {%- set bgp_multihop_prefixes_v4 = [] %} + {%- set bgp_multihop_prefixes_v6 = [] %} + {%- for prefix in 'bgp-multihop'|get_netbox_tagged_prefixes %} + {%- if prefix|ipv4 %}{% do bgp_multihop_prefixes_v4.append( prefix ) %} + {%- elif prefix|ipv6 %}{% do bgp_multihop_prefixes_v6.append( prefix ) %} + {%- endif %} + {%- endfor %} + + {%- set bgp_allowed_prefixes_v4 = [] %} + {%- set bgp_allowed_prefixes_v6 = [] %} + {%- for prefix in 'bgp-allowed'|get_netbox_tagged_prefixes %} + {%- if prefix|ipv4 %}{% do bgp_allowed_prefixes_v4.append( prefix ) %} + {%- elif prefix|ipv6 %}{% do bgp_allowed_prefixes_v6.append( prefix ) %} + {%- endif %} + {%- endfor %} + + {%- set ldp_allowed_prefixes_v4 = [] %} + {%- set ldp_allowed_prefixes_v6 = [] %} + {%- for prefix in 'ldp-allowed'|get_netbox_tagged_prefixes %} + {%- if prefix|ipv4 %}{% do ldp_allowed_prefixes_v4.append( prefix ) %} + {%- elif prefix|ipv6 %}{% do ldp_allowed_prefixes_v6.append( prefix ) %} + {%- endif %} + {%- endfor %} + + family inet { + filter control-plane-protection-IPv4 { + + {% if bgp_multihop_prefixes_v4 %} + term allow-multihop-bgp { + from { + source-address { + {% for prefix in bgp_multihop_prefixes_v4 %} + {{ prefix }}; /* {{ prefix.description }} */ + {% endfor %} + } + protocol tcp; + port 179; + } + then { + accept; + } + } + {% endif %} + {% if bgp_allowed_prefixes_v4 %} + term allow-gtsm-bgp { + from { + protocol tcp; + source-address { + {% for prefix in bgp_allowed_prefixes_v4 %} + {{ prefix }}; /* {{ prefix.description }} */ + {% endfor %} + } + tcp-initial; + ttl 255; + port 179; + } + then { + accept; + } + } + term allow-established-bgp { + from { + protocol tcp; + source-address { + {% for prefix in 'bgp-allowed'|get_netbox_tagged_prefixes %}{% if prefix|ipv4 %} + {{ prefix }}; /* {{ prefix.description }} */ + {% endif %}{% endfor %} + } + tcp-established; + port 179; + } + then { + accept; + } + } + {% endif %} + term reject-bgp { + from { + protocol tcp; + port 179; + } + then { + reject tcp-reset; + } + } + {% if ldp_allowed_prefixes_v4 %} + term allow-ldp { + from { + source-address { + {% for prefix in ldp_allowed_prefixes_v4 %} + {{ prefix }}; /* {{ prefix.description }} */ + {% endfor %} + } + protocol tcp; + port 646; + } + then { + accept; + } + } + {% endif %} + term reject-ldp { + from { + protocol tcp; + port 646; + } + then { + reject tcp-reset; + } + } + term else { + then { + accept; + } + } + } + } + family inet6 { + filter control-plane-protection-IPv6 { + {% if bgp_multihop_prefixes_v6 %} + term allow-multihop-bgp { + from { + source-address { + {% for prefix in bgp_multihop_prefixes_v6 %} + {{ prefix }}; /* {{ prefix.description }} */ + {% endfor %} + } + next-header tcp; + destination-port 179; + } + then { + accept; + } + } + {% endif %} + {% if bgp_allowed_prefixes_v6 %} + term allow-gtsm-bgp { + from { + next-header tcp; + source-address { + {% for prefix in bgp_allowed_prefixes_v6 %} + {{ prefix }}; /* {{ prefix.description }} */ + {% endfor %} + } + hop-limit 255; + tcp-initial; + destination-port 179; + } + then { + accept; + } + } + term allow-established-bgp { + from { + next-header tcp; + source-address { + {% for prefix in bgp_allowed_prefixes_v6 %} + {{ prefix }}; /* {{ prefix.description }} */ + {% endfor %} + } + tcp-established; + destination-port 179; + } + then { + accept; + } + } + {% endif %} + term reject-bgp { + from { + next-header tcp; + destination-port 179; + } + then { + reject tcp-reset; + } + } + {% if ldp_allowed_prefixes_v6 %} + term allow-ldp { + from { + next-header tcp; + source-address { + {% for prefix in ldp_allowed_prefixes_v6 %} + {{ prefix }}; /* {{ prefix.description }} */ + {% endfor %} + } + destination-port 646; + } + then { + accept; + } + } + {% endif %} + term reject-ldp { + from { + next-header tcp; + destination-port 646; + } + then { + reject tcp-reset; + } + } + term else { + then { + accept; + } + } + } + } +} diff --git a/includes/junos-v21-core-router/forwarding-options.j2 b/includes/junos-v21-core-router/forwarding-options.j2 index 7285fc9..7fd0e90 100644 --- a/includes/junos-v21-core-router/forwarding-options.j2 +++ b/includes/junos-v21-core-router/forwarding-options.j2 @@ -1,4 +1,4 @@ -forwarding-options { +{{ "forwarding-options"|progress }} { sampling { input { rate 10000; diff --git a/includes/junos-v21-core-router/groups.j2 b/includes/junos-v21-core-router/groups.j2 index 08e3c30..bd7692b 100644 --- a/includes/junos-v21-core-router/groups.j2 +++ b/includes/junos-v21-core-router/groups.j2 @@ -1,4 +1,4 @@ -groups { +{{ "groups"|progress }} { {%- set re_groups = [] %} {%- for interface, subinterfaces in device|get_interfaces|subinterfaces(".") %} {%- if '@' in interface.name %} diff --git a/includes/junos-v21-core-router/interfaces.j2 b/includes/junos-v21-core-router/interfaces.j2 index e3ebb19..d9f5e77 100644 --- a/includes/junos-v21-core-router/interfaces.j2 +++ b/includes/junos-v21-core-router/interfaces.j2 @@ -1,6 +1,6 @@ -interfaces { +{{ "interfaces"|progress }} { -{%- for interface, subinterfaces in device|get_interfaces|subinterfaces(".") %} +{%- for interface, subinterfaces in device_interfaces|subinterfaces(".") %} {%- set interface_context = interface.tags|get_netbox_tags_contexts|contexts_merge_last %} {%- set interface_tags = [] %} @@ -31,6 +31,10 @@ interfaces { {{ macros.interface_common(interface, interface_context) }} {%- for unit, subinterface in subinterfaces %} + {%- set subinterface_tags = [] %} + {%- for tag in subinterface.tags %} + {%- do subinterface_tags.append(tag.slug) %} + {%- endfor %} unit {{ unit }} { {%- if subinterface.untagged_vlan %} vlan-id {{ subinterface.untagged_vlan.vid }}; @@ -40,7 +44,7 @@ interfaces { {%- set subinterface_context = subinterface.tags|get_netbox_tags_contexts|contexts_merge_last %} {{ macros.interface_description(subinterface, subinterface_context) }} {{ macros.interface_common(subinterface, subinterface_context, mtu=False) }} - {{ macros.interface_addresses(device, subinterface, subinterface_context, mtu=False) }} + {{ macros.interface_addresses(device, subinterface, subinterface_context, subinterface_tags, mtu=False) }} } {%- endfor %} @@ -62,7 +66,7 @@ interfaces { unit 0 { {{ macros.interface_description(interface, interface_context) }} {{ macros.interface_common(interface, interface_context, mtu=False) }} - {{ macros.interface_addresses(device, interface, interface_context, mtu=True) }} + {{ macros.interface_addresses(device, interface, interface_context, interface_tags, mtu=True) }} } {%- elif interface.mode.value == 'tagged' %} vlan-tagging; @@ -75,6 +79,11 @@ interfaces { {%- if interface.mode.value == 'tagged' %} {%- for unit, subinterface in subinterfaces %} + {%- set subinterface_tags = [] %} + {%- for tag in subinterface.tags %} + {%- do subinterface_tags.append(tag.slug) %} + {%- endfor %} + unit {{ unit }} { {%- if subinterface.untagged_vlan %} vlan-id {{ subinterface.untagged_vlan.vid }}; @@ -84,7 +93,7 @@ interfaces { {%- set subinterface_context = subinterface.tags|get_netbox_tags_contexts|contexts_merge_last %} {{ macros.interface_description(subinterface, subinterface_context) }} {{ macros.interface_common(subinterface, subinterface_context, mtu=False) }} - {{ macros.interface_addresses(device, subinterface, subinterface_context, mtu=True) }} + {{ macros.interface_addresses(device, subinterface, subinterface_context, subinterface_tags, mtu=True) }} } {%- endfor %} {%- endif %} diff --git a/includes/junos-v21-core-router/policy-options.j2 b/includes/junos-v21-core-router/policy-options.j2 new file mode 100644 index 0000000..85dedb0 --- /dev/null +++ b/includes/junos-v21-core-router/policy-options.j2 @@ -0,0 +1,468 @@ +{{ "policy-options"|progress }} { + +{# + prefix-list V6 { + 2001:db9::/32; + } + prefix-list V4 { + 192.0.2.0/24; + } +#} + + policy-statement EXPORT-PROTECT-reject { + term 10 { + from as-path-group NEVER-TO-UPSTREAM-OR-PEERS; + then reject; + } + } + + route-filter-list BOGONS-IPv4 { + 0.0.0.0/8 orlonger; + 10.0.0.0/8 orlonger; + 100.64.0.0/10 orlonger; + 127.0.0.0/8 orlonger; + 169.254.0.0/16 orlonger; + 172.16.0.0/12 orlonger; + 192.0.0.0/24 orlonger; + 192.0.2.0/24 orlonger; + 192.168.0.0/16 orlonger; + 198.18.0.0/15 orlonger; + 198.51.100.0/24 orlonger; + 203.0.113.0/24 orlonger; + 224.0.0.0/4 orlonger; + 240.0.0.0/4 orlonger; + } + + route-filter-list BOGONS-IPv6 { + ::/128 exact; + ::1/128 exact; + ::ffff:0:0/96 orlonger; + ::/96 orlonger; + 100::/64 orlonger; + 2001:10::/28 orlonger; + 2001:db8::/32 orlonger; + fc00::/7 orlonger; + fe80::/10 orlonger; + fec0::/10 orlonger; + ff00::/8 orlonger; + } + + route-filter-list DFZ-IPv4 { + 0.0.0.0/0 prefix-length-range /8-/24; + } + + route-filter-list DFZ-IPv6 { + ::/0 prefix-length-range /20-/48; + } + + policy-statement BOGONS-reject { + term 24 { + from { + family inet; + route-filter-list BOGONS-IPv4; + } + then reject; + } + term 26 { + from { + family inet6; + route-filter-list BOGONS-IPv6; + } + then reject; + } + } + + policy-statement DEFAULT-accept { + term 14 { + from { + family inet; + route-filter 0.0.0.0/0 exact; + } + then accept; + } + term 16 { + from { + family inet6; + route-filter ::/0 exact; + } + then accept; + } + } + + policy-statement DFZ-accept { + term 14 { + from { + family inet; + route-filter 0.0.0.0/0 exact; + } + then accept; + } + term 16 { + from { + family inet6; + route-filter ::/0 exact; + } + then accept; + } + } + + policy-statement IBGP-import-IPv4 { + then accept; + } + policy-statement IBGP-import-IPv6 { + then accept; + } + policy-statement IBGP-export-IPv4 { + term 10 { + from { + protocol [ direct static ]; + } + then { + local-preference add 900; + next-hop self; + accept; + } + } + term 25 { + from { + protocol bgp; + route-type external; + } + then { + next-hop self; + accept; + } + } + term 29 { + from { + protocol bgp; + community COMMUNITY-AS59811-BLACKHOLE; + route-type external; + } + then { + next-hop 193.162.44.0; + accept; + } + } + term 30 { + from { + protocol bgp; + route-type external; + } + then { + next-hop self; + accept; + } + } + term 40 { + from protocol bgp; + then accept; + } + then reject; + } + policy-statement IBGP-export-IPv6 { + term 10 { + from { + protocol [ direct static ]; + } + then { + local-preference add 900; + next-hop self; + accept; + } + } + term 25 { + from { + protocol bgp; + route-type external; + } + then { + next-hop self; + accept; + } + } + term 29 { + from { + protocol bgp; + community COMMUNITY-AS59811-BLACKHOLE; + route-type external; + } + then { + next-hop 2a10:f0c0::; + accept; + } + } + term 30 { + from { + protocol bgp; + route-type external; + } + then { + next-hop self; + accept; + } + } + term 40 { + from protocol bgp; + then accept; + } + then reject; + } + + policy-statement LOAD-BALANCING { + then { + load-balance per-packet; + } + } + + policy-statement CONDITIONAL-DEFAULT-IPv4 { + term 10 { + from { + protocol bgp; + route-filter 198.41.0.0/24 exact; /* a.root-servers.net */ + route-filter 192.228.79.0/24 exact; /* b.root-servers.net */ + route-filter 192.33.4.0/24 exact; /* c.root-servers.net */ + route-filter 128.8.0.0/16 exact; /* d.root-servers.net */ + route-filter 192.203.230.0/24 exact; /* e.root-servers.net */ + route-filter 192.5.5.0/24 exact; /* f.root-servers.net */ + route-filter 192.112.36.0/24 exact; /* g.root-servers.net */ + route-filter 128.63.0.0/16 exact; /* h.root-servers.net */ + route-filter 192.36.148.0/24 exact; /* i.root-servers.net */ + route-filter 192.58.128.0/24 exact; /* j.root-servers.net */ + route-filter 193.0.14.0/24 exact; /* k.root-servers.net */ + route-filter 198.32.64.0/24 exact; /* l.root-servers.net */ + route-filter 202.12.27.0/24 exact; /* m.root-servers.net */ + } + then accept; + } + then reject; + } + + policy-statement CONDITIONAL-DEFAULT-IPv6 { + term 10 { + from { + protocol bgp; + route-filter 2001:503:ba3e::/48 exact; /* a.root-servers.net */ + route-filter 2001:500:2f::/48 exact; /* b.root-servers.net */ + route-filter 2001:500:1::/48 exact; /* c.root-servers.net */ + route-filter 2001:500:2d::/48 exact; /* d.root-servers.net */ + route-filter 2001:500:a8::/48 exact; /* e.root-servers.net */ + route-filter 2001:500:2f::/48 exact; /* f.root-servers.net */ + route-filter 2001:500:12::/48 exact; /* g.root-servers.net */ + route-filter 2001:500:1::/48 exact; /* h.root-servers.net */ + route-filter 2001:7fe::/33 exact; /* i.root-servers.net */ + route-filter 2001:503:c27::/48 exact; /* j.root-servers.net */ + route-filter 2001:7fd::/48 exact; /* k.root-servers.net */ + route-filter 2001:500:9f::/48 exact; /* l.root-servers.net */ + route-filter 2001:dc3::/32 exact; /* m.root-servers.net */ + } + then accept; + } + then reject; + } + + policy-statement LINX-LON1-IPv4-IN { + term 4 { + from { + family inet; + route-filter 0.0.0.0/0 prefix-length-range /0-/7; + route-filter 0.0.0.0/0 prefix-length-range /25-/32; + } + then reject; + } + term 6 { + from as-path-group LINX-LON1-ASPATH-DEPREFER; + then { + metric 10; + local-preference 400; + accept; + } + } + term 10 { + then { + metric 10; + local-preference 500; + accept; + } + } + then reject; + } + + policy-statement LINX-LON1-IPv4-OUT { + term 5 { + from { + family inet; + route-filter 0.0.0.0/0 prefix-length-range /0-/7; + route-filter 0.0.0.0/0 prefix-length-range /25-/32; + } + then reject; + } + then reject; + } + + policy-statement LINX-LON1-IPv6-IN { + term 4 { + from { + family inet6; + route-filter ::/0 prefix-length-range /0-/16; + route-filter ::/0 prefix-length-range /49-/128; + } + then reject; + } + term 6 { + from as-path-group LINX-LON1-ASPATH-DEPREFER; + then { + metric 10; + local-preference 400; + accept; + } + } + term 10 { + then { + metric 10; + local-preference 500; + accept; + } + } + then reject; + } + + policy-statement LINX-LON1-IPv6-OUT { + term 5 { + from { + family inet6; + route-filter ::/0 prefix-length-range /0-/16; + route-filter ::/0 prefix-length-range /25-/32; + } + then reject; + } + then reject; + } + + policy-statement UPSTREAM-export-IPv4 { + term 1 { + from { + community COMMUNITY-ORIGIN-AS59811; + } + then accept; + } + then reject; + } + policy-statement UPSTREAM-import-IPv4 { + term 1 { + from { + family inet; + route-filter 0.0.0.0/0 prefix-length-range /8-/24; + } + then { + accept; /* XXX this needs to go! */ + } + } + then reject; + } + policy-statement UPSTREAM-export-IPv6 { + term 1 { + from { + community COMMUNITY-ORIGIN-AS59811; + } + then accept; + } + then reject; + } + policy-statement UPSTREAM-import-IPv6 { + term 1 { + from { + family inet6; + route-filter ::/0 prefix-length-range /16-/48; + } + then { + accept; /* XXX this needs to go! */ + } + } + then reject; + } + policy-statement PEER-export-IPv4 { + term 1 { + from { + community COMMUNITY-ORIGIN-AS59811; + } + then accept; + } + then reject; + } + policy-statement PEER-import-IPv4 { + term 1 { + from { + family inet; + route-filter 0.0.0.0/0 prefix-length-range /8-/24; + } + then { + community delete COMMUNITY-AS59811-STAR; + accept; /* XXX this needs to go! */ + } + } + then reject; + } + policy-statement PEER-export-IPv6 { + term 1 { + from { + community COMMUNITY-ORIGIN-AS59811; + } + then accept; + } + then reject; + } + policy-statement PEER-import-IPv6 { + term 1 { + from { + family inet6; + route-filter ::/0 prefix-length-range /16-/48; + } + then { + community delete COMMUNITY-AS59811-STAR; + accept; /* XXX this needs to go! */ + } + } + then reject; + } + + {% for community in ''|get_bgp_communities %} + community {{ community.slug }} members {% if " " in community.value %}[ {{ community.value }} ]{% else %}{{ community.value }}{% endif %};{% endfor %} + + as-path-group NEVER-TO-UPSTREAM-OR-PEERS { + as-path TIER1-IN-PATH ".* (7018|3320|3257|6830|3356|2914|5511|3491|1239|6453|6762|1299|12956|701|6461) .*"; + as-path TIER2-IN-PATH ".* (4134|4809|7473|174|7922|6939|9002|1273|2828|4637) .*"; + } + + as-path-group LINX-LON1-ASPATH-DEPREFER { + as-path FAELIX-DEPREFER "41495 .*"; + } + + {% for asn in asns_requiring_prefixes|unique %} + {% set prefixes = asn|get_prefixes_for_asn %} + policy-statement AS{{ asn }}-import-IPv4 { + term 1 { + from { + family inet; + {% for prefix in prefixes['ipv4'] %} + route-filter {{ prefix['prefix'] }} {% if prefix['exact'] %}exact{% else %}upto /{{ prefix['less-equal'] }}{% endif %}; + {% endfor %} + } + then accept; + } + then reject; + } + policy-statement AS{{ asn }}-import-IPv6 { + term 1 { + from { + family inet6; + {% for prefix in prefixes['ipv6'] %} + route-filter {{ prefix['prefix'] }} {% if prefix['exact'] %}exact{% else %}upto /{{ prefix['less-equal'] }}{% endif %}; + {% endfor %} + } + then accept; + } + then reject; + } + {% endfor %} +} diff --git a/includes/junos-v21-core-router/protocols.j2 b/includes/junos-v21-core-router/protocols.j2 new file mode 100644 index 0000000..5faccfb --- /dev/null +++ b/includes/junos-v21-core-router/protocols.j2 @@ -0,0 +1,146 @@ +{% macro bgp_neighbor(neighbor, neighbor_data, ibgp) %} + neighbor {{ neighbor }} { + description "{% if neighbor_data['relationship'] %}{{ neighbor['relationship']|safe_string }}: {% endif %}{% if neighbor_data['service_reference'] %}{{ neighbor_data['service_reference']|safe_string }} - {% endif %}{{ neighbor_data['description']|safe_string }}"; + {% if 'local-as' in neighbor_data %}local-as {{ neighbor_data['local-as'] }};{% endif %} + peer-as {{ neighbor_data['remote-as'] }}; + {% if neighbor_data.get('encrypted_password',None) or neighbor_data.get('password',None) %}authentication-key "{{ neighbor_data['encrypted_password'] or neighbor_data['password'] }}";{% endif %} + {% if neighbor_data.get('update-source',None) %}local-address {{ neighbor_data['update-source'].split("/")[0] }};{% endif %} + {% if neighbor_data.get('ebgp-multihop',0) > 1 %}multihop ttl {{ neighbor_data['ebgp-multihop'] }};{% endif %} + {% if neighbor_data.get('shutdown',False) %}shutdown;{% endif %} + + {%- if neighbor_data['import-policies'] %} + import [ {% for policy in neighbor_data['import-policies'] %}{{ policy }} {% endfor %}]; + {%- endif %} + {%- if neighbor_data['export-policies'] %} + export [ {% for policy in neighbor_data['export-policies'] %}{{ policy }} {% endfor %}]; + {%- endif %} + + {%- if neighbor|ipv4 %} + family inet { + unicast; + } + {% if- ibgp %} + family inet-vpn { + unicast; + } + family inet6-vpn { + unicast; + } + family l2vpn { + signaling; + } + {%- endif %} + {%- elif neighbor|ipv6 %} + family inet6 { + unicast; + } + {%- endif %} + + {%- do asns_requiring_prefixes.append(neighbor_data['remote-as']) %} + } +{% endmacro %} + +{{ "protocols"|progress }} { + mpls { + ipv6-tunneling; + icmp-tunneling; + {%- for interface in device_interfaces %} + {%- set tags = interface.tags|tags_to_map %} + {%- if 'core-isis-link' in tags %} + interface {{ interface.name }}; + {%- elif 'isis-loopback' in tags %} + interface {{ interface.name }}; + {%- endif %} + {%- endfor %} + } + bgp { + + {%- set bgp_router = device|get_bgp_router() %} + /* PEERING MANAGER BGP ROUTER: {{ bgp_router }} */ + + precision-timers; + mtu-discovery; + log-updown; + ttl 255; + + {%- if bgp_router %} + {%- for (bgp_group, neighbors) in bgp_router|get_bgp_groups_and_neighbors() %} + {%- if bgp_group %} + group {{ bgp_group.slug }} { + description "{{ bgp_group.name|safe_string }}" + ttl 255; + + {% if bgp_group.import_routing_policies %}import [ {% for policy in bgp_group.import_routing_policies %}{{ policy.slug }} {% endfor %}]{% endif %}; + {% if bgp_group.export_routing_policies %}export [ {% for policy in bgp_group.export_routing_policies %}{{ policy.slug }} {% endfor %}]{% endif %}; + + {%- endif %} + {%- for neighbor in neighbors %} + {%- set ibgp = ( bgp_router.local_autonomous_system.asn == neighbor.autonomous_system.asn ) %} + {{ bgp_neighbor(neighbor.ip_address.split("/")[0], neighbor|peer_to_neighbor_data(bgp_router), ibgp=ibgp) }} + {%- endfor %} + {%- if bgp_group %} + } + {%- endif %} + {%- endfor %} + + {%- for (conn, neighbors) in bgp_router|get_bgp_internet_exchanges_and_neighbors() %} + group {{ conn.internet_exchange_point.slug }} { + description "{{ conn.internet_exchange_point.name|safe_string }}" + {%- for neighbor in neighbors %} + {%- set ibgp = ( bgp_router.local_autonomous_system.asn == neighbor.autonomous_system.asn ) %} + {{ bgp_neighbor(neighbor.ip_address.split("/")[0], neighbor|peer_to_neighbor_data(bgp_router), ibgp=ibgp) }} + {%- endfor %} + } + {%- endfor %} + {%- else %} + /* not this ASN {{ bgp_router.local_autonomous_system.asn }} */ + {%- endif %} + } + isis { + reference-bandwidth 100g; + lsp-lifetime 32767; + spf-options { + delay 50; + holddown 2000; + rapid-runs 1; + } + topologies ipv6-unicast; + level 1 disable; + level 2 { + authentication-key "$9$nR/0CAuOBEcyKcyVYoGq.p0B1EyVb2UjqUjHmPT/9vM8L7Vws4jiqxNds2ojiuOBIRSLX-ws4M8oGDjq.tuORclKvLX7VEc"; {# CaizoophoozahThaGhai5aicoo1okahl #} + authentication-type md5; + wide-metrics-only; + } + + {%- for interface in device_interfaces %} + {%- set tags = interface.tags|tags_to_map %} + {%- if 'core-isis-link' in tags %} + interface {{ interface.name }} { + point-to-point; + level 1 disable; + level 2 { + metric 1; + ipv6-unicast-metric 1; + } + } + {%- elif 'isis-loopback' in tags %} + interface {{ interface.name }} { + level 1 disable; + } + {%- endif %} + {%- endfor %} + } + ldp { + track-igp-metric; + keepalive-interval 10; + keepalive-timeout 90; + {%- for interface in device_interfaces %} + {%- set tags = interface.tags|tags_to_map %} + {%- if 'core-isis-link' in tags %} + interface {{ interface.name }}; + {%- elif 'isis-loopback' in tags %} + interface {{ interface.name }}; + {%- endif %} + {%- endfor %} + } +} diff --git a/includes/junos-v21-core-router/routing-options.j2 b/includes/junos-v21-core-router/routing-options.j2 index 39656e5..8539a13 100644 --- a/includes/junos-v21-core-router/routing-options.j2 +++ b/includes/junos-v21-core-router/routing-options.j2 @@ -1,8 +1,83 @@ -routing-options { +{{ "routing-options"|progress }} { + ppm; static { {%- for (route, route_data) in device.config_context.get('routes',{}).items() %} - route {{ route }} next-hop {{ route_data.get('next-hop', None) }}; + route {{ route }} { + next-hop {{ route_data.get('next-hop', None) }}; + retain; + no-readvertise; + } {%- endfor %} + + /* blackhole destination */ + route 193.162.44.0/32 { + discard; + no-readvertise; + } + + {% for announcement in 'as59811-origin'|get_netbox_tagged_prefixes %}{% if announcement.prefix|ipv4 %} + route {{ announcement.prefix }} { + /* {{ announcement.description }} */ + discard; + retain; + community [ {{ ("COMMUNITY-ORIGIN-AS59811"|get_bgp_community).value }} ]; + } + {% endif %}{% endfor %} + {% for announcement in 'as59811-origin'|get_netbox_tagged_aggregates %}{% if announcement.prefix|ipv4 %} + route {{ announcement.prefix }} { + /* {{ announcement.description }} */ + discard; + retain; + community [ {{ ("COMMUNITY-ORIGIN-AS59811"|get_bgp_community).value }} ]; + } + {% endif %}{% endfor %} + } + rib inet6.0 { + static { + /* blackhole destination */ + route 2a10:f0c0::/128 { + discard; + no-readvertise; + } + {% for announcement in 'as59811-origin'|get_netbox_tagged_prefixes %}{% if announcement.prefix|ipv6 %} + route {{ announcement.prefix }} { + /* {{ announcement.description }} */ + discard; + retain; + community [ {{ ("COMMUNITY-ORIGIN-AS59811"|get_bgp_community).value }} ]; + } + {% endif %}{% endfor %} + {% for announcement in 'as59811-origin'|get_netbox_tagged_aggregates %}{% if announcement.prefix|ipv6 %} + route {{ announcement.prefix }} { + /* {{ announcement.description }} */ + discard; + retain; + community [ {{ ("COMMUNITY-ORIGIN-AS59811"|get_bgp_community).value }} ]; + } + {% endif %}{% endfor %} + } + generate { + route ::/0 { + policy CONDITIONAL-DEFAULT-IPv6; + discard; + } + } } nonstop-routing; + autonomous-system 59811; + forwarding-table { + export LOAD-BALANCING; + chained-composite-next-hop { + ingress { + l2vpn; + l3vpn; + } + } + } + generate { + route 0.0.0.0/0 { + policy CONDITIONAL-DEFAULT-IPv4; + discard; + } + } } diff --git a/includes/junos-v21-core-router/snmp.j2 b/includes/junos-v21-core-router/snmp.j2 new file mode 100644 index 0000000..2954874 --- /dev/null +++ b/includes/junos-v21-core-router/snmp.j2 @@ -0,0 +1,5 @@ +{{ "snmp"|progress }} { + trap-options { + source-address lo0; + } +} diff --git a/includes/junos-v21-core-router/system.j2 b/includes/junos-v21-core-router/system.j2 index eed9448..622aba9 100644 --- a/includes/junos-v21-core-router/system.j2 +++ b/includes/junos-v21-core-router/system.j2 @@ -1,9 +1,16 @@ -system { +{{ "system"|progress }} { root-authentication { encrypted-password "$6$uC87jp7U$04FIKNRT3VcUzqDiaxKVRVqnQM2c48Q2NpIARsSuKVVK7gezNX92B7261QV.kRHg.yswiDhUY.SF4e/qgRNdL0"; ## SECRET-DATA } + ports { + console { + log-out-on-disconnect; + type vt100; + } + } commit synchronize; login { + message "\n__ _____ _ _ _____ _ _ ____ ____ ___ ___ _ _\n\\ \\ / / _ \\| \\ | | ____| | | / ___| __ _ ___| ___|/ _ \\ ( _ )/ / |\n \\ \\ / / | | | \\| | _| | | | \\___ \\ / _` / __|___ \\ (_) |/ _ \\| | |\n \\ V /| |_| | |\\ | |___| |_| |___) | | (_| \\__ \\___) \\__, | (_) | | |\n \\_/ \\___/|_| \\_|_____|\\___/|____/ \\__,_|___/____/ /_/ \\___/|_|_|\n\n"; user faelix { full-name "FAELIX NOC"; uid 2000; @@ -19,7 +26,6 @@ system { class super-user; authentication { encrypted-password "$6$4sVD2r4y$PjAIeLZ/tJcDhsQekJI9wU2l4xYf8k6mHuzvLivK2tcFXdcHMjP23Up/oUzMRWiVtEW99foiEWuXG40tL5cHy0"; - ssh-ed25519 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM05RD1X1njHcJvPTGbaCkO7rssp6T8uTCH3b6Sk4MA9 maz@lifting-shadows"; } } user nomios { @@ -28,7 +34,6 @@ system { class super-user; authentication { encrypted-password "$6$4sVD2r4y$PjAIeLZ/tJcDhsQekJI9wU2l4xYf8k6mHuzvLivK2tcFXdcHMjP23Up/oUzMRWiVtEW99foiEWuXG40tL5cHy0"; - ssh-ed25519 "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM05RD1X1njHcJvPTGbaCkO7rssp6T8uTCH3b6Sk4MA9 maz@lifting-shadows"; } } } @@ -68,12 +73,15 @@ system { {{ radius_server }} secret "{{ radius_data.get('secret') }}";{% endfor %} } accounting { - events login; + events [ login change-log interactive-commands ]; destination { radius; } } ntp { - server 185.134.196.169 prefer; + server 185.134.196.169 prefer; /* leontp.g.faelix.net */ + server 195.66.241.2 prefer; /* ntp0.linx.net */ + server 195.66.241.3 prefer; /* ntp1.linx.net */ + server 195.66.241.10 prefer; /* ntp2.linx.net */ } } diff --git a/junos-v21-core-router.j2 b/junos-v21-core-router.j2 index cb440ae..6a94ea6 100644 --- a/junos-v21-core-router.j2 +++ b/junos-v21-core-router.j2 @@ -4,9 +4,16 @@ version 21.3R1.9; +{% set asns_requiring_prefixes = [] %} +{% set device_interfaces = device|get_interfaces %} + {% include "includes/junos-v21-core-router/groups.j2" with context %} {% include "includes/junos-v21-core-router/system.j2" with context %} {% include "includes/junos-v21-core-router/chassis.j2" with context %} {% include "includes/junos-v21-core-router/interfaces.j2" with context %} +{% include "includes/junos-v21-core-router/firewall.j2" with context %} +{% include "includes/junos-v21-core-router/snmp.j2" with context %} {% include "includes/junos-v21-core-router/forwarding-options.j2" with context %} {% include "includes/junos-v21-core-router/routing-options.j2" with context %} +{% include "includes/junos-v21-core-router/protocols.j2" with context %} +{% include "includes/junos-v21-core-router/policy-options.j2" with context %}