Table of Contents
HTTPS proxy for Lynx on OpenVMS with Macproxy and Docker
Getting a VAX running Lynx onto the modern web. Lynx here was built without
SSL, so it cannot fetch a https:// URL at all — a proxy on a Raspberry Pi
terminates the TLS and hands back plain HTTP.
Verified on Macproxy Classic 25.11.1 (Docker image rdmark/macproxy)
and Lynx 2.9.3 on OpenVMS VAX V7.3.
The Pi is 172.24.9.50 and the proxy listens on port 5001. The VAX is GOZER at 172.24.9.95.
Quick Reference
| Task | Command |
|---|---|
| Start the proxy | docker run -d –restart=unless-stopped -p 5001:5001 rdmark/macproxy |
| Check it is up | curl -x http://172.24.9.50:5001 http://example.com |
| Proxy logical on VMS | DEFINE “http_proxy” “http://172.24.9.50:5001/” |
| Show what Lynx read | LYNX -show_cfg |
| Bookmark current page | a |
| Escape a Lynx prompt | Ctrl-G |
Why a proxy and not just a newer Lynx
Building Lynx with SSL on VAX means building OpenSSL on VAX first. The proxy
sidesteps that entirely, and it does something a TLS-capable Lynx would not:
it rewrites inline hyperlinks from https to http, so every link you
follow comes back through the proxy without you touching the address bar.
Macproxy also strips stylesheets and JavaScript and suppresses inline scripts. Irrelevant to Lynx, which ignores them anyway, but it shrinks the transfer — worthwhile over a slow link.
Pi setup
# Install Docker:
curl -fsSL https://get.docker.com | sh
# Let the pi user run docker without sudo:
sudo usermod -aG docker $USER
Log out and back in before this takes effect. Do not reach for sudo
docker as a workaround — fix the group.
# Run Macproxy, restarting on boot:
docker run -d --name macproxy --restart=unless-stopped -p 5001:5001 rdmark/macproxy
# Confirm it is listening:
docker ps
# Test it from the Pi before touching the VAX:
curl -x http://172.24.9.50:5001 http://example.com
If that returns HTML, the proxy works and everything after this is VMS configuration.
# Watch requests as they arrive:
docker logs -f macproxy
Leave this running in another window while you test from the VAX. It tells you immediately whether the VAX is reaching the Pi at all.
VMS setup
# Point Lynx at the proxy:
DEFINE "http_proxy" "http://172.24.9.50:5001/"
# And for https URLs:
DEFINE "https_proxy" "http://172.24.9.50:5001/"
# Keep local traffic off the proxy:
DEFINE "no_proxy" "localhost,172.24.9."
The quotes are not optional. See gotcha 1.
# Check where the binary and data live:
SHOW LOGICAL LYNX*
The kit install puts the image in SYS$SYSTEM:LYNX.EXE and its data in
SYS$COMMON:[LYNX], and defines LYNX_DIR but not LYNX_CFG.
# Point Lynx at a config file:
DEFINE LYNX_CFG SYS$COMMON:[LYNX]LYNX.CFG
# Verify Lynx actually read it:
LYNX -show_cfg
If the output shows lynx.invisible-island.net URLs, it did not — those
are the compiled-in defaults.
The gotchas that will waste your afternoon
# 1. DCL upcases logical names. Lynx looks for lowercase.
DEFINE http_proxy … creates HTTP_PROXY, and Lynx never finds it.
The symptom is no error at all — pages simply fail to load, and nothing
appears in the Macproxy log because the VAX never contacted the Pi. Quote
the name to preserve case.
DEFINE "http_proxy" "http://172.24.9.50:5001/"
# 2. With no LYNX_CFG, the compiled-in STARTFILE and HELPFILE are https.
An SSL-less Lynx cannot fetch either, so it opens on an error and ? does
nothing. Override both with http URLs in your own config.
STARTFILE:file://localhost/sys$login/bookmarks.html HELPFILE:http://172.24.9.50/lynx_help_main.html
# 3. The port changed from 5000 to 5001 in 25.11.1.
Every guide written before that release tells you 5000. If curl through
the proxy hangs, check docker ps for the real port mapping before
debugging anything else.
# 4. VMS file URLs use slashes, not brackets.
file://localhost/SYS$COMMON:[LYNX]bookmarks.html fails with “Unable to
access document”. Translate the path.
file://localhost/sys$common/lynx/bookmarks.html
Bookmarks
# Keep the bookmark file in your home directory:
BOOKMARK_FILE:bookmarks.html
A bare filename resolves against SYS$LOGIN:. Do not put it in
SYS$COMMON:[LYNX] — that is a system directory, so a fails to write
and Lynx does not always say so.
# Open straight into the bookmark list:
STARTFILE:file://localhost/sys$login/bookmarks.html
Create the file before first launch or the start page errors.
Lynx keys worth knowing
| Keys | Action |
|---|---|
a | Add current page to bookmarks |
v | View the bookmark list |
r | Remove the bookmark under the cursor |
g | Go to a URL |
Ctrl-G | Cancel out of any prompt back to command mode |
Ctrl-R | Reload and reset |
z | Abort a load in progress |
Search engines that answer a plain GET
Google returns 403 to any client without JavaScript, and no proxy fixes that — the refusal happens at Google's edge before content is served. These do not:
http://frogfind.com/?q=…— heavily stripped, rewrites result links
back through itself
https://lite.duckduckgo.com/lite/?q=…— minimal HTML, no scriptshttps://wiby.me/?q=…— indexes lightweight pages, suits a VT220
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Pages fail, nothing in docker logs | logical name got upcased | quote it: DEFINE “http_proxy” … |
LYNX -show_cfg shows invisible-island URLs | LYNX_CFG unset | DEFINE LYNX_CFG SYS$COMMON:[LYNX]LYNX.CFG |
| “Can't access startfile” | bracket syntax in a file URL | use /sys$login/bookmarks.html |
a appears to work, file unchanged | bookmark file in a system directory | BOOKMARK_FILE:bookmarks.html |
| 403 from a search page | client has no JavaScript | use FrogFind or DuckDuckGo lite |
curl through proxy hangs | wrong port | docker ps, check for 5001 |
| Some sites still demand https | rewriting is imperfect | edit the URL to http by hand |
Which one should I use?
| Macproxy | FrogFind | |
|---|---|---|
| Runs on your own hardware | yes | no |
| Works with no setup | no | yes |
| Keeps page structure | yes | no, strips to article text |
| Survives the venue's network dying | yes | no |
| Handles arbitrary sites | mostly | yes, more reliably |
Rule of thumb: Macproxy for browsing, FrogFind in your bookmarks as the fallback when the Pi misbehaves.
