Projects#
Lua earns its place as an embedded language. The operator’s projects are usually extensions to host tools rather than stand-alone applications.
Nmap NSE script#
Write a Nmap Scripting Engine probe in Lua. NSE scripts live in
/usr/share/nmap/scripts/ and are invoked with
nmap --script=<name>. Write new probes when
existing NSE coverage is thin.
-- nmap-scripts/operator-banner.nse
description = "Grab the HTTP server banner."
author = "operator"
license = "Same as Nmap"
categories = {"discovery", "safe"}
local shortport = require "shortport"
local http = require "http"
portrule = shortport.http
action = function(host, port)
local resp = http.get(host, port, "/")
return resp.header["server"] or "unknown"
end
Run.
$ nmap --script=./operator-banner.nse -p 80,443 target.example.com
Neovim plugin#
Modern Neovim is Lua-first. Plugins ship as Lua modules under
lua/<name>/ and are loaded with require. The operator
writes plugins to add custom commands, LSP integrations, or
syntax handling.
nvim-operator/
├── README.md
└── lua/
└── operator/
├── init.lua
└── commands.lua
-- lua/operator/init.lua
local M = {}
function M.setup(opts)
opts = opts or {}
vim.api.nvim_create_user_command(
"OperatorScan",
function() require("operator.commands").scan() end,
{ nargs = 0 }
)
end
return M
Wireshark dissector#
Custom protocol decoding inside Wireshark. Write one when reverse-engineering a private protocol on the wire.
-- ~/.config/wireshark/plugins/op.lua
local op = Proto("op", "Operator protocol")
local f_version = ProtoField.uint8("op.version", "Version")
local f_payload = ProtoField.bytes("op.payload", "Payload")
op.fields = { f_version, f_payload }
function op.dissector(buf, pkt, tree)
pkt.cols.protocol = "OP"
local sub = tree:add(op, buf())
sub:add(f_version, buf(0, 1))
sub:add(f_payload, buf(1))
end
local udp_table = DissectorTable.get("udp.port")
udp_table:add(31337, op)
Redis Lua script#
Atomic server-side scripts running inside Redis via EVAL /
EVALSHA. Write these for atomic
read-modify-write patterns (rate-limiters, leader election,
counter-with-cap).
-- token bucket admit
local key, rate, burst, now = KEYS[1], tonumber(ARGV[1]),
tonumber(ARGV[2]), tonumber(ARGV[3])
local tokens = tonumber(redis.call("HGET", key, "tokens") or burst)
local last = tonumber(redis.call("HGET", key, "last") or now)
tokens = math.min(burst, tokens + (now - last) * rate)
local admit = tokens >= 1
if admit then tokens = tokens - 1 end
redis.call("HMSET", key, "tokens", tokens, "last", now)
return admit and 1 or 0