-1

This looks like a trivial question, but I couldn't find the answer yet.

In my LAN (blue in the picture) I have a NAS and a Raspberry Pi, among other machines. I installed an OpenVPN server in the Raspberry Pi. I want the OpenVPN client to be able to access the NAS, meaning FTP, HTTP, etc. The client must not be able to access any machine other than the Raspberry and the NAS itself.

In this picture you have my networks topology:

networks_topology

I can connect OpenVPN client to its server. I know I have a subnet conflict but I cannot change the subnets.

My server configuration:

port 1194
proto udp
dev tun

ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/myserver.crt
key /etc/openvpn/easy-rsa/keys/myserver.key
dh /etc/openvpn/easy-rsa/keys/dh1024.pem

server 10.8.0.0 255.255.255.0
#push "route 192.168.1.0 255.255.255.0"

ifconfig-pool-persist /etc/openvpn/easy-rsa/ipp.txt

keepalive 10 120
cipher AES-128-CBC
persist-key
persist-tun

status /var/log/openvpn-status.log
#log         /var/log/openvpn.log
log-append  /var/log/openvpn.log
verb 3

My client configuration file:

client

remote x.y.z.t 1194
proto udp
dev tun

ca /etc/openvpnclient/ca.crt
cert /etc/openvpnclient/client.crt
key /etc/openvpnclient/client.key

cipher AES-128-CBC

#route-method exe
#route-delay 3
#route 10.8.0.0 255.255.255.0
###route-nopull
route 192.168.1.20 255.255.255.255

resolv-retry infinite
nobind
persist-key
persist-tun

mute 20
verb 3

I can connect using the Windows client, but I cannot ping or access anyway the NAS. I am sure I am still missing something, but couldn't figure out how I can route the traffic. I have read many topics on the subject, but still no luck.

I should be able to add a routing rule in the router that is over the OpenVPN server network, if needed.


Update 18/11/2019 @17.31 CET

I have two main requirements:

  1. I need the client to reach the NAS, but not the other machines on the LAN;
  2. I need the client to be able to connect even when its subnet conflicts with the NAS subnet (i.e. 192.168.1.0/24).

Tom Yan and this article helped me getting a solution to first issue. I believe second issue is still uncovered.

Solution for issue #1:

In server configuration I needed to add (uncomment) this line, to ensure routing requests from the OpenVPN client to the NAS:

push "route 192.168.1.0 255.255.255.0"

To enable routing from the NAS back to the OpenVPN client I added this routing rule in the NAS:

vi /etc/sysconfig/network-scripts/route-eth0

adding this line in that (empty) configuration file

10.8.0.0/24 via 192.168.1.88

And a service network restart ensured the static route to be applied.

After that, I restricted traffic in the Raspberry Pi through iptables. I actually made it permanent installing iptables-persistent and following this guide.

iptables -A FORWARD -i tun0 -s 10.8.0.0/24 -d 192.168.1.20 -j ACCEPT


Update #2

Yes, I need many clients to be able to connect and I guess I should avoid NAT and masquerading for this reason.

2
  • Please downvoter help me improve my answer: what's wrong or missing? – Kar.ma Nov 17 '19 at 17:15
  • See my updated answer. – Tom Yan Nov 18 '19 at 17:30
1

You need to add a route for 10.8.0.0/24 (where the gateway would be 192.168.1.88, i.e. Rasp.Pi the OVPN server) to either NAS or ROUTER (assuming ROUTER is the default gateway of NAS in that case, of course), so that NAS/ROUTER would know where to direct the reply traffics.

If you cannot, you will need to do SNAT/MASQUERADE with iptables (or nftables, of course) on Rasp.Pi so that all traffics from the VPN clients would appear to be originated from the server.

The client must not be able to access any machine other than the Raspberry and the NAS itself.

Make sure you limit forwarding traffics with iptables. Once you have enabled IP forwarding on Rasp.Pi (you have to, otherwise the VPN clients won't be able to reach its LAN), a client can add whatever route he/she needs to reach a certain host in the server's LAN, so just not pushing certain route is not going to help you achieve that.

Update:

To enable IP forwarding (and make the setting persistent over boots):

sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf

To allow only forwarding that you need in this case (eth0 and tun0 are assumed):

iptables -F FORWARD
iptables -P FORWARD DROP
iptables -A FORWARD -m conntrack --ctstate NEW -i tun0 -s 10.8.0.0/24 -o eth0 -d 192.168.1.20 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

To do source NAT for forwarding traffics (so that you don't have to configure return route on NAS / ROUTER) that goes out via eth0:

iptables -t nat -F POSTROUTING

(skip the above if you have some other rules in the chain that you also need)

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

or, if the IP of eth0 is persistent over time/boots:

iptables -t nat -A POSTROUTING -o eth0 -j SNAT 192.168.1.88

P.S. If you want to flush the tables you touched, you can do:

for i in $(cat /proc/net/ip_tables_names); do iptables-restore /usr/share/iptables/empty-"$i".rules; done

Also note that iptables commands are not persistent over boots, so you will want to save the rules to a file with iptables-save (and configure your system to restore them on boot by some means).

Update 2:

You should really check out the above for how to properly configure the FORWARD chain (in the filter table). Without the DROP policy (or a "default" DROP rule at the end), any ACCEPT rule would be useless. (And your rule wouldn't be enough once you fix the DROP part)

To avoid subnet (more precisely, route) conflict, it's best to push a host route (it's what you need anyway) instead of a subnet route, so you should push "route 192.168.1.20 255.255.255.255" (the subnet mask can actually be omitted) instead, as the chance that a client host would have a host route to a LAN host (other than the default gateway) is much lower (a subnet route is always added on Linux when a non-/32 address is assigned to an interface).

You can also for example push "route 10.8.1.1" and DNAT the destination to 192.168.1.20 on Rasp.Pi for the corner case where a 192.168.1.20 route already exists on a client (you should then still be able to access NAS with 10.8.1.1):

iptables -t nat -A PREROUTING -d 10.8.1.1 -j DNAT --to-destination 192.168.1.20
5
  • I'm not clear how I could do that. Should I add a line in server configuration? Or in client configuration? Or set a routing rule through a shell command? Believe me, I am trying hard and still reading a lot about routing, but I am still very confused about how I set up routing rules. – Kar.ma Nov 18 '19 at 10:08
  • Neither, but the configuration of NAS or Router. How exactly you add a route to either of them (and whether that's possible) highly depends on the devices themselves (their OSes, their administration interfaces, etc.). When I have time I will update my answer with the iptables rules I mentioned that can be used on Rasp.Pi as alternatives to return route. – Tom Yan Nov 18 '19 at 12:28
  • Today I tried in the Rasp.Pi the rule iptables -A FORWARD -i tun0 -s 10.8.0.0/24 -d 192.168.1.20 -j ACCEPT but it didn't work. I have no idea how something similar could work in the NAS itself, since it is the "unreached" ending point so far. Sorry for my poor understanding of the matter. – Kar.ma Nov 18 '19 at 14:30
  • What you need to add to NAS or ROUTER is a route. If you don't know how, just check out my updated answer for doing source NAT on Rasp.Pi. For the record, you don't have to mess with the FORWARD chain (in the filter table) to make it work. filter table is where you guard your LAN from your VPN (and so on), so essentially, it's optional. (What's mandatory is enabling IP forwarding with sysctl.) – Tom Yan Nov 18 '19 at 16:56
  • I had my system working and complete yesterday, just before reading your second update. I had implemented the same setting: moving the "push route" command to specific IP worked like a charm to resolve any subnet route conflict (except the same-IP conflict, which I don't mind). So, changing to push "route 192.168.1.20 255.255.255.255" was the final step. Thank you for your precious help. – Kar.ma Nov 19 '19 at 15:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.