Skip to content

Commit

Permalink
Add option to use kubectl to work around kubernetes-client/python#411 (
Browse files Browse the repository at this point in the history
…#813)

* Add option to use kubectl to work around kubernetes-client/python#411

* Use image built from previous commit in cronjob yaml

* Optimize by reducing api calls and other minor tweaks

* Use image built from previous commit in block-aws-cron.yaml
  • Loading branch information
jgmize authored and Dave Parfitt committed May 2, 2018
1 parent 25a22da commit cc361e0
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 71 deletions.
16 changes: 11 additions & 5 deletions k8s/tools/block-aws/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,26 @@ ENV PYTHONUNBUFFERED=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1

# add non-priviledged user
RUN adduser --uid 1000 --disabled-password --gecos '' --no-create-home webdev
RUN adduser --uid 1000 --disabled-password --gecos '' --no-create-home blocker

# end from Dockerfile.footer

WORKDIR /app

# Install app
COPY block-aws.py /app/block-aws.py
COPY block_aws.py /app/block_aws.py
COPY requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

CMD ["python", "/app/block-aws.py"]
# Install kubectl
# to get latest version: "curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt"
ENV KUBECTL_VERSION="v1.10.1"
ADD https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl /usr/local/bin/kubectl
RUN chmod +x /usr/local/bin/kubectl

CMD ["python", "/app/block_aws.py"]

# Change User
RUN chown webdev.webdev -R .
USER webdev
RUN chown blocker.blocker -R .
USER blocker

2 changes: 1 addition & 1 deletion k8s/tools/block-aws/block-aws-cron.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ spec:
spec:
containers:
- name: block-aws-cron
image: quay.io/mozmar/blockaws:1f888cb
image: quay.io/mozmar/blockaws:0905680
env:
- name: DMS_URL
valueFrom:
Expand Down
20 changes: 20 additions & 0 deletions k8s/tools/block-aws/block-aws-networkpolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: v1
items:
- apiVersion: extensions/v1beta1
kind: NetworkPolicy
metadata:
name: block-aws
spec:
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.0.0/16
podSelector:
matchExpressions:
- key: k8s-app
operator: DoesNotExist
policyTypes:
- Egress
kind: List
65 changes: 0 additions & 65 deletions k8s/tools/block-aws/block-aws.py

This file was deleted.

113 changes: 113 additions & 0 deletions k8s/tools/block-aws/block_aws.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"""
This script iterates through all k8s namespaces and installs a NetworkPolicy
that blocks the AWS metadata service (169.254.0.0/16). Namespaces can
be whitelisted via the WHITELISTED_NAMESPACES list, with kube-system
being whitelisted by default (meaning we don't install this particular
network policy in kube-system, but others may be installed in kube-system
via some other method).
"""

from collections import defaultdict
import os

from kubernetes import client, config
from munch import munchify
import requests
import sh
import yaml

WHITELISTED_NAMESPACES = os.getenv('WHITELISTED_NAMESPACES',
'kube-system').split(',')
AWS_NETWORK_POLICY_NAME = os.getenv('AWS_NETWORK_POLICY_NAME', 'block-aws')
POLICY_FILENAME = os.getenv('POLICY_FILENAME', 'block-aws-networkpolicy.yaml')
DMS_URL = os.getenv('DMS_URL')
USE_KUBECTL = os.getenv('USE_KUBECTL', True)
IN_CLUSTER = os.getenv('IN_CLUSTER', True)

if IN_CLUSTER:
config.load_incluster_config()
else:
config.load_kube_config()


def kubemunch(*args):
kubectl = sh.kubectl.bake('-o', 'yaml')
munched = munchify(yaml.load(kubectl(args).stdout))
if 'items' in munched.keys():
# override items method
munched.items = munched['items']
return munched


def namespace_network_policy_names(use_kubectl=USE_KUBECTL):
if use_kubectl:
policies = kubemunch('get', 'netpol', '--all-namespaces').items
else:
v1beta1 = client.ExtensionsV1beta1Api()
policies = v1beta1.list_network_policy_for_all_namespaces().items

ns_policies = defaultdict(list)
for policy in policies:
ns_policies[policy.metadata.namespace].append(policy.metadata.name)
return ns_policies


def namespaces(use_kubectl=USE_KUBECTL):
if use_kubectl:
return [ns.metadata.name for ns in kubemunch('get', 'ns').items]
else:
v1 = client.CoreV1Api()
return [ns.metadata.name for ns in v1.list_namespace().items]


def create_policy(namespace, use_kubectl=USE_KUBECTL):
if use_kubectl:
response = kubemunch('create', '-n', namespace, '-f', POLICY_FILENAME)
else:
md = client.V1ObjectMeta(name=AWS_NETWORK_POLICY_NAME,
namespace=namespace)
match_expression = client.V1LabelSelectorRequirement(
key='k8s-app', operator='DoesNotExist')
pod_selector = client.V1LabelSelector(
match_expressions=[match_expression])

ip_block = client.V1beta1IPBlock(
cidr='0.0.0.0/0', _except=['169.254.0.0/16'])
peer = client.V1beta1NetworkPolicyPeer(ip_block=ip_block)
egress = client.V1beta1NetworkPolicyEgressRule(to=[peer])
spec = client.V1beta1NetworkPolicySpec(
pod_selector=pod_selector,
egress=[egress],
policy_types=['Egress'])
policy = client.V1beta1NetworkPolicy(metadata=md, spec=spec)
networkingv1 = client.NetworkingV1Api()
response = networkingv1.create_namespaced_network_policy(namespace,
policy)
print("\tCreated {} in ns {}".format(response.metadata.name,
response.metadata.namespace))


def ping_dms():
if DMS_URL:
print("Notifying DMS")
r = requests.get(DMS_URL)
print(r.status_code)
else:
print('DMS_URL not found, not notifying DMS')


def main():
ns_policies = namespace_network_policy_names()
for namespace in namespaces():
print("-> ", namespace)
if namespace in WHITELISTED_NAMESPACES:
print("\tskipping, ns whitelisted")
elif AWS_NETWORK_POLICY_NAME not in ns_policies[namespace]:
create_policy(namespace)
else:
print("\tAWS already blocked")
ping_dms()


if __name__ == '__main__':
main()
2 changes: 2 additions & 0 deletions k8s/tools/block-aws/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
kubernetes
munch
requests
sh

0 comments on commit cc361e0

Please sign in to comment.