After talking to the support folks there we realized that at some point the limits were tweaked but we didn't update the docs. Signed-off-by: Christian Heusel <christian@heusel.eu>
8.2 KiB
Since Arch Linux is the continued target of DDoS attacks (see the related announcement) by all technical means we have evaluated a lot of different providers mostly regarding the following requirements:
- No need to terminate TLS with $vendor / ensure end-to-end encryption from the User to our service
- Ability to also work with non-HTTP traffic such as TCP/22 for SSH on the AUR
- Reasonable to no costs
- Technical feasibility (i.e. no need to bring our own IP subnet etc.)
- Minimize impact for legitimate user, i.e. ensure continued service reachability even for countries under sanction
As it turns out this is a rather scarce field with regards to possible providers, as most either service enterprise customers and work more on BGP level and others only do CDN-type setups which force TLS termination and are not suited for protocols other than HTTP(S).
Below you can find more information on the solution that we went for in the end.
HAProxy Application Delivery Network
Architecture and background information
- IP rewrite & nginx rate limiting: We are using the nginx realip
module to re-add the source IP of the request back to
the proxied data. The tricky thing here is that the full list of all proxies
needs to be declared trusted in nginx in order to make the rewriting work
(which is different from the Hetzner Load Balancer case as its only ever one
IP that we need to rewrite from) and the IPs for this are stored in
vault_proxy_vendor_ips.ymland might periodically need refreshing. With this in place both logging and nginx rate limiting should work with the regular configuration options. proxy_protocol: HAProxy sends us the forwarded requests with the source IP preserved in form of theproxy_protocol. In consequence we have to teach nginx how to accept the proxy protocol, as this is incompatible with a regularlistendirective in nginx. A service can listen for bothproxy_protocoland regular traffic, but then one of the twolistendirectives has to be bound to a specific interface. Most of this logic is abstracted away in thelisten-*.confsnippets as part of thenginxAnsible role.- fail2ban: Since our regular
fail2banremediation logic is based on the fact that the client is connecting to us directly and we can just ban via a ipset in firewalld this does not work for us anymore. In the future (see the related issue) we plan to we tunnel the incoming TCP traffic through a nginxstream {...}directive, which we then populate withdeny XXX.XXX.XXX.XXX;entries fromfail2ban. Additionally we need to allowlist the IPs of the ADN proxies in order to not lock the users of a certain point of presence out on accident.
Setting up a service
Preparation:
- Floating IPs: In order to give HAProxy a stable IP for the setup of
their service we reserve a new Floating IP for the server. After then
switching behind the ADN Proxy we rotate the IPs so that the attackers can
not go for the backend directly. This reservation can be done with the
floating_ipv6 = trueargument inarchlinux.tfand the resulting floating IPs need to be added to theadditional_addresseshostvar and rolled out via thecommonrole. - ADN Ticket: By going through the New ADN Property
form one can create a new service on the Application Delivery Network. Note
that we want to only create a TCP forwarding without being SSL involved on
the HAProxy side as we keep terminating TLS ourselves. For services that
support it (i.e. currently anything behind nginx) also ask for
proxy_protocolto be enabled to preserve initial clients IPs. This setup requires some manual checking on their side, so it is not instant and therefore should be prepared beforehand for any service that proved to be at risk. After the creation HAProxy will respond with the setup details like the fronting IPv4 and IPv6 addresses. SeeMSK-481-77696for an example ticket.
Setup:
- Inventory & vault changes: After reserving the Floating IPs in the
preparation setup the interface assignments need to be persisted for the
machine by using the
additional_addressesvariable from a newly created vault, since the backend IPs can not be public. In order to not rely on HAProxy working for management access(and since most services will not expose SSH via HAProxy) it also makes sense to setansible_hostto the floating IP assignment in the same vault. - IP address rotation: So far there is no way to do this by purely
automated means, hence here is a rough description of the clickops'ed
workflow:
- For each Floating IP on the server, disable protection and unassign it.
- For each Primary IP on the server, disable protection and unassign it (unassigning ensures that we actually get new IPs).
- Disable and re-enable public networking on the server.
- Turn the server back on and fix the IP address entries in Ansible
host_vars. - Make
terraformhappy again by removing the previous rdns entries from the state:terraform state rm 'hcloud_rdns.rdns_ipv4["archlinux.org"]'. - Force wireguard re-peering by running
ip link delete wg0 && networkctl reload(see the related issue) - Figure out all other gnarly dependencies on the IP in question, i.e. allowlists in some rsyncd conf or firewall entries.
- nginx Change: Most of the logic is already implemented in Ansible, so
it's mostly about the following two changes:
- Ensure that the nginx config of the service already uses the
snippets/listen-*.conf. - Set
nginx_proxy_vendor: haproxyin thehost_vars. - Deploying the service role (i.e.
aurweb) aswell as thenginxrole and manually disablefail2ban.
- Ensure that the nginx config of the service already uses the
- DNS Change: After all is ready the DNS can be set to the HAProxy provided addresses.
Services currently running behind HAProxy ADN
HAProxy has made some measurements on what regular traffic and irregulars are and recommended the some rate limits for our services after checking with us.
The effects of these limits can be seen on the WAF Realtime Overview under the "WAF Attack Breakdown" section. If a single IP needs to be investigated this is possible on the WAF Details Page, especially under the "IPs" section.
archlinux.org- https: 25
- http: 25
aur.archlinux.org- https: 50
- http: 25
- ssh: 25
bbs.archlinux.org- https: 25
- http: 25
man.archlinux.org- https: 25
- http: 25
wiki.archlinux.org- https: 25
- http: 25
test.pkgbuild.com
The unit of these limits is the amount of allowed connections per moving 10 second window per IP.
Additionally HAProxy has implemented request queuing for ASNs and specific traffic origins that frequently are the source of DDoS attacks, so far this has only been activiated for traffic coming from proxy networks. The queuing system scores traffic internally and tries to give higher priority to all traffic that is most likely not malicious.
