Hey! Listen! There are a few posts about installing OpenWrt on these travel routers. Make sure you’re reading the latest version, below.
Date | URL | Updates |
---|---|---|
2016-04-28 | OpenWrt upgrade process | |
2015-08-26 | OpenWrt with OpenVPN server on TP-Link Archer C7 | |
2015-02-15 | OpenWrt with OpenVPN client on TP-Link TL-MR3020 (rev 3) | |
2015-01-24 | OpenWrt with OpenVPN client on TP-Link TL-MR3020 (rev 2) | |
2014-10-19 | OpenWrt with OpenVPN client on TP-Link TL-MR3020 (rev 1) |
Contents
A few months ago, the team at OpenWrt released version 14.07 of OpenWrt, called Barrier Breaker. I’m going to be installing Barrier Breaker on my MR3020 and setting up an OpenVPN client. If you don’t know the difference between PPTP/IPSec/OpenVPN, IVPN has a great comparison chart.
The “why”
Before we get started, I need to get up on my soapbox and say a few things. If you’re not using a VPN, you should be. VPNs aren’t just for hackers, thieves, or people doing illegal things (you wouldn’t download a car, would you?). VPNs are great for:
- Adding a layer of security to your browsing (VPNs encrypt everything!)
- Securely connecting two routers to create one large network over the internet (businesses do this all the time)
- Students/employees connecting back to their university/office to work remotely (again, a common practice)
- Circumventing geoblocking (i.e., content blocked based on your physical location)
- Watch Netflix from outside the US
- Watch BBC iPlayer from outside the UK
- FREEDOM OF SPEECH! Use a VPN to circumvent government restrictions put on the internet (e.g., China, Iran, North Korea, etc…)
But, I digress. VPNs are great. If you don’t have one, get one. Personally, I like using Private Internet Access (I’m not compensated, just a happy customer). If you don’t know where to start, TorrentFreak has a great article on which VPN services take your anonymity seriously (newsflash, PIA is at the top of their list).
The “how”
My plan for this router is to use it when I travel. I plan on plugging it into the Ethernet port in a hotel (or my house/friend’s house/Airbnb host) and having it broadcast a wireless network. Since the router is an OpenVPN client, any devices that join that wireless network will be VPNed into PIA’s servers. Eventually, when I install OpenVPN on my home router, I can route my connection back home. It’s probably easier illustrated than explained, as below.
There are a few advantages to this setup, as opposed to installing the OpenVPN client on each device:
- Devices that don’t support OpenVPN can be protected (XBox, Roku, etc…)
- Multiple machines (phone, laptop, Roku, etc…) can share one VPN connection
- You can switch between an insecure wireless network (home/friend’s house/hotel) and a secure wireless network (OpenWrt) whenever needed
Ready? Let’s get started!
Install OpenWrt
I’m going to assume you’re already running Attitude Adjustment (AA) and want to upgrade to Barrier Breaker (BB).
Disconnect your PC from all wired and wireless networks, then connect your MR3020 to your PC. Because of the way I have this router setup from my previous post (eth0 is a DHCP client, not server), I’m going to connect to the WiFi network it’s broadcasting. I checked my IP, opened my browser, and navigated to 10.80.1.1 (your address will be 192.168.1.1 as stock). I then logged in with the username and password I had set before.
Once you’re logged into OpenWrt, go to the System tab, then the Backup/Flash Firmware tab. At this point, it’s a good idea to make a backup of your config by pressing Generate Archive.
As-of this writing, the OpenWrt wiki page for the MR3020 doesn’t list BB as the newest firmware. There are two options for the BB download: a file for the factory firmware, and a file for upgrading. We’ll choose the upgrade.
Back at your router, under Flash new firmware image, make sure Keep settings is checked to keep your current settings. I’m going to uncheck this, since I want to start from scratch. Browse to your downloaded firmware, and press Flash image to upgrade it.
Verify the checksum, and press Proceed to continue.
Wait a few minutes and the router will reboot. Check your IP again after it’s back up, as mine had changed since I erased my settings.
At this point, my MR3020 is running stock BB and I’m going to reconfigure it from scratch. Since the wireless network was wiped out, I’m going to reconnect with Ethernet.
Configure OpenWrt
From here, the OpenWrt wiki page recommends going through the basic configuration for any OpenWrt installation. I’m going to be combining some of the basic configuration with my configuration for the VPN client.
Navigate to 192.168.1.1 in your browser and you’ll be greeted by LuCI, the web interface for OpenWrt. OpenWrt recently switched to the Unified Configuration Interface, also known as UCI. The UCI is basically a collection of easy-to-read configuration files that are all centrally located, making OpenWrt much easier to configure. What’s nice about LuCI is that it reads/writes from/to the UCI files. Any changes you make in LuCI are reflected in the UCI files, and vice versa, meaning you can configure the MR3020 from the web interface, or from the command line.
Anyway, moving on. Leave the username as “root” and the password field empty. Press Login to continue.
Set a password
From the main status screen, we’re going to set a root password by using the link in the yellow box at the top of the page. If you haven’t noticed, LuCI is a lot easier on the eyes in BB than AA.
Here, you can (and should) set a root password, as well as setup SSH access (which we’ll need later). Press Save & Apply to continue.
Look for Password successfully changed! at the top of the screen.
Verify SSH access by using PuTTY or another SSH client.
[logan@Arch ~]$ ssh root@192.168.1.1 root@192.168.1.1's password: BusyBox v1.22.1 (2014-09-20 22:01:35 CEST) built-in shell (ash) Enter 'help' for a list of built-in commands. _______ ________ __ | |.-----.-----.-----.| | | |.----.| |_ | - || _ | -__| || | | || _|| _| |_______|| __|_____|__|__||________||__| |____| |__| W I R E L E S S F R E E D O M ----------------------------------------------------- BARRIER BREAKER (14.07, r42625) ----------------------------------------------------- * 1/2 oz Galliano Pour all ingredients into * 4 oz cold Coffee an irish coffee mug filled * 1 1/2 oz Dark Rum with crushed ice. Stir. * 2 tsp. Creme de Cacao ----------------------------------------------------- root@OpenWrt:~#
Setup NTP
The MR3020 doesn’t have a real-time clock or CMOS battery. Because of this, every time it loses power, the clock resets to October 1st. To circumvent this, we’re going to use NTP to get our time from the internet. You don’t have to setup NTP, but it makes troubleshooting easier when you’re looking at timestamped log files. Keep in mind, since the MR3020 is connected directly to your PC (not the internet), this won’t take effect until after we get it online. Don’t freak out if it’s not working right away.
First, set a hostname, zone name, and time zone for your router. The list of zone names/time zones can be found here. Make note of the tick marks around the zonename.
uci set system.@system[0].hostname=mr3020_home uci set system.@system[0].zonename='America/New York' uci set system.@system[0].timezone=EST5EDT,M3.2.0,M11.1.0 uci commit system
Next, we’re going to enable the NTP client. I’m using US servers from the NTP Pool Project, but change your servers as needed. Again, don’t forget the tick marks.
uci set system.ntp=timeserver uci set system.ntp.enabled=1 uci delete system.ntp.server uci add_list system.ntp.server='0.us.pool.ntp.org' uci add_list system.ntp.server='1.us.pool.ntp.org' uci add_list system.ntp.server='2.us.pool.ntp.org' uci add_list system.ntp.server='3.us.pool.ntp.org' uci commit system
Set default IP
Next, we’re going to change the default IP of the router from 192.168.1.1 to 10.80.1.1 (or whatever scheme you want). Most devices ship with 192.168.1.1 as the default, and since we’re going to be double-NATed, we can’t have two identical IPs on the same network.
uci set network.lan.ipaddr=10.80.1.1 uci commit network
You can also limit the number of addresses available in the DHCP pool (optional).
uci set dhcp.lan.start=10 uci set dhcp.lan.limit=20 uci commit dhcp /etc/init.d/network restart
Log back into the web interface at the new address using your new root password.
Create wireless network
We need to create a wireless network for the MR3020 to broadcast. Eventually, we’re going to turn off LAN access on the Ethernet port, and we’ll need a way to connect to the router locally.
Start by enabling wireless. At this point, you should be able to see the default OpenWrt network from a device.
uci delete wireless.radio0.disabled uci commit wireless /etc/init.d/network restart
Once enabled, setup your network as needed (name, channel, etc…).
uci set wireless.radio0.channel=11 uci set wireless.radio0.txpower=18 uci set wireless.radio0.country=US uci set wireless.@wifi-iface[0].ssid='Aw yiss' uci commit wireless
You should secure your network and choose a strong password (preferably WPA2-PSK with AES). Remember, this device may be a direct link back to your home network. Even if you have a strong VPN password, a weak WiFi password with weak encryption (e.g., WEP) could compromise your network.
uci set wireless.@wifi-iface[0].encryption='psk2+ccmp' uci set wireless.@wifi-iface[0].key='wirelesspasswordgoeshere' uci commit wireless /etc/init.d/network restart
At this point, you should disconnect the Ethernet cable from the MR3020 and connect to the WiFi network we just setup. Normally, it’s not recommended to configure routers over wireless, but since we’re not going to be transferring files or upgrading firmware, we should be ok.
Setup WAN interface
We need the MR3020 to request an IP address from another router when it is plugged in. For this, we’ll need to make a new interface that will act as a DHCP client. Name the interface something like WAN, with the protocol being set to DHCP client, covering the eth0 interface.
uci set network.WAN=interface uci set network.WAN.proto=dhcp uci set network.WAN.ifname=eth0 uci commit network
On the next screen, under Common Configuration, go to the Firewall Settings tab and select WAN. Press Save & Apply to continue.
uci set firewall.@zone[1].network='wan wan6 WAN' uci commit firewall /etc/init.d/network restart /etc/init.d/firewall restart
Unbridge LAN interfaces
By default, the wired and wireless interfaces are bridged. I want them to be separate, so that I can plug the wired interface into another router and use the wireless interface to broadcast a network. Essentially, I making it so that only another router can use the Ethernet port, and only clients can use the wireless network.
uci delete network.lan.ifname uci delete network.lan.type uci commit network /etc/init.d/network restart
If you don’t unbridge the interfaces, you’ve basically just created a wireless AP for the other router.
Verify internet access
At this point, plug your MR3020 into a LAN port on your other router, and connect your PC to the MR3020’s wireless network. It doesn’t matter what IP your MR3020 gets from the other router, as your PC should see the MR3020 as 10.80.1.1 (or whatever your made it).
You should be able to access the internet, as well as ping websites through SSH. In addition, go to the Status dropdown, then select Overview to make sure your Local Time field is updated with the correct time, now that we’re on the internet.
Congratulations, you are now double-NATed.
Configure extroot
Before we get started, we need to make some space for OpenVPN. The MR3020 only has 4MB of flash. After OpenWrt is installed, we’re only left with about 400KB, which won’t be enough for the 600KB+ of OpenSSL libraries we’ll need, in addition to other packages that will make life easier.
root@OpenWrt:~# df -h Filesystem Size Used Available Use% Mounted on rootfs 640.0K 228.0K 412.0K 36% / /dev/root 2.3M 2.3M 0 100% /rom tmpfs 14.1M 448.0K 13.7M 3% /tmp /dev/mtdblock3 640.0K 228.0K 412.0K 36% /overlay overlayfs:/overlay 640.0K 228.0K 412.0K 36% / tmpfs 512.0K 0 512.0K 0% /dev
There are two ways around this:
- ExtRoot, which can either extend or move the root filesystem to a USB flash drive
- Build a custom image of OpenWrt from scratch, leaving out unnecessary packages
My first instinct was to build a custom image, leaving out PPP. However, after a few hours of trying and multiple images, it still didn’t give me the space I needed. The only way to get OpenVPN on the MR3020 would be to leave LuCI out of the image, and I’m not willing to give that up.
That leaves me with using a USB flash drive to extend or move the filesystem. Thankfully, setting up ExtRoot is pretty easy, and we won’t need a huge flash drive since we’re only after a few extra MB. I picked up this flash drive since it’s small.
Start by reading the theory on ExtRoot, then go over the how-to guide. You need to decide whether you’ll be using external overlay (also called pivot-overlay) or external root (also called pivot-root). Essentially, external overlay extends the root filesystem to include the flash drive, while external root copies the root filesystem to the flash drive, then boots from the flash drive. External root has a couple advantages (that I can see):
- You can boot from multiple flash drives, each with a different config (one flash drive with a config for home, another with a config for traveling, etc…)
- If the flash drive dies, OpenWrt still boots from the internal root filesystem (without all your configs)
In this guide, I’m going to be using external root.
Since my flash drive is 8GB, I’m going to give 1GB to OpenWrt and use the rest for a SAMBA share. Any device connected to my router will have access to the other ~6.5GB share. Get stared by formatting your flash drive with two ext4 partitions. I did this on my machine using GParted, but if you’re running Windows you can use this to format the drive. In this case, /dev/sda1 is 1GB and /dev/sda2 is the remaining ~6.5GB.
Next, SSH into your router, and install a few packages. You’ll need to install the kmod-fs package for the type of filesystem that you’re using (e.g., kmod-fs-ext4, kmod-fs-ext3, kmod-fs-btrfs, etc…)
opkg update opkg install block-mount kmod-usb-storage kmod-fs-ext4
There’s a good chance your kernel modules didn’t load. If that’s the case, reboot your router and then plug in your flash drive.
kmod: failed to insert /lib/modules/3.10.49/sd_mod.ko Configuring kmod-usb-storage. Configuring kmod-crypto-hash. Configuring kmod-lib-crc16. Configuring block-mount. Configuring kmod-fs-ext4. kmod: failed to insert /lib/modules/3.10.49/ext4.ko
Find the name of your flash drive with the block info command. Mine was /dev/sda. Notice there are two partitions on the drive.
root@mr3020_home:~# block info /dev/mtdblock2: UUID="20ad40ea-d33a421e-785b7d2d-ada99230" VERSION="4.0" TYPE="squashfs" /dev/mtdblock3: TYPE="jffs2" /dev/sda1: UUID="bf19ec66-8d6a-40d7-b366-f99f48cced33" NAME="EXT_JOURNAL" VERSION="1.0" TYPE="ext4" /dev/sda2: UUID="5ca298db-53d6-406c-9db3-344c2e5ebae8" NAME="EXT_JOURNAL" VERSION="1.0" TYPE="ext4"
Create two directories and mount /dev/sda1 and /dev/sda2 on them.
mkdir /mnt/batman mount /dev/sda1 /mnt/batman mkdir /mnt/network chmod -R 777 /mnt/network mount /dev/sda2 /mnt/network
Now, copy the router’s internal flash to the flash drive. Obviously, replace /mnt/batman with whatever mount point you’re using.
mkdir -p /tmp/cproot mount --bind / /tmp/cproot tar -C /tmp/cproot -cvf - . | tar -C /mnt/batman -xf - umount /tmp/cproot
Your flash drive now has a copy of the router’s root filesystem on it (so don’t lose it). However, the router will still boot from its internal memory, so we need to change that by editing the /etc/config/fstab file. In addition to that, we’re also creating an extra entry for our SAMBA fileshare.
cat >> /etc/config/fstab << EOF config 'mount' option target / option device /dev/sda1 option fstype ext4 option options rw,sync option enabled 1 option enabled_fsck 0 config 'mount' option target /mnt/network option device /dev/sda2 option fstype ext4 option options rw,sync option enabled 1 option enabled_fsck 1 EOF
Reboot your router. When it starts up, check your mount points and you should see that /dev/sda1 has been mounted on /, while /dev/sda2 has been mounted on /mnt/network.
oot@mr3020_home:~# mount rootfs on / type rootfs (rw) /dev/root on /rom type squashfs (ro,noatime) proc on /proc type proc (rw,noatime) sysfs on /sys type sysfs (rw,noatime) tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime) /dev/sda1 on / type ext4 (rw,relatime,data=ordered) tmpfs on /dev type tmpfs (rw,relatime,size=512k,mode=755) devpts on /dev/pts type devpts (rw,relatime,mode=600) /dev/sda2 on /mnt/network type ext4 (rw,sync,relatime,data=ordered) debugfs on /sys/kernel/debug type debugfs (rw,noatime)
If you check your space again, you’ll see that your root filesystem is now larger, and you have a second partition for SAMBA.
root@mr3020_home:~# df -h Filesystem Size Used Available Use% Mounted on rootfs 975.9M 10.5M 898.2M 1% / /dev/root 2.3M 2.3M 0 100% /rom tmpfs 14.1M 360.0K 13.7M 2% /tmp /dev/sda1 975.9M 10.5M 898.2M 1% / tmpfs 512.0K 0 512.0K 0% /dev /dev/sda2 6.2G 14.5M 5.9G 0% /mnt/network
Setup VPN
Now we need to install the OpenVPN client and configure it. The VPN termination point is going to be one of PIA’s servers, but it could be any OpenVPN server. You should read OpenWrt’s VPN overview, as well the OpenVPN beginner’s guide and the client guide.
First, we’ll need to install a couple packages: openvpn-openssl for obvious reasons, the real version of wget to downlad the configuration files from PIA, and unzip to unzip the downloaded files. This is easiest done by connecting through SSH and running the commands below.
opkg update opkg install openvpn-openssl wget unzip mv /etc/config/openvpn /etc/config/openvpn_old
Unfortunately, there is no LuCI package for OpenVPN in BB, like there is in AA. As-of this writing, the package luci-app-openvpn is marked as broken. There appears to be a package for Chaos Calmer, located here, but I don’t think that will work in BB. That means we’re doing everything from the command line, which isn’t as intimidating as it may sound. Plus, since LuCI runs from the UCI files, we’ll be able to see some of our changes in LuCI when we log back in.
We’ll need to create a new interface for the VPN by using the commands below. Name the network interface whatever you’d like, and name the physical (even though it’s virtual) interface tun0.
cat >> /etc/config/network << EOF config interface 'PIA_VPN' option proto 'none' option ifname 'tun0' EOF /etc/init.d/network restart
Download the OpenVPN configuration files from PIA.
cd /etc/openvpn wget --no-check-certificate https://www.privateinternetaccess.com/openvpn/openvpn.zip unzip openvpn.zip rm openvpn.zip
Now, we need to edit each .ovpn file in /etc/openvpn to include your username and password. However, it’s a pain editing every file manually. Instead, we’ll create a single file that stores your login credentials. The file I created is called authuser. Substitute your username and password, obviously.
cat >> /etc/openvpn/authuser << EOF PIA_USERNAME PIA_PASSWORD EOF
However, now we’ll have to go back and edit each .ovpn file to look for the authuser file, which is still too much work for me. If you look at each .ovpn file, you’ll see the only difference between them is the server address. What if we created a generic .ovpn connection file which omitted the server address (and port), but specified to use the authuser file? We could pass the server address and port as an option in our command to start the VPN connection.
Create the file with the command below. See how we removed the line for the server/port, and added a line for the authuser file and auth-nocache options?
cat >> /etc/openvpn/piageneric.ovpn << EOF client dev tun proto udp resolv-retry infinite nobind persist-key persist-tun ca ca.crt tls-client remote-cert-tls server auth-user-pass authuser auth-nocache comp-lzo verb 1 reneg-sec 0 crl-verify crl.pem keepalive 10 120 EOF
To compare, this is the US East.ovpn file…
client dev tun proto udp remote us-east.privateinternetaccess.com 1194 resolv-retry infinite nobind persist-key persist-tun ca ca.crt tls-client remote-cert-tls server auth-user-pass comp-lzo verb 1 reneg-sec 0 crl-verify crl.pem
Now, we need to create a new firewall zone for this VPN connection. This is actually the same config as the WAN zone, but it’s easier to make a new zone in case we need to change anything in the future. Name the firewall zone, and substitute the network interface name you created above. We’ll also be forwarding LAN traffic to the VPN.
cat >> /etc/config/firewall << EOF config zone option name 'VPN_FW' option input 'REJECT' option output 'ACCEPT' option forward 'REJECT' option masq '1' option mtu_fix '1' option network 'PIA_VPN' config forwarding option dest 'VPN_FW' option src 'lan' EOF /etc/init.d/network restart /etc/init.d/firewall restart
If you’d like, you can login to LuCI and see the new network interface, physical interface tun0, and firewall zone. Back on the command line, use the following command to start the VPN. Specify your generic configuration file and choose a server from PIA, as well as a port number.
openvpn --cd /etc/openvpn --config /etc/openvpn/piageneric.ovpn --remote us-east.privateinternetaccess.com 1194
If everything went well, you should see something like below, ending in Initialization Sequence Completed. If not, you did something wrong. Check your logs and start looking here.
root@mr3020_home:~# openvpn --cd /etc/openvpn --config /etc/openvpn/piag eneric.ovpn --remote us-east.privateinternetaccess.com 1194 Sat Jan 24 13:16:20 2015 OpenVPN 2.3.6 mips-openwrt-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [MH] [IPv6] built on Jan 6 2015 Sat Jan 24 13:16:20 2015 library versions: OpenSSL 1.0.1k 8 Jan 2015, LZO 2.08 Sat Jan 24 13:16:20 2015 WARNING: file 'authuser' is group or others accessible Sat Jan 24 13:16:20 2015 UDPv4 link local: [undef] Sat Jan 24 13:16:20 2015 UDPv4 link remote: [AF_INET]64.237.51.174:1194 Sat Jan 24 13:16:21 2015 [Private Internet Access] Peer Connection Initiated with [AF_INET]64.237.51.174:1194 Sat Jan 24 13:16:24 2015 TUN/TAP device tun0 opened Sat Jan 24 13:16:24 2015 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0 Sat Jan 24 13:16:24 2015 /sbin/ifconfig tun0 10.121.1.6 pointopoint 10.121.1.5 mtu 1500 Sat Jan 24 13:16:24 2015 Initialization Sequence Completed
Check ifconfig to see if you have a tunnel interface. If you do, that’s good!
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:10.121.1.6 P-t-P:10.121.1.5 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 RX packets:78 errors:0 dropped:0 overruns:0 frame:0 TX packets:102 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:10371 (10.1 KiB) TX bytes:83342 (81.3 KiB)
Next, try to get on the internet. If you can’t, there’s a good chance it’s a DNS issue. To resolve this, we’ll set our DNS servers on this connection to use PIA’s DNS servers. It looks like we can set the DNS servers for a specific interface, so we’ll add them for the LAN interface.
uci add_list dhcp.lan.dhcp_option="6,209.222.18.222,209.222.18.218" uci commit dhcp /etc/init.d/network restart
Now we should have DNS working, and since we’re using PIA VPN and PIA DNS servers, we shouldn’t have any DNS leaks either. After all, what’s the point of a VPN if your DNS leaks?
Restart your VPN connection and try it again! Check your IP with an external tool, like WhatIsMyIP, both on your local wireless network, as well as the OpenWrt network. You should see the difference, meaning you are successfully connected!
Before (on my local network)…After (VPNed in)…
Now is a good time to check for DNS leaks while on the VPN. Basically, we’re looking to make sure the server giving us our IP address is also providing DNS. If it’s not, then your ISP probably providing DNS, and they’re able to see every DNS request you make.
Note – A commenter found that his DNS was still leaking when set on the LAN interface. He suggested setting it on the WAN interface, as seen here.
Run at startup
If you’d like your VPN connection to run at startup, edit the /etc/rc.local file. Paste your connection string before exit 0. The ampersand tells OpenWrt not to output anything to the screen.
Before…
# Put your custom commands here that should be executed once # the system init finished. By default this file does nothing. exit 0
After…
# Put your custom commands here that should be executed once # the system init finished. By default this file does nothing. openvpn --cd /etc/openvpn --config /etc/openvpn/piageneric.ovpn --remote us-east.privateinternetaccess.com 1194 & exit 0
Setup SAMBA
Next, we need to setup the SAMBA share by installing the SAMBA packages. You’ll need to search opkg for the correct version of SAMBA server.
opkg update opkg list | grep -i samba opkg install luci-app-samba samba36-server /etc/init.d/samba enable /etc/init.d/samba start rm /tmp/luci-indexcache
Following the last step of this guide (thanks to commenter Ben for sending this in!), go to the Services dropdown, then select Network Shares. Under Samba, select a hostname.
Then, under Shared Directories, select Add. Here, specify a share name and path (in our case, /mnt/network), and select Allow guests. If you don’t want guest access, you’ll need to setup users as described here. Press Save & Apply to continue.
Connect to your router’s wireless network, then, in your file manager (assuming you’re using Linux, since this is a ext4 SAMBA share), navigate to your share name (e.g., smb://openwrt/box/).
Note – Your distro may not have a SAMBA client installed. On Arch Linux, I needed the smbclient and gvfs-smb packages.
Setup alerting scripts
The whole point of this build was to create a connection that is always on and safe for you to use. But, what if the VPN tunnel goes down? You’d still be able to pass traffic, but it would be over the regular internet, not the encrypted VPN connection. There are a couple ways around this, including putting a route in that denies traffic when not on the VPN, as well as setting up alerting scripts to let you know when the tunnel goes down. Here, I’ll be doing the latter.
On the The OpenVPN 2.3 man page, there are options called –up and –down, which as they sound, run scripts when the VPN tunnel comes up or goes down. Basically, we’re going to create a script to email us when the tunnel comes up, and another script that will run when the tunnel goes down, but we still have internet access. Obviously, if the tunnel goes down as a result of the router being powered off or the WAN connection dying, the email isn’t going to work. We’re also going to implement a third script that will run out of root’s crontab to check for VPN connection status every 10 minutes.
Setup email
First, we need to install msmtp.
opkg update opkg install msmtp
If it’s not set already, you need to set the msmtp config file to be R/W for your account only. It won’t function otherwise.
chmod 600 /etc/msmtprc cp -p /etc/msmtprc /etc/msmtprc_old
We need an external STMP server that we can use to route messages through. Luckily, Google provides one for free if you have a Gmail account. Obviously, I would advise against using your primary Gmail account for this. Setting up a dedicated Gmail account just for this application only takes a few minutes and is worth it, in my opinion. Google’s SMTP settings are here, we’ll need them later.
Next, we’re going to edit the config file at /etc/msmtprc to include our information. There is some pretty good documentation for msmtp over at SourceForge, so I won’t bother going over all the options below. Substitute your new Gmail username and password below.
Before…
# Example for a system wide configuration file # A system wide configuration file is optional. # If it exists, it usually defines a default account. # This allows msmtp to be used like /usr/sbin/sendmail. account default # The SMTP smarthost. host mailhub.oursite.example # Construct envelope-from addresses of the form "user@oursite.example". #auto_from on #maildomain oursite.example # Use TLS. #tls on #tls_trust_file /etc/ssl/certs/ca-certificates.crt # Syslog logging with facility LOG_MAIL instead of the default LOG_USER. syslog LOG_MAIL
After…
account default tls on tls_certcheck off logfile /etc/openvpn/msmtp.log auto_from on auth on host smtp.gmail.com protocol smtp port 587 user your_gmail_address@gmail.com password your_gmail_password syslog LOG_MAIL
Next, create three scripts in your /etc/openvpn folder and set permissions on them.
touch /etc/openvpn/vpndown.sh touch /etc/openvpn/vpnup.sh touch /etc/openvpn/vpncheck.sh chmod 700 /etc/openvpn/vpndown.sh chmod 700 /etc/openvpn/vpnup.sh chmod 700 /etc/openvpn/vpncheck.sh
vpndown.sh
The only difference between the vpnup.sh script and vpndown.sh script are the words UP and DOWN in the STATUS variable in each script. Replace your recipients as needed.
#!/bin/ash #2015-01-24 #Logan Marchione STATUS=DOWN HOSTNAME=`uci get system.@system[0].hostname` RECIPIENT="recipient@address.com" DAY=`date "+%A"` DATE=`date "+%Y-%m-%d"` TIME=`date "+%H:%M:%S"` EMAIL='Subject: VPN '$STATUS' on '$HOSTNAME' From: OpenWrt Monitor As of '$DAY', '$DATE' at '$TIME' the VPN tunnel on '$HOSTNAME' is '$STATUS'.' echo "$EMAIL" | msmtp -t $RECIPIENT
vpnup.sh
The only difference between the vpnup.sh script and vpndown.sh script are the words UP and DOWN in the STATUS variable in each script. Replace your recipients as needed.
#!/bin/ash #2015-01-24 #Logan Marchione STATUS=UP HOSTNAME=`uci get system.@system[0].hostname` RECIPIENT="recipient@address.com" DAY=`date "+%A"` DATE=`date "+%Y-%m-%d"` TIME=`date "+%H:%M:%S"` EMAIL='Subject: VPN '$STATUS' on '$HOSTNAME' From: OpenWrt Monitor As of '$DAY', '$DATE' at '$TIME' the VPN tunnel on '$HOSTNAME' is '$STATUS'.' echo "$EMAIL" | msmtp -t $RECIPIENT
Now, edit the /etc/openvpn/piageneric.ovpn file. Here, we’ve added the up and down options and specified the appropriate scripts. We’ve also added the up-restart option, which allows scripts to be called for restarts as well as initial program start. Finally, I’ve set script-security level to 2, which allows calling of built-in executables and user-defined scripts.
client dev tun proto udp resolv-retry infinite nobind persist-key persist-tun ca ca.crt tls-client remote-cert-tls server auth-user-pass authuser auth-nocache comp-lzo verb 1 up vpnup.sh down vpndown.sh script-security 2 up-restart reneg-sec 0 crl-verify crl.pem keepalive 10 120
vpncheck.sh
This script calls ifconfig and looks for an adapter called tun0. If your adapter name is different, replace it as needed. Replace the line that starts the VPN manually (the same command we used earlier) with your connection string.
#!/bin/ash #2015-01-24 #Logan Marchione RESULT=`ifconfig | awk '/^tun0/ {print $1;}'` DATETIME=`date "+%Y-%m-%d %H:%M:%S"` if [ "$RESULT" == tun0 ] then echo "$DATETIME - No restart needed" >> vpncheck.log& else echo "$DATETIME - Restart needed, see below" >> vpncheck.log& openvpn --cd /etc/openvpn --config piageneric.ovpn --remote us-east.privateinternetaccess.com 1194 >> vpncheck.log& fi
The vpncheck.sh script will need to run on a schedule, and for that, we’ll be using cron. First, we need to make a file for root’s crontab and then start crontab.
touch /etc/crontabs/root /etc/init.d/cron start /etc/init.d/cron enable
If you check logs…
logread
…you should see that cron was started.
Sat Jan 24 14:17:04 2015 cron.info crond[1526]: crond: crond (busybox 1.22.1) started, log level 5
Then, add your entry to crontab. Use the schedule below to setup your job.
#Crontab Schedule # +---------------- minute (0 - 59) *=all # | +------------- hour (0 - 23) *=all # | | +---------- day of month (1 - 31) *=all # | | | +------- month (1 - 12) *=all # | | | | +---- day of week (0 - 6) (Sunday=0) *=all # | | | | | # * * * * * command to be executed # -- -- -- -- - --------------------------------- # 00 12 * * * some_command # will run some_command at 12:00 (noon) daily #Run VPN check to check for tunnel up/down 10 * * * * /etc/openvpn/vpncheck.sh > /etc/openvpn/vpncheck.log
Finally, restart cron for the changes to take effect.
/etc/init.d/cron restart
Once everything is updated, reboot your MR3020 one final time.
Test alerting scripts
vpndown.sh
Assuming your VPN is already up, use ps | grep openvpn to find and kill the OpenVPN process ID.
root@mr3020_home:~# ps | grep openvpn 911 root 3436 S openvpn --cd /etc/openvpn --config /etc/openvpn/piageneric.ovpn --remote us-east.privateinternetaccess.com 1194 root@mr3020_home:~# kill 911 root@mr3020_home:~# ps | grep openvpn 1380 root 1356 S grep openvpn
After you kill it, grep again and you should see that OpenVPN isn’t running. In a minute or so, you should you get an email alerting you that the VPN tunnel is down.
vpnup.sh
Now, start the VPN manually (using the same command we used earlier to test).
openvpn --cd /etc/openvpn --config /etc/openvpn/piageneric.ovpn --remote us-east.privateinternetaccess.com 1194 &
Here, you’ll see the output from OpenVPN starting, and you should see the script vpnup.sh running.
root@mr3020_home:~# openvpn --cd /etc/openvpn --config /etc/openvpn/piag eneric.ovpn --remote us-east.privateinternetaccess.com 1194 & root@mr3020_home:~# Sat Jan 24 13:56:03 2015 OpenVPN 2.3.6 mips-openwrt-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [MH] [IPv6] built on Jan 6 2015 Sat Jan 24 13:56:03 2015 library versions: OpenSSL 1.0.1k 8 Jan 2015, LZO 2.08 Sat Jan 24 13:56:03 2015 WARNING: file 'authuser' is group or others accessible Sat Jan 24 13:56:03 2015 NOTE: the current --script-security setting may allow this configuration to call user-defined scripts Sat Jan 24 13:56:03 2015 UDPv4 link local: [undef] Sat Jan 24 13:56:03 2015 UDPv4 link remote: [AF_INET]64.237.52.133:1194 Sat Jan 24 13:56:05 2015 [Private Internet Access] Peer Connection Initiated with [AF_INET]64.237.52.133:1194 Sat Jan 24 13:56:08 2015 TUN/TAP device tun0 opened Sat Jan 24 13:56:08 2015 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0 Sat Jan 24 13:56:08 2015 /sbin/ifconfig tun0 10.150.1.10 pointopoint 10.150.1.9 mtu 1500 Sat Jan 24 13:56:08 2015 vpnup.sh tun0 1500 1542 10.150.1.10 10.150.1.9 init Sat Jan 24 13:56:12 2015 Initialization Sequence Completed
Again, in a minute or so, you should you get an email alerting you that the VPN tunnel is up.
vpncheck.sh
This is easy to test. Kill your OpenVPN process and wait until the vpncheck.sh script runs out of crontab. Then, you should see your tunnel come back up and get an email about it.
Extras
Backup your config
You did all this work, don’t lose it. Go to the System dropdown, then select Backup/Flash Firmware and press Generate Archive to download a backup of all your configuration files. I don’t believe this backs up custom scripts/files, so keep that in mind.
Failsafe mode
At some point during this build, you’ll probably break something and lock yourself out of your router. Thankfully, you’re not left with a paper-weight. OpenWrt includes a failsafe mode that will let you telnet to your router. Steps for the MR3020 are below.
- Power off your MR3020 and connect it to your PC via Ethernet
- Set your PC’s IP to 192.168.1.2 with a subnet of 255.255.255.0 and a gatway of 192.168.1.1
- Plug in the power to the MR3020
- When the WPS button starts to flash, slide the switch labeled 3G/4G/WISP/AP back and forth really fast. At this point, the WPS button will start blinking faster than it was before. You are in failsafe mode.
- Connect to the router via telnet and you should see that you are in failsafe mode.
logan@fedora20 ~$ telnet 192.168.1.1 Trying 192.168.1.1... Connected to 192.168.1.1. Escape character is '^]'. === IMPORTANT ============================ Use 'passwd' to set your login password this will disable telnet and enable SSH ------------------------------------------ BusyBox v1.22.1 (2014-09-20 22:01:35 CEST) built-in shell (ash) Enter 'help' for a list of built-in commands. _______ ________ __ | |.-----.-----.-----.| | | |.----.| |_ | - || _ | -__| || | | || _|| _| |_______|| __|_____|__|__||________||__| |____| |__| W I R E L E S S F R E E D O M ----------------------------------------------------- BARRIER BREAKER (14.07, r42625) ----------------------------------------------------- * 1/2 oz Galliano Pour all ingredients into * 4 oz cold Coffee an irish coffee mug filled * 1 1/2 oz Dark Rum with crushed ice. Stir. * 2 tsp. Creme de Cacao -----------------------------------------------------
- Now, you should be able to change your password by entering passwd, but you may get an error about the filesystem being read-only, like below.
passwd: /etc/passwd: Read-only file system passwd: can't update password file /etc/passwd
- If that happens, enter mount_root, then try the passwd command again. At this point, you should be able to SSH into the MR3020.
- If you installed too many packages and filled up the filesystem, you can wipe it and do a factory reset with the command below.
firstboot
- Reboot the router, as below.
reboot -f
- Try to SSH in. If it doesn’t work (mine didn’t), telnet in again, set your password again, and then try SSH again.
- If you want to transfer a new firmware file to the router, you can do that with the SCP utility on your PC.
scp /path/to/file.bin root@192.168.1.1:/path/to/file.bin
- Then, flash the new firmware file with the command below.
sysupgrade -v /path/to/file.bin
HTTPS Support
Out of the box, LuCI does not support HTTPS. For that, you’ll need a couple packages.
opkg update opkg install luci-ssl uhttpd-mod-tls
First, backup the original /etc/config/uhttpd file. Then, edit the file to change your certificate settings as needed.
cp -p /etc/config/uhttpd /etc/config/uhttpd_old vi /etc/config/uhttpd
Before…
config cert 'px5g' option days '730' option bits '1024' option country 'DE' option state 'Berlin' option location 'Berlin' option commonname 'OpenWrt'
After…
config cert 'px5g' option days '730' option bits '2048' option country 'US' option state 'Pennsylvania' option location 'Pennsylvania' option commonname '10.80.1.1'
Once you have your certificate setup, restart the webserver.
/etc/init.d/uhttpd restart
You should see a message similar to the one below.
Generating RSA private key, 2048 bit long modulus Generating selfsigned certificate with subject 'C=US;ST=Pennsylvania;L=Pennsylvania;CN=10.80.1.1;' and validity 20141021000526-20161020000526
If you navigate to /etc, you should see a certificate and a key file.
-rw-r--r-- 1 root root 828 Oct 20 20:50 /etc/uhttpd.crt -rw-r--r-- 1 root root 1192 Oct 20 20:50 /etc/uhttpd.key
Open your browser, and instead of going to http://10.80.1.1, go to https://10.80.1.1. If you get a scary looking error message, that’s ok. Click Advanced.
Then, proceed to your site.
In the URL bar, you’ll still probably see some intimidating red error message.
Upon further inspection, we can see this error is because the certificate wasn’t generated by a trusted CA (Thawte, Symatec, etc…).
If you inspect the actual certificate, you can see it’s the certificate we created, so you know it can be trusted.
That’s it! I’ll be tweaking this guide as I go, but let me know if anything is incorrect or missing. Also, a couple useful posts and sources I used when stuck are located here, here, and here.
-Logan
> Start by enabling wireless. At this point, you should be able to see the default OpenWrt network from a device.
I found that the two commands shown (uci delete wireless.radio0.disabled, uci commit wireless) weren’t enough on their own to bring up the wireless interface. The wireless interface only became active – and visible to my other devices – after I restarted the network stack (/etc/init.d/network restart).
Thanks, Alex! I’ve updated the post with your change!
Thanks for the excellent tutorial Logan. My mr3020 is now working almost how I want… I’m just having trouble ironing out the last couple of things: getting DNS to work 100% reliably and also I’m trying to configure the (otherwise useless to me) WPS button to connect/disconnect to my default OpenVPN profile, when it’s pushed.
One tip for you and your readers: I’ve configured the (otherwise always-on) WPS LED to show when the VPN is up/active by using the following commands:
I think it’s useful to have a simple LED for whether the VPN link is working or not. 🙂
Hot damn, but that’s a useful suggestion! I’ve turned my MR3020 into a VPN server, but the LED performs the same function either way.
Glad to help! Also, thanks for the WPS LED config, I’ll incorporate it into my next build. What DNS issues are you having?
The client devices all behaved OK (with the exception of my MacBook, which has intermittent DNS issues of its own, seemingly due to the new-in-Yosemite discoveryd service). But I couldn’t do ‘okpg update’ or install anything, because it seemed the mr3020 itself couldn’t resolve any addresses. I’m still not sure exactly how I fixed it tbh – a reboot probably helped – but I got it working eventually.
I now have the wps button configured how I’d like too: a short press (<2sec) toggles the VPN on/off. And a longer press (3-10sec) does a 'poweroff' command, so I can safely pull the power without risky corrupting the filesystem. It all seems to be working rather nicely, although I've not tested it extensively, I admit… 🙂
How did you get the WPS button to report its $SEEN value accurately?
I’ve been testing /etc/rc.button/wps with a simple script to write the value of $SEEN to the system log before I do anything more fancy, but the times recorded are ludicrous. A simple press and release (less than a second) records a $SEEN value of 20 seconds. Holding the button down for 4 seconds returns a $SEEN value of 42,949,500 seconds, which is obviously way out (I didn’t hold the button down for 494 days!).
I used the hotplug.d method rather than procd, as the OpenWRT BB build for the MR3020 seems to have everything for hotplug.d already setup (and I couldn’t find much info on getting procd to work well, unlike hotplug.d).
See the second section on this page:
http://wiki.openwrt.org/doc/howto/hardware.button
I also found this article very helpful:
http://www.linux-magazine.com/Online/Features/The-One-Watt-Server
Ah, I’ll give hotplug.d a go; I’d been using – or trying to use – procd.
Thanks for the suggestion.
Yup, hotplug.d is the key. That works as imagined.
I just need to check the “released” $ACTION and act on the consequent $SEEN value.
Thanks for the pointer.
Hi There,
I’m not great with openwrt setups, any chance you could give details of how you got the wps button working to start and stop VPN connections?
Thank you in advance
Just a brief note for anyone considering doing what I did and adapting these instructions to create a VPN server on the TL-MR3020: do not, for the love of all that is holy, run build-dh directly on the router. Use your computer instead to generate the DH file and copy it to the router.
The script says, “This will take a long time,” and it ain’t kidding. I let it run for two hours on the router before killing the process. In contrast, my computer spewed out a DH file in under ten minutes.
I’m glad you found the LED suggestion useful. 🙂
I know what you mean re: Diffie Hellman, too. I’m using my mr3020 to connect to my OpenVPN servers that I’ve set up on my main router at home (a Ubiquiti Edgerouter Lite). It took just over an hour for ./build-dh to complete on there, for a 2048 bit strength. (It only took about 5 minutes for 1024 bit, but I figured it was a one-off activity so I was prepared to wait.)
How do you like the Edgerouter Lite? I have a pair of E2000’s running DD-WRT that I’d like to replace. I was thinking about getting the Edgerouter Lite and a wireless AP or two. I’ve heard the web interface has been overhauled and is much more robust now.
I *love* my Edgerouter Lite! (As far as you can ever love a router, that is.) It’s what got me looking into similar tiny linux-based boxes, including the mr3020…
It’s true that the GUI has improved a lot, from what I read about the older versions, but tbh if you want to do anything ‘advanced’ – which means a lot of stuff – you still need to use the CLI.
The CLI syntax is a little bit similar to the OpenWRT UCI syntax though. If you’re comfortable with that – and SSHing to Debian command line – you’ll be fine.
Their forms are very helpful too and frequented by ubnt staff as well as other customers, so you’ll get answers pretty quickly if you get stuck.
I’ve got their UAP-AC v2 too, and it seems to be great, although the 5GHz range isn’t fantastic (it’s my first 5GHz-capable AP, so I can’t make a comparison with other routers/APs). It’s certainly solid, and the guest network feature is well implemented.
I’m thinking of buying a Raspberry Pi v2 to put the Unifi controller on (at the moment it’s running on my always-on PC, but I’d prefer it on its own low-power box)… it’s fair to say I’m getting hooked on playing with little linux-based devices. 😉
Guess I’ll have to pull the trigger and pick one up. Thanks for the insight!
Hadn’t thought about that, good call. I recently built DH parameters for my SSL certificate and it took a while on my VPS, I would imagine it would drag on the little MR3020.
hello Logan-
just wanted to let you know, your instructions were very helpful and translated easily to the TL-MR10U router, which is a similar model to the 3020. The MR10U is available from a few sources on ebay and elsewhere with a h/w mod to increase onboard flash memory and RAM, which negates the need for the external USB drive. I have mine providing VPN over a wireless bridge for non-wifi devices.
Glad to help and that’s good to know! Thanks!
Hi. Would it be possible to post the contents of /etc/config/firewall and /etc/config/network here ?
I’m not at home now, but I can post it later when I get home.
root@mr3020_home:~# cat /etc/config/firewall
config defaults
option syn_flood '1'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'REJECT'
config zone
option name 'lan'
list network 'lan'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
config zone
option name 'wan'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
option masq '1'
option mtu_fix '1'
option network 'wan wan6 WAN'
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-DHCPv6'
option src 'wan'
option proto 'udp'
option src_ip 'fe80::/10'
option src_port '547'
option dest_ip 'fe80::/10'
option dest_port '546'
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 include
option path '/etc/firewall.user'
root@mr3020_home:~# cat /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 globals 'globals'
option ula_prefix 'fd1f:8e7f:5520::/48'
config interface 'lan'
option force_link '1'
option proto 'static'
option netmask '255.255.255.0'
option ip6assign '60'
option ipaddr '10.80.1.1'
config interface 'WAN'
option proto 'dhcp'
option ifname 'eth0'
Hi, thanks for posting this. I’m a bit stumped now, as there is no section for VPN neither in network nor in firewall settings ? What happened to them?
What I’m trying to do is have an MR3040 act as a mobile VPN client that connects to my home network using an HSDPA stick. Except for the VPN connection, I’ve got everything else working. VPN connects, but as soon as it does I no longer have a connection. My setup is a bit different than yours, eth0 is still in LAN, wlan0 is currently WAN. I plan to disable wlan0 as soon as I have a working setup…
Hello John,
I also was very confused, but I found the solution. He never pasted the full configuration. There were too parts that needed changed.
1) The command: uci set firewall.@zone[1].network=’wan wan6 WAN’ –> Should be “WAN” only. I have no idea what the others are in there for, but they aren’t defined anywhere else.
2) You need to add parts mentioned in the “Setup VPN” section.
Complete working configs with some notes:
http://pastebin.com/C0d4pudk
Thanks so much Logan for putting this together!
Wow guys, just looked at my config and noticed that I’m missing the VPN section. Did some digging and found out my flash drive wasn’t mounted. Not sure what happened, but it appears the drive is dead. Guess I’m going to have to rebuild my system.
I really appreciate the time and effort you put into creating this page. It seems to be thoroughly explained and detailed and I’ll definitely be following it if I decide to go with the TL-MR3020 as my travel router! Like you my goal for a travel router will be to ultimately have it act as a VPN client. Are you able to enable the VPN client feature both while on an outside wireless (WISP) and wired network? And I’m assuming that if my TL-MR3020 has factory stock firmware on it, I can use the Barrier Breaker (BB) factory firmware when I install OpenWRT on it rather then first installing Attitude Adjustment (AA), right? Or do you recommend I install AA first to then better follow along your BB instructions verbatim?
Thanks, Matt. Glad to help!
I’m sure you could enable it with a wireless and wired network, but that’s not how I have it setup here. Just thinking out loud, what if you created two wireless interfaces and one wired interface, then bridged a wired and wireless as client on the VPN? Not sure, just something to look into.
And yes, you can install BB directly from factory firmware. There are two options for the BB download: a file for the factory firmware, and a file for upgrading from AA.
Hi,
tutorial worked like a charm.
One small addition: VPN didnt connect for me at startup even with changing rc.local.
I had to go to Luci / System / Startup and set the initscript “openvpn” to enabled additionally. Now it works. Maybe this helps someone.
Good tip, thanks!
Thanks for your effort Logan, Worked like a charm.
Good to hear!
Extremely well done How-To article. Thank you. The detail level is fantastic, and I now have a whole-house VPN client working on a Xaiomi router running PandoraBox. Thank you. I am struggling how to create a Kill Switch type rule so that there is no internet access should the VPN drop. I know that this is a rule-based setup, but the syntax is confusing. I looked over than OpenVPN instructions, but they’re rather terse. Does anyone have suggestions on where I can look to find this?
Thank you.
Thanks! The killswitch will involve running two scripts: one when the VPN goes up, and another when the VPN goes down. Each script will have to edit the iptables firewall rules. See here, here, and here for an example.
Hi,
Followed this guide but was never able to complete the networking, maybe because I have a custom built image.
I’ve opened a post in official OpenWRT forums describing the issue in detail, will appreciate getting any hint here!
https://forum.openwrt.org/viewtopic.php?pid=295099#p295099
By the way, I also tried the full config posted here, still no luck:
http://pastebin.com/C0d4pudk
This is my wireless configuration:
config wifi-iface
option device ‘radio0’
option network ‘lan’
option mode ‘ap’
option ssid ‘VPNAP’
option encryption ‘psk2+ccmp’
option key ‘XXXXXXXXXXX’
Perhaps the “option network ‘lan'” should be changed to option network ‘WAN'”?
Max,
It looks (from your forum post) that you’re ok up until you delete the bridge, correct? I’ve done this build almost a dozen times without issue, so you may just be missing a step somewhere. From your pastie.org posts, it looks like you might be missing an interface name on the LAN interface.
Before
config interface 'lan'
option ifname 'eth0'
option force_link '1'
option type 'bridge'
option proto 'static'
option 'ipaddr' '10.0.0.139'
option 'netmask' '255.255.255.0'
option ip6assign '60'
After
config interface 'lan'
option force_link '1'
option proto 'static'
option 'ipaddr' '10.0.0.139'
option 'netmask' '255.255.255.0'
option ip6assign '60'
Something about deleting the bridge deleted the interface name as well (it shouldn’t have). You might need to add a line for
option ifname 'eth0'
into the section above.That would also explain why you’re receiving the firewall errors, since the firewall can’t find
eth0
, as it’s not defined.Warning: Section @zone[1] (wan) cannot resolve device of network 'wan'
Warning: Section @zone[1] (wan) cannot resolve device of network 'wan6'
Hi,
Your step “Unbridge LAN interfaces” actually has this very action:
uci delete network.lan.ifname
Also, same in the posted config here:
http://pastebin.com/C0d4pudk
The “ifname” migrated to the ‘WAN’ section:
config interface ‘WAN’
option proto ‘dhcp’
option ifname ‘eth0’ ##give the wifi hotspot dhcp of it’s own##
Can you posted your following configs:
– network
– firewall
– wireless
?
Thanks!
Unfortunately, I don’t have the device anymore, so I can’t replicate my build. Hopefully someone here can help you, or you can get some help on your forum post.
Hi Logan,
Thanks for the completely clear walkthrough. I’ve managed to successfully run it up till the up/down script , it’s always showing failed to execute.
Any pointers?
Can you run the scripts manually from the commandline? Also, did you make sure to change the permissions?
chmod 700 /etc/openvpn/vpndown.sh
chmod 700 /etc/openvpn/vpnup.sh
chmod 700 /etc/openvpn/vpncheck.sh
It gave me this from the command line
Options error: Unrecognized option or missing parameter(s) in /etc/openvpn/vpncheck.sh:5: RESULT=`ifconfig (2.3.6)
Use –help for more information.
root@MR3020:~# openvpn –cd /etc/openvpn –config /etc/openvpn/vpnup.sh
Options error: Unrecognized option or missing parameter(s) in /etc/openvpn/vpnup.sh:5: STATUS=UP (2.3.6)
Use –help for more information.
On the second command, you’re passing the vpnup.sh script to OpenVPN as a config file, which is incorrect and throwing an error. The -config option needs to use a .ovpn file (shown below).
openvpn --cd /etc/openvpn --config /etc/openvpn/piageneric.ovpn --remote us-east.privateinternetaccess.com 1194 &
everytime I include this line in the .ovpn file
up vpnup.sh
down vpndown.sh
script-security 2
the config file failed:
Thu Oct 22 23:47:02 2015 TUN/TAP device tun0 opened
Thu Oct 22 23:47:02 2015 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Thu Oct 22 23:47:02 2015 /sbin/ifconfig tun0 10.8.0.6 pointopoint 10.8.0.5 mtu 1500
Thu Oct 22 23:47:02 2015 vpnup.sh tun0 1500 1542 10.8.0.6 10.8.0.5 init
Thu Oct 22 23:47:02 2015 WARNING: Failed running command (–up/–down): could not execute external program
Thu Oct 22 23:47:02 2015 Exiting due to fatal error
root@MR3020:~# cd /etc/openvpn
root@MR3020:/etc/openvpn# vpncheck.sh
-ash: vpncheck.sh: not found
root@MR3020:/etc/openvpn#
Can you show me the permissions on the scripts?
ls -la /etc/openvpn
Also, when you run the script, you need to run it with “./” in front of it.
./vpncheck.sh
root@MR3020:~# ls -la /etc/openvpn
drwxr-xr-x 2 root root 1024 Oct 22 19:10 .
drwxr-xr-x 14 root root 1024 Oct 22 18:06 ..
-rw-r–r– 1 root root 15 Oct 22 02:25 auth
-rw-r–r– 1 root root 3629 Oct 22 23:59 client.ovpn
-rw-r–r– 1 root root 0 Oct 22 23:10 vpncheck.log?
-rwx—— 1 root root 371 Oct 22 23:21 vpncheck.sh
-rwx—— 1 root root 397 Oct 22 23:41 vpndown.sh
-rwx—— 1 root root 396 Oct 22 23:54 vpnup.sh
root@MR3020:~#
root@MR3020:/etc/openvpn# ./vpncheck.sh
-ash: ./vpncheck.sh: not found
Something weird is going on there. That file is definitely there and has the correct permissions. I assume all your scripts start with
#!/bin/ash
?Are you editing/creating these scripts directly on the router with the commandline and vi, or are you doing it in Windows then uploading it?
Put #!/bin/bash to the beginning of the script. Read somewhere that openvpn needs to know what to call to execute a script.
I upload it usinmg windows, should I try using vi instead?
Still not working.. do you think its about permissions?
I would try. I think when you edit files in Notepad, Windows puts different newline characters in the file that Linux can’t understand.
https://stackoverflow.com/questions/27275118/linux-shell-script-not-found-but-it-does-exist
I recreated all the scripts from scratch now everything works!
Thanks Logan
Sounds good!
Smartphone is getting the host-ip instead of VPN IP. Other devices work great. Do you have a conclusion for that?
Are all the other clients connected via WiFi? Do you have a static lease set for the phone’s MAC address in OpenWrt already?
Last week I bought a TL-WR710N, hoping I’d get the 8MB v2.1 model, but no such luck. I got the 4MB v2.0 model.
Pros: two Ethernet ports, perfect for a pocket-sized wired firewall in addition to wireless.
Cons: mains powered only, not USB powered (but can be modded for USB power, if you’re careful), and a bit bigger than the MR3020.
Chaos Calmer is supported on this device, even the 4MB model, although it doesn’t leave enough room to install block-mount, kmod-usb-storage, and kmod-fs-ext4. However, https://www.reddit.com/r/openwrt/comments/3sfalj/not_enough_space_to_install_packages_required_for/ came to the rescue, and pointed me in the direction of making my own OpenWRT firmware image. I was able to install Chaos Calmer without luci, add extroot support, then reinstall luci and all the rest of the stuff on this page, including OpenVPN.
I mention this because the MR3020 has 4MB storage. I’ve not yet tried Chaos Calmer on my MR3020, so I don’t know if the MR3020 also suffers from insufficient space to add the extroot packages on a standard OpenWRT installation.
Thanks! I had this same issue with my MR3020. I was unable to extroot because LuCI took up too much space and I couldn’t install block-mount, kmod-usb-storage, and kmod-fs-ext4. However, I ended up not keeping my MR3020, but this would have been a perfect solution. Have you had any issues running extroot on the WR710N?
No issues so far. It seems to be working exactly as it did on the MR3020, as far as I can tell.
Good to know! I may need to pick one up myself!
with this configuration can i still use 3g usb stick for internet access? Cause i think i saw you used usb for external storage at some point .
You would need to get a USB hub to split the single USB port into more than one.
Hi! Thanks for the tutorial. I cannot however move on starting from “Unbridge LAN interfaces”. I can either have bridged internet connection or once the wan cabel is detached – just the internal network connection (10.80.1.xxx), no internet. Can anyone provide their config files, please (network, wireless, dhcp, firewall)?
I have created a ticket https://dev.openwrt.org/ticket/21623.
Did you commit your changes and restart networking? Also, you may want to reboot the device.
I’ve acquired a new toy, and returned to this page as a reference while I configure it.
The HooToo TripMate Nano (model TM02) is incredibly tiny. It makes the TP-Link MR3020 look gargantuan in comparison. Like the MR3020 it’s powered by a regular USB cable, has a single Ethernet socket, and a single USB host socket.
It runs OpenWRT (I put Chaos Calmer on mine this afternoon) and it has 8MB of flash storage, so no need to mess about with extroot!
Very cool, thanks for sharing! I had heard a few good things about the HooToo devices, but never tried one out. I didn’t know it had 8MB flash, which is awesome! I retired my MR3020, so I’ll have to pick up one of these!
Hello, Thank you once again for your article!
I have a slightly related question:
If you have MR3020 as a travel router + one more router at home with VPN. How to avoid VPN provider limitation on device count? My VPN provider limits 1 router, 1 computer, 1 phone. Can I setup MR3020 as my phone by overriding MAC address?
There really isn’t a good way to avoid that. My provider (PIA) allows 5 devices, but doesn’t limit the type of device (router, phone, etc…).
I would assume that they are determining the device type by the MAC address, but that’s not a 100% fool-proof way. Consider companies that make computer and phones (Samsung, LG, etc…). I would think cloning your MAC would be the best way around that limitation.
Hello,
I have WR740N. I’m trying to use VPN both for LAN ports and WiFI, how to do it?
You’ll need to bridge the wired and wireless interfaces.
Wired and wireless interfaces are bridged by default. Also apparently I didn’t even need to create WAN interface, since it is already there. So I just configured VPN as you described and it worked! Thank you!
Also do you think mr3020 or wr740n can handle 30 and more clients working through the VPN? Can we switch off some services, if we are sure that modem is handling them?
Glad it worked!
To be honest, I couldn’t tell you the number of clients it could handle. It depends on the CPU specs, and I know neither of those devices have great CPUs. I’m sure it would work with 30 clients, but I’m sure it would be painfully slow. Yes, I’m sure you could disable some unnecessary services (LuCI, Samba, PPTP, etc…), but again, I don’t think it would make much difference. The CPU will be the bottleneck.
Hello Logan! Thank you for this great article! How can I bridged the interfaces? Is there a way to bridge the wireless interface with TUN? That is my solution in Windows. I need full access over VPN to clients that connected on MR3020.
What do you mean by “full access”? I don’t have a MR3020 anymore, but I think you can go the interface, then the physical tab, and check the necessary boxes to bridge the tunnel and wireless interfaces.
Hi Logan. Thanks for your reply. I need to access a Server behind the OpenWRT from Clients connected to OpenVPN-Server. I need full access to all services an ports. I have installed package “relayd” and try to bridge the LAN / TAP. But I can’t connect to server-webinterface.
Here you can find my full Config:
https://drive.google.com/open?id=0ByHou1lJfZMmZ0dtWloyQjdaZmM
Thanks
Which box is acting as the OpenVPN client? The fact that you have two OpenVPN servers in your diagram, and not a client, is throwing me off.
I have updated the diagram. Now it is correct. The OpenWRT-Router and Clients are connected to OpenVPN-Server. This Server is behind a FritzBox 7490. Clients are connected to OpenVPN-Server. On Server behind the OpenWRT-Router run a Service on Port 4500. This Service is not avaible for the Clients. This is the Service that I need.
Thank you
Nicki – Can you describe in more detail what you’re trying to achieve? Are the 2 clients on the 10.0.0.0/24 network trying to access services on the server @ 10.80.1.19? Does the server ever need to initiate connections to the clients, or is it always client initiated? Is this across 3 or more physical locations?
Can you show the internet in the drawing so that we can understand the natural physical segmentation of your network (and therefore the publicly routable vs un-routable IP address distinctions)?
Is this a business grade network with proper routing tables? Or are some things double-NAT’d (and if so, is it intentional and necessary – why double-NAT)?
There are a lot of different subnets in that diagram which makes it confusing. For example, the clients are on a different subnet than the router which is unusual. This theme repeats behind each router, where the IP address of the router (LAN, I assume, since those are un-routable IPs) are totally different subnets than the stuff behind them. And you have 2 routers that appear to be on the same IP address — presumably the internet lies between these two routers. On the server side, is it necessary for it to be behind the OpenWRT router (thus double-NAT’d)?
I have successfully managed to get full network service availability across the VPN tunnel by having 2 distinct subnets, one on each side of the tunnel.
If this is a SOHO type setup that you can fully control, I’d start by simplifying the subnets and eliminating the extra NAT stages so that you don’t have quite as many complex routes to deal with. The fact that the OpenVPN server is running through some other router as compared to the client machines is likely to be a routing nightmare. Instead of connecting the server through the OpenWRT router, you could connect both the OpenWRT router and the server to the same internet router. The same thing on the client side — eliminate the 192.168.2.1 router and connect the OVPN Server and client machines to the same router. Then, as long as you have the right routes pushed in the OVPN config, it should be possible to communicate across the tunnel.
Thanks for your reply. Here is my full diagram. I need TAP because I need broadcast.
https://drive.google.com/file/d/0ByHou1lJfZMmMHFhRU5JZTlBVjA/view?usp=sharing
Nicki – Thanks for the updated diagram. I think I understand what you’re aiming to do, but I’m not quite sure if I have any ideas that will help. That said, a few thoughts…
1) do you have the “client-to-client” directive enabled on the OVPN server? This may be required. In fact, if it is enabled, it may be possible to do establish the connection via TUN (instead of TAP) and get the desired results.
2) Is there any reason that you need to connect via the 3rd location (OVPN server)? Instead, could you possibly put an OpenVPN Server configuration on the router that is currently the OpenVPN client? This way you could connect from the client computers directly to the physical location with the server of interest, entirely eliminating the 3rd location. This would simplify the situation dramatically, removing any client-to-client considerations and would probably be the most effective and provide faster, more efficient performance.
Hello, I have a problem when I try to start the VPN. I have this on terminal:
root@mr3020_home:/etc# openvpn –cd /etc/openvpn –config /etc/openvpn/piageneric.ovpn –remote us-siliconvalley.privateinterne
taccess.com 1194
Wed Jul 20 21:16:30 2016 OpenVPN 2.3.6 mips-openwrt-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [MH] [IPv6] built on Jan 6 2015
Wed Jul 20 21:16:30 2016 library versions: OpenSSL 1.0.2f 28 Jan 2016, LZO 2.08
Wed Jul 20 21:16:30 2016 WARNING: file ‘authuser’ is group or others accessible
Wed Jul 20 21:16:30 2016 Cannot load CA certificate file ca.crt (no entries were read): error:02001002:lib(2):func(1):reason(2): error:2006D080:lib(32):func(109):reason(128)
Wed Jul 20 21:16:30 2016 Exiting due to fatal error
I´ve done all as you did it. Can you help me with this?
Thanks!
It seems like you’re missing the ca.crt file. Did you download it from PIA? Are you sure it’s in the right place?
Hi Logan, thanks for your reply. I´m not sure if ca.crt is in the right place. Also, I didn´t find where, in your tutorial, i´ve downloaded that file. I´m a little lost in this setup!! I appreciate any help.
If you’re using my config file, ca.crt needs to be in the same directory as the .ovpn file you’re using. The ca.crt file comes in the this .zip file, along with all the other .ovpn files.
Would have loved to make my own travel router, but gave up as I could not solve the technicalities due to lacking RAM. Is there another router with more RAM – size doesn’t matter – where your guide could be used? I intend to connect to my home network where I have an ASUS router running a VPN-server.
I assume by RAM you mean flash, or do you mean actual RAM? If flash, then check out HooToo and specifically this comment. I haven’t tried it personally, but I’ve heard good things about it.
Thank you for this outstanding tutorial!
My router has:
1) ISP WAN PPoE connection with DHCP address assignment.
2) VPN(tun0) connection as openvpn client (setup as described in this article)
3) LAN network 192.168.10.1/255.255.255.0
In my LAN network I have PC(192.168.10.2) and SmartTV (192.168.10.3).
So the question is how to bypass all traffic from 192.168.10.3 to ISP WAN without VPN tunnelling and traffic from PC 192.168.10.2 with VPN tunneling. I need it ’cause SmartTV traffic is too large for my VPN conection.
I think I need to modify OpenWRT firewall rules but not sure how to do it correctly!
Thank you!
Alex, I don’t have my MR3020 anymore, so I won’t be much help to you. However, I think you can either make firewall rules, or create a 2nd LAN and only use the VPN on that LAN (might be easier).
Thank you , for your article, 🙂
Hello, I’m a bit late to the party but i just got the TL-MR3020 in hope of making a mobile network in my car. I was following you pretty well (i’m useless in programming so i’m trying my best) now i made it to the extroot bit…. and here’s my problem… I plan on using this router in “3G/4G” mode and having a USB Modem in the usb slot… Literally the only reason for this entire project was simply because i wanted a VPN on my android radio in my car…. but apparently for reasons unknown i cannot get a VPN working on the radio(tried 3 different VPN methods, they all seem to ‘connect’ but dont mask my IP) , so i have resorted to putting a VPN at the source. but from what i am understanding here… i need to use the USB slot to house extra space for the actual VPN rather than the modem which will be my source of internet.. so this sorta screws up my plans… I’ve noticed most modems come with an SD card slot.. could i maybe install whatever information is required to finish this build on there? and if so, how would i do this this ???
Thanks for the advice,
Jesse
You can do one of two things:
1) Get a different mini-router than has more storage (this is the better solution)
2) Use an unpowered USB hub to turn that single USB port into 2 or more