Secure BGP sessions
Use BGP passwords to prevent attackers from injecting false routing information.
Setting a password on a BGP peering from the cluster to an external BGP speaker means that that peering will only work when the external speaker has the same password. This provides a layer of defense against an attacker impersonating the external speaker, for example in order to inject malicious routing information into the cluster.
This how-to guide uses the following Calico features:
- BGPPeer with password field
Password protection on BGP sessions
Password protection is a standardized optional feature of BGP sessions. The effect is that the two peers at either end of a BGP session can only communicate, and exchange routing information, if they are both configured with the same password.
Please note that password use does not cause the data exchange to be encrypted. It remains relatively easy to eavesdrop on the data exchange, but not to inject false information.
Using Kubernetes secrets to store passwords
In Kubernetes, the Secret resource is designed for holding sensitive information, including passwords. Therefore, for this Calico feature, we use Secrets to store BGP passwords.
To use a password on a BGP peering:
Create (or update) a Kubernetes secret in the namespace where calico-node is running, so that it has a key whose value is the desired password. Note the secret name and the key name.
Note: BGP passwords must be 80 characters or fewer. If a password longer than that is configured, the BGP sessions with that password will fail to be established.
Ensure that calico-node has RBAC permissions to access that secret.
Specify the secret and key name on the relevant BGPPeer resource.
Create or update Kubernetes secret
kubectl create -f - <<EOF apiVersion: v1 kind: Secret metadata: name: bgp-secrets namespace: kube-system type: Opaque stringData: rr-password: very-secret EOF
If calico-node in your cluster is running in a namespace other than kube-system, you should create the secret in that namespace instead of in kube-system.
To use this password below in a BGPPeer resource, you need to note the secret name
bgp-secrets and key name
Ensure RBAC permissions
The calico-node pod must have permission to access that secret. To allow calico-node to access that secret, you would configure:
kubectl create -f - <<EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: secret-access namespace: <namespace> rules: - apiGroups: [""] resources: ["secrets"] resourceNames: ["bgp-secrets"] verbs: ["watch", "list", "get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: secret-access namespace: <namespace> roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: secret-access subjects: - kind: ServiceAccount name: calico-node namespace: <namespace> EOF
Specify secret and key name on the BGPPeer resource
Then, when configuring a BGP peer, include the secret and key name in the specification of the BGPPeer resource, like this:
apiVersion: projectcalico.org/v3 kind: BGPPeer metadata: name: bgppeer-global-3040 spec: peerIP: 126.96.36.199 asNumber: 64567 password: secretKeyRef: name: bgp-secrets key: rr-password
Above and beyond
For more detail about the BGPPeer resource, see BGPPeer.
For more on configuring BGP peers, see configuring BGP peers.