├── .gitignore ├── LICENSE ├── README.md ├── figures ├── lxc_network_openwrt.png └── virtual_router_openwrt.png └── init.sh /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | cache 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Alex Athanasopoulos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### Synopsis 4 | 5 | Enable OpenWrt to run on LXD (Linux Containers), enabling full routing, firewall and IPv6 capability while creating virtual networks within LXD. 6 | 7 | 8 | This does not require rebuilding or compiling. Because of that, it should support *any* processor type including ARM. 9 | 10 | 11 | ![Virtual Network](https://raw.githubusercontent.com/cvmiller/openwrt-lxd/master/figures/lxc_network_openwrt.png) 12 | 13 | #### Update: 19.07 release no longer requires `init.sh` 14 | 15 | Although OpenWrt 19.07 has not been released (as of Sept 2019), it is possible to run a 19.07 snapshot image in LXD. OpenWrt makes **armvirt** rootfs snapshots available. Download the [armvirt32 rootfs snapshot](https://downloads.openwrt.org/snapshots/targets/armvirt/32/), and create an LXD image following the steps below. 16 | 17 | 19.07 fixes the procd bug which prevented OpenWrt from fully booting. Therefore, `init.sh` script is no longer required to run OpenWrt 19.07 in LXD containers. 18 | 19 | The rootfs snapshot does not include the web-based LuCI management tool. To install LuCI with `opkg`: 20 | 21 | ``` 22 | opkg update 23 | opkg install luci 24 | ``` 25 | 26 | 27 | ### Benefits of using OpenWrt & LXD 28 | 29 | The benefits of a virtual OpenWrt Router are: 30 | * Full IPv4/IPv6 firewall - protecting the containers behind it, thus reducing the threat surface 31 | * Excellent IPv6 support, including DHCPv6-PD (Prefix Delegation) which allows automatic IPv6 prefix (think: subnet) on the lxdbr0 bridge 32 | * Full routing protocol support via `bird` and `bird6` (see [RIPng the forgotten routing protocol](http://www.makikiweb.com/ipv6/ripng.html) ) 33 | 34 | The benifits of using LXD are: 35 | * Excellent networking support for both IPv4 and IPv6. Any container can connect to any bridge on the host 36 | * Containerized applications, once configured are very easy to roll out 37 | * Containers launch quickly 38 | * Snapshots & Migration, it is possible to back up your container or migrate the container to another host with a one line command 39 | 40 | ### Motivation 41 | 42 | OpenWrt project does an excellent job of creating images for hundreds of routers. I wanted to take a generic existing image and make it work on LXD **without recompiling, or building OpenWrt from source**. 43 | 44 | Additionally, I wanted it to run on a Raspberry Pi (ARM processor). Most implementations of OpenWrt in virtual environments run on x86 machines. 45 | 46 | If you would rather build OpenWrt, please see the github project [https://github.com/mikma/lxd-openwrt](https://github.com/mikma/lxd-openwrt) (x86 support only) 47 | 48 | ### Installing LXD on the Raspberry Pi 49 | 50 | Unfortunately the default Raspian image does not support name spaces or cgroups which are used to isolate the Linux Containers. Fortunately, there is an [Unofficial Ubuntu 18.04](https://www.finnie.org/software/raspberrypi/ubuntu-rpi3/ubuntu-18.04-preinstalled-server-armhf+raspi3.img.xz) image available for the Pi which does. Be sure to follow the login directions on the [ARM Ubuntu Page](https://wiki.ubuntu.com/ARM/RaspberryPi#First_boot_.28Username.2FPassword.29) 51 | 52 | **Additionally** follow the steps to [boot the unofficial image on the **Raspberry 3B+**](https://wiki.ubuntu.com/ARM/RaspberryPi#Booting_the_official_Pi_2_image_on_the_Pi_3B.2F3B.2B-). Be sure to update the `config.txt` file and update the bootloader files. The **Raspsberry 3B** can boot the unofficial image without these extra steps. 53 | 54 | 55 | LXD binaries are already installed on the image, but `lxd init` must still be run. If you are not familiar with LXD, please look at [Linux Containers on the Pi](http://www.makikiweb.com/Pi/lxc_on_the_pi.html) blog post. 56 | 57 | ### Creating a LXD Image 58 | 59 | **NOTE:** Unless otherwise stated, all commands are run on the Raspberry Pi 60 | 61 | Using `lxc image import` an image can pulled into LXD. The steps are: 62 | 1) Download the OpenWrt rootfs tarball 63 | 2) Create a metadata.yaml file, and place into a tar file 64 | 3) Import the rootfs tarball and metadata tarball to create an image 65 | 66 | #### Getting OpenWrt rootfs 67 | 68 | The OpenWrt project not only provides squashfs and ext4 images, but also simple tar.gz files of the rootfs. The current release is 18.06.2, and I recommend starting with it. 69 | 70 | The **ARM-virt** rootfs tarball can be found at [OpenWrt](https://downloads.openwrt.org/releases/18.06.2/targets/armvirt/32/) 71 | 72 | Download the OpenWrt 18.06.2 [rootfs tarball for Arm](https://downloads.openwrt.org/releases/18.06.2/targets/armvirt/32/openwrt-18.06.2-armvirt-32-default-rootfs.tar.gz). 73 | 74 | The **x86** rootfs is [here](https://downloads.openwrt.org/releases/18.06.2/targets/x86/generic/) 75 | 76 | 77 | #### Create a `metadata.yaml` file 78 | 79 | Although the yaml file can contain quite a bit of information the minimum requirement is **architecture** and **creation_date**. Use your favourite editor to create a file named **metadata.yaml** 80 | 81 | ``` 82 | architecture: "armhf" 83 | creation_date: 1544922658 84 | ``` 85 | The creation date is the current time (in seconds) since the unix epoch (1 Jan 1970). Easiest way to get this value it to find it on the web, such as the [EpochConverter](https://www.epochconverter.com/) 86 | 87 | Once the `metadata.yaml` file is created, tar it up and name it anything that makes sense to you. 88 | 89 | ``` 90 | tar cvf openwrt-meta.tar metadata.yaml 91 | ``` 92 | 93 | #### Import the image into LXD 94 | 95 | Place both tar files (metadata & rootfs) in the same directory on the Raspberry Pi. And use the following command to import the image: 96 | 97 | ``` 98 | lxc image import openwrt-meta.tar default-root.tar.gz --alias openwrt_armhf 99 | ``` 100 | 101 | ### Starting up Virtual OpenWrt 102 | 103 | Unfortunately, the OpenWrt image won't boot with the imported image. So a helper script has been developed to create devices in `/dev` before OpenWrt will boot properly. 104 | 105 | The steps to get your virtual OpenWrt up and running are: 106 | 1) Create the container 107 | 2) Adjust some of the parameters of the container 108 | 3) Copy the `init.sh` script to `/root` on the image 109 | 4) Log into the OpenWrt container and execute `sh init.sh` 110 | 5) Validate that OpenWrt has completed booting 111 | 112 | #### Create the OpenWrt Container 113 | 114 | I use `router` as the name of the OpenWrt container 115 | ``` 116 | lxc init local:openwrt_armhf router 117 | lxc config set router security.privileged true 118 | ``` 119 | In order for `init.sh` to run the `mknod` command the container must run as *privileged*. 120 | 121 | #### Adjust some parameters for the OpenWrt container 122 | 123 | Since this is going to be a router, it is useful to have two interfaces (for WAN & LAN), and therefore a profile for this network config must be created. Create the profile, and edit to match the config below (assuming you have `br0` as a WAN and `lxdbr0` as LAN). 124 | 125 | ``` 126 | lxc profile create twointf 127 | lxc profile edit twointf 128 | config: {} 129 | description: 2 interfaces 130 | devices: 131 | eth0: 132 | name: eth0 133 | nictype: bridged 134 | parent: lxdbr0 135 | type: nic 136 | eth1: 137 | name: eth1 138 | nictype: bridged 139 | parent: br0 140 | type: nic 141 | root: 142 | path: / 143 | pool: default 144 | type: disk 145 | name: twointf 146 | ``` 147 | And then edit the `router` container to have 2 interfaces. The only line you need to add is the **eth1** line, and be sure to have a unique MAC address (or just increment the eth0 MAC). You base_image id will be different. 148 | 149 | ``` 150 | lxc config edit router 151 | architecture: armv7l 152 | config: 153 | image.architecture: armhf 154 | image.description: 'OpenWrt 18.06.2 from armvirt/32 ' 155 | image.os: openwrt 156 | image.release: 18.06.2 157 | raw.lxc: lxc.apparmor.profile=unconfined 158 | security.privileged: "true" 159 | volatile.base_image: eae3ea75333699a733ecb9f1e134fdad99e44416a4757e372ecc6950b2de3bfa 160 | volatile.eth0.hwaddr: 00:16:3e:72:44:b5 161 | volatile.eth1.hwaddr: 00:16:3e:72:44:b6 162 | volatile.idmap.base: "0" 163 | volatile.idmap.next: '[]' 164 | volatile.last_state.idmap: '[]' 165 | volatile.last_state.power: RUNNING 166 | devices: {} 167 | ephemeral: false 168 | profiles: 169 | - twointf 170 | stateful: false 171 | description: "" 172 | ``` 173 | Now assign the `twointf` profile to the `router` container, and remove the default profile (which only has one interface) 174 | 175 | ``` 176 | lxc profile assign router twointf 177 | lxc profile remove router default 178 | ``` 179 | 180 | #### Copy the `init.sh` to the OpenWrt container 181 | 182 | In order to use the `lxc push` command the container must be running, so we'll restart it. 183 | 184 | ``` 185 | lxc start router 186 | ``` 187 | 188 | Then copy the `init.sh script to the container 189 | 190 | ``` 191 | lxc file push init.sh router/root/ 192 | ``` 193 | 194 | #### Log into the OpenWrt container and execute the `init.sh` script 195 | 196 | With the container started, the OpenWrt container boot will stall after running `procd` (think `init` in linux). By running `init.sh` the boot process will continue, and OpenWrt should be up and running. 197 | 198 | Log into the `router` container using the `lxc exec` command, and run the init.sh script. 199 | 200 | ``` 201 | lxc exec router sh 202 | # 203 | # sh init.sh 204 | wait.. 205 | wait.. 206 | wait.. 207 | wait.. 208 | 508 209 | Chain INPUT (policy ACCEPT) 210 | target prot opt source destination 211 | 212 | ... 213 | Chain FORWARD (policy ACCEPT) 214 | target prot opt source destination 215 | 216 | Chain OUTPUT (policy ACCEPT) 217 | target prot opt source destination 218 | Warning: Unable to locate ipset utility, disabling ipset support 219 | * Flushing IPv4 filter table 220 | * Flushing IPv6 filter table 221 | * Populating IPv4 filter table 222 | ... 223 | * Zone 'lan' 224 | * Zone 'wan' 225 | * Populating IPv6 filter table 226 | ... 227 | * Zone 'lan' 228 | * Zone 'wan' 229 | * Set tcp_ecn to off 230 | * Set tcp_syncookies to on 231 | * Set tcp_window_scaling to on 232 | * Running script '/etc/firewall.user' 233 | ~ # 234 | ``` 235 | 236 | #### Validating OpenWrt is up and running 237 | 238 | You can see if OpenWrt is up and running by looking at the processes. An unhappy container will only have three. A happy container will have about 12. Type `ps` inside the container should look like this: 239 | 240 | ``` 241 | ~ # ps 242 | PID USER VSZ STAT COMMAND 243 | 1 root 1324 S /sbin/procd 244 | 78 root 1064 S sh 245 | 107 root 1000 S /sbin/ubusd 246 | 196 root 1016 S /sbin/logd -S 64 247 | 213 root 1328 S /sbin/rpcd 248 | 322 root 1512 S /sbin/netifd 249 | 357 root 1228 S /usr/sbin/odhcpd 250 | 409 root 828 S /usr/sbin/dropbear -F -P /var/run/dropbear.1.pid -p 22 -K 300 -T 3 251 | 467 root 820 S odhcp6c -s /lib/netifd/dhcpv6.script -Ntry -P0 -t120 eth1 252 | 469 root 1064 S udhcpc -p /var/run/udhcpc-eth1.pid -s /lib/netifd/dhcp.script -f -t 0 -i eth1 -x hostname:router 253 | 508 root 1116 S /usr/sbin/uhttpd -f -h /www -r OpenWrt -x /cgi-bin -t 60 -T 30 -k 20 -A 1 -n 3 -N 100 -R -p 0.0. 254 | 850 dnsmasq 1152 S /usr/sbin/dnsmasq -C /var/etc/dnsmasq.conf.cfg01411c -k -x /var/run/dnsmasq/dnsmasq.cfg01411c.pi 255 | 1191 root 1064 R ps 256 | 257 | ``` 258 | 259 | Additionally, if you have *connected* the router up the right way (e.g. WAN=eth1/br0 LAN=eth0,lxdbr0) then your addressing should look something like this: 260 | 261 | ``` 262 | ~ # ip addr 263 | 1: lo: mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 264 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 265 | inet 127.0.0.1/8 scope host lo 266 | valid_lft forever preferred_lft forever 267 | inet6 ::1/128 scope host 268 | valid_lft forever preferred_lft forever 269 | 2: br-lan: mtu 1500 qdisc noqueue state UP qlen 1000 270 | link/ether 00:16:3e:72:44:b5 brd ff:ff:ff:ff:ff:ff 271 | inet 192.168.1.1/24 brd 192.168.1.255 scope global br-lan 272 | valid_lft forever preferred_lft forever 273 | inet6 fd6a:c19d:b07:2084::1/62 scope global 274 | valid_lft forever preferred_lft forever 275 | inet6 2001:db8:ebbd:2084::1/62 scope global 276 | valid_lft forever preferred_lft forever 277 | inet6 fd4b:7e4:111::1/60 scope global 278 | valid_lft forever preferred_lft forever 279 | inet6 fe80::216:3eff:fe72:44b5/64 scope link 280 | valid_lft forever preferred_lft forever 281 | 85: eth0@if86: mtu 1500 qdisc noqueue master br-lan state UP qlen 1000 282 | link/ether 00:16:3e:72:44:b5 brd ff:ff:ff:ff:ff:ff 283 | 87: eth1@if88: mtu 1500 qdisc noqueue state UP qlen 1000 284 | link/ether 00:16:3e:72:44:b6 brd ff:ff:ff:ff:ff:ff 285 | inet 192.168.215.198/24 brd 192.168.215.255 scope global eth1 286 | valid_lft forever preferred_lft forever 287 | inet6 fd6a:c19d:b07:2080:216:3eff:fe72:44b6/64 scope global 288 | valid_lft forever preferred_lft forever 289 | inet6 2001:db8:ebbd:2080:216:3eff:fe72:44b6/64 scope global 290 | valid_lft forever preferred_lft forever 291 | inet6 fd6a:c19d:b07:2080::93b/128 scope global 292 | valid_lft forever preferred_lft forever 293 | inet6 2001:db8:ebbd:2080::93b/128 scope global 294 | valid_lft forever preferred_lft forever 295 | inet6 fe80::216:3eff:fe72:44b6/64 scope link 296 | valid_lft forever preferred_lft forever 297 | ~ # 298 | 299 | ``` 300 | 301 | ### Managing the Virtual OpenWrt router 302 | 303 | The LuCI web interface by default is blocked on the WAN interface. However it is the easiest way to manage the `router`. A firewall rule allowing web access from the WAN must be inserted. 304 | 305 | The standard way it to add the following to bottom of the `/etc/config/firewall` file within the OpenWrt container. 306 | 307 | ``` 308 | lxc exec router sh 309 | 310 | # vi /etc/config/firewall 311 | 312 | ... 313 | config rule 314 | option target 'ACCEPT' 315 | option src 'wan' 316 | option proto 'tcp' 317 | option dest_port '80' 318 | option name 'ext_web' 319 | ``` 320 | Save the file and then restart the firewall within the OpenWrt container. 321 | 322 | ``` 323 | /etc/init.d/firewall restart 324 | ``` 325 | 326 | Now you should be able to point your web browser to the WAN address (see eth1 above). and login, password is blank. 327 | 328 | ``` 329 | http://[2001:db8:ebbd:2080::93b]/ 330 | ``` 331 | Follow the instructions to set a password. 332 | 333 | ![OpenWrt Web GUI](https://raw.githubusercontent.com/cvmiller/openwrt-lxd/master/figures/virtual_router_openwrt.png) 334 | 335 | 336 | ### Looking at the Virtual OpenWrt from LXC 337 | 338 | Type `exit` to return to the Raspberry Pi prompt. By looking at some `lxc` output, we can see the virtual network up and running. 339 | 340 | ``` 341 | $ lxc ls 342 | +---------+---------+------------------------+-----------------------------------------------+------------+-----------+ 343 | | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | 344 | +---------+---------+------------------------+-----------------------------------------------+------------+-----------+ 345 | | docker1 | RUNNING | 192.168.215.220 (eth0) | fd6a:c19d:b07:2080:216:3eff:fe58:1ac9 (eth0) | PERSISTENT | 0 | 346 | | | | 172.17.0.1 (docker0) | fd4b:7e4:111:0:216:3eff:fe58:1ac9 (eth0) | | | 347 | | | | | 2001:db8:ebbd:2080:216:3eff:fe58:1ac9 (eth0) | | | 348 | +---------+---------+------------------------+-----------------------------------------------+------------+-----------+ 349 | | router | RUNNING | 192.168.215.198 (eth1) | fd6a:c19d:b07:2084::1 (br-lan) | PERSISTENT | 1 | 350 | | | | 192.168.1.1 (br-lan) | fd6a:c19d:b07:2080::8d1 (eth1) | | | 351 | | | | | fd6a:c19d:b07:2080:216:3eff:fe72:44b6 (eth1) | | | 352 | | | | | fd4b:7e4:111::1 (br-lan) | | | 353 | | | | | fd4b:7e4:111:0:216:3eff:fe72:44b6 (eth1) | | | 354 | | | | | 2001:db8:ebbd:2084::1 (br-lan) | | | 355 | | | | | 2001:db8:ebbd:2080::8d1 (eth1) | | | 356 | | | | | 2001:db8:ebbd:2080:216:3eff:fe72:44b6 (eth1) | | | 357 | +---------+---------+------------------------+-----------------------------------------------+------------+-----------+ 358 | | www | RUNNING | 192.168.1.158 (eth0) | fd6a:c19d:b07:2084:216:3eff:fe01:e0a3 (eth0) | PERSISTENT | 0 | 359 | | | | | fd4b:7e4:111:0:216:3eff:fe01:e0a3 (eth0) | | | 360 | | | | | fd42:dc68:dae9:28e9:216:3eff:fe01:e0a3 (eth0) | | | 361 | | | | | 2001:db8:ebbd:2084:216:3eff:fe01:e0a3 (eth0) | | | 362 | +---------+---------+------------------------+-----------------------------------------------+------------+-----------+ 363 | 364 | ``` 365 | 366 | The `docker1` container is still running from [Linux Containers on the Pi](http://www.makikiweb.com/Pi/lxc_on_the_pi.html), and still connected to the *outside* network **br0**. You can see this by the addressing assigned (both v4 and v6). 367 | 368 | The `router` container (which is running OpenWrt) has both **eth1** (aka WAN) and **br-lan** (aka LAN) interfaces. The **br-lan** interface is connected to the *inside* **lxdbr0** virtual network. And OpenWrt routes between the two networks. 369 | 370 | Lastly the `www` container is just another instantiation of the web container (created in [Linux Containers on the Pi](http://www.makikiweb.com/Pi/lxc_on_the_pi.html)), but connected to the *inside* network. It was started with the following command: 371 | 372 | ``` 373 | lxc launch -p default local:web_image www 374 | ``` 375 | 376 | 377 | #### Managing the OpenWrt Firewall 378 | 379 | In order to permit access to webservers, a firewall rule on the virtual OpenWrt must allow the traffic. Add a new **rule** to allow port 80 traffic to pass to any host on the *inside* network (the lxdbr0 bridge) using the Web GUI (LuCI). 380 | 381 | 382 | 383 | ### OpenWrt LXD testing 384 | 385 | The `init.sh` script has been tested with LXD 3.0.2 and OpenWrt 18.06.2 on a Raspberry Pi 3B & 3B+ running 4.15.0-1030-raspi2 #31-Ubuntu 386 | 387 | 388 | ### Limitations 389 | 390 | Not everything is perfect, even in the virtual world. There are some limitations to running OpenWrt in a Linux Container. 391 | 392 | * As of version 0.93, ssh if fixed (on Pi 3B+). Login via ssh normally `ssh root@` 393 | * Prior to v0.93, ssh is tricky. Must use the `ssh root@ "/bin/sh" -i` 394 | * But you can continue to use scp, rsync, and run non-interactive commands with ssh. 395 | 396 | * `init.sh` doesn't run at boot. Haven't figured out how to do this yet, since the boot stalls very early in the process. (it is reported that in the next version of OpenWrt, `procd` will fix this problem, and `init.sh` will no longer be unnecessary) 397 | 398 | * Container will not **stop** via the `lxc stop` command. You must use: 399 | * `lxc stop --force router` or 400 | * `lxc exec router -- halt` 401 | 402 | * If you took all the defaults when running `lxd init` then lxd will have a DHCP4 server running on the bridge `lxdbr0`. Downstream containers may not get the correct IPv4 address. DHCP4 on LXD can be disabled with `lxc network set lxdbr0 ipv4.address none` 403 | 404 | * wireless interfaces don't work. What is a virtual wireless interface anyway? 405 | 406 | 407 | 408 | ### Contributors 409 | 410 | Thanks to **melato** for pointing me on the right path. Thanks also to **gjedeer** for the ssh fix. All current code by Craig Miller cvmiller at gmail dot com. But ideas, and ports to other embedded platforms beyond the Raspberry Pi are welcome. 411 | 412 | ### License 413 | 414 | This project is open source, under the MIT license (see [LICENSE](https://github.com/cvmiller/openwrt-lxd/blob/master/LICENSE)) 415 | 416 | 417 | 418 | 419 | 420 | -------------------------------------------------------------------------------- /figures/lxc_network_openwrt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvmiller/openwrt-lxd/bc09dc7ebf4f2904a9b717ed8a8a4065b5f8aaa5/figures/lxc_network_openwrt.png -------------------------------------------------------------------------------- /figures/virtual_router_openwrt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cvmiller/openwrt-lxd/bc09dc7ebf4f2904a9b717ed8a8a4065b5f8aaa5/figures/virtual_router_openwrt.png -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Original script by: melato 4 | # 5 | # Modified by Craig Miller 6 | # December 2018 7 | 8 | VERSION="0.94" 9 | 10 | usage() { 11 | echo " $0 - complete LXD OpenWrt boot " 12 | echo " e.g. $0 -m" 13 | echo " -m use mount /dev method (default: use mknod)" 14 | echo " -h this help" 15 | echo " " 16 | echo " By Craig Miller - Version: $VERSION" 17 | exit 1 18 | } 19 | 20 | # show help 21 | if [ "$1" == "-h" ]; then 22 | usage 23 | fi 24 | 25 | # use gjedeer "mount /dev" method 26 | if [ "$1" == "-m" ]; then 27 | # 8 May 2019 28 | # 29 | # gjedeer found a simpler way to get openwrt to complete the boot process 30 | # 31 | # mount /dev 32 | mount -t devtmpfs devtmpfs /dev 33 | 34 | else 35 | # use "old" way of making nodes 36 | 37 | # make devices 38 | mknod -m 666 /dev/zero c 1 5 39 | mknod -m 666 /dev/full c 1 7 40 | mknod -m 666 /dev/random c 1 8 41 | mknod -m 666 /dev/urandom c 1 9 42 | mknod -m 666 /dev/null c 1 3 43 | # create node to make ssh login better -- gjedeer 44 | mknod -m 666 /dev/ptmx c 5 2 45 | 46 | # unmount /dev/pts in order to make nodes for ssh access 47 | umount /dev/pts 48 | # make pts devices (for ssh) 49 | mknod -m 666 /dev/pts/0 c 136 0 50 | mknod -m 666 /dev/pts/1 c 136 1 51 | # remount /dev/pts now that nodes are made 52 | mount -t devpts -o rw,nosuid,noexec,relatime,mode=600,ptmxmode=000 devpts /dev/pts 53 | 54 | fi 55 | 56 | 57 | # wait, let things startup 58 | echo "waiting for rest of boot up..." 59 | while ! pgrep uhttpd 60 | do 61 | echo "wait.." 62 | sleep 1 63 | done 64 | 65 | 66 | 67 | # kick iptables, so firewall will start 68 | ip6tables -L >/dev/null 69 | iptables -L >/dev/null 70 | 71 | # added all IPv4 tables by laigor 72 | for tt in nat mangle raw ; do 73 | /usr/sbin/ip6tables -t ${tt} -L >/dev/null 74 | /usr/sbin/iptables -t ${tt} -L >/dev/null 75 | done 76 | 77 | echo "Restarting Firewall" 78 | # clear and restart firewall 79 | /etc/init.d/firewall restart 80 | 81 | # show result 82 | #ip6tables -L 83 | 84 | 85 | # insert NAT44 iptables rule if using IPv4, firewall fails to insert this rule 86 | WAN=$(uci get network.wan.ifname) 87 | if [ $(uci get firewall.@zone[1].masq) -eq 1 ]; then 88 | echo "Enabling IPv4 NAT" 89 | /usr/sbin/iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE 90 | fi 91 | 92 | echo "Pau!" 93 | 94 | --------------------------------------------------------------------------------