Tenho alguns hosts atrás de um roteador NAT que desejo acessar por meio de uma VPN wireguard. Consegui configurar a rede privada com sucesso, mas ainda há algo que me deixa perplexo.
Quero que cada colega:
- acessar uns aos outros (
172.9.9.*
) via VPN (viawg0
) - acessar todos os outros hosts fora da VPN (via
eth0
).
Aqui está um esquema da rede e configuração atual:
┌─────┐ ┌──────────┐ ┌─────┐
│ S ├────┤ Internet ├────┤ A │
└─────┘ └───┬──────┘ └─────┘
│
│
┌────┴─────┐
│ NAT DHCP │
┌──┤ Router ├──┐
│ └──────────┘ │
│ │
┌──┴──┐ ┌──┴──┐
│ X │ │ B │
└─────┘ └─────┘
S
é o servidor VPN e pode ser acessado na internet via IP estático;X
é um “servidor de computação”, pode acessar a internet, mas está atrás de um NAT e seu IP é dinâmico e não conhecido antecipadamente;A
é um "cliente remoto" ao qual deseja se conectarX
;B
é um "cliente local" ao qual deseja se conectarX
e está na mesma rede local.
Eu quero isso A
e B
posso me conectar X
através do S
, mas todos esses hosts devem usar a VPN somente quando entrarem em contato entre si e não quando acessarem a internet.
Assim, por exemplo, A
é possível executar ping em google.com diretamente, mas fará ping X
via S
.
Depois de pesquisar e ler documentações, ainda não está claro para mim se é possível fazer isso sem usar iptables
e se é possível usar apenas a configuração do wireguard.
A configuração atual é a seguinte:
## S wg0.conf
[Interface]
PrivateKey = S-private-key
Address = 172.9.9.1/24
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
[Peer]
# A
PublicKey = A-public-key
AllowedIPs = 172.9.9.100/32
[Peer]
# B
PublicKey = B-public-key
AllowedIPs = 172.9.9.101/32
[Peer]
# X
PublicKey = X-public-key
AllowedIPs = 172.9.9.10/32
# A wg0.conf
[Interface]
Address = 172.9.9.100/24
PrivateKey = A-private-key
DNS = 1.1.1.1
[Peer]
PublicKey = S-public-key
Endpoint = S-ip-address:51820
AllowedIPs = 0.0.0.0/0, ::/0
B
A configuração do é semelhante a A
, mas com IP 172.9.9.101
e chave privada diferente.
# X wg0.conf
[Interface]
Address = 172.9.9.10/24
PrivateKey = X-private-key
DNS = 1.1.1.1
[Peer]
PublicKey = S-public-key
Endpoint = S-ip-address:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25 # To keep the server reachable
Essa configuração funciona e todos os hosts podem acessar uns aos outros via VPN, mas quero que APENAS o tráfego direcionado aos hosts 172.9.9.*
passe por essa VPN. O outro tráfego será roteado pelo gateway padrão.
O que me intriga é que, se eu mudar a configuração de A
modo que
AllowedIPs = 172.9.9.0/24
então, para A
, os pacotes são roteados conforme pretendido (por exemplo, posso curl ifconfig.me
e recebo A
o IP público de ), mas se eu fizer o mesmo em X
, não funcionará e os pacotes que não funcionarem 172.9.9.0/24
não serão entregues.
EDITAR#1
Esqueci de mencionar que também adoraria se, ao conectar-me X
, os clientes locais como B
não enviassem pacotes para fora da rede local, então B -> Router -> X
e não B -> Router -> S -> Router -> X
.
Responder1
Defina AllowedIPs
os endereços IP que você desejarota para/através do par.
Em uma configuração hub-and-spoke normal, em seu (S) hub (S), você configuraria AllowedIPs
para cada par como você fez, roteando pacotes para cada par somente se eles usarem o endereço IP WireGuard do par como endereço de destino; e em seus spokes (A, B e X), você configuraria AllowedIPs
o CIDR da sua rede WireGuard ( 172.9.9.0/24
), roteando pacotes para o hub somente se eles usarem endereços IP WireGuard de outro par como endereço de destino.
Portanto, com uma configuração normal, você acessaria A de B ou X com o endereço IP WireGuard de A 172.9.9.100
, B de A ou X com 172.9.9.101
e X de A ou B com 172.9.9.10
.
Mas se você também quiser acessar cada spoke por meio do endereço IP vinculado à NIC física do spoke (por exemplo, eth0
), será necessário ajustar AllowedIPs
o hub e os spokes para incluir esses endereços IP.
Por exemplo, se o endereço de A eth0
for 198.51.100.65
, o de B for 192.168.0.66
e o de X for 192.168.0.88
, você ajustaria os pares na configuração do WireGuard do hub para isto:
## S wg0.conf
...
[Peer]
# A
PublicKey = A-public-key
AllowedIPs = 172.9.9.100/32
AllowedIPs = 198.51.100.65/32
[Peer]
# B
PublicKey = B-public-key
AllowedIPs = 172.9.9.101/32
AllowedIPs = 192.168.0.66/32
[Peer]
# X
PublicKey = X-public-key
AllowedIPs = 172.9.9.10/32
AllowedIPs = 192.168.0.88/32
E defina AllowedIPs
em cada configuração do spoke para isto:
AllowedIPs = 172.9.9.0/24
AllowedIPs = 198.51.100.65/32
AllowedIPs = 192.168.0.66/32
AllowedIPs = 192.168.0.88/32
(Observe que você também pode especificar todos os blocos em uma linha, como AllowedIPs = 172.9.9.0/24, 198.51.100.65/32, 192.168.0.66/32, 192.168.0.88/32
preferir.)
Com sua configuração atual, onde você está AllowedIPs = 0.0.0.0/0
em X, quando você executa curl 198.51.100.65
a partir de X, o que acontece é que X está roteando os pacotes destinados a A (e todo o resto) através de seu túnel WireGuard para S, e então S está roteando esses pacotes não criptografados. a Internet para A (mascarada com o endereço IP público do próprio S); em resposta, A envia pacotes não criptografados pela Internet para S, que S roteia através de seu túnel WireGuard para X.
Se você quiser ter certeza de que Snuncarotear pacotes encapsulados através de sua rede WireGuard para a Internet, você pode ajustar suas regras de iptables para evitar isso; algo como o seguinte provavelmente resolveria o problema:
PostUp = iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT; iptables -A FORWARD -i wg0 -o eth0 -j DROP; iptables -A FORWARD -i eth0 -o wg0 -j DROP
Responder2
Tive um problema com o DNS: o uso AllowedIPs = 172.9.9.0/24
me permitiu fazer ping 8.8.8.8
, mas não google.com
.
Resolvi incluir o DNS da interface nos IPs permitidos, assim consigo resolução de DNS via VPN, mas o tráfego não está na VPN:
[Interface]
...
DNS = 1.1.1.1
[Peer]
...
AllowedIPs = 172.9.9.0/24, 1.1.1.1/32
Isso não responde à segunda pergunta que eu tinha: se é possível fazer X
e B
comunicar diretamente sem passar por S
. A outra resposta ajuda a entender isso.
EDITAR
Parece que funciona também eliminando o DNS
campo, portanto deve usar o mesmo servidor DNS para ambas as interfaces.