Month: February 2018

OpenVPN Server Hardening – OpenWRT TUN device

OpenVPN Server Hardening – OpenWRT TUN device

This is a tutorial for a hardened OpenVPN Server with all important settings in a paranoid TLS based setup. I have read through different other tutorials, more or less good tutorials, but most of them lacked serious settings or had just set them wrong. So i decided to read through the complete ManPage from OpenVPN to find all the important settings by myself.
This Tutorial covers OpenVPN Version v2.4 (with compatibility to v2.3.3 clients). The next OpenVPN will cover the Client Settings for different scenarios.

Network Topology

OpenVPN Server Hardening – OpenWRT TUN device 1My Home Router is on the LAN Network 192.168.68.0/24 and i want to access it from other devices from different networks.

Firewall Rule

First we need to make the OpenVPN available on the WAN Port. For this we add a Firewall Rule to /etc/config/firewall.

OpenVPN Server Hardening – OpenWRT TUN device 2

config 'rule'
 option 'name' 'openvpn-udp'
 option 'src' 'wan' 
 option 'target' 'ACCEPT'
 option 'proto' 'udp' 
 option 'dest_port' '1194'

Generation of Certificates

Import From Future Blog Post to create your own Certificate Authority with a Root CA, different Intermediate CA’s, and Server + Client Certificates.

For this tutorial we need following Certificate and Key files:

  • RootCA (CA)
  • Intermediate CA (ICA)
  • Server Certificate
  • Server Cert & Key (+ Client Cert & Keys for Testing)
  • CRL File
  • TLS-Auth Key
  • Diffie Hellman parameters

Keysize

Regarding an ENISA – Algorithms, Key Sizes and Parameters Report keys specified to be at least ten years in use, RSA keys of 3072 bits or more are recommended.

Creation of 4096 bit RSA keys is recommended by me.

https://community.openvpn.net/openvpn/wiki/Hardening#X.509keysize

CA-Chain File

The RootCA and the ICA Certificates should be bundled into a ca-chain.cert file.

cat RootCa.pem IntermediateCA.pem > ca-chain.pem

TLS-Auth Key

Generate TLS-Auth key 
openvpn --genkey --secret openvpn/tls-auth.key
This key is available on all devices and should be kept secret.

DH Parameters

Generating DH keys takes substantial amounts of time.
openssl dhparam -out dhparam4096.pem 4096
 The DH Parameters should exceed your Server Certificate size.
  • Server Certificate 2048 bit => DH 4096 bit
  • Server Certificate 4096 bit => DH 8192 bit

Your Server Certificate should have at least 4096 bit in size.

Subnet

The VPN will create a subnet. You should choose a Net which will not overlap with any other Subnet you will possibly encounter. Stay away from 192.168.0.0/24, 192.168.0.0/24 or 10.0.0.0/24 as these nets are often seen to be used for default LAN ranges in home routers.

Multiclient

My assumption was for this tutorial a /29 net. For example any CIDR Net from a private “Class B” Address Range in between 172.16.0.0–172.31.255.255 can be choosen. Class B has not been used that often, at least it seems to me. Just try to pick a “random” net private, which has a rare chance to be unused by others.

CIDR Net Notation:  172.16.10.0/29  
Subnet Mask:        255.255.255.248 
Broadcast:          172.16.10.7
CIDR Address Range: 172.16.10.0 - 172.16.10.7 
Useable Adresses:   6 (1 Server + 5 Clients) 
Server:             172.16.10.1
Clients:            172.16.10.2 - 172.16.10.6

Point-To-Point

If the VPN is only planned for a Point-To-Point connection between two Routers or for a single Client, a /30 Net should be chosen instead. It is still a MultiClient Net, but with only two Points.

CIDR Net Notation:  172.18.25.64/30  
Subnet Mask:        255.255.255.252 
Broadcast:          172.18.25.67
CIDR Address Range: 172.18.25.64 - 172.18.25.67
Useable Adresses:   2 (1 Server + 1 Client) 
Server:             172.18.25.65
Client:             172.18.25.66

OpenVPN Server Hardening – OpenWRT TUN device 3

OpenWRT OpenVPN Settings

OpenVPN config for a TLS based and hardened Setup in /etc/config/openvpn
config openvpn 'cyber'
        option enabled '1'
#Protocol
        option dev_type 'tun'
        option dev 'cyber_tun0'
        option topology 'subnet'
        option proto 'udp'
        option port '1194'

#Routes 
        option server '172.16.10.0 255.255.255.248'
        option ifconfig '172.16.10.1 255.255.255.248'
        list push 'route 192.168.100.0 255.255.255.0'

#Client Config
        option ccd_exclusive '1'
        option client_config_dir '/etc/openvpn/ccd/'
        option max_clients '5'
        option client_to_client '1' 

#Encryption
        option ca '/etc/ssl/certs/vpn.cavebeat.lan.ca-chain.cert.pem'
        option cert '/etc/ssl/certs/ptree.vpn.cavebeat.lan.cert.pem'
        option key '/etc/ssl/private/ptree.vpn.cavebeat.lan.key.pem'
        option dh '/etc/ssl/dh4096.pem'
        option tls_crypt '/etc/ssl/tls-auth.key'
        option cipher 'AES-256-CBC'
        option ncp_ciphers 'AES-256-GCM:AES-128-GCM:AES-256-CBC:AES-128-CBC'
        option auth 'SHA512'
        option tls_server '1'
        option tls_version_min '1.2'
        option tls_cipher 'TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256'
        option reneg_sec '1800'
        option reneg_bytes '64000000'
        option remote_cert_tls 'client'
#        option verify_client_cert '1'

#Logging
        option log_append '/var/log/openvpn/openvpn.log'
        option status '/var/log/openvpn-status.log'
        option mute '5'
        option verb '4'

#Connection
        option keepalive '10 60'
        option compress 'lzo'
        option script_security '1'

#Connection Reliability
        option persist_key '1'
        option persist_tun '1'

#Permissions
       option  user 'nobody'
       option group 'nogroup'

The parameter verify_client_cert / –verify-client-cert is new in OpenVPN 2.4 and is replacing the deprecated parameter –client-cert-not-required. For more information on deprecated parameters check Deprecated OpenVPN Settings

The default value should require to verify the client cert given to the server. I have placed a PullRequest with a change for OpenWRT to add this setting.

Description of used Settings and Parameters

option enabled '1'

Protocol

option dev_type 'tun'
--dev-type device-type 
  Which device type are we using? device-type should be tun (OSI Layer 3) or tap (OSI Layer 2). 
  Use this option only if the TUN/TAP device used with --dev does not begin with tun or tap. 
option dev 'tun1'
--dev tunX | tapX | null
  tun devices encapsulate IPv4 or IPv6 (OSI Layer 3) while tap devices encapsulate Ethernet 802.3 (OSI Layer 2). 
option topology 'subnet'
--topology mode 
  Configure virtual addressing topology when running in --dev tun mode. 
  subnet -- Use a subnet rather than a point-to-point topology by configuring the tun interface with a local IP address and subnet mask, similar to the topology used in --dev tap and ethernet bridging mode. 
  This mode allocates a single IP address per connecting client and works on Windows as well. 
  Note: Using --topology subnet changes the interpretation of the arguments of --ifconfig to mean "address netmask", no longer "local remote". 

Routes

option server '172.16.10.0 255.255.255.248'
--server network netmask ['nopool'] 
  A helper directive designed to simplify the configuration of OpenVPN's server mode.  
  This directive will set up an OpenVPN server which will allocate addresses to clients out of the given network/netmask. 
  The server itself will take the ".1" address of the given network for use as the server-side endpoint of the local TUN/TAP interface.
option ifconfig '172.16.10.1 255.255.255.248'
--ifconfig l rn
  Set TUN/TAP adapter parameters. l is the IP address of the local VPN endpoint. 
  For TAP devices, or TUN devices used with --topology subnet,rn is the subnet mask of the virtual network segment which is being created or connected to. 
  For TAP devices, which provide the ability to create virtual ethernet segments, or TUN devices in --topology subnet mode (which create virtual "multipoint networks"), --ifconfig is used to set an IP address and subnet mask just as a physical ethernet adapter would be similarly configured.
list push 'route 192.168.100.0 255.255.255.0'
--push option 
  Push a config file option back to the client for remote execution.  
  Note that option must be enclosed in double quotes ("").

Client Config

option client_config_dir '/etc/openvpn/ccd/'
--client-config-dir dir 
  Specify a directory dir for custom client config files.  
  After a connecting client has been authenticated, OpenVPN will look in this directory for a file having the same name as the client's X509 common name.  
  If a matching file exists, it will be opened and parsed for client-specific configuration options. 
  If no matching file is found, OpenVPN will instead try to open and parse a default file called "DEFAULT", which may be provided but is not required. 
  Note that the configuration files must be readable by the OpenVPN process after it has dropped it's root privileges. 
option ccd_exclusive '1'
--ccd-exclusive 
  Require, as a condition of authentication, that a connecting client has a --client-config-dir file. 
option max_clients '5'
--max-clients n 
  Limit server to a maximum of n concurrent clients.
option client_to_client '0' 
--client-to-client 
  Because the OpenVPN server mode handles multiple clients through a single tun or tap interface, it is effectively a router.  
  The --client-to-client flag tells OpenVPN to internally route client-to-client traffic rather than pushing all client-originating traffic to the TUN/TAP interface. 

Encryption

option ca '/etc/ssl/certs/vpn.cavebeat.lan.ca-chain.cert.pem'
--ca file 
  Certificate authority (CA) file in .pem format, also referred to as the root certificate. 
option cert '/etc/ssl/certs/ptree.vpn.cavebeat.lan.cert.pem'
--cert file 
  Local peer's signed certificate in .pem format -- must be signed by a certificate authority whose certificate is in --ca file. 
  Each peer in an OpenVPN link running in TLS mode should have its own certificate and private key file.  
  In addition, each certificate should have been signed by the key of a certificate authority whose public key resides in the --ca certificate authority file. 
option key '/etc/ssl/private/ptree.vpn.cavebeat.lan.key.pem'
--key file 
  Local peer's private key in .pem format. 
option dh '/etc/ssl/dh4096.pem'
--dh file 
  File containing Diffie Hellman parameters in .pem format (required for --tls-server only). 
option tls_crypt '/etc/ssl/tls-auth.key'
--tls-auth file [direction] 
  Add an additional layer of HMAC authentication on top of the TLS control channel to mitigate DoS attacks and attacks on the TLS stack. 
  In a nutshell, --tls-auth enables a kind of "HMAC firewall" on OpenVPN's TCP/UDP port, where TLS control channel packets bearing an incorrect HMAC signature can be dropped immediately without response. 
  file (required) is a file in OpenVPN static key format which can be generated by --genkey
  
  Use --tls-crypt instead if you want to use the key file to not only authenticate, but also encrypt the TLS control channel. 
  
--tls-crypt keyfile
  Encrypt and authenticate all control channel packets with the key from keyfile. (See --tls-auth for more background.) 
  Encrypting (and authenticating) control channel packets: 
  + provides more privacy by hiding the certificate used for the TLS connection, 
  + makes it harder to identify OpenVPN traffic as such, 
  + provides "poor-man's" post-quantum security, against attackers who will never know the pre-shared key (i.e. no forward secrecy). 
  In contrast to --tls-auth, --tls-crypt does *not* require the user to set --key-direction
option cipher 'AES-256-CBC' 
  --cipher alg  
  Encrypt data channel packets with cipher algorithm alg.
  https://community.openvpn.net/openvpn/wiki/SWEET32#a1.Changetoalargerblockcipher  Of the currently supported ciphers, OpenVPN currently recommends using AES-256-CBC or AES-128-CBC.  
  OpenVPN 2.4 and newer will also support GCM.  
  For 2.4+, we recommend using AES-256-GCM or AES-128-GCM. 
option ncp-ciphers 'AES-256-GCM:AES-128-GCM:AES-256-CBC:AES-128-CBC'
--ncp-ciphers cipher_list 
  Restrict the allowed ciphers to be negotiated to the ciphers in cipher_list. 
  cipher_list is a colon-separated list of ciphers, and defaults to "AES-256-GCM:AES-128-GCM".
  For servers, the first cipher from cipher_list will be pushed to clients that support cipher negotiation. 
  If both peers support and do not disable NCP, the negotiated cipher will override the cipher specified by --cipher
option auth 'SHA512'
--auth alg 
  Authenticate data channel packets and (if enabled) tls-auth control channel packets with HMAC using message digest algorithm alg. 
  If an AEAD cipher mode (e.g. GCM) is chosen, the specified --auth algorithm is ignored for the data channel, and the authentication method of the AEAD cipher is used instead.  
  Note that alg still specifies the digest used for tls-auth. 
option tls_server '1'
--tls-server 
  Enable TLS and assume server role during TLS handshake. 

option tls_version_min '1.2'
--tls-version-min version ['or-highest'] 
  Sets the minimum TLS version we will accept from the peer (default is "1.0"). 
  Examples for version include "1.0", "1.1", or "1.2".
  https://community.openvpn.net/openvpn/wiki/Hardening#Useof--tls-version-min
  Since OpenVPN 2.3.3, the --tls-version-min option is available to enforce a minimum TLS version. 
  Hardened setups should set --tls-version-min to 1.2 if possible.
  But be aware that setting tls-version-min to 1.2 will make it impossible to connect for pre-2.3.3 clients
option tls_cipher 'TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256'
--tls-cipher l 
  A list l of allowable TLS ciphers delimited by a colon (":"). 
  This setting can be used to ensure that certain cipher suites are used (or not used) for the TLS connection.
  You should use a DHE cipher-suite as well for forward-secrecy. 
  https://community.openvpn.net/openvpn/wiki/Hardening#Useof--tls-cipher
  To use ECDH(E) or ECDSA cipher-suites, both client and server must be OpenVPN 2.4.0 or newer.
option reneg_sec '3600'
--reneg-sec n 
  Renegotiate data channel key after n seconds (default=3600). 
option reneg_bytes '64000000'
--reneg-bytes n 
  Renegotiate data channel key after n bytes sent or received.
option remote_cert_tls 'server'
--remote-cert-tls client|server 
  Require that peer certificate was signed with an explicit key usage and extended key usage based on RFC3280 TLS rules. 
option verify_client_cert '1'
--verify-client-cert none|optional|require 
  Specify whether the client is required to supply a valid certificate. 
  require : this is the default option. A client is required to present a certificate, otherwise VPN access is refused. 
option crl_verify ''etc/ssl/crl.pem'
--crl-verify crl ['dir'] 
  Check peer certificate against the file crl in PEM format. 
  A CRL (certificate revocation list) is used when a particular key is compromised but when the overall PKI is still intact. 
  Note: As the crl file (or directory) is read every time a peer connects, if you are dropping root privileges with --user, make sure that this user has sufficient privileges to read the file. 

Logging

option log_append '/var/log/openvpn/openvpn.log'
--log-append file 
  Append logging messages to file. If file does not exist, it will be created. 
  This option behaves exactly like --log except that it appends to rather than truncating the log file. 
--log file 
  Output logging messages to file, including output to stdout/stderr which is generated by called scripts. 
  If file already exists it will be truncated. 
option status '/var/log/openvpn-status.log'
--status file [n] 
  Write operational status to file every n seconds. 
option mute '4'
--mute n 
  Log at most n consecutive messages in the same category. 
  This is useful to limit repetitive logging of similar message types. 
option verb '4'
--verb n 
  Set output verbosity to n (default=1).  
  Each level shows all info from the previous levels. 
  Level 3 is recommended if you want a good summary of what's happening without being swamped by output. 
  - 0 -- No output except fatal errors. 
  - 1 to 4 -- Normal usage range. 

Connection

option keepalive '10 60'
--keepalive interval timeout
  A helper directive designed to simplify the expression of --ping and --ping-restart.
  This option can be used on both client and server side, but it is in enough to add this on the server side as it will push appropriate --ping and --ping-restart options to the client. 
  --ping n 
    Ping remote over the TCP/UDP control channel if no packets have been sent for at least n seconds
  --ping-restart n
    Restart after n seconds pass without reception of a ping or other packet from remote. 
    In server mode, --ping-restart, --inactive, or any other type of internally generated signal will always be applied to individual client instance objects, never to whole server itself. 
    Note also in server mode that any internally generated signal which would normally cause a restart, will cause the deletion of the client instance object instead. 
option compress 'lzo'
--compress [algorithm] Enable a compression algorithm. 
  The algorithm parameter may be "lzo", "lz4", or empty.  
  LZO and LZ4 are different compression algorithms, with LZ4 generally offering the best performance with least CPU usage. 
  For backwards compatibility with OpenVPN versions before v2.4, use "lzo" (which is identical to the older option "--comp-lzo yes"). 
option script_security '1'
--script-security level
  This directive offers policy-level control over OpenVPN's usage of external programs and scripts. 
  Lower level values are more restrictive, higher values are more permissive. 
  Settings for level:
  0 -- Strictly no calling of external programs.
  1 -- (Default) Only call built-in executables such as ifconfig, ip, route, or netsh. 
  2 -- Allow calling of built-in executables and user-defined scripts. 
  3 -- Allow passwords to be passed to scripts via environmental variables (potentially unsafe).

Connection Reliability

option persist_key '1'
--persist-key 
  Don't re-read key files across SIGUSR1 or --ping-restart. 
  This option can be combined with --user nobody to allow restarts triggered by the SIGUSR1 signal. 
  Normally if you drop root privileges in OpenVPN, the daemon cannot be restarted since it will now be unable to re-read protected key files. 
option persist_tun '1'
--persist-tun 
  Don't close and reopen TUN/TAP device or run up/down scripts across SIGUSR1 or --ping-restart restarts. 

Permissions

option  user 'nobody'
--user user 
  Change the user ID of the OpenVPN process to user after initialization, dropping privileges in the process. 
option group 'nogroup'
--group group 
  Similar to the --user option, this option changes the group ID of the OpenVPN process to group after initialization. 

Expressive 3.0.0RC1 is now ready!

We’ve been working diligently the past three weeks to finalize API changes and new
features for the Expressive 3.0 release, and are pleased to announce immediate
availability of our first release candidate, 3.0.0rc1!

Why RC and not beta?

Why the jump from alpha to release candidate? Most of our planned features
also contained API changes, whether these were namespace or class name changes,
signature changes due to adopting type hints, or wholesale refactors. As a
result, we held an extended alpha release cycle so that we could continue making
API changes as we worked on new features. In the last three weeks, we’ve
continued to release new alpha versions of components, which users were picking
up as they updated; surprisingly, the majority of these continued to work due to
efforts at backwards compatibility that we made along the way.

We feel at this point that we’ve identified and implemented all desired
changes both in terms of API as well as features, and announced a feature freeze
yesterday. This puts us in a status more analogous to release candidates than
beta (where features could still be added).

In this post, we’ll cover:

Getting started with RC1

To start a new project based on 3.0.0rc1, use
Composer to create a new project:

$ composer create-project "zendframework/zend-expressive-skeleton:3.0.0rc1"

If you want to install to a custom directory name, use the following instead:

$ composer create-project zendframework/zend-expressive-skeleton {your directory} 3.0.0rc1

The installer will prompt you for a number of things:

  • What style install (minimal, flat, or modular).
  • Which DI container to use.
  • Which router to use.
  • Which template engine to use.
  • Which error handler to use.

We recommend the defaults, except in the case of a template engine; in that
case, choose the one you’re most familiar with.

Once the installer has gathered its information, it will begin installing
dependencies, enable development mode, and then let you know it’s done!

You can create your first request handler to handle an incoming request using
our tooling:

$ composer expressive handler:create "AppHandlerHelloWorldHandler"

Tooling

Run the following command to find out what other commands we expose:

$ composer expressive help

You can also get help on individual commands:

$ composer expressive help handler:create

This will create a new class and tell you where in the filesystem you’ll find
it; it will also create a factory and tell you about that. If you have enabled a
template engine, it will also create a template file and tell you where it is.

To route to it, edit the file config/routes.php and add the following line
within the callback it defines:

    $app->get('/hello/world', AppHandlerHelloWorldHandler::class);

Next, fire up the built-in web server:

$ composer serve

and navigate to http://localhost:8080/hello/world to see your handiwork!

You can also create middleware to add to your application pipeline, or within
route-specific pipelines. From here, you have the basic building blocks and
application structure to get started!

Migrating from alpha3 to rc1

While a ton has changed between the 3.0.0alpha3 release and today, most
applications built on alpha3 should be able to continue working as they were
before, due to a number of backwards compatibility efforts we put into place to
aid migration both for alpha users, as well as v2 users.

However, we recommend making the following changes to your application as well,
to ensure it follows the structure that will be used in the final stable
release.

composer.json

Whenever you see a constraint with the format ^X.Y.ZalphaW || ^X.Y, remove the
|| ^X.Y part of the constraint. This ensures that a previous alpha version
cannot be installed if you use the --prefer-lowest flag when running composer update. More stable versions will still be installed when they become
available.

config/config.php

Ensure the following configuration providers are present:

    ZendHttpHandlerRunnerConfigProvider::class,
    ZendExpressiveConfigProvider::class,
    ZendExpressiveRouterConfigProvider::class,

Most likely, you will have been prompted to install these already anyways, but
double-check to be sure.

config/pipeline.php

alpha3 refered to the following classes via import statements; they should be
updated per the following table:

alpha3 reference rc1 reference
ZendExpressiveMiddlewareDispatchMiddleware ZendExpressiveRouterMiddlewareDispatchMiddleware
ZendExpressiveMiddlewareImplicitHeadMiddleware ZendExpressiveRouterMiddlewareImplicitHeadMiddleware
ZendExpressiveMiddlewareImplicitOptionsMiddleware ZendExpressiveRouterMiddlewareImplicitOptionsMiddleware
ZendExpressiveMiddlewareNotFoundMiddleware ZendExpressiveHandlerNotFoundHandler
ZendExpressiveMiddlewareRouteMiddleware ZendExpressiveRouterMiddlewarePathBasedRoutingMiddleware

Also add the following import statement:

use ZendExpressiveRouterMiddlewareMethodNotAllowedMiddleware;

Change the line reading:

    $app->pipe(RouteMiddleware::class);

to:

    $app->pipe(PathBasedRoutingMiddleware::class);
    $app->pipe(MethodNotAllowedMiddleware::class);

Change the line reading:

    $app->pipe(NotFoundMiddleware::class);

to:

    $app->pipe(NotFoundHandler::class);

Changes between alpha3 and rc1

A number of substantial changes were released within the core Expressive
packages. We’ll detail them package-by-package, providing cumulative changes
(vs. release-by-release changes), with general changes affecting all packages
listed first.

General changes

Potentially the most far-reaching change was a decision to no longer compose
response prototypes in classes that need to produce a response, but rather
response factories. All classes that previously accepted a
PsrHttpMessageResponseInterface instance (with the exception of
ZendStratigilityMiddlewareDoublePassMiddleware) now accept a PHP callable
capable of producing a ResponseInterface instance. The simplest form, using
zend-diactoros, would look like the following:

function () {
    return new Response();
}

We made this change for a variety of reasons.

First, not all containers allow marking an instance as non-shared. This meant
that a ResponseInterface service would return the same instance each time.
While this is generally fine, as the various with*() methods produce new
instances, it falls apart when you write to the response body, as the body is
the one part of a response that is mutable. (We often addressed this fact by
also composing a stream factory, for producing an empty body stream to use
with a response.) While we could solve this problem by indicating the
ResponseInterface service was non-shared, this would not work on all
containers, and led to convoluted solutions such as using “virtual services” to
refer to discrete instances.

Second, an upcoming specification from PHP-FIG will
largely address this. The proposed PSR-17 defines a number of interfaces
describing factories for PSR-7 HTTP messages.

By changing our classes to compose a callable factory, we accomplish several
things:

  • We can now share the ResponseInterface service safely, and re-use it in any
    service that needs to produce a response. Since the factory will always
    return a new response instance, sharing the factory for the
    ResponseInterface service is safe.

  • When PSR-17 is available, we will be able to decorate its response factory via
    a closure and continue to use it. Expressive applications will be immediately
    PSR-17 compatible.

Solving type-safety issues

The one problem with passing a PHP callable for the factory is that we have
no guarantees that it actually returns a PSR-7 ResponseInterface!

To solve this, each class that composes a response factory re-assigns it as
follows:

$this->responseFactory = function () use ($responseFactory) : ResponseInterface {
    return $responseFactory();
};

This approach ensures that a TypeError is raised if the factory returns any
other type!

zend-stratigility

Stratigility received the following changes since the Expressive alpha3 release.

  • The ZendStratigilityMiddlewareErrorHandler and NotFoundHandler classes
    were updated to accept response factories instead of prototypes, as outlined
    in the previous section.

  • All middleware and handlers, as well as the Next implementation, were marked
    final.

zend-expressive-router

zend-expressive-router underwent a massive rewrite. The rewrite can be
characterized as two major changes: routes and route results are now middleware,
and all middleware from zend-expressive other than the LazyLoadingMiddleware
was moved to this package.

One general change was made: the package now ships a ConfigProvider class and
exposes it to zend-component-installer. This allows it to ship factories for
middleware it exposes and ensure that middleware can be used immediately within
Expressive applications.

Routes and RouteResults

ZendExpressiveRouterRoute now implements the PSR-15 MiddlewareInterface.
Its process() method proxies to the middleware passed to its constructor.

ZendExpressiveRouterRouteResult also now implements MiddlewareInterface.
In the case of a successful result, its process() method will proxy to the
route matched. In the case of a failed match, the method instead acts as a
no-op, proxying directly to the handler argument. Due to these changes, we felt
we could remove the getMatchedMiddleware() method; the middleware is still
accessible via the composed Route class, and, generally speaking, you should
not need direct access to it.

These changes greatly simplify the DispatchMiddleware, as it no longer needs
to check if a successful match occurred, and can instead process the route
result directly.

Additionally, the RouteMiddleware::process() logic was simplified, as it no
longer needs to conditionally inject a RouteResult as a request attribute; it
does it regardless of the result of matching.

Middleware

All previously provided middleware (RouteMiddleware, PathBasedRoutingMiddleware,
and DispatchMiddleware) were moved to the ZendExpressiveRouterMiddleware
namespace.

Additionally, we moved the following middleware from zend-expressive into this
package:

zend-expressive middleware class zend-expressive-router middleware class
ZendExpressiveMiddlewareImplicitHeadMiddleware ZendExpressiveRouterMiddlewareImplicitHeadMiddleware
ZendExpressiveMiddlewareImplicitOptionsMiddleware ZendExpressiveRouterMiddlewareImplicitOptionsMiddleware

As detailed in the General changes section, each was
modified to compose a response factory instead of a prototype.

These middleware were imported into zend-expressive-router as they are closely
related to routing:

  • ImplicitHeadMiddleware introspects a RouteResult in order to return a
    response if a HEAD request was made and other conditions are met.

  • ImplicitOptionsMiddleware introspects a RouteResult in order to return a
    response if an OPTIONS request was made and other conditions are met.

We also refactored the RouteMiddleware (and, by extension, the
PathBasedRoutingMiddleware) in order to extract the functionality for
indicating a 405 Method Not Allowed response. This functionality is now
shipped in a new class, ZendExpressiveRouterMiddlewareMethodNotAllowedMiddleware,
which should be piped immediately following the RouteMiddleware or
PathBasedRoutingMiddleware. This solves a problem several users have reported:
we previously had no ability to modify how a 405 response is returned. You can
now pipe alternative middleware for this feature if you desire using templates,
Problem Details, or other formats.

zend-expressive

The zend-expressive package also had a large number of changes. The majority
were related to exporting functionality to more relevant packages; other
changes were made to provide backwards compatibility with previous alpha
releases, as well as v2 releases.

API/Behavior changes.

  • ZendExpressiveContainerApplicationConfigInjectionDelegator now raises an
    exception if the $callback argument produces an instance of anything other
    than a ZendExpressiveApplication instance. Previously, it would return it
    immediately. Now, it raises an exception in order to detail to the user what
    changes they need to make to their application.

  • The exceptions ZendExpressiveExceptionInvalidMiddlewareException and
    MissingDependencyException were updated to implement the PSR-11
    ContainerExceptionInterface.

New classes

  • ZendExpressiveResponseServerRequestErrorResponseGenerator is an invokable
    class capable of generating a response from a Throwable as provided by
    ZendHttpHandlerRunnerRequestHandlerRunner. The class
    ZendExpressiveContainerServerRequestErrorResponseGeneratorFactory was
    updated to create and return an instance of this class.

  • ZendExpressiveResponseErrorResponseGeneratorTrait contains the bulk of
    the logic for generating an error response used both by the above class, as
    well as the existing ZendExpressiveMiddlewareErrorResponseGenerator.

New factories

The package provides two new factories:

  • ZendExpressiveContainerResponseFactoryFactory will return a PHP callable
    capable of producing a PSR-7 ResponseInterface. By default, the class provides
    a closure around instantiation of a zend-diactoros Response instance. The
    package maps it to the service PsrHttpMessageResponseInterface.

  • ZendExpressiveContainerStreamFactoryFactory will return a PHP callable
    capable of producing a PSR-7 StreamInterface. By default, the class provides a
    closure around instantiation of a zend-diactoros Stream instance backed by a
    writable php://temp resource. The package maps it to the service
    PsrHttpMessageStreamInterface.

Middleware removals

The following middleware were removed; in all cases, they were added to the
zend-expressive-router package:

  • ZendExpressiveMiddlewareImplicitHeadMiddleware
  • ZendExpressiveMiddlewareImplicitOptionsMiddleware

The class ZendExpressiveMiddlewareNotFoundMiddleware was renamed to
ZendExpressiveHandlerNotFoundHandler, and now implements the PSR-15
RequestHandlerInterface (instead of MiddlewareInterface). The class now also
composes a response factory instead of a response prototype. (Its related
factory does this for you automatically.)

Factory removals

The following factories were removed, as they are either unnecessary, or
provided by other packages:

  • ZendExpressiveContainerRouteMiddlewareFactory (now provided in
    zend-expressive-router)
  • ZendExpressiveContainerDispatchMiddlewareFactory (now provided in
    zend-expressive-router)
  • ZendExpressiveContainerImplicitHeadMiddlewareFactory (now provided in
    zend-expressive-router)
  • ZendExpressiveContainerImplicitOptionsMiddlewareFactory (now provided in
    zend-expressive-router)

zend-expressive-tooling

We spent a fair amount of time on zend-expressive-tooling to provide both
migration tools as well as tools to make you more productive during development.
In particular, we added the following:

  • migrate:interop-middleware will migrate middleware implementing http-interop
    interfaces to PSR-15. (This was in previous releases, but not highlighted
    before!)

  • migrate:middleware-to-request-handler will scan a directory (your src/
    tree by default) for middleware. When it detects middleware that does not call
    on its handler argument, it converts it to a request handler.

  • action:create is an alias to the handler:create detailed in the previous
    post on alpha3, and exposes the same set of functionality for creating a
    PSR-15 request handler. Some developers prefer the “Action” verbiage, and
    requested this feature.

  • factory:create will generate a factory class file for the given class, using
    PHP’s Reflection API. The generated file will be a sibling to the original
    class file. The functionality also auto-registers the class and factory in
    your configuration.

    The middleware:create, handler:create, and action:create commands now
    all use this functionality to create a factory for the class generated and
    wire it in your application configuration. (You may disable this capability
    via a CLI switch.)

Additionally, we added template awareness to the handler:create and
action:create commands. By default, if they detect a
ZendExpressiveTemplateTemplateRendererInterface service in your container,
they will:

  • Generate a template named after the root namespace and newly generated class
    (minus any Handler, Action, or Middleware suffix).
  • Place a template file in the configured template path for the root namespace,
    and named after the generated class.
  • Modify the generated class to accept a TemplateRendererInterface instance to
    its constructor, and render the named template to a zend-diactoros
    HtmlResponse.

The commands allow you to disable template capabilities via a switch, as well as
provide an alternate template namespace, template name, and template file
extension.

Ecosystem updates

The skeleton releases cover the core functionality of Expressive: Stratigility,
Expressive itself, routing, template engines, and the helpers. However, the
Expressive ecosystem includes other functionality as well:

  • zend-expressive-session and its adapters
  • zend-expressive-authentication and its adapters
  • zend-expressive-authorization and its adapters
  • zend-problem-details
  • zend-expressive-hal

We have provided alpha releases of each of these packages to provide the
following:

  • PSR-15 support
  • Response factory (vs response prototype) support
  • Compatibility with core alpha and RC releases

As such, if you are using the RC1 skeleton (or have updated your alpha3
skeleton), you will be able to use these packages without issue; installing them
will grab these latest alpha versions, which will be compatible with the stable
release (and for which their own stable releases will work with the Expressive
v3 release).

Roadmap

So, we’re done, right?

Wrong!

There’s still work that remains. In particular:

  • We plan to version the existing documentation. This will allow us to provide
    version-specific docs, without confusing users about different usage and
    declarations.

  • We need to provide full documentation for the v3 release.

  • We will be issuing a 2.2 release with:

    • Deprecations, based on the v3 changes.
    • Backports of select v3 changes in order to aid migration.
  • We need to document migration from v2.2 to v3, and potentially provide
    automated tooling.

  • We anticipate users will find bugs in the RC, and will be actively
    incorporating bugfixes before the stable release.

Our target date is still 15 March 2018, but we need your help! Help by testing
the RC1 skeleton and providing your feedback. As we prepare the v2.2 release,
help by testing tooling and applying our migration documentation to your
applications, and let us know what works and what doesn’t. If you find features
that are not documented, let us know by filing issues or asking questions in
our Slack.

We look forward to the stable release, and the positive impact PSR-15 will have
on the PHP ecosystem!

Updates

  • 2018-03-01: Fixes a syntax error in the instructions for creating a
    project. Additionally, fixes a grammatical issue in one of the headers.

Privilege Escalation in 2.3M WooCommerce Shops

Who is affected Installations with the following requirements are affected by this vulnerability:
WooCommerce version < 3.2.4 WordPress version >= 4.8.3 Impact – What can an attacker do The vulnerability discussed in the following can only be exploited by an attacker that already benefits of some higher privileges. The ability to edit/add products in WooCommerce are required but not a full administration account that would allow to execute code anyway.

Are Your Labor Costs Out Of Control?

Imagine this,

You own a little cafe or a brick and mortar shop on a good street. You’ve got a handful of staff. They’re all good people.

Business seems fine. You have traffic; you’re busy on weekends. In fact, sometimes you’re so busy you kick yourself for not putting more people on the schedule because the busiest hours have you bursting at the seams.

But then you sit down to payroll and find the numbers don’t add up. You process payroll and hope your weekend deposits hit the account before the checks clear on Monday.

Everything seems to be going so well…so why is payroll such a killer?

You don’t want to pay your staff less. They work hard and you want to give them the best you can. But you know you can’t go on like this- skipping your own paychecks, putting your own money in to boost cash flow, and juggling expenses on credit cards hoping you’ll catch up later.

 

“I don’t have to imagine this….I live this!”

 

 

I’ve been there.

 

A lot of variables affect staffing in small business. Even worse, under or over staffing often masks deeper issues like poor process management or undertraining.

All good business practices begin with data, the right data. Yet, finding the right staffing balance for your business is tricky without a guide to follow.

When we started Maeva’s Coffee, I found nothing to help me understand the ins and outs of staffing.

The successful businesses I looked to held their numbers close. And the unsuccessful ones? You know the ones. They look great on social but are bleeding money through overstaffing while quietly racking up bad reviews because of slow service.

They just went of business.

In the end, all I had were general articles stating “labor costs for food service should be around 30% of revenue” and, my sister, a career barista, telling me that standard barista wages for our region were $9/hr plus tips.

Those variables are a good starting point for hiring and evaluating your year-end P&L, but if you’re losing money through

  • overstaffing

  • inefficient service

  • or high turnover

you can’t wait a year to make scheduling adjustments.

In our business, a single hour over-staffed means we have to bring in an extra $26 in revenue to break even. If four hours are wasted a day, which is easy in a shop with both a morning and evening shift, that adds up to an extra $3k in sales needed per month just to do as well as an optimally staffed business.

 

So what’s the solution?

How many people should I have on schedule?

 

I’m going to show you a calculation you can use to optimize your shop’s weekly schedule.

If your business is retail-only store, where you aren’t assembling or producing anything, the calculation is simple.

First, find the industry standard for your business’ niche.

Here’s how it would work if you ran a clothing shop:

Industry standard for annual labor (as a percentage of gross revenue) is 15.1%

If your staff’s wages are $9/hr, $9 is about 15.1% of $60.

This means any hour in which you sell $60 or less, you should only have one person on staff. That’s your breakeven point.

 

When do you add a second person? It depends on your business model.

Let’s dive further into our clothing shop example and pretend we have a boutique dress store. Formalwear requires more customer attention and additional services, like fitting for tailoring. You might decide to add a second staff member on any hours averaging more than the minimum ($60) to make sure your customer service is top notch.

It’s a risk though. You can’t predict exactly how much you’ll sell in a given hour. If you have two people on staff and sell less than $120 in revenue/per hour- you’re losing money.

Most small businesses assume some loss in labor cost. We value customer service more than our corporate counterparts. We cover this loss by hiring staff who perform better than industry standard.

Niche small businesses attract staff who have great energy, a knack for multitasking, and we invest more in training.

In our formalwear example, a veteran staff might be able to serve three prom-dress seeking customers without a problem. If this is so, we might not decide to schedule a second person until sales are averaging $300-500/hr. That’s an incredible boost to the bottom line over industry standard!

 

Let’s take this back to a simple clothing boutique, one that doesn’t have time consuming services like tailoring, etc. To maintain good customer service and lessen the chance of employee burnout, I recommend adding a second person at 1.5x the volume of the previous.

Assuming that each staff made $9 per hour:

<$60 revenue (sales) per hour                 1 staff

$61- 90 revenue per hour                         1 staff

$91- 180 revenue per hour                        2 staff

 

 

Those are the basics. Here’s how I take this a step further and fine tune to take into account behind-the-scenes labor when creating weekly schedules.

 

A Look At Maeva’s Labor

At Maeva’s, our small and mighty coffee shop at The Milton Schoolhouse, we have three staff in our kitchen. They come in for a couple of hours a day to create our fresh baked goods. In addition, I pay myself for office work, scheduling, etc.

 

Both of these payroll expenses need to be considered when thinking about how much money we have to budget for staffing behind the counter.

I need to remove these non-shop payroll expenses from our industry standard to determine how many people per hour we can afford behind our counter during operating hours.

Industry standard for coffee shops is 30%- but the number is 30% of total revenue. Our kitchen and office work comes at large intervals throughout the week- we don’t have a constant payroll expense for these. I may have a $50/hr payroll expense on Mondays when our shop is open and our kitchen staff are hard at work receiving deliveries, making soup stock and prepping food for the week. But Mondays are our slowest day- we’d never see the $150 sales hours to account for it!

 

We can’t work with the 30% industry standard hour by hour to staff our counter. That is why we need to find out:

  1. what percentage of our weekly labor is accounted for in the kitchen and office

       and

      2. subtract it from industry standard

 

to find a true percentage-per-hour on which to base our scheduling.

Last week, our kitchen and office payroll was $960.86, or, 37.6% of our payroll total.

Let’s forget the actual payroll expense and gross revenue of our shop and use a nice round number to find the percentage we should be using to calculate how many people to staff our counter by hour.

Assume revenue was $1,000 in one week and 30%  ($300) was spent in total payroll.

37.6% of that $300 was kitchen and office work ($112.80) – leaving $187.20 for your counter staff. $187.20 is 18.7% of total revenue.

We can now use this 18.7% to calculate hourly staffing in the real Maeva’s Coffee.

The average hourly wage of our staff is $9.50/hr. If I add an additional staff member at 1.5% the breakeven volume, staffing would look like this:

$0-76.5 / hr in sales revenue                 1 staff

$76.5 – 153 / hr in sales revenue            2 staff

$154 – 229 / hr in sales revenue             3 staff

$230 – 306 / hr in sales revenue            4 staff

 

 

Note: This is a VERY LOOSE calculation that doesn’t take into account your processes, your shop’s layout, how much automation your shop has, etc.


If you haven’t already put the processes and expectations in place for your staff to handle what you’ve calculated….and you find you are overstaffed… you MUST implement changes slowly.

Getting your current staff up to performance standards won’t happen overnight. You’re setting yourself up for disaster if you expect your current staff to be handling 20-50% more an hour on the next schedule without communicating these expectations and giving them the resources to do so.

Help! I’ve overstaffed. What do I do?

You’ve struggled along for years making very little profit from your business, knowing payroll is out of control. But you’re also anxious about putting fewer people on staff.

Will they be able to maintain good customer service if you set the bar higher?

What if they just don’t have the skills to handle the increase?

12 months ago, I was in the same boat with Maeva’s Coffee. I was fine working long shifts by myself, confident in my ability to multitask during fast-paced hours. During slower times, I always kept busy with extra cleaning and organizing.

One surly barista complained they didn’t like closing by themselves because it was too much work. I reacted by overstaffing. I didn’t want to be an inconsiderate, hard-ass boss after all!

The effect was instant. Overstaffing lead to boredom. In only took a few weeks morale began to slip.

One night, I was covering for a staff member and realized there was nothing to do. By the time our evening shift came on, there was literally nothing extra to stock, to dust, to wash. I was only on shift for an hour and I was dying!

 

I scaled back to where we had been immediately and was relieved when our disgruntled barista moved on.

After the experience I took a more critical look at our numbers to see what we could do better. Our shop labor expenses were averaging 22.3%- 3.6% above where we should be according to industry standard.

Here’s how I brought payroll costs under control without stressing out our staff:

 

I tested the staff’s efficiency.

I ran a speed test on our baristas after business hours. Using a series of order tickets from the day’s business, I had our baristas make the drinks while being timed. To make sure quality wasn’t sacrificed, our staff took turns tasting and temping the drinks being made by each other during the test to verify consistency.

This wasn’t able to show how they could multitask on a solo shift but it gave me data to support my assumptions of who my strongest staff were.

I didn’t fire or discipline low-performing staff. As I had expected, newer staff were slower at making drinks. I paired them with our strongest performers during our highest volume shifts; shifts where we naturally had two people on behind the counter. I asked our best staff to take time to share their own insights, tips, and tricks with our lowest performing staff. At the next testing, average production hovered just under a minute and a half with a deviation of 6.3 seconds. No one was lagging behind.

 

I met with staff and started a conversation-

about their own individual strengths and weaknesses. My full time staff and I talked about how making a commitment to longer solo shifts would leave more room for hourly wage increases and paid time off.

Think about it: My best staff can work by themselves happily and perform well above industry standard, working $80-100 sales hours without any problem. By putting them on shifts that stretch into our daily rushes just a bit, they typically save me $38 per day in labor. I saw an opportunity to split the savings as an incentive. Our best performing staff make 23-27% more than our new or slower performing staff.

Pro Tip: Conversations like this work at Maeva’s because, if you haven’t already noticed through this blog, I’m open with numbers. My staff are smart people, most of whom are in school for business or have aspirations of someday running a business of their own. They understand that even a simple business like our small coffee shop is full of complexity. By creating an open environment where our staff have access to many of the same financial reports I use, I’m able to make changes to our business model more easily because we’re all on the same page.

 

I made changes to the schedule gradually.

I knew our baristas could handle more traffic. Pacing, flow, multitasking, etc have to be learned by practice. However, much like weight lifting, you’ve got to work your way into the challenge.

On shifts I found we had been overstaffing, I started to schedule myself as that second person.

My staff all know that, in addition to Maeva’s, I run operations at The Milton Schoolhouse incubator and consult as well. I’d tell the barista on bar upfront “Hey- I’m super busy. I’m going to sit over here and work on x but, if you need help I’ll be right there.”

At first, I’d jump right in at the first sign of stress. Gradually, I’d let them work through longer ticket lines on their own. They began to find their flow. After a week or so, I’d get up to help and they would motion me to sit back down. “Hey, you keep working on what you’re doing…it’s only a couple of drinks. I’ve got this!”

The key to making this successful is framing your intent. I wasn’t sitting in the corner waiting for them to stress out so I could patronize them for not being able to handle the workload. I was their spotter at the gym, jumping in as they grew comfortable pushing their limits in a safe environment. When they changed their workflow and discovered new ways to multitask, we’d celebrate together.  

 

 

Keeping your payroll expenses under control is critical to growing as a healthy business.

Maybe you’ve run these calculations and still aren’t seeing the results you want for your business. Perhaps your brand isn’t up to your standards of quality, customer service is still poor, or profitability isn’t high enough. In my next article on staffing, I’ll help you troubleshoot these issues as we talk about

  • How to schedule with the happiness of your staff in mind

  • Creating an efficient shop layout and automating your process to increase productivity

  • And lowering your labor costs by offering better training and higher wages

 

Evocative Announces Acquisition of Cyberverse, Inc. and expansion into the Los Angeles, Phoenix and Dallas Data Center Markets

FOR IMMEDIATE RELEASE

MEDIA CONTACT:

Lisa Masiello
603-521-0015
moc.evitacovenull@sserp

Evocative Announces Acquisition of Cyberverse, Inc. and expansion into the Los Angeles, Phoenix and Dallas Data Center Markets

Evocative is expanding its footprint and bringing its highly secure edge colocation and hybrid IT solutions to the Phoenix and Dallas Markets.

San Jose, CA, February 20, 2018 – Evocative, LLC, a leading provider of secure compliant Internet infrastructure services, today announced that it has acquired Cyberverse, Inc., one of the pioneering companies in Internet services. Cyberverse was founded in 1994 by Greg Domeno and Jay Smith and over the past two and a half decades has earned the reputation of being one of the most trusted Internet infrastructure services companies. Jay Smith and the entire Cyberverse team will continue with the company. This acquisition provides Evocative additional capacity in downtown Los Angeles and expands its footprint to the Phoenix and Dallas markets. The newly acquired Tier III carrier neutral data center is located at 600 West 7th Street Los Angeles, CA in the heart of downtown and is owned and operated by Digital Realty Trust. Through the acquisition, the company now has a major presence with Aligned Data Centers in Phoenix, Arizona and Plano, Texas. The newly acquired data centers will be connected to the other 4 Evocative data centers. This is Evocative’s 4th acquisition during the last 12 months, expanding its reach as a national data center operator.

The newly added edge data and compute center adds an additional 30,000 Square Feet and 2.0 MW of capacity with expansion available to 100,000 Square Feet and 10 MW of capacity across its existing national footprint. This addition brings the company’s total capacity to over 170,000 Square Feet and 8.7 MW of IT load. All locations will be connected via multiple 40+ Gbps transport services and will create a nationwide IP backbone enabling the company to rollout active-active disaster recovery, managed distributed private cloud and complex hosting, distributed storage as well as provide direct connection to the major 4 public cloud platforms. Evocative is the trusted guardian of Internet infrastructure to over 570 clients with a roaster of Fortune 500, international and some of the best known Internet brands. Evocative is well positioned to handle flexible lab and high-density computing requirements alongside mission critical compliant colocation services. All of the company’s data centers are carrier neutral with direct access to at least 15+ native carriers and dark and lit services to major interconnection hubs. Evocative’s facilities are HIPAA, PCIDSS, SSAE16, SSAE-18, SOC 2 and ISAE3402 certified, meeting rigorous security and compliance requirements. In addition, they have consistently achieved a 100% uptime availability over the past 10 years.

Enterprises, large and small businesses and startups can benefit from Evocative’s comprehensive suite of fully customizable pay per use colocation services; managed services; public cloud interconnection, private and hybrid cloud solutions; complex hosting; network and security services. Evocative can provide visibility in terms of large scale power usage down to virtual machine resource allocation. A true pay-per-use Internet services company.

“Our primary goal as a trusted pay-per-use Internet services company is to listen to our clients and provide them the most effective solutions at fair prices. We’ve known the Cyberverse team for years and shared the same passion for providing quality services and superior customer experience. We’d like to take this opportunity to welcome our new clients, employees and partners to the Evocative family,” said Arman Khalili, Evocative’s CEO. “This acquisition is in line with our expansion plans and our acquisitions earlier this year. We look forward to continuing to grow the company both organically and through additional acquisitions.”

“I am thrilled with this acquisition and our new mission moving forward with the rest of the Evocative team,” said Jay Smith, Cyberverse’s Vice President. “We share the same views on providing top notch, high availability colocation and hosting services, while still maintaining the personalized customer service and support that our clients have come to know over the last 25 years.”

About Evocative
Evocative is a North American company and an owner and operator of secure, compliant, highly available data and compute centers.  We are the trusted guardians of our clients’ Internet infrastructure. To tour an Evocative data center or receive additional information on data center services, please visit http://www.evocative.com.

About CyberVerse

Since 1994, Cyberverse has been a pioneer in providing quality Internet services in the greater Los Angeles community. Cyberverse is Los Angeles’s most trusted provider, located at 600 W 7th Street – one of the highest-rated carrier hotels with unrivaled reliability.  The company specializes in colocation, managed services and network with emphases on top-tier product quality and personalized service for its clients.

The post Evocative Announces Acquisition of Cyberverse, Inc. and expansion into the Los Angeles, Phoenix and Dallas Data Center Markets appeared first on Evocative Data Centers.

Integrate Security Testing into PhpStorm

New State-of-the-Art Reduces Costs Typically, application security testing is performed after the source code was already committed to the source code repository. For example, a security scan is manually performed before deployment, or continuous integration is used that automatically tests the build. Our PhpStorm plugin, however, enables a new and even more efficient approach to security testing. Using our PhpStorm integration, security issues are detected where they are made – directly in the IDE.
reset password for matrix/synapse accounts

reset password for matrix/synapse accounts

Sadly Matrix/Synapse still lacks a AdminUI (issue #2032) but Users still tend to forget their passwords.

reset password for matrix/synapse accounts 4

Create Hash

Log on to your matrix account and download the hash_password script. Make it executeable and run it to create a new hash for a password.

root@matrix:~# ./hash_password -p trustno1 
$2b$12$TDvI.fxdmTDA64jO657mm.SFzoq6Xs4Fvf2XWQl7G8otiPrcr6s5m

Backup Database

Go to your location where your sqlite Database is located, stop the synapse server and make a backup first.

root@matrix:~# cd /var/lib/matrix-synapse
root@matrix:/var/lib/matrix-synapse# service matrix-synapse stop
root@matrix:/var/lib/matrix-synapse# cp homeserver.db homeserver.db.bkp

Set Password

Log in to your sqlite3 database.

root@matrix:/var/lib/matrix-synapse# sqlite3 homeserver.db

Have a Check of the already created users.

sqlite> select * from users;

Set the Hash for the User and exit.

sqlite> UPDATE users SET password_hash='$2b$12$TDvI.fxdmTDA64jO657mm.SFzoq6Xs4Fvf2XWQl7G8otiPrcr6s5m' 
  WHERE name='@foo:matrix.cavebeat.org';
sqlite> .exit

Restart Matrix

root@matrix:/var/lib/matrix-synapse# service matrix-synapse restart

That’s it, should be working fine.

 

Media Alert – Evocative President and COO Derek Garnier to Speak at Seventh Annual Northern California Data Center Summit

Garnier and other panel members will discuss how blockchain and digital currencies are affecting the modern data center.

WHO: Evocative President and COO Derek Garnier will speak at the Seventh Annual Northern California Data Center Summit.

Derek Garnier is the President & COO of Evocative and brings with him 29 years of provider experience in data center, network, and compute. Prior to joining Evocative, he served as CEO of Layer42 Networks, which was acquired by Wave Broadband in 2015, with Garnier assuming the position of SVP Data Center Services for Wave.

He has held both management and engineering roles at many top internet infrastructure providers including QTS Datacenters, United Layer, AboveNet Communications, SiteSmith, Global Crossing, Global Center, MFS Datanet, and Cabletron Systems. Garnier frequently moderates industry panels, speaks at both industry events and on radio, and provides consult for investors and companies during M&A processes.

WHAT: Blockchain & Data Centers: The Effect of Cryptocurrency on the Industry.

Garnier and other panel members will examine how blockchain technology and digital currencies are transforming data center architecture, design and development, and cloud platforms. The panel will discuss whether the requirements of cryptocurrency producers will fundamentally change the role of the traditional data center and whether the technology behind cryptocurrency will shift the demand requirements for other business verticals.

WHERE: St. Francis Yacht Club – 99 Yacht Rd., San Francisco, CA

WHEN: February 20, 2018 from 8:00am – 4:00pm

Register for CAPRE’s Seventh Annual Northern California Data Center Summit

For more information on Evocative’s suite of data center services or to take a tour of one of the company’s data centers, please visit http://www.evocative.com.

About Evocative

Evocative is a North American company and an owner and operator of secure, compliant, highly available data centers. We are the trusted guardians of our clients’ Internet infrastructure. For additional information, please visit http://www.evocative.com.

MEDIA CONTACT:

Lisa Masiello
603-521-0015
moc.evitacovenull@sserp

The post Media Alert – Evocative President and COO Derek Garnier to Speak at Seventh Annual Northern California Data Center Summit appeared first on Evocative Data Centers.

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router

There exists a seemingly endless number of VPN Providers with different kinds of quality, features and trustworthiness. They are not perfect and can not be considered as an anonymizer for everything, but they increase the privacy at least for specific use cases.

  • untrusted hostile network environment
  • public WiFi
  • P2P Torrent Traffic
  • ISP Data Retention
  • Censorship Circumvention

You should know when it’s time to use a VPN and when not. Depending on your threat-model this can secure your traffic.

In my case the Service Provider premiumize.me has added also a VPN Service. Though i usually use them for other services. But if it is in the basket, why not use it.

Other providers are for example, without any order:

  • https://frootvpn.com/
  • https://ipredator.se/
  • https://www.privatetunnel.com/
  • https://www.privateinternetaccess.com/
  • and many other more…

There exists a nice overview why you should not use or rely on a VPN service for anonymization. https://gist.github.com/joepie91/5a9909939e6ce7d09e29#dont-use-vpn-services

In this tutorial i’ll show how to run an OpenVPN client on your Router with OpenWRT. This makes it possible to have the connection always on, and reuse it in your network when u need it.

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 5

Install openvpn on OpenWRT

Following packages need to be installed:

 opkg update ; opkg install openvpn-openssl luci-app-openvpn openssl-util

The Service/OpenVPN section should become available in the LuCi Webinterface.

OpenVPN Luci Settings in OpenWRT

root@openwrt:~# openvpn --version
OpenVPN 2.4.4 mips-openwrt-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD]
library versions: OpenSSL 1.0.2n 7 Dec 2017, LZO 2.10
Originally developed by James Yonan
Copyright (C) 2002-2017 OpenVPN Technologies, Inc. 

Obtaining VPN Provider Settings

First we need the Settings for our Provider to connect with OpenVPN. Premiumize hands out client settings and their CA.crt file.

Client Settings – .ovpn file

Premiumize.me – Netherlands.ovpn

remote vpn-nl.premiumize.me
verify-x509-name CN=vpn-nl.premiumize.me
auth-user-pass
client
dev tun
proto udp
cipher AES-256-CBC
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings

-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----

verb 3
reneg-sec 0

Manually test tunnel with .ovpn file

The easiest way is to use the .ovpn file directly. SCP it to your router and place it under /etc/openvpn/nl.ovpn

root@openwrt:/etc/openvpn# ls
nl.ovpn

It’s easiest possible to test the .ovpn file directly.

root@openwrt:/etc/openvpn# openvpn nl.ovpn 
Sat Feb 17 21:10:36 2018 OpenVPN 2.4.4 mips-openwrt-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD]
Sat Feb 17 21:10:36 2018 library versions: OpenSSL 1.0.2n 7 Dec 2017, LZO 2.10
Enter Auth Username:
Enter Auth Password:
...
...
...
Sat Feb 10 19:25:15 2018 Initialization Sequence Completed

When “Initialization Sequence Completed” is printed to the screen, the device /dev/tun0 should be available and the tunnel up. Test it with ifconfig, ping and traceroute.

root@openwrt:~# ifconfig tun0
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 
 inet addr:10.8.0.29 P-t-P:10.8.0.29 Mask:255.255.0.0
 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
 RX packets:1 errors:0 dropped:0 overruns:0 frame:0
 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:100 
 RX bytes:48 (48.0 B) TX bytes:0 (0.0 B)

root@openwrt:~# ping -I tun0 blog.cavebeat.org
PING blog.cavebeat.org (31.220.43.64): 56 data bytes
64 bytes from 31.220.43.64: seq=0 ttl=58 time=59.759 ms
64 bytes from 31.220.43.64: seq=1 ttl=58 time=59.055 ms
64 bytes from 31.220.43.64: seq=2 ttl=58 time=59.755 ms
64 bytes from 31.220.43.64: seq=3 ttl=58 time=59.384 ms
^C
--- blog.cavebeat.org ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 59.055/59.488/59.759 ms

OpenWRT Settings with .ovpn

One can use the .ovpn directly in the OpenWRT Settings as an additional section in /etc/config/openvpn.

config openvpn 'nl_vpn' 
 option enabled '1' 
 option config "/etc/openvpn/nl.ovpn"

OpenWRT Settings with UCI/LUCI

Options from the .ovpn file are similar to VPN-Settings in OpenWRT. Though they are not exactly the same naming convention.

.ovpn OpenWRT
remote vpn-nl.premiumize.me list remote ‘vpn-nl.premiumize.me 1194’
verify-x509-name CN=vpn-nl.premiumize.me option verify_x509_name ‘vpn-nl.premiumize.me name’
auth-user-pass option auth_user_pass ‘/etc/openvpn/prem_userpass.txt’
client option client ‘1’
dev tun option dev ‘tun0’
proto udp option proto ‘udp’
cipher AES-256-CBC option cipher ‘aes-256-cbc’
resolv-retry infinite option resolv_retry ‘infinite’
nobind option nobind ‘1’
persist-key option persist_key ‘1’
persist-tun option persist_tun ‘1’
mute-replay-warnings option mute_replay_warnings ‘1’
verb 3 option verb ‘3’
reneg-sec 0 option reneg_sec ‘0’
ca option ca ‘/etc/openvpn/nl_prem_ca.crt’
option auth ‘sha1’
option enabled ‘1’

OpenVPN Setting in /etc/config/openvpn

root@openwrt:~# cat /etc/config/openvpn

config openvpn 'nl_prem'
 option verify_x509_name 'vpn-nl.premiumize.me name'
 list remote 'vpn-nl.premiumize.me 1194'
 option auth_user_pass '/etc/openvpn/prem_userpass.txt'
 option client '1'
 option dev 'tun0'
 option proto 'udp'
 option auth 'sha256'
 option cipher 'aes-256-cbc'
 option resolv_retry 'infinite'
 option nobind '1'
 option persist_key '1'
 option persist_tun '1'
 option ca '/etc/openvpn/nl_prem_ca.crt'
 option verb '3'
 option reneg_sec '0'
 option route_nopull '1'
 option mute_replay_warnings '1'
 option enabled '1'

It’s possible to add the settings also in Luci, but it’s easier to avoid this and add the settings manually via command line at the end of the file /etc/config/openvpn.

User Pass File

The setting auth_user_pass tells to use a Customer ID and PIN for authentication from a file.

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 6I have created a file in /etc/openvpn and added in line 1 my Customer ID and in line 2 my Premiumize PIN.

root@openwrt:~# cat /etc/config/openvpn | grep auth_user_pass
 option auth_user_pass '/etc/openvpn/prem_userpass.txt'
root@openwrt:~# cat /etc/openvpn/prem_userpass.txt
1234567890
trustno1

CA – Certificate Authority

I have placed the ca parts from the nl.ovpn file under /etc/openvpn.

root@openwrt:/etc/openvpn# cat nl_prem_ca.crt 

-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
...
...
...
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----

Ignoring redirect-gateway

If you are running OpenVPN as a client, and the server you use is using push “redirect-gateway” then your client redirects all internet traffic over the VPN. Sometimes clients do not want this, but they can not change the server’s configuration. In our case, we just want the OpenVPN Tunnel Available as an additional WAN Interface and not push just everything into it always.

I myself prefer to set the client option “option route_nopull ‘1’” and care and control the routing myself.

.ovpn OpenWRT
route-nopull option route_nopull ‘1’
--route-nopull
 When used with --client or --pull, accept options pushed by server EXCEPT for routes and dhcp options like DNS servers.
 When used on the client, this option effectively bars the server from adding routes to the client's routing table, however note that this option still allows the server to set the TCP/IP properties of the client's TUN/TAP interface.

from the OpenVPN Manpage about route-nopull

Settings in LUCI

In Luci it should be also available.

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 7VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 8

 

Create VPN Interface

In the Section Network/Interface create a new Interface with Protocol Unmanaged.

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 9VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 10Interface Configuration

root@openwrt:~# cat /etc/config/network
config interface 'nl_vpn'
 option proto 'none'
 option ifname 'tun0'
 option auto '1'

Protocol: unmanaged/none

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 11Bring Up on Boot / Auto

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 12Connected Interface name: tun0

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 13FireWall Zone – put it into a new Zone similar to your WAN Zone.

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 14

Firewall Zone Settings

root@openwrt:~# cat /etc/config/firewall 

config zone
 option name 'vpn'
 option output 'ACCEPT'
 option network 'nl_vpn'
 option masq '1'
 option input 'REJECT'
 option forward 'REJECT'
 option mtu_fix '1'

config forwarding
 option dest 'vpn'
 option src 'lan'

VPN tunnel as a WAN Interface on OpenWRT/LEDE Router 15

VPN-WAN Interface Checks

Check your Interface is up and available in ifconfig.

root@openwrt:~# ifconfig tun0
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 
 inet addr:10.8.0.33 P-t-P:10.8.0.33 Mask:255.255.0.0
 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
 RX packets:64 errors:0 dropped:0 overruns:0 frame:0
 TX packets:24 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:100 
 RX bytes:5158 (5.0 KiB) TX bytes:912 (912.0 B)

Compare a traceroute with your Tunnel Interface and with your WAN Interface.

root@openwrt:~# traceroute -i tun0 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 38 byte packets
 1 10.8.0.1 (10.8.0.1) 41.615 ms 43.000 ms 42.597 ms
 2 po-24.ce38.ams-01.nl.leaseweb.net (95.211.138.190) 42.245 ms 41.426 ms 42.694 ms
 3 te-0-5-0-10.br02.ams-01.nl.leaseweb.net (81.17.33.58) 42.514 ms xe-2-0-0.br01.ams-01.nl.leaseweb.net (81.17.33.68) 41.695 ms xe-2-1-3.br01.ams-01.nl.leaseweb.net (81.17.33.70) 41.572 ms
 4 te-0-4-0-7.bb03.ams-01.leaseweb.net (31.31.38.50) 43.000 ms te-0-0-0-7.bb03.ams-01.leaseweb.net (31.31.38.48) 42.761 ms te-0-4-0-6.bb03.ams-01.leaseweb.net (31.31.38.54) 42.602 ms
 5 unused.nl-ix.net (193.239.117.141) 43.564 ms 44.046 ms google.telecity-2-equinix-am7.nl-ix.net (193.239.117.142) 42.834 ms
 6 * * 108.170.241.193 (108.170.241.193) 44.326 ms
 7 216.239.51.171 (216.239.51.171) 44.441 ms 216.239.42.123 (216.239.42.123) 43.350 ms 108.170.230.233 (108.170.230.233) 44.816 ms
 8 google-public-dns-a.google.com (8.8.8.8) 43.820 ms 44.058 ms 44.582 ms

vs. traceroute with your WAN Interface

root@openwrt:~# traceroute -i eth0.2 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 38 byte packets
 1 10.198.64.1 (10.198.64.1) 6.240 ms 6.092 ms 5.463 ms
 2 ME36X-Manzb-01.kabsi.at (195.202.135.129) 6.701 ms 6.127 ms 7.363 ms
 3 195.202.134.82 (195.202.134.82) 8.222 ms 8.433 ms 9.342 ms
 4 te0103-asr9k-upst-inx-01.net.kabelplus.at (195.202.134.233) 18.626 ms te0011-asr9k-upst-inx-01.net.kabelplus.at (195.202.135.6) 11.888 ms 9.353 ms
 5 google.peering.cz (91.213.211.170) 15.892 ms 16.902 ms 16.608 ms
 6 108.170.245.49 (108.170.245.49) 17.024 ms 108.170.245.33 (108.170.245.33) 15.660 ms 15.917 ms
 7 216.239.63.29 (216.239.63.29) 18.292 ms 108.170.237.179 (108.170.237.179) 16.173 ms 216.239.62.183 (216.239.62.183) 18.121 ms
 8 google-public-dns-a.google.com (8.8.8.8) 15.487 ms 15.610 ms 15.236 ms

A route should be added to your tun interface

root@openwrt:~# route | grep tun0
10.8.0.0 * 255.255.0.0 U 0 0 0 tun0

Search for a line with “Initialization Sequence Completed” in your Syslog

root@openwrt:/etc/config# logread | grep openvpn | grep Seq
Sun Feb 18 17:04:21 2018 daemon.notice openvpn(nl_prem)[2752]: Initialization Sequence Completed

Usage

This new VPN-WAN Interface is now available for guest LAN/WLANs, SplitTunnel or for MultiWan Setups.

A Declaration of the Independence of Cyberspace

A Declaration of the Independence of Cyberspace

"I knew it’s also true that a good way to invent the future is to predict it. So I predicted Utopia, hoping to give Liberty a running start before the laws of Moore and Metcalfe delivered up what Ed Snowden now correctly calls 'turn-key totalitarianism.'”

A Declaration of the Independence of Cyberspace 16A Declaration of the Independence of Cyberspace

Governments of the Industrial World, you weary giants of flesh and steel, I come from Cyberspace, the new home of Mind. On behalf of the future, I ask you of the past to leave us alone. You are not welcome among us. You have no sovereignty where we gather.

We have no elected government, nor are we likely to have one, so I address you with no greater authority than that with which liberty itself always speaks. I declare the global social space we are building to be naturally independent of the tyrannies you seek to impose on us. You have no moral right to rule us nor do you possess any methods of enforcement we have true reason to fear.

Governments derive their just powers from the consent of the governed. You have neither solicited nor received ours. We did not invite you. You do not know us, nor do you know our world. Cyberspace does not lie within your borders. Do not think that you can build it, as though it were a public construction project. You cannot. It is an act of nature and it grows itself through our collective actions.

You have not engaged in our great and gathering conversation, nor did you create the wealth of our marketplaces. You do not know our culture, our ethics, or the unwritten codes that already provide our society more order than could be obtained by any of your impositions.

You claim there are problems among us that you need to solve. You use this claim as an excuse to invade our precincts. Many of these problems don't exist. Where there are real conflicts, where there are wrongs, we will identify them and address them by our means. We are forming our own Social Contract. This governance will arise according to the conditions of our world, not yours. Our world is different.

Cyberspace consists of transactions, relationships, and thought itself, arrayed like a standing wave in the web of our communications. Ours is a world that is both everywhere and nowhere, but it is not where bodies live.

We are creating a world that all may enter without privilege or prejudice accorded by race, economic power, military force, or station of birth.

We are creating a world where anyone, anywhere may express his or her beliefs, no matter how singular, without fear of being coerced into silence or conformity.

Your legal concepts of property, expression, identity, movement, and context do not apply to us. They are all based on matter, and there is no matter here.

Our identities have no bodies, so, unlike you, we cannot obtain order by physical coercion. We believe that from ethics, enlightened self-interest, and the commonweal, our governance will emerge. Our identities may be distributed across many of your jurisdictions. The only law that all our constituent cultures would generally recognize is the Golden Rule. We hope we will be able to build our particular solutions on that basis. But we cannot accept the solutions you are attempting to impose.

In the United States, you have today created a law, the Telecommunications Reform Act, which repudiates your own Constitution and insults the dreams of Jefferson, Washington, Mill, Madison, DeToqueville, and Brandeis. These dreams must now be born anew in us.

You are terrified of your own children, since they are natives in a world where you will always be immigrants. Because you fear them, you entrust your bureaucracies with the parental responsibilities you are too cowardly to confront yourselves. In our world, all the sentiments and expressions of humanity, from the debasing to the angelic, are parts of a seamless whole, the global conversation of bits. We cannot separate the air that chokes from the air upon which wings beat.

In China, Germany, France, Russia, Singapore, Italy and the United States, you are trying to ward off the virus of liberty by erecting guard posts at the frontiers of Cyberspace. These may keep out the contagion for a small time, but they will not work in a world that will soon be blanketed in bit-bearing media.

Your increasingly obsolete information industries would perpetuate themselves by proposing laws, in America and elsewhere, that claim to own speech itself throughout the world. These laws would declare ideas to be another industrial product, no more noble than pig iron. In our world, whatever the human mind may create can be reproduced and distributed infinitely at no cost. The global conveyance of thought no longer requires your factories to accomplish.

These increasingly hostile and colonial measures place us in the same position as those previous lovers of freedom and self-determination who had to reject the authorities of distant, uninformed powers. We must declare our virtual selves immune to your sovereignty, even as we continue to consent to your rule over our bodies. We will spread ourselves across the Planet so that no one can arrest our thoughts.

We will create a civilization of the Mind in Cyberspace. May it be more humane and fair than the world your governments have made before.

Davos, Switzerland
February 8, 1996
by John Perry Barlow

https://www.eff.org/deeplinks/2018/02/john-perry-barlow-internet-pioneer-1947-2018

Image from EFF License CC-BY