"go-dots" is a DDoS Open Threat Signaling (dots) implementation written in Go. This implmentation is based on the Internet drafts below.
- draft-ietf-dots-signal-channel-26
- draft-ietf-dots-data-channel-24
- draft-ietf-dots-architecture-06
- draft-ietf-dots-requirements-14
- draft-ietf-dots-use-cases-14
- draft-nishizuka-dots-signal-control-filtering-03
This implementation is not fully compliant with the documents listed above. For example, we are utilizing CoAP as the data channel protocol while the current version of the data channel document specifies RESTCONF as the data channel protocol.
Licensed under Apache License 2.0.
-
gcc 5.4.0 or higher
-
make, autoconf, automake, libtool, pkg-config, pkgconf or pkg-config
-
- go 1.11 or later is required. (for the latest GoBGP - v2.1.0)
- set PATH to go and set $GOPATH, using their instructions.
-
- OpenSSL 1.1.1 or higher (for libcoap)
-
MySQL 5.7.x and its development package (MySQL 8.0.x or higher not yet supported)
- Install mysql development package in Ubuntu: $ sudo apt-get install libmysqld-dev
- Ubuntu 16.04+
- macOS High Sierra 10.13+
Currenly supported libcoap version : 1eadd91
$ git clone https://github.com/obgm/libcoap.git
$ cd libcoap
$ git checkout 1eadd91366cab46767f26e4d10e005198246eac1
$ ./autogen.sh
$ ./configure --disable-documentation --with-openssl
$ make
$ sudo make install
To install go-dots source codes and command line programs, use the following command:
$ go get -u github.com/nttdots/go-dots/...
$ cd $GOPATH/src/github.com/nttdots/go-dots/
$ make && make install
go-dots consists of 3 daemons below:
- dots_server: dots server agent
- dots_client: dots client specified in the Internet drafts
- dots_client_controller: The controller for the dots_client. Operators controll the dots_client by this controller
To explain the relationships between each daemons in detail, here we illustrates the mitigation request procedure of our system. First, dots_client_controller passes request JSONs to the dots_client. Examples of these JSONs are located in the 'dots_client/' directory in this Github project. Remember to edit the 'mitigation-id' fields in the JSON file every time you make requests to the dots_server. Then the dots client converts the received JSON to the CBOR format and send a mitigation request to the server via a CoAP connection.
The figure below shows the detailed sequence diagram which depicts how a dots_server handles a mitigation request.
Upon receiving CoAP messages, a dots_server first find the appropriate message controller for the received message. The message controller first find the customer information bound with the common name field contained in the client certificate. The customer information is configured and stored in the RDB before the server is started. To setup databases, refer to Setting up databases. If no appropriate customer objets is found, the dots_server decline the received request.
Then the server retrieves mitigation scopes contained in the received mitigation request message. Again the dots_server validate the mitigation scopes to determine whether the customer which issued the request has the valid privilege for the mitigation operations. If the validation is successfully completed, the server select a blocker for the mitigation and execute the mitigation.
Server Configuration is done by the system configuration file and the database setup. The system configuration file is specified via '-config' option when the 'dots_server' is invoked. The sample configuration files are located as 'dots_server/dots_server.yaml' and 'dots_server/dots_server.yaml.template'.
The blocker configuration of DOTS server is defined in database. For more detail about database, refer to the Database configuration document
$ $GOPATH/bin/dots_server --config [config.yml file (ex: go-dots/dots_server/dots_server.yaml)]
$ $GOPATH/bin/dots_client --server localhost --signalChannelPort=4646 --config [config.yml file (ex: go-dots/dots_client/dots_client.yaml)] -vv
To install and run gobgp-server, refer to the following link:
The Arista Server (Arista Switch Hardware) is installed and executed on Arista Extensible Operating System (EOS) platform. In order to connect to Arista Server, DOTS server use 'goeapi' open source library that is provided by Arista Networks company and the configuration file (.eapi.conf) which contains information about the Arista networks such as: host, username, password, etc.
[connection:arista]
host=arista
username=admin
password=123456
enablepwd=passwd
transport=https
For more detailed information about the configuration of 'goeapi', refer to the following link:
The primary purpose of the signal channel is for a DOTS client to ask a DOTS server for help in mitigating an attack, and for the DOTS server to inform the DOTS client about the status of such mitigation.
$ $GOPATH/bin/dots_client_controller -request mitigation_request -method Put \
-cuid=dz6pHjaADkaFTbjr0JGBpw -mid=123 \
-json $GOPATH/src/github.com/nttdots/go-dots/dots_client/sampleMitigationRequestDraft.json
In order to handle out-of-order delivery of mitigation requests, 'mid' values MUST increase monotonically. Besides, if the 'mid' value has exceeded 3/4 of (2**32 - 1), it should be reset by sending a mitigation request with 'mid' is set to '0' to avoid 'mid' rollover. However, the reset request is only accepted by DOTS server at peace-time (have no any active mitigation request which is maintaining).
$ $GOPATH/bin/dots_client_controller -request mitigation_request -method Put \
-cuid=dz6pHjaADkaFTbjr0JGBpw -mid=0 \
-json $GOPATH/src/github.com/nttdots/go-dots/dots_client/sampleMitigationRequestDraft.json
$ $GOPATH/bin/dots_client_controller -request mitigation_request -method Get \
-cuid=dz6pHjaADkaFTbjr0JGBpw
$ $GOPATH/bin/dots_client_controller -request mitigation_request -method Get \
-cuid=dz6pHjaADkaFTbjr0JGBpw -mid=123
$ $GOPATH/bin/dots_client_controller -request mitigation_request -method Delete \
-cuid=dz6pHjaADkaFTbjr0JGBpw -mid=123
A DOTS client can convey the 'observe' option set to '0' in the GET request to receive notification whenever status of mitigation request changed and unsubscribe itself by issuing GET request with 'observe' option set to '1'
Subscribe for resource observation:
$ $GOPATH/bin/dots_client_controller -request mitigation_request -method Get \
-cuid=dz6pHjaADkaFTbjr0JGBpw -mid=123 -observe=0
Unsubscribe from resource observation:
$ $GOPATH/bin/dots_client_controller -request mitigation_request -method Get \
-cuid=dz6pHjaADkaFTbjr0JGBpw -mid=123 -observe=1
Subscriptions are valid as long as current session exists. When session is renewed (e.g DOTS client does not receive response from DOTS server for its Ping message in a period of time, it decided that server has been disconnected, then re-connects), all previous subscriptions will be lost. In such cases, DOTS clients will have to re-subscribe for observation. Below is recommended step:
・GET a list of all existing mitigations (that were created before server restarted)
・PUT mitigations one by one
・GET + Observe for all the mitigations that should be observed
A DOTS client can convey the 'If-Match' option with empty value in the PUT request to transmit DOTS mitigation efficacy update to the DOTS server:
$ $GOPATH/bin/dots_client_controller -request mitigation_request -method Put \
-cuid=dz6pHjaADkaFTbjr0JGBpw -mid=123 -ifMatch="" \
-json $GOPATH/src/github.com/nttdots/go-dots/dots_client/sampleMitigationRequestDraftEfficacyUpdate.json
$ $GOPATH/bin/dots_client_controller -request session_configuration -method Put \
-sid 234 \
-json $GOPATH/src/github.com/nttdots/go-dots/dots_client/sampleSessionConfigurationDraft.json
In order to handle out-of-order delivery of session configuration, 'sid' values MUST increase monotonically.
$ $GOPATH/bin/dots_client_controller -request session_configuration -method Get
$ $GOPATH/bin/dots_client_controller -request session_configuration -method Get \
-sid 234
$ $GOPATH/bin/dots_client_controller -request session_configuration -method Delete \
-sid 234
DOTS signal channel session configuration supports 2 sets of parameters : 'mitigating-config' and 'idle-config'. The same or distinct configuration set may be used during times when a mitigation is active ('mitigating-config') and when no mitigation is active ('idle-config'). Dots_client uses 'idle-config' parameter set by default. It can be configured to switch to the other parameter set by client_configuration request
Configure dots_client to use 'idle-config' parameters
$ $GOPATH/bin/dots_client_controller -request client_configuration -method POST \
-json $GOPATH/src/github.com/nttdots/go-dots/dots_client/sampleClientConfigurationRequest_Idle.json
Configure dots_client to use 'mitigating-config' parameters
$ $GOPATH/bin/dots_client_controller -request client_configuration -method POST \
-json $GOPATH/src/github.com/nttdots/go-dots/dots_client/sampleClientConfigurationRequest_Mitigating.json
The primary purpose of the data channel is to support DOTS related configuration and policy information exchange between the DOTS client and the DOTS server.
All shell-script and sample json files are located in below directory: $ cd $GOPATH/src/github.com/nttdots/go-dots/dots_client/data/
Get root resource:
$ ./get_root_resource.sh SERVER_NAME
Example:
- Request: $ ./get_root_resource.sh https://127.0.0.1:10443
- Response:
<XRD xmlns="https://127.0.0.1">
<Link rel="restconf" href="https://127.0.0.1:10443/v1/restconf"></Link>
</XRD>
"{href}" value will be used as the initial part of the path in the request URI of subsequent requests
Registering DOTS Clients
Post dots_client:
$ ./do_request_from_file.sh POST {href}/data/ietf-dots-data-channel:dots-data sampleClient.json
Put dots_client:
$ ./do_request_from_file.sh PUT {href}/data/ietf-dots-data-channel:dots-data/dots-client=123 sampleClient.json
Uregistering DOTS Clients
$ ./do_request_from_file.sh DELETE {href}/data/ietf-dots-data-channel:dots-data/dots-client=123
Create Aliases
Post alias:
$ ./do_request_from_file.sh POST {href}/data/ietf-dots-data-channel:dots-data/dots-client=123 sampleAlias.json
Put alias:
$ ./do_request_from_file.sh PUT {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/aliases/alias=xxx sampleAlias.json
Retrieve Installed Aliases
Get all aliases without 'content' parameter (default is get all type attributes, including configurable and non-configurable attributes):
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/aliases
Get all aliases with 'content'='config' (get configurable attributes only):
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/aliases?content=config
Get all aliases with 'content'='nonconfig' (get non-configurable attributes only):
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/aliases?content=nonconfig
Get all aliases with 'content'='all'(get all type attributes, including configurable and non-configurable attributes):
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/aliases?content=all
Get specific alias without 'content' parameter:
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/aliases/alias=https1
Get specific alias with 'content'='config':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/aliases/alias=https1?content=config
Get specific alias with 'content'='nonconfig':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/aliases/alias=https1?content=nonconfig
Get specific alias with 'content'='all':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/aliases/alias=https1?content=all
Delete Aliases
$ ./do_request_from_file.sh DELETE {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/aliases/alias=https1
Retrieve DOTS Filtering Capabilities
Get Capabilities without 'content' parameter:
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/capabilities
Get Capabilities with 'content'='config':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/capabilities?content=config
Get Capabilities with 'content'='nonconfig':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/capabilities?content=nonconfig
Get Capabilities with 'content'='all':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/capabilities?content=all
Install Filtering Rules
Post acl:
$ ./do_request_from_file.sh POST {href}/data/ietf-dots-data-channel:dots-data/dots-client=123 sampleAcl.json
Put acl:
$ ./do_request_from_file.sh PUT {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/acls/acl=xxx sampleAcl.json
Retrieve Installed Filtering Rules
Get all Acl without 'content' parameter:
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/acls
Get all Acl with 'content'='config':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/acls?content=config
Get all Acl with 'content'='nonconfig':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/acls?content=nonconfig
Get all Acl with 'content'='all':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/acls?content=all
Get specific acl without 'content' parameter:
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/acls/acl=sample-ipv4-acl
Get specific acl with 'content'='config':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/acls/acl=sample-ipv4-acl?content=config
Get specific acl with 'content'='nonconfig':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/acls/acl=sample-ipv4-acl?content=nonconfig
Get specific acl with 'content'='all':
$ ./do_request_from_file.sh GET {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/acls/acl=sample-ipv4-acl?content=all
Remove Filtering Rules
$ ./do_request_from_file.sh DELETE {href}/data/ietf-dots-data-channel:dots-data/dots-client=123/acls/acl=sample-ipv4-acl
Unlike the DOTS signal channel, the DOTS data channel is not expected to deal with attack conditions. Therefore, when DOTS client is under attacked by DDoS, the DOTS client can use DOTS signal channel protocol to manage the filtering rule in DOTS Data Channel to enhance the protection capability of DOTS protocols.
$ $GOPATH/bin/dots_client_controller -request mitigation_request -method Put \
-cuid=dz6pHjaADkaFTbjr0JGBpw -mid=123 \
-json $GOPATH/src/github.com/nttdots/go-dots/dots_client/sampleMitigationRequestDraftControlFiltering.json
To set up your database, refer to the Database configuration document
The 'dots_server' accesses the 'dots' database on MySQL as the root user.
$ cd $GOPATH/src/github.com/nttdots/go-dots/
$ mysql -u root -p dots < ./dots_server/db_models/test_dump.sql
Or you can run MySQL on docker.
$ cd $GOPATH/src/github.com/nttdots/go-dots/
$ docker run -d -p 3306:3306 -v ${PWD}/dots_server/db_models/test_dump.sql:/docker-entrypoint-initdb.d/test_dump.sql:ro -e MYSQL_DATABASE=dots -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql
DOTS server listens to DB notification (e.g changes to mitigation_scope#status) at port 9999. If you want to change to different port, you have to change it at two places:
- dots_server/dot_server.yaml: dbNotificationPort: 9999
- mysql_udf/mysql-notification.c: #define PORT 9999
After changing port number, it is neccessary to rebuild go-dots (which includes rebuilding mysql-notification.c and restarting DB) so that the change can take effect.
$ cd $GOPATH/src/github.com/nttdots/go-dots/
$ make && make install
Check the route is installed successfully in gobgp server
$ gobgp global rib
Network Next Hop AS_PATH Age Attrs
*> 172.16.238.100/32 172.16.238.254 00:00:42 [{Origin: i}]
Check the active Arista ACL that is installed successfully in Arista server
$ show running-config interfaces Ethernet 1
interface Ethernet1
description DDoS-Seg-to_internet
ip address 172.16.238.100/30
ip access-group mitigation-acl-1 in
Check the active rules in Arista ACL that is installed successfully in Arista server
$ show ip access-lists mitigation-acl-1
IP Access List mitigation-acl-1
10 deny 4 any 1.1.2.0/24
20 deny 4 any host 1.1.1.69
Check the flowspec route is installed successfully in gobgp server
$ gobgp global rib -a ipv4-flowspec
$ gobgp global rib -a ipv6-flowspec
Network Next Hop AS_PATH Age Attrs
*> [destination: 1.1.2.0/24][protocol: ==tcp][destination-port: >=443&<=800] fictitious 00:00:06 [{Origin: i} {Extcomms: [redirect: 1.1.1.0:100]}]