User Tools

Site Tools


informatica:linux:nginx

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

informatica:linux:nginx [2021/05/21 05:11] – created javiinformatica:linux:nginx [2021/05/21 05:49] (current) javi
Line 1: Line 1:
-HELLO WORLD+===== Obtener IP origen sin terminar conexión SSL ===== 
 + 
 +En este escenario: 
 + 
 +  * Edge router. Es el nginx que recibe la conexión del cliente, y expone a la DMZ los puertos TCP 443 y TCP 80. Si recibe la conexión al puerto TCP 443 lo redirige (capa 4) a "behind edge" usando proxy protocol para poder proporcionarle la IP origen 
 +  * Behind edge. Servidor que expone puertos TCP 443 y TCP 80 a 'edge router'. Cuando recibe la conexión TCP 443, por protocolo 'proxy protocol', termina la conexión SSL, y por tanto entrega los certificados (autorfirmados) SSL. Tanto por TCP 80 como por TCP 443 redirige las conexiones a 'php' 
 +  * Php. Pinta las cabeceras que recibe 
 + 
 +Requisitos: 
 + 
 +  * Docker instalado 
 +  * Docker compose instalados 
 +  * El servidor tiene que tener una IP pública 
 +  * Nombre DNS (en este ejemplo "example.com") que apunte a la IP pública del servidor 
 + 
 +1. Edge router 
 + 
 +1.1. Crear directorio: 
 + 
 +  mkdir edge 
 +   
 +1.2. Crear 'default.conf': 
 + 
 +  vim edge/default.conf 
 +   
 +Con el siguiente contenido: 
 + 
 +<code> 
 +proxy_set_header X-Real-IP       $proxy_protocol_addr; 
 +proxy_set_header X-Forwarded-For $remote_addr; 
 +# To avoid 404. Credits: 
 +# https://serverfault.com/a/407983/570054 
 +proxy_set_header Host $host:$server_port; 
 + 
 +server { 
 + listen 80; 
 + location / { 
 + proxy_pass http://behind_edge; 
 +
 +        error_page 404 /404.html; 
 +        location = /404.html { 
 +                root /usr/share/nginx/html/; 
 +                internal; 
 +        } 
 +
 +</code> 
 + 
 +1.3. Crear 'nginx.conf': 
 + 
 +  vim edge/nginx.conf 
 +   
 +Con el siguiente contenido: 
 + 
 +<code> 
 +user  nginx; 
 +worker_processes  1; 
 + 
 +error_log  /var/log/nginx/error.log warn; 
 +pid        /var/run/nginx.pid; 
 + 
 + 
 +events { 
 +    worker_connections  1024; 
 +
 + 
 + 
 +http { 
 +    include       /etc/nginx/mime.types; 
 +    default_type  application/octet-stream; 
 + 
 +    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; 
 +    #tcp_nopush     on; 
 + 
 +    keepalive_timeout  65; 
 + 
 +    #gzip  on; 
 + 
 +    include /etc/nginx/conf.d/*.conf; 
 + 
 + upstream behind_edge { 
 + # Docker container named 'behind_edge' sharing same docker network 
 +                server behind_edge:80; 
 +
 +
 + 
 +stream { 
 + 
 +    server { 
 +        listen 443; 
 + 
 +        proxy_pass behind_edge_ssl; 
 +        proxy_protocol on; 
 +    } 
 + 
 +        upstream behind_edge_ssl { 
 + # Docker container named 'behind_edge' sharing same docker network 
 +                server behind_edge:443; 
 +        } 
 + 
 +    log_format basic '$remote_addr - [$time_local] ' 
 +                        '$status ' 
 +                        ''; 
 + 
 +    access_log  /var/log/nginx/access.log  basic; 
 + 
 +
 +</code> 
 + 
 +2. Behind edge 
 + 
 +2.1. Crear directorio: 
 + 
 +  mkdir behind_edge 
 +   
 +2.2. Crear 'default.conf': 
 + 
 +  vim behind_edge/default.conf 
 +   
 +Con el siguiente contenido: 
 + 
 +<code> 
 +proxy_set_header X-Real-IP       $proxy_protocol_addr; 
 +proxy_set_header X-Forwarded-For $remote_addr; 
 +# To avoid 404. Credits: 
 +# https://serverfault.com/a/407983/570054 
 +proxy_set_header Host $host:$server_port; 
 + 
 +proxy_set_header X-Custom-IP $proxy_protocol_addr; 
 +proxy_set_header X-Custom-Port $proxy_protocol_port; 
 + 
 +server { 
 +        listen 80; 
 +        location / { 
 +                proxy_pass http://php; 
 +        } 
 +
 + 
 +server { 
 +        listen 443 ssl proxy_protocol; 
 +        location / { 
 +                proxy_pass https://php_ssl; 
 +        } 
 +        ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; 
 +        ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; 
 +
 +</code> 
 + 
 +2.3. Crear 'nginx.conf': 
 + 
 +  vim behind_edge/nginx.conf 
 +   
 +Con el siguiente contenido: 
 + 
 +<code> 
 +user  nginx; 
 +worker_processes  1; 
 + 
 +error_log  /var/log/nginx/error.log warn; 
 +pid        /var/run/nginx.pid; 
 + 
 + 
 +events { 
 +    worker_connections  1024; 
 +
 + 
 + 
 +http { 
 +    include       /etc/nginx/mime.types; 
 +    default_type  application/octet-stream; 
 + 
 +    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; 
 +    #tcp_nopush     on; 
 + 
 +    keepalive_timeout  65; 
 + 
 +    #gzip  on; 
 + 
 +    include /etc/nginx/conf.d/*.conf; 
 + 
 +        upstream php { 
 + # Docker container named 'php' sharing same docker network 
 +                server php:80; 
 +        } 
 + 
 +        upstream php_ssl { 
 + # Docker container named 'php' sharing same docker network 
 +                server php:443; 
 +        } 
 + 
 +
 +</code> 
 + 
 +2.4. Crear: 
 + 
 +  vim behind_edge/Dockerfile 
 +   
 +Con el siguiente contenido: 
 + 
 +<code> 
 +FROM nginx 
 + 
 +RUN apt-get update && apt-get install -y  \ 
 +  ssl-cert 
 +</code> 
 + 
 +3. Php 
 + 
 +**NOTA**: de hecho la parte de SSL en el contenedor PHP ya no es necesaria, pero bueno... 
 + 
 +3.1. Crear directorio: 
 + 
 +  mkdir php 
 +   
 +3.2. Crear: 
 + 
 +  vim php/index.php 
 +   
 +Con el siguiente contenido: 
 + 
 +<code> 
 +<?php 
 + 
 +foreach (getallheaders() as $name => $value) { 
 +    echo "$name: $value<br>\n"; 
 +
 + 
 +?> 
 +</code> 
 + 
 +3.3. Crear: 
 + 
 +  vim php/Dockerfile 
 +   
 +Con el siguiente contenido: 
 + 
 +<code> 
 +FROM php:7-apache 
 + 
 +RUN apt-get update && apt-get install -y  \ 
 +  ssl-cert 
 + 
 +RUN a2enmod \ 
 +  remoteip \ 
 +  ssl 
 + 
 +RUN a2ensite default-ssl.conf 
 + 
 +COPY index.php /var/www/html/ 
 +</code> 
 + 
 +4. Crear: 
 + 
 +  vim docker-compose.yml 
 +   
 +Con el siguiente contenido: 
 + 
 +<code> 
 +services: 
 + 
 +  behind_edge: 
 +    build: 
 +      context: ./behind_edge 
 +    container_name: behind_edge 
 +    volumes: 
 +      - "/home/debian/behind_edge/nginx.conf:/etc/nginx/nginx.conf:ro" 
 +      - "/home/debian/behind_edge/default.conf:/etc/nginx/conf.d/default.conf:ro" 
 + 
 +  edge: 
 +    container_name: edge 
 +    image: nginx 
 +    ports: 
 +      - 80:80 
 +      - 443:443 
 +    volumes: 
 +      - "/home/debian/edge/nginx.conf:/etc/nginx/nginx.conf:ro" 
 +      - "/home/debian/edge/default.conf:/etc/nginx/conf.d/default.conf:ro" 
 + 
 +  php: 
 +    build: 
 +      context: ./php 
 +    container_name: php 
 + 
 +version: "3.3" 
 +</code> 
 + 
 +Ajustar las rutas a los archivos, en este ejemplo "/home/debian". Resumen: 
 + 
 +<code> 
 +
 +├── behind_edge 
 +│   ├── default.conf 
 +│   ├── Dockerfile 
 +│   └── nginx.conf 
 +├── docker-compose.yml 
 +├── edge 
 +│   ├── default.conf 
 +│   └── nginx.conf 
 +└── php 
 +    ├── Dockerfile 
 +    └── index.php 
 +</code> 
 + 
 +5. Probar. Ejecutar: 
 + 
 +  curl -s -k https://example.com 
 +   
 +Resultado esperado similar a: 
 + 
 +<code> 
 +X-Real-IP: 8.8.8.8<br> 
 +X-Forwarded-For: 172.25.0.3<br> 
 +Host: php_ssl<br> 
 +Connection: close<br> 
 +User-Agent: curl/7.74.0<br> 
 +Accept: */*<br> 
 +</code> 
 + 
 +Vemos que la cabecera 'X-Real-IP' contiene la IP pública del cliente que ha enviado la petición, en este caso '8.8.8.8' 
 + 
informatica/linux/nginx.1621573900.txt.gz · Last modified: 2021/05/21 05:11 by javi