I have two cloned networks (lan1 and lan2) used for testing purposes, each with the same address space 10.20.80.0/22
:
# 10.20.80.0/22
10.20.80.0 # first address
...
10.20.83.254 # last address
They are not connected and not meant to be connected in terms of switches.
But I want to have a means to move between lan1 and lan2 through SSH. (From lan1 on host alpha, do an ssh mars
and from there on do an ssh alpha.lan2
.) So I use a (CentOS 7) linux host named mars
as an SSH hop:
mars
is attached to both lanslan1
andlan2
and listed in both lans’/etc/hosts
with the address10.20.80.55 mars
- Has the two NICs
em1
andem2
.
em1
belongs to lan1.
em2
belongs to lan2.
/etc/hosts
of all computers on lan1
and on lan2
:
10.20.80.1 alpha
10.20.80.2 beta
...
10.20.80.55 mars # ssh gateway connected to lan1 and lan2
Approach 1: ip netns (working)
(Quick readers skip to approach 3)
I used ip network namespaces to separate the network interfaces
It looks like that:
Host 'mars' with 3 network namespaces
|------------------------------------------------------------------------|
|[default/root netns] |
| |
| lo |
| 127.0.0.1|
|------------------------------------------------------------------------|
|---------------------------------| |---------------------------------|
|[netns lan1] | |[netns lan2] |
| lo | | lo |
| 127.0.0.1| | 127.0.0.1|
| sshd1 | | sshd2 |
| | | |
|10.20.80.55/22 em1 (physical) | |10.20.80.55/22 em2 (physical) |
|----------|----------------------|----|----------|----------------------|
| |
Network 10.20.80.0/22 (lan1) Network 10.20.80.0/22 (lan2)
This basically works and now I can go do the following from host alpha in lan1:
ssh mars
ip netns exec lan2 bash # Opens a bash in the network namespace 'lan2'
ssh alpha
Voilà, I arrived at host alpha in lan2!
Drawbacks:
- Services on host mars (like ntpd) run in the default network namespace, which only has the loopback interface
lo
and therefore cannot contact any other ntp peer. - sshd has to be started for each namespace
- No proxy jumping with ssh from lan1 to lan2
Code:
Remove all netns (for repeated attempts):
#!/bin/bash
for netns in $(ip netns | awk '{print $1}'); do
for pid in $(ip netns pids $netns); do
kill $pid
done
ip netns del $netns
done
Setup netns lan1
:
ip netns add lan1
ip link set em1 netns lan1
ip netns exec lan1 ip addr add 10.20.80.55/22 dev em1
ip netns exec lan1 ip link set em1 up
ip netns exec lan1 link set lo up
ip netns exec lan1 /usr/sbin/sshd -o PidFile=/var/run/sshd.lan1.pid
Setup netns lan2
:
ip netns add lan2
ip link set em1 netns lan2
ip netns exec lan2 ip addr add 10.20.80.55/22 dev em1
ip netns exec lan2 ip link set em1 up
ip netns exec lan2 link set lo up
ip netns exec lan2 /usr/sbin/sshd -o PidFile=/var/run/sshd.lan2.pid
This created two network namespaces (netns lan1 and netns lan2), added a loopback interface to each netns and moved the hardware interfaces em1 and em2 to each respective netns (network namespace). Moreover it started an SSH Daemon so that each NIC is reachable.
Approach 2: use NAT on the host-in-the-middle
Instead of using network namespaces, I want to ssh mars
from lan1 and from mars continue with another ssh alpha.lan2
into lan2 (and vice versa). So I can use host 'mars' as a proxy for ssh and do ssh jumping with ssh -J mars alpha.lan2
, also for scp or X-forwarding.
Host 'mars'
|------------------------------------------------------------------------|
|[default/root netns] |
| lo |
| 127.0.0.1|
| |
|192.168.4.55 em1 (physical) 192.168.8.55 em2 |
|iptables NAT to 10.20.80.55/22? iptables NAT to 10.20.80.55/22? |
|----------|--------------------------------------|----------------------|
| |
Network 10.20.80.0/22 (lan1) Network 10.20.80.0/22 (lan2)
I want to use NAT for that on mars.
/etc/hosts
on mars (not on the hosts on lan1 and lan2):
192.168.4.1 alpha.lan1
192.168.4.2 beta.lan1
192.168.4.55 mars.lan1 # ssh gateway connected to lan1 and lan2
192.168.8.1 alpha.lan2
192.168.8.2 beta.lan2
192.168.8.55 mars.lan2 # ssh gateway connected to lan1 and lan2
My idea is to map lan1 and lan2 to two distinct networks:
# 10.20.80.0/22 (lan1) -> 192.168.4.0/22 via NIC em1
# 10.20.80.0/22 (lan2) -> 192.168.8.0/22 via NIC em2
iptables -A PREROUTING -i em1 -j NETMAP --to 192.168.4.0/24
iptables -A POSTROUTING -o em1 -j NETMAP --to 10.20.80.0/24
This fails. Questions:
- Could it work this way? Which IP addresses do I assign to em1 and em2? I assume I can’t assign the actual
10.20.80.55
to both em1 and em2 without using network namespaces, so I tried to assign the “mapped” addresses 192.168.4.55 (to em1) and 192.168.8.55 (to em2). But that means the NICs can’t be reached from neither lan1 nor lan2 (10.20.80.0/22).
Or does it make sense to do the following?
ip address add 192.168.4.55/22 dev em1
ip address add 192.168.8.55/22 dev em2
ip address add 10.20.80.55/22 dev em1
ip address add 10.20.80.55/22 dev em2
- Which iptables rules do I need?
- Which routes do I set up finally?
- Or should I follow an approch 3 (below)?
Approach 3: use NAT with network namespaces
I think I probably need the following approach: I need 3 network namespaces (one for each of the two lans and one root namespace) in the following way:
3 network namespaces on host 'mars':
|------------------------------------------------------------------------------------------------------|
|127.0.0.1 lo [default/root netns]|
| |
|192.168.4.0/22 192.168.8.0/22 |
| ↓↑ (NAT with iptables NETMAP) ↓↑ (NAT with iptables NETMAP) |
|10.20.80.0/22 10.20.80.0/22 |
| |
|192.168.0.1/24 v-root-em1 (virtual) 192.168.0.2/24 v-root-em2 (virtual) |
|-------|----------------------------------------------------|-----------------------------------------|
| |
|-------|-----------------------------------------| |-------|-----------------------------------------|
|192.168.1.1/24 v-peer-em1 (virtual) [netns lan1]| |192.168.1.1/24 v-peer-em2 (virtual) [netns lan2]|
| | | |
| 127.0.0.1 lo| | 127.0.0.1 lo|
| | | |
|192.168.1.2/24 | |192.168.1.2/24 |
| ↓↑ (NAT) | | ↓↑ (NAT) |
|10.20.80.55/22 em1 (physical) | |10.20.80.55/22 em2 (physical) |
|----------|--------------------------------------| |----------|--------------------------------------|
| |
Network 10.20.80.0/22 (lan1) Network 10.20.80.0/22 (lan2)
Used code to setup this approach:
# Setup netns lan1:
ip netns add lan1
ip link set em1 netns lan1
ip netns exec lan1 ip addr add 10.20.80.55/22 dev em1
ip netns exec lan1 ip link set em1 up
ip netns exec lan1 link set lo up
# Create virtual interfaces and bridges to connect the namespace lan2 to the default (root) namespace:
ip link add v-root-em1 type veth peer name v-peer-em1
ip link set v-peer-em1 netns lan1
ip addr add 192.168.0.1/24 dev v-root-em1
ip netns exec lan1 addr add 192.168.1.1/24 dev v-peer-em1
ip link set v-root-em1 up
ip netns exec lan1 link set v-peer-em1 up
# Setup netns lan2:
ip netns add lan2
ip link set em2 netns lan2
ip netns exec lan2 ip addr add 10.20.80.55/22 dev em2
ip netns exec lan2 ip link set em2 up
ip netns exec lan2 link set lo up
# Create virtual interfaces and bridges to connect the namespace lan2 to the default (root) namespace:
ip link add v-root-em2 type veth peer name v-peer-em2
ip link set v-peer-em2 netns lan2
ip addr add 192.168.0.2/24 dev v-root-em2
ip netns exec lan2 addr add 192.168.1.1/24 dev v-peer-em2
ip link set v-root-em2 up
ip netns exec lan2 link set v-peer-em2 up
# Configure lan1:
ip route add 192.168.4.0/22 via 192.168.0.1 dev v-root-em1
ip netns exec lan1 ip route add 192.168.4.0/22 dev em1 # Outgoing to lan1 (10.20.80.0/22)
ip netns exec lan1 ip route add 192.168.0.0/24 via 192.168.1.1 dev v-peer-em1 # Route into default/root namespace
# Configure lan2:
ip route add 192.168.8.0/22 via 192.168.0.2 dev v-root-em2
ip netns exec lan2 ip route add 192.168.8.0/22 dev em1 # Outgoing to lan1 (10.20.80.0/22)
ip netns exec lan2 ip route add 192.168.0.0/24 via 192.168.1.1 dev v-peer-em2 # Route into default/root namespace
### Code missing to set up NAT
- How and where would I need to set up iptables rules then?
- Would I need also a /22 network for the two namespaces 'lan1' and 'lan2' instead of a /24 one?
Thanks for your contributions.
Remarks:
I recommend to disable saving ssh host keys on 'mars' when using network namespaces because hosts keys from lan1 will conflict with host keys from lan2.