Automatizando a instalação do WordPress com NGINX Unit e Ubuntu

Automatizando a instalação do WordPress com NGINX Unit e Ubuntu

Há uma abundância de materiais sobre a instalação do WordPress; uma pesquisa no Google com as palavras-chave "instalação do WordPress" retornará cerca de meio milhão de resultados. No entanto, entre esses resultados, existem muito poucos guias realmente úteis que ensinem como instalar e configurar o WordPress e o sistema operacional subjacente de maneira a garantir suporte a longo prazo. É possível que as configurações corretas dependam fortemente das necessidades específicas ou que a explicação detalhada torne o artigo difícil de ler.

Neste artigo, tentaremos unir o melhor de dois mundos, fornecendo um script em bash para instalação automática do WordPress no Ubuntu, e também vamos analisá-lo, explicando o que cada parte faz e quais compromissos fizemos durante seu desenvolvimento. Se você é um usuário experiente, pode pular o texto do artigo e simplesmente pegar o script para modificar e usar em seus ambientes. O resultado do script é uma instalação do WordPress personalizável com suporte a Lets Encrypt, rodando em NGINX Unit e adequada para uso industrial.

A arquitetura projetada para implantar o WordPress usando o NGINX Unit foi descrita em um artigo anterior, agora também vamos configurar adicionais que não foram abordados lá (assim como em muitos outros guias):

  • WordPress CLI
  • Lets Encrypt e certificados TLS/SSL
  • Atualizações automáticas de certificados
  • Cache NGINX
  • Compressão NGINX
  • Suporte a HTTPS e HTTP/2
  • Automatização do processo

O artigo descreverá a instalação em um único servidor, que hospedará simultaneamente um servidor para tratamento de estáticas, um servidor para processamento PHP e um banco de dados. A instalação com suporte a múltiplos hosts virtuais e serviços é um tema potencial para o futuro. Se você gostaria que escrevêssemos sobre algo que não está nestes artigos, deixe-nos um comentário.

Requisitos

  • Servidor-container (LXC ou LXD), máquina virtual ou servidor físico comum, com no mínimo 512MB de memória RAM e Ubuntu 18.04 ou mais recente instalado.
  • Portas 80 e 443 acessíveis pela internet
  • Um nome de domínio associado ao endereço IP público deste servidor
  • Acesso com privilégios de root (sudo).

Visão geral da arquitetura

A arquitetura é a mesma que foi descrita anteriormente, uma aplicação web de três camadas. Ela consiste em scripts PHP executados no interpretador PHP e arquivos estáticos processados pelo servidor web.

Automatizando a instalação do WordPress com NGINX Unit e Ubuntu

Princípios Gerais

  • Muitos comandos de configuração no script estão encapsulados em condições (if) para idempotência: o script pode ser executado várias vezes sem risco de alterar configurações que já estão prontas.
  • O script tenta instalar software a partir de repositórios, para que você possa aplicar atualizações do sistema em um único comando (apt upgrade para Ubuntu).
  • Os comandos tentam determinar se estão sendo executados em um contêiner, para ajustar suas configurações conforme necessário.
  • Para definir o número de processos/threads a serem executados na configuração, o script tenta adivinhar os parâmetros automáticos de configuração para operar em contêineres, máquinas virtuais e servidores físicos.
  • Ao descrever as configurações, sempre pensamos primeiro na automação, que esperamos se torne a base para a criação da sua própria infraestrutura como código.
  • Todos os comandos são executados a partir do usuário root, porque eles alteram configurações principais do sistema, mas o WordPress em si opera a partir de um usuário comum.

Configuração de Variáveis de Ambiente

Defina as seguintes variáveis de ambiente antes de executar o script:

  • WORDPRESS_DB_PASSWORD — senha do banco de dados WordPress
  • WORDPRESS_ADMIN_USER — nome do administrador WordPress
  • WORDPRESS_ADMIN_PASSWORD — senha do administrador WordPress
  • WORDPRESS_ADMIN_EMAIL — email do administrador WordPress
  • WORDPRESS_URL — URL completo do site WordPress, começando com https://.
  • LETS_ENCRYPT_STAGING — vazio por padrão, mas, ao definir o valor como 1, você usará servidores de staging do Let’s Encrypt, necessários para a solicitação frequente de certificados ao testar suas configurações, caso contrário, o Let’s Encrypt pode temporariamente bloquear seu endereço IP devido ao grande número de solicitações.

O script verifica se essas variáveis relacionadas ao WordPress estão definidas e encerra a execução se não estiverem.
As linhas do script 572-576 verificam o valor LETS_ENCRYPT_STAGING.

Configuração de Variáveis de Ambiente Derivadas

O script nas linhas 55-61 define as seguintes variáveis de ambiente, seja para um determinado valor fixo ou utilizando o valor obtido das variáveis configuradas na seção anterior:

  • DEBIAN_FRONTEND="noninteractive" — informa aos aplicativos que estão sendo executados em um script e não há possibilidade de interação com o usuário.
  • WORDPRESS_CLI_VERSION="2.4.0" — versão do aplicativo WordPress CLI.
  • WORDPRESS_CLI_MD5= "dedd5a662b80cda66e9e25d44c23b25c" — soma de verificação do arquivo executável do WordPress CLI 2.4.0 (a versão é especificada na variável WORDPRESS_CLI_VERSION). O script na linha 162 usa esse valor para verificar se o arquivo do WordPress CLI foi baixado corretamente.
  • UPLOAD_MAX_FILESIZE="16M" — tamanho máximo do arquivo que pode ser enviado ao WordPress. Essa configuração é usada em vários lugares, então é mais fácil defini-la em um só lugar.
  • TLS_HOSTNAME= "$(echo ${WORDPRESS_URL} | cut -d'\/ -f3)" — hostname do sistema, extraído da variável WORDPRESS_URL. Usado para obter os respectivos certificados TLS/SSL da Let’s Encrypt, assim como para a verificação interna do WordPress.
  • NGINX_CONF_DIR="\/etc\/nginx" — caminho para o diretório com as configurações do NGINX, incluindo o arquivo principal. nginx.conf.
  • CERT_DIR="\/etc\/letsencrypt\/live\/${TLS_HOSTNAME}" — caminho para os certificados Let’s Encrypt para o site WordPress, obtido da variável TLS_HOSTNAME.

Atribuição do hostname ao servidor WordPress.

O script define o hostname do servidor para que o valor corresponda ao nome de domínio do site. Isso não é obrigatório, mas facilita o envio de e-mails de saída via SMTP ao configurar um único servidor, como é configurado pelo script.

código do script

# Change the hostname to be the same as the WordPress hostname
if [ ! "$(hostname)" == "${TLS_HOSTNAME}" ]; then
  echo " Changing hostname to ${TLS_HOSTNAME}"
  hostnamectl set-hostname "${TLS_HOSTNAME}"
fi

Adicionando o hostname em \/etc\/hosts

Extensão WP‑Cron usado para executar tarefas periódicas, requer que o WordPress possa acessar a si mesmo via HTTP. Para garantir que o WP-Cron funcione corretamente em todos os ambientes, o script adiciona uma linha ao arquivo /etc/hosts, assim o WordPress pode acessar a si mesmo através da interface de loopback:

código do script

# Add the hostname to /etc/hosts
if [ "$(grep -m1 "${TLS_HOSTNAME}" /etc/hosts)" = "" ]; then
  echo " Adding hostname ${TLS_HOSTNAME} to /etc/hosts so that WordPress can ping itself"
  printf "::1 %sn127.0.0.1 %sn" "${TLS_HOSTNAME}" "${TLS_HOSTNAME}" >> /etc/hosts
fi

Instalação das ferramentas necessárias para as etapas subsequentes.

O restante do script requer alguns programas e assume que os repositórios estão atualizados. Atualizamos a lista de repositórios e, em seguida, instalamos as ferramentas necessárias:

código do script

# Make sure tools needed for install are present
echo " Installing prerequisite tools"
apt-get -qq update
apt-get -qq install -y 
  bc 
  ca-certificates 
  coreutils 
  curl 
  gnupg2 
  lsb-release

Adição dos repositórios NGINX Unit e NGINX.

O script instala o NGINX Unit e o NGINX de código aberto a partir dos repositórios oficiais do NGINX, para garantir que estão sendo usadas as versões mais atualizadas com correções de segurança.

O script adiciona o repositório do NGINX Unit e, em seguida, o repositório do NGINX, adicionando a chave dos repositórios e os arquivos de configuração. apt, que configuram o acesso aos repositórios pela internet.

A instalação real do NGINX Unit e NGINX ocorre na próxima seção. Adicionamos os repositórios antecipadamente para evitar atualizar os metadados várias vezes, o que torna a instalação mais rápida.

código do script

# Install the NGINX Unit repository
if [ ! -f /etc/apt/sources.list.d/unit.list ]; then
  echo " Installing NGINX Unit repository"
  curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
  echo "deb https://packages.nginx.org/unit/ubuntu/ $(lsb_release -cs) unit" > /etc/apt/sources.list.d/unit.list
fi

# Install the NGINX repository
if [ ! -f /etc/apt/sources.list.d/nginx.list ]; then
  echo " Installing NGINX repository"
  curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
  echo "deb https://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" > /etc/apt/sources.list.d/nginx.list
fi

Instalação do NGINX, NGINX Unit, PHP, MariaDB, Certbot (Let's Encrypt) e suas dependências

Assim que todos os repositórios forem adicionados, atualizamos os metadados e instalamos os aplicativos. Os pacotes instalados pelo script também incluem extensões PHP recomendadas ao iniciar o WordPress.org.

código do script

echo " Atualizando os metadados do repositório"
apt-get -qq update

# Instalar PHP com dependências e NGINX Unit
echo " Instalando PHP, NGINX Unit, NGINX, Certbot e MariaDB"
apt-get -qq install -y --no-install-recommends 
  certbot 
  python3-certbot-nginx 
  php-cli 
  php-common 
  php-bcmath 
  php-curl 
  php-gd 
  php-imagick 
  php-mbstring 
  php-mysql 
  php-opcache 
  php-xml 
  php-zip 
  ghostscript 
  nginx 
  unit 
  unit-php 
  mariadb-server

Configuração do PHP para uso com NGINX Unit e WordPress

O script cria um arquivo de configuração no diretório conf.d. Aqui é definido o tamanho máximo dos arquivos carregados para o PHP, a saída de erros do PHP é habilitada em STDERR, para que sejam gravados no log do NGINX Unit, e o NGINX Unit é reiniciado.

código do script

# Find the major and minor PHP version so that we can write to its conf.d directory
PHP_MAJOR_MINOR_VERSION="$(php -v | head -n1 | cut -d' ' -f2 | cut -d'.' -f1,2)"

if [ ! -f "/etc/php/${PHP_MAJOR_MINOR_VERSION}/embed/conf.d/30-wordpress-overrides.ini" ]; then
  echo " Configuring PHP for use with NGINX Unit and WordPress"
  # Add PHP configuration overrides
  cat > "/etc/php/${PHP_MAJOR_MINOR_VERSION}/embed/conf.d/30-wordpress-overrides.ini" << EOM
; Set a larger maximum upload size so that WordPress can handle
; bigger media files.
upload_max_filesize=${UPLOAD_MAX_FILESIZE}
post_max_size=${UPLOAD_MAX_FILESIZE}
; Write error log to STDERR so that error messages show up in the NGINX Unit log
error_log=/dev/stderr
EOM
fi

# Restart NGINX Unit because we have reconfigured PHP
echo " Restarting NGINX Unit"
service unit restart

Definindo as configurações do banco de dados MariaDB para WordPress

Escolhemos o MariaDB em vez do MySQL, pois ele tem uma comunidade mais ativa e, além disso, pode oferecer melhor desempenho por padrão (provavelmente, tudo aqui é mais simples: para instalar o MySQL, é necessário adicionar mais um repositório, nota do tradutor).

O script cria um novo banco de dados e gera as credenciais para acessar o WordPress através da interface loopback:

código do script

# Set up the WordPress database
echo " Configuring MariaDB for WordPress"
mysqladmin create wordpress || echo "Ignoring above error because database may already exist"
mysql -e "GRANT ALL PRIVILEGES ON wordpress.* TO "wordpress"@"localhost" IDENTIFIED BY "$WORDPRESS_DB_PASSWORD"; FLUSH PRIVILEGES;"

Instalação do WordPress CLI

Neste passo, o script instala o programa WP-CLI. Com ele, é possível instalar e gerenciar as configurações do WordPress sem necessidade de editar arquivos manualmente, atualizar o banco de dados ou acessar o painel de controle. Também é possível instalar temas e plugins e realizar atualizações do WordPress.

código do script

if [ ! -f /usr/local/bin/wp ]; then
  # Instalar a ferramenta WordPress CLI
  echo " Instalando a ferramenta WordPress CLI"
  curl --retry 6 -Ls "https://github.com/wp-cli/wp-cli/releases/download/v${WORDPRESS_CLI_VERSION}/wp-cli-${WORDPRESS_CLI_VERSION}.phar" > /usr/local/bin/wp
  echo "$WORDPRESS_CLI_MD5 /usr/local/bin/wp" | md5sum -c -
  chmod +x /usr/local/bin/wp
fi

Instalação e configuração do WordPress

O script instala a versão mais recente do WordPress no diretório /var/www/wordpress, e também altera as configurações:

  • A conexão com o banco de dados é feita através de unix domain socket em vez de TCP no loopback, para reduzir o tráfego TCP.
  • O WordPress adiciona um prefixo https:// para o URL, caso os clientes se conectem ao NGINX via protocolo HTTPS, e também envia o hostname remoto (como fornecido pelo NGINX) para o PHP. Aplicamos um trecho de código para configurar isso.
  • O WordPress precisa de HTTPS para login
  • A estrutura da URL é baseada em recursos por padrão
  • As permissões corretas são configuradas no sistema de arquivos para o diretório do WordPress.

código do script

if [ ! -d /var/www/wordpress ]; then
  # Criar diretórios do WordPress
  mkdir -p /var/www/wordpress
  chown -R www-data:www-data /var/www

  # Baixar o WordPress usando a CLI do WordPress
  echo " Instalando o WordPress"
  su -s /bin/sh -c 'wp --path=/var/www/wordpress core download' www-data

  WP_CONFIG_CREATE_CMD="wp --path=/var/www/wordpress config create --extra-php --dbname=wordpress --dbuser=wordpress --dbhost="localhost:/var/run/mysqld/mysqld.sock" --dbpass="${WORDPRESS_DB_PASSWORD}""

  # Este trecho é injetado no arquivo wp-config.php quando é criado;
  # ele informa ao WordPress que estamos atrás de um proxy reverso e, como tal,
  # permite que ele gere links usando HTTPS
  cat > /tmp/wp_forwarded_for.php << 'EOM'
/* Ativar HTTPS 'on' se HTTP_X_FORWARDED_PROTO corresponder a 'https' */
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
    $_SERVER['HTTPS'] = 'on';
}
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
EOM

  # Criar configuração do WordPress
  su -s /bin/sh -p -c "cat /tmp/wp_forwarded_for.php | ${WP_CONFIG_CREATE_CMD}" www-data
  rm /tmp/wp_forwarded_for.php
  su -s /bin/sh -p -c "wp --path=/var/www/wordpress config set 'FORCE_SSL_ADMIN' 'true'" www-data

  # Instalar o WordPress
  WP_SITE_INSTALL_CMD="wp --path=/var/www/wordpress core install --url="${WORDPRESS_URL}" --title="${WORDPRESS_SITE_TITLE}" --admin_user="${WORDPRESS_ADMIN_USER}" --admin_password="${WORDPRESS_ADMIN_PASSWORD}" --admin_email="${WORDPRESS_ADMIN_EMAIL}" --skip-email"
  su -s /bin/sh -p -c "${WP_SITE_INSTALL_CMD}" www-data

  # Definir a estrutura de permalink para um padrão sensato que não esteja na interface
  su -s /bin/sh -p -c "wp --path=/var/www/wordpress option update permalink_structure '/%year%/%monthnum%/%postname%/'" www-data

  # Remover arquivo de exemplo porque é supérfluo e poderia ser um problema de segurança
  rm /var/www/wordpress/wp-config-sample.php

  # Garantir que as permissões do WordPress estejam corretas
  find /var/www/wordpress -type d -exec chmod g+s {} ;
  chmod g+w /var/www/wordpress/wp-content
  chmod -R g+w /var/www/wordpress/wp-content/themes
  chmod -R g+w /var/www/wordpress/wp-content/plugins
fi

Configuração do NGINX Unit

O script configura o NGINX Unit para executar PHP e processar caminhos do WordPress, isolando o espaço de nomes dos processos PHP e otimizando as configurações de desempenho. Aqui estão três funções que merecem atenção:

  • O suporte a espaços de nomes é determinado por uma condição, baseada na verificação da execução do script em um contêiner. Isso é necessário, pois a maioria das configurações de contêiner não suportam execução aninhada de contêineres.
  • Se houver suporte a espaços de nomes, o espaço de nomes é desativado rede. Isso é necessário para permitir que o WordPress se conecte simultaneamente a endpoints e esteja disponível na internet.
  • O número máximo de processos é determinado da seguinte forma: (Memória disponível para MariaDB e NGINX Uniy em execução) / (limite de memória RAM no PHP + 5)
    Este valor é configurado nas definições do NGINX Unit.

Esse valor também pressupõe que sempre haja pelo menos dois processos PHP em execução, o que é importante, pois o WordPress faz muitas chamadas assíncronas para si mesmo e, sem processos adicionais, a execução, por exemplo, do WP-Cron, falhará. Você pode querer aumentar ou diminuir esses limites com base nas suas configurações locais, pois as configurações criadas aqui são conservadoras. Na maioria dos sistemas de produção, as configurações ficam entre 10 e 100.

código do script

if [ "${container:-unknown}" != "lxc" ] && [ "$(grep -m1 -a container=lxc /proc/1/environ | tr -d ' ')" == "" ]; then
  NAMESPACES='"namespaces": {
        "cgroup": true,
        "credential": true,
        "mount": true,
        "network": false,
        "pid": true,
        "uname": true
    }'
else
  NAMESPACES='"namespaces": {}'
fi

PHP_MEM_LIMIT="$(grep 'memory_limit' /etc/php/7.4/embed/php.ini | tr -d ' ' | cut -f2 -d= | numfmt --from=iec)"
AVAIL_MEM="$(grep MemAvailable /proc/meminfo | tr -d ' kB' | cut -f2 -d: | numfmt --from-unit=K)"
MAX_PHP_PROCESSES="$(echo "${AVAIL_MEM}/${PHP_MEM_LIMIT}+5" | bc)"
echo " Calculado o número máximo de processos PHP como ${MAX_PHP_PROCESSES}. Você pode querer ajustar este valor devido a variações na sua configuração. Não é incomum ver valores entre 10-100 em configurações de produção."

echo " Configurando o NGINX Unit para usar PHP e WordPress"
cat > /tmp/wordpress.json << EOM
{
  "settings": {
    "http": {
      "header_read_timeout": 30,
      "body_read_timeout": 30,
      "send_timeout": 30,
      "idle_timeout": 180,
      "max_body_size": $(numfmt --from=iec ${UPLOAD_MAX_FILESIZE})
    }
  },
  "listeners": {
    "127.0.0.1:8080": {
      "pass": "routes/wordpress"
    }
  },
  "routes": {
    "wordpress": [
      {
        "match": {
          "uri": [
            "*.php",
            "*.php/*",
            "/wp-admin/"
          ]
        },
        "action": {
          "pass": "applications/wordpress/direct"
        }
      },
      {
        "action": {
          "share": "/var/www/wordpress",
          "fallback": {
            "pass": "applications/wordpress/index"
          }
        }
      }
    ]
  },
  "applications": {
    "wordpress": {
      "type": "php",
      "user": "www-data",
      "group": "www-data",
      "processes": {
        "max": ${MAX_PHP_PROCESSES},
        "spare": 1
      },
      "isolation": {
        ${NAMESPACES}
      },
      "targets": {
        "direct": {
          "root": "/var/www/wordpress/"
        },
        "index": {
          "root": "/var/www/wordpress/",
          "script": "index.php"
        }
      }
    }
  }
}
EOM

curl -X PUT --data-binary @/tmp/wordpress.json --unix-socket /run/control.unit.sock http://localhost/config

Configuração do NGINX

Configuração dos parâmetros principais do NGINX

O script cria um diretório para o cache do NGINX e, em seguida, cria o arquivo de configuração principal nginx.conf. Preste atenção no número de processos manipuladores e na definição do tamanho máximo do arquivo para upload. Também há uma linha onde o arquivo de configuração de compressão é conectado, definido na seção a seguir, seguida pelas configurações de cache.

código do script

# Make directory for NGINX cache
mkdir -p /var/cache/nginx/proxy

echo " Configuring NGINX"
cat > ${NGINX_CONF_DIR}/nginx.conf << EOM
user nginx;
worker_processes auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       ${NGINX_CONF_DIR}/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;
    client_max_body_size ${UPLOAD_MAX_FILESIZE};
    keepalive_timeout  65;
    # gzip settings
    include ${NGINX_CONF_DIR}/gzip_compression.conf;
    # Cache settings
    proxy_cache_path /var/cache/nginx/proxy
        levels=1:2
        keys_zone=wp_cache:10m
        max_size=10g
        inactive=60m
        use_temp_path=off;
    include ${NGINX_CONF_DIR}/conf.d/*.conf;
}
EOM

Configuração de compressão NGINX

A compressão de conteúdo em tempo real antes de enviá-lo aos clientes é uma excelente maneira de melhorar o desempenho do site, mas somente se a compressão estiver configurada corretamente. Esta seção do script é baseada nas configurações daqui.

código do script

cat > ${NGINX_CONF_DIR}/gzip_compression.conf << 'EOM'
# Crédito: https://github.com/h5bp/server-configs-nginx/
# ----------------------------------------------------------------------
# | Compressão                                                          |
# ----------------------------------------------------------------------
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
# Ativar compressão gzip.
# Padrão: off
gzip on;
# Nível de compressão (1-9).
# 5 é um compromisso perfeito entre tamanho e uso de CPU, oferecendo cerca de 75%
# de redução para a maioria dos arquivos ASCII (quase idêntico ao nível 9).
# Padrão: 1
gzip_comp_level 6;
# Não comprimir nada que já seja pequeno e improvável de diminuir muito se as
# compressões não forem aplicadas (o padrão é 20 bytes, o que é ruim, já que geralmente gera arquivos maiores após a compressão gzip).
# Padrão: 20
gzip_min_length 256;
# Comprimir dados mesmo para clientes que estão se conectando a nós via proxies,
# identificados pelo cabeçalho "Via" (necessário para CloudFront).
# Padrão: off
gzip_proxied any;
# Dizer aos proxies para armazenar em cache tanto a versão gzipada quanto a versão regular de um recurso
# sempre que o cabeçalho de capacidades Accept-Encoding do cliente variar;
# Evita o problema em que um cliente não capaz de gzip (o que é extremamente raro
# hoje) exibiria caracteres estranhos se seu proxy desse a ele a versão gzipada.
# Padrão: off
gzip_vary on;
# Comprimir toda saída rotulada com um dos seguintes tipos MIME.
# `text/html` é sempre comprimido pelo módulo gzip.
# Padrão: text/html
gzip_types
  application/atom+xml
  application/geo+json
  application/javascript
  application/x-javascript
  application/json
  application/ld+json
  application/manifest+json
  application/rdf+xml
  application/rss+xml
  application/vnd.ms-fontobject
  application/wasm
  application/x-web-app-manifest+json
  application/xhtml+xml
  application/xml
  font/eot
  font/otf
  font/ttf
  image/bmp
  image/svg+xml
  text/cache-manifest
  text/calendar
  text/css
  text/javascript
  text/markdown
  text/plain
  text/xml
  text/vcard
  text/vnd.rim.location.xloc
  text/vtt
  text/x-component
  text/x-cross-domain-policy;
EOM

Configuração NGINX para WordPress

Em seguida, o script cria um arquivo de configuração para WordPress default.conf no diretório conf.d. Aqui está configurado:

  • Ativação dos certificados TLS obtidos da Let’s Encrypt através do Certbot (sua configuração será na seção a seguir)
  • Configuração dos parâmetros de segurança TLS, com base nas recomendações da Let’s Encrypt
  • Conexão de cache para requisições saltadas por 1 hora por padrão
  • Desativação do registro de acesso, bem como do registro de erros, se o arquivo não for encontrado, para dois arquivos comumente solicitados: favicon.ico e robots.txt
  • Proibição de acesso a arquivos ocultos e a alguns arquivos .php, para prevenir o acesso não autorizado ou a execução acidental
  • Desativar o registro de acesso para arquivos estáticos e fontes
  • Definição do cabeçalho Access-Control-Allow-Origin para arquivos de fonte
  • Adicionando roteamento para index.php e outros arquivos estáticos.

código do script

cat > ${NGINX_CONF_DIR}\/conf.d\/default.conf << EOM
upstream unit_php_upstream {
    server 127.0.0.1:8080;
    keepalive 32;
}
server {
    listen 80;
    listen [::]:80;
    # ACME-challenge usado pelo Certbot para Let's Encrypt
    location ^~ \/.well-known\/acme-challenge\/ {
      root \/var\/www\/certbot;
    }
    location \/ {
      return 301 https:\/${TLS_HOSTNAME}$request_uri;
    }
}
server {
    listen      443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ${TLS_HOSTNAME};
    root        \/var\/www\/wordpress\/;
    # Configuração do Let's Encrypt
    ssl_certificate         ${CERT_DIR}\/fullchain.pem;
    ssl_certificate_key     ${CERT_DIR}\/privkey.pem;
    ssl_trusted_certificate ${CERT_DIR}\/chain.pem;
    include ${NGINX_CONF_DIR}\/options-ssl-nginx.conf;
    ssl_dhparam ${NGINX_CONF_DIR}\/ssl-dhparams.pem;
    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    # Cache de proxy
    proxy_cache wp_cache;
    proxy_cache_valid 200 302 1h;
    proxy_cache_valid 404 1m;
    proxy_cache_revalidate on;
    proxy_cache_background_update on;
    proxy_cache_lock on;
    proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
    location = \/favicon.ico {
        log_not_found off;
        access_log off;
    }
    location = \/robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # Negar todas as tentativas de acesso a arquivos ocultos como .htaccess, .htpasswd,
    # .DS_Store (Mac)
    # Manter o registro das solicitações para análise posterior (ou para passar para ferramentas de firewall
    # como fail2ban)
    location ~ \/. {
        deny all;
    }
    # Negar acesso a quaisquer arquivos com extensão .php no diretório de uploads;
    # funciona em instalações de subdiretório e também em rede multi-site.
    # Manter o registro das solicitações para análise posterior (ou para passar para ferramentas de firewall
    # como fail2ban).
    location ~* \/(?:uploads|files)\/.*.php$ {
        deny all;
    }
    # WordPress: negar acesso a arquivos PHP em wp-content, wp-includes
    location ~* ^\/(?:wp-content|wp-includes)\/.*.php$ {
        deny all;
    }
    # Negar acesso público ao wp-config.php
    location ~* wp-config.php {
        deny all;
    }
    # Não registrar acesso para ativos estáticos, mídia
    location ~* .(?:css(.map)?|js(.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
        access_log off;
    }
    location ~* .(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
        add_header Access-Control-Allow-Origin "*";
        access_log off;
    }
    location \/ {
        try_files $uri @index_php;
    }
    location @index_php {
        proxy_socket_keepalive on;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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 Host $host;
        proxy_pass       http:\/\/unit_php_upstream;
    }
    location ~* .php$ {
        proxy_socket_keepalive on;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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 Host $host;
        try_files        $uri =404;
        proxy_pass       http:\/\/unit_php_upstream;
    }
}
EOM

Configuração do Certbot para certificados do Let’s Encrypt e sua renovação automática

Certbot — uma ferramenta gratuita da Electronic Frontier Foundation (EFF) que permite obter e renovar automaticamente certificados TLS do Let’s Encrypt. O script realiza as seguintes ações para configurar o Certbot para gerenciar certificados do Let’s Encrypt no NGINX:

  • Para de parar o NGINX
  • Baixa parâmetros TLS recomendados
  • Inicia o Certbot para obter certificados para o site
  • Reinicia o NGINX para usar os certificados
  • Configura a execução diária do Certbot às 3:24 da manhã para verificar a necessidade de renovação de certificados e, se necessário, baixar novos certificados e reiniciar o NGINX.

código do script

echo " Parando o NGINX para configurar o Let's Encrypt"
service nginx stop

mkdir -p /var/www/certbot
chown www-data:www-data /var/www/certbot
chmod g+s /var/www/certbot

if [ ! -f ${NGINX_CONF_DIR}/options-ssl-nginx.conf ]; then
  echo " Baixando parâmetros TLS recomendados"
  curl --retry 6 -Ls -z "Tue, 14 Apr 2020 16:36:07 GMT" 
    -o "${NGINX_CONF_DIR}/options-ssl-nginx.conf" 
    "https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf" 
    || echo "Não foi possível baixar o último options-ssl-nginx.conf"
fi

if [ ! -f ${NGINX_CONF_DIR}/ssl-dhparams.pem ]; then
  echo " Baixando parâmetros TLS DH recomendados"
  curl --retry 6 -Ls -z "Tue, 14 Apr 2020 16:49:18 GMT" 
    -o "${NGINX_CONF_DIR}/ssl-dhparams.pem" 
    "https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem" 
    || echo "Não foi possível baixar o último ssl-dhparams.pem"
fi

# Se o tls_certs_init.sh não foi executado antes, remova os certificados autoassinados
if [ ! -d "/etc/letsencrypt/accounts" ]; then
  echo " Removendo certificados autoassinados"
  rm -rf "${CERT_DIR}"
fi

if [ "" = "${LETS_ENCRYPT_STAGING:-}" ] || [ "0" = "${LETS_ENCRYPT_STAGING}" ]; then
  CERTBOT_STAGING_FLAG=""
else
  CERTBOT_STAGING_FLAG="--staging"
fi

if [ ! -f "${CERT_DIR}/fullchain.pem" ]; then
  echo " Gerando certificados com Let's Encrypt"
  certbot certonly --standalone 
         -m "${WORDPRESS_ADMIN_EMAIL}" 
         ${CERTBOT_STAGING_FLAG} 
         --agree-tos --force-renewal --non-interactive 
         -d "${TLS_HOSTNAME}"
fi

echo " Iniciando o NGINX para usar a nova configuração"
service nginx start

# Escreve no crontab para renovação periódica do certificado Let's Encrypt
if [ "$(crontab -l | grep -m1 'certbot renew')" == "" ]; then
  echo " Adicionando certbot ao crontab para renovação automática do Let's Encrypt"
  (crontab -l 2>/dev/null; echo "24 3 * * * certbot renew --nginx --post-hook 'service nginx reload'") | crontab -
fi

Configuração adicional do seu site

Nós acima explicamos como nosso script configura o NGINX e o NGINX Unit para gerenciar um site pronto para produção com TLS/SSL ativado. Você também pode, dependendo de suas necessidades, adicionar no futuro:

  • Suporte Brotli, compressão melhorada em tempo real sobre HTTPS
  • ModSecurity com com regras para WordPress, para prevenir ataques automáticos ao seu site
  • Backup para WordPress, que se encaixem nas suas necessidades
  • Proteção com AppArmor (no Ubuntu)
  • Postfix ou msmtp para que o WordPress possa enviar e-mails
  • Testes do seu site para que você entenda quanto tráfego ele pode suportar

Para um desempenho ainda melhor do site, recomendamos a atualização para NGINX Plus, nosso produto comercial de nível corporativo, baseado no NGINX de código aberto. Seus assinantes receberão um módulo Brotli carregado dinamicamente, além de (por um custo adicional) NGINX ModSecurity WAF. Também oferecemos NGINX App Protect, um módulo WAF para NGINX Plus, baseado na tecnologia de segurança líder da indústria da F5.

N.B. Para suporte a sites de alta carga, você pode contatar especialistas Southbridge. Garantiremos o funcionamento rápido e confiável do seu site ou serviço sob qualquer carga.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster