
Esta é provavelmente uma pergunta bastante novata, mas ...
Estou no Ubuntu 18.04.3 LTS e tenho umVPNque desejo usar para alguns aplicativos. eu verifiqueinamespaced-openvpn
e funciona! A ressalva é que não consigo me conectar a este aplicativo localmente (para fins de gerenciamento).
Existe uma maneira de encaminhar uma determinada porta dentro do túnel VPN para o host local?sem que o túnel VPN o utilize para quaisquer outros fins e, assim, vaze muitas informações?
O que já sou capaz de fazer:
- correr
namespaced-openvpn
-roteiro:sudo ./namespaced-openvpn --namespace vpn --config /etc/openvpn/vpn-xxxxx.ovpn
- execute o aplicativo dentro do namespace da rede:
sudo ip netns exec vpn application
O que eu quero alcançar:
- conecte-se ao aplicativo iniciado dentro do túnel VPN (por exemplo, porta
1234
) a partir do localhost real (enp3s0
adaptador Ethernet) - encaminhar esta porta de uma forma que me permita acessá-la de meus outros computadores na minha LAN
Responder1
Muitos anos atrasados, mas caso alguém se depare com isso, como eu gostaria de ter feito nos últimos dias ou mais.
Espero que ajude alguém.
Primeiro, aqui está o namespaced-vpn, que realiza 90% do trabalho de fazer tudo funcionar.
https://github.com/slingamn/namespaced-openvpn
E aqui está uma resposta para uma pergunta quase exatamente como esta que me ajudou muito, embora eu não entendesse o que e por que as coisas estavam sendo feitas. https://unix.stackexchange.com/questions/391193/how-to-forward-traffic-between-linux-network-namespaces
Tentarei explicar o que entendi depois de muitas tentativas e erros, usando as informações que encontrei em minhas pesquisas.
A parte mais relevante para encaminhar conexões para o seu serviço (não do PC em que o serviço está sendo executado), acredito, é esta (observe o ponto de exclamação após PREROUTING):
iptables -t nat -A PREROUTING ! -s 10.0.0.0/24 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.2
Onde, 10.0.0.0/24
representa os intervalos de IP que você NÃO QUER que sejam atribuídos.
Isso ocorre principalmente para evitar um loop de roteamento, onde qualquer serviço acessível usando 10.0.0.0/24
a sub-rede é roteado de volta para si mesmo.
--dport 80 serve apenas para encaminhar pacotes que buscam a porta 80, ou seja, uma conexão de servidor web.
10.0.0.2
é a interface veth que foi movida DENTRO do namespace que seu servidor está executando.
Isso faz com que os pacotes que chegam, NÃO da 10.0.0.0/24
sub-rede, que buscam o serviço da porta 80, tenham seu IP de destino traduzido para 10.0.0.2
. Exemplo: 192.168.1.200:80
torna-se 10.0.0.2:80
presumivelmente a interface dentro do namespace em que seu servidor reside.
Tenho vários túneis VPN em funcionamento em vários namespaces. Se eu não adicionar a regra PREROUTING ao meu iptables, não poderei acessar o recurso de fora do meu PC na minha LAN.
Se você quiser acessá-lo a partir do seu próprio PC, você deve adicionar uma regra como:
iptables --table nat --append OUTPUT --destination 192.168.1.2 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.2
Então, se você digitar no navegador, no PC o servidor está ligado, 192.168.1.2
para acessar o seu servidor, ele será roteado 10.0.0.2
.
Vou tentar explicar um pedaço da minha configuração ...
Exemplo de espaço para nome:ip netns add ns_example
Crie o primeiro par. Um lado permanecerá no namespace raiz/normal (eu chamo isso host
), o outro lado irá para o namespace com VPN.
ip link add dev ihost type veth peer name ivpn
Mova o lado VPN do par veth para o namespace de destino:
ip link set dev ivpn netns ns_example
Atribua ips ao par veth que você criou.
Eu uso /32 porque quero atribuir apenas esse IP exato e não um intervalo. Caso contrário, quando eu ativo os dispositivos, algumas rotas são inseridas automaticamente na minha ip route
tabela e isso atrapalha meu roteamento para meus outros namespaces.
Para atribuir ao lado do host.
ip addr add 10.0.0.1/32 dev ihost
Para atribuir ao lado VPN, que foi movido para o namespace, você deve prefixar o comando com ..
ip netns exec TARGET_NAMESPACE
Então, para atribuir ip ao lado VPN:
ip netns exec ns_example ip addr add 10.0.0.2/32 dev ivpn
Agora traga as interfaces.
ip link set dev ihost up
ip netns exec ns_example ip link set dev ivpn up
Aqui adiciono rotas e iptables para fazer o tráfego fluir entre eles.
No namespace raiz, para chegar ao lado da VPN ( 10.0.0.2
), use a interface ihost e reescreva o endereço de origem no lado do namespace raiz ( 10.0.0.1
).
ip route add 10.0.0.2/32 dev ihost src 10.0.0.1
Faça exatamente a mesma coisa, mas de uma perspectiva oposta dentro do namespace VPN.
ip netns exec ns_example ip route add 10.0.0.1/32 dev ivpn src 10.0.0.2
Agora, adiciono as mesmas operações às iptables
quais estou separado, ip route
mas realizo tarefas semelhantes.
Qualquer pacote enviado 10.0.0.2
terá seu endereço de origem reescrito para10.0.0.1
iptables --table nat --append POSTROUTING --destination 10.0.0.2/32 --jump SNAT --to-source 10.0.0.1
Exatamente a mesma coisa, mas perspectiva oposta e dentro do namespace.
ip netns exec ns_example iptables --table nat --append POSTROUTING --destination 10.0.0.1/32 --jump SNAT --to-source 10.0.0.2
Se bem entendi, as reescritas do endereço de origem são apenas para garantir que o pacote saiba como sair do namespace e vice-versa.
Agora, por exemplo: para acessar um webui torrent no namespace na porta 8080, eu faço isso.
Qualquer pacote indo para o ip da minha LAN (Exemplo: eu digito 192.168.1.2:8080
no navegador). Ele reescreverá o destino no namespace que meu cliente de torrent está executando (Exemplo 10.0.0.2
:).
iptables --table nat --append OUTPUT --destination 192.168.1.2/32 --protocol tcp --match tcp --dport 8080 --jump DNAT --to-destination 10.0.0.2
Esta regra encaminha especificamente apenas a porta 8080 e serve para você acessar o serviço NO PC em que o serviço está sendo executado. Qualquer outro PC com acesso à rede 192.168.1.2:8080
precisa da regra PREROUTING que mencionei no início da resposta (basta alterar --dport 80 para --dport 8080 ou qualquer porta/protocolo que você precisar).
Para pessoas que usam este método e script namespaced-vpn.py. Você pode ter problemas se precisar redefinir sua VPN. A VPN com namespace lança uma exceção quando detecta interfaces dentro do namespace de destino que não seja a lo
interface de loopback.
Aqui está a parte que lança exceções para mim quando uso namespaced-vpn.py quando meu namespace de destino já existe e tem meus pares veth.
if os.path.exists(os.path.join('/var/run/netns', namespace)):
adapters = _adapter_names(namespace)
if adapters != [b'lo']:
LOG.error('Namespace %s already has adapters %s, exiting.' % (namespace, adapters))
raise Exception
Aqui está um exemplo de modificação que usei.
allowed_adapters = [b'lo', b'ivpn']
if os.path.exists(os.path.join('/var/run/netns', namespace)):
adapters = _adapter_names(namespace)
# Iterate and ensure all are in allowed list
for a in adapters:
if not a.split(b'@')[0] in allowed_adapters:
LOG.error('Namespace %s has non-whitelisted adapters %s, exiting.' % (namespace, adapters))
raise Exception
Apenas certifique-se de adicionar uma chamada como esta para cada interface que você espera que já exista na parte inferior da função `def setup_namespace(namespace)`. substitua LO pelo nome do dispositivo
subprocess.check_call(_enter_namespace_cmd(namespace) + [IP_CMD, 'link', 'set', 'LO', 'up'])
Exemplo:
subprocess.check_call(_enter_namespace_cmd(namespace) + [IP_CMD, 'link', 'set', 'ivpn', 'up'])
Para pessoas que executam um cliente bittorrent conectado à interface VPN, você pode se deparar com o problema de seu cliente travar conexões aleatoriamente por qualquer motivo. Por exemplo, você acorda de manhã e vê que todos os seus lindos downloads foram congelados 10 minutos depois de você sair.
Acredito que esse problema se deva ao software VPN IE openvpn, reconectando-se ao provedor VPN por qualquer motivo (erro, reinicialização de ping, etc.) e recebendo um novo endereço IP. A interface VPN pode precisar ser colocada off-line por uma fração de segundo para redefinir a configuração e isso causa falhas no cliente (qBittorrent faz isso com certeza). Uma "correção" que comecei a pesquisar é escrever um script que detecte quando a interface VPN recebe um novo endereço IP ou fica off-line por qualquer motivo. O script deve normalmente (importante: elegante para evitar corromper algo/erro do sistema de arquivos) sair do cliente torrent e reiniciá-lo. Ainda não tenho um script funcional, mas parece ser um vetor decente para resolver esse problema.
Responder2
OK. Parece que esta pergunta é muito complicada para alguém responder ou talvez já tenha sido respondida antes e ninguém se importou em responder.
De qualquer forma: trabalhei nisso por outro dia e percebi que, como estou interessado apenas em expor uma porta para a interface web de um aplicativo, posso também usarsocat
. Então eu fiz.
Depois de criar a conexão namespaced-openvpn e iniciar o aplicativo dentro desse namespace de rede, executei o seguinte comando em um terminal dedicado:
sudo socat tcp-listen:PORT-TO-FORWARD-TO,fork,reuseaddr exec:'ip netns exec vpn socat STDIO tcp-connect\:127.0.0.1\:PORT-TO-LISTEN-TO',nofork
Notas:
PORT-TO-FORWARD-TO
é a porta para a qual desejo que a porta seja encaminhada (no namespace da rede raiz)PORT-TO-LISTEN-TO
é a porta do aplicativo que desejo expor no namespace raiz127.0.0.1
Eu tive que usar o localhost-IP real (nãolocalhost
ou um nome, porque parece não ter sido resolvido corretamente)- certifique-se de escapar do caractere de ponto duplo (
:
) dentro das aspas simples - Não tenho certeza se isso causa vazamentos de DNS; pelo que verifiquei, não, mas não posso ter certeza, pois não sei como testá-lo
O que resta fazer:
- automatizar todos os comandos para iniciar a aplicação e encaminhar a porta na inicialização: não preciso disso atualmente, mas se/quando eu descobrir como fazer, adicionarei aqui