This is an application to securely manage co-located servers.
-
The administrative interface is accessed via HTTPS.
-
The administrative interface communicates with an API via REST.
-
The API in turn communicates with a database.
Security is a requirement for each of these communications.
The contents are as follows:
The following are a list of requirements, along with partial installation instructions.
The following components are available for most operating systems, however for this exercise linux was used. The results should be the same for either Windows or OS/X.
For virtualization, docker (as opposed to Vagrant) was used.
Installation intructions are here:
http://docs.docker.com/install/
Version 18.09.0 was used for this exercise but any recent version of docker should be fine.
For development, docker-compose was used.
Installation intructions are here:
http://docs.docker.com/compose/install/
Version 1.23.1 was used for this exercise but any recent version of docker-compose should be fine.
The design considerations are as follows.
A number of significant factors were considered but are only partially addressed.
Best practices were followed such as privilege restriction, test-driven development (TDD) and 12-Factor App principles. Prepared statements were used for the database access to avoid any possibility of SQL injection attacks.
All communications are currently encrypted with SSL, using self-signed certificates.
Golang version 1.11 was used for this exercise but more recent versions should also work.
The recently introduced dependency manager formerly known as vgo
was also used.
One benefit of using Golang for the front-end client is that its HTML templating system automatically escapes all data, thereby preventing XSS attacks.
[Golang does not need to be installed locally, Docker & docker-compose will suffice.]
MySQL was chosen for the backend database.
No attempt has been made to harden the MySQL database used here as it is purely a prototype.
However, access is limited to secure connections (SSL at present, but TLS is also possible).
The production deployment (requirements to be determined) is not addressed.
Docker and Docker-Compose allow for a great deal of flexibility as to the eventual deployment.
All significant events should be logged.
It is assumed that this is a desirable feature (rather than having a single point of failure).
However this is not specifically addressed in this exercise; requirements to be determined.
While not specifically addressed in this exercise, these should be relatively simple.
Database backup & recovery requirements (frequency, etc) are still to be determined.
Traffic shaping, firewalling, and I.P. address filtering will not be addressed here.
These are probably best left to middleware components such as Istio as these types of features generally do not scale well.
The following are the operations required to build, run, and stop the application.
Build and run everything as follows:
$ docker-compose up
There can be timing problems as everything starts up. Best efforts have been made
to mitigate race conditions via sleep
commands in the docker-compose file but
there may still be problems.
The startup order needs to be:
mysql-backend --> golang-server --> golang-client
The sleep timings in the docker-compose.yml
file may need to be adjusted.
Indicates mysql-backend
has been successfully started:
mysql-backend_1 | 2018-10-15T14:40:17.087067Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.12' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
Indicates golang-server
has been successfully started:
golang-server_1 | 2018/10/15 14:40:24 Now serving servers ...
Indicates golang-client
has been successfully started:
golang-client_1 | 2018/10/15 14:40:24 Now serving servers ...
Once everything has been built, can change docker-compose.yml
as follows.
Comment:
command: bash -c "sleep 20; make"
Uncomment:
#command: bash -c "sleep 20; /Sadmin/compiled/admin_client"
Comment:
command: bash -c "sleep 10; make"
Uncomment:
#command: bash -c "sleep 10; /Sadmin/compiled/admin_server"
Can then use the following command for subsequent runs:
$ docker-compose up -d
View the build and/or execution logs as follows:
$ docker-compose logs golang-client
Or:
$ docker-compose logs golang-server
Or:
$ docker-compose logs mysql-backend
Shut everything down as follows:
$ docker-compose down
Clean up docker volumes as follows:
$ docker volume prune
Clean up docker images as follows:
$ docker rmi mramshaw4docs/golang-sadmin-client:1.11
And:
$ docker rmi mramshaw4docs/golang-sadmin-server:1.11
To query the co-located server list:
https://localhost:8200/Servers
This will probably require adding a security exception due to the self-signed certificate.
For the Chrome browser, this is as follows:
Click on the 'Advanced' button:
Click on the 'Proceed to localhost (unsafe)' link:
The web interface is password-protected.
The user is auth_user
and the password is secret
.
After a successful signin, the screen should be as follows:
Click on the 'Create Server Entry' link:
Now add a server (for example test.example.com).
Another option to create a co-located server entry:
https://localhost:8200/createServer
[This may also require adding a security exception.]
In this exercise, the following software versions were used:
- Golang 1.11
- Docker 18.09.0
- docker-compose 1.23.1
- MySQL 8.0.0
More recent versions of these components should be fine.
The following items remain to be done.
- Travis build with Go 1.11 dependency vendoring
- Update security certificates
- Update to latest version of Go (1.15.4)
- Determine requirements for Production deployment
- Determine requirements for Database replication
- Determine requirements for Database backup & recovery
- Determine requirements for Traffic shaping & firewalls
- Add
description
field to server entry - Implement TLS with certificates (currently self-signed)
- Revisit user interface