GitHub user ewerton-silva00 edited a comment on the discussion: Cannot view vm 
instance console remotely - site Cannot be reached

@soulfulgent, translate my message from Brazilian Portuguese to your language.

Utilizo o **Nginx** como Proxy Reverso para a **API** do Apache CloudStack, 
assim como para o **Console Proxy VM** e **Secondary Storage VM**.

Pré-requisitos:

- Mude a porta do Management Server para algo diferente de 8080 (e.g. 8180).
- Dedique um range rede privado exclusivo para SystemVMs

**Passo 01:**

Redireciona todas as requisições para HTTPS:
```
sudo tee /etc/nginx/sites-enabled/default > /dev/null <<EOF
server {
    listen 80 default_server;

    server_name _;

    return 301 https://$host$request_uri;
}
EOF
```

**Passo 02:**

Sobrescreva as configurações padrões do Nginx:
```
sudo tee /etc/nginx/nginx.conf > /dev/null <<EOF
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
}

http {
    # Basic Settings
    sendfile on;
    tcp_nopush on;
    types_hash_max_size 2048;
    server_tokens off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # SSL Settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305;
    
    # Logging Settings
    access_log /var/log/nginx/access.log;

    # Gzip Settings
    gzip on;
    gzip_types text/plain text/css application/javascript application/json;
    gzip_proxied any;
    
    # Virtual Host Configs
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
EOF
```

**Passo 03:**

Configuração da API:
```
sudo tee /etc/nginx/sites-available/api.conf > /dev/null <<'EOF'
sudo tee /etc/nginx/sites-available/api.conf > /dev/null <<'EOF'
upstream cloudstack_management {
    server 127.0.0.1:8180;
    keepalive 32;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name api.suanuvem.io;
    
    ssl_certificate /etc/letsencrypt/live/api.suanuvem.io/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.suanuvem.io/privkey.pem;
    ssl_dhparam /etc/ssl/dhparam.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; 
preload" always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options DENY always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    access_log /var/log/nginx/api.access.log main;
    error_log /var/log/nginx/api.error.log warn;
    
    if ($cf_proxy = 0) { return 403; }
    
    client_max_body_size 10M;
    
    location ^~ /client/api {
        proxy_pass http://cloudstack_management/client/api/;
        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_connect_timeout 30s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;
        proxy_request_buffering off;
    }
    
    location / {
        return 403;
    }
}
EOF
```

**Passo 04:**

Configuração do Secondary Storage VM:
```
server {
    listen 443 ssl http2;
    server_name 
~^(?<oct1>192)-(?<oct2>168)-(?<oct3>0)-(?<oct4>[1-9][0-9]?)\.secstorage\.suanuvem\.io$;

    ssl_certificate /etc/letsencrypt/live/secstorage.suanuvem.io/fullchain.pem;
    ssl_certificate_key 
/etc/letsencrypt/live/secstorage.suanuvem.io/privkey.pem;
    ssl_dhparam /etc/ssl/dhparam.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; 
preload" always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options DENY always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    access_log /var/log/nginx/secstorage.access.log;
    error_log /var/log/nginx/secstorage.error.log warn;

    if ($oct4 !~ ^(1[0-9]|[2-4][0-9]|50)$) { return 403; }

    set $backend_ip "${oct1}.${oct2}.${oct3}.${oct4}";

    client_max_body_size 0;
    proxy_http_version 1.1;
    proxy_cache off;
    proxy_request_buffering off;
    proxy_max_temp_file_size 0;
    proxy_redirect off;
    proxy_buffering off;

    location / {
        proxy_pass https://$backend_ip;
        proxy_set_header Host $http_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 Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_ssl_verify off;
        proxy_read_timeout 600;
    }
}
```

Passo 05:

Configuração do Console Proxy VM:
```
server {
    listen 443 ssl http2;
    listen 8080 ssl http2;
    server_name 
~^(?<oct1>192)-(?<oct2>168)-(?<oct3>0)-(?<oct4>[1-9][0-9]?)\.consoleproxy\.suanuvem\.io$;

    ssl_certificate 
/etc/letsencrypt/live/consoleproxy.suanuvem.io/fullchain.pem;
    ssl_certificate_key 
/etc/letsencrypt/live/consoleproxy.suanuvem.io/privkey.pem;
    ssl_dhparam /etc/ssl/dhparam.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; 
preload" always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options DENY always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    access_log /var/log/nginx/consoleproxy.access.log;
    error_log /var/log/nginx/consoleproxy.error.log warn;

    if ($oct4 !~ ^(1[0-9]|[2-4][0-9]|50)$) { return 403; }

    set $backend_ip "${oct1}.${oct2}.${oct3}.${oct4}";

    client_max_body_size 0;
    proxy_http_version 1.1;
    proxy_cache off;
    proxy_request_buffering off;
    proxy_buffering off;
    proxy_max_temp_file_size 0;
    proxy_redirect off;    

    location / {
        proxy_pass http://$backend_ip;
        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 Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 600;
    }

    location /websockify {
        proxy_pass http://$backend_ip:8080;
        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 Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_cache_bypass $http_upgrade;
        proxy_ignore_client_abort off;
        proxy_read_timeout 86400;
    }
}
```

A acesso a console web das instâncias funciona perfeitamente.

<img width="2555" height="982" alt="image" 
src="https://github.com/user-attachments/assets/764d149b-4838-4120-990a-56d520918ec0";
 />

O upload de imagens para o Secondary Storage também funciona perfeitamente.

Espero ter ajudado de alguma forma.

GitHub link: 
https://github.com/apache/cloudstack/discussions/13295#discussioncomment-17229308

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]

Reply via email to