Сертификат Let's Encrypt для сайта вместе с Jitsi Meet

У меня есть сервер под управлением Ubuntu 18.04 и Nginx, и на нем размещен полностью работающий экземпляр Jitsi Meet. С другой стороны, у меня есть 2 других сайта (один - интерфейс для реагирования, а другой - бэкэнд), и мне нужно, чтобы они имели сертификаты ssl, поскольку мы используем Jitsi Meet api из внешнего интерфейса, а хром не позволяет нам давать разрешения на микрофон и камера, потому что передняя часть не защищена.

Итак, я попытался установить certbot и получить сертификат Let's Encrypt, но когда я его получил и попытался перезапустить nginx, это не удалось.

Я думаю, это как-то связано с тем, что Jitsi использует порт 443 или что-то в этом роде, но я действительно не могу сказать ...

Это конфигурация nginx для домена jitsi:

server_names_hash_bucket_size 64;

server {
    listen 80;
    listen [::]:80;
    server_name video.<base-domain>;

    location ^~ /.well-known/acme-challenge/ {
       default_type "text/plain";
       root         <path-to-jitsi>;
    }
    location = /.well-known/acme-challenge/ {
       return 404;
    }
    location / {
       return 301 https://$host$request_uri;
    }
}
server {
    listen 4444 ssl http2;
    listen [::]:4444 ssl http2;
    server_name video.<base-domain>;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA256:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EDH+aRSA+AESGCM:EDH+aRSA+SHA256:EDH+aRSA:E$

    add_header Strict-Transport-Security "max-age=31536000";

    ssl_certificate /etc/letsencrypt/live/video.<base-domain>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/video.<base-domain>/privkey.pem;

    root <path-to-jitsi>;

    # ssi on with javascript for multidomain variables in config.js
    ssi on;
    ssi_types application/x-javascript application/javascript;

    index index.html index.htm;
    error_page 404 /static/404.html;

    gzip on;
    gzip_types text/plain text/css application/javascript application/json;
    gzip_vary on;

    location = /config.js {
        alias /etc/jitsi/meet/video.<base-domain>-config.js;
    }
 #ensure all static content can always be found first
    location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
    {
        add_header 'Access-Control-Allow-Origin' '*';
        alias <path-to-jitsi>/$1/$2;
    }

    # BOSH
    location = /http-bind {
        proxy_pass      http://localhost:5280/http-bind;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $http_host;
    }

    # xmpp websockets
    location = /xmpp-websocket {
        proxy_pass http://127.0.0.1:5280/xmpp-websocket?prefix=$prefix&$args;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        tcp_nodelay on;
    }
 location ~ ^/([^/?&:'"]+)$ {
        try_files $uri @root_path;
    }

    location @root_path {
        rewrite ^/(.*)$ / break;
    }

    location ~ ^/([^/?&:'"]+)/config.js$
    {
       set $subdomain "$1.";
       set $subdir "$1/";

       alias /etc/jitsi/meet/video.<base-domain>-config.js;
    }

    #Anything that didn't match above, and isn't a real file, assume it's a room name and redirect to /
    location ~ ^/([^/?&:'"]+)/(.*)$ {
        set $subdomain "$1.";
        set $subdir "$1/";
        rewrite ^/([^/?&:'"]+)/(.*)$ /$2;
    }
 # BOSH for subdomains
    location ~ ^/([^/?&:'"]+)/http-bind {
        set $subdomain "$1.";
        set $subdir "$1/";
        set $prefix "$1";

        rewrite ^/(.*)$ /http-bind;
    }

    # websockets for subdomains
    location ~ ^/([^/?&:'"]+)/xmpp-websocket {
        set $subdomain "$1.";
        set $subdir "$1/";
        set $prefix "$1";

        rewrite ^/(.*)$ /xmpp-websocket;
    }
}

это конфигурация nginx для внешнего домена:

server{
    server_name app.<base-domain> www.app.<base-domain>;
    root <path-to-front>;
        index index.html index.htm;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    charset utf-8;

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


    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/default-error.log error;

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }



   listen 443 ssl; # managed by Certbot
   ssl_certificate /etc/letsencrypt/live/app.<base-domain>/fullchain.pem; # managed by Certbot
   ssl_certificate_key /etc/letsencrypt/live/app.<base-domain>/privkey.pem; # managed by Certbot
   include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
   ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = app.<base-domain>) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    server_name app.<base-domain> www.app.<base-domain>;
    listen 80;
    return 404; # managed by Certbot
}

это журнал ошибок nginx:

2020/05/15 12:21:58 [emerg] 20330#20330: bind() to 0.0.0.0:443 failed (98: Address already in use)
2020/05/15 12:21:58 [emerg] 20330#20330: bind() to 0.0.0.0:443 failed (98: Address already in use)
2020/05/15 12:21:58 [emerg] 20330#20330: bind() to 0.0.0.0:443 failed (98: Address already in use)
2020/05/15 12:21:58 [emerg] 20330#20330: bind() to 0.0.0.0:443 failed (98: Address already in use)
2020/05/15 12:21:58 [emerg] 20330#20330: bind() to 0.0.0.0:443 failed (98: Address already in use)
2020/05/15 12:21:58 [emerg] 20330#20330: still could not bind()

Я надеялся, что кто-нибудь скажет, как мне это настроить, чтобы обеспечить безопасность как jitsi, так и внешнего интерфейса.

Я также добавлю, что оба домена на самом деле являются субдоменами ... это означает, что домен jitsi - это video..com, а front - это app..com.

реальная конфигурация имеет базовый домен и правильно указаны пути ... Если я удалю всю конфигурацию ssl из конфигурации внешнего интерфейса nginx, все снова заработает.


person hunvee3    schedule 15.05.2020    source источник
comment
Думаю, у меня такая же проблема. Чтобы уточнить: можете ли вы увидеть, привязан ли порт 443 для другого процесса к самому себе? Мы не можем видеть, что это что-то связано, а вы? И вы видите, что порт открыт в вашем брандмауэре? Если вы не видите, кто его связал, и порт открыт в FW, то я почти уверен, что мы испытываем ту же проблему.   -  person felix91gr    schedule 30.05.2020
comment
Привет, я забыл ответить. Видимо проблема была в поворотном сервере. Я удалил его, и все заработало. Я подписался на один из комментариев в этой ветке community.jitsi.org/t/bind-to-0-0-0-0-443-failed/28615/2   -  person hunvee3    schedule 09.06.2020
comment
Понятно. Мы решили эту проблему, в основном удалив все, что было эксклюзивно для jitsi, и выполнив индивидуальную установку, чтобы он не мог захватить порт 443. Это было довольно сложно (похоже, что jitsi действительно хочет существовать на сервере отдельно), но это сработало: 3   -  person felix91gr    schedule 10.06.2020


Ответы (1)


Если вам нужен индивидуальный файл nginx, вот он. Но вы должны поработать над безопасностью.

** Для автономной работы (без Docker) удалите «resolver 127.0.0.1 valid = 5s ipv6 = off;» затем измените остальную часть 127.0.0.1 на localhost

Docker-jitsi-meet Пользовательская конфигурация Nginx

server {
      resolver 127.0.0.1 valid=5s ipv6=off;
      listen 80;
      listen [::]:80;
       server_name jitsiConf.domain.com; # managed by Certbot
       location /.well-known/acme-challenge {
            root /var/www/letsencrypt;
            default_type "text/plain";
            try_files $uri =404;
          }
       location / {
            return 301 https://$host$request_uri;
          }
      #rewrite ^ https://$http_host$request_uri? permanent; # force redirect http to https

  }
server {
    resolver 127.0.0.1 valid=5s ipv6=off;
    listen 443 ssl;
    listen   [::]:443 ssl;
    server_name jitsiConf.domain.com; # managed by Certbot

    ssl on;
    ssl_certificate /etc/letsencrypt/live/jitsiConf.domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/jitsiConf.domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    ssl_protocols TLSv1.2 TLSv1.3;

    ssl_session_cache shared:SSL:50m;

    proxy_cookie_path / "/; HTTPOnly; Secure";
  add_header Expect-CT "enforce, max-age=21600";
  add_header Feature-Policy "payment none";

  keepalive_timeout    70;
  sendfile             on;
  client_max_body_size 0;

  gzip on;
  gzip_disable "msie6";
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_buffers 16 8k;
  gzip_http_version 1.1;
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;


    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    # this tells the browser that jitsi can't be embedded in a Frame
    add_header X-Frame-Options "DENY";

    # List of Browser-Features which are allowed / denied for this Site
    add_header Feature-Policy "geolocation 'none'; camera 'self'; microphone 'self'; speaker 'self'; autoplay 'none'; battery 'none'; accelerometer 'none'; autoplay 'none'; payment 'none';";


    ssi on;
    ssi_types application/x-javascript application/javascript;



    # ensure all static content can always be found first
    #location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
    #{
    #    add_header 'Access-Control-Allow-Origin' '*';
    #}

    #location ~ ^/(?!(http-bind|external_api\.|xmpp-websocket))([a-zA-Z0-9=_äÄöÖüÜß\?\-]+)$ {
     #  rewrite ^/(.*)$ / break;
    #}

    location / {
         expires max;
        log_not_found off;
        proxy_cache_valid 200 120m;
            ssi on;
            set $upstream_endpoint http://127.0.0.1:8100;
            proxy_pass $upstream_endpoint;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
    }
    # BOSH
    location /http-bind {
        set $upstream_endpoint http://127.0.0.1:5280;
        proxy_pass      $upstream_endpoint/http-bind;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
    }
    # xmpp websockets
    location /xmpp-websocket {
        set $upstream_endpoint http://127.0.0.1:5280;
        proxy_pass $upstream_endpoint;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        tcp_nodelay on;
    }
}

Также эта конфигурация будет зависать из-за ошибки CSP. Только для тестовых разработок этот код учтет все риски CSP. вы можете добавить под

ssl_session_cache общий: SSL: 50 м;

set $CSP_image  "img-src      'self' 'unsafe-inline' 'unsafe-eval' data: *.printfriendly.com *.w.org *.gravatar.com *.vimeocdn.com; ";
set $CSP_script "script-src   'self' 'unsafe-inline' 'unsafe-eval' *.w.org *.gravatar.com *.googleapis.com *.jsdelivr.net *.printfriendly.com *.kxcdn.com *.vimeocdn.com *.hs-analytics.net *.securitymetrics.com *.google-analytics.com; ";
set $CSP_style  "style-src    'self' 'unsafe-inline' *.googleapis.com *.bootstrapcdn.com *.gstatic.com *.vimeocdn.com; ";
set $CSP_font   "font-src     'self' data: *.googleapis.com *.bootstrapcdn.com *.gstatic.com *.googleapis.com; ";
set $CSP_frame  "frame-src    'self' *.vimeocdn.com *.vimeo.com; ";
set $CSP_object "object-src   'self' ; ";
set $CSP        "default-src  'self' ; ${CSP_image} ${CSP_script} ${CSP_style} ${CSP_font} ${CSP_frame} ${CSP_object}";

add_header Content-Security-Policy $CSP;

CSPallow ** извините, я не смог найти исходное сообщение *

person HOO    schedule 20.05.2020