I am trying to set up OpenWRT on a Raspberry Pi 3. The intent is to connect the wlan to a wifi AP as a gateway and use the Ethernet as a lan interface for some other devices. The Pi is also running a openvpn client that all the devices connected are supposed to be going through. And this works surprisingly well.
I followed the guide for setting up via Luci (https://openwrt.org/docs/guide-user/services/vpn/openvpn/client-luci) and it appears to work fine in almost all regards. The only issue is the kill-switch. When the VPN is up, everything goes through the vpn (confirmed by using curl on "what is my ip" pages). While deactivating the VPN (or deliberately breaking the config/auth) does indeed block the devices on the lan, it appears that the Pi itself can still connect to hosts on the internet. By running the curl commands on the Pi, I can see that they are not being blocked, though upping the VPN does send them through it again. I've tried setting firewall rules via Luci, but it doesn't seem to honor them for processes that are on the Pi itself. While iptables do seem to get the job done, I don't know if this is a good idea (due to my ignorance).
My worry is that if the server the openvpn client is connecting to for whatever reason goes down and it tries to do anything internet related, it could result in a leak. I'm glad I caught this as early as I did. Could there be some sort of obvious setting or config that I'm missing?
Please connect to your OpenWrt device using ssh and copy the output of the following commands and post it here using the "Preformatted text </> " button:
Remember to redact passwords, MAC addresses and any public IP addresses you may have:
That is of course necessary to send encrypted packets to the VPN server. Also you probably need DNS to initially work even outside the VPN in order to look up the IP of the VPN server, if the configuration refers to it by name.
If you know the IP of the VPN server will never change you could disable output from wan except for a rule allowing connections to the one IP and port of the VPN server. Actually a rule allowing only dest_port 1194 could work to only allow OpenVPN traffic to any server, and not DNS NTP etc that comes from inside the router.
Processes on the Pi itself are also firewalled but the rule is a traffic rule not a forwarding rule. By default all output is allowed (the option output ACCEPT in the wan zone definition) but only a few ports are allowed input.
ubus call system board
{
"kernel": "5.15.137",
"hostname": "OpenWrt",
"system": "ARMv8 Processor rev 4",
"model": "Raspberry Pi 3 Model B Plus Rev 1.3",
"board_name": "raspberrypi,3-model-b-plus",
"rootfs_type": "squashfs",
"release": {
"distribution": "OpenWrt",
"version": "23.05.2",
"revision": "r23630-842932a63d",
"target": "bcm27xx/bcm2710",
"description": "OpenWrt 23.05.2 r23630-842932a63d"
}
}
/etc/config/network
config interface 'loopback'
option device 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'
config globals 'globals'
option ula_prefix ':::/48'
config device
option name 'br-lan'
option type 'bridge'
list ports 'eth0'
config interface 'lan'
option device 'br-lan'
option proto 'static'
option ipaddr '192.168.1.1'
option netmask '255.255.255.0'
option ip6assign '60'
config interface 'wwan'
option proto 'static'
option ipaddr '192.168.x.y'
option netmask '255.255.255.0'
option gateway '192.168.x.z'
list dns '1.1.1.1'
/etc/config/wireless
config wifi-device 'radio0'
option type 'mac80211'
option path 'platform/soc/3f300000.mmcnr/mmc_host/mmc1/mmc1:0001/mmc1:0001:1'
option channel '36'
option band '5g'
option htmode 'VHT80'
option country 'US'
option cell_density '0'
config wifi-iface 'wifinet0'
option device 'radio0'
option mode 'sta'
option network 'wwan'
option ssid 'some_ssid'
option encryption 'psk2'
option key 'some_key'
/etc/config/dhcp
config dnsmasq
option domainneeded '1'
option boguspriv '1'
option filterwin2k '0'
option localise_queries '1'
option rebind_protection '1'
option rebind_localhost '1'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option nonegcache '0'
option cachesize '1000'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
option nonwildcard '1'
option localservice '1'
option ednspacket_max '1232'
option filter_aaaa '0'
option filter_a '0'
config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'
option dhcpv6 'server'
option ra 'server'
option ra_slaac '1'
list ra_flags 'managed-config'
list ra_flags 'other-config'
config dhcp 'wan'
option interface 'wan'
option ignore '1'
config odhcpd 'odhcpd'
option maindhcp '0'
option leasefile '/tmp/hosts/odhcpd'
option leasetrigger '/usr/sbin/odhcpd-update'
option loglevel '4'
/etc/config/firewall
config defaults
option syn_flood '1'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
config zone
option name 'lan'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
list network 'lan'
config zone
option name 'wan'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
option masq '1'
option mtu_fix '1'
list network 'wwan'
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 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 zone
option name 'VpnZone'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
option masq '1'
option mtu_fix '1'
list device 'tun+'
config forwarding
option src 'lan'
option dest 'VpnZone'
config rule
option name 'Allow-vpn-to-server'
option src '*'
option dest '*'
option dest_ip 'some_ip'
option target 'ACCEPT'
config rule
option name 'Block-everything-else'
option src '*'
option dest '*'
option target 'REJECT'
Concerning the firewall rules, I've tried this config and another that only has the last 3 (defined by me) rules enabled. It seems that the device does not honor the firewall rules when the packets originate from openwrt itself unless defined via iptables. Do the packets sent by openwrt completely bypass the zones and firewall rules?
Not sure how to reply to multiple people, but concerning mk24's comment about it being necessary for the pi itself to connect to the internet to establish the tunnel, I understand this. The issue is that if the vpn is in an error status and still trying to come up, the connections aren't blocked. In my case, a dns lookup is not an issue to get the server IP since its address is static so a rule created to only allow connections to the vpn server should be sufficient, but that has been less than successful. I started pinging a public dns server with the vpn down, set a rule to block it, and observed that it was still getting responses.
Sorry if the answer is in the docs somewhere, but I just couldn't find it. I probably didn't use the right terminology.
The output setting here needs to be REJECT. This means that by default no outgoing connections can be initiated, unless there is an additional rule to allow them.
You have written these as forwarding rules not traffic rules by specifying both src and dest. Connections from an internal process do not have a source zone. The allow to vpn server needs to have no src line, and dest of wan.
A "reject everything else" rule is not necessary when the zone output default is set to reject. Anything that does not match one of the definite rules will be rejected.
Also although it isn't an issue here, bear in mind that the order of rules in the file is important. They are considered from first to last in the file. When one matches, that becomes the final decision to accept or reject. Rules listed further down in the file are not processed for that packet.
Unless we're talking about preventing the router itself from connecting to the upstream, it should remain ACCEPT. The kill switch for the lan is simply the removal of the lan > wan forwarding (which has already been done).
OP also wants the router itself to never send anything to the Internet via wan except for encrypted packets to the VPN server. That is a bit excessive in my thinking as well, but it is possible to implement.
Thank you all for your input. I adjusted the firewall rules to account for the misconfigured rule, but the pings from openwrt still go through just fine. I also have an unrelated issue that just started that is preventing my traffic from getting forwarded, but I don't think it is related to the suggested changes. I reverted everything back and they persisted. I think it is an issue with how my personal computer is currently set up, so I'm going to investigate that first. I can use ssh and luci, but nothing goes across the vpn, regardless of whether it is available or not.
I changed the indicated rule to specifically set the dest as wan and dest_ip as the vpn server, and removed src so it stops being a forward rule, but while openwrt traffic will go across the vpn when it is up, it still goes out while down as well.
As for getting the time, I'm planning on using either getting it from my gateway (once I have the firewall rules figured out) or using an RTC module. Also, the VPN server's ip is static so a dns lookup isn't needed anyway.
I'm going to get my forwarding rule set up again and start from scratch with all of this in mind. I didn't deviate from the guide anymore that what was seen so far, but maybe that will automagically fix both issues. Will report back if it works.