Why Replace Apache/PHP?
This new web server solves the following problems with Apache:
- configuration
- removes all unused options and scripting
- removes "server limit", lightweight threads can allow >100K simultaneous connections
- adds extra security features
- adds complete logging of connections
- adds proxy service to retrieve data
- adds realtime notifications
Configuration File
certfile = /dps3/ssl/dss.pem
certcafile = /dps3/ssl/dssca.pem
That's it. I'll add more options as I need them, but the idea is to keep it small and simple.
Removal of Options
This server does not support PHP or any scripting language. PHP can't do threads which causes memory usage problems
when using a large number of connections, and the server does not require any scripting capabilities anyway.
We have C++ and simple, easy-to-change source.
Server Limit
This server is designed to have 300K simultaneous connections per server for real-time notifications, these
can be load balanced for unlimited connections.
Extra Security
Security is redesigned using access lists. I have the lists split into six different files.
Paramter Checking
First we check the paramters to make sure they fit a pattern, the file parmMap.txt can have:
page=*
q=node/add
q=user
q=user/register
v=*
callback=*
pos=*
These would be the only options allowed via GET, all others get code 412 returned.
Application Checking
Next we check to see if the requested path is acceptable by checking against the positive list:
/
/about
/contact
/dps/public/dfn/terms_of_service
/faq
/main
/node/1
/node/2
/node/3
/node/4
....
/favicon.ico
/misc/ajax.js
/misc/arrow-asc.png
/misc/autocomplete.js
/misc/jquery.once.js
/misc/menu-collapsed.png
...
You can use wildcards:
/sites/default/files/css/*
Page Cache
We map certain pages to local cached files so they don't have to go to the application, ie Drupal:
/=files/main.html
/main=files/main.html
/products=files/products.html
/about=files/about.html
....
Application Map
We maintain a list of valid paths in the application, ie Drupal, because we don't want to have Drupal
have to deal with invalid requests:
/user/
/user/*
/user/*/edit
/user/*/dps/bundles
/user/*/dps/companies
/user/*/dps/devices
/user/*/dps/bundles
/user/*/dsec/companies
....
And there's extra wildcarding options here to make sure it's a valid path.
Extra Logging
The bunny server has a dedicated thread for logging so each of the worker threads only writes to memory and
aquires no resources, other than a semaphore if used with Notifications, to be efficient. Also there should be
no way for a connection to not be logged. In Apache, if a connection is established but the client doesn't send
a valid HTTP message, nothing is logged. That won't happen here, every connection is logged:
195.154.167.170 - - [21/Apr/2020:07:16:16 +0000] "GET / " 200 45966
66.249.64.20 - - [21/Apr/2020:07:17:36 +0000] "GET / " 200 45966
2.56.139.185 - - [21/Apr/2020:07:20:10 +0000] "GET / " 200 45966
2.56.139.185 - - [21/Apr/2020:07:20:12 +0000] "GET /user/register " 200 8715
2.56.139.185 - - [21/Apr/2020:07:20:15 +0000] "POST /user/register " 200 8912
209.17.97.90 - - [21/Apr/2020:07:26:22 +0000] "GET / " 200 45966
54.36.149.70 - - [21/Apr/2020:07:26:31 +0000] "GET /documents/dssClient.README.html " 200 1249
173.252.111.4 - - [21/Apr/2020:07:31:37 +0000] "NONE BAD REQUEST " 0 0
162.243.130.155 - - [21/Apr/2020:07:32:16 +0000] "GET / " 200 45966
49.70.52.44 - - [21/Apr/2020:07:42:41 +0000] "GET /promotions.html " 400 0
49.70.60.166 - - [21/Apr/2020:07:42:42 +0000] "GET /promotions.html " 400 0
42.236.12.150 - - [21/Apr/2020:07:51:22 +0000] "GET / " 200 45966
42.236.12.130 - - [21/Apr/2020:07:51:30 +0000] "GET / " 200 45966
171.67.71.243 - - [21/Apr/2020:07:52:48 +0000] "NONE BAD REQUEST " 0 0
35.154.57.40 - - [21/Apr/2020:07:55:16 +0000] "GET /console " 400 0
35.154.57.40 - - [21/Apr/2020:07:55:19 +0000] "GET /cgi-bin/test-cgi " 400 0
35.154.57.40 - - [21/Apr/2020:07:55:21 +0000] "GET / " 200 45966
35.154.57.40 - - [21/Apr/2020:07:55:24 +0000] "GET /horde/imp/test.php " 400 0
35.154.57.40 - - [21/Apr/2020:07:55:27 +0000] "GET /login.action " 400 0
54.36.149.32 - - [21/Apr/2020:07:55:29 +0000] "GET /robots.txt " 200 2189
35.154.57.40 - - [21/Apr/2020:07:55:29 +0000] "GET /login?from=0.000000 " 412 0
35.154.57.40 - - [21/Apr/2020:07:55:32 +0000] "GET /phpMyAdmin/scripts/setup.php " 400 0
35.154.57.40 - - [21/Apr/2020:07:55:34 +0000] "GET /phpmyadmin/scripts/setup.php " 400 0
35.154.57.40 - - [21/Apr/2020:07:55:36 +0000] "GET / " 200 45966
35.154.57.40 - - [21/Apr/2020:07:55:39 +0000] "GET /atutor/index.php " 400 0
54.36.150.26 - - [21/Apr/2020:07:55:40 +0000] "GET / " 200 45966
196.52.84.33 - - [21/Apr/2020:07:56:29 +0000] "GET /user/register " 200 8715
196.52.84.33 - - [21/Apr/2020:07:56:31 +0000] "GET /user/register " 200 8715
196.52.84.33 - - [21/Apr/2020:07:56:34 +0000] "POST /user/register " 200 8912
71.6.167.142 - - [21/Apr/2020:11:36:28 +0000] "GET / " 200 45966
71.6.167.142 - - [21/Apr/2020:11:36:28 +0000] "NONE BAD REQUEST " 0 0
71.6.167.142 - - [21/Apr/2020:11:36:28 +0000] "NONE BAD REQUEST " 0 0
71.6.167.142 - - [21/Apr/2020:11:36:39 +0000] "NONE BAD REQUEST " 0 0
71.6.167.142 - - [21/Apr/2020:11:36:39 +0000] "NONE BAD REQUEST " 0 0
71.6.167.142 - - [21/Apr/2020:11:36:39 +0000] "NONE BAD REQUEST " 0 0
71.6.167.142 - - [21/Apr/2020:11:36:39 +0000] "NONE BAD REQUEST " 0 0
71.6.167.142 - - [21/Apr/2020:11:36:39 +0000] "NONE BAD REQUEST " 0 0
71.6.167.142 - - [21/Apr/2020:11:36:41 +0000] "NONE BAD REQUEST " 0 0
71.6.167.142 - - [21/Apr/2020:11:36:43 +0000] "GET /robots.txt " 200 2189
71.6.167.142 - - [21/Apr/2020:11:36:43 +0000] "GET /sitemap.xml " 400 0
71.6.167.142 - - [21/Apr/2020:11:36:43 +0000] "GET /.well-known/security.txt " 400 0
71.6.167.142 - - [21/Apr/2020:11:36:43 +0000] "NONE BAD REQUEST " 0 0
71.6.167.142 - - [21/Apr/2020:11:36:43 +0000] "NONE BAD REQUEST " 0 0
71.6.167.142 - - [21/Apr/2020:11:36:44 +0000] "GET /favicon.ico " 200 3078
71.6.167.142 - - [21/Apr/2020:11:36:44 +0000] "GET /misc/ajax.js " 200 25035
71.6.167.142 - - [21/Apr/2020:11:36:44 +0000] "GET /CHANGELOG.txt " 400 0
47.57.24.93 - - [21/Apr/2020:11:39:20 +0000] "GET / " 200 45966
47.57.24.93 - - [21/Apr/2020:11:39:49 +0000] "GET /about " 200 45762
125.161.104.119 - - [21/Apr/2020:12:44:30 +0000] "GET / " 200 45966
82.115.213.54 - - [21/Apr/2020:12:44:37 +0000] "GET /?q=user " 200 45966
91.76.148.82 - - [21/Apr/2020:12:54:34 +0000] "GET / " 200 45966
198.143.155.138 - - [21/Apr/2020:12:56:32 +0000] "GET / " 200 45966
198.143.155.138 - - [21/Apr/2020:12:56:41 +0000] "NONE BAD REQUEST " 0 0
198.143.155.138 - - [21/Apr/2020:12:56:45 +0000] "NONE BAD REQUEST " 0 0
198.143.155.138 - - [21/Apr/2020:12:56:54 +0000] "NONE BAD REQUEST " 0 0
Adds Proxy Service
The Bunny Server completes the preliminary security validation for the connections and logs the result. The
rest is done with proxies so no resources are acquired by the threads, except for a semaphore with Notifications.
The BunnyMan proxy takes the requests after validation and forwards them to the appropriate place, using load
balancing as needed. The requests contains a type field and everything needed to route the messages to any
type of system, but in this case we forward to the Bunny Farm, which is in PHP/C++, for processing.
Adds Realtime Notifications
This is probably the biggest problem with Apache, when to get notified when data has changed so you can get
data in a timely way without polling?
This system should support an unlimited number of notification clients.