summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Warner <antarus@gentoo.org>2018-12-09 07:57:35 -0500
committerAlec Warner <antarus@gentoo.org>2018-12-09 07:57:35 -0500
commitaff65382d7a6b709552e36a9e3ccc86855761d71 (patch)
treeca47a56d09ecaa1f88875ec9b0086f21aeb21ea0
parentTry to get more atomic syncing for serving content. (diff)
downloadantarus-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/Dockerfile2
-rw-r--r--src/infra.gentoo.org/rsync-node/deny-rsync.lua12
-rw-r--r--src/infra.gentoo.org/rsync-node/ha-proxy.conf72
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