Архив метки: Software

Балансировка нагрузки с помощью HAProxy

Пример горизонтального масштабирования для распределения запросов между несколькими серверами для повышения отказоустойчивости.




Рассмотрим решение по балансировке нескольких веб-серверов при помощи сервиса HAProxy.







Технические требования




  • Сервер под балансировщик с двумя сетевыми интерфейсами (Рекомендация. Внешний адрес для связи с внешним миром и локальный для общения между узлами кластера);
  • Два и более серверов под распределение запросов/трафика;




В примере будет использоваться дистрибутив Linux CentOS 7.




Установка и настройка backend-серверов




В качестве backend-серверов я буду использовать несколько веб-серверов с NGINX и настроенным SSL.




Прежде всего установим NGINX




yum install nginx




Выполним настройку веб-сервера




server {
    listen 80;
    server_name devservers.network;
    rewrite ^(.*)$ https://devservers.network$1 permanent;
}
 
server {
    server_name devservers.network;
    access_log /srv/www/devservers.network/logs/access.log;
    error_log /srv/www/devservers.network/logs/error.log;
    root /srv/www/devservers.network/public_html;
 
    ssl on;
    ssl_session_timeout 24h;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    listen 443 ssl http2 proxy_protocol;
 
    set_real_ip_from 10.0.1.10/32;
    real_ip_header proxy_protocol;
 
    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
 
    location / {
   try_files $uri $uri/ /index.html;
    }
 
    location ~ .(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
        try_files $uri =404;
    }
 
}




Конфигурацию SSL можно выполнить и на самом балансировщике, а бэкенд сервера оставить работать на 80 порту, но в моем случае я буду использовать режим SSL Pass-Through. Не забываем поместить SSL-сертификаты в директорию /etc/nginx/ssl.




Для того, чтобы принимать реальные IP-адреса клиентов на веб-сервере от HAProxy необходимо добавить proxy_protocol в параметр listen, а также указать реальный адрес откуда разрешить принимать запросы:




set_real_ip_from 10.0.1.10/32;
real_ip_header proxy_protocol;




Создадим приветственную страницу на обоих веб-серверах touch /srv/www/devservers.network/public_html со следующим содержимым, изменив только номер сервера для его дальнейшего определения:




<!DOCTYPE html>
<html>
<head>
<title>Server #1</title>
</head>
<body>
<h1>This is server #1</h1>
</body>
</html>




Добавляем NGINX в автозагрузку и запускаем сервис.




systemctl enable nginx
systemctl start nginx




И не забываем выполнить настройку Firewalld




firewall-cmd --permanent --add-service=https
firewall-cmd --reload




Установка и настройка балансировщика




В качестве сервера балансировки я буду использовать VDS сервер с ресурсами 1 vCPU и 1Gb RAM. При правильной настройке, данных мощностей хватит для обслуживания 10-15к одновременных сессий, чего вполне достаточно для среднестатистического интернет-ресурса.




Установим HAProxy




Пакет HAProxy доступен в базовой репозитории CentOS.




yum install haproxy




Настройка HAProxy




HAProxy обладает очень гибкими настройками и конфигурация может содержать большое количество директив и условий. Конфигурационный файл состоит из нескольких секций. Директивы frontend, backend, listen должны иметь своё имя, к примеру defaults — может, но не обязательно, а такие как global — не должны.




Выполняем конфигурацию HAProxy в файле /etc/haproxy/haproxy.cfg. Рекомендую использовать свой конфигурационный файл, а представленный по умолчанию оставить как резерв.




Секция global




global
    log   /dev/log  local0
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    stats    timeout 30s
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon




Рассмотрим настройки в директиве global:




  • log — вести лог в /dev/log сохраняя в local0;
  • chroot — настройки безопасности, позволяющие работать HAProxy только в указанной директории;
  • maxconn — максимальное количество соединений на один процесс;
  • daemon — запуск процесса как демона.




Секция defaults




В секции defaults описываются параметры по умолчанию для всех других секций, следующих за данной. В файле конфигурации может быть несколько секций defaults, в этом случае параметры, описанные в данной секции, будут переопределены в следующей, и будут применяться к секциям, идущим за ней.




В нашем примере указаны следующие параметры:




defaults
    log global
    mode http
    retries 3
    option httplog
    option redispatch
    maxconn 2000
    contimeout 2000
    timeout http-request    10s
    timeout queue   1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s




  • log — указывает в какой лог вести запись (global в данном случае означает, что используются параметры, заданные в секции global);
  • mode — устанавливает протокол взаимодействия, принимает одно из значений: tcphttphealth;
  • retries — количество попыток соединения с сервером в случае отказа;
  • option httplog — формат лога, в случае использования HAProxy для проксирования HTTP-запросов (рекомендуется включить данную настройку);
  • option redispatch — разрешает программе разорвать и переназначить сессию в случае отказа сервера;
  • contimeout — максимальное время ожидания успешного соединения с сервером.




В примере я использую параметры timeout, которые позволяют более гибко настроить поведение балансировщика. Подробно с доступными параметрами можно ознакомиться в документации к HAProxy




Секция frontend




Укажем HAProxy какие запросы он должен обрабатывать, для этого задаем секцию frontend с именем https-in:




frontend https-in
    log /dev/log local0
    mode tcp
    option tcplog
    bind *:443
    default_backend backend-https-servers




Параметр bind со значением *:443 говорит о том, что HAProxy должен принимать все запросы на 443-й порт. Ещё раз напомню, что в данном примере я использую режим SSL Pass-Through, поэтому настройка SSL на самом HAProxy не выполняется.




Параметр default_backend указывает, какие сервера будут обрабатывать эти запросы. В данном случае — backend-https-servers, именно так необходимо назвать секцию backend.




Секция backend




В этой секции мы задаем алгоритм балансировки (параметр balance) и список серверов-обработчиков (server). В качестве алгоритма балансировки указываем roundrobin.




HAProxy имеет несколько алгоритмов балансировки:




  • roundrobin — каждый сервер получает запросы пропорционально своему весу, при этом веса серверов могут меняться на лету;
  • static-rr — то же, что и roundrobin, только изменение весов на лету не даст никакого эффекта;
  • leastconn — выбирает сервер с наименьшим количеством активных соединений;
  • first — выбирает первый сервер с доступными слотами для соединения source — на основе хэша IP-адреса отправителя запроса и весов серверов назначается сервер для соединения;
  • uri — сервер выбирается на основе адреса (без параметров) страницы;
  • url_param — сервер выбирается на основе GET-параметров запроса;
  • hdr — сервер выбирается на основе заголовков запроса;
  • rdp-cookie — сервер выбирается на основе cookie (если они не установлены, то применяется обычный roundrobin);




При перечислении серверов используется следующий формат: ключевое слово server, имя сервера, IP-адрес, дополнительные параметры (в данном случае — проверка статуса хоста и Proxy Protocol, которые позволяет перенаправлять реальные IP-адреса клиента с HAProxy на веб-сервер).




backend backend-https-servers
    mode tcp
    balance roundrobin
    option ssl-hello-chk
    server nginx01 10.0.1.3:443 check send-proxy
    server nginx02 10.0.1.4:443 check send-proxy




Просмотр статистики HAProxy




Для включения расширенной статистики HAProxy необходимо в конфигурационный файл добавить секцию:




listen stats
    bind :10001
    stats enable
    stats uri /haproxy_stats
    stats auth admin:password




  • bind :10001 — HAProxy будет ожидать запросы к порту 10001;
  • stats enable — включить отчёты со статистикой;
  • stats uri — установка адреса страницы с отчётом;
  • stats auth — логин и пароль для авторизации на странице со статистикой;




В секции listen указываем HAProxy, что он должен показывать статистику на странице /haproxy_stats на порту 10001 после ввода логина admin и пароля password.




Проверяем.




Переходим по адресу HAProxy (IP-адрес или хостнйем) и просто обновляем страницу. В зависимости от выбранного балансировщиком сервера будем получать ответ This is server #1 либо This is server #2.




Проверяем статистику. Переходим по адресу SITE_NAME:10001/haproxy_stats







На этом всё. Выше рассмотрен самый простой метод балансировки. Более сложная настройка требует грамотно составленного ТЗ и технических данных проекта. HAProxy очень удобный и гибкий в настройке инструмент с помощью которого можно выполнить балансировку и других сервисов, к примеру почтовый сервер, MemcachedRedis и пр.



2022-04-14T17:49:53
Software

Блокировка доступа к NGINX

Способы ограничения доступа к ресурсу в NGINX




Блокировка по User Agent`у




Я использую эту технику, прежде всего, для защиты от роботов, которые игнорируют настройки в моем файле robots.txt.




if ($http_user_agent ~ "Windows 95|Windows 98|xpymep|TurnitinBot|sindice|Purebot|libwww-perl")  {
  return 403;
  break;
}




Я выбрал для блокирования libwww-Perl, потому что в последние несколько лет, я не видел ни GET или POST по libwww-Perl, вероятно пробовали использовать какую-то уязвимость ПО.




Блокировка по IP-адресу




deny 85.17.26.68;     # spam
deny 85.17.230.23;    # spam
deny 173.234.11.105;  # junk referrers
deny 173.234.31.9;    # junk referrers
deny 173.234.38.25;   # spam
deny 173.234.153.30;  # junk referrers
deny 173.234.153.106; # spam
deny 173.234.175.68;  # spam
deny 190.152.223.27;  # junk referrers
deny 195.191.54.90;   # odd behaviour, Mozilla, doesnt fetch js/css. Ended up doing a POST, prob a spambot
deny 195.229.241.174; # spammy comments
deny 210.212.194.60;  # junk referrers + spam




Блокировка по запросу




Кроме того, можно заблокировать доступ на основе информации которая отправляется в заголовках HTTP.




if ($http_referer ~* (viagra|sex|porn|) ) {
  return 403;
}




Я использую ключ ~* для того чтобы предотвратить запрос GET по указанным словам во всей строке.




Блокировка по подсети




deny 69.28.58.0/24;   # spam
deny 79.142.64.0/20;  # spam
deny 80.67.0.0/20;    # spam




Блокировка по геолокации




Мы можем заблокировать целые страны, основанные на данных GeoIP предоставляемых MaxMind. Необходимо, чтобы NGINX имел модуль GeoIP. Во-первых, вы должны обозначить NGINX где база данных GeoIP находится в файловой системе. Вы можете сделать это внутри HTTP {}; Конфигурация блока:




geoip_country /etc/nginx/GeoIP.dat;




Теперь сообщаем NGINX страны которые необходимо заблокировать:




if ($geoip_country_code ~ (BR|CN|KR|RU) ) {
  return 403;
}




Блокировка по паролю




В конфигурационном файле, в папке, которую хотим закрыть надо только указать файл, где хранятся пароли. Вот два примера для закрытия папки с файлами:




location ^~ /codes/ {
   root   /path/to/server;
          autoindex    on;
          autoindex_exact_size  off;
          auth_basic "Hello, please login";
          auth_basic_user_file /usr/nginx/passwords;
          access_log   /usr/nginx/logs/codes.log   download;
      }




либо админки с ограничением по IP-адресу:




location ^~ /admin/ {
   fastcgi_pass unix:/home/project/server.sock;
            include  conf/fastcgi.conf;
            allow 11.11.0.0/16;
            allow 22.22.22.22;
            deny all;
            auth_basic "Hello, Admin, please login";
            auth_basic_user_file /usr/nginx/adminpassword;
            access_log   /usr/nginx/logs/admin.log  main;
}




Добавить пользователя можно с помощью стандартной утилиты от apache:




htpasswd -b passwords NewUser NewPassword




В файле запись с зашифрованным паролем имеет вид NewUser:P47ghZ4kloG78: #Your Can Comment Here




Защиту от перебора паролей можно организовать одновременно двумя методами, основанными на использовании iptables:




  • Блокирование IP на время, если количество запросов в секунду превышает какое-либо разумное количество
  • Вести лог неудачных попыток подбора пароля и скриптом раз в минуту проверять лог и заносить IP адреса в iptables




Для первого варианта достаточно создать правила:




iptables -A INPUT -p tcp --syn --dport 80 -i eth0 -m state --state NEW
   -m recent --name bhttp --set
iptables -A INPUT -p tcp --syn --dport 80 -i eth0 -m state --state NEW
            -m recent --name bhttp --update --seconds 120
            --hitcount 360 -j DROP
iptables -A INPUT -p tcp --syn --dport 80 -i eth0 -j ACCEPT




Можно вместо DROP использовать TARPIT, чтобы усложнить жизнь ломателям.




Для второго варианта надо добавить в конфиг:




location /401.html {
   root   /usr/nginx;
            access_log   /usr/nginx/logs/denied.log  error401;
        }




Формат error401, у меня например такой:




log_format error401  '$remote_addr - $remote_user [$time_local] '
   '$status "$request"';



2022-04-14T17:32:32
Software

Деректива Nginx — location с примерами

Директива location служит для установки конфигурации в зависимости от URI-запроса.

Синтаксис location в общем виде следующий:

Syntax:   location [=|~|~*|^~] uri { ... }
   location @name { ... }
Context:  server, location

Перед тем, как перейти к более детальному изучению, нужно заметить, что location определяется в контексте server (или в location в случае вложенной директивы), и в одном настраиваемом виртуальном хосте могут использоваться разные конфигурации в зависимости от обрабатываемого сервером URI. Читать

Ошибка NGINX — Число имен серверов или их длине — could not build the server_names_hash

Исправление ошибки в числе имен серверов или их длине




Если задано большое число имён серверов, либо заданы необычно длинные имена, возможно потребуется скорректировать значения директив
server_names_hash_max_size и server_names_hash_bucket_size на уровне http.
Значение по умолчанию директивы server_names_hash_bucket_size может быть равно 3264, либо другой величине, в зависимости от размера строки кэша процессора.
Если значение по умолчанию равно 32 и имя сервера задано как “too.long.server.name.example.org”, то nginx откажется запускаться и выдаст сообщение об ошибке:




could not build the server_names_hash,
you should increase server_names_hash_bucket_size: 32




В этом случае следует увеличить значение директивы до следующей степени двойки:




http {
    server_names_hash_bucket_size  64;
    ...




Если задано большое число имён серверов, то будет выдано другое сообщение об ошибке:




could not build the server_names_hash,
you should increase either server_names_hash_max_size: 512
or server_names_hash_bucket_size: 32




В таком случае сначала следует попробовать установить server_names_hash_max_size в величину, близкую к числу имён серверов, и только если это не поможет или время запуска nginx станет неприемлемо большим, следует попытаться увеличить server_names_hash_bucket_size.




Если сервер является единственным сервером для слушающего порта, то nginx не будет проверять имена сервера вообще (а также не будет строить хэш-таблицы для слушающего порта).




За одним исключением: если имя сервера задано регулярным выражением с выделениями, то nginx’у придётся выполнить это выражение, чтобы получить значения выделений.



2022-04-14T17:28:47
Software

Полезные шаблоны конфигов и сниппеты для Nginx

Готовые варианты конфигурации для NGINX, а также полезные сниппеты для настройки необходимых условий.




Команды Nginx




Основные команды для выполнения базовый операций во время работы NGINX.




  • nginx -V — проверить версию NGINX, его скомпилированные параметры конфигурации и установленные модули.
  • nginx -t — протестировать конфигурационный файл и проверить его расположение.
  • nginx -s reload — перезапустить конфигурационный файл без перезагрузки NGINX.




Location блок на PHP




Простой шаблон для быстрой и легкой установки PHP, FPM или CGI на ваш сайт.




location ~ .php$ {
  try_files $uri =404;
  client_max_body_size 64m;
  client_body_buffer_size 128k;
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_pass unix:/path/to/php.sock;
}




Rewrite и Redirection




Force www




Корректный способ определить удаленный сервер по домену без www и перенаправить его c www:




server {
  listen 80;
  server_name example.org;
  return 301 $scheme://www.example.org$request_uri;
}
 
server {
  listen 80;
  server_name www.example.org;
  ...
}




Также работает для HTTPS




Простой шаблон для быстрой и легкой установки PHP, FPM или CGI на ваш сайт.




location ~ .php$ {
  try_files $uri =404;
  client_max_body_size 64m;
  client_body_buffer_size 128k;
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_pass unix:/path/to/php.sock;
}




Rewrite и Redirection




Force www




Корректный способ определить удаленный сервер по домену без www и перенаправить его c www:




server {
  listen 80;
  server_name example.org;
  return 301 $scheme://www.example.org$request_uri;
}
 
server {
  listen 80;
  server_name www.example.org;
  ...
}




Также работает для HTTPS




Force no-www




Корректный способ определить удаленный сервер по домену c www и перенаправить его без www:




server {
  listen 80;
  server_name example.org;
}
 
server {
  listen 80;
  server_name www.example.org;
  return 301 $scheme://example.org$request_uri;
}




Force HTTPS




Способ для переадресации с HTTP на HTTPS:




server {
  listen 80;
  return 301 https://$host$request_uri;
}
 
server {
  listen 443 ssl;
 
  # let the browsers know that we only accept HTTPS
  add_header Strict-Transport-Security max-age=2592000;
 
  ...
}




Force Trailing Slash




Данная строка добавляет слэш / в конце каждого URL только в том случае, если в URL нет точки или параметров. То есть после example.com/index.php или example.com/do?some=123 слэш не поставится.




rewrite ^([^.?]*[^/])$ $1/ permanent;




Удаление закрывающего слеша ко всем ссылкам на сайте:?




rewrite ^/(.*)/$ /$1 permanent;




Немного усложним пример и добавим исключение, тк есть, например, технические страницы:?




rewrite ^/((?!install|admin|administrator).*)/$ /$1 permanent;




Через «|» перечисленны исключения, для которых данное правило работать не должно.




Редирект на страницу




server {
  location = /oldpage.html {
    return 301 http://example.org/newpage.html;
  }
}




Редирект на сайт




server {
  server_name old-site.com
  return 301 $scheme://new-site.com$request_uri;
}




Редирект на определенный путь в URI




location /old-site {
  rewrite ^/old-site/(.*) http://example.org/new-site/$1 permanent;
}




Производительность




Кэширование




Навсегда разрешить браузерам кэшировать статические содержимое. NGINX установит оба заголовка: Expires и Cache-Control.




location /static {
  root /data;
  expires max;
}




Запретить кэширование браузерам (например для отслеживания запросов) можно следующим образом:




location = /empty.gif {
  empty_gif;
  expires -1;
}




Gzip сжатие




gzip  on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
  text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
  text/javascript application/javascript application/x-javascript
  text/x-json application/json application/x-web-app-manifest+json
  text/css text/plain text/x-component
  font/opentype application/x-font-ttf application/vnd.ms-fontobject
  image/x-icon;
gzip_disable "msie6";




Кэш файлов




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




open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;




SSL кэш




Подключение SSL кэширования позволит возобновлять SSL сессии и сократить время к следующим обращениям к SSL/TLS протоколу.




ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;




Поддержка Upstream




Активация кеширования c использованием Upstream подключений:




upstream backend {
  server 127.0.0.1:8080;
  keepalive 32;
}
 
server {
  ...
  location /api/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
  }
}




Мониторинг




По умолчанию Stub Status модуль не собирается, его сборку необходимо разрешить с помощью конфигурационного параметра —with-http_stub_status_module и активировать с помощью:




location /status {
  stub_status on;
  access_log off;
}




Данная настройка позволит вам получать статус в обычном текстовом формате по общему количеству запросов и клиентским подключениям (принятым, обработанным, активным).




Более информативный статус от NGINX можно получить с помощью Luameter, который несколько сложнее в установке и требует наличия NGINX Lua модуля. Это предоставит следующие метрики по различным конфигурационным группам в формате JSON:




  • Общее количество запросов/ответов.
  • Общее количество ответов сгруппирированных по статус кодам: 1xx, 2xx, 3xx, 4xx, 5xx.
  • Общее количество байт принятых/отправленных клиенту.
  • Промежуточные отрезки времени для оценки минимума, максимума, медианы, задержек и тд.
  • Среднестатистическое количество запросов для простоты мониторинга и составления прогнозов по нагрузке.
  • И прочее…




Демо от Luameter.




Также для сбора статистики отлично подходит ngxtop.




Безопасность




Активация базовой аунтификации




Для начала вам потребуется создать пароль и сохранить его в обычной текстовом файле:




имя:пароль




Затем установить настройки для server/location блока, который необходимо защитить:




auth_basic "This is Protected";
auth_basic_user_file /path/to/password-file;




Открыть только локальный доступ




location /local {
  allow 127.0.0.1;
  deny all;
  ...
}




Защита SSL настроек




  • Отключить SSLv3, если он включен по умолчанию. Это предотвратит POODLE SSL Attack.
  • Шифры, которые наилучшим образом обеспечат защиту. Mozilla Server Side TLS and Nginx.




don’t use SSLv3 ref: POODLE CVE-2014-356 — http://nginx.com/blog/nginx-poodle-ssl/




ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;




Ciphers set to best allow protection from Beast, while providing forwarding secrecy, as defined by Mozilla (Intermediate Set) — https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx




ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers  on;




Прочее




Подзапросы после завершения




Бывают ситуации, когда вам необходимо передать запрос на другой бэкэнд в дополнении или после его обработки. Первый случай — отслеживать количество завершенных загрузок путем вызова API, после того как пользователь скачал файл. Второй случай -отслеживать запрос, к которому вы бы хотели вернуться как можно быстрее (возможно с пустым .gif) и сделать соответствующие записи в фоновом режиме. post_action** , который позволяет вам определить подзапрос и будет отклонен по окончанию текущего запроса — является лучшим решением для обоих вариантов.




location = /empty.gif {
  empty_gif;
  expires -1;
  post_action @track;
}
 
location @track {
  internal;
  proxy_pass http://tracking-backend;
}




Распределение ресурсов между источниками




Самый простой и наиболее известный способ кросс-доменного запроса на ваш сервер:




location ~* .(eot|ttf|woff) {
  add_header Access-Control-Allow-Origin *;
}




Коллекция готовых конфигурационных шаблонов для популярных CMS и фреймворков.







Источники






2022-04-14T17:17:36
Software

KeePassXC 2.7.1 выходит с некоторыми изменениями и исправлениями ошибок

Недавно анонсирован выход новой версии KeePassXC 2.7.1, версия, в которую были внесены некоторые изменения, включая поддержку пакетов flatpak, некоторые улучшения дизайна и, прежде всего, исправления ошибок.

Для тех, кто не знает КиПассХС, они должны знать, что это это бесплатный менеджер паролей и с открытым исходным кодом под лицензией GNU Public License. Это приложение начался как форк сообщества KeePassX (сам является портом KeePass) из-за очень медленной разработки KeePassX и отсутствия ответа от сопровождающего.



Читать