Using OpenVPN to provide SSH access to router via QMI cellular connection

My setup is very simple, as is my understanding of networking. I have a WIFI cellular router and a bunch of raspberry pies connected to it. I need to get SSH access to the pies, or just SSH access to the router and from there I can SSH to the pies.

The plan is to connect to the router (and pies) using OpenVPN. To that end I have setup an OpenVPN server (thanks to https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-18-04) and seem to have setup the router as an OpenVPN client: I have an external computer connected to the VPN and the router both on the same subnet.

Now, if I configure the OpenVPN server to push DNS changes (via push "redirect-gateway def1 bypass-dhcp" option in server config) then I can ping the router from the external computer, but I can only SSH in if I disable the firewall, so something needs to be done there! BUT I also lose internet access from any of the clients (the raspberry pies). So, with DNS changes pushed I have my external and LAN clients talking, but I lose internet access, and without DNS changes pushed they don't talk but I have internet access.

I guess the ideal would be everything that's on the VPN to be able to communicate using any port and to limit that just to the router and my external computer, and for the other LAN clients to remain connected to the internet (but accessible through the router).

Here are my configuration files:

-- /etc/config/openvpn

config openvpn outdoor_router

        # Set to 1 to enable this instance:
        option enabled 1

        # Include OpenVPN configuration
        option config /etc/openvpn/vpn.conf

-- /etc/openvpn/vpn.conf

client
dev tun
proto udp
remote xxx 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
auth SHA256
key-direction 1
verb 3
<ca>
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</ca>
<cert>
...
</cert>
<key>
...
</key>
<tls-auth>
...
</tls-auth>

-- /etc/config/network

config interface 'loopback'
	option ifname 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config interface 'lan'
	option type 'bridge'
	option proto 'static'
	option ipaddr '192.168.30.1'
	option netmask '255.255.255.0'
	option ifname 'eth1'

config interface 'wan'
	option proto 'dhcp'
	option ifname 'eth0'

config interface 'MOBILE'
	option proto 'qmi'
	option device '/dev/cdc-wdm0'

config interface 'vpn'
	option proto 'none'
	option ifname 'tun0'
	option auto '1'
	option delegate '0'

-- /etc/config/firewall

config defaults
	option syn_flood '1'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'

config zone
	option name 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	option network 'lan'

config zone
	option name 'wan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	option network 'wan wan6 MOBILE'

config forwarding
	option src 'lan'
	option dest 'wan'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option target 'ACCEPT'
	option family 'ipv4'

config rule
	option name 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-DHCPv6'
	option src 'wan'
	option proto 'udp'
	option src_ip 'fc00::/6'
	option dest_ip 'fc00::/6'
	option dest_port '546'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'wan'
	option dest '*'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config include
	option path '/etc/firewall.user'

config include 'miniupnpd'
	option type 'script'
	option path '/usr/share/miniupnpd/firewall.include'
	option family 'any'
	option reload '1'

config zone
	option name 'vpn_fw'
	option forward 'REJECT'
	option output 'ACCEPT'
	option network 'vpn'
	option input 'REJECT'
	option masq '1'
	option mtu_fix '1'

config forwarding
	option dest 'vpn_fw'
	option src 'lan'

Any help much appreciated!

Since the OpenVPN is only for management and should not provide internet access, I would do the following:

Remove the vpn_fw zone and add the vpn network interface in the LAN firewall zone.
Do not advertise the default gateway over the OpenVPN tunnel. What needs to be added is a static route in the OpenVPN server for the LAN subnet 192.168.30.0/24 via the tun0 IP address.

1 Like

Thanks Trendy for taking the time to reply. Unfortunately I failed miserably to get OpenVPN to work in this way - I just don't know enough about networking and routing to make it work. In the end I went with a WireGuard setup and was quickly able to get something up and running that worked with minimal configuraiton (or understanding from me!): the router and my VPN 'server' on the same subnet with the VPN restricted to the VPN subnet range (and VPN server IP) using the Allowed IPs option in WireGuard. That created a split tunnel VPN that meant I could SSH to the router via the VPN server on the VPN subnet, and from there SSH to each of the raspberry pies on the LAN subnet.

Joy.

If you post the configuration of Wireguard and the firewall we could hep you fine tune it so that you can SSH directly to the Pies.

1 Like

OK! That would be nice, as long as the configuration isn't too complex and ideally not requiring any configuration on the pies themselves - nice to be able to just add a new pi and connect to the wifi without having to do any additional configuration.

Here's /etc/config/network:

config interface 'loopback'
	option ifname 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config interface 'lan'
	option type 'bridge'
	option proto 'static'
	option ipaddr '192.168.30.1'
	option netmask '255.255.255.0'
	option ifname 'eth1'

config interface 'wan'
	option proto 'dhcp'
	option ifname 'eth0'

config interface 'MOBILE'
	option proto 'qmi'
	option device '/dev/cdc-wdm0'

config interface 'WG'
	option proto 'wireguard'
	option private_key '[private key removed]'
	list addresses '9.10.0.2/32'
	list addresses 'fd86:ea04:1111::2'

config wireguard_WG
	option endpoint_host '[server ip removed]'
	option endpoint_port '51820'
	option persistent_keepalive '25'
	option public_key '[public key removed]'
	option route_allowed_ips '1'
	list allowed_ips '9.10.0.0/24'
	list allowed_ips 'fd86:ea04:1111::/64'
	list allowed_ips '[server ip removed]/24'

/etc/config/firewall

config defaults
	option syn_flood '1'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'

config zone
	option name 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	option network 'lan'

config zone
	option name 'wan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	option network 'wan wan6 MOBILE WG'

config forwarding
	option src 'lan'
	option dest 'wan'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option target 'ACCEPT'
	option family 'ipv4'

config rule
	option name 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-DHCPv6'
	option src 'wan'
	option proto 'udp'
	option src_ip 'fc00::/6'
	option dest_ip 'fc00::/6'
	option dest_port '546'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'wan'
	option dest '*'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config include
	option path '/etc/firewall.user'

config include 'miniupnpd'
	option type 'script'
	option path '/usr/share/miniupnpd/firewall.include'
	option family 'any'
	option reload '1'

... and the server wireguard config:

[Interface]
Address = 9.10.0.1/24
Address = fd86:ea04:1111::1/64
SaveConfig = true
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens3 -j MASQUERADE
ListenPort = 51820
PrivateKey = [private key removed]

[Peer]
PublicKey = [public key removed]
AllowedIPs = 9.10.0.2/32, fd86:ea04:1111::2/128

Change this to /24

That is not needed. Server's IP is 9.10.0.1 and is allowed.
You need to add in server 192.168.30.0/24 as allowed IPs.

Finally consider changing the address space of 9.X.Y.Z that you are using. It is public space, not private. Use instead 10.X.Y.Z which is private.

Oh nice! Thanks - I will give that a try!

Hmmm. I stuffed it up in some way and could no longer access the router on any IP! Had to reset and reconfigure.

Anyway, I've got to install this setup at a remote site in a couple of days so I'm just going to go with the setup as it is and then try and get a second router configured in the way you suggest sometime the following week when I have more time to deal with any issues!

Thanks again for the help! I will report back on my second attempt when I get to it.

1 Like