diff options
author | Alec Warner <antarus@gentoo.org> | 2018-12-09 07:57:35 -0500 |
---|---|---|
committer | Alec Warner <antarus@gentoo.org> | 2018-12-09 07:57:35 -0500 |
commit | aff65382d7a6b709552e36a9e3ccc86855761d71 (patch) | |
tree | ca47a56d09ecaa1f88875ec9b0086f21aeb21ea0 | |
parent | Try to get more atomic syncing for serving content. (diff) | |
download | antarus-aff65382d7a6b709552e36a9e3ccc86855761d71.tar.gz antarus-aff65382d7a6b709552e36a9e3ccc86855761d71.tar.bz2 antarus-aff65382d7a6b709552e36a9e3ccc86855761d71.zip |
Add Robin's ha-proxy bits for non-cloud LB.
This supports denying syncing when busy / out of date
and an rsync friendly deny message; similar to http 429 (TOO_BUSY)
or 503 (SERVICE_UNAVAILABLE.)
Signed-off-by: Alec Warner <antarus@gentoo.org>
-rw-r--r-- | src/infra.gentoo.org/rsync-node/Dockerfile | 2 | ||||
-rw-r--r-- | src/infra.gentoo.org/rsync-node/deny-rsync.lua | 12 | ||||
-rw-r--r-- | src/infra.gentoo.org/rsync-node/ha-proxy.conf | 72 |
3 files changed, 85 insertions, 1 deletions
diff --git a/src/infra.gentoo.org/rsync-node/Dockerfile b/src/infra.gentoo.org/rsync-node/Dockerfile index 2098508..cd10282 100644 --- a/src/infra.gentoo.org/rsync-node/Dockerfile +++ b/src/infra.gentoo.org/rsync-node/Dockerfile @@ -13,7 +13,7 @@ ENV SOURCE_MIRROR=rsync://boobie.gentoo.org/gentoo-portage # Where to write the data in this container. ENV DEST_DIR=/dev/shm/gentoo # How long to wait between syncs; must be a valid argument to sleep -ENV WAIT_TIME=10m +ENV WAIT_TIME=30s # This needs to exist in the container. WORKDIR $DEST_DIR diff --git a/src/infra.gentoo.org/rsync-node/deny-rsync.lua b/src/infra.gentoo.org/rsync-node/deny-rsync.lua new file mode 100644 index 0000000..df68ce5 --- /dev/null +++ b/src/infra.gentoo.org/rsync-node/deny-rsync.lua @@ -0,0 +1,12 @@ +function rsync_deny(applet) + applet:send("@RSYNCD: 29.0\n") + local banmsg = applet:get_var("txn.rsync_deny_message") + if banmsg == nil then + banmsg = "MESSAGE GOES HERE" + end + applet:send(banmsg) + applet:send("\n") + applet:send("@RSYNCD: EXIT\n") +end + +core.register_service("deny-rsync", "tcp", rsync_deny) diff --git a/src/infra.gentoo.org/rsync-node/ha-proxy.conf b/src/infra.gentoo.org/rsync-node/ha-proxy.conf new file mode 100644 index 0000000..0b24063 --- /dev/null +++ b/src/infra.gentoo.org/rsync-node/ha-proxy.conf @@ -0,0 +1,72 @@ +# This is a very very minimal rsync config that gives ratelimit and ban messages + +global + lua-load 01-deny-rsync.lua + +frontend fe_rsync + mode tcp + bind *:9873 + tcp-request content set-var(txn.rsync_deny_message) str("") # Start empty + # Track the backend state + acl rsync_dead nbsrv(be_rsync) lt 1 + # Clients will see 'rsync: did not see server greeting' + tcp-request content reject if rsync_dead + # Clients will see 'rsync offline' + tcp-request content set-var(txn.rsync_deny_message) str("rsync offline") if rsync_dead + + # Track abuse + stick-table type ip size 200k expire 30s store gpc0,conn_rate(10s),http_req_rate(10s) + acl source_is_abuser src_get_gpc0 gt 0 + acl conn_rate_abuse sc1_conn_rate gt 3 + acl mark_as_abuser sc1_inc_gpc0 ge 0 + tcp-request connection track-sc1 src + tcp-request content set-var(txn.rsync_deny_message) str("BANHAMMER") if conn_rate_abuse mark_as_abuser source_is_abuser + + # If the deny message is longer than zero, issue deny message + # Clients will see the message and the rsync client will exit with a SUCCESS state! + tcp-request content use-service lua.deny-rsync if { var(txn.rsync_deny_message) -m len gt 0 } + + # Otherwise use the backend + default_backend be_rsync + +backend be_rsync + mode tcp + # This gives pure HAProxy check + # Other alternatives would be external-check that execs rsync or very + # bleeding edge lua-check + option tcp-check + tcp-check connect + # Step 1 + tcp-check comment "Client Initialization" + tcp-check send "@RSYNCD: 28.0\n" + # Step 2 + tcp-check comment "Server Initialization" + tcp-check expect rstring "@RSYNCD: [0-9.]+" + # Step 3 + tcp-check comment "Client Query (module name rsync-health)" + tcp-check send "rsync-health\n" + # Step 4 + tcp-check comment "Data (module name rsync-health)" + tcp-check expect string "@RSYNCD: OK\n" + # If the directory for the healthcheck does not exist, rsync will generate + # "@ERROR: chroot failed" + # Step 5 + tcp-check comment "Cleanup" + tcp-check send "@RSYNCD: EXIT\n" + # This still leads to messy logs in rsync itself + # and rsync doesn't have the original source IP (does it really need it?) + # rsyncd[6562]: connect from localhost (127.0.0.1) + # rsyncd[6562]: rsync: safe_read failed to read 1 bytes [Receiver]: Connection reset by peer (104) + # rsyncd[6562]: rsync error: error in rsync protocol data stream (code 12) at io.c(276) [Receiver=3.1.3] + + # This is where we'd put the realservers using discovery + server localhost localhost:873 check + # Service discovery instead would look like: + #server-template gentoo-rsync 50 _gentoo-rsync._tcp.service.consul resolvers consul resolve-prefer ipv4 maxconn 64 check rise 3 fall 2 check + +#resolvers consul +# nameserver consul $consul-client-ip:8600 +# resolve_retries 30 +# timeout retry 2s +# hold valid 120s +# accepted_payload_size 8192 |