GithubHelp home page GithubHelp logo

ltd-beget / syncookied Goto Github PK

View Code? Open in Web Editor NEW
316.0 22.0 47.0 296 KB

syn flood protection

License: GNU General Public License v2.0

Rust 63.78% C 30.38% Assembly 5.29% Shell 0.55%
netmap traffic-filtering flood-attacks traffic rust tcp syn-flood

syncookied's Introduction

syncookied

syncookied logo

Build Status

syncookied emulates linux kernel syncookie functionality by intercepting SYN packets and sending replies to them using the same cookie generation alghorithm. It can achieve better performance under SYN flood attacks thanks to kernel bypass (netmap).

Installation

  1. Install rust (instructions here: https://www.rust-lang.org/en-US/downloads.html)
  2. Install build-essential and libpcap-dev or equivalent package for your distribution
  3. Install netmap. Make sure netmap.h / netmap_user.h can be found in /usr/include. Alternative you can point CFLAGS variable to their location: example.
  4. run cargo build --release, resulting binary will be found in target/release/syncookied.

Note: we use AVX-accelerated SHA1 function by default. SSE3 implementation is also available under sse3 feature flag, i.e.: cargo build --features=sse3 --no-default-features --release.

How to run

On server you want to protect

  1. Install tcpsecrets linux kernel mode to expose tcp syncookie key and timestamp
  2. Start syncookied in server mode: syncookied server <proto://ip:port>. Running this commands automatically starts a TCP or UDP server on specified ip/port and sets net.ipv4.tcp_syncookies to 2 on first request.

On server you want to use for packet processing

  1. Install netmap and make sure it works (pkt-gen)

  2. Disable NIC offloading features on the interface you want to use (eth2 here):

    ethtool -K eth2 gro off gso off tso off lro off rx off tx off 
    ethtool -A eth2 rx off tx off
    ethtool -G eth2 rx 2048 tx 2048
    
  3. Set up queues and affinities. Here we bind 12 queues to first 12 cpu cores:

    QUEUES=12
    ethtool -L eth2 combined $QUEUES
    ./set_irq_affinity -x 0-11 eth2
    

    set_irq_affinity is available at https://github.com/majek/ixgbe/blob/master/scripts/set_irq_affinity

  4. Create hosts.yml file in the working directory, which looks like this

    - ip: 185.50.25.4
      secrets_addr: udp://192.168.3.231:1488
      mac: 0c:c4:7a:6a:fa:bf
    

Here ip is external ip you want to protect, secrets_addr is the address of syncookied server running on protected host, and mac is its MAC address.

  1. Run syncookied -i eth2. It will print something like this:

    Configuration: 185.50.25.4 -> c:c4:7a:6a:fa:bf
    interfaces: [Rx: eth2/3c:fd:fe:9f:a8:82, Tx: eth2/3c:fd:fe:9f:a8:82] Cores: 24
    12 Rx rings @ eth2, 12 Tx rings @ eth2 Queue: 1048576
    Starting RX thread for ring 0 at eth2
    Starting TX thread for ring 0 at eth2
    Uptime reader for 185.50.25.4 starting
    ...
    
  2. Configure your network equipment to direct traffic for protected ip to syncookied.

  3. You can reload configuration at any time by changing hosts.yml and sending HUP signal to syncookied. It will print something like this:

    Uptime reader for 185.50.25.4 exiting
    All uptime readers dead
    Old readers are dead, all hail to new readers
    Uptime reader for 185.50.25.4 starting
    ...
    
  4. Enjoy your ddos protection

Notes

syncookied has some options you may want to tune, see syncookied --help. If you have more than 1 interface on your server, you may want to look into -O to use second one for TX. This greatly improves performance and latency as forwarding and syn-reply traffic is separated.

Traffic filtering

It's possible to filter traffic by adding "filters" section to host configuration like this:

- ip: 185.50.25.4
  secrets_addr: 127.0.0.1:1488
  mac: 0c:c4:7a:6b:0a:78
  filters:
   tcp and dst port 53: drop
   tcp and dst port 22: pass
   default: pass

Filters are written in pcap syntax. Consult pcap-filter(7) for more information. Default policy is "pass". It can be changed by using default key. Note that filtering happens on layer 4.

Troubleshooting

Please check the FAQ before filing an issue.

Need help?

Join us on Telegram: https://telegram.me/syncookied

Performance

syncookied under 12.65 Mpps syn flood attack utilizing 12 cores of Xeon E5-2680v3: syncookied perf

License

syncookied is distributed under the term of GPLv2.

syncookied's People

Contributors

alexeymanikin avatar polachok avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

syncookied's Issues

Travis fails to upload binary

/home/travis/.rvm/gems/ruby-2.2.5/gems/octokit-4.3.0/lib/octokit/response/raise_error.rb:16:in `on_complete': GET https://api.github.com/user: 401 - Bad credentials // See: https://developer.github.com/v3 (Octokit::Unauthorized)
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/faraday-0.9.2/lib/faraday/response.rb:9:in `block in call'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/faraday-0.9.2/lib/faraday/response.rb:57:in `on_complete'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/faraday-0.9.2/lib/faraday/response.rb:8:in `call'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/octokit-4.3.0/lib/octokit/middleware/follow_redirects.rb:73:in `perform_with_redirection'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/octokit-4.3.0/lib/octokit/middleware/follow_redirects.rb:61:in `call'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/faraday-0.9.2/lib/faraday/rack_builder.rb:139:in `build_response'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/faraday-0.9.2/lib/faraday/connection.rb:377:in `run_request'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/faraday-0.9.2/lib/faraday/connection.rb:140:in `get'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/sawyer-0.7.0/lib/sawyer/agent.rb:94:in `call'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/octokit-4.3.0/lib/octokit/connection.rb:154:in `request'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/octokit-4.3.0/lib/octokit/connection.rb:19:in `get'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/octokit-4.3.0/lib/octokit/client/users.rb:34:in `user'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/dpl-1.8.22/lib/dpl/provider/releases.rb:43:in `user'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/dpl-1.8.22/lib/dpl/provider/releases.rb:68:in `setup_auth'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/dpl-1.8.22/lib/dpl/provider/releases.rb:72:in `check_auth'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/dpl-1.8.22/lib/dpl/provider.rb:133:in `block in deploy'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/dpl-1.8.22/lib/dpl/cli.rb:41:in `fold'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/dpl-1.8.22/lib/dpl/provider.rb:132:in `deploy'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/dpl-1.8.22/lib/dpl/cli.rb:32:in `run'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/dpl-1.8.22/lib/dpl/cli.rb:7:in `run'
    from /home/travis/.rvm/gems/ruby-2.2.5/gems/dpl-1.8.22/bin/dpl:5:in `<top (required)>'
    from /home/travis/.rvm/gems/ruby-2.2.5/bin/dpl:23:in `load'
    from /home/travis/.rvm/gems/ruby-2.2.5/bin/dpl:23:in `<main>'
failed to deploy

Server broke tcp connection with RST flag

We trying to use Syncookied on test env and have trouble with connection.
telnet trying to connect to opened 80 port on Protected server, but unsuccessfully.

Transition of the client session:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on venet0, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
11:05:33.316435 IP 92.63.98.40.36798 > 89.111.56.136.http: Flags [S], seq 3208781071, win 14600, options [mss 1460,sackOK,TS val 1624259346 ecr 0,nop,wscale 8], length 0
11:05:33.383044 IP 89.111.56.136.http > 92.63.98.40.36798: Flags [S.], seq 369175399, ack 3208781072, win 65535, options [mss 1460,sackOK,TS val 437399 ecr 1624259346,nop,wscale 7], length 0
11:05:33.383083 IP 92.63.98.40.36798 > 89.111.56.136.http: Flags [.], ack 1, win 58, options [nop,nop,TS val 1624259413 ecr 437399], length 0
11:05:33.446237 IP 89.111.56.136.http > 92.63.98.40.36798: Flags [R], seq 369175400, win 0, length 0

Firewall running Syncookied with arguments syncookied -i eth0 -c /etc/syncookied/hosts.yml -o eth2

Contents of hosts.yml

- ip: 89.111.56.136
  local_ip: 10.10.11.177:1488
  mac: 5e:e2:67:9e:57:c1
  filters:
   tcp and dst port 9081: pass
   tcp and dst port 80: pass
   tcp and dst port 22: drop
   default: drop

Transition of Firewall session:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:07:21.648426 IP 92.63.98.40.55916 > 89.111.56.136.80: Flags [S], seq 183530866, win 14600, options [mss 1460,sackOK,TS val 1624367227 ecr 0,nop,wscale 8], length 0
11:07:21.709491 IP 92.63.98.40.55916 > 89.111.56.136.80: Flags [.], ack 973748478, win 58, options [nop,nop,TS val 1624367288 ecr 464407], length 0

Transition of Protected server session:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
11:07:21.747190 IP 92.63.98.40.55916 > 89.111.56.136.80: Flags [.], ack 973748478, win 58, options [nop,nop,TS val 1624367288 ecr 464407], length 0
11:07:21.747255 IP 89.111.56.136.80 > 92.63.98.40.55916: Flags [R], seq 973748478, win 0, length 0

Opened ports on Protected server:

State      Recv-Q Send-Q                                                  Local Address:Port                                                    Peer Address:Port 
LISTEN     0      5                                                           127.0.0.1:53                                                                 *:*     
LISTEN     0      128                                                                :::22                                                                :::*     
LISTEN     0      128                                                                 *:22                                                                 *:*      
LISTEN     0      1                                                                   *:80                                                                 *:*  

Content of /proc/tcp_secrets on Protected server:

4295469164 286364 250
07612fc7.eca943e4.072eabf9.429ddef1.eae04bcc.68cf7123.3d326366.ab0719ee.e6083207.d9b3f2af.eac58f40.2d7b6011.fe5ec306.214a71cb.e75566bb.631b1295.0b0298e6.
439aacec.9a5eca30.de5bb1d9.5af5d652.b609bada.2469f79c.55e4b2ba.f0ca7737.ad545720.5f83ae96.5badb7a0.e71e693a.4b35c6cb.7d61c477.23145335.96bc2b77.6ca1e633.

Protected server Linux xen-photo-cache1 4.6.0-0.bpo.1-amd64 #1 SMP Debian 4.6.4-1~bpo8+1 (2016-08-11) x86_64 GNU/Linux
Firewall server Linux pheonixs-test4 4.6.0-0.bpo.1-amd64 #1 SMP Debian 4.6.4-1~bpo8+1 (2016-08-11) x86_64 GNU/Linux

Also on Router we have static arp binding: 89.111.56.136<->18:03:73:ef:67:56

Ifconfig of Firewall:


1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc netmap_generic state UP group default qlen 1000
    link/ether 18:03:73:ef:67:56 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 18:03:73:ef:67:58 brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.52/22 brd 10.10.11.255 scope global eth1
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc netmap_generic state UP group default qlen 1000
    link/ether 18:03:73:ef:67:5a brd ff:ff:ff:ff:ff:ff
5: eth3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 18:03:73:ef:67:5c brd ff:ff:ff:ff:ff:ff

Ifconfig of Protected Server:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
    link/ether 5e:e2:67:9e:57:c1 brd ff:ff:ff:ff:ff:ff
    inet 89.111.56.136/24 brd 89.111.56.255 scope global eth0
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
    link/ether 82:04:8f:be:ce:27 brd ff:ff:ff:ff:ff:ff
    inet 10.10.11.177/22 brd 10.10.11.255 scope global eth1
       valid_lft forever preferred_lft forever


Investigate performance of libpnet upgrade

libpnet changed its packet structure in 0.10.x branch
We should investigate how it affects performance to see if it would be possible to upgrade instead of using our own branch

Passthrough mode

Hello,

What is "passthrough" mode supposed to do in the current implementation?

Metrics dashboard

What dashboard are you using for grafana?
I wasn't able to find it on their web.

Implement REST API for syncookied

Requested features:

  • Get currently protected IP list
  • Get firewall rules for IP
  • Add/remove IP to protected list
  • Add/remove firewall rule for protected IP
  • Change default firewall policy for IP

Static binaries

Provide statically linked binaries to simplify deployment

AVX support need is unclear

It seems that syncookied cookie_hash() function (in src/cookie.rs) heavily depends on AVX support by CPU by default, and if there's none it results it 'invalid opcode' errors, which is pretty predictable.
We found that there are several variations of sha1_transform function which depend on various instruction sets. So we just commented the AVX version and uncommented SSE3. And it worked.

What I'd suggest is to include this information in README so people without AVX extensions won't have to research why it doesn't work and/or probably even make the default sha1_transform the most compatible one.

There's also a comment:

TODO: use cargo features or runtime detection to choose the fastest

I'd add to that '...the fastest among compatible' .

port-forwarding probblem

Hello,

For some reason iptables port-forwarding doesn't work when syncookied is used to deliver the traffic.
Example:
iptables -t nat -A PREROUTING -i -p tcp -m tcp --dport 80 -j DNAT --to-destination :8080
The packet gets forwarded and immediately rejected (the web server replies with tcp-rst).

Any ideas ?

SYNPROXY mode

It would be very handy to have transparent SYNPROXY mode in syncookied
This will allow to protect any device without modication in kernel/OS/etc.

Question

What would be the best way to remove "cookie" and implement pure syn proxy ?
If possible - point me in the right direction.

Не компилируется

Здравствуйте!

Уточните, пожалуйста, почему может не компилироваться:
Running rustc /root/.cargo/git/checkouts/libpnet-ae38e659f18cc3c8/syncookied/pnet_macros/src/lib.rs --crate-name pnet_macros --crate-type lib -C opt-level=3 -g --cfg feature=\"syntex_syntax\" --cfg feature=\"with-syntex\" --cfg feature=\"default\" --cfg feature=\"syntex\" -C metadata=a683be57cc4c7cfe -C extra-filename=-a683be57cc4c7cfe --out-dir /usr/src/syncookied/target/release/deps --emit=dep-info,link -L dependency=/usr/src/syncookied/target/release/deps -L dependency=/usr/src/syncookied/target/release/deps --extern regex=/usr/src/syncookied/target/release/deps/libregex-a99351f81f55a22d.rlib --extern syntex_syntax=/usr/src/syncookied/target/release/deps/libsyntex_syntax-5a1d94417b53af6a.rlib --extern syntex=/usr/src/syncookied/target/release/deps/libsyntex-d786ed71bd2d7a6d.rlib --cap-lints allow
/root/.cargo/git/checkouts/bounded-spsc-queue-da0656e60eed9ff6/with/src/lib.rs:2:1: 2:68 error: #[feature] may not be used on the stable release channel [E0554]
/root/.cargo/git/checkouts/bounded-spsc-queue-da0656e60eed9ff6/with/src/lib.rs:2 #![feature(heap_api, oom, alloc, box_syntax, optin_builtin_traits)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Build failed, waiting for other jobs to finish...
error: Could not compile bounded-spsc-queue.

Caused by:
Process didn't exit successfully: rustc /root/.cargo/git/checkouts/bounded-spsc-queue-da0656e60eed9ff6/with/src/lib.rs --crate-name bounded_spsc_queue --crate-type lib -C opt-level=3 -g --cfg feature="default" -C metadata=83cd369280c8532d -C extra-filename=-83cd369280c8532d --out-dir /usr/src/syncookied/target/release/deps --emit=dep-info,link -L dependency=/usr/src/syncookied/target/release/deps -L dependency=/usr/src/syncookied/target/release/deps --cap-lints allow (exit code: 101)

Есть ли собранные deb и rpm-пакеты демона?

Passthrough performance

Passthrough performance with no filters is lower than expected (~8Mpps) on our test setup.

Docker image

Build docker image with compiled syncookied to simplify deploy.
Add documentation on how to run it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.