Existe uma maneira para processos não-root para vincular a portas “privilegiadas” sobre Linux?
-
03-07-2019 - |
Pergunta
É muito chato ter essa limitação na minha caixa de desenvolvimento, quando não será jamais qualquer outro usuário do que eu.
Estou ciente as soluções padrão , mas nenhum deles faz exatamente o que Eu quero:
- authbind (A versão em testes Debian, 1.0, suporta apenas IPv4)
- Usando o alvo iptables redireccionar para redireccionar uma porta baixa a uma porta alta (a tabela "nat" ainda não está implementado para ip6tables, a versão IPv6 do iptables)
- sudo (executado como root é o que eu estou tentando evitar)
- SELinux (ou similar). (Esta é apenas a minha caixa de dev, eu não quero introduzir um monte de complexidade extra.)
Existe alguma variável sysctl
simples para permitir que processos não-root para vincular a portas "privilegiadas" (portos inferior a 1024) no Linux, ou estou apenas fora de sorte?
EDIT: Em alguns casos, você pode capacidades de uso para fazer isso.
Solução
Ok, graças às pessoas que apontaram o sistema capacidades e capacidade CAP_NET_BIND_SERVICE
. Se você tem um kernel recente, é de facto possível usar isso para iniciar um serviço como portas baixas e não-raiz, mas bind. A resposta curta é que você faz:
setcap 'cap_net_bind_service=+ep' /path/to/program
E, em seguida, a qualquer hora program
é executado depois disso terá a capacidade CAP_NET_BIND_SERVICE
. setcap
está no libcap2-bin
pacote debian.
Agora, para as advertências:
- Você vai precisar de pelo menos um 2.6.24 do kernel
- Isso não vai funcionar se o arquivo é um script. (Ou seja, usa um #! Linha para lançar um intérprete). Neste caso, tanto eu como entender, você tem que aplicar a capacidade do próprio executável intérprete, que, naturalmente, é um pesadelo de segurança, uma vez que qualquer programa usando esse intérprete terá a capacidade. Eu não era capaz de encontrar qualquer maneira limpa, fácil de contornar este problema.
- Linux irá desativar LD_LIBRARY_PATH em qualquer
program
que possui elevados privilégios comosetcap
ousuid
. Portanto, se seuprogram
usa seu próprio.../lib/
, você pode ter que olhar para outra opção como o encaminhamento de porta.
Recursos:
- capacidades (7) página homem . Leia este longo e difícil se você estiver indo para usar recursos em um ambiente de produção. Existem alguns detalhes realmente complicadas de como as capacidades são herdadas através de exec () chamadas que são detalhadas aqui.
- setcap página homem
- "portas Bind abaixo de 1024 sem raiz no GNU / Linux" : O documento que primeiro apontou-me para
setcap
.
Outras dicas
A forma padrão é torná-los "setuid" para que eles começam-se como root, e então eles jogar fora esse privilégio raiz, logo que eles vinculado à porta, mas antes de começar a aceitar ligações a ele. Você pode ver bons exemplos de que no código fonte para o Apache eo INN. Disseram-me que Lighttpd é outro bom exemplo.
Outro exemplo é Postfix, que usa vários daemons que se comunicam através de tubos, e apenas um ou dois deles (que fazem muito pouco, exceto aceitar ou emite bytes) são executados como root eo resto corrida em um privilégio menor.
Você pode fazer um redirecionamento de portas. Isto é o que eu faço para um servidor de políticas Silverlight rodando em uma caixa de Linux
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300
Você pode configurar um túnel SSH local, por exemplo, se você quer a porta 80 para bater seu aplicativo vinculado a 3000:
sudo ssh $USERNAME@localhost -L 80:localhost:3000 -N
Isto tem a vantagem de trabalhar com servidores de script, e ser muito simples.
ou corrigir o seu kernel e remover a seleção.
(opção de último recurso, não recomendado).
Em net/ipv4/af_inet.c
, remova as duas linhas que ler
if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
goto out;
eo kernel não irá verificar portas privilegiadas mais.
recursos de arquivo não são ideais, porque eles podem quebrar após uma atualização do pacote.
A solução ideal, IMHO, deve ser uma capacidade de criar um escudo com o conjunto CAP_NET_BIND_SERVICE
hereditária.
Aqui está uma maneira um pouco complicado de fazer isso:
sg $DAEMONUSER "capsh --keep=1 --uid=`id -u $DAEMONUSER` \
--caps='cap_net_bind_service+pei' -- \
YOUR_COMMAND_GOES_HERE"
utilidade capsh
pode ser encontrado no pacote libcap2-bin em distribuições Debian / Ubuntu. Aqui está o que acontece:
-
sg
muda ID de grupo efetiva para o do usuário daemon. Isso é necessário porque as folhascapsh
GID inalterado e nós definitivamente não quero isso. - Conjuntos pouco 'capacidades de KEEP ON alteração UID'.
- Alterações UID para
$DAEMONUSER
- Drops todos os tampões (neste momento todas as tampas ainda estão presentes por causa da
--keep=1
), excetocap_net_bind_service
inheritable - Executa o comando ( '-' é um separador)
O resultado é um processo com o utilizador especificado e em grupo, e privilégios cap_net_bind_service
.
Como um exemplo, uma linha de roteiro ejabberd
arranque:
sg $EJABBERDUSER "capsh --keep=1 --uid=`id -u $EJABBERDUSER` --caps='cap_net_bind_service+pei' -- $EJABBERD --noshell -detached"
Duas possibilidades outra simples:
Não é uma solução de idade (fora de moda) para o "um daemon que se liga em uma porta baixa e mãos controlar a seu daemon". É chamado inetd (ou xinetd). Os contras são:
- suas necessidades daemon para falar sobre stdin / stdout (se você não controlar o daemon - se você não tem o código-fonte - então este é talvez um desmancha-prazeres, embora alguns serviços podem ter uma bandeira inetd-compatibilidade )
- um novo processo daemon é bifurcada para cada conexão
- É uma ligação extra na cadeia
Pros:
- disponível em qualquer idade UNIX
- Uma vez que seu sysadmin criou a configuração, você está pronto para ir sobre o seu desenvolvimento (quando você re-construir o seu daemon, você pode perder capacidades setcap? E então você vai ter que voltar para o seu admin "por favor senhor ... ")
- daemon não precisa se preocupar com esse material em rede, só tem que falar em stdin / stdout
- pode configurar para executar o seu daemon como um usuário não-root, conforme solicitado
Outra alternativa: um proxy hackeado-up (netcat ou mesmo algo mais robusto ) a partir do porto privilégio de alguns porta arbitrária numeradas de alta onde você pode executar o seu daemon alvo. (Netcat não é, obviamente, uma solução de produção, mas "apenas a minha caixa de dev", certo?). Desta forma, você pode continuar a usar uma versão com capacidade de rede do seu servidor, só precisa de root / sudo para iniciar proxy (na inicialização), não estaria contando com capacidades complexas / potencialmente frágeis.
As minhas aplicações "Solução padrão" socat como o redirecionador de espaço do usuário:
socat tcp6-listen:80,fork tcp6:8080
Tenha em atenção que este não escala, bifurcando-se é caro, mas é o caminho socat obras.
Atualização de 2017:
Use authbind
Muito melhor do que CAP_NET_BIND_SERVICE ou um kernel personalizado.
- CAP_NET_BIND_SERVICE concede confiança para o binário, mas não fornece
controlo sobre o acesso por porta.
-
Authbind concede confiança à de utilizador / grupo e proporciona controlo sobre o acesso por porta, e suporta tanto IPv4 e IPv6 (suporte IPv6 foi adicionado como de tarde).
-
Instale:
apt-get install authbind
-
Configurar o acesso aos portos relevantes, por exemplo, 80 e 443 para todos os usuários e grupos:
sudo touch / etc / authbind / byport / 80
sudo touch / etc / authbind / byport / 443
sudo chmod 777 / etc / authbind / byport / 80
sudo chmod 777 / etc / authbind / byport / 443
-
Executar o comando via
authbind
(Opcionalmente especificando--deep
ou outros argumentos, consulte a página do manual):authbind --deep /path/to/binary command line args
por exemplo.
authbind --deep java -jar SomeServer.jar
-
Como um follow-up para fabuloso (= não recomendado se você não sabe o que você faz) a recomendação de Joshua para cortar o kernel:
Eu primeiro postou aqui .
Simples. Com um kernel normal ou velho, você não.
Como apontado por outros, iptables pode encaminhar uma porta.
Como também apontado por outros, CAP_NET_BIND_SERVICE também pode fazer o trabalho.
Claro CAP_NET_BIND_SERVICE irá falhar se você lançar o seu programa a partir de um script, a menos que você defina o limite para o interpretador shell, que é inútil, você poderia muito bem executar o seu serviço como raiz ...
por exemplo. para Java, você tem que aplicá-lo à JAVA JVM
sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/lib/jvm/java-8-openjdk/jre/bin/java
Obviamente, isso significa que, em seguida, qualquer programa Java pode vincular as portas do sistema.
Dito de mono / NET.
Eu também tenho certeza que xinetd não é a melhor das idéias.
Mas desde que ambos os métodos são hacks, porque não basta levantar o limite levantando a restrição?
Ninguém disse que você tem que correr um kernel normal, assim você pode simplesmente executar o seu próprio.
Você acabou de baixar a fonte para o kernel mais recente (ou a mesma que você tem atualmente). Depois, acesse:
/usr/src/linux-<version_number>/include/net/sock.h:
Lá você olhar para esta linha
/* Sockets 0-1023 can't be bound to unless you are superuser */
#define PROT_SOCK 1024
e mude para
#define PROT_SOCK 0
Se você não quer ter uma situação ssh inseguro, você alterá-lo para isto: #define PROT_SOCK 24
Geralmente, eu uso a configuração mais baixa que você precisa, por exemplo 79 para http, ou 24 quando utilizar SMTP na porta 25.
Isso já é tudo.
Compilar o kernel, e instalá-lo.
Reinicialização.
Acabados -. Esse limite estúpido se foi, e que também trabalha para scripts
Veja como você compilar um kernel:
https://help.ubuntu.com/community/Kernel/Compile
# You can get the kernel-source via package linux-source, no manual download required
apt-get install linux-source fakeroot
mkdir ~/src
cd ~/src
tar xjvf /usr/src/linux-source-<version>.tar.bz2
cd linux-source-<version>
# Apply the changes to PROT_SOCK define in /include/net/sock.h
# Copy the kernel config file you are currently using
cp -vi /boot/config-`uname -r` .config
# Install ncurses libary, if you want to run menuconfig
apt-get install libncurses5 libncurses5-dev
# Run menuconfig (optional)
make menuconfig
# Define the number of threads you wanna use when compiling (should be <number CPU cores> - 1), e.g. for quad-core
export CONCURRENCY_LEVEL=3
# Now compile the custom kernel
fakeroot make-kpkg --initrd --append-to-version=custom kernel-image kernel-headers
# And wait a long long time
cd ..
Em poucas palavras, use iptables se você quiser ficar seguro, compilar o kernel se você quiser ter certeza que esta restrição não incomoda-lo novamente.
O Linux suporta capacidades para apoiar mais permissões de grão fino do que apenas "esta aplicação é executada como root". Um desses recursos é CAP_NET_BIND_SERVICE
que é de cerca de ligação a uma porta privilegiada (<1,024).
Infelizmente eu não sei como explorar isso para executar um aplicativo como não-root enquanto ainda dando-lhe CAP_NET_BIND_SERVICE
(provavelmente usando setcap
, mas não é obrigado a ser uma solução existente para isso).
Eu sei que isto é uma questão antiga, mas agora com a recente (> = 4.3) kernels há finalmente uma boa resposta para isso -. Capacidades ambientais
A resposta rápida é pegar uma cópia do mais recente (como-ainda-unreleased) versão do libcap a partir git e compilá-lo. Copie o progs/capsh
algum lugar binário resultante (/usr/local/bin
é uma boa escolha). Então, como root, inicie o seu programa com
/usr/local/bin/capsh --keep=1 --user='your-service-user-name' \
--inh='cap_net_bind_service' --addamb='cap_net_bind_service' \
-- -c 'your-program'
No fim, somos
- Declarando que quando alternar usuários, nós queremos manter os nossos conjuntos de capacidade de corrente
- Comutação de usuário e grupo para 'seu-service-user-name'
- Adicionando a capacidade
cap_net_bind_service
aos conjuntos hereditárias e ambientais - bifurcação
bash -c 'your-command'
(desdecapsh
inicia automaticamente festa com os argumentos depois--
)
Há muita coisa acontecendo sob o capô aqui.
Em primeiro lugar, estamos executando como root, então por padrão, temos um conjunto completo de recursos. Incluído neste é a capacidade de alternar uid e gid com as setuid
e setgid
syscalls. No entanto, normalmente quando um programa faz isso, perde seu conjunto de recursos - isso é para que a velha maneira de deixar cair raiz com setuid
ainda funciona. A bandeira --keep=1
diz capsh
para emitir o syscall prctl(PR_SET_KEEPCAPS)
, que desativa o lançamento de capacidades quando mudar de usuário. A mudança real de usuários por capsh
acontece com a bandeira --user
, que corre setuid
e setgid
.
O próximo problema que precisamos resolver é como capacidades definidas de forma que carrega depois que exec
nossos filhos. O sistema de recursos tem sempre tido um conjunto 'herdada' de capacidades, o qual é "um conjunto de capacidades preservadas através de um execve (2)" [ capacidades (7) ]. Enquanto isso soa como ele resolve o nosso problema (apenas definir a capacidade cap_net_bind_service
para herdada, certo?), Isso realmente só se aplica para os processos privilegiados - e nosso processo não é privilegiada mais, porque já mudou de usuário (com a bandeira --user
).
O novo conjunto de capacidades ambiente funciona em torno este problema - é "um conjunto de capacidades que são preservadas através de um execve (2) de um programa que não é privilegiada." Colocando cap_net_bind_service
no conjunto de ambiente, quando capsh
exec é o nosso programa de servidor, o nosso programa vai herdar esta capacidade e ser capaz de ouvintes ligam a portas baixas.
Se você está interessado em aprender mais, as capacidades página de manual explica isso em grande detalhe. Correndo capsh
através strace
também é muito informativo!
TLDR:. Para "a resposta" (a meu ver), pular para a >> TLDR << parte nesta resposta ??em>
OK, eu descobri-lo (para esse tempo real), a resposta a esta pergunta, e esta resposta da mina é também uma forma de pedir desculpas para a promoção outra resposta (tanto aqui como no twitter) que eu pensei que era 'o melhor', mas depois de tentar, descobri que eu estava enganado sobre isso. Aprender com o meu erro crianças: não promover algo até que você realmente tentou fazê-lo-se
Mais uma vez, eu revi todas as respostas aqui. Eu tentei alguns deles (e optou por não tentar outros, porque eu simplesmente não gostava das soluções). Eu pensei que a solução foi usar systemd
com suas configurações Capabilities=
e CapabilitiesBindingSet=
. Depois de lutar com isso por algum tempo, descobri que essa não é a solução porque:
Recursos são destinados para restringir os processos de raiz!
Como o OP sabiamente afirmou, é sempre melhor para evitar que (para todos os seus daemons se possível!).
Você não pode usar os recursos de opções com User=
e Group=
em arquivos de unidades systemd
relacionados, porque capacidades são Sempre reposto quando execev
(ou qualquer que seja a função é) é chamado. Em outras palavras, quando garfos systemd
e deixa cair os seus perms, os recursos são repostas. Não há maneira de contornar isso, e tudo o que a lógica de ligação no kernel é de cerca básica uid = 0, não capacidades. Isto significa que é improvável que Capacidades nunca vai ser a resposta certa para esta questão (pelo menos no curto prazo). Aliás, setcap
, como os outros, não é uma solução. Não funcionou para mim, ele não funciona muito bem com scripts, e aqueles são repostos de qualquer maneira sempre que as alterações de arquivo.
Na minha escassa defesa, eu fiz estado (no comentário Eu já eliminada), que James' iptables sugestão (que o OP também menciona), foi a "segunda melhor solução". :-P
>> TLDR <<
A solução é combinar systemd
com comandos iptables
on-the-fly, como este ( retirado DNSChain ):
[Unit]
Description=dnschain
After=network.target
Wants=namecoin.service
[Service]
ExecStart=/usr/local/bin/dnschain
Environment=DNSCHAIN_SYSD_VER=0.0.1
PermissionsStartOnly=true
ExecStartPre=/sbin/sysctl -w net.ipv4.ip_forward=1
ExecStartPre=-/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=-/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStartPre=/sbin/iptables -A INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=/sbin/iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStopPost=/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStopPost=/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
User=dns
Group=dns
Restart=always
RestartSec=5
WorkingDirectory=/home/dns
PrivateTmp=true
NoNewPrivileges=true
ReadOnlyDirectories=/etc
# Unfortunately, capabilities are basically worthless because they're designed to restrict root daemons. Instead, we use iptables to listen on privileged ports.
# Capabilities=cap_net_bind_service+pei
# SecureBits=keep-caps
[Install]
WantedBy=multi-user.target
Aqui nós realizar o seguinte:
- As escutas daemon em 5333, mas as conexões são aceitos com sucesso em 53, graças a
iptables
- Podemos incluir os comandos no próprio arquivo da unidade, e, assim, salvar as pessoas dores de cabeça. limpa
systemd
as regras de firewall para nós, certificando-se de removê-los quando o daemon não está em execução. - Nós nunca executado como root, e fazemos de privilégios impossíveis (pelo menos
systemd
reivindicações para), supostamente mesmo se o daemon está comprometido e conjuntosuid=0
.
iptables
ainda é, infelizmente, muito um utilitário feio e difícil de usar. Se o daemon está escutando eth0:0
vez de eth0
, por exemplo, os comandos são ligeiramente diferente .
systemd é um substituto sysvinit que tem uma opção para lançar um daemon com capacidades específicas . Opções Capacidades =, = CapabilityBoundingSet em systemd.exec (5) de manual.
Port redirecionamento fez mais sentido para nós, mas nós funcionamos em um problema onde nossa aplicação iria resolver um url localmente que também precisava ser re-roteados; (Isso significa que você baile ).
Isso também irá permitir que você seja redirecionado ao acessar a url na máquina local.
iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -A OUTPUT -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
Por alguma razão, ninguém menção sobre a redução sysctl net.ipv4.ip_unprivileged_port_start ao valor que você precisa. Exemplo:. Precisamos ligar o nosso app para 443 port
sysctl net.ipv4.ip_unprivileged_port_start=443
Alguns podem dizer, há um potencial problema de segurança: usuários sem privilégios agora podem ligar para os outros portos privilegiados (444-1024). Mas você pode resolver este problema facilmente com iptables, bloqueando outras portas:
iptables -I INPUT -p tcp --dport 444:1024 -j DROP
iptables -I INPUT -p udp --dport 444:1024 -j DROP
A comparação com outros métodos. Este método:
- de algum ponto é (IMO) ainda mais seguro do que a criação CAP_NET_BIND_SERVICE / Setuid, já que um aplicativo não setuid em tudo, mesmo parcialmente (capacidades realmente são). Por exemplo, para pegar um coredump de aplicativo habilitado para capacidade você precisará fs.suid_dumpable mudança sysctl (que leva a outra potenciais problemas de segurança) Além disso, quando CAP / suid está definido, / proc diretório / PID é propriedade de raiz, para que o seu usuário não-root não terá informações completas / controle do processo em execução, por exemplo, o usuário não será capaz (no caso comum) para determinar quais conexões pertencem a aplicação via / proc / PID / fd /. (-aptn netstat | grep PID)
- tem desvantagem de segurança: enquanto seu aplicativo (ou qualquer aplicativo que usa as portas 443-1024) é baixo, por algum motivo, um outro aplicativo poderia tomar o porto. Mas este problema também poderia ser aplicada a CAP / suid (no caso de você colocou sobre intérprete, por exemplo java / nodejs) e iptables-redirect. Use o método-socket systemd para excluir este problema. Use método authbind para permitir apenas a ligação de usuário especial.
- não requer configuração CAP / suid cada vez que você implantar nova versão do aplicativo.
- não requer suporte application / modificação, como método systemd-socket.
- não requer núcleo reconstruir (se a versão em execução suporta essa configuração sysctl)
- não faz LD_PRELOAD como authbind método / privbind, isso poderia afetar o desempenho, a segurança, o comportamento (não é? Não testei). No authbind resto é método muito flexível e seguro.
- over-executa iptables método de redirecionamento / DNAT, uma vez que não requer a tradução de endereços, rastreamento de estado da conexão, etc. Isso só perceptível em sistemas de alta carga.
Dependendo da situação, eu iria escolher entre sysctl, CAP, authbind e iptables-redirect. E isso é ótimo que temos tantas opções.
Na inicialização:
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
Em seguida, você pode ligar para a porta que você para frente.
Com systemd, você só precisa modificar ligeiramente o seu serviço para aceitar soquetes pré-ativadas.
Você pode usar mais tarde systemd tomada ativar .
Não capacidades, são necessários iptables ou outros truques.
Este é o conteúdo de arquivos Systemd relevantes a partir deste exemplo de simples python http servidor
httpd-true.service
Arquivo
[Unit]
Description=Httpd true
[Service]
ExecStart=/usr/local/bin/httpd-true
User=subsonic
PrivateTmp=yes
httpd-true.socket
Arquivo
[Unit]
Description=HTTPD true
[Socket]
ListenStream=80
[Install]
WantedBy=default.target
Há também o 'caminho djb'. Você pode usar esse método para iniciar o seu processo como root rodando em qualquer porto sob tcpserver, então ele vai entregar o controle do processo para o usuário especificado imediatamente após o processo começa.
#!/bin/sh
UID=`id -u yourusername`
GID=`id -g yourusername`
exec tcpserver -u $UID -g $GID -RHl0 0 portnumber /path/to/your/process &
Para obter mais informações, consulte: http://thedjbway.b0llix.net/daemontools/uidgid. html
Use a privbind utilidade :. que permite uma aplicação sem privilégios de se ligar a portas reservadas
Uma vez que o OP é apenas desenvolvimento / testes, menos do que as soluções elegantes pode ser útil:
setcap pode ser usado em intérprete de um script para conceder recursos para scripts. Se setcaps sobre o binário intérprete global não é aceitável, fazer uma cópia local do binário (qualquer usuário pode) e obter raiz para setcap sobre esta cópia. Python2 (pelo menos) funciona corretamente com uma cópia local do intérprete na sua árvore de desenvolvimento do roteiro. Sem suid é necessário para o usuário root pode controlar o que os usuários capacidades têm acesso.
Se você precisa acompanhar as atualizações de todo o sistema para o intérprete, use um script shell como o seguinte para executar o script:
#!/bin/sh
#
# Watch for updates to the Python2 interpreter
PRG=python_net_raw
PRG_ORIG=/usr/bin/python2.7
cmp $PRG_ORIG $PRG || {
echo ""
echo "***** $PRG_ORIG has been updated *****"
echo "Run the following commands to refresh $PRG:"
echo ""
echo " $ cp $PRG_ORIG $PRG"
echo " # setcap cap_net_raw+ep $PRG"
echo ""
exit
}
./$PRG $*
Eu tentei as iptables PREROUTING método de redirecionamento. Em kernels mais antigos parece que este tipo de regra não foi apoiada por IPv6 . Mas, aparentemente, é agora suportado em ip6tables v1.4.18 e Linux v3.8 kernel.
Eu também achei que PREROUTING REDIRECT não funciona para conexões iniciadas dentro da máquina. Para trabalho para conexões da máquina local, adicionar uma regra OUTPUT também - veja iptables porta redirecionamento não funciona para localhost . Por exemplo. algo como:
iptables -t nat -I OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080
Eu também achei que PREROUTING REDIRECT também afeta encaminhados . Ou seja, se a máquina também está encaminhando pacotes entre as interfaces (por exemplo, se ele está agindo como um ponto de acesso Wi-Fi conectado a uma rede Ethernet), então o iptables regra também vai pegar conexões dos clientes conectados para destinos de Internet, e redirecioná-los para a máquina. Isso não é o que eu queria-eu só queria redirecionar conexões que foram dirigidas à própria máquina. Eu descobri que eu posso fazer isso só afetam pacotes endereçados à caixa, adicionando -m addrtype --dst-type LOCAL
. Por exemplo. algo como:
iptables -A PREROUTING -t nat -p tcp --dport 80 -m addrtype --dst-type LOCAL -j REDIRECT --to-port 8080
Uma outra possibilidade é usar o encaminhamento de porta TCP. Por exemplo. usando socat
:
socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080
No entanto uma desvantagem com este método é, a aplicação que está a escutar a porta 8080, em seguida, não sabe o endereço da fonte de conexões de entrada (por exemplo, para outros fins de identificação ou log).
Resposta em 2015 / Sep:
ip6tables agora suporta IPV6 NAT: http: // www.netfilter.org/projects/iptables/files/changes-iptables-1.4.17.txt
Você vai precisar do kernel 3.7 +
Proof:
[09:09:23] root@X:~ ip6tables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REDIRECT tcp eth0 * ::/0 ::/0 tcp dpt:80 redir ports 8080
0 0 REDIRECT tcp eth0 * ::/0 ::/0 tcp dpt:443 redir ports 1443
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 6148 packets, 534K bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 6148 packets, 534K bytes)
pkts bytes target prot opt in out source destination