diff --git a/autoconf/IngressController.py b/autoconf/IngressController.py index 76a70de..6f7a095 100644 --- a/autoconf/IngressController.py +++ b/autoconf/IngressController.py @@ -18,8 +18,20 @@ class IngressController : raise Exception("Missing bunkerized-nginx.SERVER_NAME annotation in Service.") prefix = annotations["bunkerized-nginx.SERVER_NAME"].split(" ")[0] + "_" for annotation in annotations : - if annotation.startswith("bunkerized-nginx.") and annotation.split(".")[1] != "" and annotation.split(".")[1] != "AUTOCONF" : - env[prefix + annotation.split(".")[1]] = annotations[annotation] + if annotation.startswith("bunkerized-nginx.") and annotation.replace("bunkerized-nginx.", "", 1) != "" and annotation.replace("bunkerized-nginx.", "", 1) != "AUTOCONF" : + env[prefix + annotation.replace("bunkerized-nginx.", "", 1)] = annotations[annotation] + return env + + def __rules_to_env(self, rules) : + env = {} + for rule in rules : + prefix = "" + if "host" in rule : + prefix = rule["host"] + "_" + for path in rule["http"]["paths"] : + env[prefix + "USE_REVERSE_PROXY"] = "yes" + env[prefix + "REVERSE_PROXY_URL"] = path["path"] + env[prefix + "REVERSE_PROXY_HOST"] = "http://" + path["backend"]["serviceName"] + ":" + str(path["backend"]["servicePort"]) return env def gen_conf(self) : @@ -31,6 +43,7 @@ class IngressController : continue if "bunkerized-nginx.AUTOCONF" in ingress.metadata.annotations : env.update(self.__annotations_to_env(ingress.metadata.annotations)) + env.update(self.__rules_to_env(ingress.spec.rules)) for service in services : if service.metadata.annotations == None : continue diff --git a/examples/kubernetes/deploy.yml b/examples/kubernetes/deploy.yml deleted file mode 100644 index 59eb15c..0000000 --- a/examples/kubernetes/deploy.yml +++ /dev/null @@ -1,102 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: bunkerized-nginx-ingress-controller -rules: -- apiGroups: [""] - resources: ["services"] - verbs: ["get", "watch", "list"] -- apiGroups: ["extensions"] - resources: ["ingresses"] - verbs: ["get", "watch", "list"] ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: bunkerized-nginx-ingress-controller ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: bunkerized-nginx-ingress-controller -subjects: -- kind: ServiceAccount - name: bunkerized-nginx-ingress-controller - apiGroup: rbac.authorization.k8s.io -roleRef: - kind: ClusterRole - name: bunkerized-nginx-ingress-controller - apiGroup: rbac.authorization.k8s.io ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: bunkerized-nginx-ingress-controller - labels: - app: bunkerized-nginx-autoconf -spec: - replicas: 1 - selector: - matchLabels: - app: bunkerized-nginx-autoconf - template: - metadata: - labels: - app: bunkerized-nginx-autoconf - spec: - serviceAccountName: bunkerized-nginx-ingress-controller - containers: - - name: bunkerized-nginx-autoconf - image: bunkerity/bunkerized-nginx-autoconf:1.3.0 - env: - - name: KUBERNETES_MODE - value: "yes" - - name: API_URI - value: "/ChangeMeToSomethingHardToGuess" - volumeMounts: - - name: config - mountPath: "/etc/nginx" - - name: certs - mountPath: "/etc/letsencrypt" - - name: challenges - mountPath: "/acme-challenge" - - name: cache - mountPath: "/cache" - volumes: - - name: config - hostPath: - path: /shared -# TODO volumes : /etc/nginx, /etc/letsencrypt, /acme-challenge, /cache ---- -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: bunkerized-nginx - labels: - app: bunkerized-nginx - annotations: - bunkerized-nginx.AUTOCONF: "yes" - bunkerized-nginx.MULTISITE: "yes" - bunkerized-nginx.SERVER_NAME: "" -spec: - selector: - matchLabels: - name: bunkerized-nginx - template: - metadata: - labels: - name: bunkerized-nginx - spec: - hostNetwork: true - dnsPolicy: ClusterFirstWithHostNet - containers: - - name: bunkerized-nginx - image: bunkerity/bunkerized-nginx:1.3.0 - env: - - name: KUBERNETES_MODE - value: "yes" - - name: USE_API - value: "yes" - - name: API_URI - value: "/ChangeMeToSomethingHardToGuess" -# TODO volumes : /etc/nginx, /etc/letsencrypt, /acme-challenge diff --git a/examples/kubernetes/php.yml b/examples/kubernetes/php.yml new file mode 100644 index 0000000..d7244b5 --- /dev/null +++ b/examples/kubernetes/php.yml @@ -0,0 +1,45 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: myapp + labels: + app: myapp +spec: + replicas: 1 + selector: + matchLabels: + app: myapp + template: + metadata: + labels: + app: myapp + spec: + containers: + - name: myapp + image: php:fpm + volumeMounts: + - name: www + mountPath: /var/www/html + volumes: + - name: www + hostPath: + path: /shared/www/myapp.example.com + type: Directory +--- +apiVersion: v1 +kind: Service +metadata: + name: myapp + annotations: + bunkerized-nginx.AUTOCONF: "yes" + bunkerized-nginx.SERVER_NAME: "myapp.example.com" + bunkerized-nginx.REMOTE_PHP: "myapp" + bunkerized-nginx.REMOTE_PHP_PATH: "/var/www/html" +spec: + type: ClusterIP + selector: + app: myapp + ports: + - protocol: TCP + port: 9000 + targetPort: 9000 \ No newline at end of file diff --git a/examples/kubernetes/reverse-proxy.yml b/examples/kubernetes/reverse-proxy.yml new file mode 100644 index 0000000..c04dde5 --- /dev/null +++ b/examples/kubernetes/reverse-proxy.yml @@ -0,0 +1,38 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: myapp + labels: + app: myapp +spec: + replicas: 1 + selector: + matchLabels: + app: myapp + template: + metadata: + labels: + app: myapp + spec: + containers: + - name: myapp + image: containous/whoami +--- +apiVersion: v1 +kind: Service +metadata: + name: myapp + annotations: + bunkerized-nginx.AUTOCONF: "yes" + bunkerized-nginx.SERVER_NAME: "myapp.example.com" + bunkerized-nginx.USE_REVERSE_PROXY: "yes" + bunkerized-nginx.REVERSE_PROXY_URL: "/" + bunkerized-nginx.REVERSE_PROXY_HOST: "http://myapp" +spec: + type: ClusterIP + selector: + app: myapp + ports: + - protocol: TCP + port: 80 + targetPort: 80 \ No newline at end of file diff --git a/helpers/kubernetes-ingress.yml b/helpers/kubernetes-ingress.yml new file mode 100644 index 0000000..e18588c --- /dev/null +++ b/helpers/kubernetes-ingress.yml @@ -0,0 +1,31 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: bunkerized-nginx-ingress + annotations: + # mandatory, keep this annotation + bunkerized-nginx.AUTOCONF: "yes" + # add any global and default environment variables here as annotations with the "bunkerized-nginx." prefix + # if the scope is "multisite", they will be applied to all services unless overriden by the service + # examples : + #bunkerized-nginx.AUTO_LETS_ENCRYPT: "yes" + #bunkerized-nginx.USE_ANTIBOT: "javascript" + #bunkerized-nginx.REDIRECT_HTTP_TO_HTTPS: "yes" + #bunkerized-nginx.app.example.com_REVERSE_PROXY_WS: "yes" + #bunkerized-nginx.app.example.com_USE_MODSECURITY: "no" + +# add "static" routes here (see https://kubernetes.io/docs/concepts/services-networking/ingress/) +# and/or add annotations to your services (see https://github.com/bunkerity/bunkerized-nginx/tree/master/examples/kubernetes) +spec: + rules: + - host: "app.example.com" + http: + paths: + - pathType: Prefix + path: "/" + backend: + service: + name: app-service + port: + number: 80 + diff --git a/helpers/kubernetes-nginx.yml b/helpers/kubernetes-nginx.yml new file mode 100644 index 0000000..b21fed7 --- /dev/null +++ b/helpers/kubernetes-nginx.yml @@ -0,0 +1,151 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bunkerized-nginx-ingress-controller + labels: + app: bunkerized-nginx-autoconf +spec: + replicas: 1 + selector: + matchLabels: + app: bunkerized-nginx-autoconf + template: + metadata: + labels: + app: bunkerized-nginx-autoconf + spec: + serviceAccountName: bunkerized-nginx-ingress-controller + containers: + - name: bunkerized-nginx-autoconf + image: bunkerity/bunkerized-nginx-autoconf:1.3.0 + env: + - name: KUBERNETES_MODE + value: "yes" + - name: API_URI + value: "/ChangeMeToSomethingHardToGuess" + volumeMounts: + - name: config + mountPath: /etc/nginx + - name: certs + mountPath: /etc/letsencrypt + - name: challenges + mountPath: /acme-challenge + - name: cache + mountPath: /cache + - name: custom-modsec + mountPath: /modsec-confs + readOnly: true + - name: custom-modsec-crs + mountPath: /modsec-crs-confs + readOnly: true + volumes: + - name: config + hostPath: + path: /shared/config + type: Directory + - name: certs + hostPath: + path: /shared/certs + type: Directory + - name: challenges + hostPath: + path: /shared/challenges + type: Directory + - name: cache + hostPath: + path: /shared/cache + type: Directory + - name: custom-modsec + hostPath: + path: /shared/custom-modsec + type: Directory + - name: custom-modsec-crs + hostPath: + path: /shared/custom-modsec-crs + type: Directory +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: bunkerized-nginx + labels: + app: bunkerized-nginx +spec: + selector: + matchLabels: + name: bunkerized-nginx + template: + metadata: + labels: + name: bunkerized-nginx + spec: + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + containers: + - name: bunkerized-nginx + image: bunkerity/bunkerized-nginx:1.3.0 + env: + - name: KUBERNETES_MODE + value: "yes" + - name: USE_API + value: "yes" + - name: API_URI + value: "/ChangeMeToSomethingHardToGuess" + volumeMounts: + - name: config + mountPath: /etc/nginx + readOnly: true + - name: certs + mountPath: /etc/letsencrypt + readOnly: true + - name: challenges + mountPath: /acme-challenge + readOnly: true + - name: www + mountPath: /www + readOnly: true + - name: custom-http + mountPath: /http-confs + readOnly: true + - name: custom-server + mountPath: /server-confs + readOnly: true + - name: custom-modsec + mountPath: /modsec-confs + readOnly: true + - name: custom-modsec-crs + mountPath: /modsec-crs-confs + readOnly: true + volumes: + - name: config + hostPath: + path: /shared/config + type: Directory + - name: certs + hostPath: + path: /shared/certs + type: Directory + - name: challenges + hostPath: + path: /shared/challenges + type: Directory + - name: www + hostPath: + path: /shared/www + type: Directory + - name: custom-http + hostPath: + path: /shared/custom-http + type: Directory + - name: custom-server + hostPath: + path: /shared/custom-server + type: Directory + - name: custom-modsec + hostPath: + path: /shared/custom-modsec + type: Directory + - name: custom-modsec-crs + hostPath: + path: /shared/custom-modsec-crs + type: Directory \ No newline at end of file diff --git a/helpers/kubernetes-rbac.yml b/helpers/kubernetes-rbac.yml new file mode 100644 index 0000000..51f3369 --- /dev/null +++ b/helpers/kubernetes-rbac.yml @@ -0,0 +1,30 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: bunkerized-nginx-ingress-controller +rules: +- apiGroups: [""] + resources: ["services"] + verbs: ["get", "watch", "list"] +- apiGroups: ["extensions"] + resources: ["ingresses"] + verbs: ["get", "watch", "list"] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: bunkerized-nginx-ingress-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: bunkerized-nginx-ingress-controller +subjects: +- kind: ServiceAccount + name: bunkerized-nginx-ingress-controller + namespace: default + apiGroup: "" +roleRef: + kind: ClusterRole + name: bunkerized-nginx-ingress-controller + apiGroup: rbac.authorization.k8s.io \ No newline at end of file