Created Instalação em servidor de Produção (markdown)

master
Leandro Roberto Silva 7 years ago
parent
commit
d792747045
  1. 956
      Instalação-em-servidor-de-Produção.md

956
Instalação-em-servidor-de-Produção.md

@ -0,0 +1,956 @@
Instalação em servidor de Produção
==================================
**Atualizado em:** 01/03/2019
--------------------------------------------------------------------------------
Trata-se de um exemplo para configuração de um servidor de produção para o **SAPL**.
Requisitos de Hardware
----------------------
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
Sistema operacional
-------------------
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
```
Configuração do sistema
-----------------------
### Atualização
Após a instalação do SO e a configuração da rede, atualize o sistema.
```
sudo apt update
sudo apt upgrade
```
### Editor de texto
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
```
### Unzip
O utilitário `unzip` deve ser instalado para realizar a extração de pacotes `.zip` se necessário.
```
sudo apt install unzip
```
### HTOP
Instale o `htop` para monitorar sistema operacioal, seus processos, etc.
```
sudo apt install htop
htop
```
### Timezone
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
```
### Locale
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
```
### Ntpdate
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
```
Segurança
---------
### Fail2ban
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](https://www.fail2ban.org/wiki/index.php/Main_Page)
### Firewall
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
```
SAPL
----
### Usuário
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
```
### Git
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
```
### Outras Dependências
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
```
### PostgreSQL
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
```
#### Base de Dados
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.
### Virtualenvwrapper
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
```
### Projeto
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
```
### Ambiente Virtual
Criar o ambiente virtual e instalar as dependecias da aplicação:
```
mkvirtualenv -a /var/intelegis/sapl -p python3 -r requirements/requirements.txt sapl
```
### Configuração do SAPL
Criar o arquivo `sapl/.env`:
```
vim sapl/.env
```
Inserir o seguinte conteúdo (Atenção na segunda linha SECRTE_KEY):
```env
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/
```
### SOLR
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
```
### Let's Encrypt
+ [https://letsencrypt.org/](https://letsencrypt.org/)
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/](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
```
### Nginx
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
```
#### VHost padrão
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
```
```nginx
#
### 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;
###
}
```
#### VHost sapl
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:
```nginx
#
## 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
```
```nginx
#
## 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
```
### Supervisor
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.
Loading…
Cancel
Save