voxpupuli / puppet-unbound Goto Github PK
View Code? Open in Web Editor NEWPuppet module for deploying the swiss-army of DNS, Unbound
Home Page: https://forge.puppet.com/puppet/unbound
License: Apache License 2.0
Puppet module for deploying the swiss-army of DNS, Unbound
Home Page: https://forge.puppet.com/puppet/unbound
License: Apache License 2.0
I believe there is currently no support for a top-level 'python-script:' section in the config.
hello,
i'm new user of your module and i did not find log-queries and log-replies options.
it's a security concern in my enterprise.
is it possible to add these options ?
thank you.
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Undefined variable "unbound::params::group"; Undefined variable "group" at /etc/puppet/environments/billing/modules/unbound/manifests/init.pp:20 on node ip-172-20-29-111.ec2.internal Warning: Not using cache on failed catalog Error: Could not retrieve catalog; skipping run
Pull request probably incoming shortly.
Hi there,
I would like to add functionality to generate local data for a zone by this unbound module.
Furthermore it would be cool to override a template for a local-zone e.g. i need to do additional stuff there.
I will create a PR for it.
Documentation on how hiera can be used is not documented.
DNS records for DKIM contain spaces and double quotes.
The unbound documentation for local-data directives advise the usage of single quotes for TXT records to handle white space et double quotes.
Here is an example of how to set a DKIM record in unbound:
local-data: 'mail._domainkey.example.com 14400 IN TXT "v=DKIM1;h=sha256;k=rsa;""p=DKIM_KEY_PART_1""DKIM_KEY_PART_2"'
How handle such a record with this Puppet Module ?
As far as I can see, the double quotes are hardcoded in the erb template:
puppet-unbound/manifests/record.pp
Line 34 in e1b498d
According to the reporter of issue #196, it seems there is way to handle this but he didn't say how :-(
I created data\os\Solaris.yaml
locally and got it working, tossing stub here for others to reference.
---
unbound::confdir: '/opt/local/etc/unbound'
unbound::pidfile: '/usr/local/etc/unbound/unbound.pid'
unbound::logdir: '/var/log/unbound'
unbound::fetch_client: 'wget -O'
unbound::control_setup_path: '/opt/local/sbin/unbound-control-setup'
unbound::control_path: '/opt/local/sbin/unbound-control'
unbound::validate_cmd: '/opt/local/sbin/unbound-checkconf %'
unbound::restart_cmd: "/usr/sbin/svcadm restart %{hiera('unbound::service_name')}"
unbound::anchor_fetch_command: "/opt/local/sbin/unbound-anchor -a %{hiera('unbound::auto_trust_anchor_file')}"
The hiera used path: "os/%{facts.os.family}/%{facts.os.release.major}.yaml"
doesn't quite fit SmartOS' structure of {"name"=>"SmartOS", "family"=>"Solaris", "release"=>{"minor"=>"11", "full"=>"5.11"}}
but using Solaris.yaml
got me functional.
Hello,
I had the problem that IPv4 addresses were generated as "stub-host" entries in the config file instead of "stub-addr".
Maybe it is better to check for valid IP instead of domain_name in the stub template?
<% if scope.function_is_ip_address([addr]) -%>
stub-addr: <%= addr %>
<% else -%>
stub-host: <%= addr %>
<% end -%>
I need to be able to set certain permissions and ownership on the unbound configuration directories. Specifically, I want conf.d to be writable by another user (so, 775 and group changed to another group).
There are a few ways to achieve this. How would you like to facilitate this? Add ownership/group options to the parameters? Or make setting the conf_d variable to false actually work so that I can define it outside of the module with the proper permissions/ownership? It doesn't right now:
Error 400 on SERVER: Puppet::Parser::AST::Resource failed with error ArgumentError: No title provided and :file is not a valid resource reference at modules/unbound/manifests/init.pp:100
I can make a patch and pull request, but I'd rather know what you should find acceptable first.
Hi,
There is a problem with the qouting in the unbound.conf file for TXT records in the local-data field. Since TXT records can contain whitespaces double quotes are needed around the rdata part of the local-data set. Hence the local-data entry has to be single quoted. This is explicitly described in the unbound.conf man page:
For record types such as TXT, use single quotes, as in
local-data: 'example. TXT "text"'.
I would suggest to use single quotes for all local-data entries. This is not explicitly allowed in the unbound.conf manual, but it works on my unbound installation flawless.
Kind regards
Count Sudoku
In order to ensure safety, me set the resource in the base class
File {
mode => '0644',
owner => 'root',
group => 'root',
}
Me get conflict with
File[$_owned_dirs] {
owner => $owner,
}
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Parameter 'owner' is already set on File[/var/lib/unbound] by #<Puppet::Resource::Type:0x1680ee80> at (file: ); cannot redefine (file: ) on node
Please tell me how we can resolve this conflict? Thx
Hi @xaque208, - Your project is missing a LICENSE file.
A piece of software, no matter how complex or trivial it is, that does not declare itself as "Open" or does not specify which kind of Open it is, is from an Open Source licensing perspective a hot potato.
While in some countries this puts your Software in the Public Domain, the Public Domain is something that in Europe for instance doesn't have the same protection from the law as elsewhere.
As such you will not find a "WTFPL", or the "Public Domain" as OSI approved license
I highly encourage you to chose one of those and attach it to your project.
Thanks for your module. I'm trying it out for the first time. I'm using 2.0.0 with Puppet 4, via vagrant's puppet apply
provisioner. I also tried the 1.3.6 tag, same error.
I'm getting the following error. I looked through your code but it all looked good to me. I can't figure out why it's tacking on /etc/unbound
to the path /var/lib/unbound/root.key
, but then again, I'm new to Unbound and don't know much about chrooting, either.
==> default: Error: Execution of '/usr/sbin/unbound-checkconf /etc/unbound/unbound.conf20161110-25141-kzxa3n' returned 1: /etc/unbound/var/lib/unbound/root.key: No such file or directory
It is not presently possible to use this module to set neg-cache-size in unbound.conf.
$ /usr/local/sbin/unbound -V 2>&1
Version 1.9.3
Configure line: --with-ssl=/usr --with-libexpat=/usr/local --disable-dnscrypt --disable-dnstap --enable-ecdsa --disable-event-api --enable-gost --with-libevent --disable-subnet --disable-tfo-client --disable-tfo-server --with-pthreads --prefix=/usr/local --localstatedir=/var --mandir=/usr/local/man --infodir=/usr/local/share/info/ --build=amd64-portbld-freebsd12.0
Linked libs: libevent 2.1.11-stable (it uses kqueue), OpenSSL 1.1.1a-freebsd 20 Nov 2018
Linked modules: dns64 respip validator iterator
BSD licensed, see LICENSE in source package for details.
Report bugs to [email protected] or https://github.com/NLnetLabs/unbound/issues
A fixture such as this should be able to catch the issue I'm currently running into.
Error: Facter: error while resolving custom facts in /var/puppet/lib/facter/unbound_version.rb: undefined method `[]' for nil:NilClass
I just realized that I didn't document any of the new features I added, i.e.:
unbound::record { 'foo.example.com-ipv4':
content => '192.168.122.13',
entry => 'foo.example.com',
}
unbound::record { 'foo.example.com-ipv4':
content => 'ffa3:45:34cd::13',
type => 'AAAA',
entry => 'foo.example.com',
}
class { 'unbound':
interface => $interface_list,
interface_automatic => false,
access => [ "${lookup('defaults::cidr')}", '127.0.0.0/8' ],
do_not_query_localhost => false,
val_permissive_mode => true,
ip_transparent => true,
}
The initial run of the puppet agent fails to start unbound as the ip-transparent
setting is not applied to the configuration file. As I am trying to bind to a failover IP address which may not exist at the time unbound is started unbound fails. The second run of puppet does add the setting and unbound starts correctly.
The configuration file for unbound should contain all of the parameters specified such that unbound starts on the first run.
Can be provided if required.
The unbound.conf.erb
template contains code to make parameters in the configuration specific to the version of unbound installed based on the fact unbound_version
. This is not set on the first run of unbound as the package is not yet installed. All of the version dependent settings eg
<%= print_config('so-reuseport', @so_reuseport, '1.4.22') -%>
<%= print_config('ip-transparent', @ip_transparent, '1.5.4') -%>
<%= print_config('ip-freebind', @ip_freebind, '1.5.9') -%>
Do not get applied as the versioncmp
at the top of the template defaults to 0.a
and decides the version of unbound is lower than the minimum requirement for that setting.
A potential fix could be to use a different variable in the template which is set after the package has been installed by running unbound -V
at that point. I'd be happy to have a go at creating a PR for this or an alternative solution.
I would like to use the new rpz feature of unbound. however, in order to do so, I need to use the respip module, which is not in the list of allowed modules:
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Resource Statement, Class[Unbound]: parameter 'module_config' index 0 expects a match for Unbound::Module = Enum['cachedb', 'dns64', 'ipsecmod', 'iterator', 'python', 'subnetcache', 'validator'], got 'respip' (file: /etc/puppetlabs/code/environments/ifi/modules/profile/manifests/unbound.pp, line: 165, column: 3)
adding 'respip' to the array in types/module.pp solves the problem.
Best,
Hp
Please add a parameter that allows specification of the root-hints file. This is part of the standard unbound.conf syntax as defined here:
http://www.unbound.net/documentation/unbound.conf.html
It would be even cooler if this module had the option of configuring a cron task that automatically updated the root hints file on a regular basis.
http://www.iana.org/domains/root/files
Having a purely caching forwarder which just forwards request to some other recursive nameserver there is no need for the root.hints file and in our case the servers can't even reach the Internet so it hangs on downloading the root.hints (until touching it manually). Please create an option not to use/download root.hints.
the unbound manifest tries to set the permissions of the pid file base directory[1]. For debian this is set to /run/unbound.pid
[2]. As such puppet tries to set the dir permissions for /run
to unbound
which is not desirable. for now im going to just going to set the value to an empty dir as unbuound on debian is compiled with the same default.
Im not sure if this is a bug or desirable, especially if we consider chroot environments. for now i have just set unbound::pidfile: ~
however i did need to patch the module[3] to get that to work. also note that dirname
doesn't act as i expected when pidfile was blank[4]
[1]https://github.com/xaque208/puppet-unbound/blob/master/manifests/init.pp#L178-L180
[2]https://github.com/xaque208/puppet-unbound/blob/master/data/os/Debian.yaml#L2
[3]#179
[4]puppetlabs/puppetlabs-stdlib#913
I ran into a strange problem today with Unbound while using this module. I'm not sure whether this is a configuration problem or a bug, so I'm reporting it here first.
On a server with two IP addresses, I had to explicitly list both IP addresses in unbound.conf before Unbound would answer queries on the second address. This ran counter to my expectation that I could set interface: 0.0.0.0
to listen on all IP addresses.
One possible solution is changing this module to explicitly list all IP addresses as listening interfaces in unbound.conf.
Before making that change, it would be prudent to:
The full story
My server had Unbound installed and configured to listen on "0.0.0.0" interface. It was successfully responding to DNS queries for other hosts as defined by the access-control
directive, even on different subnets.
Then I added a second IP address to the server as a virtual interface (eth0:0
). Strangely, Unbound refused to answer DNS queries on this second IP address, even after restarting the service. Running netstat -tapn confirmed that Unbound was listening on 0.0.0.0:53
.
Then I explicitly listed each local IP address in unbound.conf
and restarted Unbound. At that point, the server successfully responded to DNS queries as expected.
interface: 192.168.0.20
interface: 192.168.0.30
I'm using Scientific Linux 6.4, and the version of Unbound is 1.4.19 from EPEL.
Concat 2.x has been from the forge due to the problems outlined in:
https://groups.google.com/forum/#!topic/puppet-dev/4_Sxrfl4uUY
This module has been identified as a module with a pinned dependency on concat 2.x and will need to have the metadata.json adjusted.
Apologies for the inconvenience.
Thanks!
Bryan
The unbound-checkconf is unable to validate the pid file directory during first-run. This is because the epel unbound initrc creates /var/run/unbound at daemon start time.
There is a bugzilla about the issue. I happen to find the issue on both RHEL5 and RHEL6 machines. RHEL7 did not exhibit the issue.
Error: Execution of '/usr/sbin/unbound-checkconf /etc/unbound/unbound.conf20181105-56517-13c6j0h' returned 1: /var/run/unbound: No such file or directory
[1541453860] unbound-checkconf[57038:0] fatal error: pidfile directory does not exist
Error: /Stage[main]/Unbound/Concat[/etc/unbound/unbound.conf]/File[/etc/unbound/unbound.conf]/content: change from {md5}b89d00e77d575b7154c2487f31192ef0 to {md5}b0987114fd303bbfeaaa6027b04b8f3e failed: Execution of '/usr/sbin/unbound-checkconf /etc/unbound/unbound.conf20181105-56517-13c6j0h' returned 1: /var/run/unbound: No such file or directory
[1541453860] unbound-checkconf[57038:0] fatal error: pidfile directory does not exist
Notice: /Stage[main]/Unbound/Service[unbound]: Dependency File[/etc/unbound/unbound.conf] has failures: true
The fix is simply to create the directory if it doesn't exist before running the configuration.
exec { '/usr/bin/install -v --mode=755 --owner=unbound --group=unbound -d /var/run/unbound':
onlyif => '/usr/bin/test ! -d /var/run/unbound',
before => Concat[/etc/unbound/unbound.conf],
require => Package[unbound],
}
unbound::record:
'abc.example.com':
ttl: '1800'
type: 'A'
content: '192.168.1.1'
'abc.example.com':
ttl: '1800'
type: 'A'
content: '192.168.1.2'
- local-data: "abc.example.com 1800 IN A 192.168.1.1"
+ local-data: "abc.example.com 1800 IN A 192.168.1.2"
We expect the static record mapping to multiple IP, but puppet-unbound seems not support, we try to define multilple ip on same domain on puppet yaml, After run puppet agent, only write one of record to unbound.conf
No Error log
when running puppet-unbound under puppetserver, it seems unable to load the puppet_x module
Error: Could not retrieve catalog from remote server: Error 400 on SERVER:
Could not autoload puppet/parser/functions/validate_unbound_addr:
no such file to load -- puppet_x/unbound/validate_addrs on node ns01.esat
I'm not sure if this is concat related or unbound related, but I haven't managed to figure it out.
I'm using the latest version of this module and the concat module. When applying the catalog I get the following error:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Invalid parameter target on Concat_fragment[unbound-header]
I guess it's related to this:
concat::fragment { 'unbound-header':
order => '00',
target => $config_file,
content => template('unbound/unbound.conf.erb'),
}
But not exactly sure what the issue is?
I noticed that the service statement sets hasstatus
to false. I have checked ubuntu and freebsd and both seem to support status, do you remember why you turned this off?
If you change the $interface
while you have $control_enable
the interface change does not take affect. This is because if control_enable is true the service refreshes using unbound-control reload
. however as per the documentation
The interfaces are not changed on a reload (kill -HUP) but only on restart.
This means that any changes to the interfaces (even if it is the first run) do not take affect until a manual restart is preformed. The simple fix would be to remove the offending block[1] however this would mean a full restart of the daemon for any config changes which may not be desirable. A more hacky way would be to store the interfaces in a file and restart the service if that file changes. something like
file {"$confdir/interfaces.txt":
ensure => file,
notify => Exec['etc/init/.d/unbound restart'],
content => $interfaces.join('\n'),
}
exec {'/etc/init/.d/unbound restart':
refreshonly => true,
}
what do you think?
[1]https://github.com/xaque208/puppet-unbound/blob/master/manifests/init.pp#L189-L192
Hello,
regarding "name": "zleslie-unbound", "version": "2.4.1", "summary": "Puppet Unbound management module",
I would suggest this patch:
puppet-unbound.patch.txt
Best wishes
ap-16
The unbound version in the CentOS supported repo's is too old to support tls-upstream and other tls-* keywords in the configfile. Those keywords where added in module version 2.4.3 as a future replacement for the ssl-upstream (etc) versions. We should skip those on CentOS 7 (and also RedHat 7 and below)
The release (1.0.0) on puppetforge is old and has a number of issues (like, it requires ripienaar/concat, while concat has been in stdlib for a while now).
Can you do a new release and upload it to puppetforge?
Thanks,
Ward.
harden-dnssec-stripped is yes by default. In case we set no in class parameters, that will generate config without that parameter which is equals to yes.
The definition of unbound::forward on puppetforge has an extraneous comma.
It should be like this:
define unbound::forward (
$address
) {
Tunneled DNS looks to be overlooked in this module. We should add support.
Hello,
It seems that path /sbin/unbound-checkconf does not fit neighter Centos nor Scientific linux (release 6), instead it is /usr/sbin/unbound-checkconf . Maybe you can fix this $validate_cmd value in params.pp?
Could you consider please to have a patch-release 2.1.1 which includes 393d12b? To have some control over possible breaking changes, I employ release-versions only and had 2.1.0 non-functional on Debian 9, which comes with unbound-1.6.0.
Thanks for your consideration (and of course for puppet-unbound)!
Currently the module does not run clean on a FreeBSD box when trying to execute /usr/sbin/unbound-control-setup
due to the fact that the local system unbound resolver does not support the control interface with SSL.
For the moment, when i search unbound module on the Puppet forge, the module zleslie-unbound
is listed. But it looks that module moved to VP.
I created a JIra issue asking for a deprecation message :
https://tickets.puppetlabs.com/browse/FORGE-577
I'm trying to set up unbound with a different config file location.
My hiera config:
unbound::val_permissive_mode: true # Disable DNSSec
unbound::chroot: true
unbound::confdir: "/var/unbound"
unbound::config_file: "/var/unbound/unbound.conf"
unbound::runtime_dir: "/var/unbound"
unbound::interfaces:
- '127.0.0.1'
unbound::access:
- '127.0.0.1'
unbound::custom_server_conf:
- 'cache-max-ttl: 7200'
- 'cache-max-negative-ttl: 1'
However catalog compilation fails:
# puppet agent -t --environment=unbound --server=tukd-puppet-1.dapt.to
Info: Retrieving pluginfacts
Info: Retrieving plugin
Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_unbound_addr.rb]/ensure: defined content as '{md5}468519a15b83e2f5a9f2de6ffb221546'
Notice: /File[/var/lib/puppet/lib/puppet_x/unbound]/ensure: created
Notice: /File[/var/lib/puppet/lib/puppet_x/unbound/validate_addrs.rb]/ensure: defined content as '{md5}4d0719572d4d086d61cd7cbb69f0b693'
Info: Loading facts
Info: Caching catalog for hostname
Error: Failed to apply catalog: Could not find dependent Exec[concat_/etc/unbound/unbound.conf] for File[/var/lib/puppet/concat/_etc_unbound_unbound.conf/fragments/20_unbound-forward-.] at /etc/puppet/environments/unbound/modules/concat/manifests/fragment.pp:136
What isn't clear to me is why /etc/unbound/unbound.conf
is still even a thing? Which param do I need to set here?
Currently, only the local unbound shipped in newer versions of FreeBSD are managed. We should support installing and managing the port.
Greetings,
I am a security researcher, who is looking for security smells in Puppet scripts. I noticed instances of binding to 0.0.0.0. Binding an address to 0.0.0.0 indicates allowing connections from all IP addresses. I would like to draw attention to these instances. Binding to 0.0.0.0 may lead to denial of service attacks. Practitioners have reported how binding to 0.0.0.0 facilitated security issues for MySQL (https://serversforhackers.com/c/mysql-network-security), Memcached (https://news.ycombinator.com/item?id=16493480), and Kibana (https://www.elastic.co/guide/en/kibana/5.0/breaking-changes-5.0.html).
I suggest to use a dedicated IP address other than 0.0.0.0.
Any feedback is appreciated.
Source: https://github.com/xaque208/puppet-unbound/blob/master/examples/init.pp
Since PR #153 unbound::local_zone class does not exists anymore.
Unfortunately, my puppet code was heavily using this feature to configure different local zones regarding of host type, eg :
ensure_resource('unbound::local_zone', '.', { 'type' => 'refuse' })
if( $zone1) { ensure_resource('unbound::local_zone', 'my.zone1.net', { 'type' => 'transparent' }) }
if( $zone2) { ensure_resource('unbound::local_zone', 'my.zone2.net', { 'type' => 'transparent' }) }
How can I use this feature again ?
Merging all local zones a in single hash and pass it as a ::unbound class parameter seems kind of hard because of puppet immutable variable design
Support for hide_identity/hide_version got lost. In commit df87e30, see file manifests/init.pp , line number 46 + 47. The $hide_identity and $hide_version variables were removed and never replaced with $unbound::params:: equivalents.
Debian 8 is EOL since some time now. This 2.8.0 release will be the last one with Debian 8 support. The next release will be 3.0.0 without Debian 8!
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Resource type not found: Unix::Path (file: /etc/puppetlabs/code/environments/production/modules/unbound/manifests/stub.pp, line: 35, column: 3) on node
should just work
seems git commit 5868593 introduced Unix::Path
where is that supposed to come from? looking at metadata.json, I see stdlib and concat, stdlib is at git revision ee1f0551e7564a15d85ef879eb1e83595388abd2 (metadata.json says 6.2.0), should be fine, and I guess Unix::Path doesn't come from concat.
Unbound package on Debian provide two configuration file into path /etc/unbound/unbound.conf:
# cat /etc/unbound/unbound.conf.d/root-auto-trust-anchor-file.conf /etc/unbound/unbound.conf.d/qname-minimisation.conf
server:
# The following line will configure unbound to perform cryptographic
# DNSSEC validation using the root trust anchor.
auto-trust-anchor-file: "/var/lib/unbound/root.key"
server:
# Send minimum amount of information to upstream servers to enhance
# privacy. Only sends minimum required labels of the QNAME and sets
# QTYPE to NS when possible.
# See RFC 7816 "DNS Query Name Minimisation to Improve Privacy" for
# details.
qname-minimisation: yes
Configuration files are provided on Stretch and Buster code-names.
I create additional files in this folder therefore i include all configuration files from it. Furthermore it would be unclear for maintainers when some configuration files aren't use.
Unbound linter is failing that the option is provided two times.
Info: Computing checksum on file /etc/unbound/unbound.conf
Info: /Stage[main]/Unbound/Concat[/etc/unbound/unbound.conf]/File[/etc/unbound/unbound.conf]: Filebucketed /etc/unbound/unbound.conf to puppet with sum 7b9cf83ef566e394b3f259ae7b0efc7d
Error: Execution of '/usr/sbin/unbound-checkconf /etc/unbound/unbound.conf20200207-19370-19euxcc' returned 1: [1581070261] unbound-checkconf[21052:0] error: trust anchor presented twice
[1581070261] unbound-checkconf[21052:0] error: could not parse auto-trust-anchor-file /var/lib/unbound/root.key line 2
[1581070261] unbound-checkconf[21052:0] error: error reading auto-trust-anchor-file: /var/lib/unbound/root.key
[1581070261] unbound-checkconf[21052:0] error: validator: error in trustanchors config
[1581070261] unbound-checkconf[21052:0] error: validator: could not apply configuration settings.
[1581070261] unbound-checkconf[21052:0] fatal error: bad config for validator module
Error: /Stage[main]/Unbound/Concat[/etc/unbound/unbound.conf]/File[/etc/unbound/unbound.conf]/content: change from '{md5}7b9cf83ef566e394b3f259ae7b0efc7d' to '{md5}022ad60bf8e6964d0a6fec9203cd205b' failed: Execution of '/usr/sbin/unbound-checkconf /etc/unbound/unbound.conf20200207-19370-19euxcc' returned 1: [1581070261] unbound-checkconf[21052:0] error: trust anchor presented twice
[1581070261] unbound-checkconf[21052:0] error: could not parse auto-trust-anchor-file /var/lib/unbound/root.key line 2
[1581070261] unbound-checkconf[21052:0] error: error reading auto-trust-anchor-file: /var/lib/unbound/root.key
[1581070261] unbound-checkconf[21052:0] error: validator: error in trustanchors config
[1581070261] unbound-checkconf[21052:0] error: validator: could not apply configuration settings.
[1581070261] unbound-checkconf[21052:0] fatal error: bad config for validator module
The issue is that option auto-trust-anchor-file
is required see here. My idea is to make it optional then create additional configuration file which overrides the one from package. Alternative approach would be to purge unmanaged configuration files.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.