Skip to content

Repository files navigation

Cron Manager

Interface web para ver, criar, editar, excluir e executar entradas do crontab do usuário do sistema.

Tela do Cron Manager

Aviso

A aplicação executa comandos shell com os privilégios do usuário que roda o processo. Quem tem acesso a ela tem acesso ao shell do servidor. Não a exponha sem login, sem HTTPS e sem restringir os IPs de origem.

Requisitos

  • Python 3.8 ou superior
  • Node.js (apenas para reconstruir o CSS do Tailwind)
  • Um sistema com o binário crontab (Linux). Em Windows, use CRONTAB_BACKEND=file para desenvolvimento.

Instalação

python3 -m pip install -r requirements.txt
python3 manage.py migrate
python3 manage.py createsuperuser

Configuração

Toda a configuração vem de variáveis de ambiente. O arquivo .env.example documenta cada uma. Ele não é carregado automaticamente — aponte para ele com EnvironmentFile= na unit do systemd, ou exporte as variáveis na sua sessão.

Variável Padrão Descrição
SECRET_KEY Obrigatória quando DEBUG=False.
DEBUG False Nunca True em servidor exposto.
ALLOWED_HOSTS vazio Hosts aceitos, separados por vírgula.
CSRF_TRUSTED_ORIGINS vazio Origens aceitas, separadas por vírgula.
ALLOWED_IPS vazio IPs ou faixas CIDR que podem acessar. Vazia com DEBUG=False bloqueia tudo.
TRUSTED_PROXY_COUNT 0 Proxies reversos à frente. 0 ignora X-Forwarded-For.
TRUSTED_PROXIES vazio IPs/faixas dos proxies autorizados a preencher X-Forwarded-For. Vazia = header sempre ignorado, mesmo com TRUSTED_PROXY_COUNT > 0.
CRONTAB_BACKEND system system usa crontab -l/crontab -; file usa CRONTAB_FILE.
CRONTAB_FILE Caminho do arquivo quando o backend é file.
CRONTAB_BACKUP_DIR backups/ Onde as cópias do crontab são gravadas.
CRONTAB_BACKUP_KEEP 20 Quantas cópias manter. 0 mantém todas.
CRON_RUN_TIMEOUT 30 Segundos até abortar a execução manual de um job.

Rotação da SECRET_KEY

A chave que estava versionada neste repositório permanece no histórico do git e deve ser considerada comprometida. Gere uma nova e coloque-a no ambiente:

python3 manage.py generate_secret_key

Trocar a chave invalida todas as sessões, obrigando novo login.

Desenvolvimento

Em Windows não existe crontab. Aponte o backend para um arquivo:

set DEBUG=1
set CRONTAB_BACKEND=file
set CRONTAB_FILE=.\dev-crontab.txt
python manage.py runserver

Reconstruir o CSS depois de mexer em classes do Tailwind:

npm run dev

Testes

python3 manage.py test core -v 2

A suíte usa o backend de arquivo e não depende do binário crontab, então roda em qualquer sistema operacional.

Deploy

runserver não é servidor de produção. Rode com gunicorn atrás de um nginx com HTTPS, e com TRUSTED_PROXY_COUNT=1 para que a allowlist enxergue o IP real do cliente. Bloqueio de força bruta no login fica por conta do fail2ban ou do CSF — a aplicação não faz esse controle.

Gunicorn deve escutar só em loopback (127.0.0.1 ou socket Unix) — nunca em 0.0.0.0. Se o processo do gunicorn for alcançável diretamente, sem passar pelo nginx, um atacante pode forjar o header X-Forwarded-For e tentar burlar a allowlist de IP. TRUSTED_PROXY_COUNT sozinho não impede isso: é preciso também configurar TRUSTED_PROXIES (ver tabela acima e .env.example) com o endereço do próprio nginx — tipicamente 127.0.0.1, se colocado no mesmo host da aplicação. Com TRUSTED_PROXIES vazia, o header é sempre ignorado, mesmo com TRUSTED_PROXY_COUNT configurado.

SECURE_SSL_REDIRECT fica True por padrão quando DEBUG=False. O Django só enxerga a requisição original como https quando o nginx manda o header X-Forwarded-Proto. Se esse header não for configurado, toda requisição chega como http aos olhos do Django, que redireciona para https; o nginx reencaminha para o gunicorn de novo como http; e o resultado é um loop infinito de redirecionamento. A checagem de Referer do CSRF também depende desse header estar correto. Não pule essa configuração.

Exemplo: systemd + nginx

Unit do systemd (/etc/systemd/system/cron-manager.service), apontando para o .env com EnvironmentFile= e o gunicorn preso em loopback:

[Unit]
Description=Cron Manager
After=network.target

[Service]
User=cron-manager
WorkingDirectory=/opt/cron-manager
EnvironmentFile=/opt/cron-manager/.env
ExecStart=/opt/cron-manager/venv/bin/gunicorn \
    --bind 127.0.0.1:8000 \
    --workers 3 \
    cron_manager.wsgi:application
Restart=on-failure

[Install]
WantedBy=multi-user.target

Bloco location do nginx, encaminhando para o gunicorn com os headers que a aplicação precisa para funcionar corretamente (X-Forwarded-Proto evita o loop de redirecionamento acima; X-Forwarded-For alimenta a allowlist de IP, desde que TRUSTED_PROXIES inclua o IP do próprio nginx):

location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Comandos customizados

Gerar chave secreta

python3 manage.py generate_secret_key

Formatar arquivos .py, .html, .js e .css

python3 manage.py format_code

About

Painel para gerenciar crontab.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages