{"id":2086,"date":"2022-10-28T19:55:52","date_gmt":"2022-10-28T23:55:52","guid":{"rendered":"https:\/\/lowtek.ca\/roo\/?p=2086"},"modified":"2022-10-30T10:45:44","modified_gmt":"2022-10-30T14:45:44","slug":"openwrt-as-a-wireguard-client","status":"publish","type":"post","link":"https:\/\/lowtek.ca\/roo\/2022\/openwrt-as-a-wireguard-client\/","title":{"rendered":"OpenWRT as a wireguard client"},"content":{"rendered":"<p><a href=\"https:\/\/lowtek.ca\/roo\/wp-content\/uploads\/2022\/10\/wireguard-remote.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2087\" src=\"https:\/\/lowtek.ca\/roo\/wp-content\/uploads\/2022\/10\/wireguard-remote-500x133.jpg\" alt=\"\" width=\"500\" height=\"133\" srcset=\"https:\/\/lowtek.ca\/roo\/wp-content\/uploads\/2022\/10\/wireguard-remote-500x133.jpg 500w, https:\/\/lowtek.ca\/roo\/wp-content\/uploads\/2022\/10\/wireguard-remote.jpg 553w\" sizes=\"auto, (max-width: 500px) 85vw, 500px\" \/><\/a><\/p>\n<p>Previously I&#8217;ve written about <a href=\"https:\/\/lowtek.ca\/roo\/2021\/wireguard-self-hosted-vpn\/\">running wireguard as a self hosted VPN<\/a>. In this post I&#8217;ll cover how to connect a remote site back to your wireguard installation allowing that remote site to reach machines on your local (private) network. This is really no different than configuring a wireguard client on your phone or laptop, but by doing this on the router you build a network path that anyone on the remote network can use.<\/p>\n<p>I should probably mention that there are other articles that cover a <a href=\"https:\/\/openwrt.org\/docs\/guide-user\/services\/vpn\/wireguard\/site-to-site\">site-to-site<\/a> configuration, where you have two wireguard enabled routers that extend your network across an internet link. While this is super cool, it wasn&#8217;t what I wanted for this use case. I would be remiss in not mentioning <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tailscale\">tailscale<\/a> as an alternative if you want a site-to-site setup, it allows for the easy creation of a virtual network (mesh) between all of your devices.<\/p>\n<p>In my case my <a href=\"https:\/\/lowtek.ca\/roo\/category\/iot\/\">IoT<\/a> devices can all talk to my <a href=\"https:\/\/lowtek.ca\/roo\/2022\/tasmota-mqtt-and-prometheus\/\">MQTT<\/a> installation, and that communication not only allows the gathering of data from the devices, but offers a path to controlling the devices as well. What this means is that an IoT device at the remote site, if it can see the MQTT broker I host on my home server &#8211; will be controllable from my home network. Thus setting up a one way wireguard &#8216;client&#8217; link is all I need.<\/p>\n<p>I will assume that the publicly visible wireguard setup is based on the <a href=\"https:\/\/fleet.linuxserver.io\/image?name=linuxserver\/wireguard\">linuxserver.io\/wireguard<\/a> container. You&#8217;ll want to add a new peer configuration for the remote site. This should generate a <code>peer_remote.conf<\/code> file that should look something like:<\/p>\n<pre class=\"lang:default decode:true\">[Interface]\r\nAddress = 10.13.13.4\r\nPrivateKey = SECRETPRIVKEY=\r\nListenPort = 51820\r\nDNS = 10.0.0.8\r\n\r\n[Peer]\r\nPublicKey = SECRETPUBKEY=\r\nPresharedKey = SECRETPRESHARE=\r\nEndpoint = mydomain.com:51820\r\nAllowedIPs = 0.0.0.0\/0, ::\/0<\/pre>\n<p>This is the same conf file you&#8217;d grab and install into a wireguard client, but in our case we want to setup an <a href=\"https:\/\/openwrt.org\">OpenWRT<\/a> router at a remote location to use this as it&#8217;s client configuration. The <code>10.13.13.x<\/code> address is the default wireguard network for the linuxserver.io container.<\/p>\n<p>I will assume that we&#8217;re on a recent version of OpenWRT (21.02 or above), as of this writing 23.03.2 is the latest stable release. As per the <a href=\"https:\/\/openwrt.org\/docs\/guide-user\/services\/vpn\/wireguard\/client\">documentation page on setting up the client<\/a> you&#8217;ll need to install some packages. This is easy to do via the cli.<\/p>\n<pre class=\"lang:default decode:true \"># Install packages\r\nopkg update\r\n# 21.02 or above\r\nopkg install wireguard-tools luci-app-wireguard luci-proto-wireguard<\/pre>\n<p>Now there are some configuration parameters you need to setup (again in the cli, as we&#8217;re going to set some environment variables then use them later).<\/p>\n<pre class=\"lang:default decode:true\"># Configuration parameters\r\nWG_IF=\"wg0\"\r\nWG_SERV=\"mydomain.com\"\r\nWG_PORT=\"51820\"\r\nWG_ADDR=\"10.13.13.4\/32\"\r\nWG_KEY=\"SECRETPRIVKEY=\"\r\nWG_PSK=\"SECRETPRESHARE=\"\r\nWG_PUB=\"SECRETPUBKEY=\"<\/pre>\n<p>Now this is where I got stuck following the documentation. It wasn&#8217;t clear to me that the <code>WG_ADDR<\/code> value should be taken from the <code>peer_remote.conf<\/code> file as I&#8217;ve done above. I thought this was just another private network value to uniquely identify the new wg0 device I was creating on the OpenWRT router. Thankfully <a href=\"https:\/\/forum.openwrt.org\/t\/openwrt-client-to-linux-hosted-wireguard\/140733\">some kind folk on the OpenWRT forum<\/a> helped point me down the right path to figure this out.<\/p>\n<p>Obviously <code>WG_SERV<\/code> points at our existing wireguard installation, and the three secrets <code>WG_KEY<\/code>, <code>WG_PSK<\/code>, and <code>WG_PUB<\/code> all come from the same <code>peer_remote.conf<\/code> file. I do suspect that one of these might be allowed to be unique for the remote installation however, I know that this works &#8211; and I do not believe we are introducing any security issues.<\/p>\n<p>At this point we have all the configuration we need, and can proceed to configure the firewall and network<\/p>\n<pre class=\"lang:default decode:true\"># Configure firewall\r\nuci rename firewall.@zone[0]=\"lan\"\r\nuci rename firewall.@zone[1]=\"wan\"\r\nuci del_list firewall.wan.network=\"${WG_IF}\"\r\nuci add_list firewall.wan.network=\"${WG_IF}\"\r\nuci commit firewall\r\n\/etc\/init.d\/firewall restart\r\n\r\n# Configure network\r\nuci -q delete network.${WG_IF}\r\nuci set network.${WG_IF}=\"interface\"\r\nuci set network.${WG_IF}.proto=\"wireguard\"\r\nuci set network.${WG_IF}.private_key=\"${WG_KEY}\"\r\nuci add_list network.${WG_IF}.addresses=\"${WG_ADDR}\"\r\n \r\n# Add VPN peer\r\nuci -q delete network.wgserver\r\nuci set network.wgserver=\"wireguard_${WG_IF}\"\r\nuci set network.wgserver.public_key=\"${WG_PUB}\"\r\nuci set network.wgserver.preshared_key=\"${WG_PSK}\"\r\nuci set network.wgserver.endpoint_host=\"${WG_SERV}\"\r\nuci set network.wgserver.endpoint_port=\"${WG_PORT}\"\r\nuci set network.wgserver.route_allowed_ips=\"1\"\r\nuci set network.wgserver.persistent_keepalive=\"25\"\r\nuci add_list network.wgserver.allowed_ips=\"0.0.0.0\/0\"\r\nuci commit network\r\n\/etc\/init.d\/network restart<\/pre>\n<p>This sets up a full tunnel VPN configuration. If you want to permit a split-tunnel then we need to change one line in the above script.<\/p>\n<pre class=\"lang:default decode:true\">uci add_list network.wgserver.allowed_ips=\"0.0.0.0\/0\"<\/pre>\n<p>The <code>allowed_ips<\/code> needs to change to specify the subnet you want to route over this wireguard connection.<\/p>\n<p>One important note. You need to ensure that your home network and remote network do not have overlapping IP ranges. This would introduce confusion about where to route what. Let&#8217;s assume that the home network lives on <code>192.168.1.0\/24<\/code> &#8211; we&#8217;d want to ensure that our remote network did not use that range so let&#8217;s assume we&#8217;ve configure the remote OpenWRT setup to use <code>192.168.4.0\/24<\/code>. By doing this &#8211; we make it easy to know which network we mean when we are routing packets around.<\/p>\n<p>Thus if we wanted to only send traffic destined for the home network over the wireguard interface, we&#8217;d specify:<\/p>\n<pre class=\"lang:default decode:true \">uci add_list network.wgserver.allowed_ips=\"192.168.1.0\/24\"<\/pre>\n<p>As another way of viewing this configuration, let&#8217;s go take a peek at the config files on the OpenWRT router.<\/p>\n<p><code>\/etc\/config\/network<\/code> will have two new sections<\/p>\n<pre class=\"lang:default decode:true\">config interface 'wg0'\r\n\toption proto 'wireguard'\r\n\toption private_key 'SECRETPRIVKEY='\r\n\tlist addresses '10.13.13.4\/32'\r\n\r\nconfig wireguard_wg0 'wgserver'\r\n\toption public_key 'SECRETPUBKEY='\r\n\toption preshared_key 'SECRETPRESHARE='\r\n\toption endpoint_host 'mydomain.com'\r\n\toption endpoint_port '51820'\r\n\toption route_allowed_ips '1'\r\n\toption persistent_keepalive '25'\r\n\tlist allowed_ips '192.168.1.0\/24'<\/pre>\n<p>and the <code>\/etc\/config\/firewall<\/code> will have one modified section<\/p>\n<pre class=\"lang:default decode:true \">config zone 'wan'\r\n\toption name 'wan'\r\n\tlist network 'wan'\r\n\tlist network 'wan6'\r\n\tlist network 'wg0'\r\n\toption input 'REJECT'\r\n\toption output 'ACCEPT'\r\n\toption forward 'REJECT'\r\n\toption masq '1'\r\n\toption mtu_fix '1'<\/pre>\n<p>You&#8217;ll note that the <code>wg0<\/code> device is part of the <code>wan<\/code> zone.<\/p>\n<p>It really is pretty cool to have IoT devices at a remote site, magically controlled over the internet &#8211; and I don&#8217;t need any cloud services to do this.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Previously I&#8217;ve written about running wireguard as a self hosted VPN. In this post I&#8217;ll cover how to connect a remote site back to your wireguard installation allowing that remote site to reach machines on your local (private) network. This is really no different than configuring a wireguard client on your phone or laptop, but &hellip; <a href=\"https:\/\/lowtek.ca\/roo\/2022\/openwrt-as-a-wireguard-client\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;OpenWRT as a wireguard client&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,12,21],"tags":[],"class_list":["post-2086","post","type-post","status-publish","format-standard","hentry","category-computing","category-how-to","category-network"],"_links":{"self":[{"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/posts\/2086","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/comments?post=2086"}],"version-history":[{"count":3,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/posts\/2086\/revisions"}],"predecessor-version":[{"id":2090,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/posts\/2086\/revisions\/2090"}],"wp:attachment":[{"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/media?parent=2086"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/categories?post=2086"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/tags?post=2086"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}