Giter Club home page Giter Club logo

ciscodevnet / mud-manager Goto Github PK

View Code? Open in Web Editor NEW
22.0 24.0 10.0 1.13 MB

Manufacturer Usage Description (MUD) is a technique whereby constrained end devices (e.g., IoT devices) can signal to the network what sort of access and network functionality they require to properly function

License: BSD 3-Clause "New" or "Revised" License

Makefile 6.10% M4 0.22% C 57.88% Shell 29.36% C++ 4.57% CSS 0.06% PHP 1.54% JavaScript 0.28%
ietf iot testing-tools

mud-manager's Introduction

alt text

MUD-Manager Version 3.0

A list of changes can be found down below.

Introduction

Manufacturer Usage Description (MUD) is a technique whereby constrained end devices (e.g., IoT devices) can signal to the network what sort of access and network functionality they require to properly function. The end device performs this signaling by issuing a URL in LLDP, DHCP, or as part of an X.509 certificate. A MUD Manager is a service sitting in the network that receives the MUD URL, fetches a MUD file containing access requirements provided by a manufacturer, and creates Access Control Lists (ACLs) that can be installed on network equipment to allow that access.

The MUD specification can be found in (https://tools.ietf.org/html/draft-ietf-opsawg-mud-25), which has been approved to be an IETF RFC. This implementation supports all abstractions, except model. In addition, source and destination IPv4 and IP networks from the ACL model are supported, so long as they are multicast addresses.

After you have installed the MUD Manager, guidance is available at (https://developer.cisco.com/docs/mud/#!mud-developer-guide) if you need help creating a MUD file, and/or preparing a device to emit a URL to a MUD file.

How the MUD Manager is used

The MUD Manager is used by a RADIUS server to translate a MUD URL into access control policies. The MUD Manager receives REST APIs containing the MUD URL (and possibly other information), and returns RADIUS attributes that can be sent to a Network Access Device (NAD) such as an Ethernet switch. The NAD installs the policy on the access port, which restricts the device providing the MUD URL to just its required network access.

A MUD URL is an "https://..." file, which means that TLS is used to fetch the file.

Dependancies

The MUD manager depends on the following packages.

OpenSSL

OpenSSL is used for cryptographic services, and is available on most Linux systems. If not, then a recent release will need to be installed. It may be available using a package installer (such as apt-get), else it can be downloaded from https://www.openssl.org.

If a Linux distribution has openssl, but you cannot link to it try:

sudo apt-get install -y libssl-dev # debian

or

yum install openssl-devel # centos

cJSON

cJSON is used for JSON processing in "C". Download it from GitHub:

git clone https://github.com/DaveGamble/cJSON
cd cJSON 
make
sudo make install

MongoDB

MongoDB is used to store the MUD URLs, policy derived from the MUD URLs, and MAC addresses that are associated with a MUD URL.

Instructions for installing MongoDB with a package manager can be found here. Alternatively it can be downloaded with git, and the follow the instructions in its README.

git clone https://github.com/mongodb/mongo.git

The MongoDB service should be started automatically when the system boots. If you see an indication that the MUD Manager cannot reach the MongoDB server, you can try

sudo service mongodb start # (Recent Debian/Ubuntu releases)
sudo /etc/init.d/mongod start # Amazon/CentOS\

Mongo C driver

The Mongo C driver is needed for the MUD manager to communicate with MongoDB. Download from https://github.com/mongodb/mongo-c-driver/releases. We suggest version 1.7.0 or later, but in any case a version that supports PKG-CONFIG (this excludes the Debian package manager).

To retrieve, make and install 1.7.0:

wget https://github.com/mongodb/mongo-c-driver
cd mongo-c-driver
cmake
make
sudo make install

libcurl

Libcurl is used to fetch MUD files from a MUD file server.

sudo apt-get install libcurl4-openssl-dev # Debian/Ubuntu

or

sudo yum install libcurl-devel # CentOS/Amazon

If you retrieve libcurl and build it on your own, you may wish to build against OpenSSL rather than GNUTLS, as the latter dramatically increases the number of dependencies (this includes such things as the GSSAPI and MySQL, which are really unused in this case).

Building the MUD Manager

Run configure and make.

./configure 
make
sudo make install

Editing the configuration file.

The default location for the configuration file is:

/usr/local/etc/mud_manager_config.json

The following fields can be set in the configuration file.

1. MUDManagerAPIProtocol

This defines whether the REST APIs should be http:// or https://. The default configuration file setting is http://.

If https:// is used, then the MUD Manager will also need the following TLS-related fields added:

  • MUDManager_cert, with a pathname to the MUD Manager's signing certificate
  • MUDManager_key, with a pathname to the MUD Manager's private key
  • Enterprise_CACert, with a pathname to the CA certificate that signed the MUDManager_cert

2. Default_VLAN

This provides for a VLAN when same-manufacturer is not used.

3. ACL_Type

This directs the MUD manager to return ACLs only to enforce policy on the "ingress" direction (i.e., from the device), or whether to enforce policy on both ingress and egress (i.e., to and from the device). Its setting depends on the capabilities of the NAD.

The safest choice is to leave it as dACL-ingress-only, however if you have a NAD that will also enforce egress policy you should set it as dACL-ingress-egress.

4. COA_Password

In some cases, a RADIUS server will complete an Authentication exchange for a device before the NAD gives it a MUD URL associated with that device. When the association is subsequently made, the MUD policy will not become effective on the NAD before the next Authentication session. A convenient way to cause the Authentication to happen is for the MUD manager to send a Change of Authorization (CoA) to the NAD, instructing it to perform authentication with the RADIUS server again.

For the CoA to succeed, the MUD Manager must share a password with the NAD. Replace the sample password provided in the configuration file with the password you use on the NAD.

5. VLANs

If the VLANs array is present, it consists of a pool of VLANs available for assignment when same-manufacturer is present for a given authority. These will be automatically assigned, and stored in MUD-Manager's internal database. If they are removed from the configuration file, they will still be used. If a vlan field exists for a particular manufacturer, it will override the use of the pool.

Each array entry consists of the following elements:

  • VLAN_ID: the value of the VLAN to be used.

  • v4addrmask: a string in the form of a dotted quad and a wildcard mask also in the form of a dotted quad. For example:

     "v4addrmask" : "192.168.1.0 0.0.0.255"
    
  • v6addrmask: a string in the form of a v6 network and a mask.

Note Bene all VLANs listed in configuration or in the database must have previously been configured in all switches using the same AAA server.

6. Manufacturers

This array of manufacturers is optional. When present, it may contain information that includes an authority string, a set of certificates for validation, an optional VLAN, my-controller information for this particular instance, and any local network information to be used. If NOT present, the MUD manager will press on, but my-controller statements will be ignored. See below for more detail.

6.1 authority

The authority portion of the URL, which defines the unique manufacturer. For example, if the URL is "https://luminaire.example.com/Luminaire_150", the authority portion of the URL is "luminaire.example.com". This same string needs to be placed in the authority policy of the Manufacturer in the configuration file.

6.2 cert

The CA certificate for the manufacturer, which is used to verify the MUD file server signature.

6.3 https_port

The port used to contact the file server (e.g., 443).

6.4 my_controller_v4, my_controller_v6

These are used to define what is the local IP address for a "my-controller" statement found in a MUD file. If these are not present, the my-controller statement will be ignored.

6.5 local_networks_v4, local_networks_v6

These are used to translate a "local-networks" statement found in a MUD file.

6.6 vlan

If a "same-manufacturer" statement is found in the MUD file, this VLAN value is sent with the ACLs to the NAD. This field generally should not be used. Instead, create a group of VLAN entries in the VLANs array and allow MUD Manager to assign them.

6.7 v4addrmask, v6addrmask

For the VLAN there needs to be a statement such as "192.168.1.0 0.0.0.255" (or equivalent v6) to permit acces to that VLAN.

6.8 DNSMapping, DNSMapping_v6

If a MUD file has a DNS name in it, and that name is not resolvable (say because you are doing testing), you can add a translation here. If you do not, a DNS lookup will be performed.

6.9 ControllerMapping, ControllerMapping_v6

If a MUD file has a "controller" statement, it needs to be translated to an IP address. Do that here.

6.10 DefaultACL, DefaultACL_v6

A site policy may provide additional restrictions to the devices. These can be defined as access control list statements here. The default policy included in the configuration policy is to block all other IP and ICMP packets.

MongoDB Tools

Two scripts are included to manipulate the MUD Manager collections in MongoDB.

  • mud_clobber_db: This can be used to clean out the MUD Manager collections, which forces MUD files to be fetched and access policy to be re-gererated.
  • mud_show_db: This displays the contents of the three collections used by the MUD Manager.

Examples

The examples directory includes an example of a "luminaire", which includes a sample MUD file, sample MUD file server, certificates, and instructions how to use the mud_test_command to invoke the MUD Manager.

MUD Manager Test Command

A simple test command is included, which imitates REST APIs to the MUD Manager and verifies that the MUD Manager can download and process a MUD file.

If the "luminaire" example MUD file server is running, and the MUD manage is started on its default port, then the following test command should retrieve the MUD file and the return the ACLs contained within it.

mud_test_client -f Luminaire_150 -c 127.0.0.1 -p 8000 -w luminaire.example.com

The output should look something like this:

URL:  https://luminaire.example.com/Luminaire_150

Starting RESTful client against http://127.0.0.1:8000/getaclname
    with request {
        "MUD_URI":      "https://luminaire.example.com/Luminaire_150"
}
Got ACL Names
Full ACL Name 0: ACS:CiscoSecure-Defined-ACL=mud-21966-v4fr.in
ACLname: mud-21966-v4fr.in

Starting RESTful client against http://127.0.0.1:8000/getaclpolicy with request {
        "ACL_NAME":     "mud-21966-v4fr.in"
}
Username: mud-21966-v4fr.in
Got DACL contents:
        ACE: ip:inacl#10=permit tcp any host 172.12.212.10 range 443 443 established
        ACE: ip:inacl#20=permit udp any host 10.1.1.4 range 5684 5684
        ACE: ip:inacl#30=permit udp any host 255.255.255.255 range 5683 5683
        ACE: ip:inacl#40=permit tcp any eq 22 any
        ACE: ip:inacl#41=deny ip any any

The Web User Interface

A new web user interface is now available just for testing purposes. Beware that there is no current authentication mechanism.

Prerequisites:

  • PHP 2.7 or later
  • The PHP mongodb extension.
  • composer

The configure script will not test for PHP or mongodb, but will test for composer.

To install, issue the configure command with --with-webui=/installdirectory where the installdirectory is where you want the HTML installed.

What's new for 3.0?

  • Basic UI support.
  • Multicast support. MUD files can contain multicast addresses.
  • Source tree reorganized.
  • VLAN support improved
  • Support for new RESTful endpoint to update server
  • Github space correction.

What's New for 2.0?

The latest code contains a great many bug fixes and a number of additions. Here's a brief list:

  • Limit of 11 ACE lines removed. Memory is now realloced as required.
  • VLANs are pulled from a pool. Manufacturer entries should not list them.
  • The config file is now versioned.
  • Add a default for local-networks
  • Fix a memory corruption issue.
  • Relax the idea that somehow "protocol" was required in the MUD file.
  • Relax the MIME check on MUD files. Yes, MUD File Servers should use application/json, but as most people are just going to use apache, let's not be too pedantic.

To begin with, you don't need to list a manufacturer in the config file. Until you do, of course, the controller functions are quite limited. We are also now using the updated MUD specification, reading in all the informational elements into the MongoDB. This will become more important later on as we begin to offer at least something of a graphical interface to All of This.

Contributors

Rashmikant Shah

Brian Weis

Cheryl Madson

Eliot Lear

mud-manager's People

Contributors

adrienne-at-work avatar cmadsoncisco avatar elear avatar iggy2028 avatar paralax avatar unapologtic avatar vafa-andalibi avatar

Stargazers

 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  avatar  avatar

mud-manager's Issues

"Manufacturers" in Config not handling multiple MUD URLs from same manufacturer properly

Right now the array in the config file points to "Authority" components, and that is exactly what is needed for same-manufacturer. However, you can't really just tie that to my-controller, because you can have the following:

https://www.example.com/mudurl1
https://www.example.com/mudurl2

And each of these could have different controllers.

We can handle this in one of two ways:

  • Restructure "Manufacturers" to be relative to the MUD URL instead of the Authority
  • Just sort the matter in the upcoming web interface.

While I am tempted to do the latter, the problem is that the web interface needs the full MUD URL somewhere in the config.

On bouncing expired certs

Currently, if a signature was valid at the time of signing, we will still produce an error. That is based on OpenSSL's CMS behavior. It is possible to configure OpenSSL not to do that, but the reason that it is the way it is, is because the clock used to sign the file is under the control of the one with the certificate.

The general argument runs that if you're interested in non-repudiation more than whether the cert was valid at the time of signing, then it's okay to consider the check based on that time. But if you're interested in whether the cert was in fact valid at the time the signature was made, then a secure time stamp is required, or the file must be resigned. MUD has no notion of a secure timestamp, and that in itself would require some neutral and complex service.

Still there will be a lot of devices and manufacturers who generally will NOT resign their files. This is a little bit of a problem.

Add model support

Manufacturer = match the authority section.
Model = match the whole URL

Web UI | Class 'MongoDB\Driver\Manager' not found

Hey,
I have installed the MUD-Manager with the web GUI, everything went ok
now when i tried to run the GUI i get the following issue
`MUD Manager Configuration

This is the MUD Manager Configuration Screen. Click "edit" on those rows you wish to change.

Fatal error: Uncaught Error: Class 'MongoDB\Driver\Manager' not found in /home/tester/MUD-Manager/web/vendor/mongodb/mongodb/src/Client.php:87 Stack trace: #0 /home/tester/MUD-Manager/web/funcs.php(78): MongoDB\Client->__construct('mongodb://local...') #1 /home/tester/MUD-Manager/web/mud-home.php(26): init_database(NULL, NULL, NULL, NULL) #2 /home/tester/MUD-Manager/web/index.php(2): include('/home/tester/MU...') #3 {main} thrown in /home/tester/MUD-Manager/web/vendor/mongodb/mongodb/src/Client.php on line 87`

mud_gui_issue

I have installed the dependency with
/usr/bin/composer require mongodb/mongodb
in the directory of the web folder

the generated JSON file of the composer contains the following

{ "require": { "mongodb/mongodb": "^1.4" } }

The files in the web folder:
GUI_issue_mud

Any suggestion where the issue could be ?

Failed to build the manager | undefined reference to symbol 'SSL_CTX_ctrl@@OPENSSL_1_1_0'

Hey,
I already did a lot of tries to build the manager but none of them have success until now
I am using ubuntu 19, and those are the details:
Distributor ID: Ubuntu
Description: Ubuntu 19.04
Release: 19.04
Codename: disco
OpenSSL 1.1.1b 26 Feb 2019
i installed all the packages as described in the instructions, the compilation fails on the following

`tester@tester-VirtualBox:~/MUD-Manager$ make
make all-recursive
make[1]: Entering directory '/home/tester/MUD-Manager'
Making all in src
make[2]: Entering directory '/home/tester/MUD-Manager/src'
/bin/bash ../libtool --tag=CC --mode=link gcc -I.. -DMG_ENABLE_SSL -Wall -W -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0 -Icivetweb -I/usr/local/include/cjson -g -O2 -o mud_manager mud_manager.o log.o sessions.o acl_types.o cisco_dacl.o mud_fs_client.o civetweb/civetweb.o -L/usr/local/lib -lmongoc-1.0 -lrt -lbson-1.0 -lpthread -lm -ldl -lcurl -lcjson_utils -lcjson
libtool: link: gcc -I.. -DMG_ENABLE_SSL -Wall -W -I/usr/local/include/libmongoc-1.0 -I/usr/local/include/libbson-1.0 -Icivetweb -I/usr/local/include/cjson -g -O2 -o mud_manager mud_manager.o log.o sessions.o acl_types.o cisco_dacl.o mud_fs_client.o civetweb/civetweb.o -L/usr/local/lib /usr/local/lib/libmongoc-1.0.so -lrt /usr/local/lib/libbson-1.0.so -lpthread -lm -ldl /usr/lib/x86_64-linux-gnu/libcurl.so -lcjson_utils -lcjson -pthread
/usr/bin/ld: mud_manager.o: undefined reference to symbol 'SSL_CTX_ctrl@@OPENSSL_1_1_0'
/usr/bin/ld: /lib/x86_64-linux-gnu/libssl.so.1.1: error adding symbols: DSO missing from command line

collect2: error: ld returned 1 exit status

make[2]: *** [Makefile:420: mud_manager] Error 1

make[2]: Leaving directory '/home/tester/MUD-Manager/src'

make[1]: *** [Makefile:410: all-recursive] Error 1

make[1]: Leaving directory '/home/tester/MUD-Manager'

make: *** [Makefile:342: all] Error 2
`

Tried also on Centos and the same issue

Is it libssl version issue or what exactly ? will be glad to get somehelp

protocol not required

Current code seems to believe protocol element is required. It's not. A particular case where it wouldn't be used is if all communications are intended to be allowed between endpoints.

MUD-Manager is doing inappropriate appending

Nowhere in the specification does it say that we should append ".json" to a file, and this is going to cause a lot of breakage. The URI is the URI is the URI and should be left alone.

kick_radius not working

Hello,

I'm trying to setup a network for IoT protected by MUD, using the raspberry pi. I'm trying to test the Luminaire example in this environment. On the raspberry pi I have:

  • Mud_controller running (tested with mud_test_client)
  • FreeRadius installed, patched and running,
  • https file server running
  • mud_test_client working for luminaire example

The problem is with the ./kick_radius.sh script. I get the following error on the radius server:

 Fri Nov 23 14:46:46 2018 : Debug: (0) Received Accounting-Request Id 7 from 127.0.0.1:35590 to 127.0.0.1:1813 length 118
 Fri Nov 23 14:46:46 2018 : Info: Dropping packet without response because of error: Received Accounting-Request packet from client 127.0.0.1 with invalid Request Authenticator!  (Shared secret is incorrect.) 

Yet I don't see any password inside the kick_radius.sh and I haven't changed the default testing123 password inside the client.conf file. Any idea what I'm doing wrong?

"manufacturer" selection process refinement

Right now "manufacturer" works on the basis of devices that only use same-manufacturer or are otherwise in the manuf_list struct. That's not quite what we want in the longer run. That means that devices not in that struct or in the config are not able to be associated with "manufacturer". To fix this, we would want to know the IP address or some other tag that we can apply an access control to. IP addresses are hard unless they're provided via DHCP_REQUEST, or we otherwise know some other topological information, like which switch the device is connected to, in which case we could poll.

Memory leak still happening

There's an extra free going on that shouldn't be in find_vlan. I have a PR ready, but may merge with other code.

Add IPv4/IPv6 support specifically for multicast

IPv4 and IPv6 addresses in MUD files are not recommended. However, they may be necessary for multicast. N.B., they are dangerous for unicast in particular if the unicast is not checked against some notion of locality. So for instance, no MUD file should ever contain private network addresses, nor any addresses that are not accessible on the Internet.

wpa_supplicant does not connect to MUDS-compatible hostapd network (EAP-TLS) with certificates

Hello,

I know this issue is probably not completely related to this repository, but I'll just write as a question maybe someone can kindly help me with this.

In previous examples the MUDS was tested on a wired connection. I have spent a lot of time trying to setup a wireless network that deploys MUDS. After several different unsuccessful configuration, I ended up setting up the network using the technical documentation of MUDS v0.6 as well as the MUD-Manager repository guides/examples.

All of the entities are installed on the same machine, including MUDS fileserver, (patched) freeradius, and hostapd (hotspot).

Things that work:

  • hostapd hotspot works fine with freeradius WPA2 Enterprise using PEAP. Test device can connect with the legitimate username and password that is added to the Freeradius.
  • Freeradius communicates with MUD-Manager
  • MUD-Manager communicates with MUD-Fileserver
  • Kick_radius.sh exampe works correctly

Things that don't work

  • wpa_supplicant does not connect to the WPA2 network using luminaire (self-signed) certificates (including CA certificate as well as device certificate and key). Note that I'm not using the certificates in the repository, instead I'm creating/signing them myself using the newly created CA, so that I have the CA cert as well. Still wpa_supplicant doesn't even send out the packets since Freeradius does not even show the receive of a packet. Wpa_supplicant shows the following error in its log:
Successfully initialized wpa_supplicant
wlp9s0: SME: Trying to authenticate with  [MAC] (SSID='MUDPI' freq=2442 MHz)
wlp9s0: Trying to associate with [MAC] (SSID='MUDPI' freq=2442 MHz)
wlp9s0: CTRL-EVENT-ASSOC-REJECT bssid= [MAC] status_code=40

This is the wpa_supplicant command that I use:

$ sudo wpa_supplicant -i wlan0 -c eap_tls.conf -d

This is the wpa_supplicant config that I'm using:

eapol_version=1

update_config=1
network={
    ssid="MUDPI"
    scan_ssid=1
    key_mgmt=IEEE8021X
    eap=TLS
    identity="ciscoC"
    ca_cert="cacert.pem"
    client_cert="DEVICE1_cert.pem"
    private_key="DEVICE1_key.pem"
    private_key_passwd="12349876"
}

and this is the hostapd configuration that I use to setup the wireless network:

interface=wlan0
driver=nl80211
ssid=MUDPI
hw_mode=g
channel=7
ieee8021x=1
auth_algs=1
eap_server=0
eapol_key_index_workaround=0 

wpa=2
wpa_key_mgmt=WPA-EAP
rsn_pairwise=CCMP
auth_server_addr=127.0.0.1
auth_server_port=1812
auth_server_shared_secret=testing123
acct_server_addr=127.0.0.1
acct_server_port=1813
acct_server_shared_secret=testing123

Again, I know this is probably not the best place to ask this question, but still I thought you might have some ideas about this issue and any help/hint would be highly appreciated.

Problems with the stable release on Raspberry Pi

I have been trying to run the basic luminaire example (on branch 2.0) on Raspberry Pi but haven't been successful yet. Things that I've found so far:

  • The Readme is suggesting installing "Mongo C driver V1.7.0", yet the code is using mongoc_collection_insert_one() which doesn't exist in V1.7.0 (here). So I built and installed V1.13.0 to be able to make the mud-manager.

  • There are a few bracket mismatch in luminaire_conf.json which causes the mud_manager -f ./luminaire_conf.json to raise error. Does it mean the luminaire example isn't tested in the stable release?

Thanks,

EDIT:

  • Another minor issue in the documentation:
    /usr/local/etc/mud_manager_config.json is changed to /usr/local/etc/mud_manager_conf.json apparently and should be updated in the documentation.

EDIT 2:

Would you accept a pull request on the stable release if I fix these and submit the PR?

About generating 802.1AR certificates

Hi,
I've got errors while generating 802.1AR certificates. The scripts in examples/certs_and_keys do not generate the 8021ARintermediate/private/8021ARintermediate.key.

Please see the errors in the
errors.txt
attached file.

Can someone help me?

"local" not quite right

As defined "local-networks" seems to generate a host element for a Cisco ACL, and the example config given is a mask. What we want is both a network component and a mask, and no "host" in the ACE.

malformed ACE

Reported by Josh Klosterman, "permit " part of ACE not created.

image

Get rid of DNS from config

Right now DNS src/dst names are in the config. Either resolve these names at time of onboarding or have a process that updates the mapping.

VLANs should be pulled from a pool

Right now VLANs are assigned to manufacturers, thus requiring per-manufacturer preconfiguration. let's do away with that and have a pool.

Drop code needs work

in cisco_dacl.c right now we properly handle accepts but aren't properly processing drops. Code needs a very minor reorg to handle drops based on action member.

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.