Heyho,
während der Entwicklung einer API (auf WSC-Basis) wollte ich Rate-Limits implementieren und diese anschließend mittels ab (apache-utils) testen:
Dabei ist mir aufgefallen, dass es scheinbar problemlos möglich ist, einen Server zu DDosen und die Last auf 100% zu pushen. Nun scheint es allerdings auch so, dass ich mit diesem Problem nicht alleine bin. Xopez und Hanashi haben gestattet, dass ich die Auswirkungen auch auf deren Servern teste (bei Xopez ist sogar CF vorgeschaltet). Ergebnis:
Tatsächlich habe ich mich bisher gar nicht so sehr damit auseinander gesetzt. Um so erschrockener bin ich über die Tatsache, dass so viele Server scheinbar nicht unbedingt zur Abwehr dieses doch sehr einfachen "Angriffs" konfiguriert sind.
Auf unserem Server sind zwar etliche IPTables-Regeln und sysctl-Konfigurationen¹ zur Abwehr (oder zumindest zur Milderung der Auswirkungen) gewisser Attacken vorhanden und auch nginx ist gewissermaßen konfiguriert², aber trotz einer 429er Response werden zig PHP und MySQL-Prozesse gestartet und ich habe keinen blassen Schimmer, wie sich das effektiv verhindern lässt, ohne legitime Aufrufe ggf. zu blockieren.
Hat sich schon einmal jemand intensiver damit auseinander gesetzt und ein paar Tipps?
¹ =
kernel.printk = 4 4 1 7
kernel.panic = 10
kernel.sysrq = 0
kernel.shmmax = 4294967296
kernel.shmall = 4194304
kernel.core_uses_pid = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
vm.swappiness = 20
vm.dirty_ratio = 80
vm.dirty_background_ratio = 5
fs.file-max = 2097152
net.core.netdev_max_backlog = 262144
net.core.rmem_default = 31457280
net.core.rmem_max = 67108864
net.core.wmem_default = 31457280
net.core.wmem_max = 67108864
net.core.somaxconn = 65535
net.core.optmem_max = 25165824
net.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 16384
net.ipv4.neigh.default.gc_interval = 5
net.ipv4.neigh.default.gc_stale_time = 120
net.netfilter.nf_conntrack_max = 10000000
net.netfilter.nf_conntrack_tcp_loose = 0
net.netfilter.nf_conntrack_tcp_timeout_established = 1800
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 20
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 20
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 20
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 20
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 10
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.ip_no_pmtu_disc = 1
net.ipv4.route.flush = 1
net.ipv4.route.max_size = 8048576
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_congestion_control = htcp
net.ipv4.tcp_mem = 65536 131072 262144
net.ipv4.udp_mem = 65536 131072 262144
net.ipv4.tcp_rmem = 4096 87380 33554432
net.ipv4.udp_rmem_min = 16384
net.ipv4.tcp_wmem = 4096 87380 33554432
net.ipv4.udp_wmem_min = 16384
net.ipv4.tcp_max_tw_buckets = 1440000
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 400000
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rfc1337 = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_fack = 1
net.ipv4.tcp_ecn = 2
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 10
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.ip_forward = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.rp_filter = 1
Alles anzeigen
² =
limit_req_status 429;
limit_conn_status 429;
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:15m;
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:15m rate=40r/s;
client_body_timeout 5s;
client_header_timeout 5s;
send_timeout 5;
# ...
limit_conn conn_limit_per_ip 40;
limit_req zone=req_limit_per_ip burst=40 nodelay;
Alles anzeigen