{"id":3271,"date":"2023-01-21T19:22:10","date_gmt":"2023-01-22T00:22:10","guid":{"rendered":"https:\/\/dft.wiki\/?p=3271"},"modified":"2026-06-08T17:09:33","modified_gmt":"2026-06-08T21:09:33","slug":"openwrt-as-lxc-in-proxmox","status":"publish","type":"post","link":"https:\/\/dft.wiki\/?p=3271","title":{"rendered":"OpenWRT as LXC in Proxmox"},"content":{"rendered":"<p><strong>OpenWrt<\/strong> [<a href=\"https:\/\/openwrt.org\/\">Link<\/a>] is an open-source lightweight firmware originally created for embedded devices such as routers and network-attached storage devices.<\/p>\n<p>Running OpenWrt in a container (such as LXC) offers several benefits:<\/p>\n<ul>\n<li>Better resource isolation and management<\/li>\n<li>Shares the kernel with the host for optimal resource usage<\/li>\n<li>Easy to back up, migrate, and clone<\/li>\n<li>Isolates the firmware from the host system and its guests<\/li>\n<\/ul>\n<p>Proxmox is an open-source hypervisor that manages containers much like virtual machines, making it a great foundation for running OpenWrt.<\/p>\n<p>This post walks through installing OpenWrt as a container (CT) in Proxmox. See more about Proxmox at [<a href=\"https:\/\/www.proxmox.com\/en\/proxmox-ve\/\">Link<\/a>] and a cheat-sheet at [<a href=\"https:\/\/dft.wiki\/?p=2602\">Link<\/a>].<\/p>\n<hr \/>\n<p><strong>DOWNLOADING THE LXC TEMPLATE<\/strong><\/p>\n<p>Navigate to <strong>https:\/\/us.lxd.images.canonical.com\/images\/openwrt\/<\/strong> and find the latest build, for example <strong>&#8230;\/22.03\/amd64\/default\/20230121_11:58\/rootfs.tar.xz<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3274\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-38-20.png\" alt=\"\" width=\"742\" height=\"297\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-38-20.png 742w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-38-20-300x120.png 300w\" sizes=\"auto, (max-width: 742px) 100vw, 742px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3273\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-39-28.png\" alt=\"\" width=\"791\" height=\"203\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-39-28.png 791w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-39-28-300x77.png 300w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-39-28-768x197.png 768w\" sizes=\"auto, (max-width: 791px) 100vw, 791px\" \/><\/p>\n<hr \/>\n<p><strong>INSTALLING VIA CLI<\/strong><\/p>\n<p>Open the Proxmox host shell and run the following command, customizing it as needed:<\/p>\n<pre>ct create <strong>999<\/strong> \/var\/lib\/vz\/template\/cache\/OpenWRT.tar.xz --arch amd64 --hostname OpenWrt --rootfs <strong>local-lvm<\/strong>:<strong>999<\/strong> --memory 1024 --cores 2 --ostype unmanaged --unprivileged 1<\/pre>\n<p>The container ID must be unique. Choose a storage location with at least 30 GB available.<\/p>\n<hr \/>\n<p><strong>CONFIGURING THE CONTAINER&#8217;S NETWORK<\/strong><\/p>\n<p>The container needs at least 2 network interfaces from the host.<\/p>\n<p>By default, the bridge interface <strong>vmbr0<\/strong> is created during installation. If needed, create a second <strong>Linux Bridge<\/strong> interface as follows:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3276\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-58-25.png\" alt=\"\" width=\"613\" height=\"263\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-58-25.png 613w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-58-25-300x129.png 300w\" sizes=\"auto, (max-width: 613px) 100vw, 613px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3275\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-55-40.png\" alt=\"\" width=\"1082\" height=\"242\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-55-40.png 1082w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-55-40-300x67.png 300w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-55-40-1024x229.png 1024w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_17-55-40-768x172.png 768w\" sizes=\"auto, (max-width: 1082px) 100vw, 1082px\" \/><\/p>\n<p>In the container&#8217;s network configuration, add both bridge networks:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3278\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-12-44.png\" alt=\"\" width=\"724\" height=\"168\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-12-44.png 724w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-12-44-300x70.png 300w\" sizes=\"auto, (max-width: 724px) 100vw, 724px\" \/><\/p>\n<p>The container can now be started.<\/p>\n<hr \/>\n<p><strong>BASIC SYSTEM AND FIREWALL CONFIGURATION<\/strong><\/p>\n<p>Open the container console and immediately change the root password:<\/p>\n<pre>passwd<\/pre>\n<p>Then check the IP assigned to the WAN interface <strong>eth0<\/strong>:<\/p>\n<pre>ip a<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3279\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-24-48.png\" alt=\"\" width=\"559\" height=\"360\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-24-48.png 559w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-24-48-300x193.png 300w\" sizes=\"auto, (max-width: 559px) 100vw, 559px\" \/><\/p>\n<p>Edit the firewall configuration:<\/p>\n<pre>vim \/etc\/config\/firewall<\/pre>\n<p>Add the following lines right after the &#8220;Allow-Ping&#8221; block:<\/p>\n<pre>config rule\r\n        option name             LUCI-on-WAN\r\n        option src              wan\r\n        option proto            tcp\r\n        option family           ipv4\r\n        option dest_port        80\r\n        option target           ACCEPT<\/pre>\n<p>Then reload the firewall to apply the changes:<\/p>\n<pre>\/etc\/init.d\/firewall reload<\/pre>\n<hr \/>\n<p><strong>ACCESSING THE LUCI WEB UI<\/strong><\/p>\n<p>Navigate to <strong>http:\/\/192.168.1.180<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3281\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-40-44.png\" alt=\"\" width=\"949\" height=\"641\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-40-44.png 949w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-40-44-300x203.png 300w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-40-44-768x519.png 768w\" sizes=\"auto, (max-width: 949px) 100vw, 949px\" \/><\/p>\n<p>Go to <strong>Network &gt; Interfaces &gt; &#8220;Add new interface&#8230;&#8221;<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3282\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-45-24.png\" alt=\"\" width=\"566\" height=\"238\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-45-24.png 566w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-45-24-300x126.png 300w\" sizes=\"auto, (max-width: 566px) 100vw, 566px\" \/><\/p>\n<p>On the <strong>General Settings<\/strong> tab, set the IP to <strong>10.10.10.1<\/strong> and mask to <strong>255.255.255.0<\/strong>.<\/p>\n<p>On the <strong>Firewall Settings<\/strong> tab, select the zone &#8220;<strong>lan<\/strong>&#8220;.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3286\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_19-10-18.png\" alt=\"\" width=\"683\" height=\"242\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_19-10-18.png 683w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_19-10-18-300x106.png 300w\" sizes=\"auto, (max-width: 683px) 100vw, 683px\" \/><\/p>\n<p>Enable the <strong>DHCP server<\/strong>, then click &#8220;<strong>Save<\/strong>&#8220;.<\/p>\n<p>Optionally, remove <strong>WAN6<\/strong> if it is not needed.<\/p>\n<p>Click &#8220;<strong>Save &amp; Apply<\/strong>&#8220;. It will take a few seconds for the router (OpenWrt) to reload.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3284\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-54-53.png\" alt=\"\" width=\"950\" height=\"382\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-54-53.png 950w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-54-53-300x121.png 300w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot_2023-01-21_18-54-53-768x309.png 768w\" sizes=\"auto, (max-width: 950px) 100vw, 950px\" \/><\/p>\n<hr \/>\n<p><strong>CONCLUSION<\/strong><\/p>\n<p>By attaching virtual machines and containers to the <strong>vmbr1<\/strong> interface, they will all be isolated and protected by the OpenWrt router and its firewall rules.<\/p>\n<hr \/>\n<p><strong>BONUS: OPENVPN CLIENT AND SERVER<\/strong><\/p>\n<p>Connect to the OpenWrt CT via SSH or the Console, then run:<\/p>\n<pre>opkg update\r\nopkg install luci-app-openvpn openvpn-openssl<\/pre>\n<p><strong>Note:<\/strong> OpenWrt officially transitioned its default package manager from <code>opkg<\/code> to <code>apk<\/code> (Alpine Package Keeper) in late 2024. The equivalent commands for modern systems are:<\/p>\n<pre>apk update\r\napk add luci-app-openvpn openvpn-openssl<\/pre>\n<p>OR<\/p>\n<pre>apk --update-cache add luci-app-openvpn openvpn-openssl<\/pre>\n<p>Use <code>--simulate<\/code> for a dry run, which is especially useful when removing packages with <code>del<\/code>.<\/p>\n<p>Refresh the web UI and a new <strong>VPN<\/strong> option will appear in the top menu:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3309\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-23-20-35-01.png\" alt=\"\" width=\"944\" height=\"637\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-23-20-35-01.png 944w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-23-20-35-01-300x202.png 300w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-23-20-35-01-768x518.png 768w\" sizes=\"auto, (max-width: 944px) 100vw, 944px\" \/><\/p>\n<p>Configure and enable your VPN parameters. It will not work out of the box. Shut down the CT and connect to the Proxmox host via SSH or the Console to edit the CT configuration:<\/p>\n<pre>nano \/etc\/pve\/lxc\/<strong>103<\/strong>.conf<\/pre>\n<p>Make the necessary adjustments to include the highlighted configuration parameters:<\/p>\n<pre>arch: amd64\r\ncores: 2\r\n<strong>features: nesting=1<\/strong>\r\nhostname: OpenWrt\r\nmemory: 1024\r\nnet0: name=eth0,bridge=vmbr0,firewall=1,hwaddr=3E:4B:D3:83:67:95,ip=dhcp,type=veth\r\nnet1: name=eth1,bridge=vmbr1,firewall=1,hwaddr=06:F3:91:BF:4E:B2,ip=10.10.10.1\/24,type=veth\r\nostype: unmanaged\r\nrootfs: Storage:103\/vm-103-disk-0.raw,size=103G\r\nswap: 512\r\nunprivileged: 1\r\n<strong>lxc.cgroup2.devices.allow: c 10:200 rwm<\/strong>\r\n<strong>lxc.mount.entry: \/dev\/net dev\/net none bind,create=dir<\/strong><\/pre>\n<p>Then allow unprivileged containers to access the host&#8217;s virtual network resources (see before and after), and start the CT again:<\/p>\n<pre>ls -l \/dev\/net\/tun\r\nchown 100000:100000 \/dev\/net\/tun\r\nls -l \/dev\/net\/tun\r\npct start 103<\/pre>\n<p>From the CT console, check whether a new interface (<strong>tun0<\/strong>) appears:<\/p>\n<pre>ip a<\/pre>\n<p>The VPN tunnel may be up and reachable from the OpenWrt server, but LAN clients will not have internet access yet.<\/p>\n<p>Go back to the web UI and navigate to <strong>Network &gt; Interfaces &gt; &#8220;Add new interface&#8230;&#8221;<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3311\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-24-08-31-00.png\" alt=\"\" width=\"909\" height=\"425\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-24-08-31-00.png 909w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-24-08-31-00-300x140.png 300w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-24-08-31-00-768x359.png 768w\" sizes=\"auto, (max-width: 909px) 100vw, 909px\" \/><\/p>\n<p>Edit the new interface and on the <strong>Firewall Settings<\/strong> tab, assign it to the <strong>WAN<\/strong> firewall zone.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3312\" src=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-24-08-32-08.png\" alt=\"\" width=\"909\" height=\"226\" srcset=\"https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-24-08-32-08.png 909w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-24-08-32-08-300x75.png 300w, https:\/\/dft.wiki\/wp-content\/uploads\/sites\/15\/2023\/01\/Screenshot-from-2023-01-24-08-32-08-768x191.png 768w\" sizes=\"auto, (max-width: 909px) 100vw, 909px\" \/><\/p>\n<p>Ping an external address to test connectivity, and also verify DNS resolution. If your OpenVPN configuration includes &#8220;block-outside-dns&#8221;, DNS queries outside the tunnel will be blocked to prevent leaks. In that case, consider using a custom DNS server instead.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>OpenWrt [Link] is an open-source lightweight firmware originally created for embedded devices such as routers [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,1],"tags":[],"class_list":["post-3271","post","type-post","status-publish","format-standard","hentry","category-linux","category-ccna"],"_links":{"self":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/3271","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3271"}],"version-history":[{"count":11,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/3271\/revisions"}],"predecessor-version":[{"id":5656,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/3271\/revisions\/5656"}],"wp:attachment":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3271"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3271"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3271"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}