summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.gitignore1
-rw-r--r--make-freebsd.mk12
-rw-r--r--make-linux.mk26
-rw-r--r--make-mac.mk4
-rw-r--r--netcon/NetconEthernetTap.cpp4
-rw-r--r--netcon/NetconEthernetTap.hpp4
-rw-r--r--netcon/README.md22
-rw-r--r--netcon/make-intercept.mk53
-rw-r--r--node/Utils.cpp46
-rw-r--r--objects.mk3
-rw-r--r--one.cpp2
-rw-r--r--service/OneService.cpp23
12 files changed, 81 insertions, 119 deletions
diff --git a/.gitignore b/.gitignore
index 27e0e191..12d6e0d5 100755
--- a/.gitignore
+++ b/.gitignore
@@ -54,6 +54,7 @@ Thumbs.db
*.rpm
*.autosave
*.tmp
+.depend
node_modules
cluster-geo/cluster-geo/config.js
cluster-geo/cluster-geo/cache.*
diff --git a/make-freebsd.mk b/make-freebsd.mk
index 022540d2..7148896e 100644
--- a/make-freebsd.mk
+++ b/make-freebsd.mk
@@ -6,21 +6,21 @@ DEFS=
LIBS=
include objects.mk
-OBJS+=osdep/BSDEthernetTap.o
+OBJS+=osdep/BSDEthernetTap.o
# "make official" is a shortcut for this
ifeq ($(ZT_OFFICIAL_RELEASE),1)
- DEFS+=-DZT_OFFICIAL_RELEASE
+ DEFS+=-DZT_OFFICIAL_RELEASE
endif
# Build with ZT_ENABLE_CLUSTER=1 to build with cluster support
ifeq ($(ZT_ENABLE_CLUSTER),1)
- DEFS+=-DZT_ENABLE_CLUSTER
+ DEFS+=-DZT_ENABLE_CLUSTER
endif
# "make debug" is a shortcut for this
ifeq ($(ZT_DEBUG),1)
- DEFS+=-DZT_TRACE
+ DEFS+=-DZT_TRACE
CFLAGS+=-Wall -g -pthread $(INCLUDES) $(DEFS)
LDFLAGS+=
STRIP=echo
@@ -38,8 +38,8 @@ CXXFLAGS+=$(CFLAGS) -fno-rtti
all: one
-one: $(OBJS) one.o
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) one.o $(LIBS)
+one: $(OBJS) service/OneService.o one.o
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) service/OneService.o one.o $(LIBS)
$(STRIP) zerotier-one
ln -sf zerotier-one zerotier-idtool
ln -sf zerotier-one zerotier-cli
diff --git a/make-linux.mk b/make-linux.mk
index 2e823993..c4024f83 100644
--- a/make-linux.mk
+++ b/make-linux.mk
@@ -28,13 +28,11 @@ endif
#UNAME_M=$(shell $(CC) -dumpmachine | cut -d '-' -f 1)
-INCLUDES=-Iext/lwip/src/include -Iext/lwip/src/include/ipv4 -Iext/lwip/src/include/ipv6
-DEFS=-DZT_ENABLE_NETCON
-#CXXFLAGS+=-Wc++11-compat-deprecated-writable-strings -Wformat
+INCLUDES?=
+DEFS?=
LDLIBS?=
include objects.mk
-OBJS+=osdep/LinuxEthernetTap.o netcon/NetconEthernetTap.o
# "make official" is a shortcut for this
ifeq ($(ZT_OFFICIAL_RELEASE),1)
@@ -91,12 +89,20 @@ endif
all: one
-one: $(OBJS) one.o
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) one.o $(LDLIBS)
+one: $(OBJS) service/OneService.o one.o osdep/LinuxEthernetTap.o
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) service/OneService.o one.o osdep/LinuxEthernetTap.o $(LDLIBS)
$(STRIP) zerotier-one
ln -sf zerotier-one zerotier-idtool
ln -sf zerotier-one zerotier-cli
+netcon: one
+ # Need to selectively rebuild one.cpp and OneService.cpp with ZT_SERVICE_NETCON and ZT_ONE_NO_ROOT_CHECK defined, and also NetconEthernetTap
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -DZT_SERVICE_NETCON -DZT_ONE_NO_ROOT_CHECK -Iext/lwip/src/include -Iext/lwip/src/include/ipv4 -Iext/lwip/src/include/ipv6 -o zerotier-netcon-service one.cpp service/OneService.cpp netcon/NetconEthernetTap.cpp $(OBJS) $(LDLIBS) -ldl
+ # Build netcon/liblwip.so which must be placed in ZT home for zerotier-netcon-service to work
+ cd netcon ; make -f make-liblwip.mk
+ # Use gcc not clang to build standalone intercept library since gcc is typically used for libc and we want to ensure maximal ABI compatibility
+ cd netcon ; gcc -g -O2 -Wall -std=c99 -fPIC -DVERBOSE -DDEBUG_RPC -DCHECKS -D_GNU_SOURCE -DNETCON_INTERCEPT -I. -nostdlib -shared -o ../libzerotierintercept.so Intercept.c
+
selftest: $(OBJS) selftest.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LDLIBS)
$(STRIP) zerotier-selftest
@@ -105,9 +111,9 @@ installer: one FORCE
./ext/installfiles/linux/buildinstaller.sh
clean:
- rm -rf *.o node/*.o controller/*.o osdep/*.o service/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o $(OBJS) zerotier-one zerotier-idtool zerotier-cli zerotier-selftest build-* ZeroTierOneInstaller-* *.deb *.rpm
- # Remove files from all the funny places we put them for tests
- find netcon -type f \( -name '*.o' -o -name '*.so' -o -name '*.1.0' -o -name 'zerotier-one' -o -name 'zerotier-cli' \) -delete
+ rm -rf *.so *.o node/*.o controller/*.o osdep/*.o service/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o $(OBJS) zerotier-one zerotier-idtool zerotier-cli zerotier-selftest zerotier-netcon-service build-* ZeroTierOneInstaller-* *.deb *.rpm
+ # Remove files from all the funny places we put them for netcon tests
+ find netcon -type f \( -name '*.o' -o -name '*.so' -o -name '.depend' -o -name '*.1.0' -o -name 'zerotier-one' -o -name 'zerotier-cli' \) -delete
find netcon/docker-test -name "zerotier-intercept" -type f -delete
debug: FORCE
@@ -115,7 +121,7 @@ debug: FORCE
make ZT_DEBUG=1 selftest
official: FORCE
- make -j 4 ZT_OFFICIAL_RELEASE=1
+ make -j 4 ZT_OFFICIAL_RELEASE=1 one
make ZT_OFFICIAL_RELEASE=1 installer
FORCE:
diff --git a/make-mac.mk b/make-mac.mk
index 7c4ef907..ffaf822d 100644
--- a/make-mac.mk
+++ b/make-mac.mk
@@ -71,8 +71,8 @@ CXXFLAGS=$(CFLAGS) -fno-rtti
all: one
-one: $(OBJS) one.o
- $(CXX) $(CXXFLAGS) -o zerotier-one $(OBJS) one.o $(LIBS)
+one: $(OBJS) service/OneService.o one.o
+ $(CXX) $(CXXFLAGS) -o zerotier-one $(OBJS) service/OneService.o one.o $(LIBS)
$(STRIP) zerotier-one
ln -sf zerotier-one zerotier-idtool
ln -sf zerotier-one zerotier-cli
diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp
index 3f772883..f33e7ffa 100644
--- a/netcon/NetconEthernetTap.cpp
+++ b/netcon/NetconEthernetTap.cpp
@@ -25,8 +25,6 @@
* LLC. Start here: http://www.zerotier.com/
*/
-#ifdef ZT_ENABLE_NETCON
-
#include <algorithm>
#include <utility>
#include <dlfcn.h>
@@ -1551,5 +1549,3 @@ void NetconEthernetTap::handle_write(TcpConnection *conn)
}
} // namespace ZeroTier
-
-#endif // ZT_ENABLE_NETCON
diff --git a/netcon/NetconEthernetTap.hpp b/netcon/NetconEthernetTap.hpp
index dd51a19d..f6fdb6e1 100644
--- a/netcon/NetconEthernetTap.hpp
+++ b/netcon/NetconEthernetTap.hpp
@@ -28,8 +28,6 @@
#ifndef ZT_NETCONETHERNETTAP_HPP
#define ZT_NETCONETHERNETTAP_HPP
-#ifdef ZT_ENABLE_NETCON
-
#include <stdio.h>
#include <stdlib.h>
@@ -182,6 +180,4 @@ private:
} // namespace ZeroTier
-#endif // ZT_ENABLE_NETCON
-
#endif
diff --git a/netcon/README.md b/netcon/README.md
index b6bff667..01e57a9b 100644
--- a/netcon/README.md
+++ b/netcon/README.md
@@ -39,11 +39,13 @@ It is *likely* to work with other things but there are no guarantees. UDP, ICMP/
# Building Network Containers
-Network Containers are currently only for Linux. To build the network container host and intercept library, from the base of the ZeroTier One tree type:
+Network Containers are currently only for Linux. To build the network container host, IP stack, and intercept library, from the base of the ZeroTier One tree run:
make netcon
-This will build a binary called *zerotier-netcon-service* and a library called *libzerotierintercept.so*. The former is the same as a regular ZeroTier One build except instead of creating virtual network ports using Linux's */dev/net/tun* interface, it instead creates instances of a user-space TCP/IP stack for each virtual network and provides RPC access to this stack via a Unix domain socket called */tmp/.ztnc_##NETWORK_ID##*. The latter is a library that can be loaded with the Linux *LD\_PRELOAD* environment variable or by placement into */etc/ld.so.preload* on a Linux system or container.
+This will build a binary called *zerotier-netcon-service* and a library called *libzerotierintercept.so*. It will also build the IP stack as *netcon/liblwip.so*.
+
+The *zerotier-netcon-service* binary is almost the same as a regular ZeroTier One build except instead of creating virtual network ports using Linux's */dev/net/tun* interface, it creates instances of a user-space TCP/IP stack for each virtual network and provides RPC access to this stack via a Unix domain socket called */tmp/.ztnc_##NETWORK_ID##*. The latter is a library that can be loaded with the Linux *LD\_PRELOAD* environment variable or by placement into */etc/ld.so.preload* on a Linux system or container.
The intercept library does nothing unless the *ZT\_NC\_NWID* environment variable is set. If on program launch (or fork) it detects the presence of this environment variable, it will attempt to connect to a running *zerotier-netcon-service* at the aforementioned Unix domain socket location and will intercept calls to the Posix sockets API and redirect network traffic through the virtual network.
@@ -53,9 +55,10 @@ Unlike *zerotier-one*, *zerotier-netcon-service* does not need to be run with ro
You don't need Docker or any other container engine to try Network Containers. A simple test can be performed in user space in your own home directory.
-First, build the netcon service and intercept library as describe above. Then create a directory to act as a temporary ZeroTier home for your test netcon service instance.
+First, build the netcon service and intercept library as describe above. Then create a directory to act as a temporary ZeroTier home for your test netcon service instance. You'll need to move the liblwip.so binary that was built with *make netcon* into there, since the service must be able to find it there and load it.
mkdir /tmp/netcon-test-home
+ cp -f ./netcon/liblwip.so /tmp/netcon-test-home
Now you can run the service (no sudo needed):
@@ -106,3 +109,16 @@ Going to port 8080 on your machine won't work. Darkhttpd is listening, but only
curl http://NETCON.INSTANCE.IP:8080/README.md
Replace *NETCON.INSTANCE.IP* with the IP address that *zerotier-netcon-service* was assigned on the virtual network. (This is the same IP you pinged in your first test.) If everything works, you should get back a copy of ZeroTier One's main README.md file.
+
+# Installing in a Docker Container (or any other container engine)
+
+If it's not immediately obvious, installation into a Docker container is easy. Just install *zerotier-netcon-service*, *libzerotierintercept.so*, and *liblwip.so* into the container at an appropriate location. We suggest putting it all in */var/lib/zerotier-one* since this is the default ZeroTier home and will eliminate the need to supply a path to any of ZeroTier's services or utilities. Then, in your Docker container entry point script launch the service with *-d* to run it in the background, set the appropriate environment variables as described above, and launch your container's main application.
+
+The only bit of complexity is configuring which virtual network to join. ZeroTier's service automatically joins networks that have *.conf* files in *ZTHOME/networks.d* even if the *.conf* file is empty. So one way of doing this very easily is to add the following commands to your Dockerfile or container entry point script:
+
+ mkdir -p /var/lib/zerotier-one/networks.d
+ touch /var/lib/zerotier-one/networks.d/8056c2e21c000001.conf
+
+Replace 8056c2e21c000001 with the network ID of the network you want your container to automaticlaly join.
+
+Now your container will automatically join the specified network on startup. Authorizing the container on a private network still requires a manual authorization step either via the ZeroTier Central web UI or the API. We're working on some ideas to automate this via bearer token auth or similar since doing this manually or with scripts for large deployments is tedious. We'll have something in this area by the time Network Containers itself is ready to be pronounced no-longer-beta.
diff --git a/netcon/make-intercept.mk b/netcon/make-intercept.mk
deleted file mode 100644
index 71d6d4dc..00000000
--- a/netcon/make-intercept.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# ZeroTier One - Network Virtualization Everywhere
-# Copyright (C) 2011-2015 ZeroTier, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# --
-#
-# ZeroTier may be used and distributed under the terms of the GPLv3, which
-# are available at: http://www.gnu.org/licenses/gpl-3.0.html
-#
-# If you would like to embed ZeroTier into a commercial application or
-# redistribute it in a modified binary form, please contact ZeroTier Networks
-# LLC. Start here: http://www.zerotier.com/
-#
-
-SHCC=gcc
-
-intercept_CFLAGS = -c -fPIC -g -O2 -Wall -std=c99 -DVERBOSE -DDEBUG_RPC -DCHECKS -D_GNU_SOURCE -DNETCON_INTERCEPT
-#LIB_NAME = intercept
-SHLIB_EXT=dylib
-SHLIB_MAJOR = 1
-SHLIB_MINOR = 8
-COMMON = Common
-OBJS= Intercept.o
-#SHLIB = ${LIB_NAME}.${SHLIB_EXT}.${SHLIB_MAJOR}.${SHLIB_MINOR}
-SHLDFLAGS = -g -O2 -Wall -I. -nostdlib -shared
-LIBS = -ldl -lc -lrt -lpthread
-
-lib:
- ${SHCC} $(intercept_CFLAGS) -I. Intercept.c -o Intercept.o
- ${SHCC} $(SHLDFLAGS) Intercept.o -o libzerotierintercept.so.1.0 $(LIBS)
-
-install:
- cp libzerotierintercept.so.1.0 /lib/libzerotierintercept.so.1.0
- ln -sf /lib/libzerotierintercept.so.1.0 /lib/libzerotierintercept
- /usr/bin/install -c zerotier-intercept /usr/bin
-
-uninstall:
- rm -r /lib/libzerotierintercept.so.1.0
- rm -r /lib/libzerotierintercept
- rm -r /usr/bin/zerotier-intercept
diff --git a/node/Utils.cpp b/node/Utils.cpp
index 10146e6c..7361c2a5 100644
--- a/node/Utils.cpp
+++ b/node/Utils.cpp
@@ -29,6 +29,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <time.h>
#include <sys/stat.h>
#include "Constants.hpp"
@@ -149,44 +150,50 @@ unsigned int Utils::unhex(const char *hex,unsigned int maxlen,void *buf,unsigned
void Utils::getSecureRandom(void *buf,unsigned int bytes)
{
-#ifdef __WINDOWS__
-
- static HCRYPTPROV cryptProvider = NULL;
static Mutex globalLock;
static Salsa20 s20;
+ static bool s20Initialized = false;
Mutex::Lock _l(globalLock);
+ /* Just for posterity we Salsa20 encrypt the result of whatever system
+ * CSPRNG we use. There have been several bugs at the OS or OS distribution
+ * level in the past that resulted in systematically weak or predictable
+ * keys due to random seeding problems. This mitigates that by grabbing
+ * a bit of extra entropy and further randomizing the result, and comes
+ * at almost no cost and with no real downside if the random source is
+ * good. */
+ if (!s20Initialized) {
+ s20Initialized = true;
+ uint64_t s20Key[4];
+ s20Key[0] = (uint64_t)time(0); // system clock
+ s20Key[1] = (uint64_t)buf; // address of buf
+ s20Key[2] = (uint64_t)s20Key; // address of s20Key[]
+ s20Key[3] = (uint64_t)&s20; // address of s20
+ s20.init(s20Key,256,s20Key);
+ }
+
+#ifdef __WINDOWS__
+
+ static HCRYPTPROV cryptProvider = NULL;
+
if (cryptProvider == NULL) {
if (!CryptAcquireContextA(&cryptProvider,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) {
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() unable to obtain WinCrypt context!\r\n");
exit(1);
return;
}
- char s20key[32];
- if (!CryptGenRandom(cryptProvider,(DWORD)sizeof(s20key),(BYTE *)s20key)) {
- fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
- exit(1);
- }
- s20.init(s20key,256,s20key);
}
-
if (!CryptGenRandom(cryptProvider,(DWORD)bytes,(BYTE *)buf)) {
fprintf(stderr,"FATAL ERROR: Utils::getSecureRandom() CryptGenRandom failed!\r\n");
exit(1);
}
- s20.encrypt12(buf,buf,bytes);
#else // not __WINDOWS__
-#ifdef __UNIX_LIKE__
-
static char randomBuf[131072];
static unsigned int randomPtr = sizeof(randomBuf);
static int devURandomFd = -1;
- static Mutex globalLock;
-
- Mutex::Lock _l(globalLock);
if (devURandomFd <= 0) {
devURandomFd = ::open("/dev/urandom",O_RDONLY);
@@ -215,12 +222,9 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
((char *)buf)[i] = randomBuf[randomPtr++];
}
-#else // not __UNIX_LIKE__
+#endif // __WINDOWS__ or not
-#error No getSecureRandom() implementation available.
-
-#endif // __UNIX_LIKE__
-#endif // __WINDOWS__
+ s20.encrypt12(buf,buf,bytes);
}
std::vector<std::string> Utils::split(const char *s,const char *const sep,const char *esc,const char *quot)
diff --git a/objects.mk b/objects.mk
index 8daec8b5..d11e2812 100644
--- a/objects.mk
+++ b/objects.mk
@@ -29,5 +29,4 @@ OBJS=\
osdep/Http.o \
osdep/OSUtils.o \
service/ClusterGeoIpService.o \
- service/ControlPlane.o \
- service/OneService.o
+ service/ControlPlane.o
diff --git a/one.cpp b/one.cpp
index 685034df..deb0a398 100644
--- a/one.cpp
+++ b/one.cpp
@@ -1096,10 +1096,12 @@ int main(int argc,char **argv)
}
#ifdef __UNIX_LIKE__
+#ifndef ZT_ONE_NO_ROOT_CHECK
if ((!skipRootCheck)&&(getuid() != 0)) {
fprintf(stderr,"%s: must be run as root (uid 0)"ZT_EOL_S,argv[0]);
return 1;
}
+#endif // !ZT_ONE_NO_ROOT_CHECK
if (runAsDaemon) {
long p = (long)fork();
if (p < 0) {
diff --git a/service/OneService.cpp b/service/OneService.cpp
index c3204b5d..ed60ed2d 100644
--- a/service/OneService.cpp
+++ b/service/OneService.cpp
@@ -92,37 +92,32 @@ class SqliteNetworkController;
#endif
// Include the right tap device driver for this platform -- add new platforms here
-#ifdef ZT_ENABLE_NETCON
+#ifdef ZT_SERVICE_NETCON
+// In network containers builds, use the virtual netcon endpoint instead of a tun/tap port driver
#include "../netcon/NetconEthernetTap.hpp"
namespace ZeroTier { typedef NetconEthernetTap EthernetTap; }
-#else
-#ifdef __APPLE__
+#else // not ZT_SERVICE_NETCON so pick a tap driver
+#ifdef __APPLE__
#include "../osdep/OSXEthernetTap.hpp"
namespace ZeroTier { typedef OSXEthernetTap EthernetTap; }
-
-#endif
+#endif // __APPLE__
#ifdef __LINUX__
-
#include "../osdep/LinuxEthernetTap.hpp"
namespace ZeroTier { typedef LinuxEthernetTap EthernetTap; }
-
-#endif
+#endif // __LINUX__
#ifdef __WINDOWS__
-
#include "../osdep/WindowsEthernetTap.hpp"
namespace ZeroTier { typedef WindowsEthernetTap EthernetTap; }
-
-#endif
+#endif // __WINDOWS__
#ifdef __FreeBSD__
-
#include "../osdep/BSDEthernetTap.hpp"
namespace ZeroTier { typedef BSDEthernetTap EthernetTap; }
+#endif // __FreeBSD__
-#endif
-#endif // ZT_ENABLE_NETCON
+#endif // ZT_SERVICE_NETCON
// Sanity limits for HTTP
#define ZT_MAX_HTTP_MESSAGE_SIZE (1024 * 1024 * 64)