IP real do visitante
Toda requisição para um projeto HTTP público passa primeiro pela Zenifra, que cuida do HTTPS, da proteção contra DDoS e do roteamento até a sua aplicação. Por isso, o endereço da conexão que a aplicação recebe é um endereço interno da plataforma, não o de quem fez o acesso. O IP real do visitante chega em um cabeçalho HTTP.
Onde está o IP do visitante
| Origem | O que contém | Usar? |
|---|---|---|
Cabeçalho X-Real-IP | O IP do visitante, definido pela Zenifra | Sim |
Cabeçalho X-Forwarded-For | Uma lista de endereços. O último é o IP do visitante; os anteriores podem ter sido enviados pelo próprio visitante | Só o último item |
Endereço da conexão (req.socket.remoteAddress, REMOTE_ADDR) | Um endereço interno da plataforma, igual para todos os visitantes | Não |
A Zenifra sempre sobrescreve o X-Real-IP. Mesmo que o visitante envie esse cabeçalho com outro valor, a aplicação recebe o IP de onde a requisição veio de fato.
Não use o primeiro item do X-Forwarded-For
O visitante pode mandar o seu próprio X-Forwarded-For. A Zenifra mantém o que ele enviou e acrescenta o IP real no final:
X-Forwarded-For: 1.2.3.4, 203.0.113.10
X-Real-IP: 203.0.113.10Neste exemplo, 1.2.3.4 foi inventado pelo visitante e 203.0.113.10 é o IP real. Código que pega o primeiro item da lista pode ser enganado com um cabeçalho, o que quebra limites de requisição, bloqueios e registros de auditoria. Prefira o X-Real-IP.
Exemplos por linguagem
Em desenvolvimento local o cabeçalho não existe, por isso os exemplos usam o endereço da conexão como alternativa.
Node.js com Express
// Confia em um salto de proxy: o da Zenifra
app.set('trust proxy', 1)
app.get('/', (req, res) => {
res.send(`Seu IP: ${req.ip}`)
})Com trust proxy igual a 1, o req.ip usa o último item do X-Forwarded-For, que é o IP real. Não use trust proxy igual a true: nesse caso o Express usa o primeiro item, que o visitante pode inventar.
Node.js sem framework
const ip = req.headers['x-real-ip'] ?? req.socket.remoteAddressPython
# Flask
ip = request.headers.get('X-Real-IP', request.remote_addr)
# FastAPI
ip = request.headers.get('x-real-ip', request.client.host)
# Django
ip = request.META.get('HTTP_X_REAL_IP', request.META.get('REMOTE_ADDR'))PHP
$ip = $_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'];Go
ip := r.Header.Get("X-Real-IP")
if ip == "" {
ip, _, _ = net.SplitHostPort(r.RemoteAddr)
}HTTPS e porta originais
A aplicação recebe a requisição por uma conexão interna, mas a Zenifra informa como o visitante acessou:
X-Forwarded-Proto: https
X-Forwarded-Port: 443Assim como o X-Real-IP, esses valores são definidos pela Zenifra e não podem ser trocados pelo visitante. Com o proxy configurado como confiável, os frameworks reconhecem o acesso por HTTPS e geram URLs absolutas com https:// e cookies Secure:
- Express: com
app.set('trust proxy', 1),req.protocolvale'https'ereq.securevaletrue. - Django:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')fazrequest.is_secure()retornarTrue.
Boas práticas
- Guarde o IP como texto. Aceite IPv4 e IPv6, com até 45 caracteres.
- Use o IP em limites de requisição, logs e antifraude, sempre a partir do
X-Real-IP. - Não force HTTPS na aplicação. A Zenifra já redireciona
http://parahttps://antes de a requisição chegar. Opções comoSECURE_SSL_REDIRECTno Django,force_sslno Rails ou middlewares de redirecionamento podem criar um loop. - Para bloquear ou liberar IPs, prefira o controle de acesso por IP do console (a partir do plano Premium Plus). Ele usa o IP real do visitante e barra o acesso antes de chegar à aplicação.
- IP não é identidade. Várias pessoas podem dividir o mesmo IP, como em empresas e redes móveis. Mantenha login, tokens ou chaves de API nas rotas sensíveis.
Próximos passos
FAQ
Por que a minha aplicação mostra o mesmo IP para todos os visitantes?
Ela está lendo o endereço da conexão, que é interno da plataforma. Troque para o cabeçalho X-Real-IP, como nos exemplos acima.
O visitante consegue falsificar o X-Real-IP?
Não. A Zenifra substitui o valor enviado pelo visitante pelo IP de onde a requisição veio.
Funciona com domínio personalizado?
Sim. O cabeçalho chega da mesma forma no subdomínio da Zenifra e nos domínios personalizados.
Última atualização em
Rede e controle de acesso
Escolha entre projeto público ou privado, entenda o subdomínio da Zenifra e restrinja o acesso por IP com whitelist e blacklist em formato CIDR.
Domínios personalizados
Configure domínio raiz, subdomínios, CNAME, registros TXT de validação e HTTPS para apontar seu domínio próprio para uma aplicação na Zenifra.