web-dev-qa-db-fra.com

Redirection http -> https dans Google Kubernetes Engine

Je cherche à rediriger tout le trafic de

http://example.com -> https://example.com comme le font presque tous les sites Web.

J'ai regardé ce lien sans succès: Kubernetes HTTPS Ingress dans Google Container Engine

Et j'ai essayé les annotations suivantes dans mon fichier ingress.yaml.

nginx.ingress.kubernetes.io/configuration-snippet: |
  if ($http_x_forwarded_proto != 'https') {
    return 301 https://$Host$request_uri;
  }
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/ingress.allow-http: "false"

Le tout sans succès. Pour être clair, je peux accéder à https://example.com et http://example.com sans aucune erreur, j'ai besoin de l'appel http pour rediriger vers https.

Merci

10
Daniel Lee

Pour ce que ça vaut, j'ai fini par utiliser un proxy inverse dans NGINX.

  1. Vous devez créer des secrets et les synchroniser dans vos conteneurs
  2. Vous devez créer une configmap dans nginx avec votre configuration nginx, ainsi qu'une configuration par défaut qui référence ce fichier de configuration supplémentaire.

Voici ma configuration:

worker_processes  1;

events {
    worker_connections  1024;
}


http {

default_type  application/octet-stream;

# Logging Configs
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

access_log  /var/log/nginx/access.log  main;

sendfile        on;
keepalive_timeout  65;

# Puntdoctor Proxy Config
include /path/to/config-file.conf;

# PubSub allows 10MB Files. lets allow 11 to give some space
client_max_body_size 11M;

}

Ensuite, le config.conf

server {
listen 80;
server_name example.com;
return 301 https://$Host$request_uri;
}

server {

listen 443;
server_name example.com;

ssl_certificate           /certs/tls.crt;
ssl_certificate_key       /certs/tls.key;

ssl on;
ssl_session_cache  builtin:1000  shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-RC4-SHA:AES128-GCM-SHA256:HIGH:!RC4:!MD5:!aNULL:!EDH:!CAMELLIA;
ssl_prefer_server_ciphers on;

location / {

  proxy_set_header        Host $Host;
  proxy_set_header        X-Real-IP $remote_addr;
  proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header        X-Forwarded-Proto $scheme;
  proxy_set_header        X-Forwarded-Host $http_Host;

  # Fix the “It appears that your reverse proxy set up is broken" error.
  proxy_pass          http://deployment-name:8080/;
  proxy_read_timeout  90;

  proxy_redirect      http://deployment-name:8080/ https://example.com/;
}
}
  1. Créez un déploiement:

Voici les fichiers .yaml

---
apiVersion: v1
kind: Service
metadata:
  name: puntdoctor-lb
spec:
   ports:
    - name: https
      port: 443
      targetPort: 443
     - name: http
      port: 80
      targetPort: 80
  selector:
    app: puntdoctor-nginx-deployment
  type: LoadBalancer
  loadBalancerIP: 35.195.214.7
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: puntdoctor-nginx-deployment
spec:
   replicas: 2
  template:
    metadata:
      labels:
        app: puntdoctor-nginx-deployment
    spec:
       containers:
       - name: adcelerate-nginx-proxy
        image: nginx:1.13
         volumeMounts:
        - name: certs
          mountPath: /certs/
        - name: site-config
          mountPath: /etc/site-config/
        - name: default-config
          mountPath: /etc/nginx/
        ports:
        - containerPort: 80
          name: http
        - containerPort: 443
          name: https
      volumes:
      - name: certs
        secret:
          secretName: nginxsecret
      - name: site-config
        configMap:
          name: nginx-config
       - name: default-config
        configMap:
         name: default

J'espère que cela aide quelqu'un à résoudre ce problème, merci pour les 2 autres réponses, ils m'ont tous deux donné un aperçu précieux.

2
Daniel Lee

Actuellement, la documentation sur la façon de procéder correctement (annotations, SSL/HTTPS, contrôles de santé, etc.) fait gravement défaut et est depuis trop longtemps. Je soupçonne que c'est parce qu'ils préfèrent que vous utilisiez App Engine, qui est magique mais stupidement cher. Pour GKE, voici deux options:

  • entrée avec un certificat SSL géré par Google et une configuration de serveur NGINX supplémentaire devant votre application/site
  • le contrôleur d'entrée NGINX avec certificats SSL autogérés/tiers

Voici les étapes d'une configuration de travail utilisant la première.

1 La porte de votre application

nginx.conf: (les ellipses représentent d'autres paramètres non pertinents et non obligatoires)

user  nginx;
worker_processes  auto;

events {
    worker_connections  1024;
}

http {
    ...

    keepalive_timeout  620s;

    ## Logging ##
    ...
    ## MIME Types ##
    ...
    ## Caching ##
    ...
    ## Security Headers ##
    ...
    ## Compression ##
    ....

    server {
        listen 80;

        ## HTTP Redirect ##
        if ($http_x_forwarded_proto = "http") {
            return 301 https://[YOUR DOMAIN]$request_uri;
        }

        location /health/liveness {
            access_log off;
            default_type text/plain;
            return 200 'Server is LIVE!';
        }

        location /health/readiness {
            access_log off;
            default_type text/plain;
            return 200 'Server is READY!';
        }

        root /usr/src/app/www;
        index index.html index.htm;
        server_name [YOUR DOMAIN] www.[YOUR DOMAIN];

        location / {
            try_files $uri $uri/ /index.html;
        }
    }
}

REMARQUE: Un seul port de desserte . La règle de transfert globale ajoute l'en-tête http_x_forwarded_proto à tout le trafic qui la traverse. Étant donné que TOUT le trafic vers votre domaine passe maintenant par cette règle (rappelez-vous, un port sur le conteneur, le service et l'entrée), cet en-tête sera (crucial!) Toujours défini. Notez la vérification et la redirection ci-dessus: elle ne continue avec la diffusion que si la valeur d'en-tête est 'https'. Les valeurs racine, index et emplacement peuvent différer selon votre projet (il s'agit d'un projet angular). Keepalive_timeout est défini sur la valeur recommandé par google . Je préfère utiliser le fichier nginx.conf principal, mais la plupart des gens ajoutent un fichier custom.conf à /etc/nginx/conf.d; si vous faites cela, assurez-vous simplement que le fichier est importé dans le bloc http nginx.conf principal en utilisant un inclut instruction. Les commentaires soulignent où iront les autres paramètres que vous voudrez peut-être ajouter lorsque tout fonctionnera, comme gzip/brotli, les en-têtes de sécurité, où les journaux sont enregistrés, etc.

Dockerfile:

...
COPY nginx.conf /etc/nginx/nginx.conf
CMD ["nginx", "-g", "daemon off;"]

REMARQUE: seules les deux dernières lignes. Il n'est pas nécessaire de spécifier un port EXPOSE. COPY remplace le nginx.conf par défaut par celui modifié. CMD démarre un serveur léger.

2 Créez un manifeste de déploiement et appliquez/créez

deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: uber-dp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: uber
  template:
    metadata:
      labels:
        app: uber
    spec:
      containers:
        - name: uber-ctr
          image: gcr.io/uber/beta:v1 // or some other registry
          livenessProbe:
            failureThreshold: 3
            initialDelaySeconds: 60
            httpGet:
              path: /health/liveness
              port: 80
              scheme: HTTP
          readinessProbe:
            failureThreshold: 3
            initialDelaySeconds: 30
            httpGet:
              path: /health/readiness
              port: 80
              scheme: HTTP
          ports:
            - containerPort: 80
          imagePullPolicy: Always

REMARQUE: un seul port spécifié est nécessaire, car nous allons y pointer tout le trafic (HTTP et HTTPS). Pour plus de simplicité, nous utilisons le même chemin pour les sondes de vivacité et de préparation; ces vérifications seront traitées sur le serveur NGINX, mais vous pouvez et devez ajouter des vérifications qui sondent la santé de votre application elle-même (par exemple, une page dédiée qui renvoie 200 si elle est saine). La sonde de préparation sera également récupérée par GCE, qui a par défaut son propre bilan de santé inamovible.

3 Créez un manifeste de service et appliquez/créez

service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: uber-svc
  labels:
    app: uber
spec:
  ports:
    - name: default-port
      port: 80
  selector:
    app: uber
  sessionAffinity: None
  type: NodePort

REMARQUE: default-port spécifie le port 80 sur le conteneur.

4 Obtenez une adresse IP statique

Sur GCP dans le menu hamburger: Réseau VPC -> Adresses IP externes. Convertissez votre IP éphémère générée automatiquement ou créez-en une nouvelle. Prenez note du nom et de l'adresse.

5 Créer un certificat SSL et zone par défaut

Dans le menu hamburger: Service réseau -> Équilibrage de charge -> cliquez sur 'menu avancé' -> Certificats -> Créer un certificat SSL. Suivez les instructions, créez ou téléchargez un certificat et notez son nom. Ensuite, dans le menu: Cloud DNS -> Créer une zone. En suivant les instructions, créez une zone par défaut pour votre domaine. Ajoutez un enregistrement CNAME avec www comme nom DNS et votre domaine comme nom canonique. Ajoutez un enregistrement A avec une valeur de nom DNS vide et votre adresse IP statique comme IPV4. Sauver.

6 Créez un manifeste d'entrée et appliquez/créez

ingress.yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: mypt-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: [NAME OF YOUR STATIC IP ADDRESS]
    kubernetes.io/ingress.allow-http: "true"
    ingress.gcp.kubernetes.io/pre-shared-cert: [NAME OF YOUR GOOGLE-MANAGED SSL]
spec:
  backend:
    serviceName: mypt-svc
    servicePort: 80

REMARQUE: la propriété backend pointe vers le service, qui pointe vers le conteneur, qui contient votre application "protégée" par un serveur. Les annotations connectent votre application à SSL et autorisent HTTP pour les contrôles de santé. Combinés, le service et l'entrée configurent équilibreur de charge G7 (règle de transfert globale combinée, services et services backend et frontend, certificats SSL et proxys cibles, etc.).

7 Faites une tasse de thé ou quelque chose

Tout a besoin de ~ 10 minutes pour configurer. Vider le cache et tester votre domaine avec différents navigateurs (Tor, Opera, Safari, IE etc). Tout servira sur https.

Qu'en est-il du contrôleur d'entrée NGINX? J'ai vu que c'était mieux parce qu'il est moins cher/utilise moins de ressources et est plus flexible. Il n'est pas moins cher: il nécessite un déploiement/une charge de travail et un service supplémentaires (GCE L4). Et vous devez faire plus de configuration. Est-ce plus flexible? Oui. Mais en prenant soin de la plupart du travail, la première option vous donne un type de flexibilité plus important - c'est-à-dire vous permettant de passer à des questions plus urgentes.

5
Jai

GKE utilise GCE L7. Les règles que vous avez référencées dans l'exemple ne sont pas prises en charge et la redirection HTTP vers HTTPS doit être contrôlée au niveau de l'application.

L7 insère le x-forwarded-proto en-tête que vous pouvez utiliser pour comprendre si le trafic frontal provient de HTTP ou HTTPS. Jetez un œil ici: Rediriger HTTP vers HTTPS

Il y a aussi un exemple dans ce lien pour Nginx (copié pour plus de commodité):

# Replace '_' with your hostname.
server_name _;
if ($http_x_forwarded_proto = "http") {
    return 301 https://$Host$request_uri;
}
5

GKE utilise son propre contrôleur d'entrée qui ne prend pas en charge le forçage https.

C'est pourquoi vous devrez gérer vous-même le contrôleur d'entrée NGINX.

Voir ce post sur la façon de le faire sur GKE.

J'espère que ça aide.

4
Jahongir Rahmonov

Pour tous ceux comme moi qui recherchent cette question environ une fois par mois, Google a répondu à nos demandes et teste la redirection SSL HTTP-> HTTPS sur leurs équilibreurs de charge. Leur dernière réponse a dit qu'il devrait être en Alpha quelque temps avant la fin de janvier 2020.

Leur commentaire:

Merci de votre patience à ce sujet. La fonctionnalité est actuellement en cours de test et nous prévoyons de passer en phase Alpha avant fin janvier. Notre PM équipe aura une annonce avec plus de détails à mesure que nous nous rapprocherons du lancement d'Alpha.

2
Josh