Docker container to proxy HTTP(S) via USB PPP modem using Twilio Programmable Wireless.
Well... suppose you have a dedicated machine running home automation/alarm system and video surveillance. You want some out-of-band (i.e. cellular) notification if you lose your normal route to the WAN or if the alarm is triggered while normal connectivity is down. But you're using Twilio Programmable Wireless on a small, cheap plan (~10 MB/month) and don't want HD video streaming to offsite storage or other data-intensive things trying to go over the cellular link.
So, we use an application-level solution:
- Run a HTTP proxy in a Docker container, which routes over the cellular link.
- At the application level, send data through the proxy only if normal connectivity fails.
Essentially, a whole lot of ugly complexity and engineering to get $3/month out-of-band notifications.
This has been tested with a Huawei E397u-53 USB 4G modem.
Upon first plugging in your modem, run
lsusb | grep Huawei. If you see
ID 12d1:1505 Huawei Technologies Co., Ltd. E398 LTE/UMTS/GSM Modem/Networkcard, the USB modem is in mass storage mode. Run
usb_modeswitch -v 12d1 -p 1505 -J to fix that;
lsusb | grep Huawei should now report
12d1:1506 Huawei Technologies Co., Ltd. Modem/Networkcard.
docker run -d \ --name twilio-proxy \ -e MODEM_DEV=ttyUSB0 \ --privileged \ -p 8888:8888 \ --restart always \ jantman/twilio-ppp-proxy
- If you'd like to execute a command before starting up tinyproxy in the container, the content of the
PREPROXY_EXECenvironment variable will be passed to
bash -cif set. An example of this is if you want to allow access from other machines on the same LAN as the docker host; with a 192.168.0.0/16 LAN and a Docker host of 172.17.0.1, you could set
PREPROXY_EXEC="ip route add 192.168.0.0/16 via 172.17.0.1 dev eth0".
- By default, the container runs a healthcheck using curl against http://api.ipify.org/ every 15 minutes, starting 5 minutes after container start, with a 1-minute timeout. This should be a suitable default, but these values can be overridden in the
docker runcommand using the
--health-timeoutoptions, respectively, or disabled with the
Test that it's working:
- Point a browser to https://www.ipify.org/ and find your current WAN IP.
curl http://httpbin.org/ipshould show your real/current WAN IP
curl https://api.ipify.org/?format=jsonshould show the same real/current WAN IP
http_proxy=http://127.0.0.1:8888/ https_proxy=http://127.0.0.1:8888/ curl -L https://api.ipify.org/?format=jsonshould show a different IP, the cellular gateway (not necessarily your PPP client IP)
http_proxy=http://127.0.0.1:8888/ https_proxy=http://127.0.0.1:8888/ curl http://httpbin.org/ipshould show a different IP, the cellular gateway (not necessarily your PPP client IP)
Try restarting the container, unplugging and re-plugging the USB modem, or issuing a network reset from Twilio's site.
DEBUG environment variable for the container will enable both trace output in the bash scripts as well as passing the "debug" and "dump" options to
pon (and on to pppd).
- Try to make this a bit smaller and more efficient. Right now, this image is just using a giant hammer to get things working as quickly as possible.
- Do something better for logging than running rsyslog?
- Figure out if we can specify certain needed capabilities instead of
- Ensure that the container exits if the connection breaks/fails.
- Automatically find the modem if