summaryrefslogtreecommitdiffstats
path: root/samples/services
diff options
context:
space:
mode:
Diffstat (limited to 'samples/services')
-rw-r--r--samples/services/modsecurity/docker/.htaccess3
-rw-r--r--samples/services/modsecurity/docker/Dockerfile37
-rw-r--r--samples/services/modsecurity/docker/apache2.conf227
-rw-r--r--[-rwxr-xr-x]samples/services/modsecurity/docker/build.sh (renamed from samples/services/nginx/docker/process/nginx_process.sh)6
-rw-r--r--samples/services/modsecurity/docker/docker-entrypoint.sh15
-rw-r--r--samples/services/modsecurity/docker/proxy.conf3
-rw-r--r--samples/services/modsecurity/yaml/manifest.template38
-rw-r--r--samples/services/modsecurity/yaml/modsecurity-deployment.yaml22
-rw-r--r--samples/services/modsecurity/yaml/modsecurity-service.yaml13
-rw-r--r--samples/services/modsecurity/yaml/render_yaml.py60
-rw-r--r--samples/services/nginx/docker/grpc/nginx.proto4
-rw-r--r--samples/services/nginx/docker/grpc/nginx_client.py16
-rw-r--r--samples/services/nginx/docker/grpc/nginx_grpc_server.py113
-rw-r--r--samples/services/nginx/docker/grpc/nginx_pb2.py46
-rw-r--r--samples/services/nginx/docker/grpc/templates/server.template165
-rw-r--r--samples/services/nginx/docker/grpc/templates/upload_form.template19
-rwxr-xr-xsamples/services/nginx/docker/process/start_process.sh3
-rw-r--r--samples/services/nginx/docker/subservices/lb/Dockerfile2
-rw-r--r--samples/services/nginx/docker/subservices/proxy/Dockerfile2
-rw-r--r--samples/services/nginx/docker/subservices/server/Dockerfile104
20 files changed, 819 insertions, 79 deletions
diff --git a/samples/services/modsecurity/docker/.htaccess b/samples/services/modsecurity/docker/.htaccess
new file mode 100644
index 0000000..a2b059c
--- /dev/null
+++ b/samples/services/modsecurity/docker/.htaccess
@@ -0,0 +1,3 @@
+RewriteEngine on
+RewriteCond %{REQUEST_URI} !^/index.html$
+RewriteRule . /index.html [L] \ No newline at end of file
diff --git a/samples/services/modsecurity/docker/Dockerfile b/samples/services/modsecurity/docker/Dockerfile
new file mode 100644
index 0000000..5a01f21
--- /dev/null
+++ b/samples/services/modsecurity/docker/Dockerfile
@@ -0,0 +1,37 @@
+FROM owasp/modsecurity:v2-ubuntu-apache
+MAINTAINER Jing Lu lvjing5@huawei.com
+
+ARG COMMIT=v3.1/dev
+ARG REPO=SpiderLabs/owasp-modsecurity-crs
+ENV PARANOIA=1
+
+RUN a2enmod rewrite
+
+RUN apt-get update && \
+ apt-get -y install python git ca-certificates iproute2 vim
+
+RUN cd /opt && \
+ git clone https://github.com/${REPO}.git owasp-modsecurity-crs-3.1 && \
+ cd owasp-modsecurity-crs-3.1 && \
+ git checkout -qf ${COMMIT}
+
+RUN cd /opt && \
+ cp -R /opt/owasp-modsecurity-crs-3.1/ /etc/apache2/modsecurity.d/owasp-crs/ && \
+ mv /etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf.example /etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf && \
+ cd /etc/apache2/modsecurity.d && \
+ printf "include modsecurity.d/owasp-crs/crs-setup.conf\ninclude modsecurity.d/owasp-crs/rules/*.conf" > include.conf && \
+ sed -i -e 's/SecRuleEngine DetectionOnly/SecRuleEngine On/g' /etc/apache2/modsecurity.d/modsecurity.conf && \
+ a2enmod proxy proxy_http
+
+COPY proxy.conf /etc/apache2/modsecurity.d/proxy.conf
+COPY docker-entrypoint.sh /
+
+RUN chmod 777 /docker-entrypoint.sh
+
+COPY .htaccess /var/www/html/.htaccess
+COPY apache2.conf /etc/apache2/apache2.conf
+
+EXPOSE 80
+
+ENTRYPOINT ["/docker-entrypoint.sh"]
+CMD ["apachectl", "-D", "FOREGROUND"]
diff --git a/samples/services/modsecurity/docker/apache2.conf b/samples/services/modsecurity/docker/apache2.conf
new file mode 100644
index 0000000..f7c62d6
--- /dev/null
+++ b/samples/services/modsecurity/docker/apache2.conf
@@ -0,0 +1,227 @@
+# This is the main Apache server configuration file. It contains the
+# configuration directives that give the server its instructions.
+# See http://httpd.apache.org/docs/2.4/ for detailed information about
+# the directives and /usr/share/doc/apache2/README.Debian about Debian specific
+# hints.
+#
+#
+# Summary of how the Apache 2 configuration works in Debian:
+# The Apache 2 web server configuration in Debian is quite different to
+# upstream's suggested way to configure the web server. This is because Debian's
+# default Apache2 installation attempts to make adding and removing modules,
+# virtual hosts, and extra configuration directives as flexible as possible, in
+# order to make automating the changes and administering the server as easy as
+# possible.
+
+# It is split into several files forming the configuration hierarchy outlined
+# below, all located in the /etc/apache2/ directory:
+#
+# /etc/apache2/
+# |-- apache2.conf
+# | `-- ports.conf
+# |-- mods-enabled
+# | |-- *.load
+# | `-- *.conf
+# |-- conf-enabled
+# | `-- *.conf
+# `-- sites-enabled
+# `-- *.conf
+#
+#
+# * apache2.conf is the main configuration file (this file). It puts the pieces
+# together by including all remaining configuration files when starting up the
+# web server.
+#
+# * ports.conf is always included from the main configuration file. It is
+# supposed to determine listening ports for incoming connections which can be
+# customized anytime.
+#
+# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/
+# directories contain particular configuration snippets which manage modules,
+# global configuration fragments, or virtual host configurations,
+# respectively.
+#
+# They are activated by symlinking available configuration files from their
+# respective *-available/ counterparts. These should be managed by using our
+# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See
+# their respective man pages for detailed information.
+#
+# * The binary is called apache2. Due to the use of environment variables, in
+# the default configuration, apache2 needs to be started/stopped with
+# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
+# work with the default configuration.
+
+
+# Global configuration
+#
+
+#
+# ServerRoot: The top of the directory tree under which the server's
+# configuration, error, and log files are kept.
+#
+# NOTE! If you intend to place this on an NFS (or otherwise network)
+# mounted filesystem then please read the Mutex documentation (available
+# at <URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex>);
+# you will save yourself a lot of trouble.
+#
+# Do NOT add a slash at the end of the directory path.
+#
+#ServerRoot "/etc/apache2"
+
+#
+# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
+#
+#Mutex file:${APACHE_LOCK_DIR} default
+
+#
+# The directory where shm and other runtime files will be stored.
+#
+
+DefaultRuntimeDir ${APACHE_RUN_DIR}
+
+#
+# PidFile: The file in which the server should record its process
+# identification number when it starts.
+# This needs to be set in /etc/apache2/envvars
+#
+PidFile ${APACHE_PID_FILE}
+
+#
+# Timeout: The number of seconds before receives and sends time out.
+#
+Timeout 300
+
+#
+# KeepAlive: Whether or not to allow persistent connections (more than
+# one request per connection). Set to "Off" to deactivate.
+#
+KeepAlive On
+
+#
+# MaxKeepAliveRequests: The maximum number of requests to allow
+# during a persistent connection. Set to 0 to allow an unlimited amount.
+# We recommend you leave this number high, for maximum performance.
+#
+MaxKeepAliveRequests 100
+
+#
+# KeepAliveTimeout: Number of seconds to wait for the next request from the
+# same client on the same connection.
+#
+KeepAliveTimeout 5
+
+
+# These need to be set in /etc/apache2/envvars
+User ${APACHE_RUN_USER}
+Group ${APACHE_RUN_GROUP}
+
+#
+# HostnameLookups: Log the names of clients or just their IP addresses
+# e.g., www.apache.org (on) or 204.62.129.132 (off).
+# The default is off because it'd be overall better for the net if people
+# had to knowingly turn this feature on, since enabling it means that
+# each client request will result in AT LEAST one lookup request to the
+# nameserver.
+#
+HostnameLookups Off
+
+# ErrorLog: The location of the error log file.
+# If you do not specify an ErrorLog directive within a <VirtualHost>
+# container, error messages relating to that virtual host will be
+# logged here. If you *do* define an error logfile for a <VirtualHost>
+# container, that host's errors will be logged there and not here.
+#
+ErrorLog ${APACHE_LOG_DIR}/error.log
+
+#
+# LogLevel: Control the severity of messages logged to the error_log.
+# Available values: trace8, ..., trace1, debug, info, notice, warn,
+# error, crit, alert, emerg.
+# It is also possible to configure the log level for particular modules, e.g.
+# "LogLevel info ssl:warn"
+#
+LogLevel warn
+
+# Include module configuration:
+IncludeOptional mods-enabled/*.load
+IncludeOptional mods-enabled/*.conf
+
+# Include list of ports to listen on
+Include ports.conf
+
+
+# Sets the default security model of the Apache2 HTTPD server. It does
+# not allow access to the root filesystem outside of /usr/share and /var/www.
+# The former is used by web applications packaged in Debian,
+# the latter may be used for local directories served by the web server. If
+# your system is serving content from a sub-directory in /srv you must allow
+# access here, or in any related virtual host.
+<Directory />
+ Options FollowSymLinks
+ AllowOverride None
+ Require all denied
+</Directory>
+
+<Directory /usr/share>
+ AllowOverride None
+ Require all granted
+</Directory>
+
+<Directory /var/www/>
+ Options Indexes FollowSymLinks
+ AllowOverride All
+ Require all granted
+</Directory>
+
+#<Directory /srv/>
+# Options Indexes FollowSymLinks
+# AllowOverride None
+# Require all granted
+#</Directory>
+
+
+
+
+# AccessFileName: The name of the file to look for in each directory
+# for additional configuration directives. See also the AllowOverride
+# directive.
+#
+AccessFileName .htaccess
+
+#
+# The following lines prevent .htaccess and .htpasswd files from being
+# viewed by Web clients.
+#
+<FilesMatch "^\.ht">
+ Require all denied
+</FilesMatch>
+
+
+#
+# The following directives define some format nicknames for use with
+# a CustomLog directive.
+#
+# These deviate from the Common Log Format definitions in that they use %O
+# (the actual bytes sent including headers) instead of %b (the size of the
+# requested file), because the latter makes it impossible to detect partial
+# requests.
+#
+# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
+# Use mod_remoteip instead.
+#
+LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
+LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
+LogFormat "%h %l %u %t \"%r\" %>s %O" common
+LogFormat "%{Referer}i -> %U" referer
+LogFormat "%{User-agent}i" agent
+
+# Include of directories ignores editors' and dpkg's backup files,
+# see README.Debian for details.
+
+# Include generic snippets of statements
+IncludeOptional conf-enabled/*.conf
+
+# Include the virtual host configurations:
+IncludeOptional sites-enabled/*.conf
+
+# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
diff --git a/samples/services/nginx/docker/process/nginx_process.sh b/samples/services/modsecurity/docker/build.sh
index 00edc66..ea0feed 100755..100644
--- a/samples/services/nginx/docker/process/nginx_process.sh
+++ b/samples/services/modsecurity/docker/build.sh
@@ -8,5 +8,9 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
-service nginx restart
+IMAGE_PATH=${IMAGE_PATH:-"localhost:5000"}
+IMAGE_NAME=${IMAGE_NAME:-"clover-ns-modsecurity-crs"}
+docker build -t $IMAGE_NAME .
+docker tag $IMAGE_NAME $IMAGE_PATH/$IMAGE_NAME
+docker push $IMAGE_PATH/$IMAGE_NAME
diff --git a/samples/services/modsecurity/docker/docker-entrypoint.sh b/samples/services/modsecurity/docker/docker-entrypoint.sh
new file mode 100644
index 0000000..e8e3013
--- /dev/null
+++ b/samples/services/modsecurity/docker/docker-entrypoint.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+python -c "import re;import os;out=re.sub('(#SecAction[\S\s]*id:900000[\s\S]*paranoia_level=1\")','SecAction \\\\\n \"id:900000, \\\\\n phase:1, \\\\\n nolog, \\\\\n pass, \\\\\n t:none, \\\\\n setvar:tx.paranoia_level='+os.environ['PARANOIA']+'\"',open('/etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf','r').read());open('/etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf','w').write(out)" && \
+python -c "import re;import os;out=re.sub('(#SecAction[\S\s]*id:900330[\s\S]*total_arg_length=64000\")','SecAction \\\\\n \"id:900330, \\\\\n phase:1, \\\\\n nolog, \\\\\n pass, \\\\\n t:none, \\\\\n setvar:tx.total_arg_length=64000\"',open('/etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf','r').read());open('/etc/apache2/modsecurity.d/owasp-crs/crs-setup.conf','w').write(out)" && \
+
+if [ ! -z $PROXY ]; then
+ if [ $PROXY -eq 1 ]; then
+ APACHE_ARGUMENTS='-D crs_proxy'
+ if [ -z "$UPSTREAM" ]; then
+ export UPSTREAM=$(/sbin/ip route | grep ^default | perl -pe 's/^.*?via ([\d.]+).*/$1/g'):81
+ fi
+ fi
+fi
+
+
+exec "$@" $APACHE_ARGUMENTS
diff --git a/samples/services/modsecurity/docker/proxy.conf b/samples/services/modsecurity/docker/proxy.conf
new file mode 100644
index 0000000..4dee0c9
--- /dev/null
+++ b/samples/services/modsecurity/docker/proxy.conf
@@ -0,0 +1,3 @@
+<IfDefine crs_proxy>
+ ProxyPass "/" "http://${UPSTREAM}/"
+</IfDefine>
diff --git a/samples/services/modsecurity/yaml/manifest.template b/samples/services/modsecurity/yaml/manifest.template
new file mode 100644
index 0000000..afeb9dc
--- /dev/null
+++ b/samples/services/modsecurity/yaml/manifest.template
@@ -0,0 +1,38 @@
+---
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+ name: {{ deploy_name }}
+ labels:
+ app: {{ deploy_name }}
+spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: {{ deploy_name }}
+ spec:
+ containers:
+ - name: {{ deploy_name }}
+ image: {{ image_path }}/{{ image_name }}:{{ image_tag }}
+ ports:
+ - containerPort: {{ http_port }}
+ env:
+ - name: PARANOIA
+ value: {{ paranoia_level }}
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ deploy_name }}
+ labels:
+ app: {{ deploy_name }}
+spec:
+ ports:
+ - port: {{ http_port }}
+ name: http-modsecurity-crs
+ targetPort: {{ http_port }}
+ selector:
+ app: {{ deploy_name }}
+---
diff --git a/samples/services/modsecurity/yaml/modsecurity-deployment.yaml b/samples/services/modsecurity/yaml/modsecurity-deployment.yaml
new file mode 100644
index 0000000..450ede5
--- /dev/null
+++ b/samples/services/modsecurity/yaml/modsecurity-deployment.yaml
@@ -0,0 +1,22 @@
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+ name: modsecurity-crs
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: modsecurity-crs
+ template:
+ metadata:
+ labels:
+ app: modsecurity-crs
+ spec:
+ containers:
+ - name: modsecurity-crs
+ image: clover/clover-ns-modsecurity-crs
+ ports:
+ - containerPort: 80
+ env:
+ - name: PARANOIA
+ value: '1'
diff --git a/samples/services/modsecurity/yaml/modsecurity-service.yaml b/samples/services/modsecurity/yaml/modsecurity-service.yaml
new file mode 100644
index 0000000..8548dca
--- /dev/null
+++ b/samples/services/modsecurity/yaml/modsecurity-service.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: modsecurity-crs
+spec:
+ type: NodePort
+ ports:
+ - port: 80
+ name: http-modsecurity-crs
+ protocol: TCP
+ targetPort: 80
+ selector:
+ app: modsecurity-crs
diff --git a/samples/services/modsecurity/yaml/render_yaml.py b/samples/services/modsecurity/yaml/render_yaml.py
new file mode 100644
index 0000000..54f8069
--- /dev/null
+++ b/samples/services/modsecurity/yaml/render_yaml.py
@@ -0,0 +1,60 @@
+# Copyright (c) Authors of Clover
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import argparse
+
+from jinja2 import Template
+
+
+def render_yaml(args):
+ template_file = 'manifest.template'
+ out_file = 'modsecurity.yaml'
+
+ try:
+ with open(template_file) as f:
+ tmpl = Template(f.read())
+ output = tmpl.render(
+ image_path=args['image_path'],
+ image_name=args['image_name'],
+ image_tag=args['image_tag'],
+ deploy_name=args['deploy_name'],
+ http_port=args['http_port'],
+ paranoia_level=args['paranoia_level']
+ )
+ with open(out_file, "wb") as fh:
+ fh.write(output)
+ return "Generated manifest for {}".format(args['deploy_name'])
+ except Exception as e:
+ print(e)
+ return "Unable to generate manifest for {}".format(
+ args['deploy_name'])
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '--image_name', default='clover-ns-modsecurity-crs',
+ help='The image name to use')
+ parser.add_argument(
+ '--image_path', default='localhost:5000',
+ help='The path to the image to use')
+ parser.add_argument(
+ '--image_tag', default='latest',
+ help='The image tag to use')
+ parser.add_argument(
+ '--deploy_name', default='modsecurity-crs',
+ help='The k8s deploy name to use')
+ parser.add_argument(
+ '--http_port', default='80',
+ help='Analyze http traffic on this port')
+ parser.add_argument(
+ '--paranoia_level', default='1',
+ help='The modsecurity paranoia level')
+
+ args = parser.parse_args()
+ print(render_yaml(vars(args)))
+
diff --git a/samples/services/nginx/docker/grpc/nginx.proto b/samples/services/nginx/docker/grpc/nginx.proto
index 3779a82..8255719 100644
--- a/samples/services/nginx/docker/grpc/nginx.proto
+++ b/samples/services/nginx/docker/grpc/nginx.proto
@@ -36,6 +36,10 @@ message ConfigServer {
string server_name = 2;
string site_root = 3;
string site_index = 4;
+ string upload_path_config = 5;
+ string locations = 6;
+ string upload_path_test = 7;
+ string files = 8;
}
message ConfigLB {
diff --git a/samples/services/nginx/docker/grpc/nginx_client.py b/samples/services/nginx/docker/grpc/nginx_client.py
index 7a07464..e4ddb2a 100644
--- a/samples/services/nginx/docker/grpc/nginx_client.py
+++ b/samples/services/nginx/docker/grpc/nginx_client.py
@@ -66,9 +66,21 @@ def modify_proxy(stub):
def modify_server(stub):
+ loc = []
+ val = {}
+ val['uri_match'] = "/test"
+ val['directive'] = "try_files $uri @default1"
+ val['path'] = "/test"
+ loc.append(val)
+ locations = pickle.dumps(loc)
+ files = pickle.dumps([])
response = stub.ModifyServer(nginx_pb2.ConfigServer(
- server_port='9180', server_name='clover-server',
- site_root='/var/www/html', site_index='index.nginx-debian.html'))
+ server_port='9180', server_name='clover-server1',
+ upload_path_config='/upload',
+ upload_path_test='/upload_test',
+ locations=locations,
+ files=files,
+ site_root='/var/www/html', site_index='index.html'))
print(response.message)
diff --git a/samples/services/nginx/docker/grpc/nginx_grpc_server.py b/samples/services/nginx/docker/grpc/nginx_grpc_server.py
index 1dfe708..5ad64b5 100644
--- a/samples/services/nginx/docker/grpc/nginx_grpc_server.py
+++ b/samples/services/nginx/docker/grpc/nginx_grpc_server.py
@@ -8,9 +8,12 @@
from concurrent import futures
import time
+import os
import sys
import grpc
import subprocess
+import psutil
+import shutil
import pickle
import logging
import nginx_pb2
@@ -28,23 +31,32 @@ class Controller(nginx_pb2_grpc.ControllerServicer):
logging.basicConfig(filename='nginx.log', level=logging.DEBUG)
self.service_type = service_type
self.out_file = '/etc/nginx/nginx.conf'
- # self.out_file = 'testfile'
+ self.nginx = 0
if service_type == "proxy":
- # self.template_file = 'templates/proxy.template'
self.template_file = '/grpc/templates/proxy.template'
self.ModifyProxy(nginx_pb2.ConfigProxy(
server_port='9180', server_name='proxy-access-control',
location_path='/', proxy_path='http://http-lb:9180',
mirror_path='http://snort-ids:80'), "")
if service_type == "server":
- # self.template_file = 'templates/server.template'
self.template_file = '/grpc/templates/server.template'
+ loc = []
+ val = {}
+ val['uri_match'] = "/test"
+ val['directive'] = "try_files $uri @default1"
+ val['path'] = "/test"
+ loc.append(val)
+ locations = pickle.dumps(loc)
+ files = pickle.dumps([])
self.ModifyServer(nginx_pb2.ConfigServer(
server_port='9180', server_name='clover-server',
site_root='/var/www/html',
- site_index='index.nginx-debian.html'), "")
+ upload_path_config='/upload',
+ upload_path_test='/upload_test',
+ locations=locations,
+ files=files,
+ site_index='index.html'), "")
if service_type == "lb":
- # self.template_file = 'templates/lb.template'
self.template_file = '/grpc/templates/lb.template'
slb_list = pickle.dumps(
['clover-server1:9180', 'clover-server2:9180',
@@ -76,18 +88,54 @@ class Controller(nginx_pb2_grpc.ControllerServicer):
def ModifyServer(self, r, context):
try:
+ locations = pickle.loads(r.locations)
+ # Generate nginx config
with open(self.template_file) as f:
tmpl = Template(f.read())
output = tmpl.render(
server_port=r.server_port,
server_name=r.server_name,
site_root=r.site_root,
- site_index=r.site_index
+ site_index=r.site_index,
+ upload_path_config=r.upload_path_config,
+ upload_path_test=r.upload_path_test,
+ locations=locations
)
with open(self.out_file, "wb") as fh:
fh.write(output)
+
+ # Make dirs for locations
+ for l in locations:
+ self.MakeDirs(l['path'])
+
+ # Generate upload form for config
+ template_upload = '/grpc/templates/upload_form.template'
+ out_file = r.site_root + '/' + r.site_index
+ with open(template_upload) as f:
+ tmpl = Template(f.read())
+ output = tmpl.render(
+ upload_path=r.upload_path_config
+ )
+ with open(out_file, "wb") as fh:
+ fh.write(output)
+
+ # Generate upload form for test
+ template_upload = '/grpc/templates/upload_form.template'
+ out_file = r.site_root + '/' + 'upload_test.html'
+ with open(template_upload) as f:
+ tmpl = Template(f.read())
+ output = tmpl.render(
+ upload_path=r.upload_path_test
+ )
+ with open(out_file, "wb") as fh:
+ fh.write(output)
+
msg = "Modified nginx config"
- self.RestartNginx()
+ self.RestartNginx('custom')
+
+ # Move files that have been uploaded
+ file_ops = pickle.loads(r.files)
+ self.MoveServerFiles(file_ops)
except Exception as e:
logging.debug(e)
msg = "Failed to modify nginx config"
@@ -113,9 +161,54 @@ class Controller(nginx_pb2_grpc.ControllerServicer):
msg = "Failed to modify nginx config"
return nginx_pb2.NginxReply(message=msg)
- def RestartNginx(self):
- subprocess.Popen(
- ["service nginx restart"], shell=True)
+ def DeleteServerFiles(self, upload_folder):
+ for f in os.listdir(upload_folder):
+ file_path = os.path.join(upload_folder, f)
+ try:
+ if os.path.isfile(file_path):
+ os.unlink(file_path)
+ except Exception as e:
+ logging.debug(e)
+
+ def MoveServerFiles(self, file_ops):
+ response = 1
+ try:
+ for fo in file_ops:
+ try:
+ shutil.move(fo['src_file'], fo['dest_file'])
+ except Exception as e:
+ logging.debug(e)
+ response = 0
+ except Exception as e:
+ logging.debug(e)
+ return response
+
+ def RestartNginx(self, package='default'):
+ if package == 'custom':
+ if self.nginx == 0:
+ p = subprocess.Popen(["nginx"],
+ stdout=subprocess.PIPE,
+ shell=True,
+ preexec_fn=os.setsid)
+ else:
+ for proc in psutil.process_iter():
+ if proc.name() == "nginx":
+ proc.kill()
+ p = subprocess.Popen(["nginx"],
+ stdout=subprocess.PIPE,
+ shell=True,
+ preexec_fn=os.setsid)
+ self.nginx = p
+ else:
+ subprocess.Popen(
+ ["service nginx restart"], shell=True)
+
+ def MakeDirs(self, path, prefix='/var/www/html/'):
+ try:
+ path = prefix + path.strip('/')
+ os.makedirs(path)
+ except Exception as e:
+ logging.debug(e)
def ProcessAlerts(self, request, context):
try:
diff --git a/samples/services/nginx/docker/grpc/nginx_pb2.py b/samples/services/nginx/docker/grpc/nginx_pb2.py
index 3600b6d..5665fc4 100644
--- a/samples/services/nginx/docker/grpc/nginx_pb2.py
+++ b/samples/services/nginx/docker/grpc/nginx_pb2.py
@@ -19,7 +19,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
name='nginx.proto',
package='nginx',
syntax='proto3',
- serialized_pb=_b('\n\x0bnginx.proto\x12\x05nginx\"3\n\x0c\x41lertMessage\x12\x10\n\x08\x65vent_id\x18\x01 \x01(\t\x12\x11\n\tredis_key\x18\x02 \x01(\t\"w\n\x0b\x43onfigProxy\x12\x13\n\x0bserver_port\x18\x01 \x01(\t\x12\x13\n\x0bserver_name\x18\x02 \x01(\t\x12\x15\n\rlocation_path\x18\x03 \x01(\t\x12\x12\n\nproxy_path\x18\x04 \x01(\t\x12\x13\n\x0bmirror_path\x18\x05 \x01(\t\"_\n\x0c\x43onfigServer\x12\x13\n\x0bserver_port\x18\x01 \x01(\t\x12\x13\n\x0bserver_name\x18\x02 \x01(\t\x12\x11\n\tsite_root\x18\x03 \x01(\t\x12\x12\n\nsite_index\x18\x04 \x01(\t\"j\n\x08\x43onfigLB\x12\x13\n\x0bserver_port\x18\x01 \x01(\t\x12\x13\n\x0bserver_name\x18\x02 \x01(\t\x12\x10\n\x08slb_list\x18\x03 \x01(\t\x12\x11\n\tslb_group\x18\x04 \x01(\t\x12\x0f\n\x07lb_path\x18\x05 \x01(\t\"\x1d\n\nNginxReply\x12\x0f\n\x07message\x18\x01 \x01(\t2\xeb\x01\n\nController\x12\x36\n\x0bModifyProxy\x12\x12.nginx.ConfigProxy\x1a\x11.nginx.NginxReply\"\x00\x12\x38\n\x0cModifyServer\x12\x13.nginx.ConfigServer\x1a\x11.nginx.NginxReply\"\x00\x12\x30\n\x08ModifyLB\x12\x0f.nginx.ConfigLB\x1a\x11.nginx.NginxReply\"\x00\x12\x39\n\rProcessAlerts\x12\x13.nginx.AlertMessage\x1a\x11.nginx.NginxReply\"\x00\x62\x06proto3')
+ serialized_pb=_b('\n\x0bnginx.proto\x12\x05nginx\"3\n\x0c\x41lertMessage\x12\x10\n\x08\x65vent_id\x18\x01 \x01(\t\x12\x11\n\tredis_key\x18\x02 \x01(\t\"w\n\x0b\x43onfigProxy\x12\x13\n\x0bserver_port\x18\x01 \x01(\t\x12\x13\n\x0bserver_name\x18\x02 \x01(\t\x12\x15\n\rlocation_path\x18\x03 \x01(\t\x12\x12\n\nproxy_path\x18\x04 \x01(\t\x12\x13\n\x0bmirror_path\x18\x05 \x01(\t\"\xb7\x01\n\x0c\x43onfigServer\x12\x13\n\x0bserver_port\x18\x01 \x01(\t\x12\x13\n\x0bserver_name\x18\x02 \x01(\t\x12\x11\n\tsite_root\x18\x03 \x01(\t\x12\x12\n\nsite_index\x18\x04 \x01(\t\x12\x1a\n\x12upload_path_config\x18\x05 \x01(\t\x12\x11\n\tlocations\x18\x06 \x01(\t\x12\x18\n\x10upload_path_test\x18\x07 \x01(\t\x12\r\n\x05\x66iles\x18\x08 \x01(\t\"j\n\x08\x43onfigLB\x12\x13\n\x0bserver_port\x18\x01 \x01(\t\x12\x13\n\x0bserver_name\x18\x02 \x01(\t\x12\x10\n\x08slb_list\x18\x03 \x01(\t\x12\x11\n\tslb_group\x18\x04 \x01(\t\x12\x0f\n\x07lb_path\x18\x05 \x01(\t\"\x1d\n\nNginxReply\x12\x0f\n\x07message\x18\x01 \x01(\t2\xeb\x01\n\nController\x12\x36\n\x0bModifyProxy\x12\x12.nginx.ConfigProxy\x1a\x11.nginx.NginxReply\"\x00\x12\x38\n\x0cModifyServer\x12\x13.nginx.ConfigServer\x1a\x11.nginx.NginxReply\"\x00\x12\x30\n\x08ModifyLB\x12\x0f.nginx.ConfigLB\x1a\x11.nginx.NginxReply\"\x00\x12\x39\n\rProcessAlerts\x12\x13.nginx.AlertMessage\x1a\x11.nginx.NginxReply\"\x00\x62\x06proto3')
)
@@ -157,6 +157,34 @@ _CONFIGSERVER = _descriptor.Descriptor(
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='upload_path_config', full_name='nginx.ConfigServer.upload_path_config', index=4,
+ number=5, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='locations', full_name='nginx.ConfigServer.locations', index=5,
+ number=6, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='upload_path_test', full_name='nginx.ConfigServer.upload_path_test', index=6,
+ number=7, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None, file=DESCRIPTOR),
+ _descriptor.FieldDescriptor(
+ name='files', full_name='nginx.ConfigServer.files', index=7,
+ number=8, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None, file=DESCRIPTOR),
],
extensions=[
],
@@ -169,8 +197,8 @@ _CONFIGSERVER = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=196,
- serialized_end=291,
+ serialized_start=197,
+ serialized_end=380,
)
@@ -228,8 +256,8 @@ _CONFIGLB = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=293,
- serialized_end=399,
+ serialized_start=382,
+ serialized_end=488,
)
@@ -259,8 +287,8 @@ _NGINXREPLY = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=401,
- serialized_end=430,
+ serialized_start=490,
+ serialized_end=519,
)
DESCRIPTOR.message_types_by_name['AlertMessage'] = _ALERTMESSAGE
@@ -313,8 +341,8 @@ _CONTROLLER = _descriptor.ServiceDescriptor(
file=DESCRIPTOR,
index=0,
options=None,
- serialized_start=433,
- serialized_end=668,
+ serialized_start=522,
+ serialized_end=757,
methods=[
_descriptor.MethodDescriptor(
name='ModifyProxy',
diff --git a/samples/services/nginx/docker/grpc/templates/server.template b/samples/services/nginx/docker/grpc/templates/server.template
index b5f8f1f..c1582fa 100644
--- a/samples/services/nginx/docker/grpc/templates/server.template
+++ b/samples/services/nginx/docker/grpc/templates/server.template
@@ -3,69 +3,142 @@ worker_processes auto;
pid /run/nginx.pid;
events {
- worker_connections 768;
- # multi_accept on;
+ worker_connections 768;
+ # multi_accept on;
}
http {
- ##
- # Basic Settings
- ##
+ ##
+ # Basic Settings
+ ##
- sendfile on;
- tcp_nopush on;
- tcp_nodelay on;
- keepalive_timeout 65;
- types_hash_max_size 2048;
- # server_tokens off;
+ sendfile on;
+ tcp_nopush on;
+ tcp_nodelay on;
+ keepalive_timeout 65;
+ types_hash_max_size 2048;
+ # server_tokens off;
- include /etc/nginx/mime.types;
- default_type application/octet-stream;
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
- ##
- # SSL Settings
- ##
+ ##
+ # SSL Settings
+ ##
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
- ssl_prefer_server_ciphers on;
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
+ ssl_prefer_server_ciphers on;
- ##
- # Logging Settings
- ##
+ ##
+ # Logging Settings
+ ##
- access_log /var/log/nginx/access.log;
- error_log /var/log/nginx/error.log;
+ access_log /var/log/nginx/access.log;
+ error_log /var/log/nginx/error.log;
- ##
- # Gzip Settings
- ##
+ ##
+ # Gzip Settings
+ ##
- gzip on;
- gzip_disable "msie6";
+ gzip on;
+ gzip_disable "msie6";
- # gzip_vary on;
- # gzip_proxied any;
- # gzip_comp_level 6;
- # gzip_buffers 16 8k;
- # gzip_http_version 1.1;
- # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
+ # gzip_vary on;
+ # gzip_proxied any;
+ # gzip_comp_level 6;
+ # gzip_buffers 16 8k;
+ # gzip_http_version 1.1;
+ # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
- ##
- # Virtual Host Configs
- ##
+ ##
+ # Virtual Host Configs
+ ##
- include /etc/nginx/conf.d/*.conf;
- #include /etc/nginx/sites-enabled/*;
+ include /etc/nginx/conf.d/*.conf;
+ #include /etc/nginx/sites-enabled/*;
- server {
- listen {{ server_port }};
- server_name {{ server_name }};
+ server {
+ listen {{ server_port }};
+ server_name {{ server_name }};
+ client_max_body_size 500m;
- root {{ site_root }};
- index {{ site_index }};
- }
+ root {{ site_root }};
+ index {{ site_index }};
-}
+ {%- for l in locations %}
+
+ location {{ l["uri_match"] }} {
+ {{ l["directive"] }};
+ }
+
+ {%- endfor %}
+
+ location @default1 {
+ index ../index.html;
+ }
+
+ location @default2 {
+ index ../../index.html;
+ }
+
+ location @default3 {
+ index ../../../index.html;
+ }
+
+ # Use to upload files for download
+ location {{ upload_path_config }} {
+ # Pass altered request body to this location
+ upload_pass @return_config;
+
+ # Store files to this directory
+ upload_resumable on;
+ upload_state_store /tmp/state;
+ upload_store {{ site_root }}{{ upload_path_config }};
+
+ # Allow uploaded files to be read only by user
+ #upload_store_access user:r;
+
+ # Set specified fields in request body
+ upload_set_form_field $upload_field_name.name "$upload_file_name";
+ upload_set_form_field $upload_field_name.content_type "$upload_content_type";
+ upload_set_form_field $upload_field_name.path "$upload_tmp_path";
+ upload_set_form_field $upload_field_name.server "$server_name";
+
+ # Inform backend about hash and size of a file
+ upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
+ upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";
+ upload_pass_form_field "^submit$|^description$";
+
+ upload_cleanup 400 404 499 500-505;
+ }
+
+ location @return_config {
+ proxy_pass http://clover-controller:80;
+ proxy_http_version 1.1;
+ }
+
+ # Use to upload files for performance testing
+ location {{ upload_path_test }} {
+
+ upload_pass @return_path;
+
+ # Store files to this directory
+ upload_resumable on;
+ upload_state_store /tmp/state;
+ upload_store {{ site_root }}{{ upload_path_test }};
+
+ upload_pass_form_field "^submit$|^description$";
+
+ upload_cleanup 400 404 499 500-505;
+ }
+
+ location @return_path {
+ return 204;
+ }
+
+
+ }
+}
diff --git a/samples/services/nginx/docker/grpc/templates/upload_form.template b/samples/services/nginx/docker/grpc/templates/upload_form.template
new file mode 100644
index 0000000..60f3967
--- /dev/null
+++ b/samples/services/nginx/docker/grpc/templates/upload_form.template
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Test upload</title>
+ </head>
+ <body>
+ <h2>Select files to upload</h2>
+ <form name="upload" method="POST" enctype="multipart/form-data" action="{{ upload_path }}">
+ <input type="file" name="file1"><br>
+ <input type="file" name="file2"><br>
+ <input type="file" name="file3"><br>
+ <input type="file" name="file4"><br>
+ <input type="file" name="file5"><br>
+ <input type="file" name="file6"><br>
+ <input type="submit" name="submit" value="Upload">
+ <input type="hidden" name="test" value="value">
+ </form>
+ </body>
+</html>
diff --git a/samples/services/nginx/docker/process/start_process.sh b/samples/services/nginx/docker/process/start_process.sh
index b84d2d6..47d164b 100755
--- a/samples/services/nginx/docker/process/start_process.sh
+++ b/samples/services/nginx/docker/process/start_process.sh
@@ -8,8 +8,5 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
-# Start the nginx process
-./process/nginx_process.sh
-
# Start the grpc server
./process/grpc_process.sh $1 -D
diff --git a/samples/services/nginx/docker/subservices/lb/Dockerfile b/samples/services/nginx/docker/subservices/lb/Dockerfile
index 3b13631..0cef954 100644
--- a/samples/services/nginx/docker/subservices/lb/Dockerfile
+++ b/samples/services/nginx/docker/subservices/lb/Dockerfile
@@ -20,7 +20,7 @@ RUN \
python-pip \
&& \
# Install required python packages
- python -m pip install grpcio redis jinja2 protobuf
+ python -m pip install grpcio redis jinja2 protobuf psutil
COPY /process /process
COPY /grpc /grpc
diff --git a/samples/services/nginx/docker/subservices/proxy/Dockerfile b/samples/services/nginx/docker/subservices/proxy/Dockerfile
index b063de7..07ac5f8 100644
--- a/samples/services/nginx/docker/subservices/proxy/Dockerfile
+++ b/samples/services/nginx/docker/subservices/proxy/Dockerfile
@@ -20,7 +20,7 @@ RUN \
python-pip \
&& \
# Install required python packages
- python -m pip install grpcio redis jinja2 protobuf
+ python -m pip install grpcio redis jinja2 protobuf psutil
COPY /process /process
COPY /grpc /grpc
diff --git a/samples/services/nginx/docker/subservices/server/Dockerfile b/samples/services/nginx/docker/subservices/server/Dockerfile
index 434a8d4..1a87c82 100644
--- a/samples/services/nginx/docker/subservices/server/Dockerfile
+++ b/samples/services/nginx/docker/subservices/server/Dockerfile
@@ -7,7 +7,7 @@
FROM ubuntu:16.04
LABEL maintainer="Eddie Arrage" maintainer_email="eddie.arrage@huawei.com"
-LABEL version="0.1" description="Clover - Nginx HTTP Server"
+LABEL version="0.2" description="Clover - Nginx HTTP Server"
RUN \
apt-get update && apt-get install -y \
@@ -15,14 +15,106 @@ RUN \
wget \
libdnet \
net-tools \
-# Nginx as proxy
- nginx \
+# Packages required to build nginx from source
+ build-essential \
+ libpcre3-dev \
+ libpcre3++-dev \
+ libgeoip-dev \
+ libxslt-dev \
+ git \
+# Install required python packages
python-pip \
&& \
-# Install required python packages
- python -m pip install grpcio redis jinja2 protobuf
+ python -m pip install grpcio redis jinja2 protobuf psutil \
+&& \
+# Get nginx and module add-on source
+ wget https://nginx.org/download/nginx-1.15.0.tar.gz && tar zxvf nginx-1.15.0.tar.gz \
+&& \
+ wget https://ftp.pcre.org/pub/pcre/pcre-8.42.tar.gz && tar xzvf pcre-8.42.tar.gz \
+&& \
+ wget http://www.zlib.net/zlib-1.2.11.tar.gz && tar xzvf zlib-1.2.11.tar.gz \
+&& \
+ wget https://www.openssl.org/source/openssl-1.1.0f.tar.gz && tar xzvf openssl-1.1.0f.tar.gz \
+&& \
+ git clone https://github.com/Austinb/nginx-upload-module.git \
+&& \
+ wget https://github.com/arut/nginx-rtmp-module/archive/v1.2.1.tar.gz && tar xzvf v1.2.1.tar.gz
+RUN rm -rf *.tar.gz
+
+# Build supporting modules
+ENV LDFLAGS -fPIC
+WORKDIR /pcre-8.42
+RUN ./configure
+RUN make
+RUN make install
+
+WORKDIR /zlib-1.2.11
+RUN ./configure
+RUN make
+RUN make install
+
+WORKDIR /openssl-1.1.0f
+RUN ./config
+RUN make
+RUN make install
+
+WORKDIR /nginx-1.15.0
+
+# Build nginx with all modules in stock Ubuntu 16.04 version
+# Add upload and rtmp modules
+RUN ./configure \
+ --prefix=/usr/share/nginx \
+ --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
+ --http-scgi-temp-path=/var/lib/nginx/scgi \
+ --sbin-path=/usr/sbin/nginx \
+ --conf-path=/etc/nginx/nginx.conf \
+ --error-log-path=/var/log/nginx/error.log \
+ --http-log-path=/var/log/nginx/access.log \
+ --pid-path=/run/nginx.pid \
+ --lock-path=/var/lock/nginx.lock \
+ --with-pcre=../pcre-8.42 \
+ --with-pcre-jit \
+ --with-ipv6 \
+ --with-http_stub_status_module \
+ # --with-http_image_filter_module \
+ --with-http_xslt_module \
+ --with-mail \
+ --with-zlib=../zlib-1.2.11 \
+ --with-openssl=../openssl-1.1.0f \
+ --with-openssl-opt=enable-ec_nistp_64_gcc_128 \
+ --with-openssl-opt=no-nextprotoneg \
+ --with-openssl-opt=no-weak-ssl-ciphers \
+ --with-openssl-opt=no-ssl3 \
+ --with-http_ssl_module \
+ --with-stream \
+ --with-stream_ssl_module \
+ --with-threads \
+ --with-mail=dynamic \
+ --with-mail_ssl_module \
+ --http-client-body-temp-path=/var/lib/nginx/body \
+ --http-proxy-temp-path=/var/lib/nginx/proxy \
+ --with-http_realip_module \
+ --with-http_geoip_module \
+ --http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
+ --with-http_v2_module \
+ --with-http_sub_module \
+ --with-http_addition_module \
+ --with-http_dav_module \
+ --with-http_auth_request_module \
+ --with-http_gunzip_module \
+ --with-http_gzip_static_module \
+ --with-debug \
+ --add-module=../nginx-upload-module \
+ --add-module=../nginx-rtmp-module-1.2.1
+
+RUN make
+RUN make install
+
+WORKDIR /
+RUN mkdir /var/lib/nginx
+RUN mkdir /var/www
+RUN mkdir /var/www/html
COPY /process /process
COPY /grpc /grpc
CMD ./process/start_process.sh server
-