Skip to content

Instantly share code, notes, and snippets.

@ylxdzsw
Created May 1, 2020 16:45
Show Gist options
  • Save ylxdzsw/1eac8713c343ee935cbcf3f3d5be71c9 to your computer and use it in GitHub Desktop.
Save ylxdzsw/1eac8713c343ee935cbcf3f3d5be71c9 to your computer and use it in GitHub Desktop.
A failed attempt to abuse cloudflare workers as a web monitor.
serverchan_token = ''
telegram_token = ''
telegram_chatid = ''
secret = '' # it also acts as instance ID. Change this everytime you restart the script.
host1 = ''
host2 = '' # we need two hosts because of https://community.cloudflare.com/t/issue-with-worker-to-worker-https-request/94472
addEventListener 'fetch', (e) ->
e.respondWith main e
main = (e) ->
x = e.request.url.split '/'
level = parseInt x[x.length-1]
if x[x.length-2] isnt secret
await notify_important "cfmonitor of #{x[x.length-2]} finished as secret mismatch"
return new Response "finished", status: 200
res = do -> try
await handleRequest e.request
new Response "continue to next", status: 200
catch e
new Response 'request failed', status: 500
e.waitUntil do -> try # waitUntil prevent the auto termination when respond finished (`res` resolves)
await Promise.all [res, timeout 2000] # wait at least 2 seconds
url = new URL(e.request.url)
host = switch url.hostname
when host1 then host2
when host2 then host1
else throw "from unknown host #{url.hostname}"
next = await fetch new Request "https://#{host}/#{secret}/#{level+1}",
method: 'POST'
headers: 'Content-Type': 'application/json'
body: JSON.stringify monitors
if !next.ok
throw "#{level+1}: returns status code #{next.status}"
catch err
await notify_important "cfmonitor fail on continue: #{do err.toString}"
await res
handleRequest = (req) ->
if req.method is 'POST'
for k, v of await do req.json
Object.assign monitors[k], v
updates = for k, v of monitors
do v.update
await Promise.all updates
# notify_primary 'current status' + JSON.stringify monitors
notify_telegram = (msg) ->
res = await fetch new Request "https://api.telegram.org/bot#{telegram_token}/sendMessage",
method: 'POST'
headers:
'Accept': 'application/json'
'Content-Type': 'application/json'
body: JSON.stringify chat_id: telegram_chatid, text: msg
await do res.json
notify_serverchan = (msg) ->
fetch new Request "https://sc.ftqq.com/#{serverchan_token}.send?text=#{encodeURIComponent(msg)}",
notify_primary = notify_telegram
notify_important = (msg) ->
Promise.all [
notify_serverchan msg
notify_telegram msg
]
timeout = (time) ->
new Promise (resolve, reject) -> setTimeout resolve, time
ServerUp = (url) ->
last: null
update: ->
try
x = await fetch new Request url
throw '' if not x.ok
if @last is false
await notify_primary 'server is up'
@last = true
catch
if @last is true
await notify_primary 'server is down'
@last = false
monitors =
github: ServerUp 'http://www.github.com'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment