cccampix: updates from camp

Change-Id: I77e6d9fb6e91b0b7e2d1f89e80164ee8116b5d50
This commit is contained in:
Serge Bazanski 2019-08-29 14:53:18 +02:00
parent a2960f526c
commit ef93747aec
5 changed files with 300 additions and 24 deletions

View file

@ -20,6 +20,7 @@ var (
flagRouterID string
flagV6 bool
flagLocalIP string
flagUpstream bool
)
func init() {
@ -32,6 +33,7 @@ func main() {
flag.StringVar(&flagRouterID, "router_id", "", "Router ID")
flag.StringVar(&flagLocalIP, "local_ip", "", "Local IP")
flag.BoolVar(&flagV6, "v6", false, "V6")
flag.BoolVar(&flagUpstream, "upstream", false, "Is an upstream router")
flag.Parse()
@ -77,6 +79,17 @@ timeformat log iso long;
timeformat protocol iso long;
timeformat route iso long;
define ourASN = %d;
define filteredNumber = 65666;
define customerNumber = 65667;
define martian = 1;
define prefixTooLong64 = 2;
define prefixTooLong24 = 3;
define pathBogon = 4;
define pathTooLong = 5;
define pathFirstNotPeer = 6;
define prefixFiltered = 9;
protocol device {}
function net_martians() {
@ -84,14 +97,22 @@ function net_martians() {
}
function generic_in() {
if net_martians() then return false;
if bgp_path.len > 64 then return false;
if net.len > 64 then return false;
if net.len < 12 then return false;
if net_martians() then {
bgp_large_community.add((ourASN, filteredNumber, martian));
return false;
}
if bgp_path.len > 64 then {
bgp_large_community.add((ourASN, filteredNumber, pathTooLong));
return false;
}
if net.len > 64 then {
bgp_large_community.add((ourASN, filteredNumber, prefixTooLong64));
return false;
}
return true;
}
`
config = fmt.Sprintf(config, flagRouterID)
config = fmt.Sprintf(config, flagRouterID, 208521)
} else {
config = `
log syslog all;
@ -104,6 +125,17 @@ timeformat log iso long;
timeformat protocol iso long;
timeformat route iso long;
define ourASN = %d;
define filteredNumber = 65666;
define customerNumber = 65667;
define martian = 1;
define prefixTooLong64 = 2;
define prefixTooLong24 = 3;
define pathBogon = 4;
define pathTooLong = 5;
define pathFirstNotPeer = 6;
define prefixFiltered = 9;
protocol device {}
function net_martians() {
@ -112,14 +144,65 @@ function net_martians() {
}
function generic_in() {
if net_martians() then return false;
if bgp_path.len > 64 then return false;
if net.len > 24 then return false;
if net.len < 8 then return false;
if net_martians() then {
bgp_large_community.add((ourASN, filteredNumber, martian));
return false;
}
if bgp_path.len > 64 then {
bgp_large_community.add((ourASN, filteredNumber, pathTooLong));
return false;
}
if net.len > 24 then {
bgp_large_community.add((ourASN, filteredNumber, prefixTooLong24));
return false;
}
return true;
}
`
config = fmt.Sprintf(config, flagRouterID)
config = fmt.Sprintf(config, flagRouterID, 208521)
}
if flagUpstream {
config += `
protocol kernel {
scan time 60;
import none;
export all;
}
filter UPSTREAM_C3NOC_IN {
if net_martians() then reject;
if bgp_path.len > 64 then reject;
accept;
}
filter UPSTREAM_C3NOC_OUT {
accept;
}
`
if flagV6 {
config += `
protocol bgp UPSTREAM_C3NOC {
import filter UPSTREAM_C3NOC_IN;
export filter UPSTREAM_C3NOC_OUT;
description "UPSTREAM AS13020";
local 2a0d:eb02:4242:4242::7 as 208521;
neighbor 2a0d:eb02:4242:4242::250 as 13020;
}
`
} else {
config += `
protocol bgp UPSTREAM_C3NOC {
import filter UPSTREAM_C3NOC_IN;
export filter UPSTREAM_C3NOC_OUT;
local 185.236.243.7 as 208521;
neighbor 185.236.243.250 as 13020;
}
`
}
}
sort.Slice(res.AsConfigs, func(i, j int) bool {
@ -166,15 +249,28 @@ function generic_in() {
part := `
filter %s_in {
if !generic_in() then reject;
if net ~ [ %s ] then accept;
reject;
if bgp_path.first != %d then {
bgp_large_community.add((ourASN, filteredNumber, pathFirstNotPeer));
reject;
}
if bgp_path.last != %d then {
bgp_large_community.add((ourASN, filteredNumber, pathFirstNotPeer));
reject;
}
if ! (net ~ [ %s ]) then {
bgp_large_community.add((ourASN, filteredNumber, prefixFiltered));
reject;
}
bgp_large_community.add((ourASN, customerNumber, 2137));
accept;
}
`
part = fmt.Sprintf(part, peerid, allowed)
part = fmt.Sprintf(part, peerid, asc.Asn, asc.Asn, allowed)
config += part
part = `
filter %s_out {
if (ourASN, customerNumber, 2137) ~ bgp_large_community then reject;
accept;
}
`
@ -184,12 +280,15 @@ filter %s_out {
part = `
protocol bgp %s {
local %s as 208521;
description "PEER AS%d R%d";
neighbor %s as %d;
import filter %s_in;
import keep filtered on;
export filter %s_out;
password "%s";
}
`
part = fmt.Sprintf(part, peerid, flagLocalIP, addr, asc.Asn, peerid, router.Password)
part = fmt.Sprintf(part, peerid, flagLocalIP, asc.Asn, i, addr, asc.Asn, peerid, peerid, router.Password)
config += part
}
}

View file

@ -25,6 +25,10 @@
<p>
You can use this page to see how your CCCamp IX registration is progressing.
</p>
<h2>Looking Glass</h2>
<p>
We're running a Looking Glass web interface for our exchange at <a href="https://ix-lg.bgp.wtf/">ix-lg.bgp.wtf</a>.
</p>
<h2>System Status</h2>
<p>
If any of the above processors are down, provisioning of new peers might be delayed.

View file

@ -5,10 +5,9 @@ local kube = import "../../../kube/kube.libsonnet";
local ix = self,
local cfg = ix.cfg,
cfg:: {
image: "registry.k0.hswaw.net/bgpwtf/cccampix:1566475793-53f188c8fe83781ac057a3442830c6aa3dce5269",
image: "registry.k0.hswaw.net/bgpwtf/cccampix:1566584484-a2960f526c36de0dbcd911f05ee9db587e63eb9b",
domain: "ix-status.bgp.wtf",
grpcDomain: "ix-grpc.bgp.wtf",
octorpki: {
image: cfg.image,
storageClassName: "waw-hdd-redundant-2",
@ -20,6 +19,7 @@ local kube = import "../../../kube/kube.libsonnet";
verifier: {
image: cfg.image,
domain: "ix-grpc.bgp.wtf",
db: {
host: "public.crdb-waw1.svc.cluster.local",
port: 26257,
@ -49,9 +49,15 @@ local kube = import "../../../kube/kube.libsonnet";
},
frontend: {
domain: "ix-status.bgp.wtf",
image: cfg.image,
},
alice: {
domain: "ix-lg.bgp.wtf",
image: "registry.k0.hswaw.net/q3k/alice-lg:20190823-1557",
},
appName: "ix",
namespace: error "namespace must be defined",
prefix: "",
@ -243,6 +249,148 @@ local kube = import "../../../kube/kube.libsonnet";
],
},
alice: ix.component("alice") {
port: 7340,
volumes: {
config: kube.ConfigMapVolume(ix.alice.configMap),
theme: kube.ConfigMapVolume(ix.alice.themeMap),
},
volumeMounts: {
config: {
mountPath: "/etc/alice",
},
theme: {
mountPath: "/etc/alice-theme",
},
},
args: [
"/usr/bin/alice-lg",
"-config", "/etc/alice/alice",
],
themeMap: kube.ConfigMap(ix.name("alice-theme")) {
metadata+: ix.metadata("alice-theme"),
data: {
"content.js": |||
Alice.updateContent({
header: {
title: "CCCampIX Looking Glass",
tagline: "powered by alice-lg"
},
welcome: {
title: "CCCampIX Looking Glass",
tagline: "BGP to the tent."
}
});
|||,
},
},
configMap: kube.ConfigMap(ix.name("alice")) {
metadata+: ix.metadata("alice"),
data: {
config: |||
[server]
listen_http = 0.0.0.0:7340
enable_neighbors_status_refresh = false
asn = 208521
[housekeeping]
interval = 5
force_release_memory = true
[theme]
path = /etc/alice-theme
[pagination]
routes_filtered_page_size = 250
routes_accepted_page_size = 250
routes_not_exported_page_size = 250
[rejection_reasons]
208521:65666:1 = An IP Bogon was detected
208521:65666:2 = Prefix is longer than 64
208521:65666:3 = Prefix is longer than 24
208521:65666:4 = AS path contains a bogon AS
208521:65666:5 = AS path length is longer than 64
208521:65666:6 = BGP Path invalid (must be only peer)
208521:65666:9 = Prefix not found in RPKI for Origin AS
[neighbours_columns]
Description = Description
address = Neighbour
asn = ASN
state = State
Uptime = Uptime
routes_received = Routes Received
routes_filtered = Filtered
[routes_columns]
network = Network
gateway = Gateway
interface = Interface
metric = Metric
bgp.as_path = AS Path
[lookup_columns]
network = Network
gateway = Gateway
neighbour.asn = ASN
neighbour.description = Description
bgp.as_path = AS Path
routeserver.name = RS
[source.rs1-camp-v4]
name = rs1.camp.bgp.wtf (IPv4)
group = Camp
[source.rs1-camp-v4.birdwatcher]
timezone = UTC
api = http://isw01.camp.bgp.wtf:3000/
type = single_table
neighbors_refresh_timeout = 2
servertime = 2006-01-02T15:04:05Z
servertime_short = 2006-01-02 15:04:05
servertime_ext = 2006-01-02 15:04:05
[source.rs1-camp-v6]
name = rs1.camp.bgp.wtf (IPv6)
group = Camp
[source.rs1-camp-v6.birdwatcher]
timezone = UTC
api = http://isw01.camp.bgp.wtf:3001/
type = single_table
neighbors_refresh_timeout = 2
servertime = 2006-01-02T15:04:05Z
servertime_short = 2006-01-02 15:04:05
servertime_ext = 2006-01-02 15:04:05
[source.rs2-camp-v4]
name = rs2.camp.bgp.wtf (IPv4)
group = Camp
[source.rs2-camp-v4.birdwatcher]
timezone = UTC
api = http://isw01.camp.bgp.wtf:3002/
type = single_table
neighbors_refresh_timeout = 2
servertime = 2006-01-02T15:04:05Z
servertime_short = 2006-01-02 15:04:05
servertime_ext = 2006-01-02 15:04:05
[source.rs2-camp-v6]
name = rs2.camp.bgp.wtf (IPv6)
group = Camp
[source.rs2-camp-v6.birdwatcher]
timezone = UTC
api = http://isw01.camp.bgp.wtf:3003/
type = single_table
neighbors_refresh_timeout = 2
servertime = 2006-01-02T15:04:05Z
servertime_short = 2006-01-02 15:04:05
servertime_ext = 2006-01-02 15:04:05
|||,
},
},
},
ripeSync: kube.CronJob(ix.name("ripe-sync")) {
metadata+: ix.metadata("ripe-sync"),
spec+: {
@ -287,11 +435,11 @@ local kube = import "../../../kube/kube.libsonnet";
},
spec+: {
tls: [
{ hosts: [cfg.domain], secretName: "public-tls"}
{ hosts: [cfg.frontend.domain], secretName: "public-tls"}
],
rules: [
{
host: cfg.domain,
host: cfg.frontend.domain,
http: {
paths: [
{ path: "/", backend: ix.frontend.svc.name_port },
@ -302,6 +450,31 @@ local kube = import "../../../kube/kube.libsonnet";
},
},
aliceIngress: kube.Ingress("alice") {
metadata+: ix.metadata("alice") {
annotations+: {
"kubernetes.io/tls-acme": "true",
"certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
"nginx.ingress.kubernetes.io/proxy-body-size": "0",
},
},
spec+: {
tls: [
{ hosts: [cfg.alice.domain], secretName: "alice-tls"}
],
rules: [
{
host: cfg.alice.domain,
http: {
paths: [
{ path: "/", backend: ix.alice.svc.name_port },
],
},
},
],
},
},
grpcIngress: kube.Ingress("grpc") {
metadata+: ix.metadata("grpc") {
annotations+: {
@ -310,16 +483,15 @@ local kube = import "../../../kube/kube.libsonnet";
"kubernetes.io/ingress.class": "nginx",
"nginx.ingress.kubernetes.io/ssl-redirect": "true",
"nginx.ingress.kubernetes.io/backend-protocol": "GRPC",
"nginx.ingress.kubernetes.io/whitelist-source-range": "185.236.240.34/32",
},
},
spec+: {
tls: [
{ hosts: [cfg.grpcDomain], secretName: "grpc-tls"}
{ hosts: [cfg.verifier.domain], secretName: "grpc-tls"}
],
rules: [
{
host: cfg.grpcDomain,
host: cfg.verifier.domain,
http: {
paths: [
{ path: "/", backend: ix.verifier.svc.name_port },

View file

@ -88,6 +88,7 @@ func (p *pgp) RunAll(ctx context.Context, m model.Model) error {
case ok && s.Code() == codes.NotFound:
unknownC <- k
default:
unknownC <- k
errC <- err
}
}(key)

View file

@ -288,7 +288,7 @@ Here are your config settings:
for _, router := range pcr.Peer.Routers {
if router.V4 != nil {
plain += fmt.Sprintf(`
our addresses: 185.236.243.5 (rs1), 185.236.243.6 (rs2)
our addresses: 185.236.243.5 (rs1), 185.236.243.6 (rs2), 185.236.243.7 (upstream)
our asn: 208521
your address: %s
your asn: %d
@ -297,7 +297,7 @@ our addresses: 185.236.243.5 (rs1), 185.236.243.6 (rs2)
}
if router.V6 != nil {
plain += fmt.Sprintf(`
our addresses: 2a0d:eb02:4242:4242::5 (rs1), 2a0d:eb02:4242:4242::6 (rs2)
our addresses: 2a0d:eb02:4242:4242::5 (rs1), 2a0d:eb02:4242:4242::6 (rs2), 2a0d:eb02:4242:4242::7 (upstream)
our asn: 208521
your address: %s
your asn: %d