Laravel Lets Encrypt: Geração SSL Automática

Posted on: January 21, 2026 03:35 PM

Posted by: Renato

Categories: Laravel lets-encrypt

Views: 99

Laravel Lets Encrypt: Geração SSL Automática

 

 O que é este pacote laravel-lets-encrypt, e como usar?

 

O pacote laravel-lets-encrypt é uma ferramenta desenvolvida para facilitar a geração e renovação automática de certificados SSL gratuitos da Let's Encrypt diretamente através de uma aplicação Laravel.

Geralmente, a gestão de SSL é feita no nível do servidor (usando ferramentas como Certbot ou via Forge/Ploi). Este pacote traz essa lógica para dentro do código, o que é extremamente útil para plataformas SaaS (Multi-tenancy), onde você precisa emitir certificados para domínios customizados de clientes de forma programática.

Como o pacote funciona?

Ele utiliza o protocolo ACME para se comunicar com a Let's Encrypt. O fluxo básico consiste em:

  1. Solicitar um certificado para um domínio.

  2. Provar a propriedade do domínio (Desafio HTTP ou DNS).

  3. Receber e armazenar os arquivos do certificado (fullchain.pem, privkey.pem).

Como usar (Passo a Passo)

1. Instalação

Primeiro, instale o pacote via Composer:

Bash

composer require f60/laravel-lets-encrypt

Recomendo usar este:
 
composer require daanra/laravel-lets-encrypt

  • https://github.com/Daanra/laravel-lets-encrypt

(Nota: Existem variações deste pacote de diferentes autores, como o f60 ou driesvarts. Verifique a documentação da versão específica que você escolher, mas a lógica costuma ser similar.)

2. Configuração

Publique o arquivo de configuração para definir onde os certificados serão salvos e as credenciais da sua conta Let's Encrypt:

Bash

php artisan vendor:publish --provider="F60\LetsEncrypt\LetsEncryptServiceProvider"

No arquivo config/lets-encrypt.php, você configurará o e-mail de contato e o ambiente (Staging para testes ou Production).

3. O Desafio (Challenge)

A Let's Encrypt precisa confirmar que você é dono do domínio. O método mais comum é o HTTP-01.

  • O pacote cria uma rota automaticamente que responde em .well-known/acme-challenge/.

  • Você deve garantir que seu servidor web (Nginx/Apache) direcione essas requisições para o seu index.php do Laravel.

4. Gerando um Certificado via Código

A grande vantagem é poder disparar a criação em um Controller ou Job:

PHP

use F60\LetsEncrypt\LetsEncrypt;  public function generateSsl($domain) {     // Instancia o serviço e solicita o certificado     $letsEncrypt = app(LetsEncrypt::class);          // Isso executará o desafio e salvará os arquivos no storage definido     $letsEncrypt->create($domain);          return "Certificado gerado com sucesso!"; }

Pontos de Atenção

  • Limites de Taxa (Rate Limits): A Let's Encrypt tem limites estritos de quantas vezes você pode solicitar certificados. Sempre use o modo Staging durante o desenvolvimento.

  • Servidor Web: O pacote gera os arquivos, mas você ainda precisa configurar seu Nginx ou Apache para ler esses arquivos na pasta storage do Laravel.

  • Permissões: O usuário que roda o PHP (ex: www-data) precisa de permissão de escrita na pasta onde os certificados serão armazenados.

Quando usar este pacote?

  • SaaS: Se seu usuário aponta um domínio cliente.com para o seu IP e você quer gerar o SSL automaticamente.

  • Automação: Se você quer evitar o uso de ferramentas externas de linha de comando no servidor.

 

Pacote daanra/laravel-lets-encrypt. Ele é uma solução robusta para quem trabalha com SaaS (Software as a Service) ou qualquer aplicação onde você precise gerenciar centenas ou milhares de domínios customizados apontando para o seu servidor.

Aqui está uma análise detalhada dos pontos principais desse pacote:

1. O Diferencial: Baseado em Filas (Queues)

Diferente de outros pacotes que tentam fazer tudo de forma síncrona (travando a requisição), este pacote foi desenhado para ser assíncrono.

  • Ao chamar LetsEncrypt::create('dominio.com'), ele coloca tarefas na fila do Laravel para:

  1. Registrar a conta na Let's Encrypt.

  2. Criar o "desafio" (token de validação).

  3. Solicitar o certificado.

  4. Armazenar o certificado no banco de dados.

2. Gerenciamento via Banco de Dados

Este pacote possui uma migration própria. Isso significa que você tem um modelo Eloquent (LetsEncryptCertificate) para gerenciar os certificados. Você pode fazer consultas como:

  • Ver quais certificados expiram em breve.

  • Listar todos os domínios ativos.

  • Deletar certificados de clientes que cancelaram o serviço.

3. O Desafio HTTP (O "Pulo do Gato")

A Let's Encrypt precisa acessar uma URL no seu domínio para confirmar que você é o dono dele. O pacote salva esse token na pasta storage. O README avisa: Você precisa criar uma rota manualmente (ou configurar o Nginx) para que, quando a Let's Encrypt acessar seu-dominio.com/.well-known/acme-challenge/{token}, o Laravel entregue o conteúdo do arquivo que o pacote gerou.

4. Automação Total (Renovação)

O pacote resolve um dos maiores problemas do SSL: a expiração a cada 90 dias. Ele traz um Job pronto (RenewExpiringCertificates) que você agenda no seu Console/Kernel.php para rodar diariamente. Ele automaticamente renova certificados com mais de 60 dias de uso.

5. Encadeamento de Tarefas (Chaining)

Um recurso muito poderoso citado é a capacidade de "encadear" ações. Exemplo: Assim que o certificado for gerado com sucesso, você pode disparar automaticamente outros Jobs, como:

  • Reiniciar o servidor Apache/Nginx.

  • Notificar o usuário por e-mail que o domínio dele já está seguro.

6. Configuração Importante (Staging vs Production)

O README enfatiza: Por padrão, o pacote usa o servidor de testes (Staging) da Let's Encrypt.

  • Isso é ótimo para desenvolver sem ser bloqueado por excesso de tentativas.

  • Para o site real, você deve mudar a URL no seu .env para a URL de produção da Let's Encrypt.

Resumo: Devo usar?

  • Use se: Você está criando um sistema estilo "Shopify" ou "Wix", onde o usuário final aponta o próprio domínio para o seu servidor e você quer que o SSL apareça "magicamente" para ele.

  • Não use se: Você só quer SSL para o seu próprio site (www.meusite.com). Para isso, é muito mais simples e seguro usar o Certbot diretamente no servidor ou serviços como Cloudflare e Laravel Forge.

Dica técnica: Se você for usar este pacote, certifique-se de que seu sistema de Queues (Fila) está configurado corretamente (usando Redis ou Database), pois o pacote depende 100% disso para funcionar bem.

Para implementar esse pacote e transformar sua aplicação Laravel em um gerenciador de certificados, você precisa integrar o fluxo de solicitação, validação e renovação.

Aqui está um guia prático de como estruturar isso:

1. Configuração do Ambiente e Servidor

Antes do código, seu servidor (Nginx/Apache) precisa saber entregar o desafio que o Let's Encrypt enviará. No seu arquivo de rotas routes/web.php, adicione:

PHP

use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Route;  // Rota crucial para a validação do Let's Encrypt Route::get('/.well-known/acme-challenge/{token}', function (string $token) {     $path = 'public/.well-known/acme-challenge/' . $token;     if (Storage::disk('local')->exists($path)) {         return Storage::disk('local')->get($path);     }     abort(404); });

2. Criando um Serviço de Gestão de Domínios

Imagine que você tem um modelo Store ou Domain. Vamos criar um serviço para centralizar a criação do SSL.

PHP

namespace App\Services;  use Daanra\LaravelLetsEncrypt\Facades\LetsEncrypt; use Daanra\LaravelLetsEncrypt\Models\LetsEncryptCertificate;  class SslService {     /**

     * Gera um certificado para um novo domínio de cliente.

     */     public function createForDomain(string $domain)     {         // createNow executa de forma síncrona.          // Se preferir via fila (queue), use apenas create().         return LetsEncrypt::createNow($domain);     }      /**

     * Verifica o status de um certificado no banco.

     */     public function getStatus(string $domain)     {         $cert = LetsEncryptCertificate::where('domain', $domain)->first();                  if (!$cert) return 'not_found';                  return [             'is_valid' => $cert->is_valid,             'expires_at' => $cert->expires_at,             'needs_renewal' => $cert->requiresRenewal(),         ];     } }

3. Automatizando a Renovação

O Let's Encrypt dura apenas 90 dias. O pacote já traz um Job de renovação, você só precisa agendá-lo no arquivo app/Console/Kernel.php:

PHP

protected function schedule(Schedule $schedule) {     // Tenta renovar diariamente certificados que vencem em menos de 30 dias     $schedule->job(new \Daanra\LaravelLetsEncrypt\Jobs\RenewExpiringCertificates)->daily(); }

4. Exemplo de Fluxo em um Controller

Se você quer permitir que seu usuário clique em um botão "Ativar SSL":

PHP

public function activateSsl(Request $request, SslService $sslService) {     $domain = $request->input('domain'); // ex: cliente.com      try {         $sslService->createForDomain($domain);                  return back()->with('success', 'Certificado gerado! Pode levar alguns minutos para propagar.');     } catch (\Exception $e) {         return back()->with('error', 'Falha ao gerar SSL: ' . $e->getMessage());     } }

5. Dicas de Ouro para Produção

Onde ficam os arquivos?

Os certificados gerados são salvos no banco de dados (colunas certificate e key). Para que o seu servidor web (Nginx) os use, você precisará de um script ou Job que:

  1. Pegue o conteúdo do banco.

  2. Salve em um arquivo .pem no servidor.

  3. Recarregue o Nginx (sudo nginx -s reload).

Configuração do .env

Nunca esqueça de alternar para o servidor de produção quando for lançar o site:

Snippet de código

# Em desenvolvimento (Staging - não gera SSL válido no navegador, mas evita bloqueios)

LETS_ENCRYPT_API_URL=https://acme-staging-v02.api.letsencrypt.org/directory

 

# Em produção (SSL Real)

LETS_ENCRYPT_API_URL=https://acme-v02.api.letsencrypt.org/directory

 

Limites de Taxa

A Let's Encrypt permite apenas 50 certificados por semana por domínio registrado. Se você estiver testando muito, use sempre o modo Staging.

Você já tem os domínios dos seus clientes apontados via CNAME ou IP para o seu servidor? Isso é um pré-requisito para o teste de validação funcionar.

https://madewithlaravel.com/laravel-lets-encrypt

https://github.com/Daanra/laravel-lets-encrypt


1

Share

Donate to Site


About Author

Renato

Developer

Add a Comment
Comments 0 Comments

No comments yet! Be the first to comment

Blog Search


Categories

Laravel (227) PHP (151) linux (124) Variados (110) Dicas (58) ubuntu (58) developer (48) postgresql (45) database (44) sql (42) Docker (32) front-end (31) mysql (31) devops (26) webdev (24) programming (23) aws (19) tecnologia (19) eloquent (19) dba (18) OUTROS (17) backend (16) laravelphp (16) debian (12) dev (12) reactjs (10) 100DaysOfCode (10) git (10) react (10) nginx (9) inteligencia-artificial (9) PHP Swoole (9) node (9) javascript (9) linux-tools (8) Architecture (8) vue (7) github (7) ciencia (7) nodejs (6) api (6) vscode (6) webservice (6) jwt (6) vim (6) windows (6) arquitetura (6) authentication (5) ia (5) reactnative (5) rest (5) DevSecOps (5) servers (5) apache (5) macox (5) s3 (5) Kubernetes (4) gitlab (4) opensource (4) mariadb (4) jenkins (4) shell (4) mongodb (4) angular (4) autenticacao (4) wsl (4) Swoole (4) lets-encrypt (4) query (4) Raspberry (4) angularjs (4) inteligenciadedados (4) Padrao de design (4) artigo (4) google (4) npm (4) openai (4) js (3) mysqli (3) Black Hat (3) RabbitMQ (3) educacao (3) intel (3) CMS (2) sail (3) script (3) performance (3) json (3) authorization (3) phpswoole (3) ddd (3) blade (3) terminal (3) log (3) mac (3) fedora (3) containers (3) ssh (3) bash (3) hardware (3) tests (3) macos (3) web (2) jobs (3) websocket (3) db (3) politica (3) Curisidades (2) Solid (2) zsh (2) Go (2) BigLinux (2) POO (2) LazyVim (2) gource (2) Python (2) Oauth2 (2) android (2) unix (2) magento (2) iot (2) ffmpeg (2) combustivel (2) webhook (2) microservices (2) bancodedados (2) tailwind (2) homeOffice (2) html (2) openswoole (2) artificialintelligence (2) security (2) auth (2) cron (2) phpunit (2) kube (2) multiple_authen (2) policia (2) neovim (2) golang (2) noticias (2) livros (2) Transcribe (2) ElonMusk (2) redis (2) claude (2) ArchLinux (2) java (2) saude (1) seguranca (2) phpfpm (2) autorizacao (2) monitoring (2) laptop (2) gnome (2) powerbi (2) telefonia (2) nvm (2) imagick (2) maps (2) colors (2) Passport (2) JQuery (2) front (1) wine (1) covid19 (0) services (1) phpjasper (1) models (1) kali-linux (1) geojson (1) yarn (1) picpay (1) Monolith (1) banco (1) PNPM (1) Desenvolvedor (1) Structurizr (1) symfony (1) presenter (1) lider (1) guard (1) tensorflow (1) bootstrap (1) nuance (1) historia (1) dropbox (1) traefik (1) bug (1) akitando (1) llm (1) htm (1) transformers (1) cavalotroia (1) odd (1) m1 (1) Error (1) cinnamon (1) repmgr (1) federal (1) ruby (1) AppSec (1) orm (1) ArquiteturaDeSoftware (1) Passwordless (1) memcached (1) flow (1) compression (1) athena (1) Migration (1) workflow (1) cqrs (1) kitematic (1) geospacial (1) yeshua (1) data (1) sonarqube (1) Axios (1) pipelines (1) Mozilla (1) kvm (1) GitOps (1) sqlite (1) podcast (1) n8n (1) LaravelFilament (1) God (1) DesenvolvimentoProfissional (1) sw (1) bigtech (1) postgres (1) NoCookies (1) LeetCode (1) governancadedados (1) prf (1) nosql (1) Lideranca (1) Hackers (1) Bots (1) pytorch (1) nuxt (1) liquid (1) ec2 (1) transaction (1) c4 (1) rancher (1) algoritimo (1) Observability (1) Elasticsearch (1) translate (1) certbot (1) Oh My Zsh (1) ibm (1) escopos (1) usb (1) ckeditor (1) API_KEY_GOOGLE_MAPS (1) Manjaro (1) vicuna (1) coding (1) rust (1) markdown (1) JasperReports (1) Fibonacci (1) community (1) Samurai (1) payment (1) messaging (1) Jesus (1) flutter (1) militar (1) fullsta (1) smartphones (1) automacao (1) Monitor (1) zend (1) spaceship (1) PKCE (1) l2tp (1) Glacier (1) laraveloctane (1) Deus (1) binaural (1) gpt (1) bolsonaro (1) privacidade (1) linkedin (1) documentation (1) brain (1) adb (1) nvidia (1) host (1) ecommerce (1) c4-models (1) altadisponibilidade (1) octane (1) lucena (1) http (1) TypeScript (1) chatgpt (1) idiomas (1) eventdrive (1) uuid (1) restfull (1) aplicativo (1) optimization (1) mapas (1) Fetch (1) collections (1) RustLang (1) matematica (1) Filament (1) compactar (1) paypal (1) microg (1) forcas armadas (1) cor (1) auth (1) modelagemdedados (1) k8s (1) gasolina (1) wsl2 (1) csv (1) soap (1) piada (1) KubeCon (1) zorin-os (1) spring-boot (1) backup (1) playwright (1) Deepin (1) storage (1) benchmark (1) networking (1) Swoole (1) biologia (1) node-red (1) LETSENCRYPT (1) Grunt (1) Diagramas (1) boot (1) haru (1) dracula (1) TrabalhoEmEquipe (1) Brasil (1) queue (1) agi (1) llama (1) hotfix (1) economia (1) transcription (1) cache (1) Amazon (1) October (1) lumen (1) Hyperf (1) replication (1) faceapp (1) vala (1) cloudstack (1) rpi (1) apple (1) oracle (1) iode (1) ffaa (1) vpn (1) MeioAmbiente (1) firefox (1) composer (1) scheduling (1) Asahi (1) pendrive (1) microservice (1) front (1) OOD (0) controllers (0)

New Articles



Get Latest Updates by Email