-
Notifications
You must be signed in to change notification settings - Fork 80
Ambiente de Produção proposto por Franca São Paulo
Atualizado em: 01/03/2019
Trata-se de um exemplo para configuração de um servidor de produção para o SAPL.
Este exemplo roda em uma maquina virtual instalada em um cluster Proxmox com os seguintes recursos:
- 4GB memória RAM
- 4x CPU
- 64GB de Armazenamento
O sistema operacional utilizado para esse exemplo foi Ubuntu 18.04.1 LTS.
lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.1 LTS
Release: 18.04
Codename: bionic
Após a instalação do SO e a configuração da rede, atualize o sistema.
sudo apt update
sudo apt upgrade
Para melhorar as condições de trabalho quando houver necessidade de editar arquivos de texto no servidor, instale o editor de textos vim
.
sudo apt install vim
Para tornar o vim
o editor padrão do sistema execute o comando abaixo e em seguida escolha a opção referente ao vim
.
sudo update-alternatives --config editor
Por último, configure o vim
para exibir o número das linhas por padrão.
sudo vim /etc/vim/vimrc
Adicione as linhas abaixo no final do arquivo.
" Line number
set number
O utilitário unzip
deve ser instalado para realizar a extração de pacotes .zip
se necessário.
sudo apt install unzip
Instale o htop
para monitorar sistema operacioal, seus processos, etc.
sudo apt install htop
htop
A Timezone padrão do servidor deve ser modificada para a região em que estamos.
sudo dpkg-reconfigure tzdata
No menu escolha, por exemplo, America
e posteriormente Sao_Paulo
.
O arquivo /etc/timezone
exibe o fuzo horário escolhido com o comando anterior.
cat /etc/timezone
America/Sao_Paulo
Adicionado o idioma Português do Brasil e instale os pacotes de idiomas em português.
sudo dpkg-reconfigure locales
No menu, selecione as opções:
en_US.ISO-8859-1
en_US.UTF-8
pt_BR.ISO-8859-1
pt_BR.UTF-8
Escolha pt_BR.UTF-8
como opção padrão. O comando abaixo exibe a configuração:
locale -a
C
C.UTF-8
en_US
en_US.iso88591
en_US.utf8
POSIX
pt_BR
pt_BR.iso88591
pt_BR.utf8
Para que o servidor sincronize o seu horário, instale o utilitário ntpdate
e crie um script no diretório /etc/cron.hourly/
chamado ntp-time-sync
.
sudo apt install ntpdate
sudo vim /etc/cron.hourly/ntp-time-sync
O conteúdo do arquivo é exibido na saída do comando cat
.
cat /etc/cron.hourly/ntp-time-sync
#! /bin/sh
#
ntp=$(which ntpdate)
#
$ntp -s a.ntp.br
Conceda a permissão de execução para o script.
sudo chmod +x /etc/cron.hourly/ntp-time-sync
Para efeitos de teste você pode executar o script. A saída do script pode ser vista no log padrão do sistema em /var/log/syslog
.
sudo /etc/cron.hourly/ntp-time-sync
sudo tail -f /var/log/syslog
Para implementar um nível de segurança contra ataques de força bruta instale o software fail2ban
.
sudo apt install fail2ban
O arquivo de configuração /etc/fail2ban/jail.conf
deve copiado para outro arquivo, para que as configurações locais possam ser aplicadas, e, para não se perderem após a atualizações do sistema. Atualizações do sistema geralmente sobrescrevem aquivos de configuração do fail2ban
.
cd /etc/fail2ban
sudo cp jail.conf jail.d/local.conf
Por padrão o fail2ban
bloqueia tentativas de ataque de força bruta no servidor SSH.
Mais informações: https://www.fail2ban.org/wiki/index.php/Main_Page
Configure um firewall utilizando o ufw
, para implementar um pouco de segurança ao servidor.
sudo apt install ufw
Configure o firewall para impedir qualquer tentativa de conexão de entrada e permitir todas as conexões de saída como padrão.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw status verbose
Em seguida, libere as portas para permitir conexões SSH, HTTP e HTTPS.
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Por último habilite o firewall. Tenha certeza ter liberado as portas antes de habilitar o firewall.
sudo ufw status verbose
Tudo certo? Então habilite o firewall.
sudo ufw enable
Crie o usuário sob o qual irá rodar o servidor de aplicação:
sudo groupadd --system webapps
sudo useradd --system --gid webapps --shell /bin/bash --home /var/interlegis gunicorn
Instale o git
:
sudo apt install git
Configure as opções globais do git
:
git config --global user.name "Seu Nome"
git config --global user.email "seu@e-mail.sp.leg.br"
Para ver as configurações:
git config --list
Instalação:
sudo apt install pkg-config software-properties-common build-essential libxml2-dev libjpeg-dev libssl-dev libffi-dev libxslt1-dev curl poppler-utils antiword default-jre libpq-dev graphviz-dev graphviz python3-dev python-psycopg2 python3-setuptools python3-pip python3-venv
Instalação:
sudo apt install postgresql postgresql-contrib
Depois de instalado, altere a senha do administrador do postgresql
com o utilitário psql
.
sudo su postgres
psql
No shell do cliente do postgresql
(postgres=#
), rode o seguinte comando para alterar a senha do usuário postgres
:
postgres=# alter user postgres with password 'senha-do-postgresql';
Sair do psql
:
postges=# \q
Na sequência, altere o arquivo /etc/postgresql/10/main/pg_hba.conf
para permitir o uso do psql
por outros usuário além do usuário postgres
do sistema.
sudo vim /etc/postgresql/10/main/pg_hba.conf
A linha 85 do arquivo foi alterada.
local all postgres password
O serviço foi reiniciado.
sudo systemctl restart postgresql.service
Rode os seguintes comandos para criar a Base de Dados do SAPL:
sudo -u postgres psql -c "CREATE ROLE sapl LOGIN ENCRYPTED PASSWORD 'uma-senha' NOSUPERUSER INHERIT CREATEDB NOCREATEROLE NOREPLICATION;"
sudo -u postgres psql -c "ALTER ROLE sapl VALID UNTIL 'infinity';"
sudo -u postgres psql -c "CREATE DATABASE sapl WITH OWNER = sapl ENCODING = 'UTF8' TABLESPACE = pg_default LC_COLLATE = 'pt_BR.UTF-8' LC_CTYPE = 'pt_BR.UTF-8' CONNECTION LIMIT = -1 TEMPLATE template0;"
Utilize a senha-do-postgresql
criada anteriormente.
Instalação:
sudo pip3 install virtualenvwrapper
Diretório:
sudo mkdir -p /var/interlegis/.virtualenvs
sudo chown -R gunicorn:webapps /var/interlegis
Configuração:
sudo vim /etc/bash.bashrc
# Virtualenvwrapper
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
export WORKON_HOME=/var/interlegis/.virtualenvs
export PROJECT_HOME=/var/interlegis/
export VIRTUALENVWRAPPER_SCRIPT=/usr/local/bin/virtualenvwrapper.sh
source /usr/local/bin/virtualenvwrapper.sh
Logar com o usuário gunicorn
:
sudo su - gunicorn
Checar o diretório atual
pwd
/var/interlegis
Clonar o repositório do SAPL:
git clone -b 3.1.x --single-branch git@github.com:interlegis/sapl.git sapl
Criar o ambiente virtual e instalar as dependecias da aplicação:
mkvirtualenv -a /var/intelegis/sapl -p python3 -r requirements/requirements.txt sapl
Criar o arquivo sapl/.env
:
vim sapl/.env
Inserir o seguinte conteúdo (Atenção na segunda linha SECRTE_KEY):
DATABASE_URL = postgresql://sapl:uma-senha@localhost:5432/sapl
SECRET_KEY = '&*&*&-chave-gerada-com-o-comando-abaixo-*&*&*&*&*&'
DEBUG = False
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST = 'smtp.interlegis.leg.br'
EMAIL_HOST_USER = 'sapl@cidade.uf.leg.br'
EMAIL_SEND_USER = 'sapl@cidade.uf.leg.br'
EMAIL_HOST_PASSWORD = 'uma-senha'
Gerar a chave secreta e substituir no arquivo sapl/.env
:
python manage.py generate_secret_key
Gerar a base de dados:
./manage.py migrate
Gerar arquivos estáticos:
./manage.py collectstatic --no-input --clear
Copiar o arquivo que servirá para inicialização do sistema:
cp gunicorn-start.sh ../gunicorn-start.sh
A cópia desse arquivo é opcional. Dependendo que como você prefere iniciar o SAPL, será preciso promover ajustes nesse aquivo. Abaixo segue o arquivo com as mundanças necessárias para inicialização do SAPL nesse exemplo:
#!/bin/bash
# As seen in http://tutos.readthedocs.org/en/latest/source/ndg.html
SAPL_DIR="/var/interlegis/sapl"
# Seta um novo diretório foi passado como raiz para o SAPL
# caso esse tenha sido passado como parâmetro
if [ "$1" ]
then
SAPL_DIR="$1"
fi
NAME="SAPL" # Name of the application (*)
DJANGODIR=/var/interlegis/sapl/ # Django project directory (*)
SOCKFILE=/var/interlegis/sapl/run/gunicorn.sock # we will communicate using this unix socket (*)
USER=gunicorn # the user to run as (*)
GROUP=webapps # the group to run as (*)
NUM_WORKERS=9 # how many worker processes should Gunicorn spawn (*)
# NUM_WORKERS = 2 * CPUS + 1
TIMEOUT=60
MAX_REQUESTS=100 # number of requests before restarting worker
DJANGO_SETTINGS_MODULE=sapl.settings # which settings file should Django use (*)
DJANGO_WSGI_MODULE=sapl.wsgi # WSGI module name (*)
echo "Starting $NAME as gunicorn on base dir $SAPL_DIR"
# parameter can be passed to run without virtualenv
if [[ "$@" != "no-venv" ]]; then
# Activate the virtual environment
cd $DJANGODIR
source /var/interlegis/.virtualenvs/sapl/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
fi
# Create the run directory if it doesn't exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
# Start your Django Unicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--log-level debug \
--timeout $TIMEOUT \
--workers $NUM_WORKERS \
--max-requests $MAX_REQUESTS \
--user $USER \
--access-logfile /var/log/gunicorn/sapl-access.log \
--error-logfile /var/log/gunicorn/sapl-error.log \
--bind=unix:$SOCKFILE
Criar o diretório para os logs:
sudo mkdir -p /var/log/gunicorn/
sudo chown -R gunicorn\: /var/log/gunicorn/
Essa parte é opcional, mas vale a pena.
Baixar e executar o SOLR
:
cd /var/intelegis/sapl
curl -LO https://archive.apache.org/dist/lucene/solr/7.4.0/solr-7.4.0.tgz
tar xvzf solr-7.4.0.tgz
cd solr-7.4.0
./bin/solr start -c
O comando ./bin/solr start -c
deve ser executado novamente caso o servidor seja reiniciado.
Inserir as seguintes linhas no final do arquivo sapl/.env
.
USE_SOLR = True
SOLR_COLLECTION = 'sapl'
SOLR_URL = 'http://localhost:8983'
Criar a coleção sapl
no servidor solr
python solr_api.py -u http://localhost:8983 -c sapl -s 1 -rf 1 -ms 1
Criar o indice:
./manage.py rebuild_index
As páginas servidas pelo nginx
funcionam com o protocolo HTTPS, utilizando certificados emitidos pelo serviço de "CA", Autoridade Certificadora, Let's Encrypt.
Para que o processo de obtenção dos certificados funcione, antes de configurar os subdomínios é preciso instalar o certbot, que é recomendado na documentação de uso do Let's Encrypt https://letsencrypt.org/getting-started/.
sudo apt install certbot
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
O comando para renovar os certificados, que expiram a cada 3 meses, deve ser inserido no crontab.
sudo crontab -e
45 3 * * * certbot renew --quiet
Para instalar o Nginx no sistema operacional Ubuntu Server 18.04 foi utilizado o repositório padrão da distribuição, portanto:
sudo apt install nginx
Aproveitamos a funcionalidade de "VirtualHosts".
O arquivo default
localizado no diretório /etc/nginx/sites-available
, reposnável pelo "VirtualHosts" padrão do servidor nginx
deve ser alterado conforme segue:
cd /etc/nginx/sites-available
sudo cp default default.dist
sudo vim default
#
### default - server configuration
#
server {
### HTTP ###
##################################################################
# Port that the web server will listen on.
###
listen 80 default_server;
listen [::]:80 default_server;
###
##################################################################
# Host that will serve this project.
###
server_name _;
###
##################################################################
# The location of our projects public directory.
###
root /var/www/html;
###
##################################################################
# Point index to the app front controller.
###
index index.html index.htm index.nginx-debian.html;
###
##################################################################
# Useful logfor debug.
###
access_log /var/log/nginx/default.access.log;
error_log /var/log/nginx/default.error.log;
rewrite_log on;
###
##################################################################
# Redirect to sapl.municipio.uf.leg.br
###
return 301 https://sapl.municipio.uf.leg.br;
###
}
Copiar o diretório DocumentRoot
do Vhost padrão do nginx
:
sudo cp /var/www/html /var/www/sapl
sudo chown -R www-data\: /var/www/sapl
Criar o arquivo de configuração:
cd /etc/nginx/sites-available
sudo vim sapl.municipio.uf.leg.br.conf
Inicialmente o arquivo de configuração deve ser criado com o seguinte conteúdo:
#
## sapl.municipio.uf.leg.br - server configuration
#
server {
### HTTP ###
##################################################################
# Port that the web server will listen on.
###
listen 80;
listen [::]:80;
###
##################################################################
# Host that will serve this project.
###
server_name sapl.municipio.uf.leg.br;
###
##################################################################
# The location of our projects public directory.
###
root /var/www/sapl;
###
##################################################################
# Point index to the app front controller.
###
index index.html index.htm index.nginx-debian.html;
###
##################################################################
# Useful logs for debug.
###
access_log /var/log/nginx/sapl.municipio.uf.leg.br.access.log;
error_log /var/log/nginx/sapl.municipio.uf.leg.br.error.log;
rewrite_log on;
###
}
Assim, pode-se habilitar o Vhost sapl.municipio.uf.leg.br
:
sudo ln -s /etc/nginx/sites-available/sapl.municipio.uf.leg.br.conf /etc/nginx/sites-enabled/sapl.municipio.uf.leg.br.conf
Na sequência, após checar se está tudo certo com a configuração dos Vhosts no nginx
,
sudo nginx -t
o serviço deve ser reiniciado:
sudo systemctl restart nginx.service
Para obter o Certificado Let's Encrypt, rode o seguinte comando:
sudo certbot certonly --webroot -w /var/www/sapl -d sapl.municipio.uf.leg.br
Após a obtenção do certificado, altere a configuração do aquivo /etc/nginx/sites-available/sapl.municipio.uf.leg.br.conf
, para o seguinte conteúdo:
sudo vim /etc/nginx/sites-available/vim sapl.municipio.uf.leg.br.conf
#
## sapl.municipio.uf.leg.br - server configuration
#
upstream sapl.municipio.uf.leg.br {
server unix:/var/interlegis/sapl/run/gunicorn.sock fail_timeout=0;
}
server {
### HTTP ###
##################################################################
# Port that the web server will listen on.
###
listen 80;
listen [::]:80;
###
##################################################################
# Host that will serve this project.
###
server_name sapl.municipio.uf.leg.br;
###
##################################################################
# The location of our projects public directory.
###
root /var/www/sapl;
###
##################################################################
# Point index to the app front controller.
###
index index.html index.htm index.nginx-debian.html;
###
##################################################################
# Redirect to HTTPS
###
return 301 https://$server_name$request_uri;
###
##################################################################
# Useful logs for debug.
###
access_log /var/log/nginx/sapl.municipio.uf.leg.br.access.log;
error_log /var/log/nginx/sapl.municipio.uf.leg.br.error.log;
rewrite_log on;
###
}
server {
### HTTPS ###
##################################################################
# Port that the web server will listen on.
###
listen 443 ssl;
listen [::]:443 ssl;
###
##################################################################
# SSL configuration
###
ssl_certificate /etc/letsencrypt/live/sapl.municipio.uf.leg.br/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sapl.municipio.uf.leg.br/privkey.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
###
##################################################################
# Host that will serve this project.
###
server_name sapl.municipio.uf.leg.br;
###
##################################################################
# Redirect server error pages to the static page /50x.html
###
error_page 500 502 503 504 /500.html;
location = /500.html {
root /var/interlegis/sapl/sapl/static/;
}
###
##################################################################
# Point index to the app static files.
###
location /static/ {
alias /var/interlegis/sapl/sapl/collected_static/;
}
###
##################################################################
# Point index to the app media files.
###
location /media/ {
alias /var/interlegis/sapl/sapl/media/;
}
###
##################################################################
# URLs to attempt, including pretty ones.
###
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://sapl.municipio.uf.leg.br;
break;
}
}
###
##################################################################
# Max upload file size.
###
client_max_body_size 4M;
###
##################################################################
# Set header expirations
###
add_header Strict-Transport-Security "max-age=63072000";
###
##################################################################
# Security
###
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
###
##################################################################
# Useful logfor debug.
###
access_log /var/log/nginx/sapl.municipio.uf.leg.br.access.log;
error_log /var/log/nginx/sapl.municipio.uf.leg.br.error.log;
rewrite_log on;
###
##################################################################
# Compressing.
###
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
application/atom+xml
application/javascript
application/json
application/ld+json
application/manifest+json
application/rss+xml
application/vnd.geo+json
application/vnd.ms-fontobject
application/x-font-ttservidores.legislativo
application/x-web-appservidores.legislativoanifest+json
application/xhtml+xmlservidores.legislativo
application/xml
font/opentype
image/bmp
image/svg+xml
image/x-icon
text/cache-manifest
text/css
text/plain
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy;
###
}
Por fim, cheque se está tudo certo com a configuração dos Vhosts no nginx
,
sudo nginx -t
e reinicie o servidor:
sudo systemctl restart nginx.service
O supervisor
fará com que o gunicorn
seja executado de maneira automatica no servidor, mantendo o SAPL no ar mesmo que ocorram reinicializações do sistema operacional.
sudo apt install supervisor
cd /etc/supervisor/conf.d
sudo vim gunicorn.conf
[program:gunicorn]
command = /var/interlegis/gunicorn-start.sh
process_name=%(program_name)s
directory = /var/interlegis/sapl
user = gunicorn
stdout_logfile = /var/log/gunicorn/sapl-std.log
stderr_logfile = /var/log/gunicorn/sapl-err.log
Reinicie o Supervisor
sudo systemctl restart supervisor.service
Autoria: Getulio Vinicius Teixeira da Silva Câmara Municipal de Franca - São Paulo.