cccampix: updates from camp
Change-Id: I77e6d9fb6e91b0b7e2d1f89e80164ee8116b5d50
diff --git a/bgpwtf/cccampix/birdie/birdie.go b/bgpwtf/cccampix/birdie/birdie.go
index c063d87..457b567 100644
--- a/bgpwtf/cccampix/birdie/birdie.go
+++ b/bgpwtf/cccampix/birdie/birdie.go
@@ -20,6 +20,7 @@
flagRouterID string
flagV6 bool
flagLocalIP string
+ flagUpstream bool
)
func init() {
@@ -32,6 +33,7 @@
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 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 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 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 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 @@
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 @@
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
}
}
diff --git a/bgpwtf/cccampix/frontend/templates/index.html b/bgpwtf/cccampix/frontend/templates/index.html
index 00f0522..035f822 100644
--- a/bgpwtf/cccampix/frontend/templates/index.html
+++ b/bgpwtf/cccampix/frontend/templates/index.html
@@ -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.
diff --git a/bgpwtf/cccampix/kube/ix.libsonnet b/bgpwtf/cccampix/kube/ix.libsonnet
index ff74f2b..7496dad 100644
--- a/bgpwtf/cccampix/kube/ix.libsonnet
+++ b/bgpwtf/cccampix/kube/ix.libsonnet
@@ -5,10 +5,9 @@
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 @@
verifier: {
image: cfg.image,
+ domain: "ix-grpc.bgp.wtf",
db: {
host: "public.crdb-waw1.svc.cluster.local",
port: 26257,
@@ -49,9 +49,15 @@
},
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 @@
],
},
+ 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 @@
},
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 @@
},
},
+ 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 @@
"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 },
diff --git a/bgpwtf/cccampix/verifier/processor_pgp.go b/bgpwtf/cccampix/verifier/processor_pgp.go
index 423cb7e..a0cea61 100644
--- a/bgpwtf/cccampix/verifier/processor_pgp.go
+++ b/bgpwtf/cccampix/verifier/processor_pgp.go
@@ -88,6 +88,7 @@
case ok && s.Code() == codes.NotFound:
unknownC <- k
default:
+ unknownC <- k
errC <- err
}
}(key)
diff --git a/bgpwtf/cccampix/verifier/service.go b/bgpwtf/cccampix/verifier/service.go
index e00b85f..5712471 100644
--- a/bgpwtf/cccampix/verifier/service.go
+++ b/bgpwtf/cccampix/verifier/service.go
@@ -288,7 +288,7 @@
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 @@
}
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